source: git/libpolys/coeffs/bigintmat.h @ e5be1c

fieker-DuValspielwiese
Last change on this file since e5be1c was e5be1c, checked in by Claus Fieker <fieker@…>, 10 years ago
comments - documentation
  • Property mode set to 100644
File size: 12.2 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/*
5* ABSTRACT: class bigintmat: matrices of number
6*
7* Matrices are stored as 1-dim c-arrays but interpreted 2-dim as matrices.
8* Both modes of addressing are supported, note however, that the 1-dim
9* adressing starts at 0, the 2-dim at 1.
10*
11* Matrices are meant to represent column modules, thus the default
12* operations are always by column.
13*
14* While basic operations are supported over any ring (coeff), some more
15* advanced ones require more special rings: eg. echelon forms, solving
16* of linear equations is only effective over principal ideal or even
17* Euclidean rings.
18*
19* Be careful with the get/set/view/rawset functions to understand which
20* arguments are copied/ deleted or only assigned.
21*/
22
23#ifndef BIGINTMAT_H
24#define BIGINTMAT_H
25
26#include <omalloc/omalloc.h>
27#include <resources/feFopen.h>
28#include <coeffs/coeffs.h>
29#include <coeffs/rmodulon.h>
30
31/// matrix of numbers
32/// NOTE: no reference counting!!!
33class bigintmat
34{
35  private:
36    coeffs m_coeffs;
37    number *v;
38    int row;
39    int col;
40  public:
41
42    bigintmat(): m_coeffs(NULL), v(NULL), row(1), col(0){}
43
44    bigintmat * transpose();
45
46    /// transpose in place
47    void inpTranspose();
48
49
50    /// constructor: the r times c zero-matrix. Beware that the creation
51    /// of a large zero matrix is expensive in terms of time and memory.
52    bigintmat(int r, int c, const coeffs n): m_coeffs(n), v(NULL), row(r), col(c)
53    {
54      assume (rows() >= 0);
55      assume (cols() >= 0);
56
57      const int l = r*c;
58
59      if (l>0) /*(r>0) && (c>0) */
60      {
61        v = (number *)omAlloc(sizeof(number)*l);
62
63        assume (basecoeffs() != NULL);
64        for (int i = l - 1; i>=0; i--)
65        {
66          v[i] = n_Init(0, basecoeffs());
67        }
68      }
69    }
70
71    /// copy constructor
72    bigintmat(const bigintmat *m): m_coeffs(m->basecoeffs()), v(NULL), row(m->rows()), col(m->cols())
73    {
74      const int l = row*col;
75
76      if (l > 0)
77      {
78        assume (rows() > 0);
79        assume (cols() > 0);
80
81        assume (m->v != NULL);
82
83        v = (number *)omAlloc(sizeof(number)*row*col);
84
85        assume (basecoeffs() != NULL);
86
87        for (int i = l-1; i>=0; i--)
88        {
89          v[i] = n_Copy((*m)[i], basecoeffs());
90        }
91      }
92    }
93    /// dubious: 1-dim access to 2-dim array. Entries are read row by row.
94    inline number& operator[](int i)
95    {
96#ifndef SING_NDEBUG
97      if((i<0)||(i>=row*col))
98      {
99        Werror("wrong bigintmat index:%d\n",i);
100      }
101#endif
102      assume ( !((i<0)||(i>=row*col)) );
103
104      return v[i];  // Hier sollte imho kein nlCopy rein...
105    }
106    inline const number& operator[](int i) const
107    {
108#ifndef SING_NDEBUG
109      if((i<0)||(i>=row*col))
110      {
111        Werror("wrong bigintmat index:%d\n",i);
112      }
113#endif
114      assume ( !((i<0)||(i>=row*col)) );
115
116      return v[i];
117    }
118#define BIMATELEM(M,I,J) (M)[(I-1)*(M).cols()+J-1]
119
120    /// UEberladener *=-Operator (fuer int und bigint)
121    /// Frage hier: *= verwenden oder lieber = und * einzeln?
122    /// problem: what about non-commuting rings. Is this from left or right?
123    void operator*=(int intop);
124
125    /// inplace versio of skalar mult. CHANGES input.
126    void inpMult(number bintop, const coeffs C = NULL);
127
128    inline int length() { return col*row; }
129    inline int  cols() const { return col; }
130    inline int  rows() const { return row; }
131    inline coeffs basecoeffs() const { return m_coeffs; }
132
133    /// canonical destructor.
134    ~bigintmat()
135    {
136      if (v!=NULL)
137      {
138        for (int i=0; i<row*col; i++) { n_Delete(&(v[i]), basecoeffs()); }
139        omFreeSize((ADDRESS)v, sizeof(number)*row*col);
140        v=NULL;
141      }
142    }
143
144    /// helper function to map from 2-dim coordinates, starting by 1 to
145    /// 1-dim coordinate, starting by 0
146    int index(int r, int c) const
147    {
148      assume (rows() >= 0 && cols() >= 0);
149
150      assume (r > 0 && c > 0);
151      assume (r <= rows() && c <= cols());
152
153      const int index = ((r-1)*cols() + (c-1));
154
155      assume (index >= 0 && index < rows() * cols());
156      return index;
157    }
158
159    /// get a copy of an entry. NOTE: starts at [1,1]
160    number get(int i, int j) const;
161    /// view an entry an entry. NOTE: starts at [1,1]
162    //do NOT delete.
163    number view(int i, int j) const;
164
165    /// get a copy of an entry. NOTE: starts at [0]
166    number get(int i) const;
167    /// view an entry. NOTE: starts at [0]
168    number view(int i) const;
169
170    /// replace an entry with a copy (delete old + copy new!).
171    /// NOTE: starts at [1,1]
172    void set(int i, int j, number n, const coeffs C = NULL);
173
174    /// replace an entry with a copy (delete old + copy new!).
175    /// NOTE: starts at [0]
176    void set(int i, number n, const coeffs C = NULL);
177
178
179    /// replace an entry with the given number n (only delete old).
180    /// NOTE: starts at [0]. Should be named set_transfer
181    inline void rawset(int i, number n, const coeffs C = NULL)
182    {
183      assume (C == NULL || C == basecoeffs());
184      assume (i >= 0);
185      const int l = rows() * cols();
186      assume (i<l);
187
188      if (i < l)
189      {
190        n_Delete(&(v[i]), basecoeffs()); v[i] = n;
191      }
192#ifndef SING_NDEBUG
193      else
194      {
195        Werror("wrong bigintmat index:%d\n",i);
196      }
197#endif
198    }
199
200    /// as above, but the 2-dim version
201    inline void rawset(int i, int j, number n, const coeffs C = NULL)
202    {
203      rawset( index(i,j), n, C);
204    }
205
206    ///IO: String returns a singular string containing the matrix, needs
207    /// freeing afterwards
208    char * String();
209    ///IO: writes the matrix into the current internal string buffer which
210    /// must be started/ allocated before (e.g. @StringSetS)
211    void Write();
212    ///IO: simply prints the matrix to the current output (screen?)
213    void Print();
214/***
215 * Returns a string as it would have been printed in the interpreter.
216 * Used e.g. in print functions of various blackbox types.
217 **/
218    char * StringAsPrinted();
219    void pprint(int maxwid);
220    int compare(const bigintmat* op) const;
221    int * getwid(int maxwid);
222
223
224    // Funktionen von Kira, Jan, Marco
225    // !WICHTIG: Überall, wo eine number ÃŒbergeben wird, und damit gearbeitet wird, die coeffs mitÃŒbergeben und erst
226    // ÃŒberprÃŒfen, ob diese mit basecoeffs ÃŒbereinstimmen. Falls nein: Breche ab!
227    /// swap columns i and j
228    void swap(int i, int j);
229
230    /// swap rows i and j
231    void swaprow(int i, int j); 
232
233    ///find index of 1st non-zero entry in row i
234    int findnonzero(int i);
235
236    ///find index of 1st non-zero entry in column j
237    int findcolnonzero(int j); 
238
239    ///copies the j-th column into the matrix a - which needs to be pre-allocated with the correct size.
240    void getcol(int j, bigintmat *a); 
241                                   
242    ///copies the no-columns staring by j (so j...j+no-1) into the pre-allocated a
243    void getColRange(int j, int no, bigintmat *a); 
244
245    void getrow(int i, bigintmat *a); // Schreibt i-te Zeile in Vektor (Matrix) a
246    void setcol(int j, bigintmat *m); // Setzt j-te Spalte gleich ÃŒbergebenem Vektor (Matrix) m
247    void setrow(int i, bigintmat *m); // Setzt i-te Zeile gleich ÃŒbergebenem Vektor (Matrix) m
248
249    ///horizontally join the matrices, m <- m|a
250    void appendCol (bigintmat *a); 
251
252    ///append i zero-columns to the matrix
253    void extendCols (int i);
254
255    bool add(bigintmat *b); // Addiert zur Matrix die Matrix b dazu. Return false => an error occured
256    bool sub(bigintmat *b); // Subtrahiert ...
257    bool skalmult(number b, coeffs c); // Multipliziert zur Matrix den Skalar b hinzu
258    bool addcol(int i, int j, number a, coeffs c); // addiert a-faches der j-ten Spalte zur i-ten dazu
259    bool addrow(int i, int j, number a, coeffs c); // ... Zeile ...
260    void colskalmult(int i, number a, coeffs c); // Multipliziert zur i-ten Spalte den Skalar a hinzu
261    void rowskalmult(int i, number a, coeffs c); // ... Zeile ...
262    void coltransform(int i, int j, number a, number b, number c, number d); //  transforms cols (i,j) using the 2x2 matrix ((a,b)(c,d)) (hopefully)
263    void concatrow(bigintmat *a, bigintmat *b); // FÃŒgt zwei Matrixen untereinander/nebeneinander in gegebene Matrix ein, bzw spaltet gegebenen Matrix auf
264    void concatcol(bigintmat *a, bigintmat *b);
265    void splitrow(bigintmat *a, bigintmat *b); // Speichert in Matrix a den oberen, in b den unteren Teil der Matrix, vorausgesetzt die Dimensionen stimmen ÃŒberein
266    void splitcol(bigintmat *a, bigintmat *b); // ... linken ... rechten ...
267    void splitcol(bigintmat *a, int i); // Speichert die ersten i Spalten als Teilmatrix in a
268    void splitrow(bigintmat *a, int i); // ... Zeilen ...
269    bool copy(bigintmat *b); // Kopiert EintrÀge von b auf Bigintmat
270    void copySubmatInto(bigintmat *, int sr, int sc, int nr, int nc, int tr, int tc);
271    void one(); // Macht Matrix (Falls quadratisch) zu Einheitsmatrix
272    int isOne(); // is matrix is identity
273    void zero(); // Setzt alle EintrÀge auf 0
274    int isZero();
275    int colIsZero(int i);
276    bigintmat *elim(int i, int j); // Liefert Streichungsmatrix (i-te Zeile und j-te Spalte gestrichen) zurÃŒck
277    number pseudoinv(bigintmat *a); // Speichert in Matrix a die Pseudoinverse, liefert den Nenner zurÃŒck
278    number trace(); // the trace ....
279    number det(); // det (via LaPlace in general, hnf for euc. rings)
280    number hnfdet(); // det via HNF
281    /// Primzahlen als long long int, mÃŒssen noch in number umgewandelt werden?
282    void hnf(); // transforms INPLACE to HNF
283    void howell(); //dito, but Howell form (only different for zero-divsors)
284    void swapMatrix(bigintmat * a);
285    bigintmat * modhnf(number p, coeffs c); // computes HNF(this | p*I)
286    bigintmat * modgauss(number p, coeffs c);
287    void skaldiv(number b); // Macht Ganzzahldivision aller MatrixeintrÀge mit b
288    void colskaldiv(int j, number b); // Macht Ganzzahldivision aller j-ten SpalteneintrÀge mit b
289    void mod(number p, coeffs c); // Reduziert komplette Matrix modulo p
290    bigintmat* inpmod(number p, coeffs c); // Liefert Kopie der Matrix zurÃŒck, allerdings im Ring Z modulo p
291    number content(); //the content, the gcd of all entries. Only makes sense for Euclidean rings (or possibly constructive PIR)
292    void simplifyContentDen(number *den); // ensures that Gcd(den, content)=1
293    // enden hier wieder
294};
295
296bool operator==(const bigintmat & lhr, const bigintmat & rhr);
297bool operator!=(const bigintmat & lhr, const bigintmat & rhr);
298
299/// Matrix-Add/-Sub/-Mult so oder mit operator+/-/* ?
300/// NOTE: NULL as a result means an error (non-compatible matrices?)
301bigintmat * bimAdd(bigintmat * a, bigintmat * b);
302bigintmat * bimAdd(bigintmat * a, int b);
303bigintmat * bimSub(bigintmat * a, bigintmat * b);
304bigintmat * bimSub(bigintmat * a, int b);
305bigintmat * bimMult(bigintmat * a, bigintmat * b);
306bigintmat * bimMult(bigintmat * a, int b);
307bigintmat * bimMult(bigintmat * a, number b, const coeffs cf);
308
309///same as copy constructor - apart from it being able to accept NULL as input
310bigintmat * bimCopy(const bigintmat * b);
311
312class intvec;
313intvec * bim2iv(bigintmat * b);
314bigintmat * iv2bim(intvec * b, const coeffs C);
315
316// Wieder von Kira, Jan, Marco
317bigintmat * bimChangeCoeff(bigintmat *a, coeffs cnew); // Liefert Kopier von Matrix a zurÃŒck, mit coeffs cnew statt den ursprÃŒnglichen
318void bimMult(bigintmat *a, bigintmat *b, bigintmat *c); // Multipliziert Matrix a und b und speichert Ergebnis in c
319
320///solve Ax=b*d. x needs to be pre-allocated to the same number of columns as b.
321/// the minimal denominator d is returned. Currently available for Z, Q and Z/nZ (and possibly for all fields: d=1 there)
322///Beware that the internal functions can find the kernel as well - but the interface is lacking.
323number solveAx(bigintmat *A, bigintmat *b, bigintmat *x); // solves Ax=b*d for a minimal denominator d. if x needs to have as many cols as b
324
325///a basis for the nullspace of a mod p: only used internally in Round2.
326/// Don't use it.
327int kernbase (bigintmat *a, bigintmat *c, number p, coeffs q);
328coeffs numbercoeffs(number n, coeffs c);
329bool nCoeffs_are_equal(coeffs r, coeffs s);
330// Geklaut aus anderer Datei:
331static inline void number2mpz(number n, coeffs c, mpz_t m){ n_MPZ(m, n, c); }
332static inline number mpz2number(mpz_t m, coeffs c){ return n_InitMPZ(m, c); }
333// enden wieder
334void diagonalForm(bigintmat *a, bigintmat **b, bigintmat **c);
335
336#endif // #ifndef BIGINTMAT_H
Note: See TracBrowser for help on using the repository browser.