From bug-octave-request at bevo dot che dot wisc dot edu Thu Jan 29 16:58:09 1998 Subject: row/column major ordering problem From: "John W. Eaton" To: Michael Hohn Cc: bug-octave at bevo dot che dot wisc dot edu Date: Thu, 29 Jan 1998 16:57:49 -0600 On 29-Jan-1998, Michael Hohn wrote: | This is a problem I thought fixed a long time ago, but here it it | again: | | I have a program writing files in matlab binary format, in either row | or column major order: | | ./a.out | Matrix: 2 by 2 | row 0: 0.846186767 0.468314366 | row 1: 0.236917463 0.65696803 | | | In matlab: | >> load foo.mat | >> mat | mat = | 0.8462 0.4683 | 0.2369 0.6570 | | | Octave, version 2.0.9 (sparc-sun-solaris2.5). | octave:1> load foo.mat | octave:2> mat | mat = | | 0.84619 0.23692 | 0.46831 0.65697 | | Oops!! Apparently, the order flag is ignored... | | Fix: | --- | (from an old message): | | The first thing written to a matlab binary file should be a long int | (4 bytes); it contains info of the form | | ... + 1000*?? + 100*ORDER + 10*?? + ... | | The ORDER flag is 0 for column major order, 1 for row major. I could never find this documented. All I ever found was a statement that the third digit was ignored. In any case, if the third digit is supposed to be a flag that says that the ordering is row or column major, here is a patch that should fix the problem. It's relative to 2.0.9.97, but I think it should work ok for 2.0.9 too. Thanks, jwe Thu Jan 29 16:25:46 1998 John W. Eaton * load-save.cc (read_mat_binary_data): Handle third digit of MOPT as flag indicating row or column major ordering. *** src/load-save.cc~ Wed Jan 28 00:41:27 1998 --- src/load-save.cc Thu Jan 29 16:52:47 1998 *************** *** 1235,1241 **** Matrix re; oct_mach_info::float_format flt_fmt = oct_mach_info::unknown; char *name = 0; ! int swap = 0, type = 0, prec = 0, mach = 0, dlen = 0; FOUR_BYTE_INT mopt, nr, nc, imag, len; --- 1235,1241 ---- Matrix re; oct_mach_info::float_format flt_fmt = oct_mach_info::unknown; char *name = 0; ! int swap = 0, type = 0, prec = 0, order = 0, mach = 0, dlen = 0; FOUR_BYTE_INT mopt, nr, nc, imag, len; *************** *** 1248,1258 **** return 0; } ! type = mopt % 10; // Full, sparse, etc. ! mopt /= 10; // Eliminate first digit. ! prec = mopt % 10; // double, float, int, etc. ! mopt /= 100; // Skip unused third digit too. ! mach = mopt % 10; // IEEE, VAX, etc. flt_fmt = mopt_digit_to_float_format (mach); --- 1248,1260 ---- return 0; } ! type = mopt % 10; // Full, sparse, etc. ! mopt /= 10; // Eliminate first digit. ! prec = mopt % 10; // double, float, int, etc. ! mopt /= 10; // Eliminate second digit. ! order = mopt % 10; // Row or column major ordering. ! mopt /= 10; // Eliminate third digit. ! mach = mopt % 10; // IEEE, VAX, etc. flt_fmt = mopt_digit_to_float_format (mach); *************** *** 1287,1292 **** --- 1289,1301 ---- if (dlen < 0) goto data_read_error; + if (order) + { + int tmp = nr; + nr = nc; + nc = tmp; + } + re.resize (nr, nc); read_mat_binary_data (is, re.fortran_vec (), prec, dlen, swap, flt_fmt); *************** *** 1315,1324 **** for (int i = 0; i < nr; i++) ctmp (i, j) = Complex (re (i, j), im (i, j)); ! tc = ctmp; } else ! tc = re; if (type == 1) tc = tc.convert_to_str (); --- 1324,1333 ---- for (int i = 0; i < nr; i++) ctmp (i, j) = Complex (re (i, j), im (i, j)); ! tc = order ? ctmp.transpose () : ctmp; } else ! tc = order ? re.transpose () : re; if (type == 1) tc = tc.convert_to_str ();