Beispiel #1
0
Datei: LU.cpp Projekt: DikBSD/STE
void
LU::solve(int const nx, double* X, double const* B) const
{
	if (!isNonsingular()) {
		throw std::runtime_error("Matrix is singular.");
	}

	// Pivot B into X.
	for (int i = 0; i < m_rows; ++i) {
		for (int j = 0; j < nx; ++j) {
			X[i * nx + j] = B[m_piv[i] * nx + j];
		}
	}

	// Solve L*Y = B(piv,:)
	for (int k = 0; k < m_cols; ++k) {
		for (int i = k + 1; i < m_cols; ++i) {
			for (int j = 0; j < nx; ++j) {
				X[i * nx + j] -= X[k * nx + j] * m_LU[i * m_cols + k];
			}
		}
	}
	// Solve U*X = Y;
	for (int k = m_cols - 1; k >= 0; --k) {
		for (int j = 0; j < nx; ++j) {
			X[k * nx + j] /= m_LU[k * m_cols + k];
		}
		for (int i = 0; i < k; ++i) {
			for (int j = 0; j < nx; j++) {
				X[i * nx + j] -= X[k * nx + j] * m_LU[i * m_cols + k];
			}
		}
	}
}
Beispiel #2
0
LUDecomposition::Matrix LUDecomposition::solve (const Matrix& B) const {
      BOOST_UBLAS_CHECK((int)B.size1() == m, bad_size("Matrix row dimensions must agree."));
      BOOST_UBLAS_CHECK(isNonsingular(), singular("Matrix is singular."));

      // Copy right hand side with pivoting
      int nx = B.size2();
      Matrix X(m,nx);
      for (int i = 0; i < m; i++) {
          row(X,i) = row(B, piv(i));
      }

      // Solve L*Y = B(piv,:)
      for (int k = 0; k < n; k++) {
         for (int i = k+1; i < n; i++) {
            for (int j = 0; j < nx; j++) {
               X(i,j) -= X(k,j)*LU(i,k);
            }
         }
      }
      // Solve U*X = Y;
      for (int k = n-1; k >= 0; k--) {
         for (int j = 0; j < nx; j++) {
            X(k,j) /= LU(k,k);
         }
         for (int i = 0; i < k; i++) {
            for (int j = 0; j < nx; j++) {
               X(i,j) -= X(k,j)*LU(i,k);
            }
         }
      }
      return X;
   }
Beispiel #3
0
void solveLU3x3(sLU& A, float x[3], float b[3])
{
  //TNT::Array1D<float> jamaB = TNT::Array1D<float>(3, &b[0]);
  //TNT::Array1D<float> jamaX = A.solve(jamaB);

	
  // Solve A, B

	{
      if (!isNonsingular(A)) {
        x[0]=0.0f;
		x[1]=0.0f;
		x[2]=0.0f;
		return;
      }


	  //Array1D<Real> Ax = permute_copy(b, piv);
	  float Ax[3];

    // permute copy: b , A.piv
	{
         for (int i = 0; i < 3; i++) 
               Ax[i] = b[A.piv[i]];
	}

      // Solve L*Y = B(piv)
      for (int k = 0; k < 3; k++) {
         for (int i = k+1; i < 3; i++) {
               Ax[i] -= Ax[k]*A.values[i][k];
            }
         }
      
	  // Solve U*X = Y;
      for (int k = 2; k >= 0; k--) {
            Ax[k] /= A.values[k][k];
      		for (int i = 0; i < k; i++) 
            	Ax[i] -= Ax[k]*A.values[i][k];
      }
     

		x[0] = Ax[0];
		x[1] = Ax[1];
		x[2] = Ax[2];
      return;
	}
}
//////////////////////////////////////////////////////////////////////
// Compute the eigenvalues of the advected texture
////////////////////////////////////////////////////////////////////// 
void WTURBULENCE::computeEigenvalues(float *_eigMin, float *_eigMax) {
  // stats
  float maxeig = -1.;
  float mineig = 10.;

  // texture coordinate eigenvalues
  for (int z = 1; z < _zResSm-1; z++) {
    for (int y = 1; y < _yResSm-1; y++) 
      for (int x = 1; x < _xResSm-1; x++)
      {
        const int index = x+ y *_resSm[0] + z*_slabSizeSm;

        // compute jacobian
        float jacobian[3][3] = {
          { minDx(x, y, z, _tcU, _resSm), minDx(x, y, z, _tcV, _resSm), minDx(x, y, z, _tcW, _resSm) } ,
          { minDy(x, y, z, _tcU, _resSm), minDy(x, y, z, _tcV, _resSm), minDy(x, y, z, _tcW, _resSm) } ,
          { minDz(x, y, z, _tcU, _resSm), minDz(x, y, z, _tcV, _resSm), minDz(x, y, z, _tcW, _resSm) }
        };

        // ONLY compute the eigenvalues after checking that the matrix
        // is nonsingular
        sLU LU = computeLU(jacobian);

        if (isNonsingular(LU))
        {
          // get the analytic eigenvalues, quite slow right now...
          Vec3 eigenvalues = Vec3(1.);
          computeEigenvalues3x3( &eigenvalues[0], jacobian);
          _eigMax[index] = MAX3V(eigenvalues);
          _eigMin[index] = MIN3V(eigenvalues);
          maxeig = MAX(_eigMax[index],maxeig);
          mineig = MIN(_eigMin[index],mineig);
        }
        else
        {
          _eigMax[index] = 10.0f;
          _eigMin[index] = 0.1;
        }
      }
  }
}