source: git/libpolys/coeffs/bigintmat.h @ 61e855

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