Esempio n. 1
0
bool C4Scoreboard::SortBy(int32_t iColKey, bool fReverse)
{
	// get sort col
	int32_t iCol = GetColByKey(iColKey);
	if (iCol<0) return false;
	// sort
	int32_t iSortDir = fReverse ? -1 : +1;
	int32_t iSortBegin=1, iSortEnd=iRows-1;
	while (iSortBegin < iSortEnd)
	{
		int32_t iNewBorder = iSortBegin; int32_t i;
		for (i = iSortBegin; i < iSortEnd; ++i)
			if (GetCell(iCol, i)->iVal * iSortDir > GetCell(iCol, i+1)->iVal * iSortDir)
			{
				SwapRows(i, i+1);
				iNewBorder = i;
			}
		iSortEnd = iNewBorder;
		for (i = iSortEnd; i > iSortBegin; --i)
			if (GetCell(iCol, i-1)->iVal * iSortDir > GetCell(iCol, i)->iVal * iSortDir)
			{
				SwapRows(i-1, i);
				iNewBorder = i;
			}
		iSortBegin = iNewBorder;
	}
	return true;
}
int
ON_Matrix::RowReduce( 
    double zero_tolerance,
    double* B,
    double* pivot 
    )
{
  double t;
  double x, piv;
  int i, k, ix, rank;

  double** this_m = ThisM();
  piv = 0.0;
  rank = 0;
  const int n = m_row_count <= m_col_count ? m_row_count : m_col_count;
  for ( k = 0; k < n; k++ ) {
    ix = k;
    x = fabs(this_m[ix][k]);
    for ( i = k+1; i < m_row_count; i++ ) {
      if ( fabs(this_m[i][k]) > x ) {
        ix = i;
        x = fabs(this_m[ix][k]);
      }
    }
    if ( x < piv || k == 0 ) {
      piv = x;
    }
    if ( x <= zero_tolerance )
      break;
    rank++;

    if ( ix != k )
    {
      // swap rows of matrix and B
      SwapRows( ix, k );
      t = B[ix]; B[ix] = B[k]; B[k] = t;
    }

    // scale row k of matrix and B
    x = 1.0/this_m[k][k];
    this_m[k][k] = 1.0;
    ON_ArrayScale( m_col_count - 1 - k, x, &this_m[k][k+1], &this_m[k][k+1] );
    B[k] *= x;

    // zero column k for rows below this_m[k][k]
    for ( i = k+1; i < m_row_count; i++ ) {
      x = -this_m[i][k];
      this_m[i][k] = 0.0;
      if ( fabs(x) > zero_tolerance ) {
        ON_Array_aA_plus_B( m_col_count - 1 - k, x, &this_m[k][k+1], &this_m[i][k+1], &this_m[i][k+1] );
        B[i] += x*B[k];
      }
    }
  }

  if ( pivot )
    *pivot = piv;

  return rank;
}
Esempio n. 3
0
void dShellSort(
	pdType	pd,		/* the array of dType */
	int		n,       /* size of the array     */
	bool	compType /* true if d's compared, false if i's   */
)
{
   int		gap,
			i,
			j;
   pdType	p,
			q;

   for(gap=n/2;gap>0;gap/=2)
   {
		for(i=gap;i<n;i++)
		{
			for(j=i-gap;j>=0;j-=gap)
			{
				p=pd+j;
				q=pd+j+gap;
				if (dCompare(p,q,compType)<=0)
					break;
				SwapRows(p,q);
         }
		}
	}
}
Esempio n. 4
0
bool Gauss(Ttensor t, Tvec r, Tvec &sol)
{
    double k; 
    for (int i=0; i<3; i++) 
    {
		for (int j=0; j<3; j++)  
		if ((j<i && Abs(t.t[j][j])<ZERO) || j>i) if (Abs(t.t[i][i])<Abs(t.t[j][i]))
        {
	 	    SwapRows(t, i, j);
		    SwapVals(r.x[i], r.x[j]);
		}
		for (int j=0; j<3; j++) if (i!=j)
        {
            if (Abs(t.t[i][i])<ZERO) continue;
            k = -t.t[j][i]/t.t[i][i];
            SumRows(t, j, t[i] * k);
            r.x[i] = r.x[i] * k;
        }
    }
    // all rows are now null or they have first non-zero element on diagonal  
    for (int i=2; i>=0; i--)
    {
        if (t[i].Length() < ZERO)
        {
            if (r[i]!=0) return false;          // no solution
            else { sol.x[i] = 1; continue; }
        }
        sol.x[i] = r.x[i];
	for (int j=i+1; j<3; j++) sol.x[i] -= sol.x[j]*t[i][j];
	sol.x[i] /= t.t[i][i];

    }
    return true;
}
int
ON_Matrix::RowReduce( 
    double zero_tolerance,
    double& determinant,
    double& pivot 
    )
{
  double x, piv, det;
  int i, k, ix, rank;

  double** this_m = ThisM();
  piv = det = 1.0;
  rank = 0;
  const int n = m_row_count <= m_col_count ? m_row_count : m_col_count;
  for ( k = 0; k < n; k++ ) {
    ix = k;
    x = fabs(this_m[ix][k]);
    for ( i = k+1; i < m_row_count; i++ ) {
      if ( fabs(this_m[i][k]) > x ) {
        ix = i;
        x = fabs(this_m[ix][k]);
      }
    }
    if ( x < piv || k == 0 ) {
      piv = x;
    }
    if ( x <= zero_tolerance ) {
      det = 0.0;
      break;
    }
    rank++;

    if ( ix != k )
    {
      // swap rows
      SwapRows( ix, k );
      det = -det;
    }

    // scale row k of matrix and B
    det *= this_m[k][k];
    x = 1.0/this_m[k][k];
    this_m[k][k] = 1.0;
    ON_ArrayScale( m_col_count - 1 - k, x, &this_m[k][k+1], &this_m[k][k+1] );

    // zero column k for rows below this_m[k][k]
    for ( i = k+1; i < m_row_count; i++ ) {
      x = -this_m[i][k];
      this_m[i][k] = 0.0;
      if ( fabs(x) > zero_tolerance ) {
        ON_Array_aA_plus_B( m_col_count - 1 - k, x, &this_m[k][k+1], &this_m[i][k+1], &this_m[i][k+1] );
      }
    }
  }

  pivot = piv;
  determinant = det;

  return rank;
}
Esempio n. 6
0
    /*  LU decomposition of general matrix  */
