/*
* -- SuperLU MT routine (version 1.0) --
* Univ. of California Berkeley, Xerox Palo Alto Research Center,
* and Lawrence Berkeley National Lab.
* August 15, 1997
*
*/
#include <stdlib.h>
#include "pdsp_defs.h"
#include "util.h"
/*
* Generate a banded square matrix A, with dimension n and semi-bandwidth b.
*/
void
dband(int n, int b, int nonz, double **nzval, int **rowind, int **colptr)
{
int iseed[] = {1992,1993,1994,1995};
register int i, j, ub, lb, ilow, ihigh, lasta = 0;
double *a;
int *asub, *xa;
double *val;
int *row;
extern double dlaran_();
printf("A banded matrix.");
dallocateA(n, nonz, nzval, rowind, colptr); /* Allocate storage */
a = *nzval;
asub = *rowind;
xa = *colptr;
ub = lb = b;
for (i = 0; i < 4; ++i) iseed[i] = abs( iseed[i] ) % 4096;
if ( iseed[3] % 2 != 1 ) ++iseed[3];
for (j = 0; j < n; ++j) {
xa[j] = lasta;
val = &a[lasta];
row = &asub[lasta];
ilow = MAX(0, j - ub);
ihigh = MIN(n-1, j + lb);
for (i = ilow; i <= ihigh; ++i) {
val[i-ilow] = dlaran_(iseed);
row[i-ilow] = i;
}
lasta += ihigh - ilow + 1;
} /* for j ... */
xa[n] = lasta;
}
/*
* Generate a block diagonal matrix A.
*/
void
dblockdiag(int nb, /* number of blocks */
int bs, /* block size */
int nonz, double **nzval, int **rowind, int **colptr)
{
int iseed[] = {1992,1993,1994,1995};
register int i, j, b, n, lasta = 0, cstart, rstart;
double *a;
int *asub, *xa;
double *val;
int *row;
extern double dlaran_();
n = bs * nb;
printf("A block diagonal matrix: nb %d, bs %d, n %d\n", nb, bs, n);
dallocateA(n, nonz, nzval, rowind, colptr); /* Allocate storage */
a = *nzval;
asub = *rowind;
xa = *colptr;
for (i = 0; i < 4; ++i) iseed[i] = abs( iseed[i] ) % 4096;
if ( iseed[3] % 2 != 1 ) ++iseed[3];
for (b = 0; b < nb; ++b) {
cstart = b * bs; /* start of the col # of the current block */
rstart = b * bs; /* start of the row # of the current block */
for (j = cstart; j < cstart + bs; ++j) {
xa[j] = lasta;
val = &a[lasta];
row = &asub[lasta];
for (i = 0; i < bs; ++i) {
val[i] = dlaran_(iseed);
row[i] = i + rstart;
}
lasta += bs;
} /* for j ... */
} /* for b ... */
xa[n] = lasta;
}
double dlaran_(int *iseed)
{
/* -- LAPACK auxiliary routine (version 2.0) --
Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
Courant Institute, Argonne National Lab, and Rice University
February 29, 1992
Purpose
=======
DLARAN returns a random real number from a uniform (0,1)
distribution.
Arguments
=========
ISEED (input/output) INT array, dimension (4)
On entry, the seed of the random number generator; the array
elements must be between 0 and 4095, and ISEED(4) must be
odd.
On exit, the seed is updated.
Further Details
===============
This routine uses a multiplicative congruential method with modulus
2**48 and multiplier 33952834046453 (see G.S.Fishman,
'Multiplicative congruential random number generators with modulus
2**b: an exhaustive analysis for b = 32 and a partial analysis for
b = 48', Math. Comp. 189, pp 331-344, 1990).
48-bit integers are stored in 4 integer array elements with 12 bits
per element. Hence the routine is portable across machines with
integers of 32 bits or more.
=====================================================================
*/
/* Local variables */
int it1, it2, it3, it4;
--iseed;
/* multiply the seed by the multiplier modulo 2**48 */
it4 = iseed[4] * 2549;
it3 = it4 / 4096;
it4 -= it3 << 12;
it3 = it3 + iseed[3] * 2549 + iseed[4] * 2508;
it2 = it3 / 4096;
it3 -= it2 << 12;
it2 = it2 + iseed[2] * 2549 + iseed[3] * 2508 + iseed[4] * 322;
it1 = it2 / 4096;
it2 -= it1 << 12;
it1 = it1 + iseed[1] * 2549 + iseed[2] * 2508 + iseed[3] * 322 + iseed[4]
* 494;
it1 %= 4096;
/* return updated seed */
iseed[1] = it1;
iseed[2] = it2;
iseed[3] = it3;
iseed[4] = it4;
/* convert 48-bit integer to a real number in the interval (0,1) */
return ((double) it1 +
((double) it2 + ((double) it3 + (double) it4 * 2.44140625e-4) *
2.44140625e-4) * 2.44140625e-4) * 2.44140625e-4;
} /* dlaran_ */
syntax highlighted by Code2HTML, v. 0.9.1