Expr SpectralPreprocessor::projectSpectral( const Array<Array<Expr> >& terms) { Expr rtn = 0.0; for (int t=0; t<terms.size(); t++) { Expr test; Expr deterministic; Array<Expr> specs; Array<Expr> testCoeffs; Array<Array<Expr> > specCoeffs; Array<SpectralBasis> specBas; parseProduct(terms[t], test, deterministic, specs); const SpectralExpr* specTest = dynamic_cast<const SpectralExpr*>(test.ptr().get()); TEUCHOS_TEST_FOR_EXCEPT(specTest==0); SpectralBasis testBasis = specTest->getSpectralBasis(); for (int i=0; i<testBasis.nterms(); i++) { testCoeffs.append(specTest->getCoeff(i)); } for (int i=0; i<specs.size(); i++) { const SpectralExpr* s = dynamic_cast<const SpectralExpr*>(specs[i].ptr().get()); SpectralBasis bas = s->getSpectralBasis(); specBas.append(bas); Array<Expr> c; for (int j=0; j<bas.nterms(); j++) { c.append(s->getCoeff(j)); } specCoeffs.append(c); } if (specs.size()==0) { for (int i=0; i<testBasis.nterms(); i++) { rtn = rtn + testCoeffs[i]*deterministic; } } else if (specs.size()==1) { for (int i=0; i<testBasis.nterms(); i++) { rtn = rtn + testCoeffs[i]*specCoeffs[0][i]*deterministic; } } else if (specs.size()==2U) { for (int i=0; i<testBasis.nterms(); i++) { for (int j=0; j<specBas[0].nterms(); j++) { for (int k=0; k<specBas[1].nterms(); k++) { double w = testBasis.expectation( specBas[0].getElement(j), specBas[1].getElement(k), i) / testBasis.expectation(0,i,i); if (w==0.0) continue; rtn = rtn + w*testCoeffs[i] *specCoeffs[0][j]*specCoeffs[1][k]*deterministic; } } } } else { TEUCHOS_TEST_FOR_EXCEPTION(specs.size() > 2, std::runtime_error, "not ready to work with more than two spectral unks"); } } return rtn; }