void gradient( Vector<Real> &g, const Vector<Real> &x, Real &tol ) {
   DualSROMVector<Real> &eg = Teuchos::dyn_cast<DualSROMVector<Real> >(g);
   const PrimalSROMVector<Real> &ex = Teuchos::dyn_cast<const PrimalSROMVector<Real> >(x);
   size_t dimension  = ex.getDimension();
   size_t numSamples = ex.getNumSamples();
   std::vector<Real> gradx(numSamples,0.), gradp(numSamples,0.);
   Real scale = 0.;
   std::vector<std::pair<size_t, Real> > data;
   std::vector<Real> val_wt(numSamples,0.), tmp(dimension,0.);
   std::vector<std::vector<Real> > val_pt(numSamples,tmp);
   for (size_t d = 0; d < dimension; d++) {
     data = moments_[d];
     for (size_t m = 0; m < data.size(); m++) {
       momentGradient(gradx,gradp,scale,d,(Real)data[m].first,data[m].second,ex);
       for (size_t k = 0; k < numSamples; k++) {
         (val_pt[k])[d] += scale*gradx[k];
         val_wt[k]      += scale*gradp[k];
       }
     }
   }
   for (size_t k = 0; k < numSamples; k++) {
     eg.setPoint(k,val_pt[k]);
     eg.setWeight(k,val_wt[k]);
   }
 }
 void hessVec( Vector<Real> &hv, const Vector<Real> &v, const Vector<Real> &x, Real &tol ) {
   DualSROMVector<Real> &ehv = Teuchos::dyn_cast<DualSROMVector<Real> >(hv);
   const PrimalSROMVector<Real> &ev = Teuchos::dyn_cast<const PrimalSROMVector<Real> >(v);
   const PrimalSROMVector<Real> &ex = Teuchos::dyn_cast<const PrimalSROMVector<Real> >(x);
   const size_t dimension  = ex.getDimension();
   const size_t numSamples = ex.getNumSamples();
   std::vector<Real> hvx1(numSamples,0.), hvx2(numSamples,0.), hvx3(numSamples,0.);
   std::vector<Real> hvp1(numSamples,0.), hvp2(numSamples,0.);
   Real scale1 = 0., scale2 = 0., scale3 = 0.;
   std::vector<std::pair<size_t, Real> > data;
   std::vector<Real> val_wt(numSamples,0.), tmp(dimension,0.);
   std::vector<std::vector<Real> > val_pt(numSamples,tmp);
   for (size_t d = 0; d < dimension; d++) {
     data = moments_[d];
     for (size_t m = 0; m < data.size(); m++) {
       momentHessVec(hvx1,hvx2,hvx3,hvp1,hvp2,scale1,scale2,scale3,
                     d,(Real)data[m].first,data[m].second,ex,ev);
       for (size_t k = 0; k < numSamples; k++) {
         (val_pt[k])[d] += (scale1+scale3)*hvx1[k] + scale2*(hvx2[k]+hvx3[k]);
         val_wt[k]      += (scale1+scale3)*hvp1[k] + scale2*hvp2[k];
       }
     }
   }
   for (size_t k = 0; k < numSamples; k++) {
     ehv.setPoint(k,val_pt[k]);
     ehv.setWeight(k,val_wt[k]);
   }
 }
 void gradient( Vector<Real> &g, const Vector<Real> &x, Real &tol ) {
   SROMVector<Real> &eg = Teuchos::dyn_cast<SROMVector<Real> >(g);
   const SROMVector<Real> &ex = Teuchos::dyn_cast<const SROMVector<Real> >(x);
   const int dimension  = ex.getDimension();
   const int numSamples = ex.getNumSamples();
   std::vector<Real> gradx(numSamples,0.), gradp(numSamples,0.);
   Real diff = 0., xpt = 0., val = 0., sum = 0.;
   std::vector<Real> val_wt(numSamples,0.), tmp(dimension,0.);
   std::vector<std::vector<Real> > val_pt(numSamples,tmp);
   for (int d = 0; d < dimension; d++) {
     for (int k = 0; k < numSamples; k++) {
       xpt = (*ex.getPoint(k))[d];
       val = gradientCDF(gradx,gradp,d,xpt,ex);
       diff = (val-dist_[d]->evaluateCDF(xpt));
       sum = 0.;
       for (int j = 0; j < numSamples; j++) {
         (val_pt[j])[d] += diff * gradx[j];
         val_wt[j]      += diff * gradp[j];
         sum            -= gradx[j]; 
       }
       (val_pt[k])[d] += diff * (sum - dist_[d]->evaluatePDF(xpt));
     }
   }
   for (int k = 0; k < numSamples; k++) {
     eg.setPoint(k,val_pt[k]);
     eg.setWeight(k,val_wt[k]);
   }
 }