예제 #1
0
void LUforw ( ptrdiff_t first, ptrdiff_t last, ptrdiff_t n, ptrdiff_t nu, ptrdiff_t maxmod,
              double eps, double *L, double *U, double *y )
{

/* ------------------------------------------------------------------
   LUforw updates the factors LC = U by performing a forward sweep
   to eliminate subdiagonals in a row spike in row 'last' of U.

   L     is n by n.
   U     is n by nu.
   y[*]  contains the row spike.  The first nonzero to be eliminated
         is in y[first] or later.
   The 'spike' row of L begins at L[ls].

   18 Mar 1990: First version with L and U stored row-wise.
   ------------------------------------------------------------------ */

  ptrdiff_t    lu, ll, ls, incu, ly, numu;
  double cs, sn;


  lu     = (first - 1)*maxmod + (3 - first)*first/2;
  ll     = (first - 1)*maxmod + 1;
  ls     = (last  - 1)*maxmod + 1;
  incu   = maxmod + 1 - first;

  for (ly = first; ly<last; ly++) {

/*   See if this element of y is worth eliminating.
     We compare y[ly] with the corresponding diagonal of U. */

     if ( fabs(y[ly]) > eps * fabs(U[lu]) ) {

/*   Generate a 2x2 elimination and apply it to U and L. */

        numu   = nu - ly;
        elmgen( &U[lu], &y[ly]  , eps    , &cs, &sn );
        if (numu > 0)
           elm ( 1, numu , &U[lu], &y[ly], cs, sn );
        elm ( 1, n, &L[subvec(ll)], &L[subvec(ls)], cs, sn );
     }

     ll    += maxmod;
     lu    += incu;
     incu--;
  }

/* Copy the remaining part of y into U. */

  numu     = nu - last + 1;
  if (numu > 0)
    LUdcopy ( numu, &y[subvec(last)], 1, &U[subvec(lu)], 1 );

/*   End of LUforw */
}
예제 #2
0
int CGSolver(SparseMatrix A,    // CSR format matrix
             const std::vector<double> &b,
             std::vector<double> &u,
             double tol,
             std::map<int, std::vector<double>> &soln_iter) {
    unsigned int n_iter = 0;
    long unsigned int max_iter = A.GetRows();

    soln_iter[n_iter] = u;    // store initial state
    auto A_u = A.MulVec(u);   // A*u
    std::vector<double> r = subvec(b, A_u);   // b - A*u
    auto L2normr0 = L2norm(r);
    std::vector<double> p = r;    // p =r

    while (n_iter < max_iter) {
        n_iter++;
        auto A_p = A.MulVec(p);                         // A * p
        double alpha = vecvec(r, r) / vecvec(p, A_p);   // (r * r)/(p * A * p)

        auto alpha_p = scalvec(alpha, p);   // alpha * p
        u = addvec(u, alpha_p);             // u = u + alpha * p

        /**
         * alpha * A * p
         * r_n+1 = r_n - alpha * A * p
         */
        std::vector<double> alpha_A_p = scalvec(alpha, A_p);
        std::vector<double> r_next = subvec(r, alpha_A_p);

        auto L2normr = L2norm(r_next);  // L2normr = L2norm(r_n+1)

        if (L2normr / L2normr0 < tol) {
            soln_iter[n_iter] = u;
            std::cout << "SUCCESS: CG solver converged in "
                      << n_iter << " iterations" << std::endl;
            break;
        } else {
            double beta = vecvec(r_next, r_next) / vecvec(r, r);
            auto beta_p = scalvec(beta, p);

            p = addvec(r_next, beta_p);
            r = r_next;

            if ((n_iter % 10 == 0) || (n_iter == 0)) {
                soln_iter[n_iter] = u;
            }
            if (n_iter == max_iter) {
                std::cout << "FAILURE: CG solver failed to converge" << std::endl;
                return 1;
            }
        }
    }
    return 0;
}
예제 #3
0
void Usolve ( int mode, ptrdiff_t maxmod, ptrdiff_t n,
              double *U, double *y )
{

  double sum, hold;
  ptrdiff_t    lu, incu, nu, i;


/* ------------------------------------------------------------------
   If  mode = 1,  Usolve solves U * y[new] = y[old].
   If  mode = 2,  Usolve solves U[transpose] * y[new] = y[old].
   U is upper triangular, stored by rows.
   y is overwritten by the solution.
   ------------------------------------------------------------------ */

  if (mode == 1) {
     lu     = (n - 1)*maxmod + (3 - n)*n/2;
     hold   = U[lu];
     y[n]  /= hold;
     incu   = maxmod + 1 - n;
     nu     = 0;

     for (i = n-1; i>=1; i--) {
        nu++;
        incu++;
        lu   -= incu;
        sum   = y[i] - LUddot ( nu, &U[subvec(lu+1)], 1, &y[subvec(i+1)], 1 );
        hold  = U[lu];
        y[i]  = sum / hold;
     }
  }
  else {
     lu     = 1;
     incu   = maxmod;
     nu     = n - 1;

     for (i = 1; i<n; i++) {
        hold = U[lu];
        y[i] /= hold;
        LUdaxpy ( nu, -y[i], &U[subvec(lu+1)], 1, &y[subvec(i+1)], 1 );
        lu   += incu;
        incu--;
        nu--;
     }
     hold = U[lu];
     y[n]  /= hold;
  }

/*    End of Usolve */
}
예제 #4
0
arma_inline
const subview_col<eT>
Col<eT>::operator()(const span& row_span) const
  {
  arma_extra_debug_sigprint();
  
  return subvec(row_span);
  }
예제 #5
0
arma_inline
subview_col<eT>
Col<eT>::rows(const span& row_span)
  {
  arma_extra_debug_sigprint();
  
  return subvec(row_span);
  }
예제 #6
0
arma_inline
const subview_row<eT>
Row<eT>::operator()(const span& col_span) const
{
    arma_extra_debug_sigprint();

    return subvec(col_span);
}
예제 #7
0
arma_inline
subview_row<eT>
Row<eT>::cols(const span& col_span)
{
    arma_extra_debug_sigprint();

    return subvec(col_span);
}
예제 #8
0
void Lprod ( int mode, ptrdiff_t maxmod, ptrdiff_t n,
             double *L, double *y, double *z )
{

  ptrdiff_t ll, i;



/* ------------------------------------------------------------------
   If  mode = 1,  Lprod  computes  z = L*y.
   If  mode = 2,  Lprod  computes  z = L[transpose]*y.
   L is stored by rows in L[*].  It is equivalent to storing
   L[transpose] by columns in a 2-D array L[maxmod,n].
   y is not altered.
   ------------------------------------------------------------------ */

  ll     = 1;
  if (mode == 1) {
     for (i = 1; i<=n; i++) {
        z[i]  = LUddot ( n, &L[subvec(ll)], 1, y, 1 );
        ll   += maxmod;
     }
  }
  else {
/*        call dzero ( n, z, 1 ) */
     for (i = 1; i<=n; i++)
        z[i]  = 0;

     for (i = 1; i<=n; i++) {
        LUdaxpy ( n, y[i], &L[subvec(ll)], 1, z, 1 );
        ll   += maxmod;
     }
  }

/*     End of Lprod */
}
예제 #9
0
파일: vector.cpp 프로젝트: otoauler/sdkpub
Vector<T> Vector<T>::get(int i, int l)
{
    if ( (i + l) > rows() )
    {
#ifdef USE_EXCEPTION
        throw MatrixErr() ;
#else
        Error error("Vector<T>::get(int,Vector<T>)");
        error << "Vector is too long to extract from  i= " << i << "from l=" << l << endl ;
        error.fatal() ;
#endif
    }

    Vector<T> subvec(l) ;
    T *aptr, *bptr ;
    aptr = &this->x[i] - 1 ;
    bptr = subvec.x -1 ;
    for ( int j = l; j > 0; --j)
        *(++bptr) = *(++aptr) ;
    return subvec ;
}
예제 #10
0
파일: myblas.c 프로젝트: gtqite/ssc
int submat( int nrowb, int row, int col)
{
  return( nrowb*(col-1) + subvec(row) );
}
예제 #11
0
void LUback ( ptrdiff_t first, ptrdiff_t *last, ptrdiff_t n, ptrdiff_t nu,
              ptrdiff_t maxmod, double eps,
              double *L, double *U, double *y, double *z )
{

/* ------------------------------------------------------------------
   LUback updates the factors LC = U by performing a backward sweep
   to eliminate all but the 'last' nonzero in the column vector z[*],
   stopping at z[first].

   If 'last' is positive, LUback searches backwards for a nonzero
   element in z and possibly alters 'last' accordingly.
   Otherwise, 'last' will be reset to abs(last) and so used.

   L     is n by n.
   U     is n by nu.
   y[*]  will eventually contain a row spike in row 'last' of U.
   The 'spike' row of L begins at L[ls].

   18 Mar 1990: First version with L and U stored row-wise.
   29 Jun 1999: Save w[last] = zlast at end so column replace
                can do correct forward sweep.
   ------------------------------------------------------------------ */

  ptrdiff_t    i, lz, lu, ll,ls, incu, numu;
  double zero = 0.0;
  double zlast, cs, sn;


  if ((*last) > 0) {

/*   Find the last significant element in z[*]. */

     for (i = (*last); i>first; i--)
        if (fabs(z[i]) > eps) break;

     (*last)   = i;
  }
  else
     (*last)   = abs((*last));

/*  Load the 'last' row of U into the end of y
    and do the backward sweep. */

  zlast  = z[(*last)];
  lu     = ((*last)  - 1)*maxmod + (3 - (*last))*(*last)/2;
  ll     = ((*last)  - 1)*maxmod + 1;
  ls     = ll;
  incu   = maxmod + 1 - (*last);
  numu   = nu     + 1 - (*last);
  if (numu > 0)
    LUdcopy ( numu, &U[subvec(lu)], 1, &y[subvec((*last))], 1 );

  for (lz = (*last) - 1; lz>=first; lz--) {
     ll    -= maxmod;
     incu++;
     lu    -= incu;
     y[lz]  = zero;

/*   See if this element of z is worth eliminating.
     We compare z[lz] with the current last nonzero, zlast. */

     if ( fabs(z[lz]) <= eps * fabs(zlast) ) continue;

/*   Generate a 2x2 elimination and apply it to U and L. */

     numu   = nu + 1 - lz;
     elmgen( &zlast, &z[lz], eps   , &cs, &sn );
     elm   ( 1, numu , &y[subvec(lz)], &U[subvec(lu)], cs, sn );
     elm   ( 1, n    , &L[subvec(ls)], &L[subvec(ll)], cs, sn );
  }

  z[(*last)] = zlast;

/*   End of LUback */
}
예제 #12
0
void LUmod ( int mode, ptrdiff_t maxmod, ptrdiff_t n, ptrdiff_t krow, ptrdiff_t kcol,
             double *L, double *U, double *y, double *z, double *w)
{
  ptrdiff_t    first, last, n1, i, j, lastu, lastl, ls, ll, lu, incu;
  double zero = 0.0;
  double one  = 1.0;
  double eps  = MACHINEPREC;   /* The machine precision -- A value slightly too large is OK. */


  n1 = n - 1;

  if (mode == 1) {
/*   ---------------------------------------------------------------
     mode = 1.  Add a row y and a column z.
     The LU factors will expand in dimension from n-1 to n.
     The new diagonal element of C is in y[n].
     --------------------------------------------------------------- */
     lastu    = n1*maxmod + (3 - n)*n/2;
     lastl    = n1*maxmod + n;
     ls       = n1*maxmod + 1;
     L[lastl] = one;
     if (n == 1) {
        U[lastu] = y[n];
        return;
     }

/*   Compute L*z and temporarily store it in w;
     (changed to w from last row of L by KE). */

     Lprod ( 1, maxmod, n1, L, z, w );

/*       Copy L*z into the new last column of U.
         Border L with zeros. */

     ll     = ls;
     lu     = n;
     incu   = maxmod - 1;
     for (j = 1; j<=n1; j++) {
        U[lu] = w[j];
        L[ll] = zero;
        ll++;
        lu   += incu;
        incu--;
     }

     ll     = n;
     for (i = 1; i<=n1; i++) {
        L[ll] = zero;
        ll   += maxmod;
     }

/*   Add row y to the factorization
     using a forward sweep of eliminations. */

     last   = n;
     LUforw ( 1, last, n, n, maxmod, eps, L, U, y );

  }
  else if (mode == 2) {
/*   ---------------------------------------------------------------
     mode=2.  Replace the kcol-th column of C by the vector z.
     ---------------------------------------------------------------*/

/*   Compute w = L*z. */

     Lprod ( 1, maxmod, n, L, z, w );

/*   Copy the top of w into column kcol of U. */

     lu     = kcol;
     incu   = maxmod - 1;
     for (i = 1; i<=kcol; i++) {
        U[lu] = w[i];
        lu   += incu;
        incu--;
     }

     if (kcol < n) {

/*      Find w[last], the last nonzero in the bottom part of w.
        Eliminate elements last-1, last-2, ... kcol+1 of w[*]
        using a partial backward sweep of eliminations. */

        first  = kcol + 1;
        last   = n;
        LUback( first, &last, n, n, maxmod, eps, L, U, y, w );
        y[kcol] = w[last];

/*      Eliminate elements kcol, kcol+1, ... last-1 of y[*]
        using a partial forward sweep of eliminations. */

        LUforw ( kcol, last, n, n, maxmod, eps, L, U, y );
     }

  }
  else if (mode == 3) {
/*   ---------------------------------------------------------------
     mode=3.  Replace the krow-th row of C by the vector y.
     --------------------------------------------------------------- */
     if (n == 1) {
        L[1] = one;
        U[1] = y[1];
        return;
     }

/*   Copy the krow-th column of L into w, and zero the column. */

     ll     = krow;
     for (i = 1; i<=n; i++) {
        w[i]  = L[ll];
        L[ll] = zero;
        ll   += maxmod;
     }

/*   Reduce the krow-th column of L to the unit vector e(last).
     where 'last' is determined by LUback.
     This is done by eliminating elements last-1, last-2, ..., 1
     using a backward sweep of eliminations.
     On exit, row 'last' of U is a spike stored in z, whose first
     nonzero entry is in z[first].  However, z will be discarded. */

     first  = 1;
     last   = n;
     LUback ( first, &last, n, n, maxmod, eps, L, U, z, w );

/*   Replace the 'last' row of L by the krow-th unit vector. */

     ll     = (last - 1)*maxmod;
     for (j = 1; j<=n; j++)
        L[ll + j] = zero;
     L[ll + krow] = one;

/*   Eliminate the elements of the new row y,
     using a forward sweep of eliminations. */

     LUforw ( 1, last, n, n, maxmod, eps, L, U, y );

  }

  else if (mode == 4) {
/*   ---------------------------------------------------------------
     mode=4.  Delete the krow-th row and the kcol-th column of C.
              Replace them by the last row and column respectively.
     --------------------------------------------------------------- */

/*   First, move the last column into position kcol. */

     if (kcol < n) {

/*      Set w = last column of U. */

        lu     = n;
        incu   = maxmod - 1;
        for (i = 1; i<=n; i++) {
           w[i] = U[lu];
           lu  += incu;
           incu--;
        }

/*      Copy the top of w into column kcol of U. */

        lu     = kcol;
        incu   = maxmod - 1;
        for (i = 1; i<=kcol; i++) {
           U[lu] = w[i];
           lu   += incu;
           incu--;
        }

/*      U now has only n-1 columns.
        Find w[last], the last nonzero in the bottom part of w.
        Eliminate elements last-1, last-2, ... kcol+1 of w[*]
        using a partial backward sweep of eliminations. */

        first  = kcol + 1;
        last   = n;
        LUback ( first, &last, n, n1, maxmod, eps, L, U, y, w );
        y[kcol] = w[last];

/*      Eliminate elements kcol, kcol+1, ... last-1 of y[*]
        using a partial forward sweep of eliminations. */

        LUforw ( kcol, last, n, n1, maxmod, eps, L, U, y );
     }

/*   Now, move the last row into position krow. */

/*   Swap columns krow and n of L, using w = krow-th column of L. */

     LUdcopy ( n, &L[subvec(krow)], maxmod, w, 1 );
     if (krow < n)
        LUdcopy ( n, &L[subvec(n)], maxmod, &L[subvec(krow)], maxmod );

/*   Reduce the last column of L (in w) to the unit vector e(n).
     This is done by eliminating elements n-1, n-2, ..., 1
     using a backward sweep of eliminations. */

     last   = - n;
     LUback ( 1, &last, n, n1, maxmod, eps, L, U, z, w );
     /* printvec(n, w, 0); */
     /* printmatUT(maxmod, n, U, 0); */
     /* printmatSQ(maxmod, n, L, 0); */
  }

/*     End of LUmod  */
}
예제 #13
0
  void NeumannVolume<D> ::
  T_CalcElementVector (const FiniteElement & base_fel,
		       const ElementTransformation & eltrans, 
		       FlatVector<SCAL> elvec,
		       LocalHeap & lh) const {

    const CompoundFiniteElement &  cfel  
      =  dynamic_cast<const CompoundFiniteElement&> (base_fel);

    const ScalarFiniteElement<D> & fel = 
      dynamic_cast<const ScalarFiniteElement<D>&> (cfel[indx]);

    FlatVector<> ushape(fel.GetNDof(), lh);
    elvec = SCAL(0);    
    IntRange re = cfel.GetRange(indx);
    int ndofe = re.Size();
    FlatVector<SCAL> subvec(ndofe,lh);
    subvec = SCAL(0);

    const IntegrationRule ir(fel.ElementType(), 2*fel.Order());
    ELEMENT_TYPE eltype = base_fel.ElementType();        
    int nfacet = ElementTopology::GetNFacets(eltype);
    Facet2ElementTrafo transform(eltype); 
    FlatVector< Vec<D> > normals = ElementTopology::GetNormals<D>(eltype);

    const MeshAccess & ma = *(const MeshAccess*)eltrans.GetMesh();

    Array<int> fnums, sels;
    ma.GetElFacets (eltrans.GetElementNr(), fnums);

    for (int k = 0; k < nfacet; k++)    {

      ma.GetFacetSurfaceElements (fnums[k], sels);

      // if interior element, then do nothing:
      if (sels.Size() == 0) continue; 

      // else: 

      Vec<D> normal_ref = normals[k];

      ELEMENT_TYPE etfacet = ElementTopology::GetFacetType (eltype, k);

      IntegrationRule ir_facet(etfacet, 2*fel.Order());
      
      // map the facet integration points to volume reference elt ipts
      IntegrationRule & ir_facet_vol = transform(k, ir_facet, lh);
      // ... and further to the physical element 
      MappedIntegrationRule<D,D> mir(ir_facet_vol, eltrans, lh);

      for (int i = 0 ; i < ir_facet_vol.GetNIP(); i++) {
	
       	SCAL G[3] ;
	G[0] = coeff_Gx -> T_Evaluate<SCAL>(mir[i]);
	G[1] = coeff_Gy -> T_Evaluate<SCAL>(mir[i]);
	if (D==3)  G[2] = coeff_Gz -> T_Evaluate<SCAL>(mir[i]);
	FlatVector<SCAL> Gval(D,lh);	
	for (int dd=0; dd<D; dd++)  Gval[dd] = G[dd];
	SCAL g = coeff_g -> T_Evaluate<SCAL>(mir[i]);

	// this is contrived to get the surface measure in "len"
	Mat<D> inv_jac = mir[i].GetJacobianInverse();
	double det = mir[i].GetMeasure();
	Vec<D> normal = det * Trans (inv_jac) * normal_ref;       
	double len = L2Norm (normal);    
	
	SCAL gg = (InnerProduct(Gval,normal) + g*len)
	          * ir_facet[i].Weight();
		
	fel.CalcShape (ir_facet_vol[i], ushape);
	        
	subvec += gg * ushape;
      }   
    }
    elvec.Rows(re) += subvec;
  }