示例#1
0
SymSchurDecomp::SymSchurDecomp(const GeneralMatrix& mata)
	: lambda(mata.numRows()), q(mata.numRows())
{
	// check mata is square
	if (mata.numRows() != mata.numCols())
		throw SYLV_MES_EXCEPTION("Matrix is not square in SymSchurDecomp constructor");

	// prepare for dsyevr
	const char* jobz = "V";
	const char* range = "A";
	const char* uplo = "U";
	lapack_int n = mata.numRows();
	GeneralMatrix tmpa(mata);
	double* a = tmpa.base();
	lapack_int lda = tmpa.getLD();
	double dum;
	double* vl = &dum;
	double* vu = &dum;
	lapack_int idum;
	lapack_int* il = &idum;
	lapack_int* iu = &idum;
	double abstol = 0.0;
	lapack_int m = n;
	double* w = lambda.base();
	double* z = q.base();
	lapack_int ldz = q.getLD();
	lapack_int* isuppz = new lapack_int[2*std::max(1,(int) m)];
	double tmpwork;
	lapack_int lwork = -1;
	lapack_int tmpiwork;
	lapack_int liwork = -1;
	lapack_int info;

	// query for lwork and liwork
	dsyevr(jobz, range, uplo, &n, a, &lda, vl, vu, il, iu, &abstol,
				  &m, w, z, &ldz, isuppz, &tmpwork, &lwork, &tmpiwork, &liwork, &info);
	lwork = (int)tmpwork;
	liwork = tmpiwork;
	// allocate work arrays
	double* work = new double[lwork];
	lapack_int* iwork = new lapack_int[liwork];
	
	// do the calculation
	dsyevr(jobz, range, uplo, &n, a, &lda, vl, vu, il, iu, &abstol,
				  &m, w, z, &ldz, isuppz, work, &lwork, iwork, &liwork, &info);

	if (info < 0)
		throw SYLV_MES_EXCEPTION("Internal error in SymSchurDecomp constructor");
	if (info > 0)
		throw SYLV_MES_EXCEPTION("Internal LAPACK error in DSYEVR");

	delete [] work;
	delete [] iwork;
	delete [] isuppz;
}
示例#2
0
void SymSchurDecomp::getFactor(GeneralMatrix& f) const
{
	if (f.numRows() != q.numRows())
		throw SYLV_MES_EXCEPTION("Wrong dimension of factor matrix in SymSchurDecomp::getFactor");
	if (f.numRows() != f.numCols())
		throw SYLV_MES_EXCEPTION("Factor matrix is not square in SymSchurDecomp::getFactor");
	if (! isPositiveSemidefinite())
		throw SYLV_MES_EXCEPTION("Symmetric decomposition not positive semidefinite in SymSchurDecomp::getFactor");

	f = q;
	for (int i = 0; i < f.numCols(); i++) {
		Vector fi(f, i);
		fi.mult(std::sqrt(lambda[i]));
	}
}
示例#3
0
void SylvMatrix::multLeft(int zero_cols, const GeneralMatrix& a, const GeneralMatrix& b)
{
	int off = a.numRows() - a.numCols();
	if (off < 0 || a.numRows() != rows || off != zero_cols ||
		rows != b.numRows() || cols != b.numCols()) {
		throw SYLV_MES_EXCEPTION("Wrong matrix dimensions for multLeft.");
	}
	// here we cannot call SylvMatrix::gemm since it would require
	// another copy of (usually big) b (we are not able to do inplace
	// submatrix of const GeneralMatrix)
	if (a.getLD() > 0 && ld > 0) {
		blas_int mm = a.numRows();
		blas_int nn = cols;
		blas_int kk = a.numCols();
		double alpha = 1.0;
		blas_int lda = a.getLD();
		blas_int ldb = ld;
		double beta = 0.0;
		blas_int ldc = ld;
		dgemm("N", "N", &mm, &nn, &kk, &alpha, a.getData().base(), &lda,
				   b.getData().base()+off, &ldb, &beta, data.base(), &ldc);
	}
}
示例#4
0
void SqSylvMatrix::multInvLeft2(GeneralMatrix& a, GeneralMatrix& b,
								double& rcond1, double& rcondinf) const
{
	if (rows != a.numRows() || rows != b.numRows()) {
		throw SYLV_MES_EXCEPTION("Wrong dimensions for multInvLeft2.");
	}
	// PLU factorization
	Vector inv(data);
	lapack_int * const ipiv = new lapack_int[rows];
	lapack_int info;
	lapack_int rows2 = rows;
	dgetrf(&rows2, &rows2, inv.base(), &rows2, ipiv, &info);
	// solve a
	lapack_int acols = a.numCols();
	double* abase = a.base();
	dgetrs("N", &rows2, &acols, inv.base(), &rows2, ipiv,
				  abase, &rows2, &info);
	// solve b
	lapack_int bcols = b.numCols();
	double* bbase = b.base();
	dgetrs("N", &rows2, &bcols, inv.base(), &rows2, ipiv,
				  bbase, &rows2, &info);
	delete [] ipiv;

	// condition numbers
	double* const work = new double[4*rows];
	lapack_int* const iwork = new lapack_int[rows];
	double norm1 = getNorm1();
	dgecon("1", &rows2, inv.base(), &rows2, &norm1, &rcond1, 
				  work, iwork, &info);
	double norminf = getNormInf();
	dgecon("I", &rows2, inv.base(), &rows2, &norminf, &rcondinf, 
				  work, iwork, &info);
	delete [] iwork;
	delete [] work;
}
示例#5
0
Vector::Vector(GeneralMatrix& m, int col)
	: len(m.numRows()), s(1), data(&(m.get(0, col))), destroy(false)
{
}
示例#6
0
SchurDecompZero::SchurDecompZero(const GeneralMatrix& m)
	: SchurDecomp(SqSylvMatrix(m, m.numRows()-m.numCols(), 0, m.numCols())),
	  ru(m, 0, 0, m.numRows()-m.numCols(), m.numCols())
{
	ru.multRight(getQ());
}