void EqSolver::LU(){
  double c;
  int aa;
  Vec d(size);
  double h[size];
  for(int i=0;i<size;++i){
    h[i]=0;
    b[i]=i;
  }
    /*  Gauss Elimination  */
  for(int i=0;i<size-1;++i){
    for(int j=i;j<size;++j)
      for(int l=i;l<size;++l){
 	c=m[j][i]/m[j][l];
 	if (fabs(c)>h[j])
 	  h[j]=c;
      }
    c=h[i];
    aa=i;
    for(int j=i;j<size;++j)
      if(h[j]>c){
 	c=h[j];
 	aa=j;
      }
    if(aa!=i)
      SwapRows(i,aa);
    for(int j=i+1;j<size;++j){
      c=m[j][i]/m[i][i];
      m[j][i]=c;//  L matrix
      for(int l=i+1;l<size;++l)
       	m[j][l]-=c*m[i][l];//  U matrix
    }
  }
}
Esempio n. 7
0
int
ON_Matrix::RowReduce( 
    double zero_tolerance,
    ON_3dPoint* B,
    double* pivot 
    )
{
  ON_3dPoint t;
  double x, piv;
  int i, k, ix, rank;

  double** this_m = ThisM();
  piv = 0.0;
  rank = 0;
  const int n = m_row_count <= m_col_count ? m_row_count : m_col_count;
  for ( k = 0; k < n; k++ ) {
    //onfree( onmalloc( 1)); // 8-06-03 lw for cancel thread responsiveness
    onmalloc( 0); // 9-4-03 lw changed to 0
    ix = k;
    x = fabs(this_m[ix][k]);
    for ( i = k+1; i < m_row_count; i++ ) {
      if ( fabs(this_m[i][k]) > x ) {
        ix = i;
        x = fabs(this_m[ix][k]);
      }
    }
    if ( x < piv || k == 0 ) {
      piv = x;
    }
    if ( x <= zero_tolerance )
      break;
    rank++;

    // swap rows of matrix and B
    SwapRows( ix, k );
    t = B[ix]; B[ix] = B[k]; B[k] = t;

    // scale row k of matrix and B
    x = 1.0/this_m[k][k];
    this_m[k][k] = 1.0;
    ON_ArrayScale( m_col_count - 1 - k, x, &this_m[k][k+1], &this_m[k][k+1] );
    B[k] *= x;

    // zero column k for rows below this_m[k][k]
    for ( i = k+1; i < m_row_count; i++ ) {
      x = -this_m[i][k];
      this_m[i][k] = 0.0;
      if ( fabs(x) > zero_tolerance ) {
        ON_Array_aA_plus_B( m_col_count - 1 - k, x, &this_m[k][k+1], &this_m[i][k+1], &this_m[i][k+1] );
        B[i] += x*B[k];
      }
    }
  }

  if ( pivot )
    *pivot = piv;

  return rank;
}
Esempio n. 8
0
bool Gauss(Ttensor t, Ttensor r, Ttensor &sol)
{
    double k; 
    for (int i=0; i<3; i++) 
    {
		for (int j=0; j<3; j++)  
		if ((j<i && Abs(t.t[j][j])<ZERO) || j>i) if (Abs(t.t[i][i])<Abs(t.t[j][i]))
        {
 		    SwapRows(t, i, j);
		    SwapRows(r, i, j);
		}
		for (int j=0; j<3; j++) if (i!=j)
        {
            if (Abs(t.t[i][i])<ZERO) continue;
            k = -t.t[j][i]/t.t[i][i];
            SumRows(t, j, t[i] * k);
		    SumRows(r, j, r[i] * k);
        }
    }
    // all rows are now null or they have first non-zero element on diagonal  

    for (int i=2; i>=0; i--)
    {
		double k = t.t[i][i];
        if (t[i].Length() < ZERO)
		{
		    if (r[i].Length() < ZERO) continue; 
		    else return false;			// ex. (0 0 0 | 1 0 2)   => no solution
		}

		for (int j=0; j<3;  j++)
		{
		    t. t[i][j] /= k;	// to have 1 on diagonal
		    r.t[i][j] /= k;
		}
		for (int j=i-1; j>=0; j--) 
		{
		    k = -t.t[j][i];
		    SumRows(t,  j, t [i]*k);
		    SumRows(r, j, r[i]*k);
		}
    }
    sol = r;
    return true;
}
Esempio n. 9
0
 void TaskEditor::OnMoveUpClicked()
 {
    LOGN_DEBUG("taskeditor.cpp", "Move Up");
    int row = mChildrenView->currentRow();
    if (row > 0)
    {
       SwapRows(row, row - 1);
       mChildrenView->setCurrentCell(row - 1, 0);
       RefreshComboBox(tr(""));
    }
 }
