From mboxrd@z Thu Jan 1 00:00:00 1970 From: Kyle Meyer Subject: Babel support for Stan Date: Sun, 23 Aug 2015 22:36:59 -0400 Message-ID: <87si794dkk.fsf@kyleam.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:46511) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZThdG-0006Jv-4V for emacs-orgmode@gnu.org; Sun, 23 Aug 2015 22:37:11 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZThdC-0001Pf-2g for emacs-orgmode@gnu.org; Sun, 23 Aug 2015 22:37:10 -0400 Received: from mail-qk0-f175.google.com ([209.85.220.175]:32850) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZThdB-0001PI-TI for emacs-orgmode@gnu.org; Sun, 23 Aug 2015 22:37:05 -0400 Received: by qkch123 with SMTP id h123so54367740qkc.0 for ; Sun, 23 Aug 2015 19:37:05 -0700 (PDT) Received: from localhost ([2601:18a:c201:560f:9e4e:36ff:fe3d:ae9c]) by smtp.gmail.com with ESMTPSA id t23sm1232513qkt.18.2015.08.23.19.37.03 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Aug 2015 19:37:04 -0700 (PDT) List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Sender: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org To: Org-mode --=-=-= Content-Type: text/plain Hi all, I'd like to put ob-stan.el (attached) in the contrib directory. It adds support for the Stan [1] programming language. I wrote it a while back, but a recent post on the Stan ML [2] made me think that others may find it useful (although I'd guess that the intersection of Stan and Org users is quite small). It's short because the only output that really makes sense is to dump the contents to a file (and maybe compile it), which is then used by a downstream interface [3]. Please let me know if you have any comments about the implementation or if you don't think contrib directory is a good place for it. Thanks. [1] http://mc-stan.org/ [2] https://groups.google.com/d/msg/stan-users/m4r8iUNiLug/Gexo8qCIBgAJ [3] http://mc-stan.org/interfaces/ -- Kyle --=-=-= Content-Type: application/emacs-lisp Content-Disposition: attachment; filename=ob-stan.el Content-Transfer-Encoding: quoted-printable ;;; ob-stan.el --- org-babel functions for Stan ;; Copyright (C) 2015 Kyle Meyer ;; Author: Kyle Meyer ;; Keywords: languages ;; Version: 0.1.0 ;; This file is NOT part of GNU Emacs. ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 3, or (at your option) ;; any later version. ;; ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to the ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, ;; Boston, MA 02110-1301, USA. ;;; Commentary: ;; Org-Babel support for evaluating Stan [1] source code. ;; ;; Evaluating a Stan block can produce two different results. ;; ;; 1) Dump the source code contents to a file. ;; ;; This file can then be used as a variable in other blocks, which ;; allows interfaces like RStan to use the model. ;; ;; 2) Compile the contents to a model file. ;; ;; This provides access to the CmdStan interface. To use this, set ;; `org-babel-stan-cmdstan-directory' and provide a :file argument ;; that does not end in ".stan". ;; ;; [1] http://mc-stan.org/ ;;; Code: (require 'ob) (require 'org-compat) (defcustom org-babel-stan-cmdstan-directory nil "CmdStan source directory. 'make' will be called from this directory to compile the Stan block. When nil, executing Stan blocks dumps the content to a plain text file." :group 'org-babel :type 'string) (defvar org-babel-default-header-args:stan '((:results . "file"))) (defun org-babel-execute:stan (body params) "Execute a block of Stan code with org-babel. A :file header argument must be given. If `org-babel-stan-cmdstan-directory' is non-nil and the file name does not have a \".stan\" extension, compile the block to file. Otherwise, write the Stan code to the file." (let ((file (expand-file-name (or (cdr (assoc :file params)) (user-error "Set :file argument to execute Stan blocks"))))) (if (or (not org-babel-stan-cmdstan-directory) (org-string-match-p "\\.stan\\'" file)) (with-temp-file file (insert body)) (with-temp-file (concat file ".stan") (insert body)) (let ((default-directory org-babel-stan-cmdstan-directory)) (call-process-shell-command (concat "make " file)))) nil)) ;; Signal that output has been written to file. (defun org-babel-prep-session:stan (session params) "Return an error because Stan does not support sessions." (user-error "Stan does not support sessions")) (provide 'ob-stan) ;;; ob-stan.el ends here --=-=-= Content-Type: text/plain Content-Disposition: attachment; filename=ob-stan-example.org * With RStan #+name: normal-stan #+begin_src stan :file model.stan data { int N; vector[N] x; } parameters { real mu; real std; } model { x ~ normal(mu, std); } #+end_src #+RESULTS: normal-stan [[file:model.stan]] #+begin_src R :session *R* :var model=normal-stan :results silent library(rstan) N <- 50 x <- rnorm(N, 20, 3) fit <- stan(file=model, data=list(N=N, x=x)) #+end_src * With CmdStan #+begin_src elisp :results silent (setq org-babel-stan-cmdstan-directory "~/src/cmdstan/") #+end_src #+name: normal-compile #+begin_src stan :file normal data { int N; vector[N] x; } parameters { real mu; real std; } model { x ~ normal(mu, std); } #+end_src #+RESULTS: normal-compile [[file:normal]] #+begin_src R :session *R* :results silent stan_rdump(c('N', 'x'), 'normal.data.R') #+end_src #+begin_src sh :results output drawer ./normal sample data file=normal.data.R #+end_src #+RESULTS: :RESULTS: method = sample (Default) sample num_samples = 1000 (Default) num_warmup = 1000 (Default) save_warmup = 0 (Default) thin = 1 (Default) adapt engaged = 1 (Default) gamma = 0.050000000000000003 (Default) delta = 0.80000000000000004 (Default) kappa = 0.75 (Default) t0 = 10 (Default) init_buffer = 75 (Default) term_buffer = 50 (Default) window = 25 (Default) algorithm = hmc (Default) hmc engine = nuts (Default) nuts max_depth = 10 (Default) metric = diag_e (Default) stepsize = 1 (Default) stepsize_jitter = 0 (Default) id = 0 (Default) data file = normal.data.R init = 2 (Default) random seed = 1573443700 output file = output.csv (Default) diagnostic_file = (Default) refresh = 100 (Default) Gradient evaluation took 4e-06 seconds 1000 transitions using 10 leapfrog steps per transition would take 0.04 seconds. Adjust your expectations accordingly! Iteration: 1 / 2000 [ 0%] (Warmup) Informational Message: The current Metropolis proposal is about to be rejected because of the following issue: stan::prob::normal_log: Scale parameter is 0, but must be > 0! If this warning occurs sporadically, such as for highly constrained variable types like covariance matrices, then the sampler is fine, but if this warning occurs often then your model may be either severely ill-conditioned or misspecified. Iteration: 100 / 2000 [ 5%] (Warmup) Iteration: 200 / 2000 [ 10%] (Warmup) Iteration: 300 / 2000 [ 15%] (Warmup) Iteration: 400 / 2000 [ 20%] (Warmup) Iteration: 500 / 2000 [ 25%] (Warmup) Iteration: 600 / 2000 [ 30%] (Warmup) Iteration: 700 / 2000 [ 35%] (Warmup) Iteration: 800 / 2000 [ 40%] (Warmup) Iteration: 900 / 2000 [ 45%] (Warmup) Iteration: 1000 / 2000 [ 50%] (Warmup) Iteration: 1001 / 2000 [ 50%] (Sampling) Iteration: 1100 / 2000 [ 55%] (Sampling) Iteration: 1200 / 2000 [ 60%] (Sampling) Iteration: 1300 / 2000 [ 65%] (Sampling) Iteration: 1400 / 2000 [ 70%] (Sampling) Iteration: 1500 / 2000 [ 75%] (Sampling) Iteration: 1600 / 2000 [ 80%] (Sampling) Iteration: 1700 / 2000 [ 85%] (Sampling) Iteration: 1800 / 2000 [ 90%] (Sampling) Iteration: 1900 / 2000 [ 95%] (Sampling) Iteration: 2000 / 2000 [100%] (Sampling) # Elapsed Time: 0.013356 seconds (Warm-up) # 0.024708 seconds (Sampling) # 0.038064 seconds (Total) :END: --=-=-=--