changeset 144:9ec558ed83d4

Merge from branch fixedlag
author Chris Cannam
date Fri, 24 Mar 2017 15:08:12 +0000
parents 5c1572dd225a (current diff) 218bfe953159 (diff)
children 0432723faf03
files MonoPitch.cpp MonoPitch.h
diffstat 24 files changed, 5313 insertions(+), 459 deletions(-) [+]
line wrap: on
line diff
--- a/LocalCandidatePYIN.cpp	Thu Aug 20 16:06:01 2015 +0100
+++ b/LocalCandidatePYIN.cpp	Fri Mar 24 15:08:12 2017 +0000
@@ -12,7 +12,7 @@
 */
 
 #include "LocalCandidatePYIN.h"
-#include "MonoPitch.h"
+#include "MonoPitchHMM.h"
 #include "YinUtil.h"
 
 #include "vamp-sdk/FFT.h"
@@ -48,12 +48,14 @@
     m_preciseTime(0.0f),
     m_pitchProb(0),
     m_timestamp(0),
-    m_nCandidate(13)
+    m_nCandidate(13),
+    m_yinUtil(0)
 {
 }
 
 LocalCandidatePYIN::~LocalCandidatePYIN()
 {
+    delete m_yinUtil;
 }
 
 string
@@ -85,7 +87,7 @@
 {
     // Increment this each time you release a version that behaves
     // differently from the previous one
-    return 2;
+    return 3;
 }
 
 string
@@ -226,7 +228,7 @@
 }
 
 void
-LocalCandidatePYIN::selectProgram(string name)
+LocalCandidatePYIN::selectProgram(string)
 {
 }
 
@@ -268,6 +270,8 @@
     m_channels = channels;
     m_stepSize = stepSize;
     m_blockSize = blockSize;
+
+    m_yinUtil = new YinUtil(m_blockSize/2);
     
     reset();
 
@@ -297,20 +301,19 @@
     
     size_t yinBufferSize = m_blockSize/2;
     double* yinBuffer = new double[yinBufferSize];
-    if (!m_preciseTime) YinUtil::fastDifference(dInputBuffers, yinBuffer, yinBufferSize);
-    else YinUtil::slowDifference(dInputBuffers, yinBuffer, yinBufferSize);    
+    if (!m_preciseTime) m_yinUtil->fastDifference(dInputBuffers, yinBuffer);
+    else m_yinUtil->slowDifference(dInputBuffers, yinBuffer);    
     
     delete [] dInputBuffers;
 
-    YinUtil::cumulativeDifference(yinBuffer, yinBufferSize);
+    m_yinUtil->cumulativeDifference(yinBuffer);
     
     float minFrequency = 60;
     float maxFrequency = 900;
-    vector<double> peakProbability = YinUtil::yinProb(yinBuffer, 
-                                                      m_threshDistr, 
-                                                      yinBufferSize, 
-                                                      m_inputSampleRate/maxFrequency, 
-                                                      m_inputSampleRate/minFrequency);
+    vector<double> peakProbability = m_yinUtil->yinProb(yinBuffer, 
+                                                        m_threshDistr, 
+                                                        m_inputSampleRate/maxFrequency, 
+                                                        m_inputSampleRate/minFrequency);
 
     vector<pair<double, double> > tempPitchProb;
     for (size_t iBuf = 0; iBuf < yinBufferSize; ++iBuf)
@@ -319,7 +322,7 @@
         {
             double currentF0 = 
                 m_inputSampleRate * (1.0 /
-                YinUtil::parabolicInterpolation(yinBuffer, iBuf, yinBufferSize));
+                m_yinUtil->parabolicInterpolation(yinBuffer, iBuf));
             double tempPitch = 12 * std::log(currentF0/440)/std::log(2.) + 69;
             tempPitchProb.push_back(pair<double, double>(tempPitch, peakProbability[iBuf]));
         }
@@ -345,7 +348,7 @@
     }
 
     // MONO-PITCH STUFF
-    MonoPitch mp;
+    MonoPitchHMM hmm(0);
     size_t nFrame = m_timestamp.size();
     vector<vector<float> > pitchTracks;
     vector<float> freqSum = vector<float>(m_nCandidate);
@@ -359,11 +362,11 @@
     for (size_t iCandidate = 0; iCandidate < m_nCandidate; ++iCandidate)
     {
         pitchTracks.push_back(vector<float>(nFrame));
-        vector<vector<pair<double,double> > > tempPitchProb;
+        vector<pair<double,double> > tempPitchProb;
+        vector<vector<double> > tempObsProb;
         float centrePitch = 45 + 3 * iCandidate;
 
         for (size_t iFrame = 0; iFrame < nFrame; ++iFrame) {
-            tempPitchProb.push_back(vector<pair<double,double> >());
             float sumProb = 0;
             float pitch = 0;
             float prob = 0;
@@ -374,26 +377,33 @@
                     boost::math::pdf(normalDist, pitch-centrePitch) /
                     maxNormalDist * 2;
                 sumProb += prob;
-                tempPitchProb[iFrame].push_back(
+                tempPitchProb.push_back(
                     pair<double,double>(pitch,prob));
             }
             for (size_t iProb = 0; iProb < m_pitchProb[iFrame].size(); ++iProb)
             {
-                tempPitchProb[iFrame][iProb].second /= sumProb;
+                tempPitchProb[iProb].second /= sumProb;
             }
+            tempObsProb.push_back(hmm.calculateObsProb(tempPitchProb));
         }
 
-        vector<float> mpOut = mp.process(tempPitchProb);
-        float prevFreq = 0;
-        for (size_t iFrame = 0; iFrame < nFrame; ++iFrame)
+        vector<int> rawPitchPath = hmm.decodeViterbi(tempObsProb);
+        vector<float> mpOut;
+
+        for (size_t iFrame = 0; iFrame < rawPitchPath.size(); ++iFrame)
+        {
+            float freq = hmm.nearestFreq(rawPitchPath[iFrame], 
+                                         m_pitchProb[iFrame]);
+            mpOut.push_back(freq); // for note processing below
+        }
+
+        for (size_t iFrame = 0; iFrame < rawPitchPath.size(); ++iFrame)
         {
             if (mpOut[iFrame] > 0) {
 
                 pitchTracks[iCandidate][iFrame] = mpOut[iFrame];
                 freqSum[iCandidate] += mpOut[iFrame];
                 freqNumber[iCandidate]++;
-                prevFreq = mpOut[iFrame];
-
             }
         }
         freqMean[iCandidate] = freqSum[iCandidate]*1.0/freqNumber[iCandidate];
--- a/LocalCandidatePYIN.h	Thu Aug 20 16:06:01 2015 +0100
+++ b/LocalCandidatePYIN.h	Fri Mar 24 15:08:12 2017 +0000
@@ -18,6 +18,8 @@
 
 #include "Yin.h"
 
+class YinUtil;
+
 class LocalCandidatePYIN : public Vamp::Plugin
 {
 public:
@@ -70,6 +72,8 @@
     vector<vector<pair<double, double> > > m_pitchProb;
     vector<Vamp::RealTime> m_timestamp;
     size_t m_nCandidate;
+
+    YinUtil *m_yinUtil;
 };
 
 #endif
--- a/Makefile.inc	Thu Aug 20 16:06:01 2015 +0100
+++ b/Makefile.inc	Fri Mar 24 15:08:12 2017 +0000
@@ -15,7 +15,6 @@
            Yin.cpp \
            YinUtil.cpp \
            MonoNote.cpp \
-           MonoPitch.cpp \
            MonoNoteParameters.cpp \
            SparseHMM.cpp \
            MonoNoteHMM.cpp \
@@ -27,14 +26,15 @@
          test/test-fft \
          test/test-yin \
          test/test-mononote
-         
+	 
 OBJECTS := $(SOURCES:.cpp=.o)
 OBJECTS := $(OBJECTS:.c=.o)
 
 PLUGIN_OBJECTS := $(OBJECTS) $(PLUGIN_MAIN:.cpp=.o)
 
 all: $(PLUGIN) $(TESTS)
-	for t in $(TESTS); do echo "Running $$t"; ./"$$t" || exit 1; done
+	@for t in $(TESTS); do echo; echo "Running $$t"; ./"$$t" || exit 1; done
+	@echo; bash ./test/regression.sh
 
 plugin: $(PLUGIN)
 
@@ -65,15 +65,14 @@
 # DO NOT DELETE
 
 libmain.o: PYinVamp.h Yin.h MeanFilter.h YinVamp.h LocalCandidatePYIN.h
-LocalCandidatePYIN.o: LocalCandidatePYIN.h Yin.h MeanFilter.h MonoPitch.h
+LocalCandidatePYIN.o: LocalCandidatePYIN.h Yin.h MeanFilter.h
 LocalCandidatePYIN.o: MonoPitchHMM.h SparseHMM.h YinUtil.h
 MonoNote.o: MonoNote.h MonoNoteHMM.h MonoNoteParameters.h SparseHMM.h
 MonoNoteHMM.o: MonoNoteHMM.h MonoNoteParameters.h SparseHMM.h
 MonoNoteParameters.o: MonoNoteParameters.h
-MonoPitch.o: MonoPitch.h MonoPitchHMM.h SparseHMM.h
 MonoPitchHMM.o: MonoPitchHMM.h SparseHMM.h
 PYinVamp.o: PYinVamp.h Yin.h MeanFilter.h MonoNote.h MonoNoteHMM.h
-PYinVamp.o: MonoNoteParameters.h SparseHMM.h MonoPitch.h MonoPitchHMM.h
+PYinVamp.o: MonoNoteParameters.h SparseHMM.h MonoPitchHMM.h
 SparseHMM.o: SparseHMM.h
 Yin.o: Yin.h MeanFilter.h YinUtil.h
 YinUtil.o: YinUtil.h MeanFilter.h
@@ -90,7 +89,6 @@
 LocalCandidatePYIN.o: Yin.h MeanFilter.h
 MonoNote.o: MonoNoteHMM.h MonoNoteParameters.h SparseHMM.h
 MonoNoteHMM.o: MonoNoteParameters.h SparseHMM.h
-MonoPitch.o: MonoPitchHMM.h SparseHMM.h
 MonoPitchHMM.o: SparseHMM.h
 PYinVamp.o: Yin.h MeanFilter.h
 Yin.o: MeanFilter.h
--- a/Makefile.linux64	Thu Aug 20 16:06:01 2015 +0100
+++ b/Makefile.linux64	Fri Mar 24 15:08:12 2017 +0000
@@ -1,5 +1,6 @@
 
-CFLAGS := $(CFLAGS) -Wall -O3 -fPIC -I../vamp-plugin-sdk/ -I../../vamp-plugin-sdk/
+CFLAGS := $(CFLAGS) -Wall -O3 -ffast-math -fPIC -I../vamp-plugin-sdk/ -I../../vamp-plugin-sdk/
+#CFLAGS := $(CFLAGS) -Wall -Wextra -Werror -g -fPIC -I../vamp-plugin-sdk/ -I../../vamp-plugin-sdk/
 
 CXXFLAGS := $(CXXFLAGS) $(CFLAGS)
 
--- a/Makefile.osx	Thu Aug 20 16:06:01 2015 +0100
+++ b/Makefile.osx	Fri Mar 24 15:08:12 2017 +0000
@@ -2,7 +2,7 @@
 CFLAGS := $(ARCHFLAGS) -O3 -I../vamp-plugin-sdk -I../../vamp-plugin-sdk -I/usr/local/boost -Wall -fPIC 
 CXXFLAGS := $(CFLAGS)
 
-LDFLAGS := -L../vamp-plugin-sdk -L../../vamp-plugin-sdk -lvamp-sdk $(ARCHFLAGS) 
+LDFLAGS := -L../vamp-plugin-sdk -L../vamp-plugin-sdk -lvamp-sdk $(ARCHFLAGS) -L/usr/local/lib 
 PLUGIN_LDFLAGS := -dynamiclib $(LDFLAGS) -exported_symbols_list vamp-plugin.list
 TEST_LDFLAGS := $(LDFLAGS) -lboost_unit_test_framework
 PLUGIN_EXT := .dylib
--- a/MonoNote.cpp	Thu Aug 20 16:06:01 2015 +0100
+++ b/MonoNote.cpp	Fri Mar 24 15:08:12 2017 +0000
@@ -22,7 +22,7 @@
 using std::pair;
 
 MonoNote::MonoNote() :
-    hmm()
+    hmm(0)
 {
 }
 
@@ -39,11 +39,9 @@
         obsProb.push_back(hmm.calculateObsProb(pitchProb[iFrame]));
     }
     
-    vector<double> *scale = new vector<double>(pitchProb.size());
-    
     vector<MonoNote::FrameOutput> out; 
     
-    vector<int> path = hmm.decodeViterbi(obsProb, scale);
+    vector<int> path = hmm.decodeViterbi(obsProb);
     
     for (size_t iFrame = 0; iFrame < path.size(); ++iFrame)
     {
@@ -54,8 +52,6 @@
         stateKind = (path[iFrame]) % hmm.par.nSPP + 1;
 
         out.push_back(FrameOutput(iFrame, currPitch, stateKind));
-        // std::cerr << path[iFrame] << " -- "<< pitchProb[iFrame][0].first << " -- "<< currPitch << " -- " << stateKind << std::endl;
     }
-    delete scale;
     return(out);
 }
--- a/MonoNoteHMM.cpp	Thu Aug 20 16:06:01 2015 +0100
+++ b/MonoNoteHMM.cpp	Fri Mar 24 15:08:12 2017 +0000
@@ -21,7 +21,8 @@
 using std::vector;
 using std::pair;
 
-MonoNoteHMM::MonoNoteHMM() :
+MonoNoteHMM::MonoNoteHMM(int fixedLag) :
+    SparseHMM(fixedLag),
     par()
 {
     build();
@@ -36,14 +37,13 @@
     
     // what is the probability of pitched
     double pIsPitched = 0;
-    for (size_t iCandidate = 0; iCandidate < nCandidate; ++iCandidate)
+    for (size_t iCand = 0; iCand < nCandidate; ++iCand)
     {
-        // pIsPitched = pitchProb[iCandidate].second > pIsPitched ? pitchProb[iCandidate].second : pIsPitched;
-        pIsPitched += pitchProb[iCandidate].second;
+        pIsPitched += pitchProb[iCand].second;
     }
 
-    // pIsPitched = std::pow(pIsPitched, (1-par.priorWeight)) * std::pow(par.priorPitchedProb, par.priorWeight);
-    pIsPitched = pIsPitched * (1-par.priorWeight) + par.priorPitchedProb * par.priorWeight;
+    pIsPitched = pIsPitched * (1-par.priorWeight) + 
+                     par.priorPitchedProb * par.priorWeight;
 
     vector<double> out = vector<double>(par.n);
     double tempProbSum = 0;
@@ -58,14 +58,15 @@
                 double minDist = 10000.0;
                 double minDistProb = 0;
                 size_t minDistCandidate = 0;
-                for (size_t iCandidate = 0; iCandidate < nCandidate; ++iCandidate)
+                for (size_t iCand = 0; iCand < nCandidate; ++iCand)
                 {
-                    double currDist = std::abs(getMidiPitch(i)-pitchProb[iCandidate].first);
+                    double currDist = std::abs(getMidiPitch(i)-
+                                               pitchProb[iCand].first);
                     if (currDist < minDist)
                     {
                         minDist = currDist;
-                        minDistProb = pitchProb[iCandidate].second;
-                        minDistCandidate = iCandidate;
+                        minDistProb = pitchProb[iCand].second;
+                        minDistCandidate = iCand;
                     }
                 }
                 tempProb = std::pow(minDistProb, par.yinTrust) * 
@@ -107,6 +108,8 @@
     //    3. attack state
     //    ...
     
+    m_nState = par.n;
+
     // observation distributions
     for (size_t iState = 0; iState < par.n; ++iState)
     {
@@ -114,9 +117,9 @@
         if (iState % par.nSPP == 2)
         {
             // silent state starts tracking
-            init.push_back(1.0/(par.nS * par.nPPS));
+            m_init.push_back(1.0/(par.nS * par.nPPS));
         } else {
-            init.push_back(0.0);            
+            m_init.push_back(0.0);            
         }
     }
 
@@ -137,27 +140,27 @@
         size_t index = iPitch * par.nSPP;
 
         // transitions from attack state
-        from.push_back(index);
-        to.push_back(index);
-        transProb.push_back(par.pAttackSelftrans);
+        m_from.push_back(index);
+        m_to.push_back(index);
+        m_transProb.push_back(par.pAttackSelftrans);
 
-        from.push_back(index);
-        to.push_back(index+1);
-        transProb.push_back(1-par.pAttackSelftrans);
+        m_from.push_back(index);
+        m_to.push_back(index+1);
+        m_transProb.push_back(1-par.pAttackSelftrans);
 
         // transitions from stable state
-        from.push_back(index+1);
-        to.push_back(index+1); // to itself
-        transProb.push_back(par.pStableSelftrans);
+        m_from.push_back(index+1);
+        m_to.push_back(index+1); // to itself
+        m_transProb.push_back(par.pStableSelftrans);
         
-        from.push_back(index+1);
-        to.push_back(index+2); // to silent
-        transProb.push_back(par.pStable2Silent);
+        m_from.push_back(index+1);
+        m_to.push_back(index+2); // to silent
+        m_transProb.push_back(par.pStable2Silent);
 
         // the "easy" transitions from silent state
-        from.push_back(index+2);
-        to.push_back(index+2);
-        transProb.push_back(par.pSilentSelftrans);
+        m_from.push_back(index+2);
+        m_to.push_back(index+2);
+        m_transProb.push_back(par.pSilentSelftrans);
         
         
         // the more complicated transitions from the silent
@@ -171,7 +174,7 @@
             double semitoneDistance = 
                 std::abs(fromPitch - toPitch) * 1.0 / par.nPPS;
             
-            // if (std::fmod(semitoneDistance, 1) == 0 && semitoneDistance > par.minSemitoneDistance)
+
             if (semitoneDistance == 0 || 
                 (semitoneDistance > par.minSemitoneDistance 
                  && semitoneDistance < par.maxJump))
@@ -184,15 +187,19 @@
 
                 tempTransProbSilent.push_back(tempWeightSilent);
 
-                from.push_back(index+2);
-                to.push_back(toIndex);
+                m_from.push_back(index+2);
+                m_to.push_back(toIndex);
             }
         }
         for (size_t i = 0; i < tempTransProbSilent.size(); ++i)
         {
-            transProb.push_back((1-par.pSilentSelftrans) * tempTransProbSilent[i]/probSumSilent);
+            m_transProb.push_back((1-par.pSilentSelftrans) * 
+                                  tempTransProbSilent[i]/probSumSilent);
         }
     }
+    m_nTrans = m_transProb.size();
+    m_delta = vector<double>(m_nState);
+    m_oldDelta = vector<double>(m_nState);
 }
 
 double
