// // Programmer: Craig Stuart Sapp // Creation Date: Sat Jul 27 14:29:44 PDT 2002 // Last Modified: Sat Jul 27 14:29:47 PDT 2002 // Filename: ...sig/examples/all/iwsearch.cpp // Web Address: http://sig.sapp.org/examples/museinfo/humdrum/iwsearch.cpp // Syntax: C++; museinfo // // Description: Search for optimal root-interval weights for chord root // identification by Monte Carlo methods. // #include "humdrum.h" #include #include #include #include typedef Array ArrayDouble; typedef Array ArrayInt; /////////////////////////////////////////////////////////////////////////// // function declarations void checkOptions (Options& opts, int argc, char* argv[]); void example (void); void usage (const char* command); void getStartingWeights (Array& weights, HumdrumFile& weightfile); void getChordInformation (Array& pitches, Array& root, Array& count, HumdrumFile& datafile); void runSearch (Array& initialweights, Array& pitches, Array& root, Array& count, int trialsperstep, double initrange, double decay, int stoplimit); double getErrors (Array& weights, Array& pitches, Array& root, Array& count); void makeRandomWeights (Array& stepweights, double range); void printWeights (Array weights); double getDistance (Array& a, Array& b); // global variables Options options; // database for command-line arguments int debugQ = 0; // used with --debug option double rangeStart = 1.0; // starting point of random variation double decay = 0.95; // decay of range between each step int trialCount = 100; // number of trials for each step int stopLimit = 10; // number of trials which can have same error int seed = 0; // random number seed /////////////////////////////////////////////////////////////////////////// int main(int argc, char* argv[]) { HumdrumFile datafile; HumdrumFile weightfile; checkOptions(options, argc, argv); // process the command-line options datafile.read(options.getArg(1)); weightfile.read(options.getArg(2)); Array count; // the frequency of the chords occurence Array root; // the root of the chord Array pitches; // the pitch class set of the chord Array initialweights; // starting weights of the search getStartingWeights(initialweights, weightfile); getChordInformation(pitches, root, count, datafile); runSearch(initialweights, pitches, root, count, trialCount, rangeStart, decay, stopLimit); return 0; } /////////////////////////////////////////////////////////////////////////// ////////////////////////////// // // getErrors -- try all chords and count how many root errors occured. // double getErrors(Array& weights, Array& pitches, Array& root, Array& count) { Array rootscores; rootscores.setSize(40); rootscores.allowGrowth(0); int i, j, m; double errors = 0; int min; for (m=0; m rootscores[i]) { min = i; } } if (root[m] != min+2) { if (debugQ) { cout << "Error: root=" << root[m] << "\tbut measured: " << min << endl; } errors += count[m]; } } return errors; } ////////////////////////////// // // runSearch -- // void runSearch(Array& initialweights, Array& pitches, Array& root, Array& count, int trialsperstep, double initrange, double decay, int stoplimit) { double range = initrange; Array stepweights; Array stepscores; stepweights.setSize(trialsperstep); stepscores.setSize(trialsperstep); int i; for (i=0; i bestweight(40); bestweight = initialweights; double bestscore = getErrors(bestweight, pitches, root, count); cout << "!! The initial best score is: " << bestscore << endl; cout << "!! Starting weights: \n"; printWeights(bestweight); cout << endl; int currentlimit = 0; int currentbest = 0; int step = 0; while (currentlimit < stoplimit) { step++; stepweights[0] = bestweight; stepscores[0] = bestscore; makeRandomWeights(stepweights, range); for (i=1; i& a, Array& b) { Array c(40); int i; double sum = 0.0; for (i=0; i& stepweights, double range) { int i, j; double delta = 0.0; for (i=1; i& weights, HumdrumFile& weightfile) { weights.setSize(40); weights.setAll(100000); weights.allowGrowth(0); int i, j; int root; double weight; for (i=0; i= 0) { weights[root] = weight; } } if (debugQ) { printWeights(weights); } } ////////////////////////////// // // printWeights -- // void printWeights(Array weights) { char buffer[128] = {0}; cout << "**kern\t**weight\n"; int i; for (i=0; i& pitches, Array& root, Array& count, HumdrumFile& datafile) { count.setSize(datafile.getNumLines()); count.setSize(0); root.setSize(datafile.getNumLines()); root.setSize(0); pitches.setSize(datafile.getNumLines()); pitches.setSize(0); char buffer[1024] = {0}; int i, j, k; int troot = -1; int tpitch = -1; double tcount = 0.0; Array tpitches; tpitches.setSize(100); tpitches.setSize(0); for (i=0; i