Mercurial > octave-nkf
annotate src/ls-mat4.cc @ 7961:a5d1e27ee1f4 ss-3-1-51
3.1.51 snapshot
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Tue, 22 Jul 2008 11:40:48 -0400 |
parents | 78eef61f75d5 |
children | 25bc2d31e1bf |
rev | line source |
---|---|
4634 | 1 /* |
2 | |
7017 | 3 Copyright (C) 1996, 1997, 2003, 2004, 2005, 2006, 2007 John W. Eaton |
4634 | 4 |
5 This file is part of Octave. | |
6 | |
7 Octave is free software; you can redistribute it and/or modify it | |
8 under the terms of the GNU General Public License as published by the | |
7016 | 9 Free Software Foundation; either version 3 of the License, or (at your |
10 option) any later version. | |
4634 | 11 |
12 Octave is distributed in the hope that it will be useful, but WITHOUT | |
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
7016 | 18 along with Octave; see the file COPYING. If not, see |
19 <http://www.gnu.org/licenses/>. | |
4634 | 20 |
21 */ | |
22 | |
23 #ifdef HAVE_CONFIG_H | |
24 #include <config.h> | |
25 #endif | |
26 | |
27 #include <cfloat> | |
28 #include <cstring> | |
29 #include <cctype> | |
30 | |
31 #include <fstream> | |
32 #include <iomanip> | |
33 #include <iostream> | |
34 #include <string> | |
4726 | 35 #include <vector> |
4634 | 36 |
37 #include "byte-swap.h" | |
38 #include "data-conv.h" | |
39 #include "file-ops.h" | |
40 #include "glob-match.h" | |
41 #include "lo-mappers.h" | |
42 #include "mach-info.h" | |
43 #include "oct-env.h" | |
44 #include "oct-time.h" | |
45 #include "quit.h" | |
46 #include "str-vec.h" | |
47 | |
48 #include "Cell.h" | |
49 #include "defun.h" | |
50 #include "error.h" | |
51 #include "gripes.h" | |
52 #include "load-save.h" | |
53 #include "oct-obj.h" | |
54 #include "oct-map.h" | |
55 #include "ov-cell.h" | |
56 #include "pager.h" | |
57 #include "pt-exp.h" | |
58 #include "sysdep.h" | |
59 #include "unwind-prot.h" | |
60 #include "utils.h" | |
61 #include "variables.h" | |
62 #include "version.h" | |
63 #include "dMatrix.h" | |
7918
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
64 #include "dSparse.h" |
4634 | 65 |
66 #include "ls-mat4.h" | |
67 | |
68 // Read LEN elements of data from IS in the format specified by | |
69 // PRECISION, placing the result in DATA. If SWAP is TRUE, swap | |
70 // the bytes of each element before copying to DATA. FLT_FMT | |
71 // specifies the format of the data if we are reading floating point | |
72 // numbers. | |
73 | |
74 static void | |
75 read_mat_binary_data (std::istream& is, double *data, int precision, | |
76 int len, bool swap, | |
77 oct_mach_info::float_format flt_fmt) | |
78 { | |
79 switch (precision) | |
80 { | |
81 case 0: | |
82 read_doubles (is, data, LS_DOUBLE, len, swap, flt_fmt); | |
83 break; | |
84 | |
85 case 1: | |
86 read_doubles (is, data, LS_FLOAT, len, swap, flt_fmt); | |
87 break; | |
88 | |
89 case 2: | |
90 read_doubles (is, data, LS_INT, len, swap, flt_fmt); | |
91 break; | |
92 | |
93 case 3: | |
94 read_doubles (is, data, LS_SHORT, len, swap, flt_fmt); | |
95 break; | |
96 | |
97 case 4: | |
98 read_doubles (is, data, LS_U_SHORT, len, swap, flt_fmt); | |
99 break; | |
100 | |
101 case 5: | |
102 read_doubles (is, data, LS_U_CHAR, len, swap, flt_fmt); | |
103 break; | |
104 | |
105 default: | |
106 break; | |
107 } | |
108 } | |
109 | |
110 int | |
5828 | 111 read_mat_file_header (std::istream& is, bool& swap, int32_t& mopt, |
112 int32_t& nr, int32_t& nc, | |
113 int32_t& imag, int32_t& len, | |
4634 | 114 int quiet) |
115 { | |
116 swap = false; | |
117 | |
118 // We expect to fail here, at the beginning of a record, so not | |
119 // being able to read another mopt value should not result in an | |
120 // error. | |
121 | |
5760 | 122 is.read (reinterpret_cast<char *> (&mopt), 4); |
4634 | 123 if (! is) |
124 return 1; | |
125 | |
5760 | 126 if (! is.read (reinterpret_cast<char *> (&nr), 4)) |
4634 | 127 goto data_read_error; |
128 | |
5760 | 129 if (! is.read (reinterpret_cast<char *> (&nc), 4)) |
4634 | 130 goto data_read_error; |
131 | |
5760 | 132 if (! is.read (reinterpret_cast<char *> (&imag), 4)) |
4634 | 133 goto data_read_error; |
134 | |
5760 | 135 if (! is.read (reinterpret_cast<char *> (&len), 4)) |
4634 | 136 goto data_read_error; |
137 | |
138 // If mopt is nonzero and the byte order is swapped, mopt will be | |
139 // bigger than we expect, so we swap bytes. | |
140 // | |
141 // If mopt is zero, it means the file was written on a little endian | |
142 // machine, and we only need to swap if we are running on a big endian | |
143 // machine. | |
144 // | |
145 // Gag me. | |
146 | |
147 if (oct_mach_info::words_big_endian () && mopt == 0) | |
148 swap = true; | |
149 | |
150 // mopt is signed, therefore byte swap may result in negative value. | |
151 | |
152 if (mopt > 9999 || mopt < 0) | |
153 swap = true; | |
154 | |
155 if (swap) | |
156 { | |
4944 | 157 swap_bytes<4> (&mopt); |
158 swap_bytes<4> (&nr); | |
159 swap_bytes<4> (&nc); | |
160 swap_bytes<4> (&imag); | |
161 swap_bytes<4> (&len); | |
4634 | 162 } |
163 | |
164 if (mopt > 9999 || mopt < 0 || imag > 1 || imag < 0) | |
165 { | |
166 if (! quiet) | |
167 error ("load: can't read binary file"); | |
168 return -1; | |
169 } | |
170 | |
171 return 0; | |
172 | |
173 data_read_error: | |
174 return -1; | |
175 } | |
176 | |
177 // We don't just use a cast here, because we need to be able to detect | |
178 // possible errors. | |
179 | |
180 oct_mach_info::float_format | |
181 mopt_digit_to_float_format (int mach) | |
182 { | |
183 oct_mach_info::float_format flt_fmt = oct_mach_info::flt_fmt_unknown; | |
184 | |
185 switch (mach) | |
186 { | |
187 case 0: | |
188 flt_fmt = oct_mach_info::flt_fmt_ieee_little_endian; | |
189 break; | |
190 | |
191 case 1: | |
192 flt_fmt = oct_mach_info::flt_fmt_ieee_big_endian; | |
193 break; | |
194 | |
195 case 2: | |
196 flt_fmt = oct_mach_info::flt_fmt_vax_d; | |
197 break; | |
198 | |
199 case 3: | |
200 flt_fmt = oct_mach_info::flt_fmt_vax_g; | |
201 break; | |
202 | |
203 case 4: | |
204 flt_fmt = oct_mach_info::flt_fmt_cray; | |
205 break; | |
206 | |
207 default: | |
208 flt_fmt = oct_mach_info::flt_fmt_unknown; | |
209 break; | |
210 } | |
211 | |
212 return flt_fmt; | |
213 } | |
214 | |
215 int | |
216 float_format_to_mopt_digit (oct_mach_info::float_format flt_fmt) | |
217 { | |
218 int retval = -1; | |
219 | |
220 switch (flt_fmt) | |
221 { | |
222 case oct_mach_info::flt_fmt_ieee_little_endian: | |
223 retval = 0; | |
224 break; | |
225 | |
226 case oct_mach_info::flt_fmt_ieee_big_endian: | |
227 retval = 1; | |
228 break; | |
229 | |
230 case oct_mach_info::flt_fmt_vax_d: | |
231 retval = 2; | |
232 break; | |
233 | |
234 case oct_mach_info::flt_fmt_vax_g: | |
235 retval = 3; | |
236 break; | |
237 | |
238 case oct_mach_info::flt_fmt_cray: | |
239 retval = 4; | |
240 break; | |
241 | |
242 default: | |
243 break; | |
244 } | |
245 | |
246 return retval; | |
247 } | |
248 | |
249 // Extract one value (scalar, matrix, string, etc.) from stream IS and | |
250 // place it in TC, returning the name of the variable. | |
251 // | |
252 // The data is expected to be in Matlab version 4 .mat format, though | |
253 // not all the features of that format are supported. | |
254 // | |
255 // FILENAME is used for error messages. | |
256 // | |
257 // This format provides no way to tag the data as global. | |
258 | |
259 std::string | |
260 read_mat_binary_data (std::istream& is, const std::string& filename, | |
261 octave_value& tc) | |
262 { | |
263 std::string retval; | |
264 | |
265 // These are initialized here instead of closer to where they are | |
266 // first used to avoid errors from gcc about goto crossing | |
267 // initialization of variable. | |
268 | |
269 Matrix re; | |
270 oct_mach_info::float_format flt_fmt = oct_mach_info::flt_fmt_unknown; | |
271 bool swap = false; | |
272 int type = 0; | |
273 int prec = 0; | |
274 int order = 0; | |
275 int mach = 0; | |
276 int dlen = 0; | |
277 | |
5828 | 278 int32_t mopt, nr, nc, imag, len; |
4634 | 279 |
280 int err = read_mat_file_header (is, swap, mopt, nr, nc, imag, len); | |
281 if (err) | |
282 { | |
283 if (err < 0) | |
284 goto data_read_error; | |
285 else | |
286 return retval; | |
287 } | |
288 | |
289 type = mopt % 10; // Full, sparse, etc. | |
290 mopt /= 10; // Eliminate first digit. | |
291 prec = mopt % 10; // double, float, int, etc. | |
292 mopt /= 10; // Eliminate second digit. | |
293 order = mopt % 10; // Row or column major ordering. | |
294 mopt /= 10; // Eliminate third digit. | |
295 mach = mopt % 10; // IEEE, VAX, etc. | |
296 | |
297 flt_fmt = mopt_digit_to_float_format (mach); | |
298 | |
299 if (flt_fmt == oct_mach_info::flt_fmt_unknown) | |
300 { | |
301 error ("load: unrecognized binary format!"); | |
302 return retval; | |
303 } | |
304 | |
305 if (imag && type == 1) | |
306 { | |
307 error ("load: encountered complex matrix with string flag set!"); | |
308 return retval; | |
309 } | |
310 | |
311 // LEN includes the terminating character, and the file is also | |
312 // supposed to include it, but apparently not all files do. Either | |
313 // way, I think this should work. | |
314 | |
315 { | |
316 OCTAVE_LOCAL_BUFFER (char, name, len+1); | |
317 name[len] = '\0'; | |
5760 | 318 if (! is.read (name, len)) |
4634 | 319 goto data_read_error; |
320 retval = name; | |
321 | |
322 dlen = nr * nc; | |
323 if (dlen < 0) | |
324 goto data_read_error; | |
325 | |
326 if (order) | |
327 { | |
5275 | 328 octave_idx_type tmp = nr; |
4634 | 329 nr = nc; |
330 nc = tmp; | |
331 } | |
332 | |
7918
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
333 if (type == 2) |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
334 { |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
335 if (nc == 4) |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
336 { |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
337 octave_idx_type nr_new, nc_new; |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
338 Array<Complex> data (dim_vector (1, nr - 1)); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
339 Array<octave_idx_type> c (dim_vector (1, nr - 1)); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
340 Array<octave_idx_type> r (dim_vector (1, nr - 1)); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
341 OCTAVE_LOCAL_BUFFER (double, dtmp, nr); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
342 OCTAVE_LOCAL_BUFFER (double, ctmp, nr); |
4634 | 343 |
7918
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
344 read_mat_binary_data (is, dtmp, prec, nr, swap, flt_fmt); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
345 for (octave_idx_type i = 0; i < nr - 1; i++) |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
346 r.xelem(i) = dtmp[i] - 1; |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
347 nr_new = dtmp[nr - 1]; |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
348 read_mat_binary_data (is, dtmp, prec, nr, swap, flt_fmt); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
349 for (octave_idx_type i = 0; i < nr - 1; i++) |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
350 c.xelem(i) = dtmp[i] - 1; |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
351 nc_new = dtmp[nr - 1]; |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
352 read_mat_binary_data (is, dtmp, prec, nr - 1, swap, flt_fmt); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
353 read_mat_binary_data (is, ctmp, prec, 1, swap, flt_fmt); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
354 read_mat_binary_data (is, ctmp, prec, nr - 1, swap, flt_fmt); |
4634 | 355 |
7918
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
356 for (octave_idx_type i = 0; i < nr - 1; i++) |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
357 data.xelem(i) = Complex (dtmp[i], ctmp[i]); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
358 read_mat_binary_data (is, ctmp, prec, 1, swap, flt_fmt); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
359 |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
360 SparseComplexMatrix smc = SparseComplexMatrix (data, r, c, |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
361 nr_new, nc_new); |
4634 | 362 |
7918
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
363 tc = order ? smc.transpose () : smc; |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
364 } |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
365 else |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
366 { |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
367 octave_idx_type nr_new, nc_new; |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
368 Array<double> data (dim_vector (1, nr - 1)); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
369 Array<octave_idx_type> c (dim_vector (1, nr - 1)); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
370 Array<octave_idx_type> r (dim_vector (1, nr - 1)); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
371 OCTAVE_LOCAL_BUFFER (double, dtmp, nr); |
4634 | 372 |
7918
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
373 read_mat_binary_data (is, dtmp, prec, nr, swap, flt_fmt); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
374 for (octave_idx_type i = 0; i < nr - 1; i++) |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
375 r.xelem(i) = dtmp[i] - 1; |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
376 nr_new = dtmp[nr - 1]; |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
377 read_mat_binary_data (is, dtmp, prec, nr, swap, flt_fmt); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
378 for (octave_idx_type i = 0; i < nr - 1; i++) |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
379 c.xelem(i) = dtmp[i] - 1; |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
380 nc_new = dtmp[nr - 1]; |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
381 read_mat_binary_data (is, data.fortran_vec (), prec, nr - 1, swap, flt_fmt); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
382 read_mat_binary_data (is, dtmp, prec, 1, swap, flt_fmt); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
383 |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
384 SparseMatrix sm = SparseMatrix (data, r, c, nr_new, nc_new); |
4634 | 385 |
7918
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
386 tc = order ? sm.transpose () : sm; |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
387 } |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
388 } |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
389 else |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
390 { |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
391 re.resize (nr, nc); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
392 |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
393 read_mat_binary_data (is, re.fortran_vec (), prec, dlen, swap, flt_fmt); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
394 |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
395 if (! is || error_state) |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
396 { |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
397 error ("load: reading matrix data for `%s'", name); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
398 goto data_read_error; |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
399 } |
4634 | 400 |
7918
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
401 if (imag) |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
402 { |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
403 Matrix im (nr, nc); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
404 |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
405 read_mat_binary_data (is, im.fortran_vec (), prec, dlen, swap, |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
406 flt_fmt); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
407 |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
408 if (! is || error_state) |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
409 { |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
410 error ("load: reading imaginary matrix data for `%s'", name); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
411 goto data_read_error; |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
412 } |
4634 | 413 |
7918
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
414 ComplexMatrix ctmp (nr, nc); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
415 |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
416 for (octave_idx_type j = 0; j < nc; j++) |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
417 for (octave_idx_type i = 0; i < nr; i++) |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
418 ctmp (i, j) = Complex (re (i, j), im (i, j)); |
4634 | 419 |
7918
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
420 tc = order ? ctmp.transpose () : ctmp; |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
421 } |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
422 else |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
423 tc = order ? re.transpose () : re; |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
424 |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
425 if (type == 1) |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
426 tc = tc.convert_to_str (false, true, '\''); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
427 } |
4634 | 428 |
429 return retval; | |
430 } | |
431 | |
432 data_read_error: | |
433 error ("load: trouble reading binary file `%s'", filename.c_str ()); | |
434 return retval; | |
435 } | |
436 | |
437 // Save the data from TC along with the corresponding NAME on stream OS | |
438 // in the MatLab version 4 binary format. | |
439 | |
440 bool | |
441 save_mat_binary_data (std::ostream& os, const octave_value& tc, | |
442 const std::string& name) | |
443 { | |
5828 | 444 int32_t mopt = 0; |
4634 | 445 |
7918
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
446 mopt += tc.is_sparse_type () ? 2 : tc.is_string () ? 1 : 0; |
4634 | 447 |
448 oct_mach_info::float_format flt_fmt = | |
449 oct_mach_info::native_float_format ();; | |
450 | |
451 mopt += 1000 * float_format_to_mopt_digit (flt_fmt); | |
452 | |
5760 | 453 os.write (reinterpret_cast<char *> (&mopt), 4); |
4634 | 454 |
7918
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
455 octave_idx_type len; |
5828 | 456 int32_t nr = tc.rows (); |
4634 | 457 |
5828 | 458 int32_t nc = tc.columns (); |
7918
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
459 |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
460 if (tc.is_sparse_type ()) |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
461 { |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
462 len = tc.nnz (); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
463 uint32_t nnz = len + 1; |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
464 os.write (reinterpret_cast<char *> (&nnz), 4); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
465 |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
466 uint32_t iscmplx = tc.is_complex_type () ? 4 : 3; |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
467 os.write (reinterpret_cast<char *> (&iscmplx), 4); |
4634 | 468 |
7918
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
469 uint32_t tmp = 0; |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
470 os.write (reinterpret_cast<char *> (&tmp), 4); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
471 } |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
472 else |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
473 { |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
474 os.write (reinterpret_cast<char *> (&nr), 4); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
475 os.write (reinterpret_cast<char *> (&nc), 4); |
4634 | 476 |
7918
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
477 int32_t imag = tc.is_complex_type () ? 1 : 0; |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
478 os.write (reinterpret_cast<char *> (&imag), 4); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
479 |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
480 len = nr * nc; |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
481 } |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
482 |
4634 | 483 |
484 // LEN includes the terminating character, and the file is also | |
485 // supposed to include it. | |
486 | |
5828 | 487 int32_t name_len = name.length () + 1; |
4634 | 488 |
5760 | 489 os.write (reinterpret_cast<char *> (&name_len), 4); |
4634 | 490 os << name << '\0'; |
491 | |
492 if (tc.is_string ()) | |
493 { | |
494 unwind_protect::begin_frame ("save_mat_binary_data"); | |
495 | |
496 charMatrix chm = tc.char_matrix_value (); | |
497 | |
5275 | 498 octave_idx_type nrow = chm.rows (); |
499 octave_idx_type ncol = chm.cols (); | |
4634 | 500 |
501 OCTAVE_LOCAL_BUFFER (double, buf, ncol*nrow); | |
502 | |
5275 | 503 for (octave_idx_type i = 0; i < nrow; i++) |
4634 | 504 { |
505 std::string tstr = chm.row_as_string (i); | |
506 const char *s = tstr.data (); | |
507 | |
5275 | 508 for (octave_idx_type j = 0; j < ncol; j++) |
4634 | 509 buf[j*nrow+i] = static_cast<double> (*s++ & 0x00FF); |
510 } | |
5760 | 511 os.write (reinterpret_cast<char *> (buf), nrow*ncol*sizeof(double)); |
4634 | 512 |
513 unwind_protect::run_frame ("save_mat_binary_data"); | |
514 } | |
515 else if (tc.is_range ()) | |
516 { | |
517 Range r = tc.range_value (); | |
518 double base = r.base (); | |
519 double inc = r.inc (); | |
5275 | 520 octave_idx_type nel = r.nelem (); |
521 for (octave_idx_type i = 0; i < nel; i++) | |
4634 | 522 { |
523 double x = base + i * inc; | |
5760 | 524 os.write (reinterpret_cast<char *> (&x), 8); |
4634 | 525 } |
526 } | |
527 else if (tc.is_real_scalar ()) | |
528 { | |
529 double tmp = tc.double_value (); | |
5760 | 530 os.write (reinterpret_cast<char *> (&tmp), 8); |
4634 | 531 } |
7918
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
532 else if (tc.is_sparse_type ()) |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
533 { |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
534 double ds; |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
535 OCTAVE_LOCAL_BUFFER (double, dtmp, len); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
536 if (tc.is_complex_matrix ()) |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
537 { |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
538 SparseComplexMatrix m = tc.sparse_complex_matrix_value (); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
539 |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
540 for (octave_idx_type i = 0; i < len; i++) |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
541 dtmp [i] = m.ridx(i) + 1; |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
542 os.write (reinterpret_cast<const char *> (dtmp), 8 * len); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
543 ds = nr; |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
544 os.write (reinterpret_cast<const char *> (&ds), 8); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
545 |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
546 octave_idx_type ii = 0; |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
547 for (octave_idx_type j = 0; j < nc; j++) |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
548 for (octave_idx_type i = m.cidx(j); i < m.cidx(j+1); i++) |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
549 dtmp[ii++] = j + 1; |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
550 os.write (reinterpret_cast<const char *> (dtmp), 8 * len); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
551 ds = nc; |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
552 os.write (reinterpret_cast<const char *> (&ds), 8); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
553 |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
554 for (octave_idx_type i = 0; i < len; i++) |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
555 dtmp [i] = std::real (m.data(i)); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
556 os.write (reinterpret_cast<const char *> (dtmp), 8 * len); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
557 ds = 0.; |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
558 os.write (reinterpret_cast<const char *> (&ds), 8); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
559 |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
560 for (octave_idx_type i = 0; i < len; i++) |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
561 dtmp [i] = std::imag (m.data(i)); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
562 os.write (reinterpret_cast<const char *> (dtmp), 8 * len); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
563 os.write (reinterpret_cast<const char *> (&ds), 8); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
564 } |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
565 else |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
566 { |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
567 SparseMatrix m = tc.sparse_matrix_value (); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
568 |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
569 for (octave_idx_type i = 0; i < len; i++) |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
570 dtmp [i] = m.ridx(i) + 1; |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
571 os.write (reinterpret_cast<const char *> (dtmp), 8 * len); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
572 ds = nr; |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
573 os.write (reinterpret_cast<const char *> (&ds), 8); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
574 |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
575 octave_idx_type ii = 0; |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
576 for (octave_idx_type j = 0; j < nc; j++) |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
577 for (octave_idx_type i = m.cidx(j); i < m.cidx(j+1); i++) |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
578 dtmp[ii++] = j + 1; |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
579 os.write (reinterpret_cast<const char *> (dtmp), 8 * len); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
580 ds = nc; |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
581 os.write (reinterpret_cast<const char *> (&ds), 8); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
582 |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
583 os.write (reinterpret_cast<const char *> (m.data ()), 8 * len); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
584 ds = 0.; |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
585 os.write (reinterpret_cast<const char *> (&ds), 8); |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
586 } |
78eef61f75d5
Add matlab V4 sparse matrixload/save
David Bateman <dbateman@free.fr>
parents:
7336
diff
changeset
|
587 } |
4634 | 588 else if (tc.is_real_matrix ()) |
589 { | |
590 Matrix m = tc.matrix_value (); | |
5760 | 591 os.write (reinterpret_cast<const char *> (m.data ()), 8 * len); |
4634 | 592 } |
593 else if (tc.is_complex_scalar ()) | |
594 { | |
595 Complex tmp = tc.complex_value (); | |
5760 | 596 os.write (reinterpret_cast<char *> (&tmp), 16); |
4634 | 597 } |
598 else if (tc.is_complex_matrix ()) | |
599 { | |
600 ComplexMatrix m_cmplx = tc.complex_matrix_value (); | |
601 Matrix m = ::real (m_cmplx); | |
5760 | 602 os.write (reinterpret_cast<const char *> (m.data ()), 8 * len); |
4634 | 603 m = ::imag (m_cmplx); |
5760 | 604 os.write (reinterpret_cast<const char *> (m.data ()), 8 * len); |
4634 | 605 } |
606 else | |
607 gripe_wrong_type_arg ("save", tc, false); | |
608 | |
609 return os; | |
610 } | |
611 | |
612 /* | |
613 ;;; Local Variables: *** | |
614 ;;; mode: C++ *** | |
615 ;;; End: *** | |
616 */ |