|
kusano |
7d535a |
|
|
kusano |
7d535a |
/*! @file ddiagonal.c
|
|
kusano |
7d535a |
* \brief Auxiliary routines to work with diagonal elements
|
|
kusano |
7d535a |
*
|
|
kusano |
7d535a |
*
|
|
kusano |
7d535a |
* -- SuperLU routine (version 4.0) --
|
|
kusano |
7d535a |
* Lawrence Berkeley National Laboratory
|
|
kusano |
7d535a |
* June 30, 2009
|
|
kusano |
7d535a |
*
|
|
kusano |
7d535a |
*/
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
#include "slu_ddefs.h"
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
int dfill_diag(int n, NCformat *Astore)
|
|
kusano |
7d535a |
/* fill explicit zeros on the diagonal entries, so that the matrix is not
|
|
kusano |
7d535a |
structurally singular. */
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
double *nzval = (double *)Astore->nzval;
|
|
kusano |
7d535a |
int *rowind = Astore->rowind;
|
|
kusano |
7d535a |
int *colptr = Astore->colptr;
|
|
kusano |
7d535a |
int nnz = colptr[n];
|
|
kusano |
7d535a |
int fill = 0;
|
|
kusano |
7d535a |
double *nzval_new;
|
|
kusano |
7d535a |
double zero = 0.0;
|
|
kusano |
7d535a |
int *rowind_new;
|
|
kusano |
7d535a |
int i, j, diag;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
for (i = 0; i < n; i++)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
diag = -1;
|
|
kusano |
7d535a |
for (j = colptr[i]; j < colptr[i + 1]; j++)
|
|
kusano |
7d535a |
if (rowind[j] == i) diag = j;
|
|
kusano |
7d535a |
if (diag < 0) fill++;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (fill)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
nzval_new = doubleMalloc(nnz + fill);
|
|
kusano |
7d535a |
rowind_new = intMalloc(nnz + fill);
|
|
kusano |
7d535a |
fill = 0;
|
|
kusano |
7d535a |
for (i = 0; i < n; i++)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
diag = -1;
|
|
kusano |
7d535a |
for (j = colptr[i] - fill; j < colptr[i + 1]; j++)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
if ((rowind_new[j + fill] = rowind[j]) == i) diag = j;
|
|
kusano |
7d535a |
nzval_new[j + fill] = nzval[j];
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (diag < 0)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
rowind_new[colptr[i + 1] + fill] = i;
|
|
kusano |
7d535a |
nzval_new[colptr[i + 1] + fill] = zero;
|
|
kusano |
7d535a |
fill++;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
colptr[i + 1] += fill;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
Astore->nzval = nzval_new;
|
|
kusano |
7d535a |
Astore->rowind = rowind_new;
|
|
kusano |
7d535a |
SUPERLU_FREE(nzval);
|
|
kusano |
7d535a |
SUPERLU_FREE(rowind);
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
Astore->nnz += fill;
|
|
kusano |
7d535a |
return fill;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
int ddominate(int n, NCformat *Astore)
|
|
kusano |
7d535a |
/* make the matrix diagonally dominant */
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
double *nzval = (double *)Astore->nzval;
|
|
kusano |
7d535a |
int *rowind = Astore->rowind;
|
|
kusano |
7d535a |
int *colptr = Astore->colptr;
|
|
kusano |
7d535a |
int nnz = colptr[n];
|
|
kusano |
7d535a |
int fill = 0;
|
|
kusano |
7d535a |
double *nzval_new;
|
|
kusano |
7d535a |
int *rowind_new;
|
|
kusano |
7d535a |
int i, j, diag;
|
|
kusano |
7d535a |
double s;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
for (i = 0; i < n; i++)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
diag = -1;
|
|
kusano |
7d535a |
for (j = colptr[i]; j < colptr[i + 1]; j++)
|
|
kusano |
7d535a |
if (rowind[j] == i) diag = j;
|
|
kusano |
7d535a |
if (diag < 0) fill++;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (fill)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
nzval_new = doubleMalloc(nnz + fill);
|
|
kusano |
7d535a |
rowind_new = intMalloc(nnz+ fill);
|
|
kusano |
7d535a |
fill = 0;
|
|
kusano |
7d535a |
for (i = 0; i < n; i++)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
s = 1e-6;
|
|
kusano |
7d535a |
diag = -1;
|
|
kusano |
7d535a |
for (j = colptr[i] - fill; j < colptr[i + 1]; j++)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
if ((rowind_new[j + fill] = rowind[j]) == i) diag = j;
|
|
kusano |
7d535a |
s += fabs(nzval_new[j + fill] = nzval[j]);
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if (diag >= 0) {
|
|
kusano |
7d535a |
nzval_new[diag+fill] = s * 3.0;
|
|
kusano |
7d535a |
} else {
|
|
kusano |
7d535a |
rowind_new[colptr[i + 1] + fill] = i;
|
|
kusano |
7d535a |
nzval_new[colptr[i + 1] + fill] = s * 3.0;
|
|
kusano |
7d535a |
fill++;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
colptr[i + 1] += fill;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
Astore->nzval = nzval_new;
|
|
kusano |
7d535a |
Astore->rowind = rowind_new;
|
|
kusano |
7d535a |
SUPERLU_FREE(nzval);
|
|
kusano |
7d535a |
SUPERLU_FREE(rowind);
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
else
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
for (i = 0; i < n; i++)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
s = 1e-6;
|
|
kusano |
7d535a |
diag = -1;
|
|
kusano |
7d535a |
for (j = colptr[i]; j < colptr[i + 1]; j++)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
if (rowind[j] == i) diag = j;
|
|
kusano |
7d535a |
s += fabs(nzval[j]);
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
nzval[diag] = s * 3.0;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
Astore->nnz += fill;
|
|
kusano |
7d535a |
return fill;
|
|
kusano |
7d535a |
}
|