void ModButterfly::findHalfStencil(RgbVertexC& v, Pos& pos, vector<RgbVertexC>& stencil) { assert(v.vp() == pos.v); Pos p; p = pos; p.FlipV(); RgbVertexC v2 = RgbVertexC(*v.m,*v.rgbInfo,p.v); int maxlevel = v.getLevel(); if (maxlevel < v2.getLevel()) maxlevel = v2.getLevel(); p = pos; rotate(v,p,2); RgbVertexC vtemp = move(v,p,maxlevel); stencil.push_back(vtemp); #ifndef NDEBUG Pos ptemp; ptemp = pos; ptemp.FlipV(); rotate(v2,ptemp,2); RgbVertexC vtemp2 = move(v2,ptemp,maxlevel); assert(vtemp.index == vtemp2.index); #endif p = pos; rotate(v,p,4); stencil.push_back(move(v,p,maxlevel)); p = pos; p.FlipV(); rotate(v2,p,4); stencil.push_back(move(v2,p,maxlevel)); }
ModButterfly::RgbVertexC ModButterfly::move(RgbVertexC& v, Pos& pos, int level) { assert(v.vp() == pos.v); assert(level >= v.getLevel()); int vl = level; RgbVertexC lastv; do { pos.FlipV(); lastv = RgbVertexC(*v.m,*v.rgbInfo,pos.v); if (lastv.getLevel() <= vl) break; // no need to continue, in fact a rotation of exactly 6 can be impossible in some cases rotate(lastv,pos,6); pos.FlipF(); assert(lastv.getLevel() > vl); } while (lastv.getLevel() > vl); return RgbVertexC(*v.m,*v.rgbInfo,pos.v); }
ModButterfly::Point ModButterfly::computeExtraordinary(RgbVertexC& v, Pos& pos) { int rank; if (v.getLevel() == 0) rank = baseArity(v); else rank = 4; vector<Point> points; vector<double> coeff; computeExtraordinaryPattern(coeff,rank); points.reserve(rank+1); points.push_back(v.getCoord()); if (!v.getIsBorder()) { int angle = rank * 2; do { pos.FlipV(); points.push_back(pos.v->P()); assert(pos.v != v.vp()); pos.FlipV(); rotate(v,pos,2); angle -= 2; assert (angle >= 0); } while (angle != 0); } else { Pos pos2 = pos; // Border int angle = (rank-1) * 2; do { pos.FlipV(); points.push_back(pos.v->P()); assert(pos.v != v.vp()); pos.FlipV(); assert(pos.v == v.vp()); rotate(v,pos,2); angle -= 2; assert (angle >= 0); } while ((!pos.IsBorder()) && (angle != 0)); pos.FlipV(); points.push_back(pos.v->P()); assert(pos.v != v.vp()); pos.FlipV(); assert(angle >= 0); vector<Point> pointsreverse; pos2.FlipF(); rotate(v,pos2,2); angle -= 2; if ((!pos2.IsBorder()) && (angle != 0)) { do { pos2.FlipV(); pointsreverse.push_back(pos2.v->P()); assert(pos2.v != v.vp()); pos2.FlipV(); assert(pos2.v == v.vp()); rotate(v,pos2,2); angle -= 2; assert (angle >= 0); } while ((!pos2.IsBorder()) && (angle != 0)); } assert(angle == 0); pos.FlipV(); points.push_back(pos.v->P()); assert(pos.v != v.vp()); pos.FlipV(); for(int i=pointsreverse.size()-1;i>= 0; i--) points.push_back(pointsreverse[i]); } assert(points.size() == (unsigned int)(rank + 1)); assert(points.size() == coeff.size()); Point acc = Point(0.0,0.0,0.0); for (int i=0; i<rank+1; i++) { Point tmp = points[i] * coeff[i]; acc += tmp; } return acc; }