Beispiel #1
0
// Find adjacent intervals with smallest $\chi^2$
IntervalList::iterator find_min_chi_chi()
{
	// Compute $\chi^2$ value for each adjacent interval,
	//  keeping track of minimum value
	IntervalList::iterator lit = g_intervals.begin(),
		lend = g_intervals.end();
	IntervalList::iterator next = lit, min_lit = lend;

	float min_chisquared = 1e6;
	bool first = true;

	for ( ; lit != lend; ++lit) {
        next = lit;
		++next;

		if (next == lend) break;

		float chisquared = compute_chisquared(*lit, *next);

		// Debug
		print_interval_set(*lit);
		cout << "\\chi^2 = " << chisquared << endl;

		if (first || chisquared < min_chisquared) {
			min_lit = lit;
			min_chisquared = chisquared;
		}

		first = false;
	}

	cout << "min_chisquared = " << min_chisquared << endl;

    return min_lit;
}
Beispiel #2
0
void print_interval_summary(ostream& os, int dimIndex)
{
	IntervalList::iterator lit = g_intervals.begin(),
		lend = g_intervals.end();
	IntervalList::iterator next = lit;

	vector<DataType> split_points;

	os << "\n" "Feature " << (dimIndex+1) << ":" << endl;
	os << "Ranges: ";

	for ( ; lit != lend; ++lit) {
        next = lit;
		++next;

		pair<DataType, DataType> range, next_range;
		range = get_range(*lit, dimIndex);

		if (next != lend) {
            next_range = get_range(*next, dimIndex);

			float average = (range.second + next_range.first) * 0.5f;
			split_points.push_back(average);
		}

		os << "[" << range.first << ", " << range.second << "] ";
	}

	os << endl;

	os << "Split points: ";
	copy(split_points.begin(), split_points.end(),
		ostream_iterator<DataType>(os, ", "));
	os << endl;
}
Beispiel #3
0
// Initialize intervals, one for each unique attribute value
void initialize_intervals(int dimIndex)
{
	g_intervals.clear();

	IntervalSet interval;

	TupleVec::iterator it = g_data.begin(), end = g_data.end(), next;
	int index = 0;
	for ( ; it != end; ++it, ++index) {
		next = it+1;

		// Add element (index) to interval
		interval.insert(index);

		bool insertInterval = (next == end) ||
			( (next->first)[dimIndex] != (it->first)[dimIndex] );

		if (insertInterval) {
			// Insert interval into list if
			//  (a) end of sequence or
			//  (b) next element is not the same as current element
			g_intervals.push_back(interval);
			interval.clear();
		}
	}

	// Debug
	print_all_intervals();
}
Beispiel #4
0
// Debugging -- print all intervals
void print_all_intervals()
{
	IntervalList::iterator lit = g_intervals.begin(),
		lend = g_intervals.end();

	cout << "[intervals]" << endl;

	for ( ; lit != lend; ++lit) {
		IntervalSet& indices = *lit;
		print_interval_set(indices);
	}
}
Beispiel #5
0
// $\chi^2$ just for one dimension
void chi_chi_dim_analysis(int dimIndex)
{	
	// Sort and initialize one interval per unique attribute value

	sort(g_data.begin(), g_data.end(), tuple_less_than<Tuple>(dimIndex));

	TupleVec::iterator tit = g_data.begin(), tend = g_data.end();

	cout << "[sort]" << endl;

	int index = 0;
	for ( ; tit != tend; ++tit, ++index) {
		cout << index << ":";
		copy(tit->first.begin(), tit->first.end(), ostream_iterator<float>(cout, ", "));
		cout << tit->second << endl;		
	}

	initialize_intervals(dimIndex);

	// Count instances of all classes
	count_classes();

	while ((int)g_intervals.size() > g_max_intervals) {
		// Find adjacent intervals with smallest $\chi^2$
		IntervalList::iterator min_lit = find_min_chi_chi();
		assert(min_lit != g_intervals.end());

		IntervalList::iterator min_lit_next = min_lit;
		++min_lit_next;

		cout << "[before merge] ";
		print_all_intervals();

		// Merge
		IntervalSet& interval_1 = *min_lit;
		IntervalSet& interval_2 = *min_lit_next;

		interval_1.insert(interval_2.begin(), interval_2.end());

		g_intervals.erase(min_lit_next);

		cout << "[after merge] ";
		print_all_intervals();
	}

	// Debugging
	print_interval_summary(cout, dimIndex);

	// Logged output
	print_interval_summary(olog, dimIndex);
}
Beispiel #6
0
//--------------------------------------------------------------------------------------------------
void Index::get_reachable(unsigned x, std::vector<unsigned>& nodes){
	x=g->getNodeId(x);

	if (!intervals[x])
		return;

	IntervalList* intlist = intervals[x];
	const std::vector<unsigned>& lower=intlist->get_lower();
	const std::vector<unsigned>& upper=intlist->get_upper();

	for (unsigned i=0; i < lower.size(); i++){
		for (unsigned node=lower[i]; node<=upper[i];++node){
			nodes.push_back(g->getNodeById(id2node[node]));
		}
	}
}
void IntervalList::addIntervalList(const IntervalList& intervals)
{
  const QList<Interval> list = intervals.getList();

  QList<Interval>::const_iterator it = list.constBegin();

  for( ; it != list.constEnd(); ++it)
  {
    addInterval((*it));
  }
}
bool IntervalList::isParsable(const QString &input, const IntervalList &container)
{
  try
  {
    const IntervalList test(input);
    return container.contains(test);
  } 
  catch (std::exception&)
  {
    return false;
  }
}
IntervalList IntervalList::intersect(const IntervalList& a, const IntervalList& b)
{
  IntervalList output;

  const QList<Interval> aList = a.getList();
  const QList<Interval> bList = b.getList();

  QList<Interval>::const_iterator aIt = aList.constBegin();
  QList<Interval>::const_iterator bIt = bList.constBegin();

  QList<Interval>::const_iterator aItEnd = aList.constEnd();
  QList<Interval>::const_iterator bItEnd = bList.constEnd();

  bool a_open = false;
  bool b_open = false;

  int start = 0;
  int end = 0;

  // This looks atrocious, but is probably one of the quickest available methods
  // to find the intersections of two lists of Intervals.  An easier (but much 
  // less effecient way) would be to define Interval::intersect(Interval a, Interval b)
  // for the Interval class, and then use that method to intersect two lists.  

  // Plus, this is probably overkill anyway: who is going to spend time typing 
  // in an interval list big enough to slow a computer down?
  while(aIt != aItEnd && bIt != bItEnd)
  {
    if(!a_open && !b_open)
    {
      if((*aIt).start() < (*bIt).start())
      {
        a_open = true;
      } 
      else if((*aIt).start() > (*bIt).start())
      {
        b_open = true;
      }
      else
      {
        a_open = true;
        b_open = true;
        start = (*aIt).start();
      }
    }
    else if(a_open && !b_open)
    {
      if((*aIt).end() < (*bIt).start())
      {
        a_open = false;
        ++aIt;
      } 
      else if((*aIt).end() > (*bIt).start())
      {
        b_open = true;
        start = (*bIt).start();
      }
      else
      {
        a_open = false;
        b_open = true;
        start = (*aIt).end();
        end = (*bIt).start();
        Interval interval(start, end);
        output.addInterval(interval);
        ++aIt;
      }
    }
    else if(!a_open && b_open)
    {
      if((*bIt).end() < (*aIt).start())
      {
        b_open = false;
        ++bIt;
      } 
      else if((*aIt).end() > (*bIt).start())
      {
        a_open = true;
        start = (*aIt).start();
      }
      else
      {
        b_open = false;
        a_open = true;
        start = (*bIt).end();
        end = (*aIt).start();
        Interval interval(start, end);
        output.addInterval(interval);
        ++bIt;
      }
    }
    else
    {
      if((*aIt).end() < (*bIt).end())
      {
        a_open = false;
        end = (*aIt).end();
        Interval interval(start, end);
        output.addInterval(interval);
        ++aIt;
      } 
      else if((*aIt).end() > (*bIt).end())
      {
        b_open = false;
        end = (*bIt).end();
        Interval interval(start, end);
        output.addInterval(interval);
        ++bIt;
      }
      else
      {
        a_open = false;
        b_open = false;
        end = (*aIt).end();
        Interval interval(start, end);
        output.addInterval(interval);
        ++aIt;
        ++bIt;
      }
    }
  }

  return output;
}
void IntervalList::setIntervalList(const IntervalList& intervals)
{
  m_list = QList<Interval>(intervals.getList());
}
/*!
 * \param other interval list to merge into this interval list
 */