Esempio n. 10
0
 void TaskEditor::OnMoveDownClicked()
 {
    LOGN_DEBUG("taskeditor.cpp", "Move Down");
    int row = mChildrenView->currentRow();
    if (row < (mChildrenView->rowCount() - 1))
    {
       SwapRows(row, row + 1);
       mChildrenView->setCurrentCell(row + 1, 0);
       RefreshComboBox(tr(""));
    }
 }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
DAF::LightsOutSolver::ReduceGameMatrix()
{
    _vbElementaryOperationMatrix = IdentityMatrix();
    _vbReducedGameMatrix = GameMatrix();
    
    const std::size_t kuGameDimension = _uDimension * _uDimension;
    
    std::size_t uNextRow = 0;
    for (std::size_t uColumn = 0; uColumn < kuGameDimension; ++uColumn)
    {
        for (std::size_t uRow = uNextRow; uRow < kuGameDimension; ++uRow)
        {
            const std::size_t kuLinearIndex = ConvertToLinearIndex(kuGameDimension, uRow, uColumn);
            if ( _vbReducedGameMatrix[kuLinearIndex] )
            {
                SwapRows(kuGameDimension, _vbElementaryOperationMatrix, uNextRow, uRow);
                SwapRows(kuGameDimension, _vbReducedGameMatrix, uNextRow, uRow);
                
                for (size_t uClearRow = 0; uClearRow < kuGameDimension; ++uClearRow)
                {
                    if ( uClearRow == uNextRow )
                        continue;
                    
                    const size_t kuClearLinearIndex = ConvertToLinearIndex(kuGameDimension, uClearRow, uColumn);
                    if ( _vbReducedGameMatrix[kuClearLinearIndex] )
                    {
                        AddRowToRow(kuGameDimension, _vbElementaryOperationMatrix, uNextRow, uClearRow);
                        AddRowToRow(kuGameDimension, _vbReducedGameMatrix, uNextRow, uClearRow);
                    }
                }
                
                ++uNextRow;
                
                break;
            }
        }
    }
    
    FindNullSpaceBasis();
}
Esempio n. 12
0
void ExtImportPrefs::DoOnRuleTableKeyDown (int keycode)
{
   int selrow = RuleTable->GetGridCursorRow ();
   wxString ts;
   if (keycode == WXK_UP)
   {
      if (selrow == 0)
         return;
      SwapRows (selrow - 1, selrow);
      RuleTable->MoveCursorUp (false);
      RuleTable->SelectRow (selrow - 1);
   }
   else if (keycode == WXK_DOWN)
   {
      if (selrow == RuleTable->GetNumberRows() - 1)
         return;
      SwapRows (selrow, selrow + 1);
      RuleTable->MoveCursorDown (false);
      RuleTable->SelectRow (selrow + 1);
   }
}
void BinaryMatrix::SortRowsAsc() {
	int itemsLen = _row;
	bool swapped = true;
	int n = 0;
	while (swapped) {
		swapped = false;
		int loopCount = itemsLen - n - 1;
		for (int i = 0; i < loopCount; i++) {
			int j = i + 1;
			if (CompareRows(i, j) > 0) {
				SwapRows(i, j);
				swapped = true;
			}
		}
		n++;
	}
};
Esempio n. 14
0
    /*  Gauss Elimination, returning result  */
