CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

| Download

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

Views: 418425
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
/**
25
* The class Sublattice_Representation represents a sublattice of Z^n as Z^r.
26
* To transform vectors of the sublattice use:
27
* Z^r --> Z^n and Z^n --> Z^r
28
* v |-> vA u |-> (uB)/c
29
* A r x n matrix
30
* B n x r matrix
31
* c Number
32
*
33
* We have kept c though it is always 1 for coefficients over a field
34
*/
35
36
37
#include "libQnormaliz/Qsublattice_representation.h"
38
#include "libQnormaliz/Qvector_operations.h"
39
40
//---------------------------------------------------------------------------
41
42
namespace libQnormaliz {
43
using namespace std;
44
45
/**
46
* creates a representation of Z^n as a sublattice of itself
47
*/
48
template<typename Number>
49
Sublattice_Representation<Number>::Sublattice_Representation(size_t n) {
50
dim = n;
51
rank = n;
52
external_index = 1;
53
A = Matrix<Number>(n);
54
B = Matrix<Number>(n);
55
c = 1;
56
Equations_computed=false;
57
is_identity=true;
58
}
59
60
//---------------------------------------------------------------------------
61
62
/**
63
* Main Constructor
64
* creates a representation of a sublattice of Z^n
65
* if direct_summand is false the sublattice is generated by the rows of M
66
* otherwise it is a direct summand of Z^n containing the rows of M
67
*/
68
69
template<typename Number>
70
Sublattice_Representation<Number>::Sublattice_Representation(const Matrix<Number>& M, bool take_saturation) {
71
initialize(M); // take saturation is complewtely irrelevant for coefficients in a field
72
}
73
74
75
template<typename Number>
76
void Sublattice_Representation<Number>::initialize(const Matrix<Number>& M) {
77
78
Equations_computed=false;
79
is_identity=false;
80
81
dim=M.nr_of_columns();
82
Matrix<Number> N=M;
83
84
bool success; // dummy for field coefficients
85
rank=N.row_echelon_reduce(success); // cleans corner columns and makes corner elements positive
86
87
if(rank==dim){
88
A = B = Matrix<Number>(dim);
89
c=1;
90
is_identity=true;
91
return;
92
}
93
94
vector<key_t> col(rank);
95
vector<bool> col_is_corner(dim,false);
96
for(size_t k=0;k<rank;++k){
97
size_t j=0;
98
for(;j<dim;++j)
99
if(N[k][j]!=0)
100
break;
101
col_is_corner[j]=true;
102
col[k]=j;
103
if(N[k][j]<0)
104
v_scalar_multiplication<Number>(N[k],-1);
105
}
106
107
A=Matrix<Number>(rank, dim);
108
B=Matrix<Number>(dim,rank);
109
110
for(size_t k=0;k<rank;++k)
111
A[k]=N[k];
112
size_t j=0;
113
for(size_t k=0;k<dim;++k){
114
if(col_is_corner[k]){
115
B[k][j]=1/A[j][k]; //to make the inverse of the diagonal matrix that we get
116
j++; // by extracting the corner columns
117
}
118
};
119
c=1;
120
return;
121
122
}
123
124
//---------------------------------------------------------------------------
125
// Constructor by conversion
126
//---------------------------------------------------------------------------
127
128
template<typename Number>
129
template<typename NumberFC>
130
Sublattice_Representation<Number>::Sublattice_Representation(const
131
Sublattice_Representation<NumberFC>& Original) {
132
133
convert(A,Original.A);
134
convert(B,Original.B);
135
dim=Original.dim;
136
rank=Original.rank;
137
convert(c,Original.c);
138
is_identity=Original.is_identity;
139
Equations_computed=Original.Equations_computed;
140
convert(Equations,Original.Equations);
141
external_index=Original.external_index;
142
}
143
144
145
//---------------------------------------------------------------------------
146
// Manipulation operations
147
//---------------------------------------------------------------------------
148
149
/* first this then SR when going from Z^n to Z^r */
150
template<typename Number>
151
void Sublattice_Representation<Number>::compose(const Sublattice_Representation& SR) {
152
assert(rank == SR.dim); //TODO vielleicht doch exception?
153
154
if(SR.is_identity)
155
return;
156
157
if(is_identity){
158
*this=SR;
159
return;
160
}
161
162
Equations_computed=false;
163
164
165
rank = SR.rank;
166
// A = SR.A * A
167
A = SR.A.multiplication(A);
168
// B = B * SR.B
169
B = B.multiplication(SR.B);
170
c = c * SR.c;
171
172
is_identity&=SR.is_identity;
173
}
174
175
template<typename Number>
176
void Sublattice_Representation<Number>::compose_dual(const Sublattice_Representation& SR) {
177
178
assert(rank == SR.dim); //
179
assert(SR.c==1);
180
181
if(SR.is_identity)
182
return;
183
184
Equations_computed=false;
185
rank = SR.rank;
186
187
if(is_identity){
188
A=SR.B.transpose();
189
B=SR.A.transpose();
190
is_identity=false;
191
return;
192
}
193
194
// Now we compose with the dual of SR
195
A = SR.B.transpose().multiplication(A);
196
// B = B * SR.B
197
B = B.multiplication(SR.A.transpose());
198
199
//check if a factor can be extraced from B //TODO necessary?
200
Number g=1; // = B.matrix_gcd();
201
is_identity&=SR.is_identity;
202
}
203
204
//---------------------------------------------------------------------------
205
// Transformations
206
//---------------------------------------------------------------------------
207
208
template<typename Number>
209
Matrix<Number> Sublattice_Representation<Number>::to_sublattice (const Matrix<Number>& M) const {
210
Matrix<Number> N;
211
if(is_identity)
212
N=M;
213
else
214
N = M.multiplication(B);
215
if (c!=1) N.scalar_division(c);
216
return N;
217
}
218
template<typename Number>
219
Matrix<Number> Sublattice_Representation<Number>::from_sublattice (const Matrix<Number>& M) const {
220
Matrix<Number> N;
221
if(is_identity)
222
N=M;
223
else
224
N = M.multiplication(A);
225
return N;
226
}
227
228
template<typename Number>
229
Matrix<Number> Sublattice_Representation<Number>::to_sublattice_dual (const Matrix<Number>& M) const {
230
Matrix<Number> N;
231
if(is_identity)
232
N=M;
233
else
234
N = M.multiplication(A.transpose());
235
N.simplify_rows();
236
return N;
237
}
238
239
template<typename Number>
240
Matrix<Number> Sublattice_Representation<Number>::from_sublattice_dual (const Matrix<Number>& M) const {
241
Matrix<Number> N;
242
if(is_identity)
243
N=M;
244
else
245
N = M.multiplication(B.transpose());
246
N.simplify_rows();
247
return N;
248
}
249
250
251
template<typename Number>
252
vector<Number> Sublattice_Representation<Number>::to_sublattice (const vector<Number>& V) const {
253
if(is_identity)
254
return V;
255
vector<Number> N = B.VxM(V);
256
if (c!=1) v_scalar_division(N,c);
257
return N;
258
}
259
260
template<typename Number>
261
vector<Number> Sublattice_Representation<Number>::from_sublattice (const vector<Number>& V) const {
262
if(is_identity)
263
return V;
264
vector<Number> N = A.VxM(V);
265
return N;
266
}
267
268
template<typename Number>
269
vector<Number> Sublattice_Representation<Number>::to_sublattice_dual (const vector<Number>& V) const {
270
vector<Number> N;
271
if(is_identity)
272
N=V;
273
else
274
N = A.MxV(V);
275
v_simplify(N);
276
return N;
277
}
278
279
template<typename Number>
280
vector<Number> Sublattice_Representation<Number>::from_sublattice_dual (const vector<Number>& V) const {
281
vector<Number> N;
282
if(is_identity)
283
N=V;
284
else
285
N = B.MxV(V);
286
v_simplify(N);
287
return N;
288
}
289
290
template<typename Number>
291
vector<Number> Sublattice_Representation<Number>::to_sublattice_dual_no_div (const vector<Number>& V) const {
292
if(is_identity)
293
return V;
294
vector<Number> N = A.MxV(V);
295
return N;
296
}
297
298
//---------------------------------------------------------------------------
299
// Data access
300
//---------------------------------------------------------------------------
301
302
/* returns the dimension of the ambient space */
303
template<typename Number>
304
size_t Sublattice_Representation<Number>::getDim() const {
305
return dim;
306
}
307
308
//---------------------------------------------------------------------------
309
310
/* returns the rank of the sublattice */
311
template<typename Number>
312
size_t Sublattice_Representation<Number>::getRank() const {
313
return rank;
314
}
315
316
//---------------------------------------------------------------------------
317
318
template<typename Number>
319
const Matrix<Number>& Sublattice_Representation<Number>::getEmbeddingMatrix() const {
320
return A;
321
}
322
323
template<typename Number>
324
const vector<vector<Number> >& Sublattice_Representation<Number>::getEmbedding() const{
325
return getEmbeddingMatrix().get_elements();
326
}
327
328
//---------------------------------------------------------------------------
329
330
template<typename Number>
331
const Matrix<Number>& Sublattice_Representation<Number>::getProjectionMatrix() const {
332
return B;
333
}
334
335
template<typename Number>
336
const vector<vector<Number> >& Sublattice_Representation<Number>::getProjection() const{
337
return getProjectionMatrix().get_elements();
338
}
339
340
341
//---------------------------------------------------------------------------
342
343
template<typename Number>
344
Number Sublattice_Representation<Number>::getAnnihilator() const {
345
return c;
346
}
347
348
//---------------------------------------------------------------------------
349
350
template<typename Number>
351
bool Sublattice_Representation<Number>::IsIdentity() const{
352
return is_identity;
353
}
354
355
//---------------------------------------------------------------------------
356
357
358
template<typename Number>
359
const Matrix<Number>& Sublattice_Representation<Number>::getEquationsMatrix() const{
360
361
if(!Equations_computed)
362
make_equations();
363
return Equations;
364
}
365
366
template<typename Number>
367
const vector<vector<Number> >& Sublattice_Representation<Number>::getEquations() const{
368
return getEquationsMatrix().get_elements();
369
}
370
371
template<typename Number>
372
void Sublattice_Representation<Number>::make_equations() const{
373
374
if(rank==dim)
375
Equations=Matrix<Number>(0,dim);
376
else
377
Equations=A.kernel();
378
Equations.simplify_rows();
379
Equations_computed=true;
380
}
381
382
383
}
384
385