2
0
mirror of https://github.com/boostorg/math.git synced 2026-01-19 04:22:09 +00:00

Doc: Add sections Migrating Code, and Function Writing Guidelines. Additional math function overloads: acosh, asinh, atanh, cosh, erf, lambert_w0, sinc, sinh, tanh. Attempt to fix appveyor errors.

This commit is contained in:
Matt Pulver
2019-02-12 07:43:04 -05:00
parent 04aeb5fdd9
commit 9418a4e2d4
10 changed files with 1850 additions and 289 deletions

Binary file not shown.

View File

@@ -67,6 +67,7 @@ automatic differentiation] (forward mode) of mathematical functions of single an
This implementation is based upon the [@https://en.wikipedia.org/wiki/Taylor_series Taylor series] expansion of
an analytic function /f/ at the point ['x[sub 0]]:
[/ Thanks to http://www.tlhiv.org/ltxpreview/ for LaTeX-to-SVG conversions. ]
[/ \Large\begin{align*}
f(x_0+\varepsilon) &= f(x_0) + f'(x_0)\varepsilon + \frac{f''(x_0)}{2!}\varepsilon^2 + \frac{f'''(x_0)}{3!}\varepsilon^3 + \cdots \\
&= \sum_{n=0}^N\frac{f^{(n)}(x_0)}{n!}\varepsilon^n + O\left(\varepsilon^{N+1}\right).
@@ -78,20 +79,21 @@ the first-order polynomial ['x[sub 0]+\u03b5], the resulting polynomial in ['\u0
derivatives within the coefficients. Each coefficient is equal to a derivative of its respective order, divided
by the factorial of the order.
Assume one is interested in the first /N/ derivatives of /f/ at ['x[sub 0]]. Then without any loss of precision
to the calculation of the derivatives, all terms ['O(\u03b5[super N+1])] that include powers of ['\u03b5] greater
than /N/ can be discarded, and under these truncation rules, /f/ provides a polynomial-to-polynomial transformation:
Assume one is interested in calculating the first /N/ derivatives of /f/ at ['x[sub 0]]. Then without any loss of
precision to the calculation of the derivatives, all terms ['O(\u03b5[super N+1])] that include powers of ['\u03b5]
greater than /N/ can be discarded, and under these truncation rules, /f/ provides a polynomial-to-polynomial
transformation:
[/ \Large$$f \qquad : \qquad x_0+\varepsilon \qquad \mapsto \qquad
\sum_{n=0}^Ny_n\varepsilon^n=\sum_{n=0}^N\frac{f^{(n)}(x_0)}{n!}\varepsilon^n.$$ ]
[:[:[autodiff_equation polynomial_transform.svg]]]
C++'s ability to overload operators and functions allows for the creation of a class `fvar` that represents
polynomials in ['\u03b5]. Thus the same algorithm that calculates the numeric value of ['y[sub 0]=f(x[sub 0])]
is also used to calculate the polynomial ['\u03a3[sub n]y[sub n]\u03b5[super n]=f(x[sub 0]+\u03b5)].
The derivatives are then found from the product of the respective factorial and coefficient:
C++'s ability to overload operators and functions allows for the creation of a class `fvar` ([_f]orward-mode autodiff
[_var]iable) that represents polynomials in ['\u03b5]. Thus the same algorithm that calculates the numeric value of
['y[sub 0]=f(x[sub 0])] is also used to calculate the polynomial ['\u03a3[sub n]y[sub n]\u03b5[super n]=f(x[sub
0]+\u03b5)]. The derivatives are then found from the product of the respective factorial and coefficient:
[/ \Large$$f^{(n)}(x_0)=n!y_n.$$ ]
[/ \Large$$\frac{d^nf}{dx^n}(x_0)=n!y_n.$$ ]
[:[:[autodiff_equation derivative_formula.svg]]]
@@ -101,11 +103,11 @@ The derivatives are then found from the product of the respective factorial and
[h3 Calculate derivatives of ['f(x)=x[super 4]] at /x/=2.]
In this example, `autodiff_fvar<double,5>` is a data type that can hold a polynomial of up to degree 5,
and `make_fvar<double,5>(2.0)` represents the polynomial 2+['\u03b5]. Internally, this is modeled by a
`std::array<double,6>` whose elements `{2, 1, 0, 0, 0, 0}` correspond to the 6 coefficients of the polynomial upon
initialization. Its fourth power is a polynomial with coefficients `y = {16, 32, 24, 8, 1, 0}`. The derivatives
are obtained using the formula ['f[super (n)](2)=n!*y[n]].
In this example, `autodiff_fvar<double,5>` is a data type that can hold a polynomial of up to degree 5, and
`make_fvar<double,5>(2)` represents the polynomial 2+['\u03b5]. Internally, this is modeled by a `std::array<double,6>`
whose elements `{2, 1, 0, 0, 0, 0}` correspond to the 6 coefficients of the polynomial upon initialization.
Its fourth power is a polynomial with coefficients `y = {16, 32, 24, 8, 1, 0}`. The derivatives are obtained
using the formula ['f[super (n)](2)=n!*y[n]].
#include <boost/math/differentiation/autodiff.hpp>
#include <iostream>
@@ -154,15 +156,15 @@ Example 2: Multi-variable mixed partial derivatives with multi-precision data ty
[/ \Large$\frac{\partial^{12}f}{\partial w^{3}\partial x^{2}\partial y^{4}\partial z^{3}}(11,12,13,14)$]
[/ \Large$f(w,x,y,z)=\exp\left(w\sin\left(\frac{x\log(y)}{z}\right)+\sqrt{\frac{wz}{xy}}\right)+\frac{w^2}{\tan(z)}$]
[h3 Calculate [autodiff_equation mixed12.svg] with a precision of about 100 decimal digits,
[h3 Calculate [autodiff_equation mixed12.svg] with a precision of about 50 decimal digits,
where [autodiff_equation example2f.svg].]
In this example, the data type `autodiff_fvar<cpp_dec_float_100,Nw,Nx,Ny,Nz>` represents a multivariate polynomial
in 4 independent variables, where the highest powers of each are `Nw`, `Nx`, `Ny` and `Nz`. The underlying
arithmetic data type, aliased as `root_type`, is `boost::multiprecision::cpp_dec_float_100`. The internal data
type is `std::array<std::array<std::array<std::array<cpp_dec_float_100,Nz+1>,Ny+1>,Nx+1>,Nw+1>`. The `root_type`
is always the first template parameter to `autodiff_fvar<...>` followed by the maximum derivative orders that are
to be calculated for each independent variable.
In this example, the data type `autodiff_fvar<cpp_bin_float_50,Nw,Nx,Ny,Nz>` represents a multivariate polynomial in
4 independent variables, where the highest powers of each are `Nw`, `Nx`, `Ny` and `Nz`. The underlying arithmetic
data type, aliased as `root_type`, is `boost::multiprecision::cpp_bin_float_50`. The internal data structure is
`std::array<std::array<std::array<std::array<cpp_bin_float_50,Nz+1>,Ny+1>,Nx+1>,Nw+1>`. The `root_type` is always
the first template parameter to `autodiff_fvar<...>` followed by the maximum derivative orders that are to be
calculated for each independent variable.
When variables are initialized with `make_fvar<...>()`, the position of the last derivative order given in the
template parameter pack determines which variable is taken to be independent. In other words, it determines which
@@ -170,10 +172,10 @@ of the 4 different polynomial variables ['\u03b5[sub w]], ['\u03b5[sub x]], ['\u
are to be added to the constant term:
[/ \Large\begin{align*}
\texttt{make\_fvar<cpp\_dec\_float\_100,Nw>(11)} &= 11+\varepsilon_w \\
\texttt{make\_fvar<cpp\_dec\_float\_100,0,Nx>(12)} &= 12+\varepsilon_x \\
\texttt{make\_fvar<cpp\_dec\_float\_100,0,0,Ny>(13)} &= 13+\varepsilon_y \\
\texttt{make\_fvar<cpp\_dec\_float\_100,0,0,0,Nz>(14)} &= 14+\varepsilon_z
\texttt{make\_fvar<cpp\_bin\_float\_50,Nw>(11)} &= 11+\varepsilon_w \\
\texttt{make\_fvar<cpp\_bin\_float\_50,0,Nx>(12)} &= 12+\varepsilon_x \\
\texttt{make\_fvar<cpp\_bin\_float\_50,0,0,Ny>(13)} &= 13+\varepsilon_y \\
\texttt{make\_fvar<cpp\_bin\_float\_50,0,0,0,Nz>(14)} &= 14+\varepsilon_z
\end{align*}\]
[:[:[autodiff_equation example2make_fvar.svg]]]
@@ -181,7 +183,7 @@ Instances of different types are automatically promoted to the smallest multi-va
when they are combined (added, subtracted, multiplied, divided.)
#include <boost/math/differentiation/autodiff.hpp>
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <boost/multiprecision/cpp_bin_float.hpp>
#include <iostream>
template<typename T>
@@ -193,22 +195,22 @@ when they are combined (added, subtracted, multiplied, divided.)
int main()
{
using cpp_dec_float_100 = boost::multiprecision::cpp_dec_float_100;
using cpp_bin_float_50 = boost::multiprecision::cpp_bin_float_50;
using namespace boost::math::differentiation;
constexpr int Nw=3; // Max order of derivative to calculate for w
constexpr int Nx=2; // Max order of derivative to calculate for x
constexpr int Ny=4; // Max order of derivative to calculate for y
constexpr int Nz=3; // Max order of derivative to calculate for z
using var = autodiff_fvar<cpp_dec_float_100,Nw,Nx,Ny,Nz>;
const var w = make_fvar<cpp_dec_float_100,Nw>(11);
const var x = make_fvar<cpp_dec_float_100,0,Nx>(12);
const var y = make_fvar<cpp_dec_float_100,0,0,Ny>(13);
const var z = make_fvar<cpp_dec_float_100,0,0,0,Nz>(14);
using var = autodiff_fvar<cpp_bin_float_50,Nw,Nx,Ny,Nz>;
const var w = make_fvar<cpp_bin_float_50,Nw>(11);
const var x = make_fvar<cpp_bin_float_50,0,Nx>(12);
const var y = make_fvar<cpp_bin_float_50,0,0,Ny>(13);
const var z = make_fvar<cpp_bin_float_50,0,0,0,Nz>(14);
const var v = f(w,x,y,z);
// Calculated from Mathematica symbolic differentiation. See multiprecision.nb for script.
const cpp_dec_float_100 answer("1976.31960074779771777988187529041872090812118921875499076582535951111845769110560421820940516423255314");
std::cout << std::setprecision(std::numeric_limits<cpp_dec_float_100>::digits10)
const cpp_bin_float_50 answer("1976.319600747797717779881875290418720908121189218755");
std::cout << std::setprecision(std::numeric_limits<cpp_bin_float_50>::digits10)
<< "mathematica : " << answer << '\n'
<< "autodiff : " << v.derivative(Nw,Nx,Ny,Nz) << '\n'
<< "relative error: " << std::setprecision(3) << (v.derivative(Nw,Nx,Ny,Nz)/answer-1) << std::endl;
@@ -216,12 +218,12 @@ when they are combined (added, subtracted, multiplied, divided.)
}
/*
Output:
mathematica : 1976.319600747797717779881875290418720908121189218754990765825359511118457691105604218209405164232553
autodiff : 1976.319600747797717779881875290418720908121189218754990765825359511118457691105604218209405164232566
relative error: 6.47e-99
mathematica : 1976.3196007477977177798818752904187209081211892188
autodiff : 1976.3196007477977177798818752904187209081211892188
relative error: 2.67e-50
*/
[h1 Documentation]
[h1 Manual]
Additional details are in the [@../differentiation/autodiff.pdf autodiff manual].
[endsect]

File diff suppressed because it is too large Load Diff

View File

@@ -1,90 +1,94 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="95pt" height="18pt" viewBox="0 0 95 18" version="1.1">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="96pt" height="31pt" viewBox="0 0 96 31" version="1.1">
<defs>
<g>
<symbol overflow="visible" id="glyph0-0">
<path style="stroke:none;" d="M 6.390625 -5.765625 C 6.6875 -5.765625 6.796875 -5.765625 6.796875 -6.03125 C 6.796875 -6.1875 6.6875 -6.1875 6.421875 -6.1875 L 5.265625 -6.1875 C 5.53125 -7.65625 5.734375 -8.671875 5.859375 -9.140625 C 5.9375 -9.484375 6.234375 -9.8125 6.609375 -9.8125 C 6.90625 -9.8125 7.21875 -9.6875 7.359375 -9.546875 C 6.796875 -9.5 6.625 -9.078125 6.625 -8.828125 C 6.625 -8.546875 6.84375 -8.375 7.109375 -8.375 C 7.40625 -8.375 7.828125 -8.625 7.828125 -9.171875 C 7.828125 -9.765625 7.234375 -10.09375 6.59375 -10.09375 C 5.984375 -10.09375 5.375 -9.640625 5.09375 -9.078125 C 4.828125 -8.578125 4.6875 -8.0625 4.359375 -6.1875 L 3.40625 -6.1875 C 3.125 -6.1875 2.984375 -6.1875 2.984375 -5.921875 C 2.984375 -5.765625 3.0625 -5.765625 3.359375 -5.765625 L 4.28125 -5.765625 C 4.015625 -4.4375 3.421875 -1.1875 3.09375 0.34375 C 2.859375 1.59375 2.640625 2.640625 1.921875 2.640625 C 1.875 2.640625 1.46875 2.640625 1.203125 2.359375 C 1.9375 2.3125 1.9375 1.671875 1.9375 1.65625 C 1.9375 1.375 1.71875 1.203125 1.453125 1.203125 C 1.15625 1.203125 0.734375 1.453125 0.734375 2 C 0.734375 2.609375 1.359375 2.921875 1.921875 2.921875 C 3.390625 2.921875 3.984375 0.296875 4.140625 -0.421875 C 4.40625 -1.515625 5.109375 -5.328125 5.171875 -5.765625 Z M 6.390625 -5.765625 "/>
<path style="stroke:none;" d="M 7.21875 -9.59375 C 7.234375 -9.65625 7.265625 -9.734375 7.265625 -9.8125 C 7.265625 -9.953125 7.109375 -9.953125 7.078125 -9.953125 C 7.078125 -9.953125 6.375 -9.890625 6.296875 -9.890625 C 6.046875 -9.875 5.84375 -9.84375 5.578125 -9.828125 C 5.21875 -9.796875 5.125 -9.78125 5.125 -9.53125 C 5.125 -9.375 5.234375 -9.375 5.4375 -9.375 C 6.140625 -9.375 6.15625 -9.25 6.15625 -9.109375 C 6.15625 -9.015625 6.125 -8.90625 6.109375 -8.859375 L 5.234375 -5.375 C 5.078125 -5.75 4.6875 -6.328125 3.9375 -6.328125 C 2.328125 -6.328125 0.578125 -4.234375 0.578125 -2.109375 C 0.578125 -0.6875 1.40625 0.140625 2.375 0.140625 C 3.171875 0.140625 3.84375 -0.46875 4.25 -0.953125 C 4.390625 -0.09375 5.0625 0.140625 5.5 0.140625 C 5.921875 0.140625 6.265625 -0.109375 6.53125 -0.625 C 6.75 -1.125 6.953125 -2 6.953125 -2.046875 C 6.953125 -2.125 6.90625 -2.1875 6.8125 -2.1875 C 6.6875 -2.1875 6.671875 -2.109375 6.609375 -1.890625 C 6.390625 -1.046875 6.125 -0.140625 5.53125 -0.140625 C 5.125 -0.140625 5.09375 -0.515625 5.09375 -0.796875 C 5.09375 -0.859375 5.09375 -1.15625 5.1875 -1.5625 Z M 4.3125 -1.703125 C 4.25 -1.46875 4.25 -1.4375 4.046875 -1.15625 C 3.734375 -0.765625 3.09375 -0.140625 2.421875 -0.140625 C 1.84375 -0.140625 1.5 -0.671875 1.5 -1.515625 C 1.5 -2.3125 1.953125 -3.921875 2.21875 -4.515625 C 2.71875 -5.515625 3.390625 -6.03125 3.9375 -6.03125 C 4.890625 -6.03125 5.078125 -4.859375 5.078125 -4.75 C 5.078125 -4.734375 5.03125 -4.546875 5.015625 -4.515625 Z M 4.3125 -1.703125 "/>
</symbol>
<symbol overflow="visible" id="glyph0-1">
<path style="stroke:none;" d="M 6.796875 -5.859375 C 6.34375 -5.765625 6.171875 -5.421875 6.171875 -5.15625 C 6.171875 -4.8125 6.4375 -4.6875 6.640625 -4.6875 C 7.078125 -4.6875 7.375 -5.0625 7.375 -5.453125 C 7.375 -6.046875 6.6875 -6.328125 6.078125 -6.328125 C 5.203125 -6.328125 4.71875 -5.46875 4.59375 -5.1875 C 4.265625 -6.265625 3.375 -6.328125 3.109375 -6.328125 C 1.65625 -6.328125 0.875 -4.453125 0.875 -4.125 C 0.875 -4.078125 0.9375 -4 1.03125 -4 C 1.140625 -4 1.171875 -4.09375 1.203125 -4.140625 C 1.6875 -5.734375 2.65625 -6.03125 3.0625 -6.03125 C 3.71875 -6.03125 3.84375 -5.4375 3.84375 -5.09375 C 3.84375 -4.78125 3.765625 -4.453125 3.578125 -3.765625 L 3.09375 -1.796875 C 2.890625 -0.9375 2.46875 -0.140625 1.703125 -0.140625 C 1.640625 -0.140625 1.28125 -0.140625 0.96875 -0.328125 C 1.484375 -0.4375 1.609375 -0.859375 1.609375 -1.03125 C 1.609375 -1.3125 1.390625 -1.484375 1.125 -1.484375 C 0.78125 -1.484375 0.40625 -1.1875 0.40625 -0.734375 C 0.40625 -0.125 1.078125 0.140625 1.6875 0.140625 C 2.375 0.140625 2.875 -0.40625 3.171875 -0.984375 C 3.40625 -0.140625 4.109375 0.140625 4.640625 0.140625 C 6.109375 0.140625 6.890625 -1.734375 6.890625 -2.046875 C 6.890625 -2.125 6.828125 -2.1875 6.734375 -2.1875 C 6.609375 -2.1875 6.59375 -2.109375 6.5625 -2 C 6.171875 -0.734375 5.328125 -0.140625 4.6875 -0.140625 C 4.1875 -0.140625 3.921875 -0.515625 3.921875 -1.109375 C 3.921875 -1.421875 3.96875 -1.65625 4.203125 -2.59375 L 4.703125 -4.546875 C 4.921875 -5.40625 5.40625 -6.03125 6.0625 -6.03125 C 6.09375 -6.03125 6.5 -6.03125 6.796875 -5.859375 Z M 6.796875 -5.859375 "/>
<path style="stroke:none;" d="M 6.390625 -5.765625 C 6.6875 -5.765625 6.796875 -5.765625 6.796875 -6.03125 C 6.796875 -6.1875 6.6875 -6.1875 6.421875 -6.1875 L 5.265625 -6.1875 C 5.53125 -7.65625 5.734375 -8.671875 5.859375 -9.140625 C 5.9375 -9.484375 6.234375 -9.8125 6.609375 -9.8125 C 6.90625 -9.8125 7.21875 -9.6875 7.359375 -9.546875 C 6.796875 -9.5 6.625 -9.078125 6.625 -8.828125 C 6.625 -8.546875 6.84375 -8.375 7.109375 -8.375 C 7.40625 -8.375 7.828125 -8.625 7.828125 -9.171875 C 7.828125 -9.765625 7.234375 -10.09375 6.59375 -10.09375 C 5.984375 -10.09375 5.375 -9.640625 5.09375 -9.078125 C 4.828125 -8.578125 4.6875 -8.0625 4.359375 -6.1875 L 3.40625 -6.1875 C 3.125 -6.1875 2.984375 -6.1875 2.984375 -5.921875 C 2.984375 -5.765625 3.0625 -5.765625 3.359375 -5.765625 L 4.28125 -5.765625 C 4.015625 -4.4375 3.421875 -1.1875 3.09375 0.34375 C 2.859375 1.59375 2.640625 2.640625 1.921875 2.640625 C 1.875 2.640625 1.46875 2.640625 1.203125 2.359375 C 1.9375 2.3125 1.9375 1.671875 1.9375 1.65625 C 1.9375 1.375 1.71875 1.203125 1.453125 1.203125 C 1.15625 1.203125 0.734375 1.453125 0.734375 2 C 0.734375 2.609375 1.359375 2.921875 1.921875 2.921875 C 3.390625 2.921875 3.984375 0.296875 4.140625 -0.421875 C 4.40625 -1.515625 5.109375 -5.328125 5.171875 -5.765625 Z M 6.390625 -5.765625 "/>
</symbol>
<symbol overflow="visible" id="glyph0-2">
<path style="stroke:none;" d="M 2.953125 -4.203125 C 2.984375 -4.28125 3.34375 -5 3.875 -5.46875 C 4.25 -5.8125 4.734375 -6.03125 5.296875 -6.03125 C 5.859375 -6.03125 6.0625 -5.609375 6.0625 -5.03125 C 6.0625 -4.21875 5.484375 -2.578125 5.1875 -1.8125 C 5.0625 -1.46875 4.984375 -1.28125 4.984375 -1.015625 C 4.984375 -0.375 5.4375 0.140625 6.125 0.140625 C 7.453125 0.140625 7.953125 -1.96875 7.953125 -2.046875 C 7.953125 -2.125 7.90625 -2.1875 7.8125 -2.1875 C 7.6875 -2.1875 7.671875 -2.140625 7.609375 -1.890625 C 7.265625 -0.71875 6.734375 -0.140625 6.171875 -0.140625 C 6.03125 -0.140625 5.796875 -0.15625 5.796875 -0.609375 C 5.796875 -0.96875 5.953125 -1.40625 6.03125 -1.609375 C 6.328125 -2.390625 6.921875 -4 6.921875 -4.8125 C 6.921875 -5.6875 6.421875 -6.328125 5.328125 -6.328125 C 4.0625 -6.328125 3.390625 -5.421875 3.125 -5.0625 C 3.078125 -5.875 2.5 -6.328125 1.859375 -6.328125 C 1.40625 -6.328125 1.09375 -6.046875 0.84375 -5.5625 C 0.59375 -5.046875 0.390625 -4.1875 0.390625 -4.125 C 0.390625 -4.078125 0.4375 -4 0.546875 -4 C 0.65625 -4 0.671875 -4.015625 0.765625 -4.34375 C 0.984375 -5.21875 1.25 -6.03125 1.828125 -6.03125 C 2.15625 -6.03125 2.265625 -5.8125 2.265625 -5.375 C 2.265625 -5.0625 2.125 -4.5 2.015625 -4.0625 L 1.625 -2.515625 C 1.5625 -2.234375 1.40625 -1.59375 1.328125 -1.328125 C 1.234375 -0.96875 1.078125 -0.28125 1.078125 -0.21875 C 1.078125 -0.015625 1.234375 0.140625 1.453125 0.140625 C 1.625 0.140625 1.828125 0.0625 1.9375 -0.15625 C 1.96875 -0.234375 2.09375 -0.734375 2.171875 -1.015625 L 2.484375 -2.3125 Z M 2.953125 -4.203125 "/>
<path style="stroke:none;" d="M 6.796875 -5.859375 C 6.34375 -5.765625 6.171875 -5.421875 6.171875 -5.15625 C 6.171875 -4.8125 6.4375 -4.6875 6.640625 -4.6875 C 7.078125 -4.6875 7.375 -5.0625 7.375 -5.453125 C 7.375 -6.046875 6.6875 -6.328125 6.078125 -6.328125 C 5.203125 -6.328125 4.71875 -5.46875 4.59375 -5.1875 C 4.265625 -6.265625 3.375 -6.328125 3.109375 -6.328125 C 1.65625 -6.328125 0.875 -4.453125 0.875 -4.125 C 0.875 -4.078125 0.9375 -4 1.03125 -4 C 1.140625 -4 1.171875 -4.09375 1.203125 -4.140625 C 1.6875 -5.734375 2.65625 -6.03125 3.0625 -6.03125 C 3.71875 -6.03125 3.84375 -5.4375 3.84375 -5.09375 C 3.84375 -4.78125 3.765625 -4.453125 3.578125 -3.765625 L 3.09375 -1.796875 C 2.890625 -0.9375 2.46875 -0.140625 1.703125 -0.140625 C 1.640625 -0.140625 1.28125 -0.140625 0.96875 -0.328125 C 1.484375 -0.4375 1.609375 -0.859375 1.609375 -1.03125 C 1.609375 -1.3125 1.390625 -1.484375 1.125 -1.484375 C 0.78125 -1.484375 0.40625 -1.1875 0.40625 -0.734375 C 0.40625 -0.125 1.078125 0.140625 1.6875 0.140625 C 2.375 0.140625 2.875 -0.40625 3.171875 -0.984375 C 3.40625 -0.140625 4.109375 0.140625 4.640625 0.140625 C 6.109375 0.140625 6.890625 -1.734375 6.890625 -2.046875 C 6.890625 -2.125 6.828125 -2.1875 6.734375 -2.1875 C 6.609375 -2.1875 6.59375 -2.109375 6.5625 -2 C 6.171875 -0.734375 5.328125 -0.140625 4.6875 -0.140625 C 4.1875 -0.140625 3.921875 -0.515625 3.921875 -1.109375 C 3.921875 -1.421875 3.96875 -1.65625 4.203125 -2.59375 L 4.703125 -4.546875 C 4.921875 -5.40625 5.40625 -6.03125 6.0625 -6.03125 C 6.09375 -6.03125 6.5 -6.03125 6.796875 -5.859375 Z M 6.796875 -5.859375 "/>
</symbol>
<symbol overflow="visible" id="glyph0-3">
<path style="stroke:none;" d="M 3.765625 1.609375 C 3.390625 2.15625 2.828125 2.640625 2.125 2.640625 C 1.953125 2.640625 1.265625 2.609375 1.046875 1.953125 C 1.09375 1.96875 1.15625 1.96875 1.1875 1.96875 C 1.625 1.96875 1.90625 1.59375 1.90625 1.265625 C 1.90625 0.9375 1.640625 0.8125 1.421875 0.8125 C 1.1875 0.8125 0.6875 0.984375 0.6875 1.6875 C 0.6875 2.421875 1.3125 2.921875 2.125 2.921875 C 3.5625 2.921875 5 1.609375 5.40625 0.015625 L 6.8125 -5.578125 C 6.828125 -5.65625 6.859375 -5.734375 6.859375 -5.828125 C 6.859375 -6.03125 6.6875 -6.1875 6.46875 -6.1875 C 6.34375 -6.1875 6.03125 -6.125 5.921875 -5.6875 L 4.859375 -1.484375 C 4.796875 -1.21875 4.796875 -1.1875 4.671875 -1.03125 C 4.390625 -0.625 3.921875 -0.140625 3.234375 -0.140625 C 2.421875 -0.140625 2.359375 -0.9375 2.359375 -1.3125 C 2.359375 -2.140625 2.734375 -3.234375 3.125 -4.28125 C 3.28125 -4.6875 3.375 -4.890625 3.375 -5.171875 C 3.375 -5.78125 2.9375 -6.328125 2.234375 -6.328125 C 0.921875 -6.328125 0.390625 -4.25 0.390625 -4.125 C 0.390625 -4.078125 0.4375 -4 0.546875 -4 C 0.671875 -4 0.6875 -4.0625 0.75 -4.265625 C 1.09375 -5.46875 1.640625 -6.03125 2.1875 -6.03125 C 2.328125 -6.03125 2.5625 -6.03125 2.5625 -5.5625 C 2.5625 -5.1875 2.40625 -4.78125 2.1875 -4.234375 C 1.484375 -2.359375 1.484375 -1.875 1.484375 -1.53125 C 1.484375 -0.171875 2.46875 0.140625 3.1875 0.140625 C 3.59375 0.140625 4.109375 0.015625 4.625 -0.515625 L 4.640625 -0.5 C 4.421875 0.34375 4.28125 0.90625 3.765625 1.609375 Z M 3.765625 1.609375 "/>
<path style="stroke:none;" d="M 2.953125 -4.203125 C 2.984375 -4.28125 3.34375 -5 3.875 -5.46875 C 4.25 -5.8125 4.734375 -6.03125 5.296875 -6.03125 C 5.859375 -6.03125 6.0625 -5.609375 6.0625 -5.03125 C 6.0625 -4.21875 5.484375 -2.578125 5.1875 -1.8125 C 5.0625 -1.46875 4.984375 -1.28125 4.984375 -1.015625 C 4.984375 -0.375 5.4375 0.140625 6.125 0.140625 C 7.453125 0.140625 7.953125 -1.96875 7.953125 -2.046875 C 7.953125 -2.125 7.90625 -2.1875 7.8125 -2.1875 C 7.6875 -2.1875 7.671875 -2.140625 7.609375 -1.890625 C 7.265625 -0.71875 6.734375 -0.140625 6.171875 -0.140625 C 6.03125 -0.140625 5.796875 -0.15625 5.796875 -0.609375 C 5.796875 -0.96875 5.953125 -1.40625 6.03125 -1.609375 C 6.328125 -2.390625 6.921875 -4 6.921875 -4.8125 C 6.921875 -5.6875 6.421875 -6.328125 5.328125 -6.328125 C 4.0625 -6.328125 3.390625 -5.421875 3.125 -5.0625 C 3.078125 -5.875 2.5 -6.328125 1.859375 -6.328125 C 1.40625 -6.328125 1.09375 -6.046875 0.84375 -5.5625 C 0.59375 -5.046875 0.390625 -4.1875 0.390625 -4.125 C 0.390625 -4.078125 0.4375 -4 0.546875 -4 C 0.65625 -4 0.671875 -4.015625 0.765625 -4.34375 C 0.984375 -5.21875 1.25 -6.03125 1.828125 -6.03125 C 2.15625 -6.03125 2.265625 -5.8125 2.265625 -5.375 C 2.265625 -5.0625 2.125 -4.5 2.015625 -4.0625 L 1.625 -2.515625 C 1.5625 -2.234375 1.40625 -1.59375 1.328125 -1.328125 C 1.234375 -0.96875 1.078125 -0.28125 1.078125 -0.21875 C 1.078125 -0.015625 1.234375 0.140625 1.453125 0.140625 C 1.625 0.140625 1.828125 0.0625 1.9375 -0.15625 C 1.96875 -0.234375 2.09375 -0.734375 2.171875 -1.015625 L 2.484375 -2.3125 Z M 2.953125 -4.203125 "/>
</symbol>
<symbol overflow="visible" id="glyph0-4">
<path style="stroke:none;" d="M 3.765625 1.609375 C 3.390625 2.15625 2.828125 2.640625 2.125 2.640625 C 1.953125 2.640625 1.265625 2.609375 1.046875 1.953125 C 1.09375 1.96875 1.15625 1.96875 1.1875 1.96875 C 1.625 1.96875 1.90625 1.59375 1.90625 1.265625 C 1.90625 0.9375 1.640625 0.8125 1.421875 0.8125 C 1.1875 0.8125 0.6875 0.984375 0.6875 1.6875 C 0.6875 2.421875 1.3125 2.921875 2.125 2.921875 C 3.5625 2.921875 5 1.609375 5.40625 0.015625 L 6.8125 -5.578125 C 6.828125 -5.65625 6.859375 -5.734375 6.859375 -5.828125 C 6.859375 -6.03125 6.6875 -6.1875 6.46875 -6.1875 C 6.34375 -6.1875 6.03125 -6.125 5.921875 -5.6875 L 4.859375 -1.484375 C 4.796875 -1.21875 4.796875 -1.1875 4.671875 -1.03125 C 4.390625 -0.625 3.921875 -0.140625 3.234375 -0.140625 C 2.421875 -0.140625 2.359375 -0.9375 2.359375 -1.3125 C 2.359375 -2.140625 2.734375 -3.234375 3.125 -4.28125 C 3.28125 -4.6875 3.375 -4.890625 3.375 -5.171875 C 3.375 -5.78125 2.9375 -6.328125 2.234375 -6.328125 C 0.921875 -6.328125 0.390625 -4.25 0.390625 -4.125 C 0.390625 -4.078125 0.4375 -4 0.546875 -4 C 0.671875 -4 0.6875 -4.0625 0.75 -4.265625 C 1.09375 -5.46875 1.640625 -6.03125 2.1875 -6.03125 C 2.328125 -6.03125 2.5625 -6.03125 2.5625 -5.5625 C 2.5625 -5.1875 2.40625 -4.78125 2.1875 -4.234375 C 1.484375 -2.359375 1.484375 -1.875 1.484375 -1.53125 C 1.484375 -0.171875 2.46875 0.140625 3.1875 0.140625 C 3.59375 0.140625 4.109375 0.015625 4.625 -0.515625 L 4.640625 -0.5 C 4.421875 0.34375 4.28125 0.90625 3.765625 1.609375 Z M 3.765625 1.609375 "/>
</symbol>
<symbol overflow="visible" id="glyph0-5">
<path style="stroke:none;" d="M 2.640625 -0.6875 C 2.640625 -1.109375 2.296875 -1.390625 1.953125 -1.390625 C 1.53125 -1.390625 1.25 -1.046875 1.25 -0.703125 C 1.25 -0.28125 1.59375 0 1.9375 0 C 2.359375 0 2.640625 -0.34375 2.640625 -0.6875 Z M 2.640625 -0.6875 "/>
</symbol>
<symbol overflow="visible" id="glyph1-0">
<path style="stroke:none;" d="M 3.296875 2.390625 C 3.296875 2.359375 3.296875 2.34375 3.125 2.171875 C 1.890625 0.921875 1.5625 -0.96875 1.5625 -2.5 C 1.5625 -4.234375 1.9375 -5.96875 3.171875 -7.203125 C 3.296875 -7.328125 3.296875 -7.34375 3.296875 -7.375 C 3.296875 -7.453125 3.265625 -7.484375 3.203125 -7.484375 C 3.09375 -7.484375 2.203125 -6.796875 1.609375 -5.53125 C 1.109375 -4.4375 0.984375 -3.328125 0.984375 -2.5 C 0.984375 -1.71875 1.09375 -0.515625 1.640625 0.625 C 2.25 1.84375 3.09375 2.5 3.203125 2.5 C 3.265625 2.5 3.296875 2.46875 3.296875 2.390625 Z M 3.296875 2.390625 "/>
</symbol>
<symbol overflow="visible" id="glyph1-1">
<path style="stroke:none;" d="M 2.875 -2.5 C 2.875 -3.265625 2.765625 -4.46875 2.21875 -5.609375 C 1.625 -6.828125 0.765625 -7.484375 0.671875 -7.484375 C 0.609375 -7.484375 0.5625 -7.4375 0.5625 -7.375 C 0.5625 -7.34375 0.5625 -7.328125 0.75 -7.140625 C 1.734375 -6.15625 2.296875 -4.578125 2.296875 -2.5 C 2.296875 -0.78125 1.9375 0.96875 0.703125 2.21875 C 0.5625 2.34375 0.5625 2.359375 0.5625 2.390625 C 0.5625 2.453125 0.609375 2.5 0.671875 2.5 C 0.765625 2.5 1.671875 1.8125 2.25 0.546875 C 2.765625 -0.546875 2.875 -1.65625 2.875 -2.5 Z M 2.875 -2.5 "/>
</symbol>
<symbol overflow="visible" id="glyph1-2">
<path style="stroke:none;" d="M 4.578125 -3.1875 C 4.578125 -3.984375 4.53125 -4.78125 4.1875 -5.515625 C 3.734375 -6.484375 2.90625 -6.640625 2.5 -6.640625 C 1.890625 -6.640625 1.171875 -6.375 0.75 -5.453125 C 0.4375 -4.765625 0.390625 -3.984375 0.390625 -3.1875 C 0.390625 -2.4375 0.421875 -1.546875 0.84375 -0.78125 C 1.265625 0.015625 2 0.21875 2.484375 0.21875 C 3.015625 0.21875 3.78125 0.015625 4.21875 -0.9375 C 4.53125 -1.625 4.578125 -2.40625 4.578125 -3.1875 Z M 2.484375 0 C 2.09375 0 1.5 -0.25 1.328125 -1.203125 C 1.21875 -1.796875 1.21875 -2.71875 1.21875 -3.3125 C 1.21875 -3.953125 1.21875 -4.609375 1.296875 -5.140625 C 1.484375 -6.328125 2.234375 -6.421875 2.484375 -6.421875 C 2.8125 -6.421875 3.46875 -6.234375 3.65625 -5.25 C 3.765625 -4.6875 3.765625 -3.9375 3.765625 -3.3125 C 3.765625 -2.5625 3.765625 -1.890625 3.65625 -1.25 C 3.5 -0.296875 2.9375 0 2.484375 0 Z M 2.484375 0 "/>
</symbol>
<symbol overflow="visible" id="glyph2-0">
<path style="stroke:none;" d="M 0.875 -0.59375 C 0.84375 -0.4375 0.78125 -0.203125 0.78125 -0.15625 C 0.78125 0.015625 0.921875 0.109375 1.078125 0.109375 C 1.203125 0.109375 1.375 0.03125 1.453125 -0.171875 C 1.453125 -0.1875 1.578125 -0.65625 1.640625 -0.90625 L 1.859375 -1.796875 C 1.90625 -2.03125 1.96875 -2.25 2.03125 -2.46875 C 2.0625 -2.640625 2.140625 -2.9375 2.15625 -2.96875 C 2.296875 -3.28125 2.828125 -4.1875 3.78125 -4.1875 C 4.234375 -4.1875 4.3125 -3.8125 4.3125 -3.484375 C 4.3125 -2.875 3.828125 -1.59375 3.671875 -1.171875 C 3.578125 -0.9375 3.5625 -0.8125 3.5625 -0.703125 C 3.5625 -0.234375 3.921875 0.109375 4.390625 0.109375 C 5.328125 0.109375 5.6875 -1.34375 5.6875 -1.421875 C 5.6875 -1.53125 5.609375 -1.53125 5.578125 -1.53125 C 5.46875 -1.53125 5.46875 -1.5 5.421875 -1.34375 C 5.21875 -0.671875 4.890625 -0.109375 4.40625 -0.109375 C 4.234375 -0.109375 4.171875 -0.203125 4.171875 -0.4375 C 4.171875 -0.6875 4.25 -0.921875 4.34375 -1.140625 C 4.53125 -1.671875 4.953125 -2.765625 4.953125 -3.34375 C 4.953125 -4 4.53125 -4.40625 3.8125 -4.40625 C 2.90625 -4.40625 2.421875 -3.765625 2.25 -3.53125 C 2.203125 -4.09375 1.796875 -4.40625 1.328125 -4.40625 C 0.875 -4.40625 0.6875 -4.015625 0.59375 -3.84375 C 0.421875 -3.5 0.296875 -2.90625 0.296875 -2.875 C 0.296875 -2.765625 0.390625 -2.765625 0.40625 -2.765625 C 0.515625 -2.765625 0.515625 -2.78125 0.578125 -3 C 0.75 -3.703125 0.953125 -4.1875 1.3125 -4.1875 C 1.5 -4.1875 1.609375 -4.0625 1.609375 -3.734375 C 1.609375 -3.515625 1.578125 -3.40625 1.453125 -2.890625 Z M 0.875 -0.59375 "/>
</symbol>
<symbol overflow="visible" id="glyph3-0">
<symbol overflow="visible" id="glyph2-0">
<path style="stroke:none;" d="M 4.65625 3.484375 C 4.65625 3.4375 4.65625 3.40625 4.421875 3.171875 C 2.984375 1.71875 2.1875 -0.640625 2.1875 -3.578125 C 2.1875 -6.359375 2.859375 -8.75 4.515625 -10.4375 C 4.65625 -10.578125 4.65625 -10.59375 4.65625 -10.640625 C 4.65625 -10.734375 4.59375 -10.75 4.53125 -10.75 C 4.34375 -10.75 3.171875 -9.71875 2.46875 -8.3125 C 1.734375 -6.875 1.40625 -5.328125 1.40625 -3.578125 C 1.40625 -2.296875 1.609375 -0.59375 2.359375 0.953125 C 3.203125 2.671875 4.375 3.59375 4.53125 3.59375 C 4.59375 3.59375 4.65625 3.578125 4.65625 3.484375 Z M 4.65625 3.484375 "/>
</symbol>
<symbol overflow="visible" id="glyph3-1">
<symbol overflow="visible" id="glyph2-1">
<path style="stroke:none;" d="M 4.046875 -3.578125 C 4.046875 -4.65625 3.90625 -6.4375 3.09375 -8.109375 C 2.25 -9.828125 1.078125 -10.75 0.921875 -10.75 C 0.859375 -10.75 0.78125 -10.734375 0.78125 -10.640625 C 0.78125 -10.59375 0.78125 -10.578125 1.03125 -10.328125 C 2.46875 -8.875 3.265625 -6.515625 3.265625 -3.578125 C 3.265625 -0.796875 2.59375 1.59375 0.9375 3.28125 C 0.78125 3.40625 0.78125 3.4375 0.78125 3.484375 C 0.78125 3.578125 0.859375 3.59375 0.921875 3.59375 C 1.109375 3.59375 2.28125 2.5625 2.984375 1.15625 C 3.71875 -0.296875 4.046875 -1.84375 4.046875 -3.578125 Z M 4.046875 -3.578125 "/>
</symbol>
<symbol overflow="visible" id="glyph3-2">
<symbol overflow="visible" id="glyph2-2">
<path style="stroke:none;" d="M 9.6875 -4.640625 C 9.890625 -4.640625 10.140625 -4.640625 10.140625 -4.90625 C 10.140625 -5.171875 9.890625 -5.171875 9.6875 -5.171875 L 1.234375 -5.171875 C 1.03125 -5.171875 0.78125 -5.171875 0.78125 -4.921875 C 0.78125 -4.640625 1.015625 -4.640625 1.234375 -4.640625 Z M 9.6875 -1.984375 C 9.890625 -1.984375 10.140625 -1.984375 10.140625 -2.234375 C 10.140625 -2.515625 9.890625 -2.515625 9.6875 -2.515625 L 1.234375 -2.515625 C 1.03125 -2.515625 0.78125 -2.515625 0.78125 -2.25 C 0.78125 -1.984375 1.015625 -1.984375 1.234375 -1.984375 Z M 9.6875 -1.984375 "/>
</symbol>
<symbol overflow="visible" id="glyph3-3">
<symbol overflow="visible" id="glyph2-3">
<path style="stroke:none;" d="M 2.625 -9.578125 C 2.625 -10.046875 2.234375 -10.25 1.9375 -10.25 C 1.640625 -10.25 1.1875 -10.0625 1.234375 -9.453125 L 1.75 -2.890625 C 1.765625 -2.640625 1.796875 -2.578125 1.921875 -2.578125 C 2.0625 -2.578125 2.09375 -2.625 2.109375 -2.890625 Z M 2.625 -0.703125 C 2.625 -1.078125 2.3125 -1.390625 1.9375 -1.390625 C 1.53125 -1.390625 1.234375 -1.078125 1.234375 -0.6875 C 1.234375 -0.3125 1.546875 0 1.921875 0 C 2.328125 0 2.625 -0.3125 2.625 -0.703125 Z M 2.625 -0.703125 "/>
</symbol>
<symbol overflow="visible" id="glyph3-0">
<path style="stroke:none;" d="M 4.578125 -3.1875 C 4.578125 -3.984375 4.53125 -4.78125 4.1875 -5.515625 C 3.734375 -6.484375 2.90625 -6.640625 2.5 -6.640625 C 1.890625 -6.640625 1.171875 -6.375 0.75 -5.453125 C 0.4375 -4.765625 0.390625 -3.984375 0.390625 -3.1875 C 0.390625 -2.4375 0.421875 -1.546875 0.84375 -0.78125 C 1.265625 0.015625 2 0.21875 2.484375 0.21875 C 3.015625 0.21875 3.78125 0.015625 4.21875 -0.9375 C 4.53125 -1.625 4.578125 -2.40625 4.578125 -3.1875 Z M 2.484375 0 C 2.09375 0 1.5 -0.25 1.328125 -1.203125 C 1.21875 -1.796875 1.21875 -2.71875 1.21875 -3.3125 C 1.21875 -3.953125 1.21875 -4.609375 1.296875 -5.140625 C 1.484375 -6.328125 2.234375 -6.421875 2.484375 -6.421875 C 2.8125 -6.421875 3.46875 -6.234375 3.65625 -5.25 C 3.765625 -4.6875 3.765625 -3.9375 3.765625 -3.3125 C 3.765625 -2.5625 3.765625 -1.890625 3.65625 -1.25 C 3.5 -0.296875 2.9375 0 2.484375 0 Z M 2.484375 0 "/>
</symbol>
</g>
</defs>
<g id="surface1">
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-0" x="-0.114063" y="13.69414"/>
<use xlink:href="#glyph0-0" x="0.110938" y="10.7281"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph1-0" x="8.337107" y="7.77187"/>
<use xlink:href="#glyph1-0" x="7.410158" y="5.51716"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph2-0" x="12.207027" y="7.77187"/>
<use xlink:href="#glyph0-1" x="13.880858" y="10.7281"/>
</g>
<path style="fill:none;stroke-width:5.76;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 1.09375 141.601562 L 223.515625 141.601562 " transform="matrix(0.1,0,0,-0.1,0,31)"/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-0" x="0.344922" y="30.267187"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph1-1" x="18.183197" y="7.77187"/>
<use xlink:href="#glyph0-2" x="7.643932" y="30.267187"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph3-0" x="22.566007" y="13.69414"/>
<use xlink:href="#glyph1-0" x="15.626922" y="26.126957"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-1" x="28.028897" y="13.69414"/>
<use xlink:href="#glyph2-0" x="23.537862" y="20.430077"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph1-2" x="36.012097" y="15.84492"/>
<use xlink:href="#glyph0-2" x="29.000752" y="20.430077"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph3-1" x="41.492957" y="13.69414"/>
<use xlink:href="#glyph3-0" x="36.983952" y="22.580857"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph3-2" x="50.93399" y="13.69414"/>
<use xlink:href="#glyph2-1" x="42.464812" y="20.430077"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-2" x="65.846857" y="13.69414"/>
<use xlink:href="#glyph2-2" x="51.905845" y="20.430077"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph3-3" x="74.234747" y="13.69414"/>
<use xlink:href="#glyph0-3" x="66.818712" y="20.430077"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-3" x="78.140607" y="13.69414"/>
<use xlink:href="#glyph2-3" x="75.206602" y="20.430077"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph2-0" x="84.989827" y="15.84492"/>
<use xlink:href="#glyph0-4" x="79.112462" y="20.430077"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-4" x="91.460917" y="13.69414"/>
<use xlink:href="#glyph1-0" x="85.962072" y="22.580857"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-5" x="92.432772" y="20.430077"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="359pt" height="77pt" viewBox="0 0 359 77" version="1.1">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="352pt" height="77pt" viewBox="0 0 352 77" version="1.1">
<defs>
<g>
<symbol overflow="visible" id="glyph0-0">
@@ -33,57 +33,66 @@
<path style="stroke:none;" d="M 2.890625 3.1875 C 3.09375 3.1875 3.46875 3.1875 3.46875 2.765625 C 3.46875 2.359375 3.09375 2.359375 2.890625 2.359375 L 2.3125 2.359375 L 2.3125 -0.71875 C 2.65625 -0.328125 3.1875 0.09375 3.984375 0.09375 C 5.515625 0.09375 6.84375 -1.28125 6.84375 -3.09375 C 6.84375 -4.859375 5.640625 -6.265625 4.140625 -6.265625 C 3.09375 -6.265625 2.4375 -5.640625 2.3125 -5.5 C 2.3125 -5.96875 2.3125 -6.1875 1.734375 -6.1875 L 0.78125 -6.1875 C 0.59375 -6.1875 0.21875 -6.1875 0.21875 -5.765625 C 0.21875 -5.34375 0.59375 -5.34375 0.78125 -5.34375 L 1.375 -5.34375 L 1.375 2.359375 L 0.78125 2.359375 C 0.59375 2.359375 0.21875 2.359375 0.21875 2.765625 C 0.21875 3.1875 0.59375 3.1875 0.78125 3.1875 Z M 2.3125 -3.8125 C 2.3125 -4.640625 3.109375 -5.4375 4.046875 -5.4375 C 5.078125 -5.4375 5.90625 -4.390625 5.90625 -3.09375 C 5.90625 -1.71875 4.9375 -0.75 3.921875 -0.75 C 2.84375 -0.75 2.3125 -1.96875 2.3125 -2.6875 Z M 2.3125 -3.8125 "/>
</symbol>
<symbol overflow="visible" id="glyph0-10">
<path style="stroke:none;" d="M 6 -8.171875 C 6 -8.625 5.90625 -8.765625 5.421875 -8.765625 L 4.46875 -8.765625 C 4.28125 -8.765625 3.90625 -8.765625 3.90625 -8.34375 C 3.90625 -7.9375 4.28125 -7.9375 4.46875 -7.9375 L 5.0625 -7.9375 L 5.0625 -5.546875 C 4.828125 -5.78125 4.25 -6.265625 3.375 -6.265625 C 1.84375 -6.265625 0.53125 -4.890625 0.53125 -3.078125 C 0.53125 -1.3125 1.765625 0.09375 3.234375 0.09375 C 4.171875 0.09375 4.796875 -0.46875 5.0625 -0.78125 C 5.0625 -0.1875 5.0625 0 5.640625 0 L 6.578125 0 C 6.78125 0 7.15625 0 7.15625 -0.421875 C 7.15625 -0.828125 6.78125 -0.828125 6.578125 -0.828125 L 6 -0.828125 Z M 5.0625 -2.71875 C 5.0625 -1.921875 4.40625 -0.75 3.328125 -0.75 C 2.296875 -0.75 1.46875 -1.796875 1.46875 -3.078125 C 1.46875 -4.453125 2.4375 -5.4375 3.453125 -5.4375 C 4.390625 -5.4375 5.0625 -4.59375 5.0625 -3.84375 Z M 5.0625 -2.71875 "/>
<path style="stroke:none;" d="M 2.3125 -8.171875 C 2.3125 -8.625 2.21875 -8.765625 1.734375 -8.765625 L 0.78125 -8.765625 C 0.59375 -8.765625 0.21875 -8.765625 0.21875 -8.34375 C 0.21875 -7.9375 0.59375 -7.9375 0.78125 -7.9375 L 1.375 -7.9375 L 1.375 -0.59375 C 1.375 -0.328125 1.375 0 1.84375 0 C 2.3125 0 2.3125 -0.296875 2.3125 -0.71875 C 2.65625 -0.328125 3.1875 0.09375 3.984375 0.09375 C 5.515625 0.09375 6.84375 -1.28125 6.84375 -3.09375 C 6.84375 -4.859375 5.640625 -6.265625 4.140625 -6.265625 C 3.09375 -6.265625 2.4375 -5.640625 2.3125 -5.5 Z M 2.3125 -3.8125 C 2.3125 -4.640625 3.109375 -5.4375 4.046875 -5.4375 C 5.078125 -5.4375 5.90625 -4.390625 5.90625 -3.09375 C 5.90625 -1.71875 4.9375 -0.75 3.921875 -0.75 C 2.84375 -0.75 2.3125 -1.96875 2.3125 -2.6875 Z M 2.3125 -3.8125 "/>
</symbol>
<symbol overflow="visible" id="glyph0-11">
<path style="stroke:none;" d="M 4.15625 -8.171875 C 4.15625 -8.625 4.078125 -8.765625 3.578125 -8.765625 L 1.484375 -8.765625 C 1.28125 -8.765625 0.90625 -8.765625 0.90625 -8.34375 C 0.90625 -7.9375 1.28125 -7.9375 1.484375 -7.9375 L 3.234375 -7.9375 L 3.234375 -0.828125 L 1.484375 -0.828125 C 1.28125 -0.828125 0.90625 -0.828125 0.90625 -0.421875 C 0.90625 0 1.28125 0 1.484375 0 L 5.90625 0 C 6.109375 0 6.484375 0 6.484375 -0.421875 C 6.484375 -0.828125 6.109375 -0.828125 5.90625 -0.828125 L 4.15625 -0.828125 Z M 4.15625 -8.171875 "/>
<path style="stroke:none;" d="M 4.328125 -8.140625 C 4.328125 -8.484375 4.046875 -8.78125 3.6875 -8.78125 C 3.328125 -8.78125 3.046875 -8.484375 3.046875 -8.140625 C 3.046875 -7.78125 3.328125 -7.484375 3.6875 -7.484375 C 4.046875 -7.484375 4.328125 -7.78125 4.328125 -8.140625 Z M 1.859375 -6.1875 C 1.65625 -6.1875 1.296875 -6.1875 1.296875 -5.765625 C 1.296875 -5.34375 1.65625 -5.34375 1.859375 -5.34375 L 3.40625 -5.34375 L 3.40625 -0.828125 L 1.765625 -0.828125 C 1.5625 -0.828125 1.171875 -0.828125 1.171875 -0.421875 C 1.171875 0 1.5625 0 1.765625 0 L 5.75 0 C 5.953125 0 6.328125 0 6.328125 -0.421875 C 6.328125 -0.828125 5.953125 -0.828125 5.75 -0.828125 L 4.328125 -0.828125 L 4.328125 -5.59375 C 4.328125 -6.03125 4.25 -6.1875 3.765625 -6.1875 Z M 1.859375 -6.1875 "/>
</symbol>
<symbol overflow="visible" id="glyph0-12">
<path style="stroke:none;" d="M 6.546875 -3.09375 C 6.546875 -4.890625 5.234375 -6.3125 3.6875 -6.3125 C 2.140625 -6.3125 0.828125 -4.890625 0.828125 -3.09375 C 0.828125 -1.296875 2.15625 0.09375 3.6875 0.09375 C 5.21875 0.09375 6.546875 -1.296875 6.546875 -3.09375 Z M 3.6875 -0.75 C 2.65625 -0.75 1.765625 -1.84375 1.765625 -3.203125 C 1.765625 -4.53125 2.6875 -5.484375 3.6875 -5.484375 C 4.6875 -5.484375 5.609375 -4.53125 5.609375 -3.203125 C 5.609375 -1.828125 4.71875 -0.75 3.6875 -0.75 Z M 3.6875 -0.75 "/>
<path style="stroke:none;" d="M 6 -4.203125 C 6 -5.609375 5.328125 -6.265625 4.15625 -6.265625 C 3.1875 -6.265625 2.546875 -5.71875 2.3125 -5.453125 C 2.3125 -5.984375 2.3125 -6.1875 1.734375 -6.1875 L 0.78125 -6.1875 C 0.59375 -6.1875 0.21875 -6.1875 0.21875 -5.765625 C 0.21875 -5.34375 0.59375 -5.34375 0.78125 -5.34375 L 1.375 -5.34375 L 1.375 -0.828125 L 0.78125 -0.828125 C 0.59375 -0.828125 0.21875 -0.828125 0.21875 -0.421875 C 0.21875 0 0.59375 0 0.78125 0 L 2.890625 0 C 3.09375 0 3.46875 0 3.46875 -0.421875 C 3.46875 -0.828125 3.09375 -0.828125 2.890625 -0.828125 L 2.3125 -0.828125 L 2.3125 -3.421875 C 2.3125 -4.8125 3.28125 -5.4375 4.0625 -5.4375 C 4.890625 -5.4375 5.0625 -4.96875 5.0625 -4.140625 L 5.0625 -0.828125 L 4.46875 -0.828125 C 4.28125 -0.828125 3.90625 -0.828125 3.90625 -0.421875 C 3.90625 0 4.28125 0 4.46875 0 L 6.578125 0 C 6.78125 0 7.15625 0 7.15625 -0.421875 C 7.15625 -0.828125 6.78125 -0.828125 6.578125 -0.828125 L 6 -0.828125 Z M 6 -4.203125 "/>
</symbol>
<symbol overflow="visible" id="glyph0-13">
<path style="stroke:none;" d="M 3.09375 -5.34375 L 5.421875 -5.34375 C 5.625 -5.34375 6 -5.34375 6 -5.765625 C 6 -6.1875 5.625 -6.1875 5.421875 -6.1875 L 3.09375 -6.1875 L 3.09375 -7.359375 C 3.09375 -7.609375 3.09375 -7.953125 2.640625 -7.953125 C 2.171875 -7.953125 2.171875 -7.609375 2.171875 -7.359375 L 2.171875 -6.1875 L 0.953125 -6.1875 C 0.75 -6.1875 0.359375 -6.1875 0.359375 -5.765625 C 0.359375 -5.34375 0.734375 -5.34375 0.9375 -5.34375 L 2.171875 -5.34375 L 2.171875 -1.734375 C 2.171875 -0.40625 3.078125 0.09375 4.109375 0.09375 C 4.890625 0.09375 6.3125 -0.296875 6.3125 -1.765625 C 6.3125 -2.046875 6.3125 -2.359375 5.84375 -2.359375 C 5.375 -2.359375 5.375 -2.046875 5.375 -1.75 C 5.359375 -0.890625 4.546875 -0.75 4.21875 -0.75 C 3.09375 -0.75 3.09375 -1.46875 3.09375 -1.8125 Z M 3.09375 -5.34375 "/>
<path style="stroke:none;" d="M 4.15625 -8.171875 C 4.15625 -8.625 4.078125 -8.765625 3.578125 -8.765625 L 1.484375 -8.765625 C 1.28125 -8.765625 0.90625 -8.765625 0.90625 -8.34375 C 0.90625 -7.9375 1.28125 -7.9375 1.484375 -7.9375 L 3.234375 -7.9375 L 3.234375 -0.828125 L 1.484375 -0.828125 C 1.28125 -0.828125 0.90625 -0.828125 0.90625 -0.421875 C 0.90625 0 1.28125 0 1.484375 0 L 5.90625 0 C 6.109375 0 6.484375 0 6.484375 -0.421875 C 6.484375 -0.828125 6.109375 -0.828125 5.90625 -0.828125 L 4.15625 -0.828125 Z M 4.15625 -8.171875 "/>
</symbol>
<symbol overflow="visible" id="glyph0-14">
<path style="stroke:none;" d="M 4.359375 -8.34375 C 4.359375 -8.5625 4.359375 -8.9375 3.9375 -8.9375 C 3.703125 -8.9375 3.609375 -8.8125 3.53125 -8.625 C 3.25 -8 2.78125 -7.25 2.015625 -7.1875 C 1.8125 -7.171875 1.5 -7.140625 1.5 -6.765625 C 1.5 -6.53125 1.65625 -6.359375 1.96875 -6.359375 C 2.765625 -6.359375 3.390625 -6.953125 3.421875 -6.984375 L 3.421875 -0.828125 L 2.171875 -0.828125 C 1.96875 -0.828125 1.578125 -0.828125 1.578125 -0.421875 C 1.578125 0 1.96875 0 2.171875 0 L 5.625 0 C 5.828125 0 6.203125 0 6.203125 -0.421875 C 6.203125 -0.828125 5.828125 -0.828125 5.625 -0.828125 L 4.359375 -0.828125 Z M 4.359375 -8.34375 "/>
<path style="stroke:none;" d="M 6.546875 -3.09375 C 6.546875 -4.890625 5.234375 -6.3125 3.6875 -6.3125 C 2.140625 -6.3125 0.828125 -4.890625 0.828125 -3.09375 C 0.828125 -1.296875 2.15625 0.09375 3.6875 0.09375 C 5.21875 0.09375 6.546875 -1.296875 6.546875 -3.09375 Z M 3.6875 -0.75 C 2.65625 -0.75 1.765625 -1.84375 1.765625 -3.203125 C 1.765625 -4.53125 2.6875 -5.484375 3.6875 -5.484375 C 4.6875 -5.484375 5.609375 -4.53125 5.609375 -3.203125 C 5.609375 -1.828125 4.71875 -0.75 3.6875 -0.75 Z M 3.6875 -0.75 "/>
</symbol>
<symbol overflow="visible" id="glyph0-15">
<path style="stroke:none;" d="M 6.65625 -4.375 C 6.65625 -7.046875 5.234375 -8.9375 3.6875 -8.9375 C 2.125 -8.9375 0.71875 -7.015625 0.71875 -4.390625 C 0.71875 -1.71875 2.140625 0.171875 3.6875 0.171875 C 5.25 0.171875 6.65625 -1.75 6.65625 -4.375 Z M 3.6875 -0.65625 C 2.546875 -0.65625 1.65625 -2.390625 1.65625 -4.53125 C 1.65625 -6.671875 2.640625 -8.109375 3.6875 -8.109375 C 4.734375 -8.109375 5.71875 -6.671875 5.71875 -4.53125 C 5.71875 -2.40625 4.8125 -0.65625 3.6875 -0.65625 Z M 3.6875 -0.65625 "/>
<path style="stroke:none;" d="M 3.09375 -5.34375 L 5.421875 -5.34375 C 5.625 -5.34375 6 -5.34375 6 -5.765625 C 6 -6.1875 5.625 -6.1875 5.421875 -6.1875 L 3.09375 -6.1875 L 3.09375 -7.359375 C 3.09375 -7.609375 3.09375 -7.953125 2.640625 -7.953125 C 2.171875 -7.953125 2.171875 -7.609375 2.171875 -7.359375 L 2.171875 -6.1875 L 0.953125 -6.1875 C 0.75 -6.1875 0.359375 -6.1875 0.359375 -5.765625 C 0.359375 -5.34375 0.734375 -5.34375 0.9375 -5.34375 L 2.171875 -5.34375 L 2.171875 -1.734375 C 2.171875 -0.40625 3.078125 0.09375 4.109375 0.09375 C 4.890625 0.09375 6.3125 -0.296875 6.3125 -1.765625 C 6.3125 -2.046875 6.3125 -2.359375 5.84375 -2.359375 C 5.375 -2.359375 5.375 -2.046875 5.375 -1.75 C 5.359375 -0.890625 4.546875 -0.75 4.21875 -0.75 C 3.09375 -0.75 3.09375 -1.46875 3.09375 -1.8125 Z M 3.09375 -5.34375 "/>
</symbol>
<symbol overflow="visible" id="glyph0-16">
<path style="stroke:none;" d="M 3.953125 -0.046875 C 3.890625 0.40625 3.59375 0.953125 2.890625 1.1875 C 2.765625 1.21875 2.546875 1.296875 2.546875 1.5625 C 2.546875 1.75 2.765625 2 3 2 C 3.390625 2 4.8125 1.296875 4.8125 -0.265625 C 4.8125 -1.015625 4.328125 -1.625 3.703125 -1.625 C 3.171875 -1.625 2.890625 -1.203125 2.890625 -0.8125 C 2.890625 -0.34375 3.234375 0 3.6875 0 C 3.765625 0 3.875 -0.015625 3.953125 -0.046875 Z M 3.953125 -0.046875 "/>
<path style="stroke:none;" d="M 5.5625 -7.9375 C 5.765625 -7.9375 6.140625 -7.9375 6.140625 -8.34375 C 6.140625 -8.765625 5.765625 -8.765625 5.5625 -8.765625 L 1.84375 -8.765625 C 1.375 -8.765625 1.265625 -8.65625 1.265625 -8.203125 L 1.265625 -4.375 C 1.265625 -4.171875 1.265625 -3.8125 1.6875 -3.8125 C 1.921875 -3.8125 1.984375 -3.890625 2.09375 -4.03125 C 2.53125 -4.53125 3.15625 -4.765625 3.90625 -4.765625 C 5.015625 -4.765625 5.703125 -3.75 5.703125 -2.71875 C 5.703125 -1.5625 4.703125 -0.65625 3.5 -0.65625 C 2.75 -0.65625 2 -1.015625 1.734375 -1.6875 C 1.796875 -1.75 1.890625 -1.84375 1.890625 -2.109375 C 1.890625 -2.5 1.5625 -2.703125 1.3125 -2.703125 C 1.1875 -2.703125 0.734375 -2.625 0.734375 -2.0625 C 0.734375 -0.859375 1.921875 0.171875 3.5 0.171875 C 5.234375 0.171875 6.640625 -1.125 6.640625 -2.71875 C 6.640625 -4.171875 5.5625 -5.59375 3.90625 -5.59375 C 3.421875 -5.59375 2.796875 -5.515625 2.1875 -5.171875 L 2.1875 -7.9375 Z M 5.5625 -7.9375 "/>
</symbol>
<symbol overflow="visible" id="glyph0-17">
<path style="stroke:none;" d="M 2.6875 -8.28125 C 2.515625 -8.765625 2.21875 -8.765625 1.921875 -8.765625 L 0.984375 -8.765625 C 0.78125 -8.765625 0.421875 -8.765625 0.421875 -8.34375 C 0.421875 -7.9375 0.78125 -7.9375 0.984375 -7.9375 L 1.3125 -7.9375 L 1.3125 -0.828125 L 0.984375 -0.828125 C 0.78125 -0.828125 0.421875 -0.828125 0.421875 -0.421875 C 0.421875 0 0.78125 0 0.984375 0 L 2.421875 0 C 2.625 0 3.015625 0 3.015625 -0.421875 C 3.015625 -0.828125 2.625 -0.828125 2.421875 -0.828125 L 2.109375 -0.828125 L 2.109375 -7.78125 L 2.125 -7.78125 C 2.171875 -7.609375 2.296875 -7.25 2.546875 -6.515625 L 4.6875 -0.484375 C 4.859375 0 5.15625 0 5.46875 0 C 5.890625 0 6.0625 -0.046875 6.0625 -0.59375 L 6.0625 -7.9375 L 6.390625 -7.9375 C 6.578125 -7.9375 6.953125 -7.9375 6.953125 -8.34375 C 6.953125 -8.765625 6.59375 -8.765625 6.390625 -8.765625 L 4.953125 -8.765625 C 4.75 -8.765625 4.359375 -8.765625 4.359375 -8.34375 C 4.359375 -7.9375 4.75 -7.9375 4.953125 -7.9375 L 5.265625 -7.9375 L 5.265625 -0.984375 L 5.25 -0.984375 C 5.203125 -1.140625 5.078125 -1.515625 4.8125 -2.25 Z M 2.6875 -8.28125 "/>
<path style="stroke:none;" d="M 6.65625 -4.375 C 6.65625 -7.046875 5.234375 -8.9375 3.6875 -8.9375 C 2.125 -8.9375 0.71875 -7.015625 0.71875 -4.390625 C 0.71875 -1.71875 2.140625 0.171875 3.6875 0.171875 C 5.25 0.171875 6.65625 -1.75 6.65625 -4.375 Z M 3.6875 -0.65625 C 2.546875 -0.65625 1.65625 -2.390625 1.65625 -4.53125 C 1.65625 -6.671875 2.640625 -8.109375 3.6875 -8.109375 C 4.734375 -8.109375 5.71875 -6.671875 5.71875 -4.53125 C 5.71875 -2.40625 4.8125 -0.65625 3.6875 -0.65625 Z M 3.6875 -0.65625 "/>
</symbol>
<symbol overflow="visible" id="glyph0-18">
<path style="stroke:none;" d="M 6.453125 -5.34375 C 6.796875 -5.34375 7.15625 -5.34375 7.15625 -5.765625 C 7.15625 -6.1875 6.765625 -6.1875 6.5625 -6.1875 L 4.96875 -6.1875 C 4.765625 -6.1875 4.375 -6.1875 4.375 -5.765625 C 4.375 -5.34375 4.765625 -5.34375 4.96875 -5.34375 L 5.640625 -5.34375 L 4.921875 -0.96875 L 4.90625 -0.96875 C 4.84375 -1.34375 4.625 -2.15625 4.46875 -2.609375 C 4.21875 -3.546875 4.171875 -3.71875 3.703125 -3.71875 C 3.234375 -3.71875 3.1875 -3.546875 2.921875 -2.625 C 2.640625 -1.65625 2.53125 -1.234375 2.5 -0.96875 L 2.484375 -0.96875 L 1.734375 -5.34375 L 2.40625 -5.34375 C 2.609375 -5.34375 3 -5.34375 3 -5.765625 C 3 -6.1875 2.609375 -6.1875 2.40625 -6.1875 L 0.796875 -6.1875 C 0.609375 -6.1875 0.21875 -6.1875 0.21875 -5.765625 C 0.21875 -5.34375 0.578125 -5.34375 0.921875 -5.34375 L 1.78125 -0.46875 C 1.859375 0.03125 2.09375 0.078125 2.421875 0.078125 C 2.984375 0.078125 3.015625 -0.046875 3.296875 -1.03125 C 3.421875 -1.53125 3.65625 -2.328125 3.703125 -2.71875 L 3.71875 -2.71875 C 3.734375 -2.53125 3.796875 -2.125 4.109375 -1.015625 C 4.390625 -0.0625 4.421875 0.078125 4.96875 0.078125 C 5.203125 0.078125 5.5 0.078125 5.59375 -0.453125 Z M 6.453125 -5.34375 "/>
<path style="stroke:none;" d="M 3.953125 -0.046875 C 3.890625 0.40625 3.59375 0.953125 2.890625 1.1875 C 2.765625 1.21875 2.546875 1.296875 2.546875 1.5625 C 2.546875 1.75 2.765625 2 3 2 C 3.390625 2 4.8125 1.296875 4.8125 -0.265625 C 4.8125 -1.015625 4.328125 -1.625 3.703125 -1.625 C 3.171875 -1.625 2.890625 -1.203125 2.890625 -0.8125 C 2.890625 -0.34375 3.234375 0 3.6875 0 C 3.765625 0 3.875 -0.015625 3.953125 -0.046875 Z M 3.953125 -0.046875 "/>
</symbol>
<symbol overflow="visible" id="glyph0-19">
<path style="stroke:none;" d="M 6.3125 -3.9375 C 6.484375 -4.046875 6.578125 -4.203125 6.578125 -4.375 C 6.578125 -4.640625 6.421875 -4.734375 6.3125 -4.8125 L 1.609375 -7.796875 C 1.5 -7.859375 1.390625 -7.953125 1.265625 -7.953125 C 1.046875 -7.953125 0.78125 -7.78125 0.78125 -7.46875 C 0.78125 -7.21875 0.953125 -7.125 1.09375 -7.03125 L 5.25 -4.390625 L 1.09375 -1.734375 C 0.953125 -1.640625 0.78125 -1.546875 0.78125 -1.296875 C 0.78125 -0.984375 1.046875 -0.8125 1.265625 -0.8125 L 1.296875 -0.828125 C 1.40625 -0.84375 1.4375 -0.84375 1.59375 -0.96875 Z M 6.3125 -3.9375 "/>
<path style="stroke:none;" d="M 2.6875 -8.28125 C 2.515625 -8.765625 2.21875 -8.765625 1.921875 -8.765625 L 0.984375 -8.765625 C 0.78125 -8.765625 0.421875 -8.765625 0.421875 -8.34375 C 0.421875 -7.9375 0.78125 -7.9375 0.984375 -7.9375 L 1.3125 -7.9375 L 1.3125 -0.828125 L 0.984375 -0.828125 C 0.78125 -0.828125 0.421875 -0.828125 0.421875 -0.421875 C 0.421875 0 0.78125 0 0.984375 0 L 2.421875 0 C 2.625 0 3.015625 0 3.015625 -0.421875 C 3.015625 -0.828125 2.625 -0.828125 2.421875 -0.828125 L 2.109375 -0.828125 L 2.109375 -7.78125 L 2.125 -7.78125 C 2.171875 -7.609375 2.296875 -7.25 2.546875 -6.515625 L 4.6875 -0.484375 C 4.859375 0 5.15625 0 5.46875 0 C 5.890625 0 6.0625 -0.046875 6.0625 -0.59375 L 6.0625 -7.9375 L 6.390625 -7.9375 C 6.578125 -7.9375 6.953125 -7.9375 6.953125 -8.34375 C 6.953125 -8.765625 6.59375 -8.765625 6.390625 -8.765625 L 4.953125 -8.765625 C 4.75 -8.765625 4.359375 -8.765625 4.359375 -8.34375 C 4.359375 -7.9375 4.75 -7.9375 4.953125 -7.9375 L 5.265625 -7.9375 L 5.265625 -0.984375 L 5.25 -0.984375 C 5.203125 -1.140625 5.078125 -1.515625 4.8125 -2.25 Z M 2.6875 -8.28125 "/>
</symbol>
<symbol overflow="visible" id="glyph0-20">
<path style="stroke:none;" d="M 6.140625 0.8125 C 6.140625 0.625 6.03125 0.578125 5.84375 0.4375 C 3.859375 -0.9375 3.375 -2.984375 3.375 -4.375 C 3.375 -5.734375 3.828125 -7.796875 5.84375 -9.1875 C 6.03125 -9.34375 6.140625 -9.390625 6.140625 -9.578125 C 6.140625 -9.71875 6.0625 -9.953125 5.71875 -9.953125 C 5.359375 -9.953125 4.296875 -9.125 3.640625 -8.1875 C 2.84375 -7.078125 2.4375 -5.734375 2.4375 -4.375 C 2.4375 -2.78125 3.015625 -1.453125 3.609375 -0.609375 C 4.28125 0.3125 5.328125 1.1875 5.71875 1.1875 C 6.0625 1.1875 6.140625 0.953125 6.140625 0.8125 Z M 6.140625 0.8125 "/>
<path style="stroke:none;" d="M 6.453125 -5.34375 C 6.796875 -5.34375 7.15625 -5.34375 7.15625 -5.765625 C 7.15625 -6.1875 6.765625 -6.1875 6.5625 -6.1875 L 4.96875 -6.1875 C 4.765625 -6.1875 4.375 -6.1875 4.375 -5.765625 C 4.375 -5.34375 4.765625 -5.34375 4.96875 -5.34375 L 5.640625 -5.34375 L 4.921875 -0.96875 L 4.90625 -0.96875 C 4.84375 -1.34375 4.625 -2.15625 4.46875 -2.609375 C 4.21875 -3.546875 4.171875 -3.71875 3.703125 -3.71875 C 3.234375 -3.71875 3.1875 -3.546875 2.921875 -2.625 C 2.640625 -1.65625 2.53125 -1.234375 2.5 -0.96875 L 2.484375 -0.96875 L 1.734375 -5.34375 L 2.40625 -5.34375 C 2.609375 -5.34375 3 -5.34375 3 -5.765625 C 3 -6.1875 2.609375 -6.1875 2.40625 -6.1875 L 0.796875 -6.1875 C 0.609375 -6.1875 0.21875 -6.1875 0.21875 -5.765625 C 0.21875 -5.34375 0.578125 -5.34375 0.921875 -5.34375 L 1.78125 -0.46875 C 1.859375 0.03125 2.09375 0.078125 2.421875 0.078125 C 2.984375 0.078125 3.015625 -0.046875 3.296875 -1.03125 C 3.421875 -1.53125 3.65625 -2.328125 3.703125 -2.71875 L 3.71875 -2.71875 C 3.734375 -2.53125 3.796875 -2.125 4.109375 -1.015625 C 4.390625 -0.0625 4.421875 0.078125 4.96875 0.078125 C 5.203125 0.078125 5.5 0.078125 5.59375 -0.453125 Z M 6.453125 -5.34375 "/>
</symbol>
<symbol overflow="visible" id="glyph0-21">
<path style="stroke:none;" d="M 4.9375 -4.375 C 4.9375 -5.5 4.65625 -6.9375 3.625 -8.328125 C 3.140625 -9 2.078125 -9.953125 1.65625 -9.953125 C 1.3125 -9.953125 1.234375 -9.703125 1.234375 -9.578125 C 1.234375 -9.40625 1.328125 -9.34375 1.59375 -9.171875 C 3.34375 -7.9375 4 -6.015625 4 -4.390625 C 4 -3.09375 3.578125 -0.984375 1.53125 0.4375 C 1.34375 0.5625 1.234375 0.625 1.234375 0.8125 C 1.234375 0.953125 1.3125 1.1875 1.65625 1.1875 C 2.015625 1.1875 3.0625 0.359375 3.734375 -0.578125 C 4.5625 -1.75 4.9375 -3.09375 4.9375 -4.375 Z M 4.9375 -4.375 "/>
<path style="stroke:none;" d="M 6.3125 -3.9375 C 6.484375 -4.046875 6.578125 -4.203125 6.578125 -4.375 C 6.578125 -4.640625 6.421875 -4.734375 6.3125 -4.8125 L 1.609375 -7.796875 C 1.5 -7.859375 1.390625 -7.953125 1.265625 -7.953125 C 1.046875 -7.953125 0.78125 -7.78125 0.78125 -7.46875 C 0.78125 -7.21875 0.953125 -7.125 1.09375 -7.03125 L 5.25 -4.390625 L 1.09375 -1.734375 C 0.953125 -1.640625 0.78125 -1.546875 0.78125 -1.296875 C 0.78125 -0.984375 1.046875 -0.8125 1.265625 -0.8125 L 1.296875 -0.828125 C 1.40625 -0.84375 1.4375 -0.84375 1.59375 -0.96875 Z M 6.3125 -3.9375 "/>
</symbol>
<symbol overflow="visible" id="glyph0-22">
<path style="stroke:none;" d="M 4.046875 -3.1875 L 5.6875 -5.34375 L 6.203125 -5.34375 C 6.390625 -5.34375 6.765625 -5.34375 6.765625 -5.765625 C 6.765625 -6.1875 6.390625 -6.1875 6.203125 -6.1875 L 4.609375 -6.1875 C 4.40625 -6.1875 4.03125 -6.1875 4.03125 -5.765625 C 4.03125 -5.34375 4.375 -5.34375 4.71875 -5.34375 L 3.640625 -3.875 L 2.53125 -5.34375 C 2.875 -5.34375 3.21875 -5.34375 3.21875 -5.765625 C 3.21875 -6.1875 2.84375 -6.1875 2.640625 -6.1875 L 1.046875 -6.1875 C 0.84375 -6.1875 0.46875 -6.1875 0.46875 -5.765625 C 0.46875 -5.34375 0.84375 -5.34375 1.046875 -5.34375 L 1.546875 -5.34375 L 3.25 -3.1875 L 1.46875 -0.828125 L 0.96875 -0.828125 C 0.78125 -0.828125 0.390625 -0.828125 0.390625 -0.421875 C 0.390625 0 0.78125 0 0.96875 0 L 2.546875 0 C 2.75 0 3.125 0 3.125 -0.421875 C 3.125 -0.828125 2.796875 -0.828125 2.40625 -0.828125 L 3.640625 -2.640625 L 4.9375 -0.828125 C 4.578125 -0.828125 4.234375 -0.828125 4.234375 -0.421875 C 4.234375 0 4.609375 0 4.8125 0 L 6.390625 0 C 6.59375 0 6.96875 0 6.96875 -0.421875 C 6.96875 -0.828125 6.59375 -0.828125 6.390625 -0.828125 L 5.890625 -0.828125 Z M 4.046875 -3.1875 "/>
<path style="stroke:none;" d="M 6.140625 0.8125 C 6.140625 0.625 6.03125 0.578125 5.84375 0.4375 C 3.859375 -0.9375 3.375 -2.984375 3.375 -4.375 C 3.375 -5.734375 3.828125 -7.796875 5.84375 -9.1875 C 6.03125 -9.34375 6.140625 -9.390625 6.140625 -9.578125 C 6.140625 -9.71875 6.0625 -9.953125 5.71875 -9.953125 C 5.359375 -9.953125 4.296875 -9.125 3.640625 -8.1875 C 2.84375 -7.078125 2.4375 -5.734375 2.4375 -4.375 C 2.4375 -2.78125 3.015625 -1.453125 3.609375 -0.609375 C 4.28125 0.3125 5.328125 1.1875 5.71875 1.1875 C 6.0625 1.1875 6.140625 0.953125 6.140625 0.8125 Z M 6.140625 0.8125 "/>
</symbol>
<symbol overflow="visible" id="glyph0-23">
<path style="stroke:none;" d="M 4.984375 -3.15625 C 5.1875 -3.328125 6.640625 -4.5625 6.640625 -6.15625 C 6.640625 -7.78125 5.296875 -8.9375 3.5 -8.9375 C 1.84375 -8.9375 0.734375 -7.6875 0.734375 -6.484375 C 0.734375 -5.875 1.234375 -5.84375 1.3125 -5.84375 C 1.578125 -5.84375 1.890625 -6.03125 1.890625 -6.421875 C 1.890625 -6.703125 1.796875 -6.78125 1.71875 -6.84375 C 1.921875 -7.609375 2.578125 -8.109375 3.40625 -8.109375 C 4.640625 -8.109375 5.703125 -7.40625 5.703125 -6.15625 C 5.703125 -5.03125 4.859375 -4.171875 4.09375 -3.5 L 0.9375 -0.765625 C 0.78125 -0.625 0.734375 -0.59375 0.734375 -0.421875 C 0.734375 0 1.125 0 1.3125 0 L 6.328125 0 C 6.640625 -0.09375 6.640625 -0.375 6.640625 -0.59375 L 6.640625 -0.890625 C 6.640625 -1.140625 6.640625 -1.484375 6.1875 -1.484375 C 5.703125 -1.484375 5.703125 -1.171875 5.703125 -0.828125 L 2.25 -0.828125 Z M 4.984375 -3.15625 "/>
<path style="stroke:none;" d="M 4.359375 -8.34375 C 4.359375 -8.5625 4.359375 -8.9375 3.9375 -8.9375 C 3.703125 -8.9375 3.609375 -8.8125 3.53125 -8.625 C 3.25 -8 2.78125 -7.25 2.015625 -7.1875 C 1.8125 -7.171875 1.5 -7.140625 1.5 -6.765625 C 1.5 -6.53125 1.65625 -6.359375 1.96875 -6.359375 C 2.765625 -6.359375 3.390625 -6.953125 3.421875 -6.984375 L 3.421875 -0.828125 L 2.171875 -0.828125 C 1.96875 -0.828125 1.578125 -0.828125 1.578125 -0.421875 C 1.578125 0 1.96875 0 2.171875 0 L 5.625 0 C 5.828125 0 6.203125 0 6.203125 -0.421875 C 6.203125 -0.828125 5.828125 -0.828125 5.625 -0.828125 L 4.359375 -0.828125 Z M 4.359375 -8.34375 "/>
</symbol>
<symbol overflow="visible" id="glyph0-24">
<path style="stroke:none;" d="M 6.078125 -5.34375 L 6.453125 -5.34375 C 6.65625 -5.34375 7.046875 -5.34375 7.046875 -5.765625 C 7.046875 -6.1875 6.65625 -6.1875 6.453125 -6.1875 L 4.875 -6.1875 C 4.671875 -6.1875 4.28125 -6.1875 4.28125 -5.765625 C 4.28125 -5.34375 4.671875 -5.34375 4.875 -5.34375 L 5.234375 -5.34375 C 4.828125 -4.171875 4.015625 -1.78125 3.8125 -0.96875 L 3.796875 -0.96875 C 3.734375 -1.28125 3.671875 -1.4375 3.53125 -1.828125 L 2.1875 -5.34375 L 2.53125 -5.34375 C 2.71875 -5.34375 3.109375 -5.34375 3.109375 -5.765625 C 3.109375 -6.1875 2.71875 -6.1875 2.53125 -6.1875 L 0.953125 -6.1875 C 0.75 -6.1875 0.359375 -6.1875 0.359375 -5.765625 C 0.359375 -5.34375 0.75 -5.34375 0.953125 -5.34375 L 1.328125 -5.34375 L 3.34375 -0.1875 C 3.40625 -0.046875 3.40625 -0.015625 3.40625 0 C 3.40625 0.03125 3.03125 1.28125 2.8125 1.671875 C 2.71875 1.828125 2.359375 2.5 1.671875 2.421875 C 1.6875 2.375 1.734375 2.296875 1.734375 2.140625 C 1.734375 1.8125 1.5 1.578125 1.171875 1.578125 C 0.8125 1.578125 0.609375 1.828125 0.609375 2.15625 C 0.609375 2.703125 1.0625 3.265625 1.78125 3.265625 C 3.171875 3.265625 3.78125 1.421875 3.828125 1.3125 Z M 6.078125 -5.34375 "/>
<path style="stroke:none;" d="M 4.9375 -4.375 C 4.9375 -5.5 4.65625 -6.9375 3.625 -8.328125 C 3.140625 -9 2.078125 -9.953125 1.65625 -9.953125 C 1.3125 -9.953125 1.234375 -9.703125 1.234375 -9.578125 C 1.234375 -9.40625 1.328125 -9.34375 1.59375 -9.171875 C 3.34375 -7.9375 4 -6.015625 4 -4.390625 C 4 -3.09375 3.578125 -0.984375 1.53125 0.4375 C 1.34375 0.5625 1.234375 0.625 1.234375 0.8125 C 1.234375 0.953125 1.3125 1.1875 1.65625 1.1875 C 2.015625 1.1875 3.0625 0.359375 3.734375 -0.578125 C 4.5625 -1.75 4.9375 -3.09375 4.9375 -4.375 Z M 4.9375 -4.375 "/>
</symbol>
<symbol overflow="visible" id="glyph0-25">
<path style="stroke:none;" d="M 3.671875 -4.3125 C 5.15625 -4.3125 5.828125 -3.265625 5.828125 -2.5 C 5.828125 -1.546875 4.984375 -0.65625 3.734375 -0.65625 C 2.296875 -0.65625 1.65625 -1.4375 1.65625 -1.640625 C 1.65625 -1.65625 1.65625 -1.6875 1.671875 -1.703125 C 1.734375 -1.8125 1.78125 -1.921875 1.78125 -2.046875 C 1.78125 -2.359375 1.546875 -2.625 1.203125 -2.625 C 0.90625 -2.625 0.609375 -2.4375 0.609375 -2 C 0.609375 -0.75 1.984375 0.171875 3.734375 0.171875 C 5.53125 0.171875 6.75 -1.125 6.75 -2.484375 C 6.75 -3.21875 6.359375 -4.234375 5.09375 -4.78125 C 5.96875 -5.328125 6.359375 -6.1875 6.359375 -6.921875 C 6.359375 -8 5.28125 -8.9375 3.734375 -8.9375 C 2.140625 -8.9375 1.015625 -8.25 1.015625 -7.1875 C 1.015625 -6.71875 1.375 -6.5625 1.609375 -6.5625 C 1.859375 -6.5625 2.1875 -6.765625 2.1875 -7.15625 C 2.1875 -7.390625 2.0625 -7.515625 2.0625 -7.53125 C 2.5 -8.078125 3.484375 -8.109375 3.734375 -8.109375 C 4.703125 -8.109375 5.421875 -7.59375 5.421875 -6.90625 C 5.421875 -6.5 5.15625 -5.3125 3.640625 -5.203125 C 3.109375 -5.171875 2.890625 -5.15625 2.828125 -5.15625 C 2.53125 -5.125 2.46875 -4.9375 2.46875 -4.734375 C 2.46875 -4.3125 2.765625 -4.3125 3.015625 -4.3125 Z M 3.671875 -4.3125 "/>
<path style="stroke:none;" d="M 4.046875 -3.1875 L 5.6875 -5.34375 L 6.203125 -5.34375 C 6.390625 -5.34375 6.765625 -5.34375 6.765625 -5.765625 C 6.765625 -6.1875 6.390625 -6.1875 6.203125 -6.1875 L 4.609375 -6.1875 C 4.40625 -6.1875 4.03125 -6.1875 4.03125 -5.765625 C 4.03125 -5.34375 4.375 -5.34375 4.71875 -5.34375 L 3.640625 -3.875 L 2.53125 -5.34375 C 2.875 -5.34375 3.21875 -5.34375 3.21875 -5.765625 C 3.21875 -6.1875 2.84375 -6.1875 2.640625 -6.1875 L 1.046875 -6.1875 C 0.84375 -6.1875 0.46875 -6.1875 0.46875 -5.765625 C 0.46875 -5.34375 0.84375 -5.34375 1.046875 -5.34375 L 1.546875 -5.34375 L 3.25 -3.1875 L 1.46875 -0.828125 L 0.96875 -0.828125 C 0.78125 -0.828125 0.390625 -0.828125 0.390625 -0.421875 C 0.390625 0 0.78125 0 0.96875 0 L 2.546875 0 C 2.75 0 3.125 0 3.125 -0.421875 C 3.125 -0.828125 2.796875 -0.828125 2.40625 -0.828125 L 3.640625 -2.640625 L 4.9375 -0.828125 C 4.578125 -0.828125 4.234375 -0.828125 4.234375 -0.421875 C 4.234375 0 4.609375 0 4.8125 0 L 6.390625 0 C 6.59375 0 6.96875 0 6.96875 -0.421875 C 6.96875 -0.828125 6.59375 -0.828125 6.390625 -0.828125 L 5.890625 -0.828125 Z M 4.046875 -3.1875 "/>
</symbol>
<symbol overflow="visible" id="glyph0-26">
<path style="stroke:none;" d="M 6.40625 -5.234375 C 6.578125 -5.390625 6.640625 -5.453125 6.640625 -5.703125 C 6.640625 -6.1875 6.328125 -6.1875 6.046875 -6.1875 L 1.28125 -6.1875 C 0.796875 -6.1875 0.6875 -6.0625 0.6875 -5.59375 L 0.6875 -5.015625 C 0.6875 -4.765625 0.6875 -4.4375 1.140625 -4.4375 C 1.625 -4.4375 1.625 -4.75 1.625 -5.015625 L 1.625 -5.34375 L 5.25 -5.34375 L 0.6875 -0.953125 C 0.515625 -0.78125 0.453125 -0.734375 0.453125 -0.46875 C 0.453125 0 0.78125 0 1.046875 0 L 6.109375 0 C 6.578125 0 6.6875 -0.125 6.6875 -0.59375 L 6.6875 -1.3125 C 6.6875 -1.578125 6.6875 -1.90625 6.21875 -1.90625 C 5.75 -1.90625 5.75 -1.59375 5.75 -1.3125 L 5.75 -0.828125 L 1.84375 -0.828125 Z M 6.40625 -5.234375 "/>
<path style="stroke:none;" d="M 4.984375 -3.15625 C 5.1875 -3.328125 6.640625 -4.5625 6.640625 -6.15625 C 6.640625 -7.78125 5.296875 -8.9375 3.5 -8.9375 C 1.84375 -8.9375 0.734375 -7.6875 0.734375 -6.484375 C 0.734375 -5.875 1.234375 -5.84375 1.3125 -5.84375 C 1.578125 -5.84375 1.890625 -6.03125 1.890625 -6.421875 C 1.890625 -6.703125 1.796875 -6.78125 1.71875 -6.84375 C 1.921875 -7.609375 2.578125 -8.109375 3.40625 -8.109375 C 4.640625 -8.109375 5.703125 -7.40625 5.703125 -6.15625 C 5.703125 -5.03125 4.859375 -4.171875 4.09375 -3.5 L 0.9375 -0.765625 C 0.78125 -0.625 0.734375 -0.59375 0.734375 -0.421875 C 0.734375 0 1.125 0 1.3125 0 L 6.328125 0 C 6.640625 -0.09375 6.640625 -0.375 6.640625 -0.59375 L 6.640625 -0.890625 C 6.640625 -1.140625 6.640625 -1.484375 6.1875 -1.484375 C 5.703125 -1.484375 5.703125 -1.171875 5.703125 -0.828125 L 2.25 -0.828125 Z M 4.984375 -3.15625 "/>
</symbol>
<symbol overflow="visible" id="glyph0-27">
<path style="stroke:none;" d="M 6.078125 -5.34375 L 6.453125 -5.34375 C 6.65625 -5.34375 7.046875 -5.34375 7.046875 -5.765625 C 7.046875 -6.1875 6.65625 -6.1875 6.453125 -6.1875 L 4.875 -6.1875 C 4.671875 -6.1875 4.28125 -6.1875 4.28125 -5.765625 C 4.28125 -5.34375 4.671875 -5.34375 4.875 -5.34375 L 5.234375 -5.34375 C 4.828125 -4.171875 4.015625 -1.78125 3.8125 -0.96875 L 3.796875 -0.96875 C 3.734375 -1.28125 3.671875 -1.4375 3.53125 -1.828125 L 2.1875 -5.34375 L 2.53125 -5.34375 C 2.71875 -5.34375 3.109375 -5.34375 3.109375 -5.765625 C 3.109375 -6.1875 2.71875 -6.1875 2.53125 -6.1875 L 0.953125 -6.1875 C 0.75 -6.1875 0.359375 -6.1875 0.359375 -5.765625 C 0.359375 -5.34375 0.75 -5.34375 0.953125 -5.34375 L 1.328125 -5.34375 L 3.34375 -0.1875 C 3.40625 -0.046875 3.40625 -0.015625 3.40625 0 C 3.40625 0.03125 3.03125 1.28125 2.8125 1.671875 C 2.71875 1.828125 2.359375 2.5 1.671875 2.421875 C 1.6875 2.375 1.734375 2.296875 1.734375 2.140625 C 1.734375 1.8125 1.5 1.578125 1.171875 1.578125 C 0.8125 1.578125 0.609375 1.828125 0.609375 2.15625 C 0.609375 2.703125 1.0625 3.265625 1.78125 3.265625 C 3.171875 3.265625 3.78125 1.421875 3.828125 1.3125 Z M 6.078125 -5.34375 "/>
</symbol>
<symbol overflow="visible" id="glyph0-28">
<path style="stroke:none;" d="M 3.671875 -4.3125 C 5.15625 -4.3125 5.828125 -3.265625 5.828125 -2.5 C 5.828125 -1.546875 4.984375 -0.65625 3.734375 -0.65625 C 2.296875 -0.65625 1.65625 -1.4375 1.65625 -1.640625 C 1.65625 -1.65625 1.65625 -1.6875 1.671875 -1.703125 C 1.734375 -1.8125 1.78125 -1.921875 1.78125 -2.046875 C 1.78125 -2.359375 1.546875 -2.625 1.203125 -2.625 C 0.90625 -2.625 0.609375 -2.4375 0.609375 -2 C 0.609375 -0.75 1.984375 0.171875 3.734375 0.171875 C 5.53125 0.171875 6.75 -1.125 6.75 -2.484375 C 6.75 -3.21875 6.359375 -4.234375 5.09375 -4.78125 C 5.96875 -5.328125 6.359375 -6.1875 6.359375 -6.921875 C 6.359375 -8 5.28125 -8.9375 3.734375 -8.9375 C 2.140625 -8.9375 1.015625 -8.25 1.015625 -7.1875 C 1.015625 -6.71875 1.375 -6.5625 1.609375 -6.5625 C 1.859375 -6.5625 2.1875 -6.765625 2.1875 -7.15625 C 2.1875 -7.390625 2.0625 -7.515625 2.0625 -7.53125 C 2.5 -8.078125 3.484375 -8.109375 3.734375 -8.109375 C 4.703125 -8.109375 5.421875 -7.59375 5.421875 -6.90625 C 5.421875 -6.5 5.15625 -5.3125 3.640625 -5.203125 C 3.109375 -5.171875 2.890625 -5.15625 2.828125 -5.15625 C 2.53125 -5.125 2.46875 -4.9375 2.46875 -4.734375 C 2.46875 -4.3125 2.765625 -4.3125 3.015625 -4.3125 Z M 3.671875 -4.3125 "/>
</symbol>
<symbol overflow="visible" id="glyph0-29">
<path style="stroke:none;" d="M 6.40625 -5.234375 C 6.578125 -5.390625 6.640625 -5.453125 6.640625 -5.703125 C 6.640625 -6.1875 6.328125 -6.1875 6.046875 -6.1875 L 1.28125 -6.1875 C 0.796875 -6.1875 0.6875 -6.0625 0.6875 -5.59375 L 0.6875 -5.015625 C 0.6875 -4.765625 0.6875 -4.4375 1.140625 -4.4375 C 1.625 -4.4375 1.625 -4.75 1.625 -5.015625 L 1.625 -5.34375 L 5.25 -5.34375 L 0.6875 -0.953125 C 0.515625 -0.78125 0.453125 -0.734375 0.453125 -0.46875 C 0.453125 0 0.78125 0 1.046875 0 L 6.109375 0 C 6.578125 0 6.6875 -0.125 6.6875 -0.59375 L 6.6875 -1.3125 C 6.6875 -1.578125 6.6875 -1.90625 6.21875 -1.90625 C 5.75 -1.90625 5.75 -1.59375 5.75 -1.3125 L 5.75 -0.828125 L 1.84375 -0.828125 Z M 6.40625 -5.234375 "/>
</symbol>
<symbol overflow="visible" id="glyph0-30">
<path style="stroke:none;" d="M 0.546875 -3.4375 C 0.421875 -3.25 0.421875 -3.234375 0.421875 -2.96875 C 0.421875 -2.46875 0.609375 -2.40625 0.984375 -2.40625 L 4.5 -2.40625 L 4.5 -0.828125 L 3.640625 -0.828125 C 3.4375 -0.828125 3.0625 -0.828125 3.0625 -0.421875 C 3.0625 0 3.4375 0 3.640625 0 L 6.171875 0 C 6.375 0 6.734375 0 6.734375 -0.421875 C 6.734375 -0.828125 6.375 -0.828125 6.171875 -0.828125 L 5.3125 -0.828125 L 5.3125 -2.40625 L 6.390625 -2.40625 C 6.578125 -2.40625 6.953125 -2.40625 6.953125 -2.828125 C 6.953125 -3.234375 6.578125 -3.234375 6.390625 -3.234375 L 5.3125 -3.234375 L 5.3125 -8.375 C 5.3125 -8.84375 5.203125 -8.96875 4.71875 -8.96875 L 4.390625 -8.96875 C 4.046875 -8.96875 3.96875 -8.953125 3.796875 -8.671875 Z M 1.375 -3.234375 L 4.5 -8.265625 L 4.5 -3.234375 Z M 1.375 -3.234375 "/>
</symbol>
<symbol overflow="visible" id="glyph1-0">
@@ -164,78 +173,75 @@
<use xlink:href="#glyph0-10" x="144.281" y="10.657"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-3" x="151.661014" y="10.657"/>
<use xlink:href="#glyph0-11" x="151.661014" y="10.657"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-8" x="159.041015" y="10.657"/>
<use xlink:href="#glyph0-12" x="159.041015" y="10.657"/>
</g>
<path style="fill:none;stroke-width:4.05;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 1673.046875 665.46875 L 1717.382812 665.46875 " transform="matrix(0.1,0,0,-0.1,0,77)"/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-4" x="171.74" y="10.657"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-11" x="179.120014" y="10.657"/>
<use xlink:href="#glyph0-13" x="179.120014" y="10.657"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-12" x="186.500015" y="10.657"/>
<use xlink:href="#glyph0-14" x="186.500015" y="10.657"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-1" x="193.880029" y="10.657"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-13" x="201.26003" y="10.657"/>
<use xlink:href="#glyph0-15" x="201.26003" y="10.657"/>
</g>
<path style="fill:none;stroke-width:4.05;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 2095.234375 665.46875 L 2139.609375 665.46875 " transform="matrix(0.1,0,0,-0.1,0,77)"/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-14" x="213.968" y="10.657"/>
<use xlink:href="#glyph0-16" x="213.968" y="10.657"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-15" x="221.348026" y="10.657"/>
<use xlink:href="#glyph0-17" x="221.348026" y="10.657"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-15" x="228.728052" y="10.657"/>
<use xlink:href="#glyph0-18" x="228.728052" y="10.657"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-16" x="236.108053" y="10.657"/>
<use xlink:href="#glyph0-19" x="236.108053" y="10.657"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-17" x="243.488079" y="10.657"/>
<use xlink:href="#glyph0-20" x="243.488079" y="10.657"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-18" x="250.868105" y="10.657"/>
<use xlink:href="#glyph0-21" x="250.868105" y="10.657"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-19" x="258.248131" y="10.657"/>
<use xlink:href="#glyph0-22" x="258.248131" y="10.657"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-20" x="265.628133" y="10.657"/>
<use xlink:href="#glyph0-23" x="265.628133" y="10.657"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-14" x="273.008158" y="10.657"/>
<use xlink:href="#glyph0-23" x="273.008158" y="10.657"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-14" x="280.388184" y="10.657"/>
<use xlink:href="#glyph0-24" x="280.388184" y="10.657"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-21" x="287.76821" y="10.657"/>
<use xlink:href="#glyph1-0" x="291.7731" y="10.657"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph1-0" x="299.1621" y="10.657"/>
<use xlink:href="#glyph1-1" x="306.686018" y="10.657"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph1-1" x="314.066037" y="10.657"/>
<use xlink:href="#glyph1-1" x="313.706022" y="10.657"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph1-1" x="321.086041" y="10.657"/>
<use xlink:href="#glyph1-2" x="323.92119" y="10.657"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph1-2" x="331.30121" y="10.657"/>
<use xlink:href="#glyph2-0" x="338.0333" y="10.657"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph2-0" x="345.4223" y="10.657"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph3-0" x="351.99222" y="12.80778"/>
<use xlink:href="#glyph3-0" x="344.60322" y="12.80778"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-0" x="30.29622" y="31.58198"/>
@@ -279,96 +285,93 @@
<use xlink:href="#glyph0-10" x="129.512" y="31.582"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-3" x="136.892014" y="31.582"/>
<use xlink:href="#glyph0-11" x="136.892014" y="31.582"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-8" x="144.272015" y="31.582"/>
<use xlink:href="#glyph0-12" x="144.272015" y="31.582"/>
</g>
<path style="fill:none;stroke-width:4.05;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 1525.351562 456.210938 L 1569.726562 456.210938 " transform="matrix(0.1,0,0,-0.1,0,77)"/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-4" x="156.98" y="31.582"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-11" x="164.360014" y="31.582"/>
<use xlink:href="#glyph0-13" x="164.360014" y="31.582"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-12" x="171.740015" y="31.582"/>
<use xlink:href="#glyph0-14" x="171.740015" y="31.582"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-1" x="179.120029" y="31.582"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-13" x="186.50003" y="31.582"/>
<use xlink:href="#glyph0-15" x="186.50003" y="31.582"/>
</g>
<path style="fill:none;stroke-width:4.05;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 1947.617188 456.210938 L 1991.992188 456.210938 " transform="matrix(0.1,0,0,-0.1,0,77)"/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-14" x="199.208" y="31.582"/>
<use xlink:href="#glyph0-16" x="199.208" y="31.582"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-15" x="206.588026" y="31.582"/>
<use xlink:href="#glyph0-17" x="206.588026" y="31.582"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-15" x="213.968052" y="31.582"/>
<use xlink:href="#glyph0-18" x="213.968052" y="31.582"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-16" x="221.348053" y="31.582"/>
<use xlink:href="#glyph0-17" x="221.348053" y="31.582"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-15" x="228.728079" y="31.582"/>
<use xlink:href="#glyph0-18" x="228.728079" y="31.582"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-16" x="236.108105" y="31.582"/>
<use xlink:href="#glyph0-19" x="236.108105" y="31.582"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-17" x="243.488131" y="31.582"/>
<use xlink:href="#glyph0-25" x="243.488131" y="31.582"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-22" x="250.868133" y="31.582"/>
<use xlink:href="#glyph0-21" x="250.868133" y="31.582"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-19" x="258.248158" y="31.582"/>
<use xlink:href="#glyph0-22" x="258.248158" y="31.582"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-20" x="265.628184" y="31.582"/>
<use xlink:href="#glyph0-23" x="265.628184" y="31.582"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-14" x="273.00821" y="31.582"/>
<use xlink:href="#glyph0-26" x="273.00821" y="31.582"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-23" x="280.388212" y="31.582"/>
<use xlink:href="#glyph0-24" x="280.388212" y="31.582"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-21" x="287.768238" y="31.582"/>
<use xlink:href="#glyph1-0" x="291.7728" y="31.582"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph1-0" x="299.1619" y="31.582"/>
<use xlink:href="#glyph1-1" x="306.685718" y="31.582"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph1-1" x="314.065837" y="31.582"/>
<use xlink:href="#glyph1-3" x="313.705722" y="31.582"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph1-3" x="321.085841" y="31.582"/>
<use xlink:href="#glyph1-2" x="323.92089" y="31.582"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph1-2" x="331.30101" y="31.582"/>
<use xlink:href="#glyph2-0" x="338.033" y="31.582"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph2-0" x="345.4221" y="31.582"/>
<use xlink:href="#glyph3-1" x="344.60292" y="33.73278"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph3-1" x="351.99202" y="33.73278"/>
<use xlink:href="#glyph0-0" x="15.53592" y="52.50698"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-0" x="15.53602" y="52.50698"/>
<use xlink:href="#glyph0-1" x="22.915929" y="52.50698"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-1" x="22.916029" y="52.50698"/>
<use xlink:href="#glyph0-2" x="30.29594" y="52.50698"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-2" x="30.29604" y="52.50698"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-3" x="37.67605" y="52.50698"/>
<use xlink:href="#glyph0-3" x="37.67595" y="52.50698"/>
</g>
<path style="fill:none;stroke-width:4.05;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 459.375 246.953125 L 503.75 246.953125 " transform="matrix(0.1,0,0,-0.1,0,77)"/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
@@ -400,90 +403,87 @@
<use xlink:href="#glyph0-10" x="114.752" y="52.507"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-3" x="122.132014" y="52.507"/>
<use xlink:href="#glyph0-11" x="122.132014" y="52.507"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-8" x="129.512015" y="52.507"/>
<use xlink:href="#glyph0-12" x="129.512015" y="52.507"/>
</g>
<path style="fill:none;stroke-width:4.05;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 1377.734375 246.953125 L 1422.109375 246.953125 " transform="matrix(0.1,0,0,-0.1,0,77)"/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-4" x="142.211" y="52.507"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-11" x="149.591014" y="52.507"/>
<use xlink:href="#glyph0-13" x="149.591014" y="52.507"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-12" x="156.971015" y="52.507"/>
<use xlink:href="#glyph0-14" x="156.971015" y="52.507"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-1" x="164.351029" y="52.507"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-13" x="171.73103" y="52.507"/>
<use xlink:href="#glyph0-15" x="171.73103" y="52.507"/>
</g>
<path style="fill:none;stroke-width:4.05;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 1799.921875 246.953125 L 1844.296875 246.953125 " transform="matrix(0.1,0,0,-0.1,0,77)"/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-14" x="184.439" y="52.507"/>
<use xlink:href="#glyph0-16" x="184.439" y="52.507"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-15" x="191.819014" y="52.507"/>
<use xlink:href="#glyph0-17" x="191.819014" y="52.507"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-15" x="199.199015" y="52.507"/>
<use xlink:href="#glyph0-18" x="199.199015" y="52.507"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-16" x="206.579017" y="52.507"/>
<use xlink:href="#glyph0-17" x="206.579017" y="52.507"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-15" x="213.959043" y="52.507"/>
<use xlink:href="#glyph0-18" x="213.959043" y="52.507"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-16" x="221.339069" y="52.507"/>
<use xlink:href="#glyph0-17" x="221.339069" y="52.507"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-15" x="228.719094" y="52.507"/>
<use xlink:href="#glyph0-18" x="228.719094" y="52.507"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-16" x="236.099096" y="52.507"/>
<use xlink:href="#glyph0-19" x="236.099096" y="52.507"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-17" x="243.479122" y="52.507"/>
<use xlink:href="#glyph0-27" x="243.479122" y="52.507"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-24" x="250.859148" y="52.507"/>
<use xlink:href="#glyph0-21" x="250.859148" y="52.507"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-19" x="258.239174" y="52.507"/>
<use xlink:href="#glyph0-22" x="258.239174" y="52.507"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-20" x="265.619175" y="52.507"/>
<use xlink:href="#glyph0-23" x="265.619175" y="52.507"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-14" x="272.999201" y="52.507"/>
<use xlink:href="#glyph0-28" x="272.999201" y="52.507"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-25" x="280.379227" y="52.507"/>
<use xlink:href="#glyph0-24" x="280.379227" y="52.507"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-21" x="287.759253" y="52.507"/>
<use xlink:href="#glyph1-0" x="291.773" y="52.507"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph1-0" x="299.162" y="52.507"/>
<use xlink:href="#glyph1-1" x="306.685918" y="52.507"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph1-1" x="314.065937" y="52.507"/>
<use xlink:href="#glyph1-4" x="313.705922" y="52.507"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph1-4" x="321.085941" y="52.507"/>
<use xlink:href="#glyph1-2" x="323.92109" y="52.507"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph1-2" x="331.30111" y="52.507"/>
<use xlink:href="#glyph2-0" x="338.0332" y="52.507"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph2-0" x="345.4222" y="52.507"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph3-2" x="351.99212" y="54.65778"/>
<use xlink:href="#glyph3-2" x="344.60312" y="54.65778"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-0" x="0.76712" y="73.42298"/>
@@ -527,96 +527,93 @@
<use xlink:href="#glyph0-10" x="99.9832" y="73.42305"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-3" x="107.363214" y="73.42305"/>
<use xlink:href="#glyph0-11" x="107.363214" y="73.42305"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-8" x="114.743215" y="73.42305"/>
<use xlink:href="#glyph0-12" x="114.743215" y="73.42305"/>
</g>
<path style="fill:none;stroke-width:4.05;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 1230.039062 37.8125 L 1274.414062 37.8125 " transform="matrix(0.1,0,0,-0.1,0,77)"/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-4" x="127.451" y="73.42305"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-11" x="134.831014" y="73.42305"/>
<use xlink:href="#glyph0-13" x="134.831014" y="73.42305"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-12" x="142.211015" y="73.42305"/>
<use xlink:href="#glyph0-14" x="142.211015" y="73.42305"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-1" x="149.591029" y="73.42305"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-13" x="156.97103" y="73.42305"/>
<use xlink:href="#glyph0-15" x="156.97103" y="73.42305"/>
</g>
<path style="fill:none;stroke-width:4.05;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 1652.34375 37.8125 L 1696.71875 37.8125 " transform="matrix(0.1,0,0,-0.1,0,77)"/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-14" x="169.679" y="73.42305"/>
<use xlink:href="#glyph0-16" x="169.679" y="73.42305"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-15" x="177.059014" y="73.42305"/>
<use xlink:href="#glyph0-17" x="177.059014" y="73.42305"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-15" x="184.439015" y="73.42305"/>
<use xlink:href="#glyph0-18" x="184.439015" y="73.42305"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-16" x="191.819029" y="73.42305"/>
<use xlink:href="#glyph0-17" x="191.819029" y="73.42305"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-15" x="199.19903" y="73.42305"/>
<use xlink:href="#glyph0-18" x="199.19903" y="73.42305"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-16" x="206.579056" y="73.42305"/>
<use xlink:href="#glyph0-17" x="206.579056" y="73.42305"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-15" x="213.959082" y="73.42305"/>
<use xlink:href="#glyph0-18" x="213.959082" y="73.42305"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-16" x="221.339084" y="73.42305"/>
<use xlink:href="#glyph0-17" x="221.339084" y="73.42305"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-15" x="228.71911" y="73.42305"/>
<use xlink:href="#glyph0-18" x="228.71911" y="73.42305"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-16" x="236.099136" y="73.42305"/>
<use xlink:href="#glyph0-19" x="236.099136" y="73.42305"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-17" x="243.479161" y="73.42305"/>
<use xlink:href="#glyph0-29" x="243.479161" y="73.42305"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-26" x="250.859163" y="73.42305"/>
<use xlink:href="#glyph0-21" x="250.859163" y="73.42305"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-19" x="258.239189" y="73.42305"/>
<use xlink:href="#glyph0-22" x="258.239189" y="73.42305"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-20" x="265.619215" y="73.42305"/>
<use xlink:href="#glyph0-23" x="265.619215" y="73.42305"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-14" x="272.999241" y="73.42305"/>
<use xlink:href="#glyph0-30" x="272.999241" y="73.42305"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-27" x="280.379242" y="73.42305"/>
<use xlink:href="#glyph0-24" x="280.379242" y="73.42305"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-21" x="287.759268" y="73.42305"/>
<use xlink:href="#glyph1-0" x="291.773" y="73.42305"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph1-0" x="299.162" y="73.42305"/>
<use xlink:href="#glyph1-1" x="306.685918" y="73.42305"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph1-1" x="314.065937" y="73.42305"/>
<use xlink:href="#glyph1-5" x="313.705922" y="73.42305"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph1-5" x="321.085941" y="73.42305"/>
<use xlink:href="#glyph1-2" x="323.92109" y="73.42305"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph1-2" x="331.30111" y="73.42305"/>
<use xlink:href="#glyph2-0" x="338.0332" y="73.42305"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph2-0" x="345.4222" y="73.42305"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph3-3" x="351.99212" y="75.57383"/>
<use xlink:href="#glyph3-3" x="344.60273" y="75.57383"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 60 KiB

View File

@@ -15,14 +15,14 @@ using namespace boost::math::differentiation;
template<typename X>
X phi(const X& x)
{
return boost::math::constants::one_div_root_two_pi<double>()*exp(-0.5*x*x);
return boost::math::constants::one_div_root_two_pi<X>()*exp(-0.5*x*x);
}
// Standard normal cumulative distribution function
template<typename X>
X Phi(const X& x)
{
return 0.5*erfc(-boost::math::constants::one_div_root_two<double>()*x);
return 0.5*erfc(-boost::math::constants::one_div_root_two<X>()*x);
}
enum CP { call, put };

View File

@@ -4,7 +4,7 @@
// https://www.boost.org/LICENSE_1_0.txt)
#include <boost/math/differentiation/autodiff.hpp>
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <boost/multiprecision/cpp_bin_float.hpp>
#include <iostream>
template<typename T>
@@ -16,30 +16,31 @@ T f(const T& w, const T& x, const T& y, const T& z)
int main()
{
using cpp_dec_float_100 = boost::multiprecision::cpp_dec_float_100;
using cpp_bin_float_50 = boost::multiprecision::cpp_bin_float_50;
using namespace boost::math::differentiation;
constexpr int Nw=3; // Max order of derivative to calculate for w
constexpr int Nx=2; // Max order of derivative to calculate for x
constexpr int Ny=4; // Max order of derivative to calculate for y
constexpr int Nz=3; // Max order of derivative to calculate for z
using var = autodiff_fvar<cpp_dec_float_100,Nw,Nx,Ny,Nz>;
const var w = make_fvar<cpp_dec_float_100,Nw>(11);
const var x = make_fvar<cpp_dec_float_100,0,Nx>(12);
const var y = make_fvar<cpp_dec_float_100,0,0,Ny>(13);
const var z = make_fvar<cpp_dec_float_100,0,0,0,Nz>(14);
using var = autodiff_fvar<cpp_bin_float_50,Nw,Nx,Ny,Nz>;
const var w = make_fvar<cpp_bin_float_50,Nw>(11);
const var x = make_fvar<cpp_bin_float_50,0,Nx>(12);
const var y = make_fvar<cpp_bin_float_50,0,0,Ny>(13);
const var z = make_fvar<cpp_bin_float_50,0,0,0,Nz>(14);
const var v = f(w,x,y,z);
// Calculated from Mathematica symbolic differentiation. See multiprecision.nb for script.
const cpp_dec_float_100 answer("1976.31960074779771777988187529041872090812118921875499076582535951111845769110560421820940516423255314");
std::cout << std::setprecision(std::numeric_limits<cpp_dec_float_100>::digits10)
// Calculated from Mathematica symbolic differentiation.
const cpp_bin_float_50 answer("1976.319600747797717779881875290418720908121189218755");
std::cout << std::setprecision(std::numeric_limits<cpp_bin_float_50>::digits10)
<< "mathematica : " << answer << '\n'
<< "autodiff : " << v.derivative(Nw,Nx,Ny,Nz) << '\n'
<< "relative error: " << std::setprecision(3) << (v.derivative(Nw,Nx,Ny,Nz)/answer-1) << std::endl;
<< "relative error: " << std::setprecision(3) << (v.derivative(Nw,Nx,Ny,Nz)/answer-1)
<< std::endl;
return 0;
}
/*
Output:
mathematica : 1976.319600747797717779881875290418720908121189218754990765825359511118457691105604218209405164232553
autodiff : 1976.319600747797717779881875290418720908121189218754990765825359511118457691105604218209405164232566
relative error: 6.47e-99
mathematica : 1976.3196007477977177798818752904187209081211892188
autodiff : 1976.3196007477977177798818752904187209081211892188
relative error: 2.67e-50
**/

View File

@@ -8,7 +8,7 @@
#include <boost/config.hpp>
#include <boost/math/constants/constants.hpp>
#include <boost/math/special_functions/factorials.hpp>
#include <boost/math/special_functions.hpp>
#include <boost/math/tools/promotion.hpp>
#include <algorithm>
@@ -424,9 +424,10 @@ fvar<RealType,Order> tan(const fvar<RealType,Order>&);
template<typename RealType, size_t Order>
fvar<RealType,Order> atan(const fvar<RealType,Order>&);
// fmod(cr1) | RealType
template<typename RealType, size_t Order>
fvar<RealType,Order> fmod(const fvar<RealType,Order>&, const typename fvar<RealType,Order>::root_type&);
// fmod(cr1,cr2) | RealType
template<typename RealType1, size_t Order1, typename RealType2, size_t Order2>
promote<fvar<RealType1,Order1>,fvar<RealType2,Order2>>
fmod(const fvar<RealType1,Order1>&, const fvar<RealType2,Order2>&);
// round(cr1) | RealType
template<typename RealType, size_t Order>
@@ -448,9 +449,36 @@ int itrunc(const fvar<RealType,Order>&);
template<typename RealType, size_t Order>
fvar<RealType,Order> acos(const fvar<RealType,Order>&);
template<typename RealType, size_t Order>
fvar<RealType,Order> acosh(const fvar<RealType,Order>&);
template<typename RealType, size_t Order>
fvar<RealType,Order> asinh(const fvar<RealType,Order>&);
template<typename RealType, size_t Order>
fvar<RealType,Order> atanh(const fvar<RealType,Order>&);
template<typename RealType, size_t Order>
fvar<RealType,Order> cosh(const fvar<RealType,Order>&);
template<typename RealType, size_t Order>
fvar<RealType,Order> erf(const fvar<RealType,Order>&);
template<typename RealType, size_t Order>
fvar<RealType,Order> erfc(const fvar<RealType,Order>&);
template<typename RealType, size_t Order>
fvar<RealType,Order> lambert_w0(const fvar<RealType,Order>&);
template<typename RealType, size_t Order>
fvar<RealType,Order> sinc(const fvar<RealType,Order>&);
template<typename RealType, size_t Order>
fvar<RealType,Order> sinh(const fvar<RealType,Order>&);
template<typename RealType, size_t Order>
fvar<RealType,Order> tanh(const fvar<RealType,Order>&);
template<typename RealType, size_t Order>
long lround(const fvar<RealType,Order>&);
@@ -928,8 +956,7 @@ template<typename RealType, size_t Order>
fvar<RealType,Order> fvar<RealType,Order>::apply_with_horner(const std::function<root_type(size_t)>& f) const
{
const fvar<RealType,Order> epsilon = fvar<RealType,Order>(*this).set_root(0);
auto accumulator = fvar<RealType,Order>( // Cast needed for types where operator/() does not return root_type.
static_cast<root_type>(f(order_sum) / boost::math::factorial<root_type>(order_sum)));
fvar<RealType,Order> accumulator(static_cast<root_type>(f(order_sum)/boost::math::factorial<root_type>(order_sum)));
for (size_t i=order_sum ; i-- ;)
(accumulator *= epsilon) += f(i) / boost::math::factorial<root_type>(i);
return accumulator;
@@ -942,7 +969,7 @@ fvar<RealType,Order>
fvar<RealType,Order>::apply_with_horner_factorials(const std::function<root_type(size_t)>& f) const
{
const fvar<RealType,Order> epsilon = fvar<RealType,Order>(*this).set_root(0);
auto accumulator = fvar<RealType,Order>(f(order_sum));
fvar<RealType,Order> accumulator(f(order_sum));
for (size_t i=order_sum ; i-- ;)
(accumulator *= epsilon) += f(i);
return accumulator;
@@ -1036,9 +1063,9 @@ fvar<RealType,Order> fvar<RealType,Order>::inverse() const
template<typename RealType, size_t Order>
fvar<RealType,Order> fvar<RealType,Order>::inverse_apply() const
{
root_type derivatives[order_sum+1]; // derivatives of 1/x
root_type derivatives[order_sum+1]; // LCOV_EXCL_LINE This causes a false negative on lcov coverage test.
const root_type x0 = static_cast<root_type>(*this);
derivatives[0] = 1 / x0;
*derivatives = 1 / x0;
for (size_t i=1 ; i<=order_sum ; ++i)
derivatives[i] = -derivatives[i-1] * i / x0;
return apply([&derivatives](size_t j) { return derivatives[j]; });
@@ -1131,7 +1158,7 @@ fvar<RealType,Order> pow(const fvar<RealType,Order>& x,const typename fvar<RealT
using std::pow;
using root_type = typename fvar<RealType,Order>::root_type;
constexpr size_t order = fvar<RealType,Order>::order_sum;
std::array<root_type,order+1> derivatives; // array of derivatives
root_type derivatives[order+1];
const root_type x0 = static_cast<root_type>(x);
size_t i = 0;
root_type coef = 1;
@@ -1163,21 +1190,21 @@ fvar<RealType,Order> sqrt(const fvar<RealType,Order>& cr)
using std::sqrt;
using root_type = typename fvar<RealType,Order>::root_type;
constexpr size_t order = fvar<RealType,Order>::order_sum;
std::array<root_type,order+1> derivatives;
root_type derivatives[order+1];
const root_type x = static_cast<root_type>(cr);
derivatives.front() = sqrt(x);
*derivatives = sqrt(x);
if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0)
return fvar<RealType,Order>(derivatives.front());
return fvar<RealType,Order>(*derivatives);
else
{
root_type numerator = 0.5;
root_type powers = 1;
derivatives[1] = numerator / derivatives.front();
derivatives[1] = numerator / *derivatives;
for (size_t i=2 ; i<=order ; ++i)
{
numerator *= -0.5 * ((i<<1)-3);
powers *= x;
derivatives[i] = numerator / (powers * derivatives.front());
derivatives[i] = numerator / (powers * *derivatives);
}
return cr.apply([&derivatives](size_t i) { return derivatives[i]; });
}
@@ -1203,18 +1230,16 @@ fvar<RealType,Order> log(const fvar<RealType,Order>& cr)
template<typename RealType, size_t Order>
fvar<RealType,Order> frexp(const fvar<RealType,Order>& cr, int* exp)
{
using std::exp2;
using std::frexp;
using root_type = typename fvar<RealType,Order>::root_type;
frexp(static_cast<root_type>(cr), exp);
return cr * exp2(-*exp);
return cr * std::exp2(-*exp);
}
template<typename RealType, size_t Order>
fvar<RealType,Order> ldexp(const fvar<RealType,Order>& cr, int exp)
{
using std::exp2;
return cr * exp2(exp);
return cr * std::exp2(exp);
}
template<typename RealType, size_t Order>
@@ -1292,13 +1317,14 @@ fvar<RealType,Order> atan(const fvar<RealType,Order>& cr)
}
}
template<typename RealType, size_t Order>
fvar<RealType,Order>
fmod(const fvar<RealType,Order>& cr, const typename fvar<RealType,Order>::root_type& ca)
template<typename RealType1, size_t Order1, typename RealType2, size_t Order2>
promote<fvar<RealType1,Order1>,fvar<RealType2,Order2>>
fmod(const fvar<RealType1,Order1>& cr1, const fvar<RealType2,Order2>& cr2)
{
using std::fmod;
using root_type = typename fvar<RealType,Order>::root_type;
return fvar<RealType,Order>(cr).set_root(0) += fmod(static_cast<root_type>(cr), ca);
using std::trunc;
const auto numer = static_cast<typename fvar<RealType1,Order1>::root_type>(cr1);
const auto denom = static_cast<typename fvar<RealType2,Order2>::root_type>(cr2);
return cr1 - cr2 * trunc(numer/denom);
}
template<typename RealType, size_t Order>
@@ -1351,8 +1377,92 @@ fvar<RealType,Order> acos(const fvar<RealType,Order>& cr)
return fvar<RealType,Order>(d0);
else
{
auto d1 = make_fvar<root_type,order-1>(static_cast<root_type>(cr));
d1 = -sqrt(1-(d1*=d1)).inverse(); // acos'(x) = -1 / sqrt(1-x*x).
auto x = make_fvar<root_type,order-1>(static_cast<root_type>(cr));
const auto d1 = -sqrt(1-(x*=x)).inverse(); // acos'(x) = -1 / sqrt(1-x*x).
return cr.apply_with_horner_factorials([&d0,&d1](size_t i) { return i ? d1.at(i-1)/i : d0; });
}
}
template<typename RealType, size_t Order>
fvar<RealType,Order> acosh(const fvar<RealType,Order>& cr)
{
using std::acosh;
using root_type = typename fvar<RealType,Order>::root_type;
constexpr size_t order = fvar<RealType,Order>::order_sum;
const root_type d0 = acosh(static_cast<root_type>(cr));
if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0)
return fvar<RealType,Order>(d0);
else
{
auto x = make_fvar<root_type,order-1>(static_cast<root_type>(cr));
const auto d1 = sqrt((x*=x)-1).inverse(); // acosh'(x) = 1 / sqrt(x*x-1).
return cr.apply_with_horner_factorials([&d0,&d1](size_t i) { return i ? d1.at(i-1)/i : d0; });
}
}
template<typename RealType, size_t Order>
fvar<RealType,Order> asinh(const fvar<RealType,Order>& cr)
{
using std::asinh;
using root_type = typename fvar<RealType,Order>::root_type;
constexpr size_t order = fvar<RealType,Order>::order_sum;
const root_type d0 = asinh(static_cast<root_type>(cr));
if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0)
return fvar<RealType,Order>(d0);
else
{
auto x = make_fvar<root_type,order-1>(static_cast<root_type>(cr));
const auto d1 = sqrt((x*=x)+1).inverse(); // asinh'(x) = 1 / sqrt(x*x+1).
return cr.apply_with_horner_factorials([&d0,&d1](size_t i) { return i ? d1.at(i-1)/i : d0; });
}
}
template<typename RealType, size_t Order>
fvar<RealType,Order> atanh(const fvar<RealType,Order>& cr)
{
using std::atanh;
using root_type = typename fvar<RealType,Order>::root_type;
constexpr size_t order = fvar<RealType,Order>::order_sum;
const root_type d0 = atanh(static_cast<root_type>(cr));
if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0)
return fvar<RealType,Order>(d0);
else
{
auto x = make_fvar<root_type,order-1>(static_cast<root_type>(cr));
const auto d1 = (1-(x*=x)).inverse(); // atanh'(x) = 1 / (1-x*x)
return cr.apply_with_horner_factorials([&d0,&d1](size_t i) { return i ? d1.at(i-1)/i : d0; });
}
}
template<typename RealType, size_t Order>
fvar<RealType,Order> cosh(const fvar<RealType,Order>& cr)
{
using std::cosh;
using std::sinh;
using root_type = typename fvar<RealType,Order>::root_type;
const root_type d0 = cosh(static_cast<root_type>(cr));
if BOOST_AUTODIFF_IF_CONSTEXPR (fvar<RealType,Order>::order_sum == 0)
return fvar<RealType,Order>(d0);
else
{
const root_type derivatives[2] { d0, sinh(static_cast<root_type>(cr)) };
return cr.apply_with_horner([&derivatives](size_t i) { return derivatives[i&1]; });
}
}
template<typename RealType, size_t Order>
fvar<RealType,Order> erf(const fvar<RealType,Order>& cr)
{
using std::erf;
using root_type = typename fvar<RealType,Order>::root_type;
constexpr size_t order = fvar<RealType,Order>::order_sum;
const root_type d0 = erf(static_cast<root_type>(cr));
if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0)
return fvar<RealType,Order>(d0);
else
{
auto x = make_fvar<root_type,order-1>(static_cast<root_type>(cr));
const auto d1 = 2*boost::math::constants::one_div_root_pi<root_type>()*exp(-(x*=x)); // 2/sqrt(pi)*exp(-x*x)
return cr.apply_with_horner_factorials([&d0,&d1](size_t i) { return i ? d1.at(i-1)/i : d0; });
}
}
@@ -1368,12 +1478,91 @@ fvar<RealType,Order> erfc(const fvar<RealType,Order>& cr)
return fvar<RealType,Order>(d0);
else
{
auto d1 = make_fvar<root_type,order-1>(static_cast<root_type>(cr));
d1 = -2*boost::math::constants::one_div_root_pi<root_type>()*exp(-(d1*=d1)); // erfc'(x)=-2/sqrt(pi)*exp(-x*x)
auto x = make_fvar<root_type,order-1>(static_cast<root_type>(cr));
const auto d1 = -2*boost::math::constants::one_div_root_pi<root_type>()*exp(-(x*=x)); // erfc'(x)=-erf'(x)
return cr.apply_with_horner_factorials([&d0,&d1](size_t i) { return i ? d1.at(i-1)/i : d0; });
}
}
template<typename RealType, size_t Order>
fvar<RealType,Order> lambert_w0(const fvar<RealType,Order>& cr)
{
using boost::math::lambert_w0;
using std::exp;
using root_type = typename fvar<RealType,Order>::root_type;
constexpr size_t order = fvar<RealType,Order>::order_sum;
root_type derivatives[order+1];
*derivatives = lambert_w0(static_cast<root_type>(cr));
if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0)
return fvar<RealType,Order>(*derivatives);
else
{
const root_type expw = exp(*derivatives);
derivatives[1] = 1 / (static_cast<root_type>(cr) + expw);
if BOOST_AUTODIFF_IF_CONSTEXPR (order == 1)
return cr.apply([&derivatives](size_t i) { return derivatives[i]; });
else
{
root_type d1powers = derivatives[1] * derivatives[1];
const root_type x = derivatives[1] * expw;
derivatives[2] = d1powers * (-1 - x);
std::array<root_type,order> coef { -1, -1 }; // as in derivatives[2].
for (size_t n=3 ; n<=order ; ++n)
{
coef[n-1] = coef[n-2] * -static_cast<root_type>(2*n-3);
for (size_t j=n-2 ; j!=0 ; --j)
(coef[j] *= -static_cast<root_type>(n-1)) -= (n+j-2) * coef[j-1];
coef[0] *= -static_cast<root_type>(n-1);
d1powers *= derivatives[1];
derivatives[n] = d1powers * std::accumulate(coef.crend()-(n-1), coef.crend(), coef[n-1],
[&x](const root_type& a, const root_type& b) { return a*x + b; });
}
return cr.apply([&derivatives](size_t i) { return derivatives[i]; });
}
}
}
template<typename RealType, size_t Order>
fvar<RealType,Order> sinc(const fvar<RealType,Order>& cr)
{
if (cr != 0)
return sin(cr) / cr;
using root_type = typename fvar<RealType,Order>::root_type;
constexpr size_t order = fvar<RealType,Order>::order_sum;
root_type taylor[order+1] { 1 }; // sinc(0) = 1
if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0)
return fvar<RealType,Order>(*taylor);
else
{
for (size_t n=2 ; n<=order ; n+=2)
taylor[n] = (1-static_cast<int>(n&2)) / boost::math::factorial<root_type>(n+1);
return cr.apply_with_factorials([&taylor](size_t i) { return taylor[i]; });
}
}
template<typename RealType, size_t Order>
fvar<RealType,Order> sinh(const fvar<RealType,Order>& cr)
{
using std::sinh;
using std::cosh;
using root_type = typename fvar<RealType,Order>::root_type;
const root_type d0 = sinh(static_cast<root_type>(cr));
if BOOST_AUTODIFF_IF_CONSTEXPR (fvar<RealType,Order>::order_sum == 0)
return fvar<RealType,Order>(d0);
else
{
const root_type derivatives[2] { d0, cosh(static_cast<root_type>(cr)) };
return cr.apply_with_horner([&derivatives](size_t i) { return derivatives[i&1]; });
}
}
template<typename RealType, size_t Order>
fvar<RealType,Order> tanh(const fvar<RealType,Order>& cr)
{
const fvar<RealType,Order> exp2cr = exp(cr*2);
return (exp2cr - 1) /= (exp2cr + 1);
}
template<typename RealType, size_t Order>
long lround(const fvar<RealType,Order>& cr)
{

View File

@@ -1238,7 +1238,7 @@ test-suite misc :
[ run compile_test/numerical_differentiation_incl_test.cpp compile_test_main : : : [ requires cxx11_auto_declarations cxx11_constexpr ] ]
[ compile compile_test/numerical_differentiation_concept_test.cpp : [ requires cxx11_auto_declarations cxx11_constexpr ] ]
[ run __temporary_test.cpp test_instances//test_instances : : : <test-info>always_show_run_output <pch>off ]
[ run test_autodiff.cpp ../../test/build//boost_unit_test_framework : : : [ requires cxx11_lambdas ] ]
[ run test_autodiff.cpp ../../test/build//boost_unit_test_framework : : : <toolset>msvc:<cxxflags>/bigobj [ requires cxx11_inline_namespaces ] ]
;
build-project ../example ;

View File

@@ -3,24 +3,22 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
#include <boost/math/differentiation/autodiff.hpp>
#include <boost/fusion/include/algorithm.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/math/differentiation/autodiff.hpp>
#include <boost/math/special_functions/factorials.hpp>
#include <boost/math/special_functions/fpclassify.hpp> // isnan
#include <boost/math/special_functions/round.hpp> // iround
#include <boost/math/special_functions/trunc.hpp> // itrunc
#include <boost/multiprecision/cpp_bin_float.hpp>
#include <boost/multiprecision/cpp_dec_float.hpp>
#define BOOST_TEST_MODULE test_autodiff
#include <boost/test/included/unit_test.hpp>
#include <iostream>
#include <sstream>
boost::fusion::vector<float,double,long double,boost::multiprecision::cpp_bin_float_50> bin_float_types;
//boost::fusion::vector<float,double,long double> bin_float_types; // Add cpp_bin_float_50 for boost 1.70
//boost::fusion::vector<float,double,long double,boost::multiprecision::cpp_bin_float_50> bin_float_types;
boost::fusion::vector<float,double,long double> bin_float_types; // cpp_bin_float_50 is fixed in boost 1.70
// cpp_dec_float_50 cannot be used with close_at_tolerance
//boost::fusion::vector<boost::multiprecision::cpp_dec_float_50>
boost::fusion::vector<> multiprecision_float_types;
@@ -70,10 +68,7 @@ promote<Price,Sigma,Tau,Rate>
template<typename T>
T uncast_return(const T& x)
{
if (x == 0)
return 0;
else
return 1;
return x == 0 ? 0 : 1;
}
BOOST_AUTO_TEST_SUITE(test_autodiff)
@@ -199,6 +194,26 @@ BOOST_AUTO_TEST_CASE(assignment)
boost::fusion::for_each(multiprecision_float_types, assignment_test());
}
struct ostream_test
{
template<typename T>
void operator()(const T&) const
{
constexpr int m = 3;
const T cx = 10;
const auto x = make_fvar<T,m>(cx);
std::ostringstream ss;
ss << "x = " << x;
BOOST_REQUIRE(ss.str() == "x = depth(1)(10,1,0,0)");
}
};
BOOST_AUTO_TEST_CASE(ostream)
{
boost::fusion::for_each(bin_float_types, ostream_test());
boost::fusion::for_each(multiprecision_float_types, ostream_test());
}
struct addition_assignment_test
{
template<typename T>
@@ -606,7 +621,6 @@ struct dim2_addition_test
BOOST_REQUIRE(y.derivative(0,1) == 1.0);
BOOST_REQUIRE(y.derivative(1,0) == 0.0);
BOOST_REQUIRE(y.derivative(1,1) == 0.0);
//const auto z = x + y; // ambiguous operator when root_type=cpp_bin_float_50
const auto z = x + y;
BOOST_REQUIRE(z.derivative(0,0) == cx + cy);
BOOST_REQUIRE(z.derivative(0,1) == 1.0);
@@ -711,6 +725,10 @@ struct inverse_test
BOOST_REQUIRE(xinv.derivative(1) == -1/std::pow(cx,2));
BOOST_REQUIRE(xinv.derivative(2) == 2/std::pow(cx,3));
BOOST_REQUIRE(xinv.derivative(3) == -6/std::pow(cx,4));
const auto zero = make_fvar<T,m>(0);
const auto inf = zero.inverse();
for (int i=0 ; i<=m ; ++i)
BOOST_REQUIRE(inf.derivative(i) == (i&1?-1:1)*std::numeric_limits<T>::infinity());
}
};
@@ -970,8 +988,8 @@ struct one_over_one_plus_x_squared_test
constexpr int m = 4;
constexpr float cx = 1.0;
auto f = make_fvar<T,m>(cx);
//f = ((f *= f) += 1).inverse(); // Microsoft Visual C++ version 14.0: fatal error C1001: An internal error has occurred in the compiler. on call to order_sum() in inverse_apply().
f = 1 / ((f *= f) += 1);
//f = 1 / ((f *= f) += 1);
f = ((f *= f) += 1).inverse();
BOOST_REQUIRE(f.derivative(0) == 0.5);
BOOST_REQUIRE(f.derivative(1) == -0.5);
BOOST_REQUIRE(f.derivative(2) == 0.5);
@@ -1277,6 +1295,32 @@ BOOST_AUTO_TEST_CASE(acos_test)
boost::fusion::for_each(bin_float_types, acos_test_test());
}
struct acosh_test_test
{
template<typename T>
void operator()(const T&) const
{
const T eps = 300*std::numeric_limits<T>::epsilon(); // percent
using std::acosh;
constexpr int m = 5;
const T cx = 2;
auto x = make_fvar<T,m>(cx);
auto y = acosh(x);
//BOOST_REQUIRE(y.derivative(0) == acosh(cx)); // FAILS! acosh(2) is overloaded for integral types
BOOST_REQUIRE(y.derivative(0) == acosh(static_cast<T>(x)));
BOOST_REQUIRE_CLOSE(y.derivative(1), 1/boost::math::constants::root_three<T>(), eps);
BOOST_REQUIRE_CLOSE(y.derivative(2), -2/(3*boost::math::constants::root_three<T>()), eps);
BOOST_REQUIRE_CLOSE(y.derivative(3), 1/boost::math::constants::root_three<T>(), eps);
BOOST_REQUIRE_CLOSE(y.derivative(4), -22/(9*boost::math::constants::root_three<T>()), eps);
BOOST_REQUIRE_CLOSE(y.derivative(5), 227/(27*boost::math::constants::root_three<T>()), eps);
}
};
BOOST_AUTO_TEST_CASE(acosh_test)
{
boost::fusion::for_each(bin_float_types, acosh_test_test());
}
struct asin_test_test
{
template<typename T>
@@ -1362,30 +1406,55 @@ BOOST_AUTO_TEST_CASE(asin_derivative)
boost::fusion::for_each(bin_float_types, asin_derivative_test());
}
struct tan_test_test
struct asinh_test_test
{
template<typename T>
void operator()(const T&) const
{
const T eps = 800*std::numeric_limits<T>::epsilon(); // percent
using std::sqrt;
const T eps = 300*std::numeric_limits<T>::epsilon(); // percent
using std::asinh;
constexpr int m = 5;
const T cx = boost::math::constants::third_pi<T>();
const T root_three = boost::math::constants::root_three<T>();
const auto x = make_fvar<T,m>(cx);
auto y = tan(x);
BOOST_REQUIRE_CLOSE(y.derivative(0), root_three, eps);
BOOST_REQUIRE_CLOSE(y.derivative(1), 4.0, eps);
BOOST_REQUIRE_CLOSE(y.derivative(2), 8*root_three, eps);
BOOST_REQUIRE_CLOSE(y.derivative(3), 80.0, eps);
BOOST_REQUIRE_CLOSE(y.derivative(4), 352*root_three, eps);
BOOST_REQUIRE_CLOSE(y.derivative(5), 5824.0, eps);
const T cx = 1;
auto x = make_fvar<T,m>(cx);
auto y = asinh(x);
BOOST_REQUIRE(y.derivative(0) == asinh(cx));
BOOST_REQUIRE_CLOSE(y.derivative(1), 1/boost::math::constants::root_two<T>(), eps);
BOOST_REQUIRE_CLOSE(y.derivative(2), -1/(2*boost::math::constants::root_two<T>()), eps);
BOOST_REQUIRE_CLOSE(y.derivative(3), 1/(4*boost::math::constants::root_two<T>()), eps);
BOOST_REQUIRE_CLOSE(y.derivative(4), 3/(8*boost::math::constants::root_two<T>()), eps);
BOOST_REQUIRE_CLOSE(y.derivative(5), -39/(16*boost::math::constants::root_two<T>()), eps);
}
};
BOOST_AUTO_TEST_CASE(tan_test)
BOOST_AUTO_TEST_CASE(asinh_test)
{
boost::fusion::for_each(bin_float_types, tan_test_test());
boost::fusion::for_each(bin_float_types, asinh_test_test());
}
struct atanh_test_test
{
template<typename T>
void operator()(const T&) const
{
const T eps = 300*std::numeric_limits<T>::epsilon(); // percent
using std::atanh;
constexpr int m = 5;
const T cx = 0.5;
auto x = make_fvar<T,m>(cx);
auto y = atanh(x);
// BOOST_REQUIRE(y.derivative(0) == atanh(cx)); // fails due to overload
BOOST_REQUIRE(y.derivative(0) == atanh(static_cast<T>(x)));
BOOST_REQUIRE_CLOSE(y.derivative(1), static_cast<T>(4)/3, eps);
BOOST_REQUIRE_CLOSE(y.derivative(2), static_cast<T>(16)/9, eps);
BOOST_REQUIRE_CLOSE(y.derivative(3), static_cast<T>(224)/27, eps);
BOOST_REQUIRE_CLOSE(y.derivative(4), static_cast<T>(1280)/27, eps);
BOOST_REQUIRE_CLOSE(y.derivative(5), static_cast<T>(31232)/81, eps);
}
};
BOOST_AUTO_TEST_CASE(atanh_test)
{
boost::fusion::for_each(bin_float_types, atanh_test_test());
}
struct atan_test_test
@@ -1412,6 +1481,125 @@ BOOST_AUTO_TEST_CASE(atan_test)
boost::fusion::for_each(multiprecision_float_types, atan_test_test());
}
struct erf_test_test
{
template<typename T>
void operator()(const T&) const
{
const T eps = 300*std::numeric_limits<T>::epsilon(); // percent
using std::erf;
using namespace boost;
constexpr int m = 5;
constexpr float cx = 1.0;
const auto x = make_fvar<T,m>(cx);
auto y = erf(x);
BOOST_REQUIRE(y.derivative(0) == erf(static_cast<T>(x)));
BOOST_REQUIRE_CLOSE(y.derivative(1), 2/(math::constants::e<T>()*math::constants::root_pi<T>()), eps);
BOOST_REQUIRE_CLOSE(y.derivative(2), -4/(math::constants::e<T>()*math::constants::root_pi<T>()), eps);
BOOST_REQUIRE_CLOSE(y.derivative(3), 4/(math::constants::e<T>()*math::constants::root_pi<T>()), eps);
BOOST_REQUIRE_CLOSE(y.derivative(4), 8/(math::constants::e<T>()*math::constants::root_pi<T>()), eps);
BOOST_REQUIRE_CLOSE(y.derivative(5), -40/(math::constants::e<T>()*math::constants::root_pi<T>()), eps);
}
};
BOOST_AUTO_TEST_CASE(erf_test)
{
boost::fusion::for_each(bin_float_types, erf_test_test());
boost::fusion::for_each(multiprecision_float_types, erf_test_test());
}
struct sinc_test_test
{
template<typename T>
void operator()(const T&) const
{
const T eps = 20000*std::numeric_limits<T>::epsilon(); // percent
using std::sin;
using std::cos;
constexpr int m = 5;
const T cx = 1;
auto x = make_fvar<T,m>(cx);
auto y = sinc(x);
BOOST_REQUIRE_CLOSE(y.derivative(0), sin(cx), eps);
BOOST_REQUIRE_CLOSE(y.derivative(1), cos(cx)-sin(cx), eps);
BOOST_REQUIRE_CLOSE(y.derivative(2), sin(cx)-2*cos(cx), eps);
BOOST_REQUIRE_CLOSE(y.derivative(3), 5*cos(cx)-3*sin(cx), eps);
BOOST_REQUIRE_CLOSE(y.derivative(4), 13*sin(cx)-20*cos(cx), eps);
BOOST_REQUIRE_CLOSE(y.derivative(5), 101*cos(cx)-65*sin(cx), eps);
// Test at x = 0
auto y2 = sinc(make_fvar<T,10>(0));
BOOST_REQUIRE_CLOSE(y2.derivative(0), 1, eps);
BOOST_REQUIRE_CLOSE(y2.derivative(1), 0, eps);
BOOST_REQUIRE_CLOSE(y2.derivative(2), -cx/3, eps);
BOOST_REQUIRE_CLOSE(y2.derivative(3), 0, eps);
BOOST_REQUIRE_CLOSE(y2.derivative(4), cx/5, eps);
BOOST_REQUIRE_CLOSE(y2.derivative(5), 0, eps);
BOOST_REQUIRE_CLOSE(y2.derivative(6), -cx/7, eps);
BOOST_REQUIRE_CLOSE(y2.derivative(7), 0, eps);
BOOST_REQUIRE_CLOSE(y2.derivative(8), cx/9, eps);
BOOST_REQUIRE_CLOSE(y2.derivative(9), 0, eps);
BOOST_REQUIRE_CLOSE(y2.derivative(10), -cx/11, eps);
}
};
BOOST_AUTO_TEST_CASE(sinc_test)
{
boost::fusion::for_each(bin_float_types, sinc_test_test());
}
struct sinh_and_cosh_test
{
template<typename T>
void operator()(const T&) const
{
const T eps = 300*std::numeric_limits<T>::epsilon(); // percent
using std::sinh;
constexpr int m = 5;
const T cx = 1;
auto x = make_fvar<T,m>(cx);
auto s = sinh(x);
auto c = cosh(x);
BOOST_REQUIRE(s.derivative(0) == sinh(static_cast<T>(x)));
BOOST_REQUIRE(c.derivative(0) == cosh(static_cast<T>(x)));
for (size_t i=0 ; i<=m ; ++i)
{
BOOST_REQUIRE_CLOSE(s.derivative(i), static_cast<T>(i&1?c:s), eps);
BOOST_REQUIRE_CLOSE(c.derivative(i), static_cast<T>(i&1?s:c), eps);
}
}
};
BOOST_AUTO_TEST_CASE(sinh_and_cosh)
{
boost::fusion::for_each(bin_float_types, sinh_and_cosh_test());
}
struct tan_test_test
{
template<typename T>
void operator()(const T&) const
{
const T eps = 800*std::numeric_limits<T>::epsilon(); // percent
using std::sqrt;
constexpr int m = 5;
const T cx = boost::math::constants::third_pi<T>();
const T root_three = boost::math::constants::root_three<T>();
const auto x = make_fvar<T,m>(cx);
auto y = tan(x);
BOOST_REQUIRE_CLOSE(y.derivative(0), root_three, eps);
BOOST_REQUIRE_CLOSE(y.derivative(1), 4.0, eps);
BOOST_REQUIRE_CLOSE(y.derivative(2), 8*root_three, eps);
BOOST_REQUIRE_CLOSE(y.derivative(3), 80.0, eps);
BOOST_REQUIRE_CLOSE(y.derivative(4), 352*root_three, eps);
BOOST_REQUIRE_CLOSE(y.derivative(5), 5824.0, eps);
}
};
BOOST_AUTO_TEST_CASE(tan_test)
{
boost::fusion::for_each(bin_float_types, tan_test_test());
}
struct fmod_test_test
{
template<typename T>
@@ -1421,7 +1609,7 @@ struct fmod_test_test
constexpr float cx = 3.25;
const T cy = 0.5;
auto x = make_fvar<T,m>(cx);
auto y = fmod(x,cy);
auto y = fmod(x,autodiff_fvar<T,m>(cy));
BOOST_REQUIRE(y.derivative(0) == 0.25);
BOOST_REQUIRE(y.derivative(1) == 1.0);
BOOST_REQUIRE(y.derivative(2) == 0.0);
@@ -1486,6 +1674,49 @@ BOOST_AUTO_TEST_CASE(iround_and_itrunc)
boost::fusion::for_each(multiprecision_float_types, iround_and_itrunc_test());
}
struct lambert_w0_test_test
{
template<typename T>
void operator()(const T&) const
{
const T eps = 1000*std::numeric_limits<T>::epsilon(); // percent
constexpr int m = 10;
const T cx = 3;
// Mathematica: N[Table[D[ProductLog[x], {x, n}], {n, 0, 10}] /. x -> 3, 52]
const char* const answers[m+1] {
"1.049908894964039959988697070552897904589466943706341",
"0.1707244807388472968312949774415522047470762509741737",
"-0.04336545501146252734105411312976167858858970875797718",
"0.02321456264324789334313200360870492961288748451791104",
"-0.01909049778427783072663170526188353869136655225133878",
"0.02122935002563637629500975949987796094687564718834156",
"-0.02979093848448877259041971538394953658978044986784643",
"0.05051290266216717699803334605370337985567016837482099",
"-0.1004503154972645060971099914384090562800544486549660",
"0.2292464437392250211967939182075930820454464472006425",
"-0.5905839053125614593682763387470654123192290838719517"};
auto x = make_fvar<T,m>(cx);
auto y = lambert_w0(x);
for (int i=0 ; i<=m ; ++i)
{
const T answer = boost::lexical_cast<T>(answers[i]);
BOOST_REQUIRE_CLOSE(y.derivative(i), answer, eps);
}
//const T cx0 = -1 / boost::math::constants::e<T>();
//auto edge = lambert_w0(make_fvar<T,m>(cx0));
//std::cout << "edge = " << edge << std::endl;
//edge = depth(1)(-1,inf,-inf,inf,-inf,inf,-inf,inf,-inf,inf,-inf)
//edge = depth(1)(-1,inf,-inf,inf,-inf,inf,-inf,inf,-inf,inf,-inf)
//edge = depth(1)(-1,3.68935e+19,-9.23687e+57,4.62519e+96,-2.89497e+135,2.02945e+174,-1.52431e+213,1.19943e+252,-9.75959e+290,8.14489e+329,-6.93329e+368)
}
};
BOOST_AUTO_TEST_CASE(lambert_w0_test)
{
boost::fusion::for_each(bin_float_types, lambert_w0_test_test());
boost::fusion::for_each(multiprecision_float_types, lambert_w0_test_test());
}
struct lround_llround_truncl_test
{
template<typename T>
@@ -1493,9 +1724,9 @@ struct lround_llround_truncl_test
{
using std::lround;
using std::llround;
//using std::truncl; // truncl not supported by cpp_dec_float<>.
//using std::truncl; // truncl not supported by boost::multiprecision types.
constexpr int m = 3;
constexpr float cx = 3.25;
const T cx = 3.25;
auto x = make_fvar<T,m>(cx);
long yl = lround(x);
BOOST_REQUIRE(yl == lround(cx));
@@ -1551,29 +1782,30 @@ struct multiprecision_test
template<typename T>
void operator()(const T&) const
{
constexpr double tolerance = 100e-98; // percent
using cpp_dec_float_100 = boost::multiprecision::cpp_dec_float_100;
// Calculated from Mathematica symbolic differentiation. See example/multiprecision.nb for script.
const cpp_dec_float_100 answer("1976.31960074779771777988187529041872090812118921875499076582535951111845769110560421820940516423255314");
const T eps = 600*std::numeric_limits<T>::epsilon(); // percent
constexpr int Nw=3;
constexpr int Nx=2;
constexpr int Ny=4;
constexpr int Nz=3;
const auto w = make_fvar<cpp_dec_float_100,Nw>(11);
const auto x = make_fvar<cpp_dec_float_100,0,Nx>(12);
const auto y = make_fvar<cpp_dec_float_100,0,0,Ny>(13);
const auto z = make_fvar<cpp_dec_float_100,0,0,0,Nz>(14);
const auto v = mixed_partials_f(w,x,y,z); // auto = autodiff_fvar<cpp_dec_float_100,Nw,Nx,Ny,Nz>
// BOOST_REQUIRE_CLOSE(v.derivative(Nw,Nx,Ny,Nz), answer, tolerance); Doesn't compile on travis-ci trusty.
const auto w = make_fvar<T,Nw>(11);
const auto x = make_fvar<T,0,Nx>(12);
const auto y = make_fvar<T,0,0,Ny>(13);
const auto z = make_fvar<T,0,0,0,Nz>(14);
const auto v = mixed_partials_f(w,x,y,z); // auto = autodiff_fvar<T,Nw,Nx,Ny,Nz>
// Calculated from Mathematica symbolic differentiation.
const T answer = boost::lexical_cast<T>("1976.3196007477977177798818752904187209081211892187"
"5499076582535951111845769110560421820940516423255314");
// BOOST_REQUIRE_CLOSE(v.derivative(Nw,Nx,Ny,Nz), answer, eps); // Doesn't work for cpp_dec_float
using std::fabs;
const cpp_dec_float_100 relative_error = fabs(v.derivative(Nw,Nx,Ny,Nz)/answer-1);
BOOST_REQUIRE(100*relative_error.convert_to<T>() < tolerance);
const double relative_error = static_cast<double>(fabs(v.derivative(Nw,Nx,Ny,Nz)/answer-1));
BOOST_REQUIRE(100*relative_error < eps);
}
};
BOOST_AUTO_TEST_CASE(multiprecision)
{
multiprecision_test()(boost::multiprecision::cpp_dec_float_100());
//multiprecision_test()(boost::multiprecision::cpp_bin_float_50());
boost::fusion::for_each(bin_float_types, mixed_partials_test());
}
struct black_scholes_test
@@ -1656,4 +1888,78 @@ BOOST_AUTO_TEST_CASE(black_scholes)
boost::fusion::for_each(bin_float_types, black_scholes_test());
}
/*
// Compilation tests for boost special functions.
struct boost_special_functions_test
{
template<typename T>
void operator()(const T&) const
{
using namespace boost;
constexpr int m = 3;
BOOST_REQUIRE(math::acosh(make_fvar<T,m>(1.5)) == math::acosh(static_cast<T>(1.5)));
// Policy parameter prevents proper ADL for autodiff_fvar objects. E.g. iround(v,pol) instead of iround(v).
// In cyl_bessel_j_imp() call is made to iround(v, pol) with v of type autodiff_fvar. It it were just iround(v)
// then autodiff's iround would properly be called via ADL.
//BOOST_REQUIRE(math::airy_ai(make_fvar<T,m>(1)) == math::airy_ai(static_cast<T>(1)));
//BOOST_REQUIRE(math::airy_bi(make_fvar<T,m>(1)) == math::airy_bi(static_cast<T>(1)));
//BOOST_REQUIRE(math::airy_ai_prime(make_fvar<T,m>(1)) == math::airy_ai_prime(static_cast<T>(1)));
//BOOST_REQUIRE(math::airy_bi_prime(make_fvar<T,m>(1)) == math::airy_bi_prime(static_cast<T>(1)));
BOOST_REQUIRE(math::asinh(make_fvar<T,m>(0.5)) == math::asinh(static_cast<T>(0.5)));
BOOST_REQUIRE(math::atanh(make_fvar<T,m>(0.5)) == math::atanh(static_cast<T>(0.5)));
// Policy parameter prevents ADL.
//BOOST_REQUIRE(math::cyl_bessel_j(0,make_fvar<T,m>(0.5)) == math::cyl_bessel_j(0,static_cast<T>(0.5)));
//BOOST_REQUIRE(math::cyl_neumann(0,make_fvar<T,m>(0.5)) == math::cyl_neumann(0,static_cast<T>(0.5)));
//BOOST_REQUIRE(math::cyl_bessel_j_zero(make_fvar<T,m>(0.5),0) == math::cyl_bessel_j_zero(static_cast<T>(0.5),0));
//BOOST_REQUIRE(math::cyl_neumann_zero(make_fvar<T,m>(0.5),0) == math::cyl_neumann_zero(static_cast<T>(0.5),0));
// Required sinh() (added) but then has policy parameter ADL issue.
//BOOST_REQUIRE(math::cyl_bessel_i(0,make_fvar<T,m>(0.5)) == math::cyl_bessel_i(0,static_cast<T>(0.5)));
BOOST_REQUIRE(math::cyl_bessel_k(0,make_fvar<T,m>(0.5)) == math::cyl_bessel_k(0,static_cast<T>(0.5)));
// Policy parameter prevents ADL.
//BOOST_REQUIRE(math::sph_bessel(0,make_fvar<T,m>(0.5)) == math::sph_bessel(0,static_cast<T>(0.5)));
// Required fmod() but then has policy parameter ADL issue.
//BOOST_REQUIRE(math::sph_neumann(0,make_fvar<T,m>(0.5)) == math::sph_neumann(0,static_cast<T>(0.5)));
// Policy parameter prevents ADL.
//BOOST_REQUIRE(math::cyl_bessel_j_prime(0,make_fvar<T,m>(0.5)) == math::cyl_bessel_j_prime(0,static_cast<T>(0.5)));
//BOOST_REQUIRE(math::cyl_neumann_prime(0,make_fvar<T,m>(0.5)) == math::cyl_neumann_prime(0,static_cast<T>(0.5)));
//BOOST_REQUIRE(math::cyl_bessel_i_prime(0,make_fvar<T,m>(0.5)) == math::cyl_bessel_i_prime(0,static_cast<T>(0.5)));
BOOST_REQUIRE(math::cyl_bessel_k_prime(0,make_fvar<T,m>(0.5)) == math::cyl_bessel_k_prime(0,static_cast<T>(0.5)));
// Policy parameter prevents ADL.
//BOOST_REQUIRE(math::sph_bessel_prime(0,make_fvar<T,m>(0.5)) == math::sph_bessel_prime(0,static_cast<T>(0.5)));
//BOOST_REQUIRE(math::sph_neumann_prime(0,make_fvar<T,m>(0.5)) == math::sph_neumann_prime(0,static_cast<T>(0.5)));
// Per docs: "the functions can only be instantiated on types float, double and long double."
//BOOST_REQUIRE(math::cyl_hankel_1(0,make_fvar<T,m>(0.5)).real() == math::cyl_hankel_1(0,static_cast<T>(0.5)).real());
//BOOST_REQUIRE(math::cyl_hankel_2(0,make_fvar<T,m>(0.5)).real() == math::cyl_hankel_2(0,static_cast<T>(0.5)).real());
//BOOST_REQUIRE(math::sph_hankel_1(0,make_fvar<T,m>(0.5)).real() == math::sph_hankel_1(0,static_cast<T>(0.5)).real());
//BOOST_REQUIRE(math::sph_hankel_2(0,make_fvar<T,m>(0.5)).real() == math::sph_hankel_2(0,static_cast<T>(0.5)).real());
// Compiles, but compares 0.74868571757768376251 == 0.74868571757768354047 which is false.
// BOOST_REQUIRE(static_cast<T>(math::beta(make_fvar<T,m>(1.1),make_fvar<T,m>(1.2))) == static_cast<T>(math::beta(static_cast<T>(1.1),static_cast<T>(1.2))));
// Skipped other beta functions.
std::cout.precision(20);
// Compiles, but compares 0.7937005259840996807 == 0.79370052598409979172 which is false.
//BOOST_REQUIRE(math::cbrt(make_fvar<T,m>(0.5)) == math::cbrt(static_cast<T>(0.5)));
//Skipping other Basic Functions
BOOST_REQUIRE(math::chebyshev_next(make_fvar<T,m>(0.5),make_fvar<T,m>(0.5),make_fvar<T,m>(0.5)) ==
math::chebyshev_next(static_cast<T>(0.5),static_cast<T>(0.5),static_cast<T>(0.5)));
// Requires acosh() (added)
BOOST_REQUIRE(math::chebyshev_t(0,make_fvar<T,m>(0.5)) == math::chebyshev_t(0,static_cast<T>(0.5)));
BOOST_REQUIRE(math::chebyshev_u(0,make_fvar<T,m>(0.5)) == math::chebyshev_u(0,static_cast<T>(0.5)));
BOOST_REQUIRE(math::chebyshev_t_prime(0,make_fvar<T,m>(0.5)) == math::chebyshev_t_prime(0,static_cast<T>(0.5)));
{
std::array<double,4> c{14.2, -13.7, 82.3, 96};
// /usr/include/boost/math/special_functions/chebyshev.hpp:164:40: error: cannot convert boost::math::differentiation::autodiff_v1::detail::fvar<double, 3> to double in return
//BOOST_REQUIRE(math::chebyshev_clenshaw_recurrence(c.data(),c.size(),make_fvar<T,m>(0.5)) == math::chebyshev_clenshaw_recurrence(c.data(),c.size(),static_cast<T>(0.5)));
}
// TODO Continue alphabetically through <boost/math/special_functions.hpp>
}
};
BOOST_AUTO_TEST_CASE(boost_special_functions)
{
boost_special_functions_test()(static_cast<double>(0));
//boost::fusion::for_each(bin_float_types, boost_special_functions_test());
//boost::fusion::for_each(multiprecision_float_types, boost_special_functions_test());
}
*/
BOOST_AUTO_TEST_SUITE_END()