2015-08-06 4 views
1

Я прочитал here, что можно (и я интерпретировал просто) вызвать Stan процедуры из программы на C++.Вызов подпрограмм Сцена из программы на C++

У меня есть некоторые сложные функции логарифмического правдоподобия, которые я закодировал на C++ и действительно не знаю, как я мог их кодировать с использованием языка Stan. Можно ли назвать подпрограммы Монте-Карло в Стэне с помощью функции логарифмического правдоподобия, которую я уже закодировал в C++? Если да, то есть примеры этого?

Похоже, что это очень естественная вещь, но я не могу найти примеров или указаний относительно того, как это сделать.

ответ

2

При дальнейшем рассмотрении (вы можете отказаться от моего предыдущего ответа), вы можете попробовать: Напишите программу .stan с пользовательской функцией в блоке functions, которая имеет правильную подпись (и анализирует), но в основном делает ничего. Пример: functions { real foo_log(real[] y, vector beta, matrix X, real sigma) { return not_a_number(); // replace this after parsing to C++ } } data { int<lower=1> N; int<lower=1> K; matrix[N,K] X; real y[N]; } parameters { vector[K] beta; real<lower=0> sigma; } model { y ~ foo(beta, X, sigma); // priors here } Затем используйте CmdStan для компиляции этой модели, которая будет генерировать файл .hpp в качестве промежуточного шага. Отредактируйте этот файл .hpp внутри тела foo_log, чтобы вызвать вашу шаблонную функцию C++, а также # включить заголовочный файл (ы), в котором определены ваши материалы. Затем перекомпилируйте и выполните двоичный файл.

Это может сработать для вас, но если все, что вы делаете, несколько полезно, мы бы хотели, чтобы вы внесли свой вклад в C++.

+0

Я только что работал над выходными, но мне нужно немного поработать над другими вещами :(Я пытаюсь создать неоднородную модель пуассоновского процесса, где мгновенная скорость довольно сложная, а также интеграл в функции правдоподобия. довольно конкретный, поэтому я не думаю, что это был бы достойный вклад, к сожалению. Если, возможно, я не смогу придумать способ обобщить модель немного больше - я подумаю. Еще раз спасибо. – Jeff

+0

Я получил это для работы некоторые основные примеры, еще раз спасибо за ваше решение! Мне было интересно, считаете ли вы, что кто-нибудь будет интересоваться некоторыми примерами, а также где я могу его разместить? – Jeff

+0

Возможно, GitHub wiki? (https://github.com/stan-dev/) stan/wiki) Я не знаю, позволит ли вам создать новую страницу, но один из нас может нажать ее для вас, или мы могли бы, вероятно, изменить разрешения. –

2

Я думаю, что ваш вопрос немного отличается от того, с которым вы связались. У него была полная программа Stan, и он хотел управлять ею с C++, тогда как вы спрашиваете, можете ли вы обойти писать программу Stan, вызывая внешнюю функцию C++ для оценки вероятности регистрации. Но это не привело бы вас к очень далеко, потому что вам все равно придется передавать данные в форме, которую может выполнять Стэн, объявить Стэну, какие неизвестные параметры (плюс их поддержка) и т. Д. Итак, я не думаю, что вы можете (или должен) уклоняться от изучения языка Стэна.

Но довольно легко выставить на язык Сцена функцию C++, которая по сути просто включает в себя добавление файла my_loglikelihood.hpp в нужное место под ${STAN_HOME}/lib/stan_math_${VERSION}/stan/math/, добавив инструкцию include в файл math.hpp в этом подкаталоге, и редактирование ${STAN_HOME}/src/stan/lang/function_signatures.h. В этот момент ваша программа .stan может выглядеть так же просто, как data { // declare data like y, X, etc. } parameters { // declare parameters like theta } model { // call y ~ my_logliklihood_log(theta, X) } Но я думаю, что реальный ответ на ваш вопрос заключается в том, что если вы уже написали C++-функцию для оценки логарифмической правдоподобия, то переписывание ее на языке Stan должно Не прошло и нескольких минут. Язык Стэн очень похож на C, так что легче обрабатывать файл .stan в исходный файл C++. Вот функция Stan, которую я написал для log-правдоподобия условно-гауссовского результата в контексте регрессии: functions { /** * Increments the log-posterior with the logarithm of a multivariate normal * likelihood with a scalar standard deviation for all errors * Equivalent to y ~ normal(intercept + X * beta, sigma) but faster * @param beta vector of coefficients (excluding intercept) * @param b precomputed vector of OLS coefficients (excluding intercept) * @param middle matrix (excluding ones) typically precomputed as crossprod(X) * @param intercept scalar (assuming X is centered) * @param ybar precomputed sample mean of the outcome * @param SSR positive precomputed value of the sum of squared OLS residuals * @param sigma positive value for the standard deviation of the errors * @param N integer equal to the number of observations */ void ll_mvn_ols_lp(vector beta, vector b, matrix middle, real intercept, real ybar, real SSR, real sigma, int N) { increment_log_prob(-0.5 * (quad_form_sym(middle, beta - b) + N * square(intercept - ybar) + SSR)/ square(sigma) - # 0.91... is log(sqrt(2 * pi())) N * (log(sigma) + 0.91893853320467267)); } } , который в основном просто сбрасывает то, что в противном случае могло бы быть C-синтаксисом в тело функции на языке Stan, которая затем вызывается в блоке model программы .stan.

Итак, я думаю, вам было бы проще всего переписать вашу C++-функцию как функцию Stan. Однако возможно, что ваш лог-правдоподобие включает в себя что-то экзотическое, для которого в настоящее время не существует соответствующего синтаксиса Синтаксиса. В этом случае вы можете вернуться к раскрытию этой функции C++ для языка Stan и в идеале сделать запросы на загрузку в репозитории math и stan на GitHub под stan-dev, чтобы другие люди могли его использовать (хотя тогда вам также придется писать модульные тесты, документация и т. д.).

+0

Благодарим вас за подробный ответ, Бен. Моя проблема заключается в том, что log-правдоподобие, которое я написал, содержит 100 строк строк кода C++ и использует несколько классов C++, которые я написал, поэтому мне кажется растрато переписать все это на stan-язык, Компилятор stan может преобразовать его обратно в C++.Я надеялся, что будет способ написать функции C++ для priors и log-правдоподобия, а затем передать их функции stan HMC - это вообще возможно? – Jeff

+0

Возможно, вы могли бы написать программу .stan, которая заполняет все блоки, кроме 'model', анализирует ее на C++ с CmdStan, наследует от создаваемого класса, перезаписывает метод' log_prob' в унаследованном классе, чтобы вызвать вашу функцию C++ (который должен быть шаблонизирован, чтобы он мог обрабатывать собственные скалярные типы Stan), преодолевать любые непредвиденные сложности, компилировать измененный источник C++ и надеяться на лучшее. Но я все же думаю, что было бы лучше взять один из маршрутов, упомянутых в моем главном ответе. Независимо от того, какое время тратится впустую на этот проект Стэна, вы будете хорошо работать на следующем. –

+0

Я думаю, что я напишу модель в файле .stan - это кажется намного более простым! Большое спасибо за вашу помощь, Бен. – Jeff