!Pw*      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~                                                                                      ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a bcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()+(c) Artem ChirkinBSD3None&'-.18=>?@AFHUVXk"* easytensor/Find out which basic GHC type it is at runtime.+ easytensor<This function allows to find out a type by comparing its tag4 easytensorBFind out which basic GHC type it is at runtime. It is used for  DataFrame* backend specialization: by matching a  PrimTag aN 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., easytensor Deriving D using genericsyThis implementation relies on two assumptions, which are probably true in the GHC implementation of derived generics and is not checked here: Rep aC is a sum-of-products. This means the struct offset is always 4Q for the parts of the sum type, and a constructor tag is always at position 0 in the struct.The Rep a tree is balanced. Thus, I can implement a simple tag encoding: each bit in a tag corresponds to a nesting level. That is, maximum possible nesting level is 31 and minimum is 0.Therefore, the general logic for the sum type is summarized as follows: reserve 4 bytes for the tag and try to pack alternatives as good as possible.)If a data type has only one constructor (Rep a contains no :+:), then the tag is not added.Every function in  GPrimBytes\ has the first Proxy# argument; it is simply used to enforce type parameter and allows easy coerce implementations for Meta wrapper types.All functions except  gbyteAlign0 have the second and third arguments: tag mask (Word#) and current struct size (Int#*); both start with zero at the top of the Rep a hierarchy.uThe tag mask is used by the sum constructors to find out where to write a bit value to encode left or right branch.sThe current struct size is the size (in bytes) of all elements to the left of the current one (before alignment).- easytensor"Cumulative size of a Rep structure. easytensor7Gives an offset of the current piece of a Rep structure/ easytensor=Derive a list of data selectors from the data representation Rep a.D easytensorcDefines 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.OThis module provides default implementations for all methods of this class via 0*. Hence, to make your data an instance of  PrimBytes., it is sufficient to write the instance head: hdata 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.aA 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 easytensorXStore content of a data type in a primitive byte array (should be used together with  byteOffset function).eNote, 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 easytensorXStore 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 easytensorQLoad 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 easytensorKWrite 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<Size of a data type in bytes. It should be a multiple of  byteAlign0 for indexing functions to operate correctly.]Implementation of this function must not inspect the argument value; a caller may provide  undefined in place of the argument.N easytensor&Alignment of a data type in bytes.  byteOffset" should be multiple of this value.]Implementation of this function must not inspect the argument value; a caller may provide  undefined in place of the argument.O easytensorqOffset of the data in a byte array used to store the data, measured in bytes. Should be used together with getBytese function. Unless in case of special data types represented by ByteArrays, it is equal to zero.]Implementation of this function may inspect the argument value; a caller must not provide  undefined in place of the argument.P easytensor6Offset of a data record within the data type in bytes.]Implementation of this function must not inspect the argument value; a caller may provide  undefined in place of the argument.The default (generic) implementation of this fucntion looks for the leftmost occurrence of a given field name (in case of multiple constructors). If a field with the given name is not found, it returns -1(, but this is not possible thanks to Elem name (PrimFields a) constraint.Q easytensor1Index array given an element offset (which is  byteSize a and should be a multiple of  byteAlign a).R easytensor:Read a mutable array given an element offset (which is  byteSize a and should be a multiple of  byteAlign a).S easytensor;Write a mutable array given an element offset (which is  byteSize a and should be a multiple of  byteAlign a).T easytensor A wrapper on MU easytensor A wrapper on NV easytensor A wrapper on P.W easytensorSame as : peek an element a by the offset measured in  byteSize a.tNote: the size of the element must be a multiple of its alignment for a correct operation of this function.X easytensorSame as : poke an element a by the offset measured in  byteSize a.tNote: the size of the element must be a multiple of its alignment for a correct operation of this function.Y easytensorSame as : peek an element a$ by the offset measured in bytes.UNote: you'd better be sure the address is a multiple of the data alignment ().Z easytensorSame as : poke an element a$ by the offset measured in bytes.UNote: you'd better be sure the address is a multiple of the data alignment ().[ easytensorSame as : read a data from a pointer.UNote: you'd better be sure the address is a multiple of the data alignment ().\ easytensorSame as  : write a data to a pointer.UNote: you'd better be sure the address is a multiple of the data alignment ().1 easytensor5Round up the first numer to a multiple of the second.hNB: this function is only used with alignment as the second number, which is always a power of 2.] easytensorThis function allows to find out a type by comparing its tag. This is needed for backend specialization, to infer array instances. For non-basic types it defaults to C. 2 easytensorConstructor tag position (mask) easytensor@Left neighbour cumulative size (current offset before alignment)3 easytensorConstructor tag position (mask) easytensor@Left neighbour cumulative size (current offset before alignment)4 easytensorConstructor tag position (mask) easytensor@Left neighbour cumulative size (current offset before alignment)5 easytensorConstructor tag position (mask) easytensor@Left neighbour cumulative size (current offset before alignment)6 easytensorConstructor tag position (mask) easytensor@Left neighbour cumulative size (current offset before alignment)- easytensorConstructor tag position (mask) easytensor@Left neighbour cumulative size (current offset before alignment). easytensorConstructor tag position (mask) easytensor@Left neighbour cumulative size (current offset before alignment)H easytensorOffset in bytes easytensor Source arrayI easytensor Source array easytensorByte offset in the source arrayJ easytensorDestination array easytensor$Byte offset in the destination array easytensorData to write into the array*456789:;<=>?@ABCDERSFMJGNHIKLOPQTUVWXYZ[\]*DERSFMJGNHIKLOPQTUVWXYZ[\456789:;<=>?@ABC]None&'-.=?@ACFHUVX easytensorBroadcast element into array8Warning: do not use this function at the call site; use A 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 7 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 totalDimps. 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 7 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 totalDimB 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 Idxs\Note, 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 8F exception. Otherwise, its safety is guaranteed by the type system. easytensorCalculate offset of an Idxs.xAlso check if the last index plus dimVal of subN is not bigger than the corresponding dim inside CumulDims; throw an 8 otherwise.If any of the dims in ns is unknown (n ~ XN m4), then this function is unsafe and can throw an 8F 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 8F exception. Otherwise, its safety is guaranteed by the type system. easytensor;Calculate offset of an Idxs and return remaining CumulDims.xAlso check if the last index plus dimVal of subN is not bigger than the corresponding dim inside CumulDims; throw an 8 otherwise.If any of the dims in ns is unknown (n ~ XN m4), then this function is unsafe and can throw an 8F 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 aF, 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 aF, but this is not reflected in types and is not checked at runtime. easytensor3Dimensionality of the result array; Be careful! ns depends on aF, but this is not reflected in types and is not checked at runtime. easytensorInitial offset easytensorInitial offset easytensorInitial offset easytensorInitial offsetNone%,>g6 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.9 easytensor5Short description of the error, e.g. a function name.: easytensor;Function call stack. Note, this field is ignored in the ; and < instances. easytensorThis is just an alias for the =" constraint. It servers two goals: eDocument functions that use iterative methods and can fail (supposedly in extremely rare cases).(Provide a call stack in case of failure.Use q 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 } .wNB: 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.wNB: in future, this function is to reimplemented using primops and should behave the same way as its C analogue. easytensorDDefine 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-.27>H<{ easytensor Similar to A , but may be  Incomparable. easytensor2Partial order for comparing product types --  +https://en.wikipedia.org/wiki/Product_order product order. easytensorSame as B, but may return  Incomparable. easytensorExtend A with  Incomparable option.(c) Artem ChirkinBSD3None-.124567=>?HMO? easytensor Redefine <F 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 C and D 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.XAll of this is really useful in geometry applications and for calculating things like  /https://en.wikipedia.org/wiki/Pareto_efficiencyPareto dominanceM, 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-.124567=>?HMb' easytensor Redefine <F 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: p \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 C and D 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.XAll 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 -.1=?@AFHMdE easytensor-Specialize ScalarBase type without any arraysEFG"None =>?@AFkhH easytensor#element-wise operations for vectorsI 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.JK#None =>?@AFkm"L easytensor#element-wise operations for vectorsM 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.NO$None =>?@AFkqhP easytensor#element-wise operations for vectorsQ 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.RS%None =>?@AFkuT easytensor#element-wise operations for vectorsU 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.VW&None =>?@AFkyX easytensor#element-wise operations for vectorsY 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.Z['None,-.=>?@AEFHSUVXk\ easytensor@Generic Array implementation. This array can reside in plain 7 and can share the  ByteArray#6 with other arrays. However, byte offset in the  ByteArray#& must be multiple of the element size.] easytensorAccumulates only idempotent operations! Being applied to FromScalars, executes only once! Here, idempotance means: assuming  f a b = g x,  g (g x) = g x0Also, I assume the sizes of arrays are the same.Inside, this function uses foldr; thus, if the combining function is lazy in the second argument, it may avoid some unnecessary work.^ easytensor0Do something in a loop for int i from 0 to (n-1)_ easytensorLexicographical ordering` easytensor initial value easytensorstep easytensor!final value (LESS THAN condition)\a(None -.=>?@AHXkb easytensorThe instance keeper for the P type. Using this data as a tag to the P type allows to define P: instances in two different modules without any orphans.a easytensor#Implementation behind the DataFrame3PQRS_`aNone %&',-.12=>?@AEFHMSUVX_gk"b easytensor&Represent smart constructor functions  and .c easytensorUThis 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 mW), then we give up. Just let the user do the slicing as easy as possible, and throw an 8k exception at runtime if the index plus the sliced size is greater than the original size of the DataFrame.d easytensor Index one dimension deep into a  DataFrame.e easytensor Index one dimension deep into a  DataFrame.XNote, this function does not provide indexing safety at the type level; it throws an 83 exception if an index is out of bounds (unless  unsafeindices8 package flag is enabled, which is even more dangerous).c easytensor:All component data frames must satisfy a given constraint.f easytensorAllow inferring  KnownBackends2 if you know the dimensions and the element types.g easytensorInfer  KnownBackends2 if you know the dimensions and the element types.h easytensor5I use this kind-polymorphic constraint to generalize XFrame and  SomeDataFrame over  SingleFrame and  MultiFrame.i easytensor*DataFrame with its type arguments swapped.j easytensorData frame that has an unknown dimensionality at compile time. Pattern-match against its constructor to get a Nat-indexed data framel easytensordKeep data in a primitive data frame and maintain information about Dimensions in the type systemx easytensor8A scalar DataFrame is just a newtype wrapper on a value.y easytensorEmpty MultiFramez easytensorConstructing a  MultiFrame using DataFrame columns{ easytensor)Convert a scalar back to an ordinary type| easytensor$Convert any type to a scalar wrapperd easytensor*Check the next lexeme without consuming it} 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 totalDimQ, 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 TypeApplicationsl 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 e 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 TypeApplicationsl 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 e together serve as a generic constructor for a DataFrame of an arbitrary (statically known) size. easytensor<Append one DataFrame to another, sum up the first dimension.3If you want to deconstruct a DataFrame, use  ) or  * instead. easytensor8Append a small DataFrame to a big DataFrame on the left.3If you want to deconstruct a DataFrame, use  ) or  * instead. easytensor9Append a small DataFrame to a big DataFrame on the right.3If you want to deconstruct a DataFrame, use  ) or  * instead.e easytensor4Unsafely copy two PrimBytes values into a third one. easytensor8Construct a DataFrame from a list of smaller DataFrames.%If the argument list is shorter than dP, then the rest of the frame is padded with a default value (first argument).$If the argument list is longer than d_, then unused values are dropped. If you want, you can pass an infinite list as an argument. easytensorhConstruct a dynamic DataFrame from a list of smaller DataFrames. Pattern-match against the resulting XFrame to find out its dimensionality.5You must not provide an infinite list as an argument. easytensorTry to convert between XNat-indexed DataFrames.rThis is useful for imposing restrictions on unknown DataFrames, e.g. increasing the minimum number of elements. easytensorhPlace elements of a vector on the main diagonal of a matrix; fill the rest of the matrix with zeroes.tNote, this function is naturally generalized onto higher dimensions (which can be seen from the type signature).Note, the argument of this function does not fully determine its result type. This may cause some obscure type errors. Specify type parameters n and m2 explicitly or make sure the result type is fixed.f easytensor Single frameg easytensor3Multiple "columns" of data frames of the same shapeh easytensorData frame with some dimensions missing at compile time. Pattern-match against its constructor to get a Nat-indexed data frame. easytensorTerm-level structure of a  MultiFrame ts$ is fully determined by its type  Typeable ts . Thus, gunfold! does not use its last argument (Constr<) at all, relying on the structure of the type parameter. easytensorTerm-level structure of a SingleFrame t ds3 is fully determined by its type dimensionality  Typeable ds . Thus, gunfold! does not use its last argument (Constr<) at all, relying on the structure of the type parameter.a&$%'()1,0/.*-+!#"2  DTUVSabcdefghijklonmpqrstuvwxyz{|}~jkilonmyzxwvutsrqp|{decb~Sahfg}2    &$%(')1,0/.*-+!#",0/.*-+!#"DTUVz6 (c) Artem ChirkinBSD3None-.=>?@AEFHUVXkW] easytensor_Mutable 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 8F 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 8F exception. Otherwise, its safety is guaranteed by the type system. easytensorHCopy 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 8/ exception possible). If any of the dims in as is unknown (a ~ XN mp), 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 bq), this function copies only as many elements as fits into the dataframe along this dimension (possibly none). easytensorPCopy 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 8/ exception possible). If any of the dims in as is unknown (a ~ XN mp), 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 bq), this function copies only as many elements as fits into the dataframe along this dimension (possibly none). easytensorHCopy 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 8/ exception possible). If any of the dims in as is unknown (a ~ XN mh), you may happen to write data beyond dataframe bounds. In this case, this function does nothing. easytensorPCopy 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 8/ exception possible). If any of the dims in as is unknown (a ~ XN mh), you may happen to write data beyond dataframe bounds. In this case, this function does nothing. easytensorUCopy 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. easytensor]Copy 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. easytensorCCopy content of a mutable DataFrame into a new immutable DataFrame. easytensorJCreate a new mutable DataFrame and copy content of immutable one in there. easytensoruCreate 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 gC. If the input DataFrame is a single broadcast value, use it in fm. 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 8/ exception possible). If any of the dims in ns is unknown (n ~ XN mh), 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 8F exception. Otherwise, its safety is guaranteed by the type system. easytensor\Allow 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. easytensorfCheck 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 nsi easytensor6Fill a mutable byte array with the same single element easytensorf easytensorgi easytensorOffset in elements easytensorNumber of elements (c) Artem ChirkinBSD3None%-./=>?@AEFHUVXgk easytensor+Mutable DataFrame of unknown dimensionality easytensor\Mutable 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 8F 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 8F exception. Otherwise, its safety is guaranteed by the type system. easytensorHCopy 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 8/ exception possible). If any of the dims in as is unknown (a ~ XN mp), 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 bq), this function copies only as many elements as fits into the dataframe along this dimension (possibly none). easytensorPCopy 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 8/ exception possible). If any of the dims in as is unknown (a ~ XN mp), 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 bq), this function copies only as many elements as fits into the dataframe along this dimension (possibly none). easytensorHCopy 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 8/ exception possible). If any of the dims in as is unknown (a ~ XN mh), you may happen to write data beyond dataframe bounds. In this case, this function does nothing. easytensorPCopy 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 8/ exception possible). If any of the dims in as is unknown (a ~ XN mh), you may happen to write data beyond dataframe bounds. In this case, this function does nothing. easytensorUCopy 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. easytensor]Copy 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. easytensorCCopy content of a mutable DataFrame into a new immutable DataFrame. easytensorJCreate a new mutable DataFrame and copy content of immutable one in there. easytensoruCreate 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 gC. If the input DataFrame is a single broadcast value, use it in fm. 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 8/ exception possible). If any of the dims in ns is unknown (n ~ XN mh), 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 8F exception. Otherwise, its safety is guaranteed by the type system. easytensorfCheck 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-./=>?@ACFHSUVXkC?j easytensorBHide ST monad state with a DataFrame in works inside a plain type. 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 8F exception. Otherwise, its safety is guaranteed by the type system. easytensorSet a new value to an element.If (a ~ XN mi) 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.  easytensor@Generate a DataFrame by iterating a function (index -> element).  easytensorFLeft-associative lazy fold of a DataFrame. Same rules apply as for k.  easytensorHLeft-associative strict fold of a DataFrame. Same rules apply as for foldl'. easytensorTLeft-associative lazy fold of a DataFrame with an index. Same rules apply as for k. easytensorVLeft-associative strict fold of a DataFrame with an index. Same rules apply as for foldl'. easytensorGRight-associative lazy fold of a DataFrame. Same rules apply as for l. easytensorIRight-associative strict fold of a DataFrame. Same rules apply as for foldr'. easytensorURight-associative lazy fold of a DataFrame with an index. Same rules apply as for l. easytensorWRight-associative strict fold of a DataFrame with an index. Same rules apply as for foldr'. easytensorCApply an applicative functor on each element (Lens-like traversal). easytensor_Apply an applicative functor on each element with its index (Lens-like indexed traversal). easytensorBApply an applicative functor on each element (Lens-like traversal) easytensor^Apply 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 ml) and the index falls outside of the DataFrame Dim, the argument Functor is not called and the result is pure original DataFrame. easytensorKMap each element of the DataFrame to a monoid, and combine the results. easytensorYMap each element of the DataFrame and its index to a monoid, and combine the results. easytensorCZip 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 m. 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 8F 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 mq), 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.% easytensor@Generate a DataFrame by iterating a function (index -> element).& easytensorFLeft-associative lazy fold of a DataFrame. Same rules apply as for k.' easytensorHLeft-associative strict fold of a DataFrame. Same rules apply as for foldl'.( easytensorTLeft-associative lazy fold of a DataFrame with an index. Same rules apply as for k.) easytensorVLeft-associative strict fold of a DataFrame with an index. Same rules apply as for foldl'.* easytensorGRight-associative lazy fold of a DataFrame. Same rules apply as for l.+ easytensorIRight-associative strict fold of a DataFrame. Same rules apply as for foldr'., easytensorURight-associative lazy fold of a DataFrame with an index. Same rules apply as for l.- easytensorWRight-associative strict fold of a DataFrame with an index. Same rules apply as for foldr'.. easytensorCApply an applicative functor on each element (Lens-like traversal)./ easytensor_Apply an applicative functor on each element with its index (Lens-like indexed traversal).0 easytensorBApply an applicative functor on each element (Lens-like traversal)1 easytensor^Apply an applicative functor on each element with its index (Lens-like indexed traversal)2 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.3 easytensorKMap each element of the DataFrame to a monoid, and combine the results.4 easytensorYMap each element of the DataFrame and its index to a monoid, and combine the results.5 easytensorCZip two spaces on a specified subspace element-wise (without index)6 easytensor?Zip two spaces on a specified subspace index-wise (with index).7 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 8F exception. Otherwise, its safety is guaranteed by the type system.8 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 br), this function updates only as many elements as fits into the dataframe along this dimension (possibly none).9 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 8F 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 my), 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 br), 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).< easytensorOGet an element by its index in the dataframe. This is a safe alternative to  H 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 7D 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 9H function when some of the dimensions are not known at compile time (d ~ XN m).n easytensor-Checks if all of the dimensions are non-zero. easytensorPrim element offset easytensorPrim element offset easytensorPrim element offset easytensorPrim element offset>      !"#$%&'()*+,-./0123456789:;<=>>;7=8      <!9>:$%"#562.0/1&'*+3(),-44+None .=>?@AFkIo easytensor#element-wise operations for vectorsp 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.qr,None&',-.=>?@AFHISUVXkXs easytensor6A framework for using DataFrame type family instances.3 easytensorNThis 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  BackendFamilyc, e.g. Scalar newtype wrapper. Otherwise, it falls back to the generic ArrayBase implementation.MData family would not work here, because it would give overlapping instances.t easytensor*Get DataFrame backend type family instanceu easytensorgSingleton type used to determine the currently used DataFrame backend; establishes a good bijection b  ~ t ds (better than just using  BackendFamily everywhere).v easytensorFind an instance of s class using D and w.s3vxyz (c) Artem ChirkinBSD3None%-./=>?@AEFHUVXgk*A easytensor+Mutable DataFrame of unknown dimensionalityC easytensor\Mutable DataFrame that lives in IO. Internal representation is always a MutableByteArray.D easytensorData frame with some dimensions missing at compile time. Pattern-match against its constructor to get a Nat-indexed mutable data frame.E easytensorAllow coercing between XNat -indexed and Nat-indexed Mutable DataFrames.F easytensorCreate a new mutable DataFrame.G easytensorCreate a new mutable DataFrame.H easytensor0Create a new mutable DataFrame of the same size.I 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 8F exception. Otherwise, its safety is guaranteed by the type system.J 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 8F exception. Otherwise, its safety is guaranteed by the type system.K easytensorHCopy 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 8/ exception possible). If any of the dims in as is unknown (a ~ XN mp), 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 bq), this function copies only as many elements as fits into the dataframe along this dimension (possibly none).L easytensorPCopy 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 8/ exception possible). If any of the dims in as is unknown (a ~ XN mp), 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 bq), this function copies only as many elements as fits into the dataframe along this dimension (possibly none).M easytensorHCopy 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 8/ exception possible). If any of the dims in as is unknown (a ~ XN mh), you may happen to write data beyond dataframe bounds. In this case, this function does nothing.N easytensorPCopy 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 8/ exception possible). If any of the dims in as is unknown (a ~ XN mh), you may happen to write data beyond dataframe bounds. In this case, this function does nothing.O easytensorUCopy 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.P easytensor]Copy 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 boundsQ easytensor4Make a mutable DataFrame immutable, without copying.R easytensorCCopy content of a mutable DataFrame into a new immutable DataFrame.S easytensorJCreate a new mutable DataFrame and copy content of immutable one in there.T easytensoruCreate a new mutable DataFrame and copy content of immutable one in there. The result array is pinned and aligned.U easytensor'UnsafeCoerces an underlying byte array.V easytensorGiven two continuations f and gC. If the input DataFrame is a single broadcast value, use it in fm. 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.W 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.X easytensor.Write a single element at the specified index.This function is safe (no 8/ exception possible). If any of the dims in ns is unknown (n ~ XN mh), you may happen to write data beyond dataframe bounds. In this case, this function does nothing.Y 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.Z 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 8F exception. Otherwise, its safety is guaranteed by the type system.[ easytensorfCheck 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.ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]CDDABEFGHIJKLMNOPRQSTUVXWZY[\] (c) Artem ChirkinBSD3chirkin@arch.ethz.chNone./=>?@ACFHUVXk#_ easytensoruGeneralization 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,-.=>?@AHIUVXkP 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.S easytensorxBackend resolver: Use this constraint to find any class instances defined for all DataFrame implementations, e.g. Num,  PrimBytes, etc.3PQRSTUVWXYZ[\]^_`PQR3S`_^]\[ZYXWVUT-None.>FHgg easytensor$Alias for zero-dimensional DataFrameh easytensor.Broadcast scalar value onto a whole data frame x{|cdefghNone{|cdefghg{|hfedcNone"#-.1=>?@AHUVXki 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 Rv are assumed (and not checked) to be zeros; these are not touched by the subroutine to save flops.A logical starting value for Pa is an identity matrix. The subroutine can be used for a QR decomposition:  Q = P .Returns True' if reflection has been performed, and FalseB if it was not needed. This can be used to track the sign of det P.j easytensor)Run a Householder transformation inplace. Similar to jU, but works from right to left - use to zero elements to the right from the pivot.Returns True' if reflection has been performed, and FalseB if it was not needed. This can be used to track the sign of det P.i 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 easytensor P^\intercal easytensorR easytensorn easytensorm easytensor 0 \leq k < n  easytensor 0 \leq l < m j 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 easytensor P^\intercal easytensorR easytensorn easytensorm easytensor 0 \leq k < n  easytensor 0 \leq l < m ijjiNone "#-.HUVXk yk 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.l 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.m 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.n 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.k easytensorR easytensorCurrent state of b_m (first m rows of b)l easytensorCurrent state of b (first m "columns" of x) easytensorRm easytensorL easytensorCurrent state of b (first n elements of x)n easytensorCurrent state of b easytensorLklmnklmnNone"#-.=>?@AHUVX_kp easytensorNote, Inplacer here means the input frame is modified. It does not mean the algorithm does not use extra space (it does use).q easytensorJThe required context for sorting a DataFrame is slightly different for Nat and XNatC indexed arrays. This type family abstracts away the difference.r easytensorSort a  DataFrame along the first dimension.&Note: the elements (which are of type DataFrame t ns*) are compared lexicographically.s easytensorSort a  DataFrame; along the first dimension using given comparison function.} easytensorSwap contents of two DataFrames~ easytensor(Rotate left contents of three DataFramesp easytensormust not modify state!} easytensorTemporary buffer~ easytensorTemporary bufferopqrsopsrq.None%&'-.=>?@AEFHUVXgk'{ 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 easytensorbScalar 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 easytensor[Take 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&l{|}~777None(&l{|}~)~{|}l/None"#-.1=>?@AFHUVXka easytensoryOperations 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. easytensorJCreate 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 easytensorURotation 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. easytensorURotation 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. easytensorURotation 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. easytensorMRotation 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. JrotateEuler pitch yaw roll == rotateZ roll %* rotateY yaw %* rotateX pitch 8https://en.wikipedia.org/wiki/Euler_angles#Conventions_2 easytensortCreate a transform matrix using up direction, camera position and a point to look at. Just the same as GluLookAt. easytensorLA perspective symmetric projection matrix. Right-handed coordinate system. (x - right, y - top) Dhttp://en.wikibooks.org/wiki/GLSL_Programming/Vertex_Transformations easytensorLAn orthogonal symmetric projection matrix. Right-handed coordinate system. (x - right, y - top) Dhttp://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. easytensor}Transform 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) easytensorOThe 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 %.>FHVXg 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 easytensorGCreate 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. easytensorGCreate 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%-.1=>?@AFHMV2None%-.1=>?@AFHMVNoneNone"#-.1=>?@AHUVXk 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 V (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 V (underdetermined system) QR decomposition is used to yield a minimum norm solution.None"#-.1=>?@AHUVXkE  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 easytensorbRun LU decomposition with partial pivoting inplace, such that the upper triangular part of matrix A becomes U= and the lower triangular part (without diagonal) of matrix A becomes L.UM is upper triangular. (L) is unit lower triangular; all diagonal elements of LJ are implicit and equal to 1; the rest of the elements a smaller than one |l_{ij}| \leq 1.0Pivoting is represented as a permutation vector p=; returned value is the sign of the permutation (positive if True, negative otherwise).NB: Initialize p with indices 0..n-1.rReference: Algorithm 3.4.1 on p.128 of "Matrix Computations" 4th edition by G. H. Golub and C. F. Van Loan. easytensorTemporary buffer easytensorCurrent state of permutation p easytensorCurrent state of A   3None %.=?@AFXk34None %.=?@AFXkNone/`/`5None&$%'()1,0/.*-+!#"2  DTUVSabcdefghijklonmpqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>^_`cdefghrs{|}~rsNone"#-.1=>?@AFHUVXkЅ   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"#-.1=>?@AHUVX_kA 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: Thttps://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.NThis 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 easytensorApproximate values for cos (a 2) and sin (aE2) of a Givens rotation for a 2x2 symmetric matrix. (Algorithm 2) easytensor&A quaternion for a QR Givens iteration easytensor?One iteration of the Jacobi algorithm on a symmetric 3x3 matrix3The three words arguments are indices: 0 <= i = j = k <= 2 easytensorTotal number of the Givens rotations during the Jacobi eigendecomposition part of the 3x3 SVD equals eigenItersX3*3. Value `eigenItersX3 = 6` corresponds to 18 iterations and gives a good precision. easytensorRun a few iterations of the Jacobi algorithm on a real-valued 3x3 symmetric matrix. The eigenvectors basis of such matrix is orthogonal, and can be represented as a quaternion. easytensor6One Givens rotation for a QR algorithm on a 3x3 matrix3The three words arguments are indices: 0 <= i = j = k <= 22if i < j then the eigen values are already sorted! easytensor Run QR decomposition in context of 3x3 svd: AV = US = QR The input here is matrix AV The R upper-triangular matrix here is in fact a diagonal matrix Sigma; The Q orthogonal matrix is matrix U in the svd decomposition, represented here as a quaternion. easytensorApply a series of column transformations to make b[k] (and whole column k+1) zero (page 491, 1st paragraph) when a[k+1] == 0. To make this element zero, I apply a series of Givens transforms on columns (multiply on the right).[Prerequisites: * a[k+1] == 0 * 0 <= k < min n (m-1) Invariants: * matrix B :: n \times m S is bidiagonal, represented by two diagonals; * matrix V is orthogonal *  B = A V^\intercal , where A :: n \times m is an implicit original matrix Results: * Same bidiagonal matrix with b[k] == 0; i.e. (k+1)-th column is zero. * matrix V is updated (multiplied on the right)!NB: All changes are made inplace. easytensorApply a series of row transformations to make b[k] (and whole column k) zero (page 490, last paragraph) when a[k] == 0. To make this element zero, I apply a series of Givens transforms on rows (multiply on the left).SPrerequisites: * a[k] == 0 * 0 <= k < n - 1 Invariants: * matrix B :: m \times n S is bidiagonal, represented by two diagonals; * matrix U is orthogonal *  B = U A , where A :: m \times n  is an implicit original matrix Results: * Same bidiagonal matrix with b[k] == 0; i.e. k-th column is zero. * matrix U is updated (multiplied on the right)!NB: All changes are made inplace. easytensor8A Golub-Kahan bidiagonal SVD step on an unreduced matrix easytensorEUpdate a transformation matrix with a Givens transform (on the right) easytensor4the main diagonal of B and then the singular values. easytensorfirst upper diagonal of B easytensorU easytensorV easytensorG0 < q <= nm -- size of a reduced matrix, such that leftover is diagonal easytensorthe main diagonal of B easytensorfirst upper diagonal of B easytensorV easytensor0 <= k < min (n+1) m easytensorthe main diagonal of B easytensorfirst upper diagonal of B easytensorU easytensor0 <= k < n - 1 easytensor4the main diagonal of B and then the singular values. easytensorfirst upper diagonal of B easytensorU easytensorV easytensor p : 0 <= p < q <= nm; p <= q - 2 easytensor q : 0 <= p < q <= nm; p <= q - 2  !"#  !"#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{|}~      !"#$%&'()*+,-./01234567789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]7789:;<=>?@ABCDEFGHI^JKLMNOPQRSTUVW\[XYZ]__`abcdefghijklmn(opqrstnuvwwxyz{|}~m:;                                                                               ! " # $ % & ' ) ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? * @ A B C D E F G G H I                         J K L M NO-P-Q-R-S-T-UVWXYZ[\]^_`abcdefg.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.{.|.}.~..............//////////////////////////////////////////////00000000000000000000000012      6!"9:#$%6&'6&()*+,+-./6706&16&26&3!4!4!5"6"7"8"9#:#;#<#=$>$?$@$A%B%C%D%E&F&G&H&I'J'K'L'M'N'J(OPQRSTU V WXYXZ[\ ]+^+_+`+a,a,b,c,n9>d,e,m,bfghi012jklmnopqrstuvw)easytensor-2.1.0.0-BZHU59HGm5IIVN8299nIahNumeric.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.0.0-35Ahfvt0GoU5KscbJsPaPENumeric.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$fPrimBytesPtr$fPrimBytesDouble$fPrimBytesFloat$fPrimBytesInt$fPrimBytesWord$fGPrimByteskK1 $fShowPrimTag 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$fGeneric1ProductOrd$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$fPrimArrayDataFrame$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 $fShowSVD PrimTaggedprimTag' GPrimBytes gbyteSizegbyteFieldOffset GPrimFieldsbase GHC.GenericsGeneric roundUpInt gfromBytes greadBytes gwriteBytes greadAddr gwriteAddrGHC.Prim ByteArray#OutOfDimBounds tmiUserInfo tmiCallStack GHC.ClassesEqOrdGHC.Stack.Types HasCallStackGHC.RealRealFracRealGHC.NumsignumOrderingcompareminmax ScalarBase _unScalarBase $fNumFloatX3$fBoundedFloatX3FloatX3FloatX3# $fNumFloatX2$fBoundedFloatX2FloatX2FloatX2# $fNumDoubleX4$fBoundedDoubleX4DoubleX4 DoubleX4# $fNumDoubleX3$fBoundedDoubleX3DoubleX3 DoubleX3# $fNumDoubleX2$fBoundedDoubleX2DoubleX2 DoubleX2# ArrayBaseaccumV2Idempotentloop1#$fOrdArrayBaseloop#I AllFrameslookLexunsafeAppendPBD:R:DataFrameTYPENattns0D:R:DataFrame[]Nattsns0D:R:DataFramelXNattsxns0 fillArrayMakingDF Data.FoldablefoldlfoldrGHC.Basejoin nonVoidDims $fNumFloatX4$fBoundedFloatX4FloatX4FloatX4#bSing BackendSing DimensionsinferBackendInstancehouseholderReflectionInplaceL'householderReflectionInplaceR'swapDFswap3DF luInplace jacobiGivensQ qrGivensQjacobiEigen3Iteration eigenItersX3 jacobiEigenQqrDecomp3IterationqrDecomposition3svdGolubKahanZeroColsvdGolubKahanZeroRowsvdGolubKahanStepupdateGivensMatsvdBidiagonalInplace