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); } } } } }
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; }
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; }