Vec EqSolver::Gauss(){
  double c;
  int aa;
  Vec d(size);
  double h[size];
  for(int i=0;i<size;++i)
    h[i]=0;

  for(int i=0;i<size-1;++i){
    for(int j=i;j<size;++j)
      for(int l=i;l<size;++l){//  Choosing Pivot
 	c=m[j][i]/m[j][l];
 	if (fabs(c)>h[j])
 	  h[j]=c;
      }
    c=h[i];
    aa=i;
    for(int j=i;j<size;++j)
      if(h[j]>c){
 	c=h[j];
 	aa=j;
      }
    if(aa!=i)
      SwapRows(i,aa);//  Swaping Rows to eliminate with best pivot
      /*  Eliminate lines below using row i  */
    for(int j=i+1;j<size;++j){
      c=m[j][i]/m[i][i];
      for(int l=i;l<size;++l)
       	m[j][l]-=c*m[i][l];
      b[j]-=c*b[i];
    }
  }
    /*  Solving system  Ux=b'  */
  for(int i=size-1;i>-1;--i){
    c=0;
    for(int j=size-1;j>i;--j)
      c+=m[i][j]*d[j];
    d.SetEntrie(i,(b[i]-c)/m[i][i]);
  }
  return d;
}
Esempio n. 15
0
// Reduces all elements in a column except the diagonal element
// Returns 0 on success, 1 if the column cannot be reduced
int Matrix::ReduceColumn(int column, Matrix &inverse)
{
	// loop variable for working down column
	int row, pivot = column;

	// find the first non-zero element in the column
	// that is not above the diagonal
	for (row = pivot; row < 4; row++)
		if (fabs(Element(row, pivot)) > ERROR_TOLERANCE)
			break;

	// if we didn't find one, return an error code
	if (row == 4) return 1;

	// if we did, but it wasn't on the diagonal, swap with the pivot row
	// this makes sure we never get divide by zero errors
	if (row != pivot)
	{
		SwapRows(pivot, row);
		inverse.SwapRows(pivot, row);
	}

	// now scale the pivot row so the pivot element is one
	float scaleFactor = 1.0 / Element(pivot, pivot);
	ScaleRow(pivot, scaleFactor);
	inverse.ScaleRow(pivot, scaleFactor);

	// for each row
	for (row = 0; row < 4; row++)
	{
		// skip the row we're pivoting on
		if (row == column) continue;
		scaleFactor = -Element(row, pivot);
		AddRows(row, scaleFactor, pivot);
		inverse.AddRows(row, scaleFactor, pivot);
	}

	// and we're done
	return 0;
}
Esempio n. 16
0
void Matrix::Reduce(double tol) {
  double pivot;
  int pivotr = 0;  // Initializing pivotr is not necessary, but avoids warnings
  int r = 0;       // the row we are currently reducing

  for (int j = 0; j < cols; j++) {
    if (r > rows) return;

    pivot = 0.0;
    for (int i = r; i < rows; i++)
      if (fabs((*this)[i][j]) > pivot) {
        pivot = fabs((*this)[i][j]);
        pivotr = i;
      }

    if (pivot <= tol) {
      for (int i = r; i < rows; i++) (*this)[i][j] = 0.0;
      continue;
    }

    SwapRows(pivotr, r);

    double scale = (*this)[r][j];

    (*this)[r][j] = 1.0;
    for (int k = j + 1; k < cols; k++) (*this)[r][k] /= scale;

    for (int i = r + 1; r < rows; i++) {
      scale = (*this)[i][j];
      (*this)[i][j] = 0.0;
      for (int k = j + 1; k < cols; k++) (*this)[i][k] -= (*this)[r][k] * scale;
    }

    r++;
  }
}
Esempio n. 17
0
// Sort the control based on a column and method. Bubble sort method is used
//
// nColumnIndex - Column to sort off of
// dwSortMethod - Use either SORT_ALPHA or SORT_NUMERIC
void CColumnCtrl::Sort ( int nColumnIndex, DWORD dwSortMethod )
{
	if ( nColumnIndex >= nColumns || nRows <= 1 || dwSortMethod == SORT_NONE )
	{
		return;
	}

	ASSERT ( nColumnIndex >= 0 );

	// Must be a know sort method
	if ( dwSortMethod <= SORT_MIN || dwSortMethod >= SORT_MAX )
	{
		ASSERT(FALSE);
		return;
	}	


	CString sItemText1;	// Used to compare two items
	CString sItemText2;

	int nItemNumber1;	// Used to compare two numbers
	int nItemNumber2;

	BOOL bSorted=FALSE;	// The list is not sorted

	int i;
	while ( !bSorted )
	{
		bSorted=TRUE;
		for ( i = 0; i < nRows-1; i++ )
		{
			sItemText1 = GetItemText(i, nColumnIndex);
			sItemText2 = GetItemText(i+1, nColumnIndex);

			switch ( dwSortMethod )
			{	
			case SORT_ALPHA_ASCENDING:
				{
					if ( _stricmp ( sItemText1, sItemText2 ) > 0 )
					{
						SwapRows ( i, i+1 );
						bSorted=FALSE;
					}
					break;
				}
			case SORT_ALPHA_DESCENDING:
			{
				if ( _stricmp ( sItemText1, sItemText2 ) < 0 )
				{
					SwapRows ( i, i+1 );
					bSorted=FALSE;
				}
				break;
			}
			case SORT_NUMERIC_ASCENDING:
				{
					nItemNumber1=atoi(sItemText1);
					nItemNumber2=atoi(sItemText2);

					if ( nItemNumber1 > nItemNumber2 )
					{
						SwapRows ( i, i+1 );
						bSorted=FALSE;
					}
					break;
				}
			case SORT_NUMERIC_DESCENDING:
				{
					nItemNumber1=atoi(sItemText1);
					nItemNumber2=atoi(sItemText2);

					if ( nItemNumber1 < nItemNumber2 )
					{
						SwapRows ( i, i+1 );
						bSorted=FALSE;
					}
					break;
				}
			default:
				{
					// The switch statement should have been handled above
					ASSERT(FALSE);
					break;
				}
			}			
		}
	}
}
Esempio n. 18
0
int
ON_Matrix::RowReduce( 
    double zero_tolerance,
    int pt_dim, int pt_stride, double* pt,
    double* pivot 
    )
{
  const int sizeof_pt = pt_dim*sizeof(pt[0]);
  double* tmp_pt = (double*)onmalloc(pt_dim*sizeof(tmp_pt[0]));
  double *ptA, *ptB;
  double x, piv;
  int i, k, ix, rank, pti;

  double** this_m = ThisM();
  piv = 0.0;
  rank = 0;
  const int n = m_row_count <= m_col_count ? m_row_count : m_col_count;
  for ( k = 0; k < n; k++ ) {
//    onfree( onmalloc( 1)); //  8-06-03 lw for cancel thread responsiveness
    onmalloc( 0); // 9-4-03 lw changed to 0
    ix = k;
    x = fabs(this_m[ix][k]);
    for ( i = k+1; i < m_row_count; i++ ) {
      if ( fabs(this_m[i][k]) > x ) {
        ix = i;
        x = fabs(this_m[ix][k]);
      }
    }
    if ( x < piv || k == 0 ) {
      piv = x;
    }
    if ( x <= zero_tolerance )
      break;
    rank++;

    // swap rows of matrix and B
    if ( ix != k ) {
      SwapRows( ix, k );
      ptA = pt + (ix*pt_stride);
      ptB = pt + (k*pt_stride);
      memcpy( tmp_pt, ptA, sizeof_pt );
      memcpy( ptA, ptB, sizeof_pt );
      memcpy( ptB, tmp_pt, sizeof_pt );
    }

    // scale row k of matrix and B
    x = 1.0/this_m[k][k];
    if ( x != 1.0 ) {
      this_m[k][k] = 1.0;
      ON_ArrayScale( m_col_count - 1 - k, x, &this_m[k][k+1], &this_m[k][k+1] );
      ptA = pt + (k*pt_stride);
      for ( pti = 0; pti < pt_dim; pti++ )
        ptA[pti] *= x;
    }

    // zero column k for rows below this_m[k][k]
    ptB = pt + (k*pt_stride);
    for ( i = k+1; i < m_row_count; i++ ) {
      x = -this_m[i][k];
      this_m[i][k] = 0.0;
      if ( fabs(x) > zero_tolerance ) {
        ON_Array_aA_plus_B( m_col_count - 1 - k, x, &this_m[k][k+1], &this_m[i][k+1], &this_m[i][k+1] );
        ptA = pt + (i*pt_stride);
        for ( pti = 0; pti < pt_dim; pti++ ) {
          ptA[pti] += x*ptB[pti];
        }
      }
    }
  }

  if ( pivot )
    *pivot = piv;

  onfree(tmp_pt);

  return rank;
}
Esempio n. 19
0
bool ON_Matrix::Invert( double zero_tolerance )
{
  ON_Workspace ws;
  int i, j, k, ix, jx, rank;
  double x;
  const int n = MinCount();
  if ( n < 1 )
    return false;

  ON_Matrix I(m_col_count, m_row_count);

  int* col = ws.GetIntMemory(n);

  I.SetDiagonal(1.0);
  rank = 0;

  double** this_m = ThisM();

  for ( k = 0; k < n; k++ ) {
    // find largest value in sub matrix
    ix = jx = k;
    x = fabs(this_m[ix][jx]);
    for ( i = k; i < n; i++ ) {
      for ( j = k; j < n; j++ ) {
        if ( fabs(this_m[i][j]) > x ) {
          ix = i;
          jx = j;
          x = fabs(this_m[ix][jx]);
        }
      }
    }

    SwapRows( k, ix );
    I.SwapRows( k, ix );

    SwapCols( k, jx );
    col[k] = jx;

    if ( x <= zero_tolerance ) {
      break;
    }
    x = 1.0/this_m[k][k];
    this_m[k][k] = 1.0;
    ON_ArrayScale( m_col_count-k-1, x, &this_m[k][k+1], &this_m[k][k+1] );
    I.RowScale( k, x );

    // zero this_m[!=k][k]'s 
    for ( i = 0; i < n; i++ ) {
      if ( i != k ) {
        x = -this_m[i][k];
        this_m[i][k] = 0.0;
        if ( fabs(x) > zero_tolerance ) {
          ON_Array_aA_plus_B( m_col_count-k-1, x, &this_m[k][k+1], &this_m[i][k+1], &this_m[i][k+1] );
          I.RowOp( i, x, k );
        }
      }
    }
  }

  // take care of column swaps
  for ( i = k-1; i >= 0; i-- ) {
    if ( i != col[i] )
      I.SwapRows(i,col[i]);
  }

  *this = I;

  return (k == n) ? true : false;
}
Esempio n. 20
0
int	ChSparseMatrix::Decompose_LU(int* pivarray, double* det)
{
	ChMelement* rowel;
	ChMelement* subrowel;
	int i,k, pivrow, eqpivoted;
	double r, pivot, mval, subval, newval, leader;
	int err = 0;

	if (pivarray)	// initialize pivot index array
	{
		for (int ind = 0; ind < rows; ind++)
		{ pivarray[ind] = ind;}
	}
	else return TRUE; // error: no pivot array.

	*det = 1;

	for (k=1; k < rows; k++)
	{
		pivot = GetElement((k-1),(k-1));

		if (fabs(pivot) < ACCEPT_PIVOT)
		{
			// pivoting is needed, so swap equations
			pivrow = BestPivotRow(k-1);
			SwapRows ((k-1), pivrow );
			*det = - *det;

			eqpivoted = pivarray[pivrow]; // swap eq.ids in pivot array
			pivarray[pivrow] =pivarray[k-1];
			pivarray[k-1] = eqpivoted;

			pivot = GetElement((k-1),(k-1)); // fetch new pivot
		}

		if (fabs(pivot) <= MIN_PIVOT)	// was unable to find better pivot: force solution to zero.and go ahead
		{
			//*det = *det;
			pivot = INFINITE_PIVOT;
			SetElement(k-1, k-1 , pivot);
			if (!err)
				err = (1+rows-k);	// report deficiency
		}
		else
			*det = *det * pivot;

		for (i=k; i < rows; i++)
		{
			leader = GetElement(i, (k-1));

			if (leader)
			{
			 r= leader / pivot;	// compute multiplier
			 SetElement(i,(k-1),r);				// store the multiplier in L part!!!

			 subrowel = GetElarrayMel(i); // initialize guessed sparse elements
			 rowel=GetElarrayMel(k-1);	  // for speed optimization. They are in two rows.

			 //while ((rowel->col<k) && (rowel->next))
			 //	 rowel = rowel->next;		// advance top row element till it has (col >= k)

			 for (NULL; rowel!= NULL; rowel=rowel->next)	//for (j=k; j < columns; j++)  where j = rowel->col
			 {
				 if (rowel->col >= k)	// skip
				 {
					mval = rowel->val;
					subrowel= GetElement(i, rowel->col, &subval, subrowel);
					newval = subval - r * mval;
					subrowel= SetElement(i, rowel->col, newval, subrowel);	// set the U part
				 }
			 }
			}
		}
	}

	pivot = GetElement((rows-1),(rows-1));
	if (fabs(pivot) <= MIN_PIVOT)
	{
		//*det = *det;
		pivot = INFINITE_PIVOT;
		SetElement(rows-1, rows-1 , pivot);
		if (!err)
			err = (1);	// report deficiency
	}
	else
		*det = *det * pivot;

	return err;
}
Esempio n. 21
0
int ChSparseMatrix::Solve_LinSys	(ChMatrix<>* B, ChMatrix<>* X, int* pivarray, double* det) // the object is the [A] matrix.
{
	ChMelement* rowel;
	ChMelement* subrowel;
	int i,k, pivrow, eqpivoted;
	double r, bi, x, sum, pivot, pivlast, mval, subval, newval, leader;
	int err = 0;

	if (pivarray)	// initialize pivot index array
	{
		for (int ind = 0; ind < rows; ind++)
		{ pivarray[ind] = ind;}
	}

	*det = 1;

			// FORWARD reduction
	for (k=1; k < rows; k++)
	{
		pivot = GetElement((k-1),(k-1));
		if (fabs(pivot) < ACCEPT_PIVOT)
		{
			pivrow = BestPivotRow(k-1);
			SwapRows ((k-1), pivrow );
			B->SwapRows ((k-1), pivrow );
			*det = - *det;
			if (pivarray)
			{
				eqpivoted = pivarray[pivrow]; // swap eq.ids in pivot array
				pivarray[pivrow] =pivarray[k-1];
				pivarray[k-1] = eqpivoted;
			}
			pivot = GetElement((k-1),(k-1));
		}
		if (fabs(pivot) <= MIN_PIVOT)	// was unable to find better pivot: force solution to zero.and go ahead
		{
			//*det = *det;
			pivot = INFINITE_PIVOT;
			SetElement(k-1, k-1 , pivot);
			if (!err)
				err = (1+rows-k);	// report deficiency
		}
		else
			*det = *det * pivot;

		for (i=k; i < rows; i++)
		{
			leader = GetElement(i, (k-1));

			if (leader)
			{
		  	 r = leader / pivot;

			 bi= B->GetElement(i,0) - r * B->GetElement((k-1),0);
			 B->SetElement(i,0, bi);

			 subrowel = GetElarrayMel(i);
			 rowel=GetElarrayMel(k-1);

			 //while ((rowel->col<k) && (rowel->next))
			//	 rowel = rowel->next;		// advance top row element till it has (col >= k)

			 for (NULL; rowel!=NULL ; rowel=rowel->next)
			 {
				if (rowel->col >= k)		// skip
				{
					mval = rowel->val;
					subrowel= GetElement(i, rowel->col, &subval, subrowel);
					newval = subval - r * mval;
					subrowel= SetElement(i, rowel->col, newval, subrowel);
				}
			 }
			}
		}
	}

	pivlast = GetElement((rows-1),(rows-1));
	if (fabs(pivlast) <= MIN_PIVOT)
	{
		//*det = *det;
		pivlast = INFINITE_PIVOT;
		SetElement(rows-1, rows-1 , pivlast);
		if (!err)
			err = (1);	// report deficiency
	}
	else
		*det = *det * pivlast;

			// BACKWARD substitution
	double xlast = B->GetElement(rows-1,0) / pivlast;
	X->SetElement((rows-1),0,xlast);

	for (k=(rows-2); k>= 0; k--)
	{
		sum = 0;

		rowel=GetElarrayMel(k);

		for (NULL; rowel!=NULL ; rowel=rowel->next) //for (j=(k+1); j< rows; j++)
		{
			if (rowel->col >= k+1)		// skip L part,
			{
				sum += rowel->val * (X->GetElement(rowel->col,0)); //sum += (GetElement(k,j))*(X->GetElement(j,0));
			}
		}

		x = (B->GetElement(k,0) - sum) / GetElement(k,k);
		X->SetElement(k,0, x);
	}

	return err;
}