Git Product home page Git Product logo

mappedtensor's Introduction

Transparent lazy data access for matlab

By default, Matlab matrices must be fully loaded into memory. This can make allocating and working with huge matrices a pain, especially if you only really need access to a small portion of the matrix at a time. memmapfile allows the data for a matrix to be stored on disk, but you can't access the matrix transparently in functions that don't expect a memmapfile object without reading in the whole matrix. MappedTensor is a matlab class that looks like a simple matlab tensor, with all the data stored on disk.

A few extra niceties over memmapfile are included, such as built-in per-slice access; fast addition, subtraction, multiplication and division by scalars; fast negation; permutation; complex support.

Tensor data is automatically allocated on disk in a temporary file, which is removed when all referencing objects are cleared. Existing binary files can also be accessed. MappedTensor is a handle class, which means that assigning an existing mapped tensor to another variable will not make a copy, but both variables will point to the same data. Changing the data in one variable will change both variables.

MappedTensor internally uses mex functions, which need to be compiled the first time MappedTensor is used. If compilation fails then slower, non-mex versions will be used.

Download and install

Download MappedTensor
Unzip the @MappedTensor directory to somewhere on the Matlab path. The @ ampersand symbol is important, as it signals to Matlab that this is a class directory. Then type:

addpath /path/to/Mappedtensor

Note: MappedTensor provides an accelerated MEX function for performing file reads and writes. MappedTensor will attempt to compile this function when a MappedTensor variable is first created. This requires mex to be configured correctly for your system. If compilation fails, then a slower pure Matlab version will be used.

Creating a MappedTensor object

M = MappedTensor([dim1 dim2...], ...) M = MappedTensor(dim1, dim2, ...) M = MappedTensor(dim, ...) allocates a MappedTensor object to store an array with specified size [d1 d2...]. When only one dimension value is specified, the actual dimension is for a square array [d d].

M = MappedTensor(FILENAME, [d1 d2...], 'FORMAT', class, ...) constructs a MappedTensor object that re-uses an existing map file FILENAME for an array with dimensions [d1 d2...]. The full size, class, and offset of the file must
be known and specified in advance. This file will not be removed when all handle references are destroyed.

M = MappedTensor(ARRAY) constructs a MappedTensor object that maps a numeric array ARRAY into a temporary file. The array must be 2D or more (not scalar, nor vector that would conflict with a dimension setting). This syntax implies to already allocate the initial array, which limits the size of the MappedTensor. For large arrays, it is more efficient to pre-allocate the object with specified dimensions or the 'Size' property and then set the content, per chunks.

M = MappedTensor(..., PROP1, VALUE1, PROP2, VALUE2, ...) constructs a MappedTensor object, and sets the properties of that object that are named in the argument list (PROP1, PROP2, etc.) to the given values (VALUE1, VALUE2, etc.). All property name arguments must be quoted strings (e.g., 'writable'). Any properties that are not specified are given their default values.

Note: When a variable containing a MappedTensor object goes out of scope or is otherwise cleared, the memory map is automatically closed. You may also call the DELETE method to force clear the object.

Tensor properties

All properties can be accessed with syntax e.g. M.property. All these properties can also be set when building the tensor.

Property Description
Data The actual Data
Filename Binary data file name on disk (real part of tensor)
FilenameCmplx Binary data file name on disk (complex part of tensor)
Format The class of this mapped tensor
MachineFormat The desired machine format of the mapped file
Offset The number of bytes to skip at the beginning of the file
Temporary A flag which records whether a temporary file was created
Writable Should the data be protected from writing?

We detail below the use of these properties, especially to set an initial tensor.

Format: Char string (defaults to 'double').

Format of the contents of the mapped region. Format specifies that the mapped data is to be accessed as a single vector of type specified by Format's value. Supported char arrays are 'int8', 'int16', 'int32', 'int64', 'uint8', 'uint16', 'uint32', 'uint64', 'single', and 'double'. Complex arrays are supported. Sparse arrays are not supported. You can change later the storage class of the object with the CAST method, however this is usually not recommended.

Offset: Non-negative integer (defaults to 0).

Number of bytes from the start of the file to the start of the mapped region. Offset 0 represents the start of the file. This allows to skip over the beginning of an (existing) binary file, by throwing away the specified number of header bytes. You can use methdos FREAD and FWRITE to read this header region.

Writable: True or false (defaults to false).

