void
  TensorProductBasis<BASIS0,BASIS1>::reconstruct_1(const Index& lambda,
						   const int j,
						   InfiniteVector<double, Index>& c) const {
    if (lambda.j() >= j) {
      // then we can just copy \psi_\lambda
      c.add_coefficient(lambda, 1.0);
    } else {
      // reconstruct by recursion
      
      typedef typename BASIS0::Index Index0;
      typedef typename BASIS1::Index Index1;
      InfiniteVector<double,Index0> c1;
      InfiniteVector<double,Index1> c2;
      basis0().reconstruct_1(lambda.index0(), lambda.j()+1, c1);
      basis1().reconstruct_1(lambda.index1(), lambda.j()+1, c2);

      for (typename InfiniteVector<double,Index0>::const_iterator it1(c1.begin()), it1end(c1.end());
	   it1 != it1end; ++it1)
	for (typename InfiniteVector<double,Index1>::const_iterator it2(c2.begin()), it2end(c2.end());
	     it2 != it2end; ++it2) {
	  InfiniteVector<double,Index> d;
	  reconstruct_1(Index(it1.index(), it2.index()), j, d);
	  c.add(*it1 * *it2, d);
	}
    }
  }
  void
  TensorProductBasis<BASIS0,BASIS1>::decompose_1(const Index& lambda,
						 const int j0,
						 InfiniteVector<double, Index>& c) const {
    assert(lambda.j() >= j0);
    c.clear();
    if (lambda.index0().e() != 0 || lambda.index1().e() != 0) {
      // the true wavelet coefficients don't have to be modified
      c.set_coefficient(lambda, 1.0);
    } else {
      // a generator on a (possibly) fine level
      if (lambda.j() == j0) {
 	// generators from the coarsest level can be copied
 	c.set_coefficient(lambda, 1.0);
      }	else {
 	// j>j0, perform multiscale decomposition

 	typedef typename BASIS0::Index Index0;
 	typedef typename BASIS1::Index Index1;
 	InfiniteVector<double,Index0> c1;
 	InfiniteVector<double,Index1> c2;
	basis0().decompose_1(lambda.index0(), lambda.j()-1, c1);
  	basis1().decompose_1(lambda.index1(), lambda.j()-1, c2);

 	for (typename InfiniteVector<double,Index0>::const_iterator it1(c1.begin()), it1end(c1.end());
  	     it1 != it1end; ++it1)
  	  for (typename InfiniteVector<double,Index1>::const_iterator it2(c2.begin()), it2end(c2.end());
  	       it2 != it2end; ++it2) {
// 	    if (it1.index().e() == 0 && it2.index().e() == 0) { // generators have to be refined further
	    InfiniteVector<double,Index> d;
	    decompose_1(Index(it1.index(), it2.index()), j0, d);
	    c.add(*it1 * *it2, d);
// 	    } else
// 	      c.set_coefficient(Index(this, it1.index(), it2.index()), *it1 * *it2);
	  }
      }
    }
  }
Matrix<double> BspCurvBasisFuncSet::CreateMatrixIntegral(int lev1, int lev2) const
{
	KnotSet kset1 = KnotSet(*kts,ord,num).CreateKnotSetDeriv(lev1);
	KnotSet kset2 = KnotSet(*kts,ord,num).CreateKnotSetDeriv(lev2);
	
	Matrix<double> mat(kset1.GetNum()-(ord-lev1),kset2.GetNum()-(ord-lev2));
	
	BspCurvBasisFuncSet basis1(kset1.GetKnots(),ord-lev1,kset1.GetNum());
	BspCurvBasisFuncSet basis2(kset2.GetKnots(),ord-lev2,kset2.GetNum());

	// find the first basis function for which the last distinct
	// knot is greater than x1



	Matrix<double> mat1(kset1.GetNum()-ord+lev1,kset2.GetNum()-ord+lev2,0.0);



	for (int i=0; i<kset1.GetNum()-ord+lev1; i++)
		for (int j=0; j<kset2.GetNum()-ord+lev2; j++) {
		
			
			// create the two std::sets representing the two knot std::sets
			Vector<double> temp1((*(basis1.b))[i].GetKnots());
			Vector<double> temp2((*(basis2.b))[j].GetKnots());
			std::set<double> s1(temp1.begin(),temp1.end());
			std::set<double> s2(temp2.begin(),temp2.end());

			if (*(--s2.end()) > *(s1.begin())) {
				// form the intersection
				std::set<double> s3;
				std::set_intersection(s1.begin(),s1.end(),s2.begin(),s2.end(),std::inserter(s3,s3.begin()));
			
				// if there is an intersection
				if (s3.size() > 1) {
					Vector<double> v(s3.size());
					std::set<double>::iterator s = s3.begin();

					// copy the elements into a vector
					for (unsigned int k=0; k<s3.size(); k++) v[k] = *s++;
				
					// create the compbezcurvs
					Vector<BezCurv<double> > vec1(s3.size()-1);
					Vector<BezCurv<double> > vec2(s3.size()-1);

					BspCurv<double> b1((*(basis1.b))[i].GetBspCurv()), b2((*(basis2.b))[j].GetBspCurv());
				
					// find the segments of intersection
					for (unsigned int k=0; k<s3.size()-1; k++) {
						int segb1 = b1.GetKnotSet().Find_segment(v[k]);
						int segb2 = b2.GetKnotSet().Find_segment(v[k]);
						
						vec1[k] = b1.GetSegment(segb1);
						vec2[k] = b2.GetSegment(segb2);
					}
				
					CompBezCurv<double> cb1(vec1,s3.size()-1,v);
					CompBezCurv<double> cb2(vec2,s3.size()-1,v);
					CompBezCurv<double> prod = cb1.Product(cb2);
				
					mat1[i][j] = prod.ConvertBspCurv().Integrate((*kts)[ord-1],(*kts)[num-ord]);
				}
			}
		}
	
	
	
	return mat1;
}