예제 #1
0
void QRDecomposition<T>::backSub(const VectorT& b, VectorT& x) const
{
  if(x.n == 0) x.resize(QR.n);
  Assert(QR.m == b.n);
  Assert(QR.n == x.n);

  /* compute rhs = Q^T b */
  VectorT rhs;
  QtMul(b,rhs);
  if(QR.m == QR.n) {
    /* Solve R x = rhs, storing x in-place */
    UBackSubstitute(QR,rhs,x);
    //UBackSubstitute(QR,x,x);
  }
  else if(QR.m > QR.n) {
    //solve the top part of R x = rhs
    MatrixT R1; R1.setRef(QR,0,0,1,1,QR.n,QR.n);
    VectorT rhs1; rhs1.setRef(rhs,0,1,QR.n);
    UBackSubstitute(R1,rhs1,x);
  }
  else {
    cerr<<"What do we do with m < n?"<<endl;
    MatrixPrinter mprint(QR); mprint.mode = MatrixPrinter::AsciiShade;
    cerr<<mprint<<endl;
    //solve the left part of R x = rhs
    MatrixT R1; R1.setRef(QR,0,0,1,1,QR.m,QR.m);
    VectorT x1; x1.setRef(x,0,1,QR.m);
    UBackSubstitute(R1,rhs,x1);
    getchar();
  }
}
      void operator()(LinPdeSysT const & pde_system,
                      SegmentT   const & segment,
                      StorageType      & storage,
                      MatrixT          & system_matrix,
                      VectorT          & load_vector)
      {
        typedef viennamath::equation                          equ_type;
        typedef viennamath::expr                              expr_type;
        typedef typename expr_type::interface_type            interface_type;
        typedef typename expr_type::numeric_type              numeric_type;

        typedef typename viennagrid::result_of::cell_tag<SegmentT>::type CellTag;

        std::size_t map_index = viennafvm::create_mapping(pde_system, segment, storage);

        system_matrix.clear();
        system_matrix.resize(map_index, map_index, false);
        load_vector.clear();
        load_vector.resize(map_index);


        for (std::size_t pde_index = 0; pde_index < pde_system.size(); ++pde_index)
        {
#ifdef VIENNAFVM_DEBUG
          std::cout << std::endl;
          std::cout << "//" << std::endl;
          std::cout << "//   Equation " << pde_index << std::endl;
          std::cout << "//" << std::endl;
#endif
          assemble(pde_system, pde_index,
                   segment, storage,
                   system_matrix, load_vector);

        } // for pde_index
      } // functor
