• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<html>
2<head>
3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
4<title>User guide</title>
5<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
6<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
7<link rel="home" href="../index.html" title="Chapter 1. Boost.Histogram">
8<link rel="up" href="../index.html" title="Chapter 1. Boost.Histogram">
9<link rel="prev" href="getting_started.html" title="Getting started">
10<link rel="next" href="benchmarks.html" title="Benchmarks">
11</head>
12<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
13<table cellpadding="2" width="100%"><tr>
14<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
15<td align="center"><a href="../../../../../index.html">Home</a></td>
16<td align="center"><a href="../../../../libraries.htm">Libraries</a></td>
17<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
18<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
19<td align="center"><a href="../../../../../more/index.htm">More</a></td>
20</tr></table>
21<hr>
22<div class="spirit-nav">
23<a accesskey="p" href="getting_started.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="benchmarks.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
24</div>
25<div class="section">
26<div class="titlepage"><div><div><h2 class="title" style="clear: both">
27<a name="histogram.guide"></a><a class="link" href="guide.html" title="User guide">User guide</a>
28</h2></div></div></div>
29<div class="toc"><dl class="toc">
30<dt><span class="section"><a href="guide.html#histogram.guide.making_histograms">Making histograms</a></span></dt>
31<dt><span class="section"><a href="guide.html#histogram.guide.axis_guide">Axis guide</a></span></dt>
32<dd><dl>
33<dt><span class="section"><a href="guide.html#histogram.guide.axis_guide.overview">Overview</a></span></dt>
34<dt><span class="section"><a href="guide.html#histogram.guide.axis_guide.axis_configuration">Axis
35        configuration</a></span></dt>
36</dl></dd>
37<dt><span class="section"><a href="guide.html#histogram.guide.filling_histograms_and_accessing">Filling
38      histograms and accessing cells</a></span></dt>
39<dt><span class="section"><a href="guide.html#histogram.guide.using_profiles">Using profiles</a></span></dt>
40<dt><span class="section"><a href="guide.html#histogram.guide.using_operators">Using operators</a></span></dt>
41<dt><span class="section"><a href="guide.html#histogram.guide.using_algorithms">Using algorithms</a></span></dt>
42<dd><dl>
43<dt><span class="section"><a href="guide.html#histogram.guide.using_algorithms.algorithms_from_the_c_standard_l">Algorithms
44        from the C++ standard library</a></span></dt>
45<dt><span class="section"><a href="guide.html#histogram.guide.using_algorithms.summation">Summation</a></span></dt>
46<dt><span class="section"><a href="guide.html#histogram.guide.using_algorithms.projection">Projection</a></span></dt>
47<dt><span class="section"><a href="guide.html#histogram.guide.using_algorithms.reduction">Reduction</a></span></dt>
48</dl></dd>
49<dt><span class="section"><a href="guide.html#histogram.guide.streaming">Streaming</a></span></dt>
50<dt><span class="section"><a href="guide.html#histogram.guide.serialization">Serialization</a></span></dt>
51<dt><span class="section"><a href="guide.html#histogram.guide.using_histograms_in_apis">Using histograms
52      in APIs</a></span></dt>
53<dt><span class="section"><a href="guide.html#histogram.guide.expert">Advanced usage</a></span></dt>
54<dd><dl>
55<dt><span class="section"><a href="guide.html#histogram.guide.expert.user_defined_axes">User-defined
56        axes</a></span></dt>
57<dt><span class="section"><a href="guide.html#histogram.guide.expert.axis_with_several_arguments">Axis
58        with several arguments</a></span></dt>
59<dt><span class="section"><a href="guide.html#histogram.guide.expert.user_defined_storage_class">User-defined
60        storage class</a></span></dt>
61<dt><span class="section"><a href="guide.html#histogram.guide.expert.parallelisation_options">Parallelisation
62        options</a></span></dt>
63<dt><span class="section"><a href="guide.html#histogram.guide.expert.user_defined_accumulators">User-defined
64        accumulators</a></span></dt>
65</dl></dd>
66</dl></div>
67<p>
68      Boost.Histogram is designed to make simple things simple, yet complex things
69      possible. Correspondingly, this guides covers the basic usage first, and the
70      advanced usage in later sections. For an alternative quick start guide, have
71      a look at the <a class="link" href="getting_started.html" title="Getting started">Getting started</a>
72      section.
73    </p>
74<div class="section">
75<div class="titlepage"><div><div><h3 class="title">
76<a name="histogram.guide.making_histograms"></a><a class="link" href="guide.html#histogram.guide.making_histograms" title="Making histograms">Making histograms</a>
77</h3></div></div></div>
78<p>
79        A histogram consists of a collection of <a class="link" href="concepts.html#histogram.concepts.Axis" title="Axis">axis
80        objects</a> and a <a class="link" href="concepts.html#histogram.concepts.Storage" title="Storage">storage</a>.
81        The storage holds a collection of accumulators, one for each cell. The axis
82        objects maps input values to indices, which are combined into a global index
83        that is used to look up the cell in the storage.
84      </p>
85<p>
86        To start off you do not have to worry about the storage, the library provides
87        a good default. Learning more about the many interesting axis types to choose
88        from, however, will pay off very quickly (which are discussed further below).
89        For now, let us stick to the most common axis, the <code class="computeroutput"><a class="link" href="../boost/histogram/axis/regular.html" title="Class template regular">regular</a></code>
90        axis. It represents equidistant intervals on the real line.
91      </p>
92<p>
93        Histograms are created with the convenient factory function <code class="computeroutput"><a class="link" href="reference.html#header.boost.histogram.make_histogram_hpp" title="Header &lt;boost/histogram/make_histogram.hpp&gt;">make_histogram</a></code>.
94        The following example shows how to make a histogram with a single axis.
95      </p>
96<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
97<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
98
99<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
100  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>
101
102  <span class="comment">// create a 1d-histogram in default configuration which</span>
103  <span class="comment">// covers the real line from -1 to 1 in 100 bins</span>
104  <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">100</span><span class="special">,</span> <span class="special">-</span><span class="number">1.0</span><span class="special">,</span> <span class="number">1.0</span><span class="special">));</span>
105
106  <span class="comment">// rank is the number of axes</span>
107  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">rank</span><span class="special">()</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
108<span class="special">}</span>
109</pre>
110<p>
111        An axis object defines how input values are mapped to bins, it is a mapping
112        functor of input values to indices. The axis object holds information such
113        as how many bins there are, where the bin edges are, metadata about the axis
114        and so on. The rank of a histogram is given by the number of axes. A histogram
115        with one axis is one-dimensional. If you provide two, it is two-dimensional,
116        and so on.
117      </p>
118<p>
119        In the example above, the compiler knows the number of axes and their type
120        at compile-time, the information can be deduced from the arguments to <code class="computeroutput"><a class="link" href="reference.html#header.boost.histogram.make_histogram_hpp" title="Header &lt;boost/histogram/make_histogram.hpp&gt;">make_histogram</a></code>. This
121        gives the best performance, but sometimes you only know the axis configuration
122        at run-time, because it depends on information that's only available at run-time.
123        For that case you can also create axes at run-time and pass them to an overload
124        of the <code class="computeroutput"><a class="link" href="reference.html#header.boost.histogram.make_histogram_hpp" title="Header &lt;boost/histogram/make_histogram.hpp&gt;">make_histogram</a></code>
125        function. Here is an example.
126      </p>
127<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
128<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
129<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">sstream</span><span class="special">&gt;</span>
130<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">vector</span><span class="special">&gt;</span>
131
132<span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">config</span> <span class="special">=</span> <span class="string">"4 1.0 2.0\n"</span>
133                     <span class="string">"5 3.0 4.0\n"</span><span class="special">;</span>
134
135<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
136  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>
137
138  <span class="comment">// read axis config from a config file (mocked here with std::istringstream)</span>
139  <span class="comment">// and create vector of regular axes, the number of axis is not known at compile-time</span>
140  <span class="identifier">std</span><span class="special">::</span><span class="identifier">istringstream</span> <span class="identifier">is</span><span class="special">(</span><span class="identifier">config</span><span class="special">);</span>
141  <span class="keyword">auto</span> <span class="identifier">v1</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;&gt;();</span>
142  <span class="keyword">while</span> <span class="special">(</span><span class="identifier">is</span><span class="special">.</span><span class="identifier">good</span><span class="special">())</span> <span class="special">{</span>
143    <span class="keyword">unsigned</span> <span class="identifier">bins</span><span class="special">;</span>
144    <span class="keyword">double</span> <span class="identifier">start</span><span class="special">,</span> <span class="identifier">stop</span><span class="special">;</span>
145    <span class="identifier">is</span> <span class="special">&gt;&gt;</span> <span class="identifier">bins</span> <span class="special">&gt;&gt;</span> <span class="identifier">start</span> <span class="special">&gt;&gt;</span> <span class="identifier">stop</span><span class="special">;</span>
146    <span class="identifier">v1</span><span class="special">.</span><span class="identifier">emplace_back</span><span class="special">(</span><span class="identifier">bins</span><span class="special">,</span> <span class="identifier">start</span><span class="special">,</span> <span class="identifier">stop</span><span class="special">);</span>
147  <span class="special">}</span>
148
149  <span class="comment">// create histogram from iterator range</span>
150  <span class="comment">// (copying or moving the vector also works, move is shown below)</span>
151  <span class="keyword">auto</span> <span class="identifier">h1</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">v1</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">v1</span><span class="special">.</span><span class="identifier">end</span><span class="special">());</span>
152  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">rank</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">v1</span><span class="special">.</span><span class="identifier">size</span><span class="special">());</span>
153
154  <span class="comment">// with a vector of axis::variant (polymorphic axis type that can hold any one of the</span>
155  <span class="comment">// template arguments at a time) the types and number of axis can vary at run-time</span>
156  <span class="keyword">auto</span> <span class="identifier">v2</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">variant</span><span class="special">&lt;</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;,</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;&gt;&gt;&gt;();</span>
157  <span class="identifier">v2</span><span class="special">.</span><span class="identifier">emplace_back</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">100</span><span class="special">,</span> <span class="special">-</span><span class="number">1.0</span><span class="special">,</span> <span class="number">1.0</span><span class="special">));</span>
158  <span class="identifier">v2</span><span class="special">.</span><span class="identifier">emplace_back</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;&gt;(</span><span class="number">1</span><span class="special">,</span> <span class="number">7</span><span class="special">));</span>
159
160  <span class="comment">// create dynamic histogram by moving the vector</span>
161  <span class="keyword">auto</span> <span class="identifier">h2</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">v2</span><span class="special">));</span>
162  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">.</span><span class="identifier">rank</span><span class="special">()</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span>
163<span class="special">}</span>
164</pre>
165<div class="note"><table border="0" summary="Note">
166<tr>
167<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
168<th align="left">Note</th>
169</tr>
170<tr><td align="left" valign="top"><p>
171          When the axis types are known at compile-time, the histogram internally
172          holds them in a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span></code>, which is very efficient and avoids
173          a heap memory allocation. If the number of axes is only known at run-time,
174          they are stored in a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span></code>.
175          The interface hides this difference very well, but there are a corner cases
176          where the difference becomes apparent. The <a class="link" href="overview.html#histogram.overview.structure.host" title="Histogram host class">overview</a>
177          has more details on this point.
178        </p></td></tr>
179</table></div>
180<p>
181        The factory function named <code class="computeroutput"><a class="link" href="reference.html#header.boost.histogram.make_histogram_hpp" title="Header &lt;boost/histogram/make_histogram.hpp&gt;">make_histogram</a></code>
182        uses the default storage type, which provides safe counting, is fast, and
183        memory efficient. If you want to create a histogram with another storage
184        type, use <code class="computeroutput"><a class="link" href="reference.html#header.boost.histogram.make_histogram_hpp" title="Header &lt;boost/histogram/make_histogram.hpp&gt;">make_histogram_with</a></code>.
185        To learn more about other storage types and how to create your own, have
186        a look at the section <a class="link" href="guide.html#histogram.guide.expert" title="Advanced usage">Advanced Usage</a>.
187      </p>
188</div>
189<div class="section">
190<div class="titlepage"><div><div><h3 class="title">
191<a name="histogram.guide.axis_guide"></a><a class="link" href="guide.html#histogram.guide.axis_guide" title="Axis guide">Axis guide</a>
192</h3></div></div></div>
193<div class="toc"><dl class="toc">
194<dt><span class="section"><a href="guide.html#histogram.guide.axis_guide.overview">Overview</a></span></dt>
195<dt><span class="section"><a href="guide.html#histogram.guide.axis_guide.axis_configuration">Axis
196        configuration</a></span></dt>
197</dl></div>
198<p>
199        The library provides a number of useful axis types. The builtin axis types
200        can be configured to fit many needs. If you still need something more exotic,
201        no problem, it is easy to write your own axis types, see the <a class="link" href="guide.html#histogram.guide.expert" title="Advanced usage">Advanced
202        usage section</a> for details. In the following, we give some advice when
203        to use which of the builtin axis types.
204      </p>
205<div class="section">
206<div class="titlepage"><div><div><h4 class="title">
207<a name="histogram.guide.axis_guide.overview"></a><a class="link" href="guide.html#histogram.guide.axis_guide.overview" title="Overview">Overview</a>
208</h4></div></div></div>
209<div class="variablelist">
210<p class="title"><b></b></p>
211<dl class="variablelist">
212<dt><span class="term"> <code class="computeroutput"><a class="link" href="../boost/histogram/axis/regular.html" title="Class template regular">regular</a></code>
213            </span></dt>
214<dd><p>
215                Axis over intervals on the real line which have equal width. Value-to-index
216                conversion is O(1) and very fast. The axis does not allocate memory
217                dynamically. The axis is very flexible thanks to transforms (see
218                below). Due to finite precision of floating point calculations, bin
219                edges may not be exactly at expected values, though. If you need
220                bin edges at exactly defined floating point values, use the <code class="computeroutput"><a class="link" href="../boost/histogram/axis/variable.html" title="Class template variable">variable</a></code> axis.
221                If you need bins at exact consecutive integral values, use the <code class="computeroutput"><a class="link" href="../boost/histogram/axis/integer.html" title="Class template integer">integer</a></code> axis.
222              </p></dd>
223<dt><span class="term"> <code class="computeroutput"><a class="link" href="../boost/histogram/axis/variable.html" title="Class template variable">variable</a></code>
224            </span></dt>
225<dd><p>
226                Axis over intervals on the real line of variable width. Value-to-index
227                conversion is O(log(N)). The axis allocates memory dynamically to
228                store the bin edges. Use this if the regular axis with transforms
229                cannot represent the binning you want. If you need bin edges at exactly
230                defined floating point values, use this axis.
231              </p></dd>
232<dt><span class="term"> <code class="computeroutput"><a class="link" href="../boost/histogram/axis/integer.html" title="Class template integer">integer</a></code>
233            </span></dt>
234<dd><p>
235                Axis over an integer sequence [i, i+1, i+2, ...]. It can be configured
236                to handle real input values, too, and then acts like a fast regular
237                axis with a fixed bin width of 1. Value-to-index conversion is O(1)
238                and faster than for the <code class="computeroutput"><a class="link" href="../boost/histogram/axis/regular.html" title="Class template regular">regular</a></code>
239                axis. Does not allocate memory dynamically. Use this when your input
240                consists of an integer range or pre-digitized values with low dynamic
241                range, like pixel values for individual colours in an image.
242              </p></dd>
243<dt><span class="term"> <code class="computeroutput"><a class="link" href="../boost/histogram/axis/boolean.html" title="Class template boolean">boolean</a></code>
244            </span></dt>
245<dd><p>
246                Axis over the two values [false, true]. It is a common specialization
247                of the <code class="computeroutput"><a class="link" href="../boost/histogram/axis/regular.html" title="Class template regular">regular</a></code>
248                axis. Value-to-index conversion is a pass-through operation, so this
249                is the fastest possible axis. The axis has no state other than the
250                metadata (which can be stateless). Does not allocate memory dynamically.
251                Use this when your input consists of binary categories, like signal
252                and background.
253              </p></dd>
254<dt><span class="term"> <code class="computeroutput"><a class="link" href="../boost/histogram/axis/category.html" title="Class template category">category</a></code>
255            </span></dt>
256<dd><p>
257                Axis over a set of unique values of an arbitrary equal-comparable
258                type. Value-to-index conversion is O(N), but still faster than the
259                O(logN) complexity of the <code class="computeroutput"><a class="link" href="../boost/histogram/axis/variable.html" title="Class template variable">variable</a></code>
260                axis for N &lt; 10, the typical use case. The axis allocates memory
261                from the heap to store the values.
262              </p></dd>
263</dl>
264</div>
265<p>
266          Here is an example which shows the basic use case for each axis type.
267        </p>
268<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><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">hpp</span><span class="special">&gt;</span>
269<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">limits</span><span class="special">&gt;</span>
270
271<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
272  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>
273
274  <span class="comment">// make a regular axis with 10 bins over interval from 1.5 to 2.5</span>
275  <span class="keyword">auto</span> <span class="identifier">r</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;{</span><span class="number">10</span><span class="special">,</span> <span class="number">1.5</span><span class="special">,</span> <span class="number">2.5</span><span class="special">};</span>
276  <span class="comment">// `&lt;&gt;` is needed in C++14 because the axis is templated,</span>
277  <span class="comment">// in C++17 you can do: auto r = axis::regular{10, 1.5, 2.5};</span>
278  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">10</span><span class="special">);</span>
279  <span class="comment">// alternatively, you can define the step size with the `step` marker</span>
280  <span class="keyword">auto</span> <span class="identifier">r_step</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;{</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">step</span><span class="special">(</span><span class="number">0.1</span><span class="special">),</span> <span class="number">1.5</span><span class="special">,</span> <span class="number">2.5</span><span class="special">};</span>
281  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_step</span> <span class="special">==</span> <span class="identifier">r</span><span class="special">);</span>
282
283  <span class="comment">// histogram uses the `index` method to convert values to indices</span>
284  <span class="comment">// note: intervals of builtin axis types are always semi-open [a, b)</span>
285  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">1.5</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>
286  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">1.6</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
287  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">2.4</span><span class="special">)</span> <span class="special">==</span> <span class="number">9</span><span class="special">);</span>
288  <span class="comment">// index for a value below the start of the axis is always -1</span>
289  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">1.0</span><span class="special">)</span> <span class="special">==</span> <span class="special">-</span><span class="number">1</span><span class="special">);</span>
290  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(-</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;::</span><span class="identifier">infinity</span><span class="special">())</span> <span class="special">==</span> <span class="special">-</span><span class="number">1</span><span class="special">);</span>
291  <span class="comment">// index for a value below the above the end of the axis is always `size()`</span>
292  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">3.0</span><span class="special">)</span> <span class="special">==</span> <span class="number">10</span><span class="special">);</span>
293  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;::</span><span class="identifier">infinity</span><span class="special">())</span> <span class="special">==</span> <span class="number">10</span><span class="special">);</span>
294  <span class="comment">// index for not-a-number is also `size()` by convention</span>
295  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;::</span><span class="identifier">quiet_NaN</span><span class="special">())</span> <span class="special">==</span> <span class="number">10</span><span class="special">);</span>
296
297  <span class="comment">// make a variable axis with 3 bins [-1.5, 0.1), [0.1, 0.3), [0.3, 10)</span>
298  <span class="keyword">auto</span> <span class="identifier">v</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">variable</span><span class="special">&lt;&gt;{-</span><span class="number">1.5</span><span class="special">,</span> <span class="number">0.1</span><span class="special">,</span> <span class="number">0.3</span><span class="special">,</span> <span class="number">10.</span><span class="special">};</span>
299  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">v</span><span class="special">.</span><span class="identifier">index</span><span class="special">(-</span><span class="number">2.0</span><span class="special">)</span> <span class="special">==</span> <span class="special">-</span><span class="number">1</span><span class="special">);</span>
300  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">v</span><span class="special">.</span><span class="identifier">index</span><span class="special">(-</span><span class="number">1.5</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>
301  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">v</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">0.1</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
302  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">v</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">0.3</span><span class="special">)</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span>
303  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">v</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">10</span><span class="special">)</span> <span class="special">==</span> <span class="number">3</span><span class="special">);</span>
304  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">v</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">20</span><span class="special">)</span> <span class="special">==</span> <span class="number">3</span><span class="special">);</span>
305
306  <span class="comment">// make an integer axis with 3 bins at -1, 0, 1</span>
307  <span class="keyword">auto</span> <span class="identifier">i</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;&gt;{-</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">};</span>
308  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">i</span><span class="special">.</span><span class="identifier">index</span><span class="special">(-</span><span class="number">2</span><span class="special">)</span> <span class="special">==</span> <span class="special">-</span><span class="number">1</span><span class="special">);</span>
309  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">i</span><span class="special">.</span><span class="identifier">index</span><span class="special">(-</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>
310  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">i</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
311  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">i</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span>
312  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">i</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">2</span><span class="special">)</span> <span class="special">==</span> <span class="number">3</span><span class="special">);</span>
313
314  <span class="comment">// make an integer axis called "foo"</span>
315  <span class="keyword">auto</span> <span class="identifier">i_with_label</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;&gt;{-</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="string">"foo"</span><span class="special">};</span>
316  <span class="comment">// all builtin axis types allow you to pass some optional metadata as the last</span>
317  <span class="comment">// argument in the constructor; a string by default, but can be any copyable type</span>
318
319  <span class="comment">// two axis do not compare equal if they differ in their metadata</span>
320  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">i</span> <span class="special">!=</span> <span class="identifier">i_with_label</span><span class="special">);</span>
321
322  <span class="comment">// integer axis also work well with unscoped enums</span>
323  <span class="keyword">enum</span> <span class="special">{</span> <span class="identifier">red</span><span class="special">,</span> <span class="identifier">blue</span> <span class="special">};</span>
324  <span class="keyword">auto</span> <span class="identifier">i_for_enum</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;&gt;{</span><span class="identifier">red</span><span class="special">,</span> <span class="identifier">blue</span> <span class="special">+</span> <span class="number">1</span><span class="special">};</span>
325  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">i_for_enum</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="identifier">red</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>
326  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">i_for_enum</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="identifier">blue</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
327
328  <span class="comment">// make a category axis from a scoped enum and/or if the identifiers are not consecutive</span>
329  <span class="keyword">enum</span> <span class="keyword">class</span> <span class="identifier">Bar</span> <span class="special">{</span> <span class="identifier">red</span> <span class="special">=</span> <span class="number">12</span><span class="special">,</span> <span class="identifier">blue</span> <span class="special">=</span> <span class="number">6</span> <span class="special">};</span>
330  <span class="keyword">auto</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">category</span><span class="special">&lt;</span><span class="identifier">Bar</span><span class="special">&gt;{</span><span class="identifier">Bar</span><span class="special">::</span><span class="identifier">red</span><span class="special">,</span> <span class="identifier">Bar</span><span class="special">::</span><span class="identifier">blue</span><span class="special">};</span>
331  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">c</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="identifier">Bar</span><span class="special">::</span><span class="identifier">red</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>
332  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">c</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="identifier">Bar</span><span class="special">::</span><span class="identifier">blue</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
333  <span class="comment">// c.index(12) is a compile-time error, since the argument must be of type `Bar`</span>
334
335  <span class="comment">// category axis can be created for any copyable and equal-comparable type</span>
336  <span class="keyword">auto</span> <span class="identifier">c_str</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">category</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;{</span><span class="string">"red"</span><span class="special">,</span> <span class="string">"blue"</span><span class="special">};</span>
337  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">c_str</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="string">"red"</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>
338  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">c_str</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="string">"blue"</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
339<span class="special">}</span>
340</pre>
341<div class="note"><table border="0" summary="Note">
342<tr>
343<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
344<th align="left">Note</th>
345</tr>
346<tr><td align="left" valign="top"><p>
347            All builtin axes over a continuous value range use semi-open intervals
348            in their constructors as a convention. As a mnemonic, think of iterator
349            ranges from <code class="computeroutput"><span class="identifier">begin</span></code> to
350            <code class="computeroutput"><span class="identifier">end</span></code>, where <code class="computeroutput"><span class="identifier">end</span></code> is also never included.
351          </p></td></tr>
352</table></div>
353<p>
354          As mentioned in the previous example, you can assign an optional label
355          to any axis to keep track of what the axis is about. Assume you have census
356          data and you want to investigate how yearly income correlates with age,
357          you could do:
358        </p>
359<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
360
361<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
362  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>
363
364  <span class="comment">// create a 2d-histogram with an "age" and an "income" axis</span>
365  <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">20</span><span class="special">,</span> <span class="number">0.0</span><span class="special">,</span> <span class="number">100.0</span><span class="special">,</span> <span class="string">"age in years"</span><span class="special">),</span>
366                          <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">20</span><span class="special">,</span> <span class="number">0.0</span><span class="special">,</span> <span class="number">100.0</span><span class="special">,</span> <span class="string">"yearly income in Thousands"</span><span class="special">));</span>
367
368  <span class="comment">// do something with h</span>
369<span class="special">}</span>
370</pre>
371<p>
372          Without the metadata it would be difficult to see which axis was covering
373          which quantity. Metadata is the only axis property that can be modified
374          after construction by the user. Axis objects with different metadata do
375          not compare equal.
376        </p>
377<p>
378          By default, strings are used to store the metadata, but any type compatible
379          with the <a class="link" href="concepts.html#histogram.concepts.Axis" title="Axis"><span class="bold"><strong>Metadata</strong></span>
380          concept</a> can be used.
381        </p>
382</div>
383<div class="section">
384<div class="titlepage"><div><div><h4 class="title">
385<a name="histogram.guide.axis_guide.axis_configuration"></a><a class="link" href="guide.html#histogram.guide.axis_guide.axis_configuration" title="Axis configuration">Axis
386        configuration</a>
387</h4></div></div></div>
388<div class="toc"><dl class="toc">
389<dt><span class="section"><a href="guide.html#histogram.guide.axis_guide.axis_configuration.transforms">Transforms</a></span></dt>
390<dt><span class="section"><a href="guide.html#histogram.guide.axis_guide.axis_configuration.options">Options</a></span></dt>
391</dl></div>
392<p>
393          All builtin axis types have template arguments for customisation. All arguments
394          have reasonable defaults so you can use empty brackets. If your compiler
395          supports C++17, you can drop the brackets altogether. Suitable arguments
396          are then deduced from the constructor call. The template arguments are
397          in order:
398        </p>
399<div class="variablelist">
400<p class="title"><b></b></p>
401<dl class="variablelist">
402<dt><span class="term">Value</span></dt>
403<dd><p>
404                The value type is the argument type of the <code class="computeroutput"><span class="identifier">index</span><span class="special">()</span></code> method. An argument passed to the
405                axis must be implicitly convertible to this type.
406              </p></dd>
407<dt><span class="term">Transform (only <code class="computeroutput"><a class="link" href="../boost/histogram/axis/regular.html" title="Class template regular">regular</a></code>
408            axis)</span></dt>
409<dd><p>
410                A class that implements a monotonic transform between the data space
411                and the space in which the bins are equi-distant. Users can define
412                their own transforms and use them with the axis.
413              </p></dd>
414<dt><span class="term">Metadata</span></dt>
415<dd><p>
416                The axis uses an instance this type to store metadata. It is a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> by default, but it can by
417                any copyable type. If you want to save a small amount of stack memory
418                per axis, you pass the empty <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">null_type</span></code>
419                here.
420              </p></dd>
421<dt><span class="term">Options</span></dt>
422<dd><p>
423                <code class="computeroutput"><a class="link" href="reference.html#header.boost.histogram.axis.option_hpp" title="Header &lt;boost/histogram/axis/option.hpp&gt;">Compile-time options</a></code>
424                for the axis. This is used to enable/disable under- and overflow
425                bins, to make an axis circular, or to enable dynamic growth of the
426                axis beyond the initial range.
427              </p></dd>
428<dt><span class="term">Allocator (only <code class="computeroutput"><a class="link" href="../boost/histogram/axis/variable.html" title="Class template variable">variable</a></code>
429            and <code class="computeroutput"><a class="link" href="../boost/histogram/axis/category.html" title="Class template category">category</a></code>
430            axes)</span></dt>
431<dd><p>
432                Allocator that is used to request memory dynamically to store values.
433                If you don't know what an allocator is you can safely ignore this
434                argument.
435              </p></dd>
436</dl>
437</div>
438<p>
439          You can use the <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">use_default</span></code> tag type for any of these
440          options, except for the Value and Allocator, to use the library default.
441        </p>
442<div class="section">
443<div class="titlepage"><div><div><h5 class="title">
444<a name="histogram.guide.axis_guide.axis_configuration.transforms"></a><a class="link" href="guide.html#histogram.guide.axis_guide.axis_configuration.transforms" title="Transforms">Transforms</a>
445</h5></div></div></div>
446<p>
447            Transforms are a way to customize a <code class="computeroutput"><a class="link" href="../boost/histogram/axis/regular.html" title="Class template regular">regular</a></code>
448            axis. Transforms allow you to chose the faster stack-allocated regular
449            axis over the generic <code class="computeroutput"><a class="link" href="../boost/histogram/axis/variable.html" title="Class template variable">variable
450            axis</a></code> in some cases. The default is the identity transform
451            which does nothing. A common need is a regular binning in the logarithm
452            of the input value. This can be achieved with a <code class="computeroutput"><a class="link" href="../boost/histogram/axis/transform/log.html" title="Struct log">log</a></code>
453            transform. The follow example shows the builtin transforms.
454          </p>
455<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><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">regular</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
456<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">limits</span><span class="special">&gt;</span>
457
458<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
459  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>
460
461  <span class="comment">// make a regular axis with a log transform over [10, 100), [100, 1000), [1000, 10000)</span>
462  <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">,</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">transform</span><span class="special">::</span><span class="identifier">log</span><span class="special">&gt;</span> <span class="identifier">r_log</span><span class="special">{</span><span class="number">3</span><span class="special">,</span> <span class="number">10.</span><span class="special">,</span> <span class="number">10000.</span><span class="special">};</span>
463  <span class="comment">// log transform:</span>
464  <span class="comment">// - useful when values vary dramatically in magnitude, like brightness of stars</span>
465  <span class="comment">// - edges are not exactly at 10, 100, 1000, because of finite floating point precision</span>
466  <span class="comment">// - values &gt;= 0 but smaller than the starting value of the axis are mapped to -1</span>
467  <span class="comment">// - values &lt; 0 are mapped to `size()`, because the result of std::log(value) is NaN</span>
468  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_log</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">10.1</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>
469  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_log</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">100.1</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
470  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_log</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">1000.1</span><span class="special">)</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span>
471  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_log</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="special">-</span><span class="number">1</span><span class="special">);</span>
472  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_log</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="special">-</span><span class="number">1</span><span class="special">);</span>
473  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_log</span><span class="special">.</span><span class="identifier">index</span><span class="special">(-</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">3</span><span class="special">);</span>
474
475  <span class="comment">// make a regular axis with a sqrt transform over [4, 9), [9, 16), [16, 25)</span>
476  <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">,</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">transform</span><span class="special">::</span><span class="identifier">sqrt</span><span class="special">&gt;</span> <span class="identifier">r_sqrt</span><span class="special">{</span><span class="number">3</span><span class="special">,</span> <span class="number">4.</span><span class="special">,</span> <span class="number">25.</span><span class="special">};</span>
477  <span class="comment">// sqrt transform:</span>
478  <span class="comment">// - bin widths are more mildly increasing compared to log transform</span>
479  <span class="comment">// - axis starting at value == 0 is ok, sqrt(0) == 0 unlike log transform</span>
480  <span class="comment">// - values &lt; 0 are mapped to `size()`, because the result of std::sqrt(value) is NaN</span>
481  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_sqrt</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="special">-</span><span class="number">1</span><span class="special">);</span>
482  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_sqrt</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">4.1</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>
483  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_sqrt</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">9.1</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
484  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_sqrt</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">16.1</span><span class="special">)</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span>
485  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_sqrt</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">25.1</span><span class="special">)</span> <span class="special">==</span> <span class="number">3</span><span class="special">);</span>
486  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_sqrt</span><span class="special">.</span><span class="identifier">index</span><span class="special">(-</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">3</span><span class="special">);</span>
487
488  <span class="comment">// make a regular axis with a power transform x^1/3 over [1, 8), [8, 27), [27, 64)</span>
489  <span class="keyword">using</span> <span class="identifier">pow_trans</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">transform</span><span class="special">::</span><span class="identifier">pow</span><span class="special">;</span>
490  <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">,</span> <span class="identifier">pow_trans</span><span class="special">&gt;</span> <span class="identifier">r_pow</span><span class="special">(</span><span class="identifier">pow_trans</span><span class="special">{</span><span class="number">1.</span> <span class="special">/</span> <span class="number">3.</span><span class="special">},</span> <span class="number">3</span><span class="special">,</span> <span class="number">1.</span><span class="special">,</span> <span class="number">64.</span><span class="special">);</span>
491  <span class="comment">// pow transform:</span>
492  <span class="comment">// - generalization of the sqrt transform</span>
493  <span class="comment">// - starting the axis at value == 0 is ok for power p &gt; 0, 0^p == 0 for p &gt; 0</span>
494  <span class="comment">// - values &lt; 0 are mapped to `size()` if power p is not a positive integer</span>
495  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_pow</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="special">-</span><span class="number">1</span><span class="special">);</span>
496  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_pow</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">1.1</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>
497  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_pow</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">8.1</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
498  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_pow</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">27.1</span><span class="special">)</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span>
499  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_pow</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">64.1</span><span class="special">)</span> <span class="special">==</span> <span class="number">3</span><span class="special">);</span>
500  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_pow</span><span class="special">.</span><span class="identifier">index</span><span class="special">(-</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">3</span><span class="special">);</span>
501<span class="special">}</span>
502</pre>
503<p>
504            Due to the finite precision of floating point calculations, the bin edges
505            of a transformed regular axis may not be exactly at the expected values.
506            If you need exact correspondence, use a <code class="computeroutput"><a class="link" href="../boost/histogram/axis/variable.html" title="Class template variable">variable</a></code>
507            axis.
508          </p>
509<p>
510            Users may write their own transforms and use them with the builtin <code class="computeroutput"><a class="link" href="../boost/histogram/axis/regular.html" title="Class template regular">regular</a></code> axis, by implementing
511            a type that matches the <a class="link" href="concepts.html#histogram.concepts.Transform" title="Transform"><span class="bold"><strong>Transform</strong></span> concept</a>.
512          </p>
513</div>
514<div class="section">
515<div class="titlepage"><div><div><h5 class="title">
516<a name="histogram.guide.axis_guide.axis_configuration.options"></a><a class="link" href="guide.html#histogram.guide.axis_guide.axis_configuration.options" title="Options">Options</a>
517</h5></div></div></div>
518<p>
519            <code class="computeroutput"><a class="link" href="reference.html#header.boost.histogram.axis.option_hpp" title="Header &lt;boost/histogram/axis/option.hpp&gt;">Options</a></code>
520            can be used to configure each axis type. The option flags are implemented
521            as tag types with the suffix <code class="computeroutput"><span class="identifier">_t</span></code>.
522            Each tag type has a corresponding value without the suffix. The values
523            have set semantics: You can compute the union with <code class="computeroutput"><span class="keyword">operator</span><span class="special">|</span></code> and the intersection with <code class="computeroutput"><span class="keyword">operator</span><span class="special">&amp;</span></code>.
524            When you pass a single option flag to an axis as a template parameter,
525            use the tag type. When you need to pass the union of several options
526            to an axis as a template parameter, surround the union of option values
527            with a <code class="computeroutput"><span class="keyword">decltype</span></code>. Both ways
528            of passing options are shown in the following examples.
529          </p>
530<p>
531            <span class="bold"><strong>Under- and overflow bins</strong></span>
532          </p>
533<p>
534            Under- and overflow bins are added automatically for most axis types.
535            If you create an axis with 10 bins, the histogram will actually have
536            12 bins along that axis. The extra bins are very useful, as explained
537            in the <a class="link" href="rationale.html#histogram.rationale.uoflow" title="Under- and overflow bins">rationale</a>. If
538            the input cannot exceed the axis range or if you are really tight on
539            memory, you can disable the extra bins. A demonstration:
540          </p>
541<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
542<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">string</span><span class="special">&gt;</span>
543
544<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
545  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>
546
547  <span class="comment">// create a 1d-histogram over integer values from 1 to 6</span>
548  <span class="keyword">auto</span> <span class="identifier">h1</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="number">1</span><span class="special">,</span> <span class="number">7</span><span class="special">));</span>
549  <span class="comment">// axis has size 6...</span>
550  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">axis</span><span class="special">().</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">6</span><span class="special">);</span>
551  <span class="comment">// ... but histogram has size 8, because of overflow and underflow bins</span>
552  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">8</span><span class="special">);</span>
553
554  <span class="comment">// create a 1d-histogram for throws of a six-sided die without extra bins,</span>
555  <span class="comment">// since the values cannot be smaller than 1 or larger than 6</span>
556  <span class="keyword">auto</span> <span class="identifier">h2</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">use_default</span><span class="special">,</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">option</span><span class="special">::</span><span class="identifier">none_t</span><span class="special">&gt;(</span><span class="number">1</span><span class="special">,</span> <span class="number">7</span><span class="special">));</span>
557  <span class="comment">// now size of axis and histogram is equal</span>
558  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">.</span><span class="identifier">axis</span><span class="special">().</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">6</span><span class="special">);</span>
559  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">.</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">6</span><span class="special">);</span>
560<span class="special">}</span>
561</pre>
562<p>
563            The <code class="computeroutput"><a class="link" href="../boost/histogram/axis/category.html" title="Class template category">category</a></code>
564            axis by default comes only with an overflow bin, which counts all input
565            values that are not part of the initial set.
566          </p>
567<p>
568            <span class="bold"><strong>Circular axes</strong></span>
569          </p>
570<p>
571            Each builtin axis except the <code class="computeroutput"><a class="link" href="../boost/histogram/axis/category.html" title="Class template category">category</a></code>
572            axis can be made circular. This means that the axis is periodic at its
573            ends. This is useful if you want make a histogram over a polar angle.
574            Example:
575          </p>
576<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><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">hpp</span><span class="special">&gt;</span>
577<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">limits</span><span class="special">&gt;</span>
578
579<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
580  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>
581
582  <span class="comment">// make a circular regular axis ... [0, 180), [180, 360), [0, 180) ....</span>
583  <span class="keyword">using</span> <span class="identifier">opts</span> <span class="special">=</span> <span class="keyword">decltype</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">option</span><span class="special">::</span><span class="identifier">overflow</span> <span class="special">|</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">option</span><span class="special">::</span><span class="identifier">circular</span><span class="special">);</span>
584  <span class="keyword">auto</span> <span class="identifier">r</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">,</span> <span class="identifier">use_default</span><span class="special">,</span> <span class="identifier">use_default</span><span class="special">,</span> <span class="identifier">opts</span><span class="special">&gt;{</span><span class="number">2</span><span class="special">,</span> <span class="number">0.</span><span class="special">,</span> <span class="number">360.</span><span class="special">};</span>
585  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(-</span><span class="number">180</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
586  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>
587  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">180</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
588  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">360</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>
589  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">540</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
590  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">720</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>
591  <span class="comment">// special values are mapped to the overflow bin index</span>
592  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;::</span><span class="identifier">infinity</span><span class="special">())</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span>
593  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(-</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;::</span><span class="identifier">infinity</span><span class="special">())</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span>
594  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;::</span><span class="identifier">quiet_NaN</span><span class="special">())</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span>
595
596  <span class="comment">// since the regular axis is the most common circular axis, there exists an alias</span>
597  <span class="keyword">auto</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">circular</span><span class="special">&lt;&gt;{</span><span class="number">2</span><span class="special">,</span> <span class="number">0.</span><span class="special">,</span> <span class="number">360.</span><span class="special">};</span>
598  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span> <span class="special">==</span> <span class="identifier">c</span><span class="special">);</span>
599
600  <span class="comment">// make a circular integer axis</span>
601  <span class="keyword">auto</span> <span class="identifier">i</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">use_default</span><span class="special">,</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">option</span><span class="special">::</span><span class="identifier">circular_t</span><span class="special">&gt;{</span><span class="number">1</span><span class="special">,</span> <span class="number">4</span><span class="special">};</span>
602  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">i</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span>
603  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">i</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>
604  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">i</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">2</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
605  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">i</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">3</span><span class="special">)</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span>
606  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">i</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">4</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>
607  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">i</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">5</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
608<span class="special">}</span>
609</pre>
610<p>
611            A circular axis cannot have an underflow bin, passing both options together
612            generates a compile-time error. Since the highest bin wraps around to
613            the lowest bin, there is no possibility for overflow either. However,
614            an overflow bin is still added by default if the value is a floating
615            point type, to catch NaNs and infinities.
616          </p>
617<p>
618            <span class="bold"><strong>Growing axes</strong></span>
619          </p>
620<p>
621            Each builtin axis has an option to make it grow beyond its initial range
622            when a value outside of that range is passed to it, while the default
623            behaviour is to count this value in the under- or overflow bins (or to
624            discard it). Example:
625          </p>
626<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
627<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
628
629<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
630
631<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
632  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>
633
634  <span class="comment">// make a growing regular axis</span>
635  <span class="comment">// - it grows new bins with its constant bin width until the value is covered</span>
636  <span class="keyword">auto</span> <span class="identifier">h1</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">,</span>
637                                         <span class="identifier">use_default</span><span class="special">,</span>
638                                         <span class="identifier">use_default</span><span class="special">,</span>
639                                         <span class="identifier">axis</span><span class="special">::</span><span class="identifier">option</span><span class="special">::</span><span class="identifier">growth_t</span><span class="special">&gt;{</span><span class="number">2</span><span class="special">,</span> <span class="number">0.</span><span class="special">,</span> <span class="number">1.</span><span class="special">});</span>
640  <span class="comment">// nothing special happens here</span>
641  <span class="identifier">h1</span><span class="special">(</span><span class="number">0.1</span><span class="special">);</span>
642  <span class="identifier">h1</span><span class="special">(</span><span class="number">0.9</span><span class="special">);</span>
643  <span class="comment">// state: [0, 0.5): 1, [0.5, 1.0): 1</span>
644  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">axis</span><span class="special">().</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span>
645  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">axis</span><span class="special">().</span><span class="identifier">bin</span><span class="special">(</span><span class="number">0</span><span class="special">).</span><span class="identifier">lower</span><span class="special">()</span> <span class="special">==</span> <span class="number">0.0</span><span class="special">);</span>
646  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">axis</span><span class="special">().</span><span class="identifier">bin</span><span class="special">(</span><span class="number">1</span><span class="special">).</span><span class="identifier">upper</span><span class="special">()</span> <span class="special">==</span> <span class="number">1.0</span><span class="special">);</span>
647
648  <span class="comment">// value below range: axis grows new bins until value is in range</span>
649  <span class="identifier">h1</span><span class="special">(-</span><span class="number">0.3</span><span class="special">);</span>
650  <span class="comment">// state: [-0.5, 0.0): 1, [0, 0.5): 1, [0.5, 1.0): 1</span>
651  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">axis</span><span class="special">().</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">3</span><span class="special">);</span>
652  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">axis</span><span class="special">().</span><span class="identifier">bin</span><span class="special">(</span><span class="number">0</span><span class="special">).</span><span class="identifier">lower</span><span class="special">()</span> <span class="special">==</span> <span class="special">-</span><span class="number">0.5</span><span class="special">);</span>
653  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">axis</span><span class="special">().</span><span class="identifier">bin</span><span class="special">(</span><span class="number">2</span><span class="special">).</span><span class="identifier">upper</span><span class="special">()</span> <span class="special">==</span> <span class="number">1.0</span><span class="special">);</span>
654
655  <span class="identifier">h1</span><span class="special">(</span><span class="number">1.9</span><span class="special">);</span>
656  <span class="comment">// state: [-0.5, 0.0): 1, [0, 0.5): 1, [0.5, 1.0): 1, [1.0, 1.5): 0 [1.5, 2.0): 1</span>
657  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">axis</span><span class="special">().</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">5</span><span class="special">);</span>
658  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">axis</span><span class="special">().</span><span class="identifier">bin</span><span class="special">(</span><span class="number">0</span><span class="special">).</span><span class="identifier">lower</span><span class="special">()</span> <span class="special">==</span> <span class="special">-</span><span class="number">0.5</span><span class="special">);</span>
659  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">axis</span><span class="special">().</span><span class="identifier">bin</span><span class="special">(</span><span class="number">4</span><span class="special">).</span><span class="identifier">upper</span><span class="special">()</span> <span class="special">==</span> <span class="number">2.0</span><span class="special">);</span>
660
661  <span class="comment">// make a growing category axis (here strings)</span>
662  <span class="comment">// - empty axis is allowed: very useful if categories are not known at the beginning</span>
663  <span class="keyword">auto</span> <span class="identifier">h2</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">category</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span>
664                                          <span class="identifier">use_default</span><span class="special">,</span>
665                                          <span class="identifier">axis</span><span class="special">::</span><span class="identifier">option</span><span class="special">::</span><span class="identifier">growth_t</span><span class="special">&gt;());</span>
666  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">.</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span> <span class="comment">// histogram is empty</span>
667  <span class="identifier">h2</span><span class="special">(</span><span class="string">"foo"</span><span class="special">);</span> <span class="comment">// new bin foo, index 0</span>
668  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">.</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
669  <span class="identifier">h2</span><span class="special">(</span><span class="string">"bar"</span><span class="special">);</span> <span class="comment">// new bin bar, index 1</span>
670  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">.</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span>
671  <span class="identifier">h2</span><span class="special">(</span><span class="string">"foo"</span><span class="special">);</span>
672  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">.</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span>
673  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">[</span><span class="number">0</span><span class="special">]</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span>
674  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">[</span><span class="number">1</span><span class="special">]</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
675<span class="special">}</span>
676</pre>
677<p>
678            This feature can be very convenient, but keep two caveats in mind.
679          </p>
680<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
681<li class="listitem">
682                Growing axes come with a run-time cost, since the histogram has to
683                reallocate memory for all cells when an axis changes its size. Whether
684                this performance hit is noticeable depends on your application. This
685                is a minor issue, the next is more severe.
686              </li>
687<li class="listitem">
688                If you have unexpected outliers in your data which are far away from
689                the normal range, the axis could grow to a huge size and the corresponding
690                huge memory request could bring the computer to its knees. This is
691                one of the reason why growing axes are not the default.
692              </li>
693</ul></div>
694<p>
695            A growing axis can have under- and overflow bins, but these only count
696            the special floating point values: positive and negative infinity, and
697            NaN.
698          </p>
699</div>
700</div>
701</div>
702<div class="section">
703<div class="titlepage"><div><div><h3 class="title">
704<a name="histogram.guide.filling_histograms_and_accessing"></a><a class="link" href="guide.html#histogram.guide.filling_histograms_and_accessing" title="Filling histograms and accessing cells">Filling
705      histograms and accessing cells</a>
706</h3></div></div></div>
707<p>
708        A histogram has been created and now you want to insert values. This is done
709        with the flexible <code class="computeroutput"><a class="link" href="../boost/histogram/histogram.html#idm45503931925808-bb">call
710        operator</a></code> or the <code class="computeroutput"><a class="link" href="../boost/histogram/histogram.html#idm45503931911152-bb">fill
711        method</a></code>, which you typically call in a loop. The <code class="computeroutput"><a class="link" href="../boost/histogram/histogram.html#idm45503931925808-bb">call operator</a></code>
712        accepts <code class="computeroutput"><span class="identifier">N</span></code> arguments or a
713        <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span></code> with <code class="computeroutput"><span class="identifier">N</span></code>
714        elements, where <code class="computeroutput"><span class="identifier">N</span></code> is equal
715        to the number of axes of the histogram. It finds the corresponding bin for
716        the input and increments the bin counter by one. The <code class="computeroutput"><a class="link" href="../boost/histogram/histogram.html#idm45503931911152-bb">fill
717        method</a></code> accepts a single iterable over other iterables (which
718        must have have elements contiguous in memory) or values, see the method documentation
719        for details.
720      </p>
721<p>
722        After the histogram has been filled, use the <code class="computeroutput"><a class="link" href="../boost/histogram/histogram.html#idm45503931864512-bb">at
723        method</a></code> (in analogy to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">::</span><span class="identifier">at</span></code>) to
724        access the cell values. It accepts integer indices, one for each axis of
725        the histogram.
726      </p>
727<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
728<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
729<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">functional</span><span class="special">&gt;</span>
730<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">numeric</span><span class="special">&gt;</span>
731<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">utility</span><span class="special">&gt;</span>
732<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">vector</span><span class="special">&gt;</span>
733
734<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
735  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>
736
737  <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;&gt;(</span><span class="number">0</span><span class="special">,</span> <span class="number">3</span><span class="special">),</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">2</span><span class="special">,</span> <span class="number">0.0</span><span class="special">,</span> <span class="number">1.0</span><span class="special">));</span>
738
739  <span class="comment">// fill histogram, number of arguments must be equal to number of axes,</span>
740  <span class="comment">// types must be convertible to axis value type (here integer and double)</span>
741  <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">0.2</span><span class="special">);</span> <span class="comment">// increase a cell value by one</span>
742  <span class="identifier">h</span><span class="special">(</span><span class="number">2</span><span class="special">,</span> <span class="number">0.5</span><span class="special">);</span> <span class="comment">// increase another cell value by one</span>
743
744  <span class="comment">// fills from a tuple are also supported; passing a tuple of wrong size</span>
745  <span class="comment">// causes an error at compile-time or an assertion at runtime in debug mode</span>
746  <span class="keyword">auto</span> <span class="identifier">xy</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_tuple</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">0.3</span><span class="special">);</span>
747  <span class="identifier">h</span><span class="special">(</span><span class="identifier">xy</span><span class="special">);</span>
748
749  <span class="comment">// chunk-wise filling is also supported and more efficient, make some data...</span>
750  <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span> <span class="identifier">xy2</span><span class="special">[</span><span class="number">2</span><span class="special">]</span> <span class="special">=</span> <span class="special">{{</span><span class="number">0</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="number">5</span><span class="special">},</span> <span class="special">{</span><span class="number">0.8</span><span class="special">,</span> <span class="number">0.4</span><span class="special">,</span> <span class="number">0.7</span><span class="special">}};</span>
751
752  <span class="comment">// ... and call fill method</span>
753  <span class="identifier">h</span><span class="special">.</span><span class="identifier">fill</span><span class="special">(</span><span class="identifier">xy2</span><span class="special">);</span>
754
755  <span class="comment">// once histogram is filled, access individual cells using operator[] or at(...)</span>
756  <span class="comment">// - operator[] can only accept a single argument in the current version of C++,</span>
757  <span class="comment">//   it is convenient when you have a 1D histogram</span>
758  <span class="comment">// - at(...) can accept several values, so use this by default</span>
759  <span class="comment">// - underflow bins are at index -1, overflow bins at index `size()`</span>
760  <span class="comment">// - passing an invalid index triggers a std::out_of_range exception</span>
761  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
762  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
763  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
764  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>
765  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">2</span><span class="special">,</span> <span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
766  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">2</span><span class="special">,</span> <span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
767  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(-</span><span class="number">1</span><span class="special">,</span> <span class="special">-</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span> <span class="comment">// underflow for axis 0 and 1</span>
768  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(-</span><span class="number">1</span><span class="special">,</span> <span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>  <span class="comment">// underflow for axis 0, normal bin for axis 1</span>
769  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(-</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>  <span class="comment">// underflow for axis 0, overflow for axis 1</span>
770  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">3</span><span class="special">,</span> <span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>   <span class="comment">// overflow for axis 0, normal bin for axis 1</span>
771
772  <span class="comment">// iteration over values works, but see next example for a better way</span>
773  <span class="comment">// - iteration using begin() and end() includes under- and overflow bins</span>
774  <span class="comment">// - iteration order is an implementation detail and should not be relied upon</span>
775  <span class="keyword">const</span> <span class="keyword">double</span> <span class="identifier">sum</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">accumulate</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">h</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="number">0.0</span><span class="special">);</span>
776  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">sum</span> <span class="special">==</span> <span class="number">6</span><span class="special">);</span>
777<span class="special">}</span>
778</pre>
779<p>
780        For a histogram <code class="computeroutput"><span class="identifier">hist</span></code>, the
781        calls <code class="computeroutput"><span class="identifier">hist</span><span class="special">(</span><span class="identifier">weight</span><span class="special">(</span><span class="identifier">w</span><span class="special">),</span> <span class="special">...)</span></code>
782        and <code class="computeroutput"><span class="identifier">hist</span><span class="special">(...,</span>
783        <span class="identifier">weight</span><span class="special">(</span><span class="identifier">w</span><span class="special">))</span></code> increment
784        the bin counter by the value <code class="computeroutput"><span class="identifier">w</span></code>
785        instead, where <code class="computeroutput"><span class="identifier">w</span></code> may be an
786        integer or floating point number. The helper function <code class="computeroutput"><a class="link" href="../boost/histogram/weight.html" title="Function template weight">weight()</a></code>
787        marks this argument as a weight, so that it can be distinguished from the
788        other inputs. It can be the first or last argument. You can freely mix calls
789        with and without a weight. Calls without <code class="computeroutput"><span class="identifier">weight</span></code>
790        act like the weight is <code class="computeroutput"><span class="number">1</span></code>. Why
791        weighted increments are sometimes useful is explained <a class="link" href="rationale.html#histogram.rationale.weights" title="Support of weighted fills">in
792        the rationale</a>.
793      </p>
794<div class="note"><table border="0" summary="Note">
795<tr>
796<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
797<th align="left">Note</th>
798</tr>
799<tr><td align="left" valign="top"><p>
800          The default storage loses its no-overflow-guarantee when you pass floating
801          point weights, but maintains it for integer weights.
802        </p></td></tr>
803</table></div>
804<p>
805        When the weights come from a stochastic process, it is useful to keep track
806        of the variance of the sum of weights per cell. A specialized histogram can
807        be generated with the <code class="computeroutput"><a class="link" href="../boost/histogram/make_wei_idm45503931624016.html" title="Function template make_weighted_histogram">make_weighted_histogram</a></code>
808        factory function which does that.
809      </p>
810<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
811<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
812
813<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
814  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>
815
816  <span class="comment">// Create a histogram with weight counters that keep track of a variance estimate.</span>
817  <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_weighted_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">3</span><span class="special">,</span> <span class="number">0.0</span><span class="special">,</span> <span class="number">1.0</span><span class="special">));</span>
818
819  <span class="identifier">h</span><span class="special">(</span><span class="number">0.0</span><span class="special">,</span> <span class="identifier">weight</span><span class="special">(</span><span class="number">1</span><span class="special">));</span> <span class="comment">// weight 1 goes to first bin</span>
820  <span class="identifier">h</span><span class="special">(</span><span class="number">0.1</span><span class="special">,</span> <span class="identifier">weight</span><span class="special">(</span><span class="number">2</span><span class="special">));</span> <span class="comment">// weight 2 goes to first bin</span>
821  <span class="identifier">h</span><span class="special">(</span><span class="number">0.4</span><span class="special">,</span> <span class="identifier">weight</span><span class="special">(</span><span class="number">3</span><span class="special">));</span> <span class="comment">// weight 3 goes to second bin</span>
822  <span class="identifier">h</span><span class="special">(</span><span class="number">0.5</span><span class="special">,</span> <span class="identifier">weight</span><span class="special">(</span><span class="number">4</span><span class="special">));</span> <span class="comment">// weight 4 goes to second bin</span>
823
824  <span class="comment">// chunk-wise filling is also supported</span>
825  <span class="keyword">auto</span> <span class="identifier">x</span> <span class="special">=</span> <span class="special">{</span><span class="number">0.2</span><span class="special">,</span> <span class="number">0.6</span><span class="special">};</span>
826  <span class="keyword">auto</span> <span class="identifier">w</span> <span class="special">=</span> <span class="special">{</span><span class="number">5</span><span class="special">,</span> <span class="number">6</span><span class="special">};</span>
827  <span class="identifier">h</span><span class="special">.</span><span class="identifier">fill</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span> <span class="identifier">weight</span><span class="special">(</span><span class="identifier">w</span><span class="special">));</span>
828
829  <span class="comment">// Weight counters have methods to access the value (sum of weights) and the variance</span>
830  <span class="comment">// (sum of weights squared, why this gives the variance is explained in the rationale)</span>
831  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">[</span><span class="number">0</span><span class="special">].</span><span class="identifier">value</span><span class="special">()</span> <span class="special">==</span> <span class="number">1</span> <span class="special">+</span> <span class="number">2</span> <span class="special">+</span> <span class="number">5</span><span class="special">);</span>
832  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">[</span><span class="number">0</span><span class="special">].</span><span class="identifier">variance</span><span class="special">()</span> <span class="special">==</span> <span class="number">1</span> <span class="special">*</span> <span class="number">1</span> <span class="special">+</span> <span class="number">2</span> <span class="special">*</span> <span class="number">2</span> <span class="special">+</span> <span class="number">5</span> <span class="special">*</span> <span class="number">5</span><span class="special">);</span>
833  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">[</span><span class="number">1</span><span class="special">].</span><span class="identifier">value</span><span class="special">()</span> <span class="special">==</span> <span class="number">3</span> <span class="special">+</span> <span class="number">4</span> <span class="special">+</span> <span class="number">6</span><span class="special">);</span>
834  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">[</span><span class="number">1</span><span class="special">].</span><span class="identifier">variance</span><span class="special">()</span> <span class="special">==</span> <span class="number">3</span> <span class="special">*</span> <span class="number">3</span> <span class="special">+</span> <span class="number">4</span> <span class="special">*</span> <span class="number">4</span> <span class="special">+</span> <span class="number">6</span> <span class="special">*</span> <span class="number">6</span><span class="special">);</span>
835<span class="special">}</span>
836</pre>
837<p>
838        To iterate over all cells, the <code class="computeroutput"><a class="link" href="../boost/histogram/indexed.html" title="Function template indexed">indexed</a></code>
839        range generator is very convenient and also efficient. For almost all configurations,
840        the range generator iterates <span class="emphasis"><em>faster</em></span> than a naive for-loop.
841        Under- and overflow are skipped by default.
842      </p>
843<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">format</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
844<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
845<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
846<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
847<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">numeric</span><span class="special">&gt;</span> <span class="comment">// for std::accumulate</span>
848<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">sstream</span><span class="special">&gt;</span>
849
850<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>
851
852<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
853  <span class="comment">// make histogram with 2 x 2 = 4 bins (not counting under-/overflow bins)</span>
854  <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">2</span><span class="special">,</span> <span class="special">-</span><span class="number">1.0</span><span class="special">,</span> <span class="number">1.0</span><span class="special">),</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">2</span><span class="special">,</span> <span class="number">2.0</span><span class="special">,</span> <span class="number">4.0</span><span class="special">));</span>
855
856  <span class="identifier">h</span><span class="special">(</span><span class="identifier">weight</span><span class="special">(</span><span class="number">1</span><span class="special">),</span> <span class="special">-</span><span class="number">0.5</span><span class="special">,</span> <span class="number">2.5</span><span class="special">);</span> <span class="comment">// bin index 0, 0</span>
857  <span class="identifier">h</span><span class="special">(</span><span class="identifier">weight</span><span class="special">(</span><span class="number">2</span><span class="special">),</span> <span class="special">-</span><span class="number">0.5</span><span class="special">,</span> <span class="number">3.5</span><span class="special">);</span> <span class="comment">// bin index 0, 1</span>
858  <span class="identifier">h</span><span class="special">(</span><span class="identifier">weight</span><span class="special">(</span><span class="number">3</span><span class="special">),</span> <span class="number">0.5</span><span class="special">,</span> <span class="number">2.5</span><span class="special">);</span>  <span class="comment">// bin index 1, 0</span>
859  <span class="identifier">h</span><span class="special">(</span><span class="identifier">weight</span><span class="special">(</span><span class="number">4</span><span class="special">),</span> <span class="number">0.5</span><span class="special">,</span> <span class="number">3.5</span><span class="special">);</span>  <span class="comment">// bin index 1, 1</span>
860
861  <span class="comment">// use the `indexed` range adaptor to iterate over all bins;</span>
862  <span class="comment">// it is not only more convenient but also faster than a hand-crafted loop!</span>
863  <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os</span><span class="special">;</span>
864  <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&amp;&amp;</span> <span class="identifier">x</span> <span class="special">:</span> <span class="identifier">indexed</span><span class="special">(</span><span class="identifier">h</span><span class="special">))</span> <span class="special">{</span>
865    <span class="comment">// x is a special accessor object</span>
866    <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">i</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">0</span><span class="special">);</span> <span class="comment">// current index along first axis</span>
867    <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">j</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">1</span><span class="special">);</span> <span class="comment">// current index along second axis</span>
868    <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">b0</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">bin</span><span class="special">(</span><span class="number">0</span><span class="special">);</span>  <span class="comment">// current bin interval along first axis</span>
869    <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">b1</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">bin</span><span class="special">(</span><span class="number">1</span><span class="special">);</span>  <span class="comment">// current bin interval along second axis</span>
870    <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">v</span> <span class="special">=</span> <span class="special">*</span><span class="identifier">x</span><span class="special">;</span>         <span class="comment">// "dereference" to get the bin value</span>
871    <span class="identifier">os</span> <span class="special">&lt;&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">format</span><span class="special">(</span><span class="string">"%i %i [%2i, %i) [%2i, %i): %i\n"</span><span class="special">)</span> <span class="special">%</span> <span class="identifier">i</span> <span class="special">%</span> <span class="identifier">j</span> <span class="special">%</span> <span class="identifier">b0</span><span class="special">.</span><span class="identifier">lower</span><span class="special">()</span> <span class="special">%</span>
872              <span class="identifier">b0</span><span class="special">.</span><span class="identifier">upper</span><span class="special">()</span> <span class="special">%</span> <span class="identifier">b1</span><span class="special">.</span><span class="identifier">lower</span><span class="special">()</span> <span class="special">%</span> <span class="identifier">b1</span><span class="special">.</span><span class="identifier">upper</span><span class="special">()</span> <span class="special">%</span> <span class="identifier">v</span><span class="special">;</span>
873  <span class="special">}</span>
874
875  <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">flush</span><span class="special">;</span>
876
877  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span> <span class="string">"0 0 [-1, 0) [ 2, 3): 1\n"</span>
878                     <span class="string">"1 0 [ 0, 1) [ 2, 3): 3\n"</span>
879                     <span class="string">"0 1 [-1, 0) [ 3, 4): 2\n"</span>
880                     <span class="string">"1 1 [ 0, 1) [ 3, 4): 4\n"</span><span class="special">);</span>
881
882  <span class="comment">// `indexed` skips underflow and overflow bins by default, but can be called</span>
883  <span class="comment">// with the second argument `coverage::all` to walk over all bins</span>
884  <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os2</span><span class="special">;</span>
885  <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&amp;&amp;</span> <span class="identifier">x</span> <span class="special">:</span> <span class="identifier">indexed</span><span class="special">(</span><span class="identifier">h</span><span class="special">,</span> <span class="identifier">coverage</span><span class="special">::</span><span class="identifier">all</span><span class="special">))</span> <span class="special">{</span>
886    <span class="identifier">os2</span> <span class="special">&lt;&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">format</span><span class="special">(</span><span class="string">"%2i %2i: %i\n"</span><span class="special">)</span> <span class="special">%</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">%</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">%</span> <span class="special">*</span><span class="identifier">x</span><span class="special">;</span>
887  <span class="special">}</span>
888
889  <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">os2</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">flush</span><span class="special">;</span>
890
891  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">os2</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span> <span class="string">"-1 -1: 0\n"</span>
892                      <span class="string">" 0 -1: 0\n"</span>
893                      <span class="string">" 1 -1: 0\n"</span>
894                      <span class="string">" 2 -1: 0\n"</span>
895
896                      <span class="string">"-1  0: 0\n"</span>
897                      <span class="string">" 0  0: 1\n"</span>
898                      <span class="string">" 1  0: 3\n"</span>
899                      <span class="string">" 2  0: 0\n"</span>
900
901                      <span class="string">"-1  1: 0\n"</span>
902                      <span class="string">" 0  1: 2\n"</span>
903                      <span class="string">" 1  1: 4\n"</span>
904                      <span class="string">" 2  1: 0\n"</span>
905
906                      <span class="string">"-1  2: 0\n"</span>
907                      <span class="string">" 0  2: 0\n"</span>
908                      <span class="string">" 1  2: 0\n"</span>
909                      <span class="string">" 2  2: 0\n"</span><span class="special">);</span>
910<span class="special">}</span>
911</pre>
912</div>
913<div class="section">
914<div class="titlepage"><div><div><h3 class="title">
915<a name="histogram.guide.using_profiles"></a><a class="link" href="guide.html#histogram.guide.using_profiles" title="Using profiles">Using profiles</a>
916</h3></div></div></div>
917<p>
918        Histograms from this library can do more than counting, they can hold arbitrary
919        accumulators which accept samples. We call a histogram with accumulators
920        that compute the mean of samples in each cell a <span class="emphasis"><em>profile</em></span>.
921        Profiles can be generated with the factory function <code class="computeroutput"><a class="link" href="../boost/histogram/make_pro_idm45503931608944.html" title="Function template make_profile">make_profile</a></code>.
922      </p>
923<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">format</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
924<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
925<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
926<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
927<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">sstream</span><span class="special">&gt;</span>
928<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">tuple</span><span class="special">&gt;</span>
929
930<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
931  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>
932
933  <span class="comment">// make a profile, it computes the mean of the samples in each histogram cell</span>
934  <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_profile</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;&gt;(</span><span class="number">0</span><span class="special">,</span> <span class="number">3</span><span class="special">));</span>
935
936  <span class="comment">// mean is computed from the values marked with the sample() helper function</span>
937  <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">1</span><span class="special">));</span> <span class="comment">// sample goes to cell 0</span>
938  <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">2</span><span class="special">));</span> <span class="comment">// sample goes to cell 0</span>
939  <span class="identifier">h</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">3</span><span class="special">));</span> <span class="comment">// sample goes to cell 1</span>
940  <span class="identifier">h</span><span class="special">(</span><span class="identifier">sample</span><span class="special">(</span><span class="number">4</span><span class="special">),</span> <span class="number">1</span><span class="special">);</span> <span class="comment">// sample goes to cell 1; sample can be first or last argument</span>
941
942  <span class="comment">// fills from tuples are also supported, 5 and 6 go to cell 2</span>
943  <span class="keyword">auto</span> <span class="identifier">a</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_tuple</span><span class="special">(</span><span class="number">2</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">5</span><span class="special">));</span>
944  <span class="keyword">auto</span> <span class="identifier">b</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_tuple</span><span class="special">(</span><span class="identifier">sample</span><span class="special">(</span><span class="number">6</span><span class="special">),</span> <span class="number">2</span><span class="special">);</span>
945  <span class="identifier">h</span><span class="special">(</span><span class="identifier">a</span><span class="special">);</span>
946  <span class="identifier">h</span><span class="special">(</span><span class="identifier">b</span><span class="special">);</span>
947
948  <span class="comment">// builtin accumulators have methods to access their state</span>
949  <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os</span><span class="special">;</span>
950  <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&amp;&amp;</span> <span class="identifier">x</span> <span class="special">:</span> <span class="identifier">indexed</span><span class="special">(</span><span class="identifier">h</span><span class="special">))</span> <span class="special">{</span>
951    <span class="comment">// use `.` to access methods of accessor, like `index()`</span>
952    <span class="comment">// use `-&gt;` to access methods of accumulator</span>
953    <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">i</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">index</span><span class="special">();</span>
954    <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">n</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">-&gt;</span><span class="identifier">count</span><span class="special">();</span>     <span class="comment">// how many samples are in this bin</span>
955    <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">vl</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">-&gt;</span><span class="identifier">value</span><span class="special">();</span>    <span class="comment">// mean value</span>
956    <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">vr</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">-&gt;</span><span class="identifier">variance</span><span class="special">();</span> <span class="comment">// estimated variance of the mean value</span>
957    <span class="identifier">os</span> <span class="special">&lt;&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">format</span><span class="special">(</span><span class="string">"index %i count %i value %.1f variance %.1f\n"</span><span class="special">)</span> <span class="special">%</span> <span class="identifier">i</span> <span class="special">%</span> <span class="identifier">n</span> <span class="special">%</span> <span class="identifier">vl</span> <span class="special">%</span> <span class="identifier">vr</span><span class="special">;</span>
958  <span class="special">}</span>
959
960  <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">flush</span><span class="special">;</span>
961
962  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span> <span class="string">"index 0 count 2 value 1.5 variance 0.5\n"</span>
963                     <span class="string">"index 1 count 2 value 3.5 variance 0.5\n"</span>
964                     <span class="string">"index 2 count 2 value 5.5 variance 0.5\n"</span><span class="special">);</span>
965<span class="special">}</span>
966</pre>
967<p>
968        Just like <code class="computeroutput"><a class="link" href="../boost/histogram/weight.html" title="Function template weight">weight()</a></code>,
969        <code class="computeroutput"><a class="link" href="../boost/histogram/sample.html" title="Function template sample">sample()</a></code> is a
970        marker function. It must be the first or last argument.
971      </p>
972<p>
973        Weights and samples may be combined, if the accumulators can handle weights.
974        When both <code class="computeroutput"><a class="link" href="../boost/histogram/weight.html" title="Function template weight">weight()</a></code>
975        and <code class="computeroutput"><a class="link" href="../boost/histogram/sample.html" title="Function template sample">sample()</a></code>
976        appear in the <code class="computeroutput"><a class="link" href="../boost/histogram/histogram.html#idm45503931925808-bb">call
977        operator</a></code> or the <code class="computeroutput"><a class="link" href="../boost/histogram/histogram.html#idm45503931911152-bb">fill
978        method</a></code>, they can be in any order with respect to other, but
979        they must be the first or last arguments. To make a profile which can compute
980        weighted means with proper uncertainty estimates, use the <code class="computeroutput"><a class="link" href="../boost/histogram/make_wei_idm45503931596384.html" title="Function template make_weighted_profile">make_weighted_profile</a></code>
981        factory function.
982      </p>
983<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">format</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
984<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
985<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
986<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
987<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">sstream</span><span class="special">&gt;</span>
988
989<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
990  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>
991  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">literals</span><span class="special">;</span> <span class="comment">// _c suffix creates compile-time numbers</span>
992
993  <span class="comment">// make 2D weighted profile</span>
994  <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_weighted_profile</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;&gt;(</span><span class="number">0</span><span class="special">,</span> <span class="number">2</span><span class="special">),</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;&gt;(</span><span class="number">0</span><span class="special">,</span> <span class="number">2</span><span class="special">));</span>
995
996  <span class="comment">// The mean is computed from the values marked with the sample() helper function.</span>
997  <span class="comment">// Weights can be passed as well. The `sample` and `weight` arguments can appear in any</span>
998  <span class="comment">// order, but they must be the first or last arguments.</span>
999  <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">1</span><span class="special">));</span>            <span class="comment">// sample goes to cell (0, 0); weight is 1</span>
1000  <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">2</span><span class="special">),</span> <span class="identifier">weight</span><span class="special">(</span><span class="number">3</span><span class="special">));</span> <span class="comment">// sample goes to cell (0, 0); weight is 3</span>
1001  <span class="identifier">h</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">3</span><span class="special">));</span>            <span class="comment">// sample goes to cell (1, 0); weight is 1</span>
1002  <span class="identifier">h</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">4</span><span class="special">));</span>            <span class="comment">// sample goes to cell (1, 0); weight is 1</span>
1003  <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">5</span><span class="special">));</span>            <span class="comment">// sample goes to cell (1, 0); weight is 1</span>
1004  <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">6</span><span class="special">));</span>            <span class="comment">// sample goes to cell (1, 0); weight is 1</span>
1005  <span class="identifier">h</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="identifier">weight</span><span class="special">(</span><span class="number">4</span><span class="special">),</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">7</span><span class="special">));</span> <span class="comment">// sample goes to cell (1, 1); weight is 4</span>
1006  <span class="identifier">h</span><span class="special">(</span><span class="identifier">weight</span><span class="special">(</span><span class="number">5</span><span class="special">),</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">8</span><span class="special">),</span> <span class="number">1</span><span class="special">,</span> <span class="number">1</span><span class="special">);</span> <span class="comment">// sample goes to cell (1, 1); weight is 5</span>
1007
1008  <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os</span><span class="special">;</span>
1009  <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&amp;&amp;</span> <span class="identifier">x</span> <span class="special">:</span> <span class="identifier">indexed</span><span class="special">(</span><span class="identifier">h</span><span class="special">))</span> <span class="special">{</span>
1010    <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">i</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">0</span><span class="identifier">_c</span><span class="special">);</span>
1011    <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">j</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">1</span><span class="identifier">_c</span><span class="special">);</span>
1012    <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">m</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">-&gt;</span><span class="identifier">value</span><span class="special">();</span>    <span class="comment">// weighted mean</span>
1013    <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">v</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">-&gt;</span><span class="identifier">variance</span><span class="special">();</span> <span class="comment">// estimated variance of weighted mean</span>
1014    <span class="identifier">os</span> <span class="special">&lt;&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">format</span><span class="special">(</span><span class="string">"index %i,%i mean %.1f variance %.1f\n"</span><span class="special">)</span> <span class="special">%</span> <span class="identifier">i</span> <span class="special">%</span> <span class="identifier">j</span> <span class="special">%</span> <span class="identifier">m</span> <span class="special">%</span> <span class="identifier">v</span><span class="special">;</span>
1015  <span class="special">}</span>
1016
1017  <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">flush</span><span class="special">;</span>
1018
1019  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span> <span class="string">"index 0,0 mean 1.8 variance 0.5\n"</span>
1020                     <span class="string">"index 1,0 mean 3.5 variance 0.5\n"</span>
1021                     <span class="string">"index 0,1 mean 5.5 variance 0.5\n"</span>
1022                     <span class="string">"index 1,1 mean 7.6 variance 0.5\n"</span><span class="special">);</span>
1023<span class="special">}</span>
1024</pre>
1025</div>
1026<div class="section">
1027<div class="titlepage"><div><div><h3 class="title">
1028<a name="histogram.guide.using_operators"></a><a class="link" href="guide.html#histogram.guide.using_operators" title="Using operators">Using operators</a>
1029</h3></div></div></div>
1030<p>
1031        The following operators are supported for pairs of histograms <code class="computeroutput"><span class="special">+,</span> <span class="special">-,</span> <span class="special">*,</span>
1032        <span class="special">/,</span> <span class="special">==,</span> <span class="special">!=</span></code>. Histograms can also be multiplied and
1033        divided by a scalar. Only a subset of the arithmetic operators is available
1034        when the underlying accumulator only supports that subset.
1035      </p>
1036<p>
1037        The arithmetic operators can only be used when the histograms have the same
1038        axis configuration. This checked at run-time. An exception is thrown if the
1039        configurations do not match. Two histograms have the same axis configuration,
1040        if all axes compare equal, which includes a comparison of their metadata.
1041        Two histograms compare equal, when their axis configurations and all their
1042        cell values compare equal.
1043      </p>
1044<div class="note"><table border="0" summary="Note">
1045<tr>
1046<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
1047<th align="left">Note</th>
1048</tr>
1049<tr><td align="left" valign="top"><p>
1050          If the metadata type has <code class="computeroutput"><span class="keyword">operator</span><span class="special">==</span></code> defined, it is used in the axis configuration
1051          comparison. Metadata types without <code class="computeroutput"><span class="keyword">operator</span><span class="special">==</span></code> are considered equal, if they are the
1052          same type.
1053        </p></td></tr>
1054</table></div>
1055<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
1056<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
1057<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">vector</span><span class="special">&gt;</span>
1058
1059<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
1060  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>
1061
1062  <span class="comment">// make two histograms</span>
1063  <span class="keyword">auto</span> <span class="identifier">h1</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">2</span><span class="special">,</span> <span class="special">-</span><span class="number">1.0</span><span class="special">,</span> <span class="number">1.0</span><span class="special">));</span>
1064  <span class="keyword">auto</span> <span class="identifier">h2</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">2</span><span class="special">,</span> <span class="special">-</span><span class="number">1.0</span><span class="special">,</span> <span class="number">1.0</span><span class="special">));</span>
1065
1066  <span class="identifier">h1</span><span class="special">(-</span><span class="number">0.5</span><span class="special">);</span> <span class="comment">// counts are: 1 0</span>
1067  <span class="identifier">h2</span><span class="special">(</span><span class="number">0.5</span><span class="special">);</span>  <span class="comment">// counts are: 0 1</span>
1068
1069  <span class="comment">// add them</span>
1070  <span class="keyword">auto</span> <span class="identifier">h3</span> <span class="special">=</span> <span class="identifier">h1</span><span class="special">;</span>
1071  <span class="identifier">h3</span> <span class="special">+=</span> <span class="identifier">h2</span><span class="special">;</span> <span class="comment">// counts are: 1 1</span>
1072
1073  <span class="comment">// adding multiple histograms at once is likely to be optimized by the compiler so that</span>
1074  <span class="comment">// superfluous temporaries avoided, but no guarantees are given; use this equivalent</span>
1075  <span class="comment">// code when you want to make sure: h4 = h1; h4 += h2; h4 += h3;</span>
1076  <span class="keyword">auto</span> <span class="identifier">h4</span> <span class="special">=</span> <span class="identifier">h1</span> <span class="special">+</span> <span class="identifier">h2</span> <span class="special">+</span> <span class="identifier">h3</span><span class="special">;</span> <span class="comment">// counts are: 2 2</span>
1077
1078  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h4</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">2</span> <span class="special">&amp;&amp;</span> <span class="identifier">h4</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span>
1079
1080  <span class="comment">// multiply by number, h4 *= 2 also works</span>
1081  <span class="keyword">auto</span> <span class="identifier">h5</span> <span class="special">=</span> <span class="identifier">h4</span> <span class="special">*</span> <span class="number">2</span><span class="special">;</span> <span class="comment">// counts are: 4 4</span>
1082
1083  <span class="comment">// divide by number; s4 /= 4 also works</span>
1084  <span class="keyword">auto</span> <span class="identifier">h6</span> <span class="special">=</span> <span class="identifier">h5</span> <span class="special">/</span> <span class="number">4</span><span class="special">;</span> <span class="comment">// counts are: 1 1</span>
1085
1086  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h6</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span> <span class="special">&amp;&amp;</span> <span class="identifier">h6</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
1087  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h6</span> <span class="special">!=</span> <span class="identifier">h5</span> <span class="special">&amp;&amp;</span> <span class="identifier">h5</span> <span class="special">==</span> <span class="number">4</span> <span class="special">*</span> <span class="identifier">h6</span><span class="special">);</span>
1088
1089  <span class="comment">// note the special effect of multiplication on weight_storage</span>
1090  <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram_with</span><span class="special">(</span><span class="identifier">weight_storage</span><span class="special">(),</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">2</span><span class="special">,</span> <span class="special">-</span><span class="number">1.0</span><span class="special">,</span> <span class="number">1.0</span><span class="special">));</span>
1091  <span class="identifier">h</span><span class="special">(-</span><span class="number">0.5</span><span class="special">);</span>
1092
1093  <span class="comment">// counts are: 1 0</span>
1094  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">).</span><span class="identifier">value</span><span class="special">()</span> <span class="special">==</span> <span class="number">1</span> <span class="special">&amp;&amp;</span> <span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">1</span><span class="special">).</span><span class="identifier">value</span><span class="special">()</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>
1095
1096  <span class="keyword">auto</span> <span class="identifier">h_sum</span> <span class="special">=</span> <span class="identifier">h</span> <span class="special">+</span> <span class="identifier">h</span><span class="special">;</span>
1097  <span class="keyword">auto</span> <span class="identifier">h_mul</span> <span class="special">=</span> <span class="number">2</span> <span class="special">*</span> <span class="identifier">h</span><span class="special">;</span>
1098
1099  <span class="comment">// values are the same as expected...</span>
1100  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h_sum</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">).</span><span class="identifier">value</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">h_mul</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">).</span><span class="identifier">value</span><span class="special">());</span>
1101  <span class="comment">// ... but variances differ</span>
1102  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h_sum</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">).</span><span class="identifier">variance</span><span class="special">()</span> <span class="special">==</span> <span class="number">2</span> <span class="special">&amp;&amp;</span> <span class="identifier">h_mul</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">).</span><span class="identifier">variance</span><span class="special">()</span> <span class="special">==</span> <span class="number">4</span><span class="special">);</span>
1103
1104  <span class="comment">// equality operator checks variances, so histograms are not equal</span>
1105  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h_sum</span> <span class="special">!=</span> <span class="identifier">h_mul</span><span class="special">);</span>
1106<span class="special">}</span>
1107</pre>
1108<div class="note"><table border="0" summary="Note">
1109<tr>
1110<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
1111<th align="left">Note</th>
1112</tr>
1113<tr><td align="left" valign="top"><p>
1114          A histogram with default storage converts its cell values to double when
1115          they are to be multiplied with or divided by a real number, or when a real
1116          number is added or subtracted. At this point the no-overflow-guarantee
1117          is lost.
1118        </p></td></tr>
1119</table></div>
1120<div class="note"><table border="0" summary="Note">
1121<tr>
1122<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
1123<th align="left">Note</th>
1124</tr>
1125<tr><td align="left" valign="top"><p>
1126          When the storage tracks weight variances, such as <code class="computeroutput"><a class="link" href="reference.html#boost.histogram.weight_storage">boost::histogram::weight_storage</a></code>,
1127          adding two copies of a histogram produces a different result than scaling
1128          the histogram by a factor of two, as shown in the last example. The is
1129          a consequence of the mathematical properties of variances. They can be
1130          added like normal numbers, but scaling by <code class="computeroutput"><span class="identifier">s</span></code>
1131          means that variances are scaled by <code class="computeroutput"><span class="identifier">s</span><span class="special">^</span><span class="number">2</span></code>.
1132        </p></td></tr>
1133</table></div>
1134</div>
1135<div class="section">
1136<div class="titlepage"><div><div><h3 class="title">
1137<a name="histogram.guide.using_algorithms"></a><a class="link" href="guide.html#histogram.guide.using_algorithms" title="Using algorithms">Using algorithms</a>
1138</h3></div></div></div>
1139<div class="toc"><dl class="toc">
1140<dt><span class="section"><a href="guide.html#histogram.guide.using_algorithms.algorithms_from_the_c_standard_l">Algorithms
1141        from the C++ standard library</a></span></dt>
1142<dt><span class="section"><a href="guide.html#histogram.guide.using_algorithms.summation">Summation</a></span></dt>
1143<dt><span class="section"><a href="guide.html#histogram.guide.using_algorithms.projection">Projection</a></span></dt>
1144<dt><span class="section"><a href="guide.html#histogram.guide.using_algorithms.reduction">Reduction</a></span></dt>
1145</dl></div>
1146<p>
1147        The library was designed to work with algorithms from the C++ standard library.
1148        In addition, a support library of algorithms is included with common operations
1149        on histograms.
1150      </p>
1151<div class="section">
1152<div class="titlepage"><div><div><h4 class="title">
1153<a name="histogram.guide.using_algorithms.algorithms_from_the_c_standard_l"></a><a class="link" href="guide.html#histogram.guide.using_algorithms.algorithms_from_the_c_standard_l" title="Algorithms from the C++ standard library">Algorithms
1154        from the C++ standard library</a>
1155</h4></div></div></div>
1156<p>
1157          The histogram class has standard random-access iterators which can be used
1158          with various algorithms from the standard library. Some things need to
1159          be kept in mind:
1160        </p>
1161<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
1162<li class="listitem">
1163              The histogram iterators also walk over the under- and overflow bins,
1164              if they are present. To skip the extra bins one should use the fast
1165              iterators from the <code class="computeroutput"><a class="link" href="../boost/histogram/indexed.html" title="Function template indexed">boost::histogram::indexed</a></code>
1166              range generator instead.
1167            </li>
1168<li class="listitem">
1169              The iteration order for histograms with several axes is an implementation-detail,
1170              but for histograms with one axis it is guaranteed to be the obvious
1171              order: bins are accessed in order from the lowest to the highest index.
1172            </li>
1173</ul></div>
1174<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
1175<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
1176
1177<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">algorithm</span><span class="special">&gt;</span> <span class="comment">// fill, any_of, min_element, max_element</span>
1178<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cmath</span><span class="special">&gt;</span>     <span class="comment">// sqrt</span>
1179<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">numeric</span><span class="special">&gt;</span>   <span class="comment">// partial_sum, inner_product</span>
1180
1181<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
1182  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>
1183
1184  <span class="comment">// make histogram that represents a probability density function (PDF)</span>
1185  <span class="keyword">auto</span> <span class="identifier">h1</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">4</span><span class="special">,</span> <span class="number">1.0</span><span class="special">,</span> <span class="number">3.0</span><span class="special">));</span>
1186
1187  <span class="comment">// make indexed range to skip underflow and overflow cells</span>
1188  <span class="keyword">auto</span> <span class="identifier">ind</span> <span class="special">=</span> <span class="identifier">indexed</span><span class="special">(</span><span class="identifier">h1</span><span class="special">);</span>
1189
1190  <span class="comment">// use std::fill to set all counters to 0.25 (except under- and overflow counters)</span>
1191  <span class="identifier">std</span><span class="special">::</span><span class="identifier">fill</span><span class="special">(</span><span class="identifier">ind</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">ind</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="number">0.25</span><span class="special">);</span>
1192
1193  <span class="comment">// compute the cumulative density function (CDF), overriding cell values</span>
1194  <span class="identifier">std</span><span class="special">::</span><span class="identifier">partial_sum</span><span class="special">(</span><span class="identifier">ind</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">ind</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="identifier">ind</span><span class="special">.</span><span class="identifier">begin</span><span class="special">());</span>
1195
1196  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">at</span><span class="special">(-</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">0.00</span><span class="special">);</span>
1197  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">0.25</span><span class="special">);</span>
1198  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">0.50</span><span class="special">);</span>
1199  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">2</span><span class="special">)</span> <span class="special">==</span> <span class="number">0.75</span><span class="special">);</span>
1200  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">3</span><span class="special">)</span> <span class="special">==</span> <span class="number">1.00</span><span class="special">);</span>
1201  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">4</span><span class="special">)</span> <span class="special">==</span> <span class="number">0.00</span><span class="special">);</span>
1202
1203  <span class="comment">// use any_of to check if any cell values are smaller than 0.1,</span>
1204  <span class="keyword">auto</span> <span class="identifier">b</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">any_of</span><span class="special">(</span><span class="identifier">ind</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">ind</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="special">[](</span><span class="keyword">const</span> <span class="keyword">auto</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">x</span> <span class="special">&lt;</span> <span class="number">0.1</span><span class="special">;</span> <span class="special">});</span>
1205  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">b</span> <span class="special">==</span> <span class="keyword">false</span><span class="special">);</span> <span class="comment">// under- and overflow cells are zero, but skipped</span>
1206
1207  <span class="comment">// find minimum element</span>
1208  <span class="keyword">auto</span> <span class="identifier">min_it</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">min_element</span><span class="special">(</span><span class="identifier">ind</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">ind</span><span class="special">.</span><span class="identifier">end</span><span class="special">());</span>
1209  <span class="identifier">assert</span><span class="special">(*</span><span class="identifier">min_it</span> <span class="special">==</span> <span class="number">0.25</span><span class="special">);</span> <span class="comment">// under- and overflow cells are skipped</span>
1210
1211  <span class="comment">// find maximum element</span>
1212  <span class="keyword">auto</span> <span class="identifier">max_it</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">max_element</span><span class="special">(</span><span class="identifier">ind</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">ind</span><span class="special">.</span><span class="identifier">end</span><span class="special">());</span>
1213  <span class="identifier">assert</span><span class="special">(*</span><span class="identifier">max_it</span> <span class="special">==</span> <span class="number">1.0</span><span class="special">);</span>
1214
1215  <span class="comment">// make second PDF</span>
1216  <span class="keyword">auto</span> <span class="identifier">h2</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">4</span><span class="special">,</span> <span class="number">1.0</span><span class="special">,</span> <span class="number">4.0</span><span class="special">));</span>
1217  <span class="identifier">h2</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">=</span> <span class="number">0.1</span><span class="special">;</span>
1218  <span class="identifier">h2</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">=</span> <span class="number">0.3</span><span class="special">;</span>
1219  <span class="identifier">h2</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">2</span><span class="special">)</span> <span class="special">=</span> <span class="number">0.2</span><span class="special">;</span>
1220  <span class="identifier">h2</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">3</span><span class="special">)</span> <span class="special">=</span> <span class="number">0.4</span><span class="special">;</span>
1221
1222  <span class="comment">// computing cosine similiarity: cos(theta) = A dot B / sqrt((A dot A) * (B dot B))</span>
1223  <span class="keyword">auto</span> <span class="identifier">ind2</span> <span class="special">=</span> <span class="identifier">indexed</span><span class="special">(</span><span class="identifier">h2</span><span class="special">);</span>
1224  <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">aa</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">inner_product</span><span class="special">(</span><span class="identifier">ind</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">ind</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="identifier">ind</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="number">0.0</span><span class="special">);</span>
1225  <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">bb</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">inner_product</span><span class="special">(</span><span class="identifier">ind2</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">ind2</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="identifier">ind2</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="number">0.0</span><span class="special">);</span>
1226  <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">ab</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">inner_product</span><span class="special">(</span><span class="identifier">ind</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">ind</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="identifier">ind2</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="number">0.0</span><span class="special">);</span>
1227  <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">cos_sim</span> <span class="special">=</span> <span class="identifier">ab</span> <span class="special">/</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">sqrt</span><span class="special">(</span><span class="identifier">aa</span> <span class="special">*</span> <span class="identifier">bb</span><span class="special">);</span>
1228
1229  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">abs</span><span class="special">(</span><span class="identifier">cos_sim</span> <span class="special">-</span> <span class="number">0.967</span><span class="special">)</span> <span class="special">&lt;</span> <span class="number">1e-2</span><span class="special">);</span>
1230<span class="special">}</span>
1231</pre>
1232</div>
1233<div class="section">
1234<div class="titlepage"><div><div><h4 class="title">
1235<a name="histogram.guide.using_algorithms.summation"></a><a class="link" href="guide.html#histogram.guide.using_algorithms.summation" title="Summation">Summation</a>
1236</h4></div></div></div>
1237<p>
1238          It is easy to iterate over all histogram cells to compute the sum of cell
1239          values by hand or to use an algorithm from the standard library to do so,
1240          but it is not safe. The result may not be accurate or overflow, if the
1241          sum is represented by an integer type. The library provides <code class="computeroutput"><a class="link" href="../boost/histogram/algorithm/sum.html" title="Function template sum">boost::histogram::algorithm::sum</a></code>
1242          as a safer, albeit slower, alternative. It uses the <a href="https://en.wikipedia.org/wiki/Kahan_summation_algorithm" target="_top">Neumaier
1243          algorithm</a> in double precision for integers and floating point cells,
1244          and does the naive sum otherwise.
1245        </p>
1246</div>
1247<div class="section">
1248<div class="titlepage"><div><div><h4 class="title">
1249<a name="histogram.guide.using_algorithms.projection"></a><a class="link" href="guide.html#histogram.guide.using_algorithms.projection" title="Projection">Projection</a>
1250</h4></div></div></div>
1251<p>
1252          It is sometimes convenient to generate a high-dimensional histogram first
1253          and then extract smaller or lower-dimensional versions from it. Lower-dimensional
1254          histograms are obtained by summing the bin contents of the removed axes.
1255          This is called a <span class="emphasis"><em>projection</em></span>. If the histogram has
1256          under- and overflow bins along all axes, this operation creates a histogram
1257          which is identical to one that would have been obtained by filling the
1258          original data.
1259        </p>
1260<p>
1261          Projection is useful if you found out that there is no interesting structure
1262          along an axis, so it is not worth keeping that axis around, or if you want
1263          to visualize 1d or 2d summaries of a high-dimensional histogram.
1264        </p>
1265<p>
1266          The library provides the <code class="computeroutput"><a class="link" href="../boost/histogram/algorithm/project_idm45503931171616.html" title="Function template project">boost::histogram::algorithm::project</a></code>
1267          function for this purpose. It accepts the original histogram and the indices
1268          (one or more) of the axes that are kept and returns the lower-dimensional
1269          histogram. If the histogram is static, meaning the axis configuration is
1270          known at compile-time, compile-time numbers should be used as indices to
1271          obtain another static histogram. Using normal numbers or iterators over
1272          indices produces a histogram with a dynamic axis configuration.
1273        </p>
1274<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
1275<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
1276<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
1277<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">sstream</span><span class="special">&gt;</span>
1278
1279<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
1280  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>
1281  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">literals</span><span class="special">;</span> <span class="comment">// enables _c suffix</span>
1282
1283  <span class="comment">// make a 2d histogram</span>
1284  <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">3</span><span class="special">,</span> <span class="special">-</span><span class="number">1.0</span><span class="special">,</span> <span class="number">1.0</span><span class="special">),</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;&gt;(</span><span class="number">0</span><span class="special">,</span> <span class="number">2</span><span class="special">));</span>
1285
1286  <span class="identifier">h</span><span class="special">(-</span><span class="number">0.9</span><span class="special">,</span> <span class="number">0</span><span class="special">);</span>
1287  <span class="identifier">h</span><span class="special">(</span><span class="number">0.9</span><span class="special">,</span> <span class="number">1</span><span class="special">);</span>
1288  <span class="identifier">h</span><span class="special">(</span><span class="number">0.1</span><span class="special">,</span> <span class="number">0</span><span class="special">);</span>
1289
1290  <span class="keyword">auto</span> <span class="identifier">hr0</span> <span class="special">=</span> <span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">project</span><span class="special">(</span><span class="identifier">h</span><span class="special">,</span> <span class="number">0</span><span class="identifier">_c</span><span class="special">);</span> <span class="comment">// keep only first axis</span>
1291  <span class="keyword">auto</span> <span class="identifier">hr1</span> <span class="special">=</span> <span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">project</span><span class="special">(</span><span class="identifier">h</span><span class="special">,</span> <span class="number">1</span><span class="identifier">_c</span><span class="special">);</span> <span class="comment">// keep only second axis</span>
1292
1293  <span class="comment">// reduce does not remove counts; returned histograms are summed over</span>
1294  <span class="comment">// the removed axes, so h, hr0, and hr1 have same number of total counts;</span>
1295  <span class="comment">// we compute the sum of counts with the sum algorithm</span>
1296  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">sum</span><span class="special">(</span><span class="identifier">h</span><span class="special">)</span> <span class="special">==</span> <span class="number">3</span> <span class="special">&amp;&amp;</span> <span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">sum</span><span class="special">(</span><span class="identifier">hr0</span><span class="special">)</span> <span class="special">==</span> <span class="number">3</span> <span class="special">&amp;&amp;</span> <span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">sum</span><span class="special">(</span><span class="identifier">hr1</span><span class="special">)</span> <span class="special">==</span> <span class="number">3</span><span class="special">);</span>
1297
1298  <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os1</span><span class="special">;</span>
1299  <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&amp;&amp;</span> <span class="identifier">x</span> <span class="special">:</span> <span class="identifier">indexed</span><span class="special">(</span><span class="identifier">h</span><span class="special">))</span>
1300    <span class="identifier">os1</span> <span class="special">&lt;&lt;</span> <span class="string">"("</span> <span class="special">&lt;&lt;</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">", "</span> <span class="special">&lt;&lt;</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">"): "</span> <span class="special">&lt;&lt;</span> <span class="special">*</span><span class="identifier">x</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
1301  <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">os1</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">flush</span><span class="special">;</span>
1302  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">os1</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span> <span class="string">"(0, 0): 1\n"</span>
1303                      <span class="string">"(1, 0): 1\n"</span>
1304                      <span class="string">"(2, 0): 0\n"</span>
1305                      <span class="string">"(0, 1): 0\n"</span>
1306                      <span class="string">"(1, 1): 0\n"</span>
1307                      <span class="string">"(2, 1): 1\n"</span><span class="special">);</span>
1308
1309  <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os2</span><span class="special">;</span>
1310  <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&amp;&amp;</span> <span class="identifier">x</span> <span class="special">:</span> <span class="identifier">indexed</span><span class="special">(</span><span class="identifier">hr0</span><span class="special">))</span> <span class="identifier">os2</span> <span class="special">&lt;&lt;</span> <span class="string">"("</span> <span class="special">&lt;&lt;</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">", -): "</span> <span class="special">&lt;&lt;</span> <span class="special">*</span><span class="identifier">x</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
1311  <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">os2</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">flush</span><span class="special">;</span>
1312  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">os2</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span> <span class="string">"(0, -): 1\n"</span>
1313                      <span class="string">"(1, -): 1\n"</span>
1314                      <span class="string">"(2, -): 1\n"</span><span class="special">);</span>
1315
1316  <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os3</span><span class="special">;</span>
1317  <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&amp;&amp;</span> <span class="identifier">x</span> <span class="special">:</span> <span class="identifier">indexed</span><span class="special">(</span><span class="identifier">hr1</span><span class="special">))</span> <span class="identifier">os3</span> <span class="special">&lt;&lt;</span> <span class="string">"(- ,"</span> <span class="special">&lt;&lt;</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">"): "</span> <span class="special">&lt;&lt;</span> <span class="special">*</span><span class="identifier">x</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
1318  <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">os3</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">flush</span><span class="special">;</span>
1319  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">os3</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span> <span class="string">"(- ,0): 2\n"</span>
1320                      <span class="string">"(- ,1): 1\n"</span><span class="special">);</span>
1321<span class="special">}</span>
1322</pre>
1323</div>
1324<div class="section">
1325<div class="titlepage"><div><div><h4 class="title">
1326<a name="histogram.guide.using_algorithms.reduction"></a><a class="link" href="guide.html#histogram.guide.using_algorithms.reduction" title="Reduction">Reduction</a>
1327</h4></div></div></div>
1328<p>
1329          A projection removes an axis completely. A less drastic way to obtain a
1330          smaller histogram is the <code class="computeroutput"><a class="link" href="../boost/histogram/algorithm/reduce_idm45503931121408.html" title="Function template reduce">reduce</a></code>
1331          function, which allows one to <span class="emphasis"><em>slice</em></span>, <span class="emphasis"><em>shrink</em></span>
1332          or <span class="emphasis"><em>rebin</em></span> individual axes.
1333        </p>
1334<p>
1335          Shrinking means that the value range of an axis is reduced and the number
1336          of bins along that axis. Slicing does the same, but is based on axis indices
1337          while shrinking is based on the axis values. To <span class="emphasis"><em>rebin</em></span>
1338          means that adjacent bins are merged into larger bins, the histogram is
1339          made coarser. For N adjacent bins, a new bin is formed which covers the
1340          common interval of the merged bins and has their added content. These two
1341          operations can be combined and applied to several axes at once. Doing it
1342          in one step is much more efficient than doing it in several steps.
1343        </p>
1344<p>
1345          The <code class="computeroutput"><a class="link" href="../boost/histogram/algorithm/reduce_idm45503931121408.html" title="Function template reduce">reduce</a></code>
1346          function does not change the total count if all modified axes in the histogram
1347          have underflow and overflow bins. Counts in removed bins are added to the
1348          corresponding under- and overflow bins. As in case of the <code class="computeroutput"><a class="link" href="../boost/histogram/algorithm/project_idm45503931171616.html" title="Function template project">project</a></code> function,
1349          such a histogram is guaranteed to be identical to one obtained from filling
1350          the original data.
1351        </p>
1352<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
1353<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
1354
1355<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
1356  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>
1357  <span class="comment">// import reduce commands into local namespace to save typing</span>
1358  <span class="keyword">using</span> <span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">rebin</span><span class="special">;</span>
1359  <span class="keyword">using</span> <span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">shrink</span><span class="special">;</span>
1360  <span class="keyword">using</span> <span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">slice</span><span class="special">;</span>
1361
1362  <span class="comment">// make a 2d histogram</span>
1363  <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">4</span><span class="special">,</span> <span class="number">0.0</span><span class="special">,</span> <span class="number">4.0</span><span class="special">),</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">4</span><span class="special">,</span> <span class="special">-</span><span class="number">2.0</span><span class="special">,</span> <span class="number">2.0</span><span class="special">));</span>
1364
1365  <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="special">-</span><span class="number">0.9</span><span class="special">);</span>
1366  <span class="identifier">h</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">0.9</span><span class="special">);</span>
1367  <span class="identifier">h</span><span class="special">(</span><span class="number">2</span><span class="special">,</span> <span class="number">0.1</span><span class="special">);</span>
1368  <span class="identifier">h</span><span class="special">(</span><span class="number">3</span><span class="special">,</span> <span class="number">0.1</span><span class="special">);</span>
1369
1370  <span class="comment">// reduce takes positional commands which are applied to the axes in order</span>
1371  <span class="comment">// - shrink is applied to the first axis; the new axis range is 0.0 to 3.0</span>
1372  <span class="comment">// - rebin is applied to the second axis; pairs of adjacent bins are merged</span>
1373  <span class="keyword">auto</span> <span class="identifier">h2</span> <span class="special">=</span> <span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">reduce</span><span class="special">(</span><span class="identifier">h</span><span class="special">,</span> <span class="identifier">shrink</span><span class="special">(</span><span class="number">0.0</span><span class="special">,</span> <span class="number">3.0</span><span class="special">),</span> <span class="identifier">rebin</span><span class="special">(</span><span class="number">2</span><span class="special">));</span>
1374
1375  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">.</span><span class="identifier">axis</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">3</span><span class="special">,</span> <span class="number">0.0</span><span class="special">,</span> <span class="number">3.0</span><span class="special">));</span>
1376  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">.</span><span class="identifier">axis</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">2</span><span class="special">,</span> <span class="special">-</span><span class="number">2.0</span><span class="special">,</span> <span class="number">2.0</span><span class="special">));</span>
1377
1378  <span class="comment">// reduce does not change the total count if the histogram has underflow/overflow bins</span>
1379  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">sum</span><span class="special">(</span><span class="identifier">h</span><span class="special">)</span> <span class="special">==</span> <span class="number">4</span> <span class="special">&amp;&amp;</span> <span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">sum</span><span class="special">(</span><span class="identifier">h2</span><span class="special">)</span> <span class="special">==</span> <span class="number">4</span><span class="special">);</span>
1380
1381  <span class="comment">// One can also explicitly specify the index of the axis in the histogram on which the</span>
1382  <span class="comment">// command should act, by using this index as the the first parameter. The position of</span>
1383  <span class="comment">// the command in the argument list of reduce is then ignored. We use this to slice only</span>
1384  <span class="comment">// the second axis (axis has index 1 in the histogram) from bin index 2 to 4.</span>
1385  <span class="keyword">auto</span> <span class="identifier">h3</span> <span class="special">=</span> <span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">reduce</span><span class="special">(</span><span class="identifier">h</span><span class="special">,</span> <span class="identifier">slice</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="number">4</span><span class="special">));</span>
1386
1387  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h3</span><span class="special">.</span><span class="identifier">axis</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="identifier">h</span><span class="special">.</span><span class="identifier">axis</span><span class="special">(</span><span class="number">0</span><span class="special">));</span> <span class="comment">// unchanged</span>
1388  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h3</span><span class="special">.</span><span class="identifier">axis</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">2</span><span class="special">,</span> <span class="number">0.0</span><span class="special">,</span> <span class="number">2.0</span><span class="special">));</span>
1389<span class="special">}</span>
1390</pre>
1391</div>
1392</div>
1393<div class="section">
1394<div class="titlepage"><div><div><h3 class="title">
1395<a name="histogram.guide.streaming"></a><a class="link" href="guide.html#histogram.guide.streaming" title="Streaming">Streaming</a>
1396</h3></div></div></div>
1397<p>
1398        Simple streaming operators are shipped with the library. They are internally
1399        used by the unit tests and give simple text representations of axis and histogram
1400        configurations and show the histogram content. One-dimensional histograms
1401        are rendered as ASCII drawings. The text representations may be useful for
1402        debugging or more, but users may want to use their own implementations. Therefore,
1403        the headers with the builtin implementations are not included by any other
1404        header of the library. The following example shows the effect of output streaming.
1405      </p>
1406<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
1407<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">/</span><span class="identifier">ostream</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
1408<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
1409<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
1410<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">sstream</span><span class="special">&gt;</span>
1411<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">string</span><span class="special">&gt;</span>
1412
1413<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
1414  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>
1415
1416  <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os</span><span class="special">;</span>
1417
1418  <span class="keyword">auto</span> <span class="identifier">h1</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">5</span><span class="special">,</span> <span class="special">-</span><span class="number">1.0</span><span class="special">,</span> <span class="number">1.0</span><span class="special">,</span> <span class="string">"axis 1"</span><span class="special">));</span>
1419  <span class="identifier">h1</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">=</span> <span class="number">2</span><span class="special">;</span>
1420  <span class="identifier">h1</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">=</span> <span class="number">4</span><span class="special">;</span>
1421  <span class="identifier">h1</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">2</span><span class="special">)</span> <span class="special">=</span> <span class="number">3</span><span class="special">;</span>
1422  <span class="identifier">h1</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">4</span><span class="special">)</span> <span class="special">=</span> <span class="number">1</span><span class="special">;</span>
1423
1424  <span class="comment">// 1D histograms are rendered as an ASCII drawing</span>
1425  <span class="identifier">os</span> <span class="special">&lt;&lt;</span> <span class="identifier">h1</span><span class="special">;</span>
1426
1427  <span class="keyword">auto</span> <span class="identifier">h2</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">2</span><span class="special">,</span> <span class="special">-</span><span class="number">1.0</span><span class="special">,</span> <span class="number">1.0</span><span class="special">,</span> <span class="string">"axis 1"</span><span class="special">),</span>
1428                           <span class="identifier">axis</span><span class="special">::</span><span class="identifier">category</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;({</span><span class="string">"red"</span><span class="special">,</span> <span class="string">"blue"</span><span class="special">},</span> <span class="string">"axis 2"</span><span class="special">));</span>
1429
1430  <span class="comment">// higher dimensional histograms just have their cell counts listed</span>
1431  <span class="identifier">os</span> <span class="special">&lt;&lt;</span> <span class="identifier">h2</span><span class="special">;</span>
1432
1433  <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
1434
1435  <span class="identifier">assert</span><span class="special">(</span>
1436      <span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span>
1437      <span class="string">"histogram(regular(5, -1, 1, metadata=\"axis 1\", options=underflow | overflow))\n"</span>
1438      <span class="string">"               +-------------------------------------------------------------+\n"</span>
1439      <span class="string">"[-inf,   -1) 0 |                                                             |\n"</span>
1440      <span class="string">"[  -1, -0.6) 2 |==============================                               |\n"</span>
1441      <span class="string">"[-0.6, -0.2) 4 |============================================================ |\n"</span>
1442      <span class="string">"[-0.2,  0.2) 3 |=============================================                |\n"</span>
1443      <span class="string">"[ 0.2,  0.6) 0 |                                                             |\n"</span>
1444      <span class="string">"[ 0.6,    1) 1 |===============                                              |\n"</span>
1445      <span class="string">"[   1,  inf) 0 |                                                             |\n"</span>
1446      <span class="string">"               +-------------------------------------------------------------+\n"</span>
1447      <span class="string">"histogram(\n"</span>
1448      <span class="string">"  regular(2, -1, 1, metadata=\"axis 1\", options=underflow | overflow)\n"</span>
1449      <span class="string">"  category(\"red\", \"blue\", metadata=\"axis 2\", options=overflow)\n"</span>
1450      <span class="string">"  (-1 0): 0 ( 0 0): 0 ( 1 0): 0 ( 2 0): 0 (-1 1): 0 ( 0 1): 0\n"</span>
1451      <span class="string">"  ( 1 1): 0 ( 2 1): 0 (-1 2): 0 ( 0 2): 0 ( 1 2): 0 ( 2 2): 0\n"</span>
1452      <span class="string">")"</span><span class="special">);</span>
1453<span class="special">}</span>
1454</pre>
1455</div>
1456<div class="section">
1457<div class="titlepage"><div><div><h3 class="title">
1458<a name="histogram.guide.serialization"></a><a class="link" href="guide.html#histogram.guide.serialization" title="Serialization">Serialization</a>
1459</h3></div></div></div>
1460<p>
1461        The library supports serialization via <a href="../../../../../libs/serialization/index.html" target="_top">Boost.Serialization</a>.
1462        The serialization code is not included by the super header <code class="computeroutput"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span></code>,
1463        so that the library can be used without Boost.Serialization or with another
1464        compatible serialization library.
1465      </p>
1466<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">archive</span><span class="special">/</span><span class="identifier">text_iarchive</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
1467<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">archive</span><span class="special">/</span><span class="identifier">text_oarchive</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
1468<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
1469<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">/</span><span class="identifier">serialization</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span> <span class="comment">// includes serialization code</span>
1470<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
1471<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">sstream</span><span class="special">&gt;</span>
1472
1473<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
1474  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>
1475
1476  <span class="keyword">auto</span> <span class="identifier">a</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">3</span><span class="special">,</span> <span class="special">-</span><span class="number">1.0</span><span class="special">,</span> <span class="number">1.0</span><span class="special">,</span> <span class="string">"axis 0"</span><span class="special">),</span>
1477                          <span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;&gt;(</span><span class="number">0</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="string">"axis 1"</span><span class="special">));</span>
1478  <span class="identifier">a</span><span class="special">(</span><span class="number">0.5</span><span class="special">,</span> <span class="number">1</span><span class="special">);</span>
1479
1480  <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">buf</span><span class="special">;</span> <span class="comment">// to hold persistent representation</span>
1481
1482  <span class="comment">// store histogram</span>
1483  <span class="special">{</span>
1484    <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os</span><span class="special">;</span>
1485    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">archive</span><span class="special">::</span><span class="identifier">text_oarchive</span> <span class="identifier">oa</span><span class="special">(</span><span class="identifier">os</span><span class="special">);</span>
1486    <span class="identifier">oa</span> <span class="special">&lt;&lt;</span> <span class="identifier">a</span><span class="special">;</span>
1487    <span class="identifier">buf</span> <span class="special">=</span> <span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">();</span>
1488  <span class="special">}</span>
1489
1490  <span class="keyword">auto</span> <span class="identifier">b</span> <span class="special">=</span> <span class="keyword">decltype</span><span class="special">(</span><span class="identifier">a</span><span class="special">)();</span> <span class="comment">// create a default-constructed second histogram</span>
1491
1492  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">b</span> <span class="special">!=</span> <span class="identifier">a</span><span class="special">);</span> <span class="comment">// b is empty, a is not</span>
1493
1494  <span class="comment">// load histogram</span>
1495  <span class="special">{</span>
1496    <span class="identifier">std</span><span class="special">::</span><span class="identifier">istringstream</span> <span class="identifier">is</span><span class="special">(</span><span class="identifier">buf</span><span class="special">);</span>
1497    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">archive</span><span class="special">::</span><span class="identifier">text_iarchive</span> <span class="identifier">ia</span><span class="special">(</span><span class="identifier">is</span><span class="special">);</span>
1498    <span class="identifier">ia</span> <span class="special">&gt;&gt;</span> <span class="identifier">b</span><span class="special">;</span>
1499  <span class="special">}</span>
1500
1501  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">b</span> <span class="special">==</span> <span class="identifier">a</span><span class="special">);</span> <span class="comment">// now b is equal to a</span>
1502<span class="special">}</span>
1503</pre>
1504</div>
1505<div class="section">
1506<div class="titlepage"><div><div><h3 class="title">
1507<a name="histogram.guide.using_histograms_in_apis"></a><a class="link" href="guide.html#histogram.guide.using_histograms_in_apis" title="Using histograms in APIs">Using histograms
1508      in APIs</a>
1509</h3></div></div></div>
1510<p>
1511        Letting the compiler deduce the histogram type is recommended, because the
1512        templated type is tedious to write down explicitly. Functions or methods
1513        which accept or return histograms should be templated to work with all kinds
1514        of histograms. It is also possible to write templated versions which accept
1515        only histograms with dynamic axes or only histograms with static axes. The
1516        following example demonstrates all this.
1517      </p>
1518<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
1519<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
1520
1521<span class="comment">// function accepts any histogram and returns a copy</span>
1522<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Axes</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Storage</span><span class="special">&gt;</span>
1523<span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">&lt;</span><span class="identifier">Axes</span><span class="special">,</span> <span class="identifier">Storage</span><span class="special">&gt;</span> <span class="identifier">any_histogram</span><span class="special">(</span>
1524    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">&lt;</span><span class="identifier">Axes</span><span class="special">,</span> <span class="identifier">Storage</span><span class="special">&gt;&amp;</span> <span class="identifier">h</span><span class="special">)</span> <span class="special">{</span>
1525  <span class="keyword">return</span> <span class="identifier">h</span><span class="special">;</span>
1526<span class="special">}</span>
1527
1528<span class="comment">// function only accepts histograms with fixed axis types and returns a copy</span>
1529<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Storage</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">Axes</span><span class="special">&gt;</span>
1530<span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="identifier">Axes</span><span class="special">...&gt;,</span> <span class="identifier">Storage</span><span class="special">&gt;</span> <span class="identifier">only_static_histogram</span><span class="special">(</span>
1531    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="identifier">Axes</span><span class="special">...&gt;,</span> <span class="identifier">Storage</span><span class="special">&gt;&amp;</span> <span class="identifier">h</span><span class="special">)</span> <span class="special">{</span>
1532  <span class="keyword">return</span> <span class="identifier">h</span><span class="special">;</span>
1533<span class="special">}</span>
1534
1535<span class="comment">// function only accepts histograms with dynamic axis types and returns a copy</span>
1536<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Storage</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">Axes</span><span class="special">&gt;</span>
1537<span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><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><span class="special">&lt;</span><span class="identifier">Axes</span><span class="special">...&gt;&gt;,</span>
1538                            <span class="identifier">Storage</span><span class="special">&gt;</span>
1539<span class="identifier">only_dynamic_histogram</span><span class="special">(</span>
1540    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><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><span class="special">&lt;</span><span class="identifier">Axes</span><span class="special">...&gt;&gt;,</span>
1541                                <span class="identifier">Storage</span><span class="special">&gt;&amp;</span> <span class="identifier">h</span><span class="special">)</span> <span class="special">{</span>
1542  <span class="keyword">return</span> <span class="identifier">h</span><span class="special">;</span>
1543<span class="special">}</span>
1544
1545<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
1546  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>
1547
1548  <span class="keyword">auto</span> <span class="identifier">histogram_with_static_axes</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">10</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="number">1</span><span class="special">));</span>
1549
1550  <span class="keyword">using</span> <span class="identifier">axis_variant</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">variant</span><span class="special">&lt;</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;,</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;&gt;&gt;;</span>
1551  <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">axis_variant</span><span class="special">&gt;</span> <span class="identifier">axes</span><span class="special">;</span>
1552  <span class="identifier">axes</span><span class="special">.</span><span class="identifier">emplace_back</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">5</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="number">1</span><span class="special">));</span>
1553  <span class="identifier">axes</span><span class="special">.</span><span class="identifier">emplace_back</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;&gt;(</span><span class="number">0</span><span class="special">,</span> <span class="number">1</span><span class="special">));</span>
1554  <span class="keyword">auto</span> <span class="identifier">histogram_with_dynamic_axes</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axes</span><span class="special">);</span>
1555
1556  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">any_histogram</span><span class="special">(</span><span class="identifier">histogram_with_static_axes</span><span class="special">)</span> <span class="special">==</span> <span class="identifier">histogram_with_static_axes</span><span class="special">);</span>
1557  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">any_histogram</span><span class="special">(</span><span class="identifier">histogram_with_dynamic_axes</span><span class="special">)</span> <span class="special">==</span> <span class="identifier">histogram_with_dynamic_axes</span><span class="special">);</span>
1558  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">only_static_histogram</span><span class="special">(</span><span class="identifier">histogram_with_static_axes</span><span class="special">)</span> <span class="special">==</span> <span class="identifier">histogram_with_static_axes</span><span class="special">);</span>
1559  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">only_dynamic_histogram</span><span class="special">(</span><span class="identifier">histogram_with_dynamic_axes</span><span class="special">)</span> <span class="special">==</span>
1560         <span class="identifier">histogram_with_dynamic_axes</span><span class="special">);</span>
1561
1562  <span class="comment">// does not compile: only_static_histogram(histogram_with_dynamic_axes)</span>
1563  <span class="comment">// does not compile: only_dynamic_histogram(histogram_with_static_axes)</span>
1564<span class="special">}</span>
1565</pre>
1566<p>
1567        If the histogram type has to be written down explicitly, the types are constructed
1568        as follows. In all cases, the <code class="computeroutput"><span class="identifier">default_storage</span></code>
1569        type argument may be replaced by any other storage type or omitted entirely.
1570      </p>
1571<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
1572<li class="listitem">
1573<p class="simpara">
1574            Histogram with fixed axis types:
1575          </p>
1576<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">&lt;</span>
1577  <span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="identifier">axis_type_1</span><span class="special">,</span> <span class="identifier">axis_type_2</span><span class="special">,</span> <span class="special">...,</span> <span class="identifier">axis_type_N</span><span class="special">&gt;</span>
1578  <span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">default_storage</span>
1579<span class="special">&gt;</span>
1580</pre>
1581</li>
1582<li class="listitem">
1583<p class="simpara">
1584            Histogram with a variable number of the same axis type:
1585          </p>
1586<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">&lt;</span>
1587  <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span>
1588    <span class="identifier">axis_type_1</span>
1589  <span class="special">&gt;</span>
1590  <span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">default_storage</span>
1591<span class="special">&gt;</span>
1592</pre>
1593</li>
1594<li class="listitem">
1595<p class="simpara">
1596            Histogram with variable axis types:
1597          </p>
1598<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">&lt;</span>
1599  <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span>
1600    <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><span class="special">&lt;</span>
1601      <span class="identifier">axis_type_1</span><span class="special">,</span> <span class="identifier">axis_type_2</span><span class="special">,</span> <span class="special">...,</span> <span class="identifier">axis_type_N</span>
1602    <span class="special">&gt;</span>
1603  <span class="special">&gt;</span>
1604  <span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">default_storage</span>
1605<span class="special">&gt;</span>
1606</pre>
1607</li>
1608</ul></div>
1609</div>
1610<div class="section">
1611<div class="titlepage"><div><div><h3 class="title">
1612<a name="histogram.guide.expert"></a><a class="link" href="guide.html#histogram.guide.expert" title="Advanced usage">Advanced usage</a>
1613</h3></div></div></div>
1614<div class="toc"><dl class="toc">
1615<dt><span class="section"><a href="guide.html#histogram.guide.expert.user_defined_axes">User-defined
1616        axes</a></span></dt>
1617<dt><span class="section"><a href="guide.html#histogram.guide.expert.axis_with_several_arguments">Axis
1618        with several arguments</a></span></dt>
1619<dt><span class="section"><a href="guide.html#histogram.guide.expert.user_defined_storage_class">User-defined
1620        storage class</a></span></dt>
1621<dt><span class="section"><a href="guide.html#histogram.guide.expert.parallelisation_options">Parallelisation
1622        options</a></span></dt>
1623<dt><span class="section"><a href="guide.html#histogram.guide.expert.user_defined_accumulators">User-defined
1624        accumulators</a></span></dt>
1625</dl></div>
1626<p>
1627        The library is customisable and extensible by users. Users can create new
1628        axis types and use them with the histogram, or implement a custom storage
1629        policy, or use a builtin storage policy with a custom counter type. The library
1630        was designed to make this very easy. This section shows how to do this.
1631      </p>
1632<div class="section">
1633<div class="titlepage"><div><div><h4 class="title">
1634<a name="histogram.guide.expert.user_defined_axes"></a><a class="link" href="guide.html#histogram.guide.expert.user_defined_axes" title="User-defined axes">User-defined
1635        axes</a>
1636</h4></div></div></div>
1637<p>
1638          It is easy to make custom axis classes that work with the library. The
1639          custom axis class must meet the requirements of the <a class="link" href="concepts.html#histogram.concepts.Axis" title="Axis"><span class="bold"><strong>Axis</strong></span> concept</a>.
1640        </p>
1641<p>
1642          Users can create a custom axis by derive from a builtin axis type and customize
1643          its behavior. The following examples demonstrates a modification of the
1644          <code class="computeroutput"><a class="link" href="../boost/histogram/axis/integer.html" title="Class template integer">integer axis</a></code>.
1645        </p>
1646<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
1647<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
1648<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
1649<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">sstream</span><span class="special">&gt;</span>
1650
1651<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
1652  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>
1653
1654  <span class="comment">// custom axis, which adapts builtin integer axis</span>
1655  <span class="keyword">struct</span> <span class="identifier">custom_axis</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;&gt;</span> <span class="special">{</span>
1656    <span class="keyword">using</span> <span class="identifier">value_type</span> <span class="special">=</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*;</span> <span class="comment">// type that is fed to the axis</span>
1657
1658    <span class="keyword">using</span> <span class="identifier">integer</span><span class="special">::</span><span class="identifier">integer</span><span class="special">;</span> <span class="comment">// inherit ctors of base</span>
1659
1660    <span class="comment">// the customization point</span>
1661    <span class="comment">// - accept const char* and convert to int</span>
1662    <span class="comment">// - then call index method of base class</span>
1663    <span class="identifier">axis</span><span class="special">::</span><span class="identifier">index_type</span> <span class="identifier">index</span><span class="special">(</span><span class="identifier">value_type</span> <span class="identifier">s</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">integer</span><span class="special">::</span><span class="identifier">index</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">atoi</span><span class="special">(</span><span class="identifier">s</span><span class="special">));</span> <span class="special">}</span>
1664  <span class="special">};</span>
1665
1666  <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">custom_axis</span><span class="special">(</span><span class="number">3</span><span class="special">,</span> <span class="number">6</span><span class="special">));</span>
1667  <span class="identifier">h</span><span class="special">(</span><span class="string">"-10"</span><span class="special">);</span>
1668  <span class="identifier">h</span><span class="special">(</span><span class="string">"3"</span><span class="special">);</span>
1669  <span class="identifier">h</span><span class="special">(</span><span class="string">"4"</span><span class="special">);</span>
1670  <span class="identifier">h</span><span class="special">(</span><span class="string">"9"</span><span class="special">);</span>
1671
1672  <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os</span><span class="special">;</span>
1673  <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&amp;&amp;</span> <span class="identifier">b</span> <span class="special">:</span> <span class="identifier">indexed</span><span class="special">(</span><span class="identifier">h</span><span class="special">))</span> <span class="special">{</span>
1674    <span class="identifier">os</span> <span class="special">&lt;&lt;</span> <span class="string">"bin "</span> <span class="special">&lt;&lt;</span> <span class="identifier">b</span><span class="special">.</span><span class="identifier">index</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">" ["</span> <span class="special">&lt;&lt;</span> <span class="identifier">b</span><span class="special">.</span><span class="identifier">bin</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">"] "</span> <span class="special">&lt;&lt;</span> <span class="special">*</span><span class="identifier">b</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
1675  <span class="special">}</span>
1676
1677  <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
1678
1679  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span> <span class="string">"bin 0 [3] 1\n"</span>
1680                     <span class="string">"bin 1 [4] 1\n"</span>
1681                     <span class="string">"bin 2 [5] 0\n"</span><span class="special">);</span>
1682<span class="special">}</span>
1683</pre>
1684<p>
1685          How to make an axis completely from scratch is shown in the next example.
1686        </p>
1687<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
1688<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
1689
1690<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
1691  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>
1692
1693  <span class="comment">// stateless axis which returns 1 if the input is even and 0 otherwise</span>
1694  <span class="keyword">struct</span> <span class="identifier">even_odd_axis</span> <span class="special">{</span>
1695    <span class="identifier">axis</span><span class="special">::</span><span class="identifier">index_type</span> <span class="identifier">index</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">x</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">x</span> <span class="special">%</span> <span class="number">2</span><span class="special">;</span> <span class="special">}</span>
1696    <span class="identifier">axis</span><span class="special">::</span><span class="identifier">index_type</span> <span class="identifier">size</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span> <span class="keyword">return</span> <span class="number">2</span><span class="special">;</span> <span class="special">}</span>
1697  <span class="special">};</span>
1698
1699  <span class="comment">// threshold axis which returns 1 if the input is above threshold</span>
1700  <span class="keyword">struct</span> <span class="identifier">threshold_axis</span> <span class="special">{</span>
1701    <span class="identifier">threshold_axis</span><span class="special">(</span><span class="keyword">double</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">thr</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span> <span class="special">{}</span>
1702    <span class="identifier">axis</span><span class="special">::</span><span class="identifier">index_type</span> <span class="identifier">index</span><span class="special">(</span><span class="keyword">double</span> <span class="identifier">x</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">x</span> <span class="special">&gt;=</span> <span class="identifier">thr</span><span class="special">;</span> <span class="special">}</span>
1703    <span class="identifier">axis</span><span class="special">::</span><span class="identifier">index_type</span> <span class="identifier">size</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span> <span class="keyword">return</span> <span class="number">2</span><span class="special">;</span> <span class="special">}</span>
1704    <span class="keyword">double</span> <span class="identifier">thr</span><span class="special">;</span>
1705  <span class="special">};</span>
1706
1707  <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">even_odd_axis</span><span class="special">(),</span> <span class="identifier">threshold_axis</span><span class="special">(</span><span class="number">3.0</span><span class="special">));</span>
1708
1709  <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">2.0</span><span class="special">);</span>
1710  <span class="identifier">h</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">4.0</span><span class="special">);</span>
1711  <span class="identifier">h</span><span class="special">(</span><span class="number">2</span><span class="special">,</span> <span class="number">4.0</span><span class="special">);</span>
1712
1713  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span> <span class="comment">// even, below threshold</span>
1714  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span> <span class="comment">// even, above threshold</span>
1715  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span> <span class="comment">// odd, below threshold</span>
1716  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span> <span class="comment">// odd, above threshold</span>
1717<span class="special">}</span>
1718</pre>
1719<p>
1720          Such minimal axis types lack many features provided by the builtin axis
1721          types, for example, one cannot iterate over them, but this functionality
1722          can be added as needed.
1723        </p>
1724</div>
1725<div class="section">
1726<div class="titlepage"><div><div><h4 class="title">
1727<a name="histogram.guide.expert.axis_with_several_arguments"></a><a class="link" href="guide.html#histogram.guide.expert.axis_with_several_arguments" title="Axis with several arguments">Axis
1728        with several arguments</a>
1729</h4></div></div></div>
1730<p>
1731          Multi-dimensional histograms usually have an orthogonal system of axes.
1732          Orthogonal means that each axis takes care of only one value and computes
1733          its local index independently of all the other axes and values. A checker-board
1734          is such an orthogonal grid in 2D.
1735        </p>
1736<p>
1737          There are other interesting grids which are not orthogonal, notably the
1738          honeycomb grid. In such a grid, each cell is hexagonal and even though
1739          the cells form a perfectly regular pattern, it is not possible to sort
1740          values into these cells using two orthogonal axes.
1741        </p>
1742<p>
1743          The library supports non-orthogonal grids by allowing axis types to accept
1744          a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span></code> of values. The axis can compute
1745          an index from the values passed to it in an arbitrary way. The following
1746          example demonstrates this.
1747        </p>
1748<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
1749<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
1750
1751<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
1752  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>
1753
1754  <span class="comment">// axis which returns 1 if the input falls inside the unit circle and zero otherwise</span>
1755  <span class="keyword">struct</span> <span class="identifier">circle_axis</span> <span class="special">{</span>
1756    <span class="comment">// accepts a 2D point in form of a std::tuple</span>
1757    <span class="identifier">axis</span><span class="special">::</span><span class="identifier">index_type</span> <span class="identifier">index</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">,</span> <span class="keyword">double</span><span class="special">&gt;&amp;</span> <span class="identifier">point</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">{</span>
1758      <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">get</span><span class="special">&lt;</span><span class="number">0</span><span class="special">&gt;(</span><span class="identifier">point</span><span class="special">);</span>
1759      <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">y</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">get</span><span class="special">&lt;</span><span class="number">1</span><span class="special">&gt;(</span><span class="identifier">point</span><span class="special">);</span>
1760      <span class="keyword">return</span> <span class="identifier">x</span> <span class="special">*</span> <span class="identifier">x</span> <span class="special">+</span> <span class="identifier">y</span> <span class="special">*</span> <span class="identifier">y</span> <span class="special">&lt;=</span> <span class="number">1.0</span><span class="special">;</span>
1761    <span class="special">}</span>
1762
1763    <span class="identifier">axis</span><span class="special">::</span><span class="identifier">index_type</span> <span class="identifier">size</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span> <span class="keyword">return</span> <span class="number">2</span><span class="special">;</span> <span class="special">}</span>
1764  <span class="special">};</span>
1765
1766  <span class="keyword">auto</span> <span class="identifier">h1</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">circle_axis</span><span class="special">());</span>
1767
1768  <span class="comment">// fill looks normal for a histogram which has only one Nd-axis</span>
1769  <span class="identifier">h1</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">0</span><span class="special">);</span>   <span class="comment">// in</span>
1770  <span class="identifier">h1</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="special">-</span><span class="number">1</span><span class="special">);</span>  <span class="comment">// in</span>
1771  <span class="identifier">h1</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">1</span><span class="special">);</span>   <span class="comment">// in</span>
1772  <span class="identifier">h1</span><span class="special">(-</span><span class="number">1</span><span class="special">,</span> <span class="number">0</span><span class="special">);</span>  <span class="comment">// in</span>
1773  <span class="identifier">h1</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">0</span><span class="special">);</span>   <span class="comment">// in</span>
1774  <span class="identifier">h1</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">1</span><span class="special">);</span>   <span class="comment">// out</span>
1775  <span class="identifier">h1</span><span class="special">(-</span><span class="number">1</span><span class="special">,</span> <span class="special">-</span><span class="number">1</span><span class="special">);</span> <span class="comment">// out</span>
1776
1777  <span class="comment">// 2D histogram, but only 1D index</span>
1778  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span> <span class="comment">// out</span>
1779  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">5</span><span class="special">);</span> <span class="comment">// in</span>
1780
1781  <span class="comment">// other axes can be combined with a Nd-axis</span>
1782  <span class="keyword">auto</span> <span class="identifier">h2</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">circle_axis</span><span class="special">(),</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">category</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;({</span><span class="string">"red"</span><span class="special">,</span> <span class="string">"blue"</span><span class="special">}));</span>
1783
1784  <span class="comment">// now we need to pass arguments for Nd-axis explicitly as std::tuple</span>
1785  <span class="identifier">h2</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">make_tuple</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">0</span><span class="special">),</span> <span class="string">"red"</span><span class="special">);</span>
1786  <span class="identifier">h2</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">make_tuple</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">1</span><span class="special">),</span> <span class="string">"blue"</span><span class="special">);</span>
1787
1788  <span class="comment">// 3D histogram, but only 2D index</span>
1789  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span> <span class="comment">// out, red</span>
1790  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span> <span class="comment">// out, blue</span>
1791  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span> <span class="comment">// in, red</span>
1792  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span> <span class="comment">// in, blue</span>
1793<span class="special">}</span>
1794</pre>
1795</div>
1796<div class="section">
1797<div class="titlepage"><div><div><h4 class="title">
1798<a name="histogram.guide.expert.user_defined_storage_class"></a><a class="link" href="guide.html#histogram.guide.expert.user_defined_storage_class" title="User-defined storage class">User-defined
1799        storage class</a>
1800</h4></div></div></div>
1801<p>
1802          Histograms which use a different storage class can easily created with
1803          the factory function <code class="computeroutput"><a class="link" href="reference.html#header.boost.histogram.make_histogram_hpp" title="Header &lt;boost/histogram/make_histogram.hpp&gt;">make_histogram_with</a></code>.
1804          For convenience, this factory function accepts many standard containers
1805          as storage backends: vectors, arrays, and maps. These are automatically
1806          wrapped with a <code class="computeroutput"><a class="link" href="../boost/histogram/storage_adaptor.html" title="Class template storage_adaptor">boost::histogram::storage_adaptor</a></code>
1807          to provide the storage interface needed by the library. Users may also
1808          place custom accumulators in the vector, as described in the next section.
1809        </p>
1810<div class="warning"><table border="0" summary="Warning">
1811<tr>
1812<td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="../../../../../doc/src/images/warning.png"></td>
1813<th align="left">Warning</th>
1814</tr>
1815<tr><td align="left" valign="top"><p>
1816            The no-overflow-guarantee is only valid if the <code class="computeroutput"><a class="link" href="../boost/histogram/unlimited_storage.html" title="Class template unlimited_storage">unlimited_storage</a></code>
1817            (the default) is used. If you change the storage policy, you need to
1818            know what you are doing.
1819          </p></td></tr>
1820</table></div>
1821<p>
1822          A <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span></code> may provide higher performance
1823          than the <code class="computeroutput"><a class="link" href="../boost/histogram/unlimited_storage.html" title="Class template unlimited_storage">unlimited_storage</a></code>
1824          with a carefully chosen counter type. Usually, this would be an integral
1825          or floating point type. A <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span></code>-based
1826          storage may be faster for low-dimensional histograms (or not, you need
1827          to measure).
1828        </p>
1829<p>
1830          Users who work exclusively with weighted histograms should chose a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span></code>,
1831          it will be faster. If they also want to track the variance of the sum of
1832          weights, a vector-based storage of <code class="computeroutput"><a class="link" href="../boost/histogram/accumulators/weighted_sum.html" title="Class template weighted_sum">weighted_sum</a></code>
1833          accumulators should be used. The factory function <code class="computeroutput"><a class="link" href="../boost/histogram/make_wei_idm45503931624016.html" title="Function template make_weighted_histogram">make_weighted_histogram</a></code>
1834          is a convenient way to generate a histogram with this storage.
1835        </p>
1836<p>
1837          An interesting alternative to a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span></code>
1838          is to use a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span></code>. The latter provides a storage
1839          with a fixed maximum capacity (the size of the array). <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span></code>
1840          allocates the memory on the stack. In combination with a static axis configuration
1841          this allows one to create histograms completely on the stack without any
1842          dynamic memory allocation. Small stack-based histograms can be created
1843          and destroyed very fast.
1844        </p>
1845<p>
1846          Finally, a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span></code> or <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">unordered_map</span></code>
1847          or any other map type that implements the STL interface can be used to
1848          generate a histogram with a sparse storage, where empty cells do not consume
1849          any memory. This sounds attractive, but the memory consumption per cell
1850          in such a data structure is much larger than for a vector or array, so
1851          the number of empty cells must be substantial to gain. Moreover, cell lookup
1852          in a sparse data structure may be less performant. Whether a sparse storage
1853          performs better than a dense storage depends on the use case. The library
1854          makes it easy to switch from dense to sparse storage and back, so users
1855          are invited to test both options.
1856        </p>
1857<p>
1858          The following example shows how histograms are constructed which use an
1859          alternative storage classes.
1860        </p>
1861<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">algorithm</span><span class="special">&gt;</span> <span class="comment">// std::for_each</span>
1862<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">array</span><span class="special">&gt;</span>
1863<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
1864<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">/</span><span class="identifier">algorithm</span><span class="special">/</span><span class="identifier">sum</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
1865<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">functional</span><span class="special">&gt;</span> <span class="comment">// std::ref</span>
1866<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">unordered_map</span><span class="special">&gt;</span>
1867<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">vector</span><span class="special">&gt;</span>
1868
1869<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
1870  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>
1871  <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">axis</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">10</span><span class="special">,</span> <span class="number">0.0</span><span class="special">,</span> <span class="number">1.0</span><span class="special">);</span>
1872
1873  <span class="keyword">auto</span> <span class="identifier">data</span> <span class="special">=</span> <span class="special">{</span><span class="number">0.1</span><span class="special">,</span> <span class="number">0.3</span><span class="special">,</span> <span class="number">0.2</span><span class="special">,</span> <span class="number">0.7</span><span class="special">};</span>
1874
1875  <span class="comment">// Create static histogram with vector&lt;int&gt; as counter storage, you can use</span>
1876  <span class="comment">// other arithmetic types as counters, e.g. double.</span>
1877  <span class="keyword">auto</span> <span class="identifier">h1</span> <span class="special">=</span> <span class="identifier">make_histogram_with</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(),</span> <span class="identifier">axis</span><span class="special">);</span>
1878  <span class="identifier">std</span><span class="special">::</span><span class="identifier">for_each</span><span class="special">(</span><span class="identifier">data</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">data</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ref</span><span class="special">(</span><span class="identifier">h1</span><span class="special">));</span>
1879  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">sum</span><span class="special">(</span><span class="identifier">h1</span><span class="special">)</span> <span class="special">==</span> <span class="number">4</span><span class="special">);</span>
1880
1881  <span class="comment">// Create static histogram with array&lt;int, N&gt; as counter storage which is</span>
1882  <span class="comment">// allocated completely on the stack (this is very fast). N may be larger than</span>
1883  <span class="comment">// the actual number of bins used; an exception is raised if N is too small to</span>
1884  <span class="comment">// hold all bins.</span>
1885  <span class="keyword">auto</span> <span class="identifier">h2</span> <span class="special">=</span> <span class="identifier">make_histogram_with</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="number">12</span><span class="special">&gt;(),</span> <span class="identifier">axis</span><span class="special">);</span>
1886  <span class="identifier">std</span><span class="special">::</span><span class="identifier">for_each</span><span class="special">(</span><span class="identifier">data</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">data</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ref</span><span class="special">(</span><span class="identifier">h2</span><span class="special">));</span>
1887  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">sum</span><span class="special">(</span><span class="identifier">h2</span><span class="special">)</span> <span class="special">==</span> <span class="number">4</span><span class="special">);</span>
1888
1889  <span class="comment">// Create static histogram with unordered_map as counter storage; this</span>
1890  <span class="comment">// generates a sparse histogram where only memory is allocated for bins that</span>
1891  <span class="comment">// are non-zero. This sounds like a good idea for high-dimensional histograms,</span>
1892  <span class="comment">// but maps come with a memory and run-time overhead. The default_storage</span>
1893  <span class="comment">// usually performs better in high dimensions.</span>
1894  <span class="keyword">auto</span> <span class="identifier">h3</span> <span class="special">=</span> <span class="identifier">make_histogram_with</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">unordered_map</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span><span class="special">,</span> <span class="keyword">int</span><span class="special">&gt;(),</span> <span class="identifier">axis</span><span class="special">);</span>
1895  <span class="identifier">std</span><span class="special">::</span><span class="identifier">for_each</span><span class="special">(</span><span class="identifier">data</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">data</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ref</span><span class="special">(</span><span class="identifier">h3</span><span class="special">));</span>
1896  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">sum</span><span class="special">(</span><span class="identifier">h3</span><span class="special">)</span> <span class="special">==</span> <span class="number">4</span><span class="special">);</span>
1897<span class="special">}</span>
1898</pre>
1899</div>
1900<div class="section">
1901<div class="titlepage"><div><div><h4 class="title">
1902<a name="histogram.guide.expert.parallelisation_options"></a><a class="link" href="guide.html#histogram.guide.expert.parallelisation_options" title="Parallelisation options">Parallelisation
1903        options</a>
1904</h4></div></div></div>
1905<p>
1906          There are two ways to generate a single histogram using several threads.
1907        </p>
1908<p>
1909          1. Each thread has its own copy of the histogram. Each copy is independently
1910          filled. The copies are then added in the main thread. Use this as the default
1911          when you can afford having <code class="computeroutput"><span class="identifier">N</span></code>
1912          copies of the histogram in memory for <code class="computeroutput"><span class="identifier">N</span></code>
1913          threads, because it allows each thread to work on its thread-local memory
1914          and utilise the CPU cache without the need to synchronise memory access.
1915          The highest performance gains are obtained in this way.
1916        </p>
1917<p>
1918          2. There is only one histogram which is filled concurrently by several
1919          threads. This requires using a thread-safe storage that can handle concurrent
1920          writes. The library provides the <code class="computeroutput"><a class="link" href="../boost/histogram/accumulators/thread_safe.html" title="Class template thread_safe">boost::histogram::accumulators::thread_safe</a></code>
1921          accumulator, which combined with the <code class="computeroutput"><a class="link" href="reference.html#boost.histogram.dense_storage">boost::histogram::dense_storage</a></code>
1922          provides a thread-safe storage.
1923        </p>
1924<div class="note"><table border="0" summary="Note">
1925<tr>
1926<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
1927<th align="left">Note</th>
1928</tr>
1929<tr><td align="left" valign="top"><p>
1930            Filling a histogram with growing axes in a multi-threaded environment
1931            is safe, but has poor performance since the histogram must be locked
1932            on each fill. The locks are required because an axis could grow each
1933            time, which changes the number of cells and cell addressing for all other
1934            threads. Even without growing axes, there is only a performance gain
1935            if the histogram is either very large or when significant time is spend
1936            in preparing the value to fill. For small histograms, threads frequently
1937            access the same cell, whose state has to be synchronised between the
1938            threads. This is slow even with atomic counters and made worse by the
1939            effect of false sharing.
1940          </p></td></tr>
1941</table></div>
1942<p>
1943          The next example demonstrates option 2 (option 1 is straight-forward to
1944          implement).
1945        </p>
1946<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
1947<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">/</span><span class="identifier">algorithm</span><span class="special">/</span><span class="identifier">sum</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
1948<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
1949<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">functional</span><span class="special">&gt;</span>
1950<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">thread</span><span class="special">&gt;</span>
1951<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">vector</span><span class="special">&gt;</span>
1952
1953<span class="comment">// dummy fill function, to be executed in parallel by several threads</span>
1954<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Histogram</span><span class="special">&gt;</span>
1955<span class="keyword">void</span> <span class="identifier">fill</span><span class="special">(</span><span class="identifier">Histogram</span><span class="special">&amp;</span> <span class="identifier">h</span><span class="special">)</span> <span class="special">{</span>
1956  <span class="keyword">for</span> <span class="special">(</span><span class="keyword">unsigned</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special">&lt;</span> <span class="number">1000</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span> <span class="special">{</span> <span class="identifier">h</span><span class="special">(</span><span class="identifier">i</span> <span class="special">%</span> <span class="number">10</span><span class="special">);</span> <span class="special">}</span>
1957<span class="special">}</span>
1958
1959<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
1960  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>
1961
1962  <span class="comment">/*
1963    Create histogram with container of thread-safe counters for parallel filling in
1964    several threads. Only filling is thread-safe, other guarantees are not given.
1965  */</span>
1966  <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram_with</span><span class="special">(</span><span class="identifier">dense_storage</span><span class="special">&lt;</span><span class="identifier">accumulators</span><span class="special">::</span><span class="identifier">thread_safe</span><span class="special">&lt;</span><span class="keyword">unsigned</span><span class="special">&gt;&gt;(),</span>
1967                               <span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;&gt;(</span><span class="number">0</span><span class="special">,</span> <span class="number">10</span><span class="special">));</span>
1968
1969  <span class="comment">/*
1970    Run the fill function in parallel from different threads. This is safe when a
1971    thread-safe accumulator and a storage with thread-safe cell access are used.
1972  */</span>
1973  <span class="keyword">auto</span> <span class="identifier">fill_h</span> <span class="special">=</span> <span class="special">[&amp;</span><span class="identifier">h</span><span class="special">]()</span> <span class="special">{</span> <span class="identifier">fill</span><span class="special">(</span><span class="identifier">h</span><span class="special">);</span> <span class="special">};</span>
1974  <span class="identifier">std</span><span class="special">::</span><span class="identifier">thread</span> <span class="identifier">t1</span><span class="special">(</span><span class="identifier">fill_h</span><span class="special">);</span>
1975  <span class="identifier">std</span><span class="special">::</span><span class="identifier">thread</span> <span class="identifier">t2</span><span class="special">(</span><span class="identifier">fill_h</span><span class="special">);</span>
1976  <span class="identifier">std</span><span class="special">::</span><span class="identifier">thread</span> <span class="identifier">t3</span><span class="special">(</span><span class="identifier">fill_h</span><span class="special">);</span>
1977  <span class="identifier">std</span><span class="special">::</span><span class="identifier">thread</span> <span class="identifier">t4</span><span class="special">(</span><span class="identifier">fill_h</span><span class="special">);</span>
1978  <span class="identifier">t1</span><span class="special">.</span><span class="identifier">join</span><span class="special">();</span>
1979  <span class="identifier">t2</span><span class="special">.</span><span class="identifier">join</span><span class="special">();</span>
1980  <span class="identifier">t3</span><span class="special">.</span><span class="identifier">join</span><span class="special">();</span>
1981  <span class="identifier">t4</span><span class="special">.</span><span class="identifier">join</span><span class="special">();</span>
1982
1983  <span class="comment">// Without a thread-safe accumulator, this number may be smaller.</span>
1984  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">sum</span><span class="special">(</span><span class="identifier">h</span><span class="special">)</span> <span class="special">==</span> <span class="number">4000</span><span class="special">);</span>
1985<span class="special">}</span>
1986</pre>
1987</div>
1988<div class="section">
1989<div class="titlepage"><div><div><h4 class="title">
1990<a name="histogram.guide.expert.user_defined_accumulators"></a><a class="link" href="guide.html#histogram.guide.expert.user_defined_accumulators" title="User-defined accumulators">User-defined
1991        accumulators</a>
1992</h4></div></div></div>
1993<p>
1994          A storage can hold custom accumulators which can accept an arbitrary number
1995          of arguments. The arguments are passed to the accumulator via the <code class="computeroutput"><a class="link" href="../boost/histogram/sample.html" title="Function template sample">sample</a></code> call, for example,
1996          <code class="computeroutput"><span class="identifier">sample</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="number">3</span><span class="special">)</span></code>
1997          for an accumulator which accepts three arguments. Custom accumulators can
1998          be combined with any container supported by <code class="computeroutput"><a class="link" href="../boost/histogram/storage_adaptor.html" title="Class template storage_adaptor">boost::histogram::storage_adaptor</a></code>.
1999          For convenience, the alias template <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">dense_storage</span></code>
2000          is provided to make a standard storage with a custom accumulator type.
2001        </p>
2002<p>
2003          The library provides several accumulators:
2004        </p>
2005<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
2006<li class="listitem">
2007              <code class="computeroutput"><a class="link" href="../boost/histogram/accumulators/sum.html" title="Class template sum">sum</a></code>
2008              accepts no samples, but accepts a weight. It is an alternative to a
2009              plain arithmetic type as a counter. It provides an advantage when histograms
2010              are filled with weights that differ dramatically in magnitude. The
2011              sum of weights is computed incrementally with the Neumaier algorithm.
2012              The algorithm is more accurate, but consumes more CPU and memory (memory
2013              is doubled compared to a normal sum of floating point numbers).
2014            </li>
2015<li class="listitem">
2016              <code class="computeroutput"><a class="link" href="../boost/histogram/accumulators/weighted_sum.html" title="Class template weighted_sum">weighted_sum</a></code>
2017              accepts no samples, but accepts a weight. It computes the sum of weights
2018              and the sum of weights squared, the variance estimate of the sum of
2019              weights. This type is used by the <code class="computeroutput"><a class="link" href="../boost/histogram/make_wei_idm45503931624016.html" title="Function template make_weighted_histogram">make_weighted_histogram</a></code>.
2020            </li>
2021<li class="listitem">
2022              <code class="computeroutput"><a class="link" href="../boost/histogram/accumulators/mean.html" title="Class template mean">mean</a></code>
2023              accepts a sample and computes the mean of the samples. <code class="computeroutput"><a class="link" href="../boost/histogram/make_pro_idm45503931608944.html" title="Function template make_profile">make_profile</a></code> uses
2024              this accumulator.
2025            </li>
2026<li class="listitem">
2027              <code class="computeroutput"><a class="link" href="../boost/histogram/accumulators/weighted_mean.html" title="Class template weighted_mean">weighted_mean</a></code>
2028              accepts a sample and a weight. It computes the weighted mean of the
2029              samples. <code class="computeroutput"><a class="link" href="../boost/histogram/make_wei_idm45503931596384.html" title="Function template make_weighted_profile">make_weighted_profile</a></code>
2030              uses this accumulator.
2031            </li>
2032</ul></div>
2033<p>
2034          Users can easily write their own accumulators and plug them into the histogram,
2035          if they adhere to the <a class="link" href="concepts.html#histogram.concepts.Accumulator" title="Accumulator"><span class="bold"><strong>Accumulator</strong></span> concept</a>. All accumulators from
2036          <a href="../../../../../libs/accumulators/index.html" target="_top">Boost.Accumulators</a>
2037          that accept a single argument and no weights work out of the box. Other
2038          accumulators from Boost.Accumulators can be made to work by using them
2039          inside a wrapper class that implements the concept.
2040        </p>
2041<p>
2042          The first example shows how to make and use a histogram that uses one of
2043          the the builtin accumulators.
2044        </p>
2045<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">format</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
2046<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
2047<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
2048<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
2049<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">sstream</span><span class="special">&gt;</span>
2050
2051<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
2052  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>
2053  <span class="keyword">using</span> <span class="identifier">mean</span> <span class="special">=</span> <span class="identifier">accumulators</span><span class="special">::</span><span class="identifier">mean</span><span class="special">&lt;&gt;;</span>
2054
2055  <span class="comment">// Create a 1D-profile, which computes the mean of samples in each bin.</span>
2056  <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram_with</span><span class="special">(</span><span class="identifier">dense_storage</span><span class="special">&lt;</span><span class="identifier">mean</span><span class="special">&gt;(),</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;&gt;(</span><span class="number">0</span><span class="special">,</span> <span class="number">2</span><span class="special">));</span>
2057  <span class="comment">// The factory function `make_profile` is provided as a shorthand for this, so this is</span>
2058  <span class="comment">// equivalent to the previous line: auto h = make_profile(axis::integer&lt;&gt;(0, 2));</span>
2059
2060  <span class="comment">// An argument marked as `sample` is passed to the accumulator.</span>
2061  <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">1</span><span class="special">));</span> <span class="comment">// sample goes to first cell</span>
2062  <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">2</span><span class="special">));</span> <span class="comment">// sample goes to first cell</span>
2063  <span class="identifier">h</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">3</span><span class="special">));</span> <span class="comment">// sample goes to second cell</span>
2064  <span class="identifier">h</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">4</span><span class="special">));</span> <span class="comment">// sample goes to second cell</span>
2065
2066  <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os</span><span class="special">;</span>
2067  <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&amp;&amp;</span> <span class="identifier">x</span> <span class="special">:</span> <span class="identifier">indexed</span><span class="special">(</span><span class="identifier">h</span><span class="special">))</span> <span class="special">{</span>
2068    <span class="comment">// Accumulators usually have methods to access their state. Use the arrow</span>
2069    <span class="comment">// operator to access them. Here, `count()` gives the number of samples,</span>
2070    <span class="comment">// `value()` the mean, and `variance()` the variance estimate of the mean.</span>
2071    <span class="identifier">os</span> <span class="special">&lt;&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">format</span><span class="special">(</span><span class="string">"index %i count %i mean %.1f variance %.1f\n"</span><span class="special">)</span> <span class="special">%</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">index</span><span class="special">()</span> <span class="special">%</span>
2072              <span class="identifier">x</span><span class="special">-&gt;</span><span class="identifier">count</span><span class="special">()</span> <span class="special">%</span> <span class="identifier">x</span><span class="special">-&gt;</span><span class="identifier">value</span><span class="special">()</span> <span class="special">%</span> <span class="identifier">x</span><span class="special">-&gt;</span><span class="identifier">variance</span><span class="special">();</span>
2073  <span class="special">}</span>
2074  <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">flush</span><span class="special">;</span>
2075  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span> <span class="string">"index 0 count 2 mean 1.5 variance 0.5\n"</span>
2076                     <span class="string">"index 1 count 2 mean 3.5 variance 0.5\n"</span><span class="special">);</span>
2077<span class="special">}</span>
2078</pre>
2079<p>
2080          The simplest way to make a custom accumulator is to inherit from one of
2081          the builtin accumulators. The following example shows how to add arbitrary
2082          metadata to each histogram cell by inheriting a custom accumulator from
2083          a builtin accumulator.
2084        </p>
2085<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
2086<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cmath</span><span class="special">&gt;</span>
2087<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
2088<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">sstream</span><span class="special">&gt;</span>
2089<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">string</span><span class="special">&gt;</span>
2090
2091<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
2092  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>
2093
2094  <span class="comment">// derive custom accumulator from one of the builtins</span>
2095  <span class="keyword">struct</span> <span class="identifier">accumulator_with_metadata</span> <span class="special">:</span> <span class="identifier">accumulators</span><span class="special">::</span><span class="identifier">count</span><span class="special">&lt;&gt;</span> <span class="special">{</span>
2096    <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">meta</span><span class="special">;</span> <span class="comment">// custom meta data</span>
2097
2098    <span class="comment">// arbitrary additional data and interface could be added here</span>
2099  <span class="special">};</span>
2100
2101  <span class="comment">// make 1D histogram with custom accmulator</span>
2102  <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram_with</span><span class="special">(</span><span class="identifier">dense_storage</span><span class="special">&lt;</span><span class="identifier">accumulator_with_metadata</span><span class="special">&gt;(),</span>
2103                               <span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;&gt;(</span><span class="number">1</span><span class="special">,</span> <span class="number">4</span><span class="special">));</span>
2104
2105  <span class="comment">// fill some weighted entries</span>
2106  <span class="keyword">auto</span> <span class="identifier">x</span> <span class="special">=</span> <span class="special">{</span><span class="number">1</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="number">1</span><span class="special">};</span>
2107  <span class="identifier">h</span><span class="special">.</span><span class="identifier">fill</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span>
2108
2109  <span class="comment">// assigning meta data to two bins</span>
2110  <span class="identifier">h</span><span class="special">[</span><span class="number">0</span><span class="special">].</span><span class="identifier">meta</span> <span class="special">=</span> <span class="string">"Foo"</span><span class="special">;</span>
2111  <span class="identifier">h</span><span class="special">[</span><span class="number">2</span><span class="special">].</span><span class="identifier">meta</span> <span class="special">=</span> <span class="string">"Bar"</span><span class="special">;</span>
2112
2113  <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os</span><span class="special">;</span>
2114  <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&amp;&amp;</span> <span class="identifier">x</span> <span class="special">:</span> <span class="identifier">indexed</span><span class="special">(</span><span class="identifier">h</span><span class="special">))</span>
2115    <span class="identifier">os</span> <span class="special">&lt;&lt;</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">bin</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">" value "</span> <span class="special">&lt;&lt;</span> <span class="identifier">x</span><span class="special">-&gt;</span><span class="identifier">value</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">" meta "</span> <span class="special">&lt;&lt;</span> <span class="identifier">x</span><span class="special">-&gt;</span><span class="identifier">meta</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
2116
2117  <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">flush</span><span class="special">;</span>
2118  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span> <span class="string">"1 value 2 meta Foo\n"</span>
2119                     <span class="string">"2 value 1 meta \n"</span>
2120                     <span class="string">"3 value 0 meta Bar\n"</span><span class="special">);</span>
2121<span class="special">}</span>
2122</pre>
2123<p>
2124          The next example shows how to making a custom accumulators completely from
2125          scratch. The library was designed to make this as easy as possible.
2126        </p>
2127<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">format</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
2128<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
2129<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
2130<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
2131<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">sstream</span><span class="special">&gt;</span>
2132
2133<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
2134  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>
2135
2136  <span class="comment">// A custom accumulator which tracks the maximum of the samples.</span>
2137  <span class="comment">// It must have a call operator that accepts the argument of the `sample` function.</span>
2138  <span class="keyword">struct</span> <span class="identifier">maximum</span> <span class="special">{</span>
2139    <span class="comment">// return value is ignored, so we use void</span>
2140    <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">double</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span>
2141      <span class="keyword">if</span> <span class="special">(</span><span class="identifier">x</span> <span class="special">&gt;</span> <span class="identifier">value</span><span class="special">)</span> <span class="identifier">value</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">;</span>
2142    <span class="special">}</span>
2143    <span class="keyword">double</span> <span class="identifier">value</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="comment">// value is public and initialized to zero</span>
2144  <span class="special">};</span>
2145
2146  <span class="comment">// Create 1D histogram that uses the custom accumulator.</span>
2147  <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram_with</span><span class="special">(</span><span class="identifier">dense_storage</span><span class="special">&lt;</span><span class="identifier">maximum</span><span class="special">&gt;(),</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;&gt;(</span><span class="number">0</span><span class="special">,</span> <span class="number">2</span><span class="special">));</span>
2148  <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">1.0</span><span class="special">));</span> <span class="comment">// sample goes to first cell</span>
2149  <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">2.0</span><span class="special">));</span> <span class="comment">// sample goes to first cell</span>
2150  <span class="identifier">h</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">3.0</span><span class="special">));</span> <span class="comment">// sample goes to second cell</span>
2151  <span class="identifier">h</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">4.0</span><span class="special">));</span> <span class="comment">// sample goes to second cell</span>
2152
2153  <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os</span><span class="special">;</span>
2154  <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&amp;&amp;</span> <span class="identifier">x</span> <span class="special">:</span> <span class="identifier">indexed</span><span class="special">(</span><span class="identifier">h</span><span class="special">))</span> <span class="special">{</span>
2155    <span class="identifier">os</span> <span class="special">&lt;&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">format</span><span class="special">(</span><span class="string">"index %i maximum %.1f\n"</span><span class="special">)</span> <span class="special">%</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">index</span><span class="special">()</span> <span class="special">%</span> <span class="identifier">x</span><span class="special">-&gt;</span><span class="identifier">value</span><span class="special">;</span>
2156  <span class="special">}</span>
2157  <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">flush</span><span class="special">;</span>
2158  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span> <span class="string">"index 0 maximum 2.0\n"</span>
2159                     <span class="string">"index 1 maximum 4.0\n"</span><span class="special">);</span>
2160<span class="special">}</span>
2161</pre>
2162<p>
2163          The next example shows a more complex custom accumulator that accepts two
2164          samples at once and an optional weight. It independently computes the mean
2165          for each sample. This is more efficient than filling two separate profiles,
2166          because the cell lookup has to be done only once.
2167        </p>
2168<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">format</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
2169<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
2170<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
2171<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">sstream</span><span class="special">&gt;</span>
2172
2173<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
2174  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>
2175
2176  <span class="comment">// Accumulator accepts two samples and an optional weight and computes the mean of each.</span>
2177  <span class="keyword">struct</span> <span class="identifier">multi_mean</span> <span class="special">{</span>
2178    <span class="identifier">accumulators</span><span class="special">::</span><span class="identifier">mean</span><span class="special">&lt;&gt;</span> <span class="identifier">mx</span><span class="special">,</span> <span class="identifier">my</span><span class="special">;</span>
2179
2180    <span class="comment">// called when no weight is passed</span>
2181    <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">double</span> <span class="identifier">x</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">{</span>
2182      <span class="identifier">mx</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span>
2183      <span class="identifier">my</span><span class="special">(</span><span class="identifier">y</span><span class="special">);</span>
2184    <span class="special">}</span>
2185
2186    <span class="comment">// called when a weight is passed</span>
2187    <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">weight_type</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span> <span class="identifier">w</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">x</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">{</span>
2188      <span class="identifier">mx</span><span class="special">(</span><span class="identifier">w</span><span class="special">,</span> <span class="identifier">x</span><span class="special">);</span>
2189      <span class="identifier">my</span><span class="special">(</span><span class="identifier">w</span><span class="special">,</span> <span class="identifier">y</span><span class="special">);</span>
2190    <span class="special">}</span>
2191  <span class="special">};</span>
2192  <span class="comment">// Note: The implementation can be made more efficient by sharing the sum of weights.</span>
2193
2194  <span class="comment">// Create a 1D histogram that uses the custom accumulator.</span>
2195  <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram_with</span><span class="special">(</span><span class="identifier">dense_storage</span><span class="special">&lt;</span><span class="identifier">multi_mean</span><span class="special">&gt;(),</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;&gt;(</span><span class="number">0</span><span class="special">,</span> <span class="number">2</span><span class="special">));</span>
2196  <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">));</span>            <span class="comment">// samples go to first cell</span>
2197  <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">3</span><span class="special">,</span> <span class="number">4</span><span class="special">));</span>            <span class="comment">// samples go to first cell</span>
2198  <span class="identifier">h</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">5</span><span class="special">,</span> <span class="number">6</span><span class="special">),</span> <span class="identifier">weight</span><span class="special">(</span><span class="number">2</span><span class="special">));</span> <span class="comment">// samples go to second cell</span>
2199  <span class="identifier">h</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">7</span><span class="special">,</span> <span class="number">8</span><span class="special">),</span> <span class="identifier">weight</span><span class="special">(</span><span class="number">3</span><span class="special">));</span> <span class="comment">// samples go to second cell</span>
2200
2201  <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os</span><span class="special">;</span>
2202  <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&amp;&amp;</span> <span class="identifier">bin</span> <span class="special">:</span> <span class="identifier">indexed</span><span class="special">(</span><span class="identifier">h</span><span class="special">))</span> <span class="special">{</span>
2203    <span class="identifier">os</span> <span class="special">&lt;&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">format</span><span class="special">(</span><span class="string">"index %i mean-x %.1f mean-y %.1f\n"</span><span class="special">)</span> <span class="special">%</span> <span class="identifier">bin</span><span class="special">.</span><span class="identifier">index</span><span class="special">()</span> <span class="special">%</span>
2204              <span class="identifier">bin</span><span class="special">-&gt;</span><span class="identifier">mx</span><span class="special">.</span><span class="identifier">value</span><span class="special">()</span> <span class="special">%</span> <span class="identifier">bin</span><span class="special">-&gt;</span><span class="identifier">my</span><span class="special">.</span><span class="identifier">value</span><span class="special">();</span>
2205  <span class="special">}</span>
2206  <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">flush</span><span class="special">;</span>
2207  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span> <span class="string">"index 0 mean-x 2.0 mean-y 3.0\n"</span>
2208                     <span class="string">"index 1 mean-x 6.2 mean-y 7.2\n"</span><span class="special">);</span>
2209<span class="special">}</span>
2210</pre>
2211<p>
2212          And finally, just for fun, we use a histogram as the accumulator for another
2213          histogram.
2214        </p>
2215<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
2216<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cmath</span><span class="special">&gt;</span>
2217<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
2218<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">sstream</span><span class="special">&gt;</span>
2219<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">string</span><span class="special">&gt;</span>
2220
2221<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
2222  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>
2223
2224  <span class="comment">// First we define the nested histogram type.</span>
2225  <span class="keyword">using</span> <span class="identifier">axis_t</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">category</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">null_type</span><span class="special">,</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">option</span><span class="special">::</span><span class="identifier">growth_t</span><span class="special">&gt;;</span>
2226  <span class="keyword">using</span> <span class="identifier">base_t</span> <span class="special">=</span> <span class="identifier">histogram</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="identifier">axis_t</span><span class="special">&gt;&gt;;</span>
2227
2228  <span class="comment">// Now we make an accumulator out of it by using inheritance.</span>
2229  <span class="comment">// We only need to implement operator(). A matching version of operator() is actually</span>
2230  <span class="comment">// present in base_t, but it is templated and this is not allowed by the accumulator</span>
2231  <span class="comment">// concept. Initialization could also happen here. We don't need to initialize anything</span>
2232  <span class="comment">// here, because the default constructor of base_t is called automatically and</span>
2233  <span class="comment">// sufficient for this example.</span>
2234  <span class="keyword">struct</span> <span class="identifier">hist_t</span> <span class="special">:</span> <span class="identifier">base_t</span> <span class="special">{</span>
2235    <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">const</span> <span class="keyword">double</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span> <span class="identifier">base_t</span><span class="special">::</span><span class="keyword">operator</span><span class="special">()(</span><span class="identifier">x</span><span class="special">);</span> <span class="special">}</span>
2236  <span class="special">};</span>
2237
2238  <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram_with</span><span class="special">(</span><span class="identifier">dense_storage</span><span class="special">&lt;</span><span class="identifier">hist_t</span><span class="special">&gt;(),</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;&gt;(</span><span class="number">1</span><span class="special">,</span> <span class="number">4</span><span class="special">));</span>
2239
2240  <span class="keyword">auto</span> <span class="identifier">x</span> <span class="special">=</span> <span class="special">{</span><span class="number">1</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="number">2</span><span class="special">};</span>
2241  <span class="keyword">auto</span> <span class="identifier">s</span> <span class="special">=</span> <span class="special">{</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="number">3</span><span class="special">,</span> <span class="number">3</span><span class="special">};</span> <span class="comment">// samples are filled into the nested histograms</span>
2242  <span class="identifier">h</span><span class="special">.</span><span class="identifier">fill</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="identifier">s</span><span class="special">));</span>
2243
2244  <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os</span><span class="special">;</span>
2245  <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&amp;&amp;</span> <span class="identifier">x</span> <span class="special">:</span> <span class="identifier">indexed</span><span class="special">(</span><span class="identifier">h</span><span class="special">))</span> <span class="special">{</span>
2246    <span class="identifier">os</span> <span class="special">&lt;&lt;</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">bin</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">" "</span><span class="special">;</span>
2247    <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&amp;&amp;</span> <span class="identifier">y</span> <span class="special">:</span> <span class="identifier">indexed</span><span class="special">(*</span><span class="identifier">x</span><span class="special">))</span> <span class="special">{</span> <span class="identifier">os</span> <span class="special">&lt;&lt;</span> <span class="string">"("</span> <span class="special">&lt;&lt;</span> <span class="identifier">y</span><span class="special">.</span><span class="identifier">bin</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">": "</span> <span class="special">&lt;&lt;</span> <span class="special">*</span><span class="identifier">y</span> <span class="special">&lt;&lt;</span> <span class="string">") "</span><span class="special">;</span> <span class="special">}</span>
2248    <span class="identifier">os</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
2249  <span class="special">}</span>
2250
2251  <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">flush</span><span class="special">;</span>
2252  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span> <span class="string">"1 (1: 1) (2: 1) \n"</span>
2253                     <span class="string">"2 (3: 2) \n"</span>
2254                     <span class="string">"3 \n"</span><span class="special">);</span>
2255<span class="special">}</span>
2256</pre>
2257<p>
2258          Note that the axis size of the nested histogram differs from bin to bin.
2259          Creating a 2D histogram in this way is not as efficient as the normal way,
2260          but it allows one to create a histograms with such a non-rectangular layout
2261          of cells.
2262        </p>
2263</div>
2264</div>
2265</div>
2266<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
2267<td align="left"></td>
2268<td align="right"><div class="copyright-footer">Copyright © 2016-2019 Hans
2269      Dembinski<p>
2270        Distributed under the Boost Software License, Version 1.0. (See accompanying
2271        file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
2272      </p>
2273</div></td>
2274</tr></table>
2275<hr>
2276<div class="spirit-nav">
2277<a accesskey="p" href="getting_started.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="benchmarks.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
2278</div>
2279</body>
2280</html>
2281