Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

netcdf defVar: order of dimensions

137 views
Skip to first unread message

Penny

unread,
Feb 27, 2009, 3:34:01 PM2/27/09
to
Using the netcdf tools in matlab R2008b, it seems that the convention for the order of dimensions is opposite the standard. For example, suppose I run the following:

ncid = netcdf.create('mynetcdffile','NC_write');

rows = 10;
cols = 2;
myvar = ones(rows,cols) ;

irows = netcdf.defDim(ncid,'Nrows', rows ) ;
icols = netcdf.defDim(ncid,'Ncols', cols) ;

imyvar = netcdf.defVar(ncid,'myvar','double', [irows,icols]) ;

netcdf.endDef(ncid);
netcdf.putVar(ncid,imyvar,myvar) ;

netcdf.close(ncid)

The ncdump I get is

netcdf mynetcdffile {
dimensions:
Nrows = 10 ;
Ncols = 2 ;
variables:
double myvar(Ncols, Nrows) ;
data:

myvar =
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ;
}


Have I gotten mixed up somewhere, is this a bug, or is this the new convention?

Ashish Uthama

unread,
Feb 27, 2009, 4:45:46 PM2/27/09
to

Does the second paragraph below help? (From R2008b)

>> help netcdf.defVar

netcdf.defVar Create netCDF variable.
varid = netcdf.defVar(ncid,varname,xtype,dimids) creates a new
variable given a name, datatype, and list of dimension IDs. The
datatype is given by xtype, and can be either a string
representation such as 'double', or it may be the numeric equivalent
provided by netcdf.getConstant. The return value is the numeric ID
corresponding to the new variable.


This function corresponds to the "nc_def_var" function in the netCDF
library C API, but because MATLAB uses FORTRAN-style ordering, the
the fastest-varying dimension comes first and the slowest comes
last. Any unlimited dimension is therefore last in the list of
dimension IDs. This ordering is the reverse of that found in the C
API.


Penny

unread,
Feb 27, 2009, 5:54:01 PM2/27/09
to
Thanks for the response. I'm pretty new to creating and modifying netcdf files, and I don't fully understand. A few questions...

1) What is meant by the fastest-varying dimension? Aren't my dimensions constant?

2) What is meant by "comes first?" Comes first where? How does this relate to the order in my defVar statement? If I switch it in my code, the rows/cols switch:

netcdf.defVar(ncid,'myvar','double', [irows,icols]) ;

gives me an opposite ordering from

netcdf.defVar(ncid,'myvar','double', [icols,irows]) ;

At any rate, if you have a situation where rows=cols you could get in to trouble if you read in the netcdf data assuming certain dimensions (without verifying).

Ashish Uthama

unread,
Feb 27, 2009, 7:25:00 PM2/27/09
to

I guess the documentation could have been better :|

Consider the 3x3 MATLAB array:
1 2 3
4 5 6
7 8 9 --(1)

MATLAB stores this internaly in a linear fashion as such:

1 4 7 2 5 8 3 6 9 --(2)

This is FORTRAN-style ordering (also called row-major), i.e the column
elements are stored first.


Now consider a 2D C array (or how the netcdf library looks at a 2D array).
It would use C-Style or Column major ordering. If you consider the same 2D
matrix as shown above (13), then in C terms, it would appear in memory
linearly as:

1 2 3 4 5 6 7 8 9. --(3)


So this issue here is that MATLAB gives (2) to the C library and tells it
that it is a 3x3 array. The C library uses it own interpretation and
arrives at the following 2D array:
1 4 7
2 5 8
3 6 9 --(4)


You could try this out with a non-square shape and see how this means that
C sees a transpose of what M code sees.

To better understand this, write something other than 1's (like below).
Fool around with transposing the data before you write it and also with
switching the order of rows and columns.
rows = 4;
cols = 2;
myvar = [ 1 2 3 4;
5 6 7 8];


You have options:
1. Transpose the data in MATLAB before giving it to the C library. This is
not advicible for large data.
2. Do nothing if the data is expected to be both read and written to from
MATLAB (the round trip will cancel the effect)
3. If possible, change the behaviour of the other program which is
expected to read this data.

PS:

if you use:
rows = 4;
cols = 2;
myvar = [ 1 2 3 4;
5 6 7 8];
...
netcdf.putVar(ncid,imyvar,myvar') ;

ncdump will give you:

netcdf mynetcdffile {
dimensions:
Nrows = 4 ;


Ncols = 2 ;
variables:
double myvar(Ncols, Nrows) ;
data:

myvar =
1, 2, 3, 4,
5, 6, 7, 8 ;
}


HTH

0 new messages