Exemple #1
0
void SubMtx_fillRowZV (int irow)
{
  double *rowvec = ZV_entries ();
  double *entries;
  int ii, ipivot, jrow, kk, m;
  int *pivotsizes;

  SubMtx_blockDiagonalInfo (&pivotsizes);

  for (jrow = ipivot = kk = 0; jrow <= irow; ipivot++)
    {
      m = pivotsizes[ipivot];
      if (jrow <= irow && irow < jrow + m)
	for (ii = jrow; ii < irow; ii++)
	  {
	    rowvec[2*ii] = entries[2*kk];
	    rowvec[2*ii+1] = entries[2*kk+1];
	  }
      jrow += m;
    }
}
Exemple #2
0
/*
   -------------------------------------------------------
   purpose -- to find matrix entry (irow,jcol) if present.

   return value --
     if entry (irow,jcol) is not present then
        *pReal and *pImag are 0.0
        return value is -1
     else entry (irow,jcol) is present then
        (*pReal,*pImag) is the matrix entry
        return value is offset into entries array 
     endif

   created -- 98may01, cca
   -------------------------------------------------------
*/
int
SubMtx_complexEntry (
   SubMtx   *mtx,
   int      irow,
   int      jcol,
   double   *pReal,
   double   *pImag
) {
/*
   ---------------
   check the input
   ---------------
*/
if (  mtx == NULL || irow < 0 || irow >= mtx->nrow || jcol < 0 
   || jcol >= mtx->ncol || pReal == NULL || pImag == NULL ) {
   fprintf(stderr, 
           "\n fatal error in SubMtx_complexEntry(%p,%d,%d,%p,%p)"
           "\n bad input\n", mtx, irow, jcol, pReal, pImag) ;
   exit(-1) ;
}
if ( ! SUBMTX_IS_COMPLEX(mtx) ) {
   fprintf(stderr, 
           "\n fatal error in SubMtx_complexEntry(%p,%d,%d,%p,%p)"
           "\n bad type %d, must be SPOOLES_COMPLEX\n", 
           mtx, irow, jcol, pReal, pImag, mtx->type) ;
   exit(-1) ;
}
*pReal = *pImag = 0 ;
switch ( mtx->mode ) {
case SUBMTX_DENSE_ROWS :
case SUBMTX_DENSE_COLUMNS : {
   double   *entries ;
   int      inc1, inc2, ncol, nrow, offset ;

   SubMtx_denseInfo(mtx, &nrow, &ncol, &inc1, &inc2, &entries) ;
   if ( irow < 0 || irow >= nrow || jcol < 0 || jcol >= ncol ) {
      return(-1) ;
   }
   offset = irow*inc1 + jcol*inc2 ;
   *pReal = entries[2*offset] ;
   *pImag = entries[2*offset+1] ;
   return(offset) ;
   } break ;
case SUBMTX_SPARSE_ROWS : {
   double   *entries ;
   int      ii, jj, nent, nrow, offset, *indices, *sizes ;

   SubMtx_sparseRowsInfo(mtx, &nrow, &nent, &sizes, &indices, &entries) ;
   if ( irow < 0 || irow >= nrow ) {
      return(-1) ;
   }
   for ( ii = offset = 0 ; ii < irow ; ii++ ) {
      offset += sizes[ii] ;
   }
   for ( ii = 0, jj = offset ; ii < sizes[irow] ; ii++, jj++ ) {
      if ( indices[jj] == jcol ) {
         *pReal = entries[2*jj] ;
         *pImag = entries[2*jj+1] ;
         return(jj) ;
      }
   }
   return(-1) ;
   } break ;
case SUBMTX_SPARSE_COLUMNS : {
   double   *entries ;
   int      ii, jj, nent, ncol, offset, *indices, *sizes ;

   SubMtx_sparseColumnsInfo(mtx, &ncol, &nent, 
                          &sizes, &indices, &entries) ;
   if ( jcol < 0 || jcol >= ncol ) {
      return(-1) ;
   }
   for ( ii = offset = 0 ; ii < jcol ; ii++ ) {
      offset += sizes[ii] ;
   }
   for ( ii = 0, jj = offset ; ii < sizes[jcol] ; ii++, jj++ ) {
      if ( indices[jj] == irow ) {
         *pReal = entries[2*jj] ;
         *pImag = entries[2*jj+1] ;
         return(jj) ;
      }
   }
   return(-1) ;
   } break ;
case SUBMTX_SPARSE_TRIPLES : {
   double   *entries ;
   int      ii, nent, *colids, *rowids ;

   SubMtx_sparseTriplesInfo(mtx, &nent, &rowids, &colids, &entries) ;
   for ( ii = 0 ; ii < nent ; ii++ ) {
      if ( irow == rowids[ii] && jcol == colids[ii] ) {
         *pReal = entries[2*ii] ;
         *pImag = entries[2*ii+1] ;
         return(ii) ;
      }
   }
   return(-1) ;
   } break ;
case SUBMTX_DENSE_SUBROWS : {
   double   *entries ;
   int      ii, joff, nent, nrow, offset, *firstlocs, *sizes ;

   SubMtx_denseSubrowsInfo(mtx, &nrow, &nent, 
                         &firstlocs, &sizes, &entries) ;
   if ( irow < 0 || irow >= nrow || sizes[irow] == 0 ) { 
      return(-1) ;
   }
   for ( ii = offset = 0 ; ii < irow ; ii++ ) {
      offset += sizes[ii] ;
   }
   if ( 0 <= (joff = jcol - firstlocs[irow]) && joff < sizes[irow] ) {
      offset += joff ;
      *pReal = entries[2*offset] ;
      *pImag = entries[2*offset+1] ;
      return(offset) ;
   }
   return(-1) ;       
   } break ;
case SUBMTX_DENSE_SUBCOLUMNS : {
   double   *entries ;
   int      ii, ioff, nent, ncol, offset, *firstlocs, *sizes ;

   SubMtx_denseSubcolumnsInfo(mtx, &ncol, &nent, 
                            &firstlocs, &sizes, &entries) ;
   if ( jcol < 0 || jcol >= ncol || sizes[jcol] == 0 ) { 
      return(-1) ;
   }
   for ( ii = offset = 0 ; ii < jcol ; ii++ ) {
      offset += sizes[ii] ;
   }
   if ( 0 <= (ioff = irow - firstlocs[jcol]) && ioff < sizes[jcol] ) {
      offset += ioff ;
      *pReal = entries[2*offset] ;
      *pImag = entries[2*offset+1] ;
      return(offset) ;
   }
   return(-1) ;       
   } break ;
case SUBMTX_DIAGONAL : {
   double   *entries ;
   int      ncol ;

   if ( irow < 0 || jcol < 0 || irow != jcol ) {
      return(-1) ;
   }
   SubMtx_diagonalInfo(mtx, &ncol, &entries) ;
   if ( irow >= ncol || jcol >= ncol ) { 
      return(-1) ;
   }
   *pReal = entries[2*irow] ;
   *pImag = entries[2*irow+1] ;
   return(irow) ;
   } break ;
case SUBMTX_BLOCK_DIAGONAL_SYM : {
   double   *entries ;
   int      ii, ipivot, jrow, kk, m, ncol, nent, size ;
   int      *pivotsizes ;

   if ( irow < 0 || jcol < 0 ) {
      return(-1) ;
   }
   if ( irow > jcol ) {
      ii   = irow ;
      irow = jcol ;
      jcol = ii   ;
   }
   SubMtx_blockDiagonalInfo(mtx, &ncol, &nent, &pivotsizes, &entries) ;
   if ( irow >= ncol || jcol >= ncol ) { 
      return(-1) ;
   }
   for ( jrow = ipivot = kk = 0 ; jrow <= irow ; ipivot++ ) {
      size = m = pivotsizes[ipivot] ;
      for ( ii = 0 ; ii < m ; ii++, jrow++ ) {
         if ( jrow == irow ) {
            if ( jcol - irow > m - ii - 1 ) {
               return(-1) ;
            } else {
               kk += jcol - irow ;
               *pReal = entries[2*kk] ;
               *pImag = entries[2*kk+1] ;
               return(kk) ;
            }
         } else {
            kk += size-- ;
         }
      }
   }
   return(kk) ;
   } break ;
case SUBMTX_BLOCK_DIAGONAL_HERM : {
   double   sign ;
   double   *entries ;
   int      ii, ipivot, jrow, kk, m, ncol, nent, size ;
   int      *pivotsizes ;

   if ( irow < 0 || jcol < 0 ) {
      return(-1) ;
   }
   if ( irow > jcol ) {
      ii   = irow ;
      irow = jcol ;
      jcol = ii   ;
      sign = -1.0 ;
   } else {
      sign = 1.0 ;
   }
   SubMtx_blockDiagonalInfo(mtx, &ncol, &nent, &pivotsizes, &entries) ;
   if ( irow >= ncol || jcol >= ncol ) { 
      return(-1) ;
   }
   for ( jrow = ipivot = kk = 0 ; jrow <= irow ; ipivot++ ) {
      size = m = pivotsizes[ipivot] ;
      for ( ii = 0 ; ii < m ; ii++, jrow++ ) {
         if ( jrow == irow ) {
            if ( jcol - irow > m - ii - 1 ) {
               return(-1) ;
            } else {
               kk += jcol - irow ;
               *pReal = entries[2*kk] ;
               *pImag = sign*entries[2*kk+1] ;
               return(kk) ;
            }
         } else {
            kk += size-- ;
         }
      }
   }
   return(kk) ;
   } break ;
default :
   fprintf(stderr, 
           "\n fatal error in SubMtx_complexEntry(%p,%d,%d,%p,%p)"
           "\n bad mode %d", mtx, irow, jcol, pReal, pImag, mtx->mode) ;
   exit(-1) ;
   break ;
}
return(-1) ; }
/*
   -------------------------------------------------------------
   compute the inertia of a symmetric matrix

   fill *pnnegative with the number of negative eigenvalues of A
   fill *pnzero     with the number of zero eigenvalues of A
   fill *pnpositive with the number of positive eigenvalues of A

   created -- 98may04, cca
   -------------------------------------------------------------
*/
void
FrontMtx_inertia (
    FrontMtx   *frontmtx,
    int        *pnnegative,
    int        *pnzero,
    int        *pnpositive
) {
    SubMtx     *mtx ;
    double   arm, areal, bimag, breal, creal, mid, val ;
    double   *entries ;
    int      ii, ipivot, irow, J, nent, nfront, nJ,
             nnegative, npositive, nzero ;
    int      *pivotsizes ;
    /*
       ---------------
       check the input
       ---------------
    */
    if (  frontmtx == NULL
            || pnnegative == NULL || pnzero == NULL || pnpositive == NULL ) {
        fprintf(stderr, "\n fatal error in FrontMtx_inertia(%p,%p,%p,%p)"
                "\n bad input\n",
                frontmtx, pnnegative, pnzero, pnpositive) ;
        fflush(stdout) ;
    }
    if ( FRONTMTX_IS_REAL(frontmtx) && ! FRONTMTX_IS_SYMMETRIC(frontmtx) ) {
        fprintf(stderr, "\n fatal error in FrontMtx_inertia(%p,%p,%p,%p)"
                "\n matrix is real and not symmetric \n",
                frontmtx, pnnegative, pnzero, pnpositive) ;
        fflush(stdout) ;
    } else if ( FRONTMTX_IS_COMPLEX(frontmtx)
                &&  ! FRONTMTX_IS_HERMITIAN(frontmtx) ) {
        fprintf(stderr, "\n fatal error in FrontMtx_inertia(%p,%p,%p,%p)"
                "\n matrix is complex and not hermitian \n",
                frontmtx, pnnegative, pnzero, pnpositive) ;
        fflush(stdout) ;
    }
    nfront = frontmtx->nfront ;
    nnegative = nzero = npositive = 0 ;
    for ( J = 0 ; J < nfront ; J++ ) {
        mtx = FrontMtx_diagMtx(frontmtx, J) ;
        if ( mtx != NULL ) {
            if ( ! FRONTMTX_IS_PIVOTING(frontmtx) ) {
                /*
                         -----------
                         no pivoting
                         -----------
                */
                SubMtx_diagonalInfo(mtx, &nJ, &entries) ;
                if ( FRONTMTX_IS_REAL(frontmtx) ) {
                    for ( ii = 0 ; ii < nJ ; ii++ ) {
                        if ( entries[ii] < 0.0 ) {
                            nnegative++ ;
                        } else if ( entries[ii] > 0.0 ) {
                            npositive++ ;
                        } else {
                            nzero++ ;
                        }
                    }
                } else if ( FRONTMTX_IS_COMPLEX(frontmtx) ) {
                    for ( ii = 0 ; ii < nJ ; ii++ ) {
                        if ( entries[2*ii] < 0.0 ) {
                            nnegative++ ;
                        } else if ( entries[2*ii] > 0.0 ) {
                            npositive++ ;
                        } else {
                            nzero++ ;
                        }
                    }
                }
            } else {
                /*
                         --------
                         pivoting
                         --------
                */
                SubMtx_blockDiagonalInfo(mtx, &nJ, &nent,
                                         &pivotsizes, &entries) ;
                if ( FRONTMTX_IS_REAL(frontmtx) ) {
                    for ( irow = ipivot = ii = 0 ; irow < nJ ; ipivot++ ) {
                        if ( pivotsizes[ipivot] == 1 ) {
                            val = entries[ii] ;
                            if ( val < 0.0 ) {
                                nnegative++ ;
                            } else if ( val > 0.0 ) {
                                npositive++ ;
                            } else {
                                nzero++ ;
                            }
                            irow++ ;
                            ii++ ;
                        } else {
                            areal = entries[ii] ;
                            breal = entries[ii+1] ;
                            creal = entries[ii+2] ;
                            mid = 0.5*(areal + creal) ;
                            arm = sqrt(0.25*(areal - creal)*(areal - creal)
                                       + breal*breal) ;
                            val = mid + arm ;
                            if ( val < 0.0 ) {
                                nnegative++ ;
                            } else if ( val > 0.0 ) {
                                npositive++ ;
                            } else {
                                nzero++ ;
                            }
                            val = mid - arm ;
                            if ( val < 0.0 ) {
                                nnegative++ ;
                            } else if ( val > 0.0 ) {
                                npositive++ ;
                            } else {
                                nzero++ ;
                            }
                            irow += 2 ;
                            ii += 3 ;
                        }
                    }
                } else if ( FRONTMTX_IS_COMPLEX(frontmtx) ) {
                    for ( irow = ipivot = ii = 0 ; irow < nJ ; ipivot++ ) {
                        if ( pivotsizes[ipivot] == 1 ) {
                            val = entries[2*ii] ;
                            if ( val < 0.0 ) {
                                nnegative++ ;
                            } else if ( val > 0.0 ) {
                                npositive++ ;
                            } else {
                                nzero++ ;
                            }
                            irow++ ;
                            ii++ ;
                        } else {
                            areal = entries[2*ii]   ;
                            breal = entries[2*ii+2] ;
                            bimag = entries[2*ii+3] ;
                            creal = entries[2*ii+4] ;
                            mid = 0.5*(areal + creal) ;
                            arm = sqrt(0.25*(areal - creal)*(areal - creal)
                                       + breal*breal + bimag*bimag) ;
                            val = mid + arm ;
                            if ( val < 0.0 ) {
                                nnegative++ ;
                            } else if ( val > 0.0 ) {
                                npositive++ ;
                            } else {
                                nzero++ ;
                            }
                            val = mid - arm ;
                            if ( val < 0.0 ) {
                                nnegative++ ;
                            } else if ( val > 0.0 ) {
                                npositive++ ;
                            } else {
                                nzero++ ;
                            }
                            irow += 2 ;
                            ii += 3 ;
                        }
                    }
                }
            }
        }
    }
    *pnnegative = nnegative ;
    *pnzero     = nzero     ;
    *pnpositive = npositive ;

    return ;
}
Exemple #4
0
/*
   -------------------------------------------------
   purpose -- to return a pointer to the location of
               matrix entry (irow,jcol) if present.

   if entry (irow,jcol) is not present then
      *ppValue is NULL
   else entry (irow,jcol) is present then
      *ppValue is the location of the matrix entry
   endif

   created -- 98may01, cca
   -------------------------------------------------
*/
void
SubMtx_locationOfRealEntry (
   SubMtx   *mtx,
   int      irow,
   int      jcol,
   double   **ppValue
) {
/*
   ---------------
   check the input
   ---------------
*/
if (  mtx == NULL || irow < 0 || irow >= mtx->nrow || jcol < 0 
   || jcol >= mtx->ncol || ppValue == NULL ) {
   fprintf(stderr, 
       "\n fatal error in SubMtx_locationOfRealEntry(%p,%d,%d,%p)"
           "\n bad input\n", mtx, irow, jcol, ppValue) ;
   exit(-1) ;
}
if ( ! SUBMTX_IS_REAL(mtx) ) {
   fprintf(stderr, 
       "\n fatal error in SubMtx_locationOfRealEntry(%p,%d,%d,%p)"
           "\n bad type %d, must be SPOOLES_REAL\n", 
           mtx, irow, jcol, ppValue, mtx->type) ;
   exit(-1) ;
}
*ppValue = NULL ;
switch ( mtx->mode ) {
case SUBMTX_DENSE_ROWS :
case SUBMTX_DENSE_COLUMNS : {
   double   *entries ;
   int      inc1, inc2, ncol, nrow, offset ;

   SubMtx_denseInfo(mtx, &nrow, &ncol, &inc1, &inc2, &entries) ;
   if ( irow >= 0 && irow < nrow && jcol >= 0 && jcol < ncol ) {
      offset = irow*inc1 + jcol*inc2 ;
      *ppValue = entries + offset ;
   }
   } break ;
case SUBMTX_SPARSE_ROWS : {
   double   *entries ;
   int      ii, jj, nent, nrow, offset, *indices, *sizes ;

   SubMtx_sparseRowsInfo(mtx, &nrow, &nent, &sizes, &indices, &entries);
   if ( irow >= 0 && irow < nrow ) {
      for ( ii = offset = 0 ; ii < irow ; ii++ ) {
         offset += sizes[ii] ;
      }
      for ( ii = 0, jj = offset ; ii < sizes[irow] ; ii++, jj++ ) {
         if ( indices[jj] == jcol ) {
            *ppValue = entries + jj ;
            break ;
         }
      }
   }
   } break ;
case SUBMTX_SPARSE_COLUMNS : {
   double   *entries ;
   int      ii, jj, nent, ncol, offset, *indices, *sizes ;

   SubMtx_sparseColumnsInfo(mtx, &ncol, &nent, 
                          &sizes, &indices, &entries) ;
   if ( jcol >= 0 && jcol < ncol ) {
      for ( ii = offset = 0 ; ii < jcol ; ii++ ) {
         offset += sizes[ii] ;
      }
      for ( ii = 0, jj = offset ; ii < sizes[jcol] ; ii++, jj++ ) {
         if ( indices[jj] == irow ) {
            *ppValue = entries + jj ;
            break ;
         }
      }
   }
   } break ;
case SUBMTX_SPARSE_TRIPLES : {
   double   *entries ;
   int      ii, nent, *colids, *rowids ;

   SubMtx_sparseTriplesInfo(mtx, &nent, &rowids, &colids, &entries) ;
   for ( ii = 0 ; ii < nent ; ii++ ) {
      if ( irow == rowids[ii] && jcol == colids[ii] ) {
         *ppValue = entries + ii ;
         break ;
      }
   }
   } break ;
case SUBMTX_DENSE_SUBROWS : {
   double   *entries ;
   int      ii, joff, nent, nrow, offset, *firstlocs, *sizes ;

   SubMtx_denseSubrowsInfo(mtx, &nrow, &nent, 
                         &firstlocs, &sizes, &entries) ;
   if ( irow >= 0 && irow < nrow && sizes[irow] != 0 ) { 
      for ( ii = offset = 0 ; ii < irow ; ii++ ) {
         offset += sizes[ii] ;
      }
      if ( 0 <= (joff = jcol - firstlocs[irow]) 
           && joff < sizes[irow] ) {
         offset += joff ;
         *ppValue = entries + offset ;
         break ;
      }
   }
   } break ;
case SUBMTX_DENSE_SUBCOLUMNS : {
   double   *entries ;
   int      ii, ioff, nent, ncol, offset, *firstlocs, *sizes ;

   SubMtx_denseSubcolumnsInfo(mtx, &ncol, &nent, 
                            &firstlocs, &sizes, &entries) ;
   if ( jcol >= 0 && jcol < ncol && sizes[jcol] != 0 ) { 
      for ( ii = offset = 0 ; ii < jcol ; ii++ ) {
         offset += sizes[jcol] ;
      }
      if (  0 <= (ioff = irow - firstlocs[jcol]) 
         && ioff < sizes[jcol] ) {
         offset += ioff ;
         *ppValue = entries + offset ;
         break ;
      }
   }
   } break ;
case SUBMTX_DIAGONAL : {
   double   *entries ;
   int      ncol ;

   if ( irow >= 0 && jcol >= 0 && irow == jcol ) {
      SubMtx_diagonalInfo(mtx, &ncol, &entries) ;
      if ( irow < ncol && jcol < ncol ) { 
         *ppValue = entries + irow ;
      }
   }
   } break ;
case SUBMTX_BLOCK_DIAGONAL_SYM :
case SUBMTX_BLOCK_DIAGONAL_HERM : {
   double   *entries ;
   int      ii, ipivot, jrow, kk, m, ncol, nent, size ;
   int      *pivotsizes ;

   if ( irow >= 0 && jcol >= 0 ) {
      SubMtx_blockDiagonalInfo(mtx, &ncol, &nent, 
                               &pivotsizes, &entries) ;
      if ( irow < ncol && jcol < ncol ) { 
         for ( jrow = ipivot = kk = 0 ; jrow <= irow ; ipivot++ ) {
            size = m = pivotsizes[ipivot] ;
            for ( ii = 0 ; ii < m ; ii++, jrow++ ) {
               if ( jrow == irow ) {
                  if ( jrow - irow > m - ii ) {
                     kk = -1 ;
                  } else {
                     kk += jrow - irow ;
                  }
               } else {
                  kk += size-- ;
               }
            }
         }
         if ( kk != -1 ) {
            *ppValue = entries + kk ;
         }
      }
   }
   } break ;
default :
   fprintf(stderr, 
       "\n fatal error in SubMtx_locationOfRealEntry(%p,%d,%d,%p)"
       "\n bad mode %d", mtx, irow, jcol, ppValue, mtx->mode) ;
   exit(-1) ;
   break ;
}
return ; }