void IntervalList::merge_exact(const IntervalList& other) {
  // find starting point
  if (other.empty()) {
    return;
  }
  int last_index = 0;

  // intervals of other list
  const std::vector<unsigned>& o_lower = other.get_lower();
  const std::vector<unsigned>& o_upper = other.get_upper();

  // is this interval list is empty, just copy other list
  if (empty()) {
    std::copy(o_lower.begin(), o_lower.end(), std::back_inserter(lower_));
    std::copy(o_upper.begin(), o_upper.end(), std::back_inserter(upper_));
    return;
  } else {
    // for each interval in other list, find relevant position to insert
    unsigned a, b;
    int idxa, idxb;
    bool insa, insb;
    for (unsigned i = 0; i < o_lower.size(); ++i) {
      a = o_lower[i], b = o_upper[i];
      insa = false, insb = false;
      idxa = find(a); //, last_index_);
      (void) last_index;
      idxb = idxa + 1;

      /* distinguish 4 cases a,b between/within intervals */
      // determine
      //    - index of interval containing or left of a, flag: inside
      //    - index of interval containing or right of b, flag: inside
      if (idxa != -1 && a <= upper_[idxa] + 1) {
        insa = true;
      }
      while (idxb < int(lower_.size()) && b >= lower_[idxb] - 1) {
        ++idxb;
      }

      if (idxb != 0 && b <= upper_[idxb - 1] + 1) {
        insb = true;
        --idxb;
      } else {
        insb = false;
      }

      // special cases
      if (!insb && idxb == 0) {
        // before everything
        lower_.insert(lower_.begin(), a);
        upper_.insert(upper_.begin(), b);
        last_index = 0;
        continue;                 // done
      } else if (!insa && idxa == int(lower_.size()) - 1) {
        // after everything
        lower_.push_back(a);
        upper_.push_back(b);
        last_index = lower_.size() - 1;
        continue;                 // done
      }
      if (!insa) {
        ++idxa;
      }
      if (!insb) {
        --idxb;
      }

      if (idxa > idxb) {
        // new interval between existing
        //assert(int(lower_.size()) > idxa);
        lower_.insert(lower_.begin() + idxa, a);
        upper_.insert(upper_.begin() + idxa, b);
        last_index = idxa;
        continue;                 // done
      }

      // update interval boundaries
      lower_[idxa] = std::min(lower_[idxa], a);
      upper_[idxb] = std::max(upper_[idxb], b);

      // general case
      lower_.erase(lower_.begin() + idxa + 1, lower_.begin() + idxb + 1);
      upper_.erase(upper_.begin() + idxa, upper_.begin() + idxb);
      last_index = idxb - idxa - 1;
    }
  }
}
/*!
 * \param other interval list
 */
