1<html> 2<head> 3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 4<title>User guide</title> 5<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css"> 6<meta name="generator" content="DocBook XSL Stylesheets V1.79.1"> 7<link rel="home" href="../index.html" title="Chapter 1. Boost.Histogram"> 8<link rel="up" href="../index.html" title="Chapter 1. Boost.Histogram"> 9<link rel="prev" href="getting_started.html" title="Getting started"> 10<link rel="next" href="benchmarks.html" title="Benchmarks"> 11</head> 12<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> 13<table cellpadding="2" width="100%"><tr> 14<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td> 15<td align="center"><a href="../../../../../index.html">Home</a></td> 16<td align="center"><a href="../../../../libraries.htm">Libraries</a></td> 17<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> 18<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> 19<td align="center"><a href="../../../../../more/index.htm">More</a></td> 20</tr></table> 21<hr> 22<div class="spirit-nav"> 23<a accesskey="p" href="getting_started.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="benchmarks.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a> 24</div> 25<div class="section"> 26<div class="titlepage"><div><div><h2 class="title" style="clear: both"> 27<a name="histogram.guide"></a><a class="link" href="guide.html" title="User guide">User guide</a> 28</h2></div></div></div> 29<div class="toc"><dl class="toc"> 30<dt><span class="section"><a href="guide.html#histogram.guide.making_histograms">Making histograms</a></span></dt> 31<dt><span class="section"><a href="guide.html#histogram.guide.axis_guide">Axis guide</a></span></dt> 32<dd><dl> 33<dt><span class="section"><a href="guide.html#histogram.guide.axis_guide.overview">Overview</a></span></dt> 34<dt><span class="section"><a href="guide.html#histogram.guide.axis_guide.axis_configuration">Axis 35 configuration</a></span></dt> 36</dl></dd> 37<dt><span class="section"><a href="guide.html#histogram.guide.filling_histograms_and_accessing">Filling 38 histograms and accessing cells</a></span></dt> 39<dt><span class="section"><a href="guide.html#histogram.guide.using_profiles">Using profiles</a></span></dt> 40<dt><span class="section"><a href="guide.html#histogram.guide.using_operators">Using operators</a></span></dt> 41<dt><span class="section"><a href="guide.html#histogram.guide.using_algorithms">Using algorithms</a></span></dt> 42<dd><dl> 43<dt><span class="section"><a href="guide.html#histogram.guide.using_algorithms.algorithms_from_the_c_standard_l">Algorithms 44 from the C++ standard library</a></span></dt> 45<dt><span class="section"><a href="guide.html#histogram.guide.using_algorithms.summation">Summation</a></span></dt> 46<dt><span class="section"><a href="guide.html#histogram.guide.using_algorithms.projection">Projection</a></span></dt> 47<dt><span class="section"><a href="guide.html#histogram.guide.using_algorithms.reduction">Reduction</a></span></dt> 48</dl></dd> 49<dt><span class="section"><a href="guide.html#histogram.guide.streaming">Streaming</a></span></dt> 50<dt><span class="section"><a href="guide.html#histogram.guide.serialization">Serialization</a></span></dt> 51<dt><span class="section"><a href="guide.html#histogram.guide.using_histograms_in_apis">Using histograms 52 in APIs</a></span></dt> 53<dt><span class="section"><a href="guide.html#histogram.guide.expert">Advanced usage</a></span></dt> 54<dd><dl> 55<dt><span class="section"><a href="guide.html#histogram.guide.expert.user_defined_axes">User-defined 56 axes</a></span></dt> 57<dt><span class="section"><a href="guide.html#histogram.guide.expert.axis_with_several_arguments">Axis 58 with several arguments</a></span></dt> 59<dt><span class="section"><a href="guide.html#histogram.guide.expert.user_defined_storage_class">User-defined 60 storage class</a></span></dt> 61<dt><span class="section"><a href="guide.html#histogram.guide.expert.parallelisation_options">Parallelisation 62 options</a></span></dt> 63<dt><span class="section"><a href="guide.html#histogram.guide.expert.user_defined_accumulators">User-defined 64 accumulators</a></span></dt> 65</dl></dd> 66</dl></div> 67<p> 68 Boost.Histogram is designed to make simple things simple, yet complex things 69 possible. Correspondingly, this guides covers the basic usage first, and the 70 advanced usage in later sections. For an alternative quick start guide, have 71 a look at the <a class="link" href="getting_started.html" title="Getting started">Getting started</a> 72 section. 73 </p> 74<div class="section"> 75<div class="titlepage"><div><div><h3 class="title"> 76<a name="histogram.guide.making_histograms"></a><a class="link" href="guide.html#histogram.guide.making_histograms" title="Making histograms">Making histograms</a> 77</h3></div></div></div> 78<p> 79 A histogram consists of a collection of <a class="link" href="concepts.html#histogram.concepts.Axis" title="Axis">axis 80 objects</a> and a <a class="link" href="concepts.html#histogram.concepts.Storage" title="Storage">storage</a>. 81 The storage holds a collection of accumulators, one for each cell. The axis 82 objects maps input values to indices, which are combined into a global index 83 that is used to look up the cell in the storage. 84 </p> 85<p> 86 To start off you do not have to worry about the storage, the library provides 87 a good default. Learning more about the many interesting axis types to choose 88 from, however, will pay off very quickly (which are discussed further below). 89 For now, let us stick to the most common axis, the <code class="computeroutput"><a class="link" href="../boost/histogram/axis/regular.html" title="Class template regular">regular</a></code> 90 axis. It represents equidistant intervals on the real line. 91 </p> 92<p> 93 Histograms are created with the convenient factory function <code class="computeroutput"><a class="link" href="reference.html#header.boost.histogram.make_histogram_hpp" title="Header <boost/histogram/make_histogram.hpp>">make_histogram</a></code>. 94 The following example shows how to make a histogram with a single axis. 95 </p> 96<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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> 97<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span> 98 99<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span> 100 <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span> 101 102 <span class="comment">// create a 1d-histogram in default configuration which</span> 103 <span class="comment">// covers the real line from -1 to 1 in 100 bins</span> 104 <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special"><>(</span><span class="number">100</span><span class="special">,</span> <span class="special">-</span><span class="number">1.0</span><span class="special">,</span> <span class="number">1.0</span><span class="special">));</span> 105 106 <span class="comment">// rank is the number of axes</span> 107 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">rank</span><span class="special">()</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span> 108<span class="special">}</span> 109</pre> 110<p> 111 An axis object defines how input values are mapped to bins, it is a mapping 112 functor of input values to indices. The axis object holds information such 113 as how many bins there are, where the bin edges are, metadata about the axis 114 and so on. The rank of a histogram is given by the number of axes. A histogram 115 with one axis is one-dimensional. If you provide two, it is two-dimensional, 116 and so on. 117 </p> 118<p> 119 In the example above, the compiler knows the number of axes and their type 120 at compile-time, the information can be deduced from the arguments to <code class="computeroutput"><a class="link" href="reference.html#header.boost.histogram.make_histogram_hpp" title="Header <boost/histogram/make_histogram.hpp>">make_histogram</a></code>. This 121 gives the best performance, but sometimes you only know the axis configuration 122 at run-time, because it depends on information that's only available at run-time. 123 For that case you can also create axes at run-time and pass them to an overload 124 of the <code class="computeroutput"><a class="link" href="reference.html#header.boost.histogram.make_histogram_hpp" title="Header <boost/histogram/make_histogram.hpp>">make_histogram</a></code> 125 function. Here is an example. 126 </p> 127<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> 128<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span> 129<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">sstream</span><span class="special">></span> 130<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">vector</span><span class="special">></span> 131 132<span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">config</span> <span class="special">=</span> <span class="string">"4 1.0 2.0\n"</span> 133 <span class="string">"5 3.0 4.0\n"</span><span class="special">;</span> 134 135<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span> 136 <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span> 137 138 <span class="comment">// read axis config from a config file (mocked here with std::istringstream)</span> 139 <span class="comment">// and create vector of regular axes, the number of axis is not known at compile-time</span> 140 <span class="identifier">std</span><span class="special">::</span><span class="identifier">istringstream</span> <span class="identifier">is</span><span class="special">(</span><span class="identifier">config</span><span class="special">);</span> 141 <span class="keyword">auto</span> <span class="identifier">v1</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special"><>>();</span> 142 <span class="keyword">while</span> <span class="special">(</span><span class="identifier">is</span><span class="special">.</span><span class="identifier">good</span><span class="special">())</span> <span class="special">{</span> 143 <span class="keyword">unsigned</span> <span class="identifier">bins</span><span class="special">;</span> 144 <span class="keyword">double</span> <span class="identifier">start</span><span class="special">,</span> <span class="identifier">stop</span><span class="special">;</span> 145 <span class="identifier">is</span> <span class="special">>></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> 146 <span class="identifier">v1</span><span class="special">.</span><span class="identifier">emplace_back</span><span class="special">(</span><span class="identifier">bins</span><span class="special">,</span> <span class="identifier">start</span><span class="special">,</span> <span class="identifier">stop</span><span class="special">);</span> 147 <span class="special">}</span> 148 149 <span class="comment">// create histogram from iterator range</span> 150 <span class="comment">// (copying or moving the vector also works, move is shown below)</span> 151 <span class="keyword">auto</span> <span class="identifier">h1</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">v1</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">v1</span><span class="special">.</span><span class="identifier">end</span><span class="special">());</span> 152 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">rank</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">v1</span><span class="special">.</span><span class="identifier">size</span><span class="special">());</span> 153 154 <span class="comment">// with a vector of axis::variant (polymorphic axis type that can hold any one of the</span> 155 <span class="comment">// template arguments at a time) the types and number of axis can vary at run-time</span> 156 <span class="keyword">auto</span> <span class="identifier">v2</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</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> 157 <span class="identifier">v2</span><span class="special">.</span><span class="identifier">emplace_back</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special"><>(</span><span class="number">100</span><span class="special">,</span> <span class="special">-</span><span class="number">1.0</span><span class="special">,</span> <span class="number">1.0</span><span class="special">));</span> 158 <span class="identifier">v2</span><span class="special">.</span><span class="identifier">emplace_back</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special"><>(</span><span class="number">1</span><span class="special">,</span> <span class="number">7</span><span class="special">));</span> 159 160 <span class="comment">// create dynamic histogram by moving the vector</span> 161 <span class="keyword">auto</span> <span class="identifier">h2</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">v2</span><span class="special">));</span> 162 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">.</span><span class="identifier">rank</span><span class="special">()</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span> 163<span class="special">}</span> 164</pre> 165<div class="note"><table border="0" summary="Note"> 166<tr> 167<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td> 168<th align="left">Note</th> 169</tr> 170<tr><td align="left" valign="top"><p> 171 When the axis types are known at compile-time, the histogram internally 172 holds them in a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span></code>, which is very efficient and avoids 173 a heap memory allocation. If the number of axes is only known at run-time, 174 they are stored in a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span></code>. 175 The interface hides this difference very well, but there are a corner cases 176 where the difference becomes apparent. The <a class="link" href="overview.html#histogram.overview.structure.host" title="Histogram host class">overview</a> 177 has more details on this point. 178 </p></td></tr> 179</table></div> 180<p> 181 The factory function named <code class="computeroutput"><a class="link" href="reference.html#header.boost.histogram.make_histogram_hpp" title="Header <boost/histogram/make_histogram.hpp>">make_histogram</a></code> 182 uses the default storage type, which provides safe counting, is fast, and 183 memory efficient. If you want to create a histogram with another storage 184 type, use <code class="computeroutput"><a class="link" href="reference.html#header.boost.histogram.make_histogram_hpp" title="Header <boost/histogram/make_histogram.hpp>">make_histogram_with</a></code>. 185 To learn more about other storage types and how to create your own, have 186 a look at the section <a class="link" href="guide.html#histogram.guide.expert" title="Advanced usage">Advanced Usage</a>. 187 </p> 188</div> 189<div class="section"> 190<div class="titlepage"><div><div><h3 class="title"> 191<a name="histogram.guide.axis_guide"></a><a class="link" href="guide.html#histogram.guide.axis_guide" title="Axis guide">Axis guide</a> 192</h3></div></div></div> 193<div class="toc"><dl class="toc"> 194<dt><span class="section"><a href="guide.html#histogram.guide.axis_guide.overview">Overview</a></span></dt> 195<dt><span class="section"><a href="guide.html#histogram.guide.axis_guide.axis_configuration">Axis 196 configuration</a></span></dt> 197</dl></div> 198<p> 199 The library provides a number of useful axis types. The builtin axis types 200 can be configured to fit many needs. If you still need something more exotic, 201 no problem, it is easy to write your own axis types, see the <a class="link" href="guide.html#histogram.guide.expert" title="Advanced usage">Advanced 202 usage section</a> for details. In the following, we give some advice when 203 to use which of the builtin axis types. 204 </p> 205<div class="section"> 206<div class="titlepage"><div><div><h4 class="title"> 207<a name="histogram.guide.axis_guide.overview"></a><a class="link" href="guide.html#histogram.guide.axis_guide.overview" title="Overview">Overview</a> 208</h4></div></div></div> 209<div class="variablelist"> 210<p class="title"><b></b></p> 211<dl class="variablelist"> 212<dt><span class="term"> <code class="computeroutput"><a class="link" href="../boost/histogram/axis/regular.html" title="Class template regular">regular</a></code> 213 </span></dt> 214<dd><p> 215 Axis over intervals on the real line which have equal width. Value-to-index 216 conversion is O(1) and very fast. The axis does not allocate memory 217 dynamically. The axis is very flexible thanks to transforms (see 218 below). Due to finite precision of floating point calculations, bin 219 edges may not be exactly at expected values, though. If you need 220 bin edges at exactly defined floating point values, use the <code class="computeroutput"><a class="link" href="../boost/histogram/axis/variable.html" title="Class template variable">variable</a></code> axis. 221 If you need bins at exact consecutive integral values, use the <code class="computeroutput"><a class="link" href="../boost/histogram/axis/integer.html" title="Class template integer">integer</a></code> axis. 222 </p></dd> 223<dt><span class="term"> <code class="computeroutput"><a class="link" href="../boost/histogram/axis/variable.html" title="Class template variable">variable</a></code> 224 </span></dt> 225<dd><p> 226 Axis over intervals on the real line of variable width. Value-to-index 227 conversion is O(log(N)). The axis allocates memory dynamically to 228 store the bin edges. Use this if the regular axis with transforms 229 cannot represent the binning you want. If you need bin edges at exactly 230 defined floating point values, use this axis. 231 </p></dd> 232<dt><span class="term"> <code class="computeroutput"><a class="link" href="../boost/histogram/axis/integer.html" title="Class template integer">integer</a></code> 233 </span></dt> 234<dd><p> 235 Axis over an integer sequence [i, i+1, i+2, ...]. It can be configured 236 to handle real input values, too, and then acts like a fast regular 237 axis with a fixed bin width of 1. Value-to-index conversion is O(1) 238 and faster than for the <code class="computeroutput"><a class="link" href="../boost/histogram/axis/regular.html" title="Class template regular">regular</a></code> 239 axis. Does not allocate memory dynamically. Use this when your input 240 consists of an integer range or pre-digitized values with low dynamic 241 range, like pixel values for individual colours in an image. 242 </p></dd> 243<dt><span class="term"> <code class="computeroutput"><a class="link" href="../boost/histogram/axis/boolean.html" title="Class template boolean">boolean</a></code> 244 </span></dt> 245<dd><p> 246 Axis over the two values [false, true]. It is a common specialization 247 of the <code class="computeroutput"><a class="link" href="../boost/histogram/axis/regular.html" title="Class template regular">regular</a></code> 248 axis. Value-to-index conversion is a pass-through operation, so this 249 is the fastest possible axis. The axis has no state other than the 250 metadata (which can be stateless). Does not allocate memory dynamically. 251 Use this when your input consists of binary categories, like signal 252 and background. 253 </p></dd> 254<dt><span class="term"> <code class="computeroutput"><a class="link" href="../boost/histogram/axis/category.html" title="Class template category">category</a></code> 255 </span></dt> 256<dd><p> 257 Axis over a set of unique values of an arbitrary equal-comparable 258 type. Value-to-index conversion is O(N), but still faster than the 259 O(logN) complexity of the <code class="computeroutput"><a class="link" href="../boost/histogram/axis/variable.html" title="Class template variable">variable</a></code> 260 axis for N < 10, the typical use case. The axis allocates memory 261 from the heap to store the values. 262 </p></dd> 263</dl> 264</div> 265<p> 266 Here is an example which shows the basic use case for each axis type. 267 </p> 268<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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> 269<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">limits</span><span class="special">></span> 270 271<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span> 272 <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span> 273 274 <span class="comment">// make a regular axis with 10 bins over interval from 1.5 to 2.5</span> 275 <span class="keyword">auto</span> <span class="identifier">r</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special"><>{</span><span class="number">10</span><span class="special">,</span> <span class="number">1.5</span><span class="special">,</span> <span class="number">2.5</span><span class="special">};</span> 276 <span class="comment">// `<>` is needed in C++14 because the axis is templated,</span> 277 <span class="comment">// in C++17 you can do: auto r = axis::regular{10, 1.5, 2.5};</span> 278 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">10</span><span class="special">);</span> 279 <span class="comment">// alternatively, you can define the step size with the `step` marker</span> 280 <span class="keyword">auto</span> <span class="identifier">r_step</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special"><>{</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">step</span><span class="special">(</span><span class="number">0.1</span><span class="special">),</span> <span class="number">1.5</span><span class="special">,</span> <span class="number">2.5</span><span class="special">};</span> 281 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_step</span> <span class="special">==</span> <span class="identifier">r</span><span class="special">);</span> 282 283 <span class="comment">// histogram uses the `index` method to convert values to indices</span> 284 <span class="comment">// note: intervals of builtin axis types are always semi-open [a, b)</span> 285 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">1.5</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span> 286 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">1.6</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span> 287 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">2.4</span><span class="special">)</span> <span class="special">==</span> <span class="number">9</span><span class="special">);</span> 288 <span class="comment">// index for a value below the start of the axis is always -1</span> 289 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">1.0</span><span class="special">)</span> <span class="special">==</span> <span class="special">-</span><span class="number">1</span><span class="special">);</span> 290 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(-</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</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> 291 <span class="comment">// index for a value below the above the end of the axis is always `size()`</span> 292 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">3.0</span><span class="special">)</span> <span class="special">==</span> <span class="number">10</span><span class="special">);</span> 293 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</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> 294 <span class="comment">// index for not-a-number is also `size()` by convention</span> 295 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</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> 296 297 <span class="comment">// make a variable axis with 3 bins [-1.5, 0.1), [0.1, 0.3), [0.3, 10)</span> 298 <span class="keyword">auto</span> <span class="identifier">v</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">variable</span><span class="special"><>{-</span><span class="number">1.5</span><span class="special">,</span> <span class="number">0.1</span><span class="special">,</span> <span class="number">0.3</span><span class="special">,</span> <span class="number">10.</span><span class="special">};</span> 299 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">v</span><span class="special">.</span><span class="identifier">index</span><span class="special">(-</span><span class="number">2.0</span><span class="special">)</span> <span class="special">==</span> <span class="special">-</span><span class="number">1</span><span class="special">);</span> 300 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">v</span><span class="special">.</span><span class="identifier">index</span><span class="special">(-</span><span class="number">1.5</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span> 301 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">v</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">0.1</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span> 302 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">v</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">0.3</span><span class="special">)</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span> 303 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">v</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">10</span><span class="special">)</span> <span class="special">==</span> <span class="number">3</span><span class="special">);</span> 304 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">v</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">20</span><span class="special">)</span> <span class="special">==</span> <span class="number">3</span><span class="special">);</span> 305 306 <span class="comment">// make an integer axis with 3 bins at -1, 0, 1</span> 307 <span class="keyword">auto</span> <span class="identifier">i</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special"><>{-</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">};</span> 308 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">i</span><span class="special">.</span><span class="identifier">index</span><span class="special">(-</span><span class="number">2</span><span class="special">)</span> <span class="special">==</span> <span class="special">-</span><span class="number">1</span><span class="special">);</span> 309 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">i</span><span class="special">.</span><span class="identifier">index</span><span class="special">(-</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span> 310 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">i</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span> 311 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">i</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span> 312 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">i</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">2</span><span class="special">)</span> <span class="special">==</span> <span class="number">3</span><span class="special">);</span> 313 314 <span class="comment">// make an integer axis called "foo"</span> 315 <span class="keyword">auto</span> <span class="identifier">i_with_label</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special"><>{-</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="string">"foo"</span><span class="special">};</span> 316 <span class="comment">// all builtin axis types allow you to pass some optional metadata as the last</span> 317 <span class="comment">// argument in the constructor; a string by default, but can be any copyable type</span> 318 319 <span class="comment">// two axis do not compare equal if they differ in their metadata</span> 320 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">i</span> <span class="special">!=</span> <span class="identifier">i_with_label</span><span class="special">);</span> 321 322 <span class="comment">// integer axis also work well with unscoped enums</span> 323 <span class="keyword">enum</span> <span class="special">{</span> <span class="identifier">red</span><span class="special">,</span> <span class="identifier">blue</span> <span class="special">};</span> 324 <span class="keyword">auto</span> <span class="identifier">i_for_enum</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special"><>{</span><span class="identifier">red</span><span class="special">,</span> <span class="identifier">blue</span> <span class="special">+</span> <span class="number">1</span><span class="special">};</span> 325 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">i_for_enum</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="identifier">red</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span> 326 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">i_for_enum</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="identifier">blue</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span> 327 328 <span class="comment">// make a category axis from a scoped enum and/or if the identifiers are not consecutive</span> 329 <span class="keyword">enum</span> <span class="keyword">class</span> <span class="identifier">Bar</span> <span class="special">{</span> <span class="identifier">red</span> <span class="special">=</span> <span class="number">12</span><span class="special">,</span> <span class="identifier">blue</span> <span class="special">=</span> <span class="number">6</span> <span class="special">};</span> 330 <span class="keyword">auto</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">category</span><span class="special"><</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> 331 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">c</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="identifier">Bar</span><span class="special">::</span><span class="identifier">red</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span> 332 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">c</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="identifier">Bar</span><span class="special">::</span><span class="identifier">blue</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span> 333 <span class="comment">// c.index(12) is a compile-time error, since the argument must be of type `Bar`</span> 334 335 <span class="comment">// category axis can be created for any copyable and equal-comparable type</span> 336 <span class="keyword">auto</span> <span class="identifier">c_str</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">category</span><span class="special"><</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> 337 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">c_str</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="string">"red"</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span> 338 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">c_str</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="string">"blue"</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span> 339<span class="special">}</span> 340</pre> 341<div class="note"><table border="0" summary="Note"> 342<tr> 343<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td> 344<th align="left">Note</th> 345</tr> 346<tr><td align="left" valign="top"><p> 347 All builtin axes over a continuous value range use semi-open intervals 348 in their constructors as a convention. As a mnemonic, think of iterator 349 ranges from <code class="computeroutput"><span class="identifier">begin</span></code> to 350 <code class="computeroutput"><span class="identifier">end</span></code>, where <code class="computeroutput"><span class="identifier">end</span></code> is also never included. 351 </p></td></tr> 352</table></div> 353<p> 354 As mentioned in the previous example, you can assign an optional label 355 to any axis to keep track of what the axis is about. Assume you have census 356 data and you want to investigate how yearly income correlates with age, 357 you could do: 358 </p> 359<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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> 360 361<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span> 362 <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span> 363 364 <span class="comment">// create a 2d-histogram with an "age" and an "income" axis</span> 365 <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special"><>(</span><span class="number">20</span><span class="special">,</span> <span class="number">0.0</span><span class="special">,</span> <span class="number">100.0</span><span class="special">,</span> <span class="string">"age in years"</span><span class="special">),</span> 366 <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special"><>(</span><span class="number">20</span><span class="special">,</span> <span class="number">0.0</span><span class="special">,</span> <span class="number">100.0</span><span class="special">,</span> <span class="string">"yearly income in Thousands"</span><span class="special">));</span> 367 368 <span class="comment">// do something with h</span> 369<span class="special">}</span> 370</pre> 371<p> 372 Without the metadata it would be difficult to see which axis was covering 373 which quantity. Metadata is the only axis property that can be modified 374 after construction by the user. Axis objects with different metadata do 375 not compare equal. 376 </p> 377<p> 378 By default, strings are used to store the metadata, but any type compatible 379 with the <a class="link" href="concepts.html#histogram.concepts.Axis" title="Axis"><span class="bold"><strong>Metadata</strong></span> 380 concept</a> can be used. 381 </p> 382</div> 383<div class="section"> 384<div class="titlepage"><div><div><h4 class="title"> 385<a name="histogram.guide.axis_guide.axis_configuration"></a><a class="link" href="guide.html#histogram.guide.axis_guide.axis_configuration" title="Axis configuration">Axis 386 configuration</a> 387</h4></div></div></div> 388<div class="toc"><dl class="toc"> 389<dt><span class="section"><a href="guide.html#histogram.guide.axis_guide.axis_configuration.transforms">Transforms</a></span></dt> 390<dt><span class="section"><a href="guide.html#histogram.guide.axis_guide.axis_configuration.options">Options</a></span></dt> 391</dl></div> 392<p> 393 All builtin axis types have template arguments for customisation. All arguments 394 have reasonable defaults so you can use empty brackets. If your compiler 395 supports C++17, you can drop the brackets altogether. Suitable arguments 396 are then deduced from the constructor call. The template arguments are 397 in order: 398 </p> 399<div class="variablelist"> 400<p class="title"><b></b></p> 401<dl class="variablelist"> 402<dt><span class="term">Value</span></dt> 403<dd><p> 404 The value type is the argument type of the <code class="computeroutput"><span class="identifier">index</span><span class="special">()</span></code> method. An argument passed to the 405 axis must be implicitly convertible to this type. 406 </p></dd> 407<dt><span class="term">Transform (only <code class="computeroutput"><a class="link" href="../boost/histogram/axis/regular.html" title="Class template regular">regular</a></code> 408 axis)</span></dt> 409<dd><p> 410 A class that implements a monotonic transform between the data space 411 and the space in which the bins are equi-distant. Users can define 412 their own transforms and use them with the axis. 413 </p></dd> 414<dt><span class="term">Metadata</span></dt> 415<dd><p> 416 The axis uses an instance this type to store metadata. It is a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> by default, but it can by 417 any copyable type. If you want to save a small amount of stack memory 418 per axis, you pass the empty <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">null_type</span></code> 419 here. 420 </p></dd> 421<dt><span class="term">Options</span></dt> 422<dd><p> 423 <code class="computeroutput"><a class="link" href="reference.html#header.boost.histogram.axis.option_hpp" title="Header <boost/histogram/axis/option.hpp>">Compile-time options</a></code> 424 for the axis. This is used to enable/disable under- and overflow 425 bins, to make an axis circular, or to enable dynamic growth of the 426 axis beyond the initial range. 427 </p></dd> 428<dt><span class="term">Allocator (only <code class="computeroutput"><a class="link" href="../boost/histogram/axis/variable.html" title="Class template variable">variable</a></code> 429 and <code class="computeroutput"><a class="link" href="../boost/histogram/axis/category.html" title="Class template category">category</a></code> 430 axes)</span></dt> 431<dd><p> 432 Allocator that is used to request memory dynamically to store values. 433 If you don't know what an allocator is you can safely ignore this 434 argument. 435 </p></dd> 436</dl> 437</div> 438<p> 439 You can use the <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">use_default</span></code> tag type for any of these 440 options, except for the Value and Allocator, to use the library default. 441 </p> 442<div class="section"> 443<div class="titlepage"><div><div><h5 class="title"> 444<a name="histogram.guide.axis_guide.axis_configuration.transforms"></a><a class="link" href="guide.html#histogram.guide.axis_guide.axis_configuration.transforms" title="Transforms">Transforms</a> 445</h5></div></div></div> 446<p> 447 Transforms are a way to customize a <code class="computeroutput"><a class="link" href="../boost/histogram/axis/regular.html" title="Class template regular">regular</a></code> 448 axis. Transforms allow you to chose the faster stack-allocated regular 449 axis over the generic <code class="computeroutput"><a class="link" href="../boost/histogram/axis/variable.html" title="Class template variable">variable 450 axis</a></code> in some cases. The default is the identity transform 451 which does nothing. A common need is a regular binning in the logarithm 452 of the input value. This can be achieved with a <code class="computeroutput"><a class="link" href="../boost/histogram/axis/transform/log.html" title="Struct log">log</a></code> 453 transform. The follow example shows the builtin transforms. 454 </p> 455<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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> 456<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">limits</span><span class="special">></span> 457 458<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span> 459 <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span> 460 461 <span class="comment">// make a regular axis with a log transform over [10, 100), [100, 1000), [1000, 10000)</span> 462 <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special"><</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> 463 <span class="comment">// log transform:</span> 464 <span class="comment">// - useful when values vary dramatically in magnitude, like brightness of stars</span> 465 <span class="comment">// - edges are not exactly at 10, 100, 1000, because of finite floating point precision</span> 466 <span class="comment">// - values >= 0 but smaller than the starting value of the axis are mapped to -1</span> 467 <span class="comment">// - values < 0 are mapped to `size()`, because the result of std::log(value) is NaN</span> 468 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_log</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">10.1</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span> 469 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_log</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">100.1</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span> 470 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_log</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">1000.1</span><span class="special">)</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span> 471 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_log</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="special">-</span><span class="number">1</span><span class="special">);</span> 472 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_log</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="special">-</span><span class="number">1</span><span class="special">);</span> 473 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_log</span><span class="special">.</span><span class="identifier">index</span><span class="special">(-</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">3</span><span class="special">);</span> 474 475 <span class="comment">// make a regular axis with a sqrt transform over [4, 9), [9, 16), [16, 25)</span> 476 <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special"><</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> 477 <span class="comment">// sqrt transform:</span> 478 <span class="comment">// - bin widths are more mildly increasing compared to log transform</span> 479 <span class="comment">// - axis starting at value == 0 is ok, sqrt(0) == 0 unlike log transform</span> 480 <span class="comment">// - values < 0 are mapped to `size()`, because the result of std::sqrt(value) is NaN</span> 481 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_sqrt</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="special">-</span><span class="number">1</span><span class="special">);</span> 482 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_sqrt</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">4.1</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span> 483 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_sqrt</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">9.1</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span> 484 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_sqrt</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">16.1</span><span class="special">)</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span> 485 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_sqrt</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">25.1</span><span class="special">)</span> <span class="special">==</span> <span class="number">3</span><span class="special">);</span> 486 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_sqrt</span><span class="special">.</span><span class="identifier">index</span><span class="special">(-</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">3</span><span class="special">);</span> 487 488 <span class="comment">// make a regular axis with a power transform x^1/3 over [1, 8), [8, 27), [27, 64)</span> 489 <span class="keyword">using</span> <span class="identifier">pow_trans</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">transform</span><span class="special">::</span><span class="identifier">pow</span><span class="special">;</span> 490 <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special"><</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> 491 <span class="comment">// pow transform:</span> 492 <span class="comment">// - generalization of the sqrt transform</span> 493 <span class="comment">// - starting the axis at value == 0 is ok for power p > 0, 0^p == 0 for p > 0</span> 494 <span class="comment">// - values < 0 are mapped to `size()` if power p is not a positive integer</span> 495 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_pow</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="special">-</span><span class="number">1</span><span class="special">);</span> 496 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_pow</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">1.1</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span> 497 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_pow</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">8.1</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span> 498 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_pow</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">27.1</span><span class="special">)</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span> 499 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_pow</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">64.1</span><span class="special">)</span> <span class="special">==</span> <span class="number">3</span><span class="special">);</span> 500 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_pow</span><span class="special">.</span><span class="identifier">index</span><span class="special">(-</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">3</span><span class="special">);</span> 501<span class="special">}</span> 502</pre> 503<p> 504 Due to the finite precision of floating point calculations, the bin edges 505 of a transformed regular axis may not be exactly at the expected values. 506 If you need exact correspondence, use a <code class="computeroutput"><a class="link" href="../boost/histogram/axis/variable.html" title="Class template variable">variable</a></code> 507 axis. 508 </p> 509<p> 510 Users may write their own transforms and use them with the builtin <code class="computeroutput"><a class="link" href="../boost/histogram/axis/regular.html" title="Class template regular">regular</a></code> axis, by implementing 511 a type that matches the <a class="link" href="concepts.html#histogram.concepts.Transform" title="Transform"><span class="bold"><strong>Transform</strong></span> concept</a>. 512 </p> 513</div> 514<div class="section"> 515<div class="titlepage"><div><div><h5 class="title"> 516<a name="histogram.guide.axis_guide.axis_configuration.options"></a><a class="link" href="guide.html#histogram.guide.axis_guide.axis_configuration.options" title="Options">Options</a> 517</h5></div></div></div> 518<p> 519 <code class="computeroutput"><a class="link" href="reference.html#header.boost.histogram.axis.option_hpp" title="Header <boost/histogram/axis/option.hpp>">Options</a></code> 520 can be used to configure each axis type. The option flags are implemented 521 as tag types with the suffix <code class="computeroutput"><span class="identifier">_t</span></code>. 522 Each tag type has a corresponding value without the suffix. The values 523 have set semantics: You can compute the union with <code class="computeroutput"><span class="keyword">operator</span><span class="special">|</span></code> and the intersection with <code class="computeroutput"><span class="keyword">operator</span><span class="special">&</span></code>. 524 When you pass a single option flag to an axis as a template parameter, 525 use the tag type. When you need to pass the union of several options 526 to an axis as a template parameter, surround the union of option values 527 with a <code class="computeroutput"><span class="keyword">decltype</span></code>. Both ways 528 of passing options are shown in the following examples. 529 </p> 530<p> 531 <span class="bold"><strong>Under- and overflow bins</strong></span> 532 </p> 533<p> 534 Under- and overflow bins are added automatically for most axis types. 535 If you create an axis with 10 bins, the histogram will actually have 536 12 bins along that axis. The extra bins are very useful, as explained 537 in the <a class="link" href="rationale.html#histogram.rationale.uoflow" title="Under- and overflow bins">rationale</a>. If 538 the input cannot exceed the axis range or if you are really tight on 539 memory, you can disable the extra bins. A demonstration: 540 </p> 541<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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> 542<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">string</span><span class="special">></span> 543 544<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span> 545 <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span> 546 547 <span class="comment">// create a 1d-histogram over integer values from 1 to 6</span> 548 <span class="keyword">auto</span> <span class="identifier">h1</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special"><</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> 549 <span class="comment">// axis has size 6...</span> 550 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">axis</span><span class="special">().</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">6</span><span class="special">);</span> 551 <span class="comment">// ... but histogram has size 8, because of overflow and underflow bins</span> 552 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">8</span><span class="special">);</span> 553 554 <span class="comment">// create a 1d-histogram for throws of a six-sided die without extra bins,</span> 555 <span class="comment">// since the values cannot be smaller than 1 or larger than 6</span> 556 <span class="keyword">auto</span> <span class="identifier">h2</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special"><</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> 557 <span class="comment">// now size of axis and histogram is equal</span> 558 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">.</span><span class="identifier">axis</span><span class="special">().</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">6</span><span class="special">);</span> 559 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">.</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">6</span><span class="special">);</span> 560<span class="special">}</span> 561</pre> 562<p> 563 The <code class="computeroutput"><a class="link" href="../boost/histogram/axis/category.html" title="Class template category">category</a></code> 564 axis by default comes only with an overflow bin, which counts all input 565 values that are not part of the initial set. 566 </p> 567<p> 568 <span class="bold"><strong>Circular axes</strong></span> 569 </p> 570<p> 571 Each builtin axis except the <code class="computeroutput"><a class="link" href="../boost/histogram/axis/category.html" title="Class template category">category</a></code> 572 axis can be made circular. This means that the axis is periodic at its 573 ends. This is useful if you want make a histogram over a polar angle. 574 Example: 575 </p> 576<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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> 577<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">limits</span><span class="special">></span> 578 579<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span> 580 <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span> 581 582 <span class="comment">// make a circular regular axis ... [0, 180), [180, 360), [0, 180) ....</span> 583 <span class="keyword">using</span> <span class="identifier">opts</span> <span class="special">=</span> <span class="keyword">decltype</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">option</span><span class="special">::</span><span class="identifier">overflow</span> <span class="special">|</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">option</span><span class="special">::</span><span class="identifier">circular</span><span class="special">);</span> 584 <span class="keyword">auto</span> <span class="identifier">r</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special"><</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> 585 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(-</span><span class="number">180</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span> 586 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span> 587 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">180</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span> 588 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">360</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span> 589 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">540</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span> 590 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">720</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span> 591 <span class="comment">// special values are mapped to the overflow bin index</span> 592 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</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> 593 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(-</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</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> 594 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</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> 595 596 <span class="comment">// since the regular axis is the most common circular axis, there exists an alias</span> 597 <span class="keyword">auto</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">circular</span><span class="special"><>{</span><span class="number">2</span><span class="special">,</span> <span class="number">0.</span><span class="special">,</span> <span class="number">360.</span><span class="special">};</span> 598 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span> <span class="special">==</span> <span class="identifier">c</span><span class="special">);</span> 599 600 <span class="comment">// make a circular integer axis</span> 601 <span class="keyword">auto</span> <span class="identifier">i</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special"><</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> 602 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">i</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span> 603 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">i</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span> 604 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">i</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">2</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span> 605 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">i</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">3</span><span class="special">)</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span> 606 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">i</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">4</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span> 607 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">i</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">5</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span> 608<span class="special">}</span> 609</pre> 610<p> 611 A circular axis cannot have an underflow bin, passing both options together 612 generates a compile-time error. Since the highest bin wraps around to 613 the lowest bin, there is no possibility for overflow either. However, 614 an overflow bin is still added by default if the value is a floating 615 point type, to catch NaNs and infinities. 616 </p> 617<p> 618 <span class="bold"><strong>Growing axes</strong></span> 619 </p> 620<p> 621 Each builtin axis has an option to make it grow beyond its initial range 622 when a value outside of that range is passed to it, while the default 623 behaviour is to count this value in the under- or overflow bins (or to 624 discard it). Example: 625 </p> 626<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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> 627<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span> 628 629<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span> 630 631<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span> 632 <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span> 633 634 <span class="comment">// make a growing regular axis</span> 635 <span class="comment">// - it grows new bins with its constant bin width until the value is covered</span> 636 <span class="keyword">auto</span> <span class="identifier">h1</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special"><</span><span class="keyword">double</span><span class="special">,</span> 637 <span class="identifier">use_default</span><span class="special">,</span> 638 <span class="identifier">use_default</span><span class="special">,</span> 639 <span class="identifier">axis</span><span class="special">::</span><span class="identifier">option</span><span class="special">::</span><span class="identifier">growth_t</span><span class="special">>{</span><span class="number">2</span><span class="special">,</span> <span class="number">0.</span><span class="special">,</span> <span class="number">1.</span><span class="special">});</span> 640 <span class="comment">// nothing special happens here</span> 641 <span class="identifier">h1</span><span class="special">(</span><span class="number">0.1</span><span class="special">);</span> 642 <span class="identifier">h1</span><span class="special">(</span><span class="number">0.9</span><span class="special">);</span> 643 <span class="comment">// state: [0, 0.5): 1, [0.5, 1.0): 1</span> 644 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">axis</span><span class="special">().</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span> 645 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">axis</span><span class="special">().</span><span class="identifier">bin</span><span class="special">(</span><span class="number">0</span><span class="special">).</span><span class="identifier">lower</span><span class="special">()</span> <span class="special">==</span> <span class="number">0.0</span><span class="special">);</span> 646 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">axis</span><span class="special">().</span><span class="identifier">bin</span><span class="special">(</span><span class="number">1</span><span class="special">).</span><span class="identifier">upper</span><span class="special">()</span> <span class="special">==</span> <span class="number">1.0</span><span class="special">);</span> 647 648 <span class="comment">// value below range: axis grows new bins until value is in range</span> 649 <span class="identifier">h1</span><span class="special">(-</span><span class="number">0.3</span><span class="special">);</span> 650 <span class="comment">// state: [-0.5, 0.0): 1, [0, 0.5): 1, [0.5, 1.0): 1</span> 651 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">axis</span><span class="special">().</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">3</span><span class="special">);</span> 652 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">axis</span><span class="special">().</span><span class="identifier">bin</span><span class="special">(</span><span class="number">0</span><span class="special">).</span><span class="identifier">lower</span><span class="special">()</span> <span class="special">==</span> <span class="special">-</span><span class="number">0.5</span><span class="special">);</span> 653 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">axis</span><span class="special">().</span><span class="identifier">bin</span><span class="special">(</span><span class="number">2</span><span class="special">).</span><span class="identifier">upper</span><span class="special">()</span> <span class="special">==</span> <span class="number">1.0</span><span class="special">);</span> 654 655 <span class="identifier">h1</span><span class="special">(</span><span class="number">1.9</span><span class="special">);</span> 656 <span class="comment">// state: [-0.5, 0.0): 1, [0, 0.5): 1, [0.5, 1.0): 1, [1.0, 1.5): 0 [1.5, 2.0): 1</span> 657 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">axis</span><span class="special">().</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">5</span><span class="special">);</span> 658 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">axis</span><span class="special">().</span><span class="identifier">bin</span><span class="special">(</span><span class="number">0</span><span class="special">).</span><span class="identifier">lower</span><span class="special">()</span> <span class="special">==</span> <span class="special">-</span><span class="number">0.5</span><span class="special">);</span> 659 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">axis</span><span class="special">().</span><span class="identifier">bin</span><span class="special">(</span><span class="number">4</span><span class="special">).</span><span class="identifier">upper</span><span class="special">()</span> <span class="special">==</span> <span class="number">2.0</span><span class="special">);</span> 660 661 <span class="comment">// make a growing category axis (here strings)</span> 662 <span class="comment">// - empty axis is allowed: very useful if categories are not known at the beginning</span> 663 <span class="keyword">auto</span> <span class="identifier">h2</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">category</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> 664 <span class="identifier">use_default</span><span class="special">,</span> 665 <span class="identifier">axis</span><span class="special">::</span><span class="identifier">option</span><span class="special">::</span><span class="identifier">growth_t</span><span class="special">>());</span> 666 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">.</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span> <span class="comment">// histogram is empty</span> 667 <span class="identifier">h2</span><span class="special">(</span><span class="string">"foo"</span><span class="special">);</span> <span class="comment">// new bin foo, index 0</span> 668 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">.</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span> 669 <span class="identifier">h2</span><span class="special">(</span><span class="string">"bar"</span><span class="special">);</span> <span class="comment">// new bin bar, index 1</span> 670 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">.</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span> 671 <span class="identifier">h2</span><span class="special">(</span><span class="string">"foo"</span><span class="special">);</span> 672 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">.</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span> 673 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">[</span><span class="number">0</span><span class="special">]</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span> 674 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">[</span><span class="number">1</span><span class="special">]</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span> 675<span class="special">}</span> 676</pre> 677<p> 678 This feature can be very convenient, but keep two caveats in mind. 679 </p> 680<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 681<li class="listitem"> 682 Growing axes come with a run-time cost, since the histogram has to 683 reallocate memory for all cells when an axis changes its size. Whether 684 this performance hit is noticeable depends on your application. This 685 is a minor issue, the next is more severe. 686 </li> 687<li class="listitem"> 688 If you have unexpected outliers in your data which are far away from 689 the normal range, the axis could grow to a huge size and the corresponding 690 huge memory request could bring the computer to its knees. This is 691 one of the reason why growing axes are not the default. 692 </li> 693</ul></div> 694<p> 695 A growing axis can have under- and overflow bins, but these only count 696 the special floating point values: positive and negative infinity, and 697 NaN. 698 </p> 699</div> 700</div> 701</div> 702<div class="section"> 703<div class="titlepage"><div><div><h3 class="title"> 704<a name="histogram.guide.filling_histograms_and_accessing"></a><a class="link" href="guide.html#histogram.guide.filling_histograms_and_accessing" title="Filling histograms and accessing cells">Filling 705 histograms and accessing cells</a> 706</h3></div></div></div> 707<p> 708 A histogram has been created and now you want to insert values. This is done 709 with the flexible <code class="computeroutput"><a class="link" href="../boost/histogram/histogram.html#idm45503931925808-bb">call 710 operator</a></code> or the <code class="computeroutput"><a class="link" href="../boost/histogram/histogram.html#idm45503931911152-bb">fill 711 method</a></code>, which you typically call in a loop. The <code class="computeroutput"><a class="link" href="../boost/histogram/histogram.html#idm45503931925808-bb">call operator</a></code> 712 accepts <code class="computeroutput"><span class="identifier">N</span></code> arguments or a 713 <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span></code> with <code class="computeroutput"><span class="identifier">N</span></code> 714 elements, where <code class="computeroutput"><span class="identifier">N</span></code> is equal 715 to the number of axes of the histogram. It finds the corresponding bin for 716 the input and increments the bin counter by one. The <code class="computeroutput"><a class="link" href="../boost/histogram/histogram.html#idm45503931911152-bb">fill 717 method</a></code> accepts a single iterable over other iterables (which 718 must have have elements contiguous in memory) or values, see the method documentation 719 for details. 720 </p> 721<p> 722 After the histogram has been filled, use the <code class="computeroutput"><a class="link" href="../boost/histogram/histogram.html#idm45503931864512-bb">at 723 method</a></code> (in analogy to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">::</span><span class="identifier">at</span></code>) to 724 access the cell values. It accepts integer indices, one for each axis of 725 the histogram. 726 </p> 727<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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> 728<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span> 729<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">functional</span><span class="special">></span> 730<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">numeric</span><span class="special">></span> 731<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">utility</span><span class="special">></span> 732<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">vector</span><span class="special">></span> 733 734<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span> 735 <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span> 736 737 <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special"><>(</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> 738 739 <span class="comment">// fill histogram, number of arguments must be equal to number of axes,</span> 740 <span class="comment">// types must be convertible to axis value type (here integer and double)</span> 741 <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">0.2</span><span class="special">);</span> <span class="comment">// increase a cell value by one</span> 742 <span class="identifier">h</span><span class="special">(</span><span class="number">2</span><span class="special">,</span> <span class="number">0.5</span><span class="special">);</span> <span class="comment">// increase another cell value by one</span> 743 744 <span class="comment">// fills from a tuple are also supported; passing a tuple of wrong size</span> 745 <span class="comment">// causes an error at compile-time or an assertion at runtime in debug mode</span> 746 <span class="keyword">auto</span> <span class="identifier">xy</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_tuple</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">0.3</span><span class="special">);</span> 747 <span class="identifier">h</span><span class="special">(</span><span class="identifier">xy</span><span class="special">);</span> 748 749 <span class="comment">// chunk-wise filling is also supported and more efficient, make some data...</span> 750 <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</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> 751 752 <span class="comment">// ... and call fill method</span> 753 <span class="identifier">h</span><span class="special">.</span><span class="identifier">fill</span><span class="special">(</span><span class="identifier">xy2</span><span class="special">);</span> 754 755 <span class="comment">// once histogram is filled, access individual cells using operator[] or at(...)</span> 756 <span class="comment">// - operator[] can only accept a single argument in the current version of C++,</span> 757 <span class="comment">// it is convenient when you have a 1D histogram</span> 758 <span class="comment">// - at(...) can accept several values, so use this by default</span> 759 <span class="comment">// - underflow bins are at index -1, overflow bins at index `size()`</span> 760 <span class="comment">// - passing an invalid index triggers a std::out_of_range exception</span> 761 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span> 762 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span> 763 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span> 764 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span> 765 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">2</span><span class="special">,</span> <span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span> 766 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">2</span><span class="special">,</span> <span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span> 767 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(-</span><span class="number">1</span><span class="special">,</span> <span class="special">-</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span> <span class="comment">// underflow for axis 0 and 1</span> 768 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(-</span><span class="number">1</span><span class="special">,</span> <span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span> <span class="comment">// underflow for axis 0, normal bin for axis 1</span> 769 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(-</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span> <span class="comment">// underflow for axis 0, overflow for axis 1</span> 770 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">3</span><span class="special">,</span> <span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span> <span class="comment">// overflow for axis 0, normal bin for axis 1</span> 771 772 <span class="comment">// iteration over values works, but see next example for a better way</span> 773 <span class="comment">// - iteration using begin() and end() includes under- and overflow bins</span> 774 <span class="comment">// - iteration order is an implementation detail and should not be relied upon</span> 775 <span class="keyword">const</span> <span class="keyword">double</span> <span class="identifier">sum</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">accumulate</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">h</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="number">0.0</span><span class="special">);</span> 776 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">sum</span> <span class="special">==</span> <span class="number">6</span><span class="special">);</span> 777<span class="special">}</span> 778</pre> 779<p> 780 For a histogram <code class="computeroutput"><span class="identifier">hist</span></code>, the 781 calls <code class="computeroutput"><span class="identifier">hist</span><span class="special">(</span><span class="identifier">weight</span><span class="special">(</span><span class="identifier">w</span><span class="special">),</span> <span class="special">...)</span></code> 782 and <code class="computeroutput"><span class="identifier">hist</span><span class="special">(...,</span> 783 <span class="identifier">weight</span><span class="special">(</span><span class="identifier">w</span><span class="special">))</span></code> increment 784 the bin counter by the value <code class="computeroutput"><span class="identifier">w</span></code> 785 instead, where <code class="computeroutput"><span class="identifier">w</span></code> may be an 786 integer or floating point number. The helper function <code class="computeroutput"><a class="link" href="../boost/histogram/weight.html" title="Function template weight">weight()</a></code> 787 marks this argument as a weight, so that it can be distinguished from the 788 other inputs. It can be the first or last argument. You can freely mix calls 789 with and without a weight. Calls without <code class="computeroutput"><span class="identifier">weight</span></code> 790 act like the weight is <code class="computeroutput"><span class="number">1</span></code>. Why 791 weighted increments are sometimes useful is explained <a class="link" href="rationale.html#histogram.rationale.weights" title="Support of weighted fills">in 792 the rationale</a>. 793 </p> 794<div class="note"><table border="0" summary="Note"> 795<tr> 796<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td> 797<th align="left">Note</th> 798</tr> 799<tr><td align="left" valign="top"><p> 800 The default storage loses its no-overflow-guarantee when you pass floating 801 point weights, but maintains it for integer weights. 802 </p></td></tr> 803</table></div> 804<p> 805 When the weights come from a stochastic process, it is useful to keep track 806 of the variance of the sum of weights per cell. A specialized histogram can 807 be generated with the <code class="computeroutput"><a class="link" href="../boost/histogram/make_wei_idm45503931624016.html" title="Function template make_weighted_histogram">make_weighted_histogram</a></code> 808 factory function which does that. 809 </p> 810<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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> 811<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span> 812 813<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span> 814 <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span> 815 816 <span class="comment">// Create a histogram with weight counters that keep track of a variance estimate.</span> 817 <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_weighted_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special"><>(</span><span class="number">3</span><span class="special">,</span> <span class="number">0.0</span><span class="special">,</span> <span class="number">1.0</span><span class="special">));</span> 818 819 <span class="identifier">h</span><span class="special">(</span><span class="number">0.0</span><span class="special">,</span> <span class="identifier">weight</span><span class="special">(</span><span class="number">1</span><span class="special">));</span> <span class="comment">// weight 1 goes to first bin</span> 820 <span class="identifier">h</span><span class="special">(</span><span class="number">0.1</span><span class="special">,</span> <span class="identifier">weight</span><span class="special">(</span><span class="number">2</span><span class="special">));</span> <span class="comment">// weight 2 goes to first bin</span> 821 <span class="identifier">h</span><span class="special">(</span><span class="number">0.4</span><span class="special">,</span> <span class="identifier">weight</span><span class="special">(</span><span class="number">3</span><span class="special">));</span> <span class="comment">// weight 3 goes to second bin</span> 822 <span class="identifier">h</span><span class="special">(</span><span class="number">0.5</span><span class="special">,</span> <span class="identifier">weight</span><span class="special">(</span><span class="number">4</span><span class="special">));</span> <span class="comment">// weight 4 goes to second bin</span> 823 824 <span class="comment">// chunk-wise filling is also supported</span> 825 <span class="keyword">auto</span> <span class="identifier">x</span> <span class="special">=</span> <span class="special">{</span><span class="number">0.2</span><span class="special">,</span> <span class="number">0.6</span><span class="special">};</span> 826 <span class="keyword">auto</span> <span class="identifier">w</span> <span class="special">=</span> <span class="special">{</span><span class="number">5</span><span class="special">,</span> <span class="number">6</span><span class="special">};</span> 827 <span class="identifier">h</span><span class="special">.</span><span class="identifier">fill</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span> <span class="identifier">weight</span><span class="special">(</span><span class="identifier">w</span><span class="special">));</span> 828 829 <span class="comment">// Weight counters have methods to access the value (sum of weights) and the variance</span> 830 <span class="comment">// (sum of weights squared, why this gives the variance is explained in the rationale)</span> 831 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">[</span><span class="number">0</span><span class="special">].</span><span class="identifier">value</span><span class="special">()</span> <span class="special">==</span> <span class="number">1</span> <span class="special">+</span> <span class="number">2</span> <span class="special">+</span> <span class="number">5</span><span class="special">);</span> 832 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">[</span><span class="number">0</span><span class="special">].</span><span class="identifier">variance</span><span class="special">()</span> <span class="special">==</span> <span class="number">1</span> <span class="special">*</span> <span class="number">1</span> <span class="special">+</span> <span class="number">2</span> <span class="special">*</span> <span class="number">2</span> <span class="special">+</span> <span class="number">5</span> <span class="special">*</span> <span class="number">5</span><span class="special">);</span> 833 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">[</span><span class="number">1</span><span class="special">].</span><span class="identifier">value</span><span class="special">()</span> <span class="special">==</span> <span class="number">3</span> <span class="special">+</span> <span class="number">4</span> <span class="special">+</span> <span class="number">6</span><span class="special">);</span> 834 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">[</span><span class="number">1</span><span class="special">].</span><span class="identifier">variance</span><span class="special">()</span> <span class="special">==</span> <span class="number">3</span> <span class="special">*</span> <span class="number">3</span> <span class="special">+</span> <span class="number">4</span> <span class="special">*</span> <span class="number">4</span> <span class="special">+</span> <span class="number">6</span> <span class="special">*</span> <span class="number">6</span><span class="special">);</span> 835<span class="special">}</span> 836</pre> 837<p> 838 To iterate over all cells, the <code class="computeroutput"><a class="link" href="../boost/histogram/indexed.html" title="Function template indexed">indexed</a></code> 839 range generator is very convenient and also efficient. For almost all configurations, 840 the range generator iterates <span class="emphasis"><em>faster</em></span> than a naive for-loop. 841 Under- and overflow are skipped by default. 842 </p> 843<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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> 844<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> 845<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span> 846<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span> 847<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> 848<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">sstream</span><span class="special">></span> 849 850<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span> 851 852<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span> 853 <span class="comment">// make histogram with 2 x 2 = 4 bins (not counting under-/overflow bins)</span> 854 <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special"><>(</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> 855 856 <span class="identifier">h</span><span class="special">(</span><span class="identifier">weight</span><span class="special">(</span><span class="number">1</span><span class="special">),</span> <span class="special">-</span><span class="number">0.5</span><span class="special">,</span> <span class="number">2.5</span><span class="special">);</span> <span class="comment">// bin index 0, 0</span> 857 <span class="identifier">h</span><span class="special">(</span><span class="identifier">weight</span><span class="special">(</span><span class="number">2</span><span class="special">),</span> <span class="special">-</span><span class="number">0.5</span><span class="special">,</span> <span class="number">3.5</span><span class="special">);</span> <span class="comment">// bin index 0, 1</span> 858 <span class="identifier">h</span><span class="special">(</span><span class="identifier">weight</span><span class="special">(</span><span class="number">3</span><span class="special">),</span> <span class="number">0.5</span><span class="special">,</span> <span class="number">2.5</span><span class="special">);</span> <span class="comment">// bin index 1, 0</span> 859 <span class="identifier">h</span><span class="special">(</span><span class="identifier">weight</span><span class="special">(</span><span class="number">4</span><span class="special">),</span> <span class="number">0.5</span><span class="special">,</span> <span class="number">3.5</span><span class="special">);</span> <span class="comment">// bin index 1, 1</span> 860 861 <span class="comment">// use the `indexed` range adaptor to iterate over all bins;</span> 862 <span class="comment">// it is not only more convenient but also faster than a hand-crafted loop!</span> 863 <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os</span><span class="special">;</span> 864 <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&&</span> <span class="identifier">x</span> <span class="special">:</span> <span class="identifier">indexed</span><span class="special">(</span><span class="identifier">h</span><span class="special">))</span> <span class="special">{</span> 865 <span class="comment">// x is a special accessor object</span> 866 <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">i</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">0</span><span class="special">);</span> <span class="comment">// current index along first axis</span> 867 <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">j</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">1</span><span class="special">);</span> <span class="comment">// current index along second axis</span> 868 <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">b0</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">bin</span><span class="special">(</span><span class="number">0</span><span class="special">);</span> <span class="comment">// current bin interval along first axis</span> 869 <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">b1</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">bin</span><span class="special">(</span><span class="number">1</span><span class="special">);</span> <span class="comment">// current bin interval along second axis</span> 870 <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">v</span> <span class="special">=</span> <span class="special">*</span><span class="identifier">x</span><span class="special">;</span> <span class="comment">// "dereference" to get the bin value</span> 871 <span class="identifier">os</span> <span class="special"><<</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">format</span><span class="special">(</span><span class="string">"%i %i [%2i, %i) [%2i, %i): %i\n"</span><span class="special">)</span> <span class="special">%</span> <span class="identifier">i</span> <span class="special">%</span> <span class="identifier">j</span> <span class="special">%</span> <span class="identifier">b0</span><span class="special">.</span><span class="identifier">lower</span><span class="special">()</span> <span class="special">%</span> 872 <span class="identifier">b0</span><span class="special">.</span><span class="identifier">upper</span><span class="special">()</span> <span class="special">%</span> <span class="identifier">b1</span><span class="special">.</span><span class="identifier">lower</span><span class="special">()</span> <span class="special">%</span> <span class="identifier">b1</span><span class="special">.</span><span class="identifier">upper</span><span class="special">()</span> <span class="special">%</span> <span class="identifier">v</span><span class="special">;</span> 873 <span class="special">}</span> 874 875 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</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> 876 877 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span> <span class="string">"0 0 [-1, 0) [ 2, 3): 1\n"</span> 878 <span class="string">"1 0 [ 0, 1) [ 2, 3): 3\n"</span> 879 <span class="string">"0 1 [-1, 0) [ 3, 4): 2\n"</span> 880 <span class="string">"1 1 [ 0, 1) [ 3, 4): 4\n"</span><span class="special">);</span> 881 882 <span class="comment">// `indexed` skips underflow and overflow bins by default, but can be called</span> 883 <span class="comment">// with the second argument `coverage::all` to walk over all bins</span> 884 <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os2</span><span class="special">;</span> 885 <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&&</span> <span class="identifier">x</span> <span class="special">:</span> <span class="identifier">indexed</span><span class="special">(</span><span class="identifier">h</span><span class="special">,</span> <span class="identifier">coverage</span><span class="special">::</span><span class="identifier">all</span><span class="special">))</span> <span class="special">{</span> 886 <span class="identifier">os2</span> <span class="special"><<</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">format</span><span class="special">(</span><span class="string">"%2i %2i: %i\n"</span><span class="special">)</span> <span class="special">%</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">%</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">%</span> <span class="special">*</span><span class="identifier">x</span><span class="special">;</span> 887 <span class="special">}</span> 888 889 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</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> 890 891 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">os2</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span> <span class="string">"-1 -1: 0\n"</span> 892 <span class="string">" 0 -1: 0\n"</span> 893 <span class="string">" 1 -1: 0\n"</span> 894 <span class="string">" 2 -1: 0\n"</span> 895 896 <span class="string">"-1 0: 0\n"</span> 897 <span class="string">" 0 0: 1\n"</span> 898 <span class="string">" 1 0: 3\n"</span> 899 <span class="string">" 2 0: 0\n"</span> 900 901 <span class="string">"-1 1: 0\n"</span> 902 <span class="string">" 0 1: 2\n"</span> 903 <span class="string">" 1 1: 4\n"</span> 904 <span class="string">" 2 1: 0\n"</span> 905 906 <span class="string">"-1 2: 0\n"</span> 907 <span class="string">" 0 2: 0\n"</span> 908 <span class="string">" 1 2: 0\n"</span> 909 <span class="string">" 2 2: 0\n"</span><span class="special">);</span> 910<span class="special">}</span> 911</pre> 912</div> 913<div class="section"> 914<div class="titlepage"><div><div><h3 class="title"> 915<a name="histogram.guide.using_profiles"></a><a class="link" href="guide.html#histogram.guide.using_profiles" title="Using profiles">Using profiles</a> 916</h3></div></div></div> 917<p> 918 Histograms from this library can do more than counting, they can hold arbitrary 919 accumulators which accept samples. We call a histogram with accumulators 920 that compute the mean of samples in each cell a <span class="emphasis"><em>profile</em></span>. 921 Profiles can be generated with the factory function <code class="computeroutput"><a class="link" href="../boost/histogram/make_pro_idm45503931608944.html" title="Function template make_profile">make_profile</a></code>. 922 </p> 923<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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> 924<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> 925<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span> 926<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span> 927<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">sstream</span><span class="special">></span> 928<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">tuple</span><span class="special">></span> 929 930<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span> 931 <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span> 932 933 <span class="comment">// make a profile, it computes the mean of the samples in each histogram cell</span> 934 <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_profile</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special"><>(</span><span class="number">0</span><span class="special">,</span> <span class="number">3</span><span class="special">));</span> 935 936 <span class="comment">// mean is computed from the values marked with the sample() helper function</span> 937 <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">1</span><span class="special">));</span> <span class="comment">// sample goes to cell 0</span> 938 <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">2</span><span class="special">));</span> <span class="comment">// sample goes to cell 0</span> 939 <span class="identifier">h</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">3</span><span class="special">));</span> <span class="comment">// sample goes to cell 1</span> 940 <span class="identifier">h</span><span class="special">(</span><span class="identifier">sample</span><span class="special">(</span><span class="number">4</span><span class="special">),</span> <span class="number">1</span><span class="special">);</span> <span class="comment">// sample goes to cell 1; sample can be first or last argument</span> 941 942 <span class="comment">// fills from tuples are also supported, 5 and 6 go to cell 2</span> 943 <span class="keyword">auto</span> <span class="identifier">a</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_tuple</span><span class="special">(</span><span class="number">2</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">5</span><span class="special">));</span> 944 <span class="keyword">auto</span> <span class="identifier">b</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_tuple</span><span class="special">(</span><span class="identifier">sample</span><span class="special">(</span><span class="number">6</span><span class="special">),</span> <span class="number">2</span><span class="special">);</span> 945 <span class="identifier">h</span><span class="special">(</span><span class="identifier">a</span><span class="special">);</span> 946 <span class="identifier">h</span><span class="special">(</span><span class="identifier">b</span><span class="special">);</span> 947 948 <span class="comment">// builtin accumulators have methods to access their state</span> 949 <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os</span><span class="special">;</span> 950 <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&&</span> <span class="identifier">x</span> <span class="special">:</span> <span class="identifier">indexed</span><span class="special">(</span><span class="identifier">h</span><span class="special">))</span> <span class="special">{</span> 951 <span class="comment">// use `.` to access methods of accessor, like `index()`</span> 952 <span class="comment">// use `->` to access methods of accumulator</span> 953 <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">i</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">index</span><span class="special">();</span> 954 <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">n</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">-></span><span class="identifier">count</span><span class="special">();</span> <span class="comment">// how many samples are in this bin</span> 955 <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">vl</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">-></span><span class="identifier">value</span><span class="special">();</span> <span class="comment">// mean value</span> 956 <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">vr</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">-></span><span class="identifier">variance</span><span class="special">();</span> <span class="comment">// estimated variance of the mean value</span> 957 <span class="identifier">os</span> <span class="special"><<</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">format</span><span class="special">(</span><span class="string">"index %i count %i value %.1f variance %.1f\n"</span><span class="special">)</span> <span class="special">%</span> <span class="identifier">i</span> <span class="special">%</span> <span class="identifier">n</span> <span class="special">%</span> <span class="identifier">vl</span> <span class="special">%</span> <span class="identifier">vr</span><span class="special">;</span> 958 <span class="special">}</span> 959 960 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</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> 961 962 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span> <span class="string">"index 0 count 2 value 1.5 variance 0.5\n"</span> 963 <span class="string">"index 1 count 2 value 3.5 variance 0.5\n"</span> 964 <span class="string">"index 2 count 2 value 5.5 variance 0.5\n"</span><span class="special">);</span> 965<span class="special">}</span> 966</pre> 967<p> 968 Just like <code class="computeroutput"><a class="link" href="../boost/histogram/weight.html" title="Function template weight">weight()</a></code>, 969 <code class="computeroutput"><a class="link" href="../boost/histogram/sample.html" title="Function template sample">sample()</a></code> is a 970 marker function. It must be the first or last argument. 971 </p> 972<p> 973 Weights and samples may be combined, if the accumulators can handle weights. 974 When both <code class="computeroutput"><a class="link" href="../boost/histogram/weight.html" title="Function template weight">weight()</a></code> 975 and <code class="computeroutput"><a class="link" href="../boost/histogram/sample.html" title="Function template sample">sample()</a></code> 976 appear in the <code class="computeroutput"><a class="link" href="../boost/histogram/histogram.html#idm45503931925808-bb">call 977 operator</a></code> or the <code class="computeroutput"><a class="link" href="../boost/histogram/histogram.html#idm45503931911152-bb">fill 978 method</a></code>, they can be in any order with respect to other, but 979 they must be the first or last arguments. To make a profile which can compute 980 weighted means with proper uncertainty estimates, use the <code class="computeroutput"><a class="link" href="../boost/histogram/make_wei_idm45503931596384.html" title="Function template make_weighted_profile">make_weighted_profile</a></code> 981 factory function. 982 </p> 983<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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> 984<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> 985<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span> 986<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span> 987<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">sstream</span><span class="special">></span> 988 989<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span> 990 <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span> 991 <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">literals</span><span class="special">;</span> <span class="comment">// _c suffix creates compile-time numbers</span> 992 993 <span class="comment">// make 2D weighted profile</span> 994 <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_weighted_profile</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special"><>(</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> 995 996 <span class="comment">// The mean is computed from the values marked with the sample() helper function.</span> 997 <span class="comment">// Weights can be passed as well. The `sample` and `weight` arguments can appear in any</span> 998 <span class="comment">// order, but they must be the first or last arguments.</span> 999 <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">1</span><span class="special">));</span> <span class="comment">// sample goes to cell (0, 0); weight is 1</span> 1000 <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">2</span><span class="special">),</span> <span class="identifier">weight</span><span class="special">(</span><span class="number">3</span><span class="special">));</span> <span class="comment">// sample goes to cell (0, 0); weight is 3</span> 1001 <span class="identifier">h</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">3</span><span class="special">));</span> <span class="comment">// sample goes to cell (1, 0); weight is 1</span> 1002 <span class="identifier">h</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">4</span><span class="special">));</span> <span class="comment">// sample goes to cell (1, 0); weight is 1</span> 1003 <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">5</span><span class="special">));</span> <span class="comment">// sample goes to cell (1, 0); weight is 1</span> 1004 <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">6</span><span class="special">));</span> <span class="comment">// sample goes to cell (1, 0); weight is 1</span> 1005 <span class="identifier">h</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="identifier">weight</span><span class="special">(</span><span class="number">4</span><span class="special">),</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">7</span><span class="special">));</span> <span class="comment">// sample goes to cell (1, 1); weight is 4</span> 1006 <span class="identifier">h</span><span class="special">(</span><span class="identifier">weight</span><span class="special">(</span><span class="number">5</span><span class="special">),</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">8</span><span class="special">),</span> <span class="number">1</span><span class="special">,</span> <span class="number">1</span><span class="special">);</span> <span class="comment">// sample goes to cell (1, 1); weight is 5</span> 1007 1008 <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os</span><span class="special">;</span> 1009 <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&&</span> <span class="identifier">x</span> <span class="special">:</span> <span class="identifier">indexed</span><span class="special">(</span><span class="identifier">h</span><span class="special">))</span> <span class="special">{</span> 1010 <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">i</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">0</span><span class="identifier">_c</span><span class="special">);</span> 1011 <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">j</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">1</span><span class="identifier">_c</span><span class="special">);</span> 1012 <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">m</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">-></span><span class="identifier">value</span><span class="special">();</span> <span class="comment">// weighted mean</span> 1013 <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">v</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">-></span><span class="identifier">variance</span><span class="special">();</span> <span class="comment">// estimated variance of weighted mean</span> 1014 <span class="identifier">os</span> <span class="special"><<</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">format</span><span class="special">(</span><span class="string">"index %i,%i mean %.1f variance %.1f\n"</span><span class="special">)</span> <span class="special">%</span> <span class="identifier">i</span> <span class="special">%</span> <span class="identifier">j</span> <span class="special">%</span> <span class="identifier">m</span> <span class="special">%</span> <span class="identifier">v</span><span class="special">;</span> 1015 <span class="special">}</span> 1016 1017 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</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> 1018 1019 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span> <span class="string">"index 0,0 mean 1.8 variance 0.5\n"</span> 1020 <span class="string">"index 1,0 mean 3.5 variance 0.5\n"</span> 1021 <span class="string">"index 0,1 mean 5.5 variance 0.5\n"</span> 1022 <span class="string">"index 1,1 mean 7.6 variance 0.5\n"</span><span class="special">);</span> 1023<span class="special">}</span> 1024</pre> 1025</div> 1026<div class="section"> 1027<div class="titlepage"><div><div><h3 class="title"> 1028<a name="histogram.guide.using_operators"></a><a class="link" href="guide.html#histogram.guide.using_operators" title="Using operators">Using operators</a> 1029</h3></div></div></div> 1030<p> 1031 The following operators are supported for pairs of histograms <code class="computeroutput"><span class="special">+,</span> <span class="special">-,</span> <span class="special">*,</span> 1032 <span class="special">/,</span> <span class="special">==,</span> <span class="special">!=</span></code>. Histograms can also be multiplied and 1033 divided by a scalar. Only a subset of the arithmetic operators is available 1034 when the underlying accumulator only supports that subset. 1035 </p> 1036<p> 1037 The arithmetic operators can only be used when the histograms have the same 1038 axis configuration. This checked at run-time. An exception is thrown if the 1039 configurations do not match. Two histograms have the same axis configuration, 1040 if all axes compare equal, which includes a comparison of their metadata. 1041 Two histograms compare equal, when their axis configurations and all their 1042 cell values compare equal. 1043 </p> 1044<div class="note"><table border="0" summary="Note"> 1045<tr> 1046<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td> 1047<th align="left">Note</th> 1048</tr> 1049<tr><td align="left" valign="top"><p> 1050 If the metadata type has <code class="computeroutput"><span class="keyword">operator</span><span class="special">==</span></code> defined, it is used in the axis configuration 1051 comparison. Metadata types without <code class="computeroutput"><span class="keyword">operator</span><span class="special">==</span></code> are considered equal, if they are the 1052 same type. 1053 </p></td></tr> 1054</table></div> 1055<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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> 1056<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span> 1057<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">vector</span><span class="special">></span> 1058 1059<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span> 1060 <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span> 1061 1062 <span class="comment">// make two histograms</span> 1063 <span class="keyword">auto</span> <span class="identifier">h1</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special"><>(</span><span class="number">2</span><span class="special">,</span> <span class="special">-</span><span class="number">1.0</span><span class="special">,</span> <span class="number">1.0</span><span class="special">));</span> 1064 <span class="keyword">auto</span> <span class="identifier">h2</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special"><>(</span><span class="number">2</span><span class="special">,</span> <span class="special">-</span><span class="number">1.0</span><span class="special">,</span> <span class="number">1.0</span><span class="special">));</span> 1065 1066 <span class="identifier">h1</span><span class="special">(-</span><span class="number">0.5</span><span class="special">);</span> <span class="comment">// counts are: 1 0</span> 1067 <span class="identifier">h2</span><span class="special">(</span><span class="number">0.5</span><span class="special">);</span> <span class="comment">// counts are: 0 1</span> 1068 1069 <span class="comment">// add them</span> 1070 <span class="keyword">auto</span> <span class="identifier">h3</span> <span class="special">=</span> <span class="identifier">h1</span><span class="special">;</span> 1071 <span class="identifier">h3</span> <span class="special">+=</span> <span class="identifier">h2</span><span class="special">;</span> <span class="comment">// counts are: 1 1</span> 1072 1073 <span class="comment">// adding multiple histograms at once is likely to be optimized by the compiler so that</span> 1074 <span class="comment">// superfluous temporaries avoided, but no guarantees are given; use this equivalent</span> 1075 <span class="comment">// code when you want to make sure: h4 = h1; h4 += h2; h4 += h3;</span> 1076 <span class="keyword">auto</span> <span class="identifier">h4</span> <span class="special">=</span> <span class="identifier">h1</span> <span class="special">+</span> <span class="identifier">h2</span> <span class="special">+</span> <span class="identifier">h3</span><span class="special">;</span> <span class="comment">// counts are: 2 2</span> 1077 1078 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h4</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">2</span> <span class="special">&&</span> <span class="identifier">h4</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span> 1079 1080 <span class="comment">// multiply by number, h4 *= 2 also works</span> 1081 <span class="keyword">auto</span> <span class="identifier">h5</span> <span class="special">=</span> <span class="identifier">h4</span> <span class="special">*</span> <span class="number">2</span><span class="special">;</span> <span class="comment">// counts are: 4 4</span> 1082 1083 <span class="comment">// divide by number; s4 /= 4 also works</span> 1084 <span class="keyword">auto</span> <span class="identifier">h6</span> <span class="special">=</span> <span class="identifier">h5</span> <span class="special">/</span> <span class="number">4</span><span class="special">;</span> <span class="comment">// counts are: 1 1</span> 1085 1086 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h6</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span> <span class="special">&&</span> <span class="identifier">h6</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span> 1087 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h6</span> <span class="special">!=</span> <span class="identifier">h5</span> <span class="special">&&</span> <span class="identifier">h5</span> <span class="special">==</span> <span class="number">4</span> <span class="special">*</span> <span class="identifier">h6</span><span class="special">);</span> 1088 1089 <span class="comment">// note the special effect of multiplication on weight_storage</span> 1090 <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram_with</span><span class="special">(</span><span class="identifier">weight_storage</span><span class="special">(),</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special"><>(</span><span class="number">2</span><span class="special">,</span> <span class="special">-</span><span class="number">1.0</span><span class="special">,</span> <span class="number">1.0</span><span class="special">));</span> 1091 <span class="identifier">h</span><span class="special">(-</span><span class="number">0.5</span><span class="special">);</span> 1092 1093 <span class="comment">// counts are: 1 0</span> 1094 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">).</span><span class="identifier">value</span><span class="special">()</span> <span class="special">==</span> <span class="number">1</span> <span class="special">&&</span> <span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">1</span><span class="special">).</span><span class="identifier">value</span><span class="special">()</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span> 1095 1096 <span class="keyword">auto</span> <span class="identifier">h_sum</span> <span class="special">=</span> <span class="identifier">h</span> <span class="special">+</span> <span class="identifier">h</span><span class="special">;</span> 1097 <span class="keyword">auto</span> <span class="identifier">h_mul</span> <span class="special">=</span> <span class="number">2</span> <span class="special">*</span> <span class="identifier">h</span><span class="special">;</span> 1098 1099 <span class="comment">// values are the same as expected...</span> 1100 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h_sum</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">).</span><span class="identifier">value</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">h_mul</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">).</span><span class="identifier">value</span><span class="special">());</span> 1101 <span class="comment">// ... but variances differ</span> 1102 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h_sum</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">).</span><span class="identifier">variance</span><span class="special">()</span> <span class="special">==</span> <span class="number">2</span> <span class="special">&&</span> <span class="identifier">h_mul</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">).</span><span class="identifier">variance</span><span class="special">()</span> <span class="special">==</span> <span class="number">4</span><span class="special">);</span> 1103 1104 <span class="comment">// equality operator checks variances, so histograms are not equal</span> 1105 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h_sum</span> <span class="special">!=</span> <span class="identifier">h_mul</span><span class="special">);</span> 1106<span class="special">}</span> 1107</pre> 1108<div class="note"><table border="0" summary="Note"> 1109<tr> 1110<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td> 1111<th align="left">Note</th> 1112</tr> 1113<tr><td align="left" valign="top"><p> 1114 A histogram with default storage converts its cell values to double when 1115 they are to be multiplied with or divided by a real number, or when a real 1116 number is added or subtracted. At this point the no-overflow-guarantee 1117 is lost. 1118 </p></td></tr> 1119</table></div> 1120<div class="note"><table border="0" summary="Note"> 1121<tr> 1122<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td> 1123<th align="left">Note</th> 1124</tr> 1125<tr><td align="left" valign="top"><p> 1126 When the storage tracks weight variances, such as <code class="computeroutput"><a class="link" href="reference.html#boost.histogram.weight_storage">boost::histogram::weight_storage</a></code>, 1127 adding two copies of a histogram produces a different result than scaling 1128 the histogram by a factor of two, as shown in the last example. The is 1129 a consequence of the mathematical properties of variances. They can be 1130 added like normal numbers, but scaling by <code class="computeroutput"><span class="identifier">s</span></code> 1131 means that variances are scaled by <code class="computeroutput"><span class="identifier">s</span><span class="special">^</span><span class="number">2</span></code>. 1132 </p></td></tr> 1133</table></div> 1134</div> 1135<div class="section"> 1136<div class="titlepage"><div><div><h3 class="title"> 1137<a name="histogram.guide.using_algorithms"></a><a class="link" href="guide.html#histogram.guide.using_algorithms" title="Using algorithms">Using algorithms</a> 1138</h3></div></div></div> 1139<div class="toc"><dl class="toc"> 1140<dt><span class="section"><a href="guide.html#histogram.guide.using_algorithms.algorithms_from_the_c_standard_l">Algorithms 1141 from the C++ standard library</a></span></dt> 1142<dt><span class="section"><a href="guide.html#histogram.guide.using_algorithms.summation">Summation</a></span></dt> 1143<dt><span class="section"><a href="guide.html#histogram.guide.using_algorithms.projection">Projection</a></span></dt> 1144<dt><span class="section"><a href="guide.html#histogram.guide.using_algorithms.reduction">Reduction</a></span></dt> 1145</dl></div> 1146<p> 1147 The library was designed to work with algorithms from the C++ standard library. 1148 In addition, a support library of algorithms is included with common operations 1149 on histograms. 1150 </p> 1151<div class="section"> 1152<div class="titlepage"><div><div><h4 class="title"> 1153<a name="histogram.guide.using_algorithms.algorithms_from_the_c_standard_l"></a><a class="link" href="guide.html#histogram.guide.using_algorithms.algorithms_from_the_c_standard_l" title="Algorithms from the C++ standard library">Algorithms 1154 from the C++ standard library</a> 1155</h4></div></div></div> 1156<p> 1157 The histogram class has standard random-access iterators which can be used 1158 with various algorithms from the standard library. Some things need to 1159 be kept in mind: 1160 </p> 1161<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 1162<li class="listitem"> 1163 The histogram iterators also walk over the under- and overflow bins, 1164 if they are present. To skip the extra bins one should use the fast 1165 iterators from the <code class="computeroutput"><a class="link" href="../boost/histogram/indexed.html" title="Function template indexed">boost::histogram::indexed</a></code> 1166 range generator instead. 1167 </li> 1168<li class="listitem"> 1169 The iteration order for histograms with several axes is an implementation-detail, 1170 but for histograms with one axis it is guaranteed to be the obvious 1171 order: bins are accessed in order from the lowest to the highest index. 1172 </li> 1173</ul></div> 1174<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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> 1175<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span> 1176 1177<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> 1178<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cmath</span><span class="special">></span> <span class="comment">// sqrt</span> 1179<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> 1180 1181<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span> 1182 <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span> 1183 1184 <span class="comment">// make histogram that represents a probability density function (PDF)</span> 1185 <span class="keyword">auto</span> <span class="identifier">h1</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special"><>(</span><span class="number">4</span><span class="special">,</span> <span class="number">1.0</span><span class="special">,</span> <span class="number">3.0</span><span class="special">));</span> 1186 1187 <span class="comment">// make indexed range to skip underflow and overflow cells</span> 1188 <span class="keyword">auto</span> <span class="identifier">ind</span> <span class="special">=</span> <span class="identifier">indexed</span><span class="special">(</span><span class="identifier">h1</span><span class="special">);</span> 1189 1190 <span class="comment">// use std::fill to set all counters to 0.25 (except under- and overflow counters)</span> 1191 <span class="identifier">std</span><span class="special">::</span><span class="identifier">fill</span><span class="special">(</span><span class="identifier">ind</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">ind</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="number">0.25</span><span class="special">);</span> 1192 1193 <span class="comment">// compute the cumulative density function (CDF), overriding cell values</span> 1194 <span class="identifier">std</span><span class="special">::</span><span class="identifier">partial_sum</span><span class="special">(</span><span class="identifier">ind</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">ind</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="identifier">ind</span><span class="special">.</span><span class="identifier">begin</span><span class="special">());</span> 1195 1196 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">at</span><span class="special">(-</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">0.00</span><span class="special">);</span> 1197 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">0.25</span><span class="special">);</span> 1198 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">0.50</span><span class="special">);</span> 1199 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">2</span><span class="special">)</span> <span class="special">==</span> <span class="number">0.75</span><span class="special">);</span> 1200 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">3</span><span class="special">)</span> <span class="special">==</span> <span class="number">1.00</span><span class="special">);</span> 1201 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">4</span><span class="special">)</span> <span class="special">==</span> <span class="number">0.00</span><span class="special">);</span> 1202 1203 <span class="comment">// use any_of to check if any cell values are smaller than 0.1,</span> 1204 <span class="keyword">auto</span> <span class="identifier">b</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">any_of</span><span class="special">(</span><span class="identifier">ind</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">ind</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="special">[](</span><span class="keyword">const</span> <span class="keyword">auto</span><span class="special">&</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> 1205 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">b</span> <span class="special">==</span> <span class="keyword">false</span><span class="special">);</span> <span class="comment">// under- and overflow cells are zero, but skipped</span> 1206 1207 <span class="comment">// find minimum element</span> 1208 <span class="keyword">auto</span> <span class="identifier">min_it</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">min_element</span><span class="special">(</span><span class="identifier">ind</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">ind</span><span class="special">.</span><span class="identifier">end</span><span class="special">());</span> 1209 <span class="identifier">assert</span><span class="special">(*</span><span class="identifier">min_it</span> <span class="special">==</span> <span class="number">0.25</span><span class="special">);</span> <span class="comment">// under- and overflow cells are skipped</span> 1210 1211 <span class="comment">// find maximum element</span> 1212 <span class="keyword">auto</span> <span class="identifier">max_it</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">max_element</span><span class="special">(</span><span class="identifier">ind</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">ind</span><span class="special">.</span><span class="identifier">end</span><span class="special">());</span> 1213 <span class="identifier">assert</span><span class="special">(*</span><span class="identifier">max_it</span> <span class="special">==</span> <span class="number">1.0</span><span class="special">);</span> 1214 1215 <span class="comment">// make second PDF</span> 1216 <span class="keyword">auto</span> <span class="identifier">h2</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special"><>(</span><span class="number">4</span><span class="special">,</span> <span class="number">1.0</span><span class="special">,</span> <span class="number">4.0</span><span class="special">));</span> 1217 <span class="identifier">h2</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">=</span> <span class="number">0.1</span><span class="special">;</span> 1218 <span class="identifier">h2</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">=</span> <span class="number">0.3</span><span class="special">;</span> 1219 <span class="identifier">h2</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">2</span><span class="special">)</span> <span class="special">=</span> <span class="number">0.2</span><span class="special">;</span> 1220 <span class="identifier">h2</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">3</span><span class="special">)</span> <span class="special">=</span> <span class="number">0.4</span><span class="special">;</span> 1221 1222 <span class="comment">// computing cosine similiarity: cos(theta) = A dot B / sqrt((A dot A) * (B dot B))</span> 1223 <span class="keyword">auto</span> <span class="identifier">ind2</span> <span class="special">=</span> <span class="identifier">indexed</span><span class="special">(</span><span class="identifier">h2</span><span class="special">);</span> 1224 <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">aa</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">inner_product</span><span class="special">(</span><span class="identifier">ind</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">ind</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="identifier">ind</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="number">0.0</span><span class="special">);</span> 1225 <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">bb</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">inner_product</span><span class="special">(</span><span class="identifier">ind2</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">ind2</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="identifier">ind2</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="number">0.0</span><span class="special">);</span> 1226 <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">ab</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">inner_product</span><span class="special">(</span><span class="identifier">ind</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">ind</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="identifier">ind2</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="number">0.0</span><span class="special">);</span> 1227 <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">cos_sim</span> <span class="special">=</span> <span class="identifier">ab</span> <span class="special">/</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">sqrt</span><span class="special">(</span><span class="identifier">aa</span> <span class="special">*</span> <span class="identifier">bb</span><span class="special">);</span> 1228 1229 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">abs</span><span class="special">(</span><span class="identifier">cos_sim</span> <span class="special">-</span> <span class="number">0.967</span><span class="special">)</span> <span class="special"><</span> <span class="number">1e-2</span><span class="special">);</span> 1230<span class="special">}</span> 1231</pre> 1232</div> 1233<div class="section"> 1234<div class="titlepage"><div><div><h4 class="title"> 1235<a name="histogram.guide.using_algorithms.summation"></a><a class="link" href="guide.html#histogram.guide.using_algorithms.summation" title="Summation">Summation</a> 1236</h4></div></div></div> 1237<p> 1238 It is easy to iterate over all histogram cells to compute the sum of cell 1239 values by hand or to use an algorithm from the standard library to do so, 1240 but it is not safe. The result may not be accurate or overflow, if the 1241 sum is represented by an integer type. The library provides <code class="computeroutput"><a class="link" href="../boost/histogram/algorithm/sum.html" title="Function template sum">boost::histogram::algorithm::sum</a></code> 1242 as a safer, albeit slower, alternative. It uses the <a href="https://en.wikipedia.org/wiki/Kahan_summation_algorithm" target="_top">Neumaier 1243 algorithm</a> in double precision for integers and floating point cells, 1244 and does the naive sum otherwise. 1245 </p> 1246</div> 1247<div class="section"> 1248<div class="titlepage"><div><div><h4 class="title"> 1249<a name="histogram.guide.using_algorithms.projection"></a><a class="link" href="guide.html#histogram.guide.using_algorithms.projection" title="Projection">Projection</a> 1250</h4></div></div></div> 1251<p> 1252 It is sometimes convenient to generate a high-dimensional histogram first 1253 and then extract smaller or lower-dimensional versions from it. Lower-dimensional 1254 histograms are obtained by summing the bin contents of the removed axes. 1255 This is called a <span class="emphasis"><em>projection</em></span>. If the histogram has 1256 under- and overflow bins along all axes, this operation creates a histogram 1257 which is identical to one that would have been obtained by filling the 1258 original data. 1259 </p> 1260<p> 1261 Projection is useful if you found out that there is no interesting structure 1262 along an axis, so it is not worth keeping that axis around, or if you want 1263 to visualize 1d or 2d summaries of a high-dimensional histogram. 1264 </p> 1265<p> 1266 The library provides the <code class="computeroutput"><a class="link" href="../boost/histogram/algorithm/project_idm45503931171616.html" title="Function template project">boost::histogram::algorithm::project</a></code> 1267 function for this purpose. It accepts the original histogram and the indices 1268 (one or more) of the axes that are kept and returns the lower-dimensional 1269 histogram. If the histogram is static, meaning the axis configuration is 1270 known at compile-time, compile-time numbers should be used as indices to 1271 obtain another static histogram. Using normal numbers or iterators over 1272 indices produces a histogram with a dynamic axis configuration. 1273 </p> 1274<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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> 1275<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span> 1276<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span> 1277<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">sstream</span><span class="special">></span> 1278 1279<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span> 1280 <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span> 1281 <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">literals</span><span class="special">;</span> <span class="comment">// enables _c suffix</span> 1282 1283 <span class="comment">// make a 2d histogram</span> 1284 <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special"><>(</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> 1285 1286 <span class="identifier">h</span><span class="special">(-</span><span class="number">0.9</span><span class="special">,</span> <span class="number">0</span><span class="special">);</span> 1287 <span class="identifier">h</span><span class="special">(</span><span class="number">0.9</span><span class="special">,</span> <span class="number">1</span><span class="special">);</span> 1288 <span class="identifier">h</span><span class="special">(</span><span class="number">0.1</span><span class="special">,</span> <span class="number">0</span><span class="special">);</span> 1289 1290 <span class="keyword">auto</span> <span class="identifier">hr0</span> <span class="special">=</span> <span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">project</span><span class="special">(</span><span class="identifier">h</span><span class="special">,</span> <span class="number">0</span><span class="identifier">_c</span><span class="special">);</span> <span class="comment">// keep only first axis</span> 1291 <span class="keyword">auto</span> <span class="identifier">hr1</span> <span class="special">=</span> <span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">project</span><span class="special">(</span><span class="identifier">h</span><span class="special">,</span> <span class="number">1</span><span class="identifier">_c</span><span class="special">);</span> <span class="comment">// keep only second axis</span> 1292 1293 <span class="comment">// reduce does not remove counts; returned histograms are summed over</span> 1294 <span class="comment">// the removed axes, so h, hr0, and hr1 have same number of total counts;</span> 1295 <span class="comment">// we compute the sum of counts with the sum algorithm</span> 1296 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">sum</span><span class="special">(</span><span class="identifier">h</span><span class="special">)</span> <span class="special">==</span> <span class="number">3</span> <span class="special">&&</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> 1297 1298 <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os1</span><span class="special">;</span> 1299 <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&&</span> <span class="identifier">x</span> <span class="special">:</span> <span class="identifier">indexed</span><span class="special">(</span><span class="identifier">h</span><span class="special">))</span> 1300 <span class="identifier">os1</span> <span class="special"><<</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> 1301 <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> 1302 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">os1</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span> <span class="string">"(0, 0): 1\n"</span> 1303 <span class="string">"(1, 0): 1\n"</span> 1304 <span class="string">"(2, 0): 0\n"</span> 1305 <span class="string">"(0, 1): 0\n"</span> 1306 <span class="string">"(1, 1): 0\n"</span> 1307 <span class="string">"(2, 1): 1\n"</span><span class="special">);</span> 1308 1309 <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os2</span><span class="special">;</span> 1310 <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&&</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> 1311 <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> 1312 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">os2</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span> <span class="string">"(0, -): 1\n"</span> 1313 <span class="string">"(1, -): 1\n"</span> 1314 <span class="string">"(2, -): 1\n"</span><span class="special">);</span> 1315 1316 <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os3</span><span class="special">;</span> 1317 <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&&</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> 1318 <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> 1319 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">os3</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span> <span class="string">"(- ,0): 2\n"</span> 1320 <span class="string">"(- ,1): 1\n"</span><span class="special">);</span> 1321<span class="special">}</span> 1322</pre> 1323</div> 1324<div class="section"> 1325<div class="titlepage"><div><div><h4 class="title"> 1326<a name="histogram.guide.using_algorithms.reduction"></a><a class="link" href="guide.html#histogram.guide.using_algorithms.reduction" title="Reduction">Reduction</a> 1327</h4></div></div></div> 1328<p> 1329 A projection removes an axis completely. A less drastic way to obtain a 1330 smaller histogram is the <code class="computeroutput"><a class="link" href="../boost/histogram/algorithm/reduce_idm45503931121408.html" title="Function template reduce">reduce</a></code> 1331 function, which allows one to <span class="emphasis"><em>slice</em></span>, <span class="emphasis"><em>shrink</em></span> 1332 or <span class="emphasis"><em>rebin</em></span> individual axes. 1333 </p> 1334<p> 1335 Shrinking means that the value range of an axis is reduced and the number 1336 of bins along that axis. Slicing does the same, but is based on axis indices 1337 while shrinking is based on the axis values. To <span class="emphasis"><em>rebin</em></span> 1338 means that adjacent bins are merged into larger bins, the histogram is 1339 made coarser. For N adjacent bins, a new bin is formed which covers the 1340 common interval of the merged bins and has their added content. These two 1341 operations can be combined and applied to several axes at once. Doing it 1342 in one step is much more efficient than doing it in several steps. 1343 </p> 1344<p> 1345 The <code class="computeroutput"><a class="link" href="../boost/histogram/algorithm/reduce_idm45503931121408.html" title="Function template reduce">reduce</a></code> 1346 function does not change the total count if all modified axes in the histogram 1347 have underflow and overflow bins. Counts in removed bins are added to the 1348 corresponding under- and overflow bins. As in case of the <code class="computeroutput"><a class="link" href="../boost/histogram/algorithm/project_idm45503931171616.html" title="Function template project">project</a></code> function, 1349 such a histogram is guaranteed to be identical to one obtained from filling 1350 the original data. 1351 </p> 1352<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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> 1353<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span> 1354 1355<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span> 1356 <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span> 1357 <span class="comment">// import reduce commands into local namespace to save typing</span> 1358 <span class="keyword">using</span> <span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">rebin</span><span class="special">;</span> 1359 <span class="keyword">using</span> <span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">shrink</span><span class="special">;</span> 1360 <span class="keyword">using</span> <span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">slice</span><span class="special">;</span> 1361 1362 <span class="comment">// make a 2d histogram</span> 1363 <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special"><>(</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">2.0</span><span class="special">,</span> <span class="number">2.0</span><span class="special">));</span> 1364 1365 <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="special">-</span><span class="number">0.9</span><span class="special">);</span> 1366 <span class="identifier">h</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">0.9</span><span class="special">);</span> 1367 <span class="identifier">h</span><span class="special">(</span><span class="number">2</span><span class="special">,</span> <span class="number">0.1</span><span class="special">);</span> 1368 <span class="identifier">h</span><span class="special">(</span><span class="number">3</span><span class="special">,</span> <span class="number">0.1</span><span class="special">);</span> 1369 1370 <span class="comment">// reduce takes positional commands which are applied to the axes in order</span> 1371 <span class="comment">// - shrink is applied to the first axis; the new axis range is 0.0 to 3.0</span> 1372 <span class="comment">// - rebin is applied to the second axis; pairs of adjacent bins are merged</span> 1373 <span class="keyword">auto</span> <span class="identifier">h2</span> <span class="special">=</span> <span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">reduce</span><span class="special">(</span><span class="identifier">h</span><span class="special">,</span> <span class="identifier">shrink</span><span class="special">(</span><span class="number">0.0</span><span class="special">,</span> <span class="number">3.0</span><span class="special">),</span> <span class="identifier">rebin</span><span class="special">(</span><span class="number">2</span><span class="special">));</span> 1374 1375 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">.</span><span class="identifier">axis</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special"><>(</span><span class="number">3</span><span class="special">,</span> <span class="number">0.0</span><span class="special">,</span> <span class="number">3.0</span><span class="special">));</span> 1376 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">.</span><span class="identifier">axis</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special"><>(</span><span class="number">2</span><span class="special">,</span> <span class="special">-</span><span class="number">2.0</span><span class="special">,</span> <span class="number">2.0</span><span class="special">));</span> 1377 1378 <span class="comment">// reduce does not change the total count if the histogram has underflow/overflow bins</span> 1379 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">sum</span><span class="special">(</span><span class="identifier">h</span><span class="special">)</span> <span class="special">==</span> <span class="number">4</span> <span class="special">&&</span> <span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">sum</span><span class="special">(</span><span class="identifier">h2</span><span class="special">)</span> <span class="special">==</span> <span class="number">4</span><span class="special">);</span> 1380 1381 <span class="comment">// One can also explicitly specify the index of the axis in the histogram on which the</span> 1382 <span class="comment">// command should act, by using this index as the the first parameter. The position of</span> 1383 <span class="comment">// the command in the argument list of reduce is then ignored. We use this to slice only</span> 1384 <span class="comment">// the second axis (axis has index 1 in the histogram) from bin index 2 to 4.</span> 1385 <span class="keyword">auto</span> <span class="identifier">h3</span> <span class="special">=</span> <span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">reduce</span><span class="special">(</span><span class="identifier">h</span><span class="special">,</span> <span class="identifier">slice</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="number">4</span><span class="special">));</span> 1386 1387 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h3</span><span class="special">.</span><span class="identifier">axis</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="identifier">h</span><span class="special">.</span><span class="identifier">axis</span><span class="special">(</span><span class="number">0</span><span class="special">));</span> <span class="comment">// unchanged</span> 1388 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h3</span><span class="special">.</span><span class="identifier">axis</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special"><>(</span><span class="number">2</span><span class="special">,</span> <span class="number">0.0</span><span class="special">,</span> <span class="number">2.0</span><span class="special">));</span> 1389<span class="special">}</span> 1390</pre> 1391</div> 1392</div> 1393<div class="section"> 1394<div class="titlepage"><div><div><h3 class="title"> 1395<a name="histogram.guide.streaming"></a><a class="link" href="guide.html#histogram.guide.streaming" title="Streaming">Streaming</a> 1396</h3></div></div></div> 1397<p> 1398 Simple streaming operators are shipped with the library. They are internally 1399 used by the unit tests and give simple text representations of axis and histogram 1400 configurations and show the histogram content. One-dimensional histograms 1401 are rendered as ASCII drawings. The text representations may be useful for 1402 debugging or more, but users may want to use their own implementations. Therefore, 1403 the headers with the builtin implementations are not included by any other 1404 header of the library. The following example shows the effect of output streaming. 1405 </p> 1406<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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> 1407<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> 1408<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span> 1409<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span> 1410<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">sstream</span><span class="special">></span> 1411<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">string</span><span class="special">></span> 1412 1413<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span> 1414 <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span> 1415 1416 <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os</span><span class="special">;</span> 1417 1418 <span class="keyword">auto</span> <span class="identifier">h1</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special"><>(</span><span class="number">5</span><span class="special">,</span> <span class="special">-</span><span class="number">1.0</span><span class="special">,</span> <span class="number">1.0</span><span class="special">,</span> <span class="string">"axis 1"</span><span class="special">));</span> 1419 <span class="identifier">h1</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">=</span> <span class="number">2</span><span class="special">;</span> 1420 <span class="identifier">h1</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">=</span> <span class="number">4</span><span class="special">;</span> 1421 <span class="identifier">h1</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">2</span><span class="special">)</span> <span class="special">=</span> <span class="number">3</span><span class="special">;</span> 1422 <span class="identifier">h1</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">4</span><span class="special">)</span> <span class="special">=</span> <span class="number">1</span><span class="special">;</span> 1423 1424 <span class="comment">// 1D histograms are rendered as an ASCII drawing</span> 1425 <span class="identifier">os</span> <span class="special"><<</span> <span class="identifier">h1</span><span class="special">;</span> 1426 1427 <span class="keyword">auto</span> <span class="identifier">h2</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special"><>(</span><span class="number">2</span><span class="special">,</span> <span class="special">-</span><span class="number">1.0</span><span class="special">,</span> <span class="number">1.0</span><span class="special">,</span> <span class="string">"axis 1"</span><span class="special">),</span> 1428 <span class="identifier">axis</span><span class="special">::</span><span class="identifier">category</span><span class="special"><</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> 1429 1430 <span class="comment">// higher dimensional histograms just have their cell counts listed</span> 1431 <span class="identifier">os</span> <span class="special"><<</span> <span class="identifier">h2</span><span class="special">;</span> 1432 1433 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</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> 1434 1435 <span class="identifier">assert</span><span class="special">(</span> 1436 <span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span> 1437 <span class="string">"histogram(regular(5, -1, 1, metadata=\"axis 1\", options=underflow | overflow))\n"</span> 1438 <span class="string">" +-------------------------------------------------------------+\n"</span> 1439 <span class="string">"[-inf, -1) 0 | |\n"</span> 1440 <span class="string">"[ -1, -0.6) 2 |============================== |\n"</span> 1441 <span class="string">"[-0.6, -0.2) 4 |============================================================ |\n"</span> 1442 <span class="string">"[-0.2, 0.2) 3 |============================================= |\n"</span> 1443 <span class="string">"[ 0.2, 0.6) 0 | |\n"</span> 1444 <span class="string">"[ 0.6, 1) 1 |=============== |\n"</span> 1445 <span class="string">"[ 1, inf) 0 | |\n"</span> 1446 <span class="string">" +-------------------------------------------------------------+\n"</span> 1447 <span class="string">"histogram(\n"</span> 1448 <span class="string">" regular(2, -1, 1, metadata=\"axis 1\", options=underflow | overflow)\n"</span> 1449 <span class="string">" category(\"red\", \"blue\", metadata=\"axis 2\", options=overflow)\n"</span> 1450 <span class="string">" (-1 0): 0 ( 0 0): 0 ( 1 0): 0 ( 2 0): 0 (-1 1): 0 ( 0 1): 0\n"</span> 1451 <span class="string">" ( 1 1): 0 ( 2 1): 0 (-1 2): 0 ( 0 2): 0 ( 1 2): 0 ( 2 2): 0\n"</span> 1452 <span class="string">")"</span><span class="special">);</span> 1453<span class="special">}</span> 1454</pre> 1455</div> 1456<div class="section"> 1457<div class="titlepage"><div><div><h3 class="title"> 1458<a name="histogram.guide.serialization"></a><a class="link" href="guide.html#histogram.guide.serialization" title="Serialization">Serialization</a> 1459</h3></div></div></div> 1460<p> 1461 The library supports serialization via <a href="../../../../../libs/serialization/index.html" target="_top">Boost.Serialization</a>. 1462 The serialization code is not included by the super header <code class="computeroutput"><span class="preprocessor">#include</span> <span class="special"><</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>, 1463 so that the library can be used without Boost.Serialization or with another 1464 compatible serialization library. 1465 </p> 1466<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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> 1467<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> 1468<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> 1469<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> 1470<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span> 1471<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">sstream</span><span class="special">></span> 1472 1473<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span> 1474 <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span> 1475 1476 <span class="keyword">auto</span> <span class="identifier">a</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special"><>(</span><span class="number">3</span><span class="special">,</span> <span class="special">-</span><span class="number">1.0</span><span class="special">,</span> <span class="number">1.0</span><span class="special">,</span> <span class="string">"axis 0"</span><span class="special">),</span> 1477 <span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special"><>(</span><span class="number">0</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="string">"axis 1"</span><span class="special">));</span> 1478 <span class="identifier">a</span><span class="special">(</span><span class="number">0.5</span><span class="special">,</span> <span class="number">1</span><span class="special">);</span> 1479 1480 <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">buf</span><span class="special">;</span> <span class="comment">// to hold persistent representation</span> 1481 1482 <span class="comment">// store histogram</span> 1483 <span class="special">{</span> 1484 <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os</span><span class="special">;</span> 1485 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">archive</span><span class="special">::</span><span class="identifier">text_oarchive</span> <span class="identifier">oa</span><span class="special">(</span><span class="identifier">os</span><span class="special">);</span> 1486 <span class="identifier">oa</span> <span class="special"><<</span> <span class="identifier">a</span><span class="special">;</span> 1487 <span class="identifier">buf</span> <span class="special">=</span> <span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">();</span> 1488 <span class="special">}</span> 1489 1490 <span class="keyword">auto</span> <span class="identifier">b</span> <span class="special">=</span> <span class="keyword">decltype</span><span class="special">(</span><span class="identifier">a</span><span class="special">)();</span> <span class="comment">// create a default-constructed second histogram</span> 1491 1492 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">b</span> <span class="special">!=</span> <span class="identifier">a</span><span class="special">);</span> <span class="comment">// b is empty, a is not</span> 1493 1494 <span class="comment">// load histogram</span> 1495 <span class="special">{</span> 1496 <span class="identifier">std</span><span class="special">::</span><span class="identifier">istringstream</span> <span class="identifier">is</span><span class="special">(</span><span class="identifier">buf</span><span class="special">);</span> 1497 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">archive</span><span class="special">::</span><span class="identifier">text_iarchive</span> <span class="identifier">ia</span><span class="special">(</span><span class="identifier">is</span><span class="special">);</span> 1498 <span class="identifier">ia</span> <span class="special">>></span> <span class="identifier">b</span><span class="special">;</span> 1499 <span class="special">}</span> 1500 1501 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">b</span> <span class="special">==</span> <span class="identifier">a</span><span class="special">);</span> <span class="comment">// now b is equal to a</span> 1502<span class="special">}</span> 1503</pre> 1504</div> 1505<div class="section"> 1506<div class="titlepage"><div><div><h3 class="title"> 1507<a name="histogram.guide.using_histograms_in_apis"></a><a class="link" href="guide.html#histogram.guide.using_histograms_in_apis" title="Using histograms in APIs">Using histograms 1508 in APIs</a> 1509</h3></div></div></div> 1510<p> 1511 Letting the compiler deduce the histogram type is recommended, because the 1512 templated type is tedious to write down explicitly. Functions or methods 1513 which accept or return histograms should be templated to work with all kinds 1514 of histograms. It is also possible to write templated versions which accept 1515 only histograms with dynamic axes or only histograms with static axes. The 1516 following example demonstrates all this. 1517 </p> 1518<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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> 1519<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span> 1520 1521<span class="comment">// function accepts any histogram and returns a copy</span> 1522<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">Axes</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Storage</span><span class="special">></span> 1523<span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">histogram</span><span class="special"><</span><span class="identifier">Axes</span><span class="special">,</span> <span class="identifier">Storage</span><span class="special">></span> <span class="identifier">any_histogram</span><span class="special">(</span> 1524 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">histogram</span><span class="special"><</span><span class="identifier">Axes</span><span class="special">,</span> <span class="identifier">Storage</span><span class="special">>&</span> <span class="identifier">h</span><span class="special">)</span> <span class="special">{</span> 1525 <span class="keyword">return</span> <span class="identifier">h</span><span class="special">;</span> 1526<span class="special">}</span> 1527 1528<span class="comment">// function only accepts histograms with fixed axis types and returns a copy</span> 1529<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">Storage</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">Axes</span><span class="special">></span> 1530<span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">histogram</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span><span class="special"><</span><span class="identifier">Axes</span><span class="special">...>,</span> <span class="identifier">Storage</span><span class="special">></span> <span class="identifier">only_static_histogram</span><span class="special">(</span> 1531 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">histogram</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span><span class="special"><</span><span class="identifier">Axes</span><span class="special">...>,</span> <span class="identifier">Storage</span><span class="special">>&</span> <span class="identifier">h</span><span class="special">)</span> <span class="special">{</span> 1532 <span class="keyword">return</span> <span class="identifier">h</span><span class="special">;</span> 1533<span class="special">}</span> 1534 1535<span class="comment">// function only accepts histograms with dynamic axis types and returns a copy</span> 1536<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">Storage</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">Axes</span><span class="special">></span> 1537<span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">histogram</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</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">variant</span><span class="special"><</span><span class="identifier">Axes</span><span class="special">...>>,</span> 1538 <span class="identifier">Storage</span><span class="special">></span> 1539<span class="identifier">only_dynamic_histogram</span><span class="special">(</span> 1540 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">histogram</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</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">variant</span><span class="special"><</span><span class="identifier">Axes</span><span class="special">...>>,</span> 1541 <span class="identifier">Storage</span><span class="special">>&</span> <span class="identifier">h</span><span class="special">)</span> <span class="special">{</span> 1542 <span class="keyword">return</span> <span class="identifier">h</span><span class="special">;</span> 1543<span class="special">}</span> 1544 1545<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span> 1546 <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span> 1547 1548 <span class="keyword">auto</span> <span class="identifier">histogram_with_static_axes</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special"><>(</span><span class="number">10</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="number">1</span><span class="special">));</span> 1549 1550 <span class="keyword">using</span> <span class="identifier">axis_variant</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">variant</span><span class="special"><</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> 1551 <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">axis_variant</span><span class="special">></span> <span class="identifier">axes</span><span class="special">;</span> 1552 <span class="identifier">axes</span><span class="special">.</span><span class="identifier">emplace_back</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special"><>(</span><span class="number">5</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="number">1</span><span class="special">));</span> 1553 <span class="identifier">axes</span><span class="special">.</span><span class="identifier">emplace_back</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special"><>(</span><span class="number">0</span><span class="special">,</span> <span class="number">1</span><span class="special">));</span> 1554 <span class="keyword">auto</span> <span class="identifier">histogram_with_dynamic_axes</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axes</span><span class="special">);</span> 1555 1556 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">any_histogram</span><span class="special">(</span><span class="identifier">histogram_with_static_axes</span><span class="special">)</span> <span class="special">==</span> <span class="identifier">histogram_with_static_axes</span><span class="special">);</span> 1557 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">any_histogram</span><span class="special">(</span><span class="identifier">histogram_with_dynamic_axes</span><span class="special">)</span> <span class="special">==</span> <span class="identifier">histogram_with_dynamic_axes</span><span class="special">);</span> 1558 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">only_static_histogram</span><span class="special">(</span><span class="identifier">histogram_with_static_axes</span><span class="special">)</span> <span class="special">==</span> <span class="identifier">histogram_with_static_axes</span><span class="special">);</span> 1559 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">only_dynamic_histogram</span><span class="special">(</span><span class="identifier">histogram_with_dynamic_axes</span><span class="special">)</span> <span class="special">==</span> 1560 <span class="identifier">histogram_with_dynamic_axes</span><span class="special">);</span> 1561 1562 <span class="comment">// does not compile: only_static_histogram(histogram_with_dynamic_axes)</span> 1563 <span class="comment">// does not compile: only_dynamic_histogram(histogram_with_static_axes)</span> 1564<span class="special">}</span> 1565</pre> 1566<p> 1567 If the histogram type has to be written down explicitly, the types are constructed 1568 as follows. In all cases, the <code class="computeroutput"><span class="identifier">default_storage</span></code> 1569 type argument may be replaced by any other storage type or omitted entirely. 1570 </p> 1571<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 1572<li class="listitem"> 1573<p class="simpara"> 1574 Histogram with fixed axis types: 1575 </p> 1576<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">histogram</span><span class="special"><</span> 1577 <span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span><span class="special"><</span><span class="identifier">axis_type_1</span><span class="special">,</span> <span class="identifier">axis_type_2</span><span class="special">,</span> <span class="special">...,</span> <span class="identifier">axis_type_N</span><span class="special">></span> 1578 <span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">default_storage</span> 1579<span class="special">></span> 1580</pre> 1581</li> 1582<li class="listitem"> 1583<p class="simpara"> 1584 Histogram with a variable number of the same axis type: 1585 </p> 1586<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">histogram</span><span class="special"><</span> 1587 <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span> 1588 <span class="identifier">axis_type_1</span> 1589 <span class="special">></span> 1590 <span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">default_storage</span> 1591<span class="special">></span> 1592</pre> 1593</li> 1594<li class="listitem"> 1595<p class="simpara"> 1596 Histogram with variable axis types: 1597 </p> 1598<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">histogram</span><span class="special"><</span> 1599 <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span> 1600 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">variant</span><span class="special"><</span> 1601 <span class="identifier">axis_type_1</span><span class="special">,</span> <span class="identifier">axis_type_2</span><span class="special">,</span> <span class="special">...,</span> <span class="identifier">axis_type_N</span> 1602 <span class="special">></span> 1603 <span class="special">></span> 1604 <span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">default_storage</span> 1605<span class="special">></span> 1606</pre> 1607</li> 1608</ul></div> 1609</div> 1610<div class="section"> 1611<div class="titlepage"><div><div><h3 class="title"> 1612<a name="histogram.guide.expert"></a><a class="link" href="guide.html#histogram.guide.expert" title="Advanced usage">Advanced usage</a> 1613</h3></div></div></div> 1614<div class="toc"><dl class="toc"> 1615<dt><span class="section"><a href="guide.html#histogram.guide.expert.user_defined_axes">User-defined 1616 axes</a></span></dt> 1617<dt><span class="section"><a href="guide.html#histogram.guide.expert.axis_with_several_arguments">Axis 1618 with several arguments</a></span></dt> 1619<dt><span class="section"><a href="guide.html#histogram.guide.expert.user_defined_storage_class">User-defined 1620 storage class</a></span></dt> 1621<dt><span class="section"><a href="guide.html#histogram.guide.expert.parallelisation_options">Parallelisation 1622 options</a></span></dt> 1623<dt><span class="section"><a href="guide.html#histogram.guide.expert.user_defined_accumulators">User-defined 1624 accumulators</a></span></dt> 1625</dl></div> 1626<p> 1627 The library is customisable and extensible by users. Users can create new 1628 axis types and use them with the histogram, or implement a custom storage 1629 policy, or use a builtin storage policy with a custom counter type. The library 1630 was designed to make this very easy. This section shows how to do this. 1631 </p> 1632<div class="section"> 1633<div class="titlepage"><div><div><h4 class="title"> 1634<a name="histogram.guide.expert.user_defined_axes"></a><a class="link" href="guide.html#histogram.guide.expert.user_defined_axes" title="User-defined axes">User-defined 1635 axes</a> 1636</h4></div></div></div> 1637<p> 1638 It is easy to make custom axis classes that work with the library. The 1639 custom axis class must meet the requirements of the <a class="link" href="concepts.html#histogram.concepts.Axis" title="Axis"><span class="bold"><strong>Axis</strong></span> concept</a>. 1640 </p> 1641<p> 1642 Users can create a custom axis by derive from a builtin axis type and customize 1643 its behavior. The following examples demonstrates a modification of the 1644 <code class="computeroutput"><a class="link" href="../boost/histogram/axis/integer.html" title="Class template integer">integer axis</a></code>. 1645 </p> 1646<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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> 1647<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span> 1648<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span> 1649<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">sstream</span><span class="special">></span> 1650 1651<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span> 1652 <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span> 1653 1654 <span class="comment">// custom axis, which adapts builtin integer axis</span> 1655 <span class="keyword">struct</span> <span class="identifier">custom_axis</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special"><></span> <span class="special">{</span> 1656 <span class="keyword">using</span> <span class="identifier">value_type</span> <span class="special">=</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*;</span> <span class="comment">// type that is fed to the axis</span> 1657 1658 <span class="keyword">using</span> <span class="identifier">integer</span><span class="special">::</span><span class="identifier">integer</span><span class="special">;</span> <span class="comment">// inherit ctors of base</span> 1659 1660 <span class="comment">// the customization point</span> 1661 <span class="comment">// - accept const char* and convert to int</span> 1662 <span class="comment">// - then call index method of base class</span> 1663 <span class="identifier">axis</span><span class="special">::</span><span class="identifier">index_type</span> <span class="identifier">index</span><span class="special">(</span><span class="identifier">value_type</span> <span class="identifier">s</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">integer</span><span class="special">::</span><span class="identifier">index</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">atoi</span><span class="special">(</span><span class="identifier">s</span><span class="special">));</span> <span class="special">}</span> 1664 <span class="special">};</span> 1665 1666 <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">custom_axis</span><span class="special">(</span><span class="number">3</span><span class="special">,</span> <span class="number">6</span><span class="special">));</span> 1667 <span class="identifier">h</span><span class="special">(</span><span class="string">"-10"</span><span class="special">);</span> 1668 <span class="identifier">h</span><span class="special">(</span><span class="string">"3"</span><span class="special">);</span> 1669 <span class="identifier">h</span><span class="special">(</span><span class="string">"4"</span><span class="special">);</span> 1670 <span class="identifier">h</span><span class="special">(</span><span class="string">"9"</span><span class="special">);</span> 1671 1672 <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os</span><span class="special">;</span> 1673 <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&&</span> <span class="identifier">b</span> <span class="special">:</span> <span class="identifier">indexed</span><span class="special">(</span><span class="identifier">h</span><span class="special">))</span> <span class="special">{</span> 1674 <span class="identifier">os</span> <span class="special"><<</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> 1675 <span class="special">}</span> 1676 1677 <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> 1678 1679 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span> <span class="string">"bin 0 [3] 1\n"</span> 1680 <span class="string">"bin 1 [4] 1\n"</span> 1681 <span class="string">"bin 2 [5] 0\n"</span><span class="special">);</span> 1682<span class="special">}</span> 1683</pre> 1684<p> 1685 How to make an axis completely from scratch is shown in the next example. 1686 </p> 1687<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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> 1688<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span> 1689 1690<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span> 1691 <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span> 1692 1693 <span class="comment">// stateless axis which returns 1 if the input is even and 0 otherwise</span> 1694 <span class="keyword">struct</span> <span class="identifier">even_odd_axis</span> <span class="special">{</span> 1695 <span class="identifier">axis</span><span class="special">::</span><span class="identifier">index_type</span> <span class="identifier">index</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">x</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">x</span> <span class="special">%</span> <span class="number">2</span><span class="special">;</span> <span class="special">}</span> 1696 <span class="identifier">axis</span><span class="special">::</span><span class="identifier">index_type</span> <span class="identifier">size</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span> <span class="keyword">return</span> <span class="number">2</span><span class="special">;</span> <span class="special">}</span> 1697 <span class="special">};</span> 1698 1699 <span class="comment">// threshold axis which returns 1 if the input is above threshold</span> 1700 <span class="keyword">struct</span> <span class="identifier">threshold_axis</span> <span class="special">{</span> 1701 <span class="identifier">threshold_axis</span><span class="special">(</span><span class="keyword">double</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">thr</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span> <span class="special">{}</span> 1702 <span class="identifier">axis</span><span class="special">::</span><span class="identifier">index_type</span> <span class="identifier">index</span><span class="special">(</span><span class="keyword">double</span> <span class="identifier">x</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">x</span> <span class="special">>=</span> <span class="identifier">thr</span><span class="special">;</span> <span class="special">}</span> 1703 <span class="identifier">axis</span><span class="special">::</span><span class="identifier">index_type</span> <span class="identifier">size</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span> <span class="keyword">return</span> <span class="number">2</span><span class="special">;</span> <span class="special">}</span> 1704 <span class="keyword">double</span> <span class="identifier">thr</span><span class="special">;</span> 1705 <span class="special">};</span> 1706 1707 <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">even_odd_axis</span><span class="special">(),</span> <span class="identifier">threshold_axis</span><span class="special">(</span><span class="number">3.0</span><span class="special">));</span> 1708 1709 <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">2.0</span><span class="special">);</span> 1710 <span class="identifier">h</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">4.0</span><span class="special">);</span> 1711 <span class="identifier">h</span><span class="special">(</span><span class="number">2</span><span class="special">,</span> <span class="number">4.0</span><span class="special">);</span> 1712 1713 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span> <span class="comment">// even, below threshold</span> 1714 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span> <span class="comment">// even, above threshold</span> 1715 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span> <span class="comment">// odd, below threshold</span> 1716 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span> <span class="comment">// odd, above threshold</span> 1717<span class="special">}</span> 1718</pre> 1719<p> 1720 Such minimal axis types lack many features provided by the builtin axis 1721 types, for example, one cannot iterate over them, but this functionality 1722 can be added as needed. 1723 </p> 1724</div> 1725<div class="section"> 1726<div class="titlepage"><div><div><h4 class="title"> 1727<a name="histogram.guide.expert.axis_with_several_arguments"></a><a class="link" href="guide.html#histogram.guide.expert.axis_with_several_arguments" title="Axis with several arguments">Axis 1728 with several arguments</a> 1729</h4></div></div></div> 1730<p> 1731 Multi-dimensional histograms usually have an orthogonal system of axes. 1732 Orthogonal means that each axis takes care of only one value and computes 1733 its local index independently of all the other axes and values. A checker-board 1734 is such an orthogonal grid in 2D. 1735 </p> 1736<p> 1737 There are other interesting grids which are not orthogonal, notably the 1738 honeycomb grid. In such a grid, each cell is hexagonal and even though 1739 the cells form a perfectly regular pattern, it is not possible to sort 1740 values into these cells using two orthogonal axes. 1741 </p> 1742<p> 1743 The library supports non-orthogonal grids by allowing axis types to accept 1744 a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span></code> of values. The axis can compute 1745 an index from the values passed to it in an arbitrary way. The following 1746 example demonstrates this. 1747 </p> 1748<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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> 1749<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span> 1750 1751<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span> 1752 <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span> 1753 1754 <span class="comment">// axis which returns 1 if the input falls inside the unit circle and zero otherwise</span> 1755 <span class="keyword">struct</span> <span class="identifier">circle_axis</span> <span class="special">{</span> 1756 <span class="comment">// accepts a 2D point in form of a std::tuple</span> 1757 <span class="identifier">axis</span><span class="special">::</span><span class="identifier">index_type</span> <span class="identifier">index</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span><span class="special"><</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> 1758 <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">get</span><span class="special"><</span><span class="number">0</span><span class="special">>(</span><span class="identifier">point</span><span class="special">);</span> 1759 <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">y</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">get</span><span class="special"><</span><span class="number">1</span><span class="special">>(</span><span class="identifier">point</span><span class="special">);</span> 1760 <span class="keyword">return</span> <span class="identifier">x</span> <span class="special">*</span> <span class="identifier">x</span> <span class="special">+</span> <span class="identifier">y</span> <span class="special">*</span> <span class="identifier">y</span> <span class="special"><=</span> <span class="number">1.0</span><span class="special">;</span> 1761 <span class="special">}</span> 1762 1763 <span class="identifier">axis</span><span class="special">::</span><span class="identifier">index_type</span> <span class="identifier">size</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span> <span class="keyword">return</span> <span class="number">2</span><span class="special">;</span> <span class="special">}</span> 1764 <span class="special">};</span> 1765 1766 <span class="keyword">auto</span> <span class="identifier">h1</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">circle_axis</span><span class="special">());</span> 1767 1768 <span class="comment">// fill looks normal for a histogram which has only one Nd-axis</span> 1769 <span class="identifier">h1</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">0</span><span class="special">);</span> <span class="comment">// in</span> 1770 <span class="identifier">h1</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="special">-</span><span class="number">1</span><span class="special">);</span> <span class="comment">// in</span> 1771 <span class="identifier">h1</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">1</span><span class="special">);</span> <span class="comment">// in</span> 1772 <span class="identifier">h1</span><span class="special">(-</span><span class="number">1</span><span class="special">,</span> <span class="number">0</span><span class="special">);</span> <span class="comment">// in</span> 1773 <span class="identifier">h1</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">0</span><span class="special">);</span> <span class="comment">// in</span> 1774 <span class="identifier">h1</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">1</span><span class="special">);</span> <span class="comment">// out</span> 1775 <span class="identifier">h1</span><span class="special">(-</span><span class="number">1</span><span class="special">,</span> <span class="special">-</span><span class="number">1</span><span class="special">);</span> <span class="comment">// out</span> 1776 1777 <span class="comment">// 2D histogram, but only 1D index</span> 1778 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span> <span class="comment">// out</span> 1779 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">5</span><span class="special">);</span> <span class="comment">// in</span> 1780 1781 <span class="comment">// other axes can be combined with a Nd-axis</span> 1782 <span class="keyword">auto</span> <span class="identifier">h2</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">circle_axis</span><span class="special">(),</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">category</span><span class="special"><</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> 1783 1784 <span class="comment">// now we need to pass arguments for Nd-axis explicitly as std::tuple</span> 1785 <span class="identifier">h2</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">make_tuple</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">0</span><span class="special">),</span> <span class="string">"red"</span><span class="special">);</span> 1786 <span class="identifier">h2</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">make_tuple</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">1</span><span class="special">),</span> <span class="string">"blue"</span><span class="special">);</span> 1787 1788 <span class="comment">// 3D histogram, but only 2D index</span> 1789 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span> <span class="comment">// out, red</span> 1790 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span> <span class="comment">// out, blue</span> 1791 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span> <span class="comment">// in, red</span> 1792 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span> <span class="comment">// in, blue</span> 1793<span class="special">}</span> 1794</pre> 1795</div> 1796<div class="section"> 1797<div class="titlepage"><div><div><h4 class="title"> 1798<a name="histogram.guide.expert.user_defined_storage_class"></a><a class="link" href="guide.html#histogram.guide.expert.user_defined_storage_class" title="User-defined storage class">User-defined 1799 storage class</a> 1800</h4></div></div></div> 1801<p> 1802 Histograms which use a different storage class can easily created with 1803 the factory function <code class="computeroutput"><a class="link" href="reference.html#header.boost.histogram.make_histogram_hpp" title="Header <boost/histogram/make_histogram.hpp>">make_histogram_with</a></code>. 1804 For convenience, this factory function accepts many standard containers 1805 as storage backends: vectors, arrays, and maps. These are automatically 1806 wrapped with a <code class="computeroutput"><a class="link" href="../boost/histogram/storage_adaptor.html" title="Class template storage_adaptor">boost::histogram::storage_adaptor</a></code> 1807 to provide the storage interface needed by the library. Users may also 1808 place custom accumulators in the vector, as described in the next section. 1809 </p> 1810<div class="warning"><table border="0" summary="Warning"> 1811<tr> 1812<td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="../../../../../doc/src/images/warning.png"></td> 1813<th align="left">Warning</th> 1814</tr> 1815<tr><td align="left" valign="top"><p> 1816 The no-overflow-guarantee is only valid if the <code class="computeroutput"><a class="link" href="../boost/histogram/unlimited_storage.html" title="Class template unlimited_storage">unlimited_storage</a></code> 1817 (the default) is used. If you change the storage policy, you need to 1818 know what you are doing. 1819 </p></td></tr> 1820</table></div> 1821<p> 1822 A <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span></code> may provide higher performance 1823 than the <code class="computeroutput"><a class="link" href="../boost/histogram/unlimited_storage.html" title="Class template unlimited_storage">unlimited_storage</a></code> 1824 with a carefully chosen counter type. Usually, this would be an integral 1825 or floating point type. A <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span></code>-based 1826 storage may be faster for low-dimensional histograms (or not, you need 1827 to measure). 1828 </p> 1829<p> 1830 Users who work exclusively with weighted histograms should chose a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">double</span><span class="special">></span></code>, 1831 it will be faster. If they also want to track the variance of the sum of 1832 weights, a vector-based storage of <code class="computeroutput"><a class="link" href="../boost/histogram/accumulators/weighted_sum.html" title="Class template weighted_sum">weighted_sum</a></code> 1833 accumulators should be used. The factory function <code class="computeroutput"><a class="link" href="../boost/histogram/make_wei_idm45503931624016.html" title="Function template make_weighted_histogram">make_weighted_histogram</a></code> 1834 is a convenient way to generate a histogram with this storage. 1835 </p> 1836<p> 1837 An interesting alternative to a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span></code> 1838 is to use a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span></code>. The latter provides a storage 1839 with a fixed maximum capacity (the size of the array). <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span></code> 1840 allocates the memory on the stack. In combination with a static axis configuration 1841 this allows one to create histograms completely on the stack without any 1842 dynamic memory allocation. Small stack-based histograms can be created 1843 and destroyed very fast. 1844 </p> 1845<p> 1846 Finally, a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span></code> or <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">unordered_map</span></code> 1847 or any other map type that implements the STL interface can be used to 1848 generate a histogram with a sparse storage, where empty cells do not consume 1849 any memory. This sounds attractive, but the memory consumption per cell 1850 in such a data structure is much larger than for a vector or array, so 1851 the number of empty cells must be substantial to gain. Moreover, cell lookup 1852 in a sparse data structure may be less performant. Whether a sparse storage 1853 performs better than a dense storage depends on the use case. The library 1854 makes it easy to switch from dense to sparse storage and back, so users 1855 are invited to test both options. 1856 </p> 1857<p> 1858 The following example shows how histograms are constructed which use an 1859 alternative storage classes. 1860 </p> 1861<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">algorithm</span><span class="special">></span> <span class="comment">// std::for_each</span> 1862<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">array</span><span class="special">></span> 1863<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> 1864<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> 1865<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">functional</span><span class="special">></span> <span class="comment">// std::ref</span> 1866<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">unordered_map</span><span class="special">></span> 1867<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">vector</span><span class="special">></span> 1868 1869<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span> 1870 <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span> 1871 <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">axis</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special"><>(</span><span class="number">10</span><span class="special">,</span> <span class="number">0.0</span><span class="special">,</span> <span class="number">1.0</span><span class="special">);</span> 1872 1873 <span class="keyword">auto</span> <span class="identifier">data</span> <span class="special">=</span> <span class="special">{</span><span class="number">0.1</span><span class="special">,</span> <span class="number">0.3</span><span class="special">,</span> <span class="number">0.2</span><span class="special">,</span> <span class="number">0.7</span><span class="special">};</span> 1874 1875 <span class="comment">// Create static histogram with vector<int> as counter storage, you can use</span> 1876 <span class="comment">// other arithmetic types as counters, e.g. double.</span> 1877 <span class="keyword">auto</span> <span class="identifier">h1</span> <span class="special">=</span> <span class="identifier">make_histogram_with</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">int</span><span class="special">>(),</span> <span class="identifier">axis</span><span class="special">);</span> 1878 <span class="identifier">std</span><span class="special">::</span><span class="identifier">for_each</span><span class="special">(</span><span class="identifier">data</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">data</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ref</span><span class="special">(</span><span class="identifier">h1</span><span class="special">));</span> 1879 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">sum</span><span class="special">(</span><span class="identifier">h1</span><span class="special">)</span> <span class="special">==</span> <span class="number">4</span><span class="special">);</span> 1880 1881 <span class="comment">// Create static histogram with array<int, N> as counter storage which is</span> 1882 <span class="comment">// allocated completely on the stack (this is very fast). N may be larger than</span> 1883 <span class="comment">// the actual number of bins used; an exception is raised if N is too small to</span> 1884 <span class="comment">// hold all bins.</span> 1885 <span class="keyword">auto</span> <span class="identifier">h2</span> <span class="special">=</span> <span class="identifier">make_histogram_with</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special"><</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> 1886 <span class="identifier">std</span><span class="special">::</span><span class="identifier">for_each</span><span class="special">(</span><span class="identifier">data</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">data</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ref</span><span class="special">(</span><span class="identifier">h2</span><span class="special">));</span> 1887 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">sum</span><span class="special">(</span><span class="identifier">h2</span><span class="special">)</span> <span class="special">==</span> <span class="number">4</span><span class="special">);</span> 1888 1889 <span class="comment">// Create static histogram with unordered_map as counter storage; this</span> 1890 <span class="comment">// generates a sparse histogram where only memory is allocated for bins that</span> 1891 <span class="comment">// are non-zero. This sounds like a good idea for high-dimensional histograms,</span> 1892 <span class="comment">// but maps come with a memory and run-time overhead. The default_storage</span> 1893 <span class="comment">// usually performs better in high dimensions.</span> 1894 <span class="keyword">auto</span> <span class="identifier">h3</span> <span class="special">=</span> <span class="identifier">make_histogram_with</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">unordered_map</span><span class="special"><</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> 1895 <span class="identifier">std</span><span class="special">::</span><span class="identifier">for_each</span><span class="special">(</span><span class="identifier">data</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">data</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ref</span><span class="special">(</span><span class="identifier">h3</span><span class="special">));</span> 1896 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">sum</span><span class="special">(</span><span class="identifier">h3</span><span class="special">)</span> <span class="special">==</span> <span class="number">4</span><span class="special">);</span> 1897<span class="special">}</span> 1898</pre> 1899</div> 1900<div class="section"> 1901<div class="titlepage"><div><div><h4 class="title"> 1902<a name="histogram.guide.expert.parallelisation_options"></a><a class="link" href="guide.html#histogram.guide.expert.parallelisation_options" title="Parallelisation options">Parallelisation 1903 options</a> 1904</h4></div></div></div> 1905<p> 1906 There are two ways to generate a single histogram using several threads. 1907 </p> 1908<p> 1909 1. Each thread has its own copy of the histogram. Each copy is independently 1910 filled. The copies are then added in the main thread. Use this as the default 1911 when you can afford having <code class="computeroutput"><span class="identifier">N</span></code> 1912 copies of the histogram in memory for <code class="computeroutput"><span class="identifier">N</span></code> 1913 threads, because it allows each thread to work on its thread-local memory 1914 and utilise the CPU cache without the need to synchronise memory access. 1915 The highest performance gains are obtained in this way. 1916 </p> 1917<p> 1918 2. There is only one histogram which is filled concurrently by several 1919 threads. This requires using a thread-safe storage that can handle concurrent 1920 writes. The library provides the <code class="computeroutput"><a class="link" href="../boost/histogram/accumulators/thread_safe.html" title="Class template thread_safe">boost::histogram::accumulators::thread_safe</a></code> 1921 accumulator, which combined with the <code class="computeroutput"><a class="link" href="reference.html#boost.histogram.dense_storage">boost::histogram::dense_storage</a></code> 1922 provides a thread-safe storage. 1923 </p> 1924<div class="note"><table border="0" summary="Note"> 1925<tr> 1926<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td> 1927<th align="left">Note</th> 1928</tr> 1929<tr><td align="left" valign="top"><p> 1930 Filling a histogram with growing axes in a multi-threaded environment 1931 is safe, but has poor performance since the histogram must be locked 1932 on each fill. The locks are required because an axis could grow each 1933 time, which changes the number of cells and cell addressing for all other 1934 threads. Even without growing axes, there is only a performance gain 1935 if the histogram is either very large or when significant time is spend 1936 in preparing the value to fill. For small histograms, threads frequently 1937 access the same cell, whose state has to be synchronised between the 1938 threads. This is slow even with atomic counters and made worse by the 1939 effect of false sharing. 1940 </p></td></tr> 1941</table></div> 1942<p> 1943 The next example demonstrates option 2 (option 1 is straight-forward to 1944 implement). 1945 </p> 1946<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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> 1947<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> 1948<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span> 1949<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">functional</span><span class="special">></span> 1950<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">thread</span><span class="special">></span> 1951<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">vector</span><span class="special">></span> 1952 1953<span class="comment">// dummy fill function, to be executed in parallel by several threads</span> 1954<span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Histogram</span><span class="special">></span> 1955<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> 1956 <span class="keyword">for</span> <span class="special">(</span><span class="keyword">unsigned</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special"><</span> <span class="number">1000</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span> <span class="special">{</span> <span class="identifier">h</span><span class="special">(</span><span class="identifier">i</span> <span class="special">%</span> <span class="number">10</span><span class="special">);</span> <span class="special">}</span> 1957<span class="special">}</span> 1958 1959<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span> 1960 <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span> 1961 1962 <span class="comment">/* 1963 Create histogram with container of thread-safe counters for parallel filling in 1964 several threads. Only filling is thread-safe, other guarantees are not given. 1965 */</span> 1966 <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram_with</span><span class="special">(</span><span class="identifier">dense_storage</span><span class="special"><</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> 1967 <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> 1968 1969 <span class="comment">/* 1970 Run the fill function in parallel from different threads. This is safe when a 1971 thread-safe accumulator and a storage with thread-safe cell access are used. 1972 */</span> 1973 <span class="keyword">auto</span> <span class="identifier">fill_h</span> <span class="special">=</span> <span class="special">[&</span><span class="identifier">h</span><span class="special">]()</span> <span class="special">{</span> <span class="identifier">fill</span><span class="special">(</span><span class="identifier">h</span><span class="special">);</span> <span class="special">};</span> 1974 <span class="identifier">std</span><span class="special">::</span><span class="identifier">thread</span> <span class="identifier">t1</span><span class="special">(</span><span class="identifier">fill_h</span><span class="special">);</span> 1975 <span class="identifier">std</span><span class="special">::</span><span class="identifier">thread</span> <span class="identifier">t2</span><span class="special">(</span><span class="identifier">fill_h</span><span class="special">);</span> 1976 <span class="identifier">std</span><span class="special">::</span><span class="identifier">thread</span> <span class="identifier">t3</span><span class="special">(</span><span class="identifier">fill_h</span><span class="special">);</span> 1977 <span class="identifier">std</span><span class="special">::</span><span class="identifier">thread</span> <span class="identifier">t4</span><span class="special">(</span><span class="identifier">fill_h</span><span class="special">);</span> 1978 <span class="identifier">t1</span><span class="special">.</span><span class="identifier">join</span><span class="special">();</span> 1979 <span class="identifier">t2</span><span class="special">.</span><span class="identifier">join</span><span class="special">();</span> 1980 <span class="identifier">t3</span><span class="special">.</span><span class="identifier">join</span><span class="special">();</span> 1981 <span class="identifier">t4</span><span class="special">.</span><span class="identifier">join</span><span class="special">();</span> 1982 1983 <span class="comment">// Without a thread-safe accumulator, this number may be smaller.</span> 1984 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">sum</span><span class="special">(</span><span class="identifier">h</span><span class="special">)</span> <span class="special">==</span> <span class="number">4000</span><span class="special">);</span> 1985<span class="special">}</span> 1986</pre> 1987</div> 1988<div class="section"> 1989<div class="titlepage"><div><div><h4 class="title"> 1990<a name="histogram.guide.expert.user_defined_accumulators"></a><a class="link" href="guide.html#histogram.guide.expert.user_defined_accumulators" title="User-defined accumulators">User-defined 1991 accumulators</a> 1992</h4></div></div></div> 1993<p> 1994 A storage can hold custom accumulators which can accept an arbitrary number 1995 of arguments. The arguments are passed to the accumulator via the <code class="computeroutput"><a class="link" href="../boost/histogram/sample.html" title="Function template sample">sample</a></code> call, for example, 1996 <code class="computeroutput"><span class="identifier">sample</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="number">3</span><span class="special">)</span></code> 1997 for an accumulator which accepts three arguments. Custom accumulators can 1998 be combined with any container supported by <code class="computeroutput"><a class="link" href="../boost/histogram/storage_adaptor.html" title="Class template storage_adaptor">boost::histogram::storage_adaptor</a></code>. 1999 For convenience, the alias template <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">dense_storage</span></code> 2000 is provided to make a standard storage with a custom accumulator type. 2001 </p> 2002<p> 2003 The library provides several accumulators: 2004 </p> 2005<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 2006<li class="listitem"> 2007 <code class="computeroutput"><a class="link" href="../boost/histogram/accumulators/sum.html" title="Class template sum">sum</a></code> 2008 accepts no samples, but accepts a weight. It is an alternative to a 2009 plain arithmetic type as a counter. It provides an advantage when histograms 2010 are filled with weights that differ dramatically in magnitude. The 2011 sum of weights is computed incrementally with the Neumaier algorithm. 2012 The algorithm is more accurate, but consumes more CPU and memory (memory 2013 is doubled compared to a normal sum of floating point numbers). 2014 </li> 2015<li class="listitem"> 2016 <code class="computeroutput"><a class="link" href="../boost/histogram/accumulators/weighted_sum.html" title="Class template weighted_sum">weighted_sum</a></code> 2017 accepts no samples, but accepts a weight. It computes the sum of weights 2018 and the sum of weights squared, the variance estimate of the sum of 2019 weights. This type is used by the <code class="computeroutput"><a class="link" href="../boost/histogram/make_wei_idm45503931624016.html" title="Function template make_weighted_histogram">make_weighted_histogram</a></code>. 2020 </li> 2021<li class="listitem"> 2022 <code class="computeroutput"><a class="link" href="../boost/histogram/accumulators/mean.html" title="Class template mean">mean</a></code> 2023 accepts a sample and computes the mean of the samples. <code class="computeroutput"><a class="link" href="../boost/histogram/make_pro_idm45503931608944.html" title="Function template make_profile">make_profile</a></code> uses 2024 this accumulator. 2025 </li> 2026<li class="listitem"> 2027 <code class="computeroutput"><a class="link" href="../boost/histogram/accumulators/weighted_mean.html" title="Class template weighted_mean">weighted_mean</a></code> 2028 accepts a sample and a weight. It computes the weighted mean of the 2029 samples. <code class="computeroutput"><a class="link" href="../boost/histogram/make_wei_idm45503931596384.html" title="Function template make_weighted_profile">make_weighted_profile</a></code> 2030 uses this accumulator. 2031 </li> 2032</ul></div> 2033<p> 2034 Users can easily write their own accumulators and plug them into the histogram, 2035 if they adhere to the <a class="link" href="concepts.html#histogram.concepts.Accumulator" title="Accumulator"><span class="bold"><strong>Accumulator</strong></span> concept</a>. All accumulators from 2036 <a href="../../../../../libs/accumulators/index.html" target="_top">Boost.Accumulators</a> 2037 that accept a single argument and no weights work out of the box. Other 2038 accumulators from Boost.Accumulators can be made to work by using them 2039 inside a wrapper class that implements the concept. 2040 </p> 2041<p> 2042 The first example shows how to make and use a histogram that uses one of 2043 the the builtin accumulators. 2044 </p> 2045<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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> 2046<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> 2047<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span> 2048<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span> 2049<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">sstream</span><span class="special">></span> 2050 2051<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span> 2052 <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span> 2053 <span class="keyword">using</span> <span class="identifier">mean</span> <span class="special">=</span> <span class="identifier">accumulators</span><span class="special">::</span><span class="identifier">mean</span><span class="special"><>;</span> 2054 2055 <span class="comment">// Create a 1D-profile, which computes the mean of samples in each bin.</span> 2056 <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram_with</span><span class="special">(</span><span class="identifier">dense_storage</span><span class="special"><</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> 2057 <span class="comment">// The factory function `make_profile` is provided as a shorthand for this, so this is</span> 2058 <span class="comment">// equivalent to the previous line: auto h = make_profile(axis::integer<>(0, 2));</span> 2059 2060 <span class="comment">// An argument marked as `sample` is passed to the accumulator.</span> 2061 <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">1</span><span class="special">));</span> <span class="comment">// sample goes to first cell</span> 2062 <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">2</span><span class="special">));</span> <span class="comment">// sample goes to first cell</span> 2063 <span class="identifier">h</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">3</span><span class="special">));</span> <span class="comment">// sample goes to second cell</span> 2064 <span class="identifier">h</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">4</span><span class="special">));</span> <span class="comment">// sample goes to second cell</span> 2065 2066 <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os</span><span class="special">;</span> 2067 <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&&</span> <span class="identifier">x</span> <span class="special">:</span> <span class="identifier">indexed</span><span class="special">(</span><span class="identifier">h</span><span class="special">))</span> <span class="special">{</span> 2068 <span class="comment">// Accumulators usually have methods to access their state. Use the arrow</span> 2069 <span class="comment">// operator to access them. Here, `count()` gives the number of samples,</span> 2070 <span class="comment">// `value()` the mean, and `variance()` the variance estimate of the mean.</span> 2071 <span class="identifier">os</span> <span class="special"><<</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">format</span><span class="special">(</span><span class="string">"index %i count %i mean %.1f variance %.1f\n"</span><span class="special">)</span> <span class="special">%</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">index</span><span class="special">()</span> <span class="special">%</span> 2072 <span class="identifier">x</span><span class="special">-></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> 2073 <span class="special">}</span> 2074 <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> 2075 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span> <span class="string">"index 0 count 2 mean 1.5 variance 0.5\n"</span> 2076 <span class="string">"index 1 count 2 mean 3.5 variance 0.5\n"</span><span class="special">);</span> 2077<span class="special">}</span> 2078</pre> 2079<p> 2080 The simplest way to make a custom accumulator is to inherit from one of 2081 the builtin accumulators. The following example shows how to add arbitrary 2082 metadata to each histogram cell by inheriting a custom accumulator from 2083 a builtin accumulator. 2084 </p> 2085<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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> 2086<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cmath</span><span class="special">></span> 2087<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span> 2088<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">sstream</span><span class="special">></span> 2089<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">string</span><span class="special">></span> 2090 2091<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span> 2092 <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span> 2093 2094 <span class="comment">// derive custom accumulator from one of the builtins</span> 2095 <span class="keyword">struct</span> <span class="identifier">accumulator_with_metadata</span> <span class="special">:</span> <span class="identifier">accumulators</span><span class="special">::</span><span class="identifier">count</span><span class="special"><></span> <span class="special">{</span> 2096 <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">meta</span><span class="special">;</span> <span class="comment">// custom meta data</span> 2097 2098 <span class="comment">// arbitrary additional data and interface could be added here</span> 2099 <span class="special">};</span> 2100 2101 <span class="comment">// make 1D histogram with custom accmulator</span> 2102 <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram_with</span><span class="special">(</span><span class="identifier">dense_storage</span><span class="special"><</span><span class="identifier">accumulator_with_metadata</span><span class="special">>(),</span> 2103 <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">4</span><span class="special">));</span> 2104 2105 <span class="comment">// fill some weighted entries</span> 2106 <span class="keyword">auto</span> <span class="identifier">x</span> <span class="special">=</span> <span class="special">{</span><span class="number">1</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="number">1</span><span class="special">};</span> 2107 <span class="identifier">h</span><span class="special">.</span><span class="identifier">fill</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span> 2108 2109 <span class="comment">// assigning meta data to two bins</span> 2110 <span class="identifier">h</span><span class="special">[</span><span class="number">0</span><span class="special">].</span><span class="identifier">meta</span> <span class="special">=</span> <span class="string">"Foo"</span><span class="special">;</span> 2111 <span class="identifier">h</span><span class="special">[</span><span class="number">2</span><span class="special">].</span><span class="identifier">meta</span> <span class="special">=</span> <span class="string">"Bar"</span><span class="special">;</span> 2112 2113 <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os</span><span class="special">;</span> 2114 <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&&</span> <span class="identifier">x</span> <span class="special">:</span> <span class="identifier">indexed</span><span class="special">(</span><span class="identifier">h</span><span class="special">))</span> 2115 <span class="identifier">os</span> <span class="special"><<</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">bin</span><span class="special">()</span> <span class="special"><<</span> <span class="string">" value "</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="string">" meta "</span> <span class="special"><<</span> <span class="identifier">x</span><span class="special">-></span><span class="identifier">meta</span> <span class="special"><<</span> <span class="string">"\n"</span><span class="special">;</span> 2116 2117 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</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> 2118 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span> <span class="string">"1 value 2 meta Foo\n"</span> 2119 <span class="string">"2 value 1 meta \n"</span> 2120 <span class="string">"3 value 0 meta Bar\n"</span><span class="special">);</span> 2121<span class="special">}</span> 2122</pre> 2123<p> 2124 The next example shows how to making a custom accumulators completely from 2125 scratch. The library was designed to make this as easy as possible. 2126 </p> 2127<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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> 2128<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> 2129<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span> 2130<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span> 2131<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">sstream</span><span class="special">></span> 2132 2133<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span> 2134 <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span> 2135 2136 <span class="comment">// A custom accumulator which tracks the maximum of the samples.</span> 2137 <span class="comment">// It must have a call operator that accepts the argument of the `sample` function.</span> 2138 <span class="keyword">struct</span> <span class="identifier">maximum</span> <span class="special">{</span> 2139 <span class="comment">// return value is ignored, so we use void</span> 2140 <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">double</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span> 2141 <span class="keyword">if</span> <span class="special">(</span><span class="identifier">x</span> <span class="special">></span> <span class="identifier">value</span><span class="special">)</span> <span class="identifier">value</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">;</span> 2142 <span class="special">}</span> 2143 <span class="keyword">double</span> <span class="identifier">value</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="comment">// value is public and initialized to zero</span> 2144 <span class="special">};</span> 2145 2146 <span class="comment">// Create 1D histogram that uses the custom accumulator.</span> 2147 <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram_with</span><span class="special">(</span><span class="identifier">dense_storage</span><span class="special"><</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> 2148 <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">1.0</span><span class="special">));</span> <span class="comment">// sample goes to first cell</span> 2149 <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">2.0</span><span class="special">));</span> <span class="comment">// sample goes to first cell</span> 2150 <span class="identifier">h</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">3.0</span><span class="special">));</span> <span class="comment">// sample goes to second cell</span> 2151 <span class="identifier">h</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">4.0</span><span class="special">));</span> <span class="comment">// sample goes to second cell</span> 2152 2153 <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os</span><span class="special">;</span> 2154 <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&&</span> <span class="identifier">x</span> <span class="special">:</span> <span class="identifier">indexed</span><span class="special">(</span><span class="identifier">h</span><span class="special">))</span> <span class="special">{</span> 2155 <span class="identifier">os</span> <span class="special"><<</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> 2156 <span class="special">}</span> 2157 <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> 2158 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span> <span class="string">"index 0 maximum 2.0\n"</span> 2159 <span class="string">"index 1 maximum 4.0\n"</span><span class="special">);</span> 2160<span class="special">}</span> 2161</pre> 2162<p> 2163 The next example shows a more complex custom accumulator that accepts two 2164 samples at once and an optional weight. It independently computes the mean 2165 for each sample. This is more efficient than filling two separate profiles, 2166 because the cell lookup has to be done only once. 2167 </p> 2168<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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> 2169<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> 2170<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span> 2171<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">sstream</span><span class="special">></span> 2172 2173<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span> 2174 <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span> 2175 2176 <span class="comment">// Accumulator accepts two samples and an optional weight and computes the mean of each.</span> 2177 <span class="keyword">struct</span> <span class="identifier">multi_mean</span> <span class="special">{</span> 2178 <span class="identifier">accumulators</span><span class="special">::</span><span class="identifier">mean</span><span class="special"><></span> <span class="identifier">mx</span><span class="special">,</span> <span class="identifier">my</span><span class="special">;</span> 2179 2180 <span class="comment">// called when no weight is passed</span> 2181 <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">double</span> <span class="identifier">x</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">{</span> 2182 <span class="identifier">mx</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span> 2183 <span class="identifier">my</span><span class="special">(</span><span class="identifier">y</span><span class="special">);</span> 2184 <span class="special">}</span> 2185 2186 <span class="comment">// called when a weight is passed</span> 2187 <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">weight_type</span><span class="special"><</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> 2188 <span class="identifier">mx</span><span class="special">(</span><span class="identifier">w</span><span class="special">,</span> <span class="identifier">x</span><span class="special">);</span> 2189 <span class="identifier">my</span><span class="special">(</span><span class="identifier">w</span><span class="special">,</span> <span class="identifier">y</span><span class="special">);</span> 2190 <span class="special">}</span> 2191 <span class="special">};</span> 2192 <span class="comment">// Note: The implementation can be made more efficient by sharing the sum of weights.</span> 2193 2194 <span class="comment">// Create a 1D histogram that uses the custom accumulator.</span> 2195 <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram_with</span><span class="special">(</span><span class="identifier">dense_storage</span><span class="special"><</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> 2196 <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">));</span> <span class="comment">// samples go to first cell</span> 2197 <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">3</span><span class="special">,</span> <span class="number">4</span><span class="special">));</span> <span class="comment">// samples go to first cell</span> 2198 <span class="identifier">h</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">5</span><span class="special">,</span> <span class="number">6</span><span class="special">),</span> <span class="identifier">weight</span><span class="special">(</span><span class="number">2</span><span class="special">));</span> <span class="comment">// samples go to second cell</span> 2199 <span class="identifier">h</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">7</span><span class="special">,</span> <span class="number">8</span><span class="special">),</span> <span class="identifier">weight</span><span class="special">(</span><span class="number">3</span><span class="special">));</span> <span class="comment">// samples go to second cell</span> 2200 2201 <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os</span><span class="special">;</span> 2202 <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&&</span> <span class="identifier">bin</span> <span class="special">:</span> <span class="identifier">indexed</span><span class="special">(</span><span class="identifier">h</span><span class="special">))</span> <span class="special">{</span> 2203 <span class="identifier">os</span> <span class="special"><<</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">format</span><span class="special">(</span><span class="string">"index %i mean-x %.1f mean-y %.1f\n"</span><span class="special">)</span> <span class="special">%</span> <span class="identifier">bin</span><span class="special">.</span><span class="identifier">index</span><span class="special">()</span> <span class="special">%</span> 2204 <span class="identifier">bin</span><span class="special">-></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> 2205 <span class="special">}</span> 2206 <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> 2207 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span> <span class="string">"index 0 mean-x 2.0 mean-y 3.0\n"</span> 2208 <span class="string">"index 1 mean-x 6.2 mean-y 7.2\n"</span><span class="special">);</span> 2209<span class="special">}</span> 2210</pre> 2211<p> 2212 And finally, just for fun, we use a histogram as the accumulator for another 2213 histogram. 2214 </p> 2215<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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> 2216<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cmath</span><span class="special">></span> 2217<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span> 2218<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">sstream</span><span class="special">></span> 2219<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">string</span><span class="special">></span> 2220 2221<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span> 2222 <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span> 2223 2224 <span class="comment">// First we define the nested histogram type.</span> 2225 <span class="keyword">using</span> <span class="identifier">axis_t</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">category</span><span class="special"><</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">null_type</span><span class="special">,</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">option</span><span class="special">::</span><span class="identifier">growth_t</span><span class="special">>;</span> 2226 <span class="keyword">using</span> <span class="identifier">base_t</span> <span class="special">=</span> <span class="identifier">histogram</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span><span class="special"><</span><span class="identifier">axis_t</span><span class="special">>>;</span> 2227 2228 <span class="comment">// Now we make an accumulator out of it by using inheritance.</span> 2229 <span class="comment">// We only need to implement operator(). A matching version of operator() is actually</span> 2230 <span class="comment">// present in base_t, but it is templated and this is not allowed by the accumulator</span> 2231 <span class="comment">// concept. Initialization could also happen here. We don't need to initialize anything</span> 2232 <span class="comment">// here, because the default constructor of base_t is called automatically and</span> 2233 <span class="comment">// sufficient for this example.</span> 2234 <span class="keyword">struct</span> <span class="identifier">hist_t</span> <span class="special">:</span> <span class="identifier">base_t</span> <span class="special">{</span> 2235 <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">const</span> <span class="keyword">double</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span> <span class="identifier">base_t</span><span class="special">::</span><span class="keyword">operator</span><span class="special">()(</span><span class="identifier">x</span><span class="special">);</span> <span class="special">}</span> 2236 <span class="special">};</span> 2237 2238 <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram_with</span><span class="special">(</span><span class="identifier">dense_storage</span><span class="special"><</span><span class="identifier">hist_t</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">4</span><span class="special">));</span> 2239 2240 <span class="keyword">auto</span> <span class="identifier">x</span> <span class="special">=</span> <span class="special">{</span><span class="number">1</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="number">2</span><span class="special">};</span> 2241 <span class="keyword">auto</span> <span class="identifier">s</span> <span class="special">=</span> <span class="special">{</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="number">3</span><span class="special">,</span> <span class="number">3</span><span class="special">};</span> <span class="comment">// samples are filled into the nested histograms</span> 2242 <span class="identifier">h</span><span class="special">.</span><span class="identifier">fill</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="identifier">s</span><span class="special">));</span> 2243 2244 <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os</span><span class="special">;</span> 2245 <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&&</span> <span class="identifier">x</span> <span class="special">:</span> <span class="identifier">indexed</span><span class="special">(</span><span class="identifier">h</span><span class="special">))</span> <span class="special">{</span> 2246 <span class="identifier">os</span> <span class="special"><<</span> <span class="identifier">x</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> 2247 <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&&</span> <span class="identifier">y</span> <span class="special">:</span> <span class="identifier">indexed</span><span class="special">(*</span><span class="identifier">x</span><span class="special">))</span> <span class="special">{</span> <span class="identifier">os</span> <span class="special"><<</span> <span class="string">"("</span> <span class="special"><<</span> <span class="identifier">y</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">y</span> <span class="special"><<</span> <span class="string">") "</span><span class="special">;</span> <span class="special">}</span> 2248 <span class="identifier">os</span> <span class="special"><<</span> <span class="string">"\n"</span><span class="special">;</span> 2249 <span class="special">}</span> 2250 2251 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</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> 2252 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span> <span class="string">"1 (1: 1) (2: 1) \n"</span> 2253 <span class="string">"2 (3: 2) \n"</span> 2254 <span class="string">"3 \n"</span><span class="special">);</span> 2255<span class="special">}</span> 2256</pre> 2257<p> 2258 Note that the axis size of the nested histogram differs from bin to bin. 2259 Creating a 2D histogram in this way is not as efficient as the normal way, 2260 but it allows one to create a histograms with such a non-rectangular layout 2261 of cells. 2262 </p> 2263</div> 2264</div> 2265</div> 2266<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> 2267<td align="left"></td> 2268<td align="right"><div class="copyright-footer">Copyright © 2016-2019 Hans 2269 Dembinski<p> 2270 Distributed under the Boost Software License, Version 1.0. (See accompanying 2271 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 2272 </p> 2273</div></td> 2274</tr></table> 2275<hr> 2276<div class="spirit-nav"> 2277<a accesskey="p" href="getting_started.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="benchmarks.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a> 2278</div> 2279</body> 2280</html> 2281