typename OrderList<T>::iterator OrderList<T>:: insert(iterator p, const_reference x) { typename Parent::iterator p_base = p.get_base(); OrderType tag = (p_base++)->tag + 1; typename Parent::iterator new_base = Parent::insert(p_base, NodeType(x, tag)); if (p_base->tag != tag) return iterator(new_base); // Find non-overflowing region unsigned int num_elements = 1, maximum = 1, lower = tag, upper = tag, level = 0; float inv_density = 1; typename Parent::iterator prev = p_base, next = p_base; --(--prev); ++next; // move prev back twice to skip over the newly inserted element do { lower &= ~(1 << level); upper |= (1 << level); maximum <<= 1; inv_density *= density_threshold; ++level; while (prev != Parent::end() && prev->tag >= lower) { --prev; ++num_elements; } while (next != Parent::end() && next->tag <= upper) { ++next; ++num_elements; } } while (inv_density * num_elements >= maximum); ++num_elements; // for the extra element inserted rLog(rlOrderList, "%i, %i, %i", num_elements, lower, upper); rLog(rlOrderList, "prev is at the end: %i", (prev == Parent::end())); rLog(rlOrderList, "next is at the end: %i", (next == Parent::end())); // Reorder AssertMsg((upper - lower + 1)/num_elements > 0, "Spacing between new tags must be non-zero"); for (unsigned int i = 0; i < num_elements; ++i) { (++prev)->tag = lower + i*((upper - lower + 1)/num_elements); rLog(rlOrderList, "%i", prev->tag); AssertMsg(prev->tag != 0 || prev == Parent::begin(), "Cannot assign 0 tag except at the beginning of OrderList"); } AssertMsg(++prev == next, "prev + num_elements != next in OrderList::insert()"); return iterator(new_base); }
void Simulator<FuncKernel_, EventComparison_>:: process() { Count(cSimulatorProcess); if (reached_infinity()) return; rLog(rlSimulator, "Queue size: %i", queue_.size()); Key top = queue_.top(); Event* e = *top; rLog(rlSimulator, "Processing event: %s", intostring(*e).c_str()); current_ = e->root_stack().top(); e->root_stack().pop(); queue_.demoted(top); // Get the top element out of the queue, put it back depending on what process() says if (!(e->process(this))) { queue_.remove(top); delete e; } ++count_; }
void Vineyard<I,It,E>:: start_vine(Iter i) { rLog(rlVineyard, "Starting new vine"); AssertMsg(i->sign(), "Can only start vines for positive simplices"); Dimension dim = evaluator->dimension(i); vines_vector[dim]->push_back(Vine()); i->set_vine(&vines_vector[dim]->back()); i->pair->set_vine(i->vine()); }
void Discrete_upper_envelope::sort_and_filter_by_slope( OutputIter out, InputIter begin, InputIter end) const { typedef std::pair<int, const Line* > Line_pair; typedef std::vector< std::pair<int, const Line* > > Line_pair_vec; // sort the input by slope // we do this by creating a vector where the key is the slope // and the value is a pointer to the line. Line_pair_vec sort_lines; // TODO: @todo once we have counting sort fix slope scaling // find min slope to scale keys int min_slope = INT_MAX; for (InputIter li = begin; li != end ; ++li) { min_slope = std::min(min_slope, Line_2::slope(*li)); } int tranlate_slope = (min_slope>=0)?0:-min_slope; for (InputIter li = begin; li != end ; ++li) { sort_lines.push_back(Line_pair(Line_2::slope(*li)+tranlate_slope, &*li)); } Radix_sort::radix_sort_pair(sort_lines.begin(), sort_lines.end()); // log the sorted list rLog(upper_envelope, "Lines sorted:\n %s", pair_vect_x_ptr_to_cstring(sort_lines.begin(), sort_lines.end())); // iterate over all the sorted lines // if any two lines have the same slope, // select only the line with the larger y-intercept value // if the line was selected add it to output set of lines const Line* best_line = sort_lines[0].second; for (typename Line_pair_vec::iterator iter = sort_lines.begin()+1 ; iter != sort_lines.end() ; ++iter) { const Line* li = iter->second; // check if the next line to add has the same // slope as the ith line // if it does not add it the the return list if (line_slope_neq(*best_line, *li)) { *out++ = best_line; best_line = li; } else { // lines have sampe slopes, // pick the line with the higher y-intercept assert (*best_line != *li); // verify lines are unique if (line_y_int_lt(*best_line, *li)) { best_line = li; } } } // add the last best line *out++ = best_line; }
void Vineyard<I,It,E>:: record_diagram(Iterator bg, Iterator end) { rLog(rlVineyard, "Entered: record_diagram()"); AssertMsg(evaluator != 0, "Cannot record diagram with a null evaluator"); for (Iterator i = bg; i != end; ++i) { AssertMsg(i->vine() != 0, "Cannot process a null vine in record_diagram"); if (!i->sign()) continue; record_knee(i); } }
void Convex_hull::Graham_yao::add_helper(Poly_chain_2& chain, const Point& q, const Point_2::Orientation& orient, bool keep_colinear) { // print the chain before adding rLog(graham_yao, "Pre-insert, point: %s \n%s\tFrom: %s To: %s", thing_to_cstring(q), vect_to_cstring(chain.vertices_begin(), chain.vertices_end()), thing_to_cstring(*from), thing_to_cstring(*to)); // pop off all points that break the orientation invarient while (from != chain.vertices_rend() && (Point_2::orientation(*from, *to, q) != orient && (!keep_colinear || Point_2::orientation(*from, *to, q) != Point_2::ORIENT_COLINE)) ) { rLog(graham_yao, "%s Poping: %s", thing_to_cstring(Point_2::orientation(*from, *to, q)), thing_to_cstring(chain.back())); // pop the last element and reset the pointers chain.remove_back(); ++from; to = chain.vertices_rbegin(); } // add to back and set pointers chain.append(q); from = chain.vertices_rbegin(); ++from; to = chain.vertices_rbegin(); // print the chain after adding rLog(graham_yao, "Post-inset:\n%s\tFrom: %s To: %s", vect_to_cstring(chain.vertices_begin(), chain.vertices_end()), thing_to_cstring(*from), thing_to_cstring(*to)); }
/** * Generate a vector of variates from a Log(p) distribution with the algorithm * "LK" of Kemp (1981). * * @param n_ sample size * @param p_ parameter p in (0,1) * @param Ip_ = 1 - p_ (possibly more accurate) * @return vector of random variates from Log(p) * @author Martin Maechler */ SEXP rLog_vec_c(SEXP n_, SEXP p_, SEXP Ip_) { int n = asInteger(n_); double p = asReal(p_),Ip = asReal(Ip_); SEXP res = PROTECT(allocVector(REALSXP, n)); double* X = REAL(res); GetRNGstate(); for(int i=0; i < n; i++) X[i] = rLog(p, Ip); PutRNGstate(); UNPROTECT(1); return res; }
void Vineyard<I,It,E>:: record_knee(Iter i) { rLog(rlVineyard, "Entered record_knee()"); AssertMsg(evaluator != 0, "Cannot record knee with a null evaluator"); AssertMsg(i->vine() != 0, "Cannot add a knee to a null vine"); AssertMsg(i->sign(), "record_knee() must be called on a positive simplex"); if (i->unpaired()) i->vine()->add((*evaluator)(i), Infinity, evaluator->time()); else { rLog(rlVineyard, "Creating knee"); Knee k((*evaluator)(i), (*evaluator)((i->pair)), evaluator->time()); rLog(rlVineyard, "Knee created: %s", tostring(k).c_str()); rLog(rlVineyard, "Vine: %s", tostring(*(i->vine())).c_str()); if (!k.is_diagonal() || i->vine()->empty()) // non-diagonal k, or empty vine { rLog(rlVineyard, "Extending a vine"); i->vine()->add(k); } else if (i->vine()->back().is_diagonal()) // last knee is diagonal { AssertMsg(i->vine()->size() == 1, "Only first knee may be diagonal for a live vine"); rLog(rlVineyard, "Overwriting first diagonal knee"); i->vine()->back() = k; } else // finish this vine { rLog(rlVineyard, "Finishing a vine"); i->vine()->add(k); start_vine(i); i->vine()->add(k); } } rLog(rlVineyard, "Leaving record_knee()"); }
void StaticPersistence<D, CT, OT, E, Cmp>:: initialize(const Filtration& filtration) { order_.assign(filtration.size(), OrderElement()); rLog(rlPersistence, "Initializing persistence"); OffsetMap<typename Filtration::Index, iterator> om(filtration.begin(), begin()); for (typename Filtration::Index cur = filtration.begin(); cur != filtration.end(); ++cur) { Cycle z; BOOST_FOREACH(const typename Filtration::Simplex& s, std::make_pair(cur->boundary_begin(), cur->boundary_end())) z.push_back(index(om[filtration.find(s)])); z.sort(ocmp_); iterator ocur = om[cur]; swap_cycle(ocur, z); set_pair(ocur, ocur); } }
void Discrete_upper_envelope::build_brute_force( const std::vector< Line >& input, int LB, int UB) { typedef std::vector< Line >::const_iterator Line_iter; typedef std::list< Line_iter >::iterator Line_handel_iter; // init and verify init_build_and_verify_input(input, LB, UB); // the current set of upper lines and envelope cells being built Line_iter upper_line; for (int x = one() ; x <= U() ; ++x) { // set the first line to be the upper line upper_line = input.begin(); // iterate over lines find the lines that evaluates to the max val for (Line_iter li = DDAD_util::next(input.begin()) ; li != input.end() ; ++li) { if (line_above(*li, *upper_line, x) || (line_intersect(*li, *upper_line,x) && Line_2::slope_order(*li, *upper_line) == Line_2::SLOPE_ORDER_LESS)) { upper_line = li; } } // output the upper line rLog(up_env_brute, "Upper line %s", thing_to_cstring(*upper_line)); // setup new cell or expand last cell if (envelope_.size() == 0 || envelope_.back().line != *upper_line) { envelope_.push_back(Envelope_cell(*upper_line, x,x)); } else { envelope_.back().right = x; } } }
typename Simulator<FuncKernel_, EventComparison_>::Key Simulator<FuncKernel_, EventComparison_>:: add(const Function& f, const Event_& e) { Event* ee = new Event_(e); rLog(rlSimulator, "Solving: %s", tostring(f).c_str()); int sign = FunctionKernel::sign_at_negative_infinity(f); // going to be sign after current time rLog(rlSimulator, "Sign at -infinity: %i", sign); if (sign != 0) { FunctionKernel::solve(f, ee->root_stack()); rLog(rlSimulator, "Got solution with root stack size: %i", ee->root_stack().size()); } while (!ee->root_stack().empty() && ee->root_stack().top() < current_time()) { // rLog(rlSimulator, "Popping expired root: %f", ee->root_stack().top()); ee->root_stack().pop(); sign *= -1; } if (sign == -1) { rLog(rlSimulator, "Popping the root because of negative sign (degeneracy)"); // rLog(rlSimulator, "Popping the root because of negative sign (degeneracy): %f", ee->root_stack().top()); // rLog(rlSimulator, " Current time: %f", current_time()); // AssertMsg(ee->root_stack().top() == current_time(), // "If sign is negative, we must be in the degenerate case"); ee->root_stack().pop(); } if (ee->root_stack().empty()) rLog(rlSimulator, "Pushing event with empty root stack"); else { rLog(rlSimulator, "Root stack size: %i", ee->root_stack().size()); rLog(rlSimulator, "Pushing: %s", tostring(ee->root_stack().top()).c_str()); } Key k = queue_.push(ee); return k; }
void Discrete_upper_envelope::build_orient_with_slope_unique_lines_sorted_by_slope( const std::vector< Line >& input, int UB, Sorted_lines_mem& sorted_lines, Building_with_orient_mem& dual_points) { // init and verify init_build_and_verify_input(input, 1, UB); // log the input rLog(up_env_orient, "Input for build_orient\n %s", vect_to_string(input.begin(),input.end(), "\t","\n",true).c_str()); // create the sorted list of pointers to lines sorted_lines.resize(input.size()); std::vector< const Line * >::iterator target_iter = sorted_lines.begin(); std::vector< Line >::const_iterator src_iter = input.begin(); for ( ; src_iter != input.end() ; ++src_iter, ++target_iter) { *target_iter = &(*src_iter); } // build the due build_orient_with_slope_unique_lines_sorted_by_slope(sorted_lines, dual_points); }
void Discrete_upper_envelope::build_orient( const std::vector< Line >& input, int LB, int UB) { // typedefs and preconditions typedef Point_2::Std_point Point; // init and verify init_build_and_verify_input(input, LB, UB); // log the input rLog(up_env_orient, "Input for build_orient\n %s", vect_to_string(input.begin(),input.end(), "\t","\n",true).c_str()); // sort the lines by slope filtering duplicate slopes std::vector< const Line* > sorted_lines; sort_and_filter_by_slope(back_inserter(sorted_lines), input.begin(), input.end()); // build the DUE std::vector< Point > dual_points; dual_points.reserve(sorted_lines.size()); build_orient_with_slope_unique_lines_sorted_by_slope(sorted_lines, dual_points); }
void Discrete_upper_envelope::build_ulogu_with_slope_unique_lines_sorted_by_slope( const std::vector< const Line* >& sorted_lines, Building_envelope_mem& build_env) { // init the sorted line processor and building_envelope Line neg_inf(INT_MIN, INT_MIN); Line pos_inf(INT_MAX, INT_MAX); One_sorted_list_of_lines processor(sorted_lines); build_env.resize(0); build_env.push_back(Building_envelope_cell(&neg_inf, one()-1)); // compute the due for sorted and filtered lines between one..U due_w_bin_search_of_sorted_and_filtered_lines(build_env, processor, one(), U()); build_env.push_back(Building_envelope_cell(&pos_inf, U()+1)); // convert the building envelope to an envelope building_envelope_to_envelope(envelope_, build_env); // log the envelope rLog(up_env_ulogu, "Output of build_ulogu:\n %s", vect_to_cstring(envelope_.begin(), envelope_.end())); }
void Discrete_upper_envelope::build_orient_with_slope_unique_lines_sorted_by_slope( const std::vector< const Line* >& sorted_lines, Building_with_orient_mem& dual_points) { // typedefs and preconditions typedef Point_2::Std_point Point; typedef Poly_chain_2::Vertex_list::const_iterator Vertex_iter; // if there is only 1 line then we are done if (sorted_lines.size() == 1) { envelope_.push_back(Envelope_cell(*sorted_lines.front(), one(), U())); return; } // dualize the lines dual_points.resize(0); for (std::vector< const Line* >::const_iterator iter = sorted_lines.begin() ; iter != sorted_lines.end() ; ++iter) { dual_points.push_back(Line_2::dual(**iter)); } // log the points rLog(up_env_orient, "Dual Points:\n %s", vect_to_cstring(dual_points.begin(), dual_points.end())); // compute the lower hull of the duals points Convex_hull::Graham_yao ch; Poly_chain_2 lower_hull; lower_hull.reserve(dual_points.size()); ch.build_lower_hull(lower_hull, dual_points); // log the lower envelope rLog(up_env_orient, "Lower hull\n %s", thing_to_cstring(lower_hull)); // iterate over the lines of the upper envelope and // convert them to cells int cell_begin = one(); for (Vertex_iter pi = lower_hull.vertices_begin() ; pi != lower_hull.vertices_end() && cell_begin <= U() ; ++pi) { // compute the end of the envelope for line corresponding to pi // by getting the next dual point // if the point is the last point then dual(pi) is the // remainder of the upper envelope. // if it is not, compute the intersection of dual(pi) and // dual(pip1) to determine where the cell ends int cell_end; Vertex_iter pip1 = DDAD_util::next(pi); const Line* l_pi = (const Line*)pi->data(); if (pip1 == lower_hull.vertices_end()) { cell_end = U(); } else { int x_coord; const Line* l_pip1 = (const Line*)pip1->data(); Line_2::vertical_grid_line_left_or_thourgh_intersection( x_coord, *l_pi, *l_pip1); cell_end = std::min(U(), x_coord); } if (cell_end >= cell_begin) { envelope_.push_back(Envelope_cell(*l_pi, cell_begin, cell_end)); cell_begin = cell_end+1; } } // log the sorted list rLog(up_env_orient, "Output of build_orient:\n %s", vect_to_cstring(envelope_.begin(), envelope_.end())); }
/******************************************************** * Internal Envelope Building Ops (the heave lifting) ********************************************************/ void Discrete_upper_envelope::build_ric_with_slope_unique_lines_sorted_by_slope( std::list< const Line* >& sorted_lines, Rand_order_mem& rand_order, Building_envelope_mem& building_envelope01, Building_envelope_mem& building_envelope02) { // typedefs typedef Rand_order_mem::iterator Rand_order_iter; typedef Building_envelope::iterator Building_env_iter; // checks rAssert(rand_order.size() == sorted_lines.size()); // compute the random insertion order int bin_begin = 1 << DDAD_util::log2(sorted_lines.size()); int bin_size = sorted_lines.size()-bin_begin; while(bin_begin >= 1) { Shuffle::standard_sequential_sample_with_removal( rand_order.begin()+bin_begin, sorted_lines, bin_size); bin_size = bin_begin = bin_begin >> 1; } rAssert(sorted_lines.size() == 1); Shuffle::standard_sequential_sample_with_removal( rand_order.begin(), sorted_lines, 1); rLog(up_env_ric, "Random insertion order:\n%s", vect_to_cstring(rand_order.begin(), rand_order.end())); // init the envelopes for building between // the largest a building envelope could be is all // lines plus the end sentinal line. Line neg_inf(INT_MIN, INT_MIN); Line pos_inf(INT_MAX, INT_MAX); building_envelope01.resize(0); building_envelope02.resize(0); Building_envelope *build_env = &building_envelope01; Building_envelope *next_env = &building_envelope02; build_env->push_back(Building_envelope_cell(&neg_inf, one()-1)); build_env->push_back(Building_envelope_cell(rand_order.begin()->line, one())); build_env->push_back(Building_envelope_cell(&pos_inf, U()+1)); // init vars for adding int delta = 1, num_lines = (int)rand_order.size(); int end_offset = 0, begin_offset = std::min(end_offset+delta, num_lines-1); Building_env_iter end, begin; // add the lines in increasing sizes of powers of 2 while (end_offset < num_lines-1) { begin = rand_order.begin() + begin_offset; end = rand_order.begin() + end_offset; // log the current envelope and the lines processed in this round rLog(up_env_ric, "Building envelope:\n%s", vect_to_cstring(build_env->begin(), build_env->end())); rLog(up_env_ric, "Process:\n%s", vect_to_cstring(end+1, begin+1)); // for each line l identify the left most cell intersected by l // (if such a cell exists) // the order of the slopes of the upper envelope // must be ordered by slope so we can treat this as a // merge operation Building_env_iter c_j = build_env->begin()+build_env->size()-1; for (Rand_order_iter l = begin ; l != end ; --l) { // log the line that we are processing this iteration rLog(up_env_ric, "Finding intersections for %s", thing_to_cstring(*(l->line))); // advance along the upper envelope until // the slope of l is between the slope of two lines of the // upper envelope while ( c_j != build_env->begin() && line_slope_lt(*(l->line), *(c_j->line)) ) { --c_j; } // this assertion verifys that we found the correct possible // insertion point for l rAssert( c_j != build_env->end() && (c_j+1) != build_env->end() ); rAssert( line_slope_lt(*(c_j)->line,*(l->line))); rAssert( line_slope_lt(*(l->line), *(c_j+1)->line) ); rLog(up_env_ric, "First cell with smaller slope\n%s", thing_to_cstring(*c_j)); // next we walk backwards thought the cells, // to find the left most cell intersected by l->line // left_most will store the current left most // cell intersected by l->line. If // at the end left_most is still build_env->end() // then l->line did not intersect any cells Building_env_iter left_most = (c_j+2 != build_env->end() && line_above_or_on(*(l->line),*(c_j+1)->line, (c_j+1)->left)) ? (c_j+1) : build_env->end(); for (Building_env_iter inter = c_j; inter != build_env->begin() && line_above(*(l->line), *(inter->line), (inter+1)->left) ; --inter) { left_most = inter; rLog(up_env_ric, "Intersection with \n %s", thing_to_cstring(*inter)); } rAssert(left_most != build_env->begin()); // if the cell intersected any cells // set the intersection flag for the left most intersection cell if (left_most != build_env->end()) { l->ptr = left_most->ptr; left_most->ptr = &(*l); } rLog(up_env_ric, "Intersection test ends at \n %s", (left_most == build_env->end()) ? "NO_INTERS" : thing_to_cstring(*left_most)); } // log the current envelope after all intersections found rLog(up_env_ric, "Building envelope after intersections:\n%s", vect_to_cstring(build_env->begin(), build_env->end())); // set up the next upper envelope next_env->push_back(build_env->front()); Building_envelope_cell* left_list = &(*(build_env->begin())); Building_envelope_cell* left_list_tail = &(*(build_env->begin())); Building_env_iter inf_cell = build_env->begin()+(build_env->size()-1); // compute the upper envelope in each cell for (Building_env_iter ci = build_env->begin()+1 ; ci != inf_cell ; ++ci) { // log the cell we are updating rLog(up_env_ric, "Cell to update\n%s", thing_to_cstring(*ci)); // construct and filter the three sorted list of lines Three_sorted_lists_of_lines L(*ci, left_list, left_list_tail); rLog(up_env_ric, "Init three sorted lists:\n%s", thing_to_cstring(L)); L.filter_below(); // compute the discrete upper envelope of the intersecting lines due_w_bin_search_of_sorted_and_filtered_lines( *next_env, L, ci->left, (ci+1)->left-1); // log the envelope rLog(up_env_ric, "Next Envelope\n%s", vect_to_cstring(next_env->begin(), next_env->end())); // update the left list by filtering all lines that are before // the filter in the all sorted list L.filter_all_sorted(*(next_env->back().line)); left_list = L.all_sorted_head.ptr; left_list_tail = L.all_sorted_tail; L.all_sorted_head.ptr = NULL; } // copy the infinite cell to the end next_env->push_back(build_env->back()); // log the current envelope after all intersections found rLog(up_env_ric, "Next Envelope:\n%s", vect_to_cstring(next_env->begin(), next_env->end())); // update for the next round std::swap(next_env, build_env); next_env->resize(0); delta *= 2; end_offset = begin_offset; begin_offset = std::min(end_offset+delta, num_lines-1); } // copy build envelope over to envelope building_envelope_to_envelope(envelope_, *build_env); }
void Discrete_upper_envelope::due_w_bin_search_of_sorted_and_filtered_lines( Envelope& envelope, SortedLines& L, int one, int U) { // typedefs and preconditions typedef typename Envelope::value_type Cell; L.init_iteration(); while (! L.empty() ) { const Line* cur_line = L.least_slope_and_inc(); Line_2::Cell_inter_type inter_type; // log the line and the current state of the envelope rLog(upper_envelope, "Adding %s\n", thing_to_cstring(*cur_line)); rLog(upper_envelope, "Current envelope:\n %s", vect_to_cstring(envelope.begin(), envelope.end())); // remove all cells that are killed by the current line int back_right = U; while (envelope.size() != 1 && (inter_type = Line_2::classify_intersection(*cur_line, envelope.back().line_op(), envelope.back().left, back_right)) == Line_2::CELL_INTER_INTERIOR) { //while (envelope.size() != 1 && Line_2::interior_intersection( // *cur_line, envelope.back().line_op(), envelope.back().left, back_right)) { back_right = envelope.back().left-1; envelope.pop_back(); } // create new cell if (envelope.size() == 1) { envelope.push_back(Cell(cur_line, one)); } else { int back_end = -1; const Cell& back = envelope.back(); //Line_2::Cell_inter_type inter_type = Line_2::classify_intersection( // *cur_line, back.line_op(), back.left, back_right); switch (inter_type) { // last cell is not changed but case Line_2::CELL_INTER_EMPTY: case Line_2::CELL_INTER_RIGHT_AND_LEFT_BDD: case Line_2::CELL_INTER_RIGHT_BDD: back_end = back_right; break; // the line intersects the last cell. // Clip the old last cell and create a new cell for the current line // since I already know where the intersection occurs, I don't need // to do the binary search case Line_2::CELL_INTER_LEFT_BDD: back_end = back.left; break; // I don't know where in the last cell the intersection occurs so I need // to do a binary search to find it. case Line_2::CELL_INTER_LOWER_BDD: back_end = bin_search_intersection(*cur_line, back.line_op(), back.left, back_right); break; // If we got here then the current line does not intersect the cell // in a lower boundary. If this was true we should not have left // the while loop. case Line_2::CELL_INTER_INTERIOR: rTerminate("Unexpected State", DDAD::Unexpected_state_error()); }; // set the new end for the back cell and if necessary create a new cell // for the current line if (Predicates_2::in_closed_interval(one, U, back_end+1)) { envelope.push_back(Cell(cur_line, back_end+1)); } } // log the envelope rLog(upper_envelope, "Adding line complete:\n %s", vect_to_cstring(envelope.begin(), envelope.end())); } }
bool DynamicPersistenceTrails<D,CT,OT,E,Cmp,CCmp>:: transpose(iterator i, const DimensionFunctor& dimension, Visitor visitor) { #if LOGGING typename Traits::OutputMap outmap(order()); #endif Count(cTransposition); typedef typename Element::Trail::iterator TrailIterator; visitor.transpose(i); iterator i_prev = i++; if (dimension(i_prev) != dimension(i)) { swap(i_prev, i); rLog(rlTranspositions, "Different dimension"); Count(cTranspositionDiffDim); return false; } bool si = i_prev->sign(), sii = i->sign(); if (si && sii) { rLog(rlTranspositions, "Trail prev: %s", i_prev->trail.tostring(outmap).c_str()); // Case 1 if (trail_remove_if_contains(i_prev, index(i))) rLog(rlTranspositions, "Case 1, U[i,i+1] = 1"); iterator k = iterator_to(i_prev->pair); iterator l = iterator_to(i->pair); // rLog(rlTranspositions, "(i_prev, k), (i, l): (%s, %s), (%s, %s)", // outmap(i_prev).c_str(), outmap(k).c_str(), // outmap(i).c_str(), outmap(l).c_str()); // Explicit treatment of unpaired simplex if (l == i) { swap(i_prev, i); rLog(rlTranspositions, "Case 1.2 --- unpaired"); rLog(rlTranspositions, "%s", outmap(i_prev).c_str()); Count(cTranspositionCase12); return false; } else if (k == i_prev) { if (!(l->cycle.contains(index(i_prev)))) { // Case 1.2 swap(i_prev, i); rLog(rlTranspositions, "Case 1.2 --- unpaired"); rLog(rlTranspositions, outmap(i_prev).c_str()); Count(cTranspositionCase12); return false; } else { // Case 1.2 --- special version (plain swap, but pairing switches) swap(i_prev, i); pairing_switch(i_prev, i); visitor.switched(i, Case12); rLog(rlTranspositions, "Case 1.2 --- unpaired (pairing switch)"); rLog(rlTranspositions, outmap(i_prev).c_str()); Count(cTranspositionCase12s); return true; } } rLog(rlTranspositions, "l cycle: %s", l->cycle.tostring(outmap).c_str()); if (!(l->cycle.contains(index(i_prev)))) { // Case 1.2 rLog(rlTranspositions, "k is in l: %d", (bool) l->trail.contains(index(k))); // if true, a special update would be needed to maintain lazy decomposition swap(i_prev, i); rLog(rlTranspositions, "Case 1.2"); Count(cTranspositionCase12); return false; } else { // Case 1.1 if (std::not2(order_comparison())(index(k),index(l))) { // Case 1.1.1 swap(i_prev, i); cycle_add(l, k->cycle); // Add column k to l trail_add(k, l->trail); // Add row l to k rLog(rlTranspositions, "Case 1.1.1"); Count(cTranspositionCase111); return false; } else { // Case 1.1.2 swap(i_prev, i); cycle_add(k, l->cycle); // Add column l to k trail_add(l, k->trail); // Add row k to l pairing_switch(i_prev, i); visitor.switched(i, Case112); rLog(rlTranspositions, "Case 1.1.2"); Count(cTranspositionCase112); return true; } } } else if (!si && !sii) { // Case 2 if (!(i_prev->trail.contains(index(i)))) { // Case 2.2 swap(i_prev, i); rLog(rlTranspositions, "Case 2.2"); Count(cTranspositionCase22); return false; } else { // Case 2.1 iterator low_i = iterator_to(i_prev->pair); iterator low_ii = iterator_to(i->pair); trail_add(i_prev, i->trail); // Add row i to i_prev cycle_add(i, i_prev->cycle); // Add column i_prev to i swap(i_prev, i); if (std::not2(order_comparison())(index(low_ii), index(low_i))) { // Case 2.1.2 cycle_add(i_prev, i->cycle); // Add column i to i_prev (after transposition) trail_add(i, i_prev->trail); // Add row i to i_prev pairing_switch(i_prev, i); visitor.switched(i, Case212); rLog(rlTranspositions, "Case 2.1.2"); Count(cTranspositionCase212); return true; } // Case 2.1.1 rLog(rlTranspositions, "Case 2.1.1"); Count(cTranspositionCase211); return false; } } else if (!si && sii) { // Case 3 if (!(i_prev->trail.contains(index(i)))) { // Case 3.2 swap(i_prev, i); rLog(rlTranspositions, "Case 3.2"); Count(cTranspositionCase32); return false; } else { // Case 3.1 trail_add(i_prev, i->trail); // Add row i to i_prev cycle_add(i, i_prev->cycle); // Add column i_prev to i swap(i_prev, i); cycle_add(i_prev, i->cycle); // Add column i_prev to i (after transposition) trail_add(i, i_prev->trail); // Add row i to i_prev pairing_switch(i_prev, i); visitor.switched(i, Case31); rLog(rlTranspositions, "Case 3.1"); Count(cTranspositionCase31); return true; } } else if (si && !sii) { // Case 4 if (trail_remove_if_contains(i_prev, index(i))) rLog(rlTranspositions, "Case 4, U[i,i+1] = 1"); swap(i_prev, i); rLog(rlTranspositions, "Case 4"); Count(cTranspositionCase4); return false; } return false; // to avoid compiler complaints; we should never reach this point }
char internal_buffer[256]; }; // end::rtdata-impl[] struct osc_t osc; struct sequencer_t seq; struct lfo_t lfo; struct lpf_t filter; // tag::ports[] #define Units(x) rMap(units, x) #define UnitLess rProp(unitless) #define rObject sequencer_t rtosc::Ports seq_ports = { rArrayF(freq, 8, rLog(0.1, 10e3), Units(Hz), "Frequency"), rParamF(noise_level, rLinear(0, 3), UnitLess, "White Noise Peak Gain"), rParamF(noise_decay, rLinear(1e-4,1), UnitLess, "Noise Decay Over Step"), rParamF(bpm, rLinear(0,1000), Units(bpm), "Beats Per Minute"), }; #undef rObject #define rObject lfo_t rtosc::Ports lfo_ports = { rParamF(freq, rLog(0.1, 1e3), Units(Hz), "Frequency"), rParamF(amount, rLinear(0,8), UnitLess, "LFO Strength"), }; #undef rObject #define rObject lpf_t rtosc::Ports filter_ports = {
void StaticPersistence<D, CT, OT, E, Cmp>:: pair_simplices(iterator bg, iterator end, bool store_negative, const Visitor& visitor) { #if LOGGING typename ContainerTraits::OutputMap outmap(order_); #endif // FIXME: need sane output for logging rLog(rlPersistence, "Entered: pair_simplices"); for (iterator j = bg; j != end; ++j) { visitor.init(j); rLog(rlPersistence, "Simplex %s", outmap(j).c_str()); Cycle z; swap_cycle(j, z); rLog(rlPersistence, " has boundary: %s", z.tostring(outmap).c_str()); // Sparsify the cycle by removing the negative elements if (!store_negative) { typename OrderElement::Cycle zz; BOOST_FOREACH(OrderIndex i, z) if (i->sign()) // positive zz.push_back(i); z.swap(zz); } // -------------------------- CountNum(cPersistencePairBoundaries, z.size()); #ifdef COUNTERS Count(cPersistencePair); #endif // COUNTERS while(!z.empty()) { OrderIndex i = z.top(ocmp_); // take the youngest element with respect to the OrderComparison rLog(rlPersistence, " %s: %s", outmap(i).c_str(), outmap(i->pair).c_str()); // TODO: is this even a meaningful assert? AssertMsg(!ocmp_(i, index(j)), "Simplices in the cycle must precede current simplex: (%s in cycle of %s)", outmap(i).c_str(), outmap(j).c_str()); // i is not paired, so we pair j with i if (iterator_to(i->pair) == iterator_to(i)) { rLog(rlPersistence, " Pairing %s and %s with cycle %s", outmap(i).c_str(), outmap(j).c_str(), z.tostring(outmap).c_str()); set_pair(i, j); swap_cycle(j, z); set_pair(j, i); CountNum(cPersistencePairCycleLength, j->cycle.size()); CountBy (cPersistencePairCycleLength, j->cycle.size()); break; } // update element z.add(i->pair->cycle, ocmp_); visitor.update(j, iterator_to(i)); rLog(rlPersistence, " new cycle: %s", z.tostring(outmap).c_str()); } // if z was empty, so is (already) j->cycle, so nothing to do visitor.finished(j); rLog(rlPersistence, "Finished with %s: %s", outmap(j).c_str(), outmap(j->pair).c_str()); }