Skip to content

Commit ee4acf9

Browse files
author
Romain Lebreton
committed
Merge dixonsparseelim & dixondenseLU into dixonsolve
Add solveSingular & solveNonsingular to the interface of DixonSolver<..., Method::SparseElimination> Careful : I had to remove the last argument m.trialsBeforeFailure of solve to have a unified interface for DixonSolver<..., Method::SparseElimination> and DixonSolver<...,Method::DenseElimination>
1 parent 6883198 commit ee4acf9

File tree

5 files changed

+166
-79
lines changed

5 files changed

+166
-79
lines changed

examples/Makefile.am

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ SUBDIRS=data
2929

3030
EXAMPLES=rank det minpoly valence solve dot-product echelon sparseelimdet \
3131
sparseelimrank checksolve doubledet smithvalence charpoly blassolve \
32-
dixonsparseelim dixondenseLU sparsesolverat densesolverat \
32+
dixonsolve sparsesolverat densesolverat \
3333
ratdet poweroftwo_ranks power_rank genprime smithsparse nullspacebasis_rat nullspacebasis matrices
3434
#polysmith bench-fft bench-matpoly-mult
3535
# EXAMPLES+=nulp yabla
@@ -66,8 +66,7 @@ echelon_SOURCES = echelon.C
6666
smithvalence_SOURCES = smithvalence.C
6767
sparseelimdet_SOURCES = sparseelimdet.C
6868
sparseelimrank_SOURCES = sparseelimrank.C
69-
dixonsparseelim_SOURCES = dixonsparseelim.C
70-
dixondenseLU_SOURCES = dixondenseLU.C
69+
dixonsolve_SOURCES = dixonsolve.C
7170
ratdet_SOURCES = ratdet.C
7271
sparsesolverat_SOURCES = sparsesolverat.C
7372
densesolverat_SOURCES = densesolverat.C

examples/dixondenseLU.C renamed to examples/dixonsolve.C

Lines changed: 126 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,28 @@
1818
* ========LICENCE========
1919
*/
2020

21-
/**\file examples/dixondenseelim.C
22-
@example examples/dixondenseelim.C
21+
/**\file examples/dixonsolve.C
22+
@example examples/dixonsolve.C
2323
24-
* \brief Dixon System Solving Lifting using dense LU
24+
25+
* \brief Dixon System Solving via Lifting using dense LU or sparse LU
2526
* \ingroup examples
2627
*/
2728
#include <iostream>
2829
#include <omp.h>
29-
#include "linbox/matrix/dense-matrix.h"
30-
#include "linbox/solutions/solve.h"
31-
#include "linbox/util/matrix-stream.h"
30+
31+
#include "linbox/algorithms/rational-solver.h"
3232
#include "linbox/solutions/methods.h"
33+
#include "linbox/solutions/solve.h"
3334
#include "linbox/util/args-parser.h"
34-
#include "linbox/algorithms/rational-solver.h"
35+
#include "linbox/util/error.h"
36+
#include "linbox/util/matrix-stream.h"
37+
38+
// DenseLU
39+
#include "linbox/matrix/dense-matrix.h"
40+
41+
// SparseElim
42+
#include "linbox/matrix/sparse-matrix.h"
3543

3644
using namespace LinBox;
3745
typedef Givaro::ZRing<Givaro::Integer> Ints;
@@ -49,65 +57,45 @@ struct FixPrime {
4957
template<class _ModField> void setBitsField() { }
5058
};
5159