Access level which determines whether or not Data property (see below) may be assigned to. This property can be changed after object creation.

Temporary: True or false (default to true when created from array).

When false, the associated file is kept when the object is cleared. Such files can be further reused. When the object is created from an array, Temporary is true. When creating from an existing map file Temporary is false. You can change this property after creation. When saving an object, the Temporary state is set to false. This property can be changed after object creation.

MachineFormat: big-endian ('ieee-be') or little-endian ('ieee-le')

If not specified, the machine-native format will be used.

Data: array

Array to assign to the mapped object. This property can be changed after object creation. You can also set the Data with syntax:

set(M, 'Data', array)
M(:)            = whole_array;
M([ 1 3 5... ]) = slice; 
Filename: Char array.

Contains the name of the file being mapped. You can also get the mapped file with FILEPARTS.

FilenameCmplx: Char array.

Contains the name of the file being mapped (complex part). You can also get the mapped file with FILEPARTS.

Additional Name/Value pair options at build only

TempDir: Directory path

Directory where the mapped file(s) should stored. The default path is e.g. TMPDIR or /tmp. You may also use /dev/shm on Linux systems to map the file into memory. This can be very efficient in terms of I/O, and an be coupled with tensor compression with the pack method.

Like: array

Specified array dimension and class is used to preallocate a new object. Note that sparse arrays are not supported.

Size: [d1 d2 ...] array

Vector which specifies the size of the mapped array. This is the same as specifying dimensions as first arguments (see above).

All the properties above may also be accessed after the MappedTensor object has been created with the GET method. For example,

set(M, 'Writable', true); % or M.Writable = true;

changes the Writable property of M to true.

Loading from data files

The LOAD method allows to lazy import binary data sets with syntax

m = load(MappedTensor, 'filename');

with the following data formats.

Extension Description
EDF ESRF Data Format (2D)
POS Atom Probe Tomography (4 columns)
NPY Python NumPy array (nD)
MRC MAP CCP4 RES MRC MRC/CCP4/MAP electronic density map (3D)
MAR MAR CCD image (2D)
IMG MCCD ADSC X-ray detector image SMV (2D)

Using the array

The MappedTensor array can be used in most cases just as a normal Matlab array, as many class methods have been defined to match the usual behaviour.

You may access the array with indices as in M(I,J,..). The full tensor content is retrieved with M(:) as a column, or M(:,:) as pages, and finally as M.Data to get the raw shaped array.

Most standard Matlab operators just work transparently with MAPPEDTENSOR. You may use single objects, and even array of tensors for a vectorized processing, such as in:

m=MappedTensor(rand(100)); n=copyobj(m); p=2*[m n];

These objects contain a reference to the actual data. Defining n=m actually access the same data. To make a copy, use the COPYOBJ method.

Transparent casting to other classes is supported in O(1) time. Note that due to transparent casting and tranparent O(1) scaling, rounding may occur in a different class to the returned data, and therefore may not match Matlab rounding precisely. If this is an issue, index the tensor and then scale the returned values rather than rely on O(1) scaling of the entire tensor.

To work efficiently on very large arrays, it is recommended to employ the ARRAYFUN method, which applies a function FUN along a given dimension. This is done transparently for many unary and binary operators (with ARRAYFUN2).

The NUMEL method returns 1 on a single object, and the number of elements in vectors of objects. To get the number of elements in a single object, use NUMEL2(M) or PROD(SIZE(M)). This behaviour allows most methods to be vectorized on sequences on tensors.

If you need to handle many such tensors, it may be a good idea to compress them with pack(m) while you are not using them. This can be done for instance right after loading content. Decompression is performed transparently while you access the tensor array. Think about re-compressing afterwards to save disk/memory. Compression is usually extremely efficient on data with low randomness.

An efficient processing pipeline could be:

  • load tensors
  • compress them with pack
  • do whatever you need (extraction is performed automatically)
  • recompress as soon as possible with pack

A list of available methods is shown below.