void IntervalList::merge(const IntervalList& other) {
  // find starting point
  if (other.empty()) {
    return;
  }
  int last_index = 0;

  // other interval list
  const std::vector<unsigned>& o_lower = other.get_lower();
  const std::vector<unsigned>& o_upper = other.get_upper();
  const std::vector<char>& o_exact = other.get_exact();
  //assert((o_lower.size() == o_upper.size()) && (o_lower.size() == o_exact.size()));

  // if this list is empty, just copy other list
  if (empty()) {
    std::copy(o_lower.begin(), o_lower.end(), std::back_inserter(lower_));
    std::copy(o_upper.begin(), o_upper.end(), std::back_inserter(upper_));
    std::copy(o_exact.begin(), o_exact.end(), std::back_inserter(exact_));
    return;
  } else {
    // for each interval in other list, find relevant position to insert
    unsigned a, b;
    char ex;
    int idxa, idxb;
    bool insa, insb;
    for (unsigned i = 0; i < o_lower.size(); ++i) {
      a = o_lower[i], b = o_upper[i];
      ex = o_exact[i];
      insa = false, insb = false;

      // determine idxa
      if (a < lower_.front()) {
        idxa = -1;
      } else if (a > upper_.back()) {
        idxa = upper_.size() - 1;
      } else {
        // no special case, perform binary search
        int _min = last_index, _max = lower_.size(), _mid;
        while (true) {
          if (_min == _max) {
            if (a < lower_[_min]) {
              idxa = _min - 1; // immediately to the left
              break;
            } else {
              idxa = _min; // included in interval, or immediately to the right
              break;
            }
          }
          _mid = (_max + _min) / 2;
          if (lower_[_mid] <= a && a <= upper_[_mid]) {
            idxa = _mid;
            break;
          } else if (a < lower_[_mid]) {
            _max = _mid;
          } else {
            _min = _mid + 1;
          }
        }
      }
      idxb = idxa + 1;

      /* distinguish 4 cases a,b between/within intervals */
      // determine
      //    - index of interval containing or left of a, flag: inside
      //    - index of interval containing or right of b, flag: inside
      if (idxa != -1 && a <= upper_[idxa] + 1) {
        insa = true;
      }
      while (idxb < int(lower_.size()) && b >= lower_[idxb] - 1) {
        ++idxb;
      }

      if (idxb != 0 && b <= upper_[idxb - 1] + 1) {
        insb = true;
        --idxb;
      } else {
        insb = false;
      }

      // special cases
      if (!insb && idxb == 0) {
        // before everything
        lower_.insert(lower_.begin(), a);
        upper_.insert(upper_.begin(), b);
        exact_.insert(exact_.begin(), ex);
        last_index = 0;
        continue;                 // done
      } else if (!insa && idxa == int(lower_.size()) - 1) {
        // after everything
        lower_.push_back(a);
        upper_.push_back(b);
        exact_.push_back(ex);
        last_index = lower_.size() - 1;
        continue;                 // done
      }

      if (!insa) {
        ++idxa;
      }
      if (!insb) {
        --idxb;
      }

      if (idxa > idxb) {
        // new interval between existing
        //assert(int(lower_.size()) > idxa);
        lower_.insert(lower_.begin() + idxa, a);
        upper_.insert(upper_.begin() + idxa, b);
        exact_.insert(exact_.begin() + idxa, ex);
        last_index = idxa;
        continue;                 // done
      }

      // non-exact interval subsumed
      if (!ex && insa && insb && idxa == idxb && lower_[idxa] <= a
          && b <= upper_[idxa]) {
        last_index = idxa;
        continue;
      }

      // update interval boundaries
      lower_[idxa] = std::min(lower_[idxa], a);
      upper_[idxb] = std::max(upper_[idxb], b);

      // general case
      assert(idxb <= int(lower_.size()));
      lower_.erase(lower_.begin() + idxa + 1, lower_.begin() + idxb + 1);
      upper_.erase(upper_.begin() + idxa, upper_.begin() + idxb);
      char new_exact = ex;
      if (ex) {
        for (int i = idxa; i <= idxb; ++i) {
          if (!exact_[i]) {
            new_exact = 0;
            break;
          }
        }
      }
      exact_[idxa] = new_exact;
      exact_.erase(exact_.begin() + idxa + 1, exact_.begin() + idxb + 1);
      last_index = std::max(0, idxa);
    }
  }
}
Beispiel #13
0
std::vector<Tuning*> *Tuning::getTunings() {
    
    // if already have tunings, return them
    // TODO: It would be polite to check the mtime on the tunings file
    //       and to re-read it if it's been changed. For now, you need
    //       to restart Rosegarden.
    if (!m_tunings.empty())
        return &m_tunings;
    
    QString tuningsPath =
        ResourceFinder().getResourcePath("pitches", "tunings.xml");
    if (tuningsPath == "") return NULL;
    #   if (TUNING_DEBUG > 1)
    qDebug() << "Path to tunings file:" << tuningsPath;
    #   endif
    QFile infile(tuningsPath);
    
    IntervalList *intervals = new IntervalList;
    SpellingList *spellings = new SpellingList;
    
    if (infile.open(QIODevice::ReadOnly) ) {
        QXmlStreamReader stream(&infile);
        QString tuningName, intervalRatio;
        
        stream.readNextStartElement();
        if (stream.name() != "rosegarden_scales") {
            qDebug()  << "Tunings configuration file " << tuningsPath
                      << " is not a valid rosegarden scales file. "
                      << "(Root element is " << stream.name() << ")";
            return NULL;
        }
        
        enum {needTuning, needName, needInterval, needSpellings} state;
#       if (TUNING_DEBUG > 2)
        static const char * stateNames[] = {
            "expecting <tuning>", "expecting <name>", 
            "expecting <interval>", "expecting <spelling>"
        };
#       endif
        state = needTuning;
        
        while(!stream.atEnd()) {

            // Read to the next element delimiter
            do {
                stream.readNext();
            } while(!stream.isStartElement() &&
                    !stream.isEndElement() &&
                    !stream.atEnd());
            
            if (stream.atEnd()) break;
                        
            // Perform state transistions at end elements
            if (stream.isEndElement()) {
                if (stream.name() == "tuning") {
                    // Save the tuning and prepare for a new one
                    saveTuning(tuningName, intervals, spellings);
                    intervals = new IntervalList;
                    spellings = new SpellingList;       
                    state = needTuning;
                } else if (stream.name() == "name") {
                    // End of tuning name: expect intervals
                    state = needInterval;
                } else if (stream.name() == "interval") {
                    // After an </interval>, we're expecting another interval
                    state = needInterval;
                } else if (stream.name() == "rosegarden_scales") {
                    // XML's fininshed. Don't need the current tuning
                    // or spelling lists created when the last tuning ended
                    // so let's not leak memory.
                    delete intervals;
                    delete spellings;
                    // Don't bother reading any more of the file
                    break;
                }
                
#               if (TUNING_DEBUG > 2)
                qDebug() << "End of XML element " << stream.name()
                         << "New state: " << state
                         << " (" << stateNames[state] << ")";
#               endif
                continue;
            }
            
            // So it's a start element. Parse it.
            
            // If we are in the needSpellings state but hit a new interval,
            // we need to process that. So force a state-change here.
            if (state == needSpellings && stream.name() == "interval") {
                state = needInterval;
            }
            
#           if (TUNING_DEBUG > 2)
            qDebug() << "XML Element: " << stream.name()
            << " Current XML parser state: " << state
            << " (" << stateNames[state] << ")";
#           endif
            
            switch (state) {
            case needTuning:
                if (stream.name() != "tuning") {
                    qDebug() << "Reading Tunings. Expected tuning element, "
                             << "found " << stream.name();
                    stream.skipCurrentElement();
                } else {                
                    // Require a name element
                    state = needName;
                }
                break;
                
            case needName:
                if (stream.name() != "name") {
                    qDebug() << "Tuning must start with a <name> element, "
                             << "found <" << stream.name() << ">";
                    stream.skipCurrentElement();
                } else {
                    tuningName = stream.readElementText();
                    state = needInterval;
#                   if (TUNING_DEBUG > 1)
                    qDebug() << "\nNew Tuning: " << tuningName;
#                   endif
                }
                break;
                
            case needInterval:
                if (stream.name() != "interval") {
                    qDebug() << "Expecting an <interval> element, "
                             << "found <" << stream.name() << ">";
                    // Bail out
                    stream.skipCurrentElement();
                } else {
                    intervalRatio =
                        stream.attributes().value("ratio").toString();
#                   if (TUNING_DEBUG > 1)
                    qDebug() << "New Ratio: " << intervalRatio;
#                   endif
                    const double cents =
                        scalaIntervalToCents(intervalRatio,
                                             stream.lineNumber());
                    intervals->push_back(cents);
                    state = needSpellings;
                }
                break;
            
            case needSpellings:
                if (stream.name() != "spelling") {
                    qDebug() << "Intervals may contain only spellings. "
                             << "Found <" << stream.name() << ">";
                    // Keep looking for spellings
                    stream.skipCurrentElement();
                } else {
                    // Parse this spelling
                    parseSpelling(stream.readElementText(),
                                  intervals, spellings);
                }
                break;
            
            default:
                // Illegal state (can't happen: it's an enumerated type!)
                qDebug() << "Something nasty happened reading tunings. "
                            "Illegal state at line " << stream.lineNumber();
                stream.skipCurrentElement();
                break;
            } // end switch(state)
        } // end while(!stream.atEnd())
#       if (TUNING_DEBUG > 1)
        qDebug() << "Closing tunings file";
#       endif
        infile.close();
    } // end if (m_infile.open(...
    
    return &m_tunings;
}
Beispiel #14
0
/**
 * 2DO extend to support non default references
 * If no tuning present, will default to 12ET
 */
