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

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