Chris@49
|
1 // Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
|
Chris@49
|
2 // Copyright (C) 2008-2012 Conrad Sanderson
|
Chris@49
|
3 // Copyright (C) 2009-2010 Ian Cullinan
|
Chris@49
|
4 // Copyright (C) 2012 Ryan Curtin
|
Chris@49
|
5 // Copyright (C) 2013 Szabolcs Horvat
|
Chris@49
|
6 //
|
Chris@49
|
7 // This Source Code Form is subject to the terms of the Mozilla Public
|
Chris@49
|
8 // License, v. 2.0. If a copy of the MPL was not distributed with this
|
Chris@49
|
9 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
Chris@49
|
10
|
Chris@49
|
11
|
Chris@49
|
12 //! \addtogroup diskio
|
Chris@49
|
13 //! @{
|
Chris@49
|
14
|
Chris@49
|
15
|
Chris@49
|
16 //! Generate the first line of the header used for saving matrices in text format.
|
Chris@49
|
17 //! Format: "ARMA_MAT_TXT_ABXYZ".
|
Chris@49
|
18 //! A is one of: I (for integral types) or F (for floating point types).
|
Chris@49
|
19 //! B is one of: U (for unsigned types), S (for signed types), N (for not appliable) or C (for complex types).
|
Chris@49
|
20 //! XYZ specifies the width of each element in terms of bytes, e.g. "008" indicates eight bytes.
|
Chris@49
|
21 template<typename eT>
|
Chris@49
|
22 inline
|
Chris@49
|
23 std::string
|
Chris@49
|
24 diskio::gen_txt_header(const Mat<eT>& x)
|
Chris@49
|
25 {
|
Chris@49
|
26 arma_type_check(( is_supported_elem_type<eT>::value == false ));
|
Chris@49
|
27
|
Chris@49
|
28 arma_ignore(x);
|
Chris@49
|
29
|
Chris@49
|
30 if(is_u8<eT>::value == true)
|
Chris@49
|
31 {
|
Chris@49
|
32 return std::string("ARMA_MAT_TXT_IU001");
|
Chris@49
|
33 }
|
Chris@49
|
34 else
|
Chris@49
|
35 if(is_s8<eT>::value == true)
|
Chris@49
|
36 {
|
Chris@49
|
37 return std::string("ARMA_MAT_TXT_IS001");
|
Chris@49
|
38 }
|
Chris@49
|
39 else
|
Chris@49
|
40 if(is_u16<eT>::value == true)
|
Chris@49
|
41 {
|
Chris@49
|
42 return std::string("ARMA_MAT_TXT_IU002");
|
Chris@49
|
43 }
|
Chris@49
|
44 else
|
Chris@49
|
45 if(is_s16<eT>::value == true)
|
Chris@49
|
46 {
|
Chris@49
|
47 return std::string("ARMA_MAT_TXT_IS002");
|
Chris@49
|
48 }
|
Chris@49
|
49 else
|
Chris@49
|
50 if(is_u32<eT>::value == true)
|
Chris@49
|
51 {
|
Chris@49
|
52 return std::string("ARMA_MAT_TXT_IU004");
|
Chris@49
|
53 }
|
Chris@49
|
54 else
|
Chris@49
|
55 if(is_s32<eT>::value == true)
|
Chris@49
|
56 {
|
Chris@49
|
57 return std::string("ARMA_MAT_TXT_IS004");
|
Chris@49
|
58 }
|
Chris@49
|
59 #if defined(ARMA_USE_U64S64)
|
Chris@49
|
60 else
|
Chris@49
|
61 if(is_u64<eT>::value == true)
|
Chris@49
|
62 {
|
Chris@49
|
63 return std::string("ARMA_MAT_TXT_IU008");
|
Chris@49
|
64 }
|
Chris@49
|
65 else
|
Chris@49
|
66 if(is_s64<eT>::value == true)
|
Chris@49
|
67 {
|
Chris@49
|
68 return std::string("ARMA_MAT_TXT_IS008");
|
Chris@49
|
69 }
|
Chris@49
|
70 #endif
|
Chris@49
|
71 #if defined(ARMA_ALLOW_LONG)
|
Chris@49
|
72 else
|
Chris@49
|
73 if(is_ulng_t_32<eT>::value == true)
|
Chris@49
|
74 {
|
Chris@49
|
75 return std::string("ARMA_MAT_TXT_IU004");
|
Chris@49
|
76 }
|
Chris@49
|
77 else
|
Chris@49
|
78 if(is_slng_t_32<eT>::value == true)
|
Chris@49
|
79 {
|
Chris@49
|
80 return std::string("ARMA_MAT_TXT_IS004");
|
Chris@49
|
81 }
|
Chris@49
|
82 else
|
Chris@49
|
83 if(is_ulng_t_64<eT>::value == true)
|
Chris@49
|
84 {
|
Chris@49
|
85 return std::string("ARMA_MAT_TXT_IU008");
|
Chris@49
|
86 }
|
Chris@49
|
87 else
|
Chris@49
|
88 if(is_slng_t_64<eT>::value == true)
|
Chris@49
|
89 {
|
Chris@49
|
90 return std::string("ARMA_MAT_TXT_IS008");
|
Chris@49
|
91 }
|
Chris@49
|
92 #endif
|
Chris@49
|
93 else
|
Chris@49
|
94 if(is_float<eT>::value == true)
|
Chris@49
|
95 {
|
Chris@49
|
96 return std::string("ARMA_MAT_TXT_FN004");
|
Chris@49
|
97 }
|
Chris@49
|
98 else
|
Chris@49
|
99 if(is_double<eT>::value == true)
|
Chris@49
|
100 {
|
Chris@49
|
101 return std::string("ARMA_MAT_TXT_FN008");
|
Chris@49
|
102 }
|
Chris@49
|
103 else
|
Chris@49
|
104 if(is_complex_float<eT>::value == true)
|
Chris@49
|
105 {
|
Chris@49
|
106 return std::string("ARMA_MAT_TXT_FC008");
|
Chris@49
|
107 }
|
Chris@49
|
108 else
|
Chris@49
|
109 if(is_complex_double<eT>::value == true)
|
Chris@49
|
110 {
|
Chris@49
|
111 return std::string("ARMA_MAT_TXT_FC016");
|
Chris@49
|
112 }
|
Chris@49
|
113 else
|
Chris@49
|
114 {
|
Chris@49
|
115 return std::string();
|
Chris@49
|
116 }
|
Chris@49
|
117
|
Chris@49
|
118 }
|
Chris@49
|
119
|
Chris@49
|
120
|
Chris@49
|
121
|
Chris@49
|
122 //! Generate the first line of the header used for saving matrices in binary format.
|
Chris@49
|
123 //! Format: "ARMA_MAT_BIN_ABXYZ".
|
Chris@49
|
124 //! A is one of: I (for integral types) or F (for floating point types).
|
Chris@49
|
125 //! B is one of: U (for unsigned types), S (for signed types), N (for not appliable) or C (for complex types).
|
Chris@49
|
126 //! XYZ specifies the width of each element in terms of bytes, e.g. "008" indicates eight bytes.
|
Chris@49
|
127 template<typename eT>
|
Chris@49
|
128 inline
|
Chris@49
|
129 std::string
|
Chris@49
|
130 diskio::gen_bin_header(const Mat<eT>& x)
|
Chris@49
|
131 {
|
Chris@49
|
132 arma_type_check(( is_supported_elem_type<eT>::value == false ));
|
Chris@49
|
133
|
Chris@49
|
134 arma_ignore(x);
|
Chris@49
|
135
|
Chris@49
|
136 if(is_u8<eT>::value == true)
|
Chris@49
|
137 {
|
Chris@49
|
138 return std::string("ARMA_MAT_BIN_IU001");
|
Chris@49
|
139 }
|
Chris@49
|
140 else
|
Chris@49
|
141 if(is_s8<eT>::value == true)
|
Chris@49
|
142 {
|
Chris@49
|
143 return std::string("ARMA_MAT_BIN_IS001");
|
Chris@49
|
144 }
|
Chris@49
|
145 else
|
Chris@49
|
146 if(is_u16<eT>::value == true)
|
Chris@49
|
147 {
|
Chris@49
|
148 return std::string("ARMA_MAT_BIN_IU002");
|
Chris@49
|
149 }
|
Chris@49
|
150 else
|
Chris@49
|
151 if(is_s16<eT>::value == true)
|
Chris@49
|
152 {
|
Chris@49
|
153 return std::string("ARMA_MAT_BIN_IS002");
|
Chris@49
|
154 }
|
Chris@49
|
155 else
|
Chris@49
|
156 if(is_u32<eT>::value == true)
|
Chris@49
|
157 {
|
Chris@49
|
158 return std::string("ARMA_MAT_BIN_IU004");
|
Chris@49
|
159 }
|
Chris@49
|
160 else
|
Chris@49
|
161 if(is_s32<eT>::value == true)
|
Chris@49
|
162 {
|
Chris@49
|
163 return std::string("ARMA_MAT_BIN_IS004");
|
Chris@49
|
164 }
|
Chris@49
|
165 #if defined(ARMA_USE_U64S64)
|
Chris@49
|
166 else
|
Chris@49
|
167 if(is_u64<eT>::value == true)
|
Chris@49
|
168 {
|
Chris@49
|
169 return std::string("ARMA_MAT_BIN_IU008");
|
Chris@49
|
170 }
|
Chris@49
|
171 else
|
Chris@49
|
172 if(is_s64<eT>::value == true)
|
Chris@49
|
173 {
|
Chris@49
|
174 return std::string("ARMA_MAT_BIN_IS008");
|
Chris@49
|
175 }
|
Chris@49
|
176 #endif
|
Chris@49
|
177 #if defined(ARMA_ALLOW_LONG)
|
Chris@49
|
178 else
|
Chris@49
|
179 if(is_ulng_t_32<eT>::value == true)
|
Chris@49
|
180 {
|
Chris@49
|
181 return std::string("ARMA_MAT_BIN_IU004");
|
Chris@49
|
182 }
|
Chris@49
|
183 else
|
Chris@49
|
184 if(is_slng_t_32<eT>::value == true)
|
Chris@49
|
185 {
|
Chris@49
|
186 return std::string("ARMA_MAT_BIN_IS004");
|
Chris@49
|
187 }
|
Chris@49
|
188 else
|
Chris@49
|
189 if(is_ulng_t_64<eT>::value == true)
|
Chris@49
|
190 {
|
Chris@49
|
191 return std::string("ARMA_MAT_BIN_IU008");
|
Chris@49
|
192 }
|
Chris@49
|
193 else
|
Chris@49
|
194 if(is_slng_t_64<eT>::value == true)
|
Chris@49
|
195 {
|
Chris@49
|
196 return std::string("ARMA_MAT_BIN_IS008");
|
Chris@49
|
197 }
|
Chris@49
|
198 #endif
|
Chris@49
|
199 else
|
Chris@49
|
200 if(is_float<eT>::value == true)
|
Chris@49
|
201 {
|
Chris@49
|
202 return std::string("ARMA_MAT_BIN_FN004");
|
Chris@49
|
203 }
|
Chris@49
|
204 else
|
Chris@49
|
205 if(is_double<eT>::value == true)
|
Chris@49
|
206 {
|
Chris@49
|
207 return std::string("ARMA_MAT_BIN_FN008");
|
Chris@49
|
208 }
|
Chris@49
|
209 else
|
Chris@49
|
210 if(is_complex_float<eT>::value == true)
|
Chris@49
|
211 {
|
Chris@49
|
212 return std::string("ARMA_MAT_BIN_FC008");
|
Chris@49
|
213 }
|
Chris@49
|
214 else
|
Chris@49
|
215 if(is_complex_double<eT>::value == true)
|
Chris@49
|
216 {
|
Chris@49
|
217 return std::string("ARMA_MAT_BIN_FC016");
|
Chris@49
|
218 }
|
Chris@49
|
219 else
|
Chris@49
|
220 {
|
Chris@49
|
221 return std::string();
|
Chris@49
|
222 }
|
Chris@49
|
223
|
Chris@49
|
224 }
|
Chris@49
|
225
|
Chris@49
|
226
|
Chris@49
|
227
|
Chris@49
|
228 //! Generate the first line of the header used for saving matrices in binary format.
|
Chris@49
|
229 //! Format: "ARMA_SPM_BIN_ABXYZ".
|
Chris@49
|
230 //! A is one of: I (for integral types) or F (for floating point types).
|
Chris@49
|
231 //! B is one of: U (for unsigned types), S (for signed types), N (for not appliable) or C (for complex types).
|
Chris@49
|
232 //! XYZ specifies the width of each element in terms of bytes, e.g. "008" indicates eight bytes.
|
Chris@49
|
233 template<typename eT>
|
Chris@49
|
234 inline
|
Chris@49
|
235 std::string
|
Chris@49
|
236 diskio::gen_bin_header(const SpMat<eT>& x)
|
Chris@49
|
237 {
|
Chris@49
|
238 arma_type_check(( is_supported_elem_type<eT>::value == false ));
|
Chris@49
|
239
|
Chris@49
|
240 arma_ignore(x);
|
Chris@49
|
241
|
Chris@49
|
242 if(is_u8<eT>::value == true)
|
Chris@49
|
243 {
|
Chris@49
|
244 return std::string("ARMA_SPM_BIN_IU001");
|
Chris@49
|
245 }
|
Chris@49
|
246 else
|
Chris@49
|
247 if(is_s8<eT>::value == true)
|
Chris@49
|
248 {
|
Chris@49
|
249 return std::string("ARMA_SPM_BIN_IS001");
|
Chris@49
|
250 }
|
Chris@49
|
251 else
|
Chris@49
|
252 if(is_u16<eT>::value == true)
|
Chris@49
|
253 {
|
Chris@49
|
254 return std::string("ARMA_SPM_BIN_IU002");
|
Chris@49
|
255 }
|
Chris@49
|
256 else
|
Chris@49
|
257 if(is_s16<eT>::value == true)
|
Chris@49
|
258 {
|
Chris@49
|
259 return std::string("ARMA_SPM_BIN_IS002");
|
Chris@49
|
260 }
|
Chris@49
|
261 else
|
Chris@49
|
262 if(is_u32<eT>::value == true)
|
Chris@49
|
263 {
|
Chris@49
|
264 return std::string("ARMA_SPM_BIN_IU004");
|
Chris@49
|
265 }
|
Chris@49
|
266 else
|
Chris@49
|
267 if(is_s32<eT>::value == true)
|
Chris@49
|
268 {
|
Chris@49
|
269 return std::string("ARMA_SPM_BIN_IS004");
|
Chris@49
|
270 }
|
Chris@49
|
271 #if defined(ARMA_USE_U64S64)
|
Chris@49
|
272 else
|
Chris@49
|
273 if(is_u64<eT>::value == true)
|
Chris@49
|
274 {
|
Chris@49
|
275 return std::string("ARMA_SPM_BIN_IU008");
|
Chris@49
|
276 }
|
Chris@49
|
277 else
|
Chris@49
|
278 if(is_s64<eT>::value == true)
|
Chris@49
|
279 {
|
Chris@49
|
280 return std::string("ARMA_SPM_BIN_IS008");
|
Chris@49
|
281 }
|
Chris@49
|
282 #endif
|
Chris@49
|
283 #if defined(ARMA_ALLOW_LONG)
|
Chris@49
|
284 else
|
Chris@49
|
285 if(is_ulng_t_32<eT>::value == true)
|
Chris@49
|
286 {
|
Chris@49
|
287 return std::string("ARMA_SPM_BIN_IU004");
|
Chris@49
|
288 }
|
Chris@49
|
289 else
|
Chris@49
|
290 if(is_slng_t_32<eT>::value == true)
|
Chris@49
|
291 {
|
Chris@49
|
292 return std::string("ARMA_SPM_BIN_IS004");
|
Chris@49
|
293 }
|
Chris@49
|
294 else
|
Chris@49
|
295 if(is_ulng_t_64<eT>::value == true)
|
Chris@49
|
296 {
|
Chris@49
|
297 return std::string("ARMA_SPM_BIN_IU008");
|
Chris@49
|
298 }
|
Chris@49
|
299 else
|
Chris@49
|
300 if(is_slng_t_64<eT>::value == true)
|
Chris@49
|
301 {
|
Chris@49
|
302 return std::string("ARMA_SPM_BIN_IS008");
|
Chris@49
|
303 }
|
Chris@49
|
304 #endif
|
Chris@49
|
305 else
|
Chris@49
|
306 if(is_float<eT>::value == true)
|
Chris@49
|
307 {
|
Chris@49
|
308 return std::string("ARMA_SPM_BIN_FN004");
|
Chris@49
|
309 }
|
Chris@49
|
310 else
|
Chris@49
|
311 if(is_double<eT>::value == true)
|
Chris@49
|
312 {
|
Chris@49
|
313 return std::string("ARMA_SPM_BIN_FN008");
|
Chris@49
|
314 }
|
Chris@49
|
315 else
|
Chris@49
|
316 if(is_complex_float<eT>::value == true)
|
Chris@49
|
317 {
|
Chris@49
|
318 return std::string("ARMA_SPM_BIN_FC008");
|
Chris@49
|
319 }
|
Chris@49
|
320 else
|
Chris@49
|
321 if(is_complex_double<eT>::value == true)
|
Chris@49
|
322 {
|
Chris@49
|
323 return std::string("ARMA_SPM_BIN_FC016");
|
Chris@49
|
324 }
|
Chris@49
|
325 else
|
Chris@49
|
326 {
|
Chris@49
|
327 return std::string();
|
Chris@49
|
328 }
|
Chris@49
|
329
|
Chris@49
|
330 }
|
Chris@49
|
331
|
Chris@49
|
332
|
Chris@49
|
333 //! Generate the first line of the header used for saving cubes in text format.
|
Chris@49
|
334 //! Format: "ARMA_CUB_TXT_ABXYZ".
|
Chris@49
|
335 //! A is one of: I (for integral types) or F (for floating point types).
|
Chris@49
|
336 //! B is one of: U (for unsigned types), S (for signed types), N (for not appliable) or C (for complex types).
|
Chris@49
|
337 //! XYZ specifies the width of each element in terms of bytes, e.g. "008" indicates eight bytes.
|
Chris@49
|
338 template<typename eT>
|
Chris@49
|
339 inline
|
Chris@49
|
340 std::string
|
Chris@49
|
341 diskio::gen_txt_header(const Cube<eT>& x)
|
Chris@49
|
342 {
|
Chris@49
|
343 arma_type_check(( is_supported_elem_type<eT>::value == false ));
|
Chris@49
|
344
|
Chris@49
|
345 arma_ignore(x);
|
Chris@49
|
346
|
Chris@49
|
347 if(is_u8<eT>::value == true)
|
Chris@49
|
348 {
|
Chris@49
|
349 return std::string("ARMA_CUB_TXT_IU001");
|
Chris@49
|
350 }
|
Chris@49
|
351 else
|
Chris@49
|
352 if(is_s8<eT>::value == true)
|
Chris@49
|
353 {
|
Chris@49
|
354 return std::string("ARMA_CUB_TXT_IS001");
|
Chris@49
|
355 }
|
Chris@49
|
356 else
|
Chris@49
|
357 if(is_u16<eT>::value == true)
|
Chris@49
|
358 {
|
Chris@49
|
359 return std::string("ARMA_CUB_TXT_IU002");
|
Chris@49
|
360 }
|
Chris@49
|
361 else
|
Chris@49
|
362 if(is_s16<eT>::value == true)
|
Chris@49
|
363 {
|
Chris@49
|
364 return std::string("ARMA_CUB_TXT_IS002");
|
Chris@49
|
365 }
|
Chris@49
|
366 else
|
Chris@49
|
367 if(is_u32<eT>::value == true)
|
Chris@49
|
368 {
|
Chris@49
|
369 return std::string("ARMA_CUB_TXT_IU004");
|
Chris@49
|
370 }
|
Chris@49
|
371 else
|
Chris@49
|
372 if(is_s32<eT>::value == true)
|
Chris@49
|
373 {
|
Chris@49
|
374 return std::string("ARMA_CUB_TXT_IS004");
|
Chris@49
|
375 }
|
Chris@49
|
376 #if defined(ARMA_USE_U64S64)
|
Chris@49
|
377 else
|
Chris@49
|
378 if(is_u64<eT>::value == true)
|
Chris@49
|
379 {
|
Chris@49
|
380 return std::string("ARMA_CUB_TXT_IU008");
|
Chris@49
|
381 }
|
Chris@49
|
382 else
|
Chris@49
|
383 if(is_s64<eT>::value == true)
|
Chris@49
|
384 {
|
Chris@49
|
385 return std::string("ARMA_CUB_TXT_IS008");
|
Chris@49
|
386 }
|
Chris@49
|
387 #endif
|
Chris@49
|
388 #if defined(ARMA_ALLOW_LONG)
|
Chris@49
|
389 else
|
Chris@49
|
390 if(is_ulng_t_32<eT>::value == true)
|
Chris@49
|
391 {
|
Chris@49
|
392 return std::string("ARMA_CUB_TXT_IU004");
|
Chris@49
|
393 }
|
Chris@49
|
394 else
|
Chris@49
|
395 if(is_slng_t_32<eT>::value == true)
|
Chris@49
|
396 {
|
Chris@49
|
397 return std::string("ARMA_CUB_TXT_IS004");
|
Chris@49
|
398 }
|
Chris@49
|
399 else
|
Chris@49
|
400 if(is_ulng_t_64<eT>::value == true)
|
Chris@49
|
401 {
|
Chris@49
|
402 return std::string("ARMA_CUB_TXT_IU008");
|
Chris@49
|
403 }
|
Chris@49
|
404 else
|
Chris@49
|
405 if(is_slng_t_64<eT>::value == true)
|
Chris@49
|
406 {
|
Chris@49
|
407 return std::string("ARMA_CUB_TXT_IS008");
|
Chris@49
|
408 }
|
Chris@49
|
409 #endif
|
Chris@49
|
410 else
|
Chris@49
|
411 if(is_float<eT>::value == true)
|
Chris@49
|
412 {
|
Chris@49
|
413 return std::string("ARMA_CUB_TXT_FN004");
|
Chris@49
|
414 }
|
Chris@49
|
415 else
|
Chris@49
|
416 if(is_double<eT>::value == true)
|
Chris@49
|
417 {
|
Chris@49
|
418 return std::string("ARMA_CUB_TXT_FN008");
|
Chris@49
|
419 }
|
Chris@49
|
420 else
|
Chris@49
|
421 if(is_complex_float<eT>::value == true)
|
Chris@49
|
422 {
|
Chris@49
|
423 return std::string("ARMA_CUB_TXT_FC008");
|
Chris@49
|
424 }
|
Chris@49
|
425 else
|
Chris@49
|
426 if(is_complex_double<eT>::value == true)
|
Chris@49
|
427 {
|
Chris@49
|
428 return std::string("ARMA_CUB_TXT_FC016");
|
Chris@49
|
429 }
|
Chris@49
|
430 else
|
Chris@49
|
431 {
|
Chris@49
|
432 return std::string();
|
Chris@49
|
433 }
|
Chris@49
|
434
|
Chris@49
|
435 }
|
Chris@49
|
436
|
Chris@49
|
437
|
Chris@49
|
438
|
Chris@49
|
439 //! Generate the first line of the header used for saving cubes in binary format.
|
Chris@49
|
440 //! Format: "ARMA_CUB_BIN_ABXYZ".
|
Chris@49
|
441 //! A is one of: I (for integral types) or F (for floating point types).
|
Chris@49
|
442 //! B is one of: U (for unsigned types), S (for signed types), N (for not appliable) or C (for complex types).
|
Chris@49
|
443 //! XYZ specifies the width of each element in terms of bytes, e.g. "008" indicates eight bytes.
|
Chris@49
|
444 template<typename eT>
|
Chris@49
|
445 inline
|
Chris@49
|
446 std::string
|
Chris@49
|
447 diskio::gen_bin_header(const Cube<eT>& x)
|
Chris@49
|
448 {
|
Chris@49
|
449 arma_type_check(( is_supported_elem_type<eT>::value == false ));
|
Chris@49
|
450
|
Chris@49
|
451 arma_ignore(x);
|
Chris@49
|
452
|
Chris@49
|
453 if(is_u8<eT>::value == true)
|
Chris@49
|
454 {
|
Chris@49
|
455 return std::string("ARMA_CUB_BIN_IU001");
|
Chris@49
|
456 }
|
Chris@49
|
457 else
|
Chris@49
|
458 if(is_s8<eT>::value == true)
|
Chris@49
|
459 {
|
Chris@49
|
460 return std::string("ARMA_CUB_BIN_IS001");
|
Chris@49
|
461 }
|
Chris@49
|
462 else
|
Chris@49
|
463 if(is_u16<eT>::value == true)
|
Chris@49
|
464 {
|
Chris@49
|
465 return std::string("ARMA_CUB_BIN_IU002");
|
Chris@49
|
466 }
|
Chris@49
|
467 else
|
Chris@49
|
468 if(is_s16<eT>::value == true)
|
Chris@49
|
469 {
|
Chris@49
|
470 return std::string("ARMA_CUB_BIN_IS002");
|
Chris@49
|
471 }
|
Chris@49
|
472 else
|
Chris@49
|
473 if(is_u32<eT>::value == true)
|
Chris@49
|
474 {
|
Chris@49
|
475 return std::string("ARMA_CUB_BIN_IU004");
|
Chris@49
|
476 }
|
Chris@49
|
477 else
|
Chris@49
|
478 if(is_s32<eT>::value == true)
|
Chris@49
|
479 {
|
Chris@49
|
480 return std::string("ARMA_CUB_BIN_IS004");
|
Chris@49
|
481 }
|
Chris@49
|
482 #if defined(ARMA_USE_U64S64)
|
Chris@49
|
483 else
|
Chris@49
|
484 if(is_u64<eT>::value == true)
|
Chris@49
|
485 {
|
Chris@49
|
486 return std::string("ARMA_CUB_BIN_IU008");
|
Chris@49
|
487 }
|
Chris@49
|
488 else
|
Chris@49
|
489 if(is_s64<eT>::value == true)
|
Chris@49
|
490 {
|
Chris@49
|
491 return std::string("ARMA_CUB_BIN_IS008");
|
Chris@49
|
492 }
|
Chris@49
|
493 #endif
|
Chris@49
|
494 #if defined(ARMA_ALLOW_LONG)
|
Chris@49
|
495 else
|
Chris@49
|
496 if(is_ulng_t_32<eT>::value == true)
|
Chris@49
|
497 {
|
Chris@49
|
498 return std::string("ARMA_CUB_BIN_IU004");
|
Chris@49
|
499 }
|
Chris@49
|
500 else
|
Chris@49
|
501 if(is_slng_t_32<eT>::value == true)
|
Chris@49
|
502 {
|
Chris@49
|
503 return std::string("ARMA_CUB_BIN_IS004");
|
Chris@49
|
504 }
|
Chris@49
|
505 else
|
Chris@49
|
506 if(is_ulng_t_64<eT>::value == true)
|
Chris@49
|
507 {
|
Chris@49
|
508 return std::string("ARMA_CUB_BIN_IU008");
|
Chris@49
|
509 }
|
Chris@49
|
510 else
|
Chris@49
|
511 if(is_slng_t_64<eT>::value == true)
|
Chris@49
|
512 {
|
Chris@49
|
513 return std::string("ARMA_CUB_BIN_IS008");
|
Chris@49
|
514 }
|
Chris@49
|
515 #endif
|
Chris@49
|
516 else
|
Chris@49
|
517 if(is_float<eT>::value == true)
|
Chris@49
|
518 {
|
Chris@49
|
519 return std::string("ARMA_CUB_BIN_FN004");
|
Chris@49
|
520 }
|
Chris@49
|
521 else
|
Chris@49
|
522 if(is_double<eT>::value == true)
|
Chris@49
|
523 {
|
Chris@49
|
524 return std::string("ARMA_CUB_BIN_FN008");
|
Chris@49
|
525 }
|
Chris@49
|
526 else
|
Chris@49
|
527 if(is_complex_float<eT>::value == true)
|
Chris@49
|
528 {
|
Chris@49
|
529 return std::string("ARMA_CUB_BIN_FC008");
|
Chris@49
|
530 }
|
Chris@49
|
531 else
|
Chris@49
|
532 if(is_complex_double<eT>::value == true)
|
Chris@49
|
533 {
|
Chris@49
|
534 return std::string("ARMA_CUB_BIN_FC016");
|
Chris@49
|
535 }
|
Chris@49
|
536 else
|
Chris@49
|
537 {
|
Chris@49
|
538 return std::string();
|
Chris@49
|
539 }
|
Chris@49
|
540
|
Chris@49
|
541 }
|
Chris@49
|
542
|
Chris@49
|
543
|
Chris@49
|
544
|
Chris@49
|
545 inline
|
Chris@49
|
546 file_type
|
Chris@49
|
547 diskio::guess_file_type(std::istream& f)
|
Chris@49
|
548 {
|
Chris@49
|
549 arma_extra_debug_sigprint();
|
Chris@49
|
550
|
Chris@49
|
551 f.clear();
|
Chris@49
|
552 const std::fstream::pos_type pos1 = f.tellg();
|
Chris@49
|
553
|
Chris@49
|
554 f.clear();
|
Chris@49
|
555 f.seekg(0, ios::end);
|
Chris@49
|
556
|
Chris@49
|
557 f.clear();
|
Chris@49
|
558 const std::fstream::pos_type pos2 = f.tellg();
|
Chris@49
|
559
|
Chris@49
|
560 const uword N = ( (pos1 >= 0) && (pos2 >= 0) ) ? uword(pos2 - pos1) : 0;
|
Chris@49
|
561
|
Chris@49
|
562 f.clear();
|
Chris@49
|
563 f.seekg(pos1);
|
Chris@49
|
564
|
Chris@49
|
565 podarray<unsigned char> data(N);
|
Chris@49
|
566
|
Chris@49
|
567 unsigned char* ptr = data.memptr();
|
Chris@49
|
568
|
Chris@49
|
569 f.clear();
|
Chris@49
|
570 f.read( reinterpret_cast<char*>(ptr), std::streamsize(N) );
|
Chris@49
|
571
|
Chris@49
|
572 const bool load_okay = f.good();
|
Chris@49
|
573
|
Chris@49
|
574 f.clear();
|
Chris@49
|
575 f.seekg(pos1);
|
Chris@49
|
576
|
Chris@49
|
577 bool has_binary = false;
|
Chris@49
|
578 bool has_comma = false;
|
Chris@49
|
579 bool has_bracket = false;
|
Chris@49
|
580
|
Chris@49
|
581 if(load_okay == true)
|
Chris@49
|
582 {
|
Chris@49
|
583 uword i = 0;
|
Chris@49
|
584 uword j = (N >= 2) ? 1 : 0;
|
Chris@49
|
585
|
Chris@49
|
586 for(; j<N; i+=2, j+=2)
|
Chris@49
|
587 {
|
Chris@49
|
588 const unsigned char val_i = ptr[i];
|
Chris@49
|
589 const unsigned char val_j = ptr[j];
|
Chris@49
|
590
|
Chris@49
|
591 // the range checking can be made more elaborate
|
Chris@49
|
592 if( ((val_i <= 8) || (val_i >= 123)) || ((val_j <= 8) || (val_j >= 123)) )
|
Chris@49
|
593 {
|
Chris@49
|
594 has_binary = true;
|
Chris@49
|
595 break;
|
Chris@49
|
596 }
|
Chris@49
|
597
|
Chris@49
|
598 if( (val_i == ',') || (val_j == ',') )
|
Chris@49
|
599 {
|
Chris@49
|
600 has_comma = true;
|
Chris@49
|
601 }
|
Chris@49
|
602
|
Chris@49
|
603 if( (val_i == '(') || (val_j == '(') || (val_i == ')') || (val_j == ')') )
|
Chris@49
|
604 {
|
Chris@49
|
605 has_bracket = true;
|
Chris@49
|
606 }
|
Chris@49
|
607 }
|
Chris@49
|
608 }
|
Chris@49
|
609 else
|
Chris@49
|
610 {
|
Chris@49
|
611 return file_type_unknown;
|
Chris@49
|
612 }
|
Chris@49
|
613
|
Chris@49
|
614 if(has_binary)
|
Chris@49
|
615 {
|
Chris@49
|
616 return raw_binary;
|
Chris@49
|
617 }
|
Chris@49
|
618
|
Chris@49
|
619 if(has_comma && (has_bracket == false))
|
Chris@49
|
620 {
|
Chris@49
|
621 return csv_ascii;
|
Chris@49
|
622 }
|
Chris@49
|
623
|
Chris@49
|
624 return raw_ascii;
|
Chris@49
|
625 }
|
Chris@49
|
626
|
Chris@49
|
627
|
Chris@49
|
628
|
Chris@49
|
629 inline
|
Chris@49
|
630 char
|
Chris@49
|
631 diskio::conv_to_hex_char(const u8 x)
|
Chris@49
|
632 {
|
Chris@49
|
633 char out;
|
Chris@49
|
634
|
Chris@49
|
635 switch(x)
|
Chris@49
|
636 {
|
Chris@49
|
637 case 0: out = '0'; break;
|
Chris@49
|
638 case 1: out = '1'; break;
|
Chris@49
|
639 case 2: out = '2'; break;
|
Chris@49
|
640 case 3: out = '3'; break;
|
Chris@49
|
641 case 4: out = '4'; break;
|
Chris@49
|
642 case 5: out = '5'; break;
|
Chris@49
|
643 case 6: out = '6'; break;
|
Chris@49
|
644 case 7: out = '7'; break;
|
Chris@49
|
645 case 8: out = '8'; break;
|
Chris@49
|
646 case 9: out = '9'; break;
|
Chris@49
|
647 case 10: out = 'a'; break;
|
Chris@49
|
648 case 11: out = 'b'; break;
|
Chris@49
|
649 case 12: out = 'c'; break;
|
Chris@49
|
650 case 13: out = 'd'; break;
|
Chris@49
|
651 case 14: out = 'e'; break;
|
Chris@49
|
652 case 15: out = 'f'; break;
|
Chris@49
|
653 default: out = '-'; break;
|
Chris@49
|
654 }
|
Chris@49
|
655
|
Chris@49
|
656 return out;
|
Chris@49
|
657 }
|
Chris@49
|
658
|
Chris@49
|
659
|
Chris@49
|
660
|
Chris@49
|
661 inline
|
Chris@49
|
662 void
|
Chris@49
|
663 diskio::conv_to_hex(char* out, const u8 x)
|
Chris@49
|
664 {
|
Chris@49
|
665 const u8 a = x / 16;
|
Chris@49
|
666 const u8 b = x - 16*a;
|
Chris@49
|
667
|
Chris@49
|
668 out[0] = conv_to_hex_char(a);
|
Chris@49
|
669 out[1] = conv_to_hex_char(b);
|
Chris@49
|
670 }
|
Chris@49
|
671
|
Chris@49
|
672
|
Chris@49
|
673
|
Chris@49
|
674 //! Append a quasi-random string to the given filename.
|
Chris@49
|
675 //! The rand() function is deliberately not used,
|
Chris@49
|
676 //! as rand() has an internal state that changes
|
Chris@49
|
677 //! from call to call. Such states should not be
|
Chris@49
|
678 //! modified in scientific applications, where the
|
Chris@49
|
679 //! results should be reproducable and not affected
|
Chris@49
|
680 //! by saving data.
|
Chris@49
|
681 inline
|
Chris@49
|
682 std::string
|
Chris@49
|
683 diskio::gen_tmp_name(const std::string& x)
|
Chris@49
|
684 {
|
Chris@49
|
685 const std::string* ptr_x = &x;
|
Chris@49
|
686 const u8* ptr_ptr_x = reinterpret_cast<const u8*>(&ptr_x);
|
Chris@49
|
687
|
Chris@49
|
688 const char* extra = ".tmp_";
|
Chris@49
|
689 const uword extra_size = 5;
|
Chris@49
|
690
|
Chris@49
|
691 const uword tmp_size = 2*sizeof(u8*) + 2*2;
|
Chris@49
|
692 char tmp[tmp_size];
|
Chris@49
|
693
|
Chris@49
|
694 uword char_count = 0;
|
Chris@49
|
695
|
Chris@49
|
696 for(uword i=0; i<sizeof(u8*); ++i)
|
Chris@49
|
697 {
|
Chris@49
|
698 conv_to_hex(&tmp[char_count], ptr_ptr_x[i]);
|
Chris@49
|
699 char_count += 2;
|
Chris@49
|
700 }
|
Chris@49
|
701
|
Chris@49
|
702 const uword x_size = static_cast<uword>(x.size());
|
Chris@49
|
703 u8 sum = 0;
|
Chris@49
|
704
|
Chris@49
|
705 for(uword i=0; i<x_size; ++i)
|
Chris@49
|
706 {
|
Chris@49
|
707 sum += u8(x[i]);
|
Chris@49
|
708 }
|
Chris@49
|
709
|
Chris@49
|
710 conv_to_hex(&tmp[char_count], sum);
|
Chris@49
|
711 char_count += 2;
|
Chris@49
|
712
|
Chris@49
|
713 conv_to_hex(&tmp[char_count], u8(x_size));
|
Chris@49
|
714
|
Chris@49
|
715
|
Chris@49
|
716 std::string out;
|
Chris@49
|
717 out.resize(x_size + extra_size + tmp_size);
|
Chris@49
|
718
|
Chris@49
|
719
|
Chris@49
|
720 for(uword i=0; i<x_size; ++i)
|
Chris@49
|
721 {
|
Chris@49
|
722 out[i] = x[i];
|
Chris@49
|
723 }
|
Chris@49
|
724
|
Chris@49
|
725 for(uword i=0; i<extra_size; ++i)
|
Chris@49
|
726 {
|
Chris@49
|
727 out[x_size + i] = extra[i];
|
Chris@49
|
728 }
|
Chris@49
|
729
|
Chris@49
|
730 for(uword i=0; i<tmp_size; ++i)
|
Chris@49
|
731 {
|
Chris@49
|
732 out[x_size + extra_size + i] = tmp[i];
|
Chris@49
|
733 }
|
Chris@49
|
734
|
Chris@49
|
735 return out;
|
Chris@49
|
736 }
|
Chris@49
|
737
|
Chris@49
|
738
|
Chris@49
|
739
|
Chris@49
|
740 //! Safely rename a file.
|
Chris@49
|
741 //! Before renaming, test if we can write to the final file.
|
Chris@49
|
742 //! This should prevent:
|
Chris@49
|
743 //! (i) overwriting files that are write protected,
|
Chris@49
|
744 //! (ii) overwriting directories.
|
Chris@49
|
745 inline
|
Chris@49
|
746 bool
|
Chris@49
|
747 diskio::safe_rename(const std::string& old_name, const std::string& new_name)
|
Chris@49
|
748 {
|
Chris@49
|
749 std::fstream f(new_name.c_str(), std::fstream::out | std::fstream::app);
|
Chris@49
|
750 f.put(' ');
|
Chris@49
|
751
|
Chris@49
|
752 bool save_okay = f.good();
|
Chris@49
|
753 f.close();
|
Chris@49
|
754
|
Chris@49
|
755 if(save_okay == true)
|
Chris@49
|
756 {
|
Chris@49
|
757 std::remove(new_name.c_str());
|
Chris@49
|
758
|
Chris@49
|
759 const int mv_result = std::rename(old_name.c_str(), new_name.c_str());
|
Chris@49
|
760
|
Chris@49
|
761 save_okay = (mv_result == 0);
|
Chris@49
|
762 }
|
Chris@49
|
763
|
Chris@49
|
764 return save_okay;
|
Chris@49
|
765 }
|
Chris@49
|
766
|
Chris@49
|
767
|
Chris@49
|
768
|
Chris@49
|
769 template<typename eT>
|
Chris@49
|
770 inline
|
Chris@49
|
771 bool
|
Chris@49
|
772 diskio::convert_naninf(eT& val, const std::string& token)
|
Chris@49
|
773 {
|
Chris@49
|
774 // see if the token represents a NaN or Inf
|
Chris@49
|
775
|
Chris@49
|
776 if( (token.length() == 3) || (token.length() == 4) )
|
Chris@49
|
777 {
|
Chris@49
|
778 const bool neg = (token[0] == '-');
|
Chris@49
|
779 const bool pos = (token[0] == '+');
|
Chris@49
|
780
|
Chris@49
|
781 const size_t offset = ( (neg || pos) && (token.length() == 4) ) ? 1 : 0;
|
Chris@49
|
782
|
Chris@49
|
783 const std::string token2 = token.substr(offset, 3);
|
Chris@49
|
784
|
Chris@49
|
785 if( (token2 == "inf") || (token2 == "Inf") || (token2 == "INF") )
|
Chris@49
|
786 {
|
Chris@49
|
787 val = neg ? -(Datum<eT>::inf) : Datum<eT>::inf;
|
Chris@49
|
788
|
Chris@49
|
789 return true;
|
Chris@49
|
790 }
|
Chris@49
|
791 else
|
Chris@49
|
792 if( (token2 == "nan") || (token2 == "Nan") || (token2 == "NaN") || (token2 == "NAN") )
|
Chris@49
|
793 {
|
Chris@49
|
794 val = neg ? -(Datum<eT>::nan) : Datum<eT>::nan;
|
Chris@49
|
795
|
Chris@49
|
796 return true;
|
Chris@49
|
797 }
|
Chris@49
|
798 }
|
Chris@49
|
799
|
Chris@49
|
800 return false;
|
Chris@49
|
801 }
|
Chris@49
|
802
|
Chris@49
|
803
|
Chris@49
|
804
|
Chris@49
|
805 template<typename T>
|
Chris@49
|
806 inline
|
Chris@49
|
807 bool
|
Chris@49
|
808 diskio::convert_naninf(std::complex<T>& val, const std::string& token)
|
Chris@49
|
809 {
|
Chris@49
|
810 if( token.length() >= 5 )
|
Chris@49
|
811 {
|
Chris@49
|
812 std::stringstream ss( token.substr(1, token.length()-2) ); // strip '(' at the start and ')' at the end
|
Chris@49
|
813
|
Chris@49
|
814 std::string token_real;
|
Chris@49
|
815 std::string token_imag;
|
Chris@49
|
816
|
Chris@49
|
817 std::getline(ss, token_real, ',');
|
Chris@49
|
818 std::getline(ss, token_imag);
|
Chris@49
|
819
|
Chris@49
|
820 std::stringstream ss_real(token_real);
|
Chris@49
|
821 std::stringstream ss_imag(token_imag);
|
Chris@49
|
822
|
Chris@49
|
823 T val_real = T(0);
|
Chris@49
|
824 T val_imag = T(0);
|
Chris@49
|
825
|
Chris@49
|
826 ss_real >> val_real;
|
Chris@49
|
827 ss_imag >> val_imag;
|
Chris@49
|
828
|
Chris@49
|
829 bool success_real = true;
|
Chris@49
|
830 bool success_imag = true;
|
Chris@49
|
831
|
Chris@49
|
832 if(ss_real.fail() == true)
|
Chris@49
|
833 {
|
Chris@49
|
834 success_real = diskio::convert_naninf( val_real, token_real );
|
Chris@49
|
835 }
|
Chris@49
|
836
|
Chris@49
|
837 if(ss_imag.fail() == true)
|
Chris@49
|
838 {
|
Chris@49
|
839 success_imag = diskio::convert_naninf( val_imag, token_imag );
|
Chris@49
|
840 }
|
Chris@49
|
841
|
Chris@49
|
842 val = std::complex<T>(val_real, val_imag);
|
Chris@49
|
843
|
Chris@49
|
844 return (success_real && success_imag);
|
Chris@49
|
845 }
|
Chris@49
|
846
|
Chris@49
|
847 return false;
|
Chris@49
|
848 }
|
Chris@49
|
849
|
Chris@49
|
850
|
Chris@49
|
851
|
Chris@49
|
852 //! Save a matrix as raw text (no header, human readable).
|
Chris@49
|
853 //! Matrices can be loaded in Matlab and Octave, as long as they don't have complex elements.
|
Chris@49
|
854 template<typename eT>
|
Chris@49
|
855 inline
|
Chris@49
|
856 bool
|
Chris@49
|
857 diskio::save_raw_ascii(const Mat<eT>& x, const std::string& final_name)
|
Chris@49
|
858 {
|
Chris@49
|
859 arma_extra_debug_sigprint();
|
Chris@49
|
860
|
Chris@49
|
861 const std::string tmp_name = diskio::gen_tmp_name(final_name);
|
Chris@49
|
862
|
Chris@49
|
863 std::fstream f(tmp_name.c_str(), std::fstream::out);
|
Chris@49
|
864
|
Chris@49
|
865 bool save_okay = f.is_open();
|
Chris@49
|
866
|
Chris@49
|
867 if(save_okay == true)
|
Chris@49
|
868 {
|
Chris@49
|
869 save_okay = diskio::save_raw_ascii(x, f);
|
Chris@49
|
870
|
Chris@49
|
871 f.flush();
|
Chris@49
|
872 f.close();
|
Chris@49
|
873
|
Chris@49
|
874 if(save_okay == true)
|
Chris@49
|
875 {
|
Chris@49
|
876 save_okay = diskio::safe_rename(tmp_name, final_name);
|
Chris@49
|
877 }
|
Chris@49
|
878 }
|
Chris@49
|
879
|
Chris@49
|
880 return save_okay;
|
Chris@49
|
881 }
|
Chris@49
|
882
|
Chris@49
|
883
|
Chris@49
|
884
|
Chris@49
|
885 //! Save a matrix as raw text (no header, human readable).
|
Chris@49
|
886 //! Matrices can be loaded in Matlab and Octave, as long as they don't have complex elements.
|
Chris@49
|
887 template<typename eT>
|
Chris@49
|
888 inline
|
Chris@49
|
889 bool
|
Chris@49
|
890 diskio::save_raw_ascii(const Mat<eT>& x, std::ostream& f)
|
Chris@49
|
891 {
|
Chris@49
|
892 arma_extra_debug_sigprint();
|
Chris@49
|
893
|
Chris@49
|
894 uword cell_width;
|
Chris@49
|
895
|
Chris@49
|
896 // TODO: need sane values for complex numbers
|
Chris@49
|
897
|
Chris@49
|
898 if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
|
Chris@49
|
899 {
|
Chris@49
|
900 f.setf(ios::scientific);
|
Chris@49
|
901 f.precision(12);
|
Chris@49
|
902 cell_width = 20;
|
Chris@49
|
903 }
|
Chris@49
|
904
|
Chris@49
|
905 for(uword row=0; row < x.n_rows; ++row)
|
Chris@49
|
906 {
|
Chris@49
|
907 for(uword col=0; col < x.n_cols; ++col)
|
Chris@49
|
908 {
|
Chris@49
|
909 f.put(' ');
|
Chris@49
|
910
|
Chris@49
|
911 if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
|
Chris@49
|
912 {
|
Chris@49
|
913 f.width(cell_width);
|
Chris@49
|
914 }
|
Chris@49
|
915
|
Chris@49
|
916 f << x.at(row,col);
|
Chris@49
|
917 }
|
Chris@49
|
918
|
Chris@49
|
919 f.put('\n');
|
Chris@49
|
920 }
|
Chris@49
|
921
|
Chris@49
|
922 return f.good();
|
Chris@49
|
923 }
|
Chris@49
|
924
|
Chris@49
|
925
|
Chris@49
|
926
|
Chris@49
|
927 //! Save a matrix as raw binary (no header)
|
Chris@49
|
928 template<typename eT>
|
Chris@49
|
929 inline
|
Chris@49
|
930 bool
|
Chris@49
|
931 diskio::save_raw_binary(const Mat<eT>& x, const std::string& final_name)
|
Chris@49
|
932 {
|
Chris@49
|
933 arma_extra_debug_sigprint();
|
Chris@49
|
934
|
Chris@49
|
935 const std::string tmp_name = diskio::gen_tmp_name(final_name);
|
Chris@49
|
936
|
Chris@49
|
937 std::ofstream f(tmp_name.c_str(), std::fstream::binary);
|
Chris@49
|
938
|
Chris@49
|
939 bool save_okay = f.is_open();
|
Chris@49
|
940
|
Chris@49
|
941 if(save_okay == true)
|
Chris@49
|
942 {
|
Chris@49
|
943 save_okay = diskio::save_raw_binary(x, f);
|
Chris@49
|
944
|
Chris@49
|
945 f.flush();
|
Chris@49
|
946 f.close();
|
Chris@49
|
947
|
Chris@49
|
948 if(save_okay == true)
|
Chris@49
|
949 {
|
Chris@49
|
950 save_okay = diskio::safe_rename(tmp_name, final_name);
|
Chris@49
|
951 }
|
Chris@49
|
952 }
|
Chris@49
|
953
|
Chris@49
|
954 return save_okay;
|
Chris@49
|
955 }
|
Chris@49
|
956
|
Chris@49
|
957
|
Chris@49
|
958
|
Chris@49
|
959 template<typename eT>
|
Chris@49
|
960 inline
|
Chris@49
|
961 bool
|
Chris@49
|
962 diskio::save_raw_binary(const Mat<eT>& x, std::ostream& f)
|
Chris@49
|
963 {
|
Chris@49
|
964 arma_extra_debug_sigprint();
|
Chris@49
|
965
|
Chris@49
|
966 f.write( reinterpret_cast<const char*>(x.mem), std::streamsize(x.n_elem*sizeof(eT)) );
|
Chris@49
|
967
|
Chris@49
|
968 return f.good();
|
Chris@49
|
969 }
|
Chris@49
|
970
|
Chris@49
|
971
|
Chris@49
|
972
|
Chris@49
|
973 //! Save a matrix in text format (human readable),
|
Chris@49
|
974 //! with a header that indicates the matrix type as well as its dimensions
|
Chris@49
|
975 template<typename eT>
|
Chris@49
|
976 inline
|
Chris@49
|
977 bool
|
Chris@49
|
978 diskio::save_arma_ascii(const Mat<eT>& x, const std::string& final_name)
|
Chris@49
|
979 {
|
Chris@49
|
980 arma_extra_debug_sigprint();
|
Chris@49
|
981
|
Chris@49
|
982 const std::string tmp_name = diskio::gen_tmp_name(final_name);
|
Chris@49
|
983
|
Chris@49
|
984 std::ofstream f(tmp_name.c_str());
|
Chris@49
|
985
|
Chris@49
|
986 bool save_okay = f.is_open();
|
Chris@49
|
987
|
Chris@49
|
988 if(save_okay == true)
|
Chris@49
|
989 {
|
Chris@49
|
990 save_okay = diskio::save_arma_ascii(x, f);
|
Chris@49
|
991
|
Chris@49
|
992 f.flush();
|
Chris@49
|
993 f.close();
|
Chris@49
|
994
|
Chris@49
|
995 if(save_okay == true)
|
Chris@49
|
996 {
|
Chris@49
|
997 save_okay = diskio::safe_rename(tmp_name, final_name);
|
Chris@49
|
998 }
|
Chris@49
|
999 }
|
Chris@49
|
1000
|
Chris@49
|
1001 return save_okay;
|
Chris@49
|
1002 }
|
Chris@49
|
1003
|
Chris@49
|
1004
|
Chris@49
|
1005
|
Chris@49
|
1006 //! Save a matrix in text format (human readable),
|
Chris@49
|
1007 //! with a header that indicates the matrix type as well as its dimensions
|
Chris@49
|
1008 template<typename eT>
|
Chris@49
|
1009 inline
|
Chris@49
|
1010 bool
|
Chris@49
|
1011 diskio::save_arma_ascii(const Mat<eT>& x, std::ostream& f)
|
Chris@49
|
1012 {
|
Chris@49
|
1013 arma_extra_debug_sigprint();
|
Chris@49
|
1014
|
Chris@49
|
1015 const ios::fmtflags orig_flags = f.flags();
|
Chris@49
|
1016
|
Chris@49
|
1017 f << diskio::gen_txt_header(x) << '\n';
|
Chris@49
|
1018 f << x.n_rows << ' ' << x.n_cols << '\n';
|
Chris@49
|
1019
|
Chris@49
|
1020 uword cell_width;
|
Chris@49
|
1021
|
Chris@49
|
1022 // TODO: need sane values for complex numbers
|
Chris@49
|
1023
|
Chris@49
|
1024 if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
|
Chris@49
|
1025 {
|
Chris@49
|
1026 f.setf(ios::scientific);
|
Chris@49
|
1027 f.precision(12);
|
Chris@49
|
1028 cell_width = 20;
|
Chris@49
|
1029 }
|
Chris@49
|
1030
|
Chris@49
|
1031 for(uword row=0; row < x.n_rows; ++row)
|
Chris@49
|
1032 {
|
Chris@49
|
1033 for(uword col=0; col < x.n_cols; ++col)
|
Chris@49
|
1034 {
|
Chris@49
|
1035 f.put(' ');
|
Chris@49
|
1036
|
Chris@49
|
1037 if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
|
Chris@49
|
1038 {
|
Chris@49
|
1039 f.width(cell_width);
|
Chris@49
|
1040 }
|
Chris@49
|
1041
|
Chris@49
|
1042 f << x.at(row,col);
|
Chris@49
|
1043 }
|
Chris@49
|
1044
|
Chris@49
|
1045 f.put('\n');
|
Chris@49
|
1046 }
|
Chris@49
|
1047
|
Chris@49
|
1048 const bool save_okay = f.good();
|
Chris@49
|
1049
|
Chris@49
|
1050 f.flags(orig_flags);
|
Chris@49
|
1051
|
Chris@49
|
1052 return save_okay;
|
Chris@49
|
1053 }
|
Chris@49
|
1054
|
Chris@49
|
1055
|
Chris@49
|
1056
|
Chris@49
|
1057 //! Save a matrix in CSV text format (human readable)
|
Chris@49
|
1058 template<typename eT>
|
Chris@49
|
1059 inline
|
Chris@49
|
1060 bool
|
Chris@49
|
1061 diskio::save_csv_ascii(const Mat<eT>& x, const std::string& final_name)
|
Chris@49
|
1062 {
|
Chris@49
|
1063 arma_extra_debug_sigprint();
|
Chris@49
|
1064
|
Chris@49
|
1065 const std::string tmp_name = diskio::gen_tmp_name(final_name);
|
Chris@49
|
1066
|
Chris@49
|
1067 std::ofstream f(tmp_name.c_str());
|
Chris@49
|
1068
|
Chris@49
|
1069 bool save_okay = f.is_open();
|
Chris@49
|
1070
|
Chris@49
|
1071 if(save_okay == true)
|
Chris@49
|
1072 {
|
Chris@49
|
1073 save_okay = diskio::save_csv_ascii(x, f);
|
Chris@49
|
1074
|
Chris@49
|
1075 f.flush();
|
Chris@49
|
1076 f.close();
|
Chris@49
|
1077
|
Chris@49
|
1078 if(save_okay == true)
|
Chris@49
|
1079 {
|
Chris@49
|
1080 save_okay = diskio::safe_rename(tmp_name, final_name);
|
Chris@49
|
1081 }
|
Chris@49
|
1082 }
|
Chris@49
|
1083
|
Chris@49
|
1084 return save_okay;
|
Chris@49
|
1085 }
|
Chris@49
|
1086
|
Chris@49
|
1087
|
Chris@49
|
1088
|
Chris@49
|
1089 //! Save a matrix in CSV text format (human readable)
|
Chris@49
|
1090 template<typename eT>
|
Chris@49
|
1091 inline
|
Chris@49
|
1092 bool
|
Chris@49
|
1093 diskio::save_csv_ascii(const Mat<eT>& x, std::ostream& f)
|
Chris@49
|
1094 {
|
Chris@49
|
1095 arma_extra_debug_sigprint();
|
Chris@49
|
1096
|
Chris@49
|
1097 const ios::fmtflags orig_flags = f.flags();
|
Chris@49
|
1098
|
Chris@49
|
1099 // TODO: need sane values for complex numbers
|
Chris@49
|
1100
|
Chris@49
|
1101 if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
|
Chris@49
|
1102 {
|
Chris@49
|
1103 f.setf(ios::scientific);
|
Chris@49
|
1104 f.precision(12);
|
Chris@49
|
1105 }
|
Chris@49
|
1106
|
Chris@49
|
1107 uword x_n_rows = x.n_rows;
|
Chris@49
|
1108 uword x_n_cols = x.n_cols;
|
Chris@49
|
1109
|
Chris@49
|
1110 for(uword row=0; row < x_n_rows; ++row)
|
Chris@49
|
1111 {
|
Chris@49
|
1112 for(uword col=0; col < x_n_cols; ++col)
|
Chris@49
|
1113 {
|
Chris@49
|
1114 f << x.at(row,col);
|
Chris@49
|
1115
|
Chris@49
|
1116 if( col < (x_n_cols-1) )
|
Chris@49
|
1117 {
|
Chris@49
|
1118 f.put(',');
|
Chris@49
|
1119 }
|
Chris@49
|
1120 }
|
Chris@49
|
1121
|
Chris@49
|
1122 f.put('\n');
|
Chris@49
|
1123 }
|
Chris@49
|
1124
|
Chris@49
|
1125 const bool save_okay = f.good();
|
Chris@49
|
1126
|
Chris@49
|
1127 f.flags(orig_flags);
|
Chris@49
|
1128
|
Chris@49
|
1129 return save_okay;
|
Chris@49
|
1130 }
|
Chris@49
|
1131
|
Chris@49
|
1132
|
Chris@49
|
1133
|
Chris@49
|
1134 //! Save a matrix in binary format,
|
Chris@49
|
1135 //! with a header that stores the matrix type as well as its dimensions
|
Chris@49
|
1136 template<typename eT>
|
Chris@49
|
1137 inline
|
Chris@49
|
1138 bool
|
Chris@49
|
1139 diskio::save_arma_binary(const Mat<eT>& x, const std::string& final_name)
|
Chris@49
|
1140 {
|
Chris@49
|
1141 arma_extra_debug_sigprint();
|
Chris@49
|
1142
|
Chris@49
|
1143 const std::string tmp_name = diskio::gen_tmp_name(final_name);
|
Chris@49
|
1144
|
Chris@49
|
1145 std::ofstream f(tmp_name.c_str(), std::fstream::binary);
|
Chris@49
|
1146
|
Chris@49
|
1147 bool save_okay = f.is_open();
|
Chris@49
|
1148
|
Chris@49
|
1149 if(save_okay == true)
|
Chris@49
|
1150 {
|
Chris@49
|
1151 save_okay = diskio::save_arma_binary(x, f);
|
Chris@49
|
1152
|
Chris@49
|
1153 f.flush();
|
Chris@49
|
1154 f.close();
|
Chris@49
|
1155
|
Chris@49
|
1156 if(save_okay == true)
|
Chris@49
|
1157 {
|
Chris@49
|
1158 save_okay = diskio::safe_rename(tmp_name, final_name);
|
Chris@49
|
1159 }
|
Chris@49
|
1160 }
|
Chris@49
|
1161
|
Chris@49
|
1162 return save_okay;
|
Chris@49
|
1163 }
|
Chris@49
|
1164
|
Chris@49
|
1165
|
Chris@49
|
1166
|
Chris@49
|
1167 //! Save a matrix in binary format,
|
Chris@49
|
1168 //! with a header that stores the matrix type as well as its dimensions
|
Chris@49
|
1169 template<typename eT>
|
Chris@49
|
1170 inline
|
Chris@49
|
1171 bool
|
Chris@49
|
1172 diskio::save_arma_binary(const Mat<eT>& x, std::ostream& f)
|
Chris@49
|
1173 {
|
Chris@49
|
1174 arma_extra_debug_sigprint();
|
Chris@49
|
1175
|
Chris@49
|
1176 f << diskio::gen_bin_header(x) << '\n';
|
Chris@49
|
1177 f << x.n_rows << ' ' << x.n_cols << '\n';
|
Chris@49
|
1178
|
Chris@49
|
1179 f.write( reinterpret_cast<const char*>(x.mem), std::streamsize(x.n_elem*sizeof(eT)) );
|
Chris@49
|
1180
|
Chris@49
|
1181 return f.good();
|
Chris@49
|
1182 }
|
Chris@49
|
1183
|
Chris@49
|
1184
|
Chris@49
|
1185
|
Chris@49
|
1186 //! Save a matrix as a PGM greyscale image
|
Chris@49
|
1187 template<typename eT>
|
Chris@49
|
1188 inline
|
Chris@49
|
1189 bool
|
Chris@49
|
1190 diskio::save_pgm_binary(const Mat<eT>& x, const std::string& final_name)
|
Chris@49
|
1191 {
|
Chris@49
|
1192 arma_extra_debug_sigprint();
|
Chris@49
|
1193
|
Chris@49
|
1194 const std::string tmp_name = diskio::gen_tmp_name(final_name);
|
Chris@49
|
1195
|
Chris@49
|
1196 std::fstream f(tmp_name.c_str(), std::fstream::out | std::fstream::binary);
|
Chris@49
|
1197
|
Chris@49
|
1198 bool save_okay = f.is_open();
|
Chris@49
|
1199
|
Chris@49
|
1200 if(save_okay == true)
|
Chris@49
|
1201 {
|
Chris@49
|
1202 save_okay = diskio::save_pgm_binary(x, f);
|
Chris@49
|
1203
|
Chris@49
|
1204 f.flush();
|
Chris@49
|
1205 f.close();
|
Chris@49
|
1206
|
Chris@49
|
1207 if(save_okay == true)
|
Chris@49
|
1208 {
|
Chris@49
|
1209 save_okay = diskio::safe_rename(tmp_name, final_name);
|
Chris@49
|
1210 }
|
Chris@49
|
1211 }
|
Chris@49
|
1212
|
Chris@49
|
1213 return save_okay;
|
Chris@49
|
1214 }
|
Chris@49
|
1215
|
Chris@49
|
1216
|
Chris@49
|
1217
|
Chris@49
|
1218 //
|
Chris@49
|
1219 // TODO:
|
Chris@49
|
1220 // add functionality to save the image in a normalised format,
|
Chris@49
|
1221 // i.e. scaled so that every value falls in the [0,255] range.
|
Chris@49
|
1222
|
Chris@49
|
1223 //! Save a matrix as a PGM greyscale image
|
Chris@49
|
1224 template<typename eT>
|
Chris@49
|
1225 inline
|
Chris@49
|
1226 bool
|
Chris@49
|
1227 diskio::save_pgm_binary(const Mat<eT>& x, std::ostream& f)
|
Chris@49
|
1228 {
|
Chris@49
|
1229 arma_extra_debug_sigprint();
|
Chris@49
|
1230
|
Chris@49
|
1231 f << "P5" << '\n';
|
Chris@49
|
1232 f << x.n_cols << ' ' << x.n_rows << '\n';
|
Chris@49
|
1233 f << 255 << '\n';
|
Chris@49
|
1234
|
Chris@49
|
1235 const uword n_elem = x.n_rows * x.n_cols;
|
Chris@49
|
1236 podarray<u8> tmp(n_elem);
|
Chris@49
|
1237
|
Chris@49
|
1238 uword i = 0;
|
Chris@49
|
1239
|
Chris@49
|
1240 for(uword row=0; row < x.n_rows; ++row)
|
Chris@49
|
1241 {
|
Chris@49
|
1242 for(uword col=0; col < x.n_cols; ++col)
|
Chris@49
|
1243 {
|
Chris@49
|
1244 tmp[i] = u8( x.at(row,col) ); // TODO: add round() ?
|
Chris@49
|
1245 ++i;
|
Chris@49
|
1246 }
|
Chris@49
|
1247 }
|
Chris@49
|
1248
|
Chris@49
|
1249 f.write(reinterpret_cast<const char*>(tmp.mem), std::streamsize(n_elem) );
|
Chris@49
|
1250
|
Chris@49
|
1251 return f.good();
|
Chris@49
|
1252 }
|
Chris@49
|
1253
|
Chris@49
|
1254
|
Chris@49
|
1255
|
Chris@49
|
1256 //! Save a matrix as a PGM greyscale image
|
Chris@49
|
1257 template<typename T>
|
Chris@49
|
1258 inline
|
Chris@49
|
1259 bool
|
Chris@49
|
1260 diskio::save_pgm_binary(const Mat< std::complex<T> >& x, const std::string& final_name)
|
Chris@49
|
1261 {
|
Chris@49
|
1262 arma_extra_debug_sigprint();
|
Chris@49
|
1263
|
Chris@49
|
1264 const uchar_mat tmp = conv_to<uchar_mat>::from(x);
|
Chris@49
|
1265
|
Chris@49
|
1266 return diskio::save_pgm_binary(tmp, final_name);
|
Chris@49
|
1267 }
|
Chris@49
|
1268
|
Chris@49
|
1269
|
Chris@49
|
1270
|
Chris@49
|
1271 //! Save a matrix as a PGM greyscale image
|
Chris@49
|
1272 template<typename T>
|
Chris@49
|
1273 inline
|
Chris@49
|
1274 bool
|
Chris@49
|
1275 diskio::save_pgm_binary(const Mat< std::complex<T> >& x, std::ostream& f)
|
Chris@49
|
1276 {
|
Chris@49
|
1277 arma_extra_debug_sigprint();
|
Chris@49
|
1278
|
Chris@49
|
1279 const uchar_mat tmp = conv_to<uchar_mat>::from(x);
|
Chris@49
|
1280
|
Chris@49
|
1281 return diskio::save_pgm_binary(tmp, f);
|
Chris@49
|
1282 }
|
Chris@49
|
1283
|
Chris@49
|
1284
|
Chris@49
|
1285
|
Chris@49
|
1286 //! Save a matrix as part of a HDF5 file
|
Chris@49
|
1287 template<typename eT>
|
Chris@49
|
1288 inline
|
Chris@49
|
1289 bool
|
Chris@49
|
1290 diskio::save_hdf5_binary(const Mat<eT>& x, const std::string& final_name)
|
Chris@49
|
1291 {
|
Chris@49
|
1292 arma_extra_debug_sigprint();
|
Chris@49
|
1293
|
Chris@49
|
1294 #if defined(ARMA_USE_HDF5)
|
Chris@49
|
1295 {
|
Chris@49
|
1296 #if !defined(ARMA_PRINT_HDF5_ERRORS)
|
Chris@49
|
1297 {
|
Chris@49
|
1298 // Disable annoying HDF5 error messages.
|
Chris@49
|
1299 H5Eset_auto(H5E_DEFAULT, NULL, NULL);
|
Chris@49
|
1300 }
|
Chris@49
|
1301 #endif
|
Chris@49
|
1302
|
Chris@49
|
1303 bool save_okay = false;
|
Chris@49
|
1304
|
Chris@49
|
1305 const std::string tmp_name = diskio::gen_tmp_name(final_name);
|
Chris@49
|
1306
|
Chris@49
|
1307 // Set up the file according to HDF5's preferences
|
Chris@49
|
1308 hid_t file = H5Fcreate(tmp_name.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
|
Chris@49
|
1309
|
Chris@49
|
1310 // We need to create a dataset, datatype, and dataspace
|
Chris@49
|
1311 hsize_t dims[2];
|
Chris@49
|
1312 dims[1] = x.n_rows;
|
Chris@49
|
1313 dims[0] = x.n_cols;
|
Chris@49
|
1314
|
Chris@49
|
1315 hid_t dataspace = H5Screate_simple(2, dims, NULL); // treat the matrix as a 2d array dataspace
|
Chris@49
|
1316 hid_t datatype = hdf5_misc::get_hdf5_type<eT>();
|
Chris@49
|
1317
|
Chris@49
|
1318 // If this returned something invalid, well, it's time to crash.
|
Chris@49
|
1319 arma_check(datatype == -1, "Mat::save(): unknown datatype for HDF5");
|
Chris@49
|
1320
|
Chris@49
|
1321 // MATLAB forces the users to specify a name at save time for HDF5; Octave
|
Chris@49
|
1322 // will use the default of 'dataset' unless otherwise specified, so we will
|
Chris@49
|
1323 // use that.
|
Chris@49
|
1324 hid_t dataset = H5Dcreate(file, "dataset", datatype, dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
|
Chris@49
|
1325
|
Chris@49
|
1326 // H5Dwrite does not make a distinction between row-major and column-major;
|
Chris@49
|
1327 // it just writes the memory. MATLAB and Octave store HDF5 matrices as
|
Chris@49
|
1328 // column-major, though, so we can save ours like that too and not need to
|
Chris@49
|
1329 // transpose.
|
Chris@49
|
1330 herr_t status = H5Dwrite(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, x.mem);
|
Chris@49
|
1331 save_okay = (status >= 0);
|
Chris@49
|
1332
|
Chris@49
|
1333 H5Dclose(dataset);
|
Chris@49
|
1334 H5Tclose(datatype);
|
Chris@49
|
1335 H5Sclose(dataspace);
|
Chris@49
|
1336 H5Fclose(file);
|
Chris@49
|
1337
|
Chris@49
|
1338 if(save_okay == true) { save_okay = diskio::safe_rename(tmp_name, final_name); }
|
Chris@49
|
1339
|
Chris@49
|
1340 return save_okay;
|
Chris@49
|
1341 }
|
Chris@49
|
1342 #else
|
Chris@49
|
1343 {
|
Chris@49
|
1344 arma_ignore(x);
|
Chris@49
|
1345 arma_ignore(final_name);
|
Chris@49
|
1346
|
Chris@49
|
1347 arma_stop("Mat::save(): use of HDF5 needs to be enabled");
|
Chris@49
|
1348
|
Chris@49
|
1349 return false;
|
Chris@49
|
1350 }
|
Chris@49
|
1351 #endif
|
Chris@49
|
1352 }
|
Chris@49
|
1353
|
Chris@49
|
1354
|
Chris@49
|
1355
|
Chris@49
|
1356 //! Load a matrix as raw text (no header, human readable).
|
Chris@49
|
1357 //! Can read matrices saved as text in Matlab and Octave.
|
Chris@49
|
1358 //! NOTE: this is much slower than reading a file with a header.
|
Chris@49
|
1359 template<typename eT>
|
Chris@49
|
1360 inline
|
Chris@49
|
1361 bool
|
Chris@49
|
1362 diskio::load_raw_ascii(Mat<eT>& x, const std::string& name, std::string& err_msg)
|
Chris@49
|
1363 {
|
Chris@49
|
1364 arma_extra_debug_sigprint();
|
Chris@49
|
1365
|
Chris@49
|
1366 std::fstream f;
|
Chris@49
|
1367 f.open(name.c_str(), std::fstream::in);
|
Chris@49
|
1368
|
Chris@49
|
1369 bool load_okay = f.is_open();
|
Chris@49
|
1370
|
Chris@49
|
1371 if(load_okay == true)
|
Chris@49
|
1372 {
|
Chris@49
|
1373 load_okay = diskio::load_raw_ascii(x, f, err_msg);
|
Chris@49
|
1374 f.close();
|
Chris@49
|
1375 }
|
Chris@49
|
1376
|
Chris@49
|
1377 return load_okay;
|
Chris@49
|
1378 }
|
Chris@49
|
1379
|
Chris@49
|
1380
|
Chris@49
|
1381
|
Chris@49
|
1382 //! Load a matrix as raw text (no header, human readable).
|
Chris@49
|
1383 //! Can read matrices saved as text in Matlab and Octave.
|
Chris@49
|
1384 //! NOTE: this is much slower than reading a file with a header.
|
Chris@49
|
1385 template<typename eT>
|
Chris@49
|
1386 inline
|
Chris@49
|
1387 bool
|
Chris@49
|
1388 diskio::load_raw_ascii(Mat<eT>& x, std::istream& f, std::string& err_msg)
|
Chris@49
|
1389 {
|
Chris@49
|
1390 arma_extra_debug_sigprint();
|
Chris@49
|
1391
|
Chris@49
|
1392 bool load_okay = f.good();
|
Chris@49
|
1393
|
Chris@49
|
1394 f.clear();
|
Chris@49
|
1395 const std::fstream::pos_type pos1 = f.tellg();
|
Chris@49
|
1396
|
Chris@49
|
1397 //
|
Chris@49
|
1398 // work out the size
|
Chris@49
|
1399
|
Chris@49
|
1400 uword f_n_rows = 0;
|
Chris@49
|
1401 uword f_n_cols = 0;
|
Chris@49
|
1402
|
Chris@49
|
1403 bool f_n_cols_found = false;
|
Chris@49
|
1404
|
Chris@49
|
1405 std::string line_string;
|
Chris@49
|
1406 std::string token;
|
Chris@49
|
1407
|
Chris@49
|
1408 std::stringstream line_stream;
|
Chris@49
|
1409
|
Chris@49
|
1410 while( (f.good() == true) && (load_okay == true) )
|
Chris@49
|
1411 {
|
Chris@49
|
1412 std::getline(f, line_string);
|
Chris@49
|
1413
|
Chris@49
|
1414 if(line_string.size() == 0)
|
Chris@49
|
1415 {
|
Chris@49
|
1416 break;
|
Chris@49
|
1417 }
|
Chris@49
|
1418
|
Chris@49
|
1419 line_stream.clear();
|
Chris@49
|
1420 line_stream.str(line_string);
|
Chris@49
|
1421
|
Chris@49
|
1422 uword line_n_cols = 0;
|
Chris@49
|
1423
|
Chris@49
|
1424 while (line_stream >> token)
|
Chris@49
|
1425 {
|
Chris@49
|
1426 ++line_n_cols;
|
Chris@49
|
1427 }
|
Chris@49
|
1428
|
Chris@49
|
1429 if(f_n_cols_found == false)
|
Chris@49
|
1430 {
|
Chris@49
|
1431 f_n_cols = line_n_cols;
|
Chris@49
|
1432 f_n_cols_found = true;
|
Chris@49
|
1433 }
|
Chris@49
|
1434 else
|
Chris@49
|
1435 {
|
Chris@49
|
1436 if(line_n_cols != f_n_cols)
|
Chris@49
|
1437 {
|
Chris@49
|
1438 err_msg = "inconsistent number of columns in ";
|
Chris@49
|
1439 load_okay = false;
|
Chris@49
|
1440 }
|
Chris@49
|
1441 }
|
Chris@49
|
1442
|
Chris@49
|
1443 ++f_n_rows;
|
Chris@49
|
1444 }
|
Chris@49
|
1445
|
Chris@49
|
1446 if(load_okay == true)
|
Chris@49
|
1447 {
|
Chris@49
|
1448 f.clear();
|
Chris@49
|
1449 f.seekg(pos1);
|
Chris@49
|
1450
|
Chris@49
|
1451 x.set_size(f_n_rows, f_n_cols);
|
Chris@49
|
1452
|
Chris@49
|
1453 std::stringstream ss;
|
Chris@49
|
1454
|
Chris@49
|
1455 for(uword row=0; (row < x.n_rows) && (load_okay == true); ++row)
|
Chris@49
|
1456 {
|
Chris@49
|
1457 for(uword col=0; (col < x.n_cols) && (load_okay == true); ++col)
|
Chris@49
|
1458 {
|
Chris@49
|
1459 f >> token;
|
Chris@49
|
1460
|
Chris@49
|
1461 ss.clear();
|
Chris@49
|
1462 ss.str(token);
|
Chris@49
|
1463
|
Chris@49
|
1464 eT val = eT(0);
|
Chris@49
|
1465 ss >> val;
|
Chris@49
|
1466
|
Chris@49
|
1467 if(ss.fail() == false)
|
Chris@49
|
1468 {
|
Chris@49
|
1469 x.at(row,col) = val;
|
Chris@49
|
1470 }
|
Chris@49
|
1471 else
|
Chris@49
|
1472 {
|
Chris@49
|
1473 const bool success = diskio::convert_naninf( x.at(row,col), token );
|
Chris@49
|
1474
|
Chris@49
|
1475 if(success == false)
|
Chris@49
|
1476 {
|
Chris@49
|
1477 load_okay = false;
|
Chris@49
|
1478 err_msg = "couldn't interpret data in ";
|
Chris@49
|
1479 }
|
Chris@49
|
1480 }
|
Chris@49
|
1481 }
|
Chris@49
|
1482 }
|
Chris@49
|
1483 }
|
Chris@49
|
1484
|
Chris@49
|
1485
|
Chris@49
|
1486 // an empty file indicates an empty matrix
|
Chris@49
|
1487 if( (f_n_cols_found == false) && (load_okay == true) )
|
Chris@49
|
1488 {
|
Chris@49
|
1489 x.reset();
|
Chris@49
|
1490 }
|
Chris@49
|
1491
|
Chris@49
|
1492
|
Chris@49
|
1493 return load_okay;
|
Chris@49
|
1494 }
|
Chris@49
|
1495
|
Chris@49
|
1496
|
Chris@49
|
1497
|
Chris@49
|
1498 //! Load a matrix in binary format (no header);
|
Chris@49
|
1499 //! the matrix is assumed to have one column
|
Chris@49
|
1500 template<typename eT>
|
Chris@49
|
1501 inline
|
Chris@49
|
1502 bool
|
Chris@49
|
1503 diskio::load_raw_binary(Mat<eT>& x, const std::string& name, std::string& err_msg)
|
Chris@49
|
1504 {
|
Chris@49
|
1505 arma_extra_debug_sigprint();
|
Chris@49
|
1506
|
Chris@49
|
1507 std::ifstream f;
|
Chris@49
|
1508 f.open(name.c_str(), std::fstream::binary);
|
Chris@49
|
1509
|
Chris@49
|
1510 bool load_okay = f.is_open();
|
Chris@49
|
1511
|
Chris@49
|
1512 if(load_okay == true)
|
Chris@49
|
1513 {
|
Chris@49
|
1514 load_okay = diskio::load_raw_binary(x, f, err_msg);
|
Chris@49
|
1515 f.close();
|
Chris@49
|
1516 }
|
Chris@49
|
1517
|
Chris@49
|
1518 return load_okay;
|
Chris@49
|
1519 }
|
Chris@49
|
1520
|
Chris@49
|
1521
|
Chris@49
|
1522
|
Chris@49
|
1523 template<typename eT>
|
Chris@49
|
1524 inline
|
Chris@49
|
1525 bool
|
Chris@49
|
1526 diskio::load_raw_binary(Mat<eT>& x, std::istream& f, std::string& err_msg)
|
Chris@49
|
1527 {
|
Chris@49
|
1528 arma_extra_debug_sigprint();
|
Chris@49
|
1529 arma_ignore(err_msg);
|
Chris@49
|
1530
|
Chris@49
|
1531 f.clear();
|
Chris@49
|
1532 const std::streampos pos1 = f.tellg();
|
Chris@49
|
1533
|
Chris@49
|
1534 f.clear();
|
Chris@49
|
1535 f.seekg(0, ios::end);
|
Chris@49
|
1536
|
Chris@49
|
1537 f.clear();
|
Chris@49
|
1538 const std::streampos pos2 = f.tellg();
|
Chris@49
|
1539
|
Chris@49
|
1540 const uword N = ( (pos1 >= 0) && (pos2 >= 0) ) ? uword(pos2 - pos1) : 0;
|
Chris@49
|
1541
|
Chris@49
|
1542 f.clear();
|
Chris@49
|
1543 //f.seekg(0, ios::beg);
|
Chris@49
|
1544 f.seekg(pos1);
|
Chris@49
|
1545
|
Chris@49
|
1546 x.set_size(N / sizeof(eT), 1);
|
Chris@49
|
1547
|
Chris@49
|
1548 f.clear();
|
Chris@49
|
1549 f.read( reinterpret_cast<char *>(x.memptr()), std::streamsize(N) );
|
Chris@49
|
1550
|
Chris@49
|
1551 return f.good();
|
Chris@49
|
1552 }
|
Chris@49
|
1553
|
Chris@49
|
1554
|
Chris@49
|
1555
|
Chris@49
|
1556 //! Load a matrix in text format (human readable),
|
Chris@49
|
1557 //! with a header that indicates the matrix type as well as its dimensions
|
Chris@49
|
1558 template<typename eT>
|
Chris@49
|
1559 inline
|
Chris@49
|
1560 bool
|
Chris@49
|
1561 diskio::load_arma_ascii(Mat<eT>& x, const std::string& name, std::string& err_msg)
|
Chris@49
|
1562 {
|
Chris@49
|
1563 arma_extra_debug_sigprint();
|
Chris@49
|
1564
|
Chris@49
|
1565 std::ifstream f(name.c_str());
|
Chris@49
|
1566
|
Chris@49
|
1567 bool load_okay = f.is_open();
|
Chris@49
|
1568
|
Chris@49
|
1569 if(load_okay == true)
|
Chris@49
|
1570 {
|
Chris@49
|
1571 load_okay = diskio::load_arma_ascii(x, f, err_msg);
|
Chris@49
|
1572 f.close();
|
Chris@49
|
1573 }
|
Chris@49
|
1574
|
Chris@49
|
1575 return load_okay;
|
Chris@49
|
1576 }
|
Chris@49
|
1577
|
Chris@49
|
1578
|
Chris@49
|
1579
|
Chris@49
|
1580 //! Load a matrix in text format (human readable),
|
Chris@49
|
1581 //! with a header that indicates the matrix type as well as its dimensions
|
Chris@49
|
1582 template<typename eT>
|
Chris@49
|
1583 inline
|
Chris@49
|
1584 bool
|
Chris@49
|
1585 diskio::load_arma_ascii(Mat<eT>& x, std::istream& f, std::string& err_msg)
|
Chris@49
|
1586 {
|
Chris@49
|
1587 arma_extra_debug_sigprint();
|
Chris@49
|
1588
|
Chris@49
|
1589 bool load_okay = true;
|
Chris@49
|
1590
|
Chris@49
|
1591 std::string f_header;
|
Chris@49
|
1592 uword f_n_rows;
|
Chris@49
|
1593 uword f_n_cols;
|
Chris@49
|
1594
|
Chris@49
|
1595 f >> f_header;
|
Chris@49
|
1596 f >> f_n_rows;
|
Chris@49
|
1597 f >> f_n_cols;
|
Chris@49
|
1598
|
Chris@49
|
1599 if(f_header == diskio::gen_txt_header(x))
|
Chris@49
|
1600 {
|
Chris@49
|
1601 x.zeros(f_n_rows, f_n_cols);
|
Chris@49
|
1602
|
Chris@49
|
1603 std::string token;
|
Chris@49
|
1604 std::stringstream ss;
|
Chris@49
|
1605
|
Chris@49
|
1606 for(uword row=0; row < x.n_rows; ++row)
|
Chris@49
|
1607 {
|
Chris@49
|
1608 for(uword col=0; col < x.n_cols; ++col)
|
Chris@49
|
1609 {
|
Chris@49
|
1610 f >> token;
|
Chris@49
|
1611
|
Chris@49
|
1612 ss.clear();
|
Chris@49
|
1613 ss.str(token);
|
Chris@49
|
1614
|
Chris@49
|
1615 eT val = eT(0);
|
Chris@49
|
1616 ss >> val;
|
Chris@49
|
1617
|
Chris@49
|
1618 if(ss.fail() == false)
|
Chris@49
|
1619 {
|
Chris@49
|
1620 x.at(row,col) = val;
|
Chris@49
|
1621 }
|
Chris@49
|
1622 else
|
Chris@49
|
1623 {
|
Chris@49
|
1624 diskio::convert_naninf( x.at(row,col), token );
|
Chris@49
|
1625 }
|
Chris@49
|
1626 }
|
Chris@49
|
1627 }
|
Chris@49
|
1628
|
Chris@49
|
1629 load_okay = f.good();
|
Chris@49
|
1630 }
|
Chris@49
|
1631 else
|
Chris@49
|
1632 {
|
Chris@49
|
1633 load_okay = false;
|
Chris@49
|
1634 err_msg = "incorrect header in ";
|
Chris@49
|
1635 }
|
Chris@49
|
1636
|
Chris@49
|
1637 return load_okay;
|
Chris@49
|
1638 }
|
Chris@49
|
1639
|
Chris@49
|
1640
|
Chris@49
|
1641
|
Chris@49
|
1642 //! Load a matrix in CSV text format (human readable)
|
Chris@49
|
1643 template<typename eT>
|
Chris@49
|
1644 inline
|
Chris@49
|
1645 bool
|
Chris@49
|
1646 diskio::load_csv_ascii(Mat<eT>& x, const std::string& name, std::string& err_msg)
|
Chris@49
|
1647 {
|
Chris@49
|
1648 arma_extra_debug_sigprint();
|
Chris@49
|
1649
|
Chris@49
|
1650 std::fstream f;
|
Chris@49
|
1651 f.open(name.c_str(), std::fstream::in);
|
Chris@49
|
1652
|
Chris@49
|
1653 bool load_okay = f.is_open();
|
Chris@49
|
1654
|
Chris@49
|
1655 if(load_okay == true)
|
Chris@49
|
1656 {
|
Chris@49
|
1657 load_okay = diskio::load_csv_ascii(x, f, err_msg);
|
Chris@49
|
1658 f.close();
|
Chris@49
|
1659 }
|
Chris@49
|
1660
|
Chris@49
|
1661 return load_okay;
|
Chris@49
|
1662 }
|
Chris@49
|
1663
|
Chris@49
|
1664
|
Chris@49
|
1665
|
Chris@49
|
1666 //! Load a matrix in CSV text format (human readable)
|
Chris@49
|
1667 template<typename eT>
|
Chris@49
|
1668 inline
|
Chris@49
|
1669 bool
|
Chris@49
|
1670 diskio::load_csv_ascii(Mat<eT>& x, std::istream& f, std::string&)
|
Chris@49
|
1671 {
|
Chris@49
|
1672 arma_extra_debug_sigprint();
|
Chris@49
|
1673
|
Chris@49
|
1674 bool load_okay = f.good();
|
Chris@49
|
1675
|
Chris@49
|
1676 f.clear();
|
Chris@49
|
1677 const std::fstream::pos_type pos1 = f.tellg();
|
Chris@49
|
1678
|
Chris@49
|
1679 //
|
Chris@49
|
1680 // work out the size
|
Chris@49
|
1681
|
Chris@49
|
1682 uword f_n_rows = 0;
|
Chris@49
|
1683 uword f_n_cols = 0;
|
Chris@49
|
1684
|
Chris@49
|
1685 std::string line_string;
|
Chris@49
|
1686 std::string token;
|
Chris@49
|
1687
|
Chris@49
|
1688 std::stringstream line_stream;
|
Chris@49
|
1689
|
Chris@49
|
1690 while( (f.good() == true) && (load_okay == true) )
|
Chris@49
|
1691 {
|
Chris@49
|
1692 std::getline(f, line_string);
|
Chris@49
|
1693
|
Chris@49
|
1694 if(line_string.size() == 0)
|
Chris@49
|
1695 {
|
Chris@49
|
1696 break;
|
Chris@49
|
1697 }
|
Chris@49
|
1698
|
Chris@49
|
1699 line_stream.clear();
|
Chris@49
|
1700 line_stream.str(line_string);
|
Chris@49
|
1701
|
Chris@49
|
1702 uword line_n_cols = 0;
|
Chris@49
|
1703
|
Chris@49
|
1704 while(line_stream.good() == true)
|
Chris@49
|
1705 {
|
Chris@49
|
1706 std::getline(line_stream, token, ',');
|
Chris@49
|
1707 ++line_n_cols;
|
Chris@49
|
1708 }
|
Chris@49
|
1709
|
Chris@49
|
1710 if(f_n_cols < line_n_cols)
|
Chris@49
|
1711 {
|
Chris@49
|
1712 f_n_cols = line_n_cols;
|
Chris@49
|
1713 }
|
Chris@49
|
1714
|
Chris@49
|
1715 ++f_n_rows;
|
Chris@49
|
1716 }
|
Chris@49
|
1717
|
Chris@49
|
1718 f.clear();
|
Chris@49
|
1719 f.seekg(pos1);
|
Chris@49
|
1720
|
Chris@49
|
1721 x.zeros(f_n_rows, f_n_cols);
|
Chris@49
|
1722
|
Chris@49
|
1723 uword row = 0;
|
Chris@49
|
1724
|
Chris@49
|
1725 std::stringstream ss;
|
Chris@49
|
1726
|
Chris@49
|
1727 while(f.good() == true)
|
Chris@49
|
1728 {
|
Chris@49
|
1729 std::getline(f, line_string);
|
Chris@49
|
1730
|
Chris@49
|
1731 if(line_string.size() == 0)
|
Chris@49
|
1732 {
|
Chris@49
|
1733 break;
|
Chris@49
|
1734 }
|
Chris@49
|
1735
|
Chris@49
|
1736 line_stream.clear();
|
Chris@49
|
1737 line_stream.str(line_string);
|
Chris@49
|
1738
|
Chris@49
|
1739 uword col = 0;
|
Chris@49
|
1740
|
Chris@49
|
1741 while(line_stream.good() == true)
|
Chris@49
|
1742 {
|
Chris@49
|
1743 std::getline(line_stream, token, ',');
|
Chris@49
|
1744
|
Chris@49
|
1745 ss.clear();
|
Chris@49
|
1746 ss.str(token);
|
Chris@49
|
1747
|
Chris@49
|
1748 eT val = eT(0);
|
Chris@49
|
1749 ss >> val;
|
Chris@49
|
1750
|
Chris@49
|
1751 if(ss.fail() == false)
|
Chris@49
|
1752 {
|
Chris@49
|
1753 x.at(row,col) = val;
|
Chris@49
|
1754 }
|
Chris@49
|
1755 else
|
Chris@49
|
1756 {
|
Chris@49
|
1757 diskio::convert_naninf( x.at(row,col), token );
|
Chris@49
|
1758 }
|
Chris@49
|
1759
|
Chris@49
|
1760 ++col;
|
Chris@49
|
1761 }
|
Chris@49
|
1762
|
Chris@49
|
1763 ++row;
|
Chris@49
|
1764 }
|
Chris@49
|
1765
|
Chris@49
|
1766 return load_okay;
|
Chris@49
|
1767 }
|
Chris@49
|
1768
|
Chris@49
|
1769
|
Chris@49
|
1770
|
Chris@49
|
1771 //! Load a matrix in binary format,
|
Chris@49
|
1772 //! with a header that indicates the matrix type as well as its dimensions
|
Chris@49
|
1773 template<typename eT>
|
Chris@49
|
1774 inline
|
Chris@49
|
1775 bool
|
Chris@49
|
1776 diskio::load_arma_binary(Mat<eT>& x, const std::string& name, std::string& err_msg)
|
Chris@49
|
1777 {
|
Chris@49
|
1778 arma_extra_debug_sigprint();
|
Chris@49
|
1779
|
Chris@49
|
1780 std::ifstream f;
|
Chris@49
|
1781 f.open(name.c_str(), std::fstream::binary);
|
Chris@49
|
1782
|
Chris@49
|
1783 bool load_okay = f.is_open();
|
Chris@49
|
1784
|
Chris@49
|
1785 if(load_okay == true)
|
Chris@49
|
1786 {
|
Chris@49
|
1787 load_okay = diskio::load_arma_binary(x, f, err_msg);
|
Chris@49
|
1788 f.close();
|
Chris@49
|
1789 }
|
Chris@49
|
1790
|
Chris@49
|
1791 return load_okay;
|
Chris@49
|
1792 }
|
Chris@49
|
1793
|
Chris@49
|
1794
|
Chris@49
|
1795
|
Chris@49
|
1796 template<typename eT>
|
Chris@49
|
1797 inline
|
Chris@49
|
1798 bool
|
Chris@49
|
1799 diskio::load_arma_binary(Mat<eT>& x, std::istream& f, std::string& err_msg)
|
Chris@49
|
1800 {
|
Chris@49
|
1801 arma_extra_debug_sigprint();
|
Chris@49
|
1802
|
Chris@49
|
1803 bool load_okay = true;
|
Chris@49
|
1804
|
Chris@49
|
1805 std::string f_header;
|
Chris@49
|
1806 uword f_n_rows;
|
Chris@49
|
1807 uword f_n_cols;
|
Chris@49
|
1808
|
Chris@49
|
1809 f >> f_header;
|
Chris@49
|
1810 f >> f_n_rows;
|
Chris@49
|
1811 f >> f_n_cols;
|
Chris@49
|
1812
|
Chris@49
|
1813 if(f_header == diskio::gen_bin_header(x))
|
Chris@49
|
1814 {
|
Chris@49
|
1815 //f.seekg(1, ios::cur); // NOTE: this may not be portable, as on a Windows machine a newline could be two characters
|
Chris@49
|
1816 f.get();
|
Chris@49
|
1817
|
Chris@49
|
1818 x.set_size(f_n_rows,f_n_cols);
|
Chris@49
|
1819 f.read( reinterpret_cast<char *>(x.memptr()), std::streamsize(x.n_elem*sizeof(eT)) );
|
Chris@49
|
1820
|
Chris@49
|
1821 load_okay = f.good();
|
Chris@49
|
1822 }
|
Chris@49
|
1823 else
|
Chris@49
|
1824 {
|
Chris@49
|
1825 load_okay = false;
|
Chris@49
|
1826 err_msg = "incorrect header in ";
|
Chris@49
|
1827 }
|
Chris@49
|
1828
|
Chris@49
|
1829 return load_okay;
|
Chris@49
|
1830 }
|
Chris@49
|
1831
|
Chris@49
|
1832
|
Chris@49
|
1833
|
Chris@49
|
1834 inline
|
Chris@49
|
1835 void
|
Chris@49
|
1836 diskio::pnm_skip_comments(std::istream& f)
|
Chris@49
|
1837 {
|
Chris@49
|
1838 while( isspace(f.peek()) )
|
Chris@49
|
1839 {
|
Chris@49
|
1840 while( isspace(f.peek()) )
|
Chris@49
|
1841 {
|
Chris@49
|
1842 f.get();
|
Chris@49
|
1843 }
|
Chris@49
|
1844
|
Chris@49
|
1845 if(f.peek() == '#')
|
Chris@49
|
1846 {
|
Chris@49
|
1847 while( (f.peek() != '\r') && (f.peek()!='\n') )
|
Chris@49
|
1848 {
|
Chris@49
|
1849 f.get();
|
Chris@49
|
1850 }
|
Chris@49
|
1851 }
|
Chris@49
|
1852 }
|
Chris@49
|
1853 }
|
Chris@49
|
1854
|
Chris@49
|
1855
|
Chris@49
|
1856
|
Chris@49
|
1857 //! Load a PGM greyscale image as a matrix
|
Chris@49
|
1858 template<typename eT>
|
Chris@49
|
1859 inline
|
Chris@49
|
1860 bool
|
Chris@49
|
1861 diskio::load_pgm_binary(Mat<eT>& x, const std::string& name, std::string& err_msg)
|
Chris@49
|
1862 {
|
Chris@49
|
1863 arma_extra_debug_sigprint();
|
Chris@49
|
1864
|
Chris@49
|
1865 std::fstream f;
|
Chris@49
|
1866 f.open(name.c_str(), std::fstream::in | std::fstream::binary);
|
Chris@49
|
1867
|
Chris@49
|
1868 bool load_okay = f.is_open();
|
Chris@49
|
1869
|
Chris@49
|
1870 if(load_okay == true)
|
Chris@49
|
1871 {
|
Chris@49
|
1872 load_okay = diskio::load_pgm_binary(x, f, err_msg);
|
Chris@49
|
1873 f.close();
|
Chris@49
|
1874 }
|
Chris@49
|
1875
|
Chris@49
|
1876 return load_okay;
|
Chris@49
|
1877 }
|
Chris@49
|
1878
|
Chris@49
|
1879
|
Chris@49
|
1880
|
Chris@49
|
1881 //! Load a PGM greyscale image as a matrix
|
Chris@49
|
1882 template<typename eT>
|
Chris@49
|
1883 inline
|
Chris@49
|
1884 bool
|
Chris@49
|
1885 diskio::load_pgm_binary(Mat<eT>& x, std::istream& f, std::string& err_msg)
|
Chris@49
|
1886 {
|
Chris@49
|
1887 bool load_okay = true;
|
Chris@49
|
1888
|
Chris@49
|
1889 std::string f_header;
|
Chris@49
|
1890 f >> f_header;
|
Chris@49
|
1891
|
Chris@49
|
1892 if(f_header == "P5")
|
Chris@49
|
1893 {
|
Chris@49
|
1894 uword f_n_rows = 0;
|
Chris@49
|
1895 uword f_n_cols = 0;
|
Chris@49
|
1896 int f_maxval = 0;
|
Chris@49
|
1897
|
Chris@49
|
1898 diskio::pnm_skip_comments(f);
|
Chris@49
|
1899
|
Chris@49
|
1900 f >> f_n_cols;
|
Chris@49
|
1901 diskio::pnm_skip_comments(f);
|
Chris@49
|
1902
|
Chris@49
|
1903 f >> f_n_rows;
|
Chris@49
|
1904 diskio::pnm_skip_comments(f);
|
Chris@49
|
1905
|
Chris@49
|
1906 f >> f_maxval;
|
Chris@49
|
1907 f.get();
|
Chris@49
|
1908
|
Chris@49
|
1909 if( (f_maxval > 0) || (f_maxval <= 65535) )
|
Chris@49
|
1910 {
|
Chris@49
|
1911 x.set_size(f_n_rows,f_n_cols);
|
Chris@49
|
1912
|
Chris@49
|
1913 if(f_maxval <= 255)
|
Chris@49
|
1914 {
|
Chris@49
|
1915 const uword n_elem = f_n_cols*f_n_rows;
|
Chris@49
|
1916 podarray<u8> tmp(n_elem);
|
Chris@49
|
1917
|
Chris@49
|
1918 f.read( reinterpret_cast<char*>(tmp.memptr()), std::streamsize(n_elem) );
|
Chris@49
|
1919
|
Chris@49
|
1920 uword i = 0;
|
Chris@49
|
1921
|
Chris@49
|
1922 //cout << "f_n_cols = " << f_n_cols << endl;
|
Chris@49
|
1923 //cout << "f_n_rows = " << f_n_rows << endl;
|
Chris@49
|
1924
|
Chris@49
|
1925
|
Chris@49
|
1926 for(uword row=0; row < f_n_rows; ++row)
|
Chris@49
|
1927 {
|
Chris@49
|
1928 for(uword col=0; col < f_n_cols; ++col)
|
Chris@49
|
1929 {
|
Chris@49
|
1930 x.at(row,col) = eT(tmp[i]);
|
Chris@49
|
1931 ++i;
|
Chris@49
|
1932 }
|
Chris@49
|
1933 }
|
Chris@49
|
1934
|
Chris@49
|
1935 }
|
Chris@49
|
1936 else
|
Chris@49
|
1937 {
|
Chris@49
|
1938 const uword n_elem = f_n_cols*f_n_rows;
|
Chris@49
|
1939 podarray<u16> tmp(n_elem);
|
Chris@49
|
1940
|
Chris@49
|
1941 f.read( reinterpret_cast<char *>(tmp.memptr()), std::streamsize(n_elem*2) );
|
Chris@49
|
1942
|
Chris@49
|
1943 uword i = 0;
|
Chris@49
|
1944
|
Chris@49
|
1945 for(uword row=0; row < f_n_rows; ++row)
|
Chris@49
|
1946 {
|
Chris@49
|
1947 for(uword col=0; col < f_n_cols; ++col)
|
Chris@49
|
1948 {
|
Chris@49
|
1949 x.at(row,col) = eT(tmp[i]);
|
Chris@49
|
1950 ++i;
|
Chris@49
|
1951 }
|
Chris@49
|
1952 }
|
Chris@49
|
1953
|
Chris@49
|
1954 }
|
Chris@49
|
1955
|
Chris@49
|
1956 }
|
Chris@49
|
1957 else
|
Chris@49
|
1958 {
|
Chris@49
|
1959 load_okay = false;
|
Chris@49
|
1960 err_msg = "currently no code available to handle loading ";
|
Chris@49
|
1961 }
|
Chris@49
|
1962
|
Chris@49
|
1963 if(f.good() == false)
|
Chris@49
|
1964 {
|
Chris@49
|
1965 load_okay = false;
|
Chris@49
|
1966 }
|
Chris@49
|
1967 }
|
Chris@49
|
1968 else
|
Chris@49
|
1969 {
|
Chris@49
|
1970 load_okay = false;
|
Chris@49
|
1971 err_msg = "unsupported header in ";
|
Chris@49
|
1972 }
|
Chris@49
|
1973
|
Chris@49
|
1974 return load_okay;
|
Chris@49
|
1975 }
|
Chris@49
|
1976
|
Chris@49
|
1977
|
Chris@49
|
1978
|
Chris@49
|
1979 //! Load a PGM greyscale image as a matrix
|
Chris@49
|
1980 template<typename T>
|
Chris@49
|
1981 inline
|
Chris@49
|
1982 bool
|
Chris@49
|
1983 diskio::load_pgm_binary(Mat< std::complex<T> >& x, const std::string& name, std::string& err_msg)
|
Chris@49
|
1984 {
|
Chris@49
|
1985 arma_extra_debug_sigprint();
|
Chris@49
|
1986
|
Chris@49
|
1987 uchar_mat tmp;
|
Chris@49
|
1988 const bool load_okay = diskio::load_pgm_binary(tmp, name, err_msg);
|
Chris@49
|
1989
|
Chris@49
|
1990 x = conv_to< Mat< std::complex<T> > >::from(tmp);
|
Chris@49
|
1991
|
Chris@49
|
1992 return load_okay;
|
Chris@49
|
1993 }
|
Chris@49
|
1994
|
Chris@49
|
1995
|
Chris@49
|
1996
|
Chris@49
|
1997 //! Load a PGM greyscale image as a matrix
|
Chris@49
|
1998 template<typename T>
|
Chris@49
|
1999 inline
|
Chris@49
|
2000 bool
|
Chris@49
|
2001 diskio::load_pgm_binary(Mat< std::complex<T> >& x, std::istream& is, std::string& err_msg)
|
Chris@49
|
2002 {
|
Chris@49
|
2003 arma_extra_debug_sigprint();
|
Chris@49
|
2004
|
Chris@49
|
2005 uchar_mat tmp;
|
Chris@49
|
2006 const bool load_okay = diskio::load_pgm_binary(tmp, is, err_msg);
|
Chris@49
|
2007
|
Chris@49
|
2008 x = conv_to< Mat< std::complex<T> > >::from(tmp);
|
Chris@49
|
2009
|
Chris@49
|
2010 return load_okay;
|
Chris@49
|
2011 }
|
Chris@49
|
2012
|
Chris@49
|
2013
|
Chris@49
|
2014
|
Chris@49
|
2015 //! Load a HDF5 file as a matrix
|
Chris@49
|
2016 template<typename eT>
|
Chris@49
|
2017 inline
|
Chris@49
|
2018 bool
|
Chris@49
|
2019 diskio::load_hdf5_binary(Mat<eT>& x, const std::string& name, std::string& err_msg)
|
Chris@49
|
2020 {
|
Chris@49
|
2021 arma_extra_debug_sigprint();
|
Chris@49
|
2022
|
Chris@49
|
2023 #if defined(ARMA_USE_HDF5)
|
Chris@49
|
2024 {
|
Chris@49
|
2025
|
Chris@49
|
2026 // These may be necessary to store the error handler (if we need to).
|
Chris@49
|
2027 herr_t (*old_func)(hid_t, void*);
|
Chris@49
|
2028 void *old_client_data;
|
Chris@49
|
2029
|
Chris@49
|
2030 #if !defined(ARMA_PRINT_HDF5_ERRORS)
|
Chris@49
|
2031 {
|
Chris@49
|
2032 // Save old error handler.
|
Chris@49
|
2033 H5Eget_auto(H5E_DEFAULT, &old_func, &old_client_data);
|
Chris@49
|
2034
|
Chris@49
|
2035 // Disable annoying HDF5 error messages.
|
Chris@49
|
2036 H5Eset_auto(H5E_DEFAULT, NULL, NULL);
|
Chris@49
|
2037 }
|
Chris@49
|
2038 #endif
|
Chris@49
|
2039
|
Chris@49
|
2040 bool load_okay = false;
|
Chris@49
|
2041
|
Chris@49
|
2042 hid_t fid = H5Fopen(name.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
|
Chris@49
|
2043
|
Chris@49
|
2044 if(fid >= 0)
|
Chris@49
|
2045 {
|
Chris@49
|
2046 // MATLAB HDF5 dataset names are user-specified;
|
Chris@49
|
2047 // Octave tends to store the datasets in a group, with the actual dataset being referred to as "value".
|
Chris@49
|
2048 // So we will search for "dataset" and "value", and if those are not found we will take the first dataset we do find.
|
Chris@49
|
2049 std::vector<std::string> searchNames;
|
Chris@49
|
2050 searchNames.push_back("dataset");
|
Chris@49
|
2051 searchNames.push_back("value");
|
Chris@49
|
2052
|
Chris@49
|
2053 hid_t dataset = hdf5_misc::search_hdf5_file(searchNames, fid, 2, false);
|
Chris@49
|
2054
|
Chris@49
|
2055 if(dataset >= 0)
|
Chris@49
|
2056 {
|
Chris@49
|
2057 hid_t filespace = H5Dget_space(dataset);
|
Chris@49
|
2058
|
Chris@49
|
2059 // This must be <= 2 due to our search rules.
|
Chris@49
|
2060 const int ndims = H5Sget_simple_extent_ndims(filespace);
|
Chris@49
|
2061
|
Chris@49
|
2062 hsize_t dims[2];
|
Chris@49
|
2063 const herr_t query_status = H5Sget_simple_extent_dims(filespace, dims, NULL);
|
Chris@49
|
2064
|
Chris@49
|
2065 // arma_check(query_status < 0, "Mat::load(): cannot get size of HDF5 dataset");
|
Chris@49
|
2066 if(query_status < 0)
|
Chris@49
|
2067 {
|
Chris@49
|
2068 err_msg = "cannot get size of HDF5 dataset in ";
|
Chris@49
|
2069
|
Chris@49
|
2070 H5Sclose(filespace);
|
Chris@49
|
2071 H5Dclose(dataset);
|
Chris@49
|
2072 H5Fclose(fid);
|
Chris@49
|
2073
|
Chris@49
|
2074 #if !defined(ARMA_PRINT_HDF5_ERRORS)
|
Chris@49
|
2075 {
|
Chris@49
|
2076 // Restore HDF5 error handler.
|
Chris@49
|
2077 H5Eset_auto(H5E_DEFAULT, old_func, old_client_data);
|
Chris@49
|
2078 }
|
Chris@49
|
2079 #endif
|
Chris@49
|
2080
|
Chris@49
|
2081 return false;
|
Chris@49
|
2082 }
|
Chris@49
|
2083
|
Chris@49
|
2084 if(ndims == 1) { dims[1] = 1; } // Vector case; fake second dimension (one column).
|
Chris@49
|
2085
|
Chris@49
|
2086 x.set_size(dims[1], dims[0]);
|
Chris@49
|
2087
|
Chris@49
|
2088 // Now we have to see what type is stored to figure out how to load it.
|
Chris@49
|
2089 hid_t datatype = H5Dget_type(dataset);
|
Chris@49
|
2090 hid_t mat_type = hdf5_misc::get_hdf5_type<eT>();
|
Chris@49
|
2091
|
Chris@49
|
2092 // If these are the same type, it is simple.
|
Chris@49
|
2093 if(H5Tequal(datatype, mat_type) > 0)
|
Chris@49
|
2094 {
|
Chris@49
|
2095 // Load directly; H5S_ALL used so that we load the entire dataset.
|
Chris@49
|
2096 hid_t read_status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(x.memptr()));
|
Chris@49
|
2097
|
Chris@49
|
2098 if(read_status >= 0) { load_okay = true; }
|
Chris@49
|
2099 }
|
Chris@49
|
2100 else
|
Chris@49
|
2101 {
|
Chris@49
|
2102 // Load into another array and convert its type accordingly.
|
Chris@49
|
2103 hid_t read_status = hdf5_misc::load_and_convert_hdf5(x.memptr(), dataset, datatype, x.n_elem);
|
Chris@49
|
2104
|
Chris@49
|
2105 if(read_status >= 0) { load_okay = true; }
|
Chris@49
|
2106 }
|
Chris@49
|
2107
|
Chris@49
|
2108 // Now clean up.
|
Chris@49
|
2109 H5Tclose(datatype);
|
Chris@49
|
2110 H5Tclose(mat_type);
|
Chris@49
|
2111 H5Sclose(filespace);
|
Chris@49
|
2112 }
|
Chris@49
|
2113
|
Chris@49
|
2114 H5Dclose(dataset);
|
Chris@49
|
2115
|
Chris@49
|
2116 H5Fclose(fid);
|
Chris@49
|
2117
|
Chris@49
|
2118 if(load_okay == false)
|
Chris@49
|
2119 {
|
Chris@49
|
2120 err_msg = "unsupported or incorrect HDF5 data in ";
|
Chris@49
|
2121 }
|
Chris@49
|
2122 }
|
Chris@49
|
2123 else
|
Chris@49
|
2124 {
|
Chris@49
|
2125 err_msg = "cannot open file ";
|
Chris@49
|
2126 }
|
Chris@49
|
2127
|
Chris@49
|
2128 #if !defined(ARMA_PRINT_HDF5_ERRORS)
|
Chris@49
|
2129 {
|
Chris@49
|
2130 // Restore HDF5 error handler.
|
Chris@49
|
2131 H5Eset_auto(H5E_DEFAULT, old_func, old_client_data);
|
Chris@49
|
2132 }
|
Chris@49
|
2133 #endif
|
Chris@49
|
2134
|
Chris@49
|
2135 return load_okay;
|
Chris@49
|
2136 }
|
Chris@49
|
2137 #else
|
Chris@49
|
2138 {
|
Chris@49
|
2139 arma_ignore(x);
|
Chris@49
|
2140 arma_ignore(name);
|
Chris@49
|
2141 arma_ignore(err_msg);
|
Chris@49
|
2142
|
Chris@49
|
2143 arma_stop("Mat::load(): use of HDF5 needs to be enabled");
|
Chris@49
|
2144
|
Chris@49
|
2145 return false;
|
Chris@49
|
2146 }
|
Chris@49
|
2147 #endif
|
Chris@49
|
2148 }
|
Chris@49
|
2149
|
Chris@49
|
2150
|
Chris@49
|
2151
|
Chris@49
|
2152 //! Try to load a matrix by automatically determining its type
|
Chris@49
|
2153 template<typename eT>
|
Chris@49
|
2154 inline
|
Chris@49
|
2155 bool
|
Chris@49
|
2156 diskio::load_auto_detect(Mat<eT>& x, const std::string& name, std::string& err_msg)
|
Chris@49
|
2157 {
|
Chris@49
|
2158 arma_extra_debug_sigprint();
|
Chris@49
|
2159
|
Chris@49
|
2160 #if defined(ARMA_USE_HDF5)
|
Chris@49
|
2161 // We're currently using the C bindings for the HDF5 library, which don't support C++ streams
|
Chris@49
|
2162 if( H5Fis_hdf5(name.c_str()) ) { return load_hdf5_binary(x, name, err_msg); }
|
Chris@49
|
2163 #endif
|
Chris@49
|
2164
|
Chris@49
|
2165 std::fstream f;
|
Chris@49
|
2166 f.open(name.c_str(), std::fstream::in | std::fstream::binary);
|
Chris@49
|
2167
|
Chris@49
|
2168 bool load_okay = f.is_open();
|
Chris@49
|
2169
|
Chris@49
|
2170 if(load_okay == true)
|
Chris@49
|
2171 {
|
Chris@49
|
2172 load_okay = diskio::load_auto_detect(x, f, err_msg);
|
Chris@49
|
2173 f.close();
|
Chris@49
|
2174 }
|
Chris@49
|
2175
|
Chris@49
|
2176 return load_okay;
|
Chris@49
|
2177 }
|
Chris@49
|
2178
|
Chris@49
|
2179
|
Chris@49
|
2180
|
Chris@49
|
2181 //! Try to load a matrix by automatically determining its type
|
Chris@49
|
2182 template<typename eT>
|
Chris@49
|
2183 inline
|
Chris@49
|
2184 bool
|
Chris@49
|
2185 diskio::load_auto_detect(Mat<eT>& x, std::istream& f, std::string& err_msg)
|
Chris@49
|
2186 {
|
Chris@49
|
2187 arma_extra_debug_sigprint();
|
Chris@49
|
2188
|
Chris@49
|
2189 static const std::string ARMA_MAT_TXT = "ARMA_MAT_TXT";
|
Chris@49
|
2190 static const std::string ARMA_MAT_BIN = "ARMA_MAT_BIN";
|
Chris@49
|
2191 static const std::string P5 = "P5";
|
Chris@49
|
2192
|
Chris@49
|
2193 podarray<char> raw_header(ARMA_MAT_TXT.length() + 1);
|
Chris@49
|
2194
|
Chris@49
|
2195 std::streampos pos = f.tellg();
|
Chris@49
|
2196
|
Chris@49
|
2197 f.read( raw_header.memptr(), std::streamsize(ARMA_MAT_TXT.length()) );
|
Chris@49
|
2198 raw_header[ARMA_MAT_TXT.length()] = '\0';
|
Chris@49
|
2199
|
Chris@49
|
2200 f.clear();
|
Chris@49
|
2201 f.seekg(pos);
|
Chris@49
|
2202
|
Chris@49
|
2203 const std::string header = raw_header.mem;
|
Chris@49
|
2204
|
Chris@49
|
2205 if(ARMA_MAT_TXT == header.substr(0,ARMA_MAT_TXT.length()))
|
Chris@49
|
2206 {
|
Chris@49
|
2207 return load_arma_ascii(x, f, err_msg);
|
Chris@49
|
2208 }
|
Chris@49
|
2209 else
|
Chris@49
|
2210 if(ARMA_MAT_BIN == header.substr(0,ARMA_MAT_BIN.length()))
|
Chris@49
|
2211 {
|
Chris@49
|
2212 return load_arma_binary(x, f, err_msg);
|
Chris@49
|
2213 }
|
Chris@49
|
2214 else
|
Chris@49
|
2215 if(P5 == header.substr(0,P5.length()))
|
Chris@49
|
2216 {
|
Chris@49
|
2217 return load_pgm_binary(x, f, err_msg);
|
Chris@49
|
2218 }
|
Chris@49
|
2219 else
|
Chris@49
|
2220 {
|
Chris@49
|
2221 const file_type ft = guess_file_type(f);
|
Chris@49
|
2222
|
Chris@49
|
2223 switch(ft)
|
Chris@49
|
2224 {
|
Chris@49
|
2225 case csv_ascii:
|
Chris@49
|
2226 return load_csv_ascii(x, f, err_msg);
|
Chris@49
|
2227 break;
|
Chris@49
|
2228
|
Chris@49
|
2229 case raw_binary:
|
Chris@49
|
2230 return load_raw_binary(x, f, err_msg);
|
Chris@49
|
2231 break;
|
Chris@49
|
2232
|
Chris@49
|
2233 case raw_ascii:
|
Chris@49
|
2234 return load_raw_ascii(x, f, err_msg);
|
Chris@49
|
2235 break;
|
Chris@49
|
2236
|
Chris@49
|
2237 default:
|
Chris@49
|
2238 err_msg = "unknown data in ";
|
Chris@49
|
2239 return false;
|
Chris@49
|
2240 }
|
Chris@49
|
2241 }
|
Chris@49
|
2242
|
Chris@49
|
2243 return false;
|
Chris@49
|
2244 }
|
Chris@49
|
2245
|
Chris@49
|
2246
|
Chris@49
|
2247
|
Chris@49
|
2248 //
|
Chris@49
|
2249 // sparse matrices
|
Chris@49
|
2250 //
|
Chris@49
|
2251
|
Chris@49
|
2252
|
Chris@49
|
2253
|
Chris@49
|
2254 //! Save a matrix in ASCII coord format
|
Chris@49
|
2255 template<typename eT>
|
Chris@49
|
2256 inline
|
Chris@49
|
2257 bool
|
Chris@49
|
2258 diskio::save_coord_ascii(const SpMat<eT>& x, const std::string& final_name)
|
Chris@49
|
2259 {
|
Chris@49
|
2260 arma_extra_debug_sigprint();
|
Chris@49
|
2261
|
Chris@49
|
2262 const std::string tmp_name = diskio::gen_tmp_name(final_name);
|
Chris@49
|
2263
|
Chris@49
|
2264 std::ofstream f(tmp_name.c_str());
|
Chris@49
|
2265
|
Chris@49
|
2266 bool save_okay = f.is_open();
|
Chris@49
|
2267
|
Chris@49
|
2268 if(save_okay == true)
|
Chris@49
|
2269 {
|
Chris@49
|
2270 save_okay = diskio::save_coord_ascii(x, f);
|
Chris@49
|
2271
|
Chris@49
|
2272 f.flush();
|
Chris@49
|
2273 f.close();
|
Chris@49
|
2274
|
Chris@49
|
2275 if(save_okay == true)
|
Chris@49
|
2276 {
|
Chris@49
|
2277 save_okay = diskio::safe_rename(tmp_name, final_name);
|
Chris@49
|
2278 }
|
Chris@49
|
2279 }
|
Chris@49
|
2280
|
Chris@49
|
2281 return save_okay;
|
Chris@49
|
2282 }
|
Chris@49
|
2283
|
Chris@49
|
2284
|
Chris@49
|
2285
|
Chris@49
|
2286 //! Save a matrix in ASCII coord format
|
Chris@49
|
2287 template<typename eT>
|
Chris@49
|
2288 inline
|
Chris@49
|
2289 bool
|
Chris@49
|
2290 diskio::save_coord_ascii(const SpMat<eT>& x, std::ostream& f)
|
Chris@49
|
2291 {
|
Chris@49
|
2292 arma_extra_debug_sigprint();
|
Chris@49
|
2293
|
Chris@49
|
2294 const ios::fmtflags orig_flags = f.flags();
|
Chris@49
|
2295
|
Chris@49
|
2296 typename SpMat<eT>::const_iterator iter = x.begin();
|
Chris@49
|
2297 typename SpMat<eT>::const_iterator iter_end = x.end();
|
Chris@49
|
2298
|
Chris@49
|
2299 for(; iter != iter_end; ++iter)
|
Chris@49
|
2300 {
|
Chris@49
|
2301 f.setf(ios::fixed);
|
Chris@49
|
2302
|
Chris@49
|
2303 f << iter.row() << ' ' << iter.col() << ' ';
|
Chris@49
|
2304
|
Chris@49
|
2305 if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
|
Chris@49
|
2306 {
|
Chris@49
|
2307 f.setf(ios::scientific);
|
Chris@49
|
2308 f.precision(12);
|
Chris@49
|
2309 }
|
Chris@49
|
2310
|
Chris@49
|
2311 f << (*iter) << '\n';
|
Chris@49
|
2312 }
|
Chris@49
|
2313
|
Chris@49
|
2314
|
Chris@49
|
2315 // make sure it's possible to figure out the matrix size later
|
Chris@49
|
2316 if( (x.n_rows > 0) && (x.n_cols > 0) )
|
Chris@49
|
2317 {
|
Chris@49
|
2318 const uword max_row = (x.n_rows > 0) ? x.n_rows-1 : 0;
|
Chris@49
|
2319 const uword max_col = (x.n_cols > 0) ? x.n_cols-1 : 0;
|
Chris@49
|
2320
|
Chris@49
|
2321 if( x.at(max_row, max_col) == eT(0) )
|
Chris@49
|
2322 {
|
Chris@49
|
2323 f.setf(ios::fixed);
|
Chris@49
|
2324
|
Chris@49
|
2325 f << max_row << ' ' << max_col << " 0\n";
|
Chris@49
|
2326 }
|
Chris@49
|
2327 }
|
Chris@49
|
2328
|
Chris@49
|
2329 const bool save_okay = f.good();
|
Chris@49
|
2330
|
Chris@49
|
2331 f.flags(orig_flags);
|
Chris@49
|
2332
|
Chris@49
|
2333 return save_okay;
|
Chris@49
|
2334 }
|
Chris@49
|
2335
|
Chris@49
|
2336
|
Chris@49
|
2337
|
Chris@49
|
2338 //! Save a matrix in ASCII coord format (complex numbers)
|
Chris@49
|
2339 template<typename T>
|
Chris@49
|
2340 inline
|
Chris@49
|
2341 bool
|
Chris@49
|
2342 diskio::save_coord_ascii(const SpMat< std::complex<T> >& x, std::ostream& f)
|
Chris@49
|
2343 {
|
Chris@49
|
2344 arma_extra_debug_sigprint();
|
Chris@49
|
2345
|
Chris@49
|
2346 const ios::fmtflags orig_flags = f.flags();
|
Chris@49
|
2347
|
Chris@49
|
2348 typedef typename std::complex<T> eT;
|
Chris@49
|
2349
|
Chris@49
|
2350 typename SpMat<eT>::const_iterator iter = x.begin();
|
Chris@49
|
2351 typename SpMat<eT>::const_iterator iter_end = x.end();
|
Chris@49
|
2352
|
Chris@49
|
2353 for(; iter != iter_end; ++iter)
|
Chris@49
|
2354 {
|
Chris@49
|
2355 f.setf(ios::fixed);
|
Chris@49
|
2356
|
Chris@49
|
2357 f << iter.row() << ' ' << iter.col() << ' ';
|
Chris@49
|
2358
|
Chris@49
|
2359 if( (is_float<T>::value == true) || (is_double<T>::value == true) )
|
Chris@49
|
2360 {
|
Chris@49
|
2361 f.setf(ios::scientific);
|
Chris@49
|
2362 f.precision(12);
|
Chris@49
|
2363 }
|
Chris@49
|
2364
|
Chris@49
|
2365 const eT val = (*iter);
|
Chris@49
|
2366
|
Chris@49
|
2367 f << val.real() << ' ' << val.imag() << '\n';
|
Chris@49
|
2368 }
|
Chris@49
|
2369
|
Chris@49
|
2370 // make sure it's possible to figure out the matrix size later
|
Chris@49
|
2371 if( (x.n_rows > 0) && (x.n_cols > 0) )
|
Chris@49
|
2372 {
|
Chris@49
|
2373 const uword max_row = (x.n_rows > 0) ? x.n_rows-1 : 0;
|
Chris@49
|
2374 const uword max_col = (x.n_cols > 0) ? x.n_cols-1 : 0;
|
Chris@49
|
2375
|
Chris@49
|
2376 if( x.at(max_row, max_col) == eT(0) )
|
Chris@49
|
2377 {
|
Chris@49
|
2378 f.setf(ios::fixed);
|
Chris@49
|
2379
|
Chris@49
|
2380 f << max_row << ' ' << max_col << " 0 0\n";
|
Chris@49
|
2381 }
|
Chris@49
|
2382 }
|
Chris@49
|
2383
|
Chris@49
|
2384 const bool save_okay = f.good();
|
Chris@49
|
2385
|
Chris@49
|
2386 f.flags(orig_flags);
|
Chris@49
|
2387
|
Chris@49
|
2388 return save_okay;
|
Chris@49
|
2389 }
|
Chris@49
|
2390
|
Chris@49
|
2391
|
Chris@49
|
2392
|
Chris@49
|
2393 //! Save a matrix in binary format,
|
Chris@49
|
2394 //! with a header that stores the matrix type as well as its dimensions
|
Chris@49
|
2395 template<typename eT>
|
Chris@49
|
2396 inline
|
Chris@49
|
2397 bool
|
Chris@49
|
2398 diskio::save_arma_binary(const SpMat<eT>& x, const std::string& final_name)
|
Chris@49
|
2399 {
|
Chris@49
|
2400 arma_extra_debug_sigprint();
|
Chris@49
|
2401
|
Chris@49
|
2402 const std::string tmp_name = diskio::gen_tmp_name(final_name);
|
Chris@49
|
2403
|
Chris@49
|
2404 std::ofstream f(tmp_name.c_str(), std::fstream::binary);
|
Chris@49
|
2405
|
Chris@49
|
2406 bool save_okay = f.is_open();
|
Chris@49
|
2407
|
Chris@49
|
2408 if(save_okay == true)
|
Chris@49
|
2409 {
|
Chris@49
|
2410 save_okay = diskio::save_arma_binary(x, f);
|
Chris@49
|
2411
|
Chris@49
|
2412 f.flush();
|
Chris@49
|
2413 f.close();
|
Chris@49
|
2414
|
Chris@49
|
2415 if(save_okay == true)
|
Chris@49
|
2416 {
|
Chris@49
|
2417 save_okay = diskio::safe_rename(tmp_name, final_name);
|
Chris@49
|
2418 }
|
Chris@49
|
2419 }
|
Chris@49
|
2420
|
Chris@49
|
2421 return save_okay;
|
Chris@49
|
2422 }
|
Chris@49
|
2423
|
Chris@49
|
2424
|
Chris@49
|
2425
|
Chris@49
|
2426 //! Save a matrix in binary format,
|
Chris@49
|
2427 //! with a header that stores the matrix type as well as its dimensions
|
Chris@49
|
2428 template<typename eT>
|
Chris@49
|
2429 inline
|
Chris@49
|
2430 bool
|
Chris@49
|
2431 diskio::save_arma_binary(const SpMat<eT>& x, std::ostream& f)
|
Chris@49
|
2432 {
|
Chris@49
|
2433 arma_extra_debug_sigprint();
|
Chris@49
|
2434
|
Chris@49
|
2435 f << diskio::gen_bin_header(x) << '\n';
|
Chris@49
|
2436 f << x.n_rows << ' ' << x.n_cols << ' ' << x.n_nonzero << '\n';
|
Chris@49
|
2437
|
Chris@49
|
2438 f.write( reinterpret_cast<const char*>(x.values), std::streamsize(x.n_nonzero*sizeof(eT)) );
|
Chris@49
|
2439 f.write( reinterpret_cast<const char*>(x.row_indices), std::streamsize(x.n_nonzero*sizeof(uword)) );
|
Chris@49
|
2440 f.write( reinterpret_cast<const char*>(x.col_ptrs), std::streamsize((x.n_cols+1)*sizeof(uword)) );
|
Chris@49
|
2441
|
Chris@49
|
2442 return f.good();
|
Chris@49
|
2443 }
|
Chris@49
|
2444
|
Chris@49
|
2445
|
Chris@49
|
2446
|
Chris@49
|
2447 template<typename eT>
|
Chris@49
|
2448 inline
|
Chris@49
|
2449 bool
|
Chris@49
|
2450 diskio::load_coord_ascii(SpMat<eT>& x, const std::string& name, std::string& err_msg)
|
Chris@49
|
2451 {
|
Chris@49
|
2452 arma_extra_debug_sigprint();
|
Chris@49
|
2453
|
Chris@49
|
2454 std::fstream f;
|
Chris@49
|
2455 f.open(name.c_str(), std::fstream::in | std::fstream::binary);
|
Chris@49
|
2456
|
Chris@49
|
2457 bool load_okay = f.is_open();
|
Chris@49
|
2458
|
Chris@49
|
2459 if(load_okay == true)
|
Chris@49
|
2460 {
|
Chris@49
|
2461 load_okay = diskio::load_coord_ascii(x, f, err_msg);
|
Chris@49
|
2462 f.close();
|
Chris@49
|
2463 }
|
Chris@49
|
2464
|
Chris@49
|
2465 return load_okay;
|
Chris@49
|
2466 }
|
Chris@49
|
2467
|
Chris@49
|
2468
|
Chris@49
|
2469
|
Chris@49
|
2470 template<typename eT>
|
Chris@49
|
2471 inline
|
Chris@49
|
2472 bool
|
Chris@49
|
2473 diskio::load_coord_ascii(SpMat<eT>& x, std::istream& f, std::string& err_msg)
|
Chris@49
|
2474 {
|
Chris@49
|
2475 bool load_okay = f.good();
|
Chris@49
|
2476
|
Chris@49
|
2477 f.clear();
|
Chris@49
|
2478 const std::fstream::pos_type pos1 = f.tellg();
|
Chris@49
|
2479
|
Chris@49
|
2480 //
|
Chris@49
|
2481 // work out the size
|
Chris@49
|
2482
|
Chris@49
|
2483 uword f_n_rows = 0;
|
Chris@49
|
2484 uword f_n_cols = 0;
|
Chris@49
|
2485 uword f_n_nz = 0;
|
Chris@49
|
2486
|
Chris@49
|
2487 bool size_found = false;
|
Chris@49
|
2488
|
Chris@49
|
2489 std::string line_string;
|
Chris@49
|
2490 std::string token;
|
Chris@49
|
2491
|
Chris@49
|
2492 std::stringstream line_stream;
|
Chris@49
|
2493 std::stringstream ss;
|
Chris@49
|
2494
|
Chris@49
|
2495 uword last_line_row = 0;
|
Chris@49
|
2496 uword last_line_col = 0;
|
Chris@49
|
2497
|
Chris@49
|
2498 bool first_line = true;
|
Chris@49
|
2499 bool weird_format = false;
|
Chris@49
|
2500
|
Chris@49
|
2501
|
Chris@49
|
2502 while( (f.good() == true) && (load_okay == true) )
|
Chris@49
|
2503 {
|
Chris@49
|
2504 std::getline(f, line_string);
|
Chris@49
|
2505
|
Chris@49
|
2506 if(line_string.size() == 0)
|
Chris@49
|
2507 {
|
Chris@49
|
2508 break;
|
Chris@49
|
2509 }
|
Chris@49
|
2510
|
Chris@49
|
2511 line_stream.clear();
|
Chris@49
|
2512 line_stream.str(line_string);
|
Chris@49
|
2513
|
Chris@49
|
2514 uword line_row = 0;
|
Chris@49
|
2515 uword line_col = 0;
|
Chris@49
|
2516
|
Chris@49
|
2517 // a valid line in co-ord format has at least 2 entries
|
Chris@49
|
2518
|
Chris@49
|
2519 line_stream >> line_row;
|
Chris@49
|
2520
|
Chris@49
|
2521 if(line_stream.good() == false)
|
Chris@49
|
2522 {
|
Chris@49
|
2523 load_okay = false;
|
Chris@49
|
2524 break;
|
Chris@49
|
2525 }
|
Chris@49
|
2526
|
Chris@49
|
2527 line_stream >> line_col;
|
Chris@49
|
2528
|
Chris@49
|
2529 size_found = true;
|
Chris@49
|
2530
|
Chris@49
|
2531 if(f_n_rows < line_row) f_n_rows = line_row;
|
Chris@49
|
2532 if(f_n_cols < line_col) f_n_cols = line_col;
|
Chris@49
|
2533
|
Chris@49
|
2534 if(first_line == true)
|
Chris@49
|
2535 {
|
Chris@49
|
2536 first_line = false;
|
Chris@49
|
2537 }
|
Chris@49
|
2538 else
|
Chris@49
|
2539 {
|
Chris@49
|
2540 if( (line_col < last_line_col) || ((line_row <= last_line_row) && (line_col <= last_line_col)) )
|
Chris@49
|
2541 {
|
Chris@49
|
2542 weird_format = true;
|
Chris@49
|
2543 }
|
Chris@49
|
2544 }
|
Chris@49
|
2545
|
Chris@49
|
2546 last_line_row = line_row;
|
Chris@49
|
2547 last_line_col = line_col;
|
Chris@49
|
2548
|
Chris@49
|
2549
|
Chris@49
|
2550 if(line_stream.good() == true)
|
Chris@49
|
2551 {
|
Chris@49
|
2552 eT final_val = eT(0);
|
Chris@49
|
2553
|
Chris@49
|
2554 line_stream >> token;
|
Chris@49
|
2555
|
Chris@49
|
2556 if(line_stream.fail() == false)
|
Chris@49
|
2557 {
|
Chris@49
|
2558 eT val = eT(0);
|
Chris@49
|
2559
|
Chris@49
|
2560 ss.clear();
|
Chris@49
|
2561 ss.str(token);
|
Chris@49
|
2562
|
Chris@49
|
2563 ss >> val;
|
Chris@49
|
2564
|
Chris@49
|
2565 if(ss.fail() == false)
|
Chris@49
|
2566 {
|
Chris@49
|
2567 final_val = val;
|
Chris@49
|
2568 }
|
Chris@49
|
2569 else
|
Chris@49
|
2570 {
|
Chris@49
|
2571 val = eT(0);
|
Chris@49
|
2572
|
Chris@49
|
2573 const bool success = diskio::convert_naninf( val, token );
|
Chris@49
|
2574
|
Chris@49
|
2575 if(success == true)
|
Chris@49
|
2576 {
|
Chris@49
|
2577 final_val = val;
|
Chris@49
|
2578 }
|
Chris@49
|
2579 }
|
Chris@49
|
2580 }
|
Chris@49
|
2581
|
Chris@49
|
2582 if(final_val != eT(0))
|
Chris@49
|
2583 {
|
Chris@49
|
2584 ++f_n_nz;
|
Chris@49
|
2585 }
|
Chris@49
|
2586 }
|
Chris@49
|
2587 }
|
Chris@49
|
2588
|
Chris@49
|
2589
|
Chris@49
|
2590 if(size_found == true)
|
Chris@49
|
2591 {
|
Chris@49
|
2592 // take into account that indices start at 0
|
Chris@49
|
2593 f_n_rows++;
|
Chris@49
|
2594 f_n_cols++;
|
Chris@49
|
2595 }
|
Chris@49
|
2596
|
Chris@49
|
2597
|
Chris@49
|
2598 if(load_okay == true)
|
Chris@49
|
2599 {
|
Chris@49
|
2600 f.clear();
|
Chris@49
|
2601 f.seekg(pos1);
|
Chris@49
|
2602
|
Chris@49
|
2603 x.set_size(f_n_rows, f_n_cols);
|
Chris@49
|
2604
|
Chris@49
|
2605 if(weird_format == false)
|
Chris@49
|
2606 {
|
Chris@49
|
2607 x.mem_resize(f_n_nz);
|
Chris@49
|
2608 }
|
Chris@49
|
2609
|
Chris@49
|
2610 uword pos = 0;
|
Chris@49
|
2611
|
Chris@49
|
2612 while(f.good() == true)
|
Chris@49
|
2613 {
|
Chris@49
|
2614 std::getline(f, line_string);
|
Chris@49
|
2615
|
Chris@49
|
2616 if(line_string.size() == 0)
|
Chris@49
|
2617 {
|
Chris@49
|
2618 break;
|
Chris@49
|
2619 }
|
Chris@49
|
2620
|
Chris@49
|
2621 line_stream.clear();
|
Chris@49
|
2622 line_stream.str(line_string);
|
Chris@49
|
2623
|
Chris@49
|
2624 uword line_row = 0;
|
Chris@49
|
2625 uword line_col = 0;
|
Chris@49
|
2626
|
Chris@49
|
2627 line_stream >> line_row;
|
Chris@49
|
2628 line_stream >> line_col;
|
Chris@49
|
2629
|
Chris@49
|
2630 eT final_val = eT(0);
|
Chris@49
|
2631
|
Chris@49
|
2632 line_stream >> token;
|
Chris@49
|
2633
|
Chris@49
|
2634 if(line_stream.fail() == false)
|
Chris@49
|
2635 {
|
Chris@49
|
2636 eT val = eT(0);
|
Chris@49
|
2637
|
Chris@49
|
2638 ss.clear();
|
Chris@49
|
2639 ss.str(token);
|
Chris@49
|
2640
|
Chris@49
|
2641 ss >> val;
|
Chris@49
|
2642
|
Chris@49
|
2643 if(ss.fail() == false)
|
Chris@49
|
2644 {
|
Chris@49
|
2645 final_val = val;
|
Chris@49
|
2646 }
|
Chris@49
|
2647 else
|
Chris@49
|
2648 {
|
Chris@49
|
2649 val = eT(0);
|
Chris@49
|
2650
|
Chris@49
|
2651 const bool success = diskio::convert_naninf( val, token );
|
Chris@49
|
2652
|
Chris@49
|
2653 if(success == true)
|
Chris@49
|
2654 {
|
Chris@49
|
2655 final_val = val;
|
Chris@49
|
2656 }
|
Chris@49
|
2657 }
|
Chris@49
|
2658 }
|
Chris@49
|
2659
|
Chris@49
|
2660
|
Chris@49
|
2661 if(final_val != eT(0))
|
Chris@49
|
2662 {
|
Chris@49
|
2663 if(weird_format == false)
|
Chris@49
|
2664 {
|
Chris@49
|
2665 access::rw(x.row_indices[pos]) = line_row;
|
Chris@49
|
2666 access::rw(x.values[pos]) = final_val;
|
Chris@49
|
2667 ++access::rw(x.col_ptrs[line_col + 1]);
|
Chris@49
|
2668
|
Chris@49
|
2669 ++pos;
|
Chris@49
|
2670 }
|
Chris@49
|
2671 else
|
Chris@49
|
2672 {
|
Chris@49
|
2673 x.at(line_row,line_col) = final_val;
|
Chris@49
|
2674 }
|
Chris@49
|
2675 }
|
Chris@49
|
2676 }
|
Chris@49
|
2677
|
Chris@49
|
2678 if(weird_format == false)
|
Chris@49
|
2679 {
|
Chris@49
|
2680 for(uword c = 1; c <= f_n_cols; ++c)
|
Chris@49
|
2681 {
|
Chris@49
|
2682 access::rw(x.col_ptrs[c]) += x.col_ptrs[c - 1];
|
Chris@49
|
2683 }
|
Chris@49
|
2684 }
|
Chris@49
|
2685 }
|
Chris@49
|
2686
|
Chris@49
|
2687 return load_okay;
|
Chris@49
|
2688 }
|
Chris@49
|
2689
|
Chris@49
|
2690
|
Chris@49
|
2691
|
Chris@49
|
2692 template<typename T>
|
Chris@49
|
2693 inline
|
Chris@49
|
2694 bool
|
Chris@49
|
2695 diskio::load_coord_ascii(SpMat< std::complex<T> >& x, std::istream& f, std::string& err_msg)
|
Chris@49
|
2696 {
|
Chris@49
|
2697 bool load_okay = f.good();
|
Chris@49
|
2698
|
Chris@49
|
2699 f.clear();
|
Chris@49
|
2700 const std::fstream::pos_type pos1 = f.tellg();
|
Chris@49
|
2701
|
Chris@49
|
2702 //
|
Chris@49
|
2703 // work out the size
|
Chris@49
|
2704
|
Chris@49
|
2705 uword f_n_rows = 0;
|
Chris@49
|
2706 uword f_n_cols = 0;
|
Chris@49
|
2707 uword f_n_nz = 0;
|
Chris@49
|
2708
|
Chris@49
|
2709 bool size_found = false;
|
Chris@49
|
2710
|
Chris@49
|
2711 std::string line_string;
|
Chris@49
|
2712 std::string token_real;
|
Chris@49
|
2713 std::string token_imag;
|
Chris@49
|
2714
|
Chris@49
|
2715 std::stringstream line_stream;
|
Chris@49
|
2716 std::stringstream ss;
|
Chris@49
|
2717
|
Chris@49
|
2718 uword last_line_row = 0;
|
Chris@49
|
2719 uword last_line_col = 0;
|
Chris@49
|
2720
|
Chris@49
|
2721 bool first_line = true;
|
Chris@49
|
2722 bool weird_format = false;
|
Chris@49
|
2723
|
Chris@49
|
2724 while( (f.good() == true) && (load_okay == true) )
|
Chris@49
|
2725 {
|
Chris@49
|
2726 std::getline(f, line_string);
|
Chris@49
|
2727
|
Chris@49
|
2728 if(line_string.size() == 0)
|
Chris@49
|
2729 {
|
Chris@49
|
2730 break;
|
Chris@49
|
2731 }
|
Chris@49
|
2732
|
Chris@49
|
2733 line_stream.clear();
|
Chris@49
|
2734 line_stream.str(line_string);
|
Chris@49
|
2735
|
Chris@49
|
2736 uword line_row = 0;
|
Chris@49
|
2737 uword line_col = 0;
|
Chris@49
|
2738
|
Chris@49
|
2739 // a valid line in co-ord format has at least 2 entries
|
Chris@49
|
2740
|
Chris@49
|
2741 line_stream >> line_row;
|
Chris@49
|
2742
|
Chris@49
|
2743 if(line_stream.good() == false)
|
Chris@49
|
2744 {
|
Chris@49
|
2745 load_okay = false;
|
Chris@49
|
2746 break;
|
Chris@49
|
2747 }
|
Chris@49
|
2748
|
Chris@49
|
2749 line_stream >> line_col;
|
Chris@49
|
2750
|
Chris@49
|
2751 size_found = true;
|
Chris@49
|
2752
|
Chris@49
|
2753 if(f_n_rows < line_row) f_n_rows = line_row;
|
Chris@49
|
2754 if(f_n_cols < line_col) f_n_cols = line_col;
|
Chris@49
|
2755
|
Chris@49
|
2756
|
Chris@49
|
2757 if(first_line == true)
|
Chris@49
|
2758 {
|
Chris@49
|
2759 first_line = false;
|
Chris@49
|
2760 }
|
Chris@49
|
2761 else
|
Chris@49
|
2762 {
|
Chris@49
|
2763 if( (line_col < last_line_col) || ((line_row <= last_line_row) && (line_col <= last_line_col)) )
|
Chris@49
|
2764 {
|
Chris@49
|
2765 weird_format = true;
|
Chris@49
|
2766 }
|
Chris@49
|
2767 }
|
Chris@49
|
2768
|
Chris@49
|
2769 last_line_row = line_row;
|
Chris@49
|
2770 last_line_col = line_col;
|
Chris@49
|
2771
|
Chris@49
|
2772
|
Chris@49
|
2773 if(line_stream.good() == true)
|
Chris@49
|
2774 {
|
Chris@49
|
2775 T final_val_real = T(0);
|
Chris@49
|
2776 T final_val_imag = T(0);
|
Chris@49
|
2777
|
Chris@49
|
2778
|
Chris@49
|
2779 line_stream >> token_real;
|
Chris@49
|
2780
|
Chris@49
|
2781 if(line_stream.fail() == false)
|
Chris@49
|
2782 {
|
Chris@49
|
2783 T val_real = T(0);
|
Chris@49
|
2784
|
Chris@49
|
2785 ss.clear();
|
Chris@49
|
2786 ss.str(token_real);
|
Chris@49
|
2787
|
Chris@49
|
2788 ss >> val_real;
|
Chris@49
|
2789
|
Chris@49
|
2790 if(ss.fail() == false)
|
Chris@49
|
2791 {
|
Chris@49
|
2792 final_val_real = val_real;
|
Chris@49
|
2793 }
|
Chris@49
|
2794 else
|
Chris@49
|
2795 {
|
Chris@49
|
2796 val_real = T(0);
|
Chris@49
|
2797
|
Chris@49
|
2798 const bool success = diskio::convert_naninf( val_real, token_real );
|
Chris@49
|
2799
|
Chris@49
|
2800 if(success == true)
|
Chris@49
|
2801 {
|
Chris@49
|
2802 final_val_real = val_real;
|
Chris@49
|
2803 }
|
Chris@49
|
2804 }
|
Chris@49
|
2805 }
|
Chris@49
|
2806
|
Chris@49
|
2807
|
Chris@49
|
2808 line_stream >> token_imag;
|
Chris@49
|
2809
|
Chris@49
|
2810 if(line_stream.fail() == false)
|
Chris@49
|
2811 {
|
Chris@49
|
2812 T val_imag = T(0);
|
Chris@49
|
2813
|
Chris@49
|
2814 ss.clear();
|
Chris@49
|
2815 ss.str(token_imag);
|
Chris@49
|
2816
|
Chris@49
|
2817 ss >> val_imag;
|
Chris@49
|
2818
|
Chris@49
|
2819 if(ss.fail() == false)
|
Chris@49
|
2820 {
|
Chris@49
|
2821 final_val_imag = val_imag;
|
Chris@49
|
2822 }
|
Chris@49
|
2823 else
|
Chris@49
|
2824 {
|
Chris@49
|
2825 val_imag = T(0);
|
Chris@49
|
2826
|
Chris@49
|
2827 const bool success = diskio::convert_naninf( val_imag, token_imag );
|
Chris@49
|
2828
|
Chris@49
|
2829 if(success == true)
|
Chris@49
|
2830 {
|
Chris@49
|
2831 final_val_imag = val_imag;
|
Chris@49
|
2832 }
|
Chris@49
|
2833 }
|
Chris@49
|
2834 }
|
Chris@49
|
2835
|
Chris@49
|
2836
|
Chris@49
|
2837 if( (final_val_real != T(0)) || (final_val_imag != T(0)) )
|
Chris@49
|
2838 {
|
Chris@49
|
2839 ++f_n_nz;
|
Chris@49
|
2840 }
|
Chris@49
|
2841 }
|
Chris@49
|
2842 }
|
Chris@49
|
2843
|
Chris@49
|
2844
|
Chris@49
|
2845 if(size_found == true)
|
Chris@49
|
2846 {
|
Chris@49
|
2847 // take into account that indices start at 0
|
Chris@49
|
2848 f_n_rows++;
|
Chris@49
|
2849 f_n_cols++;
|
Chris@49
|
2850 }
|
Chris@49
|
2851
|
Chris@49
|
2852
|
Chris@49
|
2853 if(load_okay == true)
|
Chris@49
|
2854 {
|
Chris@49
|
2855 f.clear();
|
Chris@49
|
2856 f.seekg(pos1);
|
Chris@49
|
2857
|
Chris@49
|
2858 x.set_size(f_n_rows, f_n_cols);
|
Chris@49
|
2859
|
Chris@49
|
2860 if(weird_format == false)
|
Chris@49
|
2861 {
|
Chris@49
|
2862 x.mem_resize(f_n_nz);
|
Chris@49
|
2863 }
|
Chris@49
|
2864
|
Chris@49
|
2865 uword pos = 0;
|
Chris@49
|
2866
|
Chris@49
|
2867 while(f.good() == true)
|
Chris@49
|
2868 {
|
Chris@49
|
2869 std::getline(f, line_string);
|
Chris@49
|
2870
|
Chris@49
|
2871 if(line_string.size() == 0)
|
Chris@49
|
2872 {
|
Chris@49
|
2873 break;
|
Chris@49
|
2874 }
|
Chris@49
|
2875
|
Chris@49
|
2876 line_stream.clear();
|
Chris@49
|
2877 line_stream.str(line_string);
|
Chris@49
|
2878
|
Chris@49
|
2879 uword line_row = 0;
|
Chris@49
|
2880 uword line_col = 0;
|
Chris@49
|
2881
|
Chris@49
|
2882 line_stream >> line_row;
|
Chris@49
|
2883 line_stream >> line_col;
|
Chris@49
|
2884
|
Chris@49
|
2885 T final_val_real = T(0);
|
Chris@49
|
2886 T final_val_imag = T(0);
|
Chris@49
|
2887
|
Chris@49
|
2888
|
Chris@49
|
2889 line_stream >> token_real;
|
Chris@49
|
2890
|
Chris@49
|
2891 if(line_stream.fail() == false)
|
Chris@49
|
2892 {
|
Chris@49
|
2893 T val_real = T(0);
|
Chris@49
|
2894
|
Chris@49
|
2895 ss.clear();
|
Chris@49
|
2896 ss.str(token_real);
|
Chris@49
|
2897
|
Chris@49
|
2898 ss >> val_real;
|
Chris@49
|
2899
|
Chris@49
|
2900 if(ss.fail() == false)
|
Chris@49
|
2901 {
|
Chris@49
|
2902 final_val_real = val_real;
|
Chris@49
|
2903 }
|
Chris@49
|
2904 else
|
Chris@49
|
2905 {
|
Chris@49
|
2906 val_real = T(0);
|
Chris@49
|
2907
|
Chris@49
|
2908 const bool success = diskio::convert_naninf( val_real, token_real );
|
Chris@49
|
2909
|
Chris@49
|
2910 if(success == true)
|
Chris@49
|
2911 {
|
Chris@49
|
2912 final_val_real = val_real;
|
Chris@49
|
2913 }
|
Chris@49
|
2914 }
|
Chris@49
|
2915 }
|
Chris@49
|
2916
|
Chris@49
|
2917
|
Chris@49
|
2918 line_stream >> token_imag;
|
Chris@49
|
2919
|
Chris@49
|
2920 if(line_stream.fail() == false)
|
Chris@49
|
2921 {
|
Chris@49
|
2922 T val_imag = T(0);
|
Chris@49
|
2923
|
Chris@49
|
2924 ss.clear();
|
Chris@49
|
2925 ss.str(token_imag);
|
Chris@49
|
2926
|
Chris@49
|
2927 ss >> val_imag;
|
Chris@49
|
2928
|
Chris@49
|
2929 if(ss.fail() == false)
|
Chris@49
|
2930 {
|
Chris@49
|
2931 final_val_imag = val_imag;
|
Chris@49
|
2932 }
|
Chris@49
|
2933 else
|
Chris@49
|
2934 {
|
Chris@49
|
2935 val_imag = T(0);
|
Chris@49
|
2936
|
Chris@49
|
2937 const bool success = diskio::convert_naninf( val_imag, token_imag );
|
Chris@49
|
2938
|
Chris@49
|
2939 if(success == true)
|
Chris@49
|
2940 {
|
Chris@49
|
2941 final_val_imag = val_imag;
|
Chris@49
|
2942 }
|
Chris@49
|
2943 }
|
Chris@49
|
2944 }
|
Chris@49
|
2945
|
Chris@49
|
2946
|
Chris@49
|
2947 if( (final_val_real != T(0)) || (final_val_imag != T(0)) )
|
Chris@49
|
2948 {
|
Chris@49
|
2949 if(weird_format == false)
|
Chris@49
|
2950 {
|
Chris@49
|
2951 access::rw(x.row_indices[pos]) = line_row;
|
Chris@49
|
2952 access::rw(x.values[pos]) = std::complex<T>(final_val_real, final_val_imag);
|
Chris@49
|
2953 ++access::rw(x.col_ptrs[line_col + 1]);
|
Chris@49
|
2954
|
Chris@49
|
2955 ++pos;
|
Chris@49
|
2956 }
|
Chris@49
|
2957 else
|
Chris@49
|
2958 {
|
Chris@49
|
2959 x.at(line_row,line_col) = std::complex<T>(final_val_real, final_val_imag);
|
Chris@49
|
2960 }
|
Chris@49
|
2961 }
|
Chris@49
|
2962 }
|
Chris@49
|
2963
|
Chris@49
|
2964
|
Chris@49
|
2965 if(weird_format == false)
|
Chris@49
|
2966 {
|
Chris@49
|
2967 for(uword c = 1; c <= f_n_cols; ++c)
|
Chris@49
|
2968 {
|
Chris@49
|
2969 access::rw(x.col_ptrs[c]) += x.col_ptrs[c - 1];
|
Chris@49
|
2970 }
|
Chris@49
|
2971 }
|
Chris@49
|
2972 }
|
Chris@49
|
2973
|
Chris@49
|
2974 return load_okay;
|
Chris@49
|
2975 }
|
Chris@49
|
2976
|
Chris@49
|
2977
|
Chris@49
|
2978
|
Chris@49
|
2979 //! Load a matrix in binary format,
|
Chris@49
|
2980 //! with a header that indicates the matrix type as well as its dimensions
|
Chris@49
|
2981 template<typename eT>
|
Chris@49
|
2982 inline
|
Chris@49
|
2983 bool
|
Chris@49
|
2984 diskio::load_arma_binary(SpMat<eT>& x, const std::string& name, std::string& err_msg)
|
Chris@49
|
2985 {
|
Chris@49
|
2986 arma_extra_debug_sigprint();
|
Chris@49
|
2987
|
Chris@49
|
2988 std::ifstream f;
|
Chris@49
|
2989 f.open(name.c_str(), std::fstream::binary);
|
Chris@49
|
2990
|
Chris@49
|
2991 bool load_okay = f.is_open();
|
Chris@49
|
2992
|
Chris@49
|
2993 if(load_okay == true)
|
Chris@49
|
2994 {
|
Chris@49
|
2995 load_okay = diskio::load_arma_binary(x, f, err_msg);
|
Chris@49
|
2996 f.close();
|
Chris@49
|
2997 }
|
Chris@49
|
2998
|
Chris@49
|
2999 return load_okay;
|
Chris@49
|
3000 }
|
Chris@49
|
3001
|
Chris@49
|
3002
|
Chris@49
|
3003
|
Chris@49
|
3004 template<typename eT>
|
Chris@49
|
3005 inline
|
Chris@49
|
3006 bool
|
Chris@49
|
3007 diskio::load_arma_binary(SpMat<eT>& x, std::istream& f, std::string& err_msg)
|
Chris@49
|
3008 {
|
Chris@49
|
3009 arma_extra_debug_sigprint();
|
Chris@49
|
3010
|
Chris@49
|
3011 bool load_okay = true;
|
Chris@49
|
3012
|
Chris@49
|
3013 std::string f_header;
|
Chris@49
|
3014
|
Chris@49
|
3015 f >> f_header;
|
Chris@49
|
3016
|
Chris@49
|
3017 if(f_header == diskio::gen_bin_header(x))
|
Chris@49
|
3018 {
|
Chris@49
|
3019 uword f_n_rows;
|
Chris@49
|
3020 uword f_n_cols;
|
Chris@49
|
3021 uword f_n_nz;
|
Chris@49
|
3022
|
Chris@49
|
3023 f >> f_n_rows;
|
Chris@49
|
3024 f >> f_n_cols;
|
Chris@49
|
3025 f >> f_n_nz;
|
Chris@49
|
3026
|
Chris@49
|
3027 //f.seekg(1, ios::cur); // NOTE: this may not be portable, as on a Windows machine a newline could be two characters
|
Chris@49
|
3028 f.get();
|
Chris@49
|
3029
|
Chris@49
|
3030 x.set_size(f_n_rows, f_n_cols);
|
Chris@49
|
3031
|
Chris@49
|
3032 x.mem_resize(f_n_nz);
|
Chris@49
|
3033
|
Chris@49
|
3034 f.read( reinterpret_cast<char*>(access::rwp(x.values)), std::streamsize(x.n_nonzero*sizeof(eT)) );
|
Chris@49
|
3035 f.read( reinterpret_cast<char*>(access::rwp(x.row_indices)), std::streamsize(x.n_nonzero*sizeof(uword)) );
|
Chris@49
|
3036 f.read( reinterpret_cast<char*>(access::rwp(x.col_ptrs)), std::streamsize((x.n_cols+1)*sizeof(uword)) );
|
Chris@49
|
3037
|
Chris@49
|
3038 load_okay = f.good();
|
Chris@49
|
3039 }
|
Chris@49
|
3040 else
|
Chris@49
|
3041 {
|
Chris@49
|
3042 load_okay = false;
|
Chris@49
|
3043 err_msg = "incorrect header in ";
|
Chris@49
|
3044 }
|
Chris@49
|
3045
|
Chris@49
|
3046 return load_okay;
|
Chris@49
|
3047 }
|
Chris@49
|
3048
|
Chris@49
|
3049
|
Chris@49
|
3050
|
Chris@49
|
3051 // cubes
|
Chris@49
|
3052
|
Chris@49
|
3053
|
Chris@49
|
3054
|
Chris@49
|
3055 //! Save a cube as raw text (no header, human readable).
|
Chris@49
|
3056 template<typename eT>
|
Chris@49
|
3057 inline
|
Chris@49
|
3058 bool
|
Chris@49
|
3059 diskio::save_raw_ascii(const Cube<eT>& x, const std::string& final_name)
|
Chris@49
|
3060 {
|
Chris@49
|
3061 arma_extra_debug_sigprint();
|
Chris@49
|
3062
|
Chris@49
|
3063 const std::string tmp_name = diskio::gen_tmp_name(final_name);
|
Chris@49
|
3064
|
Chris@49
|
3065 std::fstream f(tmp_name.c_str(), std::fstream::out);
|
Chris@49
|
3066
|
Chris@49
|
3067 bool save_okay = f.is_open();
|
Chris@49
|
3068
|
Chris@49
|
3069 if(save_okay == true)
|
Chris@49
|
3070 {
|
Chris@49
|
3071 save_okay = save_raw_ascii(x, f);
|
Chris@49
|
3072
|
Chris@49
|
3073 f.flush();
|
Chris@49
|
3074 f.close();
|
Chris@49
|
3075
|
Chris@49
|
3076 if(save_okay == true)
|
Chris@49
|
3077 {
|
Chris@49
|
3078 save_okay = diskio::safe_rename(tmp_name, final_name);
|
Chris@49
|
3079 }
|
Chris@49
|
3080 }
|
Chris@49
|
3081
|
Chris@49
|
3082 return save_okay;
|
Chris@49
|
3083 }
|
Chris@49
|
3084
|
Chris@49
|
3085
|
Chris@49
|
3086
|
Chris@49
|
3087 //! Save a cube as raw text (no header, human readable).
|
Chris@49
|
3088 template<typename eT>
|
Chris@49
|
3089 inline
|
Chris@49
|
3090 bool
|
Chris@49
|
3091 diskio::save_raw_ascii(const Cube<eT>& x, std::ostream& f)
|
Chris@49
|
3092 {
|
Chris@49
|
3093 arma_extra_debug_sigprint();
|
Chris@49
|
3094
|
Chris@49
|
3095 uword cell_width;
|
Chris@49
|
3096
|
Chris@49
|
3097 // TODO: need sane values for complex numbers
|
Chris@49
|
3098
|
Chris@49
|
3099 if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
|
Chris@49
|
3100 {
|
Chris@49
|
3101 f.setf(ios::scientific);
|
Chris@49
|
3102 f.precision(12);
|
Chris@49
|
3103 cell_width = 20;
|
Chris@49
|
3104 }
|
Chris@49
|
3105
|
Chris@49
|
3106 for(uword slice=0; slice < x.n_slices; ++slice)
|
Chris@49
|
3107 {
|
Chris@49
|
3108 for(uword row=0; row < x.n_rows; ++row)
|
Chris@49
|
3109 {
|
Chris@49
|
3110 for(uword col=0; col < x.n_cols; ++col)
|
Chris@49
|
3111 {
|
Chris@49
|
3112 f.put(' ');
|
Chris@49
|
3113
|
Chris@49
|
3114 if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
|
Chris@49
|
3115 {
|
Chris@49
|
3116 f.width(cell_width);
|
Chris@49
|
3117 }
|
Chris@49
|
3118
|
Chris@49
|
3119 f << x.at(row,col,slice);
|
Chris@49
|
3120 }
|
Chris@49
|
3121
|
Chris@49
|
3122 f.put('\n');
|
Chris@49
|
3123 }
|
Chris@49
|
3124 }
|
Chris@49
|
3125
|
Chris@49
|
3126 return f.good();
|
Chris@49
|
3127 }
|
Chris@49
|
3128
|
Chris@49
|
3129
|
Chris@49
|
3130
|
Chris@49
|
3131 //! Save a cube as raw binary (no header)
|
Chris@49
|
3132 template<typename eT>
|
Chris@49
|
3133 inline
|
Chris@49
|
3134 bool
|
Chris@49
|
3135 diskio::save_raw_binary(const Cube<eT>& x, const std::string& final_name)
|
Chris@49
|
3136 {
|
Chris@49
|
3137 arma_extra_debug_sigprint();
|
Chris@49
|
3138
|
Chris@49
|
3139 const std::string tmp_name = diskio::gen_tmp_name(final_name);
|
Chris@49
|
3140
|
Chris@49
|
3141 std::ofstream f(tmp_name.c_str(), std::fstream::binary);
|
Chris@49
|
3142
|
Chris@49
|
3143 bool save_okay = f.is_open();
|
Chris@49
|
3144
|
Chris@49
|
3145 if(save_okay == true)
|
Chris@49
|
3146 {
|
Chris@49
|
3147 save_okay = diskio::save_raw_binary(x, f);
|
Chris@49
|
3148
|
Chris@49
|
3149 f.flush();
|
Chris@49
|
3150 f.close();
|
Chris@49
|
3151
|
Chris@49
|
3152 if(save_okay == true)
|
Chris@49
|
3153 {
|
Chris@49
|
3154 save_okay = diskio::safe_rename(tmp_name, final_name);
|
Chris@49
|
3155 }
|
Chris@49
|
3156 }
|
Chris@49
|
3157
|
Chris@49
|
3158 return save_okay;
|
Chris@49
|
3159 }
|
Chris@49
|
3160
|
Chris@49
|
3161
|
Chris@49
|
3162
|
Chris@49
|
3163 template<typename eT>
|
Chris@49
|
3164 inline
|
Chris@49
|
3165 bool
|
Chris@49
|
3166 diskio::save_raw_binary(const Cube<eT>& x, std::ostream& f)
|
Chris@49
|
3167 {
|
Chris@49
|
3168 arma_extra_debug_sigprint();
|
Chris@49
|
3169
|
Chris@49
|
3170 f.write( reinterpret_cast<const char*>(x.mem), std::streamsize(x.n_elem*sizeof(eT)) );
|
Chris@49
|
3171
|
Chris@49
|
3172 return f.good();
|
Chris@49
|
3173 }
|
Chris@49
|
3174
|
Chris@49
|
3175
|
Chris@49
|
3176
|
Chris@49
|
3177 //! Save a cube in text format (human readable),
|
Chris@49
|
3178 //! with a header that indicates the cube type as well as its dimensions
|
Chris@49
|
3179 template<typename eT>
|
Chris@49
|
3180 inline
|
Chris@49
|
3181 bool
|
Chris@49
|
3182 diskio::save_arma_ascii(const Cube<eT>& x, const std::string& final_name)
|
Chris@49
|
3183 {
|
Chris@49
|
3184 arma_extra_debug_sigprint();
|
Chris@49
|
3185
|
Chris@49
|
3186 const std::string tmp_name = diskio::gen_tmp_name(final_name);
|
Chris@49
|
3187
|
Chris@49
|
3188 std::ofstream f(tmp_name.c_str());
|
Chris@49
|
3189
|
Chris@49
|
3190 bool save_okay = f.is_open();
|
Chris@49
|
3191
|
Chris@49
|
3192 if(save_okay == true)
|
Chris@49
|
3193 {
|
Chris@49
|
3194 save_okay = diskio::save_arma_ascii(x, f);
|
Chris@49
|
3195
|
Chris@49
|
3196 f.flush();
|
Chris@49
|
3197 f.close();
|
Chris@49
|
3198
|
Chris@49
|
3199 if(save_okay == true)
|
Chris@49
|
3200 {
|
Chris@49
|
3201 save_okay = diskio::safe_rename(tmp_name, final_name);
|
Chris@49
|
3202 }
|
Chris@49
|
3203 }
|
Chris@49
|
3204
|
Chris@49
|
3205 return save_okay;
|
Chris@49
|
3206 }
|
Chris@49
|
3207
|
Chris@49
|
3208
|
Chris@49
|
3209
|
Chris@49
|
3210 //! Save a cube in text format (human readable),
|
Chris@49
|
3211 //! with a header that indicates the cube type as well as its dimensions
|
Chris@49
|
3212 template<typename eT>
|
Chris@49
|
3213 inline
|
Chris@49
|
3214 bool
|
Chris@49
|
3215 diskio::save_arma_ascii(const Cube<eT>& x, std::ostream& f)
|
Chris@49
|
3216 {
|
Chris@49
|
3217 arma_extra_debug_sigprint();
|
Chris@49
|
3218
|
Chris@49
|
3219 const ios::fmtflags orig_flags = f.flags();
|
Chris@49
|
3220
|
Chris@49
|
3221 f << diskio::gen_txt_header(x) << '\n';
|
Chris@49
|
3222 f << x.n_rows << ' ' << x.n_cols << ' ' << x.n_slices << '\n';
|
Chris@49
|
3223
|
Chris@49
|
3224 uword cell_width;
|
Chris@49
|
3225
|
Chris@49
|
3226 // TODO: need sane values for complex numbers
|
Chris@49
|
3227
|
Chris@49
|
3228 if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
|
Chris@49
|
3229 {
|
Chris@49
|
3230 f.setf(ios::scientific);
|
Chris@49
|
3231 f.precision(12);
|
Chris@49
|
3232 cell_width = 20;
|
Chris@49
|
3233 }
|
Chris@49
|
3234
|
Chris@49
|
3235 for(uword slice=0; slice < x.n_slices; ++slice)
|
Chris@49
|
3236 {
|
Chris@49
|
3237 for(uword row=0; row < x.n_rows; ++row)
|
Chris@49
|
3238 {
|
Chris@49
|
3239 for(uword col=0; col < x.n_cols; ++col)
|
Chris@49
|
3240 {
|
Chris@49
|
3241 f.put(' ');
|
Chris@49
|
3242
|
Chris@49
|
3243 if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
|
Chris@49
|
3244 {
|
Chris@49
|
3245 f.width(cell_width);
|
Chris@49
|
3246 }
|
Chris@49
|
3247
|
Chris@49
|
3248 f << x.at(row,col,slice);
|
Chris@49
|
3249 }
|
Chris@49
|
3250
|
Chris@49
|
3251 f.put('\n');
|
Chris@49
|
3252 }
|
Chris@49
|
3253 }
|
Chris@49
|
3254
|
Chris@49
|
3255 const bool save_okay = f.good();
|
Chris@49
|
3256
|
Chris@49
|
3257 f.flags(orig_flags);
|
Chris@49
|
3258
|
Chris@49
|
3259 return save_okay;
|
Chris@49
|
3260 }
|
Chris@49
|
3261
|
Chris@49
|
3262
|
Chris@49
|
3263
|
Chris@49
|
3264 //! Save a cube in binary format,
|
Chris@49
|
3265 //! with a header that stores the cube type as well as its dimensions
|
Chris@49
|
3266 template<typename eT>
|
Chris@49
|
3267 inline
|
Chris@49
|
3268 bool
|
Chris@49
|
3269 diskio::save_arma_binary(const Cube<eT>& x, const std::string& final_name)
|
Chris@49
|
3270 {
|
Chris@49
|
3271 arma_extra_debug_sigprint();
|
Chris@49
|
3272
|
Chris@49
|
3273 const std::string tmp_name = diskio::gen_tmp_name(final_name);
|
Chris@49
|
3274
|
Chris@49
|
3275 std::ofstream f(tmp_name.c_str(), std::fstream::binary);
|
Chris@49
|
3276
|
Chris@49
|
3277 bool save_okay = f.is_open();
|
Chris@49
|
3278
|
Chris@49
|
3279 if(save_okay == true)
|
Chris@49
|
3280 {
|
Chris@49
|
3281 save_okay = diskio::save_arma_binary(x, f);
|
Chris@49
|
3282
|
Chris@49
|
3283 f.flush();
|
Chris@49
|
3284 f.close();
|
Chris@49
|
3285
|
Chris@49
|
3286 if(save_okay == true)
|
Chris@49
|
3287 {
|
Chris@49
|
3288 save_okay = diskio::safe_rename(tmp_name, final_name);
|
Chris@49
|
3289 }
|
Chris@49
|
3290 }
|
Chris@49
|
3291
|
Chris@49
|
3292 return save_okay;
|
Chris@49
|
3293 }
|
Chris@49
|
3294
|
Chris@49
|
3295
|
Chris@49
|
3296
|
Chris@49
|
3297 //! Save a cube in binary format,
|
Chris@49
|
3298 //! with a header that stores the cube type as well as its dimensions
|
Chris@49
|
3299 template<typename eT>
|
Chris@49
|
3300 inline
|
Chris@49
|
3301 bool
|
Chris@49
|
3302 diskio::save_arma_binary(const Cube<eT>& x, std::ostream& f)
|
Chris@49
|
3303 {
|
Chris@49
|
3304 arma_extra_debug_sigprint();
|
Chris@49
|
3305
|
Chris@49
|
3306 f << diskio::gen_bin_header(x) << '\n';
|
Chris@49
|
3307 f << x.n_rows << ' ' << x.n_cols << ' ' << x.n_slices << '\n';
|
Chris@49
|
3308
|
Chris@49
|
3309 f.write( reinterpret_cast<const char*>(x.mem), std::streamsize(x.n_elem*sizeof(eT)) );
|
Chris@49
|
3310
|
Chris@49
|
3311 return f.good();
|
Chris@49
|
3312 }
|
Chris@49
|
3313
|
Chris@49
|
3314
|
Chris@49
|
3315
|
Chris@49
|
3316 //! Save a cube as part of a HDF5 file
|
Chris@49
|
3317 template<typename eT>
|
Chris@49
|
3318 inline
|
Chris@49
|
3319 bool
|
Chris@49
|
3320 diskio::save_hdf5_binary(const Cube<eT>& x, const std::string& final_name)
|
Chris@49
|
3321 {
|
Chris@49
|
3322 arma_extra_debug_sigprint();
|
Chris@49
|
3323
|
Chris@49
|
3324 #if defined(ARMA_USE_HDF5)
|
Chris@49
|
3325 {
|
Chris@49
|
3326 #if !defined(ARMA_PRINT_HDF5_ERRORS)
|
Chris@49
|
3327 {
|
Chris@49
|
3328 // Disable annoying HDF5 error messages.
|
Chris@49
|
3329 H5Eset_auto(H5E_DEFAULT, NULL, NULL);
|
Chris@49
|
3330 }
|
Chris@49
|
3331 #endif
|
Chris@49
|
3332
|
Chris@49
|
3333 bool save_okay = false;
|
Chris@49
|
3334
|
Chris@49
|
3335 const std::string tmp_name = diskio::gen_tmp_name(final_name);
|
Chris@49
|
3336
|
Chris@49
|
3337 // Set up the file according to HDF5's preferences
|
Chris@49
|
3338 hid_t file = H5Fcreate(tmp_name.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
|
Chris@49
|
3339
|
Chris@49
|
3340 // We need to create a dataset, datatype, and dataspace
|
Chris@49
|
3341 hsize_t dims[3];
|
Chris@49
|
3342 dims[2] = x.n_rows;
|
Chris@49
|
3343 dims[1] = x.n_cols;
|
Chris@49
|
3344 dims[0] = x.n_slices;
|
Chris@49
|
3345
|
Chris@49
|
3346 hid_t dataspace = H5Screate_simple(3, dims, NULL); // treat the cube as a 3d array dataspace
|
Chris@49
|
3347 hid_t datatype = hdf5_misc::get_hdf5_type<eT>();
|
Chris@49
|
3348
|
Chris@49
|
3349 // If this returned something invalid, well, it's time to crash.
|
Chris@49
|
3350 arma_check(datatype == -1, "Cube::save(): unknown datatype for HDF5");
|
Chris@49
|
3351
|
Chris@49
|
3352 // MATLAB forces the users to specify a name at save time for HDF5; Octave
|
Chris@49
|
3353 // will use the default of 'dataset' unless otherwise specified, so we will
|
Chris@49
|
3354 // use that.
|
Chris@49
|
3355 hid_t dataset = H5Dcreate(file, "dataset", datatype, dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
|
Chris@49
|
3356
|
Chris@49
|
3357 herr_t status = H5Dwrite(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, x.mem);
|
Chris@49
|
3358 save_okay = (status >= 0);
|
Chris@49
|
3359
|
Chris@49
|
3360 H5Dclose(dataset);
|
Chris@49
|
3361 H5Tclose(datatype);
|
Chris@49
|
3362 H5Sclose(dataspace);
|
Chris@49
|
3363 H5Fclose(file);
|
Chris@49
|
3364
|
Chris@49
|
3365 if(save_okay == true) { save_okay = diskio::safe_rename(tmp_name, final_name); }
|
Chris@49
|
3366
|
Chris@49
|
3367 return save_okay;
|
Chris@49
|
3368 }
|
Chris@49
|
3369 #else
|
Chris@49
|
3370 {
|
Chris@49
|
3371 arma_ignore(x);
|
Chris@49
|
3372 arma_ignore(final_name);
|
Chris@49
|
3373
|
Chris@49
|
3374 arma_stop("Cube::save(): use of HDF5 needs to be enabled");
|
Chris@49
|
3375
|
Chris@49
|
3376 return false;
|
Chris@49
|
3377 }
|
Chris@49
|
3378 #endif
|
Chris@49
|
3379 }
|
Chris@49
|
3380
|
Chris@49
|
3381
|
Chris@49
|
3382
|
Chris@49
|
3383 //! Load a cube as raw text (no header, human readable).
|
Chris@49
|
3384 //! NOTE: this is much slower than reading a file with a header.
|
Chris@49
|
3385 template<typename eT>
|
Chris@49
|
3386 inline
|
Chris@49
|
3387 bool
|
Chris@49
|
3388 diskio::load_raw_ascii(Cube<eT>& x, const std::string& name, std::string& err_msg)
|
Chris@49
|
3389 {
|
Chris@49
|
3390 arma_extra_debug_sigprint();
|
Chris@49
|
3391
|
Chris@49
|
3392 Mat<eT> tmp;
|
Chris@49
|
3393 const bool load_okay = diskio::load_raw_ascii(tmp, name, err_msg);
|
Chris@49
|
3394
|
Chris@49
|
3395 if(load_okay == true)
|
Chris@49
|
3396 {
|
Chris@49
|
3397 if(tmp.is_empty() == false)
|
Chris@49
|
3398 {
|
Chris@49
|
3399 x.set_size(tmp.n_rows, tmp.n_cols, 1);
|
Chris@49
|
3400
|
Chris@49
|
3401 x.slice(0) = tmp;
|
Chris@49
|
3402 }
|
Chris@49
|
3403 else
|
Chris@49
|
3404 {
|
Chris@49
|
3405 x.reset();
|
Chris@49
|
3406 }
|
Chris@49
|
3407 }
|
Chris@49
|
3408
|
Chris@49
|
3409 return load_okay;
|
Chris@49
|
3410 }
|
Chris@49
|
3411
|
Chris@49
|
3412
|
Chris@49
|
3413
|
Chris@49
|
3414 //! Load a cube as raw text (no header, human readable).
|
Chris@49
|
3415 //! NOTE: this is much slower than reading a file with a header.
|
Chris@49
|
3416 template<typename eT>
|
Chris@49
|
3417 inline
|
Chris@49
|
3418 bool
|
Chris@49
|
3419 diskio::load_raw_ascii(Cube<eT>& x, std::istream& f, std::string& err_msg)
|
Chris@49
|
3420 {
|
Chris@49
|
3421 arma_extra_debug_sigprint();
|
Chris@49
|
3422
|
Chris@49
|
3423 Mat<eT> tmp;
|
Chris@49
|
3424 const bool load_okay = diskio::load_raw_ascii(tmp, f, err_msg);
|
Chris@49
|
3425
|
Chris@49
|
3426 if(load_okay == true)
|
Chris@49
|
3427 {
|
Chris@49
|
3428 if(tmp.is_empty() == false)
|
Chris@49
|
3429 {
|
Chris@49
|
3430 x.set_size(tmp.n_rows, tmp.n_cols, 1);
|
Chris@49
|
3431
|
Chris@49
|
3432 x.slice(0) = tmp;
|
Chris@49
|
3433 }
|
Chris@49
|
3434 else
|
Chris@49
|
3435 {
|
Chris@49
|
3436 x.reset();
|
Chris@49
|
3437 }
|
Chris@49
|
3438 }
|
Chris@49
|
3439
|
Chris@49
|
3440 return load_okay;
|
Chris@49
|
3441 }
|
Chris@49
|
3442
|
Chris@49
|
3443
|
Chris@49
|
3444
|
Chris@49
|
3445 //! Load a cube in binary format (no header);
|
Chris@49
|
3446 //! the cube is assumed to have one slice with one column
|
Chris@49
|
3447 template<typename eT>
|
Chris@49
|
3448 inline
|
Chris@49
|
3449 bool
|
Chris@49
|
3450 diskio::load_raw_binary(Cube<eT>& x, const std::string& name, std::string& err_msg)
|
Chris@49
|
3451 {
|
Chris@49
|
3452 arma_extra_debug_sigprint();
|
Chris@49
|
3453
|
Chris@49
|
3454 std::ifstream f;
|
Chris@49
|
3455 f.open(name.c_str(), std::fstream::binary);
|
Chris@49
|
3456
|
Chris@49
|
3457 bool load_okay = f.is_open();
|
Chris@49
|
3458
|
Chris@49
|
3459 if(load_okay == true)
|
Chris@49
|
3460 {
|
Chris@49
|
3461 load_okay = diskio::load_raw_binary(x, f, err_msg);
|
Chris@49
|
3462 f.close();
|
Chris@49
|
3463 }
|
Chris@49
|
3464
|
Chris@49
|
3465 return load_okay;
|
Chris@49
|
3466 }
|
Chris@49
|
3467
|
Chris@49
|
3468
|
Chris@49
|
3469
|
Chris@49
|
3470 template<typename eT>
|
Chris@49
|
3471 inline
|
Chris@49
|
3472 bool
|
Chris@49
|
3473 diskio::load_raw_binary(Cube<eT>& x, std::istream& f, std::string& err_msg)
|
Chris@49
|
3474 {
|
Chris@49
|
3475 arma_extra_debug_sigprint();
|
Chris@49
|
3476 arma_ignore(err_msg);
|
Chris@49
|
3477
|
Chris@49
|
3478 f.clear();
|
Chris@49
|
3479 const std::streampos pos1 = f.tellg();
|
Chris@49
|
3480
|
Chris@49
|
3481 f.clear();
|
Chris@49
|
3482 f.seekg(0, ios::end);
|
Chris@49
|
3483
|
Chris@49
|
3484 f.clear();
|
Chris@49
|
3485 const std::streampos pos2 = f.tellg();
|
Chris@49
|
3486
|
Chris@49
|
3487 const uword N = ( (pos1 >= 0) && (pos2 >= 0) ) ? uword(pos2 - pos1) : 0;
|
Chris@49
|
3488
|
Chris@49
|
3489 f.clear();
|
Chris@49
|
3490 //f.seekg(0, ios::beg);
|
Chris@49
|
3491 f.seekg(pos1);
|
Chris@49
|
3492
|
Chris@49
|
3493 x.set_size(N / sizeof(eT), 1, 1);
|
Chris@49
|
3494
|
Chris@49
|
3495 f.clear();
|
Chris@49
|
3496 f.read( reinterpret_cast<char *>(x.memptr()), std::streamsize(N) );
|
Chris@49
|
3497
|
Chris@49
|
3498 return f.good();
|
Chris@49
|
3499 }
|
Chris@49
|
3500
|
Chris@49
|
3501
|
Chris@49
|
3502
|
Chris@49
|
3503 //! Load a cube in text format (human readable),
|
Chris@49
|
3504 //! with a header that indicates the cube type as well as its dimensions
|
Chris@49
|
3505 template<typename eT>
|
Chris@49
|
3506 inline
|
Chris@49
|
3507 bool
|
Chris@49
|
3508 diskio::load_arma_ascii(Cube<eT>& x, const std::string& name, std::string& err_msg)
|
Chris@49
|
3509 {
|
Chris@49
|
3510 arma_extra_debug_sigprint();
|
Chris@49
|
3511
|
Chris@49
|
3512 std::ifstream f(name.c_str());
|
Chris@49
|
3513
|
Chris@49
|
3514 bool load_okay = f.is_open();
|
Chris@49
|
3515
|
Chris@49
|
3516 if(load_okay == true)
|
Chris@49
|
3517 {
|
Chris@49
|
3518 load_okay = diskio::load_arma_ascii(x, f, err_msg);
|
Chris@49
|
3519 f.close();
|
Chris@49
|
3520 }
|
Chris@49
|
3521
|
Chris@49
|
3522 return load_okay;
|
Chris@49
|
3523 }
|
Chris@49
|
3524
|
Chris@49
|
3525
|
Chris@49
|
3526
|
Chris@49
|
3527 //! Load a cube in text format (human readable),
|
Chris@49
|
3528 //! with a header that indicates the cube type as well as its dimensions
|
Chris@49
|
3529 template<typename eT>
|
Chris@49
|
3530 inline
|
Chris@49
|
3531 bool
|
Chris@49
|
3532 diskio::load_arma_ascii(Cube<eT>& x, std::istream& f, std::string& err_msg)
|
Chris@49
|
3533 {
|
Chris@49
|
3534 arma_extra_debug_sigprint();
|
Chris@49
|
3535
|
Chris@49
|
3536 bool load_okay = true;
|
Chris@49
|
3537
|
Chris@49
|
3538 std::string f_header;
|
Chris@49
|
3539 uword f_n_rows;
|
Chris@49
|
3540 uword f_n_cols;
|
Chris@49
|
3541 uword f_n_slices;
|
Chris@49
|
3542
|
Chris@49
|
3543 f >> f_header;
|
Chris@49
|
3544 f >> f_n_rows;
|
Chris@49
|
3545 f >> f_n_cols;
|
Chris@49
|
3546 f >> f_n_slices;
|
Chris@49
|
3547
|
Chris@49
|
3548 if(f_header == diskio::gen_txt_header(x))
|
Chris@49
|
3549 {
|
Chris@49
|
3550 x.set_size(f_n_rows, f_n_cols, f_n_slices);
|
Chris@49
|
3551
|
Chris@49
|
3552 for(uword slice=0; slice < x.n_slices; ++slice)
|
Chris@49
|
3553 {
|
Chris@49
|
3554 for(uword row=0; row < x.n_rows; ++row)
|
Chris@49
|
3555 {
|
Chris@49
|
3556 for(uword col=0; col < x.n_cols; ++col)
|
Chris@49
|
3557 {
|
Chris@49
|
3558 f >> x.at(row,col,slice);
|
Chris@49
|
3559 }
|
Chris@49
|
3560 }
|
Chris@49
|
3561 }
|
Chris@49
|
3562
|
Chris@49
|
3563 load_okay = f.good();
|
Chris@49
|
3564 }
|
Chris@49
|
3565 else
|
Chris@49
|
3566 {
|
Chris@49
|
3567 load_okay = false;
|
Chris@49
|
3568 err_msg = "incorrect header in ";
|
Chris@49
|
3569 }
|
Chris@49
|
3570
|
Chris@49
|
3571 return load_okay;
|
Chris@49
|
3572 }
|
Chris@49
|
3573
|
Chris@49
|
3574
|
Chris@49
|
3575
|
Chris@49
|
3576 //! Load a cube in binary format,
|
Chris@49
|
3577 //! with a header that indicates the cube type as well as its dimensions
|
Chris@49
|
3578 template<typename eT>
|
Chris@49
|
3579 inline
|
Chris@49
|
3580 bool
|
Chris@49
|
3581 diskio::load_arma_binary(Cube<eT>& x, const std::string& name, std::string& err_msg)
|
Chris@49
|
3582 {
|
Chris@49
|
3583 arma_extra_debug_sigprint();
|
Chris@49
|
3584
|
Chris@49
|
3585 std::ifstream f;
|
Chris@49
|
3586 f.open(name.c_str(), std::fstream::binary);
|
Chris@49
|
3587
|
Chris@49
|
3588 bool load_okay = f.is_open();
|
Chris@49
|
3589
|
Chris@49
|
3590 if(load_okay == true)
|
Chris@49
|
3591 {
|
Chris@49
|
3592 load_okay = diskio::load_arma_binary(x, f, err_msg);
|
Chris@49
|
3593 f.close();
|
Chris@49
|
3594 }
|
Chris@49
|
3595
|
Chris@49
|
3596 return load_okay;
|
Chris@49
|
3597 }
|
Chris@49
|
3598
|
Chris@49
|
3599
|
Chris@49
|
3600
|
Chris@49
|
3601 template<typename eT>
|
Chris@49
|
3602 inline
|
Chris@49
|
3603 bool
|
Chris@49
|
3604 diskio::load_arma_binary(Cube<eT>& x, std::istream& f, std::string& err_msg)
|
Chris@49
|
3605 {
|
Chris@49
|
3606 arma_extra_debug_sigprint();
|
Chris@49
|
3607
|
Chris@49
|
3608 bool load_okay = true;
|
Chris@49
|
3609
|
Chris@49
|
3610 std::string f_header;
|
Chris@49
|
3611 uword f_n_rows;
|
Chris@49
|
3612 uword f_n_cols;
|
Chris@49
|
3613 uword f_n_slices;
|
Chris@49
|
3614
|
Chris@49
|
3615 f >> f_header;
|
Chris@49
|
3616 f >> f_n_rows;
|
Chris@49
|
3617 f >> f_n_cols;
|
Chris@49
|
3618 f >> f_n_slices;
|
Chris@49
|
3619
|
Chris@49
|
3620 if(f_header == diskio::gen_bin_header(x))
|
Chris@49
|
3621 {
|
Chris@49
|
3622 //f.seekg(1, ios::cur); // NOTE: this may not be portable, as on a Windows machine a newline could be two characters
|
Chris@49
|
3623 f.get();
|
Chris@49
|
3624
|
Chris@49
|
3625 x.set_size(f_n_rows, f_n_cols, f_n_slices);
|
Chris@49
|
3626 f.read( reinterpret_cast<char *>(x.memptr()), std::streamsize(x.n_elem*sizeof(eT)) );
|
Chris@49
|
3627
|
Chris@49
|
3628 load_okay = f.good();
|
Chris@49
|
3629 }
|
Chris@49
|
3630 else
|
Chris@49
|
3631 {
|
Chris@49
|
3632 load_okay = false;
|
Chris@49
|
3633 err_msg = "incorrect header in ";
|
Chris@49
|
3634 }
|
Chris@49
|
3635
|
Chris@49
|
3636 return load_okay;
|
Chris@49
|
3637 }
|
Chris@49
|
3638
|
Chris@49
|
3639
|
Chris@49
|
3640
|
Chris@49
|
3641 //! Load a HDF5 file as a cube
|
Chris@49
|
3642 template<typename eT>
|
Chris@49
|
3643 inline
|
Chris@49
|
3644 bool
|
Chris@49
|
3645 diskio::load_hdf5_binary(Cube<eT>& x, const std::string& name, std::string& err_msg)
|
Chris@49
|
3646 {
|
Chris@49
|
3647 arma_extra_debug_sigprint();
|
Chris@49
|
3648
|
Chris@49
|
3649 #if defined(ARMA_USE_HDF5)
|
Chris@49
|
3650 {
|
Chris@49
|
3651
|
Chris@49
|
3652 // These may be necessary to store the error handler (if we need to).
|
Chris@49
|
3653 herr_t (*old_func)(hid_t, void*);
|
Chris@49
|
3654 void *old_client_data;
|
Chris@49
|
3655
|
Chris@49
|
3656 #if !defined(ARMA_PRINT_HDF5_ERRORS)
|
Chris@49
|
3657 {
|
Chris@49
|
3658 // Save old error handler.
|
Chris@49
|
3659 H5Eget_auto(H5E_DEFAULT, &old_func, &old_client_data);
|
Chris@49
|
3660
|
Chris@49
|
3661 // Disable annoying HDF5 error messages.
|
Chris@49
|
3662 H5Eset_auto(H5E_DEFAULT, NULL, NULL);
|
Chris@49
|
3663 }
|
Chris@49
|
3664 #endif
|
Chris@49
|
3665
|
Chris@49
|
3666 bool load_okay = false;
|
Chris@49
|
3667
|
Chris@49
|
3668 hid_t fid = H5Fopen(name.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
|
Chris@49
|
3669
|
Chris@49
|
3670 if(fid >= 0)
|
Chris@49
|
3671 {
|
Chris@49
|
3672 // MATLAB HDF5 dataset names are user-specified;
|
Chris@49
|
3673 // Octave tends to store the datasets in a group, with the actual dataset being referred to as "value".
|
Chris@49
|
3674 // So we will search for "dataset" and "value", and if those are not found we will take the first dataset we do find.
|
Chris@49
|
3675 std::vector<std::string> searchNames;
|
Chris@49
|
3676 searchNames.push_back("dataset");
|
Chris@49
|
3677 searchNames.push_back("value");
|
Chris@49
|
3678
|
Chris@49
|
3679 hid_t dataset = hdf5_misc::search_hdf5_file(searchNames, fid, 3, false);
|
Chris@49
|
3680
|
Chris@49
|
3681 if(dataset >= 0)
|
Chris@49
|
3682 {
|
Chris@49
|
3683 hid_t filespace = H5Dget_space(dataset);
|
Chris@49
|
3684
|
Chris@49
|
3685 // This must be <= 3 due to our search rules.
|
Chris@49
|
3686 const int ndims = H5Sget_simple_extent_ndims(filespace);
|
Chris@49
|
3687
|
Chris@49
|
3688 hsize_t dims[3];
|
Chris@49
|
3689 const herr_t query_status = H5Sget_simple_extent_dims(filespace, dims, NULL);
|
Chris@49
|
3690
|
Chris@49
|
3691 // arma_check(query_status < 0, "Cube::load(): cannot get size of HDF5 dataset");
|
Chris@49
|
3692 if(query_status < 0)
|
Chris@49
|
3693 {
|
Chris@49
|
3694 err_msg = "cannot get size of HDF5 dataset in ";
|
Chris@49
|
3695
|
Chris@49
|
3696 H5Sclose(filespace);
|
Chris@49
|
3697 H5Dclose(dataset);
|
Chris@49
|
3698 H5Fclose(fid);
|
Chris@49
|
3699
|
Chris@49
|
3700 #if !defined(ARMA_PRINT_HDF5_ERRORS)
|
Chris@49
|
3701 {
|
Chris@49
|
3702 // Restore HDF5 error handler.
|
Chris@49
|
3703 H5Eset_auto(H5E_DEFAULT, old_func, old_client_data);
|
Chris@49
|
3704 }
|
Chris@49
|
3705 #endif
|
Chris@49
|
3706
|
Chris@49
|
3707 return false;
|
Chris@49
|
3708 }
|
Chris@49
|
3709
|
Chris@49
|
3710 if (ndims == 1) { dims[1] = 1; dims[2] = 1; } // Vector case; one row/colum, several slices
|
Chris@49
|
3711 if (ndims == 2) { dims[2] = 1; } // Matrix case; one column, several rows/slices
|
Chris@49
|
3712
|
Chris@49
|
3713 x.set_size(dims[2], dims[1], dims[0]);
|
Chris@49
|
3714
|
Chris@49
|
3715 // Now we have to see what type is stored to figure out how to load it.
|
Chris@49
|
3716 hid_t datatype = H5Dget_type(dataset);
|
Chris@49
|
3717 hid_t mat_type = hdf5_misc::get_hdf5_type<eT>();
|
Chris@49
|
3718
|
Chris@49
|
3719 // If these are the same type, it is simple.
|
Chris@49
|
3720 if(H5Tequal(datatype, mat_type) > 0)
|
Chris@49
|
3721 {
|
Chris@49
|
3722 // Load directly; H5S_ALL used so that we load the entire dataset.
|
Chris@49
|
3723 hid_t read_status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(x.memptr()));
|
Chris@49
|
3724
|
Chris@49
|
3725 if(read_status >= 0) { load_okay = true; }
|
Chris@49
|
3726 }
|
Chris@49
|
3727 else
|
Chris@49
|
3728 {
|
Chris@49
|
3729 // Load into another array and convert its type accordingly.
|
Chris@49
|
3730 hid_t read_status = hdf5_misc::load_and_convert_hdf5(x.memptr(), dataset, datatype, x.n_elem);
|
Chris@49
|
3731
|
Chris@49
|
3732 if(read_status >= 0) { load_okay = true; }
|
Chris@49
|
3733 }
|
Chris@49
|
3734
|
Chris@49
|
3735 // Now clean up.
|
Chris@49
|
3736 H5Tclose(datatype);
|
Chris@49
|
3737 H5Tclose(mat_type);
|
Chris@49
|
3738 H5Sclose(filespace);
|
Chris@49
|
3739 }
|
Chris@49
|
3740
|
Chris@49
|
3741 H5Dclose(dataset);
|
Chris@49
|
3742
|
Chris@49
|
3743 H5Fclose(fid);
|
Chris@49
|
3744
|
Chris@49
|
3745 if(load_okay == false)
|
Chris@49
|
3746 {
|
Chris@49
|
3747 err_msg = "unsupported or incorrect HDF5 data in ";
|
Chris@49
|
3748 }
|
Chris@49
|
3749 }
|
Chris@49
|
3750 else
|
Chris@49
|
3751 {
|
Chris@49
|
3752 err_msg = "cannot open file ";
|
Chris@49
|
3753 }
|
Chris@49
|
3754
|
Chris@49
|
3755 #if !defined(ARMA_PRINT_HDF5_ERRORS)
|
Chris@49
|
3756 {
|
Chris@49
|
3757 // Restore HDF5 error handler.
|
Chris@49
|
3758 H5Eset_auto(H5E_DEFAULT, old_func, old_client_data);
|
Chris@49
|
3759 }
|
Chris@49
|
3760 #endif
|
Chris@49
|
3761
|
Chris@49
|
3762 return load_okay;
|
Chris@49
|
3763 }
|
Chris@49
|
3764 #else
|
Chris@49
|
3765 {
|
Chris@49
|
3766 arma_ignore(x);
|
Chris@49
|
3767 arma_ignore(name);
|
Chris@49
|
3768 arma_ignore(err_msg);
|
Chris@49
|
3769
|
Chris@49
|
3770 arma_stop("Cube::load(): use of HDF5 needs to be enabled");
|
Chris@49
|
3771
|
Chris@49
|
3772 return false;
|
Chris@49
|
3773 }
|
Chris@49
|
3774 #endif
|
Chris@49
|
3775 }
|
Chris@49
|
3776
|
Chris@49
|
3777
|
Chris@49
|
3778
|
Chris@49
|
3779 //! Try to load a cube by automatically determining its type
|
Chris@49
|
3780 template<typename eT>
|
Chris@49
|
3781 inline
|
Chris@49
|
3782 bool
|
Chris@49
|
3783 diskio::load_auto_detect(Cube<eT>& x, const std::string& name, std::string& err_msg)
|
Chris@49
|
3784 {
|
Chris@49
|
3785 arma_extra_debug_sigprint();
|
Chris@49
|
3786
|
Chris@49
|
3787 #if defined(ARMA_USE_HDF5)
|
Chris@49
|
3788 // We're currently using the C bindings for the HDF5 library, which don't support C++ streams
|
Chris@49
|
3789 if( H5Fis_hdf5(name.c_str()) ) { return load_hdf5_binary(x, name, err_msg); }
|
Chris@49
|
3790 #endif
|
Chris@49
|
3791
|
Chris@49
|
3792 std::fstream f;
|
Chris@49
|
3793 f.open(name.c_str(), std::fstream::in | std::fstream::binary);
|
Chris@49
|
3794
|
Chris@49
|
3795 bool load_okay = f.is_open();
|
Chris@49
|
3796
|
Chris@49
|
3797 if(load_okay == true)
|
Chris@49
|
3798 {
|
Chris@49
|
3799 load_okay = diskio::load_auto_detect(x, f, err_msg);
|
Chris@49
|
3800 f.close();
|
Chris@49
|
3801 }
|
Chris@49
|
3802
|
Chris@49
|
3803 return load_okay;
|
Chris@49
|
3804 }
|
Chris@49
|
3805
|
Chris@49
|
3806
|
Chris@49
|
3807
|
Chris@49
|
3808 //! Try to load a cube by automatically determining its type
|
Chris@49
|
3809 template<typename eT>
|
Chris@49
|
3810 inline
|
Chris@49
|
3811 bool
|
Chris@49
|
3812 diskio::load_auto_detect(Cube<eT>& x, std::istream& f, std::string& err_msg)
|
Chris@49
|
3813 {
|
Chris@49
|
3814 arma_extra_debug_sigprint();
|
Chris@49
|
3815
|
Chris@49
|
3816 static const std::string ARMA_CUB_TXT = "ARMA_CUB_TXT";
|
Chris@49
|
3817 static const std::string ARMA_CUB_BIN = "ARMA_CUB_BIN";
|
Chris@49
|
3818 static const std::string P6 = "P6";
|
Chris@49
|
3819
|
Chris@49
|
3820 podarray<char> raw_header(ARMA_CUB_TXT.length() + 1);
|
Chris@49
|
3821
|
Chris@49
|
3822 std::streampos pos = f.tellg();
|
Chris@49
|
3823
|
Chris@49
|
3824 f.read( raw_header.memptr(), std::streamsize(ARMA_CUB_TXT.length()) );
|
Chris@49
|
3825 raw_header[ARMA_CUB_TXT.length()] = '\0';
|
Chris@49
|
3826
|
Chris@49
|
3827 f.clear();
|
Chris@49
|
3828 f.seekg(pos);
|
Chris@49
|
3829
|
Chris@49
|
3830 const std::string header = raw_header.mem;
|
Chris@49
|
3831
|
Chris@49
|
3832 if(ARMA_CUB_TXT == header.substr(0, ARMA_CUB_TXT.length()))
|
Chris@49
|
3833 {
|
Chris@49
|
3834 return load_arma_ascii(x, f, err_msg);
|
Chris@49
|
3835 }
|
Chris@49
|
3836 else
|
Chris@49
|
3837 if(ARMA_CUB_BIN == header.substr(0, ARMA_CUB_BIN.length()))
|
Chris@49
|
3838 {
|
Chris@49
|
3839 return load_arma_binary(x, f, err_msg);
|
Chris@49
|
3840 }
|
Chris@49
|
3841 else
|
Chris@49
|
3842 if(P6 == header.substr(0, P6.length()))
|
Chris@49
|
3843 {
|
Chris@49
|
3844 return load_ppm_binary(x, f, err_msg);
|
Chris@49
|
3845 }
|
Chris@49
|
3846 else
|
Chris@49
|
3847 {
|
Chris@49
|
3848 const file_type ft = guess_file_type(f);
|
Chris@49
|
3849
|
Chris@49
|
3850 switch(ft)
|
Chris@49
|
3851 {
|
Chris@49
|
3852 // case csv_ascii:
|
Chris@49
|
3853 // return load_csv_ascii(x, f, err_msg);
|
Chris@49
|
3854 // break;
|
Chris@49
|
3855
|
Chris@49
|
3856 case raw_binary:
|
Chris@49
|
3857 return load_raw_binary(x, f, err_msg);
|
Chris@49
|
3858 break;
|
Chris@49
|
3859
|
Chris@49
|
3860 case raw_ascii:
|
Chris@49
|
3861 return load_raw_ascii(x, f, err_msg);
|
Chris@49
|
3862 break;
|
Chris@49
|
3863
|
Chris@49
|
3864 default:
|
Chris@49
|
3865 err_msg = "unknown data in ";
|
Chris@49
|
3866 return false;
|
Chris@49
|
3867 }
|
Chris@49
|
3868 }
|
Chris@49
|
3869
|
Chris@49
|
3870 return false;
|
Chris@49
|
3871 }
|
Chris@49
|
3872
|
Chris@49
|
3873
|
Chris@49
|
3874
|
Chris@49
|
3875
|
Chris@49
|
3876
|
Chris@49
|
3877 // fields
|
Chris@49
|
3878
|
Chris@49
|
3879
|
Chris@49
|
3880
|
Chris@49
|
3881 template<typename T1>
|
Chris@49
|
3882 inline
|
Chris@49
|
3883 bool
|
Chris@49
|
3884 diskio::save_arma_binary(const field<T1>& x, const std::string& final_name)
|
Chris@49
|
3885 {
|
Chris@49
|
3886 arma_extra_debug_sigprint();
|
Chris@49
|
3887
|
Chris@49
|
3888 const std::string tmp_name = diskio::gen_tmp_name(final_name);
|
Chris@49
|
3889
|
Chris@49
|
3890 std::ofstream f( tmp_name.c_str(), std::fstream::binary );
|
Chris@49
|
3891
|
Chris@49
|
3892 bool save_okay = f.is_open();
|
Chris@49
|
3893
|
Chris@49
|
3894 if(save_okay == true)
|
Chris@49
|
3895 {
|
Chris@49
|
3896 save_okay = diskio::save_arma_binary(x, f);
|
Chris@49
|
3897
|
Chris@49
|
3898 f.flush();
|
Chris@49
|
3899 f.close();
|
Chris@49
|
3900
|
Chris@49
|
3901 if(save_okay == true)
|
Chris@49
|
3902 {
|
Chris@49
|
3903 save_okay = diskio::safe_rename(tmp_name, final_name);
|
Chris@49
|
3904 }
|
Chris@49
|
3905 }
|
Chris@49
|
3906
|
Chris@49
|
3907 return save_okay;
|
Chris@49
|
3908 }
|
Chris@49
|
3909
|
Chris@49
|
3910
|
Chris@49
|
3911
|
Chris@49
|
3912 template<typename T1>
|
Chris@49
|
3913 inline
|
Chris@49
|
3914 bool
|
Chris@49
|
3915 diskio::save_arma_binary(const field<T1>& x, std::ostream& f)
|
Chris@49
|
3916 {
|
Chris@49
|
3917 arma_extra_debug_sigprint();
|
Chris@49
|
3918
|
Chris@49
|
3919 arma_type_check(( (is_Mat<T1>::value == false) && (is_Cube<T1>::value == false) ));
|
Chris@49
|
3920
|
Chris@49
|
3921 f << "ARMA_FLD_BIN" << '\n';
|
Chris@49
|
3922 f << x.n_rows << '\n';
|
Chris@49
|
3923 f << x.n_cols << '\n';
|
Chris@49
|
3924
|
Chris@49
|
3925 bool save_okay = true;
|
Chris@49
|
3926
|
Chris@49
|
3927 for(uword i=0; i<x.n_elem; ++i)
|
Chris@49
|
3928 {
|
Chris@49
|
3929 save_okay = diskio::save_arma_binary(x[i], f);
|
Chris@49
|
3930
|
Chris@49
|
3931 if(save_okay == false)
|
Chris@49
|
3932 {
|
Chris@49
|
3933 break;
|
Chris@49
|
3934 }
|
Chris@49
|
3935 }
|
Chris@49
|
3936
|
Chris@49
|
3937 return save_okay;
|
Chris@49
|
3938 }
|
Chris@49
|
3939
|
Chris@49
|
3940
|
Chris@49
|
3941
|
Chris@49
|
3942 template<typename T1>
|
Chris@49
|
3943 inline
|
Chris@49
|
3944 bool
|
Chris@49
|
3945 diskio::load_arma_binary(field<T1>& x, const std::string& name, std::string& err_msg)
|
Chris@49
|
3946 {
|
Chris@49
|
3947 arma_extra_debug_sigprint();
|
Chris@49
|
3948
|
Chris@49
|
3949 std::ifstream f( name.c_str(), std::fstream::binary );
|
Chris@49
|
3950
|
Chris@49
|
3951 bool load_okay = f.is_open();
|
Chris@49
|
3952
|
Chris@49
|
3953 if(load_okay == true)
|
Chris@49
|
3954 {
|
Chris@49
|
3955 load_okay = diskio::load_arma_binary(x, f, err_msg);
|
Chris@49
|
3956 f.close();
|
Chris@49
|
3957 }
|
Chris@49
|
3958
|
Chris@49
|
3959 return load_okay;
|
Chris@49
|
3960 }
|
Chris@49
|
3961
|
Chris@49
|
3962
|
Chris@49
|
3963
|
Chris@49
|
3964 template<typename T1>
|
Chris@49
|
3965 inline
|
Chris@49
|
3966 bool
|
Chris@49
|
3967 diskio::load_arma_binary(field<T1>& x, std::istream& f, std::string& err_msg)
|
Chris@49
|
3968 {
|
Chris@49
|
3969 arma_extra_debug_sigprint();
|
Chris@49
|
3970
|
Chris@49
|
3971 arma_type_check(( (is_Mat<T1>::value == false) && (is_Cube<T1>::value == false) ));
|
Chris@49
|
3972
|
Chris@49
|
3973 bool load_okay = true;
|
Chris@49
|
3974
|
Chris@49
|
3975 std::string f_type;
|
Chris@49
|
3976 f >> f_type;
|
Chris@49
|
3977
|
Chris@49
|
3978 if(f_type != "ARMA_FLD_BIN")
|
Chris@49
|
3979 {
|
Chris@49
|
3980 load_okay = false;
|
Chris@49
|
3981 err_msg = "unsupported field type in ";
|
Chris@49
|
3982 }
|
Chris@49
|
3983 else
|
Chris@49
|
3984 {
|
Chris@49
|
3985 uword f_n_rows;
|
Chris@49
|
3986 uword f_n_cols;
|
Chris@49
|
3987
|
Chris@49
|
3988 f >> f_n_rows;
|
Chris@49
|
3989 f >> f_n_cols;
|
Chris@49
|
3990
|
Chris@49
|
3991 x.set_size(f_n_rows, f_n_cols);
|
Chris@49
|
3992
|
Chris@49
|
3993 f.get();
|
Chris@49
|
3994
|
Chris@49
|
3995 for(uword i=0; i<x.n_elem; ++i)
|
Chris@49
|
3996 {
|
Chris@49
|
3997 load_okay = diskio::load_arma_binary(x[i], f, err_msg);
|
Chris@49
|
3998
|
Chris@49
|
3999 if(load_okay == false)
|
Chris@49
|
4000 {
|
Chris@49
|
4001 break;
|
Chris@49
|
4002 }
|
Chris@49
|
4003 }
|
Chris@49
|
4004 }
|
Chris@49
|
4005
|
Chris@49
|
4006 return load_okay;
|
Chris@49
|
4007 }
|
Chris@49
|
4008
|
Chris@49
|
4009
|
Chris@49
|
4010
|
Chris@49
|
4011 inline
|
Chris@49
|
4012 bool
|
Chris@49
|
4013 diskio::save_std_string(const field<std::string>& x, const std::string& final_name)
|
Chris@49
|
4014 {
|
Chris@49
|
4015 arma_extra_debug_sigprint();
|
Chris@49
|
4016
|
Chris@49
|
4017 const std::string tmp_name = diskio::gen_tmp_name(final_name);
|
Chris@49
|
4018
|
Chris@49
|
4019 std::ofstream f( tmp_name.c_str(), std::fstream::binary );
|
Chris@49
|
4020
|
Chris@49
|
4021 bool save_okay = f.is_open();
|
Chris@49
|
4022
|
Chris@49
|
4023 if(save_okay == true)
|
Chris@49
|
4024 {
|
Chris@49
|
4025 save_okay = diskio::save_std_string(x, f);
|
Chris@49
|
4026
|
Chris@49
|
4027 f.flush();
|
Chris@49
|
4028 f.close();
|
Chris@49
|
4029
|
Chris@49
|
4030 if(save_okay == true)
|
Chris@49
|
4031 {
|
Chris@49
|
4032 save_okay = diskio::safe_rename(tmp_name, final_name);
|
Chris@49
|
4033 }
|
Chris@49
|
4034 }
|
Chris@49
|
4035
|
Chris@49
|
4036 return save_okay;
|
Chris@49
|
4037 }
|
Chris@49
|
4038
|
Chris@49
|
4039
|
Chris@49
|
4040
|
Chris@49
|
4041 inline
|
Chris@49
|
4042 bool
|
Chris@49
|
4043 diskio::save_std_string(const field<std::string>& x, std::ostream& f)
|
Chris@49
|
4044 {
|
Chris@49
|
4045 arma_extra_debug_sigprint();
|
Chris@49
|
4046
|
Chris@49
|
4047 for(uword row=0; row<x.n_rows; ++row)
|
Chris@49
|
4048 for(uword col=0; col<x.n_cols; ++col)
|
Chris@49
|
4049 {
|
Chris@49
|
4050 f << x.at(row,col);
|
Chris@49
|
4051
|
Chris@49
|
4052 if(col < x.n_cols-1)
|
Chris@49
|
4053 {
|
Chris@49
|
4054 f << ' ';
|
Chris@49
|
4055 }
|
Chris@49
|
4056 else
|
Chris@49
|
4057 {
|
Chris@49
|
4058 f << '\n';
|
Chris@49
|
4059 }
|
Chris@49
|
4060 }
|
Chris@49
|
4061
|
Chris@49
|
4062 return f.good();
|
Chris@49
|
4063 }
|
Chris@49
|
4064
|
Chris@49
|
4065
|
Chris@49
|
4066
|
Chris@49
|
4067 inline
|
Chris@49
|
4068 bool
|
Chris@49
|
4069 diskio::load_std_string(field<std::string>& x, const std::string& name, std::string& err_msg)
|
Chris@49
|
4070 {
|
Chris@49
|
4071 arma_extra_debug_sigprint();
|
Chris@49
|
4072
|
Chris@49
|
4073 std::ifstream f( name.c_str() );
|
Chris@49
|
4074
|
Chris@49
|
4075 bool load_okay = f.is_open();
|
Chris@49
|
4076
|
Chris@49
|
4077 if(load_okay == true)
|
Chris@49
|
4078 {
|
Chris@49
|
4079 load_okay = diskio::load_std_string(x, f, err_msg);
|
Chris@49
|
4080 f.close();
|
Chris@49
|
4081 }
|
Chris@49
|
4082
|
Chris@49
|
4083 return load_okay;
|
Chris@49
|
4084 }
|
Chris@49
|
4085
|
Chris@49
|
4086
|
Chris@49
|
4087
|
Chris@49
|
4088 inline
|
Chris@49
|
4089 bool
|
Chris@49
|
4090 diskio::load_std_string(field<std::string>& x, std::istream& f, std::string& err_msg)
|
Chris@49
|
4091 {
|
Chris@49
|
4092 arma_extra_debug_sigprint();
|
Chris@49
|
4093
|
Chris@49
|
4094 bool load_okay = true;
|
Chris@49
|
4095
|
Chris@49
|
4096 //
|
Chris@49
|
4097 // work out the size
|
Chris@49
|
4098
|
Chris@49
|
4099 uword f_n_rows = 0;
|
Chris@49
|
4100 uword f_n_cols = 0;
|
Chris@49
|
4101
|
Chris@49
|
4102 bool f_n_cols_found = false;
|
Chris@49
|
4103
|
Chris@49
|
4104 std::string line_string;
|
Chris@49
|
4105 std::string token;
|
Chris@49
|
4106
|
Chris@49
|
4107 while( (f.good() == true) && (load_okay == true) )
|
Chris@49
|
4108 {
|
Chris@49
|
4109 std::getline(f, line_string);
|
Chris@49
|
4110 if(line_string.size() == 0)
|
Chris@49
|
4111 break;
|
Chris@49
|
4112
|
Chris@49
|
4113 std::stringstream line_stream(line_string);
|
Chris@49
|
4114
|
Chris@49
|
4115 uword line_n_cols = 0;
|
Chris@49
|
4116 while (line_stream >> token)
|
Chris@49
|
4117 line_n_cols++;
|
Chris@49
|
4118
|
Chris@49
|
4119 if(f_n_cols_found == false)
|
Chris@49
|
4120 {
|
Chris@49
|
4121 f_n_cols = line_n_cols;
|
Chris@49
|
4122 f_n_cols_found = true;
|
Chris@49
|
4123 }
|
Chris@49
|
4124 else
|
Chris@49
|
4125 {
|
Chris@49
|
4126 if(line_n_cols != f_n_cols)
|
Chris@49
|
4127 {
|
Chris@49
|
4128 load_okay = false;
|
Chris@49
|
4129 err_msg = "inconsistent number of columns in ";
|
Chris@49
|
4130 }
|
Chris@49
|
4131 }
|
Chris@49
|
4132
|
Chris@49
|
4133 ++f_n_rows;
|
Chris@49
|
4134 }
|
Chris@49
|
4135
|
Chris@49
|
4136 if(load_okay == true)
|
Chris@49
|
4137 {
|
Chris@49
|
4138 f.clear();
|
Chris@49
|
4139 f.seekg(0, ios::beg);
|
Chris@49
|
4140 //f.seekg(start);
|
Chris@49
|
4141
|
Chris@49
|
4142 x.set_size(f_n_rows, f_n_cols);
|
Chris@49
|
4143
|
Chris@49
|
4144 for(uword row=0; row < x.n_rows; ++row)
|
Chris@49
|
4145 {
|
Chris@49
|
4146 for(uword col=0; col < x.n_cols; ++col)
|
Chris@49
|
4147 {
|
Chris@49
|
4148 f >> x.at(row,col);
|
Chris@49
|
4149 }
|
Chris@49
|
4150 }
|
Chris@49
|
4151 }
|
Chris@49
|
4152
|
Chris@49
|
4153 if(f.good() == false)
|
Chris@49
|
4154 {
|
Chris@49
|
4155 load_okay = false;
|
Chris@49
|
4156 }
|
Chris@49
|
4157
|
Chris@49
|
4158 return load_okay;
|
Chris@49
|
4159 }
|
Chris@49
|
4160
|
Chris@49
|
4161
|
Chris@49
|
4162
|
Chris@49
|
4163 //! Try to load a field by automatically determining its type
|
Chris@49
|
4164 template<typename T1>
|
Chris@49
|
4165 inline
|
Chris@49
|
4166 bool
|
Chris@49
|
4167 diskio::load_auto_detect(field<T1>& x, const std::string& name, std::string& err_msg)
|
Chris@49
|
4168 {
|
Chris@49
|
4169 arma_extra_debug_sigprint();
|
Chris@49
|
4170
|
Chris@49
|
4171 std::fstream f;
|
Chris@49
|
4172 f.open(name.c_str(), std::fstream::in | std::fstream::binary);
|
Chris@49
|
4173
|
Chris@49
|
4174 bool load_okay = f.is_open();
|
Chris@49
|
4175
|
Chris@49
|
4176 if(load_okay == true)
|
Chris@49
|
4177 {
|
Chris@49
|
4178 load_okay = diskio::load_auto_detect(x, f, err_msg);
|
Chris@49
|
4179 f.close();
|
Chris@49
|
4180 }
|
Chris@49
|
4181
|
Chris@49
|
4182 return load_okay;
|
Chris@49
|
4183 }
|
Chris@49
|
4184
|
Chris@49
|
4185
|
Chris@49
|
4186
|
Chris@49
|
4187 //! Try to load a field by automatically determining its type
|
Chris@49
|
4188 template<typename T1>
|
Chris@49
|
4189 inline
|
Chris@49
|
4190 bool
|
Chris@49
|
4191 diskio::load_auto_detect(field<T1>& x, std::istream& f, std::string& err_msg)
|
Chris@49
|
4192 {
|
Chris@49
|
4193 arma_extra_debug_sigprint();
|
Chris@49
|
4194
|
Chris@49
|
4195 arma_type_check(( is_Mat<T1>::value == false ));
|
Chris@49
|
4196
|
Chris@49
|
4197 static const std::string ARMA_FLD_BIN = "ARMA_FLD_BIN";
|
Chris@49
|
4198 static const std::string P6 = "P6";
|
Chris@49
|
4199
|
Chris@49
|
4200 podarray<char> raw_header(ARMA_FLD_BIN.length() + 1);
|
Chris@49
|
4201
|
Chris@49
|
4202 std::streampos pos = f.tellg();
|
Chris@49
|
4203
|
Chris@49
|
4204 f.read( raw_header.memptr(), std::streamsize(ARMA_FLD_BIN.length()) );
|
Chris@49
|
4205
|
Chris@49
|
4206 f.clear();
|
Chris@49
|
4207 f.seekg(pos);
|
Chris@49
|
4208
|
Chris@49
|
4209 raw_header[ARMA_FLD_BIN.length()] = '\0';
|
Chris@49
|
4210
|
Chris@49
|
4211 const std::string header = raw_header.mem;
|
Chris@49
|
4212
|
Chris@49
|
4213 if(ARMA_FLD_BIN == header.substr(0, ARMA_FLD_BIN.length()))
|
Chris@49
|
4214 {
|
Chris@49
|
4215 return load_arma_binary(x, f, err_msg);
|
Chris@49
|
4216 }
|
Chris@49
|
4217 else
|
Chris@49
|
4218 if(P6 == header.substr(0, P6.length()))
|
Chris@49
|
4219 {
|
Chris@49
|
4220 return load_ppm_binary(x, f, err_msg);
|
Chris@49
|
4221 }
|
Chris@49
|
4222 else
|
Chris@49
|
4223 {
|
Chris@49
|
4224 err_msg = "unsupported header in ";
|
Chris@49
|
4225 return false;
|
Chris@49
|
4226 }
|
Chris@49
|
4227 }
|
Chris@49
|
4228
|
Chris@49
|
4229
|
Chris@49
|
4230
|
Chris@49
|
4231 //
|
Chris@49
|
4232 // handling of PPM images by cubes
|
Chris@49
|
4233
|
Chris@49
|
4234
|
Chris@49
|
4235 template<typename eT>
|
Chris@49
|
4236 inline
|
Chris@49
|
4237 bool
|
Chris@49
|
4238 diskio::load_ppm_binary(Cube<eT>& x, const std::string& name, std::string& err_msg)
|
Chris@49
|
4239 {
|
Chris@49
|
4240 arma_extra_debug_sigprint();
|
Chris@49
|
4241
|
Chris@49
|
4242 std::fstream f;
|
Chris@49
|
4243 f.open(name.c_str(), std::fstream::in | std::fstream::binary);
|
Chris@49
|
4244
|
Chris@49
|
4245 bool load_okay = f.is_open();
|
Chris@49
|
4246
|
Chris@49
|
4247 if(load_okay == true)
|
Chris@49
|
4248 {
|
Chris@49
|
4249 load_okay = diskio::load_ppm_binary(x, f, err_msg);
|
Chris@49
|
4250 f.close();
|
Chris@49
|
4251 }
|
Chris@49
|
4252
|
Chris@49
|
4253 return load_okay;
|
Chris@49
|
4254 }
|
Chris@49
|
4255
|
Chris@49
|
4256
|
Chris@49
|
4257
|
Chris@49
|
4258 template<typename eT>
|
Chris@49
|
4259 inline
|
Chris@49
|
4260 bool
|
Chris@49
|
4261 diskio::load_ppm_binary(Cube<eT>& x, std::istream& f, std::string& err_msg)
|
Chris@49
|
4262 {
|
Chris@49
|
4263 arma_extra_debug_sigprint();
|
Chris@49
|
4264
|
Chris@49
|
4265 bool load_okay = true;
|
Chris@49
|
4266
|
Chris@49
|
4267 std::string f_header;
|
Chris@49
|
4268 f >> f_header;
|
Chris@49
|
4269
|
Chris@49
|
4270 if(f_header == "P6")
|
Chris@49
|
4271 {
|
Chris@49
|
4272 uword f_n_rows = 0;
|
Chris@49
|
4273 uword f_n_cols = 0;
|
Chris@49
|
4274 int f_maxval = 0;
|
Chris@49
|
4275
|
Chris@49
|
4276 diskio::pnm_skip_comments(f);
|
Chris@49
|
4277
|
Chris@49
|
4278 f >> f_n_cols;
|
Chris@49
|
4279 diskio::pnm_skip_comments(f);
|
Chris@49
|
4280
|
Chris@49
|
4281 f >> f_n_rows;
|
Chris@49
|
4282 diskio::pnm_skip_comments(f);
|
Chris@49
|
4283
|
Chris@49
|
4284 f >> f_maxval;
|
Chris@49
|
4285 f.get();
|
Chris@49
|
4286
|
Chris@49
|
4287 if( (f_maxval > 0) || (f_maxval <= 65535) )
|
Chris@49
|
4288 {
|
Chris@49
|
4289 x.set_size(f_n_rows, f_n_cols, 3);
|
Chris@49
|
4290
|
Chris@49
|
4291 if(f_maxval <= 255)
|
Chris@49
|
4292 {
|
Chris@49
|
4293 const uword n_elem = 3*f_n_cols*f_n_rows;
|
Chris@49
|
4294 podarray<u8> tmp(n_elem);
|
Chris@49
|
4295
|
Chris@49
|
4296 f.read( reinterpret_cast<char*>(tmp.memptr()), std::streamsize(n_elem) );
|
Chris@49
|
4297
|
Chris@49
|
4298 uword i = 0;
|
Chris@49
|
4299
|
Chris@49
|
4300 //cout << "f_n_cols = " << f_n_cols << endl;
|
Chris@49
|
4301 //cout << "f_n_rows = " << f_n_rows << endl;
|
Chris@49
|
4302
|
Chris@49
|
4303
|
Chris@49
|
4304 for(uword row=0; row < f_n_rows; ++row)
|
Chris@49
|
4305 {
|
Chris@49
|
4306 for(uword col=0; col < f_n_cols; ++col)
|
Chris@49
|
4307 {
|
Chris@49
|
4308 x.at(row,col,0) = eT(tmp[i+0]);
|
Chris@49
|
4309 x.at(row,col,1) = eT(tmp[i+1]);
|
Chris@49
|
4310 x.at(row,col,2) = eT(tmp[i+2]);
|
Chris@49
|
4311 i+=3;
|
Chris@49
|
4312 }
|
Chris@49
|
4313
|
Chris@49
|
4314 }
|
Chris@49
|
4315 }
|
Chris@49
|
4316 else
|
Chris@49
|
4317 {
|
Chris@49
|
4318 const uword n_elem = 3*f_n_cols*f_n_rows;
|
Chris@49
|
4319 podarray<u16> tmp(n_elem);
|
Chris@49
|
4320
|
Chris@49
|
4321 f.read( reinterpret_cast<char *>(tmp.memptr()), std::streamsize(2*n_elem) );
|
Chris@49
|
4322
|
Chris@49
|
4323 uword i = 0;
|
Chris@49
|
4324
|
Chris@49
|
4325 for(uword row=0; row < f_n_rows; ++row)
|
Chris@49
|
4326 {
|
Chris@49
|
4327 for(uword col=0; col < f_n_cols; ++col)
|
Chris@49
|
4328 {
|
Chris@49
|
4329 x.at(row,col,0) = eT(tmp[i+0]);
|
Chris@49
|
4330 x.at(row,col,1) = eT(tmp[i+1]);
|
Chris@49
|
4331 x.at(row,col,2) = eT(tmp[i+2]);
|
Chris@49
|
4332 i+=3;
|
Chris@49
|
4333 }
|
Chris@49
|
4334
|
Chris@49
|
4335 }
|
Chris@49
|
4336
|
Chris@49
|
4337 }
|
Chris@49
|
4338
|
Chris@49
|
4339 }
|
Chris@49
|
4340 else
|
Chris@49
|
4341 {
|
Chris@49
|
4342 load_okay = false;
|
Chris@49
|
4343 err_msg = "currently no code available to handle loading ";
|
Chris@49
|
4344 }
|
Chris@49
|
4345
|
Chris@49
|
4346 if(f.good() == false)
|
Chris@49
|
4347 {
|
Chris@49
|
4348 load_okay = false;
|
Chris@49
|
4349 }
|
Chris@49
|
4350
|
Chris@49
|
4351 }
|
Chris@49
|
4352 else
|
Chris@49
|
4353 {
|
Chris@49
|
4354 load_okay = false;
|
Chris@49
|
4355 err_msg = "unsupported header in ";
|
Chris@49
|
4356 }
|
Chris@49
|
4357
|
Chris@49
|
4358 return load_okay;
|
Chris@49
|
4359 }
|
Chris@49
|
4360
|
Chris@49
|
4361
|
Chris@49
|
4362
|
Chris@49
|
4363 template<typename eT>
|
Chris@49
|
4364 inline
|
Chris@49
|
4365 bool
|
Chris@49
|
4366 diskio::save_ppm_binary(const Cube<eT>& x, const std::string& final_name)
|
Chris@49
|
4367 {
|
Chris@49
|
4368 arma_extra_debug_sigprint();
|
Chris@49
|
4369
|
Chris@49
|
4370 const std::string tmp_name = diskio::gen_tmp_name(final_name);
|
Chris@49
|
4371
|
Chris@49
|
4372 std::ofstream f( tmp_name.c_str(), std::fstream::binary );
|
Chris@49
|
4373
|
Chris@49
|
4374 bool save_okay = f.is_open();
|
Chris@49
|
4375
|
Chris@49
|
4376 if(save_okay == true)
|
Chris@49
|
4377 {
|
Chris@49
|
4378 save_okay = diskio::save_ppm_binary(x, f);
|
Chris@49
|
4379
|
Chris@49
|
4380 f.flush();
|
Chris@49
|
4381 f.close();
|
Chris@49
|
4382
|
Chris@49
|
4383 if(save_okay == true)
|
Chris@49
|
4384 {
|
Chris@49
|
4385 save_okay = diskio::safe_rename(tmp_name, final_name);
|
Chris@49
|
4386 }
|
Chris@49
|
4387 }
|
Chris@49
|
4388
|
Chris@49
|
4389 return save_okay;
|
Chris@49
|
4390 }
|
Chris@49
|
4391
|
Chris@49
|
4392
|
Chris@49
|
4393
|
Chris@49
|
4394 template<typename eT>
|
Chris@49
|
4395 inline
|
Chris@49
|
4396 bool
|
Chris@49
|
4397 diskio::save_ppm_binary(const Cube<eT>& x, std::ostream& f)
|
Chris@49
|
4398 {
|
Chris@49
|
4399 arma_extra_debug_sigprint();
|
Chris@49
|
4400
|
Chris@49
|
4401 arma_debug_check( (x.n_slices != 3), "diskio::save_ppm_binary(): given cube must have exactly 3 slices" );
|
Chris@49
|
4402
|
Chris@49
|
4403 const uword n_elem = 3 * x.n_rows * x.n_cols;
|
Chris@49
|
4404 podarray<u8> tmp(n_elem);
|
Chris@49
|
4405
|
Chris@49
|
4406 uword i = 0;
|
Chris@49
|
4407 for(uword row=0; row < x.n_rows; ++row)
|
Chris@49
|
4408 {
|
Chris@49
|
4409 for(uword col=0; col < x.n_cols; ++col)
|
Chris@49
|
4410 {
|
Chris@49
|
4411 tmp[i+0] = u8( access::tmp_real( x.at(row,col,0) ) );
|
Chris@49
|
4412 tmp[i+1] = u8( access::tmp_real( x.at(row,col,1) ) );
|
Chris@49
|
4413 tmp[i+2] = u8( access::tmp_real( x.at(row,col,2) ) );
|
Chris@49
|
4414
|
Chris@49
|
4415 i+=3;
|
Chris@49
|
4416 }
|
Chris@49
|
4417 }
|
Chris@49
|
4418
|
Chris@49
|
4419 f << "P6" << '\n';
|
Chris@49
|
4420 f << x.n_cols << '\n';
|
Chris@49
|
4421 f << x.n_rows << '\n';
|
Chris@49
|
4422 f << 255 << '\n';
|
Chris@49
|
4423
|
Chris@49
|
4424 f.write( reinterpret_cast<const char*>(tmp.mem), std::streamsize(n_elem) );
|
Chris@49
|
4425
|
Chris@49
|
4426 return f.good();
|
Chris@49
|
4427 }
|
Chris@49
|
4428
|
Chris@49
|
4429
|
Chris@49
|
4430
|
Chris@49
|
4431 //
|
Chris@49
|
4432 // handling of PPM images by fields
|
Chris@49
|
4433
|
Chris@49
|
4434
|
Chris@49
|
4435
|
Chris@49
|
4436 template<typename T1>
|
Chris@49
|
4437 inline
|
Chris@49
|
4438 bool
|
Chris@49
|
4439 diskio::load_ppm_binary(field<T1>& x, const std::string& name, std::string& err_msg)
|
Chris@49
|
4440 {
|
Chris@49
|
4441 arma_extra_debug_sigprint();
|
Chris@49
|
4442
|
Chris@49
|
4443 std::fstream f;
|
Chris@49
|
4444 f.open(name.c_str(), std::fstream::in | std::fstream::binary);
|
Chris@49
|
4445
|
Chris@49
|
4446 bool load_okay = f.is_open();
|
Chris@49
|
4447
|
Chris@49
|
4448 if(load_okay == true)
|
Chris@49
|
4449 {
|
Chris@49
|
4450 load_okay = diskio::load_ppm_binary(x, f, err_msg);
|
Chris@49
|
4451 f.close();
|
Chris@49
|
4452 }
|
Chris@49
|
4453
|
Chris@49
|
4454 return load_okay;
|
Chris@49
|
4455 }
|
Chris@49
|
4456
|
Chris@49
|
4457
|
Chris@49
|
4458
|
Chris@49
|
4459 template<typename T1>
|
Chris@49
|
4460 inline
|
Chris@49
|
4461 bool
|
Chris@49
|
4462 diskio::load_ppm_binary(field<T1>& x, std::istream& f, std::string& err_msg)
|
Chris@49
|
4463 {
|
Chris@49
|
4464 arma_extra_debug_sigprint();
|
Chris@49
|
4465
|
Chris@49
|
4466 arma_type_check(( is_Mat<T1>::value == false ));
|
Chris@49
|
4467 typedef typename T1::elem_type eT;
|
Chris@49
|
4468
|
Chris@49
|
4469 bool load_okay = true;
|
Chris@49
|
4470
|
Chris@49
|
4471 std::string f_header;
|
Chris@49
|
4472 f >> f_header;
|
Chris@49
|
4473
|
Chris@49
|
4474 if(f_header == "P6")
|
Chris@49
|
4475 {
|
Chris@49
|
4476 uword f_n_rows = 0;
|
Chris@49
|
4477 uword f_n_cols = 0;
|
Chris@49
|
4478 int f_maxval = 0;
|
Chris@49
|
4479
|
Chris@49
|
4480 diskio::pnm_skip_comments(f);
|
Chris@49
|
4481
|
Chris@49
|
4482 f >> f_n_cols;
|
Chris@49
|
4483 diskio::pnm_skip_comments(f);
|
Chris@49
|
4484
|
Chris@49
|
4485 f >> f_n_rows;
|
Chris@49
|
4486 diskio::pnm_skip_comments(f);
|
Chris@49
|
4487
|
Chris@49
|
4488 f >> f_maxval;
|
Chris@49
|
4489 f.get();
|
Chris@49
|
4490
|
Chris@49
|
4491 if( (f_maxval > 0) || (f_maxval <= 65535) )
|
Chris@49
|
4492 {
|
Chris@49
|
4493 x.set_size(3);
|
Chris@49
|
4494 Mat<eT>& R = x(0);
|
Chris@49
|
4495 Mat<eT>& G = x(1);
|
Chris@49
|
4496 Mat<eT>& B = x(2);
|
Chris@49
|
4497
|
Chris@49
|
4498 R.set_size(f_n_rows,f_n_cols);
|
Chris@49
|
4499 G.set_size(f_n_rows,f_n_cols);
|
Chris@49
|
4500 B.set_size(f_n_rows,f_n_cols);
|
Chris@49
|
4501
|
Chris@49
|
4502 if(f_maxval <= 255)
|
Chris@49
|
4503 {
|
Chris@49
|
4504 const uword n_elem = 3*f_n_cols*f_n_rows;
|
Chris@49
|
4505 podarray<u8> tmp(n_elem);
|
Chris@49
|
4506
|
Chris@49
|
4507 f.read( reinterpret_cast<char*>(tmp.memptr()), std::streamsize(n_elem) );
|
Chris@49
|
4508
|
Chris@49
|
4509 uword i = 0;
|
Chris@49
|
4510
|
Chris@49
|
4511 //cout << "f_n_cols = " << f_n_cols << endl;
|
Chris@49
|
4512 //cout << "f_n_rows = " << f_n_rows << endl;
|
Chris@49
|
4513
|
Chris@49
|
4514
|
Chris@49
|
4515 for(uword row=0; row < f_n_rows; ++row)
|
Chris@49
|
4516 {
|
Chris@49
|
4517 for(uword col=0; col < f_n_cols; ++col)
|
Chris@49
|
4518 {
|
Chris@49
|
4519 R.at(row,col) = eT(tmp[i+0]);
|
Chris@49
|
4520 G.at(row,col) = eT(tmp[i+1]);
|
Chris@49
|
4521 B.at(row,col) = eT(tmp[i+2]);
|
Chris@49
|
4522 i+=3;
|
Chris@49
|
4523 }
|
Chris@49
|
4524
|
Chris@49
|
4525 }
|
Chris@49
|
4526 }
|
Chris@49
|
4527 else
|
Chris@49
|
4528 {
|
Chris@49
|
4529 const uword n_elem = 3*f_n_cols*f_n_rows;
|
Chris@49
|
4530 podarray<u16> tmp(n_elem);
|
Chris@49
|
4531
|
Chris@49
|
4532 f.read( reinterpret_cast<char *>(tmp.memptr()), std::streamsize(2*n_elem) );
|
Chris@49
|
4533
|
Chris@49
|
4534 uword i = 0;
|
Chris@49
|
4535
|
Chris@49
|
4536 for(uword row=0; row < f_n_rows; ++row)
|
Chris@49
|
4537 {
|
Chris@49
|
4538 for(uword col=0; col < f_n_cols; ++col)
|
Chris@49
|
4539 {
|
Chris@49
|
4540 R.at(row,col) = eT(tmp[i+0]);
|
Chris@49
|
4541 G.at(row,col) = eT(tmp[i+1]);
|
Chris@49
|
4542 B.at(row,col) = eT(tmp[i+2]);
|
Chris@49
|
4543 i+=3;
|
Chris@49
|
4544 }
|
Chris@49
|
4545
|
Chris@49
|
4546 }
|
Chris@49
|
4547
|
Chris@49
|
4548 }
|
Chris@49
|
4549
|
Chris@49
|
4550 }
|
Chris@49
|
4551 else
|
Chris@49
|
4552 {
|
Chris@49
|
4553 load_okay = false;
|
Chris@49
|
4554 err_msg = "currently no code available to handle loading ";
|
Chris@49
|
4555 }
|
Chris@49
|
4556
|
Chris@49
|
4557 if(f.good() == false)
|
Chris@49
|
4558 {
|
Chris@49
|
4559 load_okay = false;
|
Chris@49
|
4560 }
|
Chris@49
|
4561
|
Chris@49
|
4562 }
|
Chris@49
|
4563 else
|
Chris@49
|
4564 {
|
Chris@49
|
4565 load_okay = false;
|
Chris@49
|
4566 err_msg = "unsupported header in ";
|
Chris@49
|
4567 }
|
Chris@49
|
4568
|
Chris@49
|
4569 return load_okay;
|
Chris@49
|
4570 }
|
Chris@49
|
4571
|
Chris@49
|
4572
|
Chris@49
|
4573
|
Chris@49
|
4574 template<typename T1>
|
Chris@49
|
4575 inline
|
Chris@49
|
4576 bool
|
Chris@49
|
4577 diskio::save_ppm_binary(const field<T1>& x, const std::string& final_name)
|
Chris@49
|
4578 {
|
Chris@49
|
4579 arma_extra_debug_sigprint();
|
Chris@49
|
4580
|
Chris@49
|
4581 const std::string tmp_name = diskio::gen_tmp_name(final_name);
|
Chris@49
|
4582 std::ofstream f( tmp_name.c_str(), std::fstream::binary );
|
Chris@49
|
4583
|
Chris@49
|
4584 bool save_okay = f.is_open();
|
Chris@49
|
4585
|
Chris@49
|
4586 if(save_okay == true)
|
Chris@49
|
4587 {
|
Chris@49
|
4588 save_okay = diskio::save_ppm_binary(x, f);
|
Chris@49
|
4589
|
Chris@49
|
4590 f.flush();
|
Chris@49
|
4591 f.close();
|
Chris@49
|
4592
|
Chris@49
|
4593 if(save_okay == true)
|
Chris@49
|
4594 {
|
Chris@49
|
4595 save_okay = diskio::safe_rename(tmp_name, final_name);
|
Chris@49
|
4596 }
|
Chris@49
|
4597 }
|
Chris@49
|
4598
|
Chris@49
|
4599 return save_okay;
|
Chris@49
|
4600 }
|
Chris@49
|
4601
|
Chris@49
|
4602
|
Chris@49
|
4603
|
Chris@49
|
4604 template<typename T1>
|
Chris@49
|
4605 inline
|
Chris@49
|
4606 bool
|
Chris@49
|
4607 diskio::save_ppm_binary(const field<T1>& x, std::ostream& f)
|
Chris@49
|
4608 {
|
Chris@49
|
4609 arma_extra_debug_sigprint();
|
Chris@49
|
4610
|
Chris@49
|
4611 arma_type_check(( is_Mat<T1>::value == false ));
|
Chris@49
|
4612
|
Chris@49
|
4613 typedef typename T1::elem_type eT;
|
Chris@49
|
4614
|
Chris@49
|
4615 arma_debug_check( (x.n_elem != 3), "diskio::save_ppm_binary(): given field must have exactly 3 matrices of equal size" );
|
Chris@49
|
4616
|
Chris@49
|
4617 bool same_size = true;
|
Chris@49
|
4618 for(uword i=1; i<3; ++i)
|
Chris@49
|
4619 {
|
Chris@49
|
4620 if( (x(0).n_rows != x(i).n_rows) || (x(0).n_cols != x(i).n_cols) )
|
Chris@49
|
4621 {
|
Chris@49
|
4622 same_size = false;
|
Chris@49
|
4623 break;
|
Chris@49
|
4624 }
|
Chris@49
|
4625 }
|
Chris@49
|
4626
|
Chris@49
|
4627 arma_debug_check( (same_size != true), "diskio::save_ppm_binary(): given field must have exactly 3 matrices of equal size" );
|
Chris@49
|
4628
|
Chris@49
|
4629 const Mat<eT>& R = x(0);
|
Chris@49
|
4630 const Mat<eT>& G = x(1);
|
Chris@49
|
4631 const Mat<eT>& B = x(2);
|
Chris@49
|
4632
|
Chris@49
|
4633 f << "P6" << '\n';
|
Chris@49
|
4634 f << R.n_cols << '\n';
|
Chris@49
|
4635 f << R.n_rows << '\n';
|
Chris@49
|
4636 f << 255 << '\n';
|
Chris@49
|
4637
|
Chris@49
|
4638 const uword n_elem = 3 * R.n_rows * R.n_cols;
|
Chris@49
|
4639 podarray<u8> tmp(n_elem);
|
Chris@49
|
4640
|
Chris@49
|
4641 uword i = 0;
|
Chris@49
|
4642 for(uword row=0; row < R.n_rows; ++row)
|
Chris@49
|
4643 {
|
Chris@49
|
4644 for(uword col=0; col < R.n_cols; ++col)
|
Chris@49
|
4645 {
|
Chris@49
|
4646 tmp[i+0] = u8( access::tmp_real( R.at(row,col) ) );
|
Chris@49
|
4647 tmp[i+1] = u8( access::tmp_real( G.at(row,col) ) );
|
Chris@49
|
4648 tmp[i+2] = u8( access::tmp_real( B.at(row,col) ) );
|
Chris@49
|
4649
|
Chris@49
|
4650 i+=3;
|
Chris@49
|
4651 }
|
Chris@49
|
4652 }
|
Chris@49
|
4653
|
Chris@49
|
4654 f.write( reinterpret_cast<const char*>(tmp.mem), std::streamsize(n_elem) );
|
Chris@49
|
4655
|
Chris@49
|
4656 return f.good();
|
Chris@49
|
4657 }
|
Chris@49
|
4658
|
Chris@49
|
4659
|
Chris@49
|
4660
|
Chris@49
|
4661 //! @}
|
Chris@49
|
4662
|