/* mmm.c */
#include "../Pencil.h"
/*--------------------------------------------------------------------*/
/*
--------------------------------
compute Y := Y + (A + sigma*B)*X
created -- 98may02, cca
--------------------------------
*/
void
Pencil_mmm (
Pencil *pencil,
DenseMtx *Y,
DenseMtx *X
) {
int ncolX, ncolY, nrhs, nrow, nrowX, nrowY ;
/*
---------------
check the input
---------------
*/
if ( pencil == NULL || Y == NULL || X == NULL ) {
fprintf(stderr, "\n fatal error in Pencil_mmm(%p,%p,%p)"
"\n bad input\n", pencil, Y, X) ;
exit(-1) ;
}
if ( !(PENCIL_IS_REAL(pencil) || PENCIL_IS_COMPLEX(pencil)) ) {
fprintf(stderr, "\n fatal error in Pencil_mmm(%p,%p,%p)"
"\n bad type %d for pencil\n", pencil, Y, X, pencil->type) ;
exit(-1) ;
}
if ( !(DENSEMTX_IS_REAL(Y) || DENSEMTX_IS_COMPLEX(Y)) ) {
fprintf(stderr, "\n fatal error in Pencil_mmm(%p,%p,%p)"
"\n bad type %d for Y\n", pencil, Y, X, Y->type) ;
exit(-1) ;
}
if ( !(DENSEMTX_IS_REAL(X) || DENSEMTX_IS_COMPLEX(X)) ) {
fprintf(stderr, "\n fatal error in Pencil_mmm(%p,%p,%p)"
"\n bad type %d for X\n", pencil, Y, X, X->type) ;
exit(-1) ;
}
if ( PENCIL_IS_REAL(pencil) && !DENSEMTX_IS_REAL(Y) ) {
fprintf(stderr, "\n fatal error in Pencil_mmm(%p,%p,%p)"
"\n pencil is real, Y is not\n", pencil, Y, X) ;
exit(-1) ;
}
if ( PENCIL_IS_REAL(pencil) && !DENSEMTX_IS_REAL(X) ) {
fprintf(stderr, "\n fatal error in Pencil_mmm(%p,%p,%p)"
"\n pencil is real, X is not\n", pencil, Y, X) ;
exit(-1) ;
}
if ( PENCIL_IS_COMPLEX(pencil) && !DENSEMTX_IS_COMPLEX(Y) ) {
fprintf(stderr, "\n fatal error in Pencil_mmm(%p,%p,%p)"
"\n pencil is complex, Y is not\n", pencil, Y, X) ;
exit(-1) ;
}
if ( PENCIL_IS_COMPLEX(pencil) && !DENSEMTX_IS_COMPLEX(X) ) {
fprintf(stderr, "\n fatal error in Pencil_mmm(%p,%p,%p)"
"\n pencil is complex, X is not\n", pencil, Y, X) ;
exit(-1) ;
}
DenseMtx_dimensions(Y, &nrowY, &ncolY) ;
DenseMtx_dimensions(X, &nrowX, &ncolX) ;
if ( nrowY != nrowX || ncolY != ncolX ) {
fprintf(stderr, "\n fatal error in Pencil_mmm(%p,%p,%p)"
"\n nrowY %d, ncolY %d, nrowX %d, ncolX %d\n",
pencil, Y, X, nrowY, ncolY, nrowX, ncolX) ;
exit(-1) ;
}
nrow = nrowY ;
nrhs = ncolY ;
if ( pencil->inpmtxA == NULL ) {
/*
-----------------
A is the identity
-----------------
*/
if ( PENCIL_IS_REAL(pencil) ) {
double *x, *y ;
int irow, jrhs ;
x = DenseMtx_entries(X) ;
y = DenseMtx_entries(Y) ;
for ( jrhs = 0 ; jrhs < nrhs ; jrhs++ ) {
for ( irow = 0 ; irow < nrow ; irow++ ) {
y[irow] += x[irow] ;
}
x += nrow ; y += nrow ;
}
} else if ( PENCIL_IS_COMPLEX(pencil) ) {
double *x, *y ;
int irow, jrhs ;
for ( jrhs = 0 ; jrhs < nrhs ; jrhs++ ) {
for ( irow = 0 ; irow < nrow ; irow++ ) {
y[2*irow] += x[2*irow] ;
y[2*irow+1] += x[2*irow+1] ;
}
x += 2*nrow ; y += 2*nrow ;
}
}
} else {
double alpha[2] ;
/*
----------------------------------------
A is not the identity, multiply x with A
----------------------------------------
*/
alpha[0] = 1.0 ; alpha[1] = 0.0 ;
if ( PENCIL_IS_SYMMETRIC(pencil) ) {
InpMtx_sym_mmm(pencil->inpmtxA, Y, alpha, X) ;
} else if ( PENCIL_IS_HERMITIAN(pencil) ) {
InpMtx_herm_mmm(pencil->inpmtxA, Y, alpha, X) ;
} else if ( PENCIL_IS_NONSYMMETRIC(pencil) ) {
InpMtx_nonsym_mmm(pencil->inpmtxA, Y, alpha, X) ;
}
}
if ( pencil->sigma[0] != 0.0 || pencil->sigma[1] != 0.0 ) {
if ( pencil->inpmtxB != NULL ) {
/*
-----------------------------------------
B is not the identity, add sigma*B*x to y
-----------------------------------------
*/
if ( PENCIL_IS_SYMMETRIC(pencil) ) {
InpMtx_sym_mmm(pencil->inpmtxB, Y, pencil->sigma, X) ;
} else if ( PENCIL_IS_HERMITIAN(pencil) ) {
InpMtx_herm_mmm(pencil->inpmtxB, Y, pencil->sigma, X) ;
} else if ( PENCIL_IS_NONSYMMETRIC(pencil) ) {
InpMtx_nonsym_mmm(pencil->inpmtxB, Y, pencil->sigma, X) ;
}
} else {
/*
-----------------------------------
B is the identity, add sigma*x to y
-----------------------------------
*/
if ( PENCIL_IS_REAL(pencil) ) {
double sigmareal ;
double *x, *y ;
int irow, jrhs ;
x = DenseMtx_entries(X) ; y = DenseMtx_entries(Y) ;
sigmareal = pencil->sigma[0] ;
for ( jrhs = 0 ; jrhs < nrhs ; jrhs++ ) {
for ( irow = 0 ; irow < nrow ; irow++ ) {
y[irow] += sigmareal*x[irow] ;
}
x += nrow ; y += nrow ;
}
} else if ( PENCIL_IS_COMPLEX(pencil) ) {
double sigmaimag, sigmareal, ximag, xreal ;
double *x, *y ;
int irow, jrhs ;
x = DenseMtx_entries(X) ; y = DenseMtx_entries(Y) ;
sigmareal = pencil->sigma[0] ; sigmaimag = pencil->sigma[1] ;
for ( jrhs = 0 ; jrhs < nrhs ; jrhs++ ) {
for ( irow = 0 ; irow < nrow ; irow++ ) {
xreal = x[2*irow] ; ximag = x[2*irow+1] ;
y[2*irow] += sigmareal*xreal - sigmaimag*ximag ;
y[2*irow+1] += sigmareal*ximag + sigmaimag*xreal ;
}
x += 2*nrow ; y += 2*nrow ;
}
}
}
}
return ; }
/*--------------------------------------------------------------------*/
syntax highlighted by Code2HTML, v. 0.9.1