cmd_stan_rb 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 71cc2e69241ee94c83e321260b0f612c75c1dd9f4b3c13b1f1c71b50d2ebbeff
4
+ data.tar.gz: f5e04d315c5dfb5d0a7a3a85d950cb0704be044b0fe2d7dd630a6656cd0b2c53
5
+ SHA512:
6
+ metadata.gz: 6e769bb30bb9e0c14fbe344a3576006cb7874ab592cf87989204cbb2f3f3de56499bc6e8bb5bf7e58d3dc44a2896c0d8572151eaf45f6eb382c83431044cb4e2
7
+ data.tar.gz: dd013cd4b43cdff86449f578ed0ba9027c0a926e73e992475a241aff7e5ccde10cf157e6b612d4a73ee410428748adcd3c7ad28484c0eb84c989de53a07e1fa3
data/.gitignore ADDED
@@ -0,0 +1,16 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ /models/
10
+ /vendor/
11
+ *.csv
12
+ /output/
13
+ # rspec failure tracking
14
+ .rspec_status
15
+ /.ipynb_checkpoints/
16
+ *.gem
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ ---
2
+ language: ruby
3
+ cache: bundler
4
+ rvm:
5
+ - 2.6.5
6
+ before_install: gem install bundler -v 2.1.3
data/CHANGELOG.md ADDED
@@ -0,0 +1,15 @@
1
+ ### Head (Not released yet)
2
+
3
+ ### v0.2.0
4
+
5
+ * Renaming to CmdStanRb (See #5)
6
+
7
+ ### v0.1.1
8
+
9
+ * Make model storage location configurable (#2)
10
+ * Make loading previously compiled models work
11
+
12
+ ### v0.1.0
13
+
14
+ * Initial Version
15
+
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in ruby_stan.gemspec
4
+ gemspec
5
+
6
+ gem "rake", "~> 12.0"
7
+ gem "rspec", "~> 3.0"
data/Gemfile.lock ADDED
@@ -0,0 +1,34 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ cmd_stan_rb (0.2.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.3)
10
+ rake (12.3.3)
11
+ rspec (3.9.0)
12
+ rspec-core (~> 3.9.0)
13
+ rspec-expectations (~> 3.9.0)
14
+ rspec-mocks (~> 3.9.0)
15
+ rspec-core (3.9.1)
16
+ rspec-support (~> 3.9.1)
17
+ rspec-expectations (3.9.1)
18
+ diff-lcs (>= 1.2.0, < 2.0)
19
+ rspec-support (~> 3.9.0)
20
+ rspec-mocks (3.9.1)
21
+ diff-lcs (>= 1.2.0, < 2.0)
22
+ rspec-support (~> 3.9.0)
23
+ rspec-support (3.9.2)
24
+
25
+ PLATFORMS
26
+ ruby
27
+
28
+ DEPENDENCIES
29
+ cmd_stan_rb!
30
+ rake (~> 12.0)
31
+ rspec (~> 3.0)
32
+
33
+ BUNDLED WITH
34
+ 2.1.3
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2020 Robin Neumann
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,141 @@
1
+ # CmdStanRb
2
+ [![Build Status](https://travis-ci.org/neumanrq/cmd_stan_rb.svg?branch=master)](https://travis-ci.org/neumanrq/cmd_stan_rb)
3
+
4
+ Ruby interface to Stan, a library a for performing high performance statistical computations, i.e.
5
+ full Bayesian Inference.
6
+
7
+ <a href="https://mc-stan.org">
8
+ <img src="https://raw.githubusercontent.com/stan-dev/logos/master/logo.png" width=200 alt="Stan Logo"/>
9
+ </a>
10
+
11
+
12
+ ## Installation
13
+
14
+ gem install cmd_stan_rb
15
+
16
+ ## Installation for IRuby notebooks
17
+
18
+ gem install cmd_stan_rb
19
+
20
+ … and then re-register your Ruby kernel by
21
+
22
+ iruby register --force
23
+
24
+ ## Before you can start…
25
+
26
+ This project makes use of [CmdStan](https://github.com/stan-dev/cmdstan) to compile models
27
+ with the Stan compiler and incorporating additional tooling from the Stan ecosystem. There
28
+ are battle-tested similar projects for other Programming languages are i.e.
29
+
30
+ * [CmdStanPy](https://github.com/stan-dev/cmdstanpy)
31
+ * [CmdStanR](https://github.com/stan-dev/cmdstanr)
32
+ * [stannis](https://github.com/sakrejda/stannis])
33
+
34
+ Because of its dependency to `CmdStan`, you need to get `CmdStan` on board to
35
+ make `CmdStanRb` work. In the future I'd like to happen this automatically, but
36
+ for now you need to do this manually.
37
+
38
+ The easiest way is cloning the repository to a location of your choice:
39
+
40
+ git clone https://github.com/stan-dev/cmdstan
41
+
42
+ Then, remember the path to that directory, as we need CmdStanRb to point
43
+ to that directory by setting a config variable
44
+
45
+ ## Usage
46
+
47
+
48
+ ```Ruby
49
+ # Tell CmdStanRb where your CmdStan repository is located.
50
+ # If you skip this step, the default value is "vendor/cmdstan"
51
+ # as I have cloned it there for my experimentation.
52
+ CmdStanRb.configuration.cmdstan_dir = "~/path/to/cmdstan"
53
+
54
+ # Optional: Tell CmdStanRb where to store the models
55
+ CmdStanRb.configuration.model_dir = "/Users/robin/cmd_stan_rb-models"
56
+
57
+ # Prepare Stan compiler and assistent tooling
58
+ CmdStanRb.build_binaries
59
+
60
+ # Now we're ready to fit some models 👨‍🔬
61
+ # First, define your model. The first argument is a name,
62
+ # which is used to identify your model for re-use later.
63
+ model =
64
+ Stan::Model.new("bernoulli-test") do
65
+ # Stan code goes here as a string
66
+ %q{
67
+ data {
68
+ int<lower=0> N;
69
+ int<lower=0,upper=1> y[N];
70
+ }
71
+
72
+ parameters {
73
+ real<lower=0,upper=1> theta;
74
+ }
75
+
76
+ model {
77
+ theta ~ beta(1,1); // uniform prior on interval 0,1
78
+ y ~ bernoulli(theta);
79
+ }
80
+ }
81
+ end
82
+
83
+ # Translate model
84
+ model.compile
85
+
86
+ # Specify data you've observed
87
+ model.data = {
88
+ "N" => 4,
89
+ "y" => [0,1,0,0]
90
+ }
91
+
92
+ # Run simulation to obtain samples from posterior distribution
93
+ model.fit
94
+
95
+ # Print result
96
+ puts model.show
97
+ ```
98
+
99
+ The latter command shows the simulation result:
100
+
101
+
102
+ Inference for Stan model: b439_model
103
+ 1 chains: each with iter=(1000); warmup=(0); thin=(1); 1000 iterations saved.
104
+
105
+ Warmup took (0.0062) seconds, 0.0062 seconds total
106
+ Sampling took (0.013) seconds, 0.013 seconds total
107
+
108
+ Mean MCSE StdDev 5% 50% 95% N_Eff N_Eff/s R_hat
109
+ lp__ -4.4 3.5e-02 0.77 -5.9 -4.1 -3.8 4.9e+02 3.7e+04 1.0e+00
110
+ accept_stat__ 0.90 4.4e-03 0.15 0.53 0.97 1.0 1.2e+03 9.2e+04 1.0e+00
111
+ stepsize__ 1.1 nan 0.00 1.1 1.1 1.1 nan nan nan
112
+ treedepth__ 1.4 1.5e-02 0.48 1.0 1.0 2.0 1.0e+03 7.6e+04 1.0e+00
113
+ n_leapfrog__ 2.3 3.2e-02 0.97 1.0 3.0 3.0 9.2e+02 6.8e+04 1.0e+00
114
+ divergent__ 0.00 nan 0.00 0.00 0.00 0.00 nan nan nan
115
+ energy__ 4.9 5.2e-02 1.1 3.9 4.6 6.8 4.3e+02 3.2e+04 1.0e+00
116
+ theta 0.34 9.3e-03 0.18 0.071 0.32 0.64 3.7e+02 2.7e+04 1.0e+00
117
+
118
+ Samples were drawn using hmc with nuts.
119
+ For each parameter, N_Eff is a crude measure of effective sample size,
120
+ and R_hat is the potential scale reduction factor on split chains (at
121
+ convergence, R_hat=1).
122
+
123
+ ### Loading previously compiled models
124
+
125
+ CmdStanRb stores models in a diretory you can define by
126
+
127
+ ```Ruby
128
+ CmdStanRb.configuration.model_dir = "/Users/robin/cmd_stan_rb-models"
129
+ ```
130
+
131
+ If you skip this, CmdStanRb will create a folder in your home directory named `cmd_stan_rb-models` and store
132
+ the model files and the compiled model binaries there.
133
+
134
+ Having compiled a model with name `my-model-01`, you can load it again by
135
+
136
+ ```Ruby
137
+ model = Stan::Model.load("my-model-01")
138
+ ```
139
+
140
+ Note that once loaded, the model's data has been wiped out, so `model.data` is blank and
141
+ needs to get set again to fit again.
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "cmd_stan_rb"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,26 @@
1
+ require_relative 'lib/cmd_stan_rb/version'
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "cmd_stan_rb"
5
+ spec.version = CmdStanRb::VERSION
6
+ spec.authors = ["Robin Neumann\n"]
7
+ spec.email = ["robin.neumann@posteo.de"]
8
+
9
+ spec.summary = %q{Ruby interface to CmdStan, the command line interface to Stan, a high performance statistical computing platform}
10
+ spec.description = %q{Stan is a state-of-the-art platform for statistical modeling and high-performance statistical computation. Thousands of users rely on Stan for statistical modeling, data analysis, and prediction in the social, biological, and physical sciences, engineering, and business. CmdStanRb offers bindings in Ruby to employ Stan, targeting easing up the integration of Stan and Bayesian Inference into Ruby-powered environments.}
11
+ spec.homepage = "https://github.com/neumanrq/cmd_stan_rb"
12
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
13
+
14
+ spec.metadata["homepage_uri"] = spec.homepage
15
+ spec.metadata["source_code_uri"] = "https://github.com/neumanrq/cmd_stan_rb"
16
+ spec.metadata["changelog_uri"] = "https://github.com/neumanrq/cmd_stan_rb"
17
+
18
+ # Specify which files should be added to the gem when it is released.
19
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
20
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
21
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
22
+ end
23
+ spec.bindir = "exe"
24
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
25
+ spec.require_paths = ["lib"]
26
+ end
data/demo.ipynb ADDED
@@ -0,0 +1,231 @@
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": 2,
6
+ "metadata": {},
7
+ "outputs": [
8
+ {
9
+ "data": {
10
+ "text/plain": [
11
+ "\"0.1.0\""
12
+ ]
13
+ },
14
+ "execution_count": 2,
15
+ "metadata": {},
16
+ "output_type": "execute_result"
17
+ }
18
+ ],
19
+ "source": [
20
+ "require \"cmd_stan_rb\"\n",
21
+ "CmdStanRb::VERSION"
22
+ ]
23
+ },
24
+ {
25
+ "cell_type": "code",
26
+ "execution_count": 6,
27
+ "metadata": {},
28
+ "outputs": [
29
+ {
30
+ "name": "stdout",
31
+ "output_type": "stream",
32
+ "text": [
33
+ "\n",
34
+ " data {\n",
35
+ " int<lower=0> N;\n",
36
+ " int<lower=0,upper=1> y[N];\n",
37
+ " }\n",
38
+ "\n",
39
+ " parameters {\n",
40
+ " real<lower=0,upper=1> theta;\n",
41
+ " }\n",
42
+ "\n",
43
+ " model {\n",
44
+ " theta ~ beta(1,1); // uniform prior on interval 0,1\n",
45
+ " y ~ bernoulli(theta);\n",
46
+ " }\n",
47
+ " \n"
48
+ ]
49
+ }
50
+ ],
51
+ "source": [
52
+ "puts CmdStanRb::Examples.bernoulli"
53
+ ]
54
+ },
55
+ {
56
+ "cell_type": "markdown",
57
+ "metadata": {},
58
+ "source": [
59
+ "# Given some data and our prior knowledge. What is the value of theta?"
60
+ ]
61
+ },
62
+ {
63
+ "cell_type": "code",
64
+ "execution_count": 7,
65
+ "metadata": {},
66
+ "outputs": [
67
+ {
68
+ "data": {
69
+ "text/plain": [
70
+ "#<CmdStanRb::Model:0x00007f81aaa9f050 @name=\"research-42\", @model_string=\"\\n data {\\n int<lower=0> N;\\n int<lower=0,upper=1> y[N];\\n }\\n\\n parameters {\\n real<lower=0,upper=1> theta;\\n }\\n\\n model {\\n theta ~ beta(1,1); // uniform prior on interval 0,1\\n y ~ bernoulli(theta);\\n }\\n \", @model_file=#<File:output/research-42/research-42.stan>>"
71
+ ]
72
+ },
73
+ "execution_count": 7,
74
+ "metadata": {},
75
+ "output_type": "execute_result"
76
+ }
77
+ ],
78
+ "source": [
79
+ "model = CmdStanRb::Model.new(\"research-42\") do \n",
80
+ " # Write Stan code here\n",
81
+ " %Q{\n",
82
+ " data {\n",
83
+ " int<lower=0> N;\n",
84
+ " int<lower=0,upper=1> y[N];\n",
85
+ " }\n",
86
+ "\n",
87
+ " parameters {\n",
88
+ " real<lower=0,upper=1> theta;\n",
89
+ " }\n",
90
+ "\n",
91
+ " model {\n",
92
+ " theta ~ beta(1,1); // uniform prior on interval 0,1\n",
93
+ " y ~ bernoulli(theta);\n",
94
+ " }\n",
95
+ " } \n",
96
+ "end"
97
+ ]
98
+ },
99
+ {
100
+ "cell_type": "code",
101
+ "execution_count": 8,
102
+ "metadata": {},
103
+ "outputs": [
104
+ {
105
+ "data": {
106
+ "text/plain": [
107
+ "{:state=>:ok, :target=>\"../../output/research-42/research-42\", :working_directory=>\"/Users/robin/private_projects/cmd_stan_rb\"}"
108
+ ]
109
+ },
110
+ "execution_count": 8,
111
+ "metadata": {},
112
+ "output_type": "execute_result"
113
+ }
114
+ ],
115
+ "source": [
116
+ "model.compile"
117
+ ]
118
+ },
119
+ {
120
+ "cell_type": "code",
121
+ "execution_count": 10,
122
+ "metadata": {},
123
+ "outputs": [
124
+ {
125
+ "data": {
126
+ "text/plain": [
127
+ "{\"N\"=>5, \"y\"=>[1, 0, 1, 1, 0]}"
128
+ ]
129
+ },
130
+ "execution_count": 10,
131
+ "metadata": {},
132
+ "output_type": "execute_result"
133
+ }
134
+ ],
135
+ "source": [
136
+ "model.data = { \n",
137
+ " \"N\" => 5, # We toss a coin 5 times \n",
138
+ " \"y\" => [1, 0, 1, 1, 0] # toss results\n",
139
+ "}"
140
+ ]
141
+ },
142
+ {
143
+ "cell_type": "code",
144
+ "execution_count": 11,
145
+ "metadata": {},
146
+ "outputs": [
147
+ {
148
+ "name": "stdout",
149
+ "output_type": "stream",
150
+ "text": [
151
+ "/Users/robin/private_projects/cmd_stan_rb/output/research-42/research-42 sample data file=output/research-42/research-42.json\n"
152
+ ]
153
+ },
154
+ {
155
+ "data": {
156
+ "text/plain": [
157
+ "{:state=>:ok, :data=>{\"N\"=>5, \"y\"=>[1, 0, 1, 1, 0]}}"
158
+ ]
159
+ },
160
+ "execution_count": 11,
161
+ "metadata": {},
162
+ "output_type": "execute_result"
163
+ }
164
+ ],
165
+ "source": [
166
+ "# Do the simulation magic\n",
167
+ "model.fit"
168
+ ]
169
+ },
170
+ {
171
+ "cell_type": "code",
172
+ "execution_count": 12,
173
+ "metadata": {},
174
+ "outputs": [
175
+ {
176
+ "name": "stdout",
177
+ "output_type": "stream",
178
+ "text": [
179
+ "Inference for Stan model: research_42_model\n",
180
+ "1 chains: each with iter=(1000); warmup=(0); thin=(1); 1000 iterations saved.\n",
181
+ "\n",
182
+ "Warmup took (0.0058) seconds, 0.0058 seconds total\n",
183
+ "Sampling took (0.013) seconds, 0.013 seconds total\n",
184
+ "\n",
185
+ " Mean MCSE StdDev 5% 50% 95% N_Eff N_Eff/s R_hat\n",
186
+ "lp__ -5.4 4.9e-02 8.7e-01 -7.0 -5.1 -4.8 3.2e+02 2.5e+04 1.0e+00\n",
187
+ "accept_stat__ 0.91 4.0e-03 1.3e-01 0.63 0.97 1.0 1.1e+03 8.8e+04 1.0e+00\n",
188
+ "stepsize__ 1.1 nan 4.4e-15 1.1 1.1 1.1 nan nan nan\n",
189
+ "treedepth__ 1.4 1.5e-02 4.8e-01 1.0 1.0 2.0 1.0e+03 8.1e+04 1.0e+00\n",
190
+ "n_leapfrog__ 2.3 3.5e-02 9.7e-01 1.0 3.0 3.0 7.7e+02 6.0e+04 1.0e+00\n",
191
+ "divergent__ 0.00 nan 0.0e+00 0.00 0.00 0.00 nan nan nan\n",
192
+ "energy__ 5.9 6.2e-02 1.1e+00 4.8 5.5 8.1 3.3e+02 2.6e+04 1.0e+00\n",
193
+ "theta 0.57 1.1e-02 1.8e-01 0.25 0.58 0.86 2.6e+02 2.1e+04 1.0e+00\n",
194
+ "\n",
195
+ "Samples were drawn using hmc with nuts.\n",
196
+ "For each parameter, N_Eff is a crude measure of effective sample size,\n",
197
+ "and R_hat is the potential scale reduction factor on split chains (at \n",
198
+ "convergence, R_hat=1).\n",
199
+ "\n",
200
+ "\n"
201
+ ]
202
+ }
203
+ ],
204
+ "source": [
205
+ "puts model.show"
206
+ ]
207
+ },
208
+ {
209
+ "cell_type": "code",
210
+ "execution_count": null,
211
+ "metadata": {},
212
+ "outputs": [],
213
+ "source": []
214
+ }
215
+ ],
216
+ "metadata": {
217
+ "kernelspec": {
218
+ "display_name": "Ruby 2.6.5",
219
+ "language": "ruby",
220
+ "name": "ruby"
221
+ },
222
+ "language_info": {
223
+ "file_extension": ".rb",
224
+ "mimetype": "application/x-ruby",
225
+ "name": "ruby",
226
+ "version": "2.6.5"
227
+ }
228
+ },
229
+ "nbformat": 4,
230
+ "nbformat_minor": 2
231
+ }
@@ -0,0 +1,28 @@
1
+ require "json"
2
+ require "cmd_stan_rb/version"
3
+ require "cmd_stan_rb/configuration"
4
+ require "stan"
5
+
6
+ module CmdStanRb
7
+ class Error < StandardError; end
8
+
9
+ class << self
10
+ attr_accessor :configuration
11
+
12
+ def build_binaries
13
+ system("make -C #{CmdStanRb.configuration.cmdstan_dir} build")
14
+ end
15
+
16
+ def reset
17
+ system("make -C #{CmdStanRb.configuration.cmdstan_dir} clean-all")
18
+ end
19
+ end
20
+
21
+ def self.configuration
22
+ @configuration ||= CmdStanRb::Configuration.new
23
+ end
24
+
25
+ def self.configure
26
+ yield(configuration)
27
+ end
28
+ end
@@ -0,0 +1,11 @@
1
+ module CmdStanRb
2
+ class Configuration
3
+ attr_accessor :cmdstan_dir
4
+ attr_accessor :model_dir
5
+
6
+ def initialize
7
+ self.cmdstan_dir = "vendor/cmdstan"
8
+ self.model_dir = "#{`echo $HOME`.gsub("\n", "")}/cmd_stan_rb-models"
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ module CmdStanRb
2
+ VERSION = "0.2.0"
3
+ end
data/lib/stan.rb ADDED
@@ -0,0 +1,5 @@
1
+ require "stan/model"
2
+ require "stan/examples"
3
+
4
+ module Stan
5
+ end
@@ -0,0 +1,23 @@
1
+ module Stan
2
+ module Examples
3
+ class << self
4
+ def bernoulli
5
+ %q{
6
+ data {
7
+ int<lower=0> N;
8
+ int<lower=0,upper=1> y[N];
9
+ }
10
+
11
+ parameters {
12
+ real<lower=0,upper=1> theta;
13
+ }
14
+
15
+ model {
16
+ theta ~ beta(1,1); // uniform prior on interval 0,1
17
+ y ~ bernoulli(theta);
18
+ }
19
+ }
20
+ end
21
+ end
22
+ end
23
+ end
data/lib/stan/model.rb ADDED
@@ -0,0 +1,106 @@
1
+ module Stan
2
+ class Model
3
+ class NoDataGivenError < StandardError ;; end
4
+
5
+ attr_accessor :compiled_model_path, :name, :data
6
+ attr_reader :model_string, :model_file
7
+
8
+ class << self
9
+ def load(name)
10
+ new(name)
11
+ end
12
+ end
13
+
14
+ def initialize(name, &block)
15
+ @name = name
16
+
17
+ # I'd like to invent a convenient DSL that
18
+ # is similar to writing "direct" Stan code,
19
+ # but to do so I need to get a better understanding
20
+ # of Stan as a language/DSL itself. Until that
21
+ # I "approximate" my goal by using a block for initialization,
22
+ # where the block always needs to return the Stan model
23
+ # as a string. You can load it from a file or write in directly!
24
+ @model_string = block.call if block_given?
25
+
26
+ `mkdir -p #{model_directory}` unless Dir.exists?(model_directory)
27
+
28
+ if File.exists?(filename)
29
+ load_model_file
30
+ else
31
+ create_model_file!
32
+ end
33
+ end
34
+
35
+ # Main interactions
36
+ #
37
+ #
38
+
39
+ def compile
40
+ system(commands[:compile])
41
+ {state: :ok, target: target, working_directory: working_directory}
42
+ end
43
+
44
+ def fit
45
+ raise NoDataGivenError.new("Please specify your model's data before running simulations!") if data.nil?
46
+ `chmod +x #{CmdStanRb.configuration.model_dir}/#{name}/#{name}`
47
+ `#{commands[:fit]}`
48
+ {state: :ok, data: data}
49
+ end
50
+
51
+ def show
52
+ `#{CmdStanRb.configuration.cmdstan_dir}/bin/stansummary output.csv`
53
+ end
54
+
55
+ def destroy
56
+ path = "#{CmdStanRb.configuration.model_dir}/#{name}"
57
+ `rm -rvf #{path}`
58
+ {state: :ok, destroyed_path: path}
59
+ end
60
+
61
+ def commands
62
+ {
63
+ compile: "make -C #{CmdStanRb.configuration.cmdstan_dir} #{target}",
64
+ fit: "#{CmdStanRb.configuration.model_dir}/#{name}/#{name} sample data file=#{data_file.path}"
65
+ }
66
+ end
67
+
68
+ private
69
+
70
+ def load_model_file
71
+ @model_file = File.open(filename, "r")
72
+ @model_string = @model_file.read
73
+ @model_file.rewind
74
+ end
75
+
76
+ def create_model_file!
77
+ @model_file = File.open(filename, "w")
78
+ @model_file.write(@model_string)
79
+ @model_file.rewind
80
+ end
81
+
82
+ def data_file
83
+ file = File.open("#{CmdStanRb.configuration.model_dir}/#{name}/#{name}.json", "w")
84
+ file.write(data.to_json)
85
+ file.rewind
86
+ file
87
+ end
88
+
89
+ def target
90
+ "#{CmdStanRb.configuration.model_dir}/#{name}/#{name}"
91
+ end
92
+
93
+ def working_directory
94
+ @wd ||= `pwd`.gsub("\n", "")
95
+ end
96
+
97
+ def model_directory
98
+ "#{CmdStanRb.configuration.model_dir}/#{name}"
99
+ end
100
+
101
+ def filename
102
+ "#{CmdStanRb.configuration.model_dir}/#{name}/#{name}.stan"
103
+ end
104
+
105
+ end
106
+ end
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cmd_stan_rb
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - 'Robin Neumann
8
+
9
+ '
10
+ autorequire:
11
+ bindir: exe
12
+ cert_chain: []
13
+ date: 2020-05-10 00:00:00.000000000 Z
14
+ dependencies: []
15
+ description: Stan is a state-of-the-art platform for statistical modeling and high-performance
16
+ statistical computation. Thousands of users rely on Stan for statistical modeling,
17
+ data analysis, and prediction in the social, biological, and physical sciences,
18
+ engineering, and business. CmdStanRb offers bindings in Ruby to employ Stan, targeting
19
+ easing up the integration of Stan and Bayesian Inference into Ruby-powered environments.
20
+ email:
21
+ - robin.neumann@posteo.de
22
+ executables: []
23
+ extensions: []
24
+ extra_rdoc_files: []
25
+ files:
26
+ - ".gitignore"
27
+ - ".rspec"
28
+ - ".travis.yml"
29
+ - CHANGELOG.md
30
+ - Gemfile
31
+ - Gemfile.lock
32
+ - LICENSE
33
+ - README.md
34
+ - Rakefile
35
+ - bin/console
36
+ - bin/setup
37
+ - cmd_stan_rb.gemspec
38
+ - demo.ipynb
39
+ - lib/cmd_stan_rb.rb
40
+ - lib/cmd_stan_rb/configuration.rb
41
+ - lib/cmd_stan_rb/version.rb
42
+ - lib/stan.rb
43
+ - lib/stan/examples.rb
44
+ - lib/stan/model.rb
45
+ homepage: https://github.com/neumanrq/cmd_stan_rb
46
+ licenses: []
47
+ metadata:
48
+ homepage_uri: https://github.com/neumanrq/cmd_stan_rb
49
+ source_code_uri: https://github.com/neumanrq/cmd_stan_rb
50
+ changelog_uri: https://github.com/neumanrq/cmd_stan_rb
51
+ post_install_message:
52
+ rdoc_options: []
53
+ require_paths:
54
+ - lib
55
+ required_ruby_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: 2.3.0
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ requirements: []
66
+ rubygems_version: 3.0.3
67
+ signing_key:
68
+ specification_version: 4
69
+ summary: Ruby interface to CmdStan, the command line interface to Stan, a high performance
70
+ statistical computing platform
71
+ test_files: []