2 4ti2 -- A software package for algebraic, geometric and combinatorial
3 problems on linear spaces.
5 Copyright (C) 2006 4ti2 team.
6 Main author(s): Matthias Walter.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 #include "linearsystem.h"
32 LinearSystem
createLinearSystem()
34 LinearSystem system
= (LinearSystem
)malloc(sizeof(linearsystem_t
));
38 fprintf(stderr
, "Fatal Error (%s/%d): Could not allocate memory for LinearSystem!\n", __FILE__
, __LINE__
);
42 system
->Equations
= 0;
43 system
->Variables
= 0;
46 system
->EqProperties
= NULL
;
47 system
->VarProperties
= NULL
;
54 void deleteLinearSystem(LinearSystem system
)
60 for (i
=0; i
<system
->Variables
; i
++)
61 deleteVector(system
->A
[i
]);
63 deleteVector(system
->b
);
64 deleteVariableProperties(system
->VarProperties
);
65 if (system
->EqProperties
)
66 free(system
->EqProperties
);
73 void setLinearSystemSize(LinearSystem system
, int variables
, int equations
)
81 if (variables
!=system
->Variables
|| equations
!=system
->Equations
)
85 for (i
=0; i
<system
->Variables
; i
++)
86 deleteVector(system
->A
[i
]);
93 system
->A
= (Vector
*)malloc(variables
*sizeof(Vector
));
96 fprintf(stderr
, "Fatal Error (%s/%d): Could not allocate memory for LinearSystem->A!\n", __FILE__
, __LINE__
);
99 for (i
=0; i
<variables
; i
++)
100 system
->A
[i
] = createVector(equations
);
104 if (equations
!=system
->Equations
)
108 deleteVector(system
->b
);
110 free(system
->EqProperties
);
111 system
->EqProperties
= NULL
;
115 system
->b
= createVector(equations
);
116 system
->EqProperties
= (EquationProperties
)malloc(equations
*sizeof(equationproperty_t
));
117 if (system
->EqProperties
==NULL
)
119 fprintf(stderr
, "Fatal Error (%s/%d): Could not allocate memory for LinearSystem->EqProperties!\n", __FILE__
, __LINE__
);
122 for (i
=0; i
<equations
; i
++)
124 system
->EqProperties
[i
].Type
= EQUATION_EQUAL
;
125 system
->EqProperties
[i
].Modulus
= 0;
130 if (variables
!=system
->Variables
)
132 if (system
->VarProperties
!=NULL
)
134 deleteVariableProperties(system
->VarProperties
);
135 system
->VarProperties
= NULL
;
138 system
->VarProperties
= createVariableProperties(variables
);
141 system
->Variables
= variables
;
142 system
->Equations
= equations
;
147 void setLinearSystemMatrix(LinearSystem system
, Matrix matrix
)
154 setLinearSystemSize(system
, matrix
->Width
, matrix
->Height
);
156 for (i
=0; i
<system
->Variables
; i
++)
157 for (j
=0; j
<system
->Equations
; j
++)
158 system
->A
[i
][j
] = matrix
->Data
[i
+j
*system
->Variables
];
163 void setLinearSystemRHS(LinearSystem system
, Vector vector
)
170 deleteVector(system
->b
);
174 if (system
->Equations
)
175 system
->b
= copyVector(vector
, system
->Equations
);
180 void setLinearSystemLimit(LinearSystem system
, int id
, int lower
, int upper
, bool free
)
186 if (id
>=0 && id
<system
->Variables
)
188 system
->VarProperties
[id
].Free
= free
;
189 system
->VarProperties
[id
].Lower
= lower
;
190 system
->VarProperties
[id
].Upper
= upper
;
194 for (id
=0; id
<system
->Variables
; id
++)
196 system
->VarProperties
[id
].Free
= free
;
197 system
->VarProperties
[id
].Lower
= lower
;
198 system
->VarProperties
[id
].Upper
= upper
;
205 void setLinearSystemBound(LinearSystem system
, int id
, char type
, int value
)
209 assert(id
<system
->Variables
);
210 assert(type
== 'u' || type
== 'l');
213 system
->VarProperties
[id
].Upper
= value
;
214 else if (type
== 'l')
215 system
->VarProperties
[id
].Lower
= value
;
220 void setLinearSystemEquationType(LinearSystem system
, int id
, EquationType type
, int modulus
)
224 assert(type
|| EQUATION_MODULO
|| modulus
!=0);
228 system
->EqProperties
[id
].Type
= type
;
229 system
->EqProperties
[id
].Modulus
= modulus
;
233 for (id
=0; id
<system
->Equations
; id
++)
235 system
->EqProperties
[id
].Type
= type
;
236 system
->EqProperties
[id
].Modulus
= modulus
;
243 int imax(int a
, int b
)
245 return a
> b
? a
: b
;
250 int numberSize(int value
)
271 int equationSize(EquationType type
)
281 int propertySize(variableproperty_t property
)
283 return (property
.Free
? 1 : imax(
284 (property
.Lower
==-MAXINT
? 1 : numberSize(property
.Lower
)),
285 (property
.Upper
==MAXINT
? 1 : numberSize(property
.Upper
))
291 void fprintLinearSystem(FILE *stream
, LinearSystem system
)
297 if (!stream
|| !system
)
299 fprintf(stderr
, "Fatal Error (%s/%d): printLinearSystem was called with wrong arguments!\n", __FILE__
, __LINE__
);
303 space
= createVector(system
->Variables
+2);
305 // Collect space need by all columns
306 for (i
=0; i
<system
->Variables
; i
++)
308 if (!checkVariableFree(system
->VarProperties
, i
))
310 space
[i
] = propertySize(system
->VarProperties
[i
]);
311 for (j
=0; j
<system
->Equations
; j
++)
312 space
[i
] = imax(space
[i
], numberSize(system
->A
[i
][j
]));
314 space
[system
->Variables
] = 0;
315 space
[system
->Variables
+1] = 0;
316 for (i
=0; i
< system
->Equations
; i
++)
318 space
[system
->Variables
] = imax(space
[system
->Variables
], equationSize(system
->EqProperties
[i
].Type
));
319 space
[system
->Variables
+1] = imax(space
[system
->Variables
+1], numberSize(system
->b
[i
]));
325 for (i
=0; i
<system
->Variables
; i
++)
327 if (checkVariableFree(system
->VarProperties
, i
))
328 fprintf(stream
, "%*s ", space
[i
], "");
329 else if (system
->VarProperties
[i
].Upper
==MAXINT
)
330 fprintf(stream
, "%*s ", space
[i
], "+");
332 fprintf(stream
, "%*d ", space
[i
], system
->VarProperties
[i
].Upper
);
334 fprintf(stream
, "\n");
335 for (i
=0; i
<system
->Variables
; i
++)
337 if (checkVariableFree(system
->VarProperties
, i
))
338 fprintf(stream
, "%*s ", space
[i
], "");
339 else if (system
->VarProperties
[i
].Lower
==-MAXINT
)
340 fprintf(stream
, "%*s ", space
[i
], "-");
342 fprintf(stream
, "%*d ", space
[i
], system
->VarProperties
[i
].Lower
);
344 fprintf(stream
, "\n\n");
347 for (i
=0; i
<system
->Equations
; i
++)
349 for (j
=0; j
<system
->Variables
; j
++)
350 fprintf(stream
, "%*d ", space
[j
], system
->A
[j
][i
]);
351 switch (system
->EqProperties
[i
].Type
)
354 case EQUATION_MODULO
:
355 fprintf(stream
, "%*s ", space
[system
->Variables
], "=");
357 case EQUATION_LESSER
:
358 fprintf(stream
, "%*s ", space
[system
->Variables
], "<");
360 case EQUATION_LESSEREQUAL
:
361 fprintf(stream
, "%*s ", space
[system
->Variables
], "<=");
363 case EQUATION_GREATER
:
364 fprintf(stream
, "%*s ", space
[system
->Variables
], ">");
366 case EQUATION_GREATEREQUAL
:
367 fprintf(stream
, "%*s ", space
[system
->Variables
], ">=");
370 fprintf(stream
, "%*d", space
[system
->Variables
+1], system
->b
[i
]);
371 if (system
->EqProperties
[i
].Type
==EQUATION_MODULO
)
372 fprintf(stream
, " (mod %d)", system
->EqProperties
[i
].Modulus
);
373 fprintf(stream
, "\n");
381 void printLinearSystem(LinearSystem system
)
383 fprintLinearSystem(stdout
, system
);
388 LinearSystem
homogenizeLinearSystem(LinearSystem old
)
396 new = createLinearSystem();
398 new->Equations
= old
->Equations
;
399 new->Variables
= old
->Variables
;
401 // RHS stays temporarily the same
402 new->b
= copyVector(old
->b
, old
->Equations
);
404 // Original matrix with properties
405 new->A
= (Vector
*)malloc(new->Variables
*sizeof(Vector
));
406 new->VarProperties
= createVariableProperties(new->Variables
);
407 for (i
=0; i
<new->Variables
; i
++)
409 new->A
[i
] = copyVector(old
->A
[i
], old
->Equations
);
410 new->VarProperties
[i
] = old
->VarProperties
[i
];
414 for (i
=0; i
<old
->Equations
; i
++)
416 if (old
->EqProperties
[i
].Type
==EQUATION_LESSER
)
420 if (old
->EqProperties
[i
].Type
==EQUATION_GREATER
)
422 switch (old
->EqProperties
[i
].Type
)
424 case EQUATION_LESSER
:
425 case EQUATION_LESSEREQUAL
:
428 case EQUATION_GREATER
:
429 case EQUATION_GREATEREQUAL
:
432 case EQUATION_MODULO
:
433 k
= old
->EqProperties
[i
].Modulus
;
442 new->A
= (Vector
*)realloc(new->A
, new->Variables
*sizeof(Vector
));
443 new->VarProperties
= (VariableProperties
)realloc(new->VarProperties
, new->Variables
*sizeof(variableproperty_t
));
444 new->A
[new->Variables
-1] = createVector(new->Equations
);
445 for (j
=0; j
<new->Equations
; j
++)
446 new->A
[new->Variables
-1][j
] = (j
==i
? k
: 0);
447 new->VarProperties
[new->Variables
-1].Free
= (old
->EqProperties
[i
].Type
==EQUATION_MODULO
);
448 new->VarProperties
[new->Variables
-1].Upper
= MAXINT
;
449 new->VarProperties
[new->Variables
-1].Lower
= (old
->EqProperties
[i
].Type
==EQUATION_MODULO
? -MAXINT
: 0);
450 new->VarProperties
[new->Variables
-1].Column
= -1;
454 // -rhs as a new row in [0;1]
455 if (normVector(new->b
, old
->Equations
)>0)
458 new->A
= (Vector
*)realloc(new->A
, new->Variables
*sizeof(Vector
));
459 new->VarProperties
= (VariableProperties
)realloc(new->VarProperties
, new->Variables
*sizeof(variableproperty_t
));
461 new->A
[new->Variables
-1] = new->b
;
462 for (i
=0; i
<old
->Equations
; i
++)
463 new->A
[new->Variables
-1][i
] *= -1;
464 new->VarProperties
[new->Variables
-1].Free
= false;
465 new->VarProperties
[new->Variables
-1].Upper
= 1;
466 new->VarProperties
[new->Variables
-1].Lower
= 0;
467 new->VarProperties
[new->Variables
-1].Column
= -2;
469 // recreate rhs as a zero-vector
470 new->b
= createVector(new->Equations
);
471 for (i
=0; i
<new->Equations
; i
++)
475 // all are now equaitons
476 new->EqProperties
= (EquationProperties
)malloc(new->Equations
*sizeof(equationproperty_t
));
477 for (i
=0; i
<new->Equations
; i
++)
479 new->EqProperties
[i
].Type
= EQUATION_EQUAL
;
480 new->EqProperties
[i
].Modulus
= 0;