///////////////////////////////////////////////////////////////////////////// // Steepest descent ///////////////////////////////////////////////////////////////////////////// void CDiffFunction::SteepestDescent(std::vector<double> &vMax, bool fTrace) { const std::vector<double> &vG = GetGradient(); int n = GetDimensions(); // // Loop of iterations // for (int Iteration = MaxSDIterations; --Iteration >= 0;) { GetOutput(&vMax[0]); ComputeGradient(); // // Maximize in gradient direction // vGCopy = vG; double x = LineOpt(&vMax[0], &vGCopy[0], fTrace); double Delta2 = 0.0; for (int i = n; --i >= 0;) { double New = Normalize(vMax[i] + x * vGCopy[i]); double Delta = New - vMax[i]; vMax[i] = New; Delta2 += Delta * Delta; } if (Delta2 < CGEpsilon) break; } }
template <class T> bool karbtest (Connector<T>* rc) { GradientParams gp; std::string in_file;// = std::string (base + "/" + std::string(rc->GetElement("/config/data-in")->Attribute("fname"))); std::string out_file;// = std::string (base + "/" + rc->GetElement("/config/data-out")->Attribute("fname")); bool simann = false; size_t hpoints = 1; rc->Attribute ("simann", &simann); rc->Attribute ("hpoints", &hpoints); if (simann) { double coolrate, startt, finalt; size_t coolit; bool verbose, exchange; rc->Attribute ("coolrate", &coolrate); rc->Attribute ("startt", &startt); rc->Attribute ("finalt", &finalt); rc->Attribute ("coolit", &coolit); rc->Attribute ("verbose", &verbose); rc->Attribute ("exchange", &exchange); SimulatedAnnealing sa (gp.k, coolit, startt, finalt, coolrate, verbose, exchange); sa.Cool(); gp.k = sa.GetSolution(); } rc->Attribute ("maxgrad", &(gp.mgr)); rc->Attribute ("maxslew", &(gp.msr)); rc->Attribute ("dt", &(gp.dt)); rc->Attribute ("gunits", &(gp.gunits)); rc->Attribute ("lunits", &(gp.lunits)); Matrix<double> x = linspace<double> (0.0,1.0,size(gp.k,0)); Matrix<double> xi = linspace<double> (0.0,1.0,size(gp.k,0)*hpoints); gp.k = interp1 (x, gp.k, xi, INTERP::AKIMA); printf ("\nComputing trajectory for ... \n"); printf (" [maxgrad: %.2f, maxslew: %.2f, dt: %.2e]\n\n", gp.mgr, gp.msr, gp.dt); SimpleTimer st ("VD spiral design"); Solution s = ComputeGradient (gp); st.Stop(); IOContext f = fopen (out_file.c_str(), WRITE); s.dump (f); fclose (f); return true; }
bool PotentialFieldSolver::m_ComputeGradient() { m_grid_gradPhi->memset(make_double3(0,0,0)); ComputeGradient(m_grid_phi->getDevicePtr(),m_grid_gradPhi->getDevicePtr(), m_SpatialHasher_mass.getCellSize().x,1.0,m_gridx,m_gridy,m_gridz); return true; }
Solution VDSpiral (SpiralParams& sp) { GradientParams gp; Matrix<double>& fov = sp.fov; Matrix<double>& rad = sp.rad; double k_max, fov_max, dr; Matrix<double> r, theta; long n = 0; assert (numel(rad) >= 2); assert (isvec(rad) == isvec(fov)); assert (numel(rad) == numel(fov)); k_max = 5.0 / sp.res; fov_max = m_max(fov); dr = sp.shots / (fov_max); n = size(fov,1)*100; r = linspace<double> (0.0, k_max, n); Matrix<double> x = k_max*rad; fov = interp1 (x, fov, r, INTERP::LINEAR); dr = sp.shots / (1500.0 * fov_max); n = ceil (k_max/dr); x = r; r = linspace<double> (0.0, k_max, n); fov = interp1 (x, fov, r, INTERP::AKIMA); theta = cumsum ((2 * PI * dr / sp.shots) * fov); gp.k = Matrix<double> (numel(r), 3); for (size_t i = 0; i < numel(r); i++) { gp.k(i,0) = r[i] * cos (theta[i]); gp.k(i,1) = r[i] * sin (theta[i]); } gp.mgr = sp.mgr; gp.msr = sp.msr; gp.dt = sp.dt; gp.gunits = sp.gunits; gp.lunits = sp.lunits; Solution s = ComputeGradient (gp); return s; }
vec4 RenderVectorGraphics( vec2 vertexPosition, vec3 bezierKLM, vec2 texUV, float pathOffset ) \n\ { \n\ float alphaBlending2 = alphaBlending; \n\ vec4 fragColor = brushColor; \n\ // switch-case not working with intel graphics cards? \n\ //switch( gradientType ){ \n\ //case 0: break; \n\ //case 1: fragColor = ComputeLinearGradient( vertexPosition ); break; \n\ //case 2: fragColor = ComputeRadialGradient( vertexPosition ); break; \n\ //} \n\ if( dashCount > 0 ) alphaBlending2 *= HandleDash( pathOffset ); \n\ if( gradientType > 0 ) fragColor = ComputeGradient( vertexPosition, pathOffset ); \n\ if( textureCount > 0 ) fragColor = texture( textures[0], texUV ); \n\ float klm = abs( bezierKLM[0] ) + abs( bezierKLM[1] ) + abs( bezierKLM[2] ); \n\ if( klm > 1E-16 ) fragColor = ComputeCubicBezier( bezierKLM, fragColor ); \n\ //fragColor = ComputeQuadraticBezier( vec2( texcoord ), fragColor ); \n\ fragColor.a *= alphaBlending2; \n\ return fragColor; \n\ }";
///////////////////////////////////////////////////////////////////////////// // Newton-Raphson's method ///////////////////////////////////////////////////////////////////////////// void CDiffFunction::Newton(std::vector<double> &vMax, bool fTrace) { const std::vector<double> &vG = GetGradient(); const std::vector<double> &vH = GetHessian(); int n = GetDimensions(); if (fTrace) std::cout << '\n'; for (int Iterations = MaxNewtonIterations; --Iterations >= 0;) { double L = GetOutput(&vMax[0]); ComputeGradient(); ComputeHessian(); if (fTrace) { std::cout << std::setw(5) << Iterations; std::cout << std::setw(12) << vMax[0]; std::cout << std::setw(12) << L; std::cout << std::setw(12) << vG[0]; std::cout << std::setw(12) << vH[0]; std::cout << '\n'; } // // Compute Gradient multiplied by inverse of opposite of Hessian // vStep = vG; if (CMatrixOperations::Cholesky(&vH[0], &vCholesky[0], n)) CMatrixOperations::Solve(&vCholesky[0], &vStep[0], n); // // If the Hessian is not definite negative, CG // else { CG(&vMax[0], fTrace); return; } // // Apply change // for (int i = n; --i >= 0;) vxTemp[i] = Normalize(vMax[i] + vStep[i]); // // If probability did not improve, use CG // double LNew = GetOutput(&vxTemp[0]); double NewtonStep = 1.0; if ((LNew != LNew || LNew < L) && NewtonStep > MinNewtonStep) { CG(&vMax[0], fTrace); return; } // // Stop looping if small improvement // vMax = vxTemp; if (LNew - L < NewtonThreshold) return; } //std::cerr << "warning: reached MaxNewtonIterations\n"; }
///////////////////////////////////////////////////////////////////////////// // Conjugate Gradient ///////////////////////////////////////////////////////////////////////////// void CDiffFunction::CG(double vMax[], bool fTrace) { const std::vector<double> &vG = GetGradient(); std::vector<double> vPrevG; std::vector<double> vD; const int Cycles = GetDimensions(); // // Loop of iterations // for (int Iteration = 0; Iteration < MaxCGIterations; Iteration++) { // // Compute output and gradient at current point // GetOutput(&vMax[0]); ComputeGradient(); // // At the beginning of a cycle, go in the gradient direction // int Cycle = Iteration % Cycles; if (Cycle == 0) { vPrevG = vG; vD = vG; } // // Otherwise, compute conjugate direction // else { double Num = 0; double Den = 0; for (int i = GetDimensions(); --i >= 0;) { Num += vG[i] * (vG[i] - vPrevG[i]); Den += vPrevG[i] * vPrevG[i]; } double Beta = Num / Den; if (Den == 0 || Beta > MaxBeta) Beta = MaxBeta; for (int i = GetDimensions(); --i >= 0;) { vD[i] = vG[i] + Beta * vD[i]; vPrevG[i] = vG[i]; } } // // Trick to avoid getting stuck at a minimum // { int x = Iteration % GetDimensions(); if (vD[x] * vD[x] == 0.0) { if (vD[x] >= 0) vD[x] = 1.0; else vD[x] = -1.0; } } // // Perform line optimization // double x = LineOpt(vMax, &vD[0], fTrace); double Delta2 = 0.0; for (int i = GetDimensions(); --i >= 0;) { double New = Normalize(vMax[i] + x * vD[i]); double Delta = New - vMax[i]; vMax[i] = New; Delta2 += Delta * Delta; } if (Cycle == 0 && Delta2 < CGEpsilon) return; } // std::cerr << "warning: reached MaxCGIterations\n"; }
// Adds sub-pixel resolution EdgeOffsets for the outline if the supplied // pix is 8-bit. Does nothing otherwise. // Operation: Consider the following near-horizontal line: // _________ // |________ // |________ // At *every* position along this line, the gradient direction will be close // to vertical. Extrapoaltion/interpolation of the position of the threshold // that was used to binarize the image gives a more precise vertical position // for each horizontal step, and the conflict in step direction and gradient // direction can be used to ignore the vertical steps. void C_OUTLINE::ComputeEdgeOffsets(int threshold, Pix* pix) { if (pixGetDepth(pix) != 8) return; const l_uint32* data = pixGetData(pix); int wpl = pixGetWpl(pix); int width = pixGetWidth(pix); int height = pixGetHeight(pix); bool negative = flag(COUT_INVERSE); delete [] offsets; offsets = new EdgeOffset[stepcount]; ICOORD pos = start; ICOORD prev_gradient; ComputeGradient(data, wpl, pos.x(), height - pos.y(), width, height, &prev_gradient); for (int s = 0; s < stepcount; ++s) { ICOORD step_vec = step(s); TPOINT pt1(pos); pos += step_vec; TPOINT pt2(pos); ICOORD next_gradient; ComputeGradient(data, wpl, pos.x(), height - pos.y(), width, height, &next_gradient); // Use the sum of the prev and next as the working gradient. ICOORD gradient = prev_gradient + next_gradient; // best_diff will be manipulated to be always positive. int best_diff = 0; // offset will be the extrapolation of the location of the greyscale // threshold from the edge with the largest difference, relative to the // location of the binary edge. int offset = 0; if (pt1.y == pt2.y && abs(gradient.y()) * 2 >= abs(gradient.x())) { // Horizontal step. diff_sign == 1 indicates black above. int diff_sign = (pt1.x > pt2.x) == negative ? 1 : -1; int x = MIN(pt1.x, pt2.x); int y = height - pt1.y; int best_sum = 0; int best_y = y; EvaluateVerticalDiff(data, wpl, diff_sign, x, y, height, &best_diff, &best_sum, &best_y); // Find the strongest edge. int test_y = y; do { ++test_y; } while (EvaluateVerticalDiff(data, wpl, diff_sign, x, test_y, height, &best_diff, &best_sum, &best_y)); test_y = y; do { --test_y; } while (EvaluateVerticalDiff(data, wpl, diff_sign, x, test_y, height, &best_diff, &best_sum, &best_y)); offset = diff_sign * (best_sum / 2 - threshold) + (y - best_y) * best_diff; } else if (pt1.x == pt2.x && abs(gradient.x()) * 2 >= abs(gradient.y())) { // Vertical step. diff_sign == 1 indicates black on the left. int diff_sign = (pt1.y > pt2.y) == negative ? 1 : -1; int x = pt1.x; int y = height - MAX(pt1.y, pt2.y); const l_uint32* line = pixGetData(pix) + y * wpl; int best_sum = 0; int best_x = x; EvaluateHorizontalDiff(line, diff_sign, x, width, &best_diff, &best_sum, &best_x); // Find the strongest edge. int test_x = x; do { ++test_x; } while (EvaluateHorizontalDiff(line, diff_sign, test_x, width, &best_diff, &best_sum, &best_x)); test_x = x; do { --test_x; } while (EvaluateHorizontalDiff(line, diff_sign, test_x, width, &best_diff, &best_sum, &best_x)); offset = diff_sign * (threshold - best_sum / 2) + (best_x - x) * best_diff; } offsets[s].offset_numerator = static_cast<inT8>(ClipToRange(offset, -MAX_INT8, MAX_INT8)); offsets[s].pixel_diff = static_cast<uinT8>(ClipToRange(best_diff, 0 , MAX_UINT8)); if (negative) gradient = -gradient; // Compute gradient angle quantized to 256 directions, rotated by 64 (pi/2) // to convert from gradient direction to edge direction. offsets[s].direction = Modulo(FCOORD::binary_angle_plus_pi(gradient.angle()) + 64, 256); prev_gradient = next_gradient; } }
//All the *_grad is the gradient of pos_score - neg_score w.r.t. the parameter * void CRelation::TrainRelatTriple(int head, bool head_is_word, int r, int tail) { real head_grads[MAX_EMBEDDING_SIZE], tail_grads[MAX_EMBEDDING_SIZE], grads_tmp[MAX_EMBEDDING_SIZE], relat_grads[MAX_EMBEDDING_SIZE], negh_grads[MAX_EMBEDDING_SIZE], negt_grads[MAX_EMBEDDING_SIZE], negr_grads[MAX_EMBEDDING_SIZE]; real head_left_mat_grads[MAX_EMBEDDING_SIZE * MAX_RELAT_RANK], head_right_mat_grads[MAX_EMBEDDING_SIZE * MAX_RELAT_RANK], tail_left_mat_grads[MAX_EMBEDDING_SIZE * MAX_RELAT_RANK], tail_right_mat_grads[MAX_EMBEDDING_SIZE * MAX_RELAT_RANK]; real negr_head_left_mat_grads[MAX_EMBEDDING_SIZE * MAX_RELAT_RANK], negr_head_right_mat_grads[MAX_EMBEDDING_SIZE * MAX_RELAT_RANK], negr_tail_left_mat_grads[MAX_EMBEDDING_SIZE * MAX_RELAT_RANK], negr_tail_right_mat_grads[MAX_EMBEDDING_SIZE * MAX_RELAT_RANK]; real head_mat_grads[MAX_RELAT_RANK], tail_mat_grads[MAX_RELAT_RANK]; real negr_head_mat_grads[MAX_RELAT_RANK], negr_tail_mat_grads[MAX_RELAT_RANK]; //Used for the diag case real off_vec[MAX_EMBEDDING_SIZE], neg_off_vec[MAX_EMBEDDING_SIZE]; real Qh_h[MAX_RELAT_RANK], Qh_negh[MAX_RELAT_RANK], Qt_t[MAX_RELAT_RANK], Qt_negt[MAX_RELAT_RANK]; real PhT_offvec[MAX_RELAT_RANK], PtT_offvec[MAX_RELAT_RANK]; memset(head_grads, 0, sizeof(real)* Opt::embeding_size); memset(tail_grads, 0, sizeof(real)* Opt::embeding_size); memset(relat_grads, 0, sizeof(real)* Opt::embeding_size); memset(negh_grads, 0, sizeof(real)* Opt::embeding_size); memset(negt_grads, 0, sizeof(real)* Opt::embeding_size); memset(negr_grads, 0, sizeof(real)* Opt::embeding_size); if (Opt::update_mat && !Opt::is_diag) { memset(head_left_mat_grads, 0, sizeof(real)* Opt::head_relat_rank * Opt::embeding_size); memset(head_right_mat_grads, 0, sizeof(real)* Opt::head_relat_rank * Opt::embeding_size); if (Opt::use_tail_mat) { memset(tail_left_mat_grads, 0, sizeof(real)* Opt::embeding_size * Opt::tail_relat_rank); memset(tail_right_mat_grads, 0, sizeof(real)* Opt::tail_relat_rank * Opt::embeding_size); } memset(negr_head_left_mat_grads, 0, sizeof(real)* Opt::embeding_size * Opt::head_relat_rank); memset(negr_head_right_mat_grads, 0, sizeof(real)* Opt::embeding_size * Opt::head_relat_rank); if (Opt::use_tail_mat) { memset(negr_tail_left_mat_grads, 0, sizeof(real)* Opt::embeding_size * Opt::tail_relat_rank); memset(negr_tail_right_mat_grads, 0, sizeof(real)* Opt::embeding_size * Opt::tail_relat_rank); } } if (Opt::update_mat && Opt::is_diag) { memset(head_mat_grads, 0, sizeof(real)* Opt::embeding_size); memset(tail_mat_grads, 0, sizeof(real)* Opt::embeding_size); memset(negr_head_mat_grads, 0, sizeof(real)* Opt::embeding_size); memset(negr_tail_mat_grads, 0, sizeof(real)* Opt::embeding_size); } //Sample neg head word and neg tail word int neg_head, neg_tail, neg_r; do { neg_head = SampleWordIdx(); } while (neg_head == head || neg_head == tail); do { neg_tail = SampleWordIdx(); } while (neg_tail == head || neg_tail == tail); do { neg_r = SampleRelatIdx(); } while (neg_r == r); real* head_embedding = WordParams::p_embedding[head]; real* tail_embedding = WordParams::p_embedding[tail]; real* relat_embedding = p_relat_emb[r]; real* relat_act_embedding = Opt::act_relat ? p_relat_act_emb[r] : NULL; real* neg_head_embedding = WordParams::p_embedding[neg_head]; real* neg_tail_embedding = WordParams::p_embedding[neg_tail]; real* neg_r_embedding = p_relat_emb[neg_r]; real* neg_r_act_embedding = Opt::act_relat ? p_relat_act_emb[neg_r] : NULL; real pos_score = ComputeScore(head, r, tail, Qh_h, Qt_t, off_vec); real negh_score = ComputeScore(neg_head, r, tail, Qh_negh, Qt_t, neg_off_vec); real hgap; bool is_negh_margin_satisfied; hgap = negh_score - pos_score; is_negh_margin_satisfied = hgap > Opt::margin; if (!is_negh_margin_satisfied) //margin is not satisfied ComputeGradient(1, Opt::relat_neg_weight, r, grads_tmp, negh_grads, tail_grads, relat_grads, head_left_mat_grads, head_right_mat_grads, tail_left_mat_grads, tail_right_mat_grads, neg_off_vec, Qh_negh, Qt_t, PhT_offvec, PtT_offvec, neg_head_embedding, tail_embedding, head_mat_grads, tail_mat_grads); //Begin updating the loss and grads for ||LR(h - t)||_2^2 - ||LR(h - negt)||_2^2 real negt_score = ComputeScore(head, r, neg_tail, Qh_h, Qt_negt, neg_off_vec); real tgap; bool is_negt_margin_satisfied; tgap = negt_score - pos_score; is_negt_margin_satisfied = tgap > Opt::margin; if (!is_negt_margin_satisfied) ComputeGradient(1, Opt::relat_neg_weight, r, grads_tmp, head_grads, negt_grads, relat_grads, head_left_mat_grads, head_right_mat_grads, tail_left_mat_grads, tail_right_mat_grads, neg_off_vec, Qh_h, Qt_negt, PhT_offvec, PtT_offvec, head_embedding, neg_tail_embedding, head_mat_grads, tail_mat_grads); real negr_score = ComputeScore(head, neg_r, tail, Qh_negh, Qt_negt, neg_off_vec); real rgap; bool is_negr_margin_satisfied = true;; rgap = negr_score - pos_score; is_negr_margin_satisfied = rgap > Opt::margin; if (!is_negr_margin_satisfied) ComputeGradient(1, Opt::relat_neg_weight, neg_r, grads_tmp, head_grads, tail_grads, negr_grads, negr_head_left_mat_grads, negr_head_right_mat_grads, negr_tail_left_mat_grads, negr_tail_right_mat_grads, neg_off_vec, Qh_negh, Qt_negt, PhT_offvec, PtT_offvec, head_embedding, tail_embedding, negr_head_mat_grads, negr_tail_mat_grads); if (!Opt::sig_relat && is_negh_margin_satisfied && is_negt_margin_satisfied && is_negr_margin_satisfied) return; int effect_cnt = (is_negh_margin_satisfied ? 0 : 1) + (is_negt_margin_satisfied ? 0 : 1) + (is_negr_margin_satisfied ? 0 : 1); ComputeGradient(-1, effect_cnt, r, grads_tmp, head_grads, tail_grads, relat_grads, head_left_mat_grads, head_right_mat_grads, tail_left_mat_grads, tail_right_mat_grads, off_vec, Qh_h, Qt_t, PhT_offvec, PtT_offvec, head_embedding, tail_embedding, head_mat_grads, tail_mat_grads); //Gradient Checking /*real gap = (is_negh_margin_satisfied ? 0 : negh_score - pos_score) + (is_negt_margin_satisfied ? 0 : negt_score - pos_score) + (is_negr_margin_satisfied ? 0 : negr_score - pos_score); if (rand() < 20) { const double epsilon = 1e-6; //head_embedding[idx] += epsilon; //p_head_left_mat[r][idx] += epsilon; //p_tail_right_mat[r][idx] += epsilon; //tail_embedding[idx] += epsilon; //p_actual_left_mat[r][idx] = 2 * Util::Sigmoid(p_left_mat[r][41]) - 1; //p_tail_left_mat[r][idx] += epsilon; //p_head_left_mat[neg_r][idx] += epsilon; //p_actual_right_mat[r][idx] = 2 * Util::Sigmoid(p_right_mat[r][idx]) - 1; //p_relat_emb[neg_r][idx] += epsilon; //p_relat_act_emb[neg_r][idx] = 2 * Util::Sigmoid(p_relat_emb[neg_r][idx]) - 1; idx = -1; for (auto x : tail_diag_mat_ele[r]) idx = x.first; printf("\n"); tail_diag_mat_ele[neg_r][idx] += epsilon; real new_gap = 0, pos_score = ComputeLoss(head, tail, r); //ComputeLoss(head, tail, neg_r) - ComputeLoss(head, tail, r); real neg_gap = ComputeLoss(neg_head, tail, r) - pos_score; if (neg_gap <= Opt::margin) new_gap += neg_gap; neg_gap = ComputeLoss(head, neg_tail, r) - pos_score; if (neg_gap <= Opt::margin) new_gap += neg_gap; neg_gap = ComputeLoss(head, tail, neg_r) - pos_score; if (neg_gap <= Opt::margin) new_gap += neg_gap; printf("real gradient: %.5f, our gradient %.5f, idx:%d\n", (new_gap - gap) / epsilon, negr_tail_mat_grads[idx], idx); //p_tail_right_mat[r][idx] -= epsilon; //p_head_left_mat[neg_r][idx] -= epsilon; //tail_embedding[idx] -= epsilon; //p_actual_right_mat[r][idx] = 2 * Util::Sigmoid(p_right_mat[r][idx]) - 1; //head_embedding[idx] -= epsilon; //p_relat_emb[neg_r][idx] -= epsilon; //p_relat_act_emb[neg_r][idx] = 2 * Util::Sigmoid(p_relat_emb[neg_r][idx]) - 1; //p_actual_left_mat[neg_r][idx] = 2 * Util::Sigmoid(p_left_mat[r][41]) - 1; tail_diag_mat_ele[neg_r][idx] -= epsilon; }*/ double step_size = GetStepSize(head, r, tail); step_size /= effect_cnt; Util::MatPlusMat(relat_embedding, relat_grads, step_size, Opt::embeding_size, 1); Util::MatPlusMat(head_embedding, head_grads, step_size, Opt::embeding_size, 1); Util::MatPlusMat(tail_embedding, tail_grads, step_size, Opt::embeding_size, 1); if (!is_negt_margin_satisfied) Util::MatPlusMat(neg_tail_embedding, negt_grads, step_size, Opt::embeding_size, 1); if (!is_negh_margin_satisfied) Util::MatPlusMat(neg_head_embedding, negh_grads, step_size, Opt::embeding_size, 1); if (!is_negr_margin_satisfied) Util::MatPlusMat(neg_r_embedding, negr_grads, step_size, Opt::embeding_size, 1); if (Opt::update_mat && !Opt::is_diag) { Util::MatPlusMat(p_head_left_mat[r], head_left_mat_grads, step_size, Opt::embeding_size, Opt::head_relat_rank); Util::MatPlusMat(p_head_right_mat[r], head_right_mat_grads, step_size, Opt::head_relat_rank, Opt::embeding_size); if (Opt::use_tail_mat) { Util::MatPlusMat(p_tail_left_mat[r], tail_left_mat_grads, step_size, Opt::embeding_size, Opt::tail_relat_rank); Util::MatPlusMat(p_tail_right_mat[r], tail_right_mat_grads, step_size, Opt::tail_relat_rank, Opt::embeding_size); } if (!is_negr_margin_satisfied) { Util::MatPlusMat(p_head_left_mat[neg_r], negr_head_left_mat_grads, step_size, Opt::embeding_size, Opt::head_relat_rank); Util::MatPlusMat(p_head_right_mat[neg_r], negr_head_right_mat_grads, step_size, Opt::embeding_size, Opt::head_relat_rank); if (Opt::use_tail_mat) { Util::MatPlusMat(p_tail_left_mat[neg_r], negr_tail_left_mat_grads, step_size, Opt::embeding_size, Opt::tail_relat_rank); Util::MatPlusMat(p_tail_right_mat[neg_r], negr_tail_right_mat_grads, step_size, Opt::embeding_size, Opt::tail_relat_rank); } } } else if (Opt::update_mat && Opt::is_diag) { for (auto x : head_diag_mat_ele[r]) head_diag_mat_ele[r][x.first] += step_size * head_mat_grads[x.first]; if (Opt::use_tail_mat) for (auto x : tail_diag_mat_ele[r]) tail_diag_mat_ele[r][x.first] += step_size * tail_mat_grads[x.first]; if (!is_negr_margin_satisfied) { for (auto x : head_diag_mat_ele[neg_r]) head_diag_mat_ele[neg_r][x.first] += step_size * negr_head_mat_grads[x.first]; if (Opt::use_tail_mat) for (auto x : tail_diag_mat_ele[neg_r]) tail_diag_mat_ele[neg_r][x.first] += step_size * negr_tail_mat_grads[x.first]; } } ConstrainParameters(r); if (!is_negr_margin_satisfied) ConstrainParameters(neg_r); }
void RemoveNegativeNodes( GPU::Classes::GCAmorphGPU& gcam, const GPU::Classes::MRIframeGPU<T>& mri, GCA_MORPH_PARMS *parms ) { /*! Implementation of gcamRemoveNegativeNodes for the GPU pipeline */ GCA_MORPH_PARMS saved_parms = *parms; double min_dt, orig_dt = parms->orig_dt, rms, last_rms, pct_change; int old_neg, new_neg, i; GPU::Algorithms::GCAmorphEnergy gcamEnergy; if( gcam.neg <=0 ) { return; } // Try simple removal gcam.RemoveSingularities(); if( gcam.neg <= 0 ) { return; } parms->noneg = 0 ; parms->l_distance = parms->l_log_likelihood = parms->l_binary = parms->l_multiscale = parms->l_spring = parms->l_area = parms->l_smoothness = parms->l_label = 0; parms->navgs = 0; parms->l_area = 0.0; parms->l_jacobian = 1; parms->dt = 0.1; parms->tol = 0.01; last_rms = rms = gcamEnergy.ComputeRMS( gcam, mri, parms ); new_neg = gcam.neg; i = 0; do { old_neg = new_neg; ComputeGradient( gcam, mri, mri, parms ); min_dt = FindOptimalTimestep( gcam, parms, mri ); parms->dt = min_dt; gcam.ApplyGradient( parms ); last_rms = rms; rms = gcamEnergy.ComputeRMS( gcam, mri, parms ); parms->dt = orig_dt; new_neg = gcam.neg; pct_change = 100.0*(last_rms-rms)/(last_rms); printf( "iter %d, dt=%2.6f: new neg %d, old_neg %d, delta %d, rms=%2.3f\n", ++i, min_dt, new_neg, old_neg, old_neg-new_neg, rms, pct_change ); } while( (new_neg>0) && (pct_change > parms->tol) && (i < kMaxNegIter) ); *parms = saved_parms; }