Method Description
abs Absolute value. (unary op)
acos Inverse cosine, result in radians. (unary op)
acosh Inverse hyperbolic cosine. (unary op)
addlistener Add listener for event.
all True if all elements of a tensor are nonzero. (unary op)
and & Logical AND. (binary op)
any True if any element of a tensor is a nonzero number or is (unary op)
arrayfun Apply a function on the entire array, in slices.
arrayfun2 Apply a function on two similar arrays, in slices.
asin Inverse sine, result in radians. (unary op)
asinh Inverse hyperbolic sine. (unary op)
atan Inverse tangent, result in radians. (unary op)
atanh Inverse hyperbolic tangent. (unary op)
cast Cast a variable to a different data type or class.
ceil Round towards plus infinity. (unary op)
char Convert tensor representation to character array (string).
conj Complex conjugate. (unary op)
copyobj Make deep copy of array.
cos Cosine of argument in radians. (unary op)
cosh Hyperbolic cosine. (unary op)
ctranspose ' Complex conjugate transpose.
cumprod Cumulative product of elements. (unary op)
cumsum Cumulative sum of elements. (unary op)
del2 Discrete Laplacian. (unary op)
delete Delete the file, if a temporary file was created for this variable
disp LAY Display array (long).
display Display array (short).
double SINGLE Convert tensor representation to double precision (float64).
end Last index in an indexing expression
eq == Equal. (binary op)
exp Exponential. (unary op)
fileparts Return the files associated with the data
find Find indices of nonzero elements. (unary op)
findobj Find objects matching specified conditions.
findprop Find property of MATLAB handle object.
floor Round towards minus infinity. (unary op)
fread Read binary data from file.
fwrite Write binary data from file.
ge >= Greater than or equal. (binary op)
get Get MATLAB object properties.
getdisp Specialized MATLAB object property display.
gt > Greater than. (binary op)
imag Complex imaginary part. (unary op)
int16 Convert tensor representation to signed 16-bit integer.
int32 Convert tensor representation to signed 32-bit integer.
int64 Convert tensor representation to signed 64-bit integer.
int8 Convert tensor representation to signed 8-bit integer.
ipermute Inverse permute array dimensions.
ischar True for character array (string).
isempty True for empty array.
isequal True if arrays are numerically equal. (binary op)
isfinite True for finite elements. (unary op)
isfloat True for floating point arrays, both single and double.
isinf True for infinite elements. (unary op)
isinteger True for arrays of integer data type.
islogical True for logical array.
ismatrix True if array is a matrix (not a scalar).
isnan True for Not-a-Number. (unary op)
isnumeric True for numeric arrays.
isreal True for real array.
isscalar True if array is a scalar.
isvalid Test handle validity.
ldivide .\ Left array divide. (binary op)
le <= Less than or equal. (binary op)
length Length of vector.
load Lazy loading from data files.
loadobj Load filter for objects.
log Natural logarithm. (unary op)
log10 Common (base 10) logarithm. (unary op)
logical UINT8 Convert tensor representation to logical (true/false).
lt < Less than. (binary op)
max Largest component.
mean Average or mean value. (unary op)
median Median value. (unary op)
min Smallest component.
minus - Minus. (binary op)
mldivide \ Backslash or left matrix divide. (binary op)
mpower ^ Matrix power. (binary op)
mrdivide / Slash or right matrix divide. (binary op)
mtimes * Matrix multiply. (binary op)
ndims Number of dimensions.
ne ~= Not equal. (binary op)
nonzeros Nonzero matrix elements. (unary op)
norm Matrix or tensor norm. (unary op)
not ~ Logical NOT. (unary op)
notify Notify listeners of event.
numel Number of objects in a vector. Use prod(size(M)) or numel2 for number of elements in an object.
numel2 NUMEL2 Number of elements in an array, same as prod(size(M))
or
pack Compress mapped data files
permute Permute array dimensions
plot Plot an array.
plus + Plus. (binary op)
power .^ Array power. (binary op)
prod Product of elements. (unary op)
rdivide ./ Right array divide. (binary op)
real Real part. (unary op)
reducevolume reduce an array size
reshape Reshape array.
round Round towards nearest integer. (unary op)
runtest runs a set of tests on object methods
saveobj Save filter for objects.
set Set MATLAB object property values.
setdisp Specialized MATLAB object property display.
sign Signum function. (unary op)
sin Sine of argument in radians. (unary op)
single Convert tensor representation to single precision (float32).
sinh Hyperbolic sine. (unary op)
size Get original tensor size, and extend dimensions if necessary
sqrt Square root. (unary op)
subsasgn Subscripted assignment
subsref Subscripted reference.
sum Sum of elements.
tan Tangent of argument in radians. (unary op)
tanh Hyperbolic tangent. (unary op)
times .* Array multiply. (binary op)
transpose .' Transpose.
uint16 Convert tensor representation to unsigned 16-bit integer.
uint32 Convert tensor representation to unsigned 32-bit integer.
uint64 Convert tensor representation to unsigned 64-bit integer.
uint8 Convert tensor representation to unsigned 8-bit integer.
uminus - Unary minus. (unary op)
unpack Decompress mapped data files
uplus + Unary plus (copyobj).
var Variance. (unary op)
version Return class version
xor Logical EXCLUSIVE OR. (binary op)

