protovoices-0.1.0.0
Safe HaskellNone
LanguageGHC2021

PVGrammar.Prob.Simple

Description

This module contains a simple (and musically rather naive) probabilistic model of protovoice derivations. This model can be used to sample a derivation, evaluate a derivations probability, or infer posterior distributions of the model parmeters from given derivations (i.e., "learn" the model's probabilities).

This model is a locally conjugate model: It samples a derivation using a sequence of random decisions with certain probabilities. These probabilities are generally unknown, so they are themselves modeled as random variables with prior distributions. The full model \(p(d, \theta)\) thus splits into \[p(D, \theta) = p(d \mid \theta) \cdot p(\theta),\] the prior over the probability variables \[p(\theta) = \prod_i p(\theta_i),\] and the likelihood of the derivation(s) given these probabilities \[p(D \mid \theta) = \prod_{d \in D} p(d \mid \theta) = \prod_{d \in D} \prod_i p(d_i \mid \theta, d_0, \ldots, d_{i-1}).\] Given all prior decisions, the likelihood of a decision \(d_i\) based on some parameter \(\theta_a\) \[p(d_i \mid \theta, d_{<i})\] is conjugate with the prior of that parameter \(p(\theta_a)\), which means that the posterior of the parameters given one (or several) derivation(s) \(p(\theta \mid D)\) can be computed analytically.

The parameters \(\theta\) and their prior distributions are represented by the higher-kinded type PVParams. Different instantiations of this type (using Hyper or Probs) results in concrete record types that represent prior or posterior distributions or concrete values (probabilities) for the parameters. PVParams also supports jeffreysPrior and uniformPrior as default priors, as well as sampleProbs for sampling from a prior (see Inferenc.Conjugate).

The likelihood \(p(d \mid \theta)\) of a derivation is represented by sampleDerivation. It can be executed under different "modes" (probability monads) for sampling, inference, or tracing (see Inference.Conjugate). The decisions during the derivation are represented by a Trace (here Trace PVParams). In order to learn from a given derivation, the corresponding trace can be obtained using observeDerivation. A combination of getting a trace and learning from it is provided by trainSinglePiece.

Synopsis

Model Parameters

A higher-kinded type that represents the global parameters (probabilities) of the model. Use it as 'Hyper PVParams' to represent hyperparameters (priors and posteriors) or as 'Probs PVParams' to represent actual probabilites. Each record field corresponds to one parameter that influences a specific type of decision in the generation process.

data PVParams (f :: Type -> Type) Source #

The combined parameters for inner and outer operations.

Constructors

PVParams 

Instances

Instances details
(FromJSON (f Beta), FromJSON (f (Dirichlet 3))) => FromJSON (PVParams f) Source # 
Instance details

Defined in PVGrammar.Prob.Simple

(ToJSON (f Beta), ToJSON (f (Dirichlet 3))) => ToJSON (PVParams f) Source # 
Instance details

Defined in PVGrammar.Prob.Simple

Generic (PVParams f) Source # 
Instance details

Defined in PVGrammar.Prob.Simple

Associated Types

type Rep (PVParams f) 
Instance details

Defined in PVGrammar.Prob.Simple

type Rep (PVParams f) = D1 ('MetaData "PVParams" "PVGrammar.Prob.Simple" "protovoices-0.1.0.0-BDEUxFN8Fm0COc6pAhx3U0" 'False) (C1 ('MetaCons "PVParams" 'PrefixI 'True) (S1 ('MetaSel ('Just "_pOuter") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (PVParamsOuter f)) :*: S1 ('MetaSel ('Just "_pInner") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (PVParamsInner f))))

Methods

from :: PVParams f -> Rep (PVParams f) x #

to :: Rep (PVParams f) x -> PVParams f #

(Show (f Beta), Show (f (Dirichlet 3))) => Show (PVParams f) Source # 
Instance details

Defined in PVGrammar.Prob.Simple

Methods

showsPrec :: Int -> PVParams f -> ShowS #

show :: PVParams f -> String #

showList :: [PVParams f] -> ShowS #

type Rep (PVParams f) Source # 
Instance details

Defined in PVGrammar.Prob.Simple

type Rep (PVParams f) = D1 ('MetaData "PVParams" "PVGrammar.Prob.Simple" "protovoices-0.1.0.0-BDEUxFN8Fm0COc6pAhx3U0" 'False) (C1 ('MetaCons "PVParams" 'PrefixI 'True) (S1 ('MetaSel ('Just "_pOuter") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (PVParamsOuter f)) :*: S1 ('MetaSel ('Just "_pInner") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (PVParamsInner f))))

data PVParamsOuter (f :: Type -> Type) Source #

Parameters for decisions about outer operations (split, spread, freeze).

Instances

Instances details
FromJSON (f Beta) => FromJSON (PVParamsOuter f) Source # 
Instance details

Defined in PVGrammar.Prob.Simple

ToJSON (f Beta) => ToJSON (PVParamsOuter f) Source # 
Instance details

Defined in PVGrammar.Prob.Simple

Generic (PVParamsOuter f) Source # 
Instance details

Defined in PVGrammar.Prob.Simple

Associated Types

type Rep (PVParamsOuter f) 
Instance details

Defined in PVGrammar.Prob.Simple

type Rep (PVParamsOuter f) = D1 ('MetaData "PVParamsOuter" "PVGrammar.Prob.Simple" "protovoices-0.1.0.0-BDEUxFN8Fm0COc6pAhx3U0" 'False) (C1 ('MetaCons "PVParamsOuter" 'PrefixI 'True) ((S1 ('MetaSel ('Just "_pSingleFreeze") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta)) :*: S1 ('MetaSel ('Just "_pDoubleLeft") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta))) :*: (S1 ('MetaSel ('Just "_pDoubleLeftFreeze") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta)) :*: S1 ('MetaSel ('Just "_pDoubleRightSplit") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta)))))
Show (f Beta) => Show (PVParamsOuter f) Source # 
Instance details

Defined in PVGrammar.Prob.Simple

type Rep (PVParamsOuter f) Source # 
Instance details

Defined in PVGrammar.Prob.Simple

type Rep (PVParamsOuter f) = D1 ('MetaData "PVParamsOuter" "PVGrammar.Prob.Simple" "protovoices-0.1.0.0-BDEUxFN8Fm0COc6pAhx3U0" 'False) (C1 ('MetaCons "PVParamsOuter" 'PrefixI 'True) ((S1 ('MetaSel ('Just "_pSingleFreeze") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta)) :*: S1 ('MetaSel ('Just "_pDoubleLeft") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta))) :*: (S1 ('MetaSel ('Just "_pDoubleLeftFreeze") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta)) :*: S1 ('MetaSel ('Just "_pDoubleRightSplit") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta)))))

data PVParamsInner (f :: Type -> Type) Source #

Parameters for decisions about inner operations (elaboration and distribution within splits and spreads).

Instances

Instances details
(FromJSON (f Beta), FromJSON (f (Dirichlet 3))) => FromJSON (PVParamsInner f) Source # 
Instance details

Defined in PVGrammar.Prob.Simple

(ToJSON (f Beta), ToJSON (f (Dirichlet 3))) => ToJSON (PVParamsInner f) Source # 
Instance details

Defined in PVGrammar.Prob.Simple

Generic (PVParamsInner f) Source # 
Instance details

Defined in PVGrammar.Prob.Simple

Associated Types

type Rep (PVParamsInner f) 
Instance details

Defined in PVGrammar.Prob.Simple

type Rep (PVParamsInner f) = D1 ('MetaData "PVParamsInner" "PVGrammar.Prob.Simple" "protovoices-0.1.0.0-BDEUxFN8Fm0COc6pAhx3U0" 'False) (C1 ('MetaCons "PVParamsInner" 'PrefixI 'True) ((((S1 ('MetaSel ('Just "_pElaborateRegular") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta)) :*: S1 ('MetaSel ('Just "_pElaborateL") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta))) :*: (S1 ('MetaSel ('Just "_pElaborateR") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta)) :*: (S1 ('MetaSel ('Just "_pRootFifths") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta)) :*: S1 ('MetaSel ('Just "_pKeepL") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta))))) :*: ((S1 ('MetaSel ('Just "_pKeepR") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta)) :*: (S1 ('MetaSel ('Just "_pRepeatOverNeighbor") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta)) :*: S1 ('MetaSel ('Just "_pNBChromatic") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta)))) :*: (S1 ('MetaSel ('Just "_pNBAlt") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta)) :*: (S1 ('MetaSel ('Just "_pRepeatLeftOverRight") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta)) :*: S1 ('MetaSel ('Just "_pRepeatAlter") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta)))))) :*: (((S1 ('MetaSel ('Just "_pRepeatAlterUp") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta)) :*: (S1 ('MetaSel ('Just "_pRepeatAlterSemis") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta)) :*: S1 ('MetaSel ('Just "_pConnect") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta)))) :*: (S1 ('MetaSel ('Just "_pConnectChromaticLeftOverRight") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta)) :*: (S1 ('MetaSel ('Just "_pPassUp") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta)) :*: S1 ('MetaSel ('Just "_pPassLeftOverRight") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta))))) :*: ((S1 ('MetaSel ('Just "_pNewPassingLeft") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta)) :*: (S1 ('MetaSel ('Just "_pNewPassingRight") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta)) :*: S1 ('MetaSel ('Just "_pNewPassingMid") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta)))) :*: (S1 ('MetaSel ('Just "_pNoteSpreadDirection") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f (Dirichlet 3))) :*: (S1 ('MetaSel ('Just "_pNotesOnOtherSide") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta)) :*: S1 ('MetaSel ('Just "_pSpreadRepetitionEdge") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta))))))))
(Show (f Beta), Show (f (Dirichlet 3))) => Show (PVParamsInner f) Source # 
Instance details

Defined in PVGrammar.Prob.Simple

type Rep (PVParamsInner f) Source # 
Instance details

Defined in PVGrammar.Prob.Simple

type Rep (PVParamsInner f) = D1 ('MetaData "PVParamsInner" "PVGrammar.Prob.Simple" "protovoices-0.1.0.0-BDEUxFN8Fm0COc6pAhx3U0" 'False) (C1 ('MetaCons "PVParamsInner" 'PrefixI 'True) ((((S1 ('MetaSel ('Just "_pElaborateRegular") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta)) :*: S1 ('MetaSel ('Just "_pElaborateL") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta))) :*: (S1 ('MetaSel ('Just "_pElaborateR") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta)) :*: (S1 ('MetaSel ('Just "_pRootFifths") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta)) :*: S1 ('MetaSel ('Just "_pKeepL") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta))))) :*: ((S1 ('MetaSel ('Just "_pKeepR") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta)) :*: (S1 ('MetaSel ('Just "_pRepeatOverNeighbor") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta)) :*: S1 ('MetaSel ('Just "_pNBChromatic") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta)))) :*: (S1 ('MetaSel ('Just "_pNBAlt") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta)) :*: (S1 ('MetaSel ('Just "_pRepeatLeftOverRight") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta)) :*: S1 ('MetaSel ('Just "_pRepeatAlter") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta)))))) :*: (((S1 ('MetaSel ('Just "_pRepeatAlterUp") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta)) :*: (S1 ('MetaSel ('Just "_pRepeatAlterSemis") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta)) :*: S1 ('MetaSel ('Just "_pConnect") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta)))) :*: (S1 ('MetaSel ('Just "_pConnectChromaticLeftOverRight") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta)) :*: (S1 ('MetaSel ('Just "_pPassUp") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta)) :*: S1 ('MetaSel ('Just "_pPassLeftOverRight") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta))))) :*: ((S1 ('MetaSel ('Just "_pNewPassingLeft") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta)) :*: (S1 ('MetaSel ('Just "_pNewPassingRight") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta)) :*: S1 ('MetaSel ('Just "_pNewPassingMid") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta)))) :*: (S1 ('MetaSel ('Just "_pNoteSpreadDirection") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f (Dirichlet 3))) :*: (S1 ('MetaSel ('Just "_pNotesOnOtherSide") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta)) :*: S1 ('MetaSel ('Just "_pSpreadRepetitionEdge") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Beta))))))))

Likelihood Model

sampleDerivation represents a probabilistic program that samples a derivation. that can be interpreted in various modes for

observeDerivation takes and existing derivation and returns the corresponding trace.

sampleDerivation Source #

Arguments

:: (SampleCtx m Bernoulli, SampleCtx m Geometric1, SampleCtx m Geometric0, SampleCtx m MagicalOctaves, SampleCtx m MagicalID, SampleCtx m (Categorical 3), RandomInterpreter m PVParams) 
=> Path (Edges SPitch) (Notes SPitch)

root path

-> m (Either String [PVLeftmost SPitch])

a probabilistic program

A probabilistic program that samples a derivation starting from a given root path. Can be interpreted by the interpreter functions in Inference.Conjugate.

sampleDerivation' :: (SampleCtx m Bernoulli, SampleCtx m Geometric1, SampleCtx m Geometric0, SampleCtx m MagicalOctaves, SampleCtx m MagicalID, SampleCtx m (Categorical 3), RandomInterpreter m PVParams) => m (Either String [PVLeftmost SPitch]) Source #

A shorthand for sampleDerivation starting from ⋊——⋉.

observeDerivation :: [PVLeftmost SPitch] -> Path (Edges SPitch) (Notes SPitch) -> Either String (Trace PVParams) Source #

Walk through a derivation (starting at a given root path) and return the corresponding Trace (if possible). The trace can be used together with sampleDerivation for inference (getPosterior) or for showing the trace (printTrace).

observeDerivation' :: [PVLeftmost SPitch] -> Either String (Trace PVParams) Source #

A shorthand for observeDerivation starting from ⋊——⋉.

Utilities

roundtrip :: FilePath -> IO (Either String ()) Source #

A helper function that tests whether observeDerivation' followed by sampleDerivation' restores the original derivation. Useful for testing the compatibility of the two functions.

trainSinglePiece :: FilePath -> IO (Maybe (PVParams HyperRep)) Source #

Helper function: Load a single derivation and infer the corresponding posterior for a uniform prior.

Likelihood model for parsing

We need these specialized functions because of a dependency across steps: During a double step (elaborating two transitions), the process must decide whether to elaborate the left or right transition. To normalize the derivation order, we can't elaborate the left transition after the right one. That means that the model *sometimes* has to make the decision to go right, and sometimes not (i.e., after a right split). During parsing, we don't know whether this decision had to be made or not, since we don't know the previous derivation step yet. Therefore, we don't include the decision in the current step, but at the end of the previous one (in generation order), where the context is known. As a consequence, the result of this decision (if made) needs to be passed to the functions scoring the previous step. When parsing, make sure to maintain this information.

sampleSingleStepParsing :: (SampleCtx m Bernoulli, SampleCtx m Geometric1, SampleCtx m Geometric0, SampleCtx m MagicalOctaves, SampleCtx m MagicalID, RandomInterpreter m PVParams) => ContextSingle SPitch -> m () Source #

Sample a single step in a bottom-up context. Only used for evaluating the probability of a step, therefore returns ().

observeSingleStepParsing Source #

Arguments

:: ContextSingle SPitch

the parent path

-> Maybe Bool

If the following (generative) step is a double op, this is the result of the "continueLeft" decision, i.e., 'Just True' for split-left and freeze-left, and 'Just False' for spread and split-right. If the following step is a single op, this is Nothing (as no decision is made).

-> LeftmostSingle (Split SPitch) (Freeze SPitch)

the performed operation

-> Either String (Trace PVParams) 

Observerse a single step in a bottom-up context. Since double operations don't know whether they have to make a "continueLeft" decision when going bottom-up, this decision is moved to the previous step, where the context is know. Therefore, if the following step would have to make this decision, it is added here.

sampleDoubleStepParsing :: (SampleCtx m Bernoulli, SampleCtx m Geometric1, SampleCtx m Geometric0, SampleCtx m MagicalOctaves, SampleCtx m MagicalID, SampleCtx m (Categorical 3), RandomInterpreter m PVParams) => ContextDouble SPitch -> LeftmostDouble (Split SPitch) (Freeze SPitch) (Spread SPitch) -> m () Source #

Sample a double step in a bottom-up context. Only used for evaluating the probability of a step, therefore takes the "resulting" op and returns ().

observeDoubleStepParsing Source #

Arguments

:: ContextDouble SPitch

the parent path

-> Maybe Bool

If the following (generative) step is a double op, this is the result of the "continueLeft" decision, i.e., 'Just True' for split-left and freeze-left and 'Just False' for spread and split-right. If the following step is a single op, this is Nothing, as not decision is made.

-> LeftmostDouble (Split SPitch) (Freeze SPitch) (Spread SPitch)

the performed operation

-> Either String (Trace PVParams) 

Observerse a double step without knowing if it happened after a right split (e.g., when parsing). The extra decision that is necessary if it doesn't follow a right split is "moved" to the previous step. Therefore, this step is rated as if it follows a right split (not making the decision). In addition, if the following step would have to make the extra decision, it is added here.

Orphan instances

FromJSON (HyperRep Beta) Source # 
Instance details

FromJSON (HyperRep (Dirichlet 3)) Source # 
Instance details

ToJSON (HyperRep Beta) Source # 
Instance details

ToJSON (HyperRep (Dirichlet 3)) Source # 
Instance details

Generic (HyperRep Beta) Source # 
Instance details

Generic (HyperRep (Dirichlet 3)) Source # 
Instance details

Associated Types

type Rep (HyperRep (Dirichlet 3)) 
Instance details

Defined in PVGrammar.Prob.Simple

type Rep (HyperRep (Dirichlet 3)) = D1 ('MetaData "HyperRep" "Inference.Conjugate" "conjugate-programs-0.1.0.0-3yRv9wXBSRgCze1zWxB2WM" 'True) (C1 ('MetaCons "HyperRep" 'PrefixI 'True) (S1 ('MetaSel ('Just "runHyper") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Hyper (AsPrior (Dirichlet 3))))))
type Rep (HyperRep (Dirichlet 3)) 
Instance details

Defined in PVGrammar.Prob.Simple

type Rep (HyperRep (Dirichlet 3)) = D1 ('MetaData "HyperRep" "Inference.Conjugate" "conjugate-programs-0.1.0.0-3yRv9wXBSRgCze1zWxB2WM" 'True) (C1 ('MetaCons "HyperRep" 'PrefixI 'True) (S1 ('MetaSel ('Just "runHyper") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Hyper (AsPrior (Dirichlet 3))))))

Methods

from :: HyperRep (Dirichlet 3) -> Rep (HyperRep (Dirichlet 3)) x #

to :: Rep (HyperRep (Dirichlet 3)) x -> HyperRep (Dirichlet 3) #