-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexplicit.html
More file actions
525 lines (486 loc) · 23.4 KB
/
explicit.html
File metadata and controls
525 lines (486 loc) · 23.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Tutorial — Semi-Markov 1.0 documentation</title>
<link rel="stylesheet" href="_static/sphinxdoc.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '1.0',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="top" title="Semi-Markov 1.0 documentation" href="index.html" />
<link rel="up" title="Semi-Markov Library Manual" href="manual.html" />
<link rel="next" title="Examples" href="examples.html" />
<link rel="prev" title="Background" href="background.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="examples.html" title="Examples"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="background.html" title="Background"
accesskey="P">previous</a> |</li>
<li><a href="index.html">Semi-Markov 1.0 documentation</a> »</li>
<li><a href="manual.html" accesskey="U">Semi-Markov Library Manual</a> »</li>
</ul>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Tutorial</a><ul>
<li><a class="reference internal" href="#using-explicittransitions-to-construct-a-gspn">Using ExplicitTransitions to Construct a GSPN</a><ul>
<li><a class="reference internal" href="#the-type-of-the-gspn-model">The Type of the GSPN Model</a></li>
<li><a class="reference internal" href="#define-transitions">Define Transitions</a></li>
<li><a class="reference internal" href="#using-explicittransitionsbuilder">Using ExplicitTransitionsBuilder</a></li>
<li><a class="reference internal" href="#create-marking-and-state">Create Marking and State</a></li>
</ul>
</li>
<li><a class="reference internal" href="#simulating-the-trajectory-of-a-semi-markov-gspn">Simulating the Trajectory of a Semi-Markov GSPN</a></li>
<li><a class="reference internal" href="#observations-of-the-state">Observations of the State</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="background.html"
title="previous chapter">Background</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="examples.html"
title="next chapter">Examples</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/explicit.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="tutorial">
<h1>Tutorial<a class="headerlink" href="#tutorial" title="Permalink to this headline">¶</a></h1>
<div class="section" id="using-explicittransitions-to-construct-a-gspn">
<h2>Using ExplicitTransitions to Construct a GSPN<a class="headerlink" href="#using-explicittransitions-to-construct-a-gspn" title="Permalink to this headline">¶</a></h2>
<p>The ExplicitTransitions class implements the GSPN concept.</p>
<div class="section" id="the-type-of-the-gspn-model">
<h3>The Type of the GSPN Model<a class="headerlink" href="#the-type-of-the-gspn-model" title="Permalink to this headline">¶</a></h3>
<p>The author of the code supplies building blocks to this class:</p>
<ul class="simple">
<li>A token type. It should have an ostream <tt class="docutils literal"><span class="pre">operator<<</span></tt> defined.
It may have any necessary data, such as a birth date
or size of truck. It must have a default constructor. The simplest
choice is to construct a <a class="reference external" href="http://en.wikipedia.org/wiki/C++11#Modification_to_the_definition_of_plain_old_data">POD type</a>.</li>
<li>A storage container for tokens at a place. The allowed option
is Uncolored<TokenType>, which is an <tt class="docutils literal"><span class="pre">std::vector.</span></tt></li>
<li>A PlaceKey, which is another POD type to uniquely identify
a place in the GSPN. It needs less-than, equal-to, and print
operators.</li>
<li>A TransitionKey, which uniquely identifies transitions in the
GSPN. It needs less-than, equal-to, and print
operators.</li>
<li>UserState. The system state consists of marking, enabled
transitions, and the absolute time. The optional UserState
struct will add arbitrary members to the state for convenience.
If a transition were to modify this state such that other
transitions would have new different enabling or distributions,
the system would no longer be semi-Markov. This state is
a good place to put constant parameters or links to
external data, such as weather.</li>
<li>A random number generator. The system assumes a single
generator for everything. This class supports the C++
<tt class="docutils literal"><span class="pre">random</span></tt> requirements.</li>
</ul>
<p>Because the library offers choices in how to define the pieces,
it will be necessary to build the GSPN and the its dynamics
in steps. There are natural dependencies among the pieces,
defined by what each entity is</p>
<a class="reference internal image-reference" href="_images/type_dependency.svg"><div align="center" class="align-center"><img alt="First define PlaceKey, TransitionKey, and the Token. Last to define is the StochasticDynamics." src="_images/type_dependency.svg" /></div>
</a>
<p>An example of a <tt class="docutils literal"><span class="pre">PlaceKey</span></tt> from an SIR model shows that defining
such a struct is verbose but painless:</p>
<div class="highlight-python"><pre>struct SIRPlace
{
size_t disease;
size_t individual;
SIRPlace()=default;
SIRPlace(size_t d, size_t i)
: disease(d), individual(i)
{}
friend inline
bool operator<(const SIRPlace& a, const SIRPlace& b)
{
return lazy_less(a.disease, b.disease, a.individual,
b.individual);
}
friend inline
bool operator==(const SIRPlace& a, const SIRPlace& b)
{
return (a.disease==b.disease)&& (a.individual==b.individual);
}
friend inline
std::ostream&
operator<<(std::ostream& os, const SIRPlace& cp)
{
return os << '(' << cp.disease << ", " << cp.individual<<')';
}
};</pre>
</div>
<p>The template parameters for <tt class="docutils literal"><span class="pre">ExplicitTransitions</span></tt> are as above:</p>
<div class="highlight-python"><pre>typedef LocalMarking<Uncolored<TokenType>> Local;
typedef ExplicitTransitions<PlaceKey, TransitionKey, Local,
RandGen, UserState> GSPN;</pre>
</div>
<p>The <tt class="docutils literal"><span class="pre">LocalMarking</span></tt> class is the marking of input and output tokens
for a particular transition. Instead of using <tt class="docutils literal"><span class="pre">PlaceKey</span></tt> to identify
particular sets of tokens, it assumes the transition can access its
edges with an ordinal (first, second, third). The idea is to define
transitions which don’t need to know how their marking is indexed and
stored.</p>
</div>
<div class="section" id="define-transitions">
<h3>Define Transitions<a class="headerlink" href="#define-transitions" title="Permalink to this headline">¶</a></h3>
<p>A transition has three responsibilities. Determine when it
is enabled, choose a continuous variable distribution function
for its firing time, and modify the marking when it fires.
Enabling and calculating a distribution happen at the same time,
so they are in one function.</p>
<p>A transition inherits from the <tt class="docutils literal"><span class="pre">ExplicitTransition</span></tt> template.
It acts on the local marking to produce distributions or move
tokens:</p>
<div class="highlight-python"><pre>using Transition=ExplicitTransition<Local,RandGen,WithParams>;
using Dist=TransitionDistribution<RandGen>;
class InfectNeighbor : public Transition
{
virtual std::pair<bool, std::unique_ptr<Dist>>
Enabled(const UserState& s, const Local& local_marking,
double te, double t0) const override
{
if (local_marking.template input_tokens_sufficient<0>())
{
return {true, std::unique_ptr<Dist>(
new WeibullDistribution(s.params.at(0), te))};
}
else
{
return {false, std::unique_ptr<Dist>(nullptr)};
}
}
virtual void Fire(UserState& s, Local& local_marking,
RandGen& rng) const override
{
local_marking.template transfer_by_stochiometric_coefficient<0>(rng);
}
};</pre>
</div>
<p>The <tt class="docutils literal"><span class="pre">Enabled()</span></tt> method’s parameters are</p>
<ul class="simple">
<li><strong>UserState</strong> - This is the same as specified above. It could
include parameters or a pointer to inhomogeneous drivers of the system.</li>
<li><strong>local_marking</strong> - Most of the work here is manipulation of the
local marking. It has methods to add a token, remove a token, move
a token, read a value from a token, or modify a token. It also has
convenience methods to move all tokens associated with a marking.
The local_marking contains stochiometric coefficients for the
transition.</li>
<li><strong>enabling_time</strong> - If the transition was previously-enabled,
this is the previous enabling time. Otherwise, it is the current
absolute time of the GSPN.</li>
<li><strong>current time</strong> - The current absolute time of the system.</li>
</ul>
<p>For a newly-enabled transition, the current time and enabling time
will be the same. The <cite>enable</cite> method will be called any time
a transition fires which shares an input or output place.
If this transition was enabled and should remain so, then it
likely wants to keep its original enabling time.</p>
</div>
<div class="section" id="using-explicittransitionsbuilder">
<h3>Using ExplicitTransitionsBuilder<a class="headerlink" href="#using-explicittransitionsbuilder" title="Permalink to this headline">¶</a></h3>
<p>The implementation of <tt class="docutils literal"><span class="pre">ExplicitTransitions</span></tt> requires that
we construct it with a builder which then produces the GSPN
object. The builder has just three methods, <cite>add_place()</cite>,
<cite>add_transition()</cite>, and <cite>build()</cite>. It checks that transitions
have, as inputs and outputs, places which exist. It ensures
every PlaceKey and TransitionKey is unique. The signatures
of its methods:</p>
<div class="highlight-python"><pre>void BuildGraph::AddPlace(const PlaceKey&, size_t token_layer);
typedef std::tuple<PlaceKey,int> BuildGraph::PlaceEdge;
void BuildGraph::AddTransition(const TransitionKey&,
const std::vector<BuildGraph::PlaceEdge>&,
std::unique_ptr<ExplicitTransition<<Local,RandGen,WithParams>);</pre>
</div>
<p>The <cite>PlaceEdge</cite> contains a PlaceKey and a stochiometric coefficient,
which should be negative on inputs and positive on outputs, and specifies
the number of tokens required and the number to move when firing.</p>
<p>For example, we can take advantage of the C++ initializer_list
to construct a GSPN succinctly:</p>
<div class="highlight-python"><pre>GSPN
build_system(size_t individual_cnt)
{
BuildGraph<GSPN> bg;
using Edge=BuildGraph<GSPN>::PlaceEdge;
enum { s, i, r };
for (size_t ind_idx=0; ind_idx<individual_cnt; ind_idx++)
{
for (size_t place : std::vector<int>{s, i, r})
{
bg.AddPlace({place, ind_idx}, 0);
}
}
for (size_t left_idx=0; left_idx<individual_cnt-1; left_idx++)
{
bg.AddTransition({left_idx, left_idx, 0},
{Edge{{i, left_idx}, -1}, Edge{{r, left_idx}, 1}},
std::unique_ptr<SIRTransition>(new Recover())
);
for (size_t right_idx=left_idx+1; right_idx<individual_cnt; right_idx++)
{
SIRPlace left{i, left_idx};
SIRPlace rights{s, right_idx};
SIRPlace righti{i, right_idx};
bg.AddTransition({left_idx, right_idx, 0},
{Edge{left, -1}, Edge{rights, -1}, Edge{left, 1}, Edge{righti, 1}},
std::unique_ptr<SIRTransition>(new InfectNeighbor()));
SIRPlace lefts{s, left_idx};
SIRPlace lefti{i, left_idx};
SIRPlace right{i, right_idx};
bg.AddTransition({right_idx, left_idx, 0},
{Edge{right, -1}, Edge{lefts, -1}, Edge{right, 1}, Edge{lefti, 1}},
std::unique_ptr<SIRTransition>(new InfectNeighbor()));
}
}
// std::move the transitions because they contain unique_ptr.
return std::move(bg.build());
}</pre>
</div>
</div>
<div class="section" id="create-marking-and-state">
<h3>Create Marking and State<a class="headerlink" href="#create-marking-and-state" title="Permalink to this headline">¶</a></h3>
<p>The last step is to create the marking and state.
There is one implementation of a marking in the library.
While we defined a <cite>PlaceKey</cite> above, the <cite>ExplicitTransitions</cite>
class uses a different place and transition key internally,
chosen by the Boost Graph Library implementation. Both are
just type <cite>size_t</cite>. The marking and state are therefore:</p>
<div class="highlight-python"><pre>using Mark=Marking<size_t, Uncolored<IndividualToken>>;
using State=GSPNState<Mark,TransitionKey,UserState>;
State state;</pre>
</div>
<p>If the <cite>UserState</cite> had a member named <cite>parameters</cite>, then we could access
it as <cite>state.user.parameters</cite>.</p>
<p>How do we initialize the marking? Unfortunately, the marking doesn’t
use our <cite>PlaceKey</cite>, so we have to add a translation step from
the <cite>PlaceKey</cite> we know to the <cite>size_t</cite> we don’t:</p>
<div class="highlight-python"><pre>size_t susceptible=gspn.PlaceVertex(
PlaceKey{Disease::Susceptible, individual_idx});
add<0>(state.marking, susceptible, IndividualToken{});</pre>
</div>
<p>The GSPN remembers the original <cite>PlaceKey</cite> and will translate
for us. The second line adds a new token to the marking.</p>
<p>That’s everything that defines the model and the state of the system.
We made places, transitions, and a marking. The next step is
to simulate a trajectory of the system.</p>
</div>
</div>
<div class="section" id="simulating-the-trajectory-of-a-semi-markov-gspn">
<h2>Simulating the Trajectory of a Semi-Markov GSPN<a class="headerlink" href="#simulating-the-trajectory-of-a-semi-markov-gspn" title="Permalink to this headline">¶</a></h2>
<p>Given a representation of a GSPN, what steps will simulate
a trajectory from that GSPN? As a semi-Markov model, the GSPN
tracks in time the state of a system and defines the possible
transitions to next states of the system. The core matrix of a
semi-Markov model is just that, the probability of any next state
and the probability of when that a particular state happens.
We simulate a trajectory by looking at only the transitions which
are enabled for the current state. This is the <em>partial core matrix.</em>
Given this partial core matrix, a propagator selects the next state.</p>
<p>The partial core matrix has two responsibilities. For the
underlying GSPN, it enforces the rule, central to this kind
of semi-Markov model, that distributions of transitions are
recalculated only when a transition fires which shares marking.
Sharing markings is the only permitted way to express dependence among
processes in the system. A distribution may depend arbitrarily
on external state, such as temperature, but no transition can
affect the distribution of another transition except by changing
the marking.</p>
<p>The partial core matrix also has a responsiblity
to present to a propagator
distributions in time of the currently-enabled competing processes.
The propagator is a function which samples these distributions to
return the next transition to fire.:</p>
<div class="highlight-python"><pre>using HazardPropagator=NonHomogeneousPoissonProcesses<TransitionKey,RandGen>;
HazardPropagator competing_hazards;
using GeneralPropagator=PropagateCompetingProcesses<TransitionKey,RandGen>;
GeneralPropagator other_processes;
using Dynamics=StochasticDynamics<SIRGSPN,SIRState,RandGen>;
Dynamics dynamics(gspn, {&competing_hazards, &other_processes});</pre>
</div>
<p>It is the StochasticDynamics class that coordinates, inside, with
the partial core matrix. It will take
enabled transitions from the GSPN and give their distributions
to the appropriate propagator, depending on whether that propagator
can calculate the firing time of that distribution.
When a transition changes the marking,
the StochasticDynamics object is able to track which parts of the
marking changed and enable or disable transitions appropriately.</p>
<p>Finally, the main loop becomes short:</p>
<div class="highlight-python"><pre>dynamics.Initialize(&state, &rng);
bool running=true;
auto nothing=[](SIRState&)->void {};
while (running) {
running=dynamics(state);
output_function(state);
}
output_function.final(state);</pre>
</div>
<p>Here, <tt class="docutils literal"><span class="pre">output_function</span></tt> is an object which acts on the state
and gathers results.</p>
</div>
<div class="section" id="observations-of-the-state">
<h2>Observations of the State<a class="headerlink" href="#observations-of-the-state" title="Permalink to this headline">¶</a></h2>
<p>After each transition, we observe the state of the
system using the GSPN object and the GSPNState object.</p>
<dl class="class">
<dt id="afidd::smv::GSPNState:Marking.UserSate:">
<em class="property">class </em><tt class="descclassname">afidd::smv::</tt><tt class="descname">GSPNState<Marking, UserSate></tt><a class="headerlink" href="#afidd::smv::GSPNState:Marking.UserSate:" title="Permalink to this definition">¶</a></dt>
<dd><p>This class is the state of the system.</p>
</dd></dl>
<dl class="member">
<dt id="GSPNState::marking__Marking:Place.Tokens:">
Marking<Place, Tokens> <tt class="descclassname">GSPNState::</tt><tt class="descname">marking</tt><a class="headerlink" href="#GSPNState::marking__Marking:Place.Tokens:" title="Permalink to this definition">¶</a></dt>
<dd><p>The marking is saved as a <cite>marking</cite> member. The member function
<cite>state.marking.modified()</cite> will list which places changed
during the last transition.</p>
</dd></dl>
<dl class="function">
<dt id="GSPNState::current_timeC">
double <tt class="descclassname">GSPNState::</tt><tt class="descname">current_time</tt><big>(</big><big>)</big><tt class="descclassname"> const</tt><a class="headerlink" href="#GSPNState::current_timeC" title="Permalink to this definition">¶</a></dt>
<dd><p>The absolute time of the system.</p>
</dd></dl>
<dl class="member">
<dt id="GSPNState::user__UserState">
UserState <tt class="descclassname">GSPNState::</tt><tt class="descname">user</tt><a class="headerlink" href="#GSPNState::user__UserState" title="Permalink to this definition">¶</a></dt>
<dd><p>This member is an instance of the class <cite>UserState.</cite></p>
</dd></dl>
<p>For example, an instance of the following class observes
when the number of infected individuals within a population
has passed a given threshold:</p>
<div class="highlight-python"><pre>template<typename GSPN>
class SIROutputFunction
{
public:
typedef void result_type;
private:
size_t _pop_cnt;
size_t _ind_cnt;
size_t _threshold;
std::vector<size_t> _infected_per_pop;
std::vector<double> _first_passage_time;
std::vector<bool> _passed;
public:
SIROutputFunction(size_t population_cnt,
size_t individuals_per_metapopulation, size_t threshold_for_passage)
: _pop_cnt(population_cnt), _ind_cnt(individuals_per_metapopulation),
_threshold(threshold_for_passage),
_first_passage_time(population_cnt, 0), _passed(population_cnt, false),
_infected_per_pop(population_cnt, 0)
{
}
result_type operator()(const GSPN& gspn, const SIRState& state)
{
auto& modified=state.marking.modified();
for (auto place_idx : modified)
{
// Translate the internal place index into the PlaceKey
// used to define the GSPN when building the graph.
SIRPlace p=gspn.vertex_place(place_idx);
if (p.disease==1)
{
bool filled=(length<0>(state.marking, place_idx)>0);
if (filled)
{
_infected_per_pop[p.metapop]+=1;
if (_infected_per_pop[p.metapop]==_threshold)
{
_first_passage_time[p.metapop]=state.current_time();
_passed[p.metapop]=true;
BOOST_LOG_TRIVIAL(info)<<"Population "<<p.metapop
<<" at time "<<state.current_time();
}
}
}
}
}
};</pre>
</div>
<p>We use such an object by calling it within the main loop:</p>
<div class="highlight-python"><pre>size_t transition_cnt=0;
auto nothing=[](SIRState&)->void {};
for ( ;
std::get<1>(next)<std::numeric_limits<double>::max();
next=propagate_competing_processes(system, nothing, rng))
{
BOOST_LOG_TRIVIAL(debug) << "trans " << std::get<0>(next) << " time " <<
std::get<1>(next);
++transition_cnt;
output(gspn, state);
}</pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="examples.html" title="Examples"
>next</a> |</li>
<li class="right" >
<a href="background.html" title="Background"
>previous</a> |</li>
<li><a href="index.html">Semi-Markov 1.0 documentation</a> »</li>
<li><a href="manual.html" >Semi-Markov Library Manual</a> »</li>
</ul>
</div>
<div class="footer">
© Copyright 2014, Andrew Dolgert, David Schneider.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>