void
  IntervalGramian<SplineBasis<d,dT,P_construction,s0,s1,sT0,sT1,J0> >::add_level
  (const Index& lambda,
   InfiniteVector<double, Index>& w, const int j,
   const double factor,
   const int J,
   const CompressionStrategy strategy) const
  {
    // quick and dirty:
    // compute a full column of the stiffness matrix
    const int jmax = std::max(j+1, lambda.j()+lambda.e());
    G_.set_level(jmax);
    std::map<size_type,double> e_lambda, col_lambda;
    size_type number_lambda = lambda.k();
    if (lambda.e() == 0) {
      number_lambda -= basis_.DeltaLmin();
    } else {
      number_lambda += basis_.Deltasize(lambda.j())-basis_.Nablamin();
    }
    e_lambda[number_lambda] = 1.0;
    G_.apply(e_lambda, col_lambda);
    
    // extract the entries from level j
    if (j == basis_.j0()-1) {
      // "generator block"
      size_type startrow = 0;
      size_type endrow   = basis_.Deltasize(basis_.j0())-1;
      std::map<size_type,double>::const_iterator it(col_lambda.lower_bound(startrow));
      for (; it != col_lambda.end() && it->first <= endrow; ++it) {
	w.add_coefficient(Index(basis_.j0(), 0, basis_.DeltaLmin()+it->first, &basis_),
			  it->second * factor);
      }
    } else {
      // j>=j0, a "wavelet block"
      size_type startrow = basis_.Deltasize(j);
      size_type endrow   = basis_.Deltasize(j+1)-1;
      std::map<size_type,double>::const_iterator it(col_lambda.lower_bound(startrow));
      for (; it != col_lambda.end() && it->first <= endrow; ++it) {
	w.add_coefficient(Index(j, 1, basis_.Nablamin()+it->first-startrow, &basis_),
			  it->second * factor);
      }
    }
  }  
  double
  PeriodicFrameIntervalGramian<RFRAME>::f(const Index& lambda) const
  {
    // f(v) = \int_0^1 g(t)v(t) dt

    double r = 0;
    
    // first we compute the support of psi_lambda
    const int j = lambda.j()+lambda.e();
    int k1, k2;
    basis_.support(lambda, k1, k2); // note: k2 may be less or equal to k1 in the case of overlap
    const int length = (k2 > k1 ? k2-k1 : k2+(1<<j)-k1); // number of subintervals
    
    // setup Gauss points and weights for a composite quadrature formula:
    const unsigned int N_Gauss = 5;
    const double h = 1.0/(1<<j);

    Array1D<double> gauss_points (N_Gauss*length), vvalues;
    int k = k1;
    for (int patch = 0; patch < length; patch++, k = dyadic_modulo(++k,j)) // work on 2^{-j}[k,k+1]
      for (unsigned int n = 0; n < N_Gauss; n++)
 	gauss_points[patch*N_Gauss+n] = h*(2*k+1+GaussPoints[N_Gauss-1][n])/2;
    //cout << h*k1 << ", " << h*k2 << endl;
    //cout << gauss_points << endl;
    
    
    // - compute point values of the integrand
    basis_.evaluate(0, lambda, gauss_points, vvalues);
    //cout << vvalues << endl;
    // - add all integral shares
    for (int patch = k1, id = 0; patch < k1+length; patch++)
      for (unsigned int n = 0; n < N_Gauss; n++, id++) {
	const double t = gauss_points[id];
	const double gauss_weight = GaussWeights[N_Gauss-1][n] * h;
	    
	const double gt = plp_.g(t);
	if (gt != 0)
	  r += gt
	    * vvalues[id]
	    * gauss_weight;
      }
    //cout << r << endl;
    return r;
  }
  double
  PeriodicFrameIntervalLaplacian<RFRAME>::f(const Index& lambda) const
  {
    // f(v) = \int_0^1 g(t)v(t) dt

    double r = 0;
    
    // first we compute the support of psi_lambda
    const int j = lambda.j()+lambda.e();
    int k1, k2;
    basis_.support(lambda, k1, k2); // note: k2 may be less or equal to k1 in the case of overlap
    const int length = (k2 > k1 ? k2-k1 : k2+(1<<j)-k1); // number of subintervals
    
    // setup Gauss points and weights for a composite quadrature formula:
    unsigned int N_Gauss = 5+lambda.p(); //möglicherweise nötig @PHK
    const double h = 1.0/(1<<j);

    Array1D<double> gauss_points (N_Gauss*length), vvalues;
    int k = k1;
    for (int patch = 0; patch < length; patch++, k = dyadic_modulo(++k,j)) // work on 2^{-j}[k,k+1]
      for (unsigned int n = 0; n < N_Gauss; n++)
 	gauss_points[patch*N_Gauss+n] = h*(2*k+1+GaussPoints[N_Gauss-1][n])/2;
    //cout << h*k1 << ", " << h*k2 << endl;
    //cout << gauss_points << endl;
    
    

    // - compute point values of the integrand
    basis_.evaluate(0, lambda, gauss_points, vvalues, 0); //evaluate without normalization
    //cout << vvalues << endl;
    // - add all integral shares
    for (int patch = k1, id = 0; patch < k1+length; patch++)
      for (unsigned int n = 0; n < N_Gauss; n++, id++) {
	const double t = gauss_points[id];
	const double gauss_weight = GaussWeights[N_Gauss-1][n] * h;
	    
	const double gt = plp_.g(t);
	if (gt != 0)
	  r += gt
	    * vvalues[id]
	    * gauss_weight;
      }
    //cout << r << endl;
    //adaption to normalized scaling functions
    
    if(lambda.e() == 0){
        N_Gauss = 9;
        Array1D<double> gauss_points2 (N_Gauss);
            
            for (unsigned int n = 0; n < N_Gauss; n++){
                    gauss_points2[n] = 0.5+GaussPoints[N_Gauss-1][n]/2;
            }
                    
            
            
//                    cout << h*k1 << ", " << h*k2 << endl;
//                    cout << gauss_points2 << endl;
            
                    const double pvalue = basis_.evaluate(0, lambda, h*k1);
//                    cout << pvalue << endl;
            // - add all integral shares
                for (unsigned int n = 0; n < N_Gauss; n++) {
                        const double t = gauss_points2[n];
                        const double gauss_weight = GaussWeights[N_Gauss - 1][n];

                        const double gt = plp_.g(t);
                        //cout << "(" << t << ", " << gt << ")" <<endl;
                        if (gt != 0)
                            r += gt
                                * pvalue
                                * gauss_weight;
                        //cout << r << endl;
                }
            
       
       
    }
     
    
    return r + 4*basis_.evaluate(0, lambda, 0.25); //second part can be added if you want a delta-distribution added at the rhs @PHK
  }
  Array1D<SampledMapping<2> >
  evaluate(const LDomainJLBasis& basis,
	   const Index& lambda,
	   const int N)
  {
    Array1D<SampledMapping<2> > r(3);

    // supp(psi_{j,e,c,k}) = 2^{-j}[k1-1,k1+1]x[k2-1,k2+1] cap Omega

    FixedArray1D<Array1D<double>,2> values;
    values[0].resize(N+1); // values in x-direction
    values[1].resize(N+1); // values in y-direction
    Array1D<double> knots;
    knots.resize(N+1);
    const double h = 1./N;
    
    // patch Omega_0 = [-1,0]x[0,1]
    for (int i = 0; i <= N; i++) {
      values[0][i] = 0.;
      values[1][i] = 0.;
    }
    if (lambda.k()[0] <= 0 && lambda.k()[1] >= 0) {
      for (int i = 0; i <= N; i++)
	knots[i] = -1.0+i*h;
      evaluate(0, lambda.j(), lambda.e()[0], lambda.c()[0], lambda.k()[0], knots, values[0]);
      for (int i = 0; i <= N; i++)
	knots[i] = i*h;
      evaluate(0, lambda.j(), lambda.e()[1], lambda.c()[1], lambda.k()[1], knots, values[1]);
    }
    r[0] = SampledMapping<2>(Point<2>(-1, 0), Point<2>(0,1), values);
    
    // patch Omega_1 = [-1,0]x[-1,0]
    for (int i = 0; i <= N; i++) {
      values[0][i] = 0.;
      values[1][i] = 0.;
    }
    if (lambda.k()[0] <= 0 && lambda.k()[1] <= 0) {
      for (int i = 0; i <= N; i++)
	knots[i] = -1.0+i*h;
      evaluate(0, lambda.j(), lambda.e()[0], lambda.c()[0], lambda.k()[0], knots, values[0]);
      evaluate(0, lambda.j(), lambda.e()[1], lambda.c()[1], lambda.k()[1], knots, values[1]);
    }
    r[1] = SampledMapping<2>(Point<2>(-1,-1), Point<2>(0,0), values);
    
    // patch Omega_2 = [0,1]x[-1,0]
    for (int i = 0; i <= N; i++) {
      values[0][i] = 0.;
      values[1][i] = 0.;
    }
    if (lambda.k()[0] >= 0 && lambda.k()[1] <= 0) {
      for (int i = 0; i <= N; i++)
	knots[i] = i*h;
      evaluate(0, lambda.j(), lambda.e()[0], lambda.c()[0], lambda.k()[0], knots, values[0]);
      for (int i = 0; i <= N; i++)
	knots[i] = -1.0+i*h;
      evaluate(0, lambda.j(), lambda.e()[1], lambda.c()[1], lambda.k()[1], knots, values[1]);
    }
    r[2] = SampledMapping<2>(Point<2>( 0,-1), Point<2>(1,0), values);
    
    return r;
  }
  void
  JLBasis::reconstruct_1(const Index& lambda,
			 const int j,
			 InfiniteVector<double, Index>& c) const {
    c.clear();
    
    if (lambda.j() >= j)
      c.set_coefficient(lambda, 1.0); 
    else {
#if _JL_PRECOND==0
      const double phi0factor = sqrt(35./26.);
      const double phi1factor = sqrt(105./2.);
#else
      const double phi0factor = sqrt(5./12.);
      const double phi1factor = sqrt(15./4.);
#endif
      if (lambda.e() == 0) {
 	// generator
	if (lambda.c() == 0) {
 	  // type phi_0
 	  // phi_0(x) = 1/2*phi_0(2*x+1)+phi_0(2*x)+1/2*phi_0(2*x-1)+3/4*phi_1(2*x+1)-3/4*phi_1(2*x-1)

	  int m = 2*lambda.k()-1; // m-2k=-1
	  { // phi_0(2x+1)
	    InfiniteVector<double, Index> dhelp;
	    reconstruct_1(Index(lambda.j()+1, 0, 0, m), j, dhelp);
	    c.add(0.5*M_SQRT1_2, dhelp);
	  }
	  if (m >= 0) { // phi_1(2x+1)
	    InfiniteVector<double, Index> dhelp;
	    reconstruct_1(Index(lambda.j()+1, 0, 1, m), j, dhelp);
	    c.add(0.75*M_SQRT1_2 * phi0factor/phi1factor, dhelp);
	  }

	  // m=2k <-> m-2k=0
	  m++;
	  { // phi_0(2x)
	    InfiniteVector<double, Index> dhelp;
	    reconstruct_1(Index(lambda.j()+1, 0, 0, m), j, dhelp);
	    c.add(M_SQRT1_2, dhelp);
	  }
	  
	  // m=2k+1 <-> m-2k=1
	  m++;
	  { // phi_0(2x-1)
	    InfiniteVector<double, Index> dhelp;
	    reconstruct_1(Index(lambda.j()+1, 0, 0, m), j, dhelp);
	    c.add(0.5*M_SQRT1_2, dhelp);
	  }
	  if (m <= (1<<(lambda.j()+1))-1) { // phi_1(2x-1)
	    InfiniteVector<double, Index> dhelp;
	    reconstruct_1(Index(lambda.j()+1, 0, 1, m), j, dhelp);
	    c.add(-0.75*M_SQRT1_2 * phi0factor/phi1factor, dhelp);
	  }
	} else { // lambda.c() == 1
  	  // type phi_1
 	  // phi_1(x) = -1/8*phi_0(2*x+1)+1/8*phi_0(2*x-1)-1/8*phi_1(2*x+1)+1/2*phi_1(2*x)-1/8*phi_1(2*x-1)
	  
	  int m = 2*lambda.k()-1; // m-2k=-1
	  { // phi_0(2x+1)
	    InfiniteVector<double, Index> dhelp;
	    reconstruct_1(Index(lambda.j()+1, 0, 0, m), j, dhelp);
	    c.add(-0.125*M_SQRT1_2 * phi1factor/phi0factor, dhelp);
	  }
	  if (m >= 0) { // phi_1(2x+1)
	    InfiniteVector<double, Index> dhelp;
	    reconstruct_1(Index(lambda.j()+1, 0, 1, m), j, dhelp);
	    c.add(-0.125*M_SQRT1_2, dhelp);
	  }

	  // m=2k <-> m-2k=0
	  m++;
	  { // phi_1(2x)
	    InfiniteVector<double, Index> dhelp;
	    reconstruct_1(Index(lambda.j()+1, 0, 1, m), j, dhelp);
	    c.add(0.5*M_SQRT1_2, dhelp);
	  }

	  // m=2k+1 <-> m-2k=1
	  m++;
	  { // phi_0(2x-1)
	    InfiniteVector<double, Index> dhelp;
	    reconstruct_1(Index(lambda.j()+1, 0, 0, m), j, dhelp);
	    c.add(0.125*M_SQRT1_2 * phi1factor/phi0factor, dhelp);
	  }
	  if (m <= (1<<(lambda.j()+1))) { // phi_1(2x-1)
	    InfiniteVector<double, Index> dhelp;
	    reconstruct_1(Index(lambda.j()+1, 0, 1, m), j, dhelp);
	    c.add(-0.125*M_SQRT1_2, dhelp);
	  }
	} // end if (lambda.c() == 0)
      } else { // lambda.e() == 1
	// wavelet
	if (lambda.c() == 0) {
 	  // type psi_0
 	  // psi_0(x) = -2*phi_0(2*x+1)+4*phi_0(2*x)-2*phi_0(2*x-1)-21*phi_1(2*x+1)+21*phi_1(2*x-1)
#if _JL_PRECOND==0
	  const double factor = sqrt(35./352.);
#else
	  const double factor = sqrt(5./3648.);
#endif

	  int m = 2*lambda.k()-1; // m-2k=-1
	  { // phi_0(2x+1)
	    InfiniteVector<double, Index> dhelp;
	    reconstruct_1(Index(lambda.j()+1, 0, 0, m), j, dhelp);
	    c.add(-2.0*M_SQRT1_2 * factor/phi0factor, dhelp);
	  }
	  if (m >= 0) { // phi_1(2x+1)
	    InfiniteVector<double, Index> dhelp;
	    reconstruct_1(Index(lambda.j()+1, 0, 1, m), j, dhelp);
	    c.add(-21.0*M_SQRT1_2 * factor/phi1factor, dhelp);
	  }

	  // m=2k <-> m-2k=0
	  m++;
	  { // phi_0(2x)
	    InfiniteVector<double, Index> dhelp;
	    reconstruct_1(Index(lambda.j()+1, 0, 0, m), j, dhelp);
	    c.add(4.0*M_SQRT1_2 * factor/phi0factor, dhelp);
	  }

	  // m=2k+1 <-> m-2k=1
	  m++;
	  { // phi_0(2x-1)
	    InfiniteVector<double, Index> dhelp;
	    reconstruct_1(Index(lambda.j()+1, 0, 0, m), j, dhelp);
	    c.add(-2.0*M_SQRT1_2 * factor/phi0factor, dhelp);
	  }
	  if (m <= (1<<(lambda.j()+1))) { // phi_1(2x-1)
	    InfiniteVector<double, Index> dhelp;
	    reconstruct_1(Index(lambda.j()+1, 0, 1, m), j, dhelp);
	    c.add(21.0*M_SQRT1_2 * factor/phi1factor, dhelp);
	  }
	} else { // lambda.c() == 1
 	  // type psi_1
 	  // psi_1(x) = phi_0(2*x+1)-phi_0(2*x-1)+ 9*phi_1(2*x+1)+12*phi_1(2*x)+ 9*phi_1(2*x-1)
#if _JL_PRECOND==0
	  const double factor = sqrt(35./48.);
#else
	  const double factor = sqrt(5./768.);
#endif
	  
	  int m = 2*lambda.k()-1; // m-2k=-1
	  { // phi_0(2x+1)
	    InfiniteVector<double, Index> dhelp;
	    reconstruct_1(Index(lambda.j()+1, 0, 0, m), j, dhelp);
	    c.add(M_SQRT1_2 * factor/phi0factor, dhelp);
	  }
	  if (m >= 0) { // phi_1(2x+1)
	    InfiniteVector<double, Index> dhelp;
	    reconstruct_1(Index(lambda.j()+1, 0, 1, m), j, dhelp);
	    c.add(9.0*M_SQRT1_2 * factor/phi1factor, dhelp);
	  }

	  // m=2k <-> m-2k=0
	  m++;
	  { // phi_1(2x)
	    InfiniteVector<double, Index> dhelp;
	    reconstruct_1(Index(lambda.j()+1, 0, 1, m), j, dhelp);
	    c.add(12.0*M_SQRT1_2 * factor/phi1factor, dhelp);
	  }

	  // m=2k+1 <-> m-2k=1
	  m++;
	  { // phi_0(2x-1)
	    InfiniteVector<double, Index> dhelp;
	    reconstruct_1(Index(lambda.j()+1, 0, 0, m), j, dhelp);
	    c.add(-M_SQRT1_2 * factor/phi0factor, dhelp);
	  }
	  if (m <= (1<<(lambda.j()+1))) { // phi_1(2x-1)
	    InfiniteVector<double, Index> dhelp;
	    reconstruct_1(Index(lambda.j()+1, 0, 1, m), j, dhelp);
	    c.add(9.0*M_SQRT1_2 * factor/phi1factor, dhelp);
	  }
	}
      }
    }
  }
  double
  CachedQuarkletProblem<PROBLEM>::a(const Index& lambda,
			    const Index& nu) const
  {
      
      //const int lambda_num = number(lambda,2);
      double r = 0;
      
      WaveletBasis mybasis(basis());
      
      
      const int jmax = mybasis.get_jmax_();
      const int pmax = mybasis.get_pmax_();
      const int lambda_num = number(lambda, jmax);
      const int nu_num = number(nu,jmax);
      
      //cout << "Punkt 1" << endl;
      // BE CAREFUL: KEY OF GENERATOR LEVEL IS j0-1 NOT j0 !!!!
      typedef typename Index::type_type generator_type;
      int j = (lambda.e() == generator_type()) ? (lambda.j()-1) : lambda.j();
      
      // check wether entry has already been computed
      typedef std::list<Index> IntersectingList;

      // search for column 'nu'
      typename ColumnCache::iterator col_lb(entries_cache.lower_bound(nu_num));
      typename ColumnCache::iterator col_it(col_lb);
      
      if (col_lb == entries_cache.end() ||
	  entries_cache.key_comp()(nu_num, col_lb->first))
	
	{
	  // insert a new column
	  typedef typename ColumnCache::value_type value_type;
	  col_it = entries_cache.insert(col_lb, value_type(nu_num, Column()));
	}
	 //cout << "Punkt 2" << endl; 
      Column& col(col_it->second);
      
      // check wether the level 'lambda' belongs to has already been calculated
      typename Column::iterator lb(col.lower_bound(j));
      typename Column::iterator it(lb);
      // no entries have ever been computed for this column and this level
      if (lb == col.end() ||
	  col.key_comp()(j, lb->first))
	{
         //cout << "Punkt 3" << endl; 
	  // compute whole level block
	  // #### ONLY CDD COMPRESSION STRATEGY IMPLEMENTED ####
	  // #### MAYBE WE ADD TRUNK FOR STEVENSON APPROACH ####
	  // #### LATER.                                    ####
	  
	  // insert a new level
	  typedef typename Column::value_type value_type;
	  it = col.insert(lb, value_type(j, Block()));

	  Block& block(it->second);	  

	  IntersectingList nus;
          
          for(int p=0; p<=pmax; p++){
	   
            intersecting_wavelets(basis(), nu,
                                  std::max(j, basis().j0()),
                                  j == (basis().j0()-1),
                                  nus, p);
//            for (typename IntersectingList::const_iterator it100(nus.begin()), itend(nus.end());
//                   it100 != itend; ++it100) {
//                cout << *it100 << endl;
//            }
            

	  // compute entries
            for (typename IntersectingList::const_iterator it(nus.begin()), itend(nus.end());
                   it != itend; ++it) {
                const double entry = problem->a(*it, nu);
//                cout << *it << ", " << nu << ": " << entry << endl;
//                cout << (*it).number()+(*it).p()*waveletsonplevel << endl;
                typedef typename Block::value_type value_type_block;
                if (entry != 0.) {
                    block.insert(block.end(), value_type_block(number(*it,jmax), entry));
                    if (number(*it,jmax) == lambda_num) {
                        r = entry;
                    }
                }
            }
          }
          //cout << "nu" << nu << endl;
          //cout << block.end() << endl;
	}
      // level already exists --> extract row corresponding to 'lambda'
      else {
	  //cout << "ja" << endl;
          Block& block(it->second);

 	//typename Block::iterator block_lb(block.lower_bound(lambda));
	typename Block::iterator block_lb(block.lower_bound(lambda_num));
 	typename Block::iterator block_it(block_lb);
	// level exists, but in row 'lambda' no entry is available ==> entry must be zero
	if (block_lb == block.end() ||
	    block.key_comp()(lambda_num, block_lb->first))
	  {
	    r = 0;
	  }
	else {
	  r = block_it->second;
	}
      }
        
    
    return r;
  }
  double
  LDomainJLGramian::a(const Index& lambda,
		      const Index& mu) const
  {
    double r = 0;
    
    // First we compute the support intersection of \psi_\lambda and \psi_\mu:
    typedef WaveletBasis::Support Support;
    Support supp;
    
    if (intersect_supports(basis_, lambda, mu, supp))
      {
	// use that both \psi_\lambda and \psi_\mu are a tensor product of 1D bases;
	// the entry of the Gramian on each square subpatch is a product of 2 1D integrals
	
	// iterate through the subsquares of supp and compute the integral shares
 	const double h = ldexp(1.0, -supp.j); // sidelength of the subsquare
	const int N_Gauss = 6;
	FixedArray1D<Array1D<double>,2> gauss_points, gauss_weights;
	for (int i = 0; i <= 1; i++) {
	  gauss_points[i].resize(N_Gauss);
	  gauss_weights[i].resize(N_Gauss);
	  for (int ii = 0; ii < N_Gauss; ii++)
	    gauss_weights[i][ii] = h*GaussWeights[N_Gauss-1][ii];
	}
 	FixedArray1D<int,2> k;
 	FixedArray1D<Array1D<double>,2>
 	  psi_lambda_values,     // values of the components of psi_lambda at gauss_points[i]
 	  psi_mu_values;         // -"-, for psi_mu
	Array1D<double> dummy;
 	for (k[0] = supp.xmin; k[0] < supp.xmax; k[0]++) {
	  if (k[0] >= -(1<<supp.j) && k[0] < (1<<supp.j)) {
	    for (int ii = 0; ii < N_Gauss; ii++)
	      gauss_points[0][ii] = h*(2*k[0]+1+GaussPoints[N_Gauss-1][ii])/2.;
	    evaluate(lambda.j(), lambda.e()[0], lambda.c()[0], lambda.k()[0],
		     gauss_points[0], psi_lambda_values[0], dummy);
	    evaluate(mu.j(), mu.e()[0], mu.c()[0], mu.k()[0],
		     gauss_points[0], psi_mu_values[0], dummy);
	    double factor0 = 0;
	    for (int i0 = 0; i0 < N_Gauss; i0++)
	      factor0 += gauss_weights[0][i0] * psi_lambda_values[0][i0] * psi_mu_values[0][i0];
	    for (k[1] = supp.ymin; k[1] < supp.ymax; k[1]++) {
	      // check whether 2^{-supp.j}[k0,k0+1]x[k1,k1+1] is contained in Omega
	      if ((k[1] >= -(1<<supp.j) && k[1] < 0)
		  || (k[0] < 0 && k[1] >= 0 && k[1] < (1<<supp.j))) {
		for (int ii = 0; ii < N_Gauss; ii++)
		  gauss_points[1][ii] = h*(2*k[1]+1+GaussPoints[N_Gauss-1][ii])/2.;
		evaluate(lambda.j(), lambda.e()[1], lambda.c()[1], lambda.k()[1],
			 gauss_points[1], psi_lambda_values[1], dummy);
		evaluate(mu.j(), mu.e()[1], mu.c()[1], mu.k()[1],
			 gauss_points[1], psi_mu_values[1], dummy);
		double factor1 = 0;
		for (int i1 = 0; i1 < N_Gauss; i1++)
		  factor1 += gauss_weights[1][i1] * psi_lambda_values[1][i1] * psi_mu_values[1][i1];
		
		r += factor0 * factor1;
	      }
 	    }
	  }
	}
      }
    
    return r;
  }