Tuning *PMLDocument::getTuning(){

    DOMElement *perf = getSingleElement(m_doc->getDocumentElement(), "performance");

    if( !perf ){
//cerr << "No performance element! Defaulting to 12ET\n";
    }
    else{

        DOMElement *tuningEl = getSingleElement(perf, "tuning");


        if( !tuningEl ){
            cout << "No tuning element! Defaulting to 12ET\n";
        }
        else{
            string tuningName = XS( tuningEl->getAttribute(XS("name")) );

            IntervalList *intervals = new IntervalList;
            SpellingList *spellingList = new SpellingList;

            /* Get intervals */
            DOMElement* intList = getSingleElement(tuningEl,"intervallist");

            DOMNodeList *intervalEls = intList->getElementsByTagName(XS("interval"));
            for( int i=0; i<intervalEls->getLength(); i++ ){
                string is = getText((DOMElement*)intervalEls->item(i));
	//cout << "Interval " << is << endl;
                intervals->push_back( atof(is.c_str())  );
            }

            /* Get enharmonic equivalent spellings */
            DOMElement *spellingListEl = getSingleElement( tuningEl, "spellinglist" );
            DOMNodeList *equivs = spellingListEl->getElementsByTagName(XS("enharmequiv"));

            for( int e=0; e<equivs->getLength(); e++ ){

                DOMElement *equiv = (DOMElement*)equivs->item(e);
                DOMNodeList *spellings = equiv->getElementsByTagName(XS("spelling"));

                for( int i=0; i<spellings->getLength(); i++ ){

                    DOMElement* spEl = (DOMElement*)spellings->item(i);

                    Accidental acc;
                    if( spEl->getAttributeNode(XS("acc")) == NULL )  
                        acc = Accidentals::NoAccidental;
                    else
                        acc = XS( spEl->getAttribute(XS("acc")) );
	//cout << "Acc " << acc << endl;
	
                    string notest = XS(spEl->getAttribute(XS("note")));
                    char note = notest[0];
	
                    PitchSpelling ps(note,acc);
                    SpellingListItem spi( e, ps );
                    spellingList->insert( spi);
                }
            }

            Tuning *tuning = new Tuning( tuningName, intervals, spellingList);
            return tuning;
        }      
    }



    std::vector<Tuning*>* tunings = Tuning::getTunings( "/usr/local/lib/tunings" );
    Tuning *tuning = tunings->at(0);
    return tuning;
}