File: basisop.c

package info (click to toggle)
iml 1.0.3-4
  • links: PTS
  • area: main
  • in suites: squeeze
  • size: 2,020 kB
  • ctags: 180
  • sloc: sh: 8,654; ansic: 6,206; makefile: 70
file content (372 lines) | stat: -rw-r--r-- 9,691 bytes parent folder | download | duplicates (6)
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
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
/* ---------------------------------------------------------------------
 *
 * -- Integer Matrix Library (IML)
 *    (C) Copyright 2004, 2006 All Rights Reserved
 *
 * -- IML routines -- Version 1.0.1 -- November, 2006
 *
 * Author         : Zhuliang Chen
 * Contributor(s) : Arne Storjohann
 * University of Waterloo -- School of Computer Science
 * Waterloo, Ontario, N2L3G1 Canada
 *
 * ---------------------------------------------------------------------
 *
 * -- Copyright notice and Licensing terms:
 *
 *  Redistribution  and  use in  source and binary forms, with or without
 *  modification, are  permitted provided  that the following  conditions
 *  are met:
 *
 * 1. Redistributions  of  source  code  must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce  the above copyright
 *    notice,  this list of conditions, and the  following disclaimer in
 *    the documentation and/or other materials provided with the distri-
 *    bution.
 * 3. The name of the University,  the IML group,  or the names of its
 *    contributors  may not be used to endorse or promote products deri-
 *    ved from this software without specific written permission.
 *
 * -- Disclaimer:
 *
 * THIS  SOFTWARE  IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,  INCLUDING,  BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,  INDIRECT, INCIDENTAL, SPE-
 * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 * TO,  PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEO-
 * RY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT  (IN-
 * CLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */



#include "basisop.h"

/*
 * Calling Sequence:
 *   Dmod(p, A, n, m, lda)
 * 
 * Summary:
 *   Perform mod p operation inplace over a double matrix/submatrix
 *
 * Description:
 *   Given a n x m matrix or submatrix A and an integer p, this function uses
 *   fmod function to do operation A mod p inplace. Although the type of input
 *   modulus p in this function is Double, it is a cast of an integer.
 *
 * Input:
 *     p: Double, module
 *     A: 1-dim Double array length n*m, representation of a n x m double 
 *        matrix/submatrix
 *     n: long, row dimension of A
 *     m: long, column dimension of A
 *   lda: long, number of entries between two continuous rows of A, help track
 *        the pointer if A is a submatrix
 *
 */

void
Dmod (const Double p, Double *A, const long n, const long m, const long lda)
{
  long i, j;
  Double temp;

  for (i = 0; i < n; i++)
    for (j = 0; j < m; j++)
      *(A+i*lda+j) = (temp = fmod(*(A+i*lda+j), p)) >= 0 ? temp : p+temp;
}

  
/*
 * Calling Sequence:
 *   DCopy(n, m, A, lda, B, ldb)
 * 
 * Summary:
 *   Copy Double matrix/submatrix A to another matrix/submatrix B
 *
 * Input:
 *     n: long, row dimension of matrix/submatrix A and B
 *     m: long, column dimension of matrix/submatrix A and B
 *     A: 1-dim Double array length n*m, representation of a n x m Double 
 *        matrix/submatrix
 *   lda: long, stride of two continuous rows of A
 *     B: 1-dim Double array length n*m, representation of a n x m Double 
 *        matrix/submatrix
 *   ldb: long, stride of two continuous rows of B
 *
 */

void 
DCopy (const long n, const long m, const Double* A, const long lda, \
       Double* B, const long ldb)
{
  long i, j;

  for (i = 0; i < n; i++)
    for (j = 0; j < m; j++)
      *(B+i*ldb+j) = *(A+i*lda+j);
}



/*
 * Calling Sequence:
 *   randomDb(n, m, bd)
 * 
 * Summary:
 *   Generate a random Double dense matrix
 * 
 * Description:
 *   Given the bound bd, this function generates a random Double dense matrix
 *   such that any entry e satisfies 0 <= e <= 2^bd-1
 *
 * Input:
 *    n: long, row dimension of the generated matrix
 *    m: long, column dimension of the generated matrix
 *   bd: long, magnitude bound of entries
 *
 * Return:
 *   M: 1-dim Double array length n*m, representation of a n x m random matrix
 *
 */

Double *
randomDb (const long n, const long m, const long bd)
{
  long i, j;
  mpz_t mp_rand;
  gmp_randstate_t state;
  unsigned long seed;
  FILE* devrandom;
  Double* M;
  static unsigned long inc = 0;

#if HAVE_TIME_H
  time_t t1;
#endif

  M = XMALLOC(Double, n*m);
  mpz_init(mp_rand);
  gmp_randinit_default(state);
  mpz_set_ui(mp_rand, 5);
  
  seed = 3828173;

  /* generate random seed using /dev/random */
  if ((devrandom = fopen("/dev/urandom", "r")) != NULL)
    {
      fread(&seed, sizeof(seed), 1, devrandom);
      fclose(devrandom);
    }
  else
    {
#if HAVE_TIME_H
       time(&t1);
       seed = (unsigned long)t1;
#endif
    }

  seed += inc;
  inc += 1;
  gmp_randseed_ui(state, seed);
  for (i = 0; i < n*m; i++)
    {
       mpz_urandomb(mp_rand, state, bd);
       M[i] = mpz_get_d(mp_rand); 
    }
  mpz_clear(mp_rand);
  gmp_randclear(state);
  return M;
}



