h$^I      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~                                                                                                                                                       +(c) Artem ChirkinBSD3None'(./29>?*4 easytensorFind out which basic GHC type it is at runtime. It is used for  DataFrame* backend specialization: by matching a  PrimTag a against its constructors, you can figure out a specific implementation of  Backend a ds (e.g. whether this is a specialized float array, or a generic polymorphic array). For non-basic types it defaults to C.D easytensorDefines how to read and write your data to and from Haskell unboxed byte arrays and plain pointers. Similarly to , this class provides functions to get the size and alignment of a data via phantom arguments. Thus, the size and alignment of the data must not depend on the data content (they depend only on the type of the data). In particular, this means that dynamically sized structures like Haskell lists or maps are not allowed.This module provides default implementations for all methods of this class via *. Hence, to make your data an instance of  PrimBytes., it is sufficient to write the instance head: data MyData a b = ... deriving Generic instance (PrimBytes a, PrimBytes b) => PrimBytes (MyData a b) .. or use the DeriveAnyClass# extension to make it even shorter: 6data MyData a b = ... deriving (Generic, PrimBytes) The derived instance tries to pack the data as dense as possible, but sometimes it is better to write the instance by hand. If a derived type has more than one constructor, the derived instance puts a Word32 tag at the beginning of the byte representation. All fields of a constructor are packed in a C-like fashion next to each other, while respecting their alignments.E easytensorList of field names.&It is used to get field offsets using P function.A Generic-derived instance has this list non-empty only if two obvious conditions are met: "The data has only one constructor.1The data uses record syntax to define its fields.F easytensorStore content of a data type in a primitive byte array (should be used together with  byteOffset function).Note, the default implementation of this function returns a not pinned array, which is aligned to 8. Thus, it ignores the alignment of the underlying data type if it is larger. However, alignment calculation still makes sense for data types that are smaller than 8% bytes: they are packed more densely.G easytensorStore content of a data type in a primitive byte array (should be used together with  byteOffset function).In contrast to F?, this function returns a pinned byte array, aligned to the  byteAlign bytes of this data.Note, GC guarantees not to move the created array. While this is very useful sometimes, it incurs a certain performance penalty.H easytensorLoad content of a data type from a primitive byte array given an offset in bytes.I easytensor=Read data from a mutable byte array given an offset in bytes.J easytensorWrite data into a mutable byte array at a given position (offset in bytes).K easytensor#Read data from a specified address.L easytensor"Write data to a specified address.M easytensor?@ABCDERSFMJGNHIKLOPQTUVWXYZ[\]*DERSFMJGNHIKLOPQTUVWXYZ[\456789:;<=>?@ABC]None'(./>C easytensorBroadcast element into array8Warning: do not use this function at the call site; use  instead. Otherwise you will miss some rewrite rules. easytensorIndex an array given an offset easytensor.Generate an array using an accumulator funtion easytensor3update a single element in an array given an offset easytensorIf the array is represented as a single broadcasted value, return this this value. Otherwise, return the full array content:  CumulDims7, array offset (elements), byte array with the content./Warning: never use this function directly. Use  instead. There is a bug in GHC 8.6, such that certain optimizations (probably, instance specialization/rewrite rules) break the code, which is only observable at runtime. The effect is that the content of a  becomes a garbage. The workaround is to use a non-inlinable wrapper to disable these optimizations. In addition, the wrapper function has some rewrite rules, which can potentially improve performance with other GHC versions. easytensor*Offset of an array as a number of elements easytensor$Normally, this returns a cumulative totalDims. However, if a particular implementation does not have the dimensionality information, it cannot return  CumulDims; In this case, it is a sign that all elements of an array are same. Thus, it is possible to return the single element value instead.Note, this function returns the only unique element only if it is a such by construction (there is no equality checks involved). easytensorDefine an array by its offset and cumulative dims in a ByteArray. Both offset and dims are given in element number (not in bytes)./Warning: never use this function directly. Use  instead. There is a bug in GHC 8.6, such that certain optimizations (probably, instance specialization/rewrite rules) break the code, which is only observable at runtime. The effect is that the content of a  becomes a garbage. The workaround is to use a non-inlinable wrapper to disable these optimizations. In addition, the wrapper function has some rewrite rules, which can potentially improve performance with other GHC versions. easytensorGiven Dims ns, CumulativeDims is a list of length  Length ns + 1; which cumulative totalDim accumulated on the right. In particular, its first element is  totalDim ds*, its last element is always is always 1. easytensorCalculate cumulative dims easytensor Get the total number of elements easytensorCalculate offset of an IdxsNote, you can take offset of subspace with CumulDims of larger space - very convenient!If any of the dims in ns is unknown (n ~ XN m4), then this function is unsafe and can throw an  exception. Otherwise, its safety is guaranteed by the type system. easytensorCalculate offset of an Idxs.Also check if the last index plus dimVal of subN is not bigger than the corresponding dim inside CumulDims; throw an  otherwise.If any of the dims in ns is unknown (n ~ XN m4), then this function is unsafe and can throw an  exception. Otherwise, its safety is guaranteed by the type system. easytensor;Calculate offset of an Idxs and return remaining CumulDims.If any of the dims in ns is unknown (n ~ XN m4), then this function is unsafe and can throw an  exception. Otherwise, its safety is guaranteed by the type system. easytensor;Calculate offset of an Idxs and return remaining CumulDims.Also check if the last index plus dimVal of subN is not bigger than the corresponding dim inside CumulDims; throw an  otherwise.If any of the dims in ns is unknown (n ~ XN m4), then this function is unsafe and can throw an  exception. Otherwise, its safety is guaranteed by the type system. easytensorSame as , but safe; returns Nothing if out of bounds. easytensorSame as , but safe; returns Nothing if out of bounds. Trims the first (slicing) dimension of the returned CumulDims to fit the original dataframe if necessary. easytensorSame as , but safe; returns Nothing if out of bounds. Trims the first (slicing) dimension of the returned CumulDims to fit the original dataframe if necessary. easytensor Try to get  CumulDims' from an array, and create it using Dims if failed. easytensorGet Dims by "de-accumulating"  CumulDims. easytensor3Index array by an integer offset (starting from 0). easytensor(Construct an array from a flat list and Dims; Be careful! ns depends on a, but this is not reflected in types and is not checked at runtime. easytensorIf the array is represented as a single broadcasted value, return this this value. Otherwise, return the full array content:  CumulDims7, array offset (elements), byte array with the content. easytensorDefine an array by its offset and cumulative dims in a ByteArray. Both offset and dims are given in element number (not in bytes).-It is better to use this function instead of  fromBytes to avoid recalculating  CumulDims% for implementations that require it. easytensorBroadcast element into array easytensor3Dimensionality of the result array; Be careful! ns depends on a, but this is not reflected in types and is not checked at runtime. easytensor3Dimensionality of the result array; Be careful! ns depends on a, but this is not reflected in types and is not checked at runtime. easytensorInitial offset easytensorInitial offset easytensorInitial offset easytensorInitial offsetNone&-?M  easytensorTypically, this exception can occur in an iterative algorithm; when the number of iterations exceeds a pre-defined limit, but the stop condition is not fulfilled.Use the < constraint to annotate functions that throw this exception. easytensorThis is just an alias for the " constraint. It servers two goals: Document functions that use iterative methods and can fail (supposedly in extremely rare cases).(Provide a call stack in case of failure.Use  function where necessary if you implement an iterative algorithm and annotate your implementation function with  constraint. easytensorExtra functions for  types. easytensor \sqrt{ x^2 + y^2 } .NB: in future, this function is to reimplemented using primops and should behave the same way as its C analogue. easytensor4Maximum finite number representable by this FP type. easytensorExtra functions for  types. easytensor copysign x y; returns a value with the magnitude of x and the sign of y.NB: in future, this function is to reimplemented using primops and should behave the same way as its C analogue. easytensorDefine a meaningful precision for complex floating-point operations. easytensor4A small positive number that depends on the type of a. Compare your values to epsilon to tell if they are near zero. easytensor4A small positive number that depends on the type of a. easytensor \frac{2}{\sqrt{\pi}}  easytensor \frac{2}{\pi}  easytensor \frac{1}{\pi}  easytensor \frac{\pi}{4}  easytensor \frac{\pi}{3}  easytensor \frac{\pi}{2}  easytensor \pi  easytensor \frac{1}{\sqrt{2}}  easytensor \sqrt{2}  easytensor \log_e 10  easytensor \log_e 2  easytensor \log_{10} e  easytensor \log_2 e  easytensor e  easytensor Negate if False%. This is a useful alternative to  , when  signum 0 == 0 causing some troubles. easytensorThrow a  exception. easytensorNote, this instance ignores  oodCallStack easytensorNote, this instance ignores  oodCallStack easytensorLabel (e.g. function name)(c) Artem ChirkinBSD3None./38?O easytensor Similar to  , but may be  Incomparable. easytensor2Partial order for comparing product types --  +https://en.wikipedia.org/wiki/Product_order product order. easytensorSame as , but may return  Incomparable. easytensorExtend  with  Incomparable option.(c) Artem ChirkinBSD3None./235678>?T[ easytensor Redefine  instance for a type which is a cartesian product -- as a partial  +https://en.wikipedia.org/wiki/Product_order product order.Since vanilla Haskell $ class is always about total order,  ProductOrd instance is not particularly correct. However, it turns out to be very useful for comparing vector or tuple-like types.The implementation of . in this module workarounds this by using a non-transitive  instance: 2 a = b \iff \neg (a > b) \land \neg (b > a) 5Another inconsistency with the Haskell Report is the  and  functions; these are simply element-wise minimum and maximum here. Thus, these instances preserve important properties like min a b <= a && min a b <= b(, but do not preserve a property that min a b == a || min a b == b.All of this is really useful in geometry applications and for calculating things like  /https://en.wikipedia.org/wiki/Pareto_efficiencyPareto dominance, but should be used with care. Remember about this if you want to put a  ProductOrd into a Set or a Map! easytensorTreat ! as EQ (non-transitive equality).(c) Artem ChirkinBSD3None./235678>?Y easytensor Redefine  instance for a type which is a cartesian product -- as a partial  +https://en.wikipedia.org/wiki/Product_order product order.Since vanilla Haskell $ class is always about total order,  ProductOrd instance is not particularly correct. However, it turns out to be very useful for comparing vector or tuple-like types.The implementation of . in this module workarounds this by using a partial compare function in an  instance:  \neg (a > b) \land \neg (b > a) \land \neg (a = b) \Rightarrow \mathtt{compare\ a\ b == undefined} 5Another inconsistency with the Haskell Report is the  and  functions; these are simply element-wise minimum and maximum here. Thus, these instances preserve important properties like min a b <= a && min a b <= b(, but do not preserve a property that min a b == a || min a b == b.All of this is really useful in geometry applications and for calculating things like  /https://en.wikipedia.org/wiki/Pareto_efficiencyPareto dominance=, but should be used with care. In particular, never use  ProductOrd as a key to a Set or a Map! easytensorTreat  as error (partial function).!None ./2>ZS easytensor-Specialize ScalarBase type without any arrays"None >?[ easytensor#element-wise operations for vectors easytensorSince Bounded is not implemented for floating point types, this instance has an unresolvable constraint. Nevetheless, it is good to have it here for nicer error messages.#None >?\ easytensor#element-wise operations for vectors easytensorSince Bounded is not implemented for floating point types, this instance has an unresolvable constraint. Nevetheless, it is good to have it here for nicer error messages.$None >?] easytensor#element-wise operations for vectors easytensorSince Bounded is not implemented for floating point types, this instance has an unresolvable constraint. Nevetheless, it is good to have it here for nicer error messages.%None >?_ easytensor#element-wise operations for vectors easytensorSince Bounded is not implemented for floating point types, this instance has an unresolvable constraint. Nevetheless, it is good to have it here for nicer error messages.&None >?`E easytensor#element-wise operations for vectors easytensorSince Bounded is not implemented for floating point types, this instance has an unresolvable constraint. Nevetheless, it is good to have it here for nicer error messages.'None-./>?a easytensorGeneric Array implementation. This array can reside in plain  and can share the  ByteArray#6 with other arrays. However, byte offset in the  ByteArray#& must be multiple of the element size. easytensorLexicographical ordering(None ./>?b  easytensor#Implementation behind the DataFrame3None &'(-./23>?| easytensor&Represent smart constructor functions  and . easytensorThis type family describes two strategies for dealing with dimensions when slicing a  DataFrame.!If the original space dimension (d) is fixed at compile time (d :: Nat or d ~ N n), then we enforce the safety of a slicing operation with types: the index space is bounded by the size of the original space minus the subframe size.!If the original space dimension (d) is not fixed (d ~ XN m), then we give up. Just let the user do the slicing as easy as possible, and throw an  exception at runtime if the index plus the sliced size is greater than the original size of the DataFrame. easytensor Index one dimension deep into a  DataFrame. easytensor Index one dimension deep into a  DataFrame.Note, this function does not provide indexing safety at the type level; it throws an 3 exception if an index is out of bounds (unless  unsafeindices8 package flag is enabled, which is even more dangerous). easytensorAllow inferring  KnownBackends2 if you know the dimensions and the element types. easytensorInfer  KnownBackends2 if you know the dimensions and the element types. easytensor5I use this kind-polymorphic constraint to generalize XFrame and  SomeDataFrame over  SingleFrame and  MultiFrame. easytensor*DataFrame with its type arguments swapped. easytensorData frame that has an unknown dimensionality at compile time. Pattern-match against its constructor to get a Nat-indexed data frame easytensorKeep data in a primitive data frame and maintain information about Dimensions in the type system easytensor8A scalar DataFrame is just a newtype wrapper on a value. easytensorEmpty MultiFrame easytensorConstructing a  MultiFrame using DataFrame columns easytensor)Convert a scalar back to an ordinary type easytensor$Convert any type to a scalar wrapper easytensor:Evidence that the elements of the DataFrame are PrimBytes. easytensor'Construct a DataFrame from a flat list.The values are filled according to the DataFrame layout: row-by-row and further from the last dimension (least significant) to the first dimension (most significant).%If the argument list is shorter than totalDim, then the rest of the frame is padded with a default value (second argument).$If the argument list is longer than totalDim, then unused values are dropped. If you want, you can pass an infinite list as an argument, i.e. the following is a valid use:,fromFlatList (dims :: Dims '[2,5]) 0 [6,8..] easytensorTakes d arguments of type DataFrame t ds and produce a DataFrame t (d ': ds).NB: always use TypeApplications extension with this function to apply all type arguments! Otherwise, a very dumb type family PackDF" will not infer the types for you. The following example creates a Matrix Double 12 3) filled with twelve 3D vectors (using  fromInteger of Vector Double 3):3packDF @Double @12 @'[3] 1 2 3 4 5 6 7 8 9 10 11 12 and  together serve as a generic constructor for a DataFrame of an arbitrary (statically known) size. easytensor+Takes a function (e.g. a constructor) with d+1, argument (df1, df2, .. dfd, Dict) and a DataFrame t (d ': ds). Feeds the dataframe elements into that function. For example, you can pass a tuple to this function, and get all dataframe elements (and some dictionaries -- useful evidence to work with element frames)NB: always use TypeApplications extension with this function to apply all type arguments! Otherwise, a very dumb type family PackDF" will not infer the types for you.>The following example unpacks a 3D vector (created using  fromInteger of Vector Double 34) into a 4-tuple with three scalars and one Dict: unpackDF @Double @3 @'[] (,,,) 2 and  together serve as a generic constructor for a DataFrame of an arbitrary (statically known) size. easytensor? easytensorMutable DataFrame type. Keeps element offset, number of elements, and a mutable byte storage easytensorAllow coercing between XNat -indexed and Nat-indexed Mutable DataFrames. easytensorCreate a new mutable DataFrame. easytensorCreate a new mutable DataFrame. easytensor0Create a new mutable DataFrame of the same size. easytensorView a part of a DataFrame.This function does not perform a copy. All changes to a new DataFrame will be reflected in the original DataFrame as well.If any of the dims in as or b is unknown (a ~ XN m4), then this function is unsafe and can throw an  exception. Otherwise, its safety is guaranteed by the type system. easytensorView a part of a DataFrame.This function does not perform a copy. All changes to a new DataFrame will be reflected in the original DataFrame as well.This is a simpler version of subDataFrameView2 that allows to view over one index at a time.If any of the dims in as is unknown (a ~ XN m4), then this function is unsafe and can throw an  exception. Otherwise, its safety is guaranteed by the type system. easytensorCopy one DataFrame into another mutable DataFrame at specified position.In contrast to copyDataFrame', this function allows to copy over a range of contiguous indices over a single dimension. For example, you can write a 3x4 matrix into a 7x4 matrix, starting at indices 0..3.This function is safe (no / exception possible). If any of the dims in as is unknown (a ~ XN m), you may happen to write data beyond dataframe bounds. In this case, this function does nothing. If (b ~ XN m) and (Idx bi + Dim bd > Dim b), this function copies only as many elements as fits into the dataframe along this dimension (possibly none). easytensorCopy one mutable DataFrame into another mutable DataFrame at specified position.In contrast to copyMutableDataFrame', this function allows to copy over a range of contiguous indices over a single dimension. For example, you can write a 3x4 matrix into a 7x4 matrix, starting at indices 0..3.This function is safe (no / exception possible). If any of the dims in as is unknown (a ~ XN m), you may happen to write data beyond dataframe bounds. In this case, this function does nothing. If (b ~ XN m) and (Idx bi + Dim bd > Dim b), this function copies only as many elements as fits into the dataframe along this dimension (possibly none). easytensorCopy one DataFrame into another mutable DataFrame at specified position.This is a simpler version of  copyDataFrame3 that allows to copy over one index at a time.This function is safe (no / exception possible). If any of the dims in as is unknown (a ~ XN m), you may happen to write data beyond dataframe bounds. In this case, this function does nothing. easytensorCopy one mutable DataFrame into another mutable DataFrame at specified position.This is a simpler version of copyMutableDataFrame3 that allows to copy over one index at a time.This function is safe (no / exception possible). If any of the dims in as is unknown (a ~ XN m), you may happen to write data beyond dataframe bounds. In this case, this function does nothing. easytensorCopy one DataFrame into another mutable DataFrame by offset in primitive elements.This is a low-level copy function; you have to keep in mind the row-major layout of Mutable DataFrames. Offset bounds are not checked. You will get an undefined behavior if you write beyond the DataFrame bounds. easytensorCopy one mutable DataFrame into another mutable DataFrame by offset in primitive elements.This is a low-level copy function; you have to keep in mind the row-major layout of Mutable DataFrames. Offset bounds are not checked. You will get an undefined behavior if you write beyond the DataFrame bounds. easytensor4Make a mutable DataFrame immutable, without copying. easytensorCopy content of a mutable DataFrame into a new immutable DataFrame. easytensorCreate a new mutable DataFrame and copy content of immutable one in there. easytensorCreate a new mutable DataFrame and copy content of immutable one in there. The result array is pinned and aligned. easytensor'UnsafeCoerces an underlying byte array. easytensorGiven two continuations f and g. If the input DataFrame is a single broadcast value, use it in f. Otherwise, create a new mutable DataFrame and copy content of immutable one in there; then use it in g.This function is useful when  thawDataFrame cannot be used due to  Dimensions ns constraint being not available. easytensor7Write a single element at the specified element offset.This is a low-level write function; you have to keep in mind the row-major layout of Mutable DataFrames. Offset bounds are not checked. You will get an undefined behavior if you write beyond the DataFrame bounds. easytensor.Write a single element at the specified index.This function is safe (no / exception possible). If any of the dims in ns is unknown (n ~ XN m), you may happen to write data beyond dataframe bounds. In this case, this function does nothing. easytensor6Read a single element at the specified element offset.This is a low-level read function; you have to keep in mind the row-major layout of Mutable DataFrames. Offset bounds are not checked. You will get an undefined behavior if you read beyond the DataFrame bounds. easytensor-Read a single element at the specified index.If any of the dims in ns is unknown (n ~ XN m4), then this function is unsafe and can throw an  exception. Otherwise, its safety is guaranteed by the type system. easytensorAllow arbitrary operations on a pointer to the beginning of the data. Only possible with RealWord state (thus, in IO) due to semantics of touch#< operation that keeps the data from being garbage collected. easytensorCheck if the byte array wrapped by this DataFrame is pinned, which means cannot be relocated by GC. easytensorGet cumulative dimensions ns of a MDataFrame s t ns easytensorf easytensorg (c) Artem ChirkinBSD3None&./0>? easytensor+Mutable DataFrame of unknown dimensionality easytensorMutable DataFrame that lives in ST. Internal representation is always a MutableByteArray. easytensorData frame with some dimensions missing at compile time. Pattern-match against its constructor to get a Nat-indexed mutable data frame. easytensorAllow coercing between XNat -indexed and Nat-indexed Mutable DataFrames. easytensorCreate a new mutable DataFrame. easytensorCreate a new mutable DataFrame. easytensor0Create a new mutable DataFrame of the same size. easytensorView a part of a DataFrame.This function does not perform a copy. All changes to a new DataFrame will be reflected in the original DataFrame as well.If any of the dims in as or b is unknown (a ~ XN m4), then this function is unsafe and can throw an  exception. Otherwise, its safety is guaranteed by the type system. easytensorView a part of a DataFrame.This function does not perform a copy. All changes to a new DataFrame will be reflected in the original DataFrame as well.This is a simpler version of subDataFrameView2 that allows to view over one index at a time.If any of the dims in as is unknown (a ~ XN m4), then this function is unsafe and can throw an  exception. Otherwise, its safety is guaranteed by the type system. easytensorCopy one DataFrame into another mutable DataFrame at specified position.In contrast to copyDataFrame', this function allows to copy over a range of contiguous indices over a single dimension. For example, you can write a 3x4 matrix into a 7x4 matrix, starting at indices 0..3.This function is safe (no / exception possible). If any of the dims in as is unknown (a ~ XN m), you may happen to write data beyond dataframe bounds. In this case, this function does nothing. If (b ~ XN m) and (Idx bi + Dim bd > Dim b), this function copies only as many elements as fits into the dataframe along this dimension (possibly none). easytensorCopy one mutable DataFrame into another mutable DataFrame at specified position.In contrast to copyMutableDataFrame', this function allows to copy over a range of contiguous indices over a single dimension. For example, you can write a 3x4 matrix into a 7x4 matrix, starting at indices 0..3.This function is safe (no / exception possible). If any of the dims in as is unknown (a ~ XN m), you may happen to write data beyond dataframe bounds. In this case, this function does nothing. If (b ~ XN m) and (Idx bi + Dim bd > Dim b), this function copies only as many elements as fits into the dataframe along this dimension (possibly none). easytensorCopy one DataFrame into another mutable DataFrame at specified position.This is a simpler version of  copyDataFrame3 that allows to copy over one index at a time.This function is safe (no / exception possible). If any of the dims in as is unknown (a ~ XN m), you may happen to write data beyond dataframe bounds. In this case, this function does nothing. easytensorCopy one mutable DataFrame into another mutable DataFrame at specified position.This is a simpler version of copyMutableDataFrame3 that allows to copy over one index at a time.This function is safe (no / exception possible). If any of the dims in as is unknown (a ~ XN m), you may happen to write data beyond dataframe bounds. In this case, this function does nothing. easytensorCopy one DataFrame into another mutable DataFrame by offset in primitive elements.This is a low-level copy function; you have to keep in mind the row-major layout of Mutable DataFrames. Offset bounds are not checked. You will get an undefined behavior if you write beyond the DataFrame bounds. easytensorCopy one mutable DataFrame into another mutable DataFrame by offset in primitive elements.This is a low-level copy function; you have to keep in mind the row-major layout of Mutable DataFrames. Offset bounds are not checked. You will get an undefined behavior if you write beyond the DataFrame bounds easytensor4Make a mutable DataFrame immutable, without copying. easytensorCopy content of a mutable DataFrame into a new immutable DataFrame. easytensorCreate a new mutable DataFrame and copy content of immutable one in there. easytensorCreate a new mutable DataFrame and copy content of immutable one in there. The result array is pinned and aligned. easytensor'UnsafeCoerces an underlying byte array. easytensorGiven two continuations f and g. If the input DataFrame is a single broadcast value, use it in f. Otherwise, create a new mutable DataFrame and copy content of immutable one in there; then use it in g.This function is useful when  thawDataFrame cannot be used due to  Dimensions ns constraint being not available. easytensor7Write a single element at the specified element offset.This is a low-level write function; you have to keep in mind the row-major layout of Mutable DataFrames. Offset bounds are not checked. You will get an undefined behavior if you write beyond the DataFrame bounds. easytensor.Write a single element at the specified index.This function is safe (no / exception possible). If any of the dims in ns is unknown (n ~ XN m), you may happen to write data beyond dataframe bounds. In this case, this function does nothing. easytensor6Read a single element at the specified element offset.This is a low-level read function; you have to keep in mind the row-major layout of Mutable DataFrames. Offset bounds are not checked. You will get an undefined behavior if you read beyond the DataFrame bounds. easytensor-Read a single element at the specified index.If any of the dims in ns is unknown (n ~ XN m4), then this function is unsafe and can throw an  exception. Otherwise, its safety is guaranteed by the type system. easytensorCheck if the byte array wrapped by this DataFrame is pinned, which means cannot be relocated by GC. easytensorGet cumulative dimensions ns of a STDataFrame s t ns (c) Artem ChirkinBSD3None./0>?a= easytensorOperations on DataFramesas is an indexing dimensionalitybs is an element dimensionalityt5 is an underlying data type (i.e. Float, Int, Double) easytensorDataFrames indexed by Nats and XNats require slightly different sets of constraints to be sliced. This family hides the difference, so that I could write one function for both kinds. easytensorUnsafely get a sub-dataframe by its primitive element offset. The offset is not checked to be aligned to the space structure or for bounds.Warning: this function is utterly unsafe -- it does not even throw an exception if the offset is too big; you just get an undefined behavior. easytensorUnsafely update a sub-dataframe by its primitive element offset. The offset is not checked to be aligned to the space structure or for bounds.Warning: this function is utterly unsafe -- it does not even throw an exception if the offset is too big; you just get an undefined behavior. easytensor-Get an element by its index in the dataframe.If (a ~ XN m3) then this function is unsafe and can throw an  exception. Otherwise, its safety is guaranteed by the type system. easytensorSet a new value to an element.If (a ~ XN m) and the index falls outside of the DataFrame dim, then this function returns the original DataFrame. easytensor.Map a function over each element of DataFrame. easytensor=Map a function over each element with its index of DataFrame. easytensor-Generate a DataFrame by repeating an element. easytensorGenerate a DataFrame by iterating a function (index -> element). easytensorLeft-associative lazy fold of a DataFrame. Same rules apply as for . easytensorLeft-associative strict fold of a DataFrame. Same rules apply as for `. easytensorLeft-associative lazy fold of a DataFrame with an index. Same rules apply as for . easytensorLeft-associative strict fold of a DataFrame with an index. Same rules apply as for `. easytensorRight-associative lazy fold of a DataFrame. Same rules apply as for . easytensorRight-associative strict fold of a DataFrame. Same rules apply as for `. easytensorRight-associative lazy fold of a DataFrame with an index. Same rules apply as for . easytensorRight-associative strict fold of a DataFrame with an index. Same rules apply as for `. easytensorApply an applicative functor on each element (Lens-like traversal). easytensorApply an applicative functor on each element with its index (Lens-like indexed traversal). easytensorApply an applicative functor on each element (Lens-like traversal) easytensorApply an applicative functor on each element with its index (Lens-like indexed traversal) easytensor3Apply a functor over a single element (simple lens)If (a ~ XN m) and the index falls outside of the DataFrame Dim, the argument Functor is not called and the result is pure original DataFrame. easytensorMap each element of the DataFrame to a monoid, and combine the results. easytensorMap each element of the DataFrame and its index to a monoid, and combine the results. easytensorZip two spaces on a specified subspace element-wise (without index) easytensor>Zip two spaces on a specified subspace index-wise (with index) easytensor)Flatten a nested DataFrame, analogous to . easytensorUnsafely get a sub-dataframe by its primitive element offset. The offset is not checked to be aligned to the space structure or for bounds.Warning: this function is utterly unsafe -- it does not even throw an exception if the offset is too big; you just get an undefined behavior. easytensorUnsafely update a sub-dataframe by its primitive element offset. The offset is not checked to be aligned to the space structure or for bounds.Warning: this function is utterly unsafe -- it does not even throw an exception if the offset is too big; you just get an undefined behavior. easytensor-Get an element by its index in the dataframe.If any of the dims in as is unknown (a ~ XN m4), then this function is unsafe and can throw an  exception. Otherwise, its safety is guaranteed by the type system. easytensorSet a new value to an element.If any of the dims in as is unknown (a ~ XN m), you may happen to update data beyond dataframe bounds. In this case, the original DataFrame is returned. easytensor.Map a function over each element of DataFrame. easytensor=Map a function over each element with its index of DataFrame. easytensor-Generate a DataFrame by repeating an element. easytensorGenerate a DataFrame by iterating a function (index -> element). easytensorLeft-associative lazy fold of a DataFrame. Same rules apply as for . easytensorLeft-associative strict fold of a DataFrame. Same rules apply as for `. easytensorLeft-associative lazy fold of a DataFrame with an index. Same rules apply as for . easytensorLeft-associative strict fold of a DataFrame with an index. Same rules apply as for `. easytensorRight-associative lazy fold of a DataFrame. Same rules apply as for . easytensorRight-associative strict fold of a DataFrame. Same rules apply as for `. easytensorRight-associative lazy fold of a DataFrame with an index. Same rules apply as for . easytensorRight-associative strict fold of a DataFrame with an index. Same rules apply as for `. easytensorApply an applicative functor on each element (Lens-like traversal). easytensorApply an applicative functor on each element with its index (Lens-like indexed traversal). easytensorApply an applicative functor on each element (Lens-like traversal) easytensorApply an applicative functor on each element with its index (Lens-like indexed traversal) easytensor3Apply a functor over a single element (simple lens)If any of the dims in as is unknown (a ~ XN m) and any of the corresponding indices fall outside of the DataFrame Dims, then the argument Functor is not called and the result is pure original DataFrame. easytensorMap each element of the DataFrame to a monoid, and combine the results. easytensorMap each element of the DataFrame and its index to a monoid, and combine the results. easytensorZip two spaces on a specified subspace element-wise (without index) easytensor?Zip two spaces on a specified subspace index-wise (with index). easytensorGet a few contiguous elements.7In a sense, this is just a more complicated version of sindex.If (b ~ XN m3) then this function is unsafe and can throw an  exception. Otherwise, its safety is guaranteed by the type system. easytensor!Update a few contiguous elements.7In a sense, this is just a more complicated version of .If (b ~ XN m) and (Idx bi + Dim bd > Dim b), this function updates only as many elements as fits into the dataframe along this dimension (possibly none). easytensorGet a few contiguous elements.7In a sense, this is just a more complicated version of .If any of the dims in as or b is unknown (a ~ XN m4), then this function is unsafe and can throw an  exception. Otherwise, its safety is guaranteed by the type system. easytensor!Update a few contiguous elements.7In a sense, this is just a more complicated version of .If any of the dims in as is unknown (a ~ XN m), you may happen to update data beyond dataframe bounds. In this case, the original DataFrame is returned. If (b ~ XN m) and (Idx bi + Dim bd > Dim b), this function updates only as many elements as fits into the dataframe along this dimension (possibly none). easytensorGet an element by its index in the dataframe. This is a safe alternative to  function when the index dimension is not known at compile time (a ~ XN m). easytensorGet an element by its index in the dataframe. This is a safe alternative to  function when some of the dimensions are not known at compile time (d ~ XN m). easytensorGet a few contiguous elements.7In a sense, this is just a more complicated version of .This is a safe alternative to  function when the slice dimension is not known at compile time (b ~ XN m). easytensorGet a few contiguous elements.7In a sense, this is just a more complicated version of .This is a safe alternative to  function when some of the dimensions are not known at compile time (d ~ XN m). easytensorPrim element offset easytensorPrim element offset easytensorPrim element offset easytensorPrim element offset>>4+None />?ڌ easytensor#element-wise operations for vectors easytensorSince Bounded is not implemented for floating point types, this instance has an unresolvable constraint. Nevetheless, it is good to have it here for nicer error messages.,None'(-./>?ݓ easytensor6A framework for using DataFrame type family instances.3 easytensorThis type family aggregates all types used for arrays with different dimensioinality. The family is injective; thus, it is possible to get type family instance given the data constructor (and vice versa). If GHC knows the dimensionality of a backend at compile time, it chooses a more efficient specialized instance of  BackendFamily, e.g. Scalar newtype wrapper. Otherwise, it falls back to the generic ArrayBase implementation.Data family would not work here, because it would give overlapping instances. easytensorFind an instance of  class using D and .3 (c) Artem ChirkinBSD3None&./0>?[ easytensor+Mutable DataFrame of unknown dimensionality easytensorMutable DataFrame that lives in IO. Internal representation is always a MutableByteArray. easytensorData frame with some dimensions missing at compile time. Pattern-match against its constructor to get a Nat-indexed mutable data frame. easytensorAllow coercing between XNat -indexed and Nat-indexed Mutable DataFrames. easytensorCreate a new mutable DataFrame. easytensorCreate a new mutable DataFrame. easytensor0Create a new mutable DataFrame of the same size. easytensorView a part of a DataFrame.This function does not perform a copy. All changes to a new DataFrame will be reflected in the original DataFrame as well.If any of the dims in as or b is unknown (a ~ XN m4), then this function is unsafe and can throw an  exception. Otherwise, its safety is guaranteed by the type system. easytensorView a part of a DataFrame.This function does not perform a copy. All changes to a new DataFrame will be reflected in the original DataFrame as well.This is a simpler version of subDataFrameView2 that allows to view over one index at a time.If any of the dims in as is unknown (a ~ XN m4), then this function is unsafe and can throw an  exception. Otherwise, its safety is guaranteed by the type system. easytensorCopy one DataFrame into another mutable DataFrame at specified position.In contrast to copyDataFrame', this function allows to copy over a range of contiguous indices over a single dimension. For example, you can write a 3x4 matrix into a 7x4 matrix, starting at indices 0..3.This function is safe (no / exception possible). If any of the dims in as is unknown (a ~ XN m), you may happen to write data beyond dataframe bounds. In this case, this function does nothing. If (b ~ XN m) and (Idx bi + Dim bd > Dim b), this function copies only as many elements as fits into the dataframe along this dimension (possibly none). easytensorCopy one mutable DataFrame into another mutable DataFrame at specified position.In contrast to copyMutableDataFrame', this function allows to copy over a range of contiguous indices over a single dimension. For example, you can write a 3x4 matrix into a 7x4 matrix, starting at indices 0..3.This function is safe (no / exception possible). If any of the dims in as is unknown (a ~ XN m), you may happen to write data beyond dataframe bounds. In this case, this function does nothing. If (b ~ XN m) and (Idx bi + Dim bd > Dim b), this function copies only as many elements as fits into the dataframe along this dimension (possibly none). easytensorCopy one DataFrame into another mutable DataFrame at specified position.This is a simpler version of  copyDataFrame3 that allows to copy over one index at a time.This function is safe (no / exception possible). If any of the dims in as is unknown (a ~ XN m), you may happen to write data beyond dataframe bounds. In this case, this function does nothing. easytensorCopy one mutable DataFrame into another mutable DataFrame at specified position.This is a simpler version of copyMutableDataFrame3 that allows to copy over one index at a time.This function is safe (no / exception possible). If any of the dims in as is unknown (a ~ XN m), you may happen to write data beyond dataframe bounds. In this case, this function does nothing. easytensorCopy one DataFrame into another mutable DataFrame by offset in primitive elements.This is a low-level copy function; you have to keep in mind the row-major layout of Mutable DataFrames. Offset bounds are not checked. You will get an undefined behavior if you write beyond the DataFrame bounds. easytensorCopy one mutable DataFrame into another mutable DataFrame by offset in primitive elements.This is a low-level copy function; you have to keep in mind the row-major layout of Mutable DataFrames. Offset bounds are not checked. You will get an undefined behavior if you write beyond the DataFrame bounds easytensor4Make a mutable DataFrame immutable, without copying. easytensorCopy content of a mutable DataFrame into a new immutable DataFrame. easytensorCreate a new mutable DataFrame and copy content of immutable one in there. easytensorCreate a new mutable DataFrame and copy content of immutable one in there. The result array is pinned and aligned. easytensor'UnsafeCoerces an underlying byte array. easytensorGiven two continuations f and g. If the input DataFrame is a single broadcast value, use it in f. Otherwise, create a new mutable DataFrame and copy content of immutable one in there; then use it in g.This function is useful when  thawDataFrame cannot be used due to  Dimensions ns constraint being not available. easytensor7Write a single element at the specified element offset.This is a low-level write function; you have to keep in mind the row-major layout of Mutable DataFrames. Offset bounds are not checked. You will get an undefined behavior if you write beyond the DataFrame bounds. easytensor.Write a single element at the specified index.This function is safe (no / exception possible). If any of the dims in ns is unknown (n ~ XN m), you may happen to write data beyond dataframe bounds. In this case, this function does nothing. easytensor6Read a single element at the specified element offset.This is a low-level read function; you have to keep in mind the row-major layout of Mutable DataFrames. Offset bounds are not checked. You will get an undefined behavior if you read beyond the DataFrame bounds. easytensor-Read a single element at the specified index.If any of the dims in ns is unknown (n ~ XN m4), then this function is unsafe and can throw an  exception. Otherwise, its safety is guaranteed by the type system. easytensorCheck if the byte array wrapped by this DataFrame is pinned, which means cannot be relocated by GC. easytensorGet cumulative dimensions ns of a IODataFrame t ns easytensorAllow arbitrary IO operations on a pointer to the beginning of the data keeping the data from garbage collecting until the arg function returns.Warning: do not let Ptr t leave the scope of the arg function, the data may be garbage-collected by then.Warning: use this function on a pinned DataFrame only; otherwise, the data may be relocated before the arg fun finishes. (c) Artem ChirkinBSD3chirkin@arch.ethz.chNone/0>?i easytensorGeneralization of a matrix product: take scalar product over one dimension and, thus, concatenate other dimesnions easytensorTensor contraction. In particular: 1. matrix-matrix product 2. matrix-vector or vector-matrix product 3. dot product of two vectors.7None-./>? easytensorA newtype wrapper for all DataFrame implementations. I need two layers of wrappers to provide default overlappable instances to all type classes using KnownBackend mechanics. Type arguments are redundant here; nevertheless, they improve readability of error messages. easytensorBackend resolver: Use this constraint to find any class instances defined for all DataFrame implementations, e.g. Num,  PrimBytes, etc.33-None/?n easytensor$Alias for zero-dimensional DataFrame easytensor.Broadcast scalar value onto a whole data frame NoneNone#$./2>?: easytensor)Run a Householder transformation inplace.Given some orthongonal matrix P, some matrix R and index (k,l), reflects R2 along some hyperplane, such that all elements of R below index  (k, l) ! become zeros, then updates P+ with the inverse of the same transform as R.Notes and invariants: 5The transformation happens inplace for both matrices P and R; if  R = P^\intercal A , then  R' = P^*PR = P'^\intercal A , where  P'  and  R' < are the updated versions of the input matrices,  P^*  and  A  are implicit matrices.,All elements below and to the left of index k,l in R are assumed (and not checked) to be zeros; these are not touched by the subroutine to save flops.A logical starting value for P is an identity matrix. The subroutine can be used for a QR decomposition:  Q = P .Returns True' if reflection has been performed, and False if it was not needed. This can be used to track the sign of det P. easytensor)Run a Householder transformation inplace. Similar to , but works from right to left - use to zero elements to the right from the pivot.Returns True' if reflection has been performed, and False if it was not needed. This can be used to track the sign of det P. easytensor.Temporary buffer for a Householder axis vector easytensorCurrent state of  P^\intercal easytensorCurrent state of R easytensor Pivot element easytensor.Temporary buffer for a Householder axis vector easytensorCurrent state of  P^\intercal easytensorCurrent state of R easytensor Pivot elementNone #$./ 3 easytensor#Solve a system of linear equations  Rx = b & or a linear least squares problem  \min {|| Rx - b ||}^2 , where  R  is an upper-triangular matrix. DataFrame  b 1 is modified in-place; by the end of the process  b_m = x .NB: you can use  to truncate b without performing a copy. easytensor#Solve a system of linear equations  xR = b , where  R  is an upper-triangular matrix. DataFrame  b 1 is modified in-place; by the end of the process  b = x_m . The  (n - m)  rows of R% are not used. Pad each dimension of x with  (n - m) , zeros if you want to get the full solution. easytensor#Solve a system of linear equations  Lx = b , where  L  is a lower-triangular matrix. DataFrame  b 1 is modified in-place; by the end of the process  b = x_n . The  (m - n)  columns of L are not used. Pad x with  (m - n) 4 zero elements if you want to get the full solution. easytensor#Solve a system of linear equations  xL = b & or a linear least squares problem  \min {|| xL - b ||}^2 , where  L  is a lower-triangular matrix. DataFrame  b 1 is modified in-place; by the end of the process  b_n = x  . The last  (m - n)  columns of L and b and are not touched. easytensorR easytensorCurrent state of b_m (first m rows of b) easytensorCurrent state of b (first m "columns" of x) easytensorR easytensorL easytensorCurrent state of b (first n elements of x) easytensorCurrent state of b easytensorLNone./>?  easytensorNote, Inplace here means the input frame is modified. It does not mean the algorithm does not use extra space (it does use). easytensorThe required context for sorting a DataFrame is slightly different for Nat and XNat indexed arrays. This type family abstracts away the difference. easytensorSort a  DataFrame along the first dimension.&Note: the elements (which are of type DataFrame t ns*) are compared lexicographically. easytensorSort a  DataFrame; along the first dimension using given comparison function. easytensormust not modify state!.None&'(./>? easytensor Packing and unpacking 4D vectors easytensorCompose a 4D vector easytensorUnpack 4D vector elements easytensor Packing and unpacking 3D vectors easytensorCompose a 3D vector easytensorUnpack 3D vector elements easytensor Packing and unpacking 2D vectors easytensorCompose a 2D vector easytensorUnpack 2D vector elements easytensorScalar product -- sum of Vecs' components products, propagated into whole Vec easytensor>Scalar product -- sum of Vecs' components products -- a scalar easytensorDot product of two vectors easytensorSum of absolute values easytensor'hypot function (square root of squares) easytensor.Normalize vector w.r.t. Euclidean metric (L2). easytensorMaximum of absolute values easytensorMinimum of absolute values easytensorNorm in Lp space easytensorTake a determinant of a matrix composed from two 2D vectors. Like a cross product in 2D. easytensor Cross product easytensor#Cross product for two vectors in 3D&777None0&)/None./>?%8 easytensorOperations on 4x4 transformation matrices and vectors in homogeneous coordinates. All angles are specified in radians.Note: since version 2 of  easytensor, DataFrames and matrices are row-major. A good SIMD implementation may drastically improve performance of 4D vector-matrix products of the form v %* m4, but not so much for products of the form m %* v (due to memory layout). Thus, all operations here assume the former form to benefit more from SIMD in future. easytensorCreate a translation matrix from a vector. The 4th coordinate is ignored.If  p ! 3 == 1 and  v ! 3 == 0, then p %* translate4 v == p + v easytensor*Create a translation matrix from a vector.If  p ! 3 == 1, then &p %* translate3 v == p + toHomVector v easytensorRotation matrix for a rotation around the X axis, angle is given in radians. e.g. p %* rotateX (pi/2) rotates point p around Ox by 90 degrees. easytensorRotation matrix for a rotation around the Y axis, angle is given in radians. e.g. p %* rotateY (pi/2) rotates point p around Oy by 90 degrees. easytensorRotation matrix for a rotation around the Z axis, angle is given in radians. e.g. p %* rotateZ (pi/2) rotates point p around Oz by 90 degrees. easytensorRotation matrix for a rotation around an arbitrary normalized vector e.g. p %* rotate (pi/2) v rotates point p around v by 90 degrees. easytensor1Rotation matrix from the Euler angles roll (axis Z ), yaw (axis Y'), and pitch (axis X''0). This order is known as Tait-Bryan angles (Z-Y'-X''< intrinsic rotations), or nautical angles, or Cardan angles. rotateEuler pitch yaw roll == rotateZ roll %* rotateY yaw %* rotateX pitch 8https://en.wikipedia.org/wiki/Euler_angles#Conventions_2 easytensorCreate a transform matrix using up direction, camera position and a point to look at. Just the same as GluLookAt. easytensorA perspective symmetric projection matrix. Right-handed coordinate system. (x - right, y - top) http://en.wikibooks.org/wiki/GLSL_Programming/Vertex_Transformations easytensorAn orthogonal symmetric projection matrix. Right-handed coordinate system. (x - right, y - top) http://en.wikibooks.org/wiki/GLSL_Programming/Vertex_Transformations easytensor'Add one more dimension and set it to 1. easytensor'Add one more dimension and set it to 0. easytensorTransform a homogenous vector or point into a normal 3D vector. If the last coordinate is not zero, divide the rest by it. easytensorMatrix inverse easytensorDeterminant of Mat easytensor&Mat with 1 on diagonal and 0 elsewhere easytensor3Put the same value on the Mat diagonal, 0 otherwise easytensorSum of diagonal elements easytensor Transpose Mat easytensorAlias for DataFrames of rank 2 easytensorCompose a 2x2D matrix easytensorCompose a 3x3D matrix easytensorCompose a 4x4D matrix easytensor pitch (axis X'') easytensor yaw (axis Y') easytensor roll (axis Z) easytensorThe up direction, not necessary unit length or perpendicular to the view vector easytensorThe viewers position easytensorThe point to look at easytensor.Near plane clipping distance (always positive) easytensor-Far plane clipping distance (always positive) easytensor'Field of view of the y axis, in radians easytensor(Aspect ratio, i.e. screen's width/height easytensorNear plane clipping distance easytensorFar plane clipping distance easytensorwidth easytensorheight/0None &/?1 easytensorQuaternion operations easytensor5Quaternion data type. The ordering of coordinates is  (x,y,z,w) , where w is the argument, and x y z" are the components of a 3D vector easytensorSet the quaternion in format  (x,y,z,w) easytensor+Get the values of the quaternion in format  (x,y,z,w) easytensor3Set the quaternion from 3D axis vector and argument easytensor,Set the quaternion from 4D vector in format  (x,y,z,w) easytensor0Transform the quaternion to 4D vector in format  (x,y,z,w) easytensor$Get scalar square of the quaternion.(realToFrac (square q) == q * conjugate q easytensor5Imaginary part of the quaternion (orientation vector) easytensorReal part of the quaternion easytensor/Imaginary part of the quaternion as a 3D vector easytensor'Real part of the quaternion as a scalar easytensori-th component easytensorj-th component easytensork-th component easytensor,Conjugate quaternion (negate imaginary part) easytensor9Rotates and scales vector in 3D using quaternion. Let 8 q = c (\cos \frac{\alpha}{2}, v \sin \frac{\alpha}{2})  ,  c > 0 ,  {|v|}^2 = 1  ; then the rotation angle is  \alpha , and the axis of rotation is v . Scaling is proportional to  c^2 .%rotScale q x == q * x * (conjugate q) easytensorCreates a quaternion q from two vectors a and b, such that rotScale q a == b. easytensorCreates a rotation versor from an axis vector and an angle in radians. Result is always a unit quaternion (versor). If the argument vector is zero, then result is a real unit quaternion. easytensorQuaternion rotation angle  \alpha  (where 9 q = c (\cos \frac{\alpha}{2}, v \sin \frac{\alpha}{2})  ,  c > 0 ,  {|v|}^2 = 1 ).6q /= 0 ==> axisRotation (imVec q) (qArg q) == signum q easytensorCreate a quaternion from a rotation matrix. Note, that rotations of q and -q are equivalent, there result of this function may be ambiguious. Assume the sign of the result to be chosen arbitrarily. easytensorCreate a quaternion from a homogenious coordinates trasform matrix. Ignores matrix translation transform. Note, that rotations of q and -q are equivalent, there result of this function may be ambiguious. Assume the sign of the result to be chosen arbitrarily. easytensorCreate a rotation matrix from a quaternion. Note, that rotations of q and -q1 are equivalent, so the following property holds:toMatrix33 q == toMatrix33 (-q) easytensorCreate a homogenious coordinates trasform matrix from a quaternion. Translation of the output matrix is zero. Note, that rotations of q and -q1 are equivalent, so the following property holds:toMatrix44 q == toMatrix44 (-q) easytensor (x,y,z,w) of a quaternion1None&./2>?22None&./2>?2ANone2gNone#$./2>?8 easytensorCompute QR factorization easytensorCompute LQ factorization easytensorResult of LQ factorization  A = LQ . easytensorLower-triangular matrix  L  easytensorOrthogonal matrix  Q  easytensor+A shortcut for evaluating a determinant of  |Q| = \pm 1  easytensorResult of QR factorization  A = QR . easytensorOrthogonal matrix  Q  easytensor+A shortcut for evaluating a determinant of  |Q| = \pm 1  easytensorUpper-triangular matrix  R  easytensor6Calculate determinant of a matrix via QR decomposition easytensor2Calculate inverse of a matrix via QR decomposition easytensor+Compute a QR or LQ decomposition of matrix  A : n \times m ), and solve a system of linear equations  Ax = b .If  n >= m  QR decomposition is used; if  n > m 7 this function solves linear least squares problem. If  n < m  (underdetermined system) LQ decomposition is used to yield a minimum norm solution. easytensor+Compute a QR or LQ decomposition of matrix  A : n \times m ), and solve a system of linear equations  xA = b .If  n <= m  LQ decomposition is used; if  n < m 7 this function solves linear least squares problem. If  n > m  (underdetermined system) QR decomposition is used to yield a minimum norm solution.None#$./2>?<  easytensor.Compute LU factorization with Partial Pivoting easytensor4Result of LU factorization with Partial Pivoting  PA = LU . easytensorUnit lower triangular matrix L%. All elements on the diagonal of L equal 1&. The rest of the elements satisfy |l_{ij}| \leq 1. easytensorUpper triangular matrix U easytensorRow permutation matrix P easytensorSign of permutation luPermDet == det . luPerm;  |P| = \pm 1. easytensorSolve Ax = b% problem given LU decomposition of A. easytensorSolve xA = b% problem given LU decomposition of A. easytensor2Calculate inverse of a matrix via LU decomposition easytensor6Calculate determinant of a matrix via LU decomposition  3None &/><None<//5None=&$%'()1"#!+-*./,02  DTUVNone#$./2>?B  easytensorDecomposition of a matrix  A = U B V^\intercal  such that  U  and  V  are orthogonal and  B  is bidiagonal. easytensor U  left orthogonal matrix easytensor+A shortcut for evaluating a determinant of  |U| = \pm 1  easytensorMain diagonal of  B  easytensorFirst upper diagonal of  B %; its last element equals zero if  n \geq m  easytensor B  left orthogonal matrix easytensor+A shortcut for evaluating a determinant of  |V| = \pm 1  easytensor5Put two vectors on the main and first upper diagonal. easytensorDecompose a matrix  A = U B V^\intercal  such that ( U ) and  V  are orthogonal and  B  is bidiagonal.The first returned number  None#$./2>?I  easytensor%Compute SVD factorization of a matrix easytensorResult of SVD factorization + M = svdU %* asDiag svdS %* transpose svdV . Invariants:Singular values 2 are in non-increasing order and are non-negative.%svdU and svdV are orthogonal matrices det svdU == 1NB: :https://en.wikipedia.org/wiki/Singular_value_decomposition SVD on wiki easytensorLeft-singular basis matrix easytensorVector of singular values easytensorRight-singular basis matrix easytensor4Obvious dummy implementation of SVD for 1x1 matrices easytensor0SVD of a 2x2 matrix can be computed analyticallyRelated discussion: https://scicomp.stackexchange.com/questions/8899/robust-algorithm-for-2-times-2-svd/ +https://ieeexplore.ieee.org/document/486688 easytensor,Get SVD decomposition of a 3x3 matrix using  function.This function reorders the singular components under the hood to make sure s1 >= s2 >= s3 >= 0*. Thus, it has some overhead on top of . easytensorGet SVD decomposition of a 3x3 matrix, with orthogonal matrices U and V represented as quaternions. Important: U and V are bound to be rotations at the expense of the last singular value being possibly negative.This is an adoptation of a specialized 3x3 SVD algorithm described in "Computing the Singular Value Decomposition of 3x3 matrices with minimal branching and elementary floating point operations", by A. McAdams, A. Selle, R. Tamstorf, J. Teran, E. Sifakis. 7http://pages.cs.wisc.edu/~sifakis/papers/SVD_TR1690.pdf  6789:;9:<9:=9>?9>@9>A9>B9>C9>D9>E9>F9>G9>H9>I9>J9>K9>L9>M9>N9>O9>P9>Q9>R9>S9>T9>U9>V9>W9>X9>Y9>Z9>[9>\9>]9>^9>_9>`9>a9>`9>_9>\9bc9bd9be9bf9bg9bh9bi9bj9>k,lmnopqrstuvwxyz{|}~(                                                                                      )                         *                                        ------.....................................//////////////////////////////////////////////0000000000000000000000001269:6766666!!!""""####$$$$%%%%&&&&'''++++,,9>,,,012)easytensor-2.1.1.0-K3wnLX20lxZC5twIGEvVbnNumeric.DataFrame.Type"Numeric.DataFrame.Internal.BackendNumeric.PrimBytes$Numeric.DataFrame.Internal.PrimArrayNumeric.BasicsNumeric.ProductOrd Numeric.ProductOrd.NonTransitiveNumeric.ProductOrd.Partial"Numeric.DataFrame.Internal.MutableNumeric.DataFrame.STNumeric.DataFrame.SubSpaceNumeric.DataFrame.IONumeric.DataFrame.ContractionNumeric.ScalarNumeric.Subroutine.Householder"Numeric.Subroutine.SolveTriangularNumeric.Subroutine.SortNumeric.VectorNumeric.MatrixNumeric.QuaternionNumeric.Matrix.QRNumeric.Matrix.LUNumeric.Matrix.BidiagonalNumeric.Matrix.SVDForeign.StorableStorable peekElemOff pokeElemOff peekByteOffpeek pokeByteOffpoke4Numeric.DataFrame.Internal.Backend.Family.ScalarBase1Numeric.DataFrame.Internal.Backend.Family.FloatX31Numeric.DataFrame.Internal.Backend.Family.FloatX22Numeric.DataFrame.Internal.Backend.Family.DoubleX42Numeric.DataFrame.Internal.Backend.Family.DoubleX32Numeric.DataFrame.Internal.Backend.Family.DoubleX23Numeric.DataFrame.Internal.Backend.Family.ArrayBase#Numeric.DataFrame.Internal.BackendIindexslice1Numeric.DataFrame.Internal.Backend.Family.FloatX4)Numeric.DataFrame.Internal.Backend.FamilyNumeric.Scalar.InternalNumeric.Vector.InternalNumeric.Matrix.InternalNumeric.Quaternion.Internal"Numeric.Quaternion.Internal.QFloat#Numeric.Quaternion.Internal.QDoubleNumeric.Matrix.Internal.FloatNumeric.Matrix.Internal.DoubleNumeric.DataFrameghc-prim GHC.TypesNat)dimensions-2.1.1.0-2AAe0No328E14IWRQP3FUrNumeric.Dimensions.IdxXIdxsIdxIdxsNumeric.Dimensions.DimDDnDxD0D1D2D3D4D5D6D7D8D9D10D11D12D13D14D15D16D17D18D19D20D21D22D23D24D25DimsXDims KnownDimsNXNXNatNumeric.TypedListTypeListUEmpty:*ConsSnocReverse TypedListDim BackendFamilyPrimTag PTagFloat PTagDoublePTagIntPTagInt8 PTagInt16 PTagInt32 PTagInt64PTagWord PTagWord8 PTagWord16 PTagWord32 PTagWord64PTagCharPTagPtr PTagOther PrimBytes PrimFieldsgetBytesgetBytesPinned fromBytes readBytes writeBytesreadAddr writeAddrbyteSize byteAlign byteOffsetbyteFieldOffset indexArray readArray writeArraybSizeOfbAlignOfbFieldOffsetOf bPeekElemOff bPokeElemOff bPeekByteOff bPokeByteOffbPeekbPokeprimTag$fGPrimByteskURec$fGPrimByteskURec0$fGPrimByteskURec1$fGPrimByteskURec2$fGPrimByteskURec3$fGPrimByteskURec4$fGPrimBytesk:+:$fGPrimBytesk:*:$fGPrimByteskM1$fGPrimByteskM10$fGPrimByteskU1$fGPrimByteskV1$fPrimTaggedPtr$fPrimTaggedChar$fPrimTaggedWord64$fPrimTaggedWord32$fPrimTaggedWord16$fPrimTaggedWord8$fPrimTaggedWord$fPrimTaggedInt64$fPrimTaggedInt32$fPrimTaggedInt16$fPrimTaggedInt8$fPrimTaggedInt$fPrimTaggedDouble$fPrimTaggedFloat $fPrimTaggeda$fPrimBytes(,,,,,,)$fPrimBytes(,,,,,)$fPrimBytes(,,,,)$fPrimBytes(,,,)$fPrimBytes(,,)$fPrimBytes(,)$fPrimBytesEither$fPrimBytesMaybe $fPrimBytes()$fPrimBytesTypedList$fPrimBytesTypedList0$fPrimBytesTypedList1$fPrimBytesIdx$fPrimBytesChar$fPrimBytesWord64$fPrimBytesWord32$fPrimBytesWord16$fPrimBytesWord8$fPrimBytesInt64$fPrimBytesInt32$fPrimBytesInt16$fPrimBytesInt8$fPrimBytesStablePtr$fPrimBytesFunPtr$fPrimBytesPtr$fPrimBytesDouble$fPrimBytesFloat$fPrimBytesInt$fPrimBytesWord$fGPrimByteskK1 $fShowPrimTag$fPrimBytesCDouble$fPrimBytesCFloat$fPrimBytesCSUSeconds$fPrimBytesCUSeconds$fPrimBytesCTime$fPrimBytesCClock$fPrimBytesCUIntMax$fPrimBytesCIntMax$fPrimBytesCUIntPtr$fPrimBytesCIntPtr$fPrimBytesCBool$fPrimBytesCULLong$fPrimBytesCLLong$fPrimBytesCSigAtomic$fPrimBytesCWchar$fPrimBytesCSize$fPrimBytesCPtrdiff$fPrimBytesCULong$fPrimBytesCLong$fPrimBytesCUInt$fPrimBytesCInt$fPrimBytesCUShort$fPrimBytesCShort$fPrimBytesCUChar$fPrimBytesCSChar$fPrimBytesCChar PrimArray broadcast#ix#gen#upd#withArrayContent# offsetElemsuniqueOrCumulDims fromElems# CumulDims unCumulDims cumulDims cdTotalDim cdTotalDim#cdIxcdIxSubgetOffAndStepsgetOffAndStepsSubcdIxMgetOffAndStepsMgetOffAndStepsSubMgetSteps fromStepsixOffunsafeFromFlatListwithArrayContent fromElems broadcast$fMonoidCumulDims$fSemigroupCumulDims$fShowCumulDimsTooManyIterationsIterativeMethodRealFloatExtrashypot maxFinite RealExtrascopysignEpsilonepsilonM_EPS M_2_SQRTPIM_2_PIM_1_PIM_PI_4M_PI_3M_PI_2M_PI M_SQRT1_2M_SQRT2M_LN10M_LN2M_LOG10EM_LOG2EM_E negateUnlesstooManyIterations$fEpsilonFloat$fEpsilonDouble$fRealExtrasDouble$fRealExtrasFloat$fRealExtrasWord64$fRealExtrasWord32$fRealExtrasWord16$fRealExtrasWord8$fRealExtrasWord$fRealExtrasInt64$fRealExtrasInt32$fRealExtrasInt16$fRealExtrasInt8$fRealExtrasInt$fRealFloatExtrasDouble$fRealFloatExtrasFloat$fExceptionTooManyIterations$fShowTooManyIterations$fOrdTooManyIterations$fEqTooManyIterationsPartialOrderingPLTPEQPGT Incomparable ProductOrdercmp fromOrdering$fMonoidPartialOrdering$fSemigroupPartialOrdering$fProductOrder(,,,,,,,,)$fProductOrder(,,,,,,,)$fProductOrder(,,,,,,)$fProductOrder(,,,,,)$fProductOrder(,,,,)$fProductOrder(,,,)$fProductOrder(,,)$fProductOrder(,)$fProductOrderTypedList$fEqPartialOrdering$fOrdPartialOrdering$fShowPartialOrdering$fReadPartialOrdering$fDataPartialOrdering$fGenericPartialOrdering$fEnumPartialOrdering$fBoundedPartialOrdering ProductOrd getProductOrd toOrdering$fOrdProductOrd$fOrdProductOrd0$fOrdProductOrd1$fOrdProductOrd2$fOrdProductOrd3$fOrdProductOrd4$fOrdProductOrd5$fOrdProductOrd6$fOrdProductOrd7$fEqProductOrd$fMonadZipProductOrd$fMonadFixProductOrd$fMonadProductOrd$fApplicativeProductOrd$fFunctorProductOrd$fFoldableProductOrd$fShowProductOrd$fReadProductOrd$fDataProductOrd$fGenericProductOrd$fGeneric1TYPEProductOrd$fNumProductOrd$fEnumProductOrd$fBoundedProductOrd$fFloatingProductOrd$fFractionalProductOrd$fSemigroupProductOrd$fMonoidProductOrd$fStorableProductOrd$fTraversableProductOrd$fRealFloatProductOrd$fRealFracProductOrd$fRealProductOrd$fFiniteBitsProductOrd$fBitsProductOrd$fIntegralProductOrd$fEqProductOrd0Backend _getBackend KnownBackendinferPrimArrayinferPrimBytes inferFloatinginferFractionalinferNum inferBoundedinferPOPartialinferPONonTransitiveinferProductOrderinferOrdinferEq inferPrimEleminferKnownBackend DFBackendPackDFSubFrameIndexCtx IndexFrame!InferKnownBackend KnownBackends DataFrame' SomeDataFrame DataFrameXFrame MultiFrame SingleFrameDF9DF8DF7DF6DF5DF4DF3DF2SZ:*:unScalarscalar fromFlatListpackDFunpackDFappendDFconsDFsnocDFfromListWithDefaultfromList constrainDFasDiag$fRealFloatExtrasDataFrame$fRealFloatDataFrame$fRealFracDataFrame$fRealExtrasDataFrame$fPrimArraytDataFrame$fProductOrderDataFrame$fOrdDataFrame$fReadDataFrame$fReadDataFrame0$fReadDataFrame1$fReadDataFrame2$fShowDataFrame$fShowDataFrame0$fShowDataFrame1$fShowDataFrame2 $fEqDataFrame$fEqDataFrame0$fStorableDataFrame$fIntegralDataFrame$fRealDataFrame$fEpsilonDataFrame$fEnumDataFrame$fPrimBytesDataFrame$fBoundedDataFrame$fFloatingDataFrame$fFractionalDataFrame$fNumDataFrame$fReadSomeDataFrame$fReadSomeDataFrame0$fShowSomeDataFrame$fShowSomeDataFrame0$fEqSomeDataFrame$fEqSomeDataFrame0$fInferKnownBackend[]tsds$fInferKnownBackendTYPEtds$fOrdDataFrame0$fDataDataFrame$fEqDataFrame1$fIndexFrame[]XNattsxdxds$fIndexFrameTYPEXNattxdxds$fIndexFrame[]Nat:dds$fIndexFrame[]Nat[]dds$fIndexFrameTYPENattdds$fIndexFrameTYPENattd[]$fDataDataFrame0$fGenericDataFrame$fGenericDataFrame0$fPrimArraytDataFrame0$fPrimBytesDataFrame0$fRealFloatExtrasDataFrame0$fRealFloatDataFrame0$fRealFracDataFrame0$fRealExtrasDataFrame0$fRealDataFrame0$fEpsilonDataFrame0$fFloatingDataFrame0$fFractionalDataFrame0$fNumDataFrame0$fIntegralDataFrame0$fEnumDataFrame0$fBoundedDataFrame0$fProductOrderDataFrame0$fOrdDataFrame1$fEqDataFrame2$fDataDataFrame' MDataFramecastDataFrame# newDataFrame#newPinnedDataFrame#oneMoreDataFrame#subDataFrameView#subDataFrameView'#copyDataFrame#copyMDataFrame#copyDataFrame'#copyMDataFrame'#copyDataFrameOff#copyMDataFrameOff#unsafeFreezeDataFrame#freezeDataFrame#thawDataFrame#thawPinDataFrame#unsafeThawDataFrame#withThawDataFrame#writeDataFrameOff#writeDataFrame#readDataFrameOff#readDataFrame#withDataFramePtr#isDataFramePinned#getDataFrameSteps#SomeSTDataFrame STDataFrameXSTFrame castDataFrame newDataFramenewPinnedDataFrameoneMoreDataFramesubDataFrameViewsubDataFrameView' copyDataFramecopyMutableDataFramecopyDataFrame'copyMutableDataFrame'copyDataFrameOffcopyMutableDataFrameOffunsafeFreezeDataFramefreezeDataFrame thawDataFramethawPinDataFrameunsafeThawDataFramewithThawDataFramewriteDataFrameOffwriteDataFramereadDataFrameOff readDataFrameisDataFramePinnedgetDataFrameStepsSubSpace SubSpaceCtxCanSlice sindexOffset supdateOffset.!supdatesewmapsiwmapsewgensiwgensewfoldl sewfoldl'siwfoldl siwfoldl'sewfoldr sewfoldr'siwfoldr siwfoldr' selementWise sindexWise selementWise_ sindexWise_selement sewfoldMap siwfoldMapsewzipsiwzip joinDataFrame indexOffset updateOffsetupdateewmapiwmapewgeniwgenewfoldlewfoldl'iwfoldliwfoldl'ewfoldrewfoldr'iwfoldriwfoldr' elementWise indexWise elementWise_ indexWise_element ewfoldMap iwfoldMapewzipiwzipsslice supdateSlice updateSliceslookuplookup ssliceMaybe sliceMaybe$fSubSpaceXNattasbsasbs$fSubSpaceNattasbsasbsSomeIODataFrame IODataFrameXIOFramewithDataFramePtr Contractioncontract%*$fContractiontasbsasbs$fKnownBackendtdsScwSciScdScfScalar fromScalarhouseholderReflectionInplaceLhouseholderReflectionInplaceRsolveUpperTriangularRsolveUpperTriangularLsolveLowerTriangularRsolveLowerTriangularLSortBy sortByInplaceSortableDataFramesortsortBy$fSortByXNatxn $fSortByNatn $fSortByNat4 $fSortByNat3 $fSortByNat2 $fSortByNat1 $fSortByNat0Vector4vec4 unpackV4#Vector3vec3 unpackV3#Vector2vec2 unpackV2#Vec4wVec3wVec2wVec4iVec3iVec2iVec4dVec3dVec2dVec4fVec3fVec2fVectorVec2Vec3Vec4.*.dot·normL1normL2 normalized normLPInf normLNInfnormLPdet2cross×Mat44dMat34dMat24dMat43dMat33dMat23dMat42dMat32dMat22dMat44fMat34fMat24fMat43fMat33fMat23fMat42fMat32fMat22f HomTransform4 translate4 translate3rotateXrotateYrotateZrotate rotateEulerlookAt perspective orthogonal toHomPoint toHomVectorfromHom MatrixInverseinverseMatrixDeterminantdet SquareMatrixeyediagtraceMatrixTranspose transposeMatrixmat22mat33mat44 QuaternionQuaterpackQunpackQ# fromVecNumfromVec4toVec4squareimreimVectakertakeitakejtakek conjugaterotScale getRotScale axisRotationqArg fromMatrix33 fromMatrix44 toMatrix33 toMatrix44QFloatQDoubleMatrixQRqrlqLQlqLlqQlqQDetQRqrQqrQDetqrRdetViaQR inverseViaQRqrSolveRqrSolveL $fMatrixQRtnm$fShowLQ$fEqLQ$fShowQR$fEqQRMatrixLUluLUluLowerluUpperluPerm luPermDetluSolveRluSolveL inverseViaLUdetViaLU $fMatrixLUtn$fEqLU$fShowLUBiDiagbdUbdUDetbdAlphabdBetabdVbdVDetbiDiagbidiagonalHouseholder $fEqBiDiag $fShowBiDiag MatrixSVDsvdSVDsvdUsvdSsvdVsvd1svd2svd3svd3q$fMatrixSVDtnm$fMatrixSVDt33$fMatrixSVDt22$fMatrixSVDt11$fEqSVD $fShowSVDbase GHC.GenericsGenericGHC.Prim ByteArray#OutOfDimBoundsGHC.Stack.Types HasCallStackGHC.RealRealFracRealGHC.NumsignumOrdering GHC.ClassescompareOrdEqminmax ScalarBase _unScalarBase $fNumFloatX3$fBoundedFloatX3FloatX3FloatX3# $fNumFloatX2$fBoundedFloatX2FloatX2FloatX2# $fNumDoubleX4$fBoundedDoubleX4DoubleX4 DoubleX4# $fNumDoubleX3$fBoundedDoubleX3DoubleX3 DoubleX3# $fNumDoubleX2$fBoundedDoubleX2DoubleX2 DoubleX2# ArrayBase$fOrdArrayBaseD:R:DataFrameTYPENattns0D:R:DataFrame[]Nattsns0D:R:DataFramelXNattsxns0 Data.FoldablefoldlfoldrGHC.Basejoin $fNumFloatX4$fBoundedFloatX4FloatX4FloatX4# DimensionsinferBackendInstance