示例#1
0
void CLinkMatrix::completePivotInformation()
{
  // We need to convert the pivot vector into a swap vector.
  mPivotInverse.resize(mRowPivots.size());

  size_t * pCurrentIndex = mPivotInverse.array();
  size_t * pEnd  = pCurrentIndex + mRowPivots.size();

  for (size_t i = 0; pCurrentIndex != pEnd; ++pCurrentIndex, ++i)
    {
      *pCurrentIndex = i;
    }

  CVector< size_t > CurrentColumn(mPivotInverse);
  size_t * pCurrentColumn = CurrentColumn.array();

  mSwapVector.resize(mRowPivots.size());
  C_INT * pJPVT = mSwapVector.array();
  pCurrentIndex = mPivotInverse.array();
  const size_t * pPivot = mRowPivots.array();

  for (; pCurrentIndex != pEnd; ++pPivot, ++pJPVT, ++pCurrentIndex, ++pCurrentColumn)
    {
      // Swap Index
      size_t * pToIndex = & mPivotInverse[*pPivot];
      size_t * pFromIndex = & mPivotInverse[*pCurrentColumn];

      // Swap Column
      size_t * pToColumn = & CurrentColumn[*pToIndex];
      size_t * pFromColumn = pCurrentColumn;

      // Swap
      *pJPVT =  *pToIndex + 1;

      size_t tmp = *pFromIndex;
      *pFromIndex = *pToIndex;
      *pToIndex = tmp;

      tmp = *pFromColumn;
      *pFromColumn = *pToColumn;
      *pToColumn = tmp;
    }
}
示例#2
0
bool CLinkMatrix::build(const CMatrix< C_FLOAT64 > & matrix)
{
  bool success = true;

  CMatrix< C_FLOAT64 > M(matrix);

  C_INT NumCols = (C_INT) M.numCols();
  C_INT NumRows = (C_INT) M.numRows();
  C_INT LDA = std::max<C_INT>(1, NumCols);

  CVector< C_INT > JPVT(NumRows);
  JPVT = 0;

  C_INT32 Dim = std::min(NumCols, NumRows);

  if (Dim == 0)
    {
      C_INT32 i;
      mRowPivots.resize(NumRows);

      for (i = 0; i < NumRows; i++)
        mRowPivots[i] = i;

      resize(NumRows, 0);

      return success;
    }

  CVector< C_FLOAT64 > TAU(Dim);

  CVector< C_FLOAT64 > WORK(1);
  C_INT LWORK = -1;
  C_INT INFO;

  // QR factorization of the stoichiometry matrix
  /*
   *  -- LAPACK routine (version 3.0) --
   *     Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
   *     Courant Institute, Argonne National Lab, and Rice University
   *     June 30, 1999
   *
   *  Purpose
   *  =======
   *
   *  DGEQP3 computes a QR factorization with column pivoting of a
   *  matrix A:  A*P = Q*R  using Level 3 BLAS.
   *
   *  Arguments
   *  =========
   *
   *  M       (input) INTEGER
   *          The number of rows of the matrix A. M >= 0.
   *
   *  N       (input) INTEGER
   *          The number of columns of the matrix A.  N >= 0.
   *
   *  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
   *          On entry, the M-by-N matrix A.
   *          On exit, the upper triangle of the array contains the
   *          min(M,N)-by-N upper trapezoidal matrix R; the elements below
   *          the diagonal, together with the array TAU, represent the
   *          orthogonal matrix Q as a product of min(M,N) elementary
   *          reflectors.
   *
   *  LDA     (input) INTEGER
   *          The leading dimension of the array A. LDA >= max(1,M).
   *
   *  JPVT    (input/output) INTEGER array, dimension (N)
   *          On entry, if JPVT(J).ne.0, the J-th column of A is permuted
   *          to the front of A*P (a leading column); if JPVT(J)=0,
   *          the J-th column of A is a free column.
   *          On exit, if JPVT(J)=K, then the J-th column of A*P was the
   *          the K-th column of A.
   *
   *  TAU     (output) DOUBLE PRECISION array, dimension (min(M,N))
   *          The scalar factors of the elementary reflectors.
   *
   *  WORK    (workspace/output) DOUBLE PRECISION array, dimension (LWORK)
   *          On exit, if INFO=0, WORK(1) returns the optimal LWORK.
   *
   *  LWORK   (input) INTEGER
   *          The dimension of the array WORK. LWORK >= 3*N+1.
   *          For optimal performance LWORK >= 2*N+(N+1)*NB, where NB
   *          is the optimal blocksize.
   *
   *          If LWORK = -1, then a workspace query is assumed; the routine
   *          only calculates the optimal size of the WORK array, returns
   *          this value as the first entry of the WORK array, and no error
   *          message related to LWORK is issued by XERBLA.
   *
   *  INFO    (output) INTEGER
   *          = 0: successful exit.
   *          < 0: if INFO = -i, the i-th argument had an illegal value.
   *
   *  Further Details
   *  ===============
   *
   *  The matrix Q is represented as a product of elementary reflectors
   *
   *     Q = H(1) H(2) . . . H(k), where k = min(m,n).
   *
   *  Each H(i) has the form
   *
   *     H(i) = I - tau * v * v'
   *
   *  where tau is a real/complex scalar, and v is a real/complex vector
   *  with v(1:i-1) = 0 and v(i) = 1; v(i+1:m) is stored on exit in
   *  A(i+1:m,i), and tau in TAU(i).
   *
   *  Based on contributions by
   *    G. Quintana-Orti, Depto. de Informatica, Universidad Jaime I, Spain
   *    X. Sun, Computer Science Dept., Duke University, USA
   *
   */

  dgeqp3_(&NumCols, &NumRows, M.array(), &LDA,
          JPVT.array(), TAU.array(), WORK.array(), &LWORK, &INFO);

  if (INFO < 0) fatalError();

  LWORK = (C_INT) WORK[0];
  WORK.resize(LWORK);

  dgeqp3_(&NumCols, &NumRows, M.array(), &LDA,
          JPVT.array(), TAU.array(), WORK.array(), &LWORK, &INFO);

  if (INFO < 0) fatalError();

  C_INT32 i;
  mRowPivots.resize(NumRows);

  for (i = 0; i < NumRows; i++)
    mRowPivots[i] = JPVT[i] - 1;

  C_INT independent = 0;

  while (independent < Dim &&
         fabs(M(independent, independent)) > 100.0 * std::numeric_limits< C_FLOAT64 >::epsilon()) independent++;

  mIndependent = independent;

  // Resize mL
  resize(NumRows - independent, independent);

  if (NumRows == independent || independent == 0)
    {
      return success;
    }

  /* to take care of differences between fortran's and c's memory  access,
       we need to take the transpose, i.e.,the upper triangular */
  char cL = 'U';
  char cU = 'N'; /* values in the diagonal of R */

  // Calculate Row Echelon form of R.
  // First invert R_1,1
  /* int dtrtri_(char *uplo,
   *             char *diag,
   *             integer *n,
   *             doublereal * A,
   *             integer *lda,
   *             integer *info);
   *  -- LAPACK routine (version 3.0) --
   *     Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
   *     Courant Institute, Argonne National Lab, and Rice University
   *     March 31, 1993
   *
   *  Purpose
   *  =======
   *
   *  DTRTRI computes the inverse of a real upper or lower triangular
   *  matrix A.
   *
   *  This is the Level 3 BLAS version of the algorithm.
   *
   *  Arguments
   *  =========
   *
   *  uplo    (input) CHARACTER*1
   *          = 'U':  A is upper triangular;
   *          = 'L':  A is lower triangular.
   *
   *  diag    (input) CHARACTER*1
   *          = 'N':  A is non-unit triangular;
   *          = 'U':  A is unit triangular.
   *
   *  n       (input) INTEGER
   *          The order of the matrix A.  n >= 0.
   *
   *  A       (input/output) DOUBLE PRECISION array, dimension (lda,n)
   *          On entry, the triangular matrix A.  If uplo = 'U', the
   *          leading n-by-n upper triangular part of the array A contains
   *          the upper triangular matrix, and the strictly lower
   *          triangular part of A is not referenced.  If uplo = 'L', the
   *          leading n-by-n lower triangular part of the array A contains
   *          the lower triangular matrix, and the strictly upper
   *          triangular part of A is not referenced.  If diag = 'U', the
   *          diagonal elements of A are also not referenced and are
   *          assumed to be 1.
   *          On exit, the (triangular) inverse of the original matrix, in
   *          the same storage format.
   *
   *  lda     (input) INTEGER
   *          The leading dimension of the array A.  lda >= max(1,n).
   *
   *  info    (output) INTEGER
   *          = 0: successful exit
   *          < 0: if info = -i, the i-th argument had an illegal value
   *          > 0: if info = i, A(i,i) is exactly zero.  The triangular
   *               matrix is singular and its inverse can not be computed.
   */
  dtrtri_(&cL, &cU, &independent, M.array(), &LDA, &INFO);

  if (INFO < 0) fatalError();

  C_INT32 j, k;

  // Compute Link_0 = inverse(R_1,1) * R_1,2
  // :TODO: Use dgemm
  C_FLOAT64 * pTmp1 = array();
  C_FLOAT64 * pTmp2;
  C_FLOAT64 * pTmp3;

  for (j = 0; j < NumRows - independent; j++)
    for (i = 0; i < independent; i++, pTmp1++)
      {
        pTmp2 = &M(j + independent, i);
        pTmp3 = &M(i, i);

        // assert(&mL(j, i) == pTmp3);
        *pTmp1 = 0.0;

        for (k = i; k < independent; k++, pTmp2++, pTmp3 += NumCols)
          {
            // assert(&M(j + independent, k) == pTmp2);
            // assert(&M(k, i) == pTmp3);

            *pTmp1 += *pTmp3 * *pTmp2;
          }

        if (fabs(*pTmp1) < 100.0 * std::numeric_limits< C_FLOAT64 >::epsilon()) *pTmp1 = 0.0;
      }

  // We need to convert the pivot vector into a swap vector.

  mPivotInverse.resize(mRowPivots.size());

  size_t * pCurrentIndex = mPivotInverse.array();
  size_t * pEnd  = pCurrentIndex + mRowPivots.size();

  for (size_t i = 0; pCurrentIndex != pEnd; ++pCurrentIndex, ++i)
    {
      *pCurrentIndex = i;
    }

  CVector< size_t > CurrentColumn(mPivotInverse);
  size_t * pCurrentColumn = CurrentColumn.array();

  mSwapVector.resize(mRowPivots.size());
  C_INT * pJPVT = mSwapVector.array();
  pCurrentIndex = mPivotInverse.array();
  const size_t * pPivot = mRowPivots.array();

  for (; pCurrentIndex != pEnd; ++pPivot, ++pJPVT, ++pCurrentIndex, ++pCurrentColumn)
    {
      // Swap Index
      size_t * pToIndex = & mPivotInverse[*pPivot];
      size_t * pFromIndex = & mPivotInverse[*pCurrentColumn];

      // Swap Column
      size_t * pToColumn = & CurrentColumn[*pToIndex];
      size_t * pFromColumn = pCurrentColumn;

      // Swap
      *pJPVT =  *pToIndex + 1;

      size_t tmp = *pFromIndex;
      *pFromIndex = *pToIndex;
      *pToIndex = tmp;

      tmp = *pFromColumn;
      *pFromColumn = *pToColumn;
      *pToColumn = tmp;
    }

  return success;
}
示例#3
0
QString toSQLParse::indentStatement(statement &stat, int level/*SQLITEMAN, toSyntaxAnalyzer &syntax*/)
{
	QString ret;

	switch (stat.Type)
	{
	default:
		{
			QMessageBox::warning(QApplication::activeWindow(), "Sqliteman",
								 "toSQLparse: Internal error in toSQLParse, should never get here");
		}
	case statement::Block:
	{
		ret = IndentComment(level, 0, stat.Comment, false);
		int exc = 0;
		for (std::list<toSQLParse::statement>::iterator i = stat.subTokens().begin();
				i != stat.subTokens().end();
				i++)
		{
			int add
			= 0;
			std::list<toSQLParse::statement>::iterator j = i;
			j++;
			if (i != stat.subTokens().begin() &&
					j != stat.subTokens().end())
				add
				= Settings.IndentLevel;
			else
				exc = 0;

			QString t;
			if ((*i).subTokens().begin() != (*i).subTokens().
					end())
				t = (*(*i).subTokens().begin()).String.toUpper();
			if (t == ("BEGIN") || t == ("WHEN") || t == ("ELSE") || t == ("ELSIF"))
				add
				= 0;
			if ((*i).Type == statement::List)
				ret += indentString(level + add
									+ exc);
			ret += indentStatement(*i, level + add
								   + exc/*SQLITEMAN , syntax*/);
			if ((*i).Type == statement::List)
			{
				int i;
				for (i = ret.length() - 1;i >= 0 && ret[i].isSpace();i--)
					;
				ret = ret.mid(0, std::max(i + 1, 0));
				ret += ("\n");
				ret += indentString(level + exc);
			}
			if (t == ("EXCEPTION"))
				exc = Settings.IndentLevel * 2;
		}
		if (Settings.EndBlockNewline && level != 0)
			ret += ("\n");
	}
	break;
	case statement::List:
	case statement::Statement:
		int maxlev = 0;
		int maxlevorig = 0;
		bool useMaxLev = false;
		bool any = true;
		int current;
		bool first;
		bool noKeyBreak = false;
		bool lineList = false;
		QString comment;
		if (stat.Type == statement::Statement)
		{
			ret = IndentComment(level, 0, stat.Comment, false);
			useMaxLev = true;
			first = true;
			current = 0;
		}
		else
		{
			for (std::list<toSQLParse::statement>::iterator i = stat.subTokens().begin();
					i != stat.subTokens().end();)
			{
				if ((*i).Type != statement::Keyword)
					noKeyBreak = true;
				else
					useMaxLev = true;
				break;
			}
			current = level;
			first = true;
		}
		if (useMaxLev)
		{
			int count = 0;
			for (std::list<toSQLParse::statement>::iterator i = stat.subTokens().begin();
					i != stat.subTokens().end();
					i++)
			{
				if (any)
				{
					QString upp = (*i).String.toUpper();
					if ((*i).Type == statement::Keyword &&
							upp != ("LOOP") &&
							upp != ("DO") &&
							upp != ("THEN") &&
							upp != ("AS") &&
							upp != ("IS"))
					{
						if (int((*i).String.length()) + 1 > maxlev)
							maxlev = (*i).String.length() + 1;
						count++;
						any = false;
					}
					else if (i == stat.subTokens().begin())
					{
						noKeyBreak = true;
						break;
					}
				}
				else if ((*i).Type == statement::Token)
					any = true;
				if ((*i).Type == statement::List)
					count++;
			}
			if (count <= 1 && maxlev > 0)
				maxlev--;
			maxlevorig = maxlev;
			any = true;
		}

		for (std::list<toSQLParse::statement>::iterator i = stat.subTokens().begin();
				i != stat.subTokens().end();
				i++)
		{
			comment = AddComment(comment, (*i).Comment);
			QString upp = (*i).String.toUpper();

#ifdef TOPARSE_DEBUG
			printf("%s\n", (const char*)(*i).String.toUtf8());
#endif

			if ((*i).Type == statement::List)
			{
				if (Settings.OperatorSpace)
				{
					ret += (" ");
					current++;
				}
				QString t = indentStatement(*i, current/*SQLITEMAN, syntax*/);
				if (t.indexOf(("\n")) >= 0)
					current = CurrentColumn(t);
				else
					current += CurrentColumn(t);
				ret += t;
				any = true;
			}
			else if ((*i).String == (","))
			{
				if (Settings.CommaBefore)
				{
					ret += IndentComment(Settings.CommentColumn, current, comment, true);
					comment = QString::null;
					ret += indentString(level + maxlev - (Settings.OperatorSpace ? 2 : 1));
					ret += (",");
				}
				else
				{
					ret += (",");
					ret += IndentComment(Settings.CommentColumn, current + 1, comment, true);
					comment = QString::null;
					ret += indentString(level + maxlev);
				}
				current = level + maxlev;
				any = false;
				lineList = true;
			}
			else if ((*i).Type == statement::Keyword && (upp == ("LOOP") ||
					 upp == ("DO") ||
					 upp == ("THEN") ||
					 upp == ("AS") ||
					 upp == ("IS")))
			{
				if (!Settings.BlockOpenLine)
				{
					if (ret.length() > 0)
					{
						if (toIsIdent(ret.at(ret.length() - 1)) ||
								ret.at(ret.length() - 1) == QUOTE_CHARACTER /*SQLITEMAN syntax.quoteCharacter()*/ ||
								ret.at(ret.length() - 1) == '\'' ||
								Settings.OperatorSpace)
						{
							ret += (" ");
							current++;
						}
					}
					ret += Settings.KeywordUpper ? (*i).String.toUpper() : (*i).String;
					current += (*i).String.length();
				}
				else
				{
					ret += IndentComment(Settings.CommentColumn, current, comment, true);
					comment = QString::null;
					ret += indentString(level);
					ret += Settings.KeywordUpper ? (*i).String.toUpper() : (*i).String;
					current = level + (*i).String.length();
				}
				any = false;
			}
			else if (any && (*i).Type == statement::Keyword && !noKeyBreak)
			{
				if (first)
					first = false;
				else
				{
					ret += IndentComment(Settings.CommentColumn, current, comment, true);
					current = 0;
					comment = QString::null;
				}
				if (current == 0)
				{
					ret += indentString(level);
					current = level;
				}
				else
					while (current < level)
					{
						ret += (" ");
						current++;
					}
				maxlev = maxlevorig;
				QString word = Settings.KeywordUpper ? (*i).String.toUpper() : (*i).String;
				if (ret.length())
				{
					ret += QString("%1").arg(word,
											 Settings.RightSeparator ? maxlev - 1 : 1 - maxlev);
					current = level + std::max(int(word.length()), maxlev - 1);
				}
				else
				{
					ret += word;
					current = level + word.length();
				}
				any = false;
				lineList = false;
			}
			else
			{
				QString t = (*i).String;
				bool add
				= false;
				if ((*i).Type == statement::Keyword)
				{
					if (!lineList &&
							!any &&
							(*i).Type == statement::Keyword &&
							!noKeyBreak &&
							upp == ("BY"))
						add
						= true;
				}
				else
				{
					any = true;
				}
				if (isKeyword(upp) /*SQLITEMAN syntax.reservedWord(upp)*/ && Settings.KeywordUpper)
					t = upp;

				int extra;
				if (first)
				{
					first = false;
					any = false;
					extra = 0;
				}
				else
				{
					if (ret.length() > 0 &&
							!ret.at(ret.length() - 1).isSpace() &&
							(Settings.OperatorSpace || ((toIsIdent(t[0]) ||
														 t[0] == QUOTE_CHARACTER /*SQLITEMAN syntax.quoteCharacter()*/ || t[0] == '\'') &&
														(toIsIdent(ret.at(ret.length() - 1)) ||
														 ret.at(ret.length() - 1) == QUOTE_CHARACTER /*SQLITEMAN syntax.quoteCharacter()*/ ||
														 ret.at(ret.length() - 1) == '\'')
													   )
							)
					   )
					{
						if (t != (";") &&
								t != (".") &&
								ret.at(ret.length() - 1) != '.' &&
								current != 0)
						{
							current++;
							ret += (" ");
						}
					}
					else if (ret.length() > 2 && ret.at(ret.length() - 2) == '*' && ret.at(ret.length() - 1) == '/')
					{
						current++;
						ret += (" ");
					}
					extra = maxlev;
				}
				if (current < level + maxlev)
				{
					if (current == 0)
						ret += indentString(level + maxlev);
					else
						while (current < level + maxlev)
						{
							ret += (" ");
							current++;
						}
					current = level + maxlev;
				}
				ret += t;
				current += t.length();
				if (t.startsWith(("<<")))
				{
					ret += ("\n");
					current = 0;
				}

				if (add
				   )
					maxlev += t.length() + 1;
			}
		}
		if (stat.Type == statement::Statement)
		{
			ret += IndentComment(Settings.CommentColumn, current, comment, true);
			comment = QString::null;
			if (Settings.EndBlockNewline &&
					level == 0 &&
					stat.subTokens().begin() != stat.subTokens().end() &&
					(*stat.subTokens().rbegin()).String == (";"))
				ret += ("\n");
		}
		else if (!comment.isEmpty())
		{
			ret += IndentComment(Settings.CommentColumn, current, comment, true);
			comment = QString::null;
			ret += indentString(level - (Settings.OperatorSpace ? 2 : 1));
		}
		break;
	}
	return ret;
}