CompositeArm
Composite Arm built from N independent sub-arms. Each observation is routed through every sub-arm's CompositeSubArm.valueExpr / CompositeSubArm.weightExpr / CompositeSubArm.filter AST before being fed to the corresponding per-sub-arm accumulator. The composite result is a ResultList of the sub-snapshots; pair with CompositePosterior to combine sub-arm draws into a single score.
Plumbing is AST-driven (no lambdas) so the whole spec is wire-serializable. Per-sub-arm encode is still applied after valueExpr; e.g. with LogNormalArm
valueExpr = Xthe lognormal's ownencode = lnruns, so don't double-log viavalueExpr = Log(X).
Example; zero-inflated lognormal revenue:
val ziln = CompositeArm(listOf(<br> CompositeSubArm(BernoulliArm(), valueExpr = IfExpr(X gt 0.0, Const(1.0), Const(0.0))),<br> CompositeSubArm(LogNormalArm(), filter = X gt 0.0),<br>))<br>val score = CompositePosterior(<br> subPosteriors = listOf(BetaPosterior, LogNormalGammaPosterior),<br> combine = V(0) * V(1),<br>)<br>val bandit = MultiArmedBandit(nbrArms = 4, policy = ThompsonSampling(ziln, score))Functions
Allocate a fresh per-arm accumulator already seeded with this arm's prior pseudo-counts.
Map a raw observation onto the scale the stat accumulates. Identity by default; LogNormalArm overrides with ln so the underlying stat tracks the log-reward and the Normal-Gamma posterior fits the log-normal generative model.
CompositeArm
createStat
Allocate a fresh per-arm accumulator already seeded with this arm's prior pseudo-counts.
subArms
Sub-arms whose stats receive routed observations.