Лично я думаю, что вы преувеличиваете издержки Scala. Например, это:
alpha ~ Gam(10,10)
mu_{k} ~ NorMV(vec(0.0,1,dim), 1, dim) , k \in [1,K]
si2 ~ IG(10,10)
pi ~ DirSym(alpha, K)
z_{n} ~ Mult(pi) , n \in [1,N]
x_{n} ~ NorMV(mu_{z_{n}}, si2, dim) , n \in [1,N]
можно записать как
def alpha = Gam(10, 10)
def mu = 1 to 'K map (k => NorMV(Vec(0.0, 1, dim), 1, dim)
def si2 = IG(10, 10)
def pi = DirSym(alpha, 'K)
def z = 1 to 'N map (n => Mult(pi))
def x = 1 to 'N map (n => NormMV(mu(z(n)), si2, dim))
В этом конкретном случае почти ничего не было сделано, кроме определения Gam
, Vec
, NorMV
и т. Д., И создания неявного определения от Symbol
до Int
или Double
, считывающего таблица, в которой вы будете хранить такие определения позже (например, с эквивалентом loadM
). Такие неявные определения будут выглядеть так:
import scala.reflect.Manifest
val unknowns = scala.collection.mutable.HashMap[Symbol,(Manifest[_], Any)]()
implicit def getInt(s: Symbol)(implicit m: Manifest[Int]): Int = unknowns.get(s) match {
case Some((`m`, x)) => x.asInstanceOf[Int]
case _ => error("Undefined unknown "+s)
}
// similarly to getInt for any other desired type
Это тоже можно записать так:
Model (
'alpha -> Gam(10, 10),
'mu -> 'n -> NorMV(Vec(0.0, 1, dim), 1, dim) With ('k in (1 to 'K)),
'si2 -> IG(10, 10),
'pi -> DirSym('alpha, 'K),
'z -> 'n -> Mult('pi) With ('n in (1 to 'N)),
'x -> 'n -> NorMV('mu of ('z of 'n), 'si2, dim)) With ('n in (1 to 'N))
)
В этом случае Gam
, Mult
и т. Д. Должны быть определены несколько иначе, чтобы обрабатывать символы, передаваемые им. Тем не менее, избыток «» определенно раздражает.
Не то чтобы у HBC не было своих собственных особенностей, таких как случайная необходимость в объявлениях типов, подчеркивание перед индексами, случайная необходимость заменить "~
" на "\in
" или даже обратная косая черта, должен предшествовать позже. Пока есть реальная польза от его использования вместо HBC, MathLab или чего-то еще, к чему привык человек, они будут немного беспокоиться.