/*
 * Calling Sequence:
 *   RandomPrime(lb, hb)
 *
 * Summary:
 *   Generate a random prime p satisfying 2^lb <= p <= 2^hb-1
 *
 * Input:
 *   lb: FiniteField, lower bound of the prime
 *   hb: FiniteField, upper bound of the prime
 *
 * Return:
 *   p: FiniteField, randomly generated prime
 *
 * Note: 
 *   lb and hb can not exceed the bit-length of unsigned long.
 *
 */

FiniteField
RandPrime (const FiniteField lb, const FiniteField hb)
{
  mpz_t mp_rand, mp_temp, mp_lb, mp_hb;
  gmp_randstate_t state;
  FiniteField p;
  unsigned long seed;
  FILE* devrandom;
  static unsigned long inc = 0;

#if HAVE_TIME_H
  time_t t1;
#endif

  { mpz_init(mp_rand); mpz_init(mp_temp); } 
  { mpz_init(mp_lb);  mpz_init(mp_hb); }
  mpz_ui_pow_ui(mp_lb, 2, lb);
  mpz_ui_pow_ui(mp_hb, 2, hb);
  mpz_sub(mp_temp, mp_hb, mp_lb);
  gmp_randinit_default(state);

  seed = 3828173;

  /* generate random seed using /dev/urandom */
  if ((devrandom = fopen("/dev/urandom", "r")) != NULL)
    {
      fread(&seed, sizeof(seed), 1, devrandom);
      fclose(devrandom);
    }
  else
    {
#if HAVE_TIME_H
      time(&t1);
      seed = (unsigned long)t1;
#endif
    }

  seed += inc;
  inc += 1;
  gmp_randseed_ui(state, seed);
  mpz_urandomm(mp_rand, state, mp_temp); /* 0 <= mp_rand <= 2^hb-2^lb-1 */
  mpz_add(mp_rand, mp_rand, mp_lb);      /* 2^lb <= mp_rand <= 2^hb-1 */
  while (mpz_probab_prime_p(mp_rand, 10) == 0) 
    mpz_sub_ui(mp_rand, mp_rand, 1); 
  p = mpz_get_ui(mp_rand);

  { mpz_clear(mp_rand); mpz_clear(mp_temp); }
  { mpz_clear(mp_lb); mpz_clear(mp_hb); }
  gmp_randclear(state);
  return p;
}



/*
 * Calling Sequence:
 *   max <-- maxMagnLong(A, n, m, lda)
 *
 * Summary:
 *   Compute maximum magnitude of a n x m signed long matrix/submatrix A
 *
 * Input:
 *     A: 1-dim long array length n*m, representation of a n x m 
 *        matrix/submatrix
 *     n: long, row dimension of A
 *     m: long, column dimension of A
 *   lda: long, number of entries of two continuous rows of A (normally m)
 *
 * Return: 
 *   max: long, maximum magnitude of A
 *
 */

long 
maxMagnLong (const long *A, const long n, const long m, const long lda)
{
  long i, j, temp, max=0;

  for (i = 0; i < n; i++)
    for (j = 0; j < m; j++)
      if ((temp = labs(A[i*lda+j])) > max) { max = temp; }
  return max;
}



/*
 *
 * Calling Sequence:
 *   maxMagnMP(mp_A, n, m, lda, mp_max)
 *
 * Summary:
 *   Compute maximum magnitude of a n x m mpz_t matrix/submatrix mp_A
 *
 * Input:
 *   mp_A: 1-dim mpz_t array length n*m, representation of a n x m 
 *         matrix/submatrix
 *      n: long, row dimension of mp_A
 *      m: long, column dimension of mp_A
 *    lda: long, number of entries of two continuous rows of mp_A (normally m)
 *
 * Output: 
 *   mp_max: mpz_t, maximum magnitude of mp_A
 *
 */

void
maxMagnMP (mpz_t *mp_A, const long n, const long m, const long lda, \
	   mpz_t mp_max)
{
  long i, j;

  mpz_set_ui(mp_max, 0);
  for (i = 0; i < n; i++) 
    for (j = 0; j < m; j++)
      if (mpz_cmpabs(mp_A[i*lda+j], mp_max) > 0) 
	mpz_abs(mp_max, mp_A[i*lda+j]);
  return;
}


/*
 * Calling Sequence:
 *   scalCpMP(n, m, lda, ldm, mp_a, mp_A, mp_M)
 *
 * Summary:
 *   Copy a submatrix with scale from one matrix to the other one
 *
 * Description:
 *   Copy with scalar n x m submatrix from A to M. The submatrix starts
 *   from position pointed by mp_A with stride lda. Then the submatrix is 
 *   copied to position pointed by mp_M with stride ldm, meanwhile, the 
 *   entries of the submatrix are scaled by factor mp_a.
 * 
 * Input: 
 *      n: long, row dimension of the submatrix
 *      m: long, column dimension of the submatrix
 *    lda: long, stride of two continuous rows of the submatrix in A
 *    ldm: long, stride of two continuous rows of the submatrix in M
 *   mp_a: mpz_t, scalar factor
 *   mp_A: mpz_t pointer, start point of the submatrix in A
 *   mp_M: mpz_t pointer, start point of the submatrix in M
 *
 */

void 
scalCpMP (const long n, const long m, const long lda, const long ldm, \
	  const mpz_t mp_a, mpz_t *mp_A, mpz_t *mp_M)
{
  long i, j;

  if (mpz_cmp_ui(mp_a, 1) != 0)
    for (i = 0; i < n; i++)
      for (j = 0; j < m; j++)
	{
	  mpz_set(mp_M[i*ldm+j], mp_A[i*lda+j]);
	  mpz_mul(mp_M[i*ldm+j], mp_M[i*ldm+j], mp_a);
	}
  else
    for (i = 0; i < n; i++)
      for (j = 0; j < m; j++)
	mpz_set(mp_M[i*ldm+j], mp_A[i*lda+j]);
}