File: ReadLatteStyle.cpp

package info (click to toggle)
latte-int 1.7.6%2Bds-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 38,260 kB
  • sloc: cpp: 32,231; sh: 4,413; makefile: 811; perl: 300
file content (199 lines) | stat: -rw-r--r-- 5,947 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
/* ReadLatteStyle.cpp -- Read input data in the LattE style

 Copyright 2006 Matthias Koeppe

 This file is part of LattE.

 LattE is free software; you can redistribute it and/or modify it
 under the terms of the version 2 of the GNU General Public License
 as published by the Free Software Foundation.

 LattE is distributed in the hope that it will be useful, but
 WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with LattE; if not, write to the Free Software Foundation,
 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
 */

#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <cctype>
#include "ReadLatteStyle.h"
#include "latte_gmp.h"
#include "latte_cddlib.h"
#include "vertices/cdd.h"
#include "LattException.h"
#include <vector>

using namespace std;

static void check_stream(const istream &f, const char *fileName,
		const char *proc) {
	if (f.bad() || f.fail()) {
		cerr << "Read error on input file " << fileName << " in " << proc
				<< "." << endl;
		THROW_LATTE(LattException::fe_Open, 0);
	}
}
;

dd_MatrixPtr ReadLatteStyleMatrix(const char *fileName, bool vrep,
		bool homogenize, bool nonnegativity) {
	ifstream f(fileName);
	if (!f) {
		cerr << "Cannot open input file " << fileName
				<< " in ReadLatteStyleMatrix." << endl;
		THROW_LATTE(LattException::fe_Open, 0);
	}
	return ReadLatteStyleMatrix(f, vrep, homogenize, fileName, nonnegativity);
}

/* NONNEGATIVITY contains 1-based variable indices.
 Add corrresponding non-negativity constraints and return a new
 matrix.
 */
static dd_MatrixPtr add_nonnegativity(dd_MatrixPtr matrix,
		const vector<int> &nonnegatives, int num_homog) {
	int num_nonnegative = nonnegatives.size();
	int numOfVectors = matrix->rowsize;
	int numOfVars_hom = matrix->colsize;
	int numOfVars = numOfVars_hom - num_homog;
	dd_MatrixPtr new_matrix = dd_CreateMatrix(numOfVectors + num_nonnegative,
			numOfVars_hom);
	new_matrix->numbtype = dd_Rational;
	new_matrix->representation = dd_Inequality;
	int i, j;
	for (i = 0; i < numOfVectors; i++) {
		for (j = 0; j < numOfVars_hom; j++)
			dd_set(new_matrix->matrix[i][j], matrix->matrix[i][j]);
		if (set_member(i + 1, matrix->linset))
			set_addelem(new_matrix->linset, i + 1);
	}
	int k;
	for (k = 0; k < num_nonnegative; k++, i++) {
		int index = nonnegatives[k]; /* 1-based */
		for (j = 0; j < numOfVars; j++)
			dd_set_si(new_matrix->matrix[i][j + num_homog], 0);
		dd_set_si(new_matrix->matrix[i][index + num_homog], 1);
	}
	return new_matrix;
}

dd_MatrixPtr ReadLatteStyleMatrix(istream &f, bool vrep, bool homogenize,
		const char *fileName, bool nonnegativity) {
	dd_set_global_constants();
	int numOfVectors, numOfVars;
	f >> numOfVectors >> numOfVars;
	int num_homog = homogenize ? 1 : 0;
	int numOfVars_hom = numOfVars + num_homog;
	check_stream(f, fileName, "ReadLatteStyleMatrix");
	dd_MatrixPtr matrix = dd_CreateMatrix(numOfVectors, numOfVars_hom);
	matrix->numbtype = dd_Rational;
	if (vrep)
		matrix->representation = dd_Generator;
	else
		matrix->representation = dd_Inequality;
	int i, j;
	mpq_class x;
	for (i = 0; i < numOfVectors; i++) {
		for (j = 0; j < numOfVars; j++) {
			f >> x;
			check_stream(f, fileName, "ReadLatteStyleMatrix");
			dd_set(matrix->matrix[i][j + num_homog], x.get_mpq_t());
		}
	}
	// Skip whitespace
	while (isspace(f.peek())) {
		char c;
		f.get(c);
	}
	while (!f.eof()) {
		// Interpret keywords
		char buffer[20];
		f.get(buffer, 20, ' ');
		if (strcmp(buffer, "linearity") == 0) {
			int num_linearity;
			f >> num_linearity;
			check_stream(f, fileName, "ReadLatteStyleMatrix");
			int i;
			for (i = 0; i < num_linearity; i++) {
				int index; /* 1-based */
				f >> index;
				check_stream(f, fileName, "ReadLatteStyleMatrix");
				set_addelem(matrix->linset, index /* 1-based */);
			}
		} else if (strcmp(buffer, "nonnegative") == 0) {
			if (vrep) {
				cerr << "Keyword `" << buffer << "' not valid in vrep mode."
						<< endl;
				THROW_LATTE(LattException::ue_BadFileOption, 0);
			}
			int num_nonnegative;
			f >> num_nonnegative;
			check_stream(f, fileName, "ReadLatteStyleMatrix");
			vector<int> nonnegatives(num_nonnegative);
			int k;
			for (k = 0; k < num_nonnegative; k++) {
				int index; /* 1-based */
				f >> index;
				check_stream(f, fileName, "ReadLatteStyleMatrix");
				nonnegatives[k] = index;
			}
			// Create a new matrix that includes non-negativity
			// inequalities.
			dd_MatrixPtr new_matrix = add_nonnegativity(matrix, nonnegatives,
					num_homog);
			dd_FreeMatrix(matrix);
			matrix = new_matrix;
		} else {
			cerr << "Unknown keyword `" << buffer << "' in input file "
					<< fileName << " in ReadLatteStyleMatrix." << endl;
			THROW_LATTE(LattException::ue_BadFileOption, 0);
		}
		// Skip whitespace
		while (!f.eof() && isspace(f.peek())) {
			char c;
			f.get(c);
		}
	}
	if (nonnegativity) {
		vector<int> nonnegatives(numOfVars);
		int k;
		for (k = 0; k < numOfVars; k++)
			nonnegatives[k] = k + 1; /* 1-based indices */
		dd_MatrixPtr new_matrix = add_nonnegativity(matrix, nonnegatives,
				num_homog);
		dd_FreeMatrix(matrix);
		matrix = new_matrix;
	}
	return matrix;
}

void WriteLatteStyleMatrix(const char *fileName, dd_MatrixPtr matrix) {
	ofstream f(fileName);
	WriteLatteStyleMatrix(f, matrix);
}

void WriteLatteStyleMatrix(ostream &f, dd_MatrixPtr matrix) {
	f << matrix->rowsize << " " << matrix->colsize << endl;
	int i;
	for (i = 0; i < matrix->rowsize; i++) {
		int j;
		for (j = 0; j < matrix->colsize; j++)
			f << matrix->matrix[i][j] << " ";
		f << endl;
	}
	int num_linearity = set_card(matrix->linset);
	if (num_linearity > 0) {
		f << "linearity " << num_linearity << " ";
		for (i = 1; i <= matrix->rowsize; i++)
			if (set_member(i, matrix->linset))
				f << i << " ";
		f << endl;
	}
}