This file is indexed.

/usr/include/singular/singular/coeffs/bigintmat.h is in libsingular4-dev-common 1:4.1.0-p3+ds-2build1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
/****************************************
*  Computer Algebra System SINGULAR     *
****************************************/
/*
* ABSTRACT: class bigintmat: matrices of number
*
* Matrices are stored as 1-dim c-arrays but interpreted 2-dim as matrices.
* Both modes of addressing are supported, note however, that the 1-dim
* adressing starts at 0, the 2-dim at 1.
*
* Matrices are meant to represent column modules, thus the default
* operations are always by column.
*
* While basic operations are supported over any ring (coeff), some more
* advanced ones require more special rings: eg. echelon forms, solving
* of linear equations is only effective over principal ideal or even
* Euclidean rings.
*
* Be careful with the get/set/view/rawset functions to understand which
* arguments are copied/ deleted or only assigned.
*/

#ifndef BIGINTMAT_H
#define BIGINTMAT_H

#include <omalloc/omalloc.h>
#include <coeffs/coeffs.h>

/**
 * @class bigintmat bigintmat.h <coeffs/bigintmat.h>
 *
 * Matrices of numbers
 *
 * Matrices are stored as 1-dim c-arrays but interpreted 2-dim as matrices.
 * Both modes of addressing are supported, note however, that the 1-dim
 * adressing starts at 0, the 2-dim at 1.
 *
 * Matrices are meant to represent column modules, thus the default
 * operations are always by column.
 *
 * While basic operations are supported over any ring (coeff), some more
 * advanced ones require more special rings: eg. echelon forms, solving
 * of linear equations is only effective over principal ideal or even
 * Euclidean rings.
 *
 * Be careful with the get/set/view/rawset functions to understand which
 * arguments are copied/ deleted or only assigned.
 *
 * @Note: no reference counting here!
 */
class bigintmat
{
  private:
    coeffs m_coeffs;
    number *v;
    int row;
    int col;
  public:

    bigintmat(): m_coeffs(NULL), v(NULL), row(1), col(0){}

    bigintmat * transpose();

    /// transpose in place
    void inpTranspose();


    /// constructor: the r times c zero-matrix. Beware that the creation
    /// of a large zero matrix is expensive in terms of time and memory.
    bigintmat(int r, int c, const coeffs n): m_coeffs(n), v(NULL), row(r), col(c)
    {
      assume (rows() >= 0);
      assume (cols() >= 0);

      const int l = r*c;

      if (l>0) /*(r>0) && (c>0) */
      {
        v = (number *)omAlloc(sizeof(number)*l);

        assume (basecoeffs() != NULL);
        for (int i = l - 1; i>=0; i--)
        {
          v[i] = n_Init(0, basecoeffs());
        }
      }
    }

    /// copy constructor
    bigintmat(const bigintmat *m): m_coeffs(m->basecoeffs()), v(NULL), row(m->rows()), col(m->cols())
    {
      const int l = row*col;

      if (l > 0)
      {
        assume (rows() > 0);
        assume (cols() > 0);

        assume (m->v != NULL);

        v = (number *)omAlloc(sizeof(number)*row*col);

        assume (basecoeffs() != NULL);

        for (int i = l-1; i>=0; i--)
        {
          v[i] = n_Copy((*m)[i], basecoeffs());
        }
      }
    }
    /// dubious: 1-dim access to 2-dim array. Entries are read row by row.
    inline number& operator[](int i)
    {
#ifndef SING_NDEBUG
      if((i<0)||(i>=row*col))
      {
        Werror("wrong bigintmat index:%d\n",i);
      }
      assume ( !((i<0)||(i>=row*col)) );
#endif
      return v[i];  // Hier sollte imho kein nlCopy rein...
    }
    inline const number& operator[](int i) const
    {
#ifndef SING_NDEBUG
      if((i<0)||(i>=row*col))
      {
        Werror("wrong bigintmat index:%d\n",i);
      }
      assume ( !((i<0)||(i>=row*col)) );
#endif
      return v[i];
    }
#define BIMATELEM(M,I,J) (M)[(I-1)*(M).cols()+J-1]

    /// UEberladener *=-Operator (fuer int und bigint)
    /// Frage hier: *= verwenden oder lieber = und * einzeln?
    /// problem: what about non-commuting rings. Is this from left or right?
    void operator*=(int intop);

    /// inplace version of skalar mult. CHANGES input.
    void inpMult(number bintop, const coeffs C = NULL);

    inline int length() { return col*row; }
    inline int  cols() const { return col; }
    inline int  rows() const { return row; }
    inline coeffs basecoeffs() const { return m_coeffs; }

