void
Rhythmic_grouping::OK()const
{
- for (int i= 1; i < divisions.sz(); i++) {
- Real dt = divisions[i] - divisions[i-1];
- assert(dt>0);
- }
- Interval u;
- for (int i= 1; i < children.sz(); i++) {
- children[i]->OK();
- u.unite(children[i]->time());
- }
-
+ assert(bool(children.sz()) != bool(interval_));
+
+ for (int i= 0; i < children.sz(); i++) {
+ children[i]->OK();
+ if (i>0)
+ assert(children[i-1]->interval().max ==
+ children[i]->interval().min);
+ }
}
Real
Rhythmic_grouping::length() const
{
- return divisions.last() - divisions[0];
+ return interval().length();
+}
+
+Interval
+Rhythmic_grouping::interval()const
+{
+ if (interval_)
+ return *interval_;
+ else
+ return
+ Interval(children[0]->interval().min,
+ children.last()->interval().max);
}
void
Rhythmic_grouping::split(Rhythmic_grouping r)
{
- svec<Real> ir = r.interior();
- split(ir);
+ if (interval_)
+ return ;
+
+ r.intersect(interval());
+ split(r.intervals());
for (int i= 0; i < children.sz(); i++) {
- Rhythmic_grouping here(r.partial_grouping(children[i]->time()));
- if (here.divisions.sz() == 2)
- here.split(2);
- children[i]->split(here);
+ if (!children[i]->interval_) {
+ Rhythmic_grouping here(r);
+ children[i]->split(here);
+ }
}
}
-svec<Real>
-Rhythmic_grouping::interior()
+
+svec<Interval>
+Rhythmic_grouping::intervals()
{
- svec<Real> r(divisions);
- r.del(0);
- r.pop();
+ svec<Interval> r;
+ if (interval_ || children.sz() == 1) {
+ Interval i(interval());
+ Interval r1(i), r2(i);
+ r1.max = r2.min = i.center();
+ r.add(r1); r.add(r2);
+ } else {
+ for (int i=0; i < children.sz(); i++)
+ r.add(children[i]->interval());
+ }
return r;
}
-void
-Rhythmic_grouping::split(int n)
+Rhythmic_grouping::Rhythmic_grouping(Interval t, int n)
{
- assert(divisions.sz() == 2 && children.sz() == 0);
- Real dt =(divisions.last()-divisions[0] )/n;
- svec<Real> r;
- for (int i= 0; i <= n; i++)
- r.add(divisions[0] +dt *i);
- divisions = r;
+ if (n == 1 || !n) {
+ interval_ = new Interval(t);
+ return;
+ }
+ Real dt = t.length()/n;
+ Interval basic = Interval(t.min, t.min+dt);
+ for (int i= 0; i < n; i++)
+ children.add(new Rhythmic_grouping( dt*i + basic ));
}
void
Rhythmic_grouping::intersect(Interval t)
{
- svec<Real> r;
- for (int i=0; i < divisions.sz(); i++)
- if (t.elt_q(divisions[i]))
- r.add(divisions[i]);
- if (r[0] > t.min ) // todo
- r.insert( t.min,0);
- if (r.last() < t.max)
- r.add(t.max);
+ if (interval_) {
+ interval_->intersect(t);
+ return;
+ }
- divisions = r;
- svec<Rhythmic_grouping*> nc;
for (int i=0; i < children.sz(); i++) {
- Interval inter = intersection(t, children[i]->time());
- if (!inter.empty()) {
- Rhythmic_grouping*p =new Rhythmic_grouping(*children[i]);
- nc.add(p);
- p->intersect(inter);
+ Interval inter = intersection(t, children[i]->interval());
+ if (inter.empty() || inter.length() < 1e-8) {
+ delete children[i];
+ children[i] =0;
+ } else {
+ children[i]->intersect(t);
}
- delete children[i];
}
- children = nc;
-}
+ for (int i=0; i < children.sz(); ) {
+ if (!children[i])
+ children.del(i);
+ else
+ i++;
+ }
-Rhythmic_grouping
-Rhythmic_grouping::partial_grouping(Interval t)
-{
- Rhythmic_grouping r(*this);
- r.intersect(t);
- return r;
}
void
-Rhythmic_grouping::split(svec<Real> splitpoints)
+Rhythmic_grouping::split(svec<Interval> splitpoints)
{
- assert(!children.sz());
- svec<Real> child;
- int j = 0, i=0;
+ //check on splitpoints..
+ int j = 0, i=0, starti = 0, startj = 0;
+
+ svec<Rhythmic_grouping*> ch;
while (1) {
- if ( i >= divisions.sz() || j >= splitpoints.sz())
+ if ( i >= children.sz() || j >= splitpoints.sz())
break;
- child.add(divisions[i]);
- if (divisions[i] < splitpoints[j]) {
- i++;
- } else if (divisions[i] > splitpoints[j]) {
- j ++;
+ assert( distance(
+ children[starti]->interval().min, splitpoints[startj].min)<1e-8);
+ if (children[i]->interval().max < splitpoints[j].max - 1e-8) {
+ i ++;
+ } else if (children[i]->interval().max > splitpoints[j].max + 1e-8) {
+ j ++;
} else {
- children.add(new Rhythmic_grouping(child));
- child.set_size(1);
- child[0] = divisions[i];
+
+ if (i == starti) {
+ ch.add(children[i]);
+ } else {
+ Rhythmic_grouping *newchild=new Rhythmic_grouping(
+ children.subvec(starti, i+1));
+
+ ch.add(newchild);
+ }
+ i ++;
+ j++;
+ starti = i;
+ startj = j;
+
+
}
}
+ if (ch.size() != 1)
+ children = ch;
+ }
+
+Rhythmic_grouping::Rhythmic_grouping(svec<Rhythmic_grouping*> r)
+ :children(r)
+{
+ interval_ =0;
}
-Rhythmic_grouping::Rhythmic_grouping(svec<Real> d)
- :divisions(d)
+Rhythmic_grouping::~Rhythmic_grouping()
{
+ junk();
}
-Rhythmic_grouping::Rhythmic_grouping()
+
+void
+Rhythmic_grouping::copy(Rhythmic_grouping const&s)
{
+ interval_ = (s.interval_)? new Interval(*s.interval_) : 0;
+ for (int i=0; i < s.children.sz(); i++)
+ children.add(new Rhythmic_grouping(*s.children[i]));
}
-Interval
-Rhythmic_grouping::time()const
+
+void
+Rhythmic_grouping::operator=(Rhythmic_grouping const &s)
{
- return Interval(divisions[0], divisions.last());
+ junk();
+ copy(s);
}
-Rhythmic_grouping::Rhythmic_grouping(Interval h)
+
+Rhythmic_grouping::Rhythmic_grouping(Rhythmic_grouping const&s)
{
- divisions.add(h.min);
- divisions.add(h.max);
+ copy(s);
}
-Rhythmic_grouping::~Rhythmic_grouping()
+void
+Rhythmic_grouping::junk()
{
+ delete interval_;
+ interval_ = 0;
for (int i=0; i < children.sz(); i++)
delete children[i];
+ children.set_size(0);
}
-
-Rhythmic_grouping::Rhythmic_grouping(Rhythmic_grouping const&s)
-{
- divisions = s.divisions;
- for (int i=0; i < s.children.sz(); i++)
- children.add(new Rhythmic_grouping(*s.children[i]));
-}
-
void
Rhythmic_grouping::print()const
{
#ifndef NPRINT
- mtor << "{ ";
- for (int i=0; i < divisions.sz(); i++) {
- mtor << divisions[i] << ',';
- }
+ mtor << "{ \n";
+ if (interval_)
+ mtor<<" Interval "<< interval_->str();
for (int i=0; i < children.sz(); i++) {
children[i]->print();
}
- mtor << "}";
+ mtor << "}\n";
#endif
}
+void
+Rhythmic_grouping::add_child(Real start, Real len)
+{
+ Real stop = start+len;
+ for (int i=0; i < children.sz(); i ++) {
+ Interval j=children[i]->interval();
+ if (distance (j.min, start)<1e-8 && distance (j.max, stop)<1e-8) {
+ return;
+ }
+ }
+
+ if (children.sz())
+ assert ( distance(children.last()->interval().max , start) < 1e-8);
+
+ children.add(new Rhythmic_grouping(Interval(start, stop)));
+}
+
+Rhythmic_grouping::Rhythmic_grouping()
+{
+ interval_ =0;
+}
+
+int
+min_elt(svec<int> v)
+{
+ int i = 1000; // ugh
+ for (int j = 0 ; j < v.sz(); j++)
+ i = i <? v[j];
+ return i;
+}
+
+svec<int>
+Rhythmic_grouping::generate_beams(svec<int> flags, int &flagidx)
+{
+
+ assert (!interval_) ;
+
+ svec< svec<int> > children_beams;
+ for (int i=0; i < children.sz(); i++) {
+ svec<int> child_beams;
+ if (children[i]->interval_) {
+ int f = flags[flagidx++];
+ child_beams.add(f);
+ } else {
+ child_beams = children[i]->
+ generate_beams(flags, flagidx);
+ }
+ children_beams.add(child_beams);
+ }
+ svec<int> beams;
+ int lastm, m, nextm;
+ for (int i=0; i < children_beams.sz(); i++) {
+ bool add_left = (i >0);
+ bool add_right = (i < children_beams.sz() -1);
+
+ if (!i)
+ m = min_elt(children_beams[i]);
+ if (add_right)
+ nextm = min_elt(children_beams[i+1]);
+
+ if (children_beams[i].sz() == 1) {
+ if (add_right)
+ beams.add(m);
+ if (add_left)
+ beams.add(m);
+ } else {
+ if (add_left)
+ beams.add(lastm <? m);
+ beams.concat(children_beams[i]);
+ if (add_right)
+ beams.add(m <? nextm);
+ }
+ lastm = m;
+ m = nextm;
+ }
+ assert(!(beams.sz()%2));
+ return beams;
+}