예제 #3
0
void RowEchelon<T>::backSub(VectorT& x) const
{
  Assert(EB.n == 1);
  Assert(EB.m == R.m);
  x.resize(R.n);
  VectorT b;
  EB.getColRef(0,b);

  Assert((int)firstEntry.size() == R.m+1);
  x.setZero();
  int m=R.m,n=R.n;
  for(int i=m-1;i>=0;i--) {
    VectorT ri; R.getRowRef(i,ri);
    //solve to set R*x = b[i]
    //calculate alpha = dot between rest of x[>ji] and R[i]
    int ji=firstEntry[i];
    if(ji == n) continue;
    int ji2=firstEntry[i+1];  //(i+1==m?n:firstEntry[i+1]);
    T alpha;
    if(ji2 == n) alpha = Zero;
    else {
      VectorT rji2; rji2.setRef(ri,ji2,1,R.n-ji2);
      VectorT xji2; xji2.setRef(x,ji2,1,R.n-ji2);
      alpha = xji2.dot(rji2);
    }
    x[ji] = (b[i]-alpha)/ri[ji];
  }
}
예제 #4
0
void SparseVectorTemplate<T>::get(VectorT& v) const
{
  v.resize(this->n);
  int k=0;
  for(const_iterator i=this->begin();i!=this->end();i++) {
    while(k < i->first) { v(k)=0; k++; }
    v(k) = i->second;
    k=i->first+1;
  }
  while(k < (int)this->n) { v(k)=0; k++; }
}
예제 #5
0
void DiagonalMatrixTemplate<T>::mulPseudoInverse(const VectorT& a, VectorT& b) const
{
  if(BaseT::n != a.n) FatalError(MatrixError_ArgIncompatibleDimensions);
  if(b.n == 0)
    b.resize(this->n);
  else if(b.n != this->n) FatalError(MatrixError_DestIncompatibleDimensions);
  
  ItT v=this->begin();
  VectorIterator<T> va=a.begin(),vb=b.begin();
  for(int i=0; i<this->n; i++, v++,va++,vb++)
    *vb = *va * PseudoInv(*v);
}
예제 #6
0
void SparseVectorCompressed<T>::get(VectorT& v) const
{
  v.resize(n);
  int i=0;
  for(int k=0;k<num_entries;k++) {
    for(;i<indices[k];i++)
      v[i]=Zero;
    v[i]=vals[k];
  }
  for(;i<this->n;i++)
    v[i]=Zero;
}
예제 #7
0
void LDLDecomposition<T>::DBackSub(const VectorT& b, VectorT& x) const
{
  x.resize(b.n);
  Assert(b.n==x.n);
  for(int i=0;i<x.n;i++) {
    if(!FuzzyZero(LDL(i,i),zeroTolerance))
      x(i) = b(i)/LDL(i,i);
    else {
      if(!FuzzyZero(b(i),zeroTolerance))
	cerr<<"LDLDecomposition::DBackSub(): Warning, zero on the diagonal"<<endl;
      x(i) = 0;
    }
  }
}
예제 #8
0
void SparseMatrixTemplate_RM<T>::mulTranspose(const VectorT& a,VectorT& x) const
{
  if(x.n == 0) x.resize(n);
  if(x.n != n) {
    FatalError("Destination vector has incorrect dimensions");
  }
  if(a.n != m) {
    FatalError("Source vector has incorrect dimensions");
  }
  x.setZero();
  for(int i=0;i<m;i++) {
    for(ConstRowIterator it=rows[i].begin();it!=rows[i].end();it++)
      x(it->first) += it->second*a(i);
  }
}
예제 #9
0
void SparseMatrixTemplate_RM<T>::mul(const VectorT& a,VectorT& x) const
{
  if(x.n == 0) x.resize(m);
  if(x.n != m) {
    FatalError("Destination vector has incorrect dimensions");
  }
  if(a.n != n) {
    FatalError("Source vector has incorrect dimensions");
  }
  for(int i=0;i<m;i++) {
    T sum=0;
    for(ConstRowIterator it=rows[i].begin();it!=rows[i].end();it++)
      sum += it->second*a(it->first);
    x(i) = sum;
  }
}
예제 #10
0
void MatrixTemplate<T>::maddTranspose(const VectorT& a, VectorT& b) const
{
  if(m != a.n)
  {
    RaiseErrorFmt(WHERE_AM_I,MatrixError_ArgIncompatibleDimensions);
  }
  if(b.n == 0)
  {
    b.resize(n);
  }
  else if(b.n != n)
  {
    RaiseErrorFmt(WHERE_AM_I,MatrixError_DestIncompatibleDimensions);
  }

  gen_array2d_vector_madd_transpose(b.getStart(),b.stride,
    getStart(),istride,jstride, 
    a.getStart(),a.stride, 
    m, n);
}
예제 #11
0
bool LDLDecomposition<T>::DBackSub(const VectorT& b, VectorT& x) const
{
  bool res=true;
  x.resize(b.n);
  Assert(b.n==x.n);
  for(int i=0;i<x.n;i++) {
    if(!FuzzyZero(LDL(i,i),zeroTolerance))
      x(i) = b(i)/LDL(i,i);
    else {
      if(!FuzzyZero(b(i),zeroTolerance)) {
	if(verbose >= 1) 
	  LOG4CXX_ERROR(KrisLibrary::logger(),"LDLDecomposition::DBackSub(): Warning, zero on the diagonal, b("<<i<<")="<<b(i));
	res = false;
	x(i) = Sign(b(i))*Inf;
      }
      else
	x(i) = 0;
    }
  }
  return res;
}
예제 #12
0
void QRDecomposition<T>::leastSquares(const VectorT& b, VectorT& x, VectorT& residual) const
{
  if(x.n == 0) x.resize(QR.n);
  Assert(QR.m >= QR.n);
  Assert(QR.m == b.n);
  Assert(QR.n == x.n);
  Assert(QR.m == residual.n);

  MatrixT R;
  R.setRef(QR,0,0,1,1,QR.n,QR.n);
  VectorT c;
  c.setRef(residual,0,1,QR.n);

  /* compute rhs = Q^T b */ 
  QtMul(b,residual);
  
  /* Solve R x = rhs */
  UBackSubstitute(R,c,x);
  
  /* Compute residual = b - A x = Q (Q^T b - R x) */
  c.setZero();
  QMul(residual,residual);
}
예제 #13
0
void LDLDecomposition<T>::getD(VectorT& d) const
{
  Assert(LDL.m == LDL.n);
  d.resize(LDL.n);
  LDL.getDiagCopy(0,d);
}
예제 #14
0
void LDLDecomposition<T>::LTBackSub(const VectorT& b, VectorT& x) const
{
  Assert(b.n == LDL.n);
  x.resize(LDL.n);
  Lt1BackSubstitute(LDL,b,x);
}
예제 #15
0
      void operator()(SystemType pde_system,
                      DomainType & domain,
                      MatrixT    & system_matrix,
                      VectorT    & load_vector
                     ) const
      {
        typedef typename viennagrid::result_of::cell_tag<DomainType>::type CellTag;

        typedef typename viennagrid::result_of::point<DomainType>::type                                   PointType;
        typedef typename viennagrid::result_of::element<DomainType, CellTag>::type                        CellType;

        typedef typename viennagrid::result_of::element_range<DomainType, CellTag>::type                  CellContainer;
        typedef typename viennagrid::result_of::iterator<CellContainer>::type                             CellIterator;

        typedef typename SystemType::equation_type                  EquationType;

     #ifdef VIENNAFEM_DEBUG
        std::cout << "Strong form: " << pde_system.pde(0) << std::endl;
     #endif
        log_strong_form(pde_system);
        EquationType weak_form_general = viennafem::make_weak_form(pde_system.pde(0));
     #ifdef VIENNAFEM_DEBUG
        std::cout << "* pde_solver::operator(): Using weak form general: " << weak_form_general << std::endl;
     #endif
        std::vector<EquationType> temp(1); temp[0] = weak_form_general;
        log_weak_form(temp, pde_system);
        EquationType weak_form = viennamath::apply_coordinate_system(viennamath::cartesian< PointType::dim >(), weak_form_general);
        //EquationType weak_form = viennamath::apply_coordinate_system(viennamath::cartesian<Config::coordinate_system_tag::dim>(), weak_form_general);
        temp[0] = weak_form;
        log_coordinated_weak_form(temp, pde_system);

     #ifdef VIENNAFEM_DEBUG
        std::cout << "* pde_solver::operator(): Using weak form " << weak_form << std::endl;
        std::cout << "* pde_solver::operator(): Write dt_dx coefficients" << std::endl;
     #endif

        typedef typename reference_cell_for_basis<CellTag, viennafem::lagrange_tag<1> >::type    ReferenceCell;

        //
        // Create accessors for performance in the subsequent dt_dx_handler step
        //

        //viennafem::dtdx_assigner<DomainType, StorageType, ReferenceCell>::apply(domain, storage);

        viennafem::dt_dx_handler<DomainType, StorageType, ReferenceCell>  dt_dx_handler(domain, storage);

        //fill with cell quantities
        CellContainer cells = viennagrid::elements<CellType>(domain);
        for (CellIterator cell_iter = cells.begin();
            cell_iter != cells.end();
            ++cell_iter)
        {
          //cell_iter->print_short();
          //viennadata::access<example_key, double>()(*cell_iter) = i;
          //viennafem::dt_dx_handler<ReferenceCell>::apply(storage, *cell_iter);
          dt_dx_handler(*cell_iter);
        }

     #ifdef VIENNAFEM_DEBUG
        std::cout << "* pde_solver::operator(): Create Mapping:" << std::endl;
     #endif
        std::size_t map_index = create_mapping(storage, pde_system, domain);

     #ifdef VIENNAFEM_DEBUG
        std::cout << "* pde_solver::operator(): Assigned degrees of freedom in domain so far: " << map_index << std::endl;
     #endif
        // resize global system matrix and load vector if needed:
        // TODO: This can be a performance bottleneck for large numbers of segments! (lots of resize operations...)
        if (map_index > system_matrix.size1())
        {
          MatrixT temp = system_matrix;
          ////std::cout << "Resizing system matrix..." << std::endl;
          system_matrix.resize(map_index, map_index, false);
          system_matrix.clear();
          system_matrix.resize(map_index, map_index, false);
          for (typename MatrixT::iterator1 row_it = temp.begin1();
               row_it != temp.end1();
               ++row_it)
          {
            for (typename MatrixT::iterator2 col_it = row_it.begin();
                 col_it != row_it.end();
                 ++col_it)
                 system_matrix(col_it.index1(), col_it.index2()) = *col_it;
          }
        }
        if (map_index > load_vector.size())
        {
          VectorT temp = load_vector;
       #ifdef VIENNAFEM_DEBUG
          std::cout << "Resizing load vector..." << std::endl;
       #endif
          load_vector.resize(map_index, false);
          load_vector.clear();
          load_vector.resize(map_index, false);
          for (std::size_t i=0; i<temp.size(); ++i)
            load_vector(i) = temp(i);
        }

     #ifdef VIENNAFEM_DEBUG
        std::cout << "* pde_solver::operator(): Transform to reference element" << std::endl;
     #endif
        EquationType transformed_weak_form = viennafem::transform_to_reference_cell<CellType>(storage, weak_form, pde_system);
        temp[0] = transformed_weak_form;
        log_transformed_weak_form<CellType, StorageType>(temp, pde_system);

        std::cout << "* pde_solver::operator(): Transformed weak form:" << std::endl;
        std::cout << transformed_weak_form << std::endl;
        //std::cout << std::endl;

     #ifdef VIENNAFEM_DEBUG
        std::cout << "* pde_solver::operator(): Assemble system" << std::endl;
     #endif

        typedef detail::equation_wrapper<MatrixT, VectorT>    wrapper_type;
        wrapper_type wrapper(system_matrix, load_vector);

        detail::pde_assembler_internal()(storage, transformed_weak_form, pde_system, domain, wrapper);
//        pde_assembler_internal()(transformed_weak_form, pde_system, domain, system_matrix, load_vector);

      }
예제 #16
0
void CholeskyDecomposition<T>::LTBackSub(const VectorT& b, VectorT& x) const
{
	x.resize(L.n);
	if(!LtBackSubstitute(L,b,x)) FatalError("CholeskyDecomposition: LtBackSubstitute failed!");
}