    /// canonical destructor.
    ~bigintmat()
    {
      if (v!=NULL)
      {
        for (int i=row*col-1;i>=0; i--) { n_Delete(&(v[i]), basecoeffs()); }
        omFreeSize((ADDRESS)v, sizeof(number)*row*col);
        v=NULL;
      }
    }

    /// helper function to map from 2-dim coordinates, starting by 1 to
    /// 1-dim coordinate, starting by 0
    int index(int r, int c) const
    {
      assume (rows() >= 0 && cols() >= 0);

      assume (r > 0 && c > 0);
      assume (r <= rows() && c <= cols());

      const int index = ((r-1)*cols() + (c-1));

      assume (index >= 0 && index < rows() * cols());
      return index;
    }

    /// get a copy of an entry. NOTE: starts at [1,1]
    number get(int i, int j) const;
    /// view an entry an entry. NOTE: starts at [1,1]
    //do NOT delete.
    number view(int i, int j) const;

    /// get a copy of an entry. NOTE: starts at [0]
    number get(int i) const;
    /// view an entry. NOTE: starts at [0]
    number view(int i) const;

    /// replace an entry with a copy (delete old + copy new!).
    /// NOTE: starts at [1,1]
    void set(int i, int j, number n, const coeffs C = NULL);

    /// replace an entry with a copy (delete old + copy new!).
    /// NOTE: starts at [0]
    void set(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_transfer
    inline void rawset(int i, number n, const coeffs C = NULL)
    {
      assume (C == NULL || C == basecoeffs());
      assume (i >= 0);
      const int l = rows() * cols();
      assume (i<l);

      if (i < l)
      {
        n_Delete(&(v[i]), basecoeffs()); v[i] = n;
      }
#ifndef SING_NDEBUG
      else
      {
        Werror("wrong bigintmat index:%d\n",i);
      }
#endif
    }

    /// as above, but the 2-dim version
    inline void rawset(int i, int j, number n, const coeffs C = NULL)
    {
      rawset( index(i,j), n, C);
    }

    ///IO: String returns a singular string containing the matrix, needs
    /// freeing afterwards
    char * String();
    ///IO: writes the matrix into the current internal string buffer which
    /// must be started/ allocated before (e.g. @ref StringSetS)
    void Write();
    ///IO: simply prints the matrix to the current output (screen?)
    void Print();

   /**
    * Returns a string as it would have been printed in the interpreter.
    * Used e.g. in print functions of various blackbox types.
    */
    char * StringAsPrinted();
    void pprint(int maxwid);
    int compare(const bigintmat* op) const;
    int * getwid(int maxwid);


    // Funktionen von Kira, Jan, Marco
    // !WICHTIG: Überall, wo eine number übergeben wird, und damit gearbeitet wird, die coeffs mitübergeben und erst
    // überprüfen, ob diese mit basecoeffs übereinstimmen. Falls nein: Breche ab!

    /// swap columns i and j
    void swap(int i, int j);

    /// swap rows i and j
    void swaprow(int i, int j);

    ///find index of 1st non-zero entry in row i
    int findnonzero(int i);

    ///find index of 1st non-zero entry in column j
    int findcolnonzero(int j);

    ///copies the j-th column into the matrix a - which needs to be pre-allocated with the correct size.
    void getcol(int j, bigintmat *a);

    ///copies the no-columns staring by j (so j...j+no-1) into the pre-allocated a
    void getColRange(int j, int no, bigintmat *a);

    void getrow(int i, bigintmat *a); ///< Schreibt i-te Zeile in Vektor (Matrix) a
    void setcol(int j, bigintmat *m); ///< Setzt j-te Spalte gleich übergebenem Vektor (Matrix) m
    void setrow(int i, bigintmat *m); ///< Setzt i-te Zeile gleich übergebenem Vektor (Matrix) m

    ///horizontally join the matrices, m <- m|a
    void appendCol (bigintmat *a);

    ///append i zero-columns to the matrix
    void extendCols (int i);

    bool add(bigintmat *b); ///< Addiert zur Matrix die Matrix b dazu. Return false => an error occurred
    bool sub(bigintmat *b); ///< Subtrahiert ...
    bool skalmult(number b, coeffs c); ///< Multipliziert zur Matrix den Skalar b hinzu
    bool addcol(int i, int j, number a, coeffs c); ///< addiert a-faches der j-ten Spalte zur i-ten dazu
    bool addrow(int i, int j, number a, coeffs c); ///< ... Zeile ...
    void colskalmult(int i, number a, coeffs c); ///< Multipliziert zur i-ten Spalte den Skalar a hinzu
    void rowskalmult(int i, number a, coeffs c); ///< ... Zeile ...
    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)
    void concatrow(bigintmat *a, bigintmat *b); ///< Fügt zwei Matrixen untereinander/nebeneinander in gegebene Matrix ein, bzw spaltet gegebenen Matrix auf
    void concatcol(bigintmat *a, bigintmat *b);
    void splitrow(bigintmat *a, bigintmat *b); ///< Speichert in Matrix a den oberen, in b den unteren Teil der Matrix, vorausgesetzt die Dimensionen stimmen überein
    void splitcol(bigintmat *a, bigintmat *b); ///< ... linken ... rechten ...
    void splitcol(bigintmat *a, int i); ///< Speichert die ersten i Spalten als Teilmatrix in a
    void splitrow(bigintmat *a, int i); ///< ... Zeilen ...
    bool copy(bigintmat *b); ///< Kopiert Einträge von b auf Bigintmat
    void copySubmatInto(bigintmat *, int sr, int sc, int nr, int nc, int tr, int tc);
    void one(); ///< Macht Matrix (Falls quadratisch) zu Einheitsmatrix
    int isOne(); ///< is matrix is identity
    void zero(); ///< Setzt alle Einträge auf 0
    int isZero();
    int colIsZero(int i);
    bigintmat *elim(int i, int j); ///< Liefert Streichungsmatrix (i-te Zeile und j-te Spalte gestrichen) zurück
    number pseudoinv(bigintmat *a); ///< Speichert in Matrix a die Pseudoinverse, liefert den Nenner zurück
    number trace(); ///< the trace ....
    number det(); ///< det (via LaPlace in general, hnf for euc. rings)
    number hnfdet(); ///< det via HNF
    /// Primzahlen als long long int, müssen noch in number umgewandelt werden?
    void hnf(); ///< transforms INPLACE to HNF
    void howell(); ///<dito, but Howell form (only different for zero-divsors)
    void swapMatrix(bigintmat * a);
    #ifdef HAVE_RINGS
    bigintmat * modhnf(number p, coeffs c); ///< computes HNF(this | p*I)
    #endif
    bigintmat * modgauss(number p, coeffs c);
    void skaldiv(number b); ///< Macht Ganzzahldivision aller Matrixeinträge mit b
    void colskaldiv(int j, number b); ///< Macht Ganzzahldivision aller j-ten Spalteneinträge mit b
    void mod(number p); ///< Reduziert komplette Matrix modulo p
    bigintmat* inpmod(number p, coeffs c); ///< Liefert Kopie der Matrix zurück, allerdings im Ring Z modulo p
    number content(); ///<the content, the gcd of all entries. Only makes sense for Euclidean rings (or possibly constructive PIR)
    void simplifyContentDen(number *den); ///< ensures that Gcd(den, content)=1
    ///< enden hier wieder
};

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

