My Project
Macros | Functions
bigintmat.cc File Reference
#include "misc/auxiliary.h"
#include "coeffs/bigintmat.h"
#include "misc/intvec.h"
#include "coeffs/rmodulon.h"
#include <cmath>

Go to the source code of this file.

Macros

#define swap(_i, _j)
 
#define MIN(a, b)   (a < b ? a : b)
 

Functions

static coeffs numbercoeffs (number n, coeffs c)
 create Z/nA of type n_Zn More...
 
bool operator== (const bigintmat &lhr, const bigintmat &rhr)
 
bool operator!= (const bigintmat &lhr, const bigintmat &rhr)
 
bigintmatbimAdd (bigintmat *a, bigintmat *b)
 Matrix-Add/-Sub/-Mult so oder mit operator+/-/* ? @Note: NULL as a result means an error (non-compatible matrices?) More...
 
bigintmatbimAdd (bigintmat *a, int b)
 
bigintmatbimSub (bigintmat *a, bigintmat *b)
 
bigintmatbimSub (bigintmat *a, int b)
 
bigintmatbimMult (bigintmat *a, bigintmat *b)
 
bigintmatbimMult (bigintmat *a, int b)
 
bigintmatbimMult (bigintmat *a, number b, const coeffs cf)
 
intvecbim2iv (bigintmat *b)
 
bigintmativ2bim (intvec *b, const coeffs C)
 
bigintmatbimCopy (const bigintmat *b)
 same as copy constructor - apart from it being able to accept NULL as input More...
 
static int intArrSum (int *a, int length)
 
static int findLongest (int *a, int length)
 
static int getShorter (int *a, int l, int j, int cols, int rows)
 
bigintmatbimChangeCoeff (bigintmat *a, coeffs cnew)
 Liefert Kopier von Matrix a zurück, mit coeffs cnew statt den ursprünglichen. More...
 
void bimMult (bigintmat *a, bigintmat *b, bigintmat *c)
 Multipliziert Matrix a und b und speichert Ergebnis in c. More...
 
static void reduce_mod_howell (bigintmat *A, bigintmat *b, bigintmat *eps, bigintmat *x)
 
static bigintmatprependIdentity (bigintmat *A)
 
static number bimFarey (bigintmat *A, number N, bigintmat *L)
 
static number solveAx_dixon (bigintmat *A, bigintmat *B, bigintmat *x, bigintmat *kern)
 
static number solveAx_howell (bigintmat *A, bigintmat *b, bigintmat *x, bigintmat *kern)
 
number solveAx (bigintmat *A, bigintmat *b, bigintmat *x)
 solve Ax=b*d. x needs to be pre-allocated to the same number of columns as b. the minimal denominator d is returned. Currently available for Z, Q and Z/nZ (and possibly for all fields: d=1 there) Beware that the internal functions can find the kernel as well - but the interface is lacking. More...
 
void diagonalForm (bigintmat *A, bigintmat **S, bigintmat **T)
 
int kernbase (bigintmat *a, bigintmat *c, number p, coeffs q)
 a basis for the nullspace of a mod p: only used internally in Round2. Don't use it. More...
 
bool nCoeffs_are_equal (coeffs r, coeffs s)
 

Macro Definition Documentation

◆ MIN

#define MIN (   a,
  b 
)    (a < b ? a : b)

◆ swap

#define swap (   _i,
  _j 
)
Value:
int __i = (_i), __j=(_j); \
number c = v[__i]; \
v[__i] = v[__j]; \
v[__j] = c \
const Variable & v
< [in] a sqrfree bivariate poly
Definition: facBivar.h:39

Function Documentation

◆ bim2iv()

intvec * bim2iv ( bigintmat b)

Definition at line 341 of file bigintmat.cc.

342{
343 intvec * iv = new intvec(b->rows(), b->cols(), 0);
344 for (int i=0; i<(b->rows())*(b->cols()); i++)
345 (*iv)[i] = n_Int((*b)[i], b->basecoeffs()); // Geht das so?
346 return iv;
347}
int i
Definition: cfEzgcd.cc:132
CanonicalForm b
Definition: cfModGcd.cc:4103
Definition: intvec.h:23
static FORCE_INLINE long n_Int(number &n, const coeffs r)
conversion of n to an int; 0 if not possible in Z/pZ: the representing int lying in (-p/2 ....
Definition: coeffs.h:547

◆ bimAdd() [1/2]

bigintmat * bimAdd ( bigintmat a,
bigintmat b 
)

Matrix-Add/-Sub/-Mult so oder mit operator+/-/* ? @Note: NULL as a result means an error (non-compatible matrices?)

Definition at line 182 of file bigintmat.cc.

183{
184 if (a->cols() != b->cols()) return NULL;
185 if (a->rows() != b->rows()) return NULL;
186 if (a->basecoeffs() != b->basecoeffs()) { return NULL; }
187
188 const coeffs basecoeffs = a->basecoeffs();
189
190 int i;
191
192 bigintmat * bim = new bigintmat(a->rows(), a->cols(), basecoeffs);
193
194 for (i=a->rows()*a->cols()-1;i>=0; i--)
195 bim->rawset(i, n_Add((*a)[i], (*b)[i], basecoeffs), basecoeffs);
196
197 return bim;
198}
Matrices of numbers.
Definition: bigintmat.h:51
int cols() const
Definition: bigintmat.h:144
int rows() const
Definition: bigintmat.h:145
void rawset(int i, number n, const coeffs C=NULL)
replace an entry with the given number n (only delete old). NOTE: starts at [0]. Should be named set_...
Definition: bigintmat.h:196
coeffs basecoeffs() const
Definition: bigintmat.h:146
static FORCE_INLINE number n_Add(number a, number b, const coeffs r)
return the sum of 'a' and 'b', i.e., a+b
Definition: coeffs.h:650
The main handler for Singular numbers which are suitable for Singular polynomials.
#define NULL
Definition: omList.c:12

◆ bimAdd() [2/2]

bigintmat * bimAdd ( bigintmat a,
int  b 
)

Definition at line 199 of file bigintmat.cc.

200{
201
202 const int mn = si_min(a->rows(),a->cols());
203
204 const coeffs basecoeffs = a->basecoeffs();
205 number bb=n_Init(b,basecoeffs);
206
207 int i;
208
209 bigintmat * bim = new bigintmat(a->rows(),a->cols() , basecoeffs);
210
211 for (i=1; i<=mn; i++)
212 BIMATELEM(*bim,i,i)=n_Add(BIMATELEM(*a,i,i), bb, basecoeffs);
213
214 n_Delete(&bb,basecoeffs);
215 return bim;
216}
static int si_min(const int a, const int b)
Definition: auxiliary.h:125
#define BIMATELEM(M, I, J)
Definition: bigintmat.h:133
static FORCE_INLINE void n_Delete(number *p, const coeffs r)
delete 'p'
Definition: coeffs.h:455
static FORCE_INLINE number n_Init(long i, const coeffs r)
a number representing i in the given coeff field/ring r
Definition: coeffs.h:538

◆ bimChangeCoeff()

bigintmat * bimChangeCoeff ( bigintmat a,
coeffs  cnew 
)

Liefert Kopier von Matrix a zurück, mit coeffs cnew statt den ursprünglichen.

Definition at line 1805 of file bigintmat.cc.

1806{
1807 coeffs cold = a->basecoeffs();
1808 bigintmat *b = new bigintmat(a->rows(), a->cols(), cnew);
1809 // Erzeugt Karte von alten coeffs nach neuen
1810 nMapFunc f = n_SetMap(cold, cnew);
1811 number t1;
1812 number t2;
1813 // apply map to all entries.
1814 for (int i=1; i<=a->rows(); i++)
1815 {
1816 for (int j=1; j<=a->cols(); j++)
1817 {
1818 t1 = a->get(i, j);
1819 t2 = f(t1, cold, cnew);
1820 b->set(i, j, t2);
1821 n_Delete(&t1, cold);
1822 n_Delete(&t2, cnew);
1823 }
1824 }
1825 return b;
1826}
FILE * f
Definition: checklibs.c:9
number get(int i, int j) const
get a copy of an entry. NOTE: starts at [1,1]
Definition: bigintmat.cc:119
static FORCE_INLINE nMapFunc n_SetMap(const coeffs src, const coeffs dst)
set the mapping function pointers for translating numbers from src to dst
Definition: coeffs.h:700
number(* nMapFunc)(number a, const coeffs src, const coeffs dst)
maps "a", which lives in src, into dst
Definition: coeffs.h:73
int j
Definition: facHensel.cc:110

◆ bimCopy()

bigintmat * bimCopy ( const bigintmat b)

same as copy constructor - apart from it being able to accept NULL as input

Definition at line 405 of file bigintmat.cc.

406{
407 if (b == NULL)
408 return NULL;
409
410 return new bigintmat(b);
411}

◆ bimFarey()

static number bimFarey ( bigintmat A,
number  N,
bigintmat L 
)
static

Definition at line 2049 of file bigintmat.cc.

2050{
2051 coeffs Z = A->basecoeffs(),
2052 Q = nInitChar(n_Q, 0);
2053 number den = n_Init(1, Z);
2054 nMapFunc f = n_SetMap(Q, Z);
2055
2056 for(int i=1; i<= A->rows(); i++)
2057 {
2058 for(int j=1; j<= A->cols(); j++)
2059 {
2060 number ad = n_Mult(den, A->view(i, j), Z);
2061 number re = n_IntMod(ad, N, Z);
2062 n_Delete(&ad, Z);
2063 number q = n_Farey(re, N, Z);
2064 n_Delete(&re, Z);
2065 if (!q)
2066 {
2067 n_Delete(&ad, Z);
2068 n_Delete(&den, Z);
2069 return NULL;
2070 }
2071
2072 number d = n_GetDenom(q, Q),
2073 n = n_GetNumerator(q, Q);
2074
2075 n_Delete(&q, Q);
2076 n_Delete(&ad, Z);
2077 number dz = f(d, Q, Z),
2078 nz = f(n, Q, Z);
2079 n_Delete(&d, Q);
2080 n_Delete(&n, Q);
2081
2082 if (!n_IsOne(dz, Z))
2083 {
2084 L->skalmult(dz, Z);
2085 n_InpMult(den, dz, Z);
2086#if 0
2087 PrintS("den increasing to ");
2088 n_Print(den, Z);
2089 PrintLn();
2090#endif
2091 }
2092 n_Delete(&dz, Z);
2093 L->rawset(i, j, nz);
2094 }
2095 }
2096
2097 nKillChar(Q);
2098 PrintS("bimFarey worked\n");
2099#if 0
2100 L->Print();
2101 PrintS("\n * 1/");
2102 n_Print(den, Z);
2103 PrintLn();
2104#endif
2105 return den;
2106}
CanonicalForm den(const CanonicalForm &f)
const CanonicalForm CFMap CFMap & N
Definition: cfEzgcd.cc:56
void Print()
IO: simply prints the matrix to the current output (screen?)
Definition: bigintmat.cc:443
bool skalmult(number b, coeffs c)
Multipliziert zur Matrix den Skalar b hinzu.
Definition: bigintmat.cc:939
static FORCE_INLINE number n_Mult(number a, number b, const coeffs r)
return the product of 'a' and 'b', i.e., a*b
Definition: coeffs.h:636
static FORCE_INLINE number n_GetDenom(number &n, const coeffs r)
return the denominator of n (if elements of r are by nature not fractional, result is 1)
Definition: coeffs.h:603
@ n_Q
rational (GMP) numbers
Definition: coeffs.h:30
void n_Print(number &a, const coeffs r)
print a number (BEWARE of string buffers!) mostly for debugging
Definition: numbers.cc:621
static FORCE_INLINE number n_Farey(number a, number b, const coeffs r)
Definition: coeffs.h:767
coeffs nInitChar(n_coeffType t, void *parameter)
one-time initialisations for new coeffs in case of an error return NULL
Definition: numbers.cc:354
static FORCE_INLINE number n_IntMod(number a, number b, const coeffs r)
for r a field, return n_Init(0,r) always: n_Div(a,b,r)*b+n_IntMod(a,b,r)==a n_IntMod(a,...
Definition: coeffs.h:628
static FORCE_INLINE void n_InpMult(number &a, number b, const coeffs r)
multiplication of 'a' and 'b'; replacement of 'a' by the product a*b
Definition: coeffs.h:641
static FORCE_INLINE number n_GetNumerator(number &n, const coeffs r)
return the numerator of n (if elements of r are by nature not fractional, result is n)
Definition: coeffs.h:608
void nKillChar(coeffs r)
undo all initialisations
Definition: numbers.cc:522
static FORCE_INLINE BOOLEAN n_IsOne(number n, const coeffs r)
TRUE iff 'n' represents the one element.
Definition: coeffs.h:468
STATIC_VAR jList * Q
Definition: janet.cc:30
void PrintS(const char *s)
Definition: reporter.cc:284
void PrintLn()
Definition: reporter.cc:310
#define A
Definition: sirandom.c:24

◆ bimMult() [1/4]

bigintmat * bimMult ( bigintmat a,
bigintmat b 
)

Definition at line 255 of file bigintmat.cc.

256{
257 const int ca = a->cols();
258 const int cb = b->cols();
259
260 const int ra = a->rows();
261 const int rb = b->rows();
262
263 if (ca != rb)
264 {
265#ifndef SING_NDEBUG
266 Werror("wrong bigintmat sizes at multiplication a * b: acols: %d != brows: %d\n", ca, rb);
267#endif
268 return NULL;
269 }
270
271 assume (ca == rb);
272
273 if (a->basecoeffs() != b->basecoeffs()) { return NULL; }
274
275 const coeffs basecoeffs = a->basecoeffs();
276
277 int i, j, k;
278
279 number sum;
280
281 bigintmat * bim = new bigintmat(ra, cb, basecoeffs);
282
283 for (i=1; i<=ra; i++)
284 for (j=1; j<=cb; j++)
285 {
286 sum = n_Init(0, basecoeffs);
287
288 for (k=1; k<=ca; k++)
289 {
290 number prod = n_Mult( BIMATELEM(*a, i, k), BIMATELEM(*b, k, j), basecoeffs);
291
292 n_InpAdd(sum, prod, basecoeffs);
293
294 n_Delete(&prod, basecoeffs);
295 }
296 bim->rawset(i, j, sum, basecoeffs);
297 }
298 return bim;
299}
int k
Definition: cfEzgcd.cc:99
static FORCE_INLINE void n_InpAdd(number &a, number b, const coeffs r)
addition of 'a' and 'b'; replacement of 'a' by the sum a+b
Definition: coeffs.h:646
fq_nmod_poly_t prod
Definition: facHensel.cc:100
#define assume(x)
Definition: mod2.h:387
void Werror(const char *fmt,...)
Definition: reporter.cc:189

◆ bimMult() [2/4]

void bimMult ( bigintmat a,
bigintmat b,
bigintmat c 
)

Multipliziert Matrix a und b und speichert Ergebnis in c.

Definition at line 1933 of file bigintmat.cc.

1934{
1935 if (!nCoeffs_are_equal(a->basecoeffs(), b->basecoeffs()))
1936 {
1937 WerrorS("Error in bimMult. Coeffs do not agree!");
1938 return;
1939 }
1940 if ((a->rows() != c->rows()) || (b->cols() != c->cols()) || (a->cols() != b->rows()))
1941 {
1942 WerrorS("Error in bimMult. Dimensions do not agree!");
1943 return;
1944 }
1945 bigintmat *tmp = bimMult(a, b);
1946 c->copy(tmp);
1947
1948 delete tmp;
1949}
bool nCoeffs_are_equal(coeffs r, coeffs s)
Definition: bigintmat.cc:2646
bigintmat * bimMult(bigintmat *a, bigintmat *b)
Definition: bigintmat.cc:255
bool copy(bigintmat *b)
Kopiert Einträge von b auf Bigintmat.
Definition: bigintmat.cc:1260
void WerrorS(const char *s)
Definition: feFopen.cc:24

◆ bimMult() [3/4]

bigintmat * bimMult ( bigintmat a,
int  b 
)

Definition at line 301 of file bigintmat.cc.

302{
303
304 const int mn = a->rows()*a->cols();
305
306 const coeffs basecoeffs = a->basecoeffs();
307 number bb=n_Init(b,basecoeffs);
308
309 int i;
310
311 bigintmat * bim = new bigintmat(a->rows(),a->cols() , basecoeffs);
312
313 for (i=0; i<mn; i++)
314 bim->rawset(i, n_Mult((*a)[i], bb, basecoeffs), basecoeffs);
315
316 n_Delete(&bb,basecoeffs);
317 return bim;
318}

◆ bimMult() [4/4]

bigintmat * bimMult ( bigintmat a,
number  b,
const coeffs  cf 
)

Definition at line 320 of file bigintmat.cc.

321{
322 if (cf!=a->basecoeffs()) return NULL;
323
324 const int mn = a->rows()*a->cols();
325
326 const coeffs basecoeffs = a->basecoeffs();
327
328 int i;
329
330 bigintmat * bim = new bigintmat(a->rows(),a->cols() , basecoeffs);
331
332 for (i=0; i<mn; i++)
333 bim->rawset(i, n_Mult((*a)[i], b, basecoeffs), basecoeffs);
334
335 return bim;
336}
CanonicalForm cf
Definition: cfModGcd.cc:4083

◆ bimSub() [1/2]

bigintmat * bimSub ( bigintmat a,
bigintmat b 
)

Definition at line 218 of file bigintmat.cc.

219{
220 if (a->cols() != b->cols()) return NULL;
221 if (a->rows() != b->rows()) return NULL;
222 if (a->basecoeffs() != b->basecoeffs()) { return NULL; }
223
224 const coeffs basecoeffs = a->basecoeffs();
225
226 int i;
227
228 bigintmat * bim = new bigintmat(a->rows(), a->cols(), basecoeffs);
229
230 for (i=a->rows()*a->cols()-1;i>=0; i--)
231 bim->rawset(i, n_Sub((*a)[i], (*b)[i], basecoeffs), basecoeffs);
232
233 return bim;
234}
static FORCE_INLINE number n_Sub(number a, number b, const coeffs r)
return the difference of 'a' and 'b', i.e., a-b
Definition: coeffs.h:655

◆ bimSub() [2/2]

bigintmat * bimSub ( bigintmat a,
int  b 
)

Definition at line 236 of file bigintmat.cc.

237{
238 const int mn = si_min(a->rows(),a->cols());
239
240 const coeffs basecoeffs = a->basecoeffs();
241 number bb=n_Init(b,basecoeffs);
242
243 int i;
244
245 bigintmat * bim = new bigintmat(a->rows(),a->cols() , basecoeffs);
246
247 for (i=1; i<=mn; i++)
248 BIMATELEM(*bim,i,i)=n_Sub(BIMATELEM(*a,i,i), bb, basecoeffs);
249
250 n_Delete(&bb,basecoeffs);
251 return bim;
252}

◆ diagonalForm()

void diagonalForm ( bigintmat A,
bigintmat **  S,
bigintmat **  T 
)

Definition at line 2476 of file bigintmat.cc.

2477{
2478 bigintmat * t, *s, *a=A;
2479 coeffs R = a->basecoeffs();
2480 if (T)
2481 {
2482 *T = new bigintmat(a->cols(), a->cols(), R),
2483 (*T)->one();
2484 t = new bigintmat(*T);
2485 }
2486 else
2487 {
2488 t = *T;
2489 }
2490
2491 if (S)
2492 {
2493 *S = new bigintmat(a->rows(), a->rows(), R);
2494 (*S)->one();
2495 s = new bigintmat(*S);
2496 }
2497 else
2498 {
2499 s = *S;
2500 }
2501
2502 int flip=0;
2503 do
2504 {
2505 bigintmat * x, *X;
2506 if (flip)
2507 {
2508 x = s;
2509 X = *S;
2510 }
2511 else
2512 {
2513 x = t;
2514 X = *T;
2515 }
2516
2517 if (x)
2518 {
2519 x->one();
2520 bigintmat * r = new bigintmat(a->rows()+a->cols(), a->cols(), R);
2521 bigintmat * rw = new bigintmat(1, a->cols(), R);
2522 for(int i=0; i<a->cols(); i++)
2523 {
2524 x->getrow(i+1, rw);
2525 r->setrow(i+1, rw);
2526 }
2527 for (int i=0; i<a->rows(); i++)
2528 {
2529 a->getrow(i+1, rw);
2530 r->setrow(i+a->cols()+1, rw);
2531 }
2532 r->hnf();
2533 for(int i=0; i<a->cols(); i++)
2534 {
2535 r->getrow(i+1, rw);
2536 x->setrow(i+1, rw);
2537 }
2538 for(int i=0; i<a->rows(); i++)
2539 {
2540 r->getrow(i+a->cols()+1, rw);
2541 a->setrow(i+1, rw);
2542 }
2543 delete rw;
2544 delete r;
2545
2546#if 0
2547 Print("X: %ld\n", X);
2548 X->Print();
2549 Print("\nx: %ld\n", x);
2550 x->Print();
2551#endif
2552 bimMult(X, x, X);
2553#if 0
2554 Print("\n2:X: %ld %ld %ld\n", X, *S, *T);
2555 X->Print();
2556 Print("\n2:x: %ld\n", x);
2557 x->Print();
2558 PrintLn();
2559#endif
2560 }
2561 else
2562 {
2563 a->hnf();
2564 }
2565
2566 int diag = 1;
2567 for(int i=a->rows(); diag && i>0; i--)
2568 {
2569 for(int j=a->cols(); j>0; j--)
2570 {
2571 if ((a->rows()-i)!=(a->cols()-j) && !n_IsZero(a->view(i, j), R))
2572 {
2573 diag = 0;
2574 break;
2575 }
2576 }
2577 }
2578#if 0
2579 PrintS("Diag ? %d\n", diag);
2580 a->Print();
2581 PrintLn();
2582#endif
2583 if (diag) break;
2584
2585 a = a->transpose(); // leaks - I need to write inpTranspose
2586 flip = 1-flip;
2587 } while (1);
2588 if (flip)
2589 a = a->transpose();
2590
2591 if (S) *S = (*S)->transpose();
2592 if (s) delete s;
2593 if (t) delete t;
2594 A->copy(a);
2595}
Variable x
Definition: cfModGcd.cc:4082
void hnf()
transforms INPLACE to HNF
Definition: bigintmat.cc:1661
bigintmat * transpose()
Definition: bigintmat.cc:37
void setrow(int i, bigintmat *m)
Setzt i-te Zeile gleich übergebenem Vektor (Matrix) m.
Definition: bigintmat.cc:861
number view(int i, int j) const
view an entry an entry. NOTE: starts at [1,1]
Definition: bigintmat.cc:127
void one()
Macht Matrix (Falls quadratisch) zu Einheitsmatrix.
Definition: bigintmat.cc:1326
void getrow(int i, bigintmat *a)
Schreibt i-te Zeile in Vektor (Matrix) a.
Definition: bigintmat.cc:792
static FORCE_INLINE BOOLEAN n_IsZero(number n, const coeffs r)
TRUE iff 'n' represents the zero element.
Definition: coeffs.h:464
#define Print
Definition: emacs.cc:80
const CanonicalForm int s
Definition: facAbsFact.cc:51
std::pair< ideal, ring > flip(const ideal I, const ring r, const gfan::ZVector interiorPoint, const gfan::ZVector facetNormal, const gfan::ZVector adjustedInteriorPoint, const gfan::ZVector adjustedFacetNormal)
Definition: flip.cc:17
STATIC_VAR jList * T
Definition: janet.cc:30
#define R
Definition: sirandom.c:27

◆ findLongest()

static int findLongest ( int *  a,
int  length 
)
static

Definition at line 537 of file bigintmat.cc.

538{
539 int l = 0;
540 int index;
541 for (int i=0; i<length; i++)
542 {
543 if (a[i] > l)
544 {
545 l = a[i];
546 index = i;
547 }
548 }
549 return index;
550}
int l
Definition: cfEzgcd.cc:100
static BOOLEAN length(leftv result, leftv arg)
Definition: interval.cc:257
static int index(p_Length length, p_Ord ord)
Definition: p_Procs_Impl.h:592

◆ getShorter()

static int getShorter ( int *  a,
int  l,
int  j,
int  cols,
int  rows 
)
static

Definition at line 552 of file bigintmat.cc.

553{
554 int sndlong = 0;
555 int min;
556 for (int i=0; i<rows; i++)
557 {
558 int index = cols*i+j;
559 if ((a[index] > sndlong) && (a[index] < l))
560 {
561 min = floor(log10((double)cols))+floor(log10((double)rows))+5;
562 if ((a[index] < min) && (min < l))
563 sndlong = min;
564 else
565 sndlong = a[index];
566 }
567 }
568 if (sndlong == 0)
569 {
570 min = floor(log10((double)cols))+floor(log10((double)rows))+5;
571 if (min < l)
572 sndlong = min;
573 else
574 sndlong = 1;
575 }
576 return sndlong;
577}
static int min(int a, int b)
Definition: fast_mult.cc:268
const signed long floor(const ampf< Precision > &x)
Definition: amp.h:773
const ampf< Precision > log10(const ampf< Precision > &x)
Definition: amp.h:1022

◆ intArrSum()

static int intArrSum ( int *  a,
int  length 
)
static

Definition at line 529 of file bigintmat.cc.

530{
531 int sum = 0;
532 for (int i=0; i<length; i++)
533 sum += a[i];
534 return sum;
535}

◆ iv2bim()

bigintmat * iv2bim ( intvec b,
const coeffs  C 
)

Definition at line 349 of file bigintmat.cc.

350{
351 const int l = (b->rows())*(b->cols());
352 bigintmat * bim = new bigintmat(b->rows(), b->cols(), C);
353
354 for (int i=0; i < l; i++)
355 bim->rawset(i, n_Init((*b)[i], C), C);
356
357 return bim;
358}

◆ kernbase()

int kernbase ( bigintmat a,
bigintmat c,
number  p,
coeffs  q 
)

a basis for the nullspace of a mod p: only used internally in Round2. Don't use it.

Definition at line 2601 of file bigintmat.cc.

2602{
2603#if 0
2604 PrintS("Kernel of ");
2605 a->Print();
2606 PrintS(" modulo ");
2607 n_Print(p, q);
2608 PrintLn();
2609#endif
2610
2611 coeffs coe = numbercoeffs(p, q);
2612 bigintmat *m = bimChangeCoeff(a, coe), *U, *V;
2613 diagonalForm(m, &U, &V);
2614#if 0
2615 PrintS("\ndiag form: ");
2616 m->Print();
2617 PrintS("\nU:\n");
2618 U->Print();
2619 PrintS("\nV:\n");
2620 V->Print();
2621 PrintLn();
2622#endif
2623
2624 int rg = 0;
2625#undef MIN
2626#define MIN(a,b) (a < b ? a : b)
2627 for(rg=0; rg<MIN(m->rows(), m->cols()) && !n_IsZero(m->view(m->rows()-rg,m->cols()-rg), coe); rg++);
2628
2629 bigintmat * k = new bigintmat(m->cols(), m->rows(), coe);
2630 for(int i=0; i<rg; i++)
2631 {
2632 number A = n_Ann(m->view(m->rows()-i, m->cols()-i), coe);
2633 k->set(m->cols()-i, i+1, A);
2634 n_Delete(&A, coe);
2635 }
2636 for(int i=rg; i<m->cols(); i++)
2637 {
2638 k->set(m->cols()-i, i+1-rg, n_Init(1, coe));
2639 }
2640 bimMult(V, k, k);
2641 c->copy(bimChangeCoeff(k, q));
2642 return c->cols();
2643}
bigintmat * bimChangeCoeff(bigintmat *a, coeffs cnew)
Liefert Kopier von Matrix a zurück, mit coeffs cnew statt den ursprünglichen.
Definition: bigintmat.cc:1805
#define MIN(a, b)
void diagonalForm(bigintmat *A, bigintmat **S, bigintmat **T)
Definition: bigintmat.cc:2476
static coeffs numbercoeffs(number n, coeffs c)
create Z/nA of type n_Zn
Definition: bigintmat.cc:21
int m
Definition: cfEzgcd.cc:128
int p
Definition: cfModGcd.cc:4078
static FORCE_INLINE number n_Ann(number a, const coeffs r)
if r is a ring with zero divisors, return an annihilator!=0 of b otherwise return NULL
Definition: coeffs.h:679

◆ nCoeffs_are_equal()

bool nCoeffs_are_equal ( coeffs  r,
coeffs  s 
)

Definition at line 2646 of file bigintmat.cc.

2647{
2648 if ((r == NULL) || (s == NULL))
2649 return false;
2650 if (r == s)
2651 return true;
2652 if ((getCoeffType(r)==n_Z) && (getCoeffType(s)==n_Z))
2653 return true;
2654 if ((getCoeffType(r)==n_Zp) && (getCoeffType(s)==n_Zp))
2655 {
2656 if (r->ch == s->ch)
2657 return true;
2658 else
2659 return false;
2660 }
2661 // n_Zn stimmt wahrscheinlich noch nicht
2662 if ((getCoeffType(r)==n_Zn) && (getCoeffType(s)==n_Zn))
2663 {
2664 if (r->ch == s->ch)
2665 return true;
2666 else
2667 return false;
2668 }
2669 if ((getCoeffType(r)==n_Q) && (getCoeffType(s)==n_Q))
2670 return true;
2671 // FALL n_Zn FEHLT NOCH!
2672 //if ((getCoeffType(r)==n_Zn) && (getCoeffType(s)==n_Zn))
2673 return false;
2674}
@ n_Zn
only used if HAVE_RINGS is defined
Definition: coeffs.h:44
@ n_Zp
\F{p < 2^31}
Definition: coeffs.h:29
@ n_Z
only used if HAVE_RINGS is defined
Definition: coeffs.h:43
static FORCE_INLINE n_coeffType getCoeffType(const coeffs r)
Returns the type of coeffs domain.
Definition: coeffs.h:421

◆ numbercoeffs()

static coeffs numbercoeffs ( number  n,
coeffs  c 
)
static

create Z/nA of type n_Zn

Definition at line 21 of file bigintmat.cc.

22{
23 mpz_t p;
24 number2mpz(n, c, p);
25 ZnmInfo *pp = new ZnmInfo;
26 pp->base = p;
27 pp->exp = 1;
28 coeffs nc = nInitChar(n_Zn, (void*)pp);
29 mpz_clear(p);
30 delete pp;
31 return nc;
32}
CanonicalForm FACTORY_PUBLIC pp(const CanonicalForm &)
CanonicalForm pp ( const CanonicalForm & f )
Definition: cf_gcd.cc:676
static FORCE_INLINE void number2mpz(number n, coeffs c, mpz_t m)
Definition: coeffs.h:987

◆ operator!=()

bool operator!= ( const bigintmat lhr,
const bigintmat rhr 
)

Definition at line 176 of file bigintmat.cc.

177{
178 return !(lhr==rhr);
179}

◆ operator==()

bool operator== ( const bigintmat lhr,
const bigintmat rhr 
)

Definition at line 159 of file bigintmat.cc.

160{
161 if (&lhr == &rhr) { return true; }
162 if (lhr.cols() != rhr.cols()) { return false; }
163 if (lhr.rows() != rhr.rows()) { return false; }
164 if (lhr.basecoeffs() != rhr.basecoeffs()) { return false; }
165
166 const int l = (lhr.rows())*(lhr.cols());
167
168 for (int i=0; i < l; i++)
169 {
170 if (!n_Equal(lhr[i], rhr[i], lhr.basecoeffs())) { return false; }
171 }
172
173 return true;
174}
static FORCE_INLINE BOOLEAN n_Equal(number a, number b, const coeffs r)
TRUE iff 'a' and 'b' represent the same number; they may have different representations.
Definition: coeffs.h:460

◆ prependIdentity()

static bigintmat * prependIdentity ( bigintmat A)
static

Definition at line 2037 of file bigintmat.cc.

2038{
2039 coeffs R = A->basecoeffs();
2040 bigintmat *m = new bigintmat(A->rows()+A->cols(), A->cols(), R);
2041 m->copySubmatInto(A, 1, 1, A->rows(), A->cols(), A->cols()+1, 1);
2042 number one = n_Init(1, R);
2043 for(int i=1; i<= A->cols(); i++)
2044 m->set(i,i,one);
2045 n_Delete(&one, R);
2046 return m;
2047}

◆ reduce_mod_howell()

static void reduce_mod_howell ( bigintmat A,
bigintmat b,
bigintmat eps,
bigintmat x 
)
static

Definition at line 1951 of file bigintmat.cc.

1952{
1953 //write b = Ax + eps where eps is "small" in the sense of bounded by the
1954 //pivot entries in H. H does not need to be Howell (or HNF) but need
1955 //to be triagonal in the same direction.
1956 //b can have multiple columns.
1957#if 0
1958 PrintS("reduce_mod_howell: A:\n");
1959 A->Print();
1960 PrintS("\nb:\n");
1961 b->Print();
1962#endif
1963
1964 coeffs R = A->basecoeffs();
1965 assume(x->basecoeffs() == R);
1966 assume(b->basecoeffs() == R);
1967 assume(eps->basecoeffs() == R);
1968 if (!A->cols())
1969 {
1970 x->zero();
1971 eps->copy(b);
1972
1973#if 0
1974 PrintS("\nx:\n");
1975 x->Print();
1976 PrintS("\neps:\n");
1977 eps->Print();
1978 PrintS("\n****************************************\n");
1979#endif
1980 return;
1981 }
1982
1983 bigintmat * B = new bigintmat(b->rows(), 1, R);
1984 for(int i=1; i<= b->cols(); i++)
1985 {
1986 int A_col = A->cols();
1987 b->getcol(i, B);
1988 for(int j = B->rows(); j>0; j--)
1989 {
1990 number Ai = A->view(A->rows() - B->rows() + j, A_col);
1991 if (n_IsZero(Ai, R) &&
1992 n_IsZero(B->view(j, 1), R))
1993 {
1994 continue; //all is fine: 0*x = 0
1995 }
1996 else if (n_IsZero(B->view(j, 1), R))
1997 {
1998 x->rawset(x->rows() - B->rows() + j, i, n_Init(0, R));
1999 A_col--;
2000 }
2001 else if (n_IsZero(Ai, R))
2002 {
2003 A_col--;
2004 }
2005 else
2006 {
2007 // "solve" ax=b, possibly enlarging d
2008 number Bj = B->view(j, 1);
2009 number q = n_Div(Bj, Ai, R);
2010 x->rawset(x->rows() - B->rows() + j, i, q);
2011 for(int k=j; k>B->rows() - A->rows(); k--)
2012 {
2013 //B[k] = B[k] - x[k]A[k][j]
2014 number s = n_Mult(q, A->view(A->rows() - B->rows() + k, A_col), R);
2015 B->rawset(k, 1, n_Sub(B->view(k, 1), s, R));
2016 n_Delete(&s, R);
2017 }
2018 A_col--;
2019 }
2020 if (!A_col)
2021 {
2022 break;
2023 }
2024 }
2025 eps->setcol(i, B);
2026 }
2027 delete B;
2028#if 0
2029 PrintS("\nx:\n");
2030 x->Print();
2031 PrintS("\neps:\n");
2032 eps->Print();
2033 PrintS("\n****************************************\n");
2034#endif
2035}
void setcol(int j, bigintmat *m)
Setzt j-te Spalte gleich übergebenem Vektor (Matrix) m.
Definition: bigintmat.cc:827
static FORCE_INLINE number n_Div(number a, number b, const coeffs r)
return the quotient of 'a' and 'b', i.e., a/b; raises an error if 'b' is not invertible in r exceptio...
Definition: coeffs.h:615
b *CanonicalForm B
Definition: facBivar.cc:52

◆ solveAx()

number solveAx ( bigintmat A,
bigintmat b,
bigintmat x 
)

solve Ax=b*d. x needs to be pre-allocated to the same number of columns as b. the minimal denominator d is returned. Currently available for Z, Q and Z/nZ (and possibly for all fields: d=1 there) Beware that the internal functions can find the kernel as well - but the interface is lacking.

Definition at line 2431 of file bigintmat.cc.

2432{
2433#if 0
2434 PrintS("Solve Ax=b for A=\n");
2435 A->Print();
2436 PrintS("\nb = \n");
2437 b->Print();
2438 PrintS("\nx = \n");
2439 x->Print();
2440 PrintLn();
2441#endif
2442
2443 coeffs R = A->basecoeffs();
2444 assume (R == b->basecoeffs());
2445 assume (R == x->basecoeffs());
2446 assume ((x->cols() == b->cols()) && (x->rows() == A->cols()) && (A->rows() == b->rows()));
2447
2448 switch (getCoeffType(R))
2449 {
2450 #ifdef HAVE_RINGS
2451 case n_Z:
2452 return solveAx_dixon(A, b, x, NULL);
2453 case n_Zn:
2454 case n_Znm:
2455 case n_Z2m:
2456 return solveAx_howell(A, b, x, NULL);
2457 #endif
2458 case n_Zp:
2459 case n_Q:
2460 case n_GF:
2461 case n_algExt:
2462 case n_transExt:
2463 WarnS("have field, should use Gauss or better");
2464 break;
2465 default:
2466 if (R->cfXExtGcd && R->cfAnn)
2467 { //assume it's Euclidean
2468 return solveAx_howell(A, b, x, NULL);
2469 }
2470 WerrorS("have no solve algorithm");
2471 break;
2472 }
2473 return NULL;
2474}
static number solveAx_dixon(bigintmat *A, bigintmat *B, bigintmat *x, bigintmat *kern)
Definition: bigintmat.cc:2109
static number solveAx_howell(bigintmat *A, bigintmat *b, bigintmat *x, bigintmat *kern)
Definition: bigintmat.cc:2299
@ n_GF
\GF{p^n < 2^16}
Definition: coeffs.h:32
@ n_Znm
only used if HAVE_RINGS is defined
Definition: coeffs.h:45
@ n_algExt
used for all algebraic extensions, i.e., the top-most extension in an extension tower is algebraic
Definition: coeffs.h:35
@ n_Z2m
only used if HAVE_RINGS is defined
Definition: coeffs.h:46
@ n_transExt
used for all transcendental extensions, i.e., the top-most extension in an extension tower is transce...
Definition: coeffs.h:38
#define WarnS
Definition: emacs.cc:78

◆ solveAx_dixon()

static number solveAx_dixon ( bigintmat A,
bigintmat B,
bigintmat x,
bigintmat kern 
)
static

Definition at line 2109 of file bigintmat.cc.

2109 {
2110 coeffs R = A->basecoeffs();
2111
2112 assume(getCoeffType(R) == n_Z);
2113
2114 number p = n_Init(536870909, R); // PreviousPrime(2^29); not clever
2115 coeffs Rp = numbercoeffs(p, R); // R/pR
2116 bigintmat *Ap = bimChangeCoeff(A, Rp),
2117 *m = prependIdentity(Ap),
2118 *Tp, *Hp;
2119 delete Ap;
2120
2121 m->howell();
2122 Hp = new bigintmat(A->rows(), A->cols(), Rp);
2123 Hp->copySubmatInto(m, A->cols()+1, 1, A->rows(), A->cols(), 1, 1);
2124 Tp = new bigintmat(A->cols(), A->cols(), Rp);
2125 Tp->copySubmatInto(m, 1, 1, A->cols(), A->cols(), 1, 1);
2126
2127 int i, j;
2128
2129 for(i=1; i<= A->cols(); i++)
2130 {
2131 for(j=m->rows(); j>A->cols(); j--)
2132 {
2133 if (!n_IsZero(m->view(j, i), Rp)) break;
2134 }
2135 if (j>A->cols()) break;
2136 }
2137// Print("Found nullity (kern dim) of %d\n", i-1);
2138 bigintmat * kp = new bigintmat(A->cols(), i-1, Rp);
2139 kp->copySubmatInto(Tp, 1, 1, A->cols(), i-1, 1, 1);
2140 kp->howell();
2141
2142 delete m;
2143
2144 //Hp is the mod-p howell form
2145 //Tp the transformation, mod p
2146 //kp a basis for the kernel, in howell form, mod p
2147
2148 bigintmat * eps_p = new bigintmat(B->rows(), B->cols(), Rp),
2149 * x_p = new bigintmat(A->cols(), B->cols(), Rp),
2150 * fps_p = new bigintmat(kp->cols(), B->cols(), Rp);
2151
2152 //initial solution
2153
2154 number zero = n_Init(0, R);
2155 x->skalmult(zero, R);
2156 n_Delete(&zero, R);
2157
2158 bigintmat * b = new bigintmat(B);
2159 number pp = n_Init(1, R);
2160 i = 1;
2161 do
2162 {
2163 bigintmat * b_p = bimChangeCoeff(b, Rp), * s;
2164 bigintmat * t1, *t2;
2165 reduce_mod_howell(Hp, b_p, eps_p, x_p);
2166 delete b_p;
2167 if (!eps_p->isZero())
2168 {
2169 PrintS("no solution, since no modular solution\n");
2170
2171 delete eps_p;
2172 delete x_p;
2173 delete Hp;
2174 delete kp;
2175 delete Tp;
2176 delete b;
2177 n_Delete(&pp, R);
2178 n_Delete(&p, R);
2179 nKillChar(Rp);
2180
2181 return NULL;
2182 }
2183 t1 = bimMult(Tp, x_p);
2184 delete x_p;
2185 x_p = t1;
2186 reduce_mod_howell(kp, x_p, x_p, fps_p); //we're not all interested in fps_p
2187 s = bimChangeCoeff(x_p, R);
2188 t1 = bimMult(A, s);
2189 t2 = bimSub(b, t1);
2190 t2->skaldiv(p);
2191 delete b;
2192 delete t1;
2193 b = t2;
2194 s->skalmult(pp, R);
2195 t1 = bimAdd(x, s);
2196 delete s;
2197 x->swapMatrix(t1);
2198 delete t1;
2199
2200 if(kern && i==1)
2201 {
2202 bigintmat * ker = bimChangeCoeff(kp, R);
2203 t1 = bimMult(A, ker);
2204 t1->skaldiv(p);
2205 t1->skalmult(n_Init(-1, R), R);
2206 b->appendCol(t1);
2207 delete t1;
2208 x->appendCol(ker);
2209 delete ker;
2210 x_p->extendCols(kp->cols());
2211 eps_p->extendCols(kp->cols());
2212 fps_p->extendCols(kp->cols());
2213 }
2214
2215 n_InpMult(pp, p, R);
2216
2217 if (b->isZero())
2218 {
2219 //exact solution found, stop
2220 delete eps_p;
2221 delete fps_p;
2222 delete x_p;
2223 delete Hp;
2224 delete kp;
2225 delete Tp;
2226 delete b;
2227 n_Delete(&pp, R);
2228 n_Delete(&p, R);
2229 nKillChar(Rp);
2230
2231 return n_Init(1, R);
2232 }
2233 else
2234 {
2235 bigintmat *y = new bigintmat(x->rows(), x->cols(), R);
2236 number d = bimFarey(x, pp, y);
2237 if (d)
2238 {
2239 bigintmat *c = bimMult(A, y);
2240 bigintmat *bd = new bigintmat(B);
2241 bd->skalmult(d, R);
2242 if (kern)
2243 {
2244 bd->extendCols(kp->cols());
2245 }
2246 if (*c == *bd)
2247 {
2248 x->swapMatrix(y);
2249 delete y;
2250 delete c;
2251 if (kern)
2252 {
2253 y = new bigintmat(x->rows(), B->cols(), R);
2254 c = new bigintmat(x->rows(), kp->cols(), R);
2255 x->splitcol(y, c);
2256 x->swapMatrix(y);
2257 delete y;
2258 kern->swapMatrix(c);
2259 delete c;
2260 }
2261
2262 delete bd;
2263
2264 delete eps_p;
2265 delete fps_p;
2266 delete x_p;
2267 delete Hp;
2268 delete kp;
2269 delete Tp;
2270 delete b;
2271 n_Delete(&pp, R);
2272 n_Delete(&p, R);
2273 nKillChar(Rp);
2274
2275 return d;
2276 }
2277 delete c;
2278 delete bd;
2279 n_Delete(&d, R);
2280 }
2281 delete y;
2282 }
2283 i++;
2284 } while (1);
2285 delete eps_p;
2286 delete fps_p;
2287 delete x_p;
2288 delete Hp;
2289 delete kp;
2290 delete Tp;
2291 n_Delete(&pp, R);
2292 n_Delete(&p, R);
2293 nKillChar(Rp);
2294 return NULL;
2295}
static void reduce_mod_howell(bigintmat *A, bigintmat *b, bigintmat *eps, bigintmat *x)
Definition: bigintmat.cc:1951
static bigintmat * prependIdentity(bigintmat *A)
Definition: bigintmat.cc:2037
bigintmat * bimSub(bigintmat *a, bigintmat *b)
Definition: bigintmat.cc:218
static number bimFarey(bigintmat *A, number N, bigintmat *L)
Definition: bigintmat.cc:2049
bigintmat * bimAdd(bigintmat *a, bigintmat *b)
Matrix-Add/-Sub/-Mult so oder mit operator+/-/* ? @Note: NULL as a result means an error (non-compati...
Definition: bigintmat.cc:182
CF_NO_INLINE bool isZero() const
Definition: cf_inline.cc:379
void swapMatrix(bigintmat *a)
Definition: bigintmat.cc:1567
int isZero()
Definition: bigintmat.cc:1364
void extendCols(int i)
append i zero-columns to the matrix
Definition: bigintmat.cc:1077
void skaldiv(number b)
Macht Ganzzahldivision aller Matrixeinträge mit b.
Definition: bigintmat.cc:1862
void copySubmatInto(bigintmat *, int sr, int sc, int nr, int nc, int tr, int tc)
copy the submatrix of b, staring at (a,b) having n rows, m cols into the given matrix at pos....
Definition: bigintmat.cc:1288
void howell()
dito, but Howell form (only different for zero-divsors)
Definition: bigintmat.cc:1586
const CanonicalForm int const CFList const Variable & y
Definition: facAbsFact.cc:53

◆ solveAx_howell()

static number solveAx_howell ( bigintmat A,
bigintmat b,
bigintmat x,
bigintmat kern 
)
static

Definition at line 2299 of file bigintmat.cc.

2300{
2301 // try to solve Ax=b, more precisely, find
2302 // number d
2303 // bigintmat x
2304 // sth. Ax=db
2305 // where d is small-ish (divides the determinant of A if this makes sense)
2306 // return 0 if there is no solution.
2307 //
2308 // if kern is non-NULL, return a basis for the kernel
2309
2310 //Algo: we do row-howell (triangular matrix). The idea is
2311 // Ax = b <=> AT T^-1x = b
2312 // y := T^-1 x, solve AT y = b
2313 // and return Ty.
2314 //Howell does not compute the trafo, hence we need to cheat:
2315 //B := (I_n | A^t)^t, then the top part of the Howell form of
2316 //B will give a useful trafo
2317 //Then we can find x by back-substitution and lcm/gcd to find the denominator
2318 //The defining property of Howell makes this work.
2319
2320 coeffs R = A->basecoeffs();
2322 m->howell(); // since m contains the identity, we'll have A->cols()
2323 // many cols.
2324 number den = n_Init(1, R);
2325
2326 bigintmat * B = new bigintmat(A->rows(), 1, R);
2327 for(int i=1; i<= b->cols(); i++)
2328 {
2329 int A_col = A->cols();
2330 b->getcol(i, B);
2331 B->skalmult(den, R);
2332 for(int j = B->rows(); j>0; j--)
2333 {
2334 number Ai = m->view(m->rows()-B->rows() + j, A_col);
2335 if (n_IsZero(Ai, R) &&
2336 n_IsZero(B->view(j, 1), R))
2337 {
2338 continue; //all is fine: 0*x = 0
2339 }
2340 else if (n_IsZero(B->view(j, 1), R))
2341 {
2342 x->rawset(x->rows() - B->rows() + j, i, n_Init(0, R));
2343 A_col--;
2344 }
2345 else if (n_IsZero(Ai, R))
2346 {
2347 delete m;
2348 delete B;
2349 n_Delete(&den, R);
2350 return 0;
2351 }
2352 else
2353 {
2354 // solve ax=db, possibly enlarging d
2355 // so x = db/a
2356 number Bj = B->view(j, 1);
2357 number g = n_Gcd(Bj, Ai, R);
2358 number xi;
2359 if (n_Equal(Ai, g, R))
2360 { //good: den stable!
2361 xi = n_Div(Bj, Ai, R);
2362 }
2363 else
2364 { //den <- den * (a/g), so old sol. needs to be adjusted
2365 number inc_d = n_Div(Ai, g, R);
2366 n_InpMult(den, inc_d, R);
2367 x->skalmult(inc_d, R);
2368 B->skalmult(inc_d, R);
2369 xi = n_Div(Bj, g, R);
2370 n_Delete(&inc_d, R);
2371 } //now for the back-substitution:
2372 x->rawset(x->rows() - B->rows() + j, i, xi);
2373 for(int k=j; k>0; k--)
2374 {
2375 //B[k] = B[k] - x[k]A[k][j]
2376 number s = n_Mult(xi, m->view(m->rows()-B->rows() + k, A_col), R);
2377 B->rawset(k, 1, n_Sub(B->view(k, 1), s, R));
2378 n_Delete(&s, R);
2379 }
2380 n_Delete(&g, R);
2381 A_col--;
2382 }
2383 if (!A_col)
2384 {
2385 if (B->isZero()) break;
2386 else
2387 {
2388 delete m;
2389 delete B;
2390 n_Delete(&den, R);
2391 return 0;
2392 }
2393 }
2394 }
2395 }
2396 delete B;
2397 bigintmat *T = new bigintmat(A->cols(), A->cols(), R);
2398 T->copySubmatInto(m, 1, 1, A->cols(), A->cols(), 1, 1);
2399 if (kern)
2400 {
2401 int i, j;
2402 for(i=1; i<= A->cols(); i++)
2403 {
2404 for(j=m->rows(); j>A->cols(); j--)
2405 {
2406 if (!n_IsZero(m->view(j, i), R)) break;
2407 }
2408 if (j>A->cols()) break;
2409 }
2410 Print("Found nullity (kern dim) of %d\n", i-1);
2411 bigintmat * ker = new bigintmat(A->rows(), i-1, R);
2412 ker->copySubmatInto(T, 1, 1, A->rows(), i-1, 1, 1);
2413 kern->swapMatrix(ker);
2414 delete ker;
2415 }
2416 delete m;
2417 bigintmat * y = bimMult(T, x);
2418 x->swapMatrix(y);
2419 delete y;
2420 x->simplifyContentDen(&den);
2421#if 0
2422 PrintS("sol = 1/");
2423 n_Print(den, R);
2424 PrintS(" *\n");
2425 x->Print();
2426 PrintLn();
2427#endif
2428 return den;
2429}
g
Definition: cfModGcd.cc:4090
static FORCE_INLINE number n_Gcd(number a, number b, const coeffs r)
in Z: return the gcd of 'a' and 'b' in Z/nZ, Z/2^kZ: computed as in the case Z in Z/pZ,...
Definition: coeffs.h:664