3 <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
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">
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>
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>
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>
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>
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>
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>
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.expert">Advanced usage</a></span></dt>
53 <dt><span class="section"><a href="guide.html#histogram.guide.expert.user_defined_axes">User-defined
55 <dt><span class="section"><a href="guide.html#histogram.guide.expert.axis_with_several_arguments">Axis
56 with several arguments</a></span></dt>
57 <dt><span class="section"><a href="guide.html#histogram.guide.expert.user_defined_storage_class">User-defined
58 storage class</a></span></dt>
59 <dt><span class="section"><a href="guide.html#histogram.guide.expert.parallelization_options">Parallelization
60 options</a></span></dt>
61 <dt><span class="section"><a href="guide.html#histogram.guide.expert.user_defined_accumulators">User-defined
62 accumulators</a></span></dt>
66 Boost.Histogram is designed to make simple things simple, yet complex things
67 possible. Correspondingly, this guides covers the basic usage first, and the
68 advanced usage in later sections. For an alternative quick start guide, have
69 a look at the <a class="link" href="getting_started.html" title="Getting started">Getting started</a>
73 <div class="titlepage"><div><div><h3 class="title">
74 <a name="histogram.guide.making_histograms"></a><a class="link" href="guide.html#histogram.guide.making_histograms" title="Making histograms">Making histograms</a>
75 </h3></div></div></div>
77 A histogram consists of a collection of <a class="link" href="concepts.html#histogram.concepts.Axis" title="Axis">axis
78 objects</a> and a <a class="link" href="concepts.html#histogram.concepts.Storage" title="Storage">storage</a>.
79 The storage holds a collection of accumulators, one for each cell. The axis
80 objects maps input values to indices, which are combined into a global index
81 that is used to look up the cell in the storage.
84 To start off you do not have to worry about the storage, the library provides
85 a good default. Learning more about the many interesting axis types to choose
86 from, however, will pay off very quickly (which are discussed further below).
87 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>
88 axis. It represents equidistant intervals on the real line.
91 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 <boost/histogram/make_histogram.hpp>">make_histogram</a></code>.
92 The following example shows how to make a histogram with a single axis.
94 <pre class="programlisting"><span class="preprocessor">#include</span> <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">hpp</span><span class="special">></span>
95 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span>
97 <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
98 <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>
100 <span class="comment">// create a 1d-histogram in default configuration which</span>
101 <span class="comment">// covers the real line from -1 to 1 in 100 bins</span>
102 <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"><>(</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>
104 <span class="comment">// rank is the number of axes</span>
105 <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>
106 <span class="special">}</span>
109 An axis object defines how input values are mapped to bins, it is a mapping
110 functor of input values to indices. The axis object holds information such
111 as how many bins there are, where the bin edges are, metadata about the axis
112 and so on. The rank of a histogram is given by the number of axes. A histogram
113 with one axis is one-dimensional. If you provide two, it is two-dimensional,
117 In the example above, the compiler knows the number of axes and their type
118 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 <boost/histogram/make_histogram.hpp>">make_histogram</a></code>. This
119 gives the best performance, but sometimes you only know the axis configuration
120 at run-time, because it depends on information that's only available at run-time.
121 For that case you can also create axes at run-time and pass them to an overload
122 of the <code class="computeroutput"><a class="link" href="reference.html#header.boost.histogram.make_histogram_hpp" title="Header <boost/histogram/make_histogram.hpp>">make_histogram</a></code>
123 function. Here is an example.
125 <pre class="programlisting"><span class="preprocessor">#include</span> <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">hpp</span><span class="special">></span>
126 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span>
127 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">sstream</span><span class="special">></span>
128 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">vector</span><span class="special">></span>
130 <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>
131 <span class="string">"5 3.0 4.0\n"</span><span class="special">;</span>
133 <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
134 <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>
136 <span class="comment">// read axis config from a config file (mocked here with std::istringstream)</span>
137 <span class="comment">// and create vector of regular axes, the number of axis is not known at compile-time</span>
138 <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>
139 <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"><</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special"><>>();</span>
140 <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>
141 <span class="keyword">unsigned</span> <span class="identifier">bins</span><span class="special">;</span>
142 <span class="keyword">double</span> <span class="identifier">start</span><span class="special">,</span> <span class="identifier">stop</span><span class="special">;</span>
143 <span class="identifier">is</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>
144 <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>
145 <span class="special">}</span>
147 <span class="comment">// create histogram from iterator range</span>
148 <span class="comment">// (copying or moving the vector also works, move is shown below)</span>
149 <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>
150 <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>
152 <span class="comment">// with a vector of axis::variant (polymorphic axis type that can hold any one of the</span>
153 <span class="comment">// template arguments at a time) the types and number of axis can vary at run-time</span>
154 <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"><</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">variant</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">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special"><>>>();</span>
155 <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"><>(</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>
156 <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"><>(</span><span class="number">1</span><span class="special">,</span> <span class="number">7</span><span class="special">));</span>
158 <span class="comment">// create dynamic histogram by moving the vector</span>
159 <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>
160 <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>
161 <span class="special">}</span>
163 <div class="note"><table border="0" summary="Note">
165 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
166 <th align="left">Note</th>
168 <tr><td align="left" valign="top"><p>
169 When the axis types are known at compile-time, the histogram internally
170 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
171 a heap memory allocation. If the number of axes is only known at run-time,
172 they are stored in a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span></code>.
173 The interface hides this difference very well, but there are a corner cases
174 where the difference becomes apparent. The <a class="link" href="overview.html#histogram.overview.structure.host" title="Histogram host class">overview</a>
175 has more details on this point.
179 The factory function named <code class="computeroutput"><a class="link" href="reference.html#header.boost.histogram.make_histogram_hpp" title="Header <boost/histogram/make_histogram.hpp>">make_histogram</a></code>
180 uses the default storage type, which provides safe counting, is fast, and
181 memory efficient. If you want to create a histogram with another storage
182 type, use <code class="computeroutput"><a class="link" href="reference.html#header.boost.histogram.make_histogram_hpp" title="Header <boost/histogram/make_histogram.hpp>">make_histogram_with</a></code>.
183 To learn more about other storage types and how to create your own, have
184 a look at the section <a class="link" href="guide.html#histogram.guide.expert" title="Advanced usage">Advanced Usage</a>.
187 <div class="section">
188 <div class="titlepage"><div><div><h3 class="title">
189 <a name="histogram.guide.axis_guide"></a><a class="link" href="guide.html#histogram.guide.axis_guide" title="Axis guide">Axis guide</a>
190 </h3></div></div></div>
191 <div class="toc"><dl class="toc">
192 <dt><span class="section"><a href="guide.html#histogram.guide.axis_guide.overview">Overview</a></span></dt>
193 <dt><span class="section"><a href="guide.html#histogram.guide.axis_guide.axis_configuration">Axis
194 configuration</a></span></dt>
197 The library provides a number of useful axis types. The builtin axis types
198 can be configured to fit many needs. If you still need something more exotic,
199 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
200 usage section</a> for details. In the following, we give some advice when
201 to use which of the builtin axis types.
203 <div class="section">
204 <div class="titlepage"><div><div><h4 class="title">
205 <a name="histogram.guide.axis_guide.overview"></a><a class="link" href="guide.html#histogram.guide.axis_guide.overview" title="Overview">Overview</a>
206 </h4></div></div></div>
207 <div class="variablelist">
208 <p class="title"><b></b></p>
209 <dl class="variablelist">
210 <dt><span class="term"> <code class="computeroutput"><a class="link" href="../boost/histogram/axis/regular.html" title="Class template regular">boost::histogram::axis::regular</a></code>
213 Axis over intervals on the real line which have equal width. Value-to-index
214 conversion is O(1) and very fast. The axis does not allocate memory
215 dynamically. The axis is very flexible thanks to transforms (see
216 below). Due to finite precision of floating point calculations, bin
217 edges may not be exactly at expected values, though. If you need
218 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 axis</a></code>.
219 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 axis</a></code>.
221 <dt><span class="term"> <code class="computeroutput"><a class="link" href="../boost/histogram/axis/variable.html" title="Class template variable">boost::histogram::axis::variable</a></code>
224 Axis over intervals on the real line of variable width. Value-to-index
225 conversion is O(log(N)). The axis allocates memory dynamically to
226 store the bin edges. Use this if the regular axis with transforms
227 cannot represent the binning you want. If you need bin edges at exactly
228 defined floating point values, use this axis.
230 <dt><span class="term"> <code class="computeroutput"><a class="link" href="../boost/histogram/axis/integer.html" title="Class template integer">boost::histogram::axis::integer</a></code>
233 Axis over an integer sequence [i, i+1, i+2, ...]. It can be configured
234 to handle real input values, too, and then acts like a fast regular
235 axis with a fixed bin width of 1. Value-to-index conversion is O(1)
236 and faster than for the <code class="computeroutput"><a class="link" href="../boost/histogram/axis/regular.html" title="Class template regular">regular
237 axis</a></code>. Does not allocate memory dynamically. Use this
238 when your input consists of an integer range or pre-digitized values
239 with low dynamic range, like pixel values for individual colors in
242 <dt><span class="term"> <code class="computeroutput"><a class="link" href="../boost/histogram/axis/category.html" title="Class template category">boost::histogram::axis::category</a></code>
245 Axis over a set of unique values of an arbitrary equal-comparable
246 type. Value-to-index conversion is O(N), but still faster than the
247 O(logN) complexity of the <code class="computeroutput"><a class="link" href="../boost/histogram/axis/variable.html" title="Class template variable">variable
248 axis</a></code> for N < 10, the typical use case. The axis allocates
249 memory from the heap to store the values.
254 Here is an example which shows the basic use case for each axis type.
256 <pre class="programlisting"><span class="preprocessor">#include</span> <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">axis</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
257 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">limits</span><span class="special">></span>
259 <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
260 <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>
262 <span class="comment">// make a regular axis with 10 bins over interval from 1.5 to 2.5</span>
263 <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"><>{</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>
264 <span class="comment">// `<>` is needed in C++14 because the axis is templated,</span>
265 <span class="comment">// in C++17 you can do: auto r = axis::regular{10, 1.5, 2.5};</span>
266 <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>
267 <span class="comment">// alternatively, you can define the step size with the `step` marker</span>
268 <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"><>{</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>
269 <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>
271 <span class="comment">// histogram uses the `index` method to convert values to indices</span>
272 <span class="comment">// note: intervals of builtin axis types are always semi-open [a, b)</span>
273 <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>
274 <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>
275 <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>
276 <span class="comment">// index for a value below the start of the axis is always -1</span>
277 <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>
278 <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"><</span><span class="keyword">double</span><span class="special">>::</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>
279 <span class="comment">// index for a value below the above the end of the axis is always `size()`</span>
280 <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>
281 <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"><</span><span class="keyword">double</span><span class="special">>::</span><span class="identifier">infinity</span><span class="special">())</span> <span class="special">==</span> <span class="number">10</span><span class="special">);</span>
282 <span class="comment">// index for not-a-number is also `size()` by convention</span>
283 <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"><</span><span class="keyword">double</span><span class="special">>::</span><span class="identifier">quiet_NaN</span><span class="special">())</span> <span class="special">==</span> <span class="number">10</span><span class="special">);</span>
285 <span class="comment">// make a variable axis with 3 bins [-1.5, 0.1), [0.1, 0.3), [0.3, 10)</span>
286 <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"><>{-</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>
287 <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>
288 <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>
289 <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>
290 <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>
291 <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>
292 <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>
294 <span class="comment">// make an integer axis with 3 bins at -1, 0, 1</span>
295 <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"><>{-</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">};</span>
296 <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>
297 <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>
298 <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>
299 <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>
300 <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>
302 <span class="comment">// make an integer axis called "foo"</span>
303 <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"><>{-</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>
304 <span class="comment">// all builtin axis types allow you to pass some optional metadata as the last</span>
305 <span class="comment">// argument in the constructor; a string by default, but can be any copyable type</span>
307 <span class="comment">// two axis do not compare equal if they differ in their metadata</span>
308 <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>
310 <span class="comment">// integer axis also work well with unscoped enums</span>
311 <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>
312 <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"><>{</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>
313 <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>
314 <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>
316 <span class="comment">// make a category axis from a scoped enum and/or if the identifiers are not consecutive</span>
317 <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>
318 <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"><</span><span class="identifier">Bar</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="identifier">Bar</span><span class="special">::</span><span class="identifier">blue</span><span class="special">};</span>
319 <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>
320 <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>
321 <span class="comment">// c.index(12) is a compile-time error, since the argument must be of type `Bar`</span>
323 <span class="comment">// category axis can be created for any copyable and equal-comparable type</span>
324 <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"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">>{</span><span class="string">"red"</span><span class="special">,</span> <span class="string">"blue"</span><span class="special">};</span>
325 <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>
326 <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>
327 <span class="special">}</span>
329 <div class="note"><table border="0" summary="Note">
331 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
332 <th align="left">Note</th>
334 <tr><td align="left" valign="top"><p>
335 All builtin axes over the real-line use semi-open bin intervals by convention.
336 As a mnemonic, think of iterator ranges from <code class="computeroutput"><span class="identifier">begin</span></code>
337 to <code class="computeroutput"><span class="identifier">end</span></code>, where <code class="computeroutput"><span class="identifier">end</span></code> is also not included.
341 As mentioned in the previous example, you can assign an optional label
342 to any axis to keep track of what the axis is about. Assume you have census
343 data and you want to investigate how yearly income correlates with age,
346 <pre class="programlisting"><span class="preprocessor">#include</span> <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">hpp</span><span class="special">></span>
348 <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
349 <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>
351 <span class="comment">// create a 2d-histogram with an "age" and an "income" axis</span>
352 <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"><>(</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>
353 <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special"><>(</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>
355 <span class="comment">// do something with h</span>
356 <span class="special">}</span>
359 Without the metadata it would be difficult to see which axis was covering
360 which quantity. Metadata is the only axis property that can be modified
361 after construction by the user. Axis objects with different metadata do
365 By default, strings are used to store the metadata, but any type compatible
366 with the <a class="link" href="concepts.html#histogram.concepts.Axis" title="Axis"><span class="bold"><strong>Metadata</strong></span>
367 concept</a> can be used.
370 <div class="section">
371 <div class="titlepage"><div><div><h4 class="title">
372 <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
374 </h4></div></div></div>
375 <div class="toc"><dl class="toc">
376 <dt><span class="section"><a href="guide.html#histogram.guide.axis_guide.axis_configuration.transforms">Transforms</a></span></dt>
377 <dt><span class="section"><a href="guide.html#histogram.guide.axis_guide.axis_configuration.options">Options</a></span></dt>
380 All builtin axis types have template arguments for customization. All arguments
381 have reasonable defaults so you can use empty brackets. If your compiler
382 supports C++17, you can drop the brackets altogether. Suitable arguments
383 are then deduced from the constructor call. The template arguments are
386 <div class="variablelist">
387 <p class="title"><b></b></p>
388 <dl class="variablelist">
389 <dt><span class="term">Value</span></dt>
391 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
392 axis must be implicitly convertible to this type.
394 <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>
397 A class that implements a monotonic transform between the data space
398 and the space in which the bins are equi-distant. Users can define
399 their own transforms and use them with the axis.
401 <dt><span class="term">Metadata</span></dt>
403 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
404 any copyable type. If you want to save a small amount of stack memory
405 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>
408 <dt><span class="term">Options</span></dt>
410 <code class="computeroutput"><a class="link" href="reference.html#header.boost.histogram.axis.option_hpp" title="Header <boost/histogram/axis/option.hpp>">Compile-time options</a></code>
411 for the axis. This is used to enable/disable under- and overflow
412 bins, to make an axis circular, or to enable dynamic growth of the
413 axis beyond the initial range.
415 <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>
416 and <code class="computeroutput"><a class="link" href="../boost/histogram/axis/category.html" title="Class template category">category</a></code>
419 Allocator that is used to request memory dynamically to store values.
420 If you don't know what an allocator is you can safely ignore this
426 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
427 options, except for the Value and Allocator, to use the library default.
429 <div class="section">
430 <div class="titlepage"><div><div><h5 class="title">
431 <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>
432 </h5></div></div></div>
434 Transforms are a way to customize a <code class="computeroutput"><a class="link" href="../boost/histogram/axis/regular.html" title="Class template regular">regular
435 axis</a></code>. The default is the identity transform which forwards
436 the value. Transforms allow you to chose the faster stack-allocated regular
437 axis over the generic <code class="computeroutput"><a class="link" href="../boost/histogram/axis/variable.html" title="Class template variable">variable
438 axis</a></code> in some cases. A common need is a regular binning in
439 the logarithm 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 transform</a></code>.
440 The follow example shows the builtin transforms.
442 <pre class="programlisting"><span class="preprocessor">#include</span> <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">axis</span><span class="special">/</span><span class="identifier">regular</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
443 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">limits</span><span class="special">></span>
445 <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
446 <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>
448 <span class="comment">// make a regular axis with a log transform over [10, 100), [100, 1000), [1000, 10000)</span>
449 <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special"><</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">></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>
450 <span class="comment">// log transform:</span>
451 <span class="comment">// - useful when values vary dramatically in magnitude, like brightness of stars</span>
452 <span class="comment">// - edges are not exactly at 10, 100, 1000, because of finite floating point precision</span>
453 <span class="comment">// - values >= 0 but smaller than the starting value of the axis are mapped to -1</span>
454 <span class="comment">// - values < 0 are mapped to `size()`, because the result of std::log(value) is NaN</span>
455 <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>
456 <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>
457 <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>
458 <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>
459 <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>
460 <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>
462 <span class="comment">// make a regular axis with a sqrt transform over [4, 9), [9, 16), [16, 25)</span>
463 <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special"><</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">></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>
464 <span class="comment">// sqrt transform:</span>
465 <span class="comment">// - bin widths are more mildly increasing compared to log transform</span>
466 <span class="comment">// - axis starting at value == 0 is ok, sqrt(0) == 0 unlike log transform</span>
467 <span class="comment">// - values < 0 are mapped to `size()`, because the result of std::sqrt(value) is NaN</span>
468 <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>
469 <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>
470 <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>
471 <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>
472 <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>
473 <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>
475 <span class="comment">// make a regular axis with a power transform x^1/3 over [1, 8), [8, 27), [27, 64)</span>
476 <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>
477 <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special"><</span><span class="keyword">double</span><span class="special">,</span> <span class="identifier">pow_trans</span><span class="special">></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>
478 <span class="comment">// pow transform:</span>
479 <span class="comment">// - generalization of the sqrt transform</span>
480 <span class="comment">// - starting the axis at value == 0 is ok for power p > 0, 0^p == 0 for p > 0</span>
481 <span class="comment">// - values < 0 are mapped to `size()` if power p is not a positive integer</span>
482 <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>
483 <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>
484 <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>
485 <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>
486 <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>
487 <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>
488 <span class="special">}</span>
491 Due to the finite precision of floating point calculations, the bin edges
492 of a transformed regular axis may not be exactly at the expected values.
493 If you need exact correspondence, use a <code class="computeroutput"><a class="link" href="../boost/histogram/axis/variable.html" title="Class template variable">variable
497 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 axis</a></code>, by implementing
498 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>.
501 <div class="section">
502 <div class="titlepage"><div><div><h5 class="title">
503 <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>
504 </h5></div></div></div>
506 <code class="computeroutput"><a class="link" href="reference.html#header.boost.histogram.axis.option_hpp" title="Header <boost/histogram/axis/option.hpp>">Options</a></code>
507 can be used to configure each axis type. The option flags are implemented
508 as tag types with the suffix <code class="computeroutput"><span class="identifier">_t</span></code>.
509 Each tag type has a corresponding value without the suffix. The values
510 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">&</span></code>.
511 When you pass a single option flag to an axis as a template parameter,
512 use the tag type. When you need to pass the union of several options
513 to an axis as a template parameter, surround the union of option values
514 with a <code class="computeroutput"><span class="keyword">decltype</span></code>. Both ways
515 of passing options are shown in the following examples.
518 <span class="bold"><strong>Under- and overflow bins</strong></span>
521 Under- and overflow bins are added automatically for most axis types.
522 If you create an axis with 10 bins, the histogram will actually have
523 12 bins along that axis. The extra bins are very useful, as explained
524 in the <a class="link" href="rationale.html#histogram.rationale.uoflow" title="Under- and overflow bins">rationale</a>. If
525 the input cannot exceed the axis range or if you are really tight on
526 memory, you can disable the extra bins. A demonstration:
528 <pre class="programlisting"><span class="preprocessor">#include</span> <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">hpp</span><span class="special">></span>
529 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">string</span><span class="special">></span>
531 <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
532 <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>
534 <span class="comment">// create a 1d-histogram over integer values from 1 to 6</span>
535 <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"><</span><span class="keyword">int</span><span class="special">>(</span><span class="number">1</span><span class="special">,</span> <span class="number">7</span><span class="special">));</span>
536 <span class="comment">// axis has size 6...</span>
537 <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>
538 <span class="comment">// ... but histogram has size 8, because of overflow and underflow bins</span>
539 <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>
541 <span class="comment">// create a 1d-histogram for throws of a six-sided die without extra bins,</span>
542 <span class="comment">// since the values cannot be smaller than 1 or larger than 6</span>
543 <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"><</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">>(</span><span class="number">1</span><span class="special">,</span> <span class="number">7</span><span class="special">));</span>
544 <span class="comment">// now size of axis and histogram is equal</span>
545 <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>
546 <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>
547 <span class="special">}</span>
550 The <code class="computeroutput"><a class="link" href="../boost/histogram/axis/category.html" title="Class template category">category axis</a></code>
551 by default comes only with an overflow bin, which counts all input values
552 that are not part of the initial set.
555 <span class="bold"><strong>Circular axes</strong></span>
558 Each builtin axis except the <code class="computeroutput"><a class="link" href="../boost/histogram/axis/category.html" title="Class template category">category</a></code>
559 axis can be made circular. This means that the axis is periodic at its
560 ends. This is useful if you want make a histogram over a polar angle.
563 <pre class="programlisting"><span class="preprocessor">#include</span> <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">axis</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
564 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">limits</span><span class="special">></span>
566 <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
567 <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>
569 <span class="comment">// make a circular regular axis ... [0, 180), [180, 360), [0, 180) ....</span>
570 <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>
571 <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"><</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">>{</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>
572 <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>
573 <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>
574 <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>
575 <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>
576 <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>
577 <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>
578 <span class="comment">// special values are mapped to the overflow bin index</span>
579 <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"><</span><span class="keyword">double</span><span class="special">>::</span><span class="identifier">infinity</span><span class="special">())</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span>
580 <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"><</span><span class="keyword">double</span><span class="special">>::</span><span class="identifier">infinity</span><span class="special">())</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span>
581 <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"><</span><span class="keyword">double</span><span class="special">>::</span><span class="identifier">quiet_NaN</span><span class="special">())</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span>
583 <span class="comment">// since the regular axis is the most common circular axis, there exists an alias</span>
584 <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"><>{</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">c</span><span class="special">);</span>
587 <span class="comment">// make a circular integer axis</span>
588 <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"><</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">>{</span><span class="number">1</span><span class="special">,</span> <span class="number">4</span><span class="special">};</span>
589 <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>
590 <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>
591 <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>
592 <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>
593 <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>
594 <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>
595 <span class="special">}</span>
598 A circular axis cannot have an underflow bin, passing both options together
599 generates a compile-time error. Since the highest bin wraps around to
600 the lowest bin, there is no possibility for overflow either. However,
601 an overflow bin is still added by default if the value is a floating
602 point type, to catch NaNs and infinities.
605 <span class="bold"><strong>Growing axes</strong></span>
608 Each builtin axis has an option to make it grow beyond its initial range
609 when a value outside of that range is passed to it, while the default
610 behavior is to count this value in the under- or overflow bins (or to
611 discard it). Example:
613 <pre class="programlisting"><span class="preprocessor">#include</span> <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">hpp</span><span class="special">></span>
614 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span>
616 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
618 <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
619 <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>
621 <span class="comment">// make a growing regular axis</span>
622 <span class="comment">// - it grows new bins with its constant bin width until the value is covered</span>
623 <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"><</span><span class="keyword">double</span><span class="special">,</span>
624 <span class="identifier">use_default</span><span class="special">,</span>
625 <span class="identifier">use_default</span><span class="special">,</span>
626 <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">>{</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>
627 <span class="comment">// nothing special happens here</span>
628 <span class="identifier">h1</span><span class="special">(</span><span class="number">0.1</span><span class="special">);</span>
629 <span class="identifier">h1</span><span class="special">(</span><span class="number">0.9</span><span class="special">);</span>
630 <span class="comment">// state: [0, 0.5): 1, [0.5, 1.0): 1</span>
631 <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>
632 <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>
633 <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>
635 <span class="comment">// value below range: axis grows new bins until value is in range</span>
636 <span class="identifier">h1</span><span class="special">(-</span><span class="number">0.3</span><span class="special">);</span>
637 <span class="comment">// state: [-0.5, 0.0): 1, [0, 0.5): 1, [0.5, 1.0): 1</span>
638 <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>
639 <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>
640 <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>
642 <span class="identifier">h1</span><span class="special">(</span><span class="number">1.9</span><span class="special">);</span>
643 <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>
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">5</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="special">-</span><span class="number">0.5</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">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>
648 <span class="comment">// make a growing category axis (here strings)</span>
649 <span class="comment">// - empty axis is allowed: very useful if categories are not known at the beginning</span>
650 <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"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span>
651 <span class="identifier">use_default</span><span class="special">,</span>
652 <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">>());</span>
653 <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>
654 <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>
655 <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>
656 <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>
657 <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>
658 <span class="identifier">h2</span><span class="special">(</span><span class="string">"foo"</span><span class="special">);</span>
659 <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>
660 <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>
661 <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>
662 <span class="special">}</span>
665 This feature can be very convenient, but keep two caveats in mind.
667 <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
668 <li class="listitem">
669 Growing axes come with a run-time cost, since the histogram has to
670 reallocate memory for all cells when an axis changes its size. Whether
671 this performance hit is noticeable depends on your application. This
672 is a minor issue, the next is more severe.
674 <li class="listitem">
675 If you have unexpected outliers in your data which are far away from
676 the normal range, the axis could grow to a huge size and the corresponding
677 huge memory request could bring the computer to its knees. This is
678 one of the reason why growing axes are not the default.
682 A growing axis can have under- and overflow bins, but these only count
683 the special floating point values: positive and negative infinity, and
689 <div class="section">
690 <div class="titlepage"><div><div><h3 class="title">
691 <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
692 histograms and accessing cells</a>
693 </h3></div></div></div>
695 A histogram has been created and now you want to insert values. This is done
696 with the flexible <code class="computeroutput"><a class="link" href="../boost/histogram/histogram.html#idm45414538352576-bb">call
697 operator</a></code> or the <code class="computeroutput"><a class="link" href="../boost/histogram/histogram.html#idm45414538337296-bb">fill
698 method</a></code>, which you typically call in a loop. <code class="computeroutput"><a class="link" href="../boost/histogram/histogram.html#idm45414538352576-bb">The
699 call operator</a></code> accepts <code class="computeroutput"><span class="identifier">N</span></code>
700 arguments or a <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>
701 elements, where <code class="computeroutput"><span class="identifier">N</span></code> is equal
702 to the number of axes of the histogram. It finds the corresponding bin for
703 the input and increments the bin counter by one. The <code class="computeroutput"><a class="link" href="../boost/histogram/histogram.html#idm45414538337296-bb">fill
704 method</a></code> accepts a single iterable over other iterables (which
705 must have have elements contiguous in memory) or values, see the method documentation
709 After the histogram has been filled, use the <code class="computeroutput"><a class="link" href="../boost/histogram/histogram.html#idm45414525334448-bb">at
710 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
711 access the cell values. It accepts integer indices, one for each axis of
714 <pre class="programlisting"><span class="preprocessor">#include</span> <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">hpp</span><span class="special">></span>
715 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span>
716 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">functional</span><span class="special">></span>
717 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">numeric</span><span class="special">></span>
718 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">utility</span><span class="special">></span>
719 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">vector</span><span class="special">></span>
721 <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
722 <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>
724 <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"><>(</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"><>(</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>
726 <span class="comment">// fill histogram, number of arguments must be equal to number of axes,</span>
727 <span class="comment">// types must be convertible to axis value type (here integer and double)</span>
728 <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>
729 <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>
731 <span class="comment">// fills from a tuple are also supported; passing a tuple of wrong size</span>
732 <span class="comment">// causes an error at compile-time or an assertion at runtime in debug mode</span>
733 <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>
734 <span class="identifier">h</span><span class="special">(</span><span class="identifier">xy</span><span class="special">);</span>
736 <span class="comment">// chunk-wise filling is also supported and more efficient, make some data...</span>
737 <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">double</span><span class="special">></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>
739 <span class="comment">// ... and call fill method</span>
740 <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>
742 <span class="comment">// once histogram is filled, access individual cells using operator[] or at(...)</span>
743 <span class="comment">// - operator[] can only accept a single argument in the current version of C++,</span>
744 <span class="comment">// it is convenient when you have a 1D histogram</span>
745 <span class="comment">// - at(...) can accept several values, so use this by default</span>
746 <span class="comment">// - underflow bins are at index -1, overflow bins at index `size()`</span>
747 <span class="comment">// - passing an invalid index triggers a std::out_of_range exception</span>
748 <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>
749 <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>
750 <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>
751 <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>
752 <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>
753 <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>
754 <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>
755 <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>
756 <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>
757 <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>
759 <span class="comment">// iteration over values works, but see next example for a better way</span>
760 <span class="comment">// - iteration using begin() and end() includes under- and overflow bins</span>
761 <span class="comment">// - iteration order is an implementation detail and should not be relied upon</span>
762 <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>
763 <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>
764 <span class="special">}</span>
767 For a histogram <code class="computeroutput"><span class="identifier">hist</span></code>, the
768 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>
769 and <code class="computeroutput"><span class="identifier">hist</span><span class="special">(...,</span>
770 <span class="identifier">weight</span><span class="special">(</span><span class="identifier">w</span><span class="special">))</span></code> increment
771 the bin counter by the value <code class="computeroutput"><span class="identifier">w</span></code>
772 instead, where <code class="computeroutput"><span class="identifier">w</span></code> may be an
773 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>
774 marks this argument as a weight, so that it can be distinguished from the
775 other inputs. It can be the first or last argument. You can freely mix calls
776 with and without a weight. Calls without <code class="computeroutput"><span class="identifier">weight</span></code>
777 act like the weight is <code class="computeroutput"><span class="number">1</span></code>. Why
778 weighted increments are sometimes useful is explained <a class="link" href="rationale.html#histogram.rationale.weights" title="Support of weighted fills">in
781 <div class="note"><table border="0" summary="Note">
783 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
784 <th align="left">Note</th>
786 <tr><td align="left" valign="top"><p>
787 The default storage loses its no-overflow-guarantee when you pass floating
788 point weights, but maintains it for integer weights.
792 When the weights come from a stochastic process, it is useful to keep track
793 of the variance of the sum of weights per cell. A specialized histogram can
794 be generated with the <code class="computeroutput"><a class="link" href="../boost/histogram/make_wei_idm45414524212960.html" title="Function template make_weighted_histogram">make_weighted_histogram</a></code>
795 factory function which does that.
797 <pre class="programlisting"><span class="preprocessor">#include</span> <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">hpp</span><span class="special">></span>
798 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span>
800 <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
801 <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>
803 <span class="comment">// Create a histogram with weight counters that keep track of a variance estimate.</span>
804 <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"><>(</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>
806 <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>
807 <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>
808 <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>
809 <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>
811 <span class="comment">// chunk-wise filling is also supported</span>
812 <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>
813 <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>
814 <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>
816 <span class="comment">// Weight counters have methods to access the value (sum of weights) and the variance</span>
817 <span class="comment">// (sum of weights squared, why this gives the variance is explained in the rationale)</span>
818 <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>
819 <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>
820 <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>
821 <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>
822 <span class="special">}</span>
825 To iterate over all cells, the <code class="computeroutput"><a class="link" href="../boost/histogram/indexed.html" title="Function template indexed">indexed</a></code>
826 range generator is very convenient and also efficient. For almost all configurations,
827 the range generator iterates <span class="emphasis"><em>faster</em></span> than a naive for-loop.
828 Under- and overflow are skipped by default.
830 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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">></span>
831 <span class="preprocessor">#include</span> <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">hpp</span><span class="special">></span>
832 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span>
833 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
834 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">numeric</span><span class="special">></span> <span class="comment">// for std::accumulate</span>
835 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">sstream</span><span class="special">></span>
837 <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>
839 <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
840 <span class="comment">// make histogram with 2 x 2 = 4 bins (not counting under-/overflow bins)</span>
841 <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"><>(</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"><>(</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>
843 <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>
844 <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>
845 <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>
846 <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>
848 <span class="comment">// use the `indexed` range adaptor to iterate over all bins;</span>
849 <span class="comment">// it is not only more convenient but also faster than a hand-crafted loop!</span>
850 <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os</span><span class="special">;</span>
851 <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&&</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>
852 <span class="comment">// x is a special accessor object</span>
853 <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>
854 <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>
855 <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>
856 <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>
857 <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>
858 <span class="identifier">os</span> <span class="special"><<</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>
859 <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>
860 <span class="special">}</span>
862 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</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="identifier">std</span><span class="special">::</span><span class="identifier">flush</span><span class="special">;</span>
864 <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>
865 <span class="string">"1 0 [ 0, 1) [ 2, 3): 3\n"</span>
866 <span class="string">"0 1 [-1, 0) [ 3, 4): 2\n"</span>
867 <span class="string">"1 1 [ 0, 1) [ 3, 4): 4\n"</span><span class="special">);</span>
869 <span class="comment">// `indexed` skips underflow and overflow bins by default, but can be called</span>
870 <span class="comment">// with the second argument `coverage::all` to walk over all bins</span>
871 <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os2</span><span class="special">;</span>
872 <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&&</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>
873 <span class="identifier">os2</span> <span class="special"><<</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>
874 <span class="special">}</span>
876 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</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="identifier">std</span><span class="special">::</span><span class="identifier">flush</span><span class="special">;</span>
878 <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>
879 <span class="string">" 0 -1: 0\n"</span>
880 <span class="string">" 1 -1: 0\n"</span>
881 <span class="string">" 2 -1: 0\n"</span>
883 <span class="string">"-1 0: 0\n"</span>
884 <span class="string">" 0 0: 1\n"</span>
885 <span class="string">" 1 0: 3\n"</span>
886 <span class="string">" 2 0: 0\n"</span>
888 <span class="string">"-1 1: 0\n"</span>
889 <span class="string">" 0 1: 2\n"</span>
890 <span class="string">" 1 1: 4\n"</span>
891 <span class="string">" 2 1: 0\n"</span>
893 <span class="string">"-1 2: 0\n"</span>
894 <span class="string">" 0 2: 0\n"</span>
895 <span class="string">" 1 2: 0\n"</span>
896 <span class="string">" 2 2: 0\n"</span><span class="special">);</span>
897 <span class="special">}</span>
900 <div class="section">
901 <div class="titlepage"><div><div><h3 class="title">
902 <a name="histogram.guide.using_profiles"></a><a class="link" href="guide.html#histogram.guide.using_profiles" title="Using profiles">Using profiles</a>
903 </h3></div></div></div>
905 Histograms from this library can do more than counting, they can hold arbitrary
906 accumulators which accept samples. We call a histogram with accumulators
907 that compute the mean of samples in each cell a <span class="emphasis"><em>profile</em></span>.
908 Profiles can be generated with the factory function <code class="computeroutput"><a class="link" href="../boost/histogram/make_pro_idm45414524176336.html" title="Function template make_profile">make_profile</a></code>.
910 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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">></span>
911 <span class="preprocessor">#include</span> <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">hpp</span><span class="special">></span>
912 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span>
913 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
914 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">sstream</span><span class="special">></span>
915 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">tuple</span><span class="special">></span>
917 <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
918 <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>
920 <span class="comment">// make a profile, it computes the mean of the samples in each histogram cell</span>
921 <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"><>(</span><span class="number">0</span><span class="special">,</span> <span class="number">3</span><span class="special">));</span>
923 <span class="comment">// mean is computed from the values marked with the sample() helper function</span>
924 <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>
925 <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>
926 <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>
927 <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>
929 <span class="comment">// fills from tuples are also supported, 5 and 6 go to cell 2</span>
930 <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>
931 <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>
932 <span class="identifier">h</span><span class="special">(</span><span class="identifier">a</span><span class="special">);</span>
933 <span class="identifier">h</span><span class="special">(</span><span class="identifier">b</span><span class="special">);</span>
935 <span class="comment">// builtin accumulators have methods to access their state</span>
936 <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os</span><span class="special">;</span>
937 <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&&</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>
938 <span class="comment">// use `.` to access methods of accessor, like `index()`</span>
939 <span class="comment">// use `->` to access methods of accumulator</span>
940 <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>
941 <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">-></span><span class="identifier">count</span><span class="special">();</span> <span class="comment">// how many samples are in this bin</span>
942 <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">-></span><span class="identifier">value</span><span class="special">();</span> <span class="comment">// mean value</span>
943 <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">-></span><span class="identifier">variance</span><span class="special">();</span> <span class="comment">// estimated variance of the mean value</span>
944 <span class="identifier">os</span> <span class="special"><<</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>
945 <span class="special">}</span>
947 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</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="identifier">std</span><span class="special">::</span><span class="identifier">flush</span><span class="special">;</span>
949 <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>
950 <span class="string">"index 1 count 2 value 3.5 variance 0.5\n"</span>
951 <span class="string">"index 2 count 2 value 5.5 variance 0.5\n"</span><span class="special">);</span>
952 <span class="special">}</span>
955 Just like <code class="computeroutput"><a class="link" href="../boost/histogram/weight.html" title="Function template weight">weight()</a></code>,
956 <code class="computeroutput"><a class="link" href="../boost/histogram/sample.html" title="Function template sample">sample()</a></code> is a
957 marker function. It must be the first or last argument.
960 Weights and samples may be combined, if the accumulators can handle weights.
961 When both <code class="computeroutput"><a class="link" href="../boost/histogram/weight.html" title="Function template weight">weight()</a></code>
962 and <code class="computeroutput"><a class="link" href="../boost/histogram/sample.html" title="Function template sample">sample()</a></code>
963 appear in the <code class="computeroutput"><a class="link" href="../boost/histogram/histogram.html#idm45414538352576-bb">call
964 operator</a></code> or the <code class="computeroutput"><a class="link" href="../boost/histogram/histogram.html#idm45414538337296-bb">fill
965 method</a></code>, they can be in any order with respect to other, but
966 they must be the first or last arguments. To make a profile which can compute
967 weighted means with proper uncertainty estimates, use the <code class="computeroutput"><a class="link" href="../boost/histogram/make_wei_idm45414524170848.html" title="Function template make_weighted_profile">make_weighted_profile</a></code>
970 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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">></span>
971 <span class="preprocessor">#include</span> <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">hpp</span><span class="special">></span>
972 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span>
973 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
974 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">sstream</span><span class="special">></span>
976 <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
977 <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>
978 <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>
980 <span class="comment">// make 2D weighted profile</span>
981 <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"><>(</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"><>(</span><span class="number">0</span><span class="special">,</span> <span class="number">2</span><span class="special">));</span>
983 <span class="comment">// The mean is computed from the values marked with the sample() helper function.</span>
984 <span class="comment">// Weights can be passed as well. The `sample` and `weight` arguments can appear in any</span>
985 <span class="comment">// order, but they must be the first or last arguments.</span>
986 <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>
987 <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>
988 <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>
989 <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>
990 <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>
991 <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>
992 <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>
993 <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>
995 <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os</span><span class="special">;</span>
996 <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&&</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>
997 <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>
998 <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>
999 <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">-></span><span class="identifier">value</span><span class="special">();</span> <span class="comment">// weighted mean</span>
1000 <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">-></span><span class="identifier">variance</span><span class="special">();</span> <span class="comment">// estimated variance of weighted mean</span>
1001 <span class="identifier">os</span> <span class="special"><<</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>
1002 <span class="special">}</span>
1004 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</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="identifier">std</span><span class="special">::</span><span class="identifier">flush</span><span class="special">;</span>
1006 <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>
1007 <span class="string">"index 1,0 mean 3.5 variance 0.5\n"</span>
1008 <span class="string">"index 0,1 mean 5.5 variance 0.5\n"</span>
1009 <span class="string">"index 1,1 mean 7.6 variance 0.5\n"</span><span class="special">);</span>
1010 <span class="special">}</span>
1013 <div class="section">
1014 <div class="titlepage"><div><div><h3 class="title">
1015 <a name="histogram.guide.using_operators"></a><a class="link" href="guide.html#histogram.guide.using_operators" title="Using operators">Using operators</a>
1016 </h3></div></div></div>
1018 The following operators are supported for pairs of histograms <code class="computeroutput"><span class="special">+,</span> <span class="special">-,</span> <span class="special">*,</span>
1019 <span class="special">/,</span> <span class="special">==,</span> <span class="special">!=</span></code>. Histograms can also be multiplied and
1020 divided by a scalar. Only a subset of the arithmetic operators is available
1021 when the underlying accumulator only supports that subset.
1024 The arithmetic operators can only be used when the histograms have the same
1025 axis configuration. This checked at run-time. An exception is thrown if the
1026 configurations do not match. Two histograms have the same axis configuration,
1027 if all axes compare equal, which includes a comparison of their metadata.
1028 Two histograms compare equal, when their axis configurations and all their
1029 cell values compare equal.
1031 <div class="note"><table border="0" summary="Note">
1033 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
1034 <th align="left">Note</th>
1036 <tr><td align="left" valign="top"><p>
1037 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
1038 comparison. Metadata types without <code class="computeroutput"><span class="keyword">operator</span><span class="special">==</span></code> are considered equal, if they are the
1042 <pre class="programlisting"><span class="preprocessor">#include</span> <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">hpp</span><span class="special">></span>
1043 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span>
1044 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">vector</span><span class="special">></span>
1046 <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
1047 <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>
1049 <span class="comment">// make two histograms</span>
1050 <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"><>(</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>
1051 <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"><>(</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>
1053 <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>
1054 <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>
1056 <span class="comment">// add them</span>
1057 <span class="keyword">auto</span> <span class="identifier">h3</span> <span class="special">=</span> <span class="identifier">h1</span><span class="special">;</span>
1058 <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>
1060 <span class="comment">// adding multiple histograms at once is likely to be optimized by the compiler so that</span>
1061 <span class="comment">// superfluous temporaries avoided, but no guarantees are given; use this equivalent</span>
1062 <span class="comment">// code when you want to make sure: h4 = h1; h4 += h2; h4 += h3;</span>
1063 <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>
1065 <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">&&</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>
1067 <span class="comment">// multiply by number, h4 *= 2 also works</span>
1068 <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>
1070 <span class="comment">// divide by number; s4 /= 4 also works</span>
1071 <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>
1073 <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">&&</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>
1074 <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">&&</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>
1076 <span class="comment">// note the special effect of multiplication on weight_storage</span>
1077 <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"><>(</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>
1078 <span class="identifier">h</span><span class="special">(-</span><span class="number">0.5</span><span class="special">);</span>
1080 <span class="comment">// counts are: 1 0</span>
1081 <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">&&</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>
1083 <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>
1084 <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>
1086 <span class="comment">// values are the same as expected...</span>
1087 <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>
1088 <span class="comment">// ... but variances differ</span>
1089 <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">&&</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>
1091 <span class="comment">// equality operator checks variances, so histograms are not equal</span>
1092 <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>
1093 <span class="special">}</span>
1095 <div class="note"><table border="0" summary="Note">
1097 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
1098 <th align="left">Note</th>
1100 <tr><td align="left" valign="top"><p>
1101 A histogram with default storage converts its cell values to double when
1102 they are to be multiplied with or divided by a real number, or when a real
1103 number is added or subtracted. At this point the no-overflow-guarantee
1107 <div class="note"><table border="0" summary="Note">
1109 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
1110 <th align="left">Note</th>
1112 <tr><td align="left" valign="top"><p>
1113 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>,
1114 adding two copies of a histogram produces a different result than scaling
1115 the histogram by a factor of two, as shown in the last example. The is
1116 a consequence of the mathematical properties of variances. They can be
1117 added like normal numbers, but scaling by <code class="computeroutput"><span class="identifier">s</span></code>
1118 means that variances are scaled by <code class="computeroutput"><span class="identifier">s</span><span class="special">^</span><span class="number">2</span></code>.
1122 <div class="section">
1123 <div class="titlepage"><div><div><h3 class="title">
1124 <a name="histogram.guide.using_algorithms"></a><a class="link" href="guide.html#histogram.guide.using_algorithms" title="Using algorithms">Using algorithms</a>
1125 </h3></div></div></div>
1126 <div class="toc"><dl class="toc">
1127 <dt><span class="section"><a href="guide.html#histogram.guide.using_algorithms.algorithms_from_the_c_standard_l">Algorithms
1128 from the C++ standard library</a></span></dt>
1129 <dt><span class="section"><a href="guide.html#histogram.guide.using_algorithms.summation">Summation</a></span></dt>
1130 <dt><span class="section"><a href="guide.html#histogram.guide.using_algorithms.projection">Projection</a></span></dt>
1131 <dt><span class="section"><a href="guide.html#histogram.guide.using_algorithms.reduction">Reduction</a></span></dt>
1134 The library was designed to work with algorithms from the C++ standard library.
1135 In addition, a support library of algorithms is included with common operations
1138 <div class="section">
1139 <div class="titlepage"><div><div><h4 class="title">
1140 <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
1141 from the C++ standard library</a>
1142 </h4></div></div></div>
1144 The histogram class has standard random-access iterators which can be used
1145 with various algorithms from the standard library. Some things need to
1148 <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
1149 <li class="listitem">
1150 The histogram iterators also walk over the under- and overflow bins,
1151 if they are present. To skip the extra bins one should use the fast
1152 iterators from the <code class="computeroutput"><a class="link" href="../boost/histogram/indexed.html" title="Function template indexed">boost::histogram::indexed</a></code>
1153 range generator instead.
1155 <li class="listitem">
1156 The iteration order for histograms with several axes is an implementation-detail,
1157 but for histograms with one axis it is guaranteed to be the obvious
1158 order: bins are accessed in order from the lowest to the highest index.
1161 <pre class="programlisting"><span class="preprocessor">#include</span> <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">hpp</span><span class="special">></span>
1162 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span>
1164 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">algorithm</span><span class="special">></span> <span class="comment">// fill, any_of, min_element, max_element</span>
1165 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cmath</span><span class="special">></span> <span class="comment">// sqrt</span>
1166 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">numeric</span><span class="special">></span> <span class="comment">// partial_sum, inner_product</span>
1168 <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
1169 <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>
1171 <span class="comment">// make histogram that represents a probability density function (PDF)</span>
1172 <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"><>(</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>
1174 <span class="comment">// make indexed range to skip underflow and overflow cells</span>
1175 <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>
1177 <span class="comment">// use std::fill to set all counters to 0.25 (except under- and overflow counters)</span>
1178 <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>
1180 <span class="comment">// compute the cumulative density function (CDF), overriding cell values</span>
1181 <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>
1183 <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>
1184 <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>
1185 <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>
1186 <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>
1187 <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>
1188 <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>
1190 <span class="comment">// use any_of to check if any cell values are smaller than 0.1,</span>
1191 <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">&</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"><</span> <span class="number">0.1</span><span class="special">;</span> <span class="special">});</span>
1192 <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>
1194 <span class="comment">// find minimum element</span>
1195 <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>
1196 <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>
1198 <span class="comment">// find maximum element</span>
1199 <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>
1200 <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>
1202 <span class="comment">// make second PDF</span>
1203 <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"><>(</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>
1204 <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>
1205 <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>
1206 <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>
1207 <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>
1209 <span class="comment">// computing cosine similiarity: cos(theta) = A dot B / sqrt((A dot A) * (B dot B))</span>
1210 <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>
1211 <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>
1212 <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>
1213 <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>
1214 <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>
1216 <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"><</span> <span class="number">1e-2</span><span class="special">);</span>
1217 <span class="special">}</span>
1220 <div class="section">
1221 <div class="titlepage"><div><div><h4 class="title">
1222 <a name="histogram.guide.using_algorithms.summation"></a><a class="link" href="guide.html#histogram.guide.using_algorithms.summation" title="Summation">Summation</a>
1223 </h4></div></div></div>
1225 It is easy to iterate over all histogram cells to compute the sum of cell
1226 values by hand or to use an algorithm from the standard library to do so,
1227 but it is not safe. The result may not be accurate or overflow, if the
1228 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>
1229 as a safer, albeit slower, alternative. It uses the <a href="https://en.wikipedia.org/wiki/Kahan_summation_algorithm" target="_top">Neumaier
1230 algorithm</a> in double precision for integers and floating point cells,
1231 and does the naive sum otherwise.
1234 <div class="section">
1235 <div class="titlepage"><div><div><h4 class="title">
1236 <a name="histogram.guide.using_algorithms.projection"></a><a class="link" href="guide.html#histogram.guide.using_algorithms.projection" title="Projection">Projection</a>
1237 </h4></div></div></div>
1239 It is sometimes convenient to generate a high-dimensional histogram first
1240 and then extract smaller or lower-dimensional versions from it. Lower-dimensional
1241 histograms are obtained by summing the bin contents of the removed axes.
1242 This is called a <span class="emphasis"><em>projection</em></span>. When the histogram has
1243 under- and overflow bins along all axes, this operation creates a histogram
1244 which is identical to one that would have been obtained by filling the
1248 Projection is useful if you found out that there is no interesting structure
1249 along an axis, so it is not worth keeping that axis around, or if you want
1250 to visualize 1d or 2d summaries of a high-dimensional histogram.
1253 The library provides the <code class="computeroutput"><a class="link" href="../boost/histogram/algorithm/project_idm45414525025232.html" title="Function template project">boost::histogram::algorithm::project</a></code>
1254 function for this purpose. It accepts the original histogram and the indices
1255 (one or more) of the axes that are kept and returns the lower-dimensional
1256 histogram. If the histogram is static, meaning the axis configuration is
1257 known at compile-time, compile-time numbers should be used as indices to
1258 obtain another static histogram. Using normal numbers or iterators over
1259 indices produces a histogram with a dynamic axis configuration.
1261 <pre class="programlisting"><span class="preprocessor">#include</span> <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">hpp</span><span class="special">></span>
1262 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span>
1263 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
1264 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">sstream</span><span class="special">></span>
1266 <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
1267 <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>
1268 <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>
1270 <span class="comment">// make a 2d histogram</span>
1271 <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"><>(</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"><>(</span><span class="number">0</span><span class="special">,</span> <span class="number">2</span><span class="special">));</span>
1273 <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>
1274 <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>
1275 <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>
1277 <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>
1278 <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>
1280 <span class="comment">// reduce does not remove counts; returned histograms are summed over</span>
1281 <span class="comment">// the removed axes, so h, hr0, and hr1 have same number of total counts;</span>
1282 <span class="comment">// we compute the sum of counts with the sum algorithm</span>
1283 <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">&&</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">&&</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>
1285 <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os1</span><span class="special">;</span>
1286 <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&&</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>
1287 <span class="identifier">os1</span> <span class="special"><<</span> <span class="string">"("</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="string">", "</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="string">"): "</span> <span class="special"><<</span> <span class="special">*</span><span class="identifier">x</span> <span class="special"><<</span> <span class="string">"\n"</span><span class="special">;</span>
1288 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</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="identifier">std</span><span class="special">::</span><span class="identifier">flush</span><span class="special">;</span>
1289 <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>
1290 <span class="string">"(1, 0): 1\n"</span>
1291 <span class="string">"(2, 0): 0\n"</span>
1292 <span class="string">"(0, 1): 0\n"</span>
1293 <span class="string">"(1, 1): 0\n"</span>
1294 <span class="string">"(2, 1): 1\n"</span><span class="special">);</span>
1296 <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os2</span><span class="special">;</span>
1297 <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&&</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"><<</span> <span class="string">"("</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="string">", -): "</span> <span class="special"><<</span> <span class="special">*</span><span class="identifier">x</span> <span class="special"><<</span> <span class="string">"\n"</span><span class="special">;</span>
1298 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</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="identifier">std</span><span class="special">::</span><span class="identifier">flush</span><span class="special">;</span>
1299 <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>
1300 <span class="string">"(1, -): 1\n"</span>
1301 <span class="string">"(2, -): 1\n"</span><span class="special">);</span>
1303 <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os3</span><span class="special">;</span>
1304 <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&&</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"><<</span> <span class="string">"(- ,"</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="string">"): "</span> <span class="special"><<</span> <span class="special">*</span><span class="identifier">x</span> <span class="special"><<</span> <span class="string">"\n"</span><span class="special">;</span>
1305 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</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="identifier">std</span><span class="special">::</span><span class="identifier">flush</span><span class="special">;</span>
1306 <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>
1307 <span class="string">"(- ,1): 1\n"</span><span class="special">);</span>
1308 <span class="special">}</span>
1311 <div class="section">
1312 <div class="titlepage"><div><div><h4 class="title">
1313 <a name="histogram.guide.using_algorithms.reduction"></a><a class="link" href="guide.html#histogram.guide.using_algorithms.reduction" title="Reduction">Reduction</a>
1314 </h4></div></div></div>
1316 A projection removes an axis completely. A less drastic way to obtain a
1317 smaller histogram is the <code class="computeroutput"><a class="link" href="../boost/histogram/algorithm/reduce_idm45414524960512.html" title="Function template reduce">boost::histogram::algorithm::reduce</a></code>
1318 function, which allows one to <span class="emphasis"><em>slice</em></span>, <span class="emphasis"><em>shrink</em></span>
1319 or <span class="emphasis"><em>rebin</em></span> individual axes.
1322 Shrinking means that the range of an axis is reduced and the number of
1323 bins along that axis. Slicing does the same, but is based on axis indices
1324 while shrinking is based on the axis values. Rebinning means that adjacent
1325 bins are merged into larger bins. For N adjacent bins, a new bin is formed
1326 which covers the common interval of the merged bins and has their added
1327 content. These two operations can be combined and applied to several axes
1328 at once (which is much more efficient than doing it sequentially).
1330 <pre class="programlisting"><span class="preprocessor">#include</span> <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">hpp</span><span class="special">></span>
1331 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span>
1333 <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
1334 <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>
1336 <span class="comment">// make a 2d histogram</span>
1337 <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"><>(</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"><>(</span><span class="number">4</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>
1339 <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>
1340 <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>
1341 <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>
1342 <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>
1344 <span class="comment">// shrink the first axis to remove the highest bin</span>
1345 <span class="comment">// rebin the second axis by merging pairs of adjacent bins</span>
1346 <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">algorithm</span><span class="special">::</span><span class="identifier">shrink</span><span class="special">(</span><span class="number">0</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">algorithm</span><span class="special">::</span><span class="identifier">rebin</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">));</span>
1348 <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="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">3</span><span class="special">);</span>
1349 <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="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>
1350 <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="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">3.0</span><span class="special">);</span>
1351 <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="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span>
1352 <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="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">1.0</span><span class="special">);</span>
1353 <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="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>
1355 <span class="comment">// reduce does not change the total count if the histogram has underflow/overflow bins;</span>
1356 <span class="comment">// counts in removed bins are added to the corresponding under- and overflow bins</span>
1357 <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">&&</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>
1358 <span class="special">}</span>
1362 <div class="section">
1363 <div class="titlepage"><div><div><h3 class="title">
1364 <a name="histogram.guide.streaming"></a><a class="link" href="guide.html#histogram.guide.streaming" title="Streaming">Streaming</a>
1365 </h3></div></div></div>
1367 Simple ostream operators are shipped with the library. They are internally
1368 used by the unit tests and give simple text representations of axis and histogram
1369 configurations and show the histogram content. One-dimensional histograms
1370 are rendered as ASCII drawings. The text representations may be useful for
1371 debugging or more, but users may want to use their own implementations. Therefore,
1372 the headers with the builtin implementations are not included by any other
1373 header of the library. The following example shows the effect of output streaming.
1375 <pre class="programlisting"><span class="preprocessor">#include</span> <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">hpp</span><span class="special">></span>
1376 <span class="preprocessor">#include</span> <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">ostream</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
1377 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span>
1378 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
1379 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">sstream</span><span class="special">></span>
1380 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">string</span><span class="special">></span>
1382 <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
1383 <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>
1385 <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os</span><span class="special">;</span>
1387 <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"><>(</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>
1388 <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>
1389 <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>
1390 <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>
1391 <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>
1393 <span class="comment">// 1D histograms are rendered as an ASCII drawing</span>
1394 <span class="identifier">os</span> <span class="special"><<</span> <span class="identifier">h1</span><span class="special">;</span>
1396 <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"><>(</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>
1397 <span class="identifier">axis</span><span class="special">::</span><span class="identifier">category</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">>({</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>
1399 <span class="comment">// higher dimensional histograms just have their cell counts listed</span>
1400 <span class="identifier">os</span> <span class="special"><<</span> <span class="identifier">h2</span><span class="special">;</span>
1402 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</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="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
1404 <span class="identifier">assert</span><span class="special">(</span>
1405 <span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span>
1406 <span class="string">"histogram(regular(5, -1, 1, metadata=\"axis 1\", options=underflow | overflow))\n"</span>
1407 <span class="string">" +-------------------------------------------------------------+\n"</span>
1408 <span class="string">"[-inf, -1) 0 | |\n"</span>
1409 <span class="string">"[ -1, -0.6) 2 |============================== |\n"</span>
1410 <span class="string">"[-0.6, -0.2) 4 |============================================================ |\n"</span>
1411 <span class="string">"[-0.2, 0.2) 3 |============================================= |\n"</span>
1412 <span class="string">"[ 0.2, 0.6) 0 | |\n"</span>
1413 <span class="string">"[ 0.6, 1) 1 |=============== |\n"</span>
1414 <span class="string">"[ 1, inf) 0 | |\n"</span>
1415 <span class="string">" +-------------------------------------------------------------+\n"</span>
1416 <span class="string">"histogram(\n"</span>
1417 <span class="string">" regular(2, -1, 1, metadata=\"axis 1\", options=underflow | overflow)\n"</span>
1418 <span class="string">" category(\"red\", \"blue\", metadata=\"axis 2\", options=overflow)\n"</span>
1419 <span class="string">" (-1 0): 0 ( 0 0): 0 ( 1 0): 0 ( 2 0): 0 (-1 1): 0 ( 0 1): 0\n"</span>
1420 <span class="string">" ( 1 1): 0 ( 2 1): 0 (-1 2): 0 ( 0 2): 0 ( 1 2): 0 ( 2 2): 0\n"</span>
1421 <span class="string">")"</span><span class="special">);</span>
1422 <span class="special">}</span>
1425 <div class="section">
1426 <div class="titlepage"><div><div><h3 class="title">
1427 <a name="histogram.guide.serialization"></a><a class="link" href="guide.html#histogram.guide.serialization" title="Serialization">Serialization</a>
1428 </h3></div></div></div>
1430 The library supports serialization via <a href="../../../../../libs/serialization/index.html" target="_top">Boost.Serialization</a>.
1431 The serialization code is not included by the super header <code class="computeroutput"><span class="preprocessor">#include</span> <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">hpp</span><span class="special">></span></code>,
1432 so that the library can be used without Boost.Serialization or with another
1433 compatible serialization library.
1435 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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">></span>
1436 <span class="preprocessor">#include</span> <span class="special"><</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">></span>
1437 <span class="preprocessor">#include</span> <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">hpp</span><span class="special">></span>
1438 <span class="preprocessor">#include</span> <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">serialization</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> <span class="comment">// includes serialization code</span>
1439 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span>
1440 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">sstream</span><span class="special">></span>
1442 <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
1443 <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>
1445 <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"><>(</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>
1446 <span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</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="string">"axis 1"</span><span class="special">));</span>
1447 <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>
1449 <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>
1451 <span class="comment">// store histogram</span>
1452 <span class="special">{</span>
1453 <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os</span><span class="special">;</span>
1454 <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>
1455 <span class="identifier">oa</span> <span class="special"><<</span> <span class="identifier">a</span><span class="special">;</span>
1456 <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>
1457 <span class="special">}</span>
1459 <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>
1461 <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>
1463 <span class="comment">// load histogram</span>
1464 <span class="special">{</span>
1465 <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>
1466 <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>
1467 <span class="identifier">ia</span> <span class="special">>></span> <span class="identifier">b</span><span class="special">;</span>
1468 <span class="special">}</span>
1470 <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>
1471 <span class="special">}</span>
1474 <div class="section">
1475 <div class="titlepage"><div><div><h3 class="title">
1476 <a name="histogram.guide.expert"></a><a class="link" href="guide.html#histogram.guide.expert" title="Advanced usage">Advanced usage</a>
1477 </h3></div></div></div>
1478 <div class="toc"><dl class="toc">
1479 <dt><span class="section"><a href="guide.html#histogram.guide.expert.user_defined_axes">User-defined
1480 axes</a></span></dt>
1481 <dt><span class="section"><a href="guide.html#histogram.guide.expert.axis_with_several_arguments">Axis
1482 with several arguments</a></span></dt>
1483 <dt><span class="section"><a href="guide.html#histogram.guide.expert.user_defined_storage_class">User-defined
1484 storage class</a></span></dt>
1485 <dt><span class="section"><a href="guide.html#histogram.guide.expert.parallelization_options">Parallelization
1486 options</a></span></dt>
1487 <dt><span class="section"><a href="guide.html#histogram.guide.expert.user_defined_accumulators">User-defined
1488 accumulators</a></span></dt>
1491 The library is customizable and extensible by users. Users can create new
1492 axis types and use them with the histogram, or implement a custom storage
1493 policy, or use a builtin storage policy with a custom counter type. The library
1494 was designed to make this very easy. This section shows how to do this.
1496 <div class="section">
1497 <div class="titlepage"><div><div><h4 class="title">
1498 <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
1500 </h4></div></div></div>
1502 It is easy to make custom axis classes that work with the library. The
1503 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>.
1506 Users can create a custom axis by derive from a builtin axis type and customize
1507 its behavior. The following examples demonstrates a modification of the
1508 <code class="computeroutput"><a class="link" href="../boost/histogram/axis/integer.html" title="Class template integer">integer axis</a></code>.
1510 <pre class="programlisting"><span class="preprocessor">#include</span> <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">hpp</span><span class="special">></span>
1511 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span>
1512 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
1513 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">sstream</span><span class="special">></span>
1515 <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
1516 <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>
1518 <span class="comment">// custom axis, which adapts builtin integer axis</span>
1519 <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"><></span> <span class="special">{</span>
1520 <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>
1522 <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>
1524 <span class="comment">// the customization point</span>
1525 <span class="comment">// - accept const char* and convert to int</span>
1526 <span class="comment">// - then call index method of base class</span>
1527 <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>
1528 <span class="special">};</span>
1530 <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>
1531 <span class="identifier">h</span><span class="special">(</span><span class="string">"-10"</span><span class="special">);</span>
1532 <span class="identifier">h</span><span class="special">(</span><span class="string">"3"</span><span class="special">);</span>
1533 <span class="identifier">h</span><span class="special">(</span><span class="string">"4"</span><span class="special">);</span>
1534 <span class="identifier">h</span><span class="special">(</span><span class="string">"9"</span><span class="special">);</span>
1536 <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os</span><span class="special">;</span>
1537 <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&&</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>
1538 <span class="identifier">os</span> <span class="special"><<</span> <span class="string">"bin "</span> <span class="special"><<</span> <span class="identifier">b</span><span class="special">.</span><span class="identifier">index</span><span class="special">()</span> <span class="special"><<</span> <span class="string">" ["</span> <span class="special"><<</span> <span class="identifier">b</span><span class="special">.</span><span class="identifier">bin</span><span class="special">()</span> <span class="special"><<</span> <span class="string">"] "</span> <span class="special"><<</span> <span class="special">*</span><span class="identifier">b</span> <span class="special"><<</span> <span class="string">"\n"</span><span class="special">;</span>
1539 <span class="special">}</span>
1541 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</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="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
1543 <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>
1544 <span class="string">"bin 1 [4] 1\n"</span>
1545 <span class="string">"bin 2 [5] 0\n"</span><span class="special">);</span>
1546 <span class="special">}</span>
1549 How to make an axis completely from scratch is shown in the next example.
1551 <pre class="programlisting"><span class="preprocessor">#include</span> <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">hpp</span><span class="special">></span>
1552 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span>
1554 <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
1555 <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>
1557 <span class="comment">// stateless axis which returns 1 if the input is even and 0 otherwise</span>
1558 <span class="keyword">struct</span> <span class="identifier">even_odd_axis</span> <span class="special">{</span>
1559 <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>
1560 <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>
1561 <span class="special">};</span>
1563 <span class="comment">// threshold axis which returns 1 if the input is above threshold</span>
1564 <span class="keyword">struct</span> <span class="identifier">threshold_axis</span> <span class="special">{</span>
1565 <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>
1566 <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">>=</span> <span class="identifier">thr</span><span class="special">;</span> <span class="special">}</span>
1567 <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>
1568 <span class="keyword">double</span> <span class="identifier">thr</span><span class="special">;</span>
1569 <span class="special">};</span>
1571 <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>
1573 <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>
1574 <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>
1575 <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>
1577 <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>
1578 <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>
1579 <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>
1580 <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>
1581 <span class="special">}</span>
1584 Such minimal axis types lack many features provided by the builtin axis
1585 types, for example, one cannot iterate over them, but this functionality
1586 can be added as needed.
1589 <div class="section">
1590 <div class="titlepage"><div><div><h4 class="title">
1591 <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
1592 with several arguments</a>
1593 </h4></div></div></div>
1595 Multi-dimensional histograms usually have an orthogonal system of axes.
1596 Orthogonal means that each axis takes care of only one value and computes
1597 its local index independently of all the other axes and values. A checker-board
1598 is such an orthogonal grid in 2D.
1601 There are other interesting grids which are not orthogonal, notably the
1602 honeycomb grid. In such a grid, each cell is hexagonal and even though
1603 the cells form a perfectly regular pattern, it is not possible to sort
1604 values into these cells using two orthogonal axes.
1607 The library supports non-orthogonal grids by allowing axis types to accept
1608 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
1609 an index from the values passed to it in an arbitrary way. The following
1610 example demonstrates this.
1612 <pre class="programlisting"><span class="preprocessor">#include</span> <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">hpp</span><span class="special">></span>
1613 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span>
1615 <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
1616 <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>
1618 <span class="comment">// axis which returns 1 if the input falls inside the unit circle and zero otherwise</span>
1619 <span class="keyword">struct</span> <span class="identifier">circle_axis</span> <span class="special">{</span>
1620 <span class="comment">// accepts a 2D point in form of a std::tuple</span>
1621 <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"><</span><span class="keyword">double</span><span class="special">,</span> <span class="keyword">double</span><span class="special">>&</span> <span class="identifier">point</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">{</span>
1622 <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"><</span><span class="number">0</span><span class="special">>(</span><span class="identifier">point</span><span class="special">);</span>
1623 <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"><</span><span class="number">1</span><span class="special">>(</span><span class="identifier">point</span><span class="special">);</span>
1624 <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"><=</span> <span class="number">1.0</span><span class="special">;</span>
1625 <span class="special">}</span>
1627 <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>
1628 <span class="special">};</span>
1630 <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>
1632 <span class="comment">// fill looks normal for a histogram which has only one Nd-axis</span>
1633 <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>
1634 <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>
1635 <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>
1636 <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>
1637 <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>
1638 <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>
1639 <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>
1641 <span class="comment">// 2D histogram, but only 1D index</span>
1642 <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>
1643 <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>
1645 <span class="comment">// other axes can be combined with a Nd-axis</span>
1646 <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"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">>({</span><span class="string">"red"</span><span class="special">,</span> <span class="string">"blue"</span><span class="special">}));</span>
1648 <span class="comment">// now we need to pass arguments for Nd-axis explicitly as std::tuple</span>
1649 <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>
1650 <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>
1652 <span class="comment">// 3D histogram, but only 2D index</span>
1653 <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>
1654 <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>
1655 <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>
1656 <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>
1657 <span class="special">}</span>
1660 <div class="section">
1661 <div class="titlepage"><div><div><h4 class="title">
1662 <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
1664 </h4></div></div></div>
1666 Histograms which use a different storage class can easily created with
1667 the factory function <code class="computeroutput"><a class="link" href="reference.html#header.boost.histogram.make_histogram_hpp" title="Header <boost/histogram/make_histogram.hpp>">make_histogram_with</a></code>.
1668 For convenience, this factory function accepts many standard containers
1669 as storage backends: vectors, arrays, and maps. These are automatically
1670 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>
1671 to provide the storage interface needed by the library. Users may also
1672 place custom accumulators in the vector, as described in the next section.
1674 <div class="warning"><table border="0" summary="Warning">
1676 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="../../../../../doc/src/images/warning.png"></td>
1677 <th align="left">Warning</th>
1679 <tr><td align="left" valign="top"><p>
1680 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">default
1681 storage</a></code> is used. If you change the storage policy, you need
1682 to know what you are doing.
1686 A <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span></code> may provide higher performance
1687 than the default storage with a carefully chosen counter type. Usually,
1688 this would be an integral or floating point type. A <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span></code>-based
1689 storage may be faster than the default storage for low-dimensional histograms
1690 (or not, you need to measure).
1693 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"><</span><span class="keyword">double</span><span class="special">></span></code>
1694 over the default storage, it will be faster. If they also want to track
1695 the variance of the sum of weights, using the factor function <code class="computeroutput"><a class="link" href="../boost/histogram/make_wei_idm45414524212960.html" title="Function template make_weighted_histogram">make_weighted_histogram</a></code>
1696 is a convenient, which provides a histogram with a vector-based storage
1697 of <code class="computeroutput"><a class="link" href="../boost/histogram/accumulators/weighted_sum.html" title="Class template weighted_sum">weighted_sum</a></code>
1701 An interesting alternative to a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span></code>
1702 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
1703 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>
1704 allocates the memory on the stack. In combination with a static axis configuration
1705 this allows one to create histograms completely on the stack without any
1706 dynamic memory allocation. Small stack-based histograms can be created
1707 and destroyed very fast.
1710 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>
1711 is adapted into a sparse storage, where empty cells do not consume any
1712 memory. This sounds very attractive, but the memory consumption per cell
1713 in a map is much larger than for a vector or array. Furthermore, the cells
1714 are usually scattered in memory, which increases cache misses and degrades
1715 performance. Whether a sparse storage performs better than a dense storage
1716 depends strongly on the usage scenario. It is easy switch from dense to
1717 sparse storage and back, so one can try both options.
1720 The following example shows how histograms are constructed which use an
1721 alternative storage classes.
1723 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">algorithm</span><span class="special">></span> <span class="comment">// std::for_each</span>
1724 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">array</span><span class="special">></span>
1725 <span class="preprocessor">#include</span> <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">hpp</span><span class="special">></span>
1726 <span class="preprocessor">#include</span> <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">algorithm</span><span class="special">/</span><span class="identifier">sum</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
1727 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">functional</span><span class="special">></span> <span class="comment">// std::ref</span>
1728 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">unordered_map</span><span class="special">></span>
1729 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">vector</span><span class="special">></span>
1731 <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
1732 <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>
1733 <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"><>(</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>
1735 <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>
1737 <span class="comment">// Create static histogram with vector<int> as counter storage, you can use</span>
1738 <span class="comment">// other arithmetic types as counters, e.g. double.</span>
1739 <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"><</span><span class="keyword">int</span><span class="special">>(),</span> <span class="identifier">axis</span><span class="special">);</span>
1740 <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>
1741 <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>
1743 <span class="comment">// Create static histogram with array<int, N> as counter storage which is</span>
1744 <span class="comment">// allocated completely on the stack (this is very fast). N may be larger than</span>
1745 <span class="comment">// the actual number of bins used; an exception is raised if N is too small to</span>
1746 <span class="comment">// hold all bins.</span>
1747 <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"><</span><span class="keyword">int</span><span class="special">,</span> <span class="number">12</span><span class="special">>(),</span> <span class="identifier">axis</span><span class="special">);</span>
1748 <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>
1749 <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>
1751 <span class="comment">// Create static histogram with unordered_map as counter storage; this</span>
1752 <span class="comment">// generates a sparse histogram where only memory is allocated for bins that</span>
1753 <span class="comment">// are non-zero. This sounds like a good idea for high-dimensional histograms,</span>
1754 <span class="comment">// but maps come with a memory and run-time overhead. The default_storage</span>
1755 <span class="comment">// usually performs better in high dimensions.</span>
1756 <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"><</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">>(),</span> <span class="identifier">axis</span><span class="special">);</span>
1757 <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>
1758 <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>
1759 <span class="special">}</span>
1762 <div class="section">
1763 <div class="titlepage"><div><div><h4 class="title">
1764 <a name="histogram.guide.expert.parallelization_options"></a><a class="link" href="guide.html#histogram.guide.expert.parallelization_options" title="Parallelization options">Parallelization
1766 </h4></div></div></div>
1768 There are two ways to generate a single histogram using several threads.
1771 1. Each thread has its own copy of the histogram. Each copy is independently
1772 filled. The copies are then added in the main thread. Use this as the default
1773 when you can afford having <code class="computeroutput"><span class="identifier">N</span></code>
1774 copies of the histogram in memory for <code class="computeroutput"><span class="identifier">N</span></code>
1775 threads, because it allows each thread to work on its thread-local memory
1776 and utilize the CPU cache without the need to synchronize memory access.
1777 The highest performance gains are obtained in this way.
1780 2. There is only one histogram which is filled concurrently by several
1781 threads. This requires using a thread-safe storage that can handle concurrent
1782 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>
1783 accumulator, which combined with the <code class="computeroutput"><a class="link" href="reference.html#boost.histogram.dense_storage">boost::histogram::dense_storage</a></code>
1784 provides a thread-safe storage.
1786 <div class="note"><table border="0" summary="Note">
1788 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
1789 <th align="left">Note</th>
1791 <tr><td align="left" valign="top"><p>
1792 Filling a histogram with growing axes in a multi-threaded environment
1793 is safe, but has poor performance since the histogram must be locked
1794 on each fill. The locks are required because an axis could grow each
1795 time, which changes the number of cells and cell addressing for all other
1796 threads. Even without growing axes, there is only a performance gain
1797 of filling a thread-safe histogram in parallel if the histogram is either
1798 very large or when significant time is spend in preparing the value to
1799 fill. For small histograms, threads frequently access the same cell,
1800 whose state has to be synchronized between the threads. This is slow
1801 even with atomic counters, since different threads are usually executed
1802 on different cores and the synchronization causes cache misses that eat
1803 up the performance gained by doing some calculations in parallel.
1807 The next example demonstrates option 2 (option 1 is straight-forward to
1810 <pre class="programlisting"><span class="preprocessor">#include</span> <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">hpp</span><span class="special">></span>
1811 <span class="preprocessor">#include</span> <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">algorithm</span><span class="special">/</span><span class="identifier">sum</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
1812 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span>
1813 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">functional</span><span class="special">></span>
1814 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">thread</span><span class="special">></span>
1815 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">vector</span><span class="special">></span>
1817 <span class="comment">// dummy fill function, to be executed in parallel by several threads</span>
1818 <span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Histogram</span><span class="special">></span>
1819 <span class="keyword">void</span> <span class="identifier">fill</span><span class="special">(</span><span class="identifier">Histogram</span><span class="special">&</span> <span class="identifier">h</span><span class="special">)</span> <span class="special">{</span>
1820 <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"><</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>
1821 <span class="special">}</span>
1823 <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
1824 <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>
1826 <span class="comment">/*
1827 Create histogram with container of thread-safe counters for parallel filling in
1828 several threads. Only filling is thread-safe, other guarantees are not given.
1830 <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"><</span><span class="identifier">accumulators</span><span class="special">::</span><span class="identifier">thread_safe</span><span class="special"><</span><span class="keyword">unsigned</span><span class="special">>>(),</span>
1831 <span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special"><>(</span><span class="number">0</span><span class="special">,</span> <span class="number">10</span><span class="special">));</span>
1833 <span class="comment">/*
1834 Run the fill function in parallel from different threads. This is safe when a
1835 thread-safe accumulator and a storage with thread-safe cell access are used.
1837 <span class="keyword">auto</span> <span class="identifier">fill_h</span> <span class="special">=</span> <span class="special">[&</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>
1838 <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>
1839 <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>
1840 <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>
1841 <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>
1842 <span class="identifier">t1</span><span class="special">.</span><span class="identifier">join</span><span class="special">();</span>
1843 <span class="identifier">t2</span><span class="special">.</span><span class="identifier">join</span><span class="special">();</span>
1844 <span class="identifier">t3</span><span class="special">.</span><span class="identifier">join</span><span class="special">();</span>
1845 <span class="identifier">t4</span><span class="special">.</span><span class="identifier">join</span><span class="special">();</span>
1847 <span class="comment">// Without a thread-safe accumulator, this number may be smaller.</span>
1848 <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>
1849 <span class="special">}</span>
1852 <div class="section">
1853 <div class="titlepage"><div><div><h4 class="title">
1854 <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
1856 </h4></div></div></div>
1858 A storage can hold arbitrary accumulators which may accept an arbitrary
1859 number of arguments. The arguments are passed to the accumulator via the
1860 <code class="computeroutput"><a class="link" href="../boost/histogram/sample.html" title="Function template sample">sample</a></code> call,
1861 for example, <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>
1862 for an accumulator which accepts three arguments. Accumulators are often
1863 placed in a vector-based storage, so the library provides an alias, the
1864 <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>, which is templated on
1865 the accumulator type.
1868 The library provides several accumulators:
1870 <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
1871 <li class="listitem">
1872 <code class="computeroutput"><a class="link" href="../boost/histogram/accumulators/sum.html" title="Class template sum">sum</a></code>
1873 accepts no samples, but accepts a weight. It is an alternative to a
1874 plain arithmetic type as a counter. It provides an advantage when histograms
1875 are filled with weights that differ dramatically in magnitude. The
1876 sum of weights is computed incrementally with the Neumaier algorithm.
1877 The algorithm is more accurate, but consumes more CPU and memory (memory
1878 is doubled compared to a normal sum of floating point numbers).
1880 <li class="listitem">
1881 <code class="computeroutput"><a class="link" href="../boost/histogram/accumulators/weighted_sum.html" title="Class template weighted_sum">weighted_sum</a></code>
1882 accepts no samples, but accepts a weight. It computes the sum of weights
1883 and the sum of weights squared, the variance estimate of the sum of
1884 weights. This type is used by the <code class="computeroutput"><a class="link" href="../boost/histogram/make_wei_idm45414524212960.html" title="Function template make_weighted_histogram">make_weighted_histogram</a></code>.
1886 <li class="listitem">
1887 <code class="computeroutput"><a class="link" href="../boost/histogram/accumulators/mean.html" title="Class template mean">mean</a></code>
1888 accepts a sample and computes the mean of the samples. <code class="computeroutput"><a class="link" href="../boost/histogram/make_pro_idm45414524176336.html" title="Function template make_profile">make_profile</a></code> uses
1891 <li class="listitem">
1892 <code class="computeroutput"><a class="link" href="../boost/histogram/accumulators/weighted_mean.html" title="Class template weighted_mean">weighted_mean</a></code>
1893 accepts a sample and a weight. It computes the weighted mean of the
1894 samples. <code class="computeroutput"><a class="link" href="../boost/histogram/make_wei_idm45414524170848.html" title="Function template make_weighted_profile">make_weighted_profile</a></code>
1895 uses this accumulator.
1899 Users can easily write their own accumulators and plug them into the histogram,
1900 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>.
1903 The first example shows how to make and use a histogram that uses one of
1904 the the builtin accumulators.
1906 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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">></span>
1907 <span class="preprocessor">#include</span> <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">hpp</span><span class="special">></span>
1908 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span>
1909 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
1910 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">sstream</span><span class="special">></span>
1912 <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
1913 <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>
1914 <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"><>;</span>
1916 <span class="comment">// Create a 1D-profile, which computes the mean of samples in each bin.</span>
1917 <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"><</span><span class="identifier">mean</span><span class="special">>(),</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special"><>(</span><span class="number">0</span><span class="special">,</span> <span class="number">2</span><span class="special">));</span>
1918 <span class="comment">// The factory function `make_profile` is provided as a shorthand for this, so this is</span>
1919 <span class="comment">// equivalent to the previous line: auto h = make_profile(axis::integer<>(0, 2));</span>
1921 <span class="comment">// An argument marked as `sample` is passed to the accumulator.</span>
1922 <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>
1923 <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>
1924 <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>
1925 <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>
1927 <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os</span><span class="special">;</span>
1928 <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&&</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>
1929 <span class="comment">// Accumulators usually have methods to access their state. Use the arrow</span>
1930 <span class="comment">// operator to access them. Here, `count()` gives the number of samples,</span>
1931 <span class="comment">// `value()` the mean, and `variance()` the variance estimate of the mean.</span>
1932 <span class="identifier">os</span> <span class="special"><<</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>
1933 <span class="identifier">x</span><span class="special">-></span><span class="identifier">count</span><span class="special">()</span> <span class="special">%</span> <span class="identifier">x</span><span class="special">-></span><span class="identifier">value</span><span class="special">()</span> <span class="special">%</span> <span class="identifier">x</span><span class="special">-></span><span class="identifier">variance</span><span class="special">();</span>
1934 <span class="special">}</span>
1935 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</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="identifier">std</span><span class="special">::</span><span class="identifier">flush</span><span class="special">;</span>
1936 <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>
1937 <span class="string">"index 1 count 2 mean 3.5 variance 0.5\n"</span><span class="special">);</span>
1938 <span class="special">}</span>
1941 The second example shows how to use a simple custom accumulator.
1943 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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">></span>
1944 <span class="preprocessor">#include</span> <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">hpp</span><span class="special">></span>
1945 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span>
1946 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
1947 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">sstream</span><span class="special">></span>
1949 <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
1950 <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>
1952 <span class="comment">// Make a custom accumulator, which tracks the maximum of the samples.</span>
1953 <span class="comment">// It must have a call operator that accepts the argument of the `sample` function.</span>
1954 <span class="keyword">struct</span> <span class="identifier">maximum</span> <span class="special">{</span>
1955 <span class="comment">// return value is ignored, so we use void</span>
1956 <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>
1957 <span class="keyword">if</span> <span class="special">(</span><span class="identifier">x</span> <span class="special">></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>
1958 <span class="special">}</span>
1959 <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 initialized to zero</span>
1960 <span class="special">};</span>
1962 <span class="comment">// Create 1D histogram that uses the custom accumulator.</span>
1963 <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"><</span><span class="identifier">maximum</span><span class="special">>(),</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special"><>(</span><span class="number">0</span><span class="special">,</span> <span class="number">2</span><span class="special">));</span>
1964 <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>
1965 <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>
1966 <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>
1967 <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>
1969 <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os</span><span class="special">;</span>
1970 <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&&</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>
1971 <span class="identifier">os</span> <span class="special"><<</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">-></span><span class="identifier">value</span><span class="special">;</span>
1972 <span class="special">}</span>
1973 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</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="identifier">std</span><span class="special">::</span><span class="identifier">flush</span><span class="special">;</span>
1974 <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>
1975 <span class="string">"index 1 maximum 4.0\n"</span><span class="special">);</span>
1976 <span class="special">}</span>
1979 The third example shows how to make and use an accumulator that accepts
1980 multiple samples at once and an optional weight. The accumulator in the
1981 example accepts two samples and independently computes the mean for each
1982 one. This is more efficient than filling two separate profiles, because
1983 the cell lookup has to be done only once.
1985 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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">></span>
1986 <span class="preprocessor">#include</span> <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">hpp</span><span class="special">></span>
1987 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
1988 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">sstream</span><span class="special">></span>
1990 <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
1991 <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>
1993 <span class="comment">// Accumulator accepts two samples and an optional weight and computes the mean of each.</span>
1994 <span class="keyword">struct</span> <span class="identifier">multi_mean</span> <span class="special">{</span>
1995 <span class="identifier">accumulators</span><span class="special">::</span><span class="identifier">mean</span><span class="special"><></span> <span class="identifier">mx</span><span class="special">,</span> <span class="identifier">my</span><span class="special">;</span>
1997 <span class="comment">// called when no weight is passed</span>
1998 <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>
1999 <span class="identifier">mx</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span>
2000 <span class="identifier">my</span><span class="special">(</span><span class="identifier">y</span><span class="special">);</span>
2001 <span class="special">}</span>
2003 <span class="comment">// called when a weight is passed</span>
2004 <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">weight_type</span><span class="special"><</span><span class="keyword">double</span><span class="special">></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>
2005 <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>
2006 <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>
2007 <span class="special">}</span>
2008 <span class="special">};</span>
2009 <span class="comment">// Note: The implementation can be made more efficient by sharing the sum of weights.</span>
2011 <span class="comment">// Create a 1D histogram that uses the custom accumulator.</span>
2012 <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"><</span><span class="identifier">multi_mean</span><span class="special">>(),</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special"><>(</span><span class="number">0</span><span class="special">,</span> <span class="number">2</span><span class="special">));</span>
2013 <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>
2014 <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>
2015 <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>
2016 <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>
2018 <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os</span><span class="special">;</span>
2019 <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&&</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>
2020 <span class="identifier">os</span> <span class="special"><<</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>
2021 <span class="identifier">bin</span><span class="special">-></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">-></span><span class="identifier">my</span><span class="special">.</span><span class="identifier">value</span><span class="special">();</span>
2022 <span class="special">}</span>
2023 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</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="identifier">std</span><span class="special">::</span><span class="identifier">flush</span><span class="special">;</span>
2024 <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>
2025 <span class="string">"index 1 mean-x 6.2 mean-y 7.2\n"</span><span class="special">);</span>
2026 <span class="special">}</span>
2031 <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
2032 <td align="left"></td>
2033 <td align="right"><div class="copyright-footer">Copyright © 2016-2019 Hans
2035 Distributed under the Boost Software License, Version 1.0. (See accompanying
2036 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
2041 <div class="spirit-nav">
2042 <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>