!J      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~                                                                             !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHI#(c) Artem ChirkinBSD3None&'-.18=>?@AFHUVXk"J easytensor/Find out which basic GHC type it is at runtime.K easytensor<This function allows to find out a type by comparing its tag3 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 B.L easytensor Deriving C 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).M easytensor"Cumulative size of a Rep structureN easytensor7Gives an offset of the current piece of a Rep structureO easytensor=Derive a list of data selectors from the data representation Rep a.C 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 P*. 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.D easytensorList of field names.&It is used to get field offsets using O 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.E 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.F easytensorXStore content of a data type in a primitive byte array (should be used together with  byteOffset function).In contrast to E?, 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.G easytensorQLoad content of a data type from a primitive byte array given an offset in bytes.H easytensor=Read data from a mutable byte array given an offset in bytes.I easytensorKWrite data into a mutable byte array at a given position (offset in bytes).J easytensor#Read data from a specified address.K easytensor"Write data to a specified address.L 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.M 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.N 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.O 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.P easytensor1Index array given an element offset (which is  byteSize a and should be a multiple of  byteAlign a).Q easytensor:Read a mutable array given an element offset (which is  byteSize a and should be a multiple of  byteAlign a).R easytensor;Write a mutable array given an element offset (which is  byteSize a and should be a multiple of  byteAlign a).S easytensor A wrapper on LT easytensor A wrapper on MU easytensor A wrapper on O.V 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.W 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.X 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 ().Y 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 ().Z 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 ().Q 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 B. R easytensorConstructor tag position (mask) easytensor@Left neighbour cumulative size (current offset before alignment)S easytensorConstructor tag position (mask) easytensor@Left neighbour cumulative size (current offset before alignment)T easytensorConstructor tag position (mask) easytensor@Left neighbour cumulative size (current offset before alignment)U easytensorConstructor tag position (mask) easytensor@Left neighbour cumulative size (current offset before alignment)V easytensorConstructor tag position (mask) easytensor@Left neighbour cumulative size (current offset before alignment)M easytensorConstructor tag position (mask) easytensor@Left neighbour cumulative size (current offset before alignment)N easytensorConstructor tag position (mask) easytensor@Left neighbour cumulative size (current offset before alignment)G easytensorOffset in bytes easytensor Source arrayH easytensor Source array easytensorByte offset in the source arrayI easytensorDestination array easytensor$Byte offset in the destination array easytensorData to write into the array*3456789:;<=>?@ABCDQRELIFMGHJKNOPSTUVWXYZ[\*CDQRELIFMGHJKNOPSTUVWXYZ[3456789:;<=>?@AB\None -.@ACFHҁ easytensorBroadcast element into array easytensorIndex an array given an offset easytensor.Generate an array using an accumulator funtion easytensor3update a single element in an array given an offset easytensor{If the array represented as a single broadcasted value, return this value. Otherwise, return full array content:  CumulDims7, array offset (elements), byte array with the content. 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). easytensorGet 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. 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! 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. 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.(c) Artem ChirkinBSD3None-.27>HI easytensor Similar to W , but may be  Incomparable. easytensor2Partial order for comparing product types --  +https://en.wikipedia.org/wiki/Product_order product order. easytensorSame as X, but may return  Incomparable. easytensorExtend W with  Incomparable option.(c) Artem ChirkinBSD3None-.124567=>?HM  easytensor Redefine YF instance for a type which is a cartesian product -- as a partial  +https://en.wikipedia.org/wiki/Product_order product order.Since vanilla Haskell Y$ 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 Z 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.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=>?HM easytensor Redefine YF instance for a type which is a cartesian product -- as a partial  +https://en.wikipedia.org/wiki/Product_order product order.Since vanilla Haskell Y$ 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 Z 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 [ 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.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=?@AFHM`] easytensor-Specialize ScalarBase type without any arrays]^_None =>?@AFk` easytensor#element-wise operations for vectorsa 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.bcNone =>?@AFk d easytensor#element-wise operations for vectorse 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.fgNone =>?@AFk Nh 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.jkNone =>?@AFkl 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.noNone =>?@AFkp 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.rsNone&',-.=>?@AEFHSUVXk"t easytensor@Generic Array implementation. This array can reside in plain u and can share the  ByteArray#6 with other arrays. However, byte offset in the  ByteArray#& must be multiple of the element size.v 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.w easytensor0Do something in a loop for int i from 0 to (n-1)x easytensorLexicographical orderingy easytensor initial value easytensorstep easytensor!final value (LESS THAN condition)tz None -.=>?@AHXk& { easytensorThe instance keeper for the  type. Using this data as a tag to the  type allows to define : instances in two different modules without any orphans. {|}~None %&',-.12=>?@AEFHMSUVX_gkr) easytensor&Represent smart constructor functions A and B. easytensor:All component data frames must satisfy a given constraint.* easytensorAllow inferring  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 frame0 easytensordKeep 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*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..]A 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 12A and Be together serve as a generic constructor for a DataFrame of an arbitrary (statically known) size.B 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 @'[] (,,,) 2A and Be together serve as a generic constructor for a DataFrame of an arbitrary (statically known) size.C easytensor<Append one DataFrame to another, sum up the first dimension.3If you want to deconstruct a DataFrame, use ! or " instead.D easytensor8Append a small DataFrame to a big DataFrame on the left.3If you want to deconstruct a DataFrame, use ! or " instead.E easytensor9Append a small DataFrame to a big DataFrame on the right.3If you want to deconstruct a DataFrame, use ! or " instead. easytensor4Unsafely copy two PrimBytes values into a third one.F 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.G 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.H easytensorTry to convert between XNat-indexed DataFrames.rThis is useful for imposing restrictions on unknown DataFrames, e.g. increasing the minimum number of elements. easytensor Single frame easytensor3Multiple "columns" of data frames of the same shape 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.Z%#$&'(0+./-),*"! 1 CSTU)*+,-./0321456789:;<=>?@ABCDEFGH./-0321=><;:987654)ABCDE@FGH,*+?1  %#$'&(0+./-),*"! +./-),*"! CSTU>6(c) Artem ChirkinBSD3None.=>?@ACFHUVXkzr easytensorOperations on DataFramesas is an indexing dimensionalitybs is an element dimensionalityt5 is an underlying data type (i.e. Float, Int, Double)s 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. Arguments are zero-based primitive element offset and subset ("bs" element) size (aka  of sub dataframe)-Normal indexing can be expressed in terms of s: ^index i = case (# dimVal (dim @bs), fromEnum i #) of (# I# n, I# j #) -> indexOffset# (n *# j)t 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. Arguments are zero-based primitive element offset and subset ("bs" element) size (aka  of sub dataframe)-Normal updating can be expressed in terms of s: `update i = case (# dimVal (dim @bs), fromEnum i #) of (# I# n, I# j #) -> updateOffset# (n *# j)u easytensor,Get an element by its index in the dataframev easytensorGet a few contiguous elements.7In a sense, this is just a more complicated version of u.w easytensorSet a new value to an elementx easytensor Update a few contiguous elements7In a sense, this is just a more complicated version of w.y easytensor-Map a function over each element of DataFramez 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)} easytensorLeft-associative fold of a DataFrame. The fold is strict, so accumulater is evaluated to WHNF; but you'd better make sure that the function is strict enough to not produce memory leaks deeply inside the result data type.~ easytensorLeft-associative fold of a DataFrame with an index The fold is strict, so accumulater is evaluated to WHNF; but you'd better make sure that the function is strict enough to not produce memory leaks deeply inside the result data type. easytensorRight-associative fold of a DataFrame The fold is strict, so accumulater is evaluated to WHNF; but you'd better make sure that the function is strict enough to not produce memory leaks deeply inside the result data type. easytensorRight-associative fold of a DataFrame with an index The fold is strict, so accumulater is evaluated to WHNF; but you'd better make sure that the function is strict enough to not produce memory leaks deeply inside the result data type. 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) 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) easytensor3Apply a functor over a single element (simple lens) easytensor'Index an element (reverse arguments of u) easytensor>Zip two spaces on a specified subspace index-wise (with index) easytensorCZip two spaces on a specified subspace element-wise (without index)s easytensorPrim element offsett easytensorPrim element offsetruw{vstxyz|}~ruw{vstxyz|}~4#None .=>?@AFk 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&',-.=>?@AFHISUVXk easytensor6A framework for using DataFrame type family instances.2 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. easytensor*Get DataFrame backend type family instance easytensorgSingleton type used to determine the currently used DataFrame backend; establishes a good bijection b  ~ t ds (better than just using  BackendFamily everywhere). easytensor2Promise that we are sure the backend is ArrayBase. easytensorFind an instance of  class using C and .2 (c) Artem ChirkinBSD3chirkin@arch.ethz.chNone-.=>?@AEFHUVXk easytensor_Mutable DataFrame type. Keeps element offset, number of elements, and a mutable byte storage easytensorCreate a new mutable DataFrame. easytensorCreate a new mutable DataFrame. 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. easytensorPCopy one mutable DataFrame into another mutable DataFrame at specified position.In contrast to copyMDataFrame', 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. easytensorHCopy one DataFrame into another mutable DataFrame at specified position.This is a simpler version of  copyDataFrame. that allows to copy over one index at a time. easytensorPCopy one mutable DataFrame into another mutable DataFrame at specified position.This is a simpler version of copyMDataFrame. that allows to copy over one index at a time. 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. easytensor6Write a single element at the specified element offset easytensor-Write a single element at the specified index easytensor5Read a single element at the specified element offset easytensor,Read a single element at the specified index 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. (c) Artem ChirkinBSD3None-.=>?@AEFHUVXk easytensor+Mutable DataFrame of unknown dimensionality easytensor\Mutable DataFrame that lives in ST. Internal representation is always a MutableByteArray. easytensorCreate a new mutable DataFrame. easytensorCreate a new mutable DataFrame. easytensorHCopy one DataFrame into another mutable DataFrame at specified position.In contrast to copyMDataFrame', 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. easytensorPCopy one mutable DataFrame into another mutable DataFrame at specified position.In contrast to copyMDataFrame', 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. easytensorHCopy one DataFrame into another mutable DataFrame at specified position.This is a simpler version of  copyDataFrame. that allows to copy over one index at a time. easytensorPCopy one mutable DataFrame into another mutable DataFrame at specified position.This is a simpler version of  copyDataFrame. that allows to copy over one index at a time. 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. easytensor-Write a single element at the specified index easytensor,Read a single element at the specified index easytensor6Write a single element at the specified element offset easytensor5Read a single element at the specified element offset easytensorfCheck if the byte array wrapped by this DataFrame is pinned, which means cannot be relocated by GC. easytensorData frame with some dimensions missing at compile time. Pattern-match against its constructor to get a Nat-indexed mutable data frame. easytensor$Pure wrapper on a mutable byte array (c) Artem ChirkinBSD3None-.=>?@AEFHUVXk0 easytensor+Mutable DataFrame of unknown dimensionality easytensor\Mutable DataFrame that lives in IO. Internal representation is always a MutableByteArray. easytensorCreate a new mutable DataFrame. easytensorCreate a new mutable DataFrame. easytensorHCopy one DataFrame into another mutable DataFrame at specified position.In contrast to copyMDataFrame', 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. easytensorPCopy one mutable DataFrame into another mutable DataFrame at specified position.In contrast to copyMDataFrame', 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. easytensorHCopy one DataFrame into another mutable DataFrame at specified position.This is a simpler version of  copyDataFrame. that allows to copy over one index at a time. easytensorPCopy one mutable DataFrame into another mutable DataFrame at specified position.This is a simpler version of  copyDataFrame. that allows to copy over one index at a time. 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. easytensor-Write a single element at the specified index easytensor,Read a single element at the specified index easytensor6Write a single element at the specified element offset easytensor5Read a single element at the specified element offset easytensorfCheck if the byte array wrapped by this DataFrame is pinned, which means cannot be relocated by GC. 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. easytensorData frame with some dimensions missing at compile time. Pattern-match against its constructor to get a Nat-indexed mutable data frame. easytensor$Pure wrapper on a mutable byte array (c) Artem ChirkinBSD3chirkin@arch.ethz.chNone./=>?@ACFHUVXk7 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,-.>@AHIUVXk@. 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. easytensorxBackend resolver: Use this constraint to find any class instances defined for all DataFrame implementations, e.g. Num,  PrimBytes, etc. easytensor#Implementation behind the DataFrame2 !"#$%&'(2('&%$#"! %None.>FHgDT easytensor$Alias for zero-dimensional DataFrame easytensor$Convert scalar back to ordinary type easytensor"Convert any type to scalar wrapper easytensor.Broadcast scalar value onto a whole data frame < NoneD&None%&'-.=>?@AEFHUVXgUO 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&0777NoneVW&0)0'None"#-.1=>?@AFHUVXk_   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. easytensor.Compute LU factorization with Partial Pivoting easytensor4Result of LU factorization with Partial Pivoting  PA = LU . easytensorLower triangular matrix L%. All elements on the diagonal of L equal 1. easytensorUpper triangular matrix U easytensorRow permutation matrix P easytensorSign of permutation luPermSign == det . luPerm! 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. easytensorSolve Ax = b% problem given LU decomposition of A./ easytensorMPermute rows that the largest magnitude elements in columns are on diagonals.Invariants of result matrix: * forall j >= i: |M[i,i]| >= M[j,i] * if M[i,i] == 0 then forall j >= i: |M[i+1,i+1]| >= M[j,i+1] 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 easytensorheight9      !"#$'%&()*+,-./(None %.FHVXgz0 easytensorQuaternion operations1 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 vector2 easytensorSet the quaternion in format  (x,y,z,w)3 easytensor+Get the values of the quaternion in format  (x,y,z,w)4 easytensor3Set the quaternion from 3D axis vector and argument5 easytensor,Set the quaternion from 4D vector in format  (x,y,z,w)6 easytensor0Transform the quaternion to 4D vector in format  (x,y,z,w)7 easytensor$Get scalar square of the quaternion.(realToFrac (square q) == q * conjugate q8 easytensor5Imaginary part of the quaternion (orientation vector)9 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)A easytensorCreates a quaternion q from two vectors a and b, such that rotScale q a == b.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.C 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 qD 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.E 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.F 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)G 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 quaternion01?83245679:;<=>@ABCDEFG1)None%-.1=>?@AFHMVƩ1H*None%-.1=>?@AFHMVǀ1INone01?83245679:;<=>@ABCDEFG1HI01?83245679:;<=>@ABCDEFGIH+None%F,None%F<Nones9      !"#$'%&()*+,-./9()$'%&"# !*     +,-/.-Noneq%#$&'(0+./-),*"! 1 CSTU)*+,-./0321456789:;<=>?@ABCDEFGHruw{vstxyz|}~      !"#$'%&()*+,-././0./1.23.24.25.26.27.28.29.2:.2;.2<.2=.2>.2?.2@.2A.2B.2C.2D.2E.2F.2G.2H.2I.2J.2K.2L.2M.2N.2O.2P.2Q.2R.2S.2T.2U.2V.2U.2T.2P.WX.WY.WZ.W[.W\.W].W^.W_.2`$abcdefghijklmnopqrstuvwxyz{|}~           !"#$%&'()*+,-.,/01123456789:;<=>?@+ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrs!"tuvwxyz{|}~                                                               %%%%%%%%&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&'''''''''''''''''''''''''''''''''''''''' ' ' ' ' ''''''''''''((((((( (!("(#($(%(&('((()(*(+(,(-(.(/(0(1)2*3456789:;<=>?@ABCDECFGCFHCFICFJCFKLLMNOPQRSTUVWXYZ[\]^_`abCcdefghb i * ) ( ' & % $ # " !  jklmno.2p#q#r#s#t$$u$v$w$,.2x$y$+$ z { | }()2*3~)easytensor-2.0.0.0-3CCWptMCWbp7hugtqFBBKpNumeric.DataFrame.Type"Numeric.DataFrame.Internal.BackendNumeric.PrimBytes$Numeric.DataFrame.Internal.PrimArrayNumeric.ProductOrd Numeric.ProductOrd.NonTransitiveNumeric.ProductOrd.PartialNumeric.DataFrame.SubSpace"Numeric.DataFrame.Internal.MutableNumeric.DataFrame.STNumeric.DataFrame.IONumeric.DataFrame.ContractionNumeric.ScalarNumeric.VectorNumeric.MatrixNumeric.QuaternionForeign.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.Mat44fNumeric.Matrix.Internal.Mat44dNumeric.DataFrame)dimensions-2.0.0.0-E3TodFh6CxsCRM2bfCokxENumeric.Dimensions.IdxIdxIdxsNumeric.Dimensions.DimDDnDxD0D1D2D3D4D5D6D7D8D9D10D11D12D13D14D15D16D17D18D19D20D21D22D23D24D25Dims KnownDimsXDimsAsXDimsNXNXNatNumeric.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 broadcastix#gen#upd# arrayContent# offsetElemsuniqueOrCumulDims fromElems CumulDims unCumulDims cumulDims cdTotalDim cdTotalDim#cdIxgetSteps fromStepsixOffunsafeFromFlatList$fMonoidCumulDims$fSemigroupCumulDimsPartialOrderingPLTPEQPGT 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 KnownBackend DFBackendinferPrimArrayinferPrimBytes inferFloatinginferFractionalinferNum inferBoundedinferPOPartialinferPONonTransitiveinferProductOrderinferOrdinferEq inferPrimEleminferKnownBackendPackDFInferKnownBackend KnownBackends DataFrame' SomeDataFrame DataFrameXFrame MultiFrame SingleFrameDF9DF8DF7DF6DF5DF4DF3DF2SZ:*: fromFlatListpackDFunpackDFappendDFconsDFsnocDFfromListWithDefaultfromList constrainDF$fReadDataFrame$fReadDataFrame0$fReadDataFrame1$fReadDataFrame2$fShowDataFrame$fShowDataFrame0$fShowDataFrame1$fShowDataFrame2 $fEqDataFrame$fEqDataFrame0$fStorableDataFrame$fReadSomeDataFrame$fReadSomeDataFrame0$fShowSomeDataFrame$fShowSomeDataFrame0$fEqSomeDataFrame$fEqSomeDataFrame0$fInferKnownBackend[]tsds$fInferKnownBackendTYPEtds$fDataDataFrame$fEqDataFrame1$fDataDataFrame0$fGenericDataFrame$fGenericDataFrame0$fPrimArrayDataFrame$fPrimBytesDataFrame$fRealFloatDataFrame$fRealFracDataFrame$fRealDataFrame$fFloatingDataFrame$fFractionalDataFrame$fNumDataFrame$fIntegralDataFrame$fEnumDataFrame$fBoundedDataFrame$fProductOrderDataFrame$fOrdDataFrame$fEqDataFrame2$fDataDataFrame'SubSpace indexOffset# updateOffset#update updateSliceewmapiwmapewgeniwgenewfoldliwfoldlewfoldriwfoldr elementWise indexWise indexWise_ elementWise_element! ewfoldMap iwfoldMapiwzipewzip$fSubSpacetasbsasbs MDataFrame newDataFrame#newPinnedDataFrame#copyDataFrame#copyMDataFrame#copyDataFrame'#copyMDataFrame'#unsafeFreezeDataFrame#freezeDataFrame#thawDataFrame#thawPinDataFrame#unsafeThawDataFrame#writeDataFrameOff#writeDataFrame#readDataFrameOff#readDataFrame#withDataFramePtr#isDataFramePinned#SomeSTDataFrame STDataFrameXSTFrame newDataFramenewPinnedDataFrame copyDataFramecopyMutableDataFramecopyDataFrame'copyMutableDataFrame'unsafeFreezeDataFramefreezeDataFrame thawDataFramethawPinDataFrameunsafeThawDataFramewriteDataFrame readDataFramewriteDataFrameOffreadDataFrameOffisDataFramePinnedSomeIODataFrame IODataFrameXIOFramewithDataFramePtr Contractioncontract%*$fContractiontasbsasbsScwSciScdScfScalarunScalarscalar fromScalarVector4vec4 unpackV4#Vector3vec3 unpackV3#Vector2vec2 unpackV2#Vec4wVec3wVec2wVec4iVec3iVec2iVec4dVec3dVec2dVec4fVec3fVec2fVectorVec2Vec3Vec4.*.dot·normL1normL2 normalized normLPInf normLNInfnormLPdet2cross×Mat44dMat34dMat24dMat43dMat33dMat23dMat42dMat32dMat22dMat44fMat34fMat24fMat43fMat33fMat23fMat42fMat32fMat22f HomTransform4 translate4 translate3rotateXrotateYrotateZrotate rotateEulerlookAt perspective orthogonal toHomPoint toHomVectorfromHomMatrixLUluLUFactluLowerluUpperluPerm luPermSign MatrixInverseinverseMatrixDeterminantdet SquareMatrixeyediagtraceMatrixTranspose transposeMatrixmat22mat33mat44luSolvepivotMat QuaternionQuaterpackQunpackQ# fromVecNumfromVec4toVec4squareimreimVectakertakeitakejtakek conjugaterotScale getRotScale axisRotationqArg fromMatrix33 fromMatrix44 toMatrix33 toMatrix44QFloatQDouble PrimTaggedprimTag' GPrimBytes gbyteSizegbyteFieldOffset GPrimFieldsbase GHC.GenericsGeneric roundUpInt gfromBytes greadBytes gwriteBytes greadAddr gwriteAddrghc-prim GHC.TypesOrdering GHC.ClassescompareOrdEqminmax ScalarBase _unScalarBase $fNumFloatX3$fBoundedFloatX3FloatX3FloatX3# $fNumFloatX2$fBoundedFloatX2FloatX2FloatX2# $fNumDoubleX4$fBoundedDoubleX4DoubleX4 DoubleX4# $fNumDoubleX3$fBoundedDoubleX3DoubleX3 DoubleX3# $fNumDoubleX2$fBoundedDoubleX2DoubleX2 DoubleX2# ArrayBaseGHC.Prim ByteArray#accumV2Idempotentloop1#$fOrdArrayBaseloop#I AllFrameslookLexunsafeAppendPBD:R:DataFrameTYPENattns0D:R:DataFrame[]Nattsns0D:R:DataFramelXNattsxns0totalDim $fNumFloatX4$fBoundedFloatX4FloatX4FloatX4#bSing BackendSing unsafeDefault DimensionsinferBackendInstanceD:R:STDataFrameXNatstxs0D:R:STDataFrameNatstns0D:R:IODataFrameXNattxs0D:R:IODataFrameNattns0