--- a/MonoNoteHMM.h	Thu Aug 20 16:06:01 2015 +0100
+++ b/MonoNoteHMM.h	Fri Mar 24 15:08:12 2017 +0000
@@ -27,8 +27,9 @@
 class MonoNoteHMM : public SparseHMM
 {
 public:
-    MonoNoteHMM();
+    MonoNoteHMM(int fixedLag);
     const std::vector<double> calculateObsProb(const vector<pair<double, double> >);
+
     double getMidiPitch(size_t index);
     double getFrequency(size_t index);
     void build();
--- a/MonoPitch.cpp	Thu Aug 20 16:06:01 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
-
-/*
-    pYIN - A fundamental frequency estimator for monophonic audio
-    Centre for Digital Music, Queen Mary, University of London.
-    
-    This program is free software; you can redistribute it and/or
-    modify it under the terms of the GNU General Public License as
-    published by the Free Software Foundation; either version 2 of the
-    License, or (at your option) any later version.  See the file
-    COPYING included with this distribution for more information.
-*/
-
-#include "MonoPitch.h"
-#include "MonoPitchHMM.h"
-#include <vector>
-
-#include <cstdio>
-#include <cmath>
-#include <complex>
-
-using std::vector;
-using std::pair;
-
-MonoPitch::MonoPitch() :
-    hmm()
-{
-}
-
-MonoPitch::~MonoPitch()
-{
-}
-
-const vector<float>
-MonoPitch::process(const vector<vector<pair<double, double> > > pitchProb)
-{
-    // std::cerr << "before observation prob calculation" << std::endl;
-    vector<vector<double> > obsProb;
-    for (size_t iFrame = 0; iFrame < pitchProb.size(); ++iFrame)
-    {
-        obsProb.push_back(hmm.calculateObsProb(pitchProb[iFrame]));
-    }
-    
-    vector<double> *scale = new vector<double>(0);
-    
-    vector<float> out; 
-    
-    // std::cerr << "before Viterbi decoding" << obsProb.size() << "ng" << obsProb[1].size() << std::endl;
-    vector<int> path = hmm.decodeViterbi(obsProb, scale);
-    // std::cerr << "after Viterbi decoding" << std::endl;
-    
-    for (size_t iFrame = 0; iFrame < path.size(); ++iFrame)
-    {
-        // std::cerr << path[iFrame] << " " << hmm.m_freqs[path[iFrame]] << std::endl;
-        float hmmFreq = hmm.m_freqs[path[iFrame]];
-        float bestFreq = 0;
-        float leastDist = 10000;
-        if (hmmFreq > 0)
-        {
-            // This was a Yin estimate, so try to get original pitch estimate back
-            // ... a bit hacky, since we could have direclty saved the frequency
-            // that was assigned to the HMM bin in hmm.calculateObsProb -- but would
-            // have had to rethink the interface of that method.
-            for (size_t iPitch = 0; iPitch < pitchProb[iFrame].size(); ++iPitch)
-            {
-                float freq = 440. * std::pow(2, (pitchProb[iFrame][iPitch].first - 69)/12);
-                float dist = std::abs(hmmFreq-freq);
-                if (dist < leastDist)
-                {
-                    leastDist = dist;
-                    bestFreq = freq;
-                }
-            }
-        } else {
-            bestFreq = hmmFreq;
-        }
-        out.push_back(bestFreq);
-    }
-    delete scale;
-    return(out);
-}
--- a/MonoPitch.h	Thu Aug 20 16:06:01 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
-
-/*
-    pYIN - A fundamental frequency estimator for monophonic audio
-    Centre for Digital Music, Queen Mary, University of London.
-    
-    This program is free software; you can redistribute it and/or
-    modify it under the terms of the GNU General Public License as
-    published by the Free Software Foundation; either version 2 of the
-    License, or (at your option) any later version.  See the file
-    COPYING included with this distribution for more information.
-*/
-
-#ifndef _MONOPITCH_H_
-#define _MONOPITCH_H_
-
-#include "MonoPitchHMM.h"
-
-#include <iostream>
-#include <vector>
-#include <exception>
-
-using std::vector;
-using std::pair;
-
-class MonoPitch {
-public:
-    MonoPitch();
-    virtual ~MonoPitch();
-    
-    // pitchProb is a frame-wise vector carrying a vector of pitch-probability pairs
-    const vector<float> process(const vector<vector<pair<double, double> > > pitchProb);
-private:
-    MonoPitchHMM hmm;
-};
-
-#endif
--- a/MonoPitchHMM.cpp	Thu Aug 20 16:06:01 2015 +0100
+++ b/MonoPitchHMM.cpp	Fri Mar 24 15:08:12 2017 +0000
@@ -17,23 +17,26 @@
 
 #include <cstdio>
 #include <cmath>
+#include <iostream>
 
 using std::vector;
 using std::pair;
 
-MonoPitchHMM::MonoPitchHMM() :
-m_minFreq(61.735),
-m_nBPS(5),
-m_nPitch(0),
-m_transitionWidth(0),
-m_selfTrans(0.99),
-m_yinTrust(.5),
-m_freqs(0)
+MonoPitchHMM::MonoPitchHMM(int fixedLag) :
+    SparseHMM(fixedLag),
+    m_minFreq(61.735),
+    m_nBPS(5),
+    m_nPitch(0),
+    m_transitionWidth(0),
+    m_selfTrans(0.99),
+    m_yinTrust(.5),
+    m_freqs(0)
 {
     m_transitionWidth = 5*(m_nBPS/2) + 1;
     m_nPitch = 69 * m_nBPS;
+    m_nState = 2 * m_nPitch; // voiced and unvoiced
     m_freqs = vector<double>(2*m_nPitch);
-    for (size_t iPitch = 0; iPitch < m_nPitch; ++iPitch)
+    for (int iPitch = 0; iPitch < m_nPitch; ++iPitch)
     {
         m_freqs[iPitch] = m_minFreq * std::pow(2, iPitch * 1.0 / (12 * m_nBPS));
         m_freqs[iPitch+m_nPitch] = -m_freqs[iPitch];
@@ -47,13 +50,13 @@
     vector<double> out = vector<double>(2*m_nPitch+1);
     double probYinPitched = 0;
     // BIN THE PITCHES
-    for (size_t iPair = 0; iPair < pitchProb.size(); ++iPair)
+    for (int iPair = 0; iPair < int(pitchProb.size()); ++iPair)
     {
         double freq = 440. * std::pow(2, (pitchProb[iPair].first - 69)/12);
         if (freq <= m_minFreq) continue;
         double d = 0;
         double oldd = 1000;
-        for (size_t iPitch = 0; iPitch < m_nPitch; ++iPitch)
+        for (int iPitch = 0; iPitch < m_nPitch; ++iPitch)
         {
             d = std::abs(freq-m_freqs[iPitch]);
             if (oldd < d && iPitch > 0)
@@ -70,7 +73,7 @@
     double probReallyPitched = m_yinTrust * probYinPitched;
     // std::cerr << probReallyPitched << " " << probYinPitched << std::endl;
     // damn, I forget what this is all about...
-    for (size_t iPitch = 0; iPitch < m_nPitch; ++iPitch)
+    for (int iPitch = 0; iPitch < m_nPitch; ++iPitch)
     {
         if (probYinPitched > 0) out[iPitch] *= (probReallyPitched/probYinPitched) ;
         out[iPitch+m_nPitch] = (1 - probReallyPitched) / m_nPitch;
@@ -83,19 +86,19 @@
 MonoPitchHMM::build()
 {
     // INITIAL VECTOR
-    init = vector<double>(2*m_nPitch, 1.0 / 2*m_nPitch);
+    m_init = vector<double>(2*m_nPitch, 1.0 / 2*m_nPitch);
     
     // TRANSITIONS
-    for (size_t iPitch = 0; iPitch < m_nPitch; ++iPitch)
+    for (int iPitch = 0; iPitch < int(m_nPitch); ++iPitch)
     {
-        int theoreticalMinNextPitch = static_cast<int>(iPitch)-static_cast<int>(m_transitionWidth/2);
+        int theoreticalMinNextPitch = iPitch-m_transitionWidth/2;
         int minNextPitch = iPitch>m_transitionWidth/2 ? iPitch-m_transitionWidth/2 : 0;
         int maxNextPitch = iPitch<m_nPitch-m_transitionWidth/2 ? iPitch+m_transitionWidth/2 : m_nPitch-1;
         
         // WEIGHT VECTOR
         double weightSum = 0;
         vector<double> weights;
-        for (size_t i = minNextPitch; i <= maxNextPitch; ++i)
+        for (int i = minNextPitch; i <= maxNextPitch; ++i)
         {
             if (i <= iPitch)
             {
@@ -110,24 +113,24 @@
         
         // std::cerr << minNextPitch << "  " << maxNextPitch << std::endl;
         // TRANSITIONS TO CLOSE PITCH
-        for (size_t i = minNextPitch; i <= maxNextPitch; ++i)
+        for (int i = minNextPitch; i <= maxNextPitch; ++i)
         {
-            from.push_back(iPitch);
-            to.push_back(i);
-            transProb.push_back(weights[i-minNextPitch] / weightSum * m_selfTrans);
+            m_from.push_back(iPitch);
+            m_to.push_back(i);
+            m_transProb.push_back(weights[i-minNextPitch] / weightSum * m_selfTrans);
 
-            from.push_back(iPitch);
-            to.push_back(i+m_nPitch);
-            transProb.push_back(weights[i-minNextPitch] / weightSum * (1-m_selfTrans));
+            m_from.push_back(iPitch);
+            m_to.push_back(i+m_nPitch);
+            m_transProb.push_back(weights[i-minNextPitch] / weightSum * (1-m_selfTrans));
 
-            from.push_back(iPitch+m_nPitch);
-            to.push_back(i+m_nPitch);
-            transProb.push_back(weights[i-minNextPitch] / weightSum * m_selfTrans);
+            m_from.push_back(iPitch+m_nPitch);
+            m_to.push_back(i+m_nPitch);
+            m_transProb.push_back(weights[i-minNextPitch] / weightSum * m_selfTrans);
             // transProb.push_back(weights[i-minNextPitch] / weightSum * 0.5);
             
-            from.push_back(iPitch+m_nPitch);
-            to.push_back(i);
-            transProb.push_back(weights[i-minNextPitch] / weightSum * (1-m_selfTrans));
+            m_from.push_back(iPitch+m_nPitch);
+            m_to.push_back(i);
+            m_transProb.push_back(weights[i-minNextPitch] / weightSum * (1-m_selfTrans));
             // transProb.push_back(weights[i-minNextPitch] / weightSum * 0.5);
         }
 
@@ -146,8 +149,48 @@
     // to.push_back(2*m_nPitch);
     // transProb.push_back(m_selfTrans);
     
-    // for (size_t i = 0; i < from.size(); ++i) {
+    // for (int i = 0; i < from.size(); ++i) {
     //     std::cerr << "P(["<< from[i] << " --> " << to[i] << "]) = " << transProb[i] << std::endl;
     // }
-    
+    m_nTrans = m_transProb.size();
+    m_delta = vector<double>(m_nState);
+    m_oldDelta = vector<double>(m_nState);
 }
+
+/*
+Takes a state number and a pitch-prob vector, then finds the pitch that would
+have been closest to the pitch of the state. Easy to understand? ;)
+*/
+const float
+MonoPitchHMM::nearestFreq(int state, vector<pair<double, double> > pitchProb)
+{
+    float hmmFreq = m_freqs[state];
+    // std::cerr << "hmmFreq " << hmmFreq << std::endl;
+    float bestFreq = 0;
+    float leastDist = 10000;
+    if (hmmFreq > 0)
+    {
+        // This was a Yin estimate, so try to get original pitch estimate back
+        // ... a bit hacky, since we could have direclty saved the frequency
+        // that was assigned to the HMM bin in hmm.calculateObsProb -- but would
+        // have had to rethink the interface of that method.
+
+        // std::cerr << "pitch prob size " << pitchProb.size() << std::endl;
+
+        for (size_t iPt = 0; iPt < pitchProb.size(); ++iPt)
+        {
+            float freq = 440. * 
+                         std::pow(2, 
+                                  (pitchProb[iPt].first - 69)/12);
+            float dist = std::abs(hmmFreq-freq);
+            if (dist < leastDist)
+            {
+                leastDist = dist;
+                bestFreq = freq;
+            }
+        }
+    } else {
+        bestFreq = hmmFreq;
+    }
+    return bestFreq;
+}
--- a/MonoPitchHMM.h	Thu Aug 20 16:06:01 2015 +0100
+++ b/MonoPitchHMM.h	Fri Mar 24 15:08:12 2017 +0000
@@ -26,15 +26,14 @@
 class MonoPitchHMM : public SparseHMM
 {
 public:
-    MonoPitchHMM();
+    MonoPitchHMM(int fixedLag);
     const std::vector<double> calculateObsProb(const vector<pair<double, double> >);
-    // double getMidiPitch(size_t index);
-    // double getFrequency(size_t index);
+    const float nearestFreq(int state, vector<pair<double, double> > pitchProb);
     void build();
     double m_minFreq; // 82.40689f/2
-    size_t m_nBPS;
-    size_t m_nPitch;
-    size_t m_transitionWidth;
+    int m_nBPS;
+    int m_nPitch;
+    int m_transitionWidth;
     double m_selfTrans;
     double m_yinTrust;
     vector<double> m_freqs;
--- a/PYinVamp.cpp	Thu Aug 20 16:06:01 2015 +0100
+++ b/PYinVamp.cpp	Fri Mar 24 15:08:12 2017 +0000
@@ -13,9 +13,7 @@
 
 #include "PYinVamp.h"
 #include "MonoNote.h"
-#include "MonoPitch.h"
-
-#include "vamp-sdk/FFT.h"
+#include "MonoPitchHMM.h"
 
 #include <vector>
 #include <algorithm>
@@ -44,14 +42,17 @@
     m_oSmoothedPitchTrack(0),
     m_oNotes(0),
     m_threshDistr(2.0f),
+    m_fixedLag(1.0f),
     m_outputUnvoiced(0.0f),
     m_preciseTime(0.0f),
     m_lowAmp(0.1f),
     m_onsetSensitivity(0.7f),
     m_pruneThresh(0.1f),
+    m_pitchHmm(0),
     m_pitchProb(0),
     m_timestamp(0),
-    m_level(0)
+    m_level(0),
+    m_pitchTrack(0)
 {
 }
 
@@ -88,7 +89,7 @@
 {
     // Increment this each time you release a version that behaves
     // differently from the previous one
-    return 2;
+    return 3;
 }
 
 string
@@ -153,6 +154,19 @@
     d.valueNames.push_back("Single Value 0.20");
     list.push_back(d);
 
+    d.valueNames.clear();
+
+    d.identifier = "fixedlag";
+    d.name = "Fixed-lag smoothing";
+    d.description = "Use fixed lag smoothing, not full Viterbi smoothing.";
+    d.unit = "";
+    d.minValue = 0.0f;
+    d.maxValue = 1.0f;
+    d.defaultValue = 0.0f;
+    d.isQuantized = true;
+    d.quantizeStep = 1.0f;
+    list.push_back(d);
+
     d.identifier = "outputunvoiced";
     d.valueNames.clear();
     d.name = "Output estimates classified as unvoiced?";
@@ -222,6 +236,9 @@
     if (identifier == "threshdistr") {
             return m_threshDistr;
     }
+    if (identifier == "fixedlag") {
+            return m_fixedLag;
+    }
     if (identifier == "outputunvoiced") {
             return m_outputUnvoiced;
     }
@@ -247,6 +264,10 @@
     {
         m_threshDistr = value;
     }
+    if (identifier == "fixedlag")
+    {
+        m_fixedLag = value;
+    }
     if (identifier == "outputunvoiced")
     {
         m_outputUnvoiced = value;
@@ -283,7 +304,7 @@
 }
 
 void
-PYinVamp::selectProgram(string name)
+PYinVamp::selectProgram(string)
 {
 }
 
@@ -419,10 +440,14 @@
     m_yin.setThresholdDistr(m_threshDistr);
     m_yin.setFrameSize(m_blockSize);
     m_yin.setFast(!m_preciseTime);
+
+    if (m_fixedLag == 1.f) m_pitchHmm = MonoPitchHMM(100);
+    else                   m_pitchHmm = MonoPitchHMM(0);
     
     m_pitchProb.clear();
     m_timestamp.clear();
     m_level.clear();
+    m_pitchTrack.clear();
 /*    
     std::cerr << "PYinVamp::reset"
           << ", blockSize = " << m_blockSize
@@ -433,8 +458,10 @@
 PYinVamp::FeatureSet
 PYinVamp::process(const float *const *inputBuffers, RealTime timestamp)
 {
+    std::cerr << timestamp << std::endl;
     int offset = m_preciseTime == 1.0 ? m_blockSize/2 : m_blockSize/4;
-    timestamp = timestamp + Vamp::RealTime::frame2RealTime(offset, lrintf(m_inputSampleRate));
+    timestamp = timestamp + Vamp::RealTime::frame2RealTime(offset, 
+        lrintf(m_inputSampleRate));
 
     FeatureSet fs;
     
@@ -455,8 +482,6 @@
 
     m_level.push_back(yo.rms);
 
-    // First, get the things out of the way that we don't want to output 
-    // immediately, but instead save for later.
     vector<pair<double, double> > tempPitchProb;
     for (size_t iCandidate = 0; iCandidate < yo.freqProb.size(); ++iCandidate)
     {
@@ -471,9 +496,53 @@
                 (tempPitch, yo.freqProb[iCandidate].second*factor));
         }
     }
+
+    vector<double> tempObsProb = m_pitchHmm.calculateObsProb(tempPitchProb);
+    if (m_timestamp.empty())
+    {
+        m_pitchHmm.initialise(tempObsProb);
+    } else {
+        m_pitchHmm.process(tempObsProb);
+    }
+
     m_pitchProb.push_back(tempPitchProb);
     m_timestamp.push_back(timestamp);
 
+    int lag = m_pitchHmm.m_fixedLag;
+
+    if (m_fixedLag == 1.f) // do fixed-lag smoothing instead of full Viterbi
+    {
+        if (int(m_timestamp.size()) == lag + 1)
+        {
+            m_timestamp.pop_front();
+            m_pitchProb.pop_front();
+
+            Feature f;
+            f.hasTimestamp = true;
+            vector<int> rawPitchPath = m_pitchHmm.track();
+            float freq = m_pitchHmm.nearestFreq(rawPitchPath[0], 
+                                                m_pitchProb[0]);
+            m_pitchTrack.push_back(freq);
+            f.timestamp = m_timestamp[0];
+            f.values.clear();
+
+            // different output modes
+            if (freq < 0 && (m_outputUnvoiced==0))
+            {
+
+            } else {
+                if (m_outputUnvoiced == 1)
+                {
+                    f.values.push_back(fabs(freq));
+                } else {
+                    f.values.push_back(freq);
+                }
+                fs[m_oSmoothedPitchTrack].push_back(f);
+            }
+        }
+    }
+
+
     // F0 CANDIDATES
     Feature f;
     f.hasTimestamp = true;
@@ -523,39 +592,49 @@
         return fs;
     }
 
-    // MONO-PITCH STUFF
-    MonoPitch mp;
-    vector<float> mpOut = mp.process(m_pitchProb);
-    for (size_t iFrame = 0; iFrame < mpOut.size(); ++iFrame)
+    // ================== P I T C H  T R A C K =================================
+
+    vector<int> rawPitchPath = m_pitchHmm.track();
+    
+    for (size_t iFrame = 0; iFrame < rawPitchPath.size(); ++iFrame)
     {
-        if (mpOut[iFrame] < 0 && (m_outputUnvoiced==0)) continue;
+        float freq = m_pitchHmm.nearestFreq(rawPitchPath[iFrame], 
+                                            m_pitchProb[iFrame]);
+        m_pitchTrack.push_back(freq); // for note processing below
+
         f.timestamp = m_timestamp[iFrame];
         f.values.clear();
+
+        // different output modes
+        if (freq < 0 && (m_outputUnvoiced==0)) continue;
         if (m_outputUnvoiced == 1)
         {
-            f.values.push_back(fabs(mpOut[iFrame]));
+            f.values.push_back(fabs(freq));
         } else {
-            f.values.push_back(mpOut[iFrame]);
+            f.values.push_back(freq);
         }
-        
         fs[m_oSmoothedPitchTrack].push_back(f);
     }
     
-    // MONO-NOTE STUFF
-//    std::cerr << "Mono Note Stuff" << std::endl;
+    // ======================== N O T E S ======================================
     MonoNote mn;
     std::vector<std::vector<std::pair<double, double> > > smoothedPitch;
-    for (size_t iFrame = 0; iFrame < mpOut.size(); ++iFrame) {
+    for (size_t iFrame = 0; iFrame < m_pitchTrack.size(); ++iFrame) {
         std::vector<std::pair<double, double> > temp;
-        if (mpOut[iFrame] > 0)
+        if (m_pitchTrack[iFrame] > 0)
         {
-            double tempPitch = 12 * std::log(mpOut[iFrame]/440)/std::log(2.) + 69;
+            double tempPitch = 12 * 
+                std::log(m_pitchTrack[iFrame]/440)/std::log(2.) + 69;
             temp.push_back(std::pair<double,double>(tempPitch, .9));
+            // std::cerr << "tempPitch: " << tempPitch << std::endl;
         }
+        // std::cerr << "temp size: " << temp.size() << std::endl;
         smoothedPitch.push_back(temp);
     }
-    // vector<MonoNote::FrameOutput> mnOut = mn.process(m_pitchProb);
+
     vector<MonoNote::FrameOutput> mnOut = mn.process(smoothedPitch);
+    std::cerr << "mnOut size: " << mnOut.size() << std::endl;
+    std::cerr << "m_pitchTrack size: " << m_pitchTrack.size() << std::endl;
     
     // turning feature into a note feature
     f.hasTimestamp = true;
@@ -565,18 +644,30 @@
     int onsetFrame = 0;
     bool isVoiced = 0;
     bool oldIsVoiced = 0;
-    size_t nFrame = m_pitchProb.size();
+    size_t nFrame = m_pitchTrack.size();
 
     float minNoteFrames = (m_inputSampleRate*m_pruneThresh) / m_stepSize;
     
-    std::vector<float> notePitchTrack; // collects pitches for one note at a time
+    // the body of the loop below should be in a function/method
+    // but what does it actually do??
+    // * takes the result of the note tracking HMM
+    // * collects contiguously pitched pitches
+    // * writes a note once it notices the voiced segment has ended
+    // complications:
+    // * it needs a lookahead of two frames for m_level (wtf was I thinking)
+    // * it needs to know the timestamp (which can be guessed from the frame no)
+    // * 
+    int offset = m_preciseTime == 1.0 ? m_blockSize/2 : m_blockSize/4;
+    RealTime timestampOffset = Vamp::RealTime::frame2RealTime(offset, 
+        lrintf(m_inputSampleRate));
+
+    std::vector<float> notePitchTrack; // collects pitches for 1 note at a time
     for (size_t iFrame = 0; iFrame < nFrame; ++iFrame)
     {
-        isVoiced = mnOut[iFrame].noteState < 3
-                   && smoothedPitch[iFrame].size() > 0
-                   && (iFrame >= nFrame-2
-                       || ((m_level[iFrame]/m_level[iFrame+2]) > m_onsetSensitivity));
-        // std::cerr << m_level[iFrame]/m_level[iFrame-1] << " " << isVoiced << std::endl;
+        isVoiced = mnOut[iFrame].noteState < 3 
+            && smoothedPitch[iFrame].size() > 0 
+            && (iFrame >= nFrame-2
+                || ((m_level[iFrame]/m_level[iFrame+2]) > m_onsetSensitivity));
         if (isVoiced && iFrame != nFrame-1)
         {
             if (oldIsVoiced == 0) // beginning of a note
@@ -588,16 +679,22 @@
         } else { // not currently voiced
             if (oldIsVoiced == 1) // end of note
             {
-                // std::cerr << notePitchTrack.size() << " " << minNoteFrames << std::endl;
                 if (notePitchTrack.size() >= minNoteFrames)
                 {
                     std::sort(notePitchTrack.begin(), notePitchTrack.end());
                     float medianPitch = notePitchTrack[notePitchTrack.size()/2];
-                    float medianFreq = std::pow(2,(medianPitch - 69) / 12) * 440;
+                    float medianFreq = 
+                        std::pow(2,(medianPitch - 69) / 12) * 440;
                     f.values.clear();
                     f.values.push_back(medianFreq);
-                    f.timestamp = m_timestamp[onsetFrame];
-                    f.duration = m_timestamp[iFrame] - m_timestamp[onsetFrame];
+                    RealTime start = RealTime::frame2RealTime(
+                        onsetFrame * m_stepSize, lrintf(m_inputSampleRate)) + 
+                        timestampOffset;
+                    RealTime end   = RealTime::frame2RealTime(
+                            iFrame * m_stepSize, lrintf(m_inputSampleRate)) + 
+                        timestampOffset;
+                    f.timestamp = start;
+                    f.duration = end - start;
                     fs[m_oNotes].push_back(f);
                 }
                 notePitchTrack.clear();
--- a/PYinVamp.h	Thu Aug 20 16:06:01 2015 +0100
+++ b/PYinVamp.h	Fri Mar 24 15:08:12 2017 +0000
@@ -17,6 +17,7 @@
 #include <vamp-sdk/Plugin.h>
 
 #include "Yin.h"
+#include "MonoPitchHMM.h"
 
 class PYinVamp : public Vamp::Plugin
 {
@@ -71,14 +72,23 @@
     mutable int m_oNotes;
 
     float m_threshDistr;
+    float m_fixedLag;
     float m_outputUnvoiced;
     float m_preciseTime;
     float m_lowAmp;
     float m_onsetSensitivity;
     float m_pruneThresh;
-    vector<vector<pair<double, double> > > m_pitchProb;
-    vector<Vamp::RealTime> m_timestamp;
+
+    MonoPitchHMM m_pitchHmm;
+
+    deque<vector<pair<double, double> > > m_pitchProb;
+    deque<Vamp::RealTime> m_timestamp;
     vector<float> m_level;
+    vector<float> m_pitchTrack;
+
+    // for note writing
+    // vector<float> m_notePitchTrack; // contains pitches of one current note
+    // bool m_oldIsVoiced;
 };
 
 #endif
--- a/SparseHMM.cpp	Thu Aug 20 16:06:01 2015 +0100
+++ b/SparseHMM.cpp	Fri Mar 24 15:08:12 2017 +0000
@@ -19,110 +19,167 @@
 using std::vector;
 using std::pair;
 
+SparseHMM::SparseHMM(int fixedLag) :
+    m_fixedLag(fixedLag),
+    m_nState(0),
+    m_nTrans(0),
+    m_init(0),
+    m_from(0),
+    m_to(0),
+    m_transProb(0),
+    m_scale(0),
+    m_psi(0),
+    m_delta(0),
+    m_oldDelta(0)
+{
+
+}
+
 const vector<double>
-SparseHMM::calculateObsProb(const vector<pair<double, double> > data)
+SparseHMM::calculateObsProb(const vector<pair<double, double> > )
 {
     // dummy (virtual?) implementation to be overloaded
     return(vector<double>());
 }
 
+void
+SparseHMM::build()
+{ }
+
 const std::vector<int> 
-SparseHMM::decodeViterbi(std::vector<vector<double> > obsProb,
-                         vector<double> *scale) 
+SparseHMM::decodeViterbi(std::vector<vector<double> > obsProb) 
 {
-    if (obsProb.size() < 1) {
+    int nFrame = obsProb.size();
+    if (nFrame < 1) {
         return vector<int>();
     }
 
-    size_t nState = init.size();
-    size_t nFrame = obsProb.size();
-    
-    // check for consistency    
-    size_t nTrans = transProb.size();
-    
-    // declaring variables
-    std::vector<double> delta = std::vector<double>(nState);
-    std::vector<double> oldDelta = std::vector<double>(nState);
-    vector<vector<int> > psi; //  "matrix" of remembered indices of the best transitions
-    vector<int> path = vector<int>(nFrame, nState-1); // the final output path (current assignment arbitrary, makes sense only for Chordino, where nChord-1 is the "no chord" label)
+    initialise(obsProb[0]);
+
+    // rest of forward step
+    for (int iFrame = 1; iFrame < nFrame; ++iFrame)
+    {
+        process(obsProb[iFrame]);
+    }
+
+    vector<int> path = track();
+    return(path);
+}
+
+void
+SparseHMM::reset()
+{
+    m_scale.clear();
+    m_psi.clear();
+    for (int i = 0; i < int(m_delta.size()); ++i) m_delta[i] = 0;
+    for (int i = 0; i < int(m_oldDelta.size()); ++i) m_oldDelta[i] = 0;
+}
+
+void
+SparseHMM::initialise(vector<double> firstObs)
+{
+    reset();
 
     double deltasum = 0;
 
     // initialise first frame
-    for (size_t iState = 0; iState < nState; ++iState)
+    for (int iState = 0; iState < m_nState; ++iState)
     {
-        oldDelta[iState] = init[iState] * obsProb[0][iState];
-        // std::cerr << iState << " ----- " << init[iState] << std::endl;
-        deltasum += oldDelta[iState];
+        m_oldDelta[iState] = m_init[iState] * firstObs[iState];
+        deltasum += m_oldDelta[iState];
     }
 
-    for (size_t iState = 0; iState < nState; ++iState)
+    for (int iState = 0; iState < m_nState; ++iState)
     {
-        oldDelta[iState] /= deltasum; // normalise (scale)
-        // std::cerr << oldDelta[iState] << std::endl;
+        m_oldDelta[iState] /= deltasum; // normalise (scale)
     }
 
-    scale->push_back(1.0/deltasum);
-    psi.push_back(vector<int>(nState,0));
+    m_scale.push_back(1.0/deltasum);
+    m_psi.push_back(vector<int>(m_nState,0));
+}
 
-    // rest of forward step
-    for (size_t iFrame = 1; iFrame < nFrame; ++iFrame)
+int
+SparseHMM::process(vector<double> newObs)
+{
+    vector<int> tempPsi = vector<int>(m_nState,0);
+
+    // calculate best previous state for every current state
+    int fromState;
+    int toState;
+    double currentTransProb;
+    double currentValue;
+    
+    // this is the "sparse" loop
+    for (int iTrans = 0; iTrans < m_nTrans; ++iTrans)
     {
-        deltasum = 0;
-        psi.push_back(vector<int>(nState,0));
-
-        // calculate best previous state for every current state
-        size_t fromState;
-        size_t toState;
-        double currentTransProb;
-        double currentValue;
+        fromState = m_from[iTrans];
+        toState = m_to[iTrans];
+        currentTransProb = m_transProb[iTrans];
         
-        // this is the "sparse" loop
-        for (size_t iTrans = 0; iTrans < nTrans; ++iTrans)
+        currentValue = m_oldDelta[fromState] * currentTransProb;
+        if (currentValue > m_delta[toState])
         {
-            fromState = from[iTrans];
-            toState = to[iTrans];
-            currentTransProb = transProb[iTrans];
-            
-            currentValue = oldDelta[fromState] * currentTransProb;
-            if (currentValue > delta[toState])
-            {
-                delta[toState] = currentValue; // will be multiplied by the right obs later!
-                psi[iFrame][toState] = fromState;
-            }            
-        }
-        
-        for (size_t jState = 0; jState < nState; ++jState)
-        {
-            delta[jState] *= obsProb[iFrame][jState];
-            deltasum += delta[jState];
-        }
-
-        if (deltasum > 0)
-        {
-            for (size_t iState = 0; iState < nState; ++iState)
-            {
-                oldDelta[iState] = delta[iState] / deltasum; // normalise (scale)
-                delta[iState] = 0;
-            }
-            scale->push_back(1.0/deltasum);
-        } else
-        {
-            std::cerr << "WARNING: Viterbi has been fed some zero probabilities, at least they become zero at frame " <<  iFrame << " in combination with the model." << std::endl;
-            for (size_t iState = 0; iState < nState; ++iState)
-            {
-                oldDelta[iState] = 1.0/nState;
-                delta[iState] = 0;
-            }
-            scale->push_back(1.0);
+            // will be multiplied by the right obs later!
+            m_delta[toState] = currentValue;
+            tempPsi[toState] = fromState;
         }
     }
+    m_psi.push_back(tempPsi);
 
+
+    double deltasum = 0;
+    for (int jState = 0; jState < m_nState; ++jState)
+    {
+        m_delta[jState] *= newObs[jState];
+        deltasum += m_delta[jState];
+    }
+
+    if (deltasum > 0)
+    {
+        for (int iState = 0; iState < m_nState; ++iState)
+        {
+            m_oldDelta[iState] = m_delta[iState] / deltasum;// normalise (scale)
+            m_delta[iState] = 0;
+        }
+        m_scale.push_back(1.0/deltasum);
+    } else
+    {
+        std::cerr << "WARNING: Viterbi has been fed some zero "
+            "probabilities, at least they become zero "
+            "in combination with the model." << std::endl;
+        for (int iState = 0; iState < m_nState; ++iState)
+        {
+            m_oldDelta[iState] = 1.0/m_nState;
+            m_delta[iState] = 0;
+        }
+        m_scale.push_back(1.0);
+    }
+
+    if (m_fixedLag > 0 && int(m_psi.size()) > m_fixedLag)
+    {
+        m_psi.pop_front();
+        m_scale.pop_front();
+    }
+
+    // std::cerr << m_fixedLag << " " << m_psi.size() << std::endl;
+
+    return 0;
+}
+
+const vector<int>
+SparseHMM::track()
+{
     // initialise backward step
+    int nFrame = m_psi.size();
+
+    // The final output path (current assignment arbitrary, makes sense only for 
+    // Chordino, where nChord-1 is the "no chord" label)
+    vector<int> path = vector<int>(nFrame, m_nState-1);
+
     double bestValue = 0;
-    for (size_t iState = 0; iState < nState; ++iState)
+    for (int iState = 0; iState < m_nState; ++iState)
     {
-        double currentValue = oldDelta[iState];
+        double currentValue = m_oldDelta[iState];
         if (currentValue > bestValue)
         {
             bestValue = currentValue;            
@@ -130,16 +187,11 @@
         }
     }
 
-    // rest of backward step
+    // Rest of backward step
     for (int iFrame = nFrame-2; iFrame != -1; --iFrame)
     {
-        path[iFrame] = psi[iFrame+1][path[iFrame+1]];
+        path[iFrame] = m_psi[iFrame+1][path[iFrame+1]];
     }
-    
-    // for (size_t iState = 0; iState < nState; ++iState)
-    // {
-    //     // std::cerr << psi[2][iState] << std::endl;
-    // }
-    
+        
     return path;
 }
--- a/SparseHMM.h	Thu Aug 20 16:06:01 2015 +0100
+++ b/SparseHMM.h	Fri Mar 24 15:08:12 2017 +0000
@@ -15,21 +15,39 @@
 #define _SPARSEHMM_H_
 
 #include <vector>
+#include <queue>
 #include <cstdio>
 
 using std::vector;
+using std::deque;
 using std::pair;
 
 class SparseHMM
 {
 public:
-    virtual const std::vector<double> calculateObsProb(const vector<pair<double, double> >);
-    const std::vector<int> decodeViterbi(std::vector<vector<double> > obs, 
-                                   vector<double> *scale);
-    vector<double> init;
-    vector<size_t> from;
-    vector<size_t> to;
-    vector<double> transProb;
+    SparseHMM(int fixedLag);
+    virtual const std::vector<double>
+                           calculateObsProb(const vector<pair<double, double> >);
+    virtual void           build();
+    const std::vector<int> decodeViterbi(std::vector<vector<double> > obs);
+    void                   reset();
+    void                   initialise(vector<double> firstObs);
+    int                    process(vector<double> newObs);
+    const vector<int>      track();
+    // "sparse" HMM definition
+    int m_fixedLag;
+    int m_nState;
+    int m_nTrans;
+    vector<double> m_init;
+    vector<size_t> m_from;
+    vector<size_t> m_to;
+    vector<double> m_transProb;
+
+    // variables for decoding
+    deque<double> m_scale;
+    deque<vector<int> > m_psi;
+    vector<double> m_delta;
+    vector<double> m_oldDelta;
 };
 
 #endif
--- a/Yin.cpp	Thu Aug 20 16:06:01 2015 +0100
+++ b/Yin.cpp	Fri Mar 24 15:08:12 2017 +0000
@@ -31,7 +31,8 @@
     m_thresh(thresh),
     m_threshDistr(2),
     m_yinBufferSize(frameSize/2),
-    m_fast(fast)
+    m_fast(fast),
+    m_yinUtil(new YinUtil(m_yinBufferSize))
 {
     if (frameSize & (frameSize-1)) {
       //  throw "N must be a power of two";
@@ -40,6 +41,7 @@
 
 Yin::~Yin() 
 {
+    delete m_yinUtil;
 }
 
 Yin::YinOutput
@@ -48,13 +50,13 @@
     double* yinBuffer = new double[m_yinBufferSize];
 
     // calculate aperiodicity function for all periods
-    if (m_fast) YinUtil::fastDifference(in, yinBuffer, m_yinBufferSize);
-    else YinUtil::slowDifference(in, yinBuffer, m_yinBufferSize);
+    if (m_fast) m_yinUtil->fastDifference(in, yinBuffer);
+    else m_yinUtil->slowDifference(in, yinBuffer);
 
-    YinUtil::cumulativeDifference(yinBuffer, m_yinBufferSize);
+    m_yinUtil->cumulativeDifference(yinBuffer);
 
     int tau = 0;
-    tau = YinUtil::absoluteThreshold(yinBuffer, m_yinBufferSize, m_thresh);
+    tau = m_yinUtil->absoluteThreshold(yinBuffer, m_thresh);
         
     double interpolatedTau;
     double aperiodicity;
@@ -62,13 +64,13 @@
     
     if (tau!=0)
     {
-        interpolatedTau = YinUtil::parabolicInterpolation(yinBuffer, abs(tau), m_yinBufferSize);
+        interpolatedTau = m_yinUtil->parabolicInterpolation(yinBuffer, abs(tau));
         f0 = m_inputSampleRate * (1.0 / interpolatedTau);
     } else {
         interpolatedTau = 0;
         f0 = 0;
     }
-    double rms = std::sqrt(YinUtil::sumSquare(in, 0, m_yinBufferSize)/m_yinBufferSize);
+    double rms = std::sqrt(m_yinUtil->sumSquare(in, 0, m_yinBufferSize)/m_yinBufferSize);
     aperiodicity = yinBuffer[abs(tau)];
     // std::cerr << aperiodicity << std::endl;
     if (tau < 0) f0 = -f0;
@@ -89,12 +91,12 @@
     double* yinBuffer = new double[m_yinBufferSize];
 
     // calculate aperiodicity function for all periods
-    if (m_fast) YinUtil::fastDifference(in, yinBuffer, m_yinBufferSize);
-    else YinUtil::slowDifference(in, yinBuffer, m_yinBufferSize);
+    if (m_fast) m_yinUtil->fastDifference(in, yinBuffer);
+    else m_yinUtil->slowDifference(in, yinBuffer);
 
-    YinUtil::cumulativeDifference(yinBuffer, m_yinBufferSize);
+    m_yinUtil->cumulativeDifference(yinBuffer);
 
-    vector<double> peakProbability = YinUtil::yinProb(yinBuffer, m_threshDistr, m_yinBufferSize);
+    vector<double> peakProbability = m_yinUtil->yinProb(yinBuffer, m_threshDistr);
     
     // calculate overall "probability" from peak probability
     double probSum = 0;
@@ -102,7 +104,7 @@
     {
         probSum += peakProbability[iBin];
     }
-    double rms = std::sqrt(YinUtil::sumSquare(in, 0, m_yinBufferSize)/m_yinBufferSize);
+    double rms = std::sqrt(m_yinUtil->sumSquare(in, 0, m_yinBufferSize)/m_yinBufferSize);
     Yin::YinOutput yo(0,0,rms);
     for (size_t iBuf = 0; iBuf < m_yinBufferSize; ++iBuf)
     {
@@ -111,7 +113,7 @@
         {
             double currentF0 = 
                 m_inputSampleRate * (1.0 /
-                YinUtil::parabolicInterpolation(yinBuffer, iBuf, m_yinBufferSize));
+                m_yinUtil->parabolicInterpolation(yinBuffer, iBuf));
             yo.freqProb.push_back(pair<double, double>(currentF0, peakProbability[iBuf]));
         }
     }
--- a/Yin.h	Thu Aug 20 16:06:01 2015 +0100
+++ b/Yin.h	Fri Mar 24 15:08:12 2017 +0000
@@ -26,7 +26,7 @@
 using std::vector;
 using std::pair;
 
-
+class YinUtil;
 
 class Yin
 {
@@ -66,6 +66,7 @@
     mutable size_t m_yinBufferSize;
     mutable bool   m_fast;
     // mutable bool m_removeUnvoiced;
+    YinUtil *m_yinUtil;
 };
 
 #endif
--- a/YinUtil.cpp	Thu Aug 20 16:06:01 2015 +0100
+++ b/YinUtil.cpp	Fri Mar 24 15:08:12 2017 +0000
@@ -21,17 +21,27 @@
 
 #include <boost/math/distributions.hpp>
 
+YinUtil::YinUtil(int yinBufferSize) :
+    m_yinBufferSize(yinBufferSize),
+    m_fft(yinBufferSize * 2)
+{
+}
+
+YinUtil::~YinUtil()
+{
+}
+
 void 
-YinUtil::slowDifference(const double *in, double *yinBuffer, const size_t yinBufferSize) 
+YinUtil::slowDifference(const double *in, double *yinBuffer) 
 {
     yinBuffer[0] = 0;
     double delta ;
     int startPoint = 0;
     int endPoint = 0;
-    for (int i = 1; i < yinBufferSize; ++i) {
+    for (int i = 1; i < int(m_yinBufferSize); ++i) {
         yinBuffer[i] = 0;
-        startPoint = yinBufferSize/2 - i/2;
-        endPoint = startPoint + yinBufferSize;
+        startPoint = m_yinBufferSize/2 - i/2;
+        endPoint = startPoint + m_yinBufferSize;
         for (int j = startPoint; j < endPoint; ++j) {
             delta = in[i+j] - in[j];
             yinBuffer[i] += delta * delta;
@@ -40,99 +50,86 @@
 }
 
 void 
-YinUtil::fastDifference(const double *in, double *yinBuffer, const size_t yinBufferSize) 
+YinUtil::fastDifference(const double *in, double *yinBuffer) 
 {
-    
     // DECLARE AND INITIALISE
     // initialisation of most of the arrays here was done in a separate function,
     // with all the arrays as members of the class... moved them back here.
     
-    size_t frameSize = 2 * yinBufferSize;
-    
-    double *audioTransformedReal = new double[frameSize];
-    double *audioTransformedImag = new double[frameSize];
-    double *nullImag = new double[frameSize];
+    int frameSize = 2 * m_yinBufferSize;
+    int halfSize = m_yinBufferSize;
+
+    double *audioTransformedComplex = new double[frameSize + 2];
+    double *audioOutReal = new double[frameSize];
     double *kernel = new double[frameSize];
-    double *kernelTransformedReal = new double[frameSize];
-    double *kernelTransformedImag = new double[frameSize];
-    double *yinStyleACFReal = new double[frameSize];
-    double *yinStyleACFImag = new double[frameSize];
-    double *powerTerms = new double[yinBufferSize];
-    
-    for (size_t j = 0; j < yinBufferSize; ++j)
-    {
-        yinBuffer[j] = 0.; // set to zero
-        powerTerms[j] = 0.; // set to zero
-    }
-    
-    for (size_t j = 0; j < frameSize; ++j)
-    {
-        nullImag[j] = 0.;
-        audioTransformedReal[j] = 0.;
-        audioTransformedImag[j] = 0.;
-        kernel[j] = 0.;
-        kernelTransformedReal[j] = 0.;
-        kernelTransformedImag[j] = 0.;
-        yinStyleACFReal[j] = 0.;
-        yinStyleACFImag[j] = 0.;
-    }
+    double *kernelTransformedComplex = new double[frameSize + 2];
+    double *yinStyleACFComplex = new double[frameSize + 2];
+    double *powerTerms = new double[m_yinBufferSize];
     
     // POWER TERM CALCULATION
     // ... for the power terms in equation (7) in the Yin paper
     powerTerms[0] = 0.0;
-    for (size_t j = 0; j < yinBufferSize; ++j) {
+    for (int j = 0; j < m_yinBufferSize; ++j) {
         powerTerms[0] += in[j] * in[j];
     }
 
     // now iteratively calculate all others (saves a few multiplications)
-    for (size_t tau = 1; tau < yinBufferSize; ++tau) {
-        powerTerms[tau] = powerTerms[tau-1] - in[tau-1] * in[tau-1] + in[tau+yinBufferSize] * in[tau+yinBufferSize];  
+    for (int tau = 1; tau < m_yinBufferSize; ++tau) {
+        powerTerms[tau] = powerTerms[tau-1] -
+            in[tau-1] * in[tau-1] +
+            in[tau+m_yinBufferSize] * in[tau+m_yinBufferSize];  
     }
 
     // YIN-STYLE AUTOCORRELATION via FFT
     // 1. data
-    Vamp::FFT::forward(frameSize, in, nullImag, audioTransformedReal, audioTransformedImag);
+    m_fft.forward(in, audioTransformedComplex);
     
     // 2. half of the data, disguised as a convolution kernel
-    for (size_t j = 0; j < yinBufferSize; ++j) {
-        kernel[j] = in[yinBufferSize-1-j];
+    for (int j = 0; j < m_yinBufferSize; ++j) {
+        kernel[j] = in[m_yinBufferSize-1-j];
     }
-    Vamp::FFT::forward(frameSize, kernel, nullImag, kernelTransformedReal, kernelTransformedImag);
+    for (int j = m_yinBufferSize; j < frameSize; ++j) {
+        kernel[j] = 0.;
+    }
+    m_fft.forward(kernel, kernelTransformedComplex);
 
     // 3. convolution via complex multiplication -- written into
-    for (size_t j = 0; j < frameSize; ++j) {
-        yinStyleACFReal[j] = audioTransformedReal[j]*kernelTransformedReal[j] - audioTransformedImag[j]*kernelTransformedImag[j]; // real
-        yinStyleACFImag[j] = audioTransformedReal[j]*kernelTransformedImag[j] + audioTransformedImag[j]*kernelTransformedReal[j]; // imaginary
+    for (int j = 0; j <= halfSize; ++j) {
+        yinStyleACFComplex[j*2] = // real
+            audioTransformedComplex[j*2] * kernelTransformedComplex[j*2] -
+            audioTransformedComplex[j*2+1] * kernelTransformedComplex[j*2+1];
+        yinStyleACFComplex[j*2+1] = // imaginary
+            audioTransformedComplex[j*2] * kernelTransformedComplex[j*2+1] +
+            audioTransformedComplex[j*2+1] * kernelTransformedComplex[j*2];
     }
-    Vamp::FFT::inverse(frameSize, yinStyleACFReal, yinStyleACFImag, audioTransformedReal, audioTransformedImag);
+
+    m_fft.inverse(yinStyleACFComplex, audioOutReal);
     
     // CALCULATION OF difference function
     // ... according to (7) in the Yin paper.
-    for (size_t j = 0; j < yinBufferSize; ++j) {
-        // taking only the real part
-        yinBuffer[j] = powerTerms[0] + powerTerms[j] - 2 * audioTransformedReal[j+yinBufferSize-1];
+    for (int j = 0; j < m_yinBufferSize; ++j) {
+        yinBuffer[j] = powerTerms[0] + powerTerms[j] - 2 *
+            audioOutReal[j+m_yinBufferSize-1];
     }
-    delete [] audioTransformedReal;
-    delete [] audioTransformedImag;
-    delete [] nullImag;
+    delete [] audioTransformedComplex;
+    delete [] audioOutReal;
     delete [] kernel;
-    delete [] kernelTransformedReal;
-    delete [] kernelTransformedImag;
-    delete [] yinStyleACFReal;
-    delete [] yinStyleACFImag;
+    delete [] kernelTransformedComplex;
+    delete [] yinStyleACFComplex;
     delete [] powerTerms;
 }
 
+
 void 
-YinUtil::cumulativeDifference(double *yinBuffer, const size_t yinBufferSize)
+YinUtil::cumulativeDifference(double *yinBuffer)
 {    
-    size_t tau;
+    int tau;
     
     yinBuffer[0] = 1;
     
     double runningSum = 0;
     
-    for (tau = 1; tau < yinBufferSize; ++tau) {
+    for (tau = 1; tau < m_yinBufferSize; ++tau) {
         runningSum += yinBuffer[tau];
         if (runningSum == 0)
         {
@@ -144,19 +141,19 @@
 }
 
 int 
-YinUtil::absoluteThreshold(const double *yinBuffer, const size_t yinBufferSize, const double thresh)
+YinUtil::absoluteThreshold(const double *yinBuffer, double thresh)
 {
-    size_t tau;
-    size_t minTau = 0;
+    int tau;
+    int minTau = 0;
     double minVal = 1000.;
     
     // using Joren Six's "loop construct" from TarsosDSP
     tau = 2;
-    while (tau < yinBufferSize)
+    while (tau < m_yinBufferSize)
     {
         if (yinBuffer[tau] < thresh)
         {
-            while (tau+1 < yinBufferSize && yinBuffer[tau+1] < yinBuffer[tau])
+            while (tau+1 < m_yinBufferSize && yinBuffer[tau+1] < yinBuffer[tau])
             {
                 ++tau;
             }
@@ -187,22 +184,22 @@
 static float single20[100] = {0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,1.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000};
 
 std::vector<double>
-YinUtil::yinProb(const double *yinBuffer, const size_t prior, const size_t yinBufferSize, const size_t minTau0, const size_t maxTau0) 
+YinUtil::yinProb(const double *yinBuffer, int prior, int minTau0, int maxTau0) 
 {
-    size_t minTau = 2;
-    size_t maxTau = yinBufferSize;
+    int minTau = 2;
+    int maxTau = m_yinBufferSize;
 
     // adapt period range, if necessary
     if (minTau0 > 0 && minTau0 < maxTau0) minTau = minTau0;
-    if (maxTau0 > 0 && maxTau0 < yinBufferSize && maxTau0 > minTau) maxTau = maxTau0;
+    if (maxTau0 > 0 && maxTau0 < m_yinBufferSize && maxTau0 > minTau) maxTau = maxTau0;
 
     double minWeight = 0.01;
-    size_t tau;
+    int tau;
     std::vector<float> thresholds;
     std::vector<float> distribution;
-    std::vector<double> peakProb = std::vector<double>(yinBufferSize);
+    std::vector<double> peakProb = std::vector<double>(m_yinBufferSize);
     
-    size_t nThreshold = 100;
+    int nThreshold = 100;
     int nThresholdInt = nThreshold;
     
     for (int i = 0; i < nThresholdInt; ++i)
@@ -243,7 +240,7 @@
     tau = minTau;
     
     // double factor = 1.0 / (0.25 * (nThresholdInt+1) * (nThresholdInt + 1)); // factor to scale down triangular weight
-    size_t minInd = 0;
+    int minInd = 0;
     float minVal = 42.f;
     // while (currThreshInd != -1 && tau < maxTau)
     // {
@@ -266,7 +263,7 @@
     //     }
     // }
     // double nonPeakProb = 1;
-    // for (size_t i = minTau; i < maxTau; ++i)
+    // for (int i = minTau; i < maxTau; ++i)
     // {
     //     nonPeakProb -= peakProb[i];
     // }
@@ -288,7 +285,7 @@
                 minInd = tau;
             }
             currThreshInd = nThresholdInt-1;
-            while (thresholds[currThreshInd] > yinBuffer[tau] && currThreshInd > -1) {
+            while (currThreshInd > -1 && thresholds[currThreshInd] > yinBuffer[tau]) {
                 // std::cerr << distribution[currThreshInd] << std::endl;
                 peakProb[tau] += distribution[currThreshInd];
                 currThreshInd--;
@@ -303,12 +300,12 @@
     
     if (peakProb[minInd] > 1) {
         std::cerr << "WARNING: yin has prob > 1 ??? I'm returning all zeros instead." << std::endl;
-        return(std::vector<double>(yinBufferSize));
+        return(std::vector<double>(m_yinBufferSize));
     }
     
     double nonPeakProb = 1;
     if (sumProb > 0) {
-        for (size_t i = minTau; i < maxTau; ++i)
+        for (int i = minTau; i < maxTau; ++i)
         {
             peakProb[i] = peakProb[i] / sumProb * peakProb[minInd];
             nonPeakProb -= peakProb[i];
@@ -324,16 +321,16 @@
 }
 
 double
-YinUtil::parabolicInterpolation(const double *yinBuffer, const size_t tau, const size_t yinBufferSize) 
+YinUtil::parabolicInterpolation(const double *yinBuffer, int tau) 
 {
     // this is taken almost literally from Joren Six's Java implementation
-    if (tau == yinBufferSize) // not valid anyway.
+    if (tau == m_yinBufferSize) // not valid anyway.
     {
         return static_cast<double>(tau);
     }
     
     double betterTau = 0.0;
-    if (tau > 0 && tau < yinBufferSize-1) {
+    if (tau > 0 && tau < m_yinBufferSize-1) {
         float s0, s1, s2;
         s0 = yinBuffer[tau-1];
         s1 = yinBuffer[tau];
@@ -352,10 +349,10 @@
 }
 
 double 
-YinUtil::sumSquare(const double *in, const size_t start, const size_t end)
+YinUtil::sumSquare(const double *in, int start, int end)
 {
     double out = 0;
-    for (size_t i = start; i < end; ++i)
+    for (int i = start; i < end; ++i)
     {
         out += in[i] * in[i];
     }
--- a/YinUtil.h	Thu Aug 20 16:06:01 2015 +0100
+++ b/YinUtil.h	Fri Mar 24 15:08:12 2017 +0000
@@ -14,29 +14,35 @@
 #ifndef _YINUTIL_H_
 #define _YINUTIL_H_
 
-#include "vamp-sdk/FFT.h"
-#include "MeanFilter.h"
-
 #include <cmath>
 
 #include <iostream>
 #include <vector>
 #include <exception>
 
+#include "vamp-sdk/FFT.h"
+
 using std::vector;
 
 class YinUtil
 {
 public:
-    static double sumSquare(const double *in, const size_t startInd, const size_t endInd);
-    static void difference(const double *in, double *yinBuffer, const size_t yinBufferSize);
-    static void fastDifference(const double *in, double *yinBuffer, const size_t yinBufferSize);
-    static void slowDifference(const double *in, double *yinBuffer, const size_t yinBufferSize);
-    static void cumulativeDifference(double *yinBuffer, const size_t yinBufferSize);
-    static int absoluteThreshold(const double *yinBuffer, const size_t yinBufferSize, const double thresh);
-    static vector<double> yinProb(const double *yinBuffer, const size_t prior, const size_t yinBufferSize, size_t minTau = 0, size_t maxTau = 0);
-    static double parabolicInterpolation(const double *yinBuffer, const size_t tau,
-                                         const size_t yinBufferSize);
+    YinUtil(int yinBufferSize);
+    ~YinUtil();
+    
+    double sumSquare(const double *in, int startInd, int endInd);
+    void difference(const double *in, double *yinBuffer);
+    void fastDifference(const double *in, double *yinBuffer);
+    void slowDifference(const double *in, double *yinBuffer);
+    void cumulativeDifference(double *yinBuffer);
+    int absoluteThreshold(const double *yinBuffer, double thresh);
+    vector<double> yinProb(const double *yinBuffer, int prior,
+                           int minTau = 0, int maxTau = 0);
+    double parabolicInterpolation(const double *yinBuffer, int tau);
+
+private:
+    const int m_yinBufferSize;
+    Vamp::FFTReal m_fft;
 };
 
 #endif
--- a/YinVamp.cpp	Thu Aug 20 16:06:01 2015 +0100
+++ b/YinVamp.cpp	Fri Mar 24 15:08:12 2017 +0000
@@ -78,7 +78,7 @@
 {
     // Increment this each time you release a version that behaves
     // differently from the previous one
-    return 2;
+    return 3;
 }
 
 string
@@ -192,7 +192,7 @@
 }
 
 void
-YinVamp::selectProgram(string name)
+YinVamp::selectProgram(string)
 {
 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/expected.csv	Fri Mar 24 15:08:12 2017 +0000
@@ -0,0 +1,4703 @@
+1.735691610,252.412
+1.741496599,254.413
+1.747301587,254.643
+1.753106576,253.891
+1.758911565,252.467
+1.764716553,253.517
+1.770521542,255.321
+1.776326531,258.847
+1.782131519,261.6
+1.787936508,263.998
+1.793741497,265.883
+1.799546485,266.994
+1.805351474,268.496
+1.811156463,269.366
+1.816961451,269.456
+1.822766440,268.831
+1.828571429,267.844
+1.834376417,266.514
+1.840181406,265.766
+1.845986395,264.956
+1.851791383,264.37
+1.857596372,264.137
+1.863401361,264.067
+1.869206349,264.323
+1.875011338,264.815
+1.880816327,265.899
+1.886621315,267.214
+1.892426304,268.953
+1.898231293,270.998
+1.904036281,273.541
+1.909841270,276.592
+1.915646259,279.918
+1.921451247,279.824
+1.927256236,278.924
+1.933061224,277.174
+1.938866213,273.883
+1.944671202,273.614
+1.950476190,275.704
+1.956281179,273.461
+1.962086168,276.074
+1.967891156,279.185
+1.973696145,285.13
+1.979501134,294.656
+1.985306122,306.645
+1.991111111,316.506
+1.996916100,326.039
+2.002721088,330.722
+2.008526077,333.649
+2.014331066,333.996
+2.020136054,335.731
+2.025941043,336.094
+2.031746032,336.23
+2.037551020,336.605
+2.043356009,335.974
+2.049160998,335.564
+2.054965986,335.253
+2.060770975,334.882
+2.066575964,334.479
+2.072380952,334.066
+2.078185941,333.512
+2.083990930,332.494
+2.089795918,331.672
+2.095600907,330.832
+2.101405896,329.969
+2.107210884,329.763
+2.113015873,329.382
+2.118820862,329.116
+2.124625850,328.764
+2.130430839,328.211
+2.136235828,327.856
+2.142040816,326.655
+2.147845805,325.664
+2.153650794,325.483
+2.159455782,324.706
+2.165260771,323.721
+2.171065760,322.11
+2.176870748,320.073
+2.182675737,316.313
+2.188480726,309.561
+2.194285714,306.083
+2.200090703,302.779
+2.205895692,299.065
+2.211700680,293.109
+2.217505669,288.801
+2.223310658,285.342
+2.229115646,282.218
+2.234920635,279.632
+2.240725624,273.15
+2.246530612,270.607
+2.252335601,267.999
+2.258140590,267.169
+2.263945578,266.127
+2.269750567,265.006
+2.275555556,264.045
+2.281360544,263.477
+2.287165533,263.399
+2.292970522,264.039
+2.298775510,264.747
+2.304580499,266.112
+2.310385488,267.01
+2.316190476,267.879
+2.321995465,268.449
+2.327800454,268.897
+2.333605442,269.227
+2.339410431,269.819
+2.345215420,270.534
+2.351020408,271.196
+2.356825397,272.272
+2.362630385,273.098
+2.368435374,273.824
+2.374240363,274.034
+2.380045351,273.791
+2.385850340,273.615
+2.391655329,273.698
+2.397460317,274.318
+2.403265306,275.918
+2.409070295,277.01
+2.414875283,278.867
+2.420680272,281.325
+2.426485261,284.908
+2.432290249,288.736
+2.438095238,294.569
+2.443900227,300.31
+2.449705215,308.271
+2.455510204,313.145
+2.461315193,317.372
+2.467120181,319.51
+2.472925170,321.016
+2.478730159,321.798
+2.484535147,322.67
+2.490340136,323.953
+2.496145125,325.347
+2.501950113,327.168
+2.507755102,327.963
+2.513560091,328.192
+2.519365079,328.1
+2.525170068,328.518
+2.530975057,328.809
+2.536780045,328.864
+2.542585034,328.943
+2.548390023,328.999
+2.554195011,328.968
+2.560000000,329.009
+2.565804989,328.974
+2.571609977,328.762
+2.577414966,328.681
+2.583219955,328.638
+2.589024943,329.024
+2.594829932,329.519
+2.600634921,330.155
+2.606439909,330.753
+2.612244898,331.158
+2.618049887,331.53
+2.623854875,331.78
+2.629659864,332.215
+2.635464853,332.58
+2.641269841,332.931
+2.647074830,332.944
+2.652879819,332.511
+2.658684807,331.749
+2.664489796,330.368
+2.670294785,328.701
+2.676099773,327.155
+2.681904762,325.393
+2.687709751,324.184
+2.693514739,324.473
+2.699319728,319.498
+2.705124717,311.588
+2.710929705,308.507
+2.716734694,306.978
+2.722539683,307.059
+2.728344671,312.666
+2.734149660,312.896
+2.739954649,314.627
+2.745759637,317.462
+2.751564626,319.347
+2.757369615,320.583
+2.763174603,323.506
+2.768979592,323.916
+2.774784580,323.069
+2.780589569,321.922
+2.786394558,319.91
+2.792199546,318.262
+2.798004535,317.344
+2.803809524,317.172
+2.809614512,317.983
+2.815419501,321.016
+2.821224490,327.503
+2.827029478,332.737
+2.832834467,335.854
+2.838639456,337.035
+2.844444444,337.862
+2.850249433,338.418
+2.856054422,337.95
+2.861859410,337.362
+2.867664399,336.394
+2.873469388,335.528
+2.879274376,334.456
+2.885079365,332.998
+2.890884354,331.52
+2.896689342,330.019
+2.902494331,329.596
+2.908299320,329.44
+2.914104308,329.863
+2.919909297,330.944
+2.925714286,332.186
+2.931519274,333.656
+2.937324263,335.226
+2.943129252,337.086
+2.948934240,338.915
+2.954739229,340.845
+2.960544218,342.906
+2.966349206,344.962
+2.972154195,347.113
+2.977959184,348.997
+2.983764172,350.634
+2.989569161,352.211
+2.995374150,353.816
+3.001179138,355.631
+3.006984127,357.547
+3.012789116,359.602
+3.018594104,361.518
+3.024399093,363.598
+3.030204082,365.586
+3.036009070,366.756
+3.041814059,367.608
+3.047619048,368.035
+3.053424036,368.299
+3.059229025,368.882
+3.065034014,369.402
+3.070839002,369.876
+3.076643991,370.259
+3.082448980,370.194
+3.088253968,369.853
+3.094058957,369.302
+3.099863946,368.579
+3.105668934,367.936
+3.111473923,367.33
+3.117278912,366.378
+3.123083900,365.526
+3.128888889,365.191
+3.134693878,366.45
+3.140498866,369.807
+3.146303855,377.487
+3.152108844,386.451
+3.157913832,397.468
+3.163718821,402.447
+3.169523810,399.475
+3.175328798,401.39
+5.143219955,202.143
+5.149024943,205.362
+5.154829932,210.774
+5.160634921,215.306
+5.166439909,218.368
+5.172244898,219.412
+5.178049887,218.697
+5.183854875,217.656
+5.189659864,216.04
+5.195464853,214.503
+5.201269841,212.6
+5.207074830,211.436
+5.212879819,210.398
+5.218684807,209.289
+5.224489796,208.006
+5.230294785,206.885
+5.236099773,206.17
+5.241904762,205.84
+5.247709751,205.712
+5.253514739,205.725
+5.259319728,206.428
+5.265124717,207.283
+5.270929705,208.38
+5.276734694,209.693
+5.282539683,211.301
+5.288344671,212.934
+5.294149660,214.319
+5.299954649,215.439
+5.305759637,217.061
+5.311564626,218.937
+5.317369615,222.237
+5.323174603,226.637
+5.328979592,230.071
+5.334784580,231.797
+5.340589569,232.447
+5.346394558,231.522
+5.352199546,230.174
+5.358004535,227.808
+5.363809524,224.731
+5.369614512,221.866
+5.375419501,219.407
+5.381224490,216.981
+5.387029478,214.839
+5.392834467,214.34
+5.398639456,215.229
+5.404444444,214.782
+5.410249433,214.051
+5.416054422,213.675
+5.421859410,213.818
+5.427664399,213.935
+5.433469388,214.431
+5.439274376,215.188
+5.445079365,216.022
+5.450884354,217.593
+5.456689342,219.325
+5.462494331,220.562
+5.468299320,221.697
+5.474104308,222.829
+5.479909297,223.538
+5.485714286,224.115
+5.491519274,224.728
+5.497324263,224.816
+5.503129252,224.773
+5.508934240,224.071
+5.514739229,223.16
+5.520544218,222.296
+5.526349206,221.399
+5.532154195,220.092
+5.537959184,218.97
+5.543764172,217.667
+5.549569161,214.954
+5.694693878,222.566
+5.700498866,223.295
+5.706303855,224.353
+5.712108844,226.091
+5.717913832,228.155
+5.723718821,229.545
+5.729523810,231.235
+5.735328798,233.01
+5.741133787,234.832
+5.746938776,236.291
+5.752743764,237.627
+5.758548753,238.746
+5.764353741,239.764
+5.770158730,240.63
+5.775963719,241.948
+5.781768707,243.459
+5.787573696,245.089
+5.793378685,246.366
+5.799183673,247.748
+5.804988662,248.889
+5.810793651,250.337
+5.816598639,251.867
+5.822403628,253.409
+5.828208617,254.557
+5.834013605,255.193
+5.839818594,255.93
+5.845623583,256.604
+5.851428571,257.607
+5.857233560,258.476
+5.863038549,259.779
+5.868843537,260.82
+5.874648526,262.085
+5.880453515,262.949
+5.886258503,263.863
+5.892063492,264.675
+5.897868481,265.614
+5.903673469,266.902
+5.909478458,267.93
+5.915283447,269.124
+5.921088435,269.714
+5.926893424,270.578
+5.932698413,271.165
+5.938503401,271.799
+5.944308390,272.252
+5.950113379,272.682
+5.955918367,272.911
+5.961723356,273.072
+5.967528345,272.722
+5.973333333,271.489
+5.979138322,269.383
+5.984943311,263.216
+5.990748299,251.7
+5.996553288,243.079
+6.002358277,234.745
+6.008163265,231.227
+6.013968254,229.352
+6.019773243,228.603
+6.025578231,230.117
+6.031383220,237.565
+6.037188209,237.182
+6.124263039,234.826
+6.130068027,234.885
+6.135873016,236.442
+6.141678005,241.44
+6.147482993,244.692
+6.153287982,247.536
+6.159092971,248.844
+6.164897959,249.57
+6.170702948,249.676
+6.176507937,249.736
+6.182312925,249.656
+6.188117914,249.752
+6.193922902,249.799
+6.199727891,249.805
+6.205532880,249.284
+6.211337868,248.866
+6.217142857,248.116
+6.222947846,247.702
+6.228752834,247.113
+6.234557823,246.612
+6.240362812,246.104
+6.246167800,245.326
+6.251972789,244.646
+6.257777778,243.594
+6.263582766,242.971
+6.269387755,242.649
+6.275192744,242.522
+6.280997732,242.644
+6.286802721,242.434
+6.292607710,241.456
+6.298412698,240.913
+6.304217687,239.588
+6.310022676,238.288
+6.315827664,236.98
+6.321632653,235.54
+6.327437642,234.138
+6.333242630,232.196
+6.339047619,229.65
+6.344852608,227
+6.350657596,223.512
+6.356462585,218.03
+6.362267574,211.172
+6.368072562,205.238
+6.373877551,201.304
+6.379682540,198.054
+6.385487528,196.76
+6.391292517,198.036
+6.397097506,200.972
+6.402902494,204.076
+6.408707483,207.163
+6.414512472,209.372
+6.420317460,211.08
+6.426122449,212.414
+6.431927438,213.723
+6.437732426,215.326
+6.443537415,217.995
+6.449342404,220.793
+6.455147392,223.074
+6.460952381,224.639
+6.466757370,225.762
+6.472562358,225.708
+6.478367347,225.028
+6.484172336,223.895
+6.489977324,222.179
+6.495782313,220.644
+6.501587302,219.285
+6.507392290,217.321
+6.513197279,216.002
+6.519002268,214.916
+6.524807256,214.116
+6.530612245,213.061
+6.536417234,212.638
+6.542222222,212.819
+6.548027211,213.363
+6.553832200,214.851
+6.559637188,216.061
+6.565442177,216.835
+6.571247166,217.108
+6.577052154,217.319
+6.582857143,217.771
+6.588662132,219.017
+6.594467120,222.693
+6.600272109,228.017
+6.606077098,232.697
+6.611882086,235.748
+6.617687075,237.614
+6.623492063,238.467
+6.629297052,237.597
+6.635102041,234.525
+6.640907029,231.367
+6.646712018,226.874
+6.652517007,221.2
+6.658321995,216.145
+6.664126984,210.932
+6.669931973,204.813
+6.675736961,200.939
+6.681541950,199.032
+6.687346939,197.011
+6.693151927,195.609
+6.698956916,194.8
+6.704761905,195.354
+6.710566893,198.917
+6.716371882,203.754
+6.722176871,207.771
+6.727981859,211.338
+6.733786848,220.502
+6.739591837,228.854
+6.745396825,237.674
+6.751201814,245.261
+6.757006803,252.686
+6.762811791,251.725
+6.768616780,248.321
+6.774421769,246.093
+6.780226757,242.515
+6.786031746,242.066
+6.791836735,241.562
+7.569705215,250.861
+7.575510204,254.016
+7.581315193,258.191
+7.587120181,261.662
+7.592925170,264.307
+7.598730159,266.468
+7.604535147,267.547
+7.610340136,268.474
+7.616145125,268.854
+7.621950113,269.617
+7.627755102,270.643
+7.633560091,271.303
+7.639365079,271.949
+7.645170068,272.534
+7.650975057,272.62
+7.656780045,272.348
+7.662585034,271.852
+7.668390023,270.978
+7.674195011,270.297
+7.680000000,270.341
+7.685804989,270.518
+7.691609977,271.171
+7.697414966,271.539
+7.703219955,271.501
+7.709024943,271.092
+7.714829932,270.764
+7.720634921,270.518
+7.726439909,270.441
+7.732244898,270.599
+7.738049887,270.857
+7.743854875,271.424
+7.749659864,272.688
+7.755464853,275.037
+7.761269841,278.28
+7.767074830,281.078
+7.772879819,282.272
+7.778684807,283.015
+7.784489796,283.022
+7.790294785,283.089
+7.796099773,284.653
+7.801904762,282.854
+7.807709751,287.781
+7.813514739,296.616
+7.819319728,303.095
+7.825124717,309.875
+7.830929705,317.103
+7.836734694,322.316
+7.842539683,326.311
+7.848344671,328.413
+7.854149660,329.266
+7.859954649,329.872
+7.865759637,330.121
+7.871564626,330.328
+7.877369615,330.591
+7.883174603,330.896
+7.888979592,331.125
+7.894784580,331.482
+7.900589569,331.468
+7.906394558,331.45
+7.912199546,331.547
+7.918004535,332.047
+7.923809524,332.977
+7.929614512,333.724
+7.935419501,334.723
+7.941224490,335.633
+7.947029478,336.756
+7.952834467,338.582
+7.958639456,339.871
+7.964444444,340.723
+7.970249433,340.541
+7.976054422,340.064
+7.981859410,339.208
+7.987664399,337.866
+7.993469388,336.578
+7.999274376,334.602
+8.005079365,332.202
+8.010884354,329.587
+8.016689342,326.897
+8.022494331,324.677
+8.028299320,322.143
+8.034104308,319.595
+8.039909297,316.029
+8.045714286,309.37
+8.051519274,302.282
+8.057324263,296.59
+8.063129252,290.306
+8.068934240,283.999
+8.074739229,279.76
+8.080544218,276.515
+8.086349206,272.788
+8.092154195,271.098
+8.097959184,270.738
+8.103764172,270.544
+8.109569161,270.507
+8.115374150,270.504
+8.121179138,270.583
+8.126984127,270.589
+8.132789116,270.781
+8.138594104,271.018
+8.144399093,271.616
+8.150204082,272.504
+8.156009070,273.5
+8.161814059,274.187
+8.167619048,274.537
+8.173424036,274.435
+8.179229025,274.253
+8.185034014,274.176
+8.190839002,274.353
+8.196643991,275.108
+8.202448980,276.234
+8.208253968,277.9
+8.214058957,279.86
+8.219863946,282.423
+8.225668934,284.334
+8.231473923,285.747
+8.237278912,286.869
+8.243083900,287.279
+8.248888889,286.539
+8.254693878,285.671
+8.260498866,284.914
+8.266303855,285.211
+8.272108844,287.247
+8.277913832,289.24
+8.283718821,291.935
+8.289523810,295.572
+8.295328798,299.241
+8.301133787,303.093
+8.306938776,308.054
+8.312743764,313.279
+8.318548753,317.123
+8.324353741,320.351
+8.330158730,326.33
+8.335963719,329.995
+8.341768707,332.347
+8.347573696,332.869
+8.353378685,332.979
+8.359183673,332.618
+8.364988662,332.159
+8.370793651,331.673
+8.376598639,331.157
+8.382403628,330.66
+8.388208617,329.988
+8.394013605,329.366
+8.399818594,328.828
+8.405623583,328.245
+8.411428571,327.996
+8.417233560,328.018
+8.423038549,328.096
+8.428843537,328.132
+8.434648526,328.294
+8.440453515,328.371
+8.446258503,328.419
+8.452063492,328.766
+8.457868481,329.087
+8.463673469,329.479
+8.469478458,329.75
+8.475283447,329.902
+8.481088435,329.859
+8.486893424,329.643
+8.492698413,329.019
+8.498503401,327.963
+8.504308390,326.356
+8.510113379,324.962
+8.515918367,324.201
+8.521723356,323.334
+8.527528345,323.451
+8.533333333,325.673
+8.539138322,317.944
+8.544943311,312.903
+8.550748299,318.088
+8.556553288,318.482
+8.562358277,318.139
+8.568163265,319.463
+8.573968254,321.886
+8.579773243,325.794
+8.585578231,330.316
+8.591383220,336.202
+8.597188209,340.257
+8.602993197,343.25
+8.608798186,344.985
+8.614603175,346.175
+8.620408163,346.972
+8.626213152,347.497
+8.632018141,347.559
+8.637823129,347.816
+8.643628118,347.576
+8.649433107,347.039
+8.655238095,346.125
+8.661043084,344.55
+8.666848073,342.817
+8.672653061,341.174
+8.678458050,339.401
+8.684263039,337.755
+8.690068027,336.289
+8.695873016,334.476
+8.701678005,332.848
+8.707482993,331.606
+8.713287982,330.77
+8.719092971,330.81
+8.724897959,331.505
+8.730702948,332.896
+8.736507937,334.4
+8.742312925,336.004
+8.748117914,337.629
+8.753922902,339.108
+8.759727891,340.557
+8.765532880,342.076
+8.771337868,343.685
+8.777142857,345.494
+8.782947846,347.207
+8.788752834,349.139
+8.794557823,351.251
+8.800362812,353.188
+8.806167800,355.414
+8.811972789,357.486
+8.817777778,359.524
+8.823582766,361.363
+8.829387755,362.924
+8.835192744,364.538
+8.840997732,365.939
+8.846802721,367.225
+8.852607710,368.424
+8.858412698,369.196
+8.864217687,369.304
+8.870022676,368.813
+8.875827664,367.863
+8.881632653,366.741
+8.887437642,366.193
+8.893242630,365.673
+8.899047619,365.364
+8.904852608,365.468
+8.910657596,365.685
+8.916462585,365.945
+8.922267574,366.384
+8.928072562,366.719
+8.933877551,367.024
+8.939682540,367.517
+8.945487528,368.053
+8.951292517,368.514
+8.957097506,368.904
+8.962902494,369.414
+8.968707483,370.003
+8.974512472,370.52
+8.980317460,371.882
+8.986122449,375.159
+11.969886621,196.411
+11.975691610,201.476
+11.981496599,207.764
+11.987301587,211.601
+11.993106576,221.157
+11.998911565,227.621
+12.004716553,231.139
+12.010521542,236.093
+12.016326531,239.618
+12.022131519,243.172
+12.027936508,246.224
+12.033741497,250.693
+12.039546485,254.743
+12.045351474,257.813
+12.051156463,260.037
+12.056961451,262.646
+12.062766440,264.664
+12.068571429,265.956
+12.074376417,266.182
+12.080181406,265.45
+12.085986395,264.858
+12.091791383,261.142
+12.097596372,257.589
+12.103401361,254.808
+12.109206349,254.232
+12.115011338,253.869
+12.120816327,253.939
+12.126621315,254.987
+12.132426304,256.715
+12.138231293,259.992
+12.144036281,262.717
+12.149841270,265.801
+12.155646259,267.579
+12.161451247,269.907
+12.167256236,271.435
+12.173061224,272.996
+12.178866213,273.951
+12.184671202,274.383
+12.190476190,274.274
+12.196281179,273.75
+12.202086168,272.506
+12.207891156,271.075
+12.213696145,269.501
+12.219501134,268.132
+12.225306122,266.702
+12.231111111,265.043
+12.236916100,263.519
+12.242721088,261.511
+12.248526077,260.019
+12.254331066,257.943
+12.260136054,256.721
+12.265941043,254.259
+12.271746032,252.087
+12.277551020,249.956
+12.283356009,248.329
+12.289160998,246.421
+12.294965986,243.999
+12.300770975,242.183
+12.306575964,241.693
+12.312380952,241.927
+12.318185941,242.228
+12.323990930,242.23
+12.329795918,242.353
+12.335600907,242.329
+12.341405896,242.31
+12.347210884,242.365
+12.353015873,242.069
+12.358820862,241.482
+12.364625850,240.535
+12.370430839,239.205
+12.376235828,237.141
+12.382040816,235.079
+12.387845805,232.978
+12.393650794,229.879
+12.399455782,226.314
+12.405260771,214.97
+12.411065760,202.445
+12.416870748,195.292
+12.422675737,189.787
+12.428480726,184.249
+12.434285714,179.32
+12.440090703,174.054
+12.445895692,168.981
+12.451700680,166.002
+12.457505669,166.395
+12.463310658,170.21
+12.469115646,170.209
+12.474920635,180.358
+12.480725624,190.407
+12.486530612,200.494
+12.492335601,205.165
+12.498140590,207.949
+12.503945578,210.557
+12.509750567,212.927
+12.515555556,215.706
+12.521360544,218.286
+12.527165533,220.398
+12.532970522,222.736
+12.538775510,224.111
+12.544580499,224.668
+12.550385488,224.525
+12.556190476,223.879
+12.561995465,222.914
+12.567800454,221.644
+12.573605442,219.726
+12.579410431,217.847
+12.585215420,216.395
+12.591020408,215.418
+12.596825397,215.148
+12.602630385,215.533
+12.608435374,216.481
+12.614240363,217.766
+12.620045351,218.729
+12.625850340,219.096
+12.631655329,219.235
+12.637460317,219.263
+12.643265306,219.565
+12.649070295,220.14
+12.654875283,221.013
+12.660680272,222.229
+12.666485261,223.708
+12.672290249,224.766
+12.678095238,225.555
+12.683900227,226.014
+12.689705215,225.844
+12.695510204,225.62
+12.701315193,225.143
+12.707120181,224.411
+12.712925170,223.479
+12.718730159,222.085
+12.724535147,220.611
+12.730340136,218.913
+12.736145125,216.956
+12.741950113,214.973
+12.747755102,213.542
+12.753560091,212.614
+12.759365079,211.898
+12.765170068,211.769
+12.770975057,211.71
+12.776780045,211.948
+12.782585034,212.717
+12.788390023,213.719
+12.794195011,215.123
+12.800000000,217.024
+12.805804989,219.267
+12.811609977,221.444
+12.817414966,223.473
+12.823219955,226.532
+12.829024943,230.164
+12.834829932,234.128
+12.840634921,236.565
+12.846439909,238.241
+12.852244898,241.686
+12.858049887,245.456
+12.863854875,251.305
+12.869659864,262.552
+12.875464853,260.546
+12.968344671,233.337
+12.974149660,233.719
+12.979954649,237.725
+12.985759637,239.12
+12.991564626,240.028
+12.997369615,240.521
+13.003174603,240.724
+13.008979592,241.882
+13.014784580,242.997
+13.020589569,244.522
+13.026394558,245.308
+13.032199546,246.034
+13.038004535,246.021
+13.043809524,245.774
+13.049614512,245.08
+13.055419501,244.274
+13.061224490,243.183
+13.067029478,241.842
+13.072834467,239.693
+13.078639456,238.169
+13.084444444,237.219
+13.090249433,236.741
+13.096054422,236.855
+13.101859410,237.125
+13.107664399,237.988
+13.113469388,239.33
+13.119274376,241.211
+13.125079365,242.33
+13.130884354,243.092
+13.136689342,243.8
+13.142494331,244.154
+13.148299320,245.263
+13.154104308,246.245
+13.159909297,247.043
+13.165714286,247.452
+13.171519274,247.284
+13.177324263,246.741
+13.183129252,245.988
+13.188934240,244.904
+13.194739229,244.416
+13.200544218,246.369
+13.206349206,250.097
+13.212154195,249.526
+13.217959184,248.575
+13.223764172,247.593
+13.229569161,246.235
+13.235374150,244.189
+13.241179138,238.178
+13.246984127,232.186
+13.252789116,242.491
+13.258594104,251.249
+13.264399093,249.905
+13.270204082,246.208
+13.276009070,243.11
+13.281814059,240.52
+13.287619048,240.432
+13.293424036,242.667
+13.450158730,241.225
+13.455963719,242.859
+13.461768707,243.284
+13.467573696,243.175
+13.473378685,243.077
+13.479183673,242.212
+13.484988662,241.31
+13.490793651,240.315
+13.496598639,239.675
+13.502403628,239.391
+13.508208617,239.318
+13.514013605,239.687
+13.519818594,240.425
+13.525623583,241.416
+13.531428571,242.663
+13.537233560,244.061
+13.543038549,245.619
+13.548843537,247.223
+13.554648526,248.748
+13.560453515,250.4
+13.566258503,252.231
+13.572063492,254.057
+13.577868481,256.673
+13.583673469,258.823
+13.589478458,261.237
+13.595283447,263.221
+13.601088435,265.579
+13.606893424,267.413
+13.612698413,269.168
+13.618503401,270.622
+13.624308390,272.05
+13.630113379,273.205
+13.635918367,274.3
+13.641723356,275.268
+13.647528345,276.213
+13.653333333,277.209
+13.659138322,278.343
+13.664943311,279.266
+13.670748299,279.869
+13.676553288,279.523
+13.682358277,278.75
+13.688163265,277.885
+13.693968254,276.336
+13.699773243,273.44
+13.705578231,269.69
+13.711383220,271.398
+13.717188209,275.118
+13.722993197,284.376
+13.728798186,291.995
+13.734603175,302.687
+13.740408163,307.035
+13.746213152,316.631
+13.752018141,319.901
+13.757823129,321.695
+13.763628118,322.89
+13.769433107,324.568
+13.775238095,326.529
+13.781043084,328.277
+13.786848073,329.809
+13.792653061,330.957
+13.798458050,331.672
+13.804263039,332.016
+13.810068027,331.657
+13.815873016,331.098
+13.821678005,330.085
+13.827482993,329.11
+13.833287982,328.127
+13.839092971,327.081
+13.844897959,326.007
+13.850702948,324.519
+13.856507937,322.595
+13.862312925,320.425
+13.868117914,318.86
+13.873922902,317.462
+13.879727891,317.306
+13.885532880,316.658
+13.891337868,311.313
+13.897142857,307.251
+13.902947846,300.286
+13.908752834,289.28
+13.914557823,279.113
+13.920362812,269.891
+13.926167800,265.108
+13.931972789,257.329
+13.937777778,253.346
+13.943582766,246.724
+13.949387755,243.275
+13.955192744,240.569
+13.960997732,239.939
+13.966802721,240.126
+13.972607710,241.211
+13.978412698,242.612
+13.984217687,244.86
+13.990022676,246.79
+13.995827664,248.185
+14.001632653,249.239
+14.007437642,249.826
+14.013242630,249.979
+14.019047619,249.967
+14.024852608,249.664
+14.030657596,249.561
+14.036462585,249.917
+14.042267574,250.438
+14.048072562,251.179
+14.053877551,252.033
+14.059682540,253.194
+14.065487528,254.943
+14.071292517,256.383
+14.077097506,258.036
+14.082902494,259.073
+14.088707483,260.243
+14.094512472,260.723
+14.100317460,261.394
+14.106122449,262.268
+14.111927438,263.609
+14.117732426,265.108
+14.123537415,266.393
+14.129342404,267.805
+14.135147392,268.742
+14.140952381,269.842
+14.146757370,270.47
+14.152562358,271.235
+14.158367347,272.311
+14.164172336,273.675
+14.169977324,275.082
+14.175782313,276.161
+14.181587302,276.835
+14.187392290,277.111
+14.193197279,277.58
+14.199002268,277.558
+14.204807256,277.276
+14.210612245,276.697
+14.216417234,276.698
+14.222222222,277.044
+14.228027211,277.277
+14.233832200,277.222
+14.239637188,278.6
+14.245442177,275.327
+14.251247166,273.674
+14.257052154,273.212
+14.262857143,273.197
+14.268662132,273.384
+14.274467120,273.117
+14.280272109,272.75
+14.286077098,271.621
+14.291882086,270.138
+14.297687075,267.159
+14.303492063,263.767
+14.309297052,259.146
+14.315102041,256.448
+14.320907029,252.089
+14.326712018,248.629
+14.332517007,243.788
+14.338321995,239.303
+14.344126984,235.543
+14.349931973,231.974
+14.355736961,228.119
+14.361541950,224.362
+14.367346939,221.104
+14.373151927,217.696
+14.378956916,215.656
+14.384761905,214.218
+14.390566893,212.975
+14.396371882,211.293
+14.402176871,210.139
+14.407981859,209.402
+14.413786848,208.941
+14.419591837,208.57
+14.425396825,208.491
+14.431201814,208.602
+14.437006803,209.011
+14.442811791,209.678
+14.448616780,210.803
+14.454421769,211.654
+14.460226757,212.243
+14.466031746,212.547
+14.471836735,212.73
+14.477641723,214.237
+14.483446712,217.111
+14.489251701,223.308
+14.495056689,225.831
+14.500861678,225.528
+14.506666667,226.504
+14.512471655,226.693
+14.518276644,226.641
+14.524081633,227.069
+14.529886621,227.128
+14.535691610,227.917
+14.541496599,229.054
+14.547301587,230.191
+14.553106576,230.779
+14.558911565,231.039
+14.564716553,230.501
+14.570521542,228.629
+14.576326531,225.763
+14.582131519,223.952
+14.587936508,222.137
+14.593741497,220.583
+14.599546485,219.182
+14.605351474,218.024
+14.611156463,216.485
+14.616961451,214.979
+14.622766440,214.357
+14.628571429,213.388
+14.634376417,212.458
+14.640181406,212.246
+14.645986395,208.59
+14.959455782,202.925
+14.965260771,211.076
+14.971065760,220.319
+14.976870748,229.585
+14.982675737,237.825
+14.988480726,247.362
+14.994285714,255.221
+15.000090703,263.223
+15.005895692,267.966
+15.011700680,270.802
+15.017505669,272.694
+15.023310658,273.602
+15.029115646,274.2
+15.034920635,274.548
+15.040725624,274.91
+15.046530612,274.66
+15.052335601,274.175
+15.058140590,272.819
+15.063945578,271.498
+15.069750567,270.361
+15.075555556,269.915
+15.081360544,269.193
+15.087165533,269.202
+15.092970522,269.367
+15.098775510,269.899
+15.104580499,270.559
+15.110385488,271.533
+15.116190476,272.319
+15.121995465,273.042
+15.127800454,273.344
+15.133605442,273.038
+15.139410431,272.004
+15.145215420,270.536
+15.151020408,268.814
+15.156825397,268.1
+15.162630385,267.799
+15.168435374,268.454
+15.174240363,269.561
+15.180045351,270.695
+15.185850340,271.685
+15.191655329,271.867
+15.197460317,271.656
+15.203265306,270.121
+15.209070295,268.713
+15.214875283,266.915
+15.220680272,265.683
+15.226485261,265.023
+15.232290249,264.992
+15.238095238,266.235
+15.243900227,267.39
+15.249705215,268.087
+15.255510204,268.698
+15.261315193,269.24
+15.267120181,269.329
+15.272925170,269.726
+15.278730159,270.204
+15.284535147,269.832
+15.290340136,269.241
+15.296145125,264.217
+15.307755102,237.723
+15.313560091,234.773
+15.319365079,231.427
+15.325170068,229.846
+15.330975057,229.45
+15.336780045,229.019
+15.342585034,226.918
+15.348390023,226.163
+15.354195011,225.638
+15.360000000,225.456
+15.365804989,224.763
+15.371609977,226.19
+15.377414966,230.329
+15.383219955,235.093
+15.389024943,243.553
+15.394829932,255.951
+15.400634921,262.582
+15.429659864,334.745
+15.435464853,335.576
+15.441269841,336.306
+15.447074830,336.891
+15.452879819,337.115
+15.458684807,336.745
+15.464489796,335.69
+15.470294785,333.946
+15.476099773,332.294
+15.481904762,331.242
+15.487709751,330.352
+15.493514739,329.921
+15.499319728,329.765
+15.505124717,329.42
+15.510929705,329.324
+15.516734694,329.63
+15.522539683,330.409
+15.528344671,331.455
+15.534149660,332.462
+15.539954649,332.974
+15.545759637,332.84
+15.551564626,332.251
+15.557369615,331.096
+15.563174603,329.846
+15.568979592,328.971
+15.574784580,328.607
+15.580589569,329.005
+15.586394558,329.761
+15.592199546,330.559
+15.598004535,331.087
+15.603809524,331.405
+15.609614512,331.403
+15.615419501,331.474
+15.621224490,331.6
+15.627029478,331.902
+15.632834467,332.451
+15.638639456,332.8
+15.644444444,333.074
+15.650249433,333.503
+15.656054422,334.142
+15.661859410,335.15
+15.667664399,336.648
+15.673469388,338.157
+15.679274376,339.665
+15.685079365,340.692
+15.690884354,341.118
+15.696689342,340.965
+15.702494331,340.948
+15.708299320,340.89
+15.714104308,341.04
+15.719909297,341.406
+15.725714286,341.404
+15.731519274,341.101
+15.737324263,340.374
+15.743129252,338.743
+15.748934240,337.001
+15.754739229,333.759
+15.760544218,325.376
+15.917278912,252.975
+15.923083900,255.979
+15.928888889,260.149
+15.934693878,262.085
+15.940498866,263.984
+15.946303855,265.803
+15.952108844,268.322
+15.957913832,270.297
+15.963718821,272.698
+15.969523810,274.195
+15.975328798,275.407
+15.981133787,276.164
+15.986938776,276.524
+15.992743764,276.462
+15.998548753,276.069
+16.004353741,275.366
+16.010158730,274.348
+16.015963719,273.251
+16.021768707,272.08
+16.027573696,271.539
+16.033378685,271.417
+16.039183673,272.354
+16.044988662,273.376
+16.050793651,275.013
+16.056598639,275.883
+16.062403628,276.202
+16.068208617,276.208
+16.074013605,276.077
+16.079818594,275.9
+16.085623583,276.092
+16.091428571,276.363
+16.097233560,276.232
+16.103038549,276.263
+16.108843537,273.766
+16.184308390,324.582
+16.190113379,329.411
+16.195918367,332.724
+16.201723356,333.18
+16.207528345,333.497
+16.213333333,333.788
+16.219138322,333.682
+16.224943311,333.263
+16.230748299,333.892
+16.236553288,336.271
+16.242358277,337.042
+16.248163265,336.306
+16.253968254,334.776
+16.259773243,331.936
+16.265578231,329.565
+16.271383220,328.149
+16.277188209,326.626
+16.282993197,325.589
+16.288798186,324.721
+16.294603175,324.274
+16.300408163,324.278
+16.306213152,324.837
+16.312018141,325.953
+16.317823129,326.956
+16.323628118,327.751
+16.329433107,328.141
+16.335238095,328.529
+16.341043084,329.002
+16.346848073,328.824
+16.352653061,329.149
+16.358458050,329.478
+16.364263039,329.681
+16.370068027,330.246
+16.375873016,330.711
+16.381678005,331.297
+16.387482993,331.978
+16.393287982,332.301
+16.399092971,331.477
+16.404897959,329.778
+16.410702948,328.368
+16.416507937,325.793
+16.422312925,323.049
+16.428117914,326.116
+16.474557823,345.818
+16.480362812,344.102
+16.486167800,341.795
+16.491972789,340.258
+16.497777778,338.802
+16.503582766,337.663
+16.509387755,336.43
+16.515192744,334.724
+16.520997732,333.287
+16.526802721,331.789
+16.532607710,330.131
+16.538412698,328.482
+16.544217687,327.195
+16.550022676,326.163
+16.555827664,325.523
+16.561632653,325.33
+16.567437642,325.375
+16.573242630,325.979
+16.579047619,327
+16.584852608,328.34
+16.590657596,330.243
+16.596462585,332.489
+16.602267574,335.082
+16.608072562,337.569
+16.613877551,340.165
+16.619682540,342.52
+16.625487528,345.218
+16.631292517,348.313
+16.637097506,351.574
+16.642902494,354.845
+16.648707483,357.652
+16.654512472,359.781
+16.660317460,361.393
+16.666122449,362.701
+16.671927438,363.744
+16.677732426,364.594
+16.683537415,365.03
+16.689342404,365.237
+16.695147392,365.194
+16.700952381,365.119
+16.706757370,365.066
+16.712562358,365.434
+16.718367347,365.788
+16.724172336,366.21
+16.729977324,366.696
+16.735782313,366.846
+16.741587302,367.573
+16.747392290,368.325
+16.753197279,370.594
+16.759002268,372.853
+16.764807256,374.458
+16.770612245,376.885
+16.776417234,376.816
+16.782222222,378.934
+19.394467120,81.7962
+19.400272109,81.7749
+19.406077098,82.2093
+19.411882086,82.6523
+19.417687075,83.0027
+19.423492063,82.223
+19.429297052,81.675
+19.435102041,81.4251
+19.440907029,81.759
+19.446712018,82.7227
+19.452517007,82.7592
+19.458321995,82.1042
+19.464126984,81.7673
+19.469931973,81.7316
+19.475736961,81.8553
+19.481541950,82.4663
+19.487346939,82.4558
+19.493151927,82.1734
+19.498956916,82.162
+19.504761905,82.0019
+19.510566893,81.9863
+19.516371882,81.9336
+19.522176871,81.9979
+19.527981859,81.8249
+19.533786848,81.8208
+19.539591837,80.5881
+19.545396825,80.6947
+19.551201814,81.3244
+19.795011338,175.889
+19.800816327,181.724
+19.806621315,186.333
+19.812426304,191.63
+19.818231293,196.636
+19.824036281,200.567
+19.829841270,203.655
+19.835646259,206.606
+19.841451247,209.013
+19.847256236,210.899
+19.853061224,212.412
+19.858866213,213.501
+19.864671202,214.412
+19.870476190,215.502
+19.876281179,216.403
+19.882086168,217.241
+19.887891156,217.844
+19.893696145,218.335
+19.899501134,218.68
+19.905306122,219.114
+19.911111111,219.641
+19.916916100,220.658
+19.922721088,221.386
+19.928526077,221.785
+19.934331066,222.109
+19.940136054,222.132
+19.945941043,222.059
+19.951746032,221.864
+19.957551020,221.225
+19.963356009,220.132
+19.969160998,217.889
+19.974965986,211.719
+20.114285714,211.79
+20.120090703,211.987
+20.125895692,212.486
+20.131700680,213.162
+20.137505669,214.835
+20.143310658,216.577
+20.149115646,218.05
+20.154920635,219.362
+20.160725624,220.896
+20.166530612,221.962
+20.172335601,222.577
+20.178140590,222.406
+20.183945578,221.631
+20.189750567,220.738
+20.195555556,219.751
+20.201360544,218.793
+20.207165533,218.368
+20.212970522,218.088
+20.218775510,218.477
+20.224580499,219.055
+20.230385488,220.244
+20.236190476,222.031
+20.241995465,224.367
+20.247800454,227.487
+20.253605442,230.594
+20.259410431,234.267
+20.265215420,239.137
+20.271020408,249.807
+20.276825397,260.532
+20.282630385,274.172
+20.288435374,286.064
+20.294240363,299.879
+20.300045351,312.259
+20.305850340,322.128
+20.311655329,333.035
+20.317460317,341.132
+20.323265306,346.968
+20.329070295,354.149
+20.334875283,356.925
+20.340680272,359.415
+20.346485261,361.22
+20.352290249,363.437
+20.358095238,365.637
+20.363900227,367.58
+20.369705215,368.194
+20.375510204,368.256
+20.381315193,367.46
+20.387120181,366.163
+20.392925170,365.721
+20.398730159,365.324
+20.404535147,364.918
+20.410340136,364.49
+20.416145125,364.22
+20.421950113,364.04
+20.427755102,364.121
+20.433560091,364.075
+20.439365079,364.303
+20.445170068,364.233
+20.450975057,364.214
+20.456780045,364.201
+20.462585034,363.897
+20.468390023,363.657
+20.474195011,363.399
+20.480000000,363.61
+20.485804989,364.081
+20.491609977,364.989
+20.497414966,366.079
+20.503219955,367.193
+20.509024943,368.117
+20.514829932,368.339
+20.520634921,368.05
+20.526439909,367.72
+20.532244898,367.638
+20.538049887,367.742
+20.543854875,367.953
+20.549659864,368.172
+20.555464853,368.189
+20.561269841,368.119
+20.567074830,367.933
+20.572879819,367.692
+20.578684807,367.499
+20.584489796,367.278
+20.590294785,367.048
+20.596099773,366.573
+20.601904762,365.902
+20.607709751,363.806
+20.613514739,358.16
+20.619319728,348.504
+20.625124717,335.721
+20.630929705,337.896
+20.636734694,345.119
+20.642539683,344.443
+20.648344671,347.687
+20.776054422,386.501
+20.781859410,382.926
+20.787664399,385.267
+20.793469388,382.285
+20.799274376,378.723
+20.805079365,376.669
+20.810884354,374.196
+20.816689342,372.199
+20.822494331,371.684
+20.828299320,372.948
+20.834104308,375.184
+20.839909297,376.308
+20.845714286,376.665
+20.851519274,376.008
+20.857324263,373.225
+20.863129252,370.849
+20.868934240,370.297
+20.874739229,370.51
+20.880544218,370.707
+20.886349206,370.461
+20.892154195,370.177
+20.897959184,369.53
+20.903764172,368.422
+20.909569161,367.416
+20.915374150,366.387
+20.921179138,365.472
+20.926984127,365.368
+20.932789116,365.525
+20.938594104,365.59
+20.944399093,365.543
+20.950204082,365.042
+20.956009070,364.328
+20.961814059,363.849
+20.967619048,363.149
+20.973424036,362.793
+20.979229025,362.518
+20.985034014,362.07
+20.990839002,361.869
+20.996643991,361.264
+21.002448980,360.832
+21.008253968,361.087
+21.014058957,362.131
+21.019863946,363.619
+21.025668934,365.433
+21.031473923,366.76
+21.037278912,367.197
+21.043083900,367.625
+21.048888889,367.806
+21.054693878,368.551
+21.060498866,370.171
+21.066303855,371.03
+21.072108844,371.204
+21.077913832,370.034
+21.083718821,364.906
+21.281088435,282.424
+21.286893424,286.808
+21.292698413,293.033
+21.298503401,295.685
+21.304308390,295.739
+21.310113379,295.262
+21.315918367,294.21
+21.321723356,292.762
+21.327528345,291.952
+21.333333333,291.464
+21.339138322,291.208
+21.344943311,291.34
+21.350748299,291.135
+21.356553288,290.852
+21.362358277,290.479
+21.368163265,289.78
+21.373968254,288.896
+21.379773243,288.037
+21.385578231,287.421
+21.391383220,287.204
+21.397188209,287.496
+21.402993197,288.061
+21.408798186,289.034
+21.414603175,290.296
+21.420408163,291.256
+21.426213152,292.384
+21.432018141,293.047
+21.437823129,293.395
+21.443628118,293.73
+21.449433107,293.876
+21.455238095,294.091
+21.461043084,294.479
+21.466848073,294.885
+21.472653061,295.106
+21.478458050,295.313
+21.484263039,295.381
+21.490068027,295.217
+21.495873016,295.052
+21.501678005,294.358
+21.507482993,293.341
+21.513287982,292.222
+21.519092971,291.326
+21.524897959,290.004
+21.530702948,288.725
+21.536507937,289.641
+21.542312925,283
+21.548117914,277.931
+21.553922902,279.158
+21.559727891,284.425
+21.565532880,291.009
+21.571337868,295.385
+21.577142857,302.913
+21.582947846,316.64
+21.588752834,324.049
+21.594557823,327.304
+21.600362812,330.633
+21.606167800,333.864
+21.611972789,337.15
+21.617777778,339.401
+21.623582766,340.619
+21.629387755,341.251
+21.635192744,341.392
+21.640997732,341.45
+21.646802721,341.72
+21.652607710,341.788
+21.658412698,341.477
+21.664217687,340.681
+21.670022676,339.749
+21.675827664,338.695
+21.681632653,337.826
+21.687437642,336.423
+21.693242630,334.661
+21.699047619,332.101
+21.704852608,327.872
+21.710657596,324.636
+21.716462585,319.413
+21.722267574,314.63
+21.728072562,309.794
+21.733877551,306.119
+21.739682540,302.626
+21.745487528,300.193
+21.751292517,299.887
+21.757097506,300.574
+21.762902494,302.928
+21.768707483,306.149
+21.774512472,308.753
+21.780317460,311.998
+21.786122449,315.349
+21.791927438,319.466
+21.797732426,325.084
+21.803537415,328.685
+21.809342404,331.115
+21.815147392,332.64
+21.820952381,334.454
+21.826757370,336.068
+21.832562358,337.042
+21.838367347,337.709
+21.844172336,338.146
+21.849977324,339.108
+21.855782313,340.322
+21.861587302,342.702
+21.867392290,345.498
+21.873197279,348.562
+21.879002268,351.427
+21.884807256,353.431
+21.890612245,355.362
+21.896417234,356.818
+21.902222222,358.679
+21.908027211,360.373
+21.913832200,362.309
+21.919637188,363.882
+21.925442177,364.673
+21.931247166,365.064
+21.937052154,365.136
+21.942857143,365.367
+21.948662132,366.387
+21.954467120,368.008
+21.960272109,369.755
+21.966077098,370.878
+21.971882086,370.831
+21.977687075,369.441
+21.983492063,366.436
+21.989297052,361.358
+21.995102041,355.12
+22.000907029,349.264
+22.006712018,341.67
+22.012517007,331.527
+22.018321995,323.7
+22.024126984,315.769
+22.029931973,309.563
+22.035736961,304.076
+22.041541950,301.596
+22.047346939,301.492
+22.053151927,302.523
+22.058956916,305.387
+22.064761905,309.655
+22.070566893,315.598
+22.076371882,321.364
+22.082176871,329.027
+22.087981859,337.008
+22.093786848,343.715
+22.099591837,348.799
+22.105396825,352.647
+22.111201814,355.78
+22.117006803,358.234
+22.122811791,360.243
+22.128616780,361.781
+22.134421769,362.959
+22.140226757,363.782
+22.146031746,364.22
+22.151836735,364.386
+22.157641723,364.151
+22.163446712,363.244
+22.169251701,361.567
+22.175056689,359.338
+22.180861678,356.451
+22.186666667,353.458
+22.192471655,350.194
+22.198276644,346.817
+22.204081633,343.493
+22.209886621,340.241
+22.215691610,336.706
+22.221496599,333.117
+22.227301587,329.98
+22.233106576,327.848
+22.238911565,326.421
+22.244716553,325.559
+22.250521542,325.78
+22.256326531,326.233
+22.262131519,326.946
+22.267936508,327.763
+22.273741497,328.771
+22.279546485,330.335
+22.285351474,332.105
+22.291156463,334.147
+22.296961451,335.861
+22.302766440,337.417
+22.308571429,338.669
+22.314376417,339.18
+22.320181406,339.174
+22.325986395,338.525
+22.331791383,337.031
+22.337596372,334.731
+22.343401361,331.888
+22.349206349,329.218
+22.355011338,326.931
+22.360816327,325.447
+22.366621315,324.872
+22.372426304,324.281
+22.378231293,323.595
+22.384036281,322.323
+22.389841270,319.485
+22.395646259,316.384
+22.401451247,314
+22.407256236,310.352
+22.413061224,306.285
+22.418866213,306.173
+22.778775510,232.67
+22.784580499,243.853
+22.790385488,256.849
+22.796190476,267.221
+22.801995465,272.096
+22.807800454,276.426
+22.813605442,280.008
+22.819410431,282.336
+22.825215420,285.052
+22.831020408,286.988
+22.836825397,287.574
+22.842630385,286.904
+22.848435374,285.847
+22.854240363,283.842
+22.860045351,281.315
+22.865850340,278.563
+22.871655329,276.194
+22.877460317,274.736
+22.883265306,273.824
+22.889070295,273.762
+22.894875283,273.803
+22.900680272,274.094
+22.906485261,274.335
+22.912290249,275.104
+22.918095238,275.872
+22.923900227,276.688
+22.929705215,277.356
+22.935510204,277.896
+22.941315193,278.71
+22.947120181,279.197
+22.952925170,279.561
+22.958730159,279.463
+22.964535147,278.837
+22.970340136,277.81
+22.976145125,276.659
+22.981950113,274.53
+22.987755102,271.813
+22.993560091,270.653
+22.999365079,269.23
+23.005170068,268.249
+23.010975057,267.04
+23.016780045,265.905
+23.022585034,264.85
+23.028390023,264.235
+23.034195011,264.137
+23.040000000,264.905
+23.045804989,265.829
+23.051609977,266.533
+23.057414966,266.749
+23.063219955,267.806
+23.069024943,268.89
+23.074829932,269.998
+23.080634921,271.185
+23.086439909,272.32
+23.092244898,272.067
+23.098049887,270.819
+23.103854875,267.8
+23.109659864,264.46
+23.115464853,262.715
+23.121269841,261.098
+23.127074830,255.885
+23.132879819,249.346
+23.138684807,243.572
+23.144489796,236.482
+23.260589569,275.143
+23.266394558,278.761
+23.272199546,288.182
+23.278004535,296.866
+23.283809524,301.338
+23.289614512,303.661
+23.295419501,308.023
+23.301224490,317.787
+23.307029478,328.815
+23.312834467,333.651
+23.318639456,336.699
+23.324444444,339.149
+23.330249433,341.558
+23.336054422,343.332
+23.341859410,344.633
+23.347664399,345.106
+23.353469388,344.751
+23.359274376,343.764
+23.365079365,342.344
+23.370884354,341.429
+23.376689342,340.769
+23.382494331,340.488
+23.388299320,340.12
+23.394104308,339.771
+23.399909297,339.239
+23.405714286,338.725
+23.411519274,338.365
+23.417324263,337.795
+23.423129252,337.165
+23.428934240,336.534
+23.434739229,335.505
+23.440544218,334.643
+23.446349206,333.823
+23.452154195,333.278
+23.457959184,333.368
+23.463764172,333.735
+23.469569161,334.183
+23.475374150,334.778
+23.481179138,334.891
+23.486984127,334.949
+23.492789116,334.692
+23.498594104,334.226
+23.504399093,333.556
+23.510204082,332.405
+23.516009070,331.408
+23.521814059,330.366
+23.527619048,329.957
+23.533424036,329.85
+23.539229025,330.18
+23.545034014,330.365
+23.550839002,330.487
+23.556643991,330.418
+23.562448980,330.098
+23.568253968,329.74
+23.574058957,329.407
+23.579863946,329.306
+23.585668934,329.332
+23.591473923,329.756
+23.597278912,329.862
+23.603083900,330.361
+23.608888889,330.961
+23.614693878,331.381
+23.620498866,332.093
+23.626303855,332.288
+23.632108844,332.055
+23.637913832,331.449
+23.643718821,330.795
+23.649523810,329.804
+23.655328798,329.38
+23.661133787,328.947
+23.666938776,328.57
+23.672743764,328.261
+23.678548753,326.727
+23.684353741,324.722
+23.690158730,322.532
+23.695963719,319.268
+23.701768707,315.793
+23.707573696,315.241
+23.713378685,313.855
+23.719183673,300.88
+23.724988662,287.878
+23.730793651,281.151
+23.736598639,278.967
+23.742403628,276.812
+23.748208617,276.038
+23.754013605,275.002
+23.759818594,274.174
+23.765623583,273.488
+23.771428571,272.75
+23.777233560,272.277
+23.783038549,271.975
+23.788843537,271.7
+23.794648526,271.424
+23.800453515,271.316
+23.806258503,271.204
+23.812063492,271.08
+23.817868481,271.143
+23.823673469,271.162
+23.829478458,271.142
+23.835283447,271.465
+23.841088435,271.781
+23.846893424,271.817
+23.852698413,271.223
+23.858503401,269.163
+23.864308390,266.764
+23.870113379,265.276
+23.875918367,264.214
+23.881723356,263.538
+23.887528345,261.816
+23.893333333,260.357
+24.026848073,305.96
+24.032653061,306.329
+24.038458050,310.138
+24.044263039,313.398
+24.050068027,322.231
+24.055873016,327.069
+24.061678005,327.956
+24.067482993,328.096
+24.073287982,327.602
+24.079092971,325.947
+24.084897959,325.879
+24.090702948,325.825
+24.096507937,325.975
+24.102312925,325.678
+24.108117914,325.375
+24.113922902,325.171
+24.119727891,324.944
+24.125532880,325.238
+24.131337868,325.65
+24.137142857,326.366
+24.142947846,327.512
+24.148752834,328.696
+24.154557823,329.97
+24.160362812,331.25
+24.166167800,332.388
+24.171972789,333.089
+24.177777778,333.557
+24.183582766,333.769
+24.189387755,333.749
+24.195192744,333.618
+24.200997732,333.448
+24.206802721,333.561
+24.212607710,333.499
+24.218412698,333.56
+24.224217687,333.672
+24.230022676,333.237
+24.235827664,332.446
+24.241632653,331.086
+24.247437642,329.56
+24.253242630,328.431
+24.259047619,327.894
+24.264852608,327.765
+24.270657596,327.756
+24.276462585,327.97
+24.282267574,328.486
+24.288072562,328.854
+24.293877551,329.346
+24.299682540,330.002
+24.305487528,330.51
+24.311292517,331.506
+24.317097506,332.242
+24.322902494,333.014
+24.328707483,333.635
+24.334512472,334.36
+24.340317460,334.911
+24.346122449,334.758
+24.351927438,333.657
+24.497052154,335.302
+24.502857143,340.811
+24.508662132,341.814
+24.514467120,341.494
+24.520272109,340.418
+24.526077098,338.63
+24.531882086,336.918
+24.537687075,336.49
+24.543492063,337.545
+24.549297052,339.141
+24.555102041,341.432
+24.560907029,343.433
+24.566712018,344.335
+24.572517007,344.797
+24.578321995,344.318
+24.584126984,343.874
+24.589931973,344.663
+24.595736961,346.187
+24.601541950,348.065
+24.607346939,350.364
+24.613151927,353.298
+24.618956916,355.913
+24.624761905,358.882
+24.630566893,361.445
+24.636371882,364.38
+24.642176871,367.619
+24.647981859,370.623
+24.653786848,373.308
+24.659591837,374.922
+24.665396825,375.376
+24.671201814,374.81
+24.677006803,373.333
+24.682811791,371.891
+24.688616780,371.301
+24.694421769,371.781
+24.700226757,372.466
+24.706031746,373.204
+24.711836735,373.791
+24.717641723,373.804
+24.723446712,373.686
+24.729251701,373.308
+24.735056689,372.889
+24.740861678,372.899
+24.746666667,374.637
+24.752471655,375.712
+24.758276644,376.33
+24.764081633,377.095
+24.769886621,374.279
+24.775691610,373.251
+24.781496599,372.224
+24.787301587,368.601
+28.189024943,194.139
+28.194829932,199.512
+28.200634921,204.62
+28.206439909,207.386
+28.212244898,210.65
+28.218049887,213.713
+28.223854875,218.687
+28.229659864,221.574
+28.235464853,223.454
+28.241269841,224.653
+28.247074830,225.423
+28.252879819,225.492
+28.258684807,225.365
+28.264489796,224.932
+28.270294785,224.176
+28.276099773,223.266
+28.281904762,221.997
+28.287709751,221.026
+28.293514739,220.661
+28.299319728,220.758
+28.305124717,220.969
+28.310929705,221.062
+28.316734694,220.878
+28.322539683,220.325
+28.328344671,219.79
+28.334149660,219.18
+28.339954649,218.666
+28.345759637,217.819
+28.351564626,217.267
+28.357369615,216.861
+28.363174603,216.811
+28.368979592,216.878
+28.374784580,217.131
+28.380589569,217.403
+28.386394558,217.47
+28.392199546,217.582
+28.398004535,217.583
+28.403809524,217.46
+28.409614512,217.439
+28.415419501,217.354
+28.421224490,217.125
+28.427029478,216.476
+28.432834467,208.5
+28.438639456,203.124
+28.444444444,207.906
+28.612789116,174.999
+28.618594104,174.051
+28.624399093,176.939
+28.630204082,181.398
+28.636009070,190.397
+28.641814059,199.082
+28.647619048,205.219
+28.653424036,213.116
+28.659229025,221.496
+28.665034014,230.233
+28.670839002,241.834
+28.676643991,246.701
+28.682448980,248.587
+28.688253968,250.798
+28.694058957,252.771
+28.699863946,255.587
+28.705668934,256.508
+28.711473923,256.876
+28.717278912,256.513
+28.723083900,255.331
+28.728888889,254.54
+28.734693878,253.181
+28.740498866,252.09
+28.746303855,250.575
+28.752108844,249.206
+28.757913832,247.619
+28.763718821,246.559
+28.769523810,245.719
+28.775328798,245.049
+28.781133787,244.492
+28.786938776,243.625
+28.792743764,242.839
+28.798548753,242.222
+28.804353741,242.178
+28.810158730,242.397
+28.815963719,242.756
+28.821768707,242.841
+28.827573696,242.75
+28.833378685,242.409
+28.839183673,241.983
+28.844988662,241.421
+28.850793651,240.968
+28.856598639,240.341
+28.862403628,239.731
+28.868208617,239.403
+28.874013605,239.19
+28.879818594,238.996
+28.885623583,239.172
+28.891428571,239.46
+28.897233560,240.084
+28.903038549,240.919
+28.908843537,241.928
+28.914648526,243.607
+28.920453515,245.659
+28.926258503,247.555
+28.932063492,249.09
+28.937868481,249.792
+28.943673469,249.701
+28.949478458,248.731
+28.955283447,247.393
+28.961088435,246.193
+28.966893424,244.983
+28.972698413,243.401
+28.978503401,241.633
+28.984308390,239.206
+28.990113379,236.392
+28.995918367,233.084
+29.001723356,228.052
+29.152653061,254.589
+29.158458050,261.815
+29.164263039,264.297
+29.170068027,266.726
+29.175873016,267.78
+29.181678005,269.104
+29.187482993,270.497
+29.193287982,271.86
+29.199092971,273.238
+29.204897959,274.123
+29.210702948,273.773
+29.216507937,272.945
+29.222312925,271.13
+29.228117914,270.004
+29.233922902,269.114
+29.239727891,268.824
+29.245532880,268.828
+29.251337868,268.806
+29.257142857,268.666
+29.262947846,268.593
+29.268752834,269.056
+29.274557823,269.538
+29.280362812,270.269
+29.286167800,270.953
+29.291972789,271.195
+29.297777778,271.247
+29.303582766,271.517
+29.309387755,271.54
+29.315192744,271.711
+29.320997732,272.054
+29.326802721,272.23
+29.332607710,272.789
+29.338412698,273.2
+29.344217687,273.341
+29.350022676,273.126
+29.355827664,272.935
+29.361632653,272.397
+29.367437642,272.071
+29.373242630,271.759
+29.379047619,271.556
+29.384852608,272.19
+29.390657596,272.732
+29.396462585,273.645
+29.402267574,274.475
+29.408072562,274.924
+29.413877551,274.945
+29.419682540,274.912
+29.425487528,274.584
+29.431292517,274.323
+29.437097506,274.232
+29.442902494,273.691
+29.448707483,273.756
+29.454512472,273.427
+29.460317460,273.334
+29.466122449,273.537
+29.471927438,273.18
+29.477732426,272.854
+29.483537415,272.124
+29.489342404,271.725
+29.495147392,271.091
+29.500952381,270.82
+29.506757370,270.8
+29.512562358,270.68
+29.518367347,271.176
+29.524172336,271.712
+29.529977324,272.41
+29.535782313,273.188
+29.541587302,273.571
+29.547392290,273.724
+29.553197279,273.986
+29.559002268,274.357
+29.564807256,274.921
+29.570612245,275.622
+29.576417234,276.189
+29.582222222,276.44
+29.588027211,276.126
+29.593832200,275.636
+29.599637188,273.929
+29.605442177,272.258
+29.611247166,269.706
+29.617052154,268.352
+29.622857143,265.674
+29.628662132,262.044
+29.634467120,245.926
+29.640272109,233.335
+29.646077098,230.728
+29.651882086,226.938
+29.657687075,231.293
+29.663492063,233.804
+29.669297052,239.609
+29.675102041,243.35
+29.680907029,243.996
+29.686712018,244.266
+29.692517007,244.441
+29.698321995,244.485
+29.704126984,244.666
+29.709931973,244.808
+29.715736961,245.058
+29.721541950,245.116
+29.727346939,244.924
+29.733151927,244.738
+29.738956916,244.652
+29.744761905,244.691
+29.750566893,244.912
+29.756371882,245.076
+29.762176871,244.926
+29.767981859,244.52
+29.773786848,244.011
+29.779591837,243.418
+29.785396825,242.979
+29.791201814,242.698
+29.797006803,242.481
+29.802811791,242.707
+29.808616780,242.916
+29.814421769,242.992
+29.820226757,243.07
+29.826031746,242.729
+29.831836735,242.292
+29.837641723,241.136
+29.843446712,239.586
+29.849251701,228.968
+29.855056689,216.611
+29.860861678,215.107
+29.866666667,205.945
+29.872471655,201.028
+29.878276644,194.362
+29.884081633,185.038
+29.889886621,181.69
+29.936326531,211.574
+29.942131519,219.196
+29.947936508,222.78
+29.953741497,222.785
+29.959546485,222.41
+29.965351474,221.785
+29.971156463,220.048
+29.976961451,218.941
+29.982766440,218.586
+29.988571429,218.407
+29.994376417,218.137
+30.000181406,218.044
+30.005986395,217.965
+30.011791383,217.983
+30.017596372,217.71
+30.023401361,217.284
+30.029206349,216.767
+30.035011338,216.269
+30.040816327,216.079
+30.046621315,216.289
+30.052426304,216.831
+30.058231293,217.829
+30.064036281,219.136
+30.069841270,219.679
+30.075646259,220.342
+30.081451247,220.906
+30.087256236,221.677
+30.093061224,222.057
+30.098866213,222.321
+30.104671202,222.664
+30.110476190,222.795
+30.116281179,222.409
+30.122086168,221.407
+30.127891156,219.778
+30.133696145,218.568
+30.139501134,217.329
+30.145306122,215.854
+30.151111111,215.012
+30.156916100,214.669
+30.162721088,214.153
+30.168526077,213.547
+30.174331066,212.827
+30.180136054,211.731
+30.185941043,210.946
+30.191746032,210.896
+30.197551020,212.897
+30.203356009,217.789
+30.209160998,223.763
+30.214965986,226.206
+30.220770975,227.756
+30.226575964,228.853
+30.232380952,229.904
+30.238185941,230.836
+30.243990930,231.327
+30.249795918,231.756
+30.255600907,231.971
+30.261405896,232.512
+30.267210884,232.718
+30.273015873,232.796
+30.278820862,231.963
+30.284625850,229.827
+30.296235828,208.886
+30.302040816,208.446
+30.307845805,203.83
+30.313650794,206.89
+30.319455782,205.164
+30.325260771,203.286
+30.331065760,199.942
+30.336870748,195.572
+30.342675737,191.326
+30.621315193,207.787
+30.627120181,217.056
+30.632925170,227.393
+30.638730159,238.688
+30.644535147,245.051
+30.650340136,249.167
+30.656145125,254.557
+30.661950113,262.199
+30.667755102,266.88
+30.673560091,269.674
+30.679365079,271.606
+30.685170068,272.821
+30.690975057,273.816
+30.696780045,274.766
+30.702585034,275.427
+30.708390023,275.61
+30.714195011,275.603
+30.720000000,274.816
+30.725804989,274.121
+30.731609977,273.223
+30.737414966,272.488
+30.743219955,272.208
+30.749024943,272.416
+30.754829932,272.929
+30.760634921,273.935
+30.766439909,275.338
+30.772244898,276.505
+30.778049887,277.842
+30.783854875,278.271
+30.789659864,278.614
+30.795464853,277.945
+30.801269841,277.096
+30.807074830,275.847
+30.812879819,274.237
+30.818684807,272.167
+30.824489796,270.093
+30.830294785,268.758
+30.836099773,267.841
+30.841904762,267.503
+30.847709751,267.387
+30.853514739,267.547
+30.859319728,267.388
+30.865124717,267.709
+30.870929705,268.445
+30.876734694,269.442
+30.882539683,270.176
+30.888344671,270.985
+30.894149660,272.034
+30.899954649,273.223
+30.905759637,274.466
+30.911564626,275.788
+30.917369615,276.231
+30.923174603,276.37
+30.928979592,276.282
+30.934784580,275.752
+30.940589569,274.433
+30.946394558,271.557
+30.952199546,268.495
+30.958004535,265.571
+30.963809524,261.599
+30.969614512,247.933
+30.975419501,241.67
+30.981224490,234.355
+31.108934240,285.607
+31.114739229,289.077
+31.120544218,294.435
+31.126349206,300.824
+31.132154195,306.84
+31.137959184,311.593
+31.143764172,315.147
+31.149569161,318.785
+31.155374150,322.57
+31.161179138,326.368
+31.166984127,329.67
+31.172789116,332.109
+31.178594104,333.91
+31.184399093,335.106
+31.190204082,335.491
+31.196009070,335.299
+31.201814059,334.474
+31.207619048,333.155
+31.213424036,331.724
+31.219229025,330.665
+31.225034014,329.915
+31.230839002,329.762
+31.236643991,330.163
+31.242448980,330.474
+31.248253968,331.514
+31.254058957,332.292
+31.259863946,333
+31.265668934,333.611
+31.271473923,333.709
+31.277278912,333.428
+31.283083900,332.655
+31.288888889,331.667
+31.294693878,330.588
+31.300498866,329.687
+31.306303855,328.88
+31.312108844,328.23
+31.317913832,327.58
+31.323718821,326.923
+31.329523810,326.388
+31.335328798,326.084
+31.341133787,326.225
+31.346938776,326.872
+31.352743764,327.67
+31.358548753,328.437
+31.364353741,329.014
+31.370158730,329.245
+31.375963719,329.427
+31.381768707,329.651
+31.387573696,329.747
+31.393378685,329.767
+31.399183673,329.879
+31.404988662,329.819
+31.410793651,329.774
+31.416598639,329.519
+31.422403628,328.914
+31.428208617,328.405
+31.434013605,327.757
+31.439818594,327.596
+31.445623583,327.96
+31.451428571,328.865
+31.457233560,330.021
+31.463038549,331.307
+31.468843537,332.501
+31.474648526,333.428
+31.480453515,334.229
+31.486258503,334.687
+31.492063492,335.191
+31.497868481,335.603
+31.503673469,335.973
+31.509478458,336.06
+31.515283447,335.967
+31.521088435,335.413
+31.526893424,333.956
+31.532698413,332.133
+31.538503401,329.739
+31.544308390,326.741
+31.550113379,323.854
+31.555918367,321.407
+31.561723356,319.839
+31.567528345,320.234
+31.573333333,321.326
+31.579138322,320.963
+31.584943311,316.826
+31.590748299,306.082
+31.596553288,303.14
+31.602358277,299.431
+31.608163265,295.266
+31.613968254,290.293
+31.619773243,286.809
+31.625578231,284.518
+31.631383220,282.141
+31.637188209,280.669
+31.642993197,279.616
+31.648798186,279.696
+31.654603175,279.781
+31.660408163,279.714
+31.666213152,279.364
+31.672018141,278.536
+31.677823129,277.568
+31.683628118,276.595
+31.689433107,275.885
+31.695238095,275.193
+31.701043084,274.21
+31.706848073,273.529
+31.712653061,270.498
+31.718458050,261.813
+31.910022676,277.592
+31.915827664,283.08
+31.921632653,289.024
+31.927437642,293.826
+31.933242630,297.571
+31.939047619,301.58
+31.944852608,307.15
+31.950657596,313.86
+31.956462585,320.425
+31.962267574,325.498
+31.968072562,329.343
+31.973877551,332.309
+31.979682540,334.352
+31.985487528,335.921
+31.991292517,336.878
+31.997097506,336.98
+32.002902494,336.414
+32.008707483,335.263
+32.014512472,334.038
+32.020317460,332.645
+32.026122449,331.769
+32.031927438,331.184
+32.037732426,330.451
+32.043537415,329.961
+32.049342404,329.296
+32.055147392,329.213
+32.060952381,329.249
+32.066757370,329.541
+32.072562358,329.948
+32.078367347,330.421
+32.084172336,330.838
+32.089977324,331.458
+32.095782313,332.094
+32.101587302,332.167
+32.107392290,332.514
+32.113197279,332.641
+32.119002268,332.714
+32.124807256,333.478
+32.130612245,334.027
+32.136417234,334.517
+32.142222222,334.831
+32.148027211,334.495
+32.153832200,333.86
+32.159637188,333.079
+32.165442177,332.024
+32.171247166,331.148
+32.177052154,330.187
+32.182857143,329.626
+32.188662132,329.45
+32.194467120,329.199
+32.200272109,329.14
+32.206077098,328.51
+32.211882086,327.876
+32.217687075,327.797
+32.223492063,327.484
+32.229297052,327.745
+32.235102041,328.115
+32.240907029,326.59
+32.246712018,325.576
+32.252517007,323.817
+32.258321995,322.849
+32.264126984,323.55
+32.269931973,323.984
+32.275736961,325.328
+32.281541950,326.284
+32.287346939,327.192
+32.293151927,328.737
+32.298956916,330.114
+32.304761905,331.393
+32.310566893,332.932
+32.316371882,333.954
+32.322176871,334.405
+32.327981859,334.277
+32.333786848,333.627
+32.339591837,333.058
+32.345396825,332.622
+32.351201814,333.337
+32.357006803,334.022
+32.362811791,334.724
+32.368616780,335.42
+32.374421769,335.485
+32.380226757,335.626
+32.386031746,335.528
+32.391836735,335.561
+32.397641723,335.791
+32.403446712,335.884
+32.409251701,335.647
+32.415056689,335.134
+32.420861678,334.241
+32.426666667,333.233
+32.432471655,332.365
+32.438276644,332.109
+32.444081633,332.803
+32.449886621,333.895
+32.455691610,335.239
+32.461496599,336.702
+32.467301587,338.322
+32.473106576,340.084
+32.478911565,342.286
+32.484716553,344.69
+32.490521542,347.452
+32.496326531,350.363
+32.502131519,353.285
+32.507936508,355.934
+32.513741497,358.206
+32.519546485,360.061
+32.525351474,361.529
+32.531156463,362.759
+32.536961451,363.911
+32.542766440,365.197
+32.548571429,366.562
+32.554376417,367.726
+32.560181406,368.987
+32.565986395,369.674
+32.571791383,370.274
+32.577596372,370.103
+32.583401361,369.648
+32.589206349,368.82
+32.595011338,367.737
+32.600816327,366.83
+32.606621315,365.563
+32.612426304,364.998
+32.618231293,364.817
+32.624036281,364.922
+32.629841270,365.239
+32.635646259,365.022
+32.641451247,364.391
+32.647256236,364.118
+32.653061224,364.036
+32.658866213,364.35
+32.664671202,365.101
+32.670476190,365.174
+32.676281179,364.462
+32.682086168,363.74
+32.687891156,362.837
+32.693696145,361.77
+32.699501134,361.283
+32.705306122,360.66
+32.711111111,360.044
+32.716916100,359.394
+32.722721088,359.174
+32.728526077,359.014
+32.734331066,359.598
+32.740136054,360.543
+32.745941043,361.648
+32.751746032,362.336
+32.757551020,362.543
+32.763356009,362.714
+32.769160998,362.63
+32.774965986,362.791
+32.780770975,362.905
+32.786575964,363.186
+32.792380952,363.585
+32.798185941,364.105
+32.803990930,365.209
+32.809795918,366.703
+32.815600907,367.952
+32.821405896,369.06
+32.827210884,369.317
+32.833015873,368.605
+32.838820862,367.214
+32.844625850,364.39
+32.850430839,364.967
+32.856235828,370.084
+32.862040816,371.276
+32.867845805,373.233
+32.873650794,376.245
+32.879455782,378.4
+32.885260771,382.408
+32.891065760,385.605
+32.896870748,382.019
+32.902675737,379.946
+32.908480726,372.46
+32.914285714,366.681
+32.920090703,362.08
+32.925895692,358.474
+32.931700680,361.644
+32.937505669,358.746
+32.943310658,357.92
+32.949115646,358.519
+32.954920635,351.794
+32.960725624,338.406
+32.966530612,336.864
+32.972335601,329.17
+33.262585034,239.473
+33.268390023,240.884
+33.274195011,240.153
+33.280000000,239.057
+33.285804989,236.239
+33.291609977,232.634
+33.297414966,225.037
+33.303219955,217.578
+33.309024943,214.428
+33.314829932,212.598
+33.320634921,210.952
+33.326439909,209.303
+33.332244898,208.213
+33.338049887,208.222
+33.343854875,208.877
+33.349659864,210.436
+33.355464853,212.333
+33.361269841,213.458
+33.367074830,214.728
+33.372879819,215.949
+33.378684807,217.711
+33.384489796,219.43
+33.390294785,220.458
+33.396099773,221.237
+33.401904762,221.624
+33.407709751,221.191
+33.413514739,220.664
+33.419319728,219.86
+33.425124717,218.973
+33.430929705,218.454
+33.436734694,217.902
+33.442539683,217.116
+33.448344671,217.003
+33.454149660,217.188
+33.459954649,217.546
+33.465759637,218.686
+33.471564626,219.509
+33.477369615,220.111
+33.483174603,220.236
+33.488979592,220.451
+33.494784580,220.523
+33.500589569,220.166
+33.506394558,219.577
+33.512199546,218.372
+33.518004535,217.117
+33.523809524,216.577
+33.529614512,215.691
+33.535419501,215.162
+33.541224490,215.404
+33.547029478,214.352
+33.552834467,215.334
+33.558639456,217.769
+33.564444444,219.82
+33.570249433,223.964
+33.576054422,228.108
+33.581859410,230.932
+33.587664399,232.462
+33.593469388,233.75
+33.599274376,235.514
+33.605079365,237.24
+33.610884354,237.976
+33.616689342,237.907
+33.622494331,237.644
+33.628299320,235.46
+33.634104308,234.071
+33.639909297,231.831
+33.645714286,228.802
+33.651519274,226.947
+33.657324263,222.491
+33.663129252,219.281
+33.668934240,216.188
+33.674739229,213.176
+33.680544218,210.804
+33.686349206,210.205
+33.692154195,210.656
+35.863219955,204.864
+35.869024943,212.295
+35.874829932,217.853
+35.880634921,222.936
+35.886439909,226.771
+35.892244898,229.422
+35.898049887,231.727
+35.903854875,233.789
+35.909659864,235.561
+35.915464853,237.39
+35.921269841,239.126
+35.927074830,240.514
+35.932879819,241.632
+35.938684807,242.558
+35.944489796,243.109
+35.950294785,243.255
+35.956099773,242.818
+35.961904762,242.235
+35.967709751,241.548
+35.973514739,240.607
+35.979319728,239.231
+35.985124717,237.2
+35.990929705,234.783
+35.996734694,232.697
+36.002539683,231.483
+36.008344671,229.694
+36.014149660,226.308
+36.141859410,335.058
+36.147664399,353.591
+36.153469388,365.658
+36.159274376,366.25
+36.165079365,366.292
+36.170884354,365.046
+36.176689342,364.335
+36.182494331,364.921
+36.188299320,366.552
+36.194104308,367.687
+36.199909297,368.716
+36.205714286,370.189
+36.211519274,370.059
+36.217324263,369.644
+36.223129252,369.229
+36.228934240,367.942
+36.234739229,366.857
+36.240544218,366.096
+36.246349206,365.882
+36.252154195,365.377
+36.257959184,365.804
+36.263764172,366.119
+36.269569161,366.008
+36.275374150,366.19
+36.281179138,365.33
+36.286984127,364.211
+36.292789116,363.227
+36.298594104,362.959
+36.304399093,363.062
+36.310204082,363.32
+36.316009070,363.924
+36.321814059,364.39
+36.327619048,364.574
+36.333424036,364.985
+36.339229025,364.535
+36.345034014,363.301
+36.350839002,361.48
+36.356643991,359.708
+36.362448980,357.947
+36.368253968,354.625
+36.374058957,351.434
+36.530793651,347.25
+36.536598639,348.693
+36.542403628,363.036
+36.548208617,370.631
+36.554013605,373.77
+36.559818594,375.332
+36.565623583,376.664
+36.571428571,377.857
+36.577233560,377.893
+36.583038549,377.068
+36.588843537,376.163
+36.594648526,374.026
+36.600453515,371.576
+36.606258503,369.849
+36.612063492,368.451
+36.617868481,367.601
+36.623673469,366.826
+36.629478458,365.905
+36.635283447,364.973
+36.641088435,364.045
+36.646893424,363.367
+36.652698413,362.918
+36.658503401,363.345
+36.664308390,364.014
+36.670113379,364.852
+36.675918367,365.765
+36.681723356,365.84
+36.687528345,365.25
+36.693333333,364.5
+36.699138322,363.616
+36.704943311,362.707
+36.710748299,362.49
+36.716553288,362.597
+36.722358277,363.24
+36.728163265,364.224
+36.733968254,365.235
+36.739773243,366.093
+36.745578231,366.796
+36.751383220,367.54
+36.757188209,368.136
+36.762993197,368.574
+36.768798186,369.1
+36.774603175,369.642
+36.780408163,370.309
+36.786213152,370.879
+36.792018141,371.356
+36.797823129,371.651
+36.803628118,371.737
+36.809433107,371.821
+36.815238095,371.732
+36.821043084,371.6
+36.826848073,371.606
+36.832653061,371.59
+36.838458050,371.205
+36.844263039,370.873
+36.850068027,369.45
+36.855873016,366.935
+36.861678005,364.712
+36.867482993,362.147
+36.873287982,359.575
+36.879092971,357.524
+36.884897959,357.712
+36.890702948,352.446
+36.896507937,348.325
+36.902312925,348.853
+36.908117914,352.504
+36.913922902,349.872
+36.919727891,346.829
+36.925532880,341.431
+36.931337868,330.99
+36.937142857,324.188
+36.942947846,315.571
+36.948752834,309.48
+36.954557823,300.847
+36.960362812,293.057
+36.966167800,281.494
+36.971972789,278.274
+36.977777778,273.127
+36.983582766,267.688
+36.989387755,267.699
+36.995192744,275.722
+37.000997732,284.697
+37.006802721,288.282
+37.012607710,297.072
+37.018412698,306.361
+37.024217687,312.212
+37.030022676,311.765
+37.035827664,320.585
+37.041632653,325.996
+37.047437642,330.706
+37.053242630,334.568
+37.059047619,338.213
+37.064852608,338.816
+37.070657596,338.936
+37.076462585,339.141
+37.082267574,338.457
+37.088072562,337.922
+37.093877551,337.664
+37.099682540,337.299
+37.105487528,337.386
+37.111292517,338.08
+37.117097506,338.857
+37.122902494,339.744
+37.128707483,340.865
+37.134512472,341.994
+37.140317460,343.444
+37.146122449,344.708
+37.151927438,345.913
+37.157732426,347.328
+37.163537415,349.296
+37.169342404,351.262
+37.175147392,353.476
+37.180952381,355.273
+37.186757370,357.064
+37.192562358,359.398
+37.198367347,360.889
+37.204172336,363.338
+37.209977324,364.472
+37.215782313,365.611
+37.221587302,366.595
+37.227392290,366.486
+37.233197279,366.263
+37.239002268,365.819
+37.244807256,365
+37.250612245,364.427
+37.256417234,364.43
+37.262222222,363.704
+37.268027211,363.426
+37.273832200,363.183
+37.279637188,363.066
+37.285442177,362.399
+37.291247166,363.183
+37.297052154,363.338
+37.302857143,362.755
+37.308662132,363.69
+37.314467120,362.443
+37.320272109,362.165
+37.326077098,362.629
+37.331882086,362.543
+37.337687075,363.535
+37.343492063,364.052
+37.349297052,364.317
+37.355102041,364.611
+37.360907029,364.93
+37.366712018,364.891
+37.372517007,364.876
+37.378321995,365.193
+37.384126984,365.332
+37.389931973,365.452
+37.395736961,365.826
+37.401541950,365.848
+37.407346939,365.583
+37.413151927,365.594
+37.418956916,365.561
+37.424761905,364.956
+37.430566893,364.36
+37.436371882,363.88
+37.442176871,363.212
+37.447981859,363.505
+37.453786848,362.675
+37.459591837,360.372
+37.465396825,358.72
+37.471201814,356.343
+37.477006803,352.138
+37.482811791,351.273
+37.488616780,351.415
+37.494421769,345.419
+37.500226757,360.741
+37.506031746,362.804
+37.511836735,363.742
+37.517641723,366.731
+37.523446712,368.464
+37.529251701,370.494
+37.535056689,371.414
+37.540861678,371.216
+37.546666667,371.224
+37.552471655,370.51
+37.558276644,370.031
+37.564081633,369.22
+37.569886621,368.416
+37.575691610,368.109
+37.581496599,367.64
+37.587301587,367.651
+37.593106576,367.29
+37.598911565,367.296
+37.604716553,367.126
+37.610521542,367.279
+37.616326531,367.746
+37.622131519,368.351
+37.627936508,369.403
+37.633741497,370.585
+37.639546485,371.546
+37.645351474,372.225
+37.651156463,372.963
+37.656961451,372.191
+37.662766440,371.435
+37.668571429,370.57
+37.790476190,334.679
+37.796281179,331.407
+37.802086168,333.024
+37.807891156,335.958
+37.813696145,337.132
+37.819501134,338.266
+37.825306122,339.929
+37.831111111,340.275
+37.836916100,339.636
+37.842721088,338.994
+37.848526077,337.513
+37.854331066,336.068
+37.860136054,335.311
+37.865941043,334.256
+37.871746032,333.135
+37.877551020,331.462
+37.883356009,329.846
+37.889160998,328.671
+37.894965986,328.254
+37.900770975,328.424
+37.906575964,328.487
+37.912380952,328.547
+37.918185941,328.384
+37.923990930,327.977
+37.929795918,327.415
+37.935600907,326.957
+37.941405896,326.646
+37.947210884,326.392
+37.953015873,326.579
+37.958820862,326.777
+37.964625850,327.287
+37.970430839,327.516
+37.976235828,327.472
+37.982040816,327.354
+37.987845805,326.673
+37.993650794,325.684
+37.999455782,324.188
+38.005260771,321.965
+38.011065760,319.255
+38.016870748,315.759
+38.022675737,311.686
+38.028480726,306.802
+38.034285714,302.193
+38.040090703,298.125
+38.045895692,294.534
+38.051700680,290.899
+38.057505669,288.102
+38.063310658,286.728
+38.069115646,286.265
+38.074920635,286.818
+38.080725624,287.685
+38.086530612,288.722
+38.092335601,290.179
+38.098140590,291.594
+38.103945578,293.067
+38.109750567,294.431
+38.115555556,295.245
+38.121360544,295.478
+38.127165533,295.01
+38.132970522,294.161
+38.138775510,293.049
+38.144580499,291.759
+38.150385488,290.336
+38.156190476,288.919
+38.161995465,287.155
+38.167800454,284.971
+38.173605442,282.379
+38.179410431,279.896
+38.185215420,277.181
+38.191020408,274.12
+38.196825397,270.82
+38.202630385,267.576
+38.208435374,265.557
+38.214240363,264.543
+38.220045351,264.672
+38.225850340,265.384
+38.231655329,266.798
+38.237460317,268.631
+38.243265306,271.1
+38.249070295,273.56
+38.254875283,276.643
+38.260680272,279.216
+38.266485261,281.421
+38.272290249,283.697
+38.278095238,285.521
+38.283900227,286.624
+38.289705215,287.072
+38.295510204,286.708
+38.301315193,285.855
+38.307120181,284.513
+38.312925170,282.951
+38.318730159,281.695
+38.324535147,280.506
+38.330340136,279.212
+38.336145125,277.852
+38.341950113,276.426
+38.347755102,274.897
+38.353560091,273.56
+38.359365079,272.46
+38.365170068,271.56
+38.370975057,271.12
+38.376780045,270.854
+38.382585034,271.116
+38.388390023,271.733
+38.394195011,272.755
+38.400000000,273.922
+38.405804989,275.046
+38.411609977,276.313
+38.417414966,278.106
+38.423219955,280.208
+38.429024943,282.718
+38.434829932,284.888
+38.440634921,286.945
+38.446439909,289.57
+38.452244898,292.037
+38.458049887,295.065
+38.463854875,297.565
+38.469659864,299.123
+38.475464853,299.691
+38.481269841,299.235
+38.487074830,297.897
+38.492879819,295.805
+38.498684807,293.051
+38.504489796,289.533
+38.510294785,286.018
+38.516099773,281.925
+38.521904762,278.331
+38.527709751,275.356
+38.533514739,272.393
+38.539319728,269.692
+38.545124717,267.592
+38.550929705,266.054
+38.556734694,267.542
+38.562539683,277.866
+38.568344671,284.336
+38.574149660,288.436
+38.579954649,291.68
+38.585759637,294.671
+38.591564626,298.232
+38.597369615,303.301
+38.603174603,305.246
+38.608979592,307.402
+38.614784580,309.02
+38.620589569,307.056
+38.626394558,310.761
+39.293968254,246.706
+39.299773243,250.272
+39.305578231,255.972
+39.311383220,261.864
+39.317188209,269.864
+39.322993197,273.127
+39.328798186,276.165
+39.334603175,279.04
+39.340408163,281.091
+39.346213152,282.512
+39.352018141,283.504
+39.357823129,283.859
+39.363628118,283.875
+39.369433107,283.324
+39.375238095,282.522
+39.381043084,281.505
+39.386848073,280.639
+39.392653061,280.29
+39.398458050,280.574
+39.404263039,281.221
+39.410068027,282.312
+39.415873016,283.676
+39.421678005,285.144
+39.427482993,285.866
+39.433287982,285.889
+39.439092971,285.644
+39.444897959,284.856
+39.450702948,284.091
+39.456507937,282.668
+39.462312925,280.95
+39.468117914,279.256
+39.473922902,276.682
+39.479727891,272.967
+39.485532880,268.555
+39.491337868,263.757
+39.497142857,261.745
+39.502947846,253.334
+39.508752834,249.443
+39.636462585,261.007
+39.642267574,271.145
+39.648072562,278.525
+39.653877551,286.428
+39.659682540,290.512
+39.665487528,292.142
+39.671292517,293.039
+39.677097506,293.725
+39.682902494,294.245
+39.688707483,294.631
+39.694512472,295.138
+39.700317460,295.529
+39.706122449,295.762
+39.711927438,295.542
+39.717732426,295.303
+39.723537415,295.118
+39.729342404,295.008
+39.735147392,295.141
+39.740952381,295.355
+39.746757370,295.593
+39.752562358,295.711
+39.758367347,295.695
+39.764172336,295.616
+39.769977324,295.489
+39.775782313,294.987
+39.781587302,294.171
+39.787392290,293.082
+39.793197279,291.026
+39.799002268,290.874
+39.949931973,370.596
+39.955736961,369.981
+39.961541950,358.121
+39.967346939,351.502
+39.973151927,346.528
+39.978956916,341.425
+39.984761905,339.071
+39.990566893,338.495
+39.996371882,336.714
+40.002176871,334.5
+40.007981859,332.514
+40.013786848,330.627
+40.019591837,329.29
+40.025396825,328.492
+40.031201814,328.026
+40.037006803,327.893
+40.042811791,327.991
+40.048616780,328.037
+40.054421769,328.049
+40.060226757,328.276
+40.066031746,328.322
+40.071836735,328.649
+40.077641723,328.88
+40.083446712,329.326
+40.089251701,329.739
+40.095056689,330.013
+40.100861678,330.635
+40.106666667,330.791
+40.112471655,331.094
+40.118276644,331.306
+40.124081633,331.484
+40.129886621,331.658
+40.135691610,331.196
+40.141496599,330.636
+40.147301587,329.99
+40.153106576,329.21
+40.158911565,328.366
+40.164716553,327.107
+40.170521542,325.085
+40.176326531,323.154
+40.182131519,320.981
+40.187936508,318.633
+40.193741497,317.878
+40.199546485,315.914
+40.205351474,309.501
+40.211156463,313.448
+40.216961451,309.536
+40.222766440,302.709
+40.228571429,296.287
+40.234376417,289.229
+40.240181406,280.464
+40.245986395,271.935
+40.251791383,265.028
+40.257596372,255.717
+40.263401361,250.674
+40.269206349,247.728
+40.275011338,247.574
+40.280816327,249.822
+40.286621315,257.449
+40.292426304,269.126
+40.298231293,273.526
+40.304036281,276.704
+40.309841270,277.803
+40.315646259,278.632
+40.321451247,278.99
+40.327256236,279.212
+40.333061224,278.993
+40.338866213,278.209
+40.344671202,277.465
+40.350476190,276.455
+40.356281179,275.636
+40.362086168,274.74
+40.367891156,273.988
+40.373696145,273.311
+40.379501134,272.873
+40.385306122,272.638
+40.391111111,272.921
+40.396916100,273.252
+40.402721088,273.667
+40.408526077,274.032
+40.414331066,274.154
+40.420136054,274.226
+40.425941043,274.513
+40.431746032,274.821
+40.437551020,275.201
+40.443356009,276.722
+40.449160998,276.747
+40.454965986,273.951
+40.460770975,271.042
+40.466575964,270.355
+40.472380952,269.59
+40.478185941,269.578
+40.483990930,269.344
+40.617505669,298.571
+40.623310658,299.062
+40.629115646,302.695
+40.634920635,303.477
+40.640725624,303.594
+40.646530612,303.578
+40.652335601,303.297
+40.658140590,302.738
+40.663945578,302.253
+40.669750567,301.834
+40.675555556,301.185
+40.681360544,300.93
+40.687165533,300.861
+40.692970522,300.465
+40.698775510,299.898
+40.704580499,298.772
+40.710385488,297.399
+40.716190476,296.378
+40.721995465,296.261
+40.727800454,296.304
+40.733605442,296.286
+40.739410431,296.226
+40.745215420,296.109
+40.751020408,291.244
+40.756825397,290.183
+40.762630385,288.72
+40.872925170,342.967
+40.878730159,339.689
+40.884535147,341.545
+40.890340136,340.997
+40.896145125,340.072
+40.901950113,338.302
+40.907755102,338.497
+40.913560091,338.479
+40.919365079,338.494
+40.925170068,338.938
+40.930975057,339.268
+40.936780045,339.374
+40.942585034,339.27
+40.948390023,338.48
+40.954195011,336.865
+40.960000000,336.477
+40.965804989,336.216
+40.971609977,335.027
+40.977414966,334.042
+40.983219955,332.697
+40.989024943,331.7
+40.994829932,330.812
+41.000634921,329.943
+41.006439909,329.19
+41.012244898,328.389
+41.018049887,327.675
+41.023854875,327.198
+41.029659864,326.737
+41.035464853,326.315
+41.041269841,325.988
+41.047074830,325.788
+41.052879819,325.873
+41.058684807,326.18
+41.064489796,326.668
+41.070294785,327.227
+41.076099773,327.687
+41.081904762,327.794
+41.087709751,327.741
+41.093514739,327.338
+41.099319728,327.037
+41.105124717,326.732
+41.110929705,326.957
+41.116734694,327.835
+41.122539683,329.557
+41.128344671,332.585
+41.134149660,334.119
+41.139954649,335.019
+41.145759637,334.32
+41.151564626,332.784
+41.157369615,333.825
+41.163174603,335.339
+41.168979592,334.277
+41.174784580,335.722
+41.180589569,319.464
+41.186394558,306.993
+41.192199546,293.89
+41.198004535,282.805
+41.203809524,270.833
+41.209614512,265.958
+41.215419501,257.563
+41.221224490,252.047
+41.227029478,248.666
+41.232834467,245.583
+41.238639456,246.461
+41.244444444,251.249
+41.250249433,259.448
+41.256054422,267.915
+41.261859410,276.343
+41.267664399,275.209
+41.273469388,279.023
+41.279274376,278.868
+41.285079365,278.625
+41.290884354,278.082
+41.296689342,277.583
+41.302494331,277.178
+41.308299320,276.722
+41.314104308,276.439
+41.319909297,276.106
+41.325714286,275.678
+41.331519274,275.324
+41.337324263,274.705
+41.343129252,274.012
+41.348934240,273.126
+41.354739229,272.246
+41.360544218,271.969
+41.366349206,272.043
+41.372154195,274.393
+41.377959184,275.932
+41.383764172,277.09
+41.389569161,278.157
+41.395374150,272.788
+41.401179138,273.441
+41.406984127,273.722
+41.412789116,274.171
+41.418594104,273.692
+41.424399093,272.598
+41.430204082,271.865
+41.436009070,270.47
+41.441814059,269.6
+41.447619048,268.408
+41.453424036,268.781
+41.604353741,278.464
+41.610158730,285.68
+41.615963719,289.842
+41.621768707,295.589
+41.627573696,298.86
+41.633378685,299.546
+41.639183673,299.71
+41.644988662,299.694
+41.650793651,298.89
+41.656598639,298.199
+41.662403628,297.721
+41.668208617,297.328
+41.674013605,297.003
+41.679818594,296.933
+41.685623583,296.968
+41.691428571,297.022
+41.697233560,297.526
+41.703038549,297.805
+41.708843537,297.849
+41.714648526,298.143
+41.720453515,298.131
+41.726258503,298.023
+41.732063492,297.858
+41.737868481,293.379
+41.894603175,358.182
+41.900408163,346.297
+41.906213152,342.125
+41.912018141,340.154
+41.917823129,340.858
+41.923628118,341.91
+41.929433107,343.261
+41.935238095,344.697
+41.941043084,344.562
+41.946848073,344.13
+41.952653061,343.462
+41.958458050,342.42
+41.964263039,341.296
+41.970068027,340.201
+41.975873016,339.029
+41.981678005,337.831
+41.987482993,336.943
+41.993287982,335.94
+41.999092971,334.941
+42.004897959,334.099
+42.010702948,333.33
+42.016507937,332.724
+42.022312925,332.243
+42.028117914,331.877
+42.033922902,331.116
+42.039727891,330.584
+42.045532880,329.993
+42.051337868,329.397
+42.057142857,329.289
+42.062947846,329.204
+42.068752834,329.542
+42.074557823,329.96
+42.080362812,330.457
+42.086167800,330.651
+42.091972789,330.782
+42.097777778,330.691
+42.103582766,330.177
+42.109387755,329.365
+42.115192744,328.179
+42.120997732,326.729
+42.126802721,325.202
+42.132607710,323.809
+42.138412698,322.524
+42.144217687,321.511
+42.150022676,321.137
+42.155827664,321.151
+42.161632653,308.751
+42.167437642,308.916
+42.173242630,307.612
+42.179047619,303.727
+42.184852608,295.465
+42.190657596,285.801
+42.196462585,277.116
+42.202267574,268.935
+42.208072562,262.404
+42.213877551,257.567
+42.219682540,255.185
+42.225487528,254.912
+42.231292517,257.252
+42.237097506,258.484
+42.242902494,264.654
+42.248707483,271.526
+42.254512472,278.573
+42.260317460,283.575
+42.266122449,286.319
+42.271927438,286.799
+42.277732426,286.531
+42.283537415,286.239
+42.289342404,285.602
+42.295147392,284.685
+42.300952381,283.58
+42.306757370,282.456
+42.312562358,281.473
+42.318367347,280.597
+42.324172336,280.093
+42.329977324,279.719
+42.335782313,279.901
+42.341587302,280.145
+42.347392290,280.251
+42.353197279,280.299
+42.359002268,279.659
+42.364807256,279.073
+42.370612245,278.573
+42.376417234,278.172
+42.382222222,278.144
+42.388027211,278.264
+42.393832200,278.46
+42.399637188,278.599
+42.405442177,278.141
+42.411247166,276.684
+42.417052154,274.076
+42.422857143,275.342
+42.585396825,291.307
+42.591201814,290.886
+42.597006803,293.244
+42.602811791,294.992
+42.608616780,296.016
+42.614421769,296.707
+42.620226757,297.031
+42.626031746,297.192
+42.631836735,297.053
+42.637641723,296.838
+42.643446712,296.498
+42.649251701,295.903
+42.655056689,295.564
+42.660861678,295.153
+42.666666667,294.791
+42.672471655,294.667
+42.678276644,294.701
+42.684081633,295.185
+42.689886621,296.063
+42.695691610,296.868
+42.701496599,297.299
+42.707301587,297.528
+42.713106576,297.456
+42.718911565,297.143
+42.724716553,296.267
+42.730521542,290.107
+42.736326531,283.859
+42.742131519,279.393
+42.893061224,339.545
+42.898866213,333.813
+42.904671202,334.37
+42.910476190,335.4
+42.916281179,337.218
+42.922086168,338.436
+42.927891156,340.078
+42.933696145,342.15
+42.939501134,343.799
+42.945306122,343.767
+42.951111111,343.563
+42.956916100,341.93
+42.962721088,340.113
+42.968526077,338.171
+42.974331066,336.711
+42.980136054,335.48
+42.985941043,334.358
+42.991746032,333.397
+42.997551020,332.338
+43.003356009,331.354
+43.009160998,330.534
+43.014965986,329.605
+43.020770975,328.943
+43.026575964,328.626
+43.032380952,328.275
+43.038185941,328.18
+43.043990930,328.145
+43.049795918,328.021
+43.055600907,328.001
+43.061405896,328.073
+43.067210884,328.178
+43.073015873,328.162
+43.078820862,328.242
+43.084625850,327.983
+43.090430839,327.593
+43.096235828,326.953
+43.102040816,325.922
+43.107845805,324.799
+43.113650794,322.945
+43.119455782,321.161
+43.125260771,319.697
+43.131065760,318.105
+43.136870748,317.017
+43.142675737,317.538
+43.148480726,309.089
+43.154285714,308.188
+43.160090703,307.781
+43.165895692,301.44
+43.171700680,294.528
+43.177505669,284.47
+43.183310658,275.401
+43.189115646,267.85
+43.194920635,259.142
+43.200725624,250.744
+43.206530612,244.563
+43.212335601,243.465
+43.218140590,245.678
+43.223945578,254.179
+43.229750567,262.092
+43.235555556,271.794
+43.241360544,280.063
+43.247165533,278.799
+43.252970522,290.375
+43.258775510,296.685
+43.264580499,298.728
+43.270385488,300.833
+43.276190476,303.31
+43.281995465,303.822
+43.287800454,303.727
+43.293605442,303.71
+43.299410431,302.785
+43.305215420,302.092
+43.311020408,301.883
+43.316825397,301.436
+43.322630385,301.09
+43.328435374,300.223
+43.334240363,299.209
+43.340045351,298.47
+43.345850340,297.41
+43.351655329,296.745
+43.357460317,296.53
+43.363265306,296.459
+43.369070295,296.463
+43.374875283,296.597
+43.380680272,296.62
+43.386485261,296.708
+43.392290249,297.18
+43.398095238,297.368
+43.403900227,297.575
+43.409705215,297.986
+43.415510204,297.879
+43.421315193,297.522
+43.427120181,296.252
+43.432925170,294.851
+43.438730159,292.493
+43.444535147,288.465
+43.554829932,273.42
+43.560634921,276.664
+43.566439909,279.242
+43.572244898,282.632
+43.578049887,284.299
+43.583854875,284.561
+43.589659864,284.669
+43.595464853,284.208
+43.601269841,283.081
+43.607074830,282.321
+43.612879819,281.596
+43.618684807,280.674
+43.624489796,279.806
+43.630294785,278.564
+43.636099773,277.725
+43.641904762,277.263
+43.647709751,276.939
+43.653514739,277.163
+43.659319728,277.508
+43.665124717,277.788
+43.670929705,278.237
+43.676734694,278.569
+43.682539683,278.87
+43.688344671,279.247
+43.694149660,279.702
+43.699954649,279.99
+43.705759637,280.239
+43.711564626,280.363
+43.717369615,279.99
+43.723174603,279.12
+43.728979592,278.118
+43.734784580,277.172
+43.740589569,276.495
+43.746394558,275.38
+43.752199546,276.238
+43.758004535,276.878
+43.763809524,276.049
+43.769614512,275.398
+43.775419501,274.931
+43.781224490,273.499
+43.787029478,272.092
+43.792834467,269.538
+43.798639456,266.424
+43.804444444,261.749
+43.810249433,255.731
+43.816054422,247.569
+43.821859410,236.071
+43.949569161,246.517
+43.955374150,248.918
+43.961179138,252.569
+43.966984127,254.442
+43.972789116,256.187
+43.978594104,258.083
+43.984399093,260.133
+43.990204082,261.906
+43.996009070,263.298
+44.001814059,264.204
+44.007619048,264.892
+44.013424036,265.398
+44.019229025,265.684
+44.025034014,266.033
+44.030839002,266.726
+44.036643991,267.431
+44.042448980,268.558
+44.048253968,269.667
+44.054058957,270.917
+44.059863946,272.286
+44.065668934,273.395
+44.071473923,274.77
+44.077278912,275.907
+44.083083900,276.969
+44.088888889,277.717
+44.094693878,278.732
+44.100498866,279.465
+44.106303855,280.251
+44.112108844,281.181
+44.117913832,282.396
+44.123718821,283.703
+44.129523810,284.723
+44.135328798,285.174
+44.141133787,285.353
+44.146938776,285.243
+44.152743764,285.133
+44.158548753,285.347
+44.164353741,285.226
+44.170158730,285.576
+44.175963719,286.01
+44.181768707,286.239
+44.187573696,286.698
+44.193378685,287.608
+44.199183673,288.642
+44.204988662,290.53
+44.210793651,292.396
+44.216598639,293.455
+44.222403628,294.224
+44.228208617,294.759
+44.234013605,294.936
+44.239818594,296.005
+44.245623583,296.608
+44.251428571,297.008
+44.257233560,298.02
+44.263038549,298.88
+44.268843537,299.889
+44.274648526,300.736
+44.280453515,301.214
+44.286258503,301.126
+44.292063492,300.478
+44.297868481,299.568
+44.303673469,298.193
+44.309478458,296.372
+44.315283447,294.188
+44.321088435,292.15
+44.326893424,290.102
+44.332698413,288.158
+44.338503401,286.431
+44.344308390,285.373
+44.350113379,284.719
+44.355918367,284.481
+44.361723356,284.856
+44.367528345,285.525
+44.373333333,286.467
+44.379138322,288.043
+44.384943311,290.235
+44.390748299,292.507
+44.396553288,294.476
+44.402358277,296.282
+44.408163265,297.696
+44.413968254,299.361
+44.419773243,301.377
+44.425578231,303.907
+44.431383220,306.409
+44.437188209,308.478
+44.442993197,309.93
+44.448798186,310.801
+44.454603175,310.323
+44.460408163,309.295
+44.466213152,308.067
+44.472018141,306.505
+44.477823129,304.109
+44.483628118,301.346
+44.489433107,298.621
+44.495238095,295.772
+44.501043084,293.008
+44.506848073,290.024
+44.512653061,288.262
+44.518458050,287.207
+44.524263039,286.252
+44.530068027,285.164
+44.535873016,284.455
+44.541678005,283.978
+44.547482993,284.622
+44.553287982,285.976
+44.559092971,287.297
+44.564897959,289.158
+44.570702948,291.43
+44.576507937,294.722
+44.582312925,296.947
+44.588117914,302.097
+44.593922902,308.925
+44.599727891,315.915
+44.605532880,322.34
+44.611337868,327.794
+44.617142857,330.333
+44.622947846,330.356
+44.628752834,328.633
+44.634557823,325.365
+44.640362812,318.938
+44.646167800,312.451
+44.651972789,306.971
+44.657777778,299.31
+44.663582766,289.746
+44.669387755,279.086
+44.675192744,268.806
+44.680997732,261.351
+44.686802721,255.338
+44.692607710,251.438
+44.698412698,248.201
+44.704217687,246.589
+44.710022676,244.982
+44.715827664,244.931
+44.721632653,247.849
+44.727437642,254.119
+44.733242630,267.227
+44.739047619,284.728
+44.744852608,293.389
+44.750657596,304.336
+44.756462585,314.418
+44.762267574,323.104
+44.768072562,332.173
+44.773877551,338.299
+44.779682540,343.776
+44.785487528,349.208
+44.791292517,357.886
+44.797097506,362.781
+44.802902494,365.519
+44.808707483,365.972
+44.814512472,362.395
+44.820317460,358.669
+44.826122449,351.23
+44.831927438,340.716
+44.837732426,325.053
+44.843537415,310.629
+44.849342404,298.493
+44.855147392,284.935
+44.860952381,272.062
+44.866757370,262.428
+44.872562358,259.395
+44.878367347,254.375
+47.159727891,272.422
+47.165532880,276.3
+47.171337868,277.93
+47.177142857,279.042
+47.182947846,279.289
+47.188752834,279.174
+47.194557823,278.932
+47.200362812,278.364
+47.206167800,277.849
+47.211972789,277.336
+47.217777778,277.249
+47.223582766,277.314
+47.229387755,277.384
+47.235192744,277.526
+47.240997732,277.339
+47.246802721,277.007
+47.252607710,276.45
+47.258412698,275.756
+47.264217687,274.638
+47.270022676,273.581
+47.275827664,272.405
+47.281632653,271.651
+47.287437642,271.165
+47.293242630,270.756
+47.299047619,270.641
+47.304852608,270.348
+47.310657596,269.415
+47.316462585,267.377
+47.322267574,264.043
+47.328072562,261.866
+47.496417234,304.278
+47.502222222,313.701
+47.508027211,317.956
+47.513832200,320.93
+47.519637188,323.421
+47.525442177,326.274
+47.531247166,329.751
+47.537052154,333.153
+47.542857143,336.772
+47.548662132,341.159
+47.554467120,345.682
+47.560272109,348.831
+47.566077098,351.393
+47.571882086,353.824
+47.577687075,356.017
+47.583492063,357.614
+47.589297052,358.808
+47.595102041,359.83
+47.600907029,360.694
+47.606712018,361.308
+47.612517007,361.894
+47.618321995,362.297
+47.624126984,362.454
+47.629931973,362.27
+47.635736961,361.373
+47.641541950,358.813
+47.647346939,353.054
+47.653151927,347.481
+47.658956916,340.658
+47.664761905,338.645
+47.780861678,385.828
+47.786666667,379.505
+47.792471655,371.336
+47.798276644,365.424
+47.804081633,361.721
+47.809886621,358.273
+47.815691610,358.34
+47.821496599,359.136
+47.827301587,360.482
+47.833106576,361.178
+47.838911565,361.557
+47.844716553,361.673
+47.850521542,361.118
+47.856326531,360.522
+47.862131519,359.426
+47.867936508,358.343
+47.873741497,357.498
+47.879546485,356.63
+47.885351474,355.823
+47.891156463,354.736
+47.896961451,353.396
+47.902766440,351.559
+47.908571429,349.325
+47.914376417,346.812
+47.920181406,343.963
+47.925986395,341.42
+47.931791383,338.946
+47.937596372,336.868
+47.943401361,335.03
+47.949206349,333.186
+47.955011338,331.435
+47.960816327,329.849
+47.966621315,328.428
+47.972426304,327.395
+47.978231293,326.73
+47.984036281,326.165
+47.989841270,326.126
+47.995646259,326.412
+48.001451247,326.858
+48.007256236,327.329
+48.013061224,327.602
+48.018866213,327.73
+48.024671202,327.682
+48.030476190,327.698
+48.036281179,327.782
+48.042086168,328.06
+48.047891156,328.51
+48.053696145,329.085
+48.059501134,329.463
+48.065306122,329.787
+48.071111111,329.562
+48.076916100,328.552
+48.082721088,326.987
+48.088526077,324.603
+48.094331066,322.464
+48.100136054,320.143
+48.105941043,316.873
+48.111746032,314.756
+48.117551020,312.935
+48.123356009,315.068
+48.129160998,311.09
+48.140770975,280.871
+48.146575964,272.353
+48.152380952,264.945
+48.158185941,265.543
+48.163990930,267.315
+48.169795918,268.419
+48.175600907,268.247
+48.181405896,267.881
+48.187210884,267.526
+48.193015873,267.133
+48.198820862,267.34
+48.204625850,267.527
+48.210430839,267.626
+48.216235828,267.763
+48.222040816,267.645
+48.227845805,267.473
+48.233650794,267.312
+48.239455782,267.08
+48.245260771,266.748
+48.251065760,266.699
+48.256870748,266.676
+48.262675737,267.096
+48.268480726,267.977
+48.274285714,269.446
+48.280090703,271.092
+48.285895692,272.401
+48.291700680,273.059
+48.297505669,273.849
+48.303310658,274.421
+48.309115646,275.467
+48.314920635,276.596
+48.320725624,276.894
+48.326530612,276.293
+48.332335601,274.149
+48.338140590,269.706
+48.343945578,267.449
+48.349750567,257.226
+48.355555556,249.63
+48.361360544,249.299
+48.367165533,249.598
+48.372970522,248.995
+48.494875283,306.078
+48.500680272,311.574
+48.506485261,317.141
+48.512290249,320.766
+48.518095238,323.314
+48.523900227,325.358
+48.529705215,327.468
+48.535510204,329.468
+48.541315193,331.451
+48.547120181,333.561
+48.552925170,335.901
+48.558730159,338.878
+48.564535147,342.574
+48.570340136,346.411
+48.576145125,350.193
+48.581950113,353.311
+48.587755102,356.31
+48.593560091,359.5
+48.599365079,361.931
+48.605170068,363.791
+48.610975057,365.334
+48.616780045,366.836
+48.622585034,369.41
+48.628390023,370.119
+48.634195011,367.533
+48.640000000,360.627
+48.645804989,357.682
+48.651609977,356.204
+48.657414966,354.968
+48.750294785,393.039
+48.756099773,386.223
+48.761904762,387.843
+48.767709751,386.736
+48.773514739,382.851
+48.779319728,379.491
+48.785124717,375.106
+48.790929705,372.083
+48.796734694,369.981
+48.802539683,366.381
+48.808344671,362.147
+48.814149660,359.308
+48.819954649,356.486
+48.825759637,353.456
+48.831564626,349.942
+48.837369615,345.971
+48.843174603,342.227
+48.848979592,339.349
+48.854784580,336.818
+48.860589569,334.833
+48.866394558,333.406
+48.872199546,332.492
+48.878004535,331.804
+48.883809524,331.284
+48.889614512,330.873
+48.895419501,330.446
+48.901224490,330.407
+48.907029478,330.357
+48.912834467,330.309
+48.918639456,330.107
+48.924444444,329.71
+48.930249433,329.101
+48.936054422,328.554
+48.941859410,328.384
+48.947664399,328.139
+48.953469388,328.062
+48.959274376,327.944
+48.965079365,327.767
+48.970884354,327.659
+48.976689342,327.488
+48.982494331,327.464
+48.988299320,327.797
+48.994104308,328.411
+48.999909297,329.221
+49.005714286,330.073
+49.011519274,330.413
+49.017324263,330.707
+49.023129252,330.907
+49.028934240,330.366
+49.034739229,329.597
+49.040544218,327.845
+49.046349206,325.14
+49.052154195,322.602
+49.057959184,319.789
+49.063764172,316.425
+49.069569161,313.793
+49.075374150,311.577
+49.081179138,306.186
+49.086984127,304.386
+49.092789116,297.139
+49.098594104,287.993
+49.104399093,277.522
+49.110204082,268.494
+49.116009070,266.759
+49.121814059,267.033
+49.127619048,273.672
+49.133424036,276.234
+49.139229025,277.037
+49.145034014,277.192
+49.150839002,277.541
+49.156643991,277.457
+49.162448980,277.144
+49.168253968,276.818
+49.174058957,276.262
+49.179863946,275.514
+49.185668934,274.587
+49.191473923,273.757
+49.197278912,273.356
+49.203083900,273.35
+49.208888889,273.14
+49.214693878,272.917
+49.220498866,272.561
+49.226303855,272.212
+49.232108844,272.009
+49.237913832,272.01
+49.243718821,272.194
+49.249523810,272.732
+49.255328798,273.637
+49.261133787,274.357
+49.266938776,275.064
+49.272743764,275.022
+49.278548753,274.517
+49.284353741,274.089
+49.290158730,273.917
+49.295963719,273.867
+49.301768707,273.874
+49.307573696,273.069
+49.446893424,291.435
+49.452698413,302.651
+49.458503401,313.149
+49.464308390,316.08
+49.470113379,318.62
+49.475918367,320.466
+49.481723356,323.992
+49.487528345,330.484
+49.493333333,338.168
+49.499138322,342.332
+49.504943311,346.281
+49.510748299,349.676
+49.516553288,352.826
+49.522358277,355.738
+49.528163265,358.902
+49.533968254,361.809
+49.539773243,363.9
+49.545578231,365.44
+49.551383220,366.581
+49.557188209,368.848
+49.562993197,373.138
+49.568798186,374.142
+49.574603175,375.781
+49.713922902,431.185
+49.719727891,447.442
+49.725532880,440.759
+49.731337868,434.282
+49.737142857,435.465
+49.742947846,419.335
+49.748752834,406.579
+49.754557823,391.456
+49.760362812,374.798
+49.766167800,368.593
+49.771972789,365.696
+49.777777778,362.469
+49.783582766,358.415
+49.789387755,355.072
+49.795192744,351.944
+49.800997732,348.32
+49.806802721,344.55
+49.812607710,341.708
+49.818412698,339.563
+49.824217687,337.821
+49.830022676,336.671
+49.835827664,335.652
+49.841632653,334.966
+49.847437642,334.457
+49.853242630,333.969
+49.859047619,333.656
+49.864852608,333.504
+49.870657596,333.255
+49.876462585,333.085
+49.882267574,332.782
+49.888072562,332.395
+49.893877551,332.166
+49.899682540,331.946
+49.905487528,332.013
+49.911292517,332.032
+49.917097506,331.731
+49.922902494,331.233
+49.928707483,330.438
+49.934512472,329.43
+49.940317460,328.654
+49.946122449,327.802
+49.951927438,327.101
+49.957732426,326.714
+49.963537415,326.524
+49.969342404,326.565
+49.975147392,327.138
+49.980952381,327.951
+49.986757370,328.616
+49.992562358,329.299
+49.998367347,329.358
+50.004172336,328.801
+50.009977324,327.434
+50.015782313,325.211
+50.021587302,322.203
+50.027392290,319.357
+50.033197279,316.259
+50.039002268,312.891
+50.044807256,312.532
+50.050612245,299.907
+50.056417234,285.34
+50.062222222,275.281
+50.068027211,270.409
+50.073832200,263.621
+50.079637188,260.299
+50.085442177,259.766
+50.091247166,266.637
+50.097052154,270.294
+50.102857143,273.407
+50.108662132,274.26
+50.114467120,275.467
+50.120272109,275.596
+50.126077098,275.7
+50.131882086,275.33
+50.137687075,274.731
+50.143492063,274.14
+50.149297052,273.853
+50.155102041,273.695
+50.160907029,273.46
+50.166712018,273.369
+50.172517007,272.823
+50.178321995,272.589
+50.184126984,272.44
+50.189931973,272.564
+50.195736961,272.795
+50.201541950,272.351
+50.207346939,271.867
+50.213151927,270.889
+50.218956916,270.306
+50.224761905,269.484
+50.230566893,268.36
+50.236371882,264.96
+50.242176871,268.702
+50.398911565,289.472
+50.404716553,300.911
+50.410521542,309.851
+50.416326531,314.214
+50.422131519,317.27
+50.427936508,320.06
+50.433741497,324.458
+50.439546485,329.741
+50.445351474,335.456
+50.451156463,341.546
+50.456961451,347.293
+50.462766440,351.479
+50.468571429,355.155
+50.474376417,358.178
+50.480181406,360.797
+50.485986395,363.242
+50.491791383,365.138
+50.497596372,366.566
+50.503401361,368.149
+50.665941043,364.541
+50.671746032,373.96
+50.677551020,385.592
+50.683356009,376.771
+50.689160998,384.038
+50.694965986,379.491
+50.700770975,370.895
+50.706575964,363.977
+50.712380952,348.839
+50.718185941,336.562
+50.723990930,332.908
+50.729795918,333.883
+50.735600907,336.045
+50.741405896,337.397
+50.747210884,337.877
+50.753015873,338.053
+50.758820862,338.882
+50.764625850,339.22
+50.770430839,339.555
+50.776235828,339.338
+50.782040816,338.799
+50.787845805,338.159
+50.793650794,337.493
+50.799455782,337.061
+50.805260771,336.685
+50.811065760,336.44
+50.816870748,336.317
+50.822675737,336.155
+50.828480726,336.031
+50.834285714,335.831
+50.840090703,335.417
+50.845895692,334.996
+50.851700680,334.788
+50.857505669,334.63
+50.863310658,334.627
+50.869115646,334.449
+50.874920635,334.074
+50.880725624,333.79
+50.886530612,333.509
+50.892335601,333.296
+50.898140590,333.132
+50.903945578,333.091
+50.909750567,333.054
+50.915555556,333.133
+50.921360544,333.285
+50.927165533,332.854
+50.932970522,332.062
+50.938775510,330.625
+50.944580499,328.89
+50.950385488,326.751
+50.956190476,324.106
+50.961995465,321.509
+50.967800454,318.564
+50.973605442,315.709
+50.979410431,313.164
+50.985215420,312.954
+50.991020408,305.614
+50.996825397,305.575
+51.002630385,295.031
+51.008435374,276.214
+51.014240363,264.193
+51.020045351,257.721
+51.025850340,250.839
+51.031655329,246.007
+51.037460317,244.31
+51.043265306,244.836
+51.049070295,251.546
+51.054875283,260.762
+51.066485261,285.914
+51.072290249,291.233
+51.078095238,294.448
+51.083900227,296.651
+51.089705215,296.973
+51.095510204,296.479
+51.101315193,295.652
+51.107120181,294
+51.112925170,293.404
+51.118730159,293.895
+51.124535147,294.39
+51.130340136,294.59
+51.136145125,294.261
+51.141950113,293.488
+51.147755102,292.697
+51.153560091,291.971
+51.159365079,291.386
+51.165170068,290.974
+51.170975057,290.757
+51.176780045,290.494
+51.182585034,290.655
+51.188390023,291.415
+51.194195011,292.005
+51.200000000,292.543
+51.205804989,292.904
+51.211609977,292.664
+51.217414966,292.387
+51.223219955,291.722
+51.229024943,290.677
+51.234829932,289.804
+51.240634921,286.994
+51.246439909,279.367
+51.252244898,271.824
+51.258049887,274.273
+51.263854875,274.795
+51.339319728,267.066
+51.345124717,274.085
+51.350929705,278.798
+51.356734694,282.554
+51.362539683,283.282
+51.368344671,282.579
+51.374149660,281.547
+51.379954649,279.964
+51.385759637,277.979
+51.391564626,276.832
+51.397369615,276.351
+51.403174603,276.073
+51.408979592,275.929
+51.414784580,275.776
+51.420589569,275.546
+51.426394558,275.216
+51.432199546,274.935
+51.438004535,274.792
+51.443809524,274.949
+51.449614512,275.22
+51.455419501,275.464
+51.461224490,275.239
+51.467029478,274.851
+51.472834467,274.309
+51.478639456,273.797
+51.484444444,274.058
+51.490249433,274.47
+51.496054422,275.131
+51.501859410,275.858
+51.507664399,276.395
+51.513469388,276.448
+51.519274376,276.226
+51.525079365,275.279
+51.530884354,274.269
+51.536689342,273.388
+51.542494331,272.178
+51.548299320,271.168
+51.554104308,271.573
+51.559909297,272.332
+51.565714286,271.342
+51.571519274,269.909
+51.577324263,267.035
+51.583129252,263.606
+51.588934240,258.066
+51.594739229,251.243
+51.600544218,240.987
+51.606349206,230.087
+51.612154195,219.227
+51.722448980,254.606
+51.728253968,261.562
+51.734058957,266.406
+51.739863946,274.787
+51.745668934,283.182
+51.751473923,292.892
+51.757278912,299.683
+51.768888889,326.132
+51.774693878,332.467
+51.780498866,338.024
+51.786303855,342.104
+51.792108844,345.871
+51.797913832,348.726
+51.803718821,350.389
+51.809523810,351.077
+51.815328798,350.762
+51.821133787,350.003
+51.826938776,348.678
+51.832743764,346.923
+51.838548753,344.8
+51.844353741,342.008
+51.850158730,338.465
+51.855963719,334.709
+51.861768707,330.545
+51.867573696,325.356
+51.873378685,319.513
+51.879183673,314.245
+51.884988662,310.568
+51.890793651,307.162
+51.896598639,303.485
+51.902403628,299.68
+51.908208617,297.141
+51.914013605,295.817
+51.919818594,294.884
+51.925623583,294.622
+51.931428571,294.222
+51.937233560,294.128
+51.943038549,294.658
+51.948843537,295.067
+51.954648526,295.583
+51.960453515,295.768
+51.966258503,295.494
+51.972063492,295.696
+51.977868481,296.242
+51.983673469,299.48
+51.989478458,301.884
+51.995283447,301.727
+52.001088435,301.562
+52.006893424,301.499
+52.012698413,301.423
+52.018503401,302.897
+52.024308390,304.158
+52.030113379,304.468
+52.035918367,305.743
+52.041723356,306.213
+52.047528345,305.687
+52.053333333,304.559
+52.059138322,301.837
+52.064943311,298.091
+52.070748299,295.481
+52.076553288,294.257
+52.082358277,293.297
+52.088163265,292.724
+52.093968254,292.068
+52.099773243,291.213
+52.105578231,290.31
+52.111383220,289.323
+52.117188209,288.128
+52.122993197,287.095
+52.128798186,286.565
+52.134603175,286.608
+52.140408163,287.08
+52.146213152,287.986
+52.152018141,289.106
+52.157823129,290.493
+52.163628118,291.797
+52.169433107,293.233
+52.175238095,294.931
+52.181043084,296.745
+52.186848073,298.783
+52.192653061,301.114
+52.198458050,302.924
+52.204263039,304.183
+52.210068027,304.981
+52.215873016,305.515
+52.221678005,305.522
+52.227482993,304.915
+52.233287982,303.562
+52.239092971,301.533
+52.244897959,298.327
+52.250702948,295.398
+52.256507937,292.524
+52.262312925,289.001
+52.268117914,285.968
+52.273922902,283.323
+52.279727891,281.605
+52.285532880,280.107
+52.291337868,279.149
+52.297142857,278.149
+52.302947846,277.477
+52.308752834,276.975
+52.314557823,275.902
+52.320362812,276.263
+52.326167800,279.877
+52.331972789,296.487
+52.337777778,315.074
+52.343582766,317.621
+52.349387755,330.156
+52.355192744,332.566
+52.360997732,337.272
+52.366802721,340.664
+52.372607710,342.718
+52.378412698,347.329
+52.384217687,351.214
+52.390022676,351.945
+52.395827664,351.37
+52.401632653,348.464
+52.407437642,343.052
+52.413242630,339.706
+52.419047619,332.662
+52.424852608,326.277
+52.430657596,318.547
+52.436462585,307.521
+52.442267574,296.418
+52.448072562,281.764
+52.453877551,268.577
+52.459682540,257.201
+52.465487528,249.244
+52.471292517,244.162
+52.477097506,242.498
+52.482902494,244.676
+52.488707483,249.856
+52.494512472,256.994
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/regression.sh	Fri Mar 24 15:08:12 2017 +0000
@@ -0,0 +1,29 @@
+#!/bin/bash
+
+set -eu
+
+testdir=$(dirname "$0")
+
+if ! sonic-annotator -v >/dev/null ; then
+    echo "No sonic-annotator available in PATH, skipping regression test"
+    exit 0
+fi
+
+echo "Running regression test..."
+
+( time ( VAMP_PATH="$testdir/.." sonic-annotator \
+	 -d vamp:pyin:pyin:smoothedpitchtrack \
+	 -w csv --csv-stdout --csv-omit-filename \
+	 "$testdir/../testdata/bob_02.wav" \
+	 > "$testdir/obtained.csv" \
+	 2> "$testdir/log.txt" ) ) 2>&1 | \
+    grep -i real | \
+    sed 's/^real/Elapsed time/'
+
+if ! cmp -s "$testdir/expected.csv" "$testdir/obtained.csv" ; then
+    echo "*** FAILED, diff follows:"
+    sdiff -w78 "$testdir/expected.csv" "$testdir/obtained.csv"
+else
+    echo "Succeeded"
+fi
+
--- a/win32-build/pyin.pro	Thu Aug 20 16:06:01 2015 +0100
+++ b/win32-build/pyin.pro	Fri Mar 24 15:08:12 2017 +0000
@@ -13,7 +13,6 @@
     ../Yin.cpp \
     ../SparseHMM.cpp \
     ../MonoPitchHMM.cpp \
-    ../MonoPitch.cpp \
     ../MonoNoteParameters.cpp \
     ../MonoNoteHMM.cpp \
     ../MonoNote.cpp \
@@ -27,7 +26,6 @@
     ../Yin.h \
     ../SparseHMM.h \
     ../MonoPitchHMM.h \
-    ../MonoPitch.h \
     ../MonoNoteParameters.h \
     ../MonoNoteHMM.h \
     ../MonoNote.h \