Skip to content

Commit

Permalink
working without the p_{ij}\alpha{i} term
Browse files Browse the repository at this point in the history
  • Loading branch information
charlesneimog committed Aug 31, 2024
1 parent 88de734 commit 337804c
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 140 deletions.
196 changes: 72 additions & 124 deletions Sources/OScofo/mdp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ void OScofoMDP::SetScoreStates(States States) {
m_PsiN = 60.0f / m_States[0].BPMExpected;
m_PsiN1 = 60.0f / m_States[0].BPMExpected;
m_LastPsiN = 60.0f / m_States[0].BPMExpected;
m_BeatsAhead = m_States[0].BPMExpected / 60 * 4;
m_BeatsAhead = m_States[0].BPMExpected / 60 * 2;

CreateMarkovMatrix();
}
Expand All @@ -47,20 +47,14 @@ void OScofoMDP::CreateMarkovMatrix() {
for (int i = -1; i < size; i++) {
double Dur = 0;
for (int j = i + 1; j < m_States.size(); j++) {
Dur += m_States[j].Duration;
double DurProb = std::exp(-(5 * Dur / m_BeatsAhead));
double DurProb = 1 - m_States[j].Duration / m_BeatsAhead;
double LastDur = Dur / m_BeatsAhead;
if (LastDur > 1 && i < j + 3) {
break;
} else if (LastDur > 1 && i >= j + 3) {
for (int k = i; k < i + 3; k++) {
double BigDurProb = std::exp(k);
m_TransitionsProb[i][k] = BigDurProb;
}
break;
if (i == j - 1) {
m_TransitionsProb[i][j] = 1;
} else {
m_TransitionsProb[i][j] = DurProb;
m_TransitionsProb[i][j] = 0;
}
// printf("%d -> %d: %f\n", i, j, m_TransitionsProb[i][j]);
}
double Sum = 0;
int innerSize = m_TransitionsProb[i].size();
Expand All @@ -70,7 +64,6 @@ void OScofoMDP::CreateMarkovMatrix() {
}
for (int j = i + 1; j <= i + innerSize; j++) {
m_TransitionsProb[i][j] /= Sum;
// printf("Trans %d -> %d = %f\n", i, j, m_TransitionsProb[i][j]);
}
}

Expand Down Expand Up @@ -106,7 +99,6 @@ void OScofoMDP::UpdatePitchTemplate() {
}
}
}
printf("Pitch Template Updated\n");
}

