1 /*************************************************************************/
2 /* */
3 /* Centre for Speech Technology Research */
4 /* University of Edinburgh, UK */
5 /* Copyright (c) 1995,1996 */
6 /* All Rights Reserved. */
7 /* */
8 /* Permission is hereby granted, free of charge, to use and distribute */
9 /* this software and its documentation without restriction, including */
10 /* without limitation the rights to use, copy, modify, merge, publish, */
11 /* distribute, sublicense, and/or sell copies of this work, and to */
12 /* permit persons to whom this work is furnished to do so, subject to */
13 /* the following conditions: */
14 /* 1. The code must retain the above copyright notice, this list of */
15 /* conditions and the following disclaimer. */
16 /* 2. Any modifications must be clearly marked as such. */
17 /* 3. Original authors' names are not deleted. */
18 /* 4. The authors' names are not used to endorse or promote products */
19 /* derived from this software without specific prior written */
20 /* permission. */
21 /* */
22 /* THE UNIVERSITY OF EDINBURGH AND THE CONTRIBUTORS TO THIS WORK */
23 /* DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING */
24 /* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT */
25 /* SHALL THE UNIVERSITY OF EDINBURGH NOR THE CONTRIBUTORS BE LIABLE */
26 /* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES */
27 /* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN */
28 /* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, */
29 /* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF */
30 /* THIS SOFTWARE. */
31 /* */
32 /*************************************************************************/
33 /* */
34 /* Author : Simon King */
35 /* Date : February 1999 */
36 /* --------------------------------------------------------------------- */
37 /* Double matrix class - copied from DMatrix ! */
38 /* */
39 /*************************************************************************/
40
41 #include <cstdlib>
42 #include <cstdio>
43 #include <fstream>
44 #include <cmath>
45 #include <climits>
46 #include "EST_String.h"
47 #include "EST_types.h"
48 #include "EST_FileType.h"
49 #include "EST_Option.h"
50 #include "EST_DMatrix.h"
51 #include "EST_cutils.h" // for swap functions
52 #include "EST_Token.h"
53 #include "rateconv.h"
54
55 EST_String EST_DMatrix::default_file_type = "est_ascii";
56
EST_DMatrix(const EST_DMatrix & a,int b)57 EST_DMatrix::EST_DMatrix(const EST_DMatrix &a, int b)
58 :EST_TSimpleMatrix<double>(a.num_rows(), a.num_columns())
59 {
60 double vv = 0.0;
61 if (b < 0)
62 return;
63 if (b == 0)
64 fill(vv);
65 }
66
operator +=(const EST_DMatrix & a)67 EST_DMatrix & EST_DMatrix::operator+=(const EST_DMatrix &a)
68 {
69 int i, j;
70 if (a.num_columns() != num_columns())
71 {
72 cerr <<"Matrix addition error: bad number of columns\n";
73 return *this;
74 }
75 if (a.num_rows() != num_rows())
76 {
77 cerr <<"Matrix addition error: bad number of rows\n";
78 return *this;
79 }
80 for (i = 0; i < num_rows(); ++i)
81 for (j = 0; j < num_columns(); ++j)
82 a_no_check(i, j) += a.a_no_check(i,j);
83
84 return *this;
85 }
86
operator -=(const EST_DMatrix & a)87 EST_DMatrix & EST_DMatrix::operator-=(const EST_DMatrix &a)
88 {
89 int i, j;
90 if (a.num_columns() != num_columns())
91 {
92 cerr <<"Matrix subtraction error: bad number of columns\n";
93 return *this;
94 }
95 if (a.num_rows() != num_rows())
96 {
97 cerr <<"Matrix subtraction error: bad number of rows\n";
98 return *this;
99 }
100 for (i = 0; i < num_rows(); ++i)
101 for (j = 0; j < num_columns(); ++j)
102 a_no_check(i, j) -= a.a_no_check(i,j);
103
104 return *this;
105 }
106
operator *=(const double f)107 EST_DMatrix & EST_DMatrix::operator*=(const double f)
108 {
109
110 int i,j;
111 for (i = 0; i < num_rows(); ++i)
112 for (j = 0; j < num_columns(); ++j)
113 a_no_check(i, j) *= f;
114
115 return *this;
116 }
117
operator /=(const double f)118 EST_DMatrix & EST_DMatrix::operator/=(const double f)
119 {
120
121 int i,j;
122 for (i = 0; i < num_rows(); ++i)
123 for (j = 0; j < num_columns(); ++j)
124 a_no_check(i, j) /= f;
125
126 return *this;
127 }
128
operator +(const EST_DMatrix & a,const EST_DMatrix & b)129 EST_DMatrix operator+(const EST_DMatrix &a, const EST_DMatrix &b)
130 {
131 EST_DMatrix ab;
132 int i, j;
133 if (a.num_columns() != b.num_columns())
134 {
135 cerr <<"Matrix addition error: bad number of columns\n";
136 return ab;
137 }
138 if (a.num_rows() != b.num_rows())
139 {
140 cerr <<"Matrix addition error: bad number of rows\n";
141 return ab;
142 }
143 ab.resize(a.num_rows(), a.num_columns());
144 for (i = 0; i < a.num_rows(); ++i)
145 for (j = 0; j < a.num_columns(); ++j)
146 ab.a_no_check(i, j) = a.a_no_check(i, j) + b.a_no_check(i, j);
147
148 return ab;
149 }
150
operator -(const EST_DMatrix & a,const EST_DMatrix & b)151 EST_DMatrix operator-(const EST_DMatrix &a,const EST_DMatrix &b)
152 {
153 EST_DMatrix ab;
154 int i, j;
155
156 if (a.num_columns() != b.num_columns())
157 {
158 cerr <<"Matrix subtraction error: bad number of columns:" <<
159 a.num_columns() << " and " << b.num_columns() << endl;
160 return ab;
161 }
162 if (a.num_rows() != b.num_rows())
163 {
164 cerr <<"Matrix subtraction error: bad number of rows\n";
165 return ab;
166 }
167 ab.resize(a.num_rows(), a.num_columns());
168 for (i = 0; i < a.num_rows(); ++i)
169 for (j = 0; j < a.num_columns(); ++j)
170 ab.a_no_check(i, j) = a.a_no_check(i, j) - b.a_no_check(i, j);
171
172 return ab;
173 }
174
operator *(const EST_DMatrix & a,const double x)175 EST_DMatrix operator*(const EST_DMatrix &a, const double x)
176 {
177 EST_DMatrix b(a, 0);
178 int i, j;
179
180 for (i = 0; i < a.num_rows(); ++i)
181 for (j = 0; j < a.num_columns(); ++j)
182 b.a_no_check(i,j) = a.a_no_check(i,j) * x;
183
184 return b;
185 }
186
operator *(const EST_DMatrix & a,const EST_DVector & v)187 EST_DVector operator*(const EST_DMatrix &a, const EST_DVector &v)
188 {
189 // treat the vector as a column vector
190 // multiply each row of the matrix in turn by the vector
191
192 EST_DVector b;
193 b.resize(a.num_rows());
194
195 if(a.num_columns() != v.n())
196 {
197 cerr <<"Matrix-vector multiplication error: matrix rows != vector size"
198 << endl;
199 return b;
200 }
201
202 int i, j;
203 for (i = 0; i < a.num_rows(); ++i){
204 b[i] = 0.0;
205 for (j = 0; j < a.num_columns(); ++j)
206 b.a_no_check(i) += a.a_no_check(i,j) * v.a_no_check(j);
207 }
208 return b;
209 }
210
operator +(const EST_DVector & a,const EST_DVector & b)211 EST_DVector operator+(const EST_DVector &a, const EST_DVector &b)
212 {
213 EST_DVector ab;
214 int i;
215 if (a.length() != b.length())
216 {
217 cerr <<"Vector addition error: mismatched lengths\n";
218 return ab;
219 }
220
221 ab.resize(a.length());
222 for (i = 0; i < a.length(); ++i)
223 ab.a_no_check(i) = a.a_no_check(i) + b.a_no_check(i);
224
225 return ab;
226 }
227
operator -(const EST_DVector & a,const EST_DVector & b)228 EST_DVector operator-(const EST_DVector &a, const EST_DVector &b)
229 {
230 EST_DVector ab;
231 int i;
232 if (a.length() != b.length())
233 {
234 cerr <<"Vector subtraction error: mismatched lengths\n";
235 return ab;
236 }
237
238 ab.resize(a.length());
239 for (i = 0; i < a.length(); ++i)
240 ab.a_no_check(i) = a.a_no_check(i) - b.a_no_check(i);
241
242 return ab;
243 }
244
245
operator *(const EST_DVector & v,const EST_DMatrix & a)246 EST_DVector operator*(const EST_DVector &v,const EST_DMatrix &a)
247 {
248 // treat the vector as a row vector
249 // multiply the vector by each column of the matrix in turn
250
251 EST_DVector b;
252 b.resize(a.num_columns());
253
254 if(a.num_columns() != v.n())
255 {
256 cerr <<"Matrix-vector multiplication error: matrix rows != vector size"
257 << endl;
258 return b;
259 }
260
261 int i, j;
262 for (j = 0; j < a.num_columns(); ++j){
263 b[j] = 0.0;
264 for (i = 0; i < a.num_rows(); ++i)
265 b.a_no_check(i) += a.a_no_check(i,j) * v.a_no_check(j);
266 }
267 return b;
268 }
269
270
271 #if 0
272 EST_DMatrix operator/(const EST_DMatrix &a, double x)
273 {
274 return (a * (1/x));
275 }
276 #endif
277
operator *(const EST_DMatrix & a,const EST_DMatrix & b)278 EST_DMatrix operator*(const EST_DMatrix &a, const EST_DMatrix &b)
279 {
280 EST_DMatrix ab;
281 multiply(a,b,ab);
282 return ab;
283 }
284
multiply(const EST_DMatrix & a,const EST_DMatrix & b,EST_DMatrix & ab)285 void multiply(const EST_DMatrix &a, const EST_DMatrix &b, EST_DMatrix &ab)
286 {
287
288 if (a.num_columns() != b.num_rows())
289 {
290 cerr <<"Matrix multiply error: a.num_columns() != b.num_rows()\n";
291 return;
292 }
293
294 ab.resize(a.num_rows(), b.num_columns());
295 int i, j, k, n;
296 n = a.num_columns(); // could also be b.num_rows()
297
298 for (i = 0; i < a.num_rows(); ++i)
299 for (k = 0; k < b.num_columns(); ++k)
300 {
301 ab.a_no_check(i, k) = 0.0;
302 for (j = 0; j < n; ++j)
303 ab.a_no_check(i, k) +=
304 a.a_no_check(i, j) * b.a_no_check(j, k);
305 }
306 }
307
copyin(double ** inx,int rows,int cols)308 void EST_DMatrix::copyin(double **inx, int rows, int cols)
309 {
310 int i, j;
311
312 resize(rows, cols);
313
314 for (i = 0; i < rows; ++i)
315 for (j = 0; j < cols; ++j)
316 a_no_check(i,j) = inx[i][j];
317
318 }
319
save(const EST_String & filename,const EST_String & type)320 EST_write_status EST_DMatrix::save(const EST_String &filename,
321 const EST_String &type)
322 {
323
324 if ((type == "est_ascii") || (type == "est_binary"))
325 return est_save(filename,type);
326 else
327 { // the old stuff raw unheadered
328 int i, j;
329 ostream *outf;
330 if (filename == "-")
331 outf = &cout;
332 else
333 outf = new ofstream(filename);
334
335 outf->precision(25);
336 if (!(*outf))
337 {
338 cerr << "DMatrix: can't open file \"" << filename
339 <<"\" for writing" << endl;
340 return misc_write_error;
341 }
342
343 for (i = 0; i < num_rows(); ++i)
344 {
345 for (j = 0; j < num_columns(); ++j)
346 *outf << a_no_check(i,j) << " ";
347 *outf << endl;
348 }
349
350 if (outf != &cout)
351 delete outf;
352
353 return write_ok;
354 }
355 }
356
est_save(const EST_String & filename,const EST_String & type)357 EST_write_status EST_DMatrix::est_save(const EST_String &filename,
358 const EST_String &type)
359 {
360 // Binary save with short header for byte swap and sizes
361 int i,j;
362 FILE *fd;
363 if (filename == "-")
364 fd = stdout;
365 else if ((fd = fopen(filename, "wb")) == NULL)
366 {
367 cerr << "EST_DMatrix: binsave: failed to open \"" << filename <<
368 "\" for writing" << endl;
369 return misc_write_error;
370 }
371
372 fprintf(fd,"EST_File dmatrix\n");
373 fprintf(fd,"version 1\n");
374 if (type == "est_binary")
375 {
376 fprintf(fd,"DataType binary\n");
377 if (EST_LITTLE_ENDIAN)
378 fprintf(fd,"ByteOrder LittleEndian\n");
379 else
380 fprintf(fd,"ByteOrder BigEndian\n");
381 }
382 else
383 fprintf(fd,"DataType ascii\n");
384
385 fprintf(fd,"rows %d\n",num_rows());
386 fprintf(fd,"columns %d\n",num_columns());
387
388 fprintf(fd,"EST_Header_End\n");
389
390 if (type == "est_binary")
391 {
392 for (i = 0; i < num_rows(); ++i)
393 for (j=0; j < num_columns(); j++)
394 if (fwrite(&a_no_check(i,j),sizeof(double),1,fd) != 1)
395 {
396 cerr << "EST_DMatrix: binsave: failed to write row "
397 << i << " column " << j
398 << " to \"" << filename << "\"" << endl;
399 return misc_write_error;
400 }
401 }
402 else
403 { // est_ascii
404 for (i = 0; i < num_rows(); ++i)
405 {
406 for (j=0; j < num_columns(); j++)
407 fprintf(fd,"%.25f ",a_no_check(i,j));
408 fprintf(fd,"\n");
409 }
410 }
411
412 if (fd != stdout)
413 fclose(fd);
414
415 return write_ok;
416 }
417
est_load(const EST_String & filename)418 EST_read_status EST_DMatrix::est_load(const EST_String &filename)
419 {
420
421 // ascii/binary load with short header for byte swap and sizes
422 int i,j,k;
423 int rows, cols, swap;
424 EST_TokenStream ts;
425 EST_read_status r;
426 EST_EstFileType t;
427 EST_Option hinfo;
428 bool ascii;
429
430 if (((filename == "-") ? ts.open(cin) : ts.open(filename)) != 0)
431 {
432 cerr << "DMatrix: can't open DMatrix input file "
433 << filename << endl;
434 return misc_read_error;
435 }
436 if ((r = read_est_header(ts, hinfo, ascii, t)) != format_ok)
437 return r;
438 if (t != est_file_dmatrix)
439 return misc_read_error;
440 if (hinfo.ival("version") != 1)
441 {
442 cerr << "DMatrix load: " << ts.pos_description() <<
443 " wrong version of DMatrix format expected 1 but found " <<
444 hinfo.ival("version") << endl;
445 return misc_read_error;
446 }
447 rows = hinfo.ival("rows");
448 cols = hinfo.ival("columns");
449 resize(rows,cols);
450
451 if (ascii)
452 { // an ascii file
453 for (i = 0; i < num_rows(); ++i)
454 {
455 for (j = 0; j < num_columns(); ++j)
456 a_no_check(i,j) = atof(ts.get().string());
457 if (!ts.eoln())
458 {
459 cerr << "DMatrix load: " << ts.pos_description() <<
460 " missing end of line at end of row " << i << endl;
461 return misc_read_error;
462 }
463 }
464 }
465 else
466 { // a binary file
467 double *buff;
468 if ((EST_BIG_ENDIAN && (hinfo.sval("ByteOrder")=="LittleEndian")) ||
469 (EST_LITTLE_ENDIAN && (hinfo.sval("ByteOrder") == "BigEndian")))
470 swap = TRUE;
471 else
472 swap = FALSE;
473
474 buff = walloc(double,rows*cols);
475 // A single read is *much* faster than multiple reads
476 if (ts.fread(buff,sizeof(double),rows*cols) != rows*cols)
477 {
478 cerr << "EST_DMatrix: binload: short file in \""
479 << filename << "\"" << endl;
480 return misc_read_error;
481 }
482 if (swap)
483 swap_bytes_double(buff,rows*cols);
484 for (k = i = 0; i < num_rows(); ++i)
485 for (j = 0; j < num_columns(); ++j)
486 a_no_check(i,j) = buff[k++];
487 wfree(buff);
488 }
489
490 ts.close();
491 return read_ok;
492 }
493
load(const EST_String & filename)494 EST_read_status EST_DMatrix::load(const EST_String &filename)
495 {
496 EST_read_status r;
497
498 if ((r = est_load(filename)) == format_ok)
499 return r;
500 else if (r == wrong_format)
501 { // maybe its an ancient ascii file
502 EST_TokenStream ts, tt;
503 EST_StrList sl;
504 int i, j, n_rows=0, n_cols=0;
505 EST_String t;
506 EST_Litem *p;
507 if (((filename == "-") ? ts.open(cin) : ts.open(filename)) != 0)
508 {
509 cerr << "Can't open DMatrix file " << filename << endl;
510 return misc_read_error;
511 }
512 // set up the character constant values for this stream
513 ts.set_SingleCharSymbols(";");
514
515 // first read in as list
516 for (n_rows = 0; !ts.eof(); ++n_rows)
517 sl.append(ts.get_upto_eoln().string());
518
519 if (n_rows > 0)
520 {
521 tt.open_string(sl.first());
522 for (n_cols = 0; !tt.eof(); ++n_cols)
523 tt.get().string();
524 }
525
526 // resize track and copy values in
527 resize(n_rows, n_cols);
528
529 for (p = sl.head(), i = 0; p != 0; ++i, p = p->next())
530 {
531 tt.open_string(sl(p));
532 for (j = 0; !tt.eof(); ++j)
533 a_no_check(i,j) = atof(tt.get().string());
534 if (j != n_cols)
535 {
536 cerr << "Wrong number of points in row " << i << endl;
537 cerr << "Expected " << n_cols << " got " << j << endl;
538 return misc_read_error;
539 }
540 }
541 return format_ok;
542 }
543 else
544 return r;
545
546 return format_ok;
547 }
548
est_load(const EST_String & filename)549 EST_read_status EST_DVector::est_load(const EST_String &filename)
550 {
551 // ascii/binary load with short header for byte swap and sizes
552 int i,k;
553 int l, swap;
554 EST_TokenStream ts;
555 EST_read_status r;
556 EST_EstFileType t;
557 EST_Option hinfo;
558 bool ascii;
559
560 if (((filename == "-") ? ts.open(cin) : ts.open(filename)) != 0)
561 {
562 cerr << "DVector: can't open DVector input file "
563 << filename << endl;
564 return misc_read_error;
565 }
566 if ((r = read_est_header(ts, hinfo, ascii, t)) != format_ok)
567 return r;
568 if (t != est_file_dvector)
569 return misc_read_error;
570 if (hinfo.ival("version") != 1)
571 {
572 cerr << "DVector load: " << ts.pos_description() <<
573 " wrong version of DVector format expected 1 but found " <<
574 hinfo.ival("version") << endl;
575 return misc_read_error;
576 }
577 l = hinfo.ival("length");
578 resize(l);
579
580 if (ascii)
581 { // an ascii file
582 for (i = 0; i < length(); ++i)
583 a_no_check(i) = atof(ts.get().string());
584 }
585 else
586 { // a binary file
587 double *buff;
588 if ((EST_BIG_ENDIAN && (hinfo.sval("ByteOrder")=="LittleEndian")) ||
589 (EST_LITTLE_ENDIAN && (hinfo.sval("ByteOrder") == "BigEndian")))
590 swap = TRUE;
591 else
592 swap = FALSE;
593
594 buff = walloc(double,l);
595 // A single read is *much* faster than multiple reads
596 if (ts.fread(buff,sizeof(double),l) != l)
597 {
598 cerr << "EST_DVector: binload: short file in \""
599 << filename << "\"" << endl;
600 return misc_read_error;
601 }
602 if (swap)
603 swap_bytes_double(buff,l);
604 for (k = i = 0; i < length(); ++i)
605 a_no_check(i) = buff[k++];
606 wfree(buff);
607 }
608
609 ts.close();
610 return read_ok;
611 }
612
load(const EST_String & filename)613 EST_read_status EST_DVector::load(const EST_String &filename)
614 {
615
616 EST_read_status r;
617
618 if ((r = est_load(filename)) == format_ok)
619 return r;
620 else if (r == wrong_format)
621 { // maybe its an ancient ascii file
622 EST_TokenStream ts;
623 EST_String s;
624 int i;
625
626 i = 0;
627
628 if (((filename == "-") ? ts.open(cin) : ts.open(filename)) != 0)
629 {
630 cerr << "can't open vector input file " << filename << endl;
631 return misc_read_error;
632 }
633 ts.set_SingleCharSymbols(";");
634
635 while (!ts.eof())
636 {
637 ts.get();
638 ++i;
639 }
640 resize(i);
641
642 ts.close();
643 if (((filename == "-") ? ts.open(cin) : ts.open(filename)) != 0)
644 {
645 cerr << "can't open vector input file " << filename << endl;
646 return misc_read_error;
647 }
648
649 for (i = 0; !ts.eof(); ++i)
650 {
651 s = ts.get().string();
652 (*this)[i] = atof(s); // actually returns double
653 }
654 ts.close();
655 return format_ok;
656 }
657 else
658 return r;
659
660 return format_ok;
661
662 }
663
664
operator +=(const EST_DVector & s)665 EST_DVector & EST_DVector::operator+=(const EST_DVector &s)
666 {
667 int i;
668 if(n() != s.n()){
669 cerr << "Cannot elementwise add vectors of differing lengths"
670 << endl;
671 return *this;
672 }
673
674 for (i = 0; i < n(); ++i)
675 (*this)[i] += s(i);
676
677
678 return *this;
679 }
680
681
operator *=(const EST_DVector & s)682 EST_DVector& EST_DVector::operator*=(const EST_DVector &s)
683 {
684 if(n() != s.n()){
685 cerr << "Cannot elementwise multiply vectors of differing lengths"
686 << endl;
687 return *this;
688 }
689
690 for (int i = 0; i < n(); ++i)
691 (*this)[i] *= s(i);
692
693 return *this;
694 }
695
operator *=(const double f)696 EST_DVector& EST_DVector::operator*=(const double f)
697 {
698 for (int i = 0; i < n(); ++i)
699 (*this)[i] *= f;
700
701 return *this;
702 }
703
operator *(const EST_DVector & v1,const EST_DVector & v2)704 double operator*(const EST_DVector &v1, const EST_DVector &v2)
705 {
706 if(v1.length() != v2.length())
707 {
708 cerr << "Can't do vector dot prod - differing vector sizes !" << endl;
709 return 0;
710 }
711 double p=0;
712 for (int i = 0; i < v1.length(); ++i)
713 p += v1.a_no_check(i) * v2.a_no_check(i);
714
715 return p;
716 }
717
718
operator /=(const double f)719 EST_DVector& EST_DVector::operator/=(const double f)
720 {
721 for (int i = 0; i < n(); ++i)
722 (*this)[i] /= f;
723
724 return *this;
725 }
726
727
save(const EST_String & filename,const EST_String & type)728 EST_write_status EST_DVector::save(const EST_String &filename,
729 const EST_String &type)
730 {
731
732 if ((type == "est_ascii") || (type == "est_binary"))
733 return est_save(filename,type);
734 else
735 { // the old stuff raw unheadered
736 int i;
737 ostream *outf;
738 if (filename == "-")
739 outf = &cout;
740 else
741 outf = new ofstream(filename);
742
743 outf->precision(25);
744 if (!(*outf))
745 {
746 cerr << "DVector: can't open file \"" << filename
747 <<"\" for writing" << endl;
748 return misc_write_error;
749 }
750
751 for (i = 0; i < length(); ++i)
752 *outf << a_no_check(i) << " ";
753 *outf << endl;
754
755 if (outf != &cout)
756 delete outf;
757
758 return write_ok;
759 }
760 }
761
est_save(const EST_String & filename,const EST_String & type)762 EST_write_status EST_DVector::est_save(const EST_String &filename,
763 const EST_String &type)
764 {
765 // Binary save with short header for byte swap and sizes
766 int i;
767 FILE *fd;
768 if (filename == "-")
769 fd = stdout;
770 else if ((fd = fopen(filename, "wb")) == NULL)
771 {
772 cerr << "EST_DVector: binsave: failed to open \"" << filename <<
773 "\" for writing" << endl;
774 return misc_write_error;
775 }
776
777 fprintf(fd,"EST_File dvector\n");
778 fprintf(fd,"version 1\n");
779 if (type == "est_binary")
780 {
781 fprintf(fd,"DataType binary\n");
782 if (EST_LITTLE_ENDIAN)
783 fprintf(fd,"ByteOrder LittleEndian\n");
784 else
785 fprintf(fd,"ByteOrder BigEndian\n");
786 }
787 else
788 fprintf(fd,"DataType ascii\n");
789
790 fprintf(fd,"length %d\n",length());
791 fprintf(fd,"EST_Header_End\n");
792
793 if (type == "est_binary")
794 {
795 for (i = 0; i < length(); ++i)
796 if (fwrite(&a_no_check(i),sizeof(double),1,fd) != 1)
797 {
798 cerr << "EST_DVector: binsave: failed to write item "
799 << i << " to \"" << filename << "\"" << endl;
800 return misc_write_error;
801 }
802 }
803 else
804 { // est_ascii
805 for (i = 0; i < length(); ++i)
806 fprintf(fd,"%.25f ",a_no_check(i));
807 fprintf(fd,"\n");
808 }
809
810 if (fd != stdout)
811 fclose(fd);
812
813 return write_ok;
814 }
815
816