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