Examples

   % To create a mapped file for a given input array:
   % A temporary file is created to hold the data.
   m = MappedTensor(rand(100,100,100));

   % To reuse a previously existing mapped file:
   m = MappedTensor('records.dat', [100 100 100], ...
         'format','double', 'writable', true);
   m(:) = rand(100, 100, 100);  % assign new data
   m(1:2:end) = 0;

Publications

This work was published in Frontiers in Neuroinformatics: DR Muir and BM Kampa. 2015. FocusStack and StimServer: A new open source MATLAB toolchain for visual stimulation and analysis of two-photon calcium neuronal imaging data, Frontiers in Neuroinformatics 8 85. DOI: 10.3389/fninf.2014.00085. Please cite our publication in lieu of thanks, if you use this code.

This version of the code has been heavily revamped by [email protected]. Please cite the following publication:

  • E. Farhi et al., J. Neut. Res., 17 (2013) 5. DOI: 10.3233/JNR-130001

mappedtensor's People

Contributors

dylanmuir avatar farhi avatar ingiehong avatar morroth avatar patricialuna avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

mappedtensor's Issues

Empty index causes error

>> a=MappedTensor(1);
>> a([])
Error using mapped_tensor_shim
*** mapped_tensor_shim: Could not allocate data buffer.

Error in MappedTensor>mt_read_data (line 1763)
   tData = hShimFunc('read_chunks', hDataFile, mnFileChunkIndices, vnLinearIndices,
   vnReverseSort, vnDataSize, strClass, nHeaderBytes, double(bBigEndian));

