408 lines
27 KiB
HTML
408 lines
27 KiB
HTML
<html>
|
||
<head>
|
||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||
<title>Overview</title>
|
||
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
|
||
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
|
||
<link rel="home" href="../index.html" title="Chapter 1. Boost.Histogram">
|
||
<link rel="up" href="../index.html" title="Chapter 1. Boost.Histogram">
|
||
<link rel="prev" href="../index.html" title="Chapter 1. Boost.Histogram">
|
||
<link rel="next" href="getting_started.html" title="Getting started">
|
||
</head>
|
||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||
<table cellpadding="2" width="100%"><tr>
|
||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
|
||
<td align="center"><a href="../../../../../index.html">Home</a></td>
|
||
<td align="center"><a href="../../../../libraries.htm">Libraries</a></td>
|
||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
|
||
</tr></table>
|
||
<hr>
|
||
<div class="spirit-nav">
|
||
<a accesskey="p" href="../index.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="getting_started.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||
<a name="histogram.overview"></a><a class="link" href="overview.html" title="Overview">Overview</a>
|
||
</h2></div></div></div>
|
||
<div class="toc"><dl class="toc">
|
||
<dt><span class="section"><a href="overview.html#histogram.overview.introduction">Introduction</a></span></dt>
|
||
<dt><span class="section"><a href="overview.html#histogram.overview.structure">Structure</a></span></dt>
|
||
<dd><dl>
|
||
<dt><span class="section"><a href="overview.html#histogram.overview.structure.host">Histogram host class</a></span></dt>
|
||
<dt><span class="section"><a href="overview.html#histogram.overview.structure.axis">Axis types</a></span></dt>
|
||
<dt><span class="section"><a href="overview.html#histogram.overview.structure.storage">Storage types</a></span></dt>
|
||
</dl></dd>
|
||
</dl></div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="histogram.overview.introduction"></a><a class="link" href="overview.html#histogram.overview.introduction" title="Introduction">Introduction</a>
|
||
</h3></div></div></div>
|
||
<p>
|
||
<a href="https://en.wikipedia.org/wiki/Histogram" target="_top">Histograms</a> are
|
||
a basic tool in statistical analysis. A histogram consists of a number of
|
||
non-overlapping cells in data space. When an input value is passed to the
|
||
histogram, the corresponding cell that envelopes the value is found and an
|
||
associated counter is incremented.
|
||
</p>
|
||
<p>
|
||
When analyzing a large low-dimensional data set, it is more convenient to
|
||
work with a histogram of the input values than the original values. Keeping
|
||
the cell counts in memory for analysis and/or processing the counts requires
|
||
far fewer resources than keeping the original values in memory and processing
|
||
them. Information present in the original can also be extracted from the
|
||
histogram<a href="#ftn.histogram.overview.introduction.f0" class="footnote" name="histogram.overview.introduction.f0"><sup class="footnote">[1]</sup></a>. Some information is lost in this way, but if the cells are small
|
||
enough<a href="#ftn.histogram.overview.introduction.f1" class="footnote" name="histogram.overview.introduction.f1"><sup class="footnote">[2]</sup></a>, the loss is negligible. A histogram is a kind of lossy data-compression.
|
||
It is also often used as a simple estimator for the <a href="https://en.wikipedia.org/wiki/Probability_density_function" target="_top">probability
|
||
density function</a> of the input data. More complex density estimators
|
||
exist, but histograms remain attractive because they are easy to reason about.
|
||
</p>
|
||
<p>
|
||
This library provides a histogram for multi-dimensional data. In the multi-dimensional
|
||
case, the input consist of tuples of values which belong together and describing
|
||
different aspects of the same entity. For example, when you make a digital
|
||
image with a camera, photons hit a pixel detector. The photon is the entity
|
||
and it has two coordinates values where it hit the detector. The camera only
|
||
counts how often a photon hit each cell, so it is a real-life example of
|
||
making a two-dimensional histogram. A two-dimensional histogram collects
|
||
more information than two separate one-dimensional histograms, one for each
|
||
coordinate. For example, if the two-dimensional image looks like a checker
|
||
board, with high and low densities are alternating along each coordinate,
|
||
then the one-dimensional histograms along each coordinate would look flat.
|
||
There would be no hint that there is a complex structure in two dimensions.
|
||
</p>
|
||
<p>
|
||
The term <span class="emphasis"><em>histogram</em></span> is usually strictly used for something
|
||
with cells over discrete or continuous data. This histogram class can also
|
||
process categorical variables and it even allows for non-consecutive cells
|
||
if that is desired. There is no restriction to numbers as input either. Any
|
||
C++ type can be fed into the histogram, if the user provides a specialized
|
||
axis class that maps values of this type to a cell index. The only remaining
|
||
restriction is that cells are non-overlapping, since there must be a unique
|
||
mapping from input value to cell. The library is not able to automatically
|
||
ensure this for user-provided axis classes, so the responsibly is on the
|
||
user.
|
||
</p>
|
||
<p>
|
||
Furthermore, the histogram can handle weighted input. Normally, the cell
|
||
counter which is connected to an input tuple is incremented by one, but sometimes
|
||
it is useful to increment by a weight, an integral or floating point number.
|
||
Finally, the histogram can be configured to store any kind of accumulator
|
||
in each cell. Arbitrary samples can be passed to this accumulator, which
|
||
may compute the mean or other interesting quantities from the samples that
|
||
are sorted into the cell. When the accumulator computes a mean, the result
|
||
is called a <span class="emphasis"><em>profile</em></span>. The feature set is informed by
|
||
popular libraries for scientific computing, notably <a href="https://root.cern.ch" target="_top">CERN's
|
||
ROOT framework</a> and the <a href="https://www.gnu.org/software/gsl" target="_top">GNU
|
||
Scientific Library</a>.
|
||
</p>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="histogram.overview.structure"></a><a class="link" href="overview.html#histogram.overview.structure" title="Structure">Structure</a>
|
||
</h3></div></div></div>
|
||
<div class="toc"><dl class="toc">
|
||
<dt><span class="section"><a href="overview.html#histogram.overview.structure.host">Histogram host class</a></span></dt>
|
||
<dt><span class="section"><a href="overview.html#histogram.overview.structure.axis">Axis types</a></span></dt>
|
||
<dt><span class="section"><a href="overview.html#histogram.overview.structure.storage">Storage types</a></span></dt>
|
||
</dl></div>
|
||
<p>
|
||
The library consists of three orthogonal components:
|
||
</p>
|
||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||
<li class="listitem">
|
||
<a class="link" href="overview.html#histogram.overview.structure.host" title="Histogram host class">histogram host class</a>:
|
||
The histogram host class defines the public user interface and holds
|
||
axis objects (one for each dimension) and a storage object. The user
|
||
can chose whether axis objects are stored in a static tuple, a vector,
|
||
or a vector of variants.
|
||
</li>
|
||
<li class="listitem">
|
||
<a class="link" href="overview.html#histogram.overview.structure.axis" title="Axis types">axis types</a>:
|
||
Defines how input values are mapped to bins. Several axis types are provided
|
||
which implement different specializations. Users can make their own axis
|
||
types following the axis concept and use them with the library. A variant
|
||
type is provided, which can hold one of several concrete axis types.
|
||
</li>
|
||
<li class="listitem">
|
||
<a class="link" href="overview.html#histogram.overview.structure.storage" title="Storage types">storage types</a>:
|
||
Manages a collection of bin counters. The requirements for a storage
|
||
differ from those of an STL container, it needs to follow the storage
|
||
concept. Two implementations are provided.
|
||
</li>
|
||
</ul></div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h4 class="title">
|
||
<a name="histogram.overview.structure.host"></a><a class="link" href="overview.html#histogram.overview.structure.host" title="Histogram host class">Histogram host class</a>
|
||
</h4></div></div></div>
|
||
<p>
|
||
Histograms store axis objects and a storage object. A one-dimensional histogram
|
||
has one axis, a multi-dimensional histogram has several. When you pass
|
||
an input tuple, say (v1, v2, v3), then the first axis will map v1 onto
|
||
index i1, the second axis v2 onto i2, and so on, to generate the index
|
||
tuple (i1, i2, i3). The histogram host class then converts these indices
|
||
into a linear global index that is used to address bin counter in the storage
|
||
object.
|
||
</p>
|
||
<div class="note"><table border="0" summary="Note">
|
||
<tr>
|
||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
|
||
<th align="left">Note</th>
|
||
</tr>
|
||
<tr><td align="left" valign="top"><p>
|
||
To understand the need for multi-dimensional histograms, think of point
|
||
coordinates. If all points that you consider lie on a line, you need
|
||
only one value to describe the point. If all points lie in a plane, you
|
||
need two values to describe the position. Three values are needed for
|
||
a point in space. A histogram puts a discrete grid over the line, the
|
||
plane or the space, and counts how many points lie in each cell of the
|
||
grid. To approximate a point distribution on a line, a 1d-histogram is
|
||
sufficient. To do the same in 3d-space, one needs a 3d-histogram.
|
||
</p></td></tr>
|
||
</table></div>
|
||
<p>
|
||
This library supports different axis types, so that the user can customize
|
||
how the mapping is done exactly, see <a class="link" href="overview.html#histogram.overview.structure.axis" title="Axis types">axis
|
||
types</a>. Users can furthermore chose between several ways of storing
|
||
axis types in the histogram.
|
||
</p>
|
||
<p>
|
||
When the number and types of the axes are known at compile-time, the histogram
|
||
host class stores axis types in a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span></code>.
|
||
We call this a <span class="emphasis"><em>static histogram</em></span>. To access a particular
|
||
axis, one should use a compile-time number as index (a run-time index also
|
||
works with some limitations). A static histogram is extremely fast (see
|
||
<a class="link" href="benchmarks.html" title="Benchmarks">benchmark</a>), because there is
|
||
no overhead and the compiler can inline code, unroll loops, and more. Also,
|
||
many user errors are can be caught at compile-time rather than run-time.
|
||
</p>
|
||
<p>
|
||
Static histograms are the best kind, but cannot be used when histograms
|
||
are to be created with an axis configuration that is only known at run-time.
|
||
This is the case, for example, when histograms are created from Python
|
||
or from a graphical user interface. Therefore also more dynamic kinds of
|
||
histograms are supported.
|
||
</p>
|
||
<p>
|
||
There are two levels of dynamism. The histogram can hold instances of a
|
||
single axis type in a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span></code>.
|
||
Now the number of axis instances per histogram can vary at run-time, but
|
||
the axis type must be the same for all instances. We call this a <span class="emphasis"><em>semi-dynamic
|
||
histogram</em></span>.
|
||
</p>
|
||
<p>
|
||
If also the axis types need to vary at run-time, one can place <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">variant</span></code> type in a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span></code>,
|
||
which can hold one of a set of different concrete axis types. We call this
|
||
a <span class="emphasis"><em>dynamic histogram</em></span>. The dynamic histogram is a single
|
||
type that can store arbitrary sequences of different axes types, which
|
||
may be generated at run-time. The polymorphic behavior of the generic
|
||
<code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">variant</span></code> type has a run-time cost, however.
|
||
Typically, the performance is reduced by a factor of two compared to a
|
||
static histogram.
|
||
</p>
|
||
<div class="note"><table border="0" summary="Note">
|
||
<tr>
|
||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
|
||
<th align="left">Note</th>
|
||
</tr>
|
||
<tr><td align="left" valign="top"><p>
|
||
The design decision to store axis types in the variant-like type <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">variant</span></code> has several advantages over
|
||
forms of run-time polymorphism. Firstly, it guarantees that axis objects
|
||
which belong to the same histogram are stored locally together in memory,
|
||
which reduces cache misses when the histogram iterates over axis objects
|
||
in a tight loop, which it often does. Secondly, each axis can accept
|
||
a different value type in this scheme. Classic polymorphism with vtables
|
||
requires that all classes share the same method call signatures, but
|
||
we want different axis to allowed to accepted different types of arguments.
|
||
Variants work well for this case.
|
||
</p></td></tr>
|
||
</table></div>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h4 class="title">
|
||
<a name="histogram.overview.structure.axis"></a><a class="link" href="overview.html#histogram.overview.structure.axis" title="Axis types">Axis types</a>
|
||
</h4></div></div></div>
|
||
<p>
|
||
An axis defines an injective mapping of (a range of) input values to a
|
||
bin. The logic is encapsulated in an axis type. Users can create their
|
||
own axis classes and use them with the library, by implementing the <a class="link" href="concepts.html#histogram.concepts.Axis" title="Axis"><span class="bold"><strong>Axis</strong></span>
|
||
concept</a>. The library comes with four builtin types, which implement
|
||
different specializations.
|
||
</p>
|
||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||
<li class="listitem">
|
||
<code class="computeroutput"><a class="link" href="../boost/histogram/axis/regular.html" title="Class template regular">boost::histogram::axis::regular</a></code>
|
||
sorts real numbers into bins with equal width. The regular axis also
|
||
supports monotonic transforms, which are applied when the input values
|
||
are passed to the axis. This can be used to make a fast logarithmic
|
||
axis, where the bins have equal width in the logarithm of the variable.
|
||
</li>
|
||
<li class="listitem">
|
||
<code class="computeroutput"><a class="link" href="../boost/histogram/axis/variable.html" title="Class template variable">boost::histogram::axis::variable</a></code>
|
||
sorts real numbers into bins with varying width.
|
||
</li>
|
||
<li class="listitem">
|
||
<code class="computeroutput"><a class="link" href="../boost/histogram/axis/integer.html" title="Class template integer">boost::histogram::axis::integer</a></code>
|
||
is a specialization of a regular axis for a range of integers with
|
||
unit bin width. It is much faster than a regular axis.
|
||
</li>
|
||
<li class="listitem">
|
||
<code class="computeroutput"><a class="link" href="../boost/histogram/axis/category.html" title="Class template category">boost::histogram::axis::category</a></code>
|
||
is a bijective mapping of unique values onto bin indices and vice versa.
|
||
This can be used with discrete categorical data, like "red",
|
||
"green", "blue", for example.
|
||
</li>
|
||
</ul></div>
|
||
<p>
|
||
Each builtin axis type has a few compile-time options, which change its
|
||
behavior.
|
||
</p>
|
||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||
<li class="listitem">
|
||
All axis types can have an optional overflow bin. When the overflow
|
||
bin is enabled and an input value is above the range covered by the
|
||
axis, it is not discarded but counted in the overflow bin.
|
||
</li>
|
||
<li class="listitem">
|
||
All axis types except the category axis can have an optional underflow
|
||
bin. When the underflow bin is enabled and an input value is below
|
||
the range covered by the axis, it is not discarded but counted in the
|
||
underflow bin.
|
||
</li>
|
||
<li class="listitem">
|
||
All axis types except the category axis can be circular, meaning that
|
||
the axis range is periodic. This is useful for periodic data like polar
|
||
angles.
|
||
</li>
|
||
<li class="listitem">
|
||
All axis types can optionally grow. When an input value is outside
|
||
of the range of an axis which is configured to grow, the range of the
|
||
axis is extended until the value is in range. This option is incompatible
|
||
with the circular option, only either can be active.
|
||
</li>
|
||
</ul></div>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h4 class="title">
|
||
<a name="histogram.overview.structure.storage"></a><a class="link" href="overview.html#histogram.overview.structure.storage" title="Storage types">Storage types</a>
|
||
</h4></div></div></div>
|
||
<p>
|
||
A storage type holds the actual cell values. It uses a one-dimensional
|
||
index for cell lookup, computed by the histogram host from the indices
|
||
generated by its axes. The storage needs to know nothing about axes. Users
|
||
can integrate their own storage classes with the library, by implementing
|
||
the <a class="link" href="concepts.html#histogram.concepts.Storage" title="Storage">storage concept</a>.
|
||
Standard containers can be used as storage backends, the library adapts
|
||
them with the <code class="computeroutput"><a class="link" href="../boost/histogram/storage_adaptor.html" title="Class template storage_adaptor">boost::histogram::storage_adaptor</a></code>.
|
||
</p>
|
||
<p>
|
||
Cell lookup is often happening in a tight loop and is random-access. A
|
||
normal <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span></code> works well as a storage backend.
|
||
Sometimes this is the best solution, but there are some caveats to this
|
||
approach. The user has to decide which type should represents the cell
|
||
counts and it is not an obvious choice. An integer type needs to be large
|
||
enough to avoid counter overflow, but only a fraction of the bits are used
|
||
if its capacity is too large. This is a waste of memory then. When memory
|
||
is wasted, more cache misses occur and performance is degraded (see the
|
||
benchmarks). The performance of modern CPUs depends a lot on effective
|
||
utilization of the CPU cache, which is still small. Using floating point
|
||
numbers instead of integers is also dangerous. They don't overflow, but
|
||
cap the bin count when the bits in the mantissa are used up.
|
||
</p>
|
||
<p>
|
||
The default storage used in the library is <code class="computeroutput"><a class="link" href="../boost/histogram/unlimited_storage.html" title="Class template unlimited_storage">boost::histogram::unlimited_storage</a></code>.
|
||
It solves these issues with a dynamic counter type management, based on
|
||
the following insight. The <a href="https://en.wikipedia.org/wiki/Curse_of_dimensionality" target="_top">curse
|
||
of dimensionality</a> makes the total number of bins grow very fast
|
||
as the dimension of the histogram grows. However, having many bins also
|
||
reduces the typical number of counts per bin, since the input values are
|
||
spread over many more bins now. This means a small counter is often sufficient
|
||
for high-dimensional histograms.
|
||
</p>
|
||
<p>
|
||
The default storage therefore starts with a minimum amount of memory per
|
||
cell, it uses an 1 byte. If the count in any cell is about to overflow,
|
||
all cells switch to the next larger integer type simultaneously. This goes
|
||
on, the capacity per cell is always doubled when it is used up, until 8
|
||
byte per bin are reached. The following images illustrate this progression
|
||
for a storage of 3 bin counters. A new memory block is always allocated
|
||
for all counters, when the first one of them hits its capacity limit.
|
||
</p>
|
||
<p>
|
||
<span class="inlinemediaobject"><object type="image/svg+xml" data="../../storage_3_uint8.svg" width="65" height="23"></object></span>
|
||
</p>
|
||
<p>
|
||
<span class="inlinemediaobject"><object type="image/svg+xml" data="../../storage_3_uint16.svg" width="129" height="23"></object></span>
|
||
</p>
|
||
<p>
|
||
<span class="inlinemediaobject"><object type="image/svg+xml" data="../../storage_3_uint32.svg" width="256" height="23"></object></span>
|
||
</p>
|
||
<p>
|
||
<span class="inlinemediaobject"><object type="image/svg+xml" data="../../storage_3_uint64.svg" width="511" height="23"></object></span>
|
||
</p>
|
||
<p>
|
||
When even that is not enough, the default storage switches to a multiprecision
|
||
type similar to those in <a href="../../../../../libs/multiprecision/index.html" target="_top">Boost.Multiprecision</a>,
|
||
whose capacity is limited only by available memory. The following image
|
||
is not to scale:
|
||
</p>
|
||
<p>
|
||
<span class="inlinemediaobject"><object type="image/svg+xml" data="../../storage_3_cpp_int.svg" width="511" height="23"></object></span>
|
||
</p>
|
||
<p>
|
||
This approach is not only memory conserving, but also provides the strong
|
||
guarantee that bin counters cannot overflow.
|
||
</p>
|
||
<div class="note"><table border="0" summary="Note">
|
||
<tr>
|
||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
|
||
<th align="left">Note</th>
|
||
</tr>
|
||
<tr><td align="left" valign="top"><p>
|
||
The no-overflow-guarantee only applies when the histogram is not using
|
||
weighted fills or if all weights are integral numbers. When floating
|
||
point weights are used, the default storage switches to a double counter
|
||
per cell to store the sum of such weights. A double cannot provide the
|
||
no-overflow-guarantee.
|
||
</p></td></tr>
|
||
</table></div>
|
||
<p>
|
||
The best part: this approach is even faster for a histogram with sufficient
|
||
size despite the run-time overheads of handling the counter type dynamically.
|
||
The benchmarks show that the gains from better cache usage outweigh the
|
||
run-time overheads of dynamic dispatching to the right bin counter type
|
||
and the occasional allocation costs. Doubling the size of the bin counters
|
||
each time helps, because the allocations happen only O(logN) times for
|
||
N increments.
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<div class="footnotes">
|
||
<br><hr style="width:100; text-align:left;margin-left: 0">
|
||
<div id="ftn.histogram.overview.introduction.f0" class="footnote"><p><a href="#histogram.overview.introduction.f0" class="para"><sup class="para">[1] </sup></a>
|
||
Parameters of interest, like the center of a distribution, can be extracted
|
||
from the histogram instead of the original data set; likewise, statistical
|
||
models can be fitted to histograms.
|
||
</p></div>
|
||
<div id="ftn.histogram.overview.introduction.f1" class="footnote"><p><a href="#histogram.overview.introduction.f1" class="para"><sup class="para">[2] </sup></a>
|
||
What small enough means has to be decided case by case.
|
||
</p></div>
|
||
</div>
|
||
</div>
|
||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||
<td align="left"></td>
|
||
<td align="right"><div class="copyright-footer">Copyright © 2016-2019 Hans
|
||
Dembinski<p>
|
||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||
</p>
|
||
</div></td>
|
||
</tr></table>
|
||
<hr>
|
||
<div class="spirit-nav">
|
||
<a accesskey="p" href="../index.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="getting_started.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||
</div>
|
||
</body>
|
||
</html>
|