void distortImageColor(cv::Mat& mat, RNG& rng, float sigma1, float sigma2, float sigma3, float sigma4) { std::vector<float> delta1(mat.channels()); std::vector<float> delta2(mat.channels()); std::vector<float> delta3(mat.channels()); std::vector<float> delta4(mat.channels()); for (int j=0;j<mat.channels();j++) { delta1[j]=rng.normal(0,sigma1); delta2[j]=rng.normal(0,sigma2); delta3[j]=rng.normal(0,sigma3); delta4[j]=rng.normal(0,sigma4); } int j=0; for (int y=0;y<mat.rows;++y) { for (int x=0;x<mat.cols;++x) { for (int i=0;i<mat.channels();++i) { mat.ptr()[j]=std::max(0,std::min(255, (int)(mat.ptr()[j]+ delta1[i]+ delta2[i]*cos(mat.ptr()[j]*3.1415926535/255)+ delta3[i]*(x-mat.cols/2)+ delta4[i]*(y-mat.rows/2)))); ++j; } } } }
void Stabilisator::update_pi(CplexSolver & solver, DoubleVector const & pi) { DoubleVector rc; solver.rc(rc); _pi_bar = pi; int n_rows((int) _pi_bar.size()); // std::cout << "avg = " << avg / _pi_bar.size() << std::endl; _dual_cost.assign(4 * _pi_bar.size(), 0); _cost.assign(4 * _pi_bar.size(), 0); _indexes.assign(4 * _pi_bar.size(), 0); int index(-1); for (int row(0); row < n_rows; ++row) { _cost[++index] = gamma1(row); _dual_cost[index] = dseta_m(); _indexes[index] = index; _cost[++index] = delta1(row); _dual_cost[index] = epsilon_m(); _indexes[index] = index; _cost[++index] = -delta2(row); _dual_cost[index] = epsilon_p(); _indexes[index] = index; _cost[++index] = -gamma2(row); _dual_cost[index] = dseta_p(); _indexes[index] = index; } solver.chgObj(_indexes, _cost); }
void OpenCVPicture::colorDistortion(RNG &rng, int sigma1, int sigma2, int sigma3, int sigma4) { // Call as a final preprocessing step, after any affine transforms and // jiggling. assert(mat.type() % 8 == 5); // float std::vector<float> delta1(mat.channels()); std::vector<float> delta2(mat.channels()); std::vector<float> delta3(mat.channels()); std::vector<float> delta4(mat.channels()); for (int j = 0; j < mat.channels(); j++) { delta1[j] = rng.normal(0, sigma1); delta2[j] = rng.normal(0, sigma2); delta3[j] = rng.normal(0, sigma3); delta4[j] = rng.normal(0, sigma4); } float *matData = ((float *)(mat.data)); for (int y = 0; y < mat.rows; y++) { for (int x = 0; x < mat.cols; x++) { int j = x * mat.channels() + y * mat.channels() * mat.cols; bool interestingPixel = false; for (int i = 0; i < mat.channels(); i++) if (std::abs(matData[i + j] - backgroundColor) > 2) interestingPixel = true; if (interestingPixel) { for (int i = 0; i < mat.channels(); i++) matData[i + j] += delta1[i] + delta2[i] * (matData[i + j] - backgroundColor) + delta3[i] * (x - mat.cols / 2) + delta4[i] * (y - mat.rows / 2); } } } }
//This is the CommsTime CSP main function int csp_thread_main() { unsigned int pid; unsigned int processcount; unsigned int* tmp; CSP_SAFE_CALL("read processid", dsmcbe_csp_channel_read(PROCESS_COUNTER_GUID, NULL, (void**)&tmp)); pid = (tmp[0])++; processcount = tmp[1]; if (tmp[0] != tmp[1]) { CSP_SAFE_CALL("write processid", dsmcbe_csp_channel_write(PROCESS_COUNTER_GUID, tmp)); } else { CSP_SAFE_CALL("free processid", dsmcbe_csp_item_free(tmp)); } unittest(pid); GUID readerChannel = CHANNEL_START_GUID + (pid % processcount); GUID writerChannel = CHANNEL_START_GUID + ((pid + 1) % processcount); CSP_SAFE_CALL("create start channel", dsmcbe_csp_channel_create(readerChannel, 0, CSP_CHANNEL_TYPE_ONE2ONE)); int call_result; if (pid == 0) call_result = delta2(readerChannel, DELTA_CHANNEL, writerChannel); else if (pid == 1) { void* data; CSP_SAFE_CALL("create prefix value", dsmcbe_csp_item_create(&data, DATA_BLOCK_SIZE)); call_result = prefix(readerChannel, writerChannel, data); } else call_result = delta1(readerChannel, writerChannel); if (call_result != CSP_CALL_POISON) printf("**** ERROR: poison is broken :(\n"); CSP_SAFE_CALL("poison start channel", dsmcbe_csp_channel_poison(writerChannel)); return CSP_CALL_SUCCESS; }
void bmsubst(char *s, char *t) { int k, i, lens = strlen(s), lent = strlen(t), q1[256], q2[lens]; delta1(s, q1); delta2(s, q2); k = lens - 1; while (k < lent) { i = lens - 1; while (t[k] == s[i]) { if (i == 0) { printf("%d ", k); break; } i--; k--; } k += max(q1[t[k]], q2[i]); } printf("\n"); }
int main(){ static vec u(K+1), un(K+1); val dt = T/N; val dx = 1.0/K; val gam = MU*dt/(dx*dx); val rho = NU*dt/(dx*dx*dx*dx); val ar = dt/(2*dx); int j,n=1; //Initialize U for (j=0;j<K+1;j++) u(j)=f(j*dx); //printf("Initial vector\n"); vecprintf(u,K); val tn = n*dt; while (tn<=T||n<N){ for (j=0;j<K+1;j++) un(j) = u(j) - gam*delta2(u,j) - rho*delta4(u,j) - ar*u(j)*delta0(u,j); for (j=0;j<K+1;j++) u(j) = un(j); n+=1; tn = n*dt; } printf("At t = 0.25 and space 0.5 the 'heat' is %24.15e\n", u(K/2)); return 0; }
delta2 operator/(double n) const { return delta2(dx / n, dy / n); }
delta2 operator*(double n) const { return delta2(dx * n, dy * n); }
bool CTrack::Move(int x, int y) { if (m_bDisabled) return false; if (!m_iHandleGrabbed) return false; // Prevent any accidental moves on the first click if (m_iHandleGrabbed == H_MOVE && !m_bMoved) { #define CLOSENESS 10 // pixels int dx = m_iLastDownX - x; int dy = m_iLastDownY - y; if (dx >= -CLOSENESS && dx <= CLOSENESS && dy >= -CLOSENESS && dy <= CLOSENESS) return false; } if (m_bShear) ConstrainXY(&x, &y, true/*bButtonDown*/, false/*bInit*/, m_bShear/*bActive*/); x = bound(x, m_BoundRectScreen.left, m_BoundRectScreen.right); y = bound(y, m_BoundRectScreen.top, m_BoundRectScreen.bottom); CPoint pt(x, y); m_ViewToDeviceMatrix.Inverse().Transform(pt); x = pt.x; y = pt.y; if (x == m_iLastX && y == m_iLastY) return false; m_bMoved = true; Draw(false/*bOn*/); switch (m_iHandleGrabbed) { case H_UL: { m_Grid.Snap(pt); m_bMoveOnly = false; if (m_bExclusive && (m_iWhatCanDo & TR_ROTATE)) Mode(m_iWhatCanDo & ~TR_ROTATE, false/*fDisplay*/); if (m_bShear) Shear(pt.x, pt.y, m_Distort.Rect.left, m_Distort.Rect.top, m_bConstrainX, m_bConstrainY); else Scale(pt.x, pt.y, m_Distort.Rect.left, m_Distort.Rect.top, m_Distort.Rect.right, m_Distort.Rect.bottom, m_bConstrainAspect ^ CONTROL); break; } case H_UR: { m_Grid.Snap(pt); m_bMoveOnly = false; if (m_bExclusive && (m_iWhatCanDo & TR_ROTATE)) Mode(m_iWhatCanDo & ~TR_ROTATE, false/*fDisplay*/); if (m_bShear) Shear(pt.x, pt.y, m_Distort.Rect.right, m_Distort.Rect.top, m_bConstrainX, m_bConstrainY); else Scale(pt.x, pt.y, m_Distort.Rect.right, m_Distort.Rect.top, m_Distort.Rect.left, m_Distort.Rect.bottom, m_bConstrainAspect ^ CONTROL); break; } case H_LR: { m_Grid.Snap(pt); m_bMoveOnly = false; if (m_bExclusive && (m_iWhatCanDo & TR_ROTATE)) Mode(m_iWhatCanDo & ~TR_ROTATE, false/*fDisplay*/); if (m_bShear) Shear(pt.x, pt.y, m_Distort.Rect.right, m_Distort.Rect.bottom, m_bConstrainX, m_bConstrainY); else Scale(pt.x, pt.y, m_Distort.Rect.right, m_Distort.Rect.bottom, m_Distort.Rect.left, m_Distort.Rect.top, m_bConstrainAspect ^ CONTROL); break; } case H_LL: { m_Grid.Snap(pt); m_bMoveOnly = false; if (m_bExclusive && (m_iWhatCanDo & TR_ROTATE)) Mode(m_iWhatCanDo & ~TR_ROTATE, false/*fDisplay*/); if (m_bShear) Shear(pt.x, pt.y, m_Distort.Rect.left, m_Distort.Rect.bottom, m_bConstrainX, m_bConstrainY); else Scale(pt.x, pt.y, m_Distort.Rect.left, m_Distort.Rect.bottom, m_Distort.Rect.right, m_Distort.Rect.top, m_bConstrainAspect ^ CONTROL); break; } case H_TOP: { m_Grid.Snap(pt); m_bMoveOnly = false; if (m_bExclusive && (m_iWhatCanDo & TR_ROTATE)) Mode(m_iWhatCanDo & ~TR_ROTATE, false/*fDisplay*/); int midx = (m_Distort.Rect.left + m_Distort.Rect.right)/2; if (m_bShear) Shear(pt.x, pt.y, midx, m_Distort.Rect.top, m_bConstrainX, m_bConstrainY); else { CPoint ptMid(midx, m_Distort.Rect.top); long dummy; m_Matrix.Transform(ptMid, pt.x, dummy); Scale(pt.x, pt.y, midx, m_Distort.Rect.top, midx, m_Distort.Rect.bottom, false/*bConstrainAspect*/); } break; } case H_RIGHT: { m_Grid.Snap(pt); m_bMoveOnly = false; if (m_bExclusive && (m_iWhatCanDo & TR_ROTATE)) Mode(m_iWhatCanDo & ~TR_ROTATE, false/*fDisplay*/); int midy = (m_Distort.Rect.top + m_Distort.Rect.bottom)/2; if (m_bShear) Shear(pt.x, pt.y, m_Distort.Rect.right, midy, m_bConstrainX, m_bConstrainY); else { CPoint ptMid(m_Distort.Rect.right, midy); long dummy; m_Matrix.Transform(ptMid, dummy, pt.y); Scale(pt.x, pt.y, m_Distort.Rect.right, midy, m_Distort.Rect.left, midy, false/*bConstrainAspect*/); } break; } case H_BOTTOM: { m_Grid.Snap(pt); m_bMoveOnly = false; if (m_bExclusive && (m_iWhatCanDo & TR_ROTATE)) Mode(m_iWhatCanDo & ~TR_ROTATE, false/*fDisplay*/); int midx = (m_Distort.Rect.left + m_Distort.Rect.right)/2; if (m_bShear) Shear(pt.x, pt.y, midx, m_Distort.Rect.bottom, m_bConstrainX, m_bConstrainY); else { CPoint ptMid(midx, m_Distort.Rect.bottom); long dummy; m_Matrix.Transform(ptMid, pt.x, dummy); Scale(pt.x, pt.y, midx, m_Distort.Rect.bottom, midx, m_Distort.Rect.top, false/*bConstrainAspect*/); } break; } case H_LEFT: { m_Grid.Snap(pt); m_bMoveOnly = false; if (m_bExclusive && (m_iWhatCanDo & TR_ROTATE)) Mode(m_iWhatCanDo & ~TR_ROTATE, false/*fDisplay*/); int midy = (m_Distort.Rect.top + m_Distort.Rect.bottom)/2; if (m_bShear) Shear(pt.x, pt.y, m_Distort.Rect.left, midy, m_bConstrainX, m_bConstrainY); else { CPoint ptMid(m_Distort.Rect.left, midy); long dummy; m_Matrix.Transform(ptMid, dummy, pt.y); Scale(pt.x, pt.y, m_Distort.Rect.left, midy, m_Distort.Rect.right, midy, false/*bConstrainAspect*/); } break; } case H_CENTER: { // transform points to transformed position m_Matrix.Transform(m_ptCenter); m_Matrix.Transform(m_ptRotate); int dx = pt.x - m_ptCenter.x; int dy = pt.y - m_ptCenter.y; m_ptRotate.x += dx; m_ptRotate.y += dy; m_ptCenter = pt; // transform points back to untransformed position m_Matrix.Inverse().Transform(m_ptCenter); m_Matrix.Inverse().Transform(m_ptRotate); break; } case H_CORNER_UL: case H_CORNER_UR: case H_CORNER_LR: case H_CORNER_LL: { m_Grid.Snap(pt); m_bMoveOnly = false; if (m_bExclusive && (m_iWhatCanDo & TR_ROTATE)) Mode(m_iWhatCanDo & ~TR_ROTATE, false/*fDisplay*/); // transform the new point back to its untransformed position CPoint ptTemp = pt; m_Matrix.Inverse().Transform(ptTemp); int i = m_iHandleGrabbed - H_CORNER_UL; m_Distort.p[i] = ptTemp; // Update the m_Distort.Rect rectangle m_Distort.Rect.left = min(min(min(m_Distort.p[0].x, m_Distort.p[1].x), m_Distort.p[2].x), m_Distort.p[3].x); m_Distort.Rect.right = max(max(max(m_Distort.p[0].x, m_Distort.p[1].x), m_Distort.p[2].x), m_Distort.p[3].x); m_Distort.Rect.top = min(min(min(m_Distort.p[0].y, m_Distort.p[1].y), m_Distort.p[2].y), m_Distort.p[3].y); m_Distort.Rect.bottom = max(max(max(m_Distort.p[0].y, m_Distort.p[1].y), m_Distort.p[2].y), m_Distort.p[3].y); break; } case H_ROTATE: { m_bMoveOnly = false; if (m_bExclusive && (m_iWhatCanDo & TR_SIZE)) Mode(m_iWhatCanDo & ~TR_SIZE, false/*fDisplay*/); // transform points to transformed position Rotate(pt.x, pt.y, m_iStartRotateX, m_iStartRotateY); m_ptRotate = pt; // transform points back to untransformed position m_Matrix.Inverse().Transform(m_ptRotate); break; } case H_MOVE: { // Calculate how far we SHOULD move CPoint delta1(pt.x - m_iLastX, pt.y - m_iLastY); // Calculate where we are right now CRect rect = m_Distort.Rect; m_Matrix.Transform(rect); // Calculate the new top-left point CPoint ptNewTL(rect.left + delta1.x, rect.top + delta1.y); // Snap it to the grid m_Grid.Snap(ptNewTL); if (m_iWhatCanDo & TR_BOUNDTOSYMBOL) { int delta; delta = ptNewTL.x - m_BoundRect.left; if (delta < 0) ptNewTL.x -= delta; delta = ptNewTL.y - m_BoundRect.top; if (delta < 0) ptNewTL.y -= delta; delta = (ptNewTL.x + rect.Width()) - m_BoundRect.right; if (delta > 0) ptNewTL.x -= delta; delta = (ptNewTL.y + rect.Height()) - m_BoundRect.bottom; if (delta > 0) ptNewTL.y -= delta; } // Calculate how far we WILL move CPoint delta2(ptNewTL.x - rect.left, ptNewTL.y - rect.top); // Adjust the point for the next time around x -= (delta1.x - delta2.x); y -= (delta1.y - delta2.y); m_Matrix.Translate(delta2.x, delta2.y); break; } default: return false; } if (m_pDrawProc && m_pAGDC) { HDC hDC = m_pAGDC->GetHDC(); m_pDrawProc(hDC, false/*bOn*/, TOOLCODE_UPDATE, m_pData); } Draw(true/*bOn*/); m_iLastX = x; m_iLastY = y; return true; }
delta2 half_rotation() const { return delta2(-dx, -dy); }
delta2 set_dy(double _dy) const { return delta2(dx, _dy); }
// // accessors // delta2 set_dx(double _dx) const { return delta2(_dx, dy); }
int main( ) { int Numbers[] = {10,40,80}; // The rank of the braid group int exp = 100; // The number of experiments to perform for each parameter value int Lengths[] = {100,400,800}; // The length of the base word // Generate instance for( int n=0 ; n<sizeof(Numbers)/sizeof(int) ; ++n ) { for( int l=0 ; l<sizeof(Lengths)/sizeof(int) ; ++l ) { int N = Numbers[n]; int L = Lengths[l]; int success_orig = 0; int success_new = 0; for( int e=0 ; e<exp ; ++e ) { cout << "++++++++++++++++++++++++++++++" << endl; cout << "e = " << e << endl; ShftConjKeyInstance SCK = ShftConjKeyInstance::random( N , L , L ); pair< Word , Word > public_key = SCK.getPublicKey( ); Word p1 = public_key.first; Word p2 = public_key.second; Word delta = getSmallDelta( N+1 ); NF nf = NF( N+1 , generatorShift( p1 ) * Word(1) * -delta ); NF nf2 = NF( N+1 , p2 * -delta ); int time_sec_bound = 60*60 ; // time bound is 60 minutes pair< bool , NF > res = nf.areConjugate_uss( nf2 , time_sec_bound ); if( !res.first ) { cout << "USS failure" << endl; continue; } NF candidate = res.second; NF candidate2 = candidate.increaseRank( N+2 ); NF s2( N+2 , Word(1) ); NF delta2( N+2 , getSmallDelta( N+2 ) ); NF p1_2( N+2 , p1 ); NF p2_2( N+2 , p2 ); candidate2 = centr_attack( N , p1_2 , p2_2 , candidate2 , delta2); if( ( candidate2 * (-delta2*p1_2*delta2) * s2 * (-delta2*-candidate2*delta2) * -p2_2 ).isTrivial( ) ) { cout << "The key is correct" << endl; // Now check with the original private key NF priv = NF( N+2 , SCK.getPrivateKey( ) ); if( priv==candidate2 ) { cout << "The original key obtained" << endl; success_orig++; } else { cout << "The obtained key is new" << endl; success_new++; } } else { cout << "The key is not correct" << endl; } } int filename_sz = 100; char filename[filename_sz]; ostrstream ostr( filename , filename_sz ); ostr << "results_N" << N << "_L" << L << ".txt" << ends; ofstream of( filename ); of << "N = " << n << endl; of << "baseLenth = " << l << endl; of << "keyLength = " << l << endl; of << "Total experiments: " << exp << endl; of << "Successful experiments: " << success_new+success_orig << endl; of << "Percentage_orig: " << 100*success_orig/exp << endl; of << "Percentage_new: " << 100*success_new/exp << endl; // test_inc_rank( ); } } return 0; }
Double Stabilisator::gamma2(int i) const { return delta2(i) + _width * 2; }
/*! SLCamera::onTouch2Move gets called whenever two fingers move on a handheld screen. */ SLbool SLCamera::onTouch2Move(const SLint x1, const SLint y1, const SLint x2, const SLint y2) { SLScene* s = SLScene::current; SLSceneView* sv = s->activeSV(); SLVec2f now1((SLfloat)x1, (SLfloat)y1); SLVec2f now2((SLfloat)x2, (SLfloat)y2); SLVec2f delta1(now1-_oldTouchPos1); SLVec2f delta2(now2-_oldTouchPos2); // Average out the deltas over the last 4 events for correct 1 pixel moves static SLuint cnt=0; static SLVec2f d1[4]; static SLVec2f d2[4]; d1[cnt%4] = delta1; d2[cnt%4] = delta2; SLVec2f avgDelta1(d1[0].x+d1[1].x+d1[2].x+d1[3].x, d1[0].y+d1[1].y+d1[2].y+d1[3].y); SLVec2f avgDelta2(d2[0].x+d2[1].x+d2[2].x+d2[3].x, d2[0].y+d2[1].y+d2[2].y+d2[3].y); avgDelta1 /= 4.0f; avgDelta2 /= 4.0f; cnt++; SLfloat r1, phi1, r2, phi2; avgDelta1.toPolar(r1, phi1); avgDelta2.toPolar(r2, phi2); // Scale the mouse delta by the lookAt distance SLfloat lookAtDist; if (_lookAtRay.length < FLT_MAX) lookAtDist = _lookAtRay.length; else lookAtDist = _focalDist; // scale factor depending on the space sice at focal dist SLfloat spaceH = tan(SL_DEG2RAD*_fov/2) * lookAtDist * 2.0f; SLfloat spaceW = spaceH * sv->scrWdivH(); //SL_LOG("avgDelta1: (%05.2f,%05.2f), dPhi=%05.2f\n", avgDelta1.x, avgDelta1.y, SL_abs(phi1-phi2)); // if fingers move parallel slide camera vertically or horizontally if (SL_abs(phi1-phi2) < 0.2f) { // Calculate center between finger points SLVec2f nowCenter((now1+now2)*0.5f); SLVec2f oldCenter((_oldTouchPos1+_oldTouchPos2)*0.5f); // For first move set oldCenter = nowCenter if (oldCenter == SLVec2f::ZERO) oldCenter = nowCenter; SLVec2f delta(nowCenter - oldCenter); // scale to 0-1 delta.x /= (SLfloat)sv->scrW(); delta.y /= (SLfloat)sv->scrH(); // scale to space size delta.x *= spaceW; delta.y *= spaceH; if (_camAnim==turntableYUp || _camAnim==turntableZUp) { // apply delta to x- and y-position _vm.translation(_vm.m(12) + delta.x, _vm.m(13) - delta.y, _vm.m(14)); setWMandState(); } else if (_camAnim == walkingYUp || _camAnim == walkingZUp) { _maxSpeed.x = delta.x * 100.0f, _maxSpeed.z = delta.y * 100.0f; } } else // Two finger pinch { // Calculate vector between fingers SLVec2f nowDist(now2 - now1); SLVec2f oldDist(_oldTouchPos2-_oldTouchPos1); // For first move set oldDist = nowDist if (oldDist == SLVec2f::ZERO) oldDist = nowDist; SLfloat delta = oldDist.length() - nowDist.length(); if (_camAnim==turntableYUp) { // scale to 0-1 delta /= (SLfloat)sv->scrH(); // scale to space height delta *= spaceH*2; // apply delta to the z-position _vm.translation(_vm.m(12), _vm.m(13), _vm.m(14) - delta); setWMandState(); } else if (_camAnim == walkingYUp) { // change field of view _fov += SL_sign(delta) * 0.5f; currentFOV = _fov; } } _oldTouchPos1.set((SLfloat)x1, (SLfloat)y1); _oldTouchPos2.set((SLfloat)x2, (SLfloat)y2); return true; }
delta2 add_quarter_rotation() const { return delta2(-dy, dx); }
delta2 subtract_quarter_rotation() const { return delta2(dy, -dx); }
delta2 operator+(double n) const { return delta2(dx + n, dy + n); }
delta2 negate() const { return delta2(-dx, -dy); }
delta2 operator-(double n) const { return delta2(dx - n, dy - n); }
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override { const PLSAATriangleEffect& te = args.fGP.cast<PLSAATriangleEffect>(); GrGLSLVertexBuilder* vsBuilder = args.fVertBuilder; GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler; GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; varyingHandler->emitAttributes(te); this->setupPosition(vsBuilder, gpArgs, te.inPosition()->fName); GrGLSLVertToFrag v1(kVec2f_GrSLType); varyingHandler->addVarying("Vertex1", &v1, kHigh_GrSLPrecision); vsBuilder->codeAppendf("%s = vec2(%s.x, %s.y);", v1.vsOut(), te.inVertex1()->fName, te.inVertex1()->fName); GrGLSLVertToFrag v2(kVec2f_GrSLType); varyingHandler->addVarying("Vertex2", &v2, kHigh_GrSLPrecision); vsBuilder->codeAppendf("%s = vec2(%s.x, %s.y);", v2.vsOut(), te.inVertex2()->fName, te.inVertex2()->fName); GrGLSLVertToFrag v3(kVec2f_GrSLType); varyingHandler->addVarying("Vertex3", &v3, kHigh_GrSLPrecision); vsBuilder->codeAppendf("%s = vec2(%s.x, %s.y);", v3.vsOut(), te.inVertex3()->fName, te.inVertex3()->fName); GrGLSLVertToFrag delta1(kVec2f_GrSLType); varyingHandler->addVarying("delta1", &delta1, kHigh_GrSLPrecision); vsBuilder->codeAppendf("%s = vec2(%s.x - %s.x, %s.y - %s.y) * 0.5;", delta1.vsOut(), v1.vsOut(), v2.vsOut(), v2.vsOut(), v1.vsOut()); GrGLSLVertToFrag delta2(kVec2f_GrSLType); varyingHandler->addVarying("delta2", &delta2, kHigh_GrSLPrecision); vsBuilder->codeAppendf("%s = vec2(%s.x - %s.x, %s.y - %s.y) * 0.5;", delta2.vsOut(), v2.vsOut(), v3.vsOut(), v3.vsOut(), v2.vsOut()); GrGLSLVertToFrag delta3(kVec2f_GrSLType); varyingHandler->addVarying("delta3", &delta3, kHigh_GrSLPrecision); vsBuilder->codeAppendf("%s = vec2(%s.x - %s.x, %s.y - %s.y) * 0.5;", delta3.vsOut(), v3.vsOut(), v1.vsOut(), v1.vsOut(), v3.vsOut()); GrGLSLVertToFrag windings(kInt_GrSLType); varyingHandler->addFlatVarying("windings", &windings, kLow_GrSLPrecision); vsBuilder->codeAppendf("%s = %s;", windings.vsOut(), te.inWindings()->fName); // emit transforms this->emitTransforms(vsBuilder, varyingHandler, uniformHandler, gpArgs->fPositionVar, te.inPosition()->fName, te.localMatrix(), args.fTransformsIn, args.fTransformsOut); GrGLSLFragmentBuilder* fsBuilder = args.fFragBuilder; SkAssertResult(fsBuilder->enableFeature( GrGLSLFragmentShaderBuilder::kPixelLocalStorage_GLSLFeature)); SkAssertResult(fsBuilder->enableFeature( GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); fsBuilder->declAppendf(GR_GL_PLS_PATH_DATA_DECL); // Compute four subsamples, each shifted a quarter pixel along x and y from // gl_FragCoord. The oriented box positioning of the subsamples is of course not // optimal, but it greatly simplifies the math and this simplification is necessary for // performance reasons. fsBuilder->codeAppendf("highp vec2 firstSample = %s.xy - vec2(0.25);", fsBuilder->fragmentPosition()); fsBuilder->codeAppendf("highp vec2 delta1 = %s;", delta1.fsIn()); fsBuilder->codeAppendf("highp vec2 delta2 = %s;", delta2.fsIn()); fsBuilder->codeAppendf("highp vec2 delta3 = %s;", delta3.fsIn()); // Check whether first sample is inside the triangle by computing three dot products. If // all are < 0, we're inside. The first vector in each case is half of what it is // "supposed" to be, because we re-use them later as adjustment factors for which half // is the correct value, so we multiply the dots by two to compensate. fsBuilder->codeAppendf("highp float d1 = dot(delta1, (firstSample - %s).yx) * 2.0;", v1.fsIn()); fsBuilder->codeAppendf("highp float d2 = dot(delta2, (firstSample - %s).yx) * 2.0;", v2.fsIn()); fsBuilder->codeAppendf("highp float d3 = dot(delta3, (firstSample - %s).yx) * 2.0;", v3.fsIn()); fsBuilder->codeAppend("highp float dmax = max(d1, max(d2, d3));"); fsBuilder->codeAppendf("pls.windings[0] += (dmax <= 0.0) ? %s : 0;", windings.fsIn()); // for subsequent samples, we don't recalculate the entire dot product -- just adjust it // to the value it would have if we did recompute it. fsBuilder->codeAppend("d1 += delta1.x;"); fsBuilder->codeAppend("d2 += delta2.x;"); fsBuilder->codeAppend("d3 += delta3.x;"); fsBuilder->codeAppend("dmax = max(d1, max(d2, d3));"); fsBuilder->codeAppendf("pls.windings[1] += (dmax <= 0.0) ? %s : 0;", windings.fsIn()); fsBuilder->codeAppend("d1 += delta1.y;"); fsBuilder->codeAppend("d2 += delta2.y;"); fsBuilder->codeAppend("d3 += delta3.y;"); fsBuilder->codeAppend("dmax = max(d1, max(d2, d3));"); fsBuilder->codeAppendf("pls.windings[2] += (dmax <= 0.0) ? %s : 0;", windings.fsIn()); fsBuilder->codeAppend("d1 -= delta1.x;"); fsBuilder->codeAppend("d2 -= delta2.x;"); fsBuilder->codeAppend("d3 -= delta3.x;"); fsBuilder->codeAppend("dmax = max(d1, max(d2, d3));"); fsBuilder->codeAppendf("pls.windings[3] += (dmax <= 0.0) ? %s : 0;", windings.fsIn()); }
delta2 operator+(delta2 const& d) const { return delta2(dx + d.dx, dy + d.dy); }
delta2 operator-(delta2 const& d) const { return delta2(dx - d.dx, dy - d.dy); }
delta2 operator-() const { return delta2(-dx, -dy); }
delta2 operator-(point2 const& p) const { return delta2(x - p.x, y - p.y); }
void Trainee::train(std::vector<std::pair<InputType, AnswerType>> minibatch, float learning_rate) { Eigen::MatrixXf dweight3 = Eigen::MatrixXf::Zero(n_outputvec, n_hid2vec); Eigen::VectorXf dbias3 = Eigen::VectorXf::Zero(n_outputvec); Eigen::MatrixXf dweight2 = Eigen::MatrixXf::Zero(n_hid2vec, n_hid1vec); Eigen::VectorXf dbias2 = Eigen::VectorXf::Zero(n_hid2vec); Eigen::MatrixXf dweight1 = Eigen::MatrixXf::Zero(n_hid1vec, n_inputvec); Eigen::VectorXf dbias1 = Eigen::VectorXf::Zero(n_hid1vec); /* For AdaGrad */ auto fn = [](float lhs, float rhs) -> float { return lhs != 0.0 ? lhs / rhs : 0.0; }; for(auto sample: minibatch){ Eigen::VectorXf inputvec = input2vec(sample.first); Eigen::VectorXf z1 = feedforward(inputvec, 1); Eigen::VectorXf z2 = feedforward(inputvec, 2); // 後付けとはいえ。この計算、あからさまに無駄だな。z1からz2を計算すべき。 // Calculate delta of output layer. Eigen::VectorXf delta3; delta3 = feedforward(inputvec, 3); delta3(sample.second) -= 1.0f; { Eigen::ArrayXXf e = delta3 * z2.transpose(); gsq_w3 += e * e; gsq_b3 += delta3.array() * delta3.array(); dweight3 += e.matrix(); dbias3 += delta3; } // Calculate delta of 2nd hidden layer. Eigen::VectorXf delta2 = Eigen::VectorXf::Zero(n_hid2vec); for(int j=0;j<n_hid2vec;j++){ for(int k=0;k<n_outputvec;k++) delta2(j) += delta3(k) * weight3(k, j) * (z2(j) >= 0.f ? 1.f : 0.f); } { Eigen::ArrayXXf e = delta2 * z1.transpose(); gsq_w2 += e * e; gsq_b2 += delta2.array() * delta2.array(); dweight2 += e.matrix(); dbias2 += delta2; } // Calculate delta of 1st hidden layer. Eigen::VectorXf delta1 = Eigen::VectorXf::Zero(n_hid1vec); for(int j=0;j<n_hid1vec;j++){ for(int k=0;k<n_hid2vec;k++) delta1(j) += delta2(k) * weight2(k, j) * (z1(j) >= 0.f ? 1.f : 0.f); } { Eigen::ArrayXXf e = delta1 * inputvec.transpose(); gsq_w1 += e * e; gsq_b1 += delta1.array() * delta1.array(); dweight1 += e.matrix(); dbias1 += delta1; } } weight1 -= dweight1.binaryExpr(gsq_w1.sqrt().matrix(), fn) * learning_rate / minibatch.size(); bias1 -= dbias1.binaryExpr(gsq_b1.sqrt().matrix(), fn) * learning_rate / minibatch.size(); weight2 -= dweight2.binaryExpr(gsq_w2.sqrt().matrix(), fn) * learning_rate / minibatch.size(); bias2 -= dbias2.binaryExpr(gsq_b2.sqrt().matrix(), fn) * learning_rate / minibatch.size(); weight3 -= dweight3.binaryExpr(gsq_w3.sqrt().matrix(), fn) * learning_rate / minibatch.size(); bias3 -= dbias3.binaryExpr(gsq_b3.sqrt().matrix(), fn) * learning_rate / minibatch.size(); }