/// Matrix-Add/-Sub/-Mult so oder mit operator+/-/* ?
/// @Note: NULL as a result means an error (non-compatible matrices?)
bigintmat * bimAdd(bigintmat * a, bigintmat * b);
bigintmat * bimAdd(bigintmat * a, int b);
bigintmat * bimSub(bigintmat * a, bigintmat * b);
bigintmat * bimSub(bigintmat * a, int b);
bigintmat * bimMult(bigintmat * a, bigintmat * b);
bigintmat * bimMult(bigintmat * a, int b);
bigintmat * bimMult(bigintmat * a, number b, const coeffs cf);

///same as copy constructor - apart from it being able to accept NULL as input
bigintmat * bimCopy(const bigintmat * b);

class intvec;
intvec * bim2iv(bigintmat * b);
bigintmat * iv2bim(intvec * b, const coeffs C);

// Wieder von Kira, Jan, Marco
bigintmat * bimChangeCoeff(bigintmat *a, coeffs cnew); ///< Liefert Kopier von Matrix a zurück, mit coeffs cnew statt den ursprünglichen
void bimMult(bigintmat *a, bigintmat *b, bigintmat *c); ///< Multipliziert Matrix a und b und speichert Ergebnis in c

///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.
number 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

///a basis for the nullspace of a mod p: only used internally in Round2.
/// Don't use it.
int kernbase (bigintmat *a, bigintmat *c, number p, coeffs q);
bool nCoeffs_are_equal(coeffs r, coeffs s);
// enden wieder
void diagonalForm(bigintmat *a, bigintmat **b, bigintmat **c);

#endif /* #ifndef BIGINTMAT_H */