Error in MappedTensor/my_subsref (line 466)
            tfData = mtVar.fRealFactor .* mt_read_data(mtVar.hShimFunc,
            mtVar.hRealContent, S, vnReferencedTensorSize, mtVar.strStorageClass,
            mtVar.nHeaderBytes, mtVar.bBigEndian, mtVar.hRepSumFunc,
Error in MappedTensor/subsref (line 375)
               [varargout{1}] = my_subsref(mtVar, subs);

As compared to a standard matrix:

>> b=zeros(1);
>> b([])
ans =
     []

Also the empty matrix is not caught in the constructor:

>> a=MappedTensor([]);
Attempted to access vnTensorSize(0); index must be a positive integer or logical.

Error in MappedTensor (line 312)
         if (vnTensorSize(end) == 1) && (numel(vnTensorSize) > 2)

Sorry for all these nit-picky bugs, I'm just putting them up here as I run into them.

Does it have to inherit from a handle object?

One thing that is tricky with handle object is that copies all point to the same object. This can be non-intuitive - best illustrated with an example:

>> a=MappedTensor(1,'Convert');
>> b=2*a;
>> a(1)

ans =

     2

I made a few changes to avoid the handle inheritance. The main thing was to declare a cleanup function (trivial) and it seems to work just fine. I haven't fully tested it so there may be some other side-effects.

I've uploaded the changes here. Sorry I don't really understand how github works properly to do clever things like a pull request.

Indexing a mapped tensor after permutation

Hi,

First off, fantastic utility and much appreciated. Makes handling my 5-10GB data sets so much easier than the rather clunky and slow Matlab native memmapfile. I am using the MappedTensor version from Matlab File Exchange. I have a particular use case wherein I permute my tensor, and then attempt to populate with some values. Simple example:

mt = MappedTensor(100,200,10);
mt = permute(mt,[3,1,2]);
[nr,nc,nf] = size(mt);
mt(:,:,1) = randn(nr,nc);

This gives the following error ...

Error using mapped_tensor_shim
*** mapped_tensor_shim: In an assignment A(I) = B, the number of elements in B and I must be the
same.

Error in MappedTensor>mt_write_data (line 1837)
hShimFunc('write_chunks', hDataFile, mnFileChunkIndices, vnUniqueDataIndices, vnDataSize, strClass, nHeaderBytes, cast(tData, strClass), double(bBigEndian));

Error in indexing (line 598)
mt_write_data(mtVar.hShimFunc, mtVar.hRealContent, S, mtVar.vnOriginalSize, mtVar.strStorageClass, mtVar.nHeaderBytes, tfData, mtVar.bBigEndian, mtVar.hRepSumFunc, mtVar.hChunkLengthFunc);

Should I be accessing the permuted tensor differently? Any help would be appreciated.

Cheers,

Robert

a=cast(a) could be implemented with strClass

When casting the entire MappedTensor, it seems it could be a trivial operation by just returning the header with the strClass changed. Then there would be no need to being the array into memory, as it does currently.

>> a=MappedTensor(100);
>> b=single(a);
Warning: --- MappedTensor: Warning: This command will allocate memory for the
entire tensor! 
> In MappedTensor.MappedTensor>MappedTensor.cast at 1368
  In MappedTensor.MappedTensor>MappedTensor.single at 1352 

Direct conversion of a tensor to a `MappedTensor` in the constructor

Do you think this is a good idea for a constructor?

>> a=rand(50,'single');
>> a=MappedTensor(a);
Error using MappedTensor (line 266)
*** MappedTensor: Error: 'vnTensorSize' must be a positive integer vector.

It gives a simple way do dump the variable to disk if it's getting large, e.g.

>> a=randn(50);
>> w=whos('a');
>> if w.bytes > 1e9; a=MappedTensor(a); end

There is obviously some ambiguity if the argument is a vector so maybe it would need a preceding string, e.g. a=MappedTensor('convert',a), or something like that.

Shortcut casting still causes errors

As before, the order of the cast/scale operations is fixed so it is going to be wrong some of the time. I don't think there is an easy remedy :(

>> a=MappedTensor(1);
>> a(1)=1.3;
>> a=uint8(2*a);a(1)
ans =
    2
>> a=1.3;
>> a=uint8(2*a);a(1)
ans =
    3

Add overloaded `prod` method

Hi Dylan,

A little bug, invalid imaginary index input not detected:

>> a=MappedTensor(1);
>> a(i)=1
Error using MappedTensor>ConvertColonsCheckLims (line 1861)
*** MappedTensor: Index exceeds matrix dimensions.
Error in MappedTensor>mt_write_data (line 1715)
   [vnLinearIndices, vnDataSize] = ConvertColonsCheckLims(sSubs.subs,
   vnTensorSize, hRepSumFunc);
Error in MappedTensor/subsasgn (line 503)
            mt_write_data(mtVar.hShimFunc, mtVar.hRealContent, subs,
            mtVar.vnOriginalSize, mtVar.strClass, mtVar.nHeaderBytes, tfData ./
            mtVar.fRealFactor, mtVar.bBigEndian, mtVar.hRepSumFunc,
            mtVar.hChunkLengthFunc); 

Also I wonder if you would consider adding these utility functions?

length
ndims
mean
prod
isfloat
isinteger

>> a=MappedTensor(1,'class','single');
>> isfloat(a)
ans =
     0
>> a=MappedTensor(1,'class','int8');
>> isinteger(a)
ans =
     0

Also, would you consider setting properties (SetAccess = private, GetAccess = public) so we can see the internals of the class using details() function?

Last thing, this is a little tricky, what should MappedTensor return for class()? Should it be of the contained values (single, double, int8, etc.)? I'm asking since a lot of (my) code checks for class and so MappedTensors require extra handling.

Thanks for your help!
Mark

340 Gigabyte data and error while creating .mex from mapped_tensor_shim.c

Dylan,
I use windows 7 x64. When I try to compile .mex function from mapped_tensor_shim.c I can such error. I deleted the whole line 33, that includes "#define UINT64_C(c) c ## i64" and it was compiled normally. I could use MappedTensor.

I tryed to work with data of 340 Gigabytes.
mtVar = MappedTensor([r_path r_file],[8240 42654189], 'Class', 'uint8');
So I have a matrice of uint8 of size(mtVar) = [8240 42654189]. Then I use the following command to get the data (I need 42654189 elements that weigh about 42 Megabytes):
tic; mtVar(1,:); toc
The elapsed time is almost 9 hours. By the way it doesn't require much RAM or CPU unlike memmapfile, which consumes 5 Gigabytes of RAM (all my RAM) in 5 minutes and my machine is hung.
Is it possible to speedup access to such data?
By the way if try to get 10^5 elements:
tic; mtVar(1,1:10^5); toc
It takes time about 66 seconds. If I then rerun this command then elapsed time will be les than 1 second. Why?

dylan

Constructor fails with complex input

When converting a regular matrix to a MappedTensor, it fails if the matrix is complex.

>> a=MappedTensor(1,'Convert');
>> a=MappedTensor(1i,'Convert');
Error using mapped_tensor_shim
*** mapped_tensor_shim: 'bReadOnly' must be a logical value.

Error in MappedTensor/make_complex (line 1389)
         mtVar.hCmplxContent = mtVar.hShimFunc('open', mtVar.strCmplxFilename, mtVar.strMachineFormat,
         mtVar.bReadOnly);

Error in MappedTensor (line 382)
            make_complex(mtVar);

Error in MappedTensor (line 270)
                        mtVar = MappedTensor(size(tfSourceTensor), varargin{:}, 'Like', tfSourceTensor);

Allow integer types for index variables

In MappedTensor.m, you could generalize the validation check to allow all integer types (int16, int32, etc.). Line 1590: validateattributes(oRefs, {'numeric'}, {'integer', 'real', 'positive'});

For the validateattributes() function, Matlab's documentation states:

  "The string 'numeric' is an
   abbreviation for the classes uint8, uint16, uint32, uint64,
   int8, int16, int32, int64, single, double."

Works for me. Thanks for creating this file, it's a real improvement over memmapfile.

Shortcut casting causes errors

It looks like the strClass way of casting added here causes problems if the scaling factor is not 1. The order of the operations is scale then cast with the MappedTensor, even if they were applied in a different order, which creates inconsistencies.

Example:

>> a=MappedTensor(1);
>> a(1)=1.5;
>> a=2*uint8(a);
>> a(1)
ans =
    3
>> a=1.5;
>> a=2*uint8(a);
>> a(1)
ans =
    4

I really like the shortcut way of doing things but it would need to track the order of the operations if there are more than 1 of them, as discussed a little bit here.

Probably best to revert this change in the meantime - sorry for the lack of insight when requesting it!

Error with uint indexes

I was getting this error when accessing TIFFStack data using uint32 indexes:

Error using TIFFStack>isvalidsubscript
*** TIFFStack: Subscript indices must either be real positive integers or logicals.

I solved this by changing line 1488 in TIFFStack.m from:
validateattributes(oRefs, {'single', 'double'}, {'integer', 'real', 'positive'});
to:
validateattributes(oRefs, {'numeric'}, {'integer', 'real', 'positive'});

Seems like a logical fix to me, but if I'm not understanding something please let me know.

Cheers,
Marcel

Data is corrupted when subsampling a large file (8Gb) on windows

Dear Doctor Muir,

I am having a problem displaying a sub-sampled version of a 8gb mapped tensor file with the "imagesc" fnction.
If i choose the x and y gap per frame to be equal or greater than 5, the image will be destroyed at the 234th frame, which is around 2gb of data.
It always happens at the 234th frame, regardless where i start displaying. For example if i start at frame 234 the image will be destroyed immediately.
Data type used was "single".
Trying to display all the frames with a sub-sampling of 4x4 or less will result in no errors at all.
The mex'ed version was used. Trying to use he non mex'ed version did not work.
I would be happy to get your insight into why this is happening.

Best regards,
Jerome

Overloaded `plus` method bug

Sorry, another bug report.

>> a=MappedTensor(100);
>> a=a+1;
Error using MappedTensor/SliceFunction (line 1128)
Not enough input arguments.
Error in  +  (line 772)
         SliceFunction(mtVar, fhAddition, nSliceDim); 

class char silently converts to double

While tinkering with the code to add a new constructor I kept seeing this problem with char arrays being converted to double.

>> b=MappedTensor(1,3,'class','char')
b = 
  MappedTensor object, containing: char [1 3].
  Methods
>> b(:)='t'
b = 
  MappedTensor object, containing: double [1 3].
  Methods

It seems to happen on lines 303-4

         % - Initialise dimension order
         mtVar.vnDimensionOrder = 1:numel(vnTensorSize);

but that doesn't make any sense to me, So I'm kind of stuck. I don't use char arrays much but it's bizarre....

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.