Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it

563554 views
1
/*
2
* Normaliz
3
* Copyright (C) 2007-2014 Winfried Bruns, Bogdan Ichim, Christof Soeger
4
* This program is free software: you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation, either version 3 of the License, or
7
* (at your option) any later version.
8
*
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
13
*
14
* You should have received a copy of the GNU General Public License
15
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16
*
17
* As an exception, when this program is distributed through (i) the App Store
18
* by Apple Inc.; (ii) the Mac App Store by Apple Inc.; or (iii) Google Play
19
* by Google Inc., then that store may impose any digital rights management,
20
* device limits and/or redistribution restrictions that are required by its
21
* terms of service.
22
*/
23
24
#include <iostream>
25
#include <cctype> // std::isdigit
26
#include <limits> // numeric_limits
27
28
#include "options.h"
29
#include "libnormaliz/libnormaliz.h"
30
#include "libnormaliz/map_operations.h"
31
#include "libnormaliz/cone_property.h"
32
33
// eats up a comment, stream must start with "/*", eats everything until "*/"
34
void skip_comment(istream& in) {
35
int i = in.get();
36
int j = in.get();
37
if (i != '/' || j != '*') {
38
throw BadInputException("Bad comment start!");
39
}
40
while (in.good()) {
41
in.ignore(numeric_limits<streamsize>::max(), '*'); //ignore everything until next '*'
42
i = in.get();
43
if (in.good() && i == '/') return; // successfully skipped comment
44
}
45
throw BadInputException("Incomplete comment!");
46
}
47
48
void save_matrix(map<Type::InputType, vector<vector<mpq_class> > >& input_map,
49
InputType input_type, const vector<vector<mpq_class> >& M) {
50
//check if this type already exists
51
if (exists_element(input_map, input_type)) {
52
/*throw BadInputException("Multiple inputs of type \"" + type_string
53
+ "\" are not allowed!");*/
54
input_map[input_type].insert(input_map[input_type].end(),M.begin(),M.end());
55
return;
56
}
57
input_map[input_type] = M;
58
}
59
60
void save_empty_matrix(map<Type::InputType, vector<vector<mpq_class> > >& input_map,
61
InputType input_type){
62
63
vector<vector<mpq_class> > M;
64
save_matrix(input_map, input_type, M);
65
}
66
67
68
vector<vector<mpq_class> > transpose_mat(const vector<vector<mpq_class> >& mat){
69
70
if(mat.size()==0 || mat[0].size()==0)
71
return vector<vector<mpq_class> >(0);
72
size_t m=mat[0].size();
73
size_t n=mat.size();
74
vector<vector<mpq_class> > transpose(m,vector<mpq_class> (n,0));
75
for(size_t i=0;i<m;++i)
76
for(size_t j=0;j<n;++j)
77
transpose[i][j]=mat[j][i];
78
return transpose;
79
}
80
81
82
void append_row(const vector<mpq_class> row, map <Type::InputType, vector< vector<mpq_class> > >& input_map,
83
Type::InputType input_type) {
84
85
vector<vector<mpq_class> > one_row(1,row);
86
save_matrix(input_map,input_type,one_row);
87
}
88
89
90
void process_constraint(const string& rel, const vector<mpq_class>& left, mpq_class right, const mpq_class modulus,
91
map <Type::InputType, vector< vector<mpq_class> > >& input_map, bool forced_hom) {
92
93
vector<mpq_class> row=left;
94
bool inhomogeneous=false;
95
if(right!=0 || rel=="<" || rel==">")
96
inhomogeneous=true;
97
string modified_rel=rel;
98
bool strict_inequality=false;
99
if(rel=="<"){
100
strict_inequality=true;
101
right-=1;
102
modified_rel="<=";
103
104
}
105
if(rel==">"){
106
strict_inequality=true;
107
right+=1;
108
modified_rel=">=";
109
}
110
if(strict_inequality && forced_hom){
111
throw BadInputException("Strict inequality not allowed in hom_constraints!");
112
}
113
if(inhomogeneous || forced_hom)
114
row.push_back(-right); // rhs --> lhs
115
if(modified_rel=="<="){ // convert <= to >=
116
for(size_t j=0; j<row.size();++j)
117
row[j]=-row[j];
118
modified_rel=">=";
119
}
120
if(rel=="~")
121
row.push_back(modulus);
122
123
if(inhomogeneous && !forced_hom){
124
if(modified_rel=="="){
125
append_row(row,input_map,Type::inhom_equations);
126
return;
127
}
128
if(modified_rel==">="){
129
append_row(row,input_map,Type::inhom_inequalities);
130
return;
131
}
132
if(modified_rel=="~"){
133
append_row(row,input_map,Type::inhom_congruences);
134
return;
135
}
136
}
137
else {
138
if(modified_rel=="="){
139
append_row(row,input_map,Type::equations);
140
return;
141
}
142
if(modified_rel==">="){
143
append_row(row,input_map,Type::inequalities);
144
return;
145
}
146
if(modified_rel=="~"){
147
append_row(row,input_map,Type::congruences);
148
return;
149
}
150
}
151
throw BadInputException("Illegal constrint type "+rel+" !");
152
}
153
154
mpq_class mpq_read(istream& in){
155
const string numeric="+-0123456789/.e";
156
in >> std::ws;
157
string s;
158
bool is_float=false;
159
while(true){
160
char c = in.peek();
161
size_t pos=numeric.find(c);
162
if(pos==string::npos)
163
break;
164
if(pos>12)
165
is_float=true;
166
in >> c;
167
s+=c;
168
}
169
170
if(s=="")
171
throw BadInputException("Error in input file. Most lekely mismatch of amb_space and matrix format.");
172
173
// cout << "t " << s << " f " << is_float << endl;
174
175
if(!is_float)
176
return mpq_class(s);
177
178
return dec_fraction_to_mpq(s);
179
}
180
181
182
bool read_modulus(istream& in, mpq_class& modulus) {
183
184
in >> std::ws; // gobble any leading white space
185
char dummy;
186
in >> dummy;
187
if(dummy != '(')
188
return false;
189
in >> modulus;
190
if(in.fail() || modulus==0)
191
return false;
192
in >> std::ws; // gobble any white space before closing
193
in >> dummy;
194
if(dummy != ')')
195
return false;
196
return true;
197
}
198
199
200
void read_symbolic_constraint(istream& in, string& rel, vector<mpq_class>& left, mpq_class& right, mpq_class& modulus, bool forced_hom) {
201
202
bool congruence=false;
203
bool modulus_read=false;
204
mpq_class side=1,sign;
205
right=0;
206
long hom_correction=0;
207
if(forced_hom)
208
hom_correction=1;
209
210
in >> std::ws;
211
char c = in.peek();
212
213
while(true){
214
if(c=='('){
215
if(modulus_read || !congruence || !read_modulus(in,modulus))
216
throw BadInputException("Error while reading modulus of congruence!");
217
modulus_read=true;
218
in >> std::ws;
219
c = in.peek();
220
}
221
if(modulus_read && c!=';')
222
throw BadInputException("Error while reading modulus of congruence!");
223
if(c==';'){
224
if(rel=="")
225
throw BadInputException("Missing relation in constraint");
226
in >> c;
227
if(congruence && !modulus_read)
228
throw BadInputException("Modulus missing in congrruence");
229
// cout << "LLLLL " << left << " " << rel << " RRR " << right << endl;
230
return;
231
}
232
233
bool rel_read=false;
234
235
if(c=='~' || c=='<' || c=='>' || c=='='){
236
rel_read=true;
237
if(rel!="")
238
throw BadInputException("Error while reading relation in constraint!");
239
if(c=='~')
240
congruence=true;
241
in >> c;
242
rel+=c;
243
}
244
c = in.peek();
245
if(rel!="" && (rel=="<" || rel==">") && c=='='){
246
in >> c;
247
rel+=c;
248
}
249
in >> std::ws;
250
c = in.peek();
251
if(rel_read){
252
side=-1;
253
continue;
254
}
255
sign=1;
256
if(c=='-'){
257
sign=-1;
258
in >> c;
259
}
260
if(c=='+'){
261
in >> c;
262
}
263
mpq_class entry=1;
264
in >> std::ws;
265
c = in.peek();
266
if(c!='x'){
267
if(c=='+' || c=='-')
268
throw BadInputException("Double sign in constraint");
269
entry=mpq_read(in);
270
if(in.fail())
271
throw BadInputException("Error while reading coefficient in constraint");
272
in >> std::ws;
273
c = in.peek();
274
}
275
if(c!='x'){
276
right-=side*sign*entry;
277
continue;
278
}
279
in >> c;
280
in >> std::ws;
281
c = in.peek();
282
if(c!='[')
283
throw BadInputException("Error while reading index in constraint");
284
in >> c;
285
long index;
286
in >> index;
287
if(in.fail() || index <1 || index+hom_correction> (long) left.size())
288
throw BadInputException("Error while reading index in constraint");
289
index-=1;
290
left[index]+=side*sign*entry;
291
in >> std::ws;
292
c = in.peek();
293
if(c!=']')
294
throw BadInputException("Error while reading index in constraint");
295
in >> c;
296
in >> std::ws;
297
c = in.peek();
298
continue;
299
}
300
301
}
302
303
304
305
void read_constraints(istream& in, long dim, map <Type::InputType, vector< vector<mpq_class> > >& input_map, bool forced_hom) {
306
307
long nr_constraints;
308
in >> nr_constraints;
309
310
if(in.fail() || nr_constraints < 0) {
311
throw BadInputException("Cannot read "
312
+ toString(nr_constraints) + " constraints!");
313
}
314
if(nr_constraints==0)
315
return;
316
317
bool symbolic=false;
318
319
in >> std::ws;
320
int c = in.peek();
321
if(c=='s'){
322
string dummy;
323
in >> dummy;
324
if(dummy!="symbolic")
325
throw BadInputException("Illegal keyword " + dummy
326
+ " in input!");
327
symbolic=true;
328
}
329
330
long hom_correction=0;
331
if(forced_hom)
332
hom_correction=1;
333
for(long i=0;i< nr_constraints; ++i) {
334
335
vector<mpq_class> left(dim-hom_correction);
336
string rel, modulus_str;
337
mpq_class right, modulus=0;
338
339
if(symbolic){
340
read_symbolic_constraint(in,rel,left,right,modulus,forced_hom);
341
}
342
else{ // ordinary constraint read here
343
for(long j=0;j<dim-hom_correction;++j){
344
left[j]=mpq_read(in);
345
}
346
in >> rel;
347
right=mpq_read(in);
348
if(rel=="~") {
349
if(!read_modulus(in,modulus))
350
throw BadInputException("Error while reading modulus of congruence!");
351
}
352
if (in.fail()) {
353
throw BadInputException("Error while reading constraint!");
354
}
355
}
356
process_constraint(rel,left,right,modulus,input_map,forced_hom);
357
}
358
}
359
360
void read_polynomial(istream& in, string& polynomial) {
361
362
char c;
363
while(true){
364
in >> c;
365
if(in.fail())
366
throw BadInputException("Error while reading polynomial!");
367
if(c==';'){
368
if(polynomial.size()==0)
369
throw BadInputException("Error while reading polynomial!");
370
return;
371
}
372
polynomial+=c;
373
}
374
}
375
376
377
bool read_sparse_vector(istream& in, vector<mpq_class>& input_vec, long length){
378
379
input_vec=vector<mpq_class> (length,0);
380
char dummy;
381
382
while(true){
383
in >> std::ws;
384
int c = in.peek();
385
if(c==';'){
386
in >> dummy; // swallow ;
387
return true;
388
}
389
long pos;
390
in >> pos;
391
if(in.fail())
392
return false;
393
pos--;
394
if(pos<0 || pos>=length)
395
return false;
396
in >> std::ws;
397
c=in.peek();
398
if(c!=':')
399
return false;
400
in >> dummy; // skip :
401
mpq_class value;
402
// in >> value;
403
value=mpq_read(in);
404
if(in.fail())
405
return false;
406
input_vec[pos]=value;
407
}
408
}
409
410
411
bool read_formatted_vector(istream& in, vector<mpq_class>& input_vec) {
412
413
input_vec.clear();
414
in >> std::ws;
415
char dummy;
416
in >> dummy; // read first proper character
417
if(dummy!='[')
418
return false;
419
bool one_more_entry_required=false;
420
while(true){
421
in >> std::ws;
422
if(!one_more_entry_required && in.peek()==']'){
423
in >> dummy;
424
return true;
425
}
426
mpq_class number;
427
number=mpq_read(in);
428
if(in.fail())
429
return false;
430
input_vec.push_back(number);
431
in >> std::ws;
432
one_more_entry_required=false;
433
if(in.peek()==',' || in.peek()==';'){ // skip potential separator
434
in >> dummy;
435
one_more_entry_required=true;
436
}
437
}
438
}
439
440
441
bool read_formatted_matrix(istream& in, vector<vector<mpq_class> >& input_mat, bool transpose) {
442
input_mat.clear();
443
in >> std::ws;
444
char dummy;
445
in >> dummy; // read first proper character
446
if(dummy!='[')
447
return false;
448
bool one_more_entry_required=false;
449
while(true){
450
in >> std::ws;
451
if(!one_more_entry_required && in.peek()==']'){ // closing ] found
452
in >> dummy;
453
if(transpose)
454
input_mat=transpose_mat(input_mat);
455
return true;
456
}
457
vector<mpq_class> input_vec;
458
if(!read_formatted_vector(in,input_vec)){
459
throw BadInputException("Error in reading input vector!");
460
}
461
if(input_mat.size()>0 && input_vec.size()!=input_mat[0].size()){
462
throw BadInputException("Rows of input matrix have unequal lengths!");
463
}
464
input_mat.push_back(input_vec);
465
in >> std::ws;
466
one_more_entry_required=false;
467
if(in.peek()==',' || in.peek()==';'){ // skip potential separator
468
in >> dummy;
469
one_more_entry_required=true;
470
}
471
}
472
}
473
474
475
476
map <Type::InputType, vector< vector<mpq_class> > > readNormalizInput (istream& in, OptionsHandler& options, string& polynomial, long& nr_coeff_quasipol) {
477
478
string type_string;
479
long i,j;
480
long nr_rows,nr_columns,nr_rows_or_columns;
481
InputType input_type;
482
mpq_class number;
483
ConeProperty::Enum cp;
484
bool we_have_a_polynomial=false;
485
bool we_have_nr_coeff=false;
486
487
map<Type::InputType, vector< vector<mpq_class> > > input_map;
488
typename map<Type::InputType, vector< vector<mpq_class> > >::iterator it;
489
490
in >> std::ws; // eat up any leading white spaces
491
int c = in.peek();
492
if ( c == EOF ) {
493
throw BadInputException("Empty input file!");
494
}
495
bool new_input_syntax = !std::isdigit(c);
496
497
if (new_input_syntax) {
498
long dim;
499
while (in.peek() == '/') {
500
skip_comment(in);
501
in >> std::ws;
502
}
503
in >> type_string;
504
if (!in.good() || type_string != "amb_space") {
505
throw BadInputException("First entry must be \"amb_space\"!");
506
}
507
bool dim_known=false;
508
in >> std::ws;
509
c=in.peek();
510
if(c=='a'){
511
string dummy;
512
in >> dummy;
513
if(dummy!="auto"){
514
throw BadInputException("Bad amb_space value!");
515
}
516
}
517
else{
518
in >> dim;
519
if (!in.good() || dim <= 0) {
520
throw BadInputException("Bad amb_space value!");
521
}
522
dim_known=true;
523
}
524
while (in.good()) { //main loop
525
526
bool transpose=false;
527
in >> std::ws; // eat up any leading white spaces
528
c = in.peek();
529
if (c == EOF) break;
530
if (c == '/') {
531
skip_comment(in);
532
} else {
533
in >> type_string;
534
if (in.fail()) {
535
throw BadInputException("Could not read type string!");
536
}
537
if (std::isdigit(c)) {
538
throw BadInputException("Unexpected number " + type_string
539
+ " when expecting a type!");
540
}
541
if (isConeProperty(cp, type_string)) {
542
options.activateInputFileConeProperty(cp);
543
continue;
544
}
545
/* if (type_string == "BigInt") {
546
options.activateInputFileBigInt();
547
continue;
548
} */
549
if (type_string == "LongLong") {
550
options.activateInputFileLongLong();
551
continue;
552
}
553
if (type_string == "NoExtRaysOutput") {
554
options.activateNoExtRaysOutput();
555
continue;
556
}
557
if (type_string == "total_degree") {
558
if(!dim_known){
559
throw BadInputException("Ambient space must be known for "+type_string+"!");
560
}
561
input_type = Type::grading;
562
save_matrix(input_map, input_type, vector< vector<mpq_class> >(1,vector<mpq_class>(dim+type_nr_columns_correction(input_type),1)));
563
continue;
564
}
565
if (type_string == "nonnegative") {
566
if(!dim_known){
567
throw BadInputException("Ambient space must be known for "+type_string+"!");
568
}
569
input_type = Type::signs;
570
save_matrix(input_map, input_type, vector< vector<mpq_class> >(1,vector<mpq_class>(dim+type_nr_columns_correction(input_type),1)));
571
continue;
572
}
573
if(type_string == "constraints") {
574
if(!dim_known){
575
throw BadInputException("Ambient space must be known for "+type_string+"!");
576
}
577
read_constraints(in,dim,input_map,false);
578
continue;
579
}
580
if(type_string == "hom_constraints") {
581
if(!dim_known){
582
throw BadInputException("Ambient space must be known for "+type_string+"!");
583
}
584
read_constraints(in,dim,input_map,true);
585
continue;
586
}
587
588
if(type_string == "polynomial") {
589
if(we_have_a_polynomial)
590
throw BadInputException("Only one polynomial allowed");
591
read_polynomial(in,polynomial);
592
we_have_a_polynomial=true;
593
continue;
594
}
595
if(type_string=="nr_coeff_quasipol"){
596
if(we_have_nr_coeff)
597
throw BadInputException("Only one nr_coeff_quasipol allowed");
598
in >> nr_coeff_quasipol;
599
we_have_nr_coeff=true;
600
if(in.fail())
601
throw BadInputException("Error while reading nr_coeff_quasipol");
602
continue;
603
}
604
605
606
input_type = to_type(type_string);
607
if(dim_known)
608
nr_columns = dim + type_nr_columns_correction(input_type);
609
610
if (type_is_vector(input_type)) {
611
nr_rows_or_columns = nr_rows = 1;
612
in >> std::ws; // eat up any leading white spaces
613
c = in.peek();
614
if (c=='u') { // must be unit vector
615
string vec_kind;
616
in >> vec_kind;
617
if (vec_kind != "unit_vector") {
618
throw BadInputException("Error while reading "
619
+ type_string
620
+ ": unit_vector expected!");
621
}
622
623
long pos = 0;
624
in >> pos;
625
if (in.fail()) {
626
throw BadInputException("Error while reading "
627
+ type_string
628
+ " as a unit_vector!");
629
}
630
631
if(!dim_known){
632
throw BadInputException("Ambient space must be known for unit vector "+type_string+"!");
633
}
634
635
vector< vector<mpq_class> > e_i = vector< vector<mpq_class> >(1,vector<mpq_class>(nr_columns,0));
636
if (pos < 1 || pos > static_cast<long>(e_i[0].size())) {
637
throw BadInputException("Error while reading "
638
+ type_string + " as a unit_vector "
639
+ toString(pos) + "!");
640
}
641
pos--; // in input file counting starts from 1
642
e_i[0].at(pos) = 1;
643
save_matrix(input_map, input_type, e_i);
644
continue;
645
} // end unit vector
646
647
if(c=='s'){ // must be "sparse"
648
string vec_kind;
649
in >> vec_kind;
650
if (vec_kind != "sparse") {
651
throw BadInputException("Error while reading "
652
+ type_string
653
+ ": sparse vector expected!");
654
}
655
656
if(!dim_known){
657
throw BadInputException("Ambient space must be known for sparse vector "+type_string+"!");
658
}
659
660
vector<mpq_class> sparse_vec;
661
nr_columns = dim + type_nr_columns_correction(input_type);
662
bool success = read_sparse_vector(in,sparse_vec,nr_columns);
663
if(!success){
664
throw BadInputException("Error while reading "
665
+ type_string
666
+ " as a sparse vector!");
667
}
668
save_matrix(input_map, input_type, vector<vector<mpq_class> > (1,sparse_vec));
669
continue;
670
}
671
672
if (c == '[') { // must be formatted vector
673
vector<mpq_class> formatted_vec;
674
bool success = read_formatted_vector(in,formatted_vec);
675
if(!dim_known){
676
dim=formatted_vec.size()- type_nr_columns_correction(input_type);
677
dim_known=true;
678
nr_columns = dim + type_nr_columns_correction(input_type);
679
}
680
if(!success || (long) formatted_vec.size()!=nr_columns){
681
throw BadInputException("Error while reading "
682
+ type_string
683
+ " as a formatted vector!");
684
}
685
save_matrix(input_map, input_type, vector<vector<mpq_class> > (1,formatted_vec));
686
continue;
687
} // end formatted vector
688
689
} else { // end vector, it is a matrix. Plain vector read as a one row matrix later on
690
in >> std::ws;
691
c = in.peek();
692
693
if(c!='[' && !std::isdigit(c)){ // must be transpose
694
string transpose_str;
695
in >> transpose_str;
696
if(transpose_str!="transpose"){
697
throw BadInputException("Illegal keyword "+transpose_str+" following matrix type!");
698
}
699
transpose=true;
700
in >> std::ws;
701
c = in.peek();
702
}
703
if(c=='['){ // it is a formatted matrix
704
vector<vector<mpq_class> > formatted_mat;
705
bool success=read_formatted_matrix(in,formatted_mat, transpose);
706
if(!success){
707
throw BadInputException("Error while reading formatted matrix "
708
+ type_string + "!");
709
}
710
if(formatted_mat.size() ==0){ // empty matrix
711
input_type = to_type(type_string);
712
save_empty_matrix(input_map, input_type);
713
continue;
714
}
715
if(!dim_known){
716
dim=formatted_mat[0].size()- type_nr_columns_correction(input_type);
717
dim_known=true;
718
nr_columns = dim + type_nr_columns_correction(input_type);
719
}
720
721
if((long) formatted_mat[0].size()!=nr_columns){
722
throw BadInputException("Error while reading formatted matrix "
723
+ type_string + "!");
724
}
725
726
save_matrix(input_map, input_type, formatted_mat);
727
continue;
728
} // only plain matrix left
729
730
in >> nr_rows_or_columns; // is number of columns if transposed
731
nr_rows=nr_rows_or_columns; // most of the time
732
}
733
734
if(!dim_known){
735
throw BadInputException("Ambient space must be known for plain matrix or vector "+type_string+"!");
736
}
737
738
if(transpose)
739
swap(nr_rows,nr_columns);
740
741
if(in.fail() || nr_rows_or_columns < 0) {
742
throw BadInputException("Error while reading "
743
+ type_string + " (a " + toString(nr_rows)
744
+ "x" + toString(nr_columns)
745
+ " matrix) !");
746
}
747
if(nr_rows==0){
748
input_type = to_type(type_string);
749
save_empty_matrix(input_map, input_type);
750
continue;
751
}
752
753
vector< vector<mpq_class> > M(nr_rows);
754
in >> std::ws;
755
c=in.peek();
756
if(c=='s'){ // must be sparse
757
string sparse_test;
758
in >> sparse_test;
759
if (sparse_test!= "sparse") {
760
throw BadInputException("Error while reading "
761
+ type_string
762
+ ": sparse matrix expected!");
763
}
764
for(long i=0;i<nr_rows;++i){
765
bool success=read_sparse_vector(in,M[i],nr_columns);
766
if(!success){
767
throw BadInputException("Error while reading "
768
+ type_string
769
+ ": corrupted sparse matrix");
770
}
771
772
}
773
} else{ // dense matrix
774
for(i=0; i<nr_rows; i++){
775
M[i].resize(nr_columns);
776
for(j=0; j<nr_columns; j++) {
777
M[i][j]=mpq_read(in);
778
}
779
}
780
}
781
if(transpose)
782
M=transpose_mat(M);
783
save_matrix(input_map, input_type, M);
784
}
785
if (in.fail()) {
786
throw BadInputException("Error while reading " + type_string
787
+ " (a " + toString(nr_rows) + "x"
788
+ toString(nr_columns) + " matrix) !");
789
}
790
}
791
} else {
792
// old input syntax
793
while (in.good()) {
794
in >> nr_rows;
795
if(in.fail())
796
break;
797
in >> nr_columns;
798
if((nr_rows <0) || (nr_columns < 0)){
799
throw BadInputException("Error while reading a "
800
+ toString(nr_rows) + "x" + toString(nr_columns)
801
+ " matrix !");
802
}
803
vector< vector<mpq_class> > M(nr_rows,vector<mpq_class>(nr_columns));
804
for(i=0; i<nr_rows; i++){
805
for(j=0; j<nr_columns; j++) {
806
number=mpq_read(in);
807
M[i][j] = number;
808
}
809
}
810
811
in >> type_string;
812
813
if ( in.fail() ) {
814
throw BadInputException("Error while reading a "
815
+ toString(nr_rows) + "x" + toString(nr_columns)
816
+ " matrix!");
817
}
818
819
input_type = to_type(type_string);
820
821
//check if this type already exists
822
save_matrix(input_map, input_type, M);
823
}
824
}
825
return input_map;
826
}
827