bool RKButcherTableauBase<Scalar>::operator== (const RKButcherTableauBase<Scalar>& rkbt) const { if (this->numStages() != rkbt.numStages()) { return false; } if (this->order() != rkbt.order()) { return false; } int N = rkbt.numStages(); // Check b and c first: const Teuchos::SerialDenseVector<int,Scalar> b_ = this->b(); const Teuchos::SerialDenseVector<int,Scalar> c_ = this->c(); const Teuchos::SerialDenseVector<int,Scalar> other_b = rkbt.b(); const Teuchos::SerialDenseVector<int,Scalar> other_c = rkbt.c(); for (int i=0 ; i<N ; ++i) { if (b_(i) != other_b(i)) { return false; } if (c_(i) != other_c(i)) { return false; } } // Then check A: const Teuchos::SerialDenseMatrix<int,Scalar>& A_ = this->A(); const Teuchos::SerialDenseMatrix<int,Scalar>& other_A = rkbt.A(); for (int i=0 ; i<N ; ++i) { for (int j=0 ; j<N ; ++j) { if (A_(i,j) != other_A(i,j)) { return false; } } } return true; }
bool isEmptyRKButcherTableau( const RKButcherTableauBase<Scalar>& rkbt ) { typedef ScalarTraits<Scalar> ST; // Check that numStages > 0 if (rkbt.numStages() == 0) { return true; } // Check that the b vector has _some_ non-zero entry int numNonZero = 0; int numStages_local = rkbt.numStages(); const Teuchos::SerialDenseVector<int,Scalar> b_local = rkbt.b(); for (int i=0 ; i<numStages_local ; ++i) { if (b_local(i) != ST::zero()) { numNonZero++; } } if (numNonZero == 0) { return true; } // There is no reason to check A and c because they can be zero and you're // producing an explicit method as long as b has something in it. return false; }