array<int> oriental_language_rep::get_hyphens (string s) { int i; array<int> penalty (N(s)+1); for (i=0; i<N(penalty); i++) penalty[i]= HYPH_INVALID; return penalty; }
void software_list_device::find_approx_matches(const std::string &name, int matches, const software_info **list, const char *interface) { // if no name, return if (name.empty()) return; // initialize everyone's states std::vector<double> penalty(matches); for (int matchnum = 0; matchnum < matches; matchnum++) { penalty[matchnum] = 2.0; list[matchnum] = nullptr; } // iterate over our info (will cause a parse if needed) std::u32string const search(ustr_from_utf8(normalize_unicode(name, unicode_normalization_form::D, true))); for (const software_info &swinfo : get_info()) { for (const software_part &swpart : swinfo.parts()) { if ((interface == nullptr || swpart.matches_interface(interface)) && is_compatible(swpart) == SOFTWARE_IS_COMPATIBLE) { // pick the best match between driver name and description double const longpenalty = util::edit_distance(search, ustr_from_utf8(normalize_unicode(swinfo.longname(), unicode_normalization_form::D, true))); double const shortpenalty = util::edit_distance(search, ustr_from_utf8(normalize_unicode(swinfo.shortname(), unicode_normalization_form::D, true))); double const curpenalty = (std::min)(longpenalty, shortpenalty); // make sure it isn't already in the table bool skip = false; for (int matchnum = 0; !skip && (matchnum < matches) && list[matchnum]; matchnum++) { if ((penalty[matchnum] == curpenalty) && (swinfo.longname() == list[matchnum]->longname()) && (swinfo.shortname() == list[matchnum]->shortname())) skip = true; } if (!skip) { // insert into the sorted table of matches for (int matchnum = matches - 1; matchnum >= 0; matchnum--) { // stop if we're worse than the current entry if (curpenalty >= penalty[matchnum]) break; // as long as this isn't the last entry, bump this one down if (matchnum < matches - 1) { penalty[matchnum + 1] = penalty[matchnum]; list[matchnum + 1] = list[matchnum]; } list[matchnum] = &swinfo; penalty[matchnum] = curpenalty; } } } } } }
void edit_distance_haste(int row) { int k, p_row_0 = penalty(row, 0); int *cmpvals_org = NULL; assert(row); /* take penalty values, or prepopulate if mpenalty is unavailable */ if (mmpenalty != NULL) { cmpvals_org = cmpvals; mmpenalty(row, row - K, &cmpvals); } else if (mpenalty != NULL) { mpenalty(row, row - K, row + K + 1, cmpvals); } else { for (k = 0; k < double_K_plus_1; ++k) { cmpvals[k] = penalty(row, row + k - K); } } /* init last element in band with move 0. */ { int k = 2 * K; dp_write[k] = dp_read[k] + cmpvals[k]; RC(row, k) = 0; } /* for each element in band except last, choose move 0 or 1. */ for (k = 0; k < 2 * K; ++k) { int penal0 = dp_read[k] + cmpvals[k], penal1 = dp_read[k+1] + p_row_0; dp_write[k] = penal0 < penal1 ? penal0 : penal1; RC(row,k) = !(penal0 < penal1); } /* for each element except first in band try to choose move 2. */ for (k = 1; k < double_K_plus_1; ++k) { int penal = dp_write[k-1] + cmp_0_all[row + k - K]; if (penal < dp_write[k]) { dp_write[k] = penal; RC(row,k) = 2; } } if (cmpvals_org != NULL) { cmpvals = cmpvals_org; } swap_dps(); }
array<int> r_language_rep::get_hyphens (string s) { int i; array<int> penalty (N(s)+1); penalty[0]= HYPH_INVALID; for (i=1; i < N(s); i++) // if ( (s[i-1] == '-' && is_alpha (s[i])) || N(s)>40 ) penalty[i]= HYPH_STD; // else penalty[i]= HYPH_INVALID; penalty[i]= HYPH_INVALID; return penalty; }
real operator() (const AdaptiveHistogram * const adh, int deltaLeaf) const { dotprecision penalty(0.0); int k = adh->getRootLeaves() + deltaLeaf - 1; // leaves-1 // double logCatk= lCk(k); accumulate(penalty, c*k, log(2.0)); // pen = c*k*log(2) return (rnd(penalty)); // return c*k*log(2) }
/** * Smith-Waterman algorithm in the simplest serial implementation: the outer loop reads left-to-right * over one of the sequences--by convention, we assume it is the shorter, although we do not make any * use of that in this particular algorithm. The inner loop is over the second sequence. * * The indexing in this function may be a little confusing on first reading. In reading the inner * loop below to keep in mind that for a given i and j, we are looking at the effect of the i-1-st * element in the short sequence and the j-1-st element in the long. The reason for this--what might * appear to be an "off by one" error--is that it makes tracing back from the ends much cleaner if the * traceback matrix has a "landing spot" at 0,j and i,0 where we can place a "STOP" sentinel. * * As for the loop bounds: we go from 1 to length-1 (inclusive) in each case. Again, this might * seem wrong, but remember the lengths in question are the buffer sizes for the short and long * sequences, which are 1 longer than the actual sequence lengths, because of the C convention for * terminating strings with a 0 byte. ALl the indexing is shifted "up 1" from what one might expect. */ void computeTheBestScores(char shortSequence[], int shortLength, char longSequence[], int longLength) { int previousBestScore; /* in the inner loop: the best score at (i-1,j-1) */ int *bestScoreUpTo_I_J; /* best overall score: see note in the inner loop below */ int scoreUsingLatestIJ; /* the best score at I,J based on a match at I-1,J-1 and the previous best score */ int bestIfGapInsertedInI, /* best score at I,J if we need to insert a gap at I */ bestIfGapInsertedInJ; /* ... or J */ int i, j; /* indices into short and long sequences */ int winner; /* best score at I,J */ int tracebackScore = 0; /* the score last time we set the traceback starting point */ tracebackMatrixSize = shortLength*longLength*sizeof(char); tracebackMoves = (char *)malloc(tracebackMatrixSize); for (i = 0; i < shortLength; i++) setTracebackMove(i, 0, longLength, STOP); for (j = 1; j < longLength; j++) setTracebackMove(0, j, longLength, STOP); winningShortSequenceEnd = -1; winningLongSequenceEnd = -1; bestScoreUpTo_I_J = calloc(longLength, sizeof(int)); /* allocates and ZEROES the storage */ for (i = 1; i < shortLength; i++) { previousBestScore = 0; for (j = 1; j < longLength; j++) { scoreUsingLatestIJ = previousBestScore + score(shortSequence[i - 1], longSequence[j - 1]); bestIfGapInsertedInI = bestScoreUpTo_I_J[j] - penalty(i-1,j,longLength,UP); bestIfGapInsertedInJ = bestScoreUpTo_I_J[j-1] - penalty(i,j-1,longLength,LEFT); previousBestScore = bestScoreUpTo_I_J[j]; /* save for the next time around the loop. */ winner = bestScoreUpTo_I_J[j] = maxOrZero(scoreUsingLatestIJ, bestIfGapInsertedInI, bestIfGapInsertedInJ); if (winner == 0) setTracebackMove(i, j, longLength, (char)STOP); else if (winner == scoreUsingLatestIJ) setTracebackMove(i, j, longLength, (char)DIAGONAL); else if (winner == bestIfGapInsertedInI) setTracebackMove(i, j, longLength, (char)UP); else setTracebackMove(i, j, longLength, (char)LEFT); if (winner > tracebackScore) { /* we should start the traceback at this i,j */ tracebackScore = winner; setTracebackStartingPoint(i,j); } } } free(bestScoreUpTo_I_J); }
real operator() (const AdaptiveHistogram * const adh, int deltaLeaf) const { dotprecision penalty(0.0); int k = adh->getRootLeaves() + deltaLeaf - 1; // leaves-1 double logCatk= lCk(k); size_t counter = adh->getRootCounter(); // total number points accumulate(penalty, c, logCatk); // pen = c*logCatk real s = adh->getRootSumLeafCountOverVol(); accumulate(penalty, s/(1.0*counter), alpha); //now pen = c*logCatk + (alpha/counter)*sum(leaf counts/vols) accumulate(penalty, 2*r, log(k+1)); //now pen = c*logCatk + (alpha/counter)*sum(leaf counts/vols) + 2*r*log(k+1) return rnd(penalty); }
void software_list_device::find_approx_matches(const char *name, int matches, const software_info **list, const char *interface) { // if no name, return if (name == nullptr || name[0] == 0) return; // initialize everyone's states std::vector<int> penalty(matches); for (int matchnum = 0; matchnum < matches; matchnum++) { penalty[matchnum] = 9999; list[matchnum] = nullptr; } // iterate over our info (will cause a parse if needed) for (const software_info &swinfo : get_info()) { const software_part &part = swinfo.parts().front(); if ((interface == nullptr || part.matches_interface(interface)) && is_compatible(part) == SOFTWARE_IS_COMPATIBLE) { // pick the best match between driver name and description int longpenalty = driver_list::penalty_compare(name, swinfo.longname().c_str()); int shortpenalty = driver_list::penalty_compare(name, swinfo.shortname().c_str()); int curpenalty = std::min(longpenalty, shortpenalty); // insert into the sorted table of matches for (int matchnum = matches - 1; matchnum >= 0; matchnum--) { // stop if we're worse than the current entry if (curpenalty >= penalty[matchnum]) break; // as long as this isn't the last entry, bump this one down if (matchnum < matches - 1) { penalty[matchnum + 1] = penalty[matchnum]; list[matchnum + 1] = list[matchnum]; } list[matchnum] = &swinfo; penalty[matchnum] = curpenalty; } } } }
int main(){ long n; scanf("%ld", &n); std::multiset<ll> s; for(long p = 0; p < n; p++){ll x; scanf("%lld", &x); s.insert(x);} if(s.size() % 2 == 0){s.insert(0);} ll penalty(0); while(s.size() > 2){ ll x = *(s.begin()); s.erase(s.begin()); ll y = *(s.begin()); s.erase(s.begin()); ll z = *(s.begin()); s.erase(s.begin()); penalty += (x + y + z); s.insert(x + y + z); } printf("%lld\n", penalty); return 0; }
double IFunctional::fx(const DoubleVector &pv) const { IFunctional* ifunc = const_cast<IFunctional*>(this); ifunc->fromVector(pv, ifunc->mParameter); //functional->mParameter.fromVector(prms); ifunc->forward->setParameter(mParameter); ifunc->backward->setParameter(mParameter); DoubleMatrix u; vector<ExtendedSpaceNode2D> info; ifunc->forward->calculateMVD(u, info, true); double intgrl = integral(u); u.clear(); return intgrl + regEpsilon*norm() + r*penalty(info); }
void tex::show_split(int n, scal w, ptr q) { begin_diagnostic(); print_nl("% split"); print_int(n); print(" to "); print_scaled(w); print_char(','); print_scaled(best_height_plus_depth); print(" p="); if (q == null) { print_int(EJECT_PENALTY); } else if (type(q) == PENALTY_NODE) { print_int(penalty(q)); } else { print("0"); } end_diagnostic(FALSE); }
real operator() (const AdaptiveHistogram * const adh, int deltaLeaf) const { dotprecision penalty(0.0); int k = adh->getRootLeaves() + deltaLeaf - 1; // leaves-1 double logCatk= lCk(k); accumulate(penalty, c, logCatk); // pen = c*logCatk accumulate(penalty, alpha, k); // pen = c*logCatk + alpha*k accumulate(penalty, c*r, log(k+1.0)); // now pen = c*logCatk + alpha*k + c*r*log(k+1) dotprecision temp(0.0); accumulate(temp, c*alpha*k, logCatk); accumulate(temp, r, log(k+1.0)); // temp = c*alpha*k*logCatk + r*log(k+1) return (rnd(penalty) + 2*sqrt(rnd(temp))); // return c*logCatk + alpha*k + c*r*log(k+1) // + 2*sqrt(c*alpha*k*logCatk + r*log(k+1)) }
ptr tex::vert_break(ptr p, scal h, scal d) { int b; ptr q; ptr r; int t; int pi=0; ptr prev_p; scal prev_dp; ptr best_place=0; int least_cost; #define INF_SHRINK_BOX "Infinite glue shrinkage found in box being split" prev_p = p; least_cost = AWFUL_BAD; do_all_six(set_height_zero); prev_dp = 0; loop { if (p == null) { pi = EJECT_PENALTY; } else { switch (type(p)) { case HLIST_NODE: case VLIST_NODE: case RULE_NODE: cur_height += prev_dp + box_height(p); prev_dp = box_depth(p); goto not_found; case WHATSIT_NODE: goto not_found; case GLUE_NODE: if (precedes_break(prev_p)) { pi = 0; } else { goto update_heights; } break; case KERN_NODE: if (link(p) == null) { t = PENALTY_NODE; } else { t = type(link(p)); } if (t == GLUE_NODE) { pi = 0; } else { goto update_heights; } break; case PENALTY_NODE: pi = penalty(p); break; case MARK_NODE: case INS_NODE: goto not_found; default: confusion("vertbreak"); } } if (pi < INF_PENALTY) { b = vert_badness(h); if (b < AWFUL_BAD) { if (pi <= EJECT_PENALTY) { b = pi; } else if (b < INF_BAD) { b += pi; } else { b = DEPLORABLE; } } if (b <= least_cost) { best_place = p; least_cost = b; best_height_plus_depth = cur_height + prev_dp; } if (b == AWFUL_BAD || pi <= EJECT_PENALTY) { return best_place; } } if (type(p) < GLUE_NODE || type(p) > KERN_NODE) { goto not_found; } update_heights: if (type(p) == KERN_NODE) { cur_height += prev_dp + kern_width(p); } else { q = glue_ptr(p); active_height[2 + stretch_order(q)] += stretch(q); active_height[6] += shrink(q); if (shrink_order(q) != NORMAL && shrink(q) != 0) { print_err(INF_SHRINK_BOX); help_inf_shrink_box(); error(); r = new_spec(q); delete_glue_ref(q); shrink_order(r) = NORMAL; glue_ptr(p) = r; } cur_height += prev_dp + glue_width(q); } prev_dp = 0; not_found: if (prev_dp > d) { cur_height = cur_height + prev_dp - d; prev_dp = d; } prev_p = p; p = link(prev_p); } }
real sa(unsigned seed) { srandom(seed); real T; if (initial_temp_method != constant) T = INFINITY; else T = initial_temp; real step_size_x = init_step_size, step_size_y = init_step_size; real pos_x = 5, pos_y = 5; real obj = bump(pos_x, pos_y); real obj_pen = obj; int samples_remaining = 5000-1; real obj_d[5000]; int n_obj_d = 0; real accepts[5000]; int n_accepts = 0; int num_trials = 0, num_acceptances = 0; int initial_trials = 500; int max_trials = temp_length; int max_acceptances = 0.6*temp_length; real alpha = 0.1, omega = 2.1; real best_obj = obj; real best_x = pos_x, best_y = pos_y; int best_time = samples_remaining; while (samples_remaining > 0) { if (best_time - samples_remaining > 500) { best_time = samples_remaining; pos_x = best_x; pos_y = best_y; obj = best_obj; obj_pen = best_obj + penalty_weight * penalty(pos_x, pos_y) / T; step_size_x = step_size_y = init_step_size; } real step_x, step_y; if (step_method == gaussian) { step_x = step_size_x * randn(); step_y = step_size_y * randn(); } else { step_x = step_size_x * (2*randf()-1); step_y = step_size_y * (2*randf()-1); } real new_x = pos_x+step_x, new_y = pos_y+step_y; real new_pen = penalty_weight * penalty(new_x, new_y); if (T == INFINITY && new_pen != 0) continue; real new_obj = bump(new_x, new_y); real new_obj_pen = new_obj + new_pen / T; samples_remaining--; num_trials++; if (new_pen == 0) { if (new_obj > best_obj) { best_obj = new_obj; best_x = new_x; best_y = new_y; best_time = samples_remaining; } } real p; if (step_method == parks) { real step_norm = sqrtr(step_x*step_x + step_y*step_y); p = exp(- (obj_pen - new_obj_pen) / (T * step_norm)); } else { p = exp(- (obj_pen - new_obj_pen) / T); } if (randf() < p) { num_acceptances++; obj_d[n_obj_d++] = new_obj_pen - obj_pen; pos_x = new_x; pos_y = new_y; obj = new_obj; obj_pen = new_obj_pen; accepts[n_accepts++] = new_obj_pen; if (T != INFINITY && step_method == parks) { step_size_x = (1-alpha)*step_size_x + alpha*omega*fabsr(step_x); step_size_y = (1-alpha)*step_size_y + alpha*omega*fabsr(step_y); } } bool reduced_T = false; if (T == INFINITY) { if (num_trials >= initial_trials) { if (initial_temp_method == kirkpatrick) T = T_kirkpatrick(obj_d, n_obj_d); else if (initial_temp_method == white) T = std(obj_d, n_obj_d); else { fprintf(stderr, "unknown temp method"); exit(1); } reduced_T = true; } } else if (num_trials >= max_trials || num_acceptances >= max_acceptances) { if (temp_decay_method == huang) { real factor; if (n_accepts < 2) factor = 0.5; else { factor = exp(-0.7*T/std(accepts, n_accepts)); if (factor < 0.5) factor = 0.5; } T *= factor; } else T *= temp_decay; reduced_T = true; } if (reduced_T) { //printf("%g\n", T); n_obj_d = 0; num_trials = 0; num_acceptances = 0; n_accepts = 1; accepts[0] = obj_pen; } } return best_obj; }
void driver_enumerator::find_approximate_matches(const char *string, int count, int *results) { #undef rand // if no name, pick random entries if (string == NULL || string[0] == 0) { // seed the RNG first srand(osd_ticks()); // allocate a temporary list dynamic_array<int> templist(m_filtered_count); int arrayindex = 0; for (int index = 0; index < s_driver_count; index++) if (m_included[index]) templist[arrayindex++] = index; assert(arrayindex == m_filtered_count); // shuffle for (int shufnum = 0; shufnum < 4 * s_driver_count; shufnum++) { int item1 = rand() % m_filtered_count; int item2 = rand() % m_filtered_count; int temp = templist[item1]; templist[item1] = templist[item2]; templist[item2] = temp; } // copy out the first few entries for (int matchnum = 0; matchnum < count; matchnum++) results[matchnum] = templist[matchnum % m_filtered_count]; return; } // allocate memory to track the penalty value dynamic_array<int> penalty(count); // initialize everyone's states for (int matchnum = 0; matchnum < count; matchnum++) { penalty[matchnum] = 9999; results[matchnum] = -1; } // scan the entire drivers array for (int index = 0; index < s_driver_count; index++) if (m_included[index]) { // skip things that can't run if ((s_drivers_sorted[index]->flags & GAME_NO_STANDALONE) != 0) continue; // pick the best match between driver name and description int curpenalty = penalty_compare(string, s_drivers_sorted[index]->description); int tmp = penalty_compare(string, s_drivers_sorted[index]->name); curpenalty = MIN(curpenalty, tmp); // insert into the sorted table of matches for (int matchnum = count - 1; matchnum >= 0; matchnum--) { // stop if we're worse than the current entry if (curpenalty >= penalty[matchnum]) break; // as long as this isn't the last entry, bump this one down if (matchnum < count - 1) { penalty[matchnum + 1] = penalty[matchnum]; results[matchnum + 1] = results[matchnum]; } results[matchnum] = index; penalty[matchnum] = curpenalty; } } }
bool theirPenalty() const { return penalty() && !ourRestart; }
bool ourPenalty() const { return penalty() && ourRestart; }
/*Main Function*/ int main(int argc, char *argv[]) { FILE *op; int i,j,prog,total[LANG]={0,0,0,0,0}; float ratio[LANG],mod_total[LANG]={0,0,0,0,0},pen_mod_total[LANG]={0,0,0,0,0}; //char filename[100]=""; //scanf("%s",filename); prog=make_mat(argv[1]); op = fopen("/home/Rahul/Desktop/Thesis/Scripts/final_loc.csv","a"); if(prog) { //printf("\tC\t\tCPP\t\tHASKELL\t\tJAVA\t\tPYTHON\n"); //printf("\t-\t\t---\t\t------\t\t----\t\t------\n"); for(i=0;i<prog;i++) { for(j=0;j<LANG;j++) { printf("\t%d\t",mat[i][j]); total[j] = total[j] + mat[i][j]; } printf("\n"); } printf("\n\t----\t\t----\t\t----\t\t----\t\t----\n"); for(i=0;i<LANG;i++) { ratio[i] = total[0]; printf("\t%d\t",total[i]); } for(i=0;i<prog;i++) for(j=0;j<LANG;j++) if(mat[i][j] == 0) ratio[j] = ratio[j] - mat[i][C]; printf("\n"); printf("\t----\t\t----\t\t----\t\t----\t\t----\n"); for(i=0;i<LANG;i++) { ratio[i] = total[i]/ratio[i]; printf("\t%f",ratio[i]); } printf("\n"); printf("\t-\t\t---\t\t------\t\t----\t\t------\n"); for(i=0;i<prog;i++) { for(j=0;j<LANG;j++) { if(mat[i][j] == 0) { if(mat[i][C] != 0) mod_mat[i][j] = ratio[j]*mat[i][C]; else mod_mat[i][j] = (ratio[j]/ratio[CPP])*mat[i][CPP]; // if(j==C) || (j==CPP) pen_mod_mat[i][j] = penalty(mod_mat[i][j],j); } else pen_mod_mat[i][j] = mod_mat[i][j] = mat[i][j]; } } printf("\tC\t\tCPP\t\tHASKELL\t\tJAVA\t\tPYTHON\n"); printf("\t-\t\t---\t\t------\t\t----\t\t------\n"); for(i=0;i<prog;i++) { for(j=0;j<LANG;j++) { if(mat[i][j]) printf("\t%f",mod_mat[i][j]); else printf("\t%.5f*",mod_mat[i][j]); mod_total[j] = mod_total[j] + mod_mat[i][j]; } printf("\n"); } printf("\t----\t\t----\t\t----\t\t----\t\t----\n"); for(i=0;i<LANG;i++) { //ratio[i] = total[0]; printf("\t%f",mod_total[i]); } printf("\n"); printf("\t-\t\t---\t\t------\t\t----\t\t------\n"); for(i=0;i<prog;i++) { for(j=0;j<LANG;j++) { if(mat[i][j]) printf("\t%f",pen_mod_mat[i][j]); else printf("\t%.5f**",pen_mod_mat[i][j]); pen_mod_total[j] = pen_mod_total[j] + pen_mod_mat[i][j]; } printf("\n"); } printf("\t----\t\t----\t\t----\t\t----\t\t----\n"); // fprintf(op,"c,cpp,haskell,java,python\n"); for(i=0;i<LANG;i++) { //ratio[i] = total[0]; printf("\t%f",pen_mod_total[i]); if ( i == LANG-1 ) fprintf(op,"%f,%f",pen_mod_total[i],pen_mod_total[i]); else fprintf(op,"%f,",pen_mod_total[i]); } fprintf(op,"\n"); printf("\n"); printf("---------------------------------------------------------------------------\n"); fclose(op); } else printf("\nfailed to open file...\n"); return 1; }
void initialize_cmp_0_all() { int k; for (k = 0; k < n2; ++k) { cmp_0_all[k] = penalty(0, k); } }
void tex::fire_up(ptr c) { int n; bool wait; ptr prev_p; scal save_vfuzz; int save_vbadness; ptr save_split_top_skip; ptr p, q, r; if (type(best_page_break) == PENALTY_NODE) { set_output_penalty(penalty(best_page_break)); penalty(best_page_break) = INF_PENALTY; } else { set_output_penalty(INF_PENALTY); } if (bot_mark != null) { if (top_mark != null) delete_token_ref(top_mark); top_mark = bot_mark; add_token_ref(top_mark); delete_token_ref(first_mark); first_mark = null; } if (c == best_page_break) { best_page_break = null; } if (box(255) != null) { print_err(null_str); print_esc("box"); print("255 is not void"); help_box_255(); box_error(255); } insert_penalties = 0; save_split_top_skip = split_top_skip; if (holding_inserts <= 0) { r = link(page_ins_head); while (r != page_ins_head) { if (best_ins_ptr(r) != null) { n = subtype(r); ensure_vbox(n); if (box(n) == null) box(n) = new_null_box(); p = node_list(box(n)); while (link(p) != null) { p = link(p); } last_ins_ptr(r) = p; } r = link(r); } } q = hold_head; link(q) = null; prev_p = page_head; p = link(prev_p); while (p != best_page_break) { if (type(p) == INS_NODE) { if (holding_inserts <= 0) { wait = insert_box(p); link(prev_p) = link(p); link(p) = null; if (wait) { q = link(q) = p; incr(insert_penalties); } else { delete_glue_ref(split_top_ptr(p)); free_node(p, INS_NODE_SIZE); } p = prev_p; } } else if (type(p) == MARK_NODE) { if (first_mark == null) { first_mark = mark_ptr(p); add_token_ref(first_mark); } if (bot_mark != null) delete_token_ref(bot_mark); bot_mark = mark_ptr(p); add_token_ref(bot_mark); } prev_p = p; p = link(prev_p); } split_top_skip = save_split_top_skip; if (p != null) { if (link(contrib_head) == null) { if (nest_ptr == nest) { tail = page_tail; } else { contrib_tail = page_tail; } } link(page_tail) = link(contrib_head); link(contrib_head) = p; link(prev_p) = null; } save_vbadness = vbadness; save_vfuzz = vfuzz; vbadness = INF_BAD; vfuzz = MAX_DIMEN; box(255) = vpackage(link(page_head), best_size, EXACTLY, page_max_depth); vbadness = save_vbadness; vfuzz = save_vfuzz; if (last_glue != null) delete_glue_ref(last_glue); start_new_page(); if (q != hold_head) { link(page_head) = link(hold_head); page_tail = q; } r = link(page_ins_head); while (r != page_ins_head) { q = link(r); free_node(r, PAGE_INS_NODE_SIZE); r = q; } link(page_ins_head) = page_ins_head; if (top_mark != null && first_mark == null) { first_mark = top_mark; add_token_ref(top_mark); } if (output_routine != null) { if (dead_cycles >= max_dead_cycles) { print_err("Output loop---"); print_int(dead_cycles); print(" consecutive dead cycles"); help_dead_cycles(); error(); } else { output_active = TRUE; incr(dead_cycles); push_nest(); mode = -VMODE; prev_depth = IGNORE_DEPTH; mode_line = -line; begin_token_list(output_routine, OUTPUT_TEXT); new_save_level(OUTPUT_GROUP); normal_paragraph(); scan_left_brace(); return; } } if (link(page_head) != null) { if (link(contrib_head) == null) { if (nest_ptr == nest) { tail = page_tail; } else { contrib_tail = page_tail; } } else { link(page_tail) = link(contrib_head); } link(contrib_head) = link(page_head); link(page_head) = null; page_tail = page_head; } ship_out(box(255)); box(255) = null; }
void tex::show_penalty(ptr p) { print_esc("penalty "); print_int(penalty(p)); }
static void __r_insert_node (struct rtree_node *node, const BoxType * query, int manage, bool force) { #ifdef SLOW_ASSERTS assert (__r_node_is_good (node)); #endif /* Ok, at this point we must already enclose the query or we're forcing * this node to expand to enclose it, so if we're a leaf, simply store * the query here */ if (node->flags.is_leaf) { register int i; if (UNLIKELY (manage)) { register int flag = 1; for (i = 0; i < M_SIZE; i++) { if (!node->u.rects[i].bptr) break; flag <<= 1; } node->flags.manage |= flag; } else { for (i = 0; i < M_SIZE; i++) if (!node->u.rects[i].bptr) break; } /* the node always has an extra space available */ node->u.rects[i].bptr = query; node->u.rects[i].bounds = *query; /* first entry in node determines initial bounding box */ if (i == 0) node->box = *query; else if (force) { MAKEMIN (node->box.X1, query->X1); MAKEMAX (node->box.X2, query->X2); MAKEMIN (node->box.Y1, query->Y1); MAKEMAX (node->box.Y2, query->Y2); } if (i < M_SIZE) { sort_node (node); return; } /* we must split the node */ split_node (node); return; } else { int i; struct rtree_node *best_node; double score, best_score; if (force) { MAKEMIN (node->box.X1, query->X1); MAKEMAX (node->box.X2, query->X2); MAKEMIN (node->box.Y1, query->Y1); MAKEMAX (node->box.Y2, query->Y2); } /* this node encloses it, but it's not a leaf, so descend the tree */ /* First check if any children actually encloses it */ assert (node->u.kids[0]); for (i = 0; i < M_SIZE; i++) { if (!node->u.kids[i]) break; if (contained (node->u.kids[i], query)) { __r_insert_node (node->u.kids[i], query, manage, false); sort_node (node); return; } } /* see if there is room for a new leaf node */ if (node->u.kids[0]->flags.is_leaf && i < M_SIZE) { struct rtree_node *new_node; new_node = (struct rtree_node *)calloc (1, sizeof (*new_node)); new_node->parent = node; new_node->flags.is_leaf = true; node->u.kids[i] = new_node; new_node->u.rects[0].bptr = query; new_node->u.rects[0].bounds = *query; new_node->box = *query; if (UNLIKELY (manage)) new_node->flags.manage = 1; sort_node (node); return; } /* Ok, so we're still here - look for the best child to push it into */ best_score = penalty (node->u.kids[0], query); best_node = node->u.kids[0]; for (i = 1; i < M_SIZE; i++) { if (!node->u.kids[i]) break; score = penalty (node->u.kids[i], query); if (score < best_score) { best_score = score; best_node = node->u.kids[i]; } } __r_insert_node (best_node, query, manage, true); sort_node (node); return; } }
void tex::insert_page(ptr p) { int n; ptr q, r; scal h, w; scal delta; if (page_contents == EMPTY) freeze_page_specs(INSERTS_ONLY); n = subtype(p); r = page_ins_head; while (n >= subtype(link(r))) r = link(r); if (subtype(r) != n) { q = new_node(PAGE_INS_NODE_SIZE); link(q) = link(r); r = link(r) = q; subtype(r) = n; type(r) = INSERTING; ensure_vbox(n); page_ins_height(r) = (box(n) == null) ? 0 : box_height(box(n)) + box_depth(box(n)); best_ins_ptr(r) = null; q = skip(n); if (count(n) == 1000) h = page_ins_height(r); else h = x_over_n(page_ins_height(r), 1000) * count(n); page_goal -= h + glue_width(q); page_so_far[2 + stretch_order(q)] += stretch(q); page_shrink += shrink(q); if (shrink_order(q) != NORMAL && shrink(q) != 0) { print_err("Infinite glue shrinkage inserted from "); print_esc("skip"); print_int(n); help_inf_shrink_ins(); error(); } } if (type(r) == SPLIT_UP) { insert_penalties += float_cost(p); return; } last_ins_ptr(r) = p; delta = page_goal - page_total - page_depth + page_shrink; if (count(n) == 1000) { h = ins_height(p); } else { h = x_over_n(ins_height(p), 1000) * count(n); } if ((h <= 0 || h <= delta) && ins_height(p) + page_ins_height(r) <= dimen(n)) { page_goal -= h; page_ins_height(r) += ins_height(p); } else { if (count(n) <= 0) { w = MAX_DIMEN; } else { w = page_goal - page_total - page_depth; if (count(n) != 1000) { w = x_over_n(w, count(n)) * 1000; } } if (w > dimen(n) - page_ins_height(r)) { w = dimen(n) - page_ins_height(r); } q = vert_break(ins_ptr(p), w, ins_depth(p)); page_ins_height(r) += best_height_plus_depth; if (tracing_pages > 0) show_split(n, w, q); if (count(n) != 1000) { best_height_plus_depth = x_over_n(best_height_plus_depth, 1000) * count(n); } page_goal -= best_height_plus_depth; type(r) = SPLIT_UP; broken_ptr(r) = q; broken_ins(r) = p; if (q == null) { insert_penalties += EJECT_PENALTY; } else if (type(q) == PENALTY_NODE) { insert_penalties += penalty(q); } } }
void partitionEntries( IndexEntry *I, /* input entry list to partition */ Int fan, /* fan or order of index */ IndexEntry **A, /* 1st group partitioned entries */ IndexEntry **B ) /* 2nd group partitioned entries */ { /* beginning of partitionEntries() */ IndexEntry *entry1; /* looping entry to find first entry of groups */ IndexEntry *entry2; /* looping entry to find first entry of groups */ IndexEntry *currentEntry; /* looping entry for input list */ IndexEntry *previousEntry; /* looping entry for input list */ IndexEntry *tempA; /* temp entry to find first entry of group A */ IndexEntry *tempB; /* temp entry to find first entry of group B */ IndexKey unionAB; /* union of first entries of group A and B */ Float volumeAB; /* volume of first entries of group A and B */ Int sizeOfGroupA; /* current size of group A */ Int sizeOfGroupB; /* current size of group B */ static Char name[] = "partitionEntries"; assert( I && I->next ); /* need at least two entries to partition */ assert( MINIMUM_FAN_SIZE > 1 ); assert( fan >= MINIMUM_FAN_SIZE ); /* * Find "worst" combination of all entries in I. The worst combination is * the one which produces the largest bounding index key, i.e., the * largest hyper-cube volume. The two entries which form the worst combo * will be the first entries into the two groups, A and B. The method * used to find the worst combo is straight forward enumeration of all * possible combinations. Note that only forward combinations are * necessary since the volume( union( A, B ) ) is the same as the * volume( union( B, A ) ). The first candidate pair for the worst case * are chosen as the first and second entries of the input list, I. */ *A = I; *B = I->next; keyUnion( &(*A)->key, &(*B)->key, &unionAB ); volumeAB = volume( unionAB ); /* * A double loop through the input list, I, is used to find all * combinations. */ for ( entry1 = I; entry1 != NULL; entry1 = entry1->next ) { for ( entry2 = entry1->next; entry2 != NULL; entry2 = entry2->next ) { IndexKey tempKey; Float tempVolume; /* * If this combination produces a worse penalty, then replace old * candidates with new pair. */ keyUnion( &entry1->key, &entry2->key, &tempKey ); tempVolume = volume( tempKey ); if ( tempVolume > volumeAB ) { *A = entry1; *B = entry2; unionAB = tempKey; volumeAB = tempVolume; } /* end of if ( tempVolume > volumeAB ) */ } /* end of loop for entry2 */ } /* end of loop for entry1 */ /* * The entry pointers, A and B, now point to the first entries of the * two groups which are forming during the partition. Remove them from the * input list, I. Set the size of each group to one for the initial * entries. The entries of I which correspond to A and B are * found by comparing pointer values. */ currentEntry = I; /* current entry (starts at beginning of I) */ previousEntry = NULL; /* previous entry (NULL for first entry) */ while ( currentEntry != NULL ) { if ( currentEntry == *A || currentEntry == *B ) { /* * Found A or B in list as currentEntry. Remove current entry from * list, checking for special case where current entry is the head * of list, i.e., no previous entry. */ if ( previousEntry == NULL ) { /* * No previous pointer means that the current entry is the * head of the list. Removing the entry means updating I and * reseting the values for currentEntry and previousEntry. */ I = currentEntry->next; currentEntry = I; previousEntry = NULL; } /* end of if ( previousEntry == NULL ) */ else { /* * Remove current entry by setting previous entry's pointer to * skip the current. */ previousEntry->next = currentEntry->next; /* * Setup entries for next loop. Since an entry was removed * from the list, the previous entry, previousEntry, does not * change. */ currentEntry = previousEntry->next; } /* end of else */ } /* end of if ( currentEntry == A || currentEntry == B ) */ else { /* * Did not find either A or B, so just set up for next loop */ previousEntry = currentEntry; currentEntry = currentEntry->next; } /* end of else */ } /* end of loop for currentEntry */ /* * Finish up by fixing the next pointers for both A and B to NULL since * their the first and only entries in the lists, and setting the size of * each group to one. */ (*A)->next = NULL; (*B)->next = NULL; sizeOfGroupA = 1; sizeOfGroupB = 1; /* * The first entries of groups A and B are now assigned and removed from * the input list, I. The "volume" for A and B is the "worst" possible * for all combinations of the entries of I. * * Assign all remaining entries of I to each group based on penalty. The * current implementation finds the penalty of the entry with the first * entries into the group, i.e., A or B. Other methods are possible, * including using the penalty of the current group rather than the first * entry into that group. */ tempA = *A; tempB = *B; while ( I != NULL ) { /* * If neither group is full, add according to penalty */ if ( sizeOfGroupA < fan && sizeOfGroupB < fan ) { if ( penalty( **A, *I ) < penalty( **B, *I ) ) { /* * Place current entry into group A, incrementing counter */ tempA->next = I; /* add current entry to group A */ I = I->next; /* increment current entry */ tempA = tempA->next; /* increment group A ptr */ tempA->next = NULL; /* remove new entry from group I */ sizeOfGroupA++; } /* end of if ( penalty( I, A ) < penalty( I, B ) ) */ else { /* * Place current entry into group B, incrementing counter */ tempB->next = I; /* add current entry to group B */ I = I->next; /* increment current entry */ tempB = tempB->next; /* increment group B ptr */ tempB->next = NULL; /* remove new entry from group I */ sizeOfGroupB++; } /* end of else */ } /* end of if ( sizeOfGroupA < fan && sizeOfGroupB < fan ) */ /* * If group A is full and there is room on group B, then add entry to * group B */ else if ( sizeOfGroupA >= fan && sizeOfGroupB < fan ) { /* * Place entry into group B, incrementing counter */ tempB->next = I; /* add current entry to group B */ I = I->next; /* increment current entry */ tempB = tempB->next; /* increment group B ptr */ tempB->next = NULL; /* remove new entry from group I */ sizeOfGroupB++; } /* end of if ( sizeOfGroupA >= fan ) */ /* * If group B is full and there is room on group A, then add entry to * group A */ else if ( sizeOfGroupB >= fan && sizeOfGroupA < fan ) { /* * Place current entry into group A, incrementing counter */ tempA->next = I; /* add current entry to group A */ I = I->next; /* increment current entry */ tempA = tempA->next; /* increment group A ptr */ tempA->next = NULL; /* remove new entry from group I */ sizeOfGroupA++; } /* end of if ( sizeOfGroupB >= fan ) */ else { /* * Special(error) case when both groups are full and no where to * place entry. Simply ignore entry and try to continue. */ I = I->next; errorMessage( "too many entries to partition", REPLACE ); errorMessage( name, PREPEND ); } } /* end of loop for currentEntry */ return; } /* end paritionEntries() */
void tex::build_page () { int pi=0, b, c; ptr p, q, r; #define INF_SHRINK_PAGE "Infinite glue shrinkage found on current page" if (link(contrib_head) == null || output_active) return; do { p = link(contrib_head); if (last_glue != null) delete_glue_ref(last_glue); last_penalty = 0; last_kern = 0; if (type(p) == GLUE_NODE) { last_glue = glue_ptr(p); add_glue_ref(last_glue); } else { last_glue = null; if (type(p) == PENALTY_NODE) { last_penalty = penalty(p); } else if (type(p) == KERN_NODE) { last_kern = kern_width(p); } } switch (type(p)) { case HLIST_NODE: case VLIST_NODE: case RULE_NODE: if (page_contents < BOX_THERE) { if (page_contents == EMPTY) { freeze_page_specs(BOX_THERE); } else { page_contents = BOX_THERE; } q = new_skip_param(TOP_SKIP_CODE); link(q) = p; link(contrib_head) = q; r = glue_ptr(q); if (glue_width(r) > box_height(p)) { glue_width(r) -= box_height(p); } else { glue_width(r) = 0; } continue; } else { page_total += page_depth + box_height(p); page_depth = box_depth(p); goto contribute; } case GLUE_NODE: if (page_contents < BOX_THERE) { goto done; } else if (precedes_break(page_tail)) { pi = 0; } else { goto update_heights; } break; case KERN_NODE: if (page_contents < BOX_THERE) { goto done; } else if (link(p) == null) { return; } else if (type(link(p)) == GLUE_NODE) { pi = 0; } else { goto update_heights; } break; case PENALTY_NODE: if (page_contents < BOX_THERE) { goto done; } else { pi = penalty(p); } break; case WHATSIT_NODE: goto contribute; case MARK_NODE: goto contribute; case INS_NODE: insert_page(p); goto contribute; default: confusion("page"); break; } if (pi < INF_PENALTY) { b = page_badness(); if (b < AWFUL_BAD) { if (pi <= EJECT_PENALTY) { c = pi; } else if (b < INF_BAD) { c = b + pi + insert_penalties; } else { c = DEPLORABLE; } } else { c = b; } if (insert_penalties >= 10000) c = AWFUL_BAD; if (tracing_pages > 0) show_page_stats(b, pi, c); if (c <= least_page_cost) { best_page_break = p; best_size = page_goal; least_page_cost = c; r = link(page_ins_head); while (r != page_ins_head) { best_ins_ptr(r) = last_ins_ptr(r); r = link(r); } } if (c == AWFUL_BAD || pi <= EJECT_PENALTY) { fire_up(p); if (output_active) return; continue; } } if (type(p) < GLUE_NODE || type(p) > KERN_NODE) { goto contribute; } update_heights: if (type(p) == KERN_NODE) { page_total += page_depth + kern_width(p); } else { q = glue_ptr(p); page_so_far[2 + stretch_order(q)] += stretch(q); page_shrink += shrink(q); if (shrink_order(q) != NORMAL && shrink(q) != 0) { print_err(INF_SHRINK_PAGE); help_inf_shrink_page(); error(); r = new_spec(q); shrink_order(r) = NORMAL; delete_glue_ref(q); q = glue_ptr(p) = r; } page_total += page_depth + glue_width(q); } page_depth = 0; contribute: if (page_depth > page_max_depth) { page_total = page_total + page_depth - page_max_depth; page_depth = page_max_depth; } page_tail = link(page_tail) = p; link(contrib_head) = link(p); link(p) = null; continue; done: link(contrib_head) = link(p); link(p) = null; flush_node_list(p); } while (link(contrib_head) != null); if (nest_ptr == nest) { tail = contrib_head; } else { contrib_tail = contrib_head; } }
tex::pen_t::pen_t(int i) { tex::type(this) = PENALTY_NODE; tex::subtype(this) = 0; penalty(this) = i; }