shabbychef
shabbychef

Reputation: 1999

How can I save a row vector to HDF in MATLAB?

For some reason, the hdf5write method in MATLAB is automatically converting my row vectors to column vectors when I re-read them:

>> hdf5write('/tmp/data.h5','/data',rand(1,10));
>> size(hdf5read('/tmp/data.h5','/data'))

ans =

    10     1

However, for a row vector in the third dimension, it comes back just fine:

>> hdf5write('/tmp/data.h5','/data',rand(1,1,10));
>> size(hdf5read('/tmp/data.h5','/data'))

ans =

     1     1    10

How can I get hdf5write to do the right thing for row vectors? They should be coming back as 1 x 10, not 10 x 1.

edit the problem is slightly more complicated because I am using c-based mex to actually read the data later, instead of hdf5read. Moreover, the problem really is in hdf5write, and this is visible in the hdf5 files themselves:

>> hdf5write('/tmp/data.h5','/data',randn(1,10));
>> ! h5ls /tmp/data.h5

data                     Dataset {10}

that is, the data is saved as a 1-dimensional array in the hdf5 file. For comparison, I try the same thing with an actual 2-d matrix (to show what it looks like), a 1-d column vector, a 1-d vector along the third dimension, and, for kicks, try the V71Dimensions trick which is in the help for both hdf5read and hdf5write:

>> hdf5write('/tmp/data.h5','/data',randn(10,1)); %1-d col vector
>> ! h5ls /tmp/data.h5

data                     Dataset {10}
>> hdf5write('/tmp/data.h5','/data',randn(1,1,10)); %1-d vector along 3rd dim; annoying
>> ! h5ls /tmp/data.h5

data                     Dataset {10, 1, 1}
>> hdf5write('/tmp/data.h5','/data',randn(2,5)); %2-d matrix. notice the reversal in dim order
>> ! h5ls /tmp/data.h5

data                     Dataset {5, 2}
>> hdf5write('/tmp/data.h5','/data',randn(1,10),'V71Dimensions',true); %1-d row; option does not help
>> ! h5ls /tmp/data.h5

data                     Dataset {10}

So, the problem does seem to be in hdf5write. The 'V71Dimensions' flag does not help: the resultant hdf5 file is still a Dataset {10} instead of a Dataset {10,1}.

Upvotes: 2

Views: 1342

Answers (2)

Simon
Simon

Reputation: 32893

I'm affraid for this you will have to use the low-level HDF5 API of Matlab.

In Matlab, the low-level API is available using for instance H5.open(...), H5D.write(...) and so on. The names correspond exactly to those of the C library (see the HDF5 doc). However there is a slight difference in the arguments they take, but the matlab help function will tell you everything you need to know...

The good news is that the Matlab version of the API is still less verbose than the C version. For instance, you don't have to close manually the datatypes, dataspaces, etc. since Matlab closes them for you when the variables go out of scope.

Upvotes: 1

Jonas
Jonas

Reputation: 74940

It's the reading that's an issue. From the help

[...] = hdf5read(..., 'V71Dimensions', BOOL) specifies whether to change the majority of data sets read from the file. If BOOL is true, hdf5read permutes the first two dimensions of the data set, as it did in previous releases (MATLAB 7.1 [R14SP3] and earlier). This behavior was intended to account for the difference in how HDF5 and MATLAB express array dimensions. HDF5 describes data set dimensions in row-major order; MATLAB stores data in column-major order. However, permuting these dimensions may not correctly reflect the intent of the data and may invalidate metadata. When BOOL is false (the default), the data dimensions correctly reflect the data ordering as it is written in the file — each dimension in the output variable matches the same dimension in the file.

Thus:

hdf5write('/tmp/data.h5','/data',rand(1,10));
size(hdf5read('/tmp/data.h5','/data','V71Dimensions',true))
ans =
     1    10

Upvotes: 4

Related Questions