// ─────────────────────────────────────
Expand Down Expand Up @@ -165,7 +157,7 @@ void OScofoMDP::SetHarmonics(int Harmonics) {
// ─────────────────────────────────────
void OScofoMDP::SetCurrentEvent(int Event) {
m_CurrentEvent = Event;
m_NewCurrentEvent = Event;
m_LastDecodedPosition = Event;
}

// ─────────────────────────────────────
Expand Down Expand Up @@ -380,121 +372,97 @@ double OScofoMDP::GetPitchSimilarity(State &State, Description &Desc) {
}

// ─────────────────────────────────────
double OScofoMDP::SojournTime(State &State, Description &Desc) {
double OScofoMDP::GetSojournTime(State &State, Description &Desc) {
double T = m_Tn + m_TimeInThisEvent;
double Duration = State.Duration;
double Sojourn = std::exp(-((T - m_Tn) / (m_PsiN1 * Duration)));

return Sojourn;
}

// ─────────────────────────────────────
// Guédon (2004)
double OScofoMDP::ForwardRecursion(Description &Desc) {
double OScofoMDP::SemiMarkovState(Description &Desc, int j) {
if (m_T == 0) {
return m_LastDecodedPosition;
}

double BestProb = 0;
for (int j = m_NewCurrentEvent; j < m_StateWindow; j++) {
unsigned int t = m_T;
if (t > 20) {
t = 20;
}

return 0;
// Observation probability b_j(x_t)
double KLDiv = GetPitchSimilarity(m_States[j], Desc);
m_PitchKL[j][m_T] = KLDiv;

// Maximum value initialization
double maxAlphaJ = -INFINITY;

// Loop over possible time steps u
for (int u = 1; u <= t; u++) {
// Product term ∏_{v=1}^{u-1} b_j(x_{t-v})
double ProdTerm = 1;
for (int v = 1; v < u; v++) {
ProdTerm *= m_PitchKL[j][m_T - v];
}

// Survival function d_j(u) (this should be defined based on your model)
double SojournTime = GetSojournTime(m_States[j], Desc);

// Transition probabilities max_{i ≠ j} (p_{ij} a_i(t-u))
double MaxProb = -INFINITY;
for (int i = m_CurrentEvent; i < m_StateWindow; i++) {
if (i != j) {
double EventProb = m_TransitionsProb[i][j] * m_PrevObserved[i][m_T - u];
if (MaxProb < EventProb) {
MaxProb = EventProb;
}
}
}
double AlphaJ = ProdTerm * SojournTime; //* MaxProb;
if (AlphaJ > maxAlphaJ) {
maxAlphaJ = AlphaJ;
}
}
return KLDiv * maxAlphaJ;
}

// ─────────────────────────────────────
double OScofoMDP::ComputeStateTransition(Description &Desc) {
int t = m_T;
double OScofoMDP::MarkovState(Description &Desc, int j) {
m_PitchKL[j][m_T] = GetPitchSimilarity(m_States[j], Desc);

int BestEvent = -1;
return 0;
}

// ─────────────────────────────────────
double OScofoMDP::GetBestEventIndex(Description &Desc) {
int BestEvent = m_LastDecodedPosition;
bool BestEventFound = false;

double BestAlphaJ = 0;
for (int j = m_NewCurrentEvent; j < m_StateWindow; j++) {
for (int j = m_LastDecodedPosition; j < m_StateWindow + 1; j++) {
if (j < 0) {
j++;
t = 1;
}
m_PitchKL[j][t] = GetPitchSimilarity(m_States[j], Desc);
double maxAlphaJ = 0;
for (int u = 1; u <= t; u++) {

// term 1
double MulKlDiv = m_PitchKL[j][t];
for (int v = 1; v < u; v++) {
MulKlDiv *= m_PitchKL[j][t - v];
}

// term 2
double Sojourn = SojournTime(m_States[j], Desc);

// term 3
double MaxProb = 0;
for (int i = m_NewCurrentEvent; i < m_NewCurrentEvent + 1; i++) {
if (i == j) {
continue;
}
double PrevObserved;
if (m_Observed.find(i) != m_Observed.end()) {
if (m_Observed[i].find(u) != m_Observed[i].end()) {
PrevObserved = m_Observed[i][u];
} else {
PrevObserved = 1;
}
} else {
PrevObserved = 1;
}
double Prob = m_TransitionsProb[i][j] * PrevObserved;

if (Prob > MaxProb) {
MaxProb = Prob;
}
}

double AlphaJT = MulKlDiv * Sojourn * MaxProb;
m_Observed[j][u] = AlphaJT;
if (AlphaJT > maxAlphaJ) {
maxAlphaJ = AlphaJT;
}
double AlphaJ;
if (m_States[j].MarkovType == SEMIMARKOV) {
AlphaJ = SemiMarkovState(Desc, j);
} else if (m_States[j].MarkovType == MARKOV) {
AlphaJ = MarkovState(Desc, j);
}
m_PrevObserved[j][m_T] = AlphaJ;

printf("Alpha %f for event %d\n", maxAlphaJ, j);
double AlphaJT = m_PitchKL[j][t] * maxAlphaJ;
if (AlphaJT > BestAlphaJ) {
BestAlphaJ = AlphaJT;
if (AlphaJ > BestAlphaJ) {
BestAlphaJ = AlphaJ;
BestEvent = j;
BestEventFound = true;
}
}

if (BestEventFound && BestEvent != m_NewCurrentEvent) {
m_NewCurrentEvent = BestEvent;
printf("Best Event: %d\n", BestEvent);
if (BestEventFound && BestEvent != m_LastDecodedPosition) {
m_LastDecodedPosition = BestEvent;
}

return m_NewCurrentEvent;
}

// ─────────────────────────────────────
double OScofoMDP::GetReward(States &PossibleStates, Description &Desc) {
double PitchWeight;
double TimeWeight;
double Event = m_CurrentEvent;
State CurrentState = PossibleStates[0];

EventType Type = CurrentState.Type;
double PreviousKlDiv = 0;

for (int i = 0; i < PossibleStates.size(); i++) {
if (PossibleStates[i].Type == NOTE) {
double Sojourn = SojournTime(PossibleStates[i], Desc);
double P = GetPitchSimilarity(PossibleStates[i], Desc);
if (P > PreviousKlDiv) {
PreviousKlDiv = P;
Event = PossibleStates[i].Index;
}
} else if (PossibleStates[i].Type == ONSET) {
}
}

return Event;
return m_LastDecodedPosition;
}

// ─────────────────────────────────────
Expand All @@ -513,13 +481,7 @@ int OScofoMDP::GetEvent(Description &Desc) {
m_Kappa = 1;
}

// Get the best event to describe the current state
int Event, UpperBound = m_CurrentEvent;
double BestReward = -1;
double EventLookAhead = 0;
int StatesSize = m_States.size();
States PossibleNextStates;

int NewUpperBound = m_CurrentEvent;
double NewEventLookAhead = 0;

Expand All @@ -530,26 +492,13 @@ int OScofoMDP::GetEvent(Description &Desc) {
if (NewUpperBound < 0) {
NewUpperBound = 0;
}
State &CurrentState = m_States[NewUpperBound];
NewEventLookAhead += CurrentState.Duration * m_PsiN;
m_StateWindow = NewUpperBound;
NewUpperBound++;
State &State = m_States[NewUpperBound];
NewEventLookAhead += State.Duration * m_PsiN;
}

while ((EventLookAhead - m_TimeInThisEvent) < (m_BeatsAhead * m_PsiN)) {
if (UpperBound >= StatesSize) {
break;
}
if (UpperBound < 0) {
UpperBound = 0;
}
State &CurrentState = m_States[UpperBound];
EventLookAhead += CurrentState.Duration * m_PsiN;
PossibleNextStates.push_back(CurrentState);
UpperBound++;
}
Event = GetReward(PossibleNextStates, Desc);
ComputeStateTransition(Desc);
int Event = GetBestEventIndex(Desc);

if (Event == m_CurrentEvent) {
return m_CurrentEvent;
Expand All @@ -576,7 +525,6 @@ int OScofoMDP::GetEvent(Description &Desc) {
m_TimeInThisEvent = 0;
m_T = 0;
LOGE();
printf("Current Event: %d\n", m_CurrentEvent);
}

m_CurrentEvent = Event;
Expand Down
9 changes: 6 additions & 3 deletions Sources/OScofo/mdp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,17 +66,20 @@ class OScofoMDP {

// Markov
void CreateMarkovMatrix();
double ComputeStateTransition(Description &Desc);
double GetBestEventIndex(Description &Desc);
double ForwardRecursion(Description &Desc);
double SemiMarkovState(Description &Desc, int j);
double MarkovState(Description &Desc, int j);

int m_StateWindow = 0;
int m_T = 0;
int m_BlocksInThisEvent = 0;
int m_NewCurrentEvent = 0;
int m_LastDecodedPosition = -1;
MatrixMap m_Believes;
MatrixMap m_PitchKL;
MatrixMap m_TransitionsProb;
MatrixMap m_Observed;
MatrixMap m_PrevObserved;

double m_BeatsAhead = 8;
double m_TimeInThisEvent = 0;
Expand Down Expand Up @@ -114,7 +117,7 @@ class OScofoMDP {
std::vector<State> m_States;
double GetReward(States &NextPossibleStates, Description &Desc);
double GetPitchSimilarity(State &NextPossibleState, Description &Desc);
double SojournTime(State &PossibleState, Description &Desc);
double GetSojournTime(State &PossibleState, Description &Desc);

// Viterbi | SemiMarkov
double ComputeViterbiRecursion(State &JState, Description &Desc);
Expand Down
31 changes: 18 additions & 13 deletions Sources/OScofo/score.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,27 +172,32 @@ void OScofoScore::Parse(States &States, std::string ScoreFile) {
}

if (Tokens[0] == "NOTE") {
State State;
State.Index = States.size();
State.Type = NOTE;
State.Line = LineCount;
State = AddNote(State, Tokens, BPM, LineCount);
if (!State.Valid) {
State.Error = "Error on line " + std::to_string(LineCount) + ": " + State.Error;
States.push_back(State);
State Note;
Note.Index = States.size();
Note.Type = NOTE;
Note.MarkovType = SEMIMARKOV;
Note.Line = LineCount;
Note = AddNote(Note, Tokens, BPM, LineCount);
if (!Note.Valid) {
Note.Error = "Error on line " + std::to_string(LineCount) + ": " + Note.Error;
States.push_back(Note);
continue;
}

if (Event != 0) {
State.OnsetExpected = LastOnset + PreviousDuration * (60 / BPM); // in Seconds
Note.OnsetExpected = LastOnset + PreviousDuration * (60 / BPM); // in Seconds
} else {
State.OnsetExpected = 0;
Note.OnsetExpected = 0;
}

Event++;
States.push_back(State);
PreviousDuration = State.Duration;
LastOnset = State.OnsetExpected;
States.push_back(Note);
PreviousDuration = Note.Duration;
LastOnset = Note.OnsetExpected;

// State DummySilence;
// DummySilence.MarkovType = MARKOV;
// States.push_back(Note);

} else if (Tokens[0] == "BPM") {
BPM = std::stof(Tokens[1]);
Expand Down

0 comments on commit 337804c

Please sign in to comment.