60+
template<typename _Matrix, typename _EliminationMethod>
61+
int test(_Matrix A, std::string vector_file, bool inv, bool pp, bool sparse_elim) {
62+
// TODO : git rm dixondenseLU dixonsparseelim
5263

53-
int main (int argc, char **argv) {
54-
55-
// TODO : seed ?
56-
std::string matrix_file = "";
57-
std::string vector_file = "";
58-
bool inv = false;
59-
bool pp = false;
64+
std::cout << "A is " << A.rowdim() << " by " << A.coldim() << std::endl;
6065

61-
Argument as[] = {
62-
{ 'm', "-m FILE", "Set the input file for the matrix.", TYPE_STR , &matrix_file },
63-
{ 'v', "-v FILE", "Set the input file for the vector.", TYPE_STR , &vector_file },
64-
{ 'i', "-i" , "whether the matrix is invertible.", TYPE_BOOL , &inv },
65-
{ 'p', "-p" , "whether you want to pretty print the matrix.", TYPE_BOOL , &pp },
66-
END_OF_ARGUMENTS
67-
};
66+
if (pp)
67+
{
68+
// Print Matrix
6869

69-
FFLAS::parseArguments(argc,argv,as);
70+
// Matrix Market
71+
// std::cout << "A is " << A << std::endl;
7072

71-
// Matrix File
72-
if (matrix_file.empty()) {
73-
std::cerr << "You must specify an input file for the matrix with -m" << std::endl;
74-
exit(-1);
73+
// Maple
74+
A.write(std::cout << "A:=", Tag::FileFormat::Maple) << ';' << std::endl;
7575
}
76-
std::ifstream input (matrix_file);
77-
if (!input) { std::cerr << "Error opening matrix file " << argv[1] << std::endl; return -1; }
7876

79-
// Vector File
77+
// Vector File
78+
Ints ZZ;
8079
std::ifstream invect;
80+
81+
ZVector B(ZZ, A.rowdim());
82+
8183
bool createB = vector_file.empty();
8284
if (!createB) {
8385
invect.open (vector_file, std::ifstream::in);
8486
if (!invect) {
8587
createB = true;
88+
} else {
89+
for(ZVector::iterator it=B.begin(); it != B.end(); ++it)
90+
invect >> *it;
8691
}
8792
}
8893

89-
// Read Integral matrix from File
90-
Ints ZZ;
91-
MatrixStream< Ints > ms( ZZ, input );
92-
DenseMatrix<Ints> A (ms);
93-
Ints::Element d;
94-
std::cout << "A is " << A.rowdim() << " by " << A.coldim() << std::endl;
95-
96-
if (pp)
97-
{
98-
// Print Matrix
99-
100-
// Matrix Market
101-
// std::cout << "A is " << A << std::endl;
102-
103-
// Maple
104-
A.write(std::cout << "A:=", Tag::FileFormat::Maple) << ';' << std::endl;
105-
}
106-
10794
// Vectors
108-
ZVector X(ZZ, A.coldim()),U(ZZ, A.coldim()),B(ZZ, A.rowdim());
95+
ZVector X(ZZ, A.coldim());
10996

11097
if (createB) {
98+
ZVector U(ZZ, A.coldim());
11199
if (inv) {
112100
std::cerr << "Creating a random {-1,1} vector " << std::endl;
113101
srand48( BaseTimer::seed() );
@@ -119,64 +107,84 @@ int main (int argc, char **argv) {
119107
} else {
120108
std::cerr << "Creating a random consistant {-1,1} vector " << std::endl;
121109
srand48( BaseTimer::seed() );
122-
for(auto& it:U)
110+
for(FFPACK::rns_double::integer& it:U)
123111
if (drand48() <0.5)
124112
it = -1;
125113
else
126114
it = 1;
127-
115+
128116
// B = A U
129117
A.apply(B,U);
130118
}
131-
} else {
132-
for(ZVector::iterator it=B.begin();
133-
it != B.end(); ++it)
134-
invect >> *it;
135119
}
136120

137121
if(pp)
138122
{
139123
// Print RHS
140124
B.write(std::cout << "B:=", Tag::FileFormat::Maple) << ';' << std::endl;
141125
}
142-
126+
143127
std::cout << "B is " << B.size() << "x1" << std::endl;
144128

145129
Timer chrono;
146130

147131
// BlasElimination
148-
Method::DenseElimination M;
132+
// TODO : à vérifier si cela marche avec Method::DenseElimination
133+
_EliminationMethod M;
134+
if (inv){
135+
M.singularity = Singularity::NonSingular;
136+
}
137+
149138

150139
//====================================================
151140
// BEGIN Replacement solve with fixed prime
141+
142+
Ints::Element d;
152143
Method::Dixon m(M);
153144
typedef Givaro::Modular<double> Field;
154145
// 0.7213475205 is an upper approximation of 1/(2log(2))
155146
size_t bitsize((size_t)( 26-(int)ceil(log((double)A.rowdim())*0.7213475205)));
156147
Givaro::Integer randomPrime( *(PrimeIterator<>(bitsize)) );
157148

158149
FixPrime fixedprime( randomPrime );
159-
DixonSolver<Ints, Field, FixPrime, Method::DenseElimination> rsolve(A.field(), fixedprime);
150+
DixonSolver<Ints, Field, FixPrime, _EliminationMethod> rsolve(A.field(), fixedprime);
160151
std::cout << "Using: " << *fixedprime << " as the fixed p-adic." << std::endl;
161152

162153
chrono.start();
163-
if (inv)
164-
{
165-
SolverReturnStatus ss = rsolve.solveNonsingular(X, d, A, B, false,(int)m.trialsBeforeFailure);
166-
if (ss != SS_OK) {
167-
std::cerr << "Error during solveNonsingular (possibly singular matrix or p-adic precision too small)" << std::endl;
168-
exit(-1);
154+
if (!sparse_elim){
155+
// Dense Elimination
156+
if (inv)
157+
{
158+
std::cout << "Solving using Dense Elimination for non singular system" << std::endl;
159+
SolverReturnStatus ss = rsolve.solveNonsingular(X, d, A, B);
160+
if (ss != SS_OK) {
161+
std::cerr << "Error during solveNonsingular (possibly singular matrix or p-adic precision too small)" << std::endl;
162+
exit(-1);
163+
}
169164
}
170-
}
171-
else
172-
{
173-
SolverReturnStatus ss = rsolve.solve(X, d, A, B, false,(int)m.trialsBeforeFailure);
174-
if (ss == SS_FAILED){
175-
std::cerr << "Error during solve (all primes used were bad)" << std::endl;
176-
exit(-1);
165+
else
166+
{
167+
std::cout << "Solving using Dense Elimination for any system" << std::endl;
168+
SolverReturnStatus ss = rsolve.solve(X, d, A, B);
169+
if (ss == SS_FAILED){
170+
std::cerr << "Error during solve (all primes used were bad)" << std::endl;
171+
exit(-1);
172+
}
173+
if (ss == SS_INCONSISTENT){
174+
std::cerr << "Error: system appeared inconsistent" << std::endl;
175+
exit(-1);
176+
}
177177
}
178-
if (ss == SS_INCONSISTENT){
179-
std::cerr << "Error: system appeared inconsistent" << std::endl;
178+
} else {
179+
// Sparse Elimination
180+
try
181+
{
182+
std::cout << "Solving using Sparse Elimination for any system" << std::endl;
183+
rsolve.solve(X, d, A, B);
184+
}
185+
catch(LinboxError& e)
186+
{
187+
std::cerr << e << '\n';
180188
exit(-1);
181189
}
182190
}
@@ -215,15 +223,59 @@ int main (int argc, char **argv) {
215223
{
216224
// Print Solution
217225

218-
std::cout << "(DenseElimination) Solution is [";
226+
std::cout << "Solution is [";
219227
for(auto it:X) ZZ.write(std::cout, it) << " ";
220228
std::cout << "] / ";
221229
ZZ.write(std::cout, d)<< std::endl;
222230
}
223-
224231
return 0;
225232
}
226233

234+
int main (int argc, char **argv) {
235+
236+
// TODO : seed ?
237+
std::string matrix_file = "";
238+
std::string vector_file = "";
239+
bool inv = false;
240+
bool pp = false;
241+
bool sparse_elim = false;
242+
243+
244+
Argument as[] = {
245+
{ 'm', "-m FILE", "Set the input file for the matrix.", TYPE_STR , &matrix_file },
246+
{ 'v', "-v FILE", "Set the input file for the vector.", TYPE_STR , &vector_file },
247+
{ 'i', "-i" , "whether the matrix is invertible.", TYPE_BOOL , &inv },
248+
{ 'p', "-p" , "whether you want to pretty print the matrix.", TYPE_BOOL , &pp },
249+
{ 's', "-s" , "whether to use sparse elimination.", TYPE_BOOL , &sparse_elim },
250+
END_OF_ARGUMENTS
251+
};
252+
253+
FFLAS::parseArguments(argc,argv,as);
254+
255+
// Matrix File
256+
if (matrix_file.empty()) {
257+
std::cerr << "You must specify an input file for the matrix with -m" << std::endl;
258+
exit(-1);
259+
}
260+
std::ifstream input (matrix_file);
261+
if (!input) { std::cerr << "Error opening matrix file " << argv[1] << std::endl; exit(-1); }
262+
263+
264+
// Read Integral matrix from File
265+
Ints ZZ;
266+
MatrixStream< Ints > ms( ZZ, input );
267+
268+
if (sparse_elim){
269+
SparseMatrix<Ints> A(ms);
270+
return test<SparseMatrix<Ints>,Method::SparseElimination>
271+
(A, vector_file, inv , pp, sparse_elim);
272+
} else {
273+
DenseMatrix<Ints> A(ms);
274+
return test<DenseMatrix<Ints>,Method::DenseElimination>
275+
(A, vector_file, inv , pp, sparse_elim);
276+
}
277+
}
278+
227279

228280
// Local Variables:
229281
// mode: C++

linbox/algorithms/rational-solver.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -716,11 +716,23 @@ namespace LinBox {
716716
{}
717717

718718

719-
// solve non singular system
719+
// solve any system
720720
template<class IMatrix, class Vector1, class Vector2>
721721
SolverReturnStatus solve(Vector1& num, Integer& den,
722722
const IMatrix& A, const Vector2& b,
723723
int maxPrimes = DEFAULT_MAXPRIMES) const;
724+
725+
// solve non singular system
726+
template<class IMatrix, class Vector1, class Vector2>
727+
SolverReturnStatus solveNonsingular(Vector1& num, Integer& den,
728+
const IMatrix& A, const Vector2& b,
729+
int maxPrimes = DEFAULT_MAXPRIMES) const;
730+
731+
// solve singular system
732+
template<class IMatrix, class Vector1, class Vector2>
733+
SolverReturnStatus solveSingular(Vector1& num, Integer& den,
734+
const IMatrix& A, const Vector2& b,
735+
int maxPrimes = DEFAULT_MAXPRIMES) const;
724736
};
725737

726738
}

linbox/algorithms/rational-solver.inl

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,30 @@ namespace LinBox
636636
return SS_OK;
637637
}
638638

639+
template <class Ring, class Field, class RandomPrime>
640+
template <class IMatrix, class Vector1, class Vector2>
641+
SolverReturnStatus
642+
DixonSolver<Ring,Field,RandomPrime,Method::SparseElimination>::solveNonsingular(Vector1& num,
643+
Integer& den,
644+
const IMatrix& A,
645+
const Vector2& b,
646+
int maxPrimes) const
647+
{
648+
return solve(num, den, A, b, maxPrimes);
649+
}
650+
651+
template <class Ring, class Field, class RandomPrime>
652+
template <class IMatrix, class Vector1, class Vector2>
653+
SolverReturnStatus
654+
DixonSolver<Ring,Field,RandomPrime,Method::SparseElimination>::solveSingular(Vector1& num,
655+
Integer& den,
656+
const IMatrix& A,
657+
const Vector2& b,
658+
int maxPrimes) const
659+
{
660+
return solve(num, den, A, b, maxPrimes);
661+
}
662+
639663
} //end of namespace LinBox
640664

641665
//BB : moved the following "guarded" code in a new file, verbatim :

linbox/vector/vector-domain.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ namespace LinBox
8282
VectorDomainBase () : _faxpy(nullptr) {std::cout<<"CST DEFAULT VDB"<<std::endl;}
8383
VectorDomainBase (const Field &F) : _faxpy(new FieldAXPY<Field>(F))
8484
{ /*std::cerr << "VDD cstor " << this << std::endl;*/}
85-
~VectorDomainBase() { if (_faxpy != nullptr) delete _faxpy; }
85+
~VectorDomainBase() { if (_faxpy != nullptr) delete _faxpy; }
8686

8787
void init(const Field &F) { if (_faxpy != nullptr) delete _faxpy; _faxpy = new FieldAXPY<Field>(F); }
8888
inline const Field & field() const { return _faxpy->field(); }

0 commit comments

Comments
 (0)