Esempio n. 1
0
Teuchos::RCP< Stokhos::Sparse3Tensor<ordinal_type, value_type> >
Stokhos::CompletePolynomialBasis<ordinal_type, value_type>::
computeTripleProductTensorOld(ordinal_type order) const
{
  // Compute Cijk = < \Psi_i \Psi_j \Psi_k >
  Teuchos::RCP< Stokhos::Sparse3Tensor<ordinal_type, value_type> > Cijk = 
    Teuchos::rcp(new Sparse3Tensor<ordinal_type, value_type>);

  // Create 1-D triple products
  Teuchos::Array< Teuchos::RCP<Dense3Tensor<ordinal_type,value_type> > > Cijk_1d(d);
  for (ordinal_type i=0; i<d; i++)
    Cijk_1d[i] = bases[i]->computeTripleProductTensor();

  for (ordinal_type j=0; j<sz; j++) {
    for (ordinal_type i=0; i<sz; i++) {
      for (ordinal_type k=0; k<order; k++) {
	value_type c = value_type(1.0);
	for (ordinal_type l=0; l<d; l++)
	  c *= (*Cijk_1d[l])(terms[i][l],terms[j][l],terms[k][l]);
	if (std::abs(c/norms[i]) > sparse_tol)
	  Cijk->add_term(i,j,k,c);
      }
    }
  }

  Cijk->fillComplete();

  return Cijk;
}
Esempio n. 2
0
Teuchos::RCP< Stokhos::Sparse3Tensor<ordinal_type, value_type> >
Stokhos::CompletePolynomialBasis<ordinal_type, value_type>::
computeTripleProductTensorNew(ordinal_type order) const
{
  // The algorithm for computing Cijk = < \Psi_i \Psi_j \Psi_k > here works
  // by factoring 
  // < \Psi_i \Psi_j \Psi_k > = 
  //    < \psi^1_{i_1}\psi^1_{j_1}\psi^1_{k_1} >_1 x ... x
  //    < \psi^d_{i_d}\psi^d_{j_d}\psi^d_{k_d} >_d
  // We compute the sparse triple product < \psi^l_i\psi^l_j\psi^l_k >_l
  // for each dimension l, and then compute all non-zero products of these
  // terms.  The complexity arises from iterating through all possible
  // combinations, throwing out terms that aren't in the basis and are beyond
  // the k-order limit provided
  Teuchos::RCP< Stokhos::Sparse3Tensor<ordinal_type, value_type> > Cijk = 
    Teuchos::rcp(new Sparse3Tensor<ordinal_type, value_type>);

  // Map the specified order limit to a limit on each dimension
  // Subtract 1 to get the term for the last order we want to include,
  // add up the orders for each term to get the total order, then add 1
  MultiIndex<ordinal_type> term = this->term(order-1);
  ordinal_type k_lim = 0;
  for (ordinal_type i=0; i<d; i++)
    k_lim = k_lim + term[i];
  k_lim++;

  // Create 1-D triple products
  Teuchos::Array< Teuchos::RCP<Sparse3Tensor<ordinal_type,value_type> > > Cijk_1d(d);
  for (ordinal_type i=0; i<d; i++) {
    if (k_lim <= basis_orders[i]+1)
      Cijk_1d[i] = bases[i]->computeSparseTripleProductTensor(k_lim);
    else
      Cijk_1d[i] = bases[i]->computeSparseTripleProductTensor(basis_orders[i]+1);
  }

  // Create i, j, k iterators for each dimension
  // Note:  we have to supply an initializer in the arrays of iterators to 
  // avoid checked-stl errors about singular iterators
  typedef Sparse3Tensor<ordinal_type,value_type> Cijk_type;
  typedef typename Cijk_type::k_iterator k_iterator;
  typedef typename Cijk_type::kj_iterator kj_iterator;
  typedef typename Cijk_type::kji_iterator kji_iterator;
  Teuchos::Array<k_iterator> k_iterators(d, Cijk_1d[0]->k_begin());
  Teuchos::Array<kj_iterator > j_iterators(d, Cijk_1d[0]->j_begin(k_iterators[0]));
  Teuchos::Array<kji_iterator > i_iterators(d, Cijk_1d[0]->i_begin(j_iterators[0]));
  MultiIndex<ordinal_type> terms_i(d), terms_j(d), terms_k(d);
  ordinal_type sum_i = 0;
  ordinal_type sum_j = 0;
  ordinal_type sum_k = 0;
  for (ordinal_type dim=0; dim<d; dim++) {
    k_iterators[dim] = Cijk_1d[dim]->k_begin();
    j_iterators[dim] = Cijk_1d[dim]->j_begin(k_iterators[dim]);
    i_iterators[dim] = Cijk_1d[dim]->i_begin(j_iterators[dim]);
    terms_i[dim] = Stokhos::index(i_iterators[dim]);
    terms_j[dim] = Stokhos::index(j_iterators[dim]);
    terms_k[dim] = Stokhos::index(k_iterators[dim]);
    sum_i += terms_i[dim];
    sum_j += terms_j[dim];
    sum_k += terms_k[dim];
  }

  ordinal_type I = 0;
  ordinal_type J = 0;
  ordinal_type K = 0;
  bool inc_i = true;
  bool inc_j = true;
  bool inc_k = true;
  bool stop = false;
  ordinal_type cnt = 0;
  while (!stop) {

    // Add term if it is in the basis
    if (sum_i <= p && sum_j <= p && sum_k <= p) {
      if (inc_k)
	K = CPBUtils::compute_index(terms_k, terms, num_terms, p);
      if (K < order) {
	if (inc_i)
	  I = CPBUtils::compute_index(terms_i, terms, num_terms, p);
	if (inc_j)
	  J = CPBUtils::compute_index(terms_j, terms, num_terms, p);
	value_type c = value_type(1.0);
	for (ordinal_type dim=0; dim<d; dim++)
	  c *= value(i_iterators[dim]);
	if (std::abs(c/norms[I]) > sparse_tol)
	  Cijk->add_term(I,J,K,c);
      }
    }
    
    // Increment iterators to the next valid term
    ordinal_type cdim = 0;
    bool inc = true;
    inc_i = false;
    inc_j = false; 
    inc_k = false;
    while (inc && cdim < d) {
      ordinal_type cur_dim = cdim;
      ++i_iterators[cdim];
      inc_i = true;
      if (i_iterators[cdim] != Cijk_1d[cdim]->i_end(j_iterators[cdim])) {
	terms_i[cdim] = Stokhos::index(i_iterators[cdim]);
	sum_i = 0;
	for (int dim=0; dim<d; dim++)
	  sum_i += terms_i[dim];
      }
      if (i_iterators[cdim] == Cijk_1d[cdim]->i_end(j_iterators[cdim]) ||
	sum_i > p) {
	++j_iterators[cdim];
	inc_j = true;
	if (j_iterators[cdim] != Cijk_1d[cdim]->j_end(k_iterators[cdim])) {
	  terms_j[cdim] = Stokhos::index(j_iterators[cdim]);
	  sum_j = 0;
	  for (int dim=0; dim<d; dim++)
	    sum_j += terms_j[dim];
	}
	if (j_iterators[cdim] == Cijk_1d[cdim]->j_end(k_iterators[cdim]) ||
	  sum_j > p) {
	  ++k_iterators[cdim];
	  inc_k = true;
	  if (k_iterators[cdim] != Cijk_1d[cdim]->k_end()) {
	    terms_k[cdim] = Stokhos::index(k_iterators[cdim]);
	    sum_k = 0;
	    for (int dim=0; dim<d; dim++)
	      sum_k += terms_k[dim];
	  }
	  if (k_iterators[cdim] == Cijk_1d[cdim]->k_end() || sum_k > p) {
	    k_iterators[cdim] = Cijk_1d[cdim]->k_begin();
	    ++cdim;
	    terms_k[cur_dim] = Stokhos::index(k_iterators[cur_dim]);
	    sum_k = 0;
	    for (int dim=0; dim<d; dim++)
	      sum_k += terms_k[dim];
	  }
	  else
	    inc = false;
	  j_iterators[cur_dim] = 
	    Cijk_1d[cur_dim]->j_begin(k_iterators[cur_dim]);
	  terms_j[cur_dim] = Stokhos::index(j_iterators[cur_dim]);
	  sum_j = 0;
	  for (int dim=0; dim<d; dim++)
	    sum_j += terms_j[dim];
	}
	else
	  inc = false;
	i_iterators[cur_dim] = Cijk_1d[cur_dim]->i_begin(j_iterators[cur_dim]);
	terms_i[cur_dim] = Stokhos::index(i_iterators[cur_dim]);
	sum_i = 0;
	for (int dim=0; dim<d; dim++)
	  sum_i += terms_i[dim];
      }
      else
	inc = false;

      if (sum_i > p || sum_j > p || sum_k > p)
	inc = true;
    }

    if (cdim == d)
      stop = true;

    cnt++;
  }

  Cijk->fillComplete();

  return Cijk;
}
Esempio n. 3
0
TEUCHOS_UNIT_TEST( Stokhos_Sparse3Tensor, Sparsity ) {
    Teuchos::RCP< Stokhos::Sparse3Tensor<int, double> > Cijk_quad =
        Teuchos::rcp(new Stokhos::Sparse3Tensor<int,double>);

    // Create 1-D triple products
    Teuchos::Array< Teuchos::RCP<Stokhos::Dense3Tensor<int,double> > > Cijk_1d(setup.d);
    for (int i=0; i<setup.d; i++)
        Cijk_1d[i] = setup.bases[i]->computeTripleProductTensor();

    for (int j=0; j<setup.sz; j++) {
        Stokhos::MultiIndex<int> terms_j = setup.basis->term(j);
        for (int i=0; i<setup.sz; i++) {
            Stokhos::MultiIndex<int> terms_i = setup.basis->term(i);
            for (int k=0; k<setup.sz; k++) {
                Stokhos::MultiIndex<int> terms_k = setup.basis->term(k);
                double c = 1.0;
                for (int l=0; l<setup.d; l++)
                    c *= (*Cijk_1d[l])(terms_i[l],terms_j[l],terms_k[l]);
                if (std::abs(c/setup.basis->norm_squared(i)) > setup.sparse_tol)
                    Cijk_quad->add_term(i,j,k,c);
            }
        }
    }
    Cijk_quad->fillComplete();

    // Check number of nonzeros
    int nnz = setup.Cijk->num_entries();
    int nnz_quad = Cijk_quad->num_entries();
    success = (nnz == nnz_quad);
    if (!success)
        out << std::endl
            << "Check:  nnz(C) = " << nnz << " == nnz(C_quad) = " << nnz_quad
            << ":  Failed";
    for (Cijk_type::k_iterator k_it=Cijk_quad->k_begin();
            k_it!=Cijk_quad->k_end(); ++k_it) {
        int k = Stokhos::index(k_it);
        for (Cijk_type::kj_iterator j_it = Cijk_quad->j_begin(k_it);
                j_it != Cijk_quad->j_end(k_it); ++j_it) {
            int j = Stokhos::index(j_it);
            for (Cijk_type::kji_iterator i_it = Cijk_quad->i_begin(j_it);
                    i_it != Cijk_quad->i_end(j_it); ++i_it) {
                int i = Stokhos::index(i_it);
                double c = setup.Cijk->getValue(i,j,k);
                double c2 = Stokhos::value(i_it);

                double tol = setup.atol + c2*setup.rtol;
                double err = std::abs(c-c2);
                bool s = err < tol;
                if (!s) {
                    out << std::endl
                        << "Check: rel_err( C(" << i << "," << j << "," << k << ") )"
                        << " = " << "rel_err( " << c << ", " << c2 << " ) = " << err
                        << " <= " << tol << " : ";
                    if (s) out << "Passed.";
                    else
                        out << "Failed!";
                    out << std::endl;
                }
                success = success && s;
            }
        }
    }
}