mirror of
https://github.com/boostorg/math.git
synced 2026-01-30 20:12:09 +00:00
768 lines
32 KiB
Plaintext
768 lines
32 KiB
Plaintext
[section:implementation Additional Implementation Notes]
|
|
|
|
The majority of the implementation notes are included with the documentation
|
|
of each function or distribution. The notes here are of a more general nature,
|
|
and reflect more the general implementation philosophy used.
|
|
|
|
[h4 Implemention philosophy]
|
|
|
|
"First be right, then be fast."
|
|
|
|
There will always be potential compromises
|
|
to be made between speed and accuracy.
|
|
It may be possible to find faster methods,
|
|
particularly for certain limited ranges of arguments,
|
|
but for most applications of math functions and distributions,
|
|
we judge that speed is rarely as important as accuracy.
|
|
|
|
So our priority is accuracy.
|
|
|
|
To permit evaluation of accuracy of the special functions,
|
|
production of extremely accurate tables of test values
|
|
has received considerable effort.
|
|
|
|
(It also required much CPU effort -
|
|
there was some danger of molten plastic dripping from the bottom of JM's laptop,
|
|
so instead, PAB's Dual-core desktop was kept 50% busy for *days*
|
|
calculating some tables of test values!)
|
|
|
|
For a specific RealType, say float or double,
|
|
it may be possible to find approximations for some functions
|
|
that are simpler and thus faster, but less accurate
|
|
(perhaps because there are no refining iterations,
|
|
for example, when calculating inverse functions).
|
|
|
|
If these prove accurate enough to be "fit for his purpose",
|
|
then a user may substitute his custom specialization.
|
|
|
|
For example, there are approximations dating back from times
|
|
when computation was a *lot* more expensive:
|
|
|
|
H Goldberg and H Levine, Approximate formulas for
|
|
percentage points and normalisation of t and chi squared,
|
|
Ann. Math. Stat., 17(4), 216 - 225 (Dec 1946).
|
|
|
|
A H Carter, Approximations to percentage points of the z-distribution,
|
|
Biometrika 34(2), 352 - 358 (Dec 1947).
|
|
|
|
These could still provide sufficient accuracy for some speed-critical applications.
|
|
|
|
[h4 Accuracy and Representation of Test Values]
|
|
|
|
In order to be accurate enough for as many as possible real types,
|
|
constant values are given to 50 decimal digits if available
|
|
(though many sources proved only accurate near to 64-bit double precision).
|
|
Values are specified as long double types by appending L,
|
|
unless they are exactly representable, for example integers, or binary fractions like 0.125.
|
|
This avoids the risk of loss of accuracy converting from double, the default type.
|
|
Values are used after static_cast<RealType>(1.2345L)
|
|
to provide the appropriate RealType for spot tests.
|
|
|
|
Functions that return constants values, like kurtosis for example, are written as
|
|
|
|
`static_cast<RealType>(-3) / 5;`
|
|
|
|
to provide the most accurate value
|
|
that the compiler can compute for the real type.
|
|
(The denominator is an integer and so will be promoted exactly).
|
|
|
|
So tests for one third, *not* exactly representable with radix two floating-point,
|
|
(should) use, for example:
|
|
|
|
`static_cast<RealType>(1) / 3;`
|
|
|
|
If a function is very sensitive to changes in input,
|
|
specifying an inexact value as input (such as 0.1) can throw
|
|
the result off by a noticeable amount: 0.1f is "wrong"
|
|
by ~1e-7 for example (because 0.1 has no exact binary representation).
|
|
That is why exact binary values - halves, quarters, and eighths etc -
|
|
are used in test code along with the occasional fraction `a/b` with `b`
|
|
a power of two (in order to ensure that the result is an exactly
|
|
representable binary value).
|
|
|
|
[h4 Tolerance of Tests]
|
|
|
|
The tolerances need to be set to the maximum of:
|
|
|
|
* Some epsilon value.
|
|
* The accuracy of the data (often only near 64-bit double).
|
|
|
|
Otherwise when long double has more digits than the test data, then no
|
|
amount of tweaking an epsilon based tolerance will work.
|
|
|
|
A common problem is when tolerances that are suitable for implementations
|
|
like Microsoft VS.NET where double and long double are the same size:
|
|
tests fail on other systems where long double is more accurate than double.
|
|
Check first that the suffix L is present, and then that the tolerance is big enough.
|
|
|
|
[h4 Handling Unsuitable Arguments]
|
|
|
|
In
|
|
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1665.pdf Errors in Mathematical Special Functions], J. Marraffino & M. Paterno
|
|
it is proposed that signalling a domain error is mandatory
|
|
when the argument would give an mathematically undefined result.
|
|
|
|
*Guideline 1
|
|
|
|
[:A mathematical function is said to be defined at a point a = (a1, a2, . . .)
|
|
if the limits as x = (x1, x2, . . .) 'approaches a from all directions agree'.
|
|
The defined value may be any number, or +infinity, or -infinity.]
|
|
|
|
Put crudely, if the function goes to + infinity
|
|
and then emerges 'round-the-back' with - infinity,
|
|
it is NOT defined.
|
|
|
|
[:The library function which approximates a mathematical function shall signal a domain error
|
|
whenever evaluated with argument values for which the mathematical function is undefined.]
|
|
|
|
*Guideline 2
|
|
|
|
[:The library function which approximates a mathematical function
|
|
shall signal a domain error whenever evaluated with argument values
|
|
for which the mathematical function obtains a non-real value.]
|
|
|
|
This implementation is believed to follow these proposals and to assist compatibility with
|
|
['ISO/IEC 9899:1999 Programming languages - C]
|
|
and with the
|
|
[@www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf Draft Technical Report on C++ Library Extensions, 2005-06-24, section 5.2.1, paragraph 5].
|
|
[link math_toolkit.main_overview.error_handling See also domain_error].
|
|
|
|
See __policy_ref for details of the error handling policies that should allow
|
|
a user to comply with any of these recommendations, as well as other behaviour.
|
|
|
|
See [link math_toolkit.main_overview.error_handling error handling]
|
|
for a detailed explanation of the mechanism, and
|
|
[link math_toolkit.dist.stat_tut.weg.error_eg error_handling example]
|
|
and
|
|
[@/../../example/error_handling_example.cpp error_handling_example.cpp]
|
|
|
|
[caution If you enable throw but do NOT have try & catch block,
|
|
then the program will terminate with an uncaught exception and probably abort.
|
|
Therefore to get the benefit of helpful error messages, enabling *all* exceptions
|
|
*and* using try&catch is recommended for all applications.
|
|
However, for simplicity, this is not done for most examples.]
|
|
|
|
[h4 Handling of Functions that are Not Mathematically defined]
|
|
|
|
Functions that are not mathematically defined,
|
|
like the Cauchy mean, fail to compile by default.
|
|
[link math_toolkit.policy.pol_ref.assert_undefined A policy]
|
|
allows control of this.
|
|
|
|
If the policy is to permit undefined functions, then calling them
|
|
throws a domain error, by default. But the error policy can be set
|
|
to not throw, and to return NaN instead. For example,
|
|
|
|
`#define BOOST_MATH_DOMAIN_ERROR_POLICY ignore_error`
|
|
|
|
appears before the first Boost include,
|
|
then if the un-implemented function is called,
|
|
mean(cauchy<>()) will return std::numeric_limits<T>::quiet_NaN().
|
|
|
|
[warning If `std::numeric_limits<T>::has_quiet_NaN` is false
|
|
(for example T is a User-defined type),
|
|
then an exception will always be thrown when a domain error occurs.
|
|
Catching exceptions is therefore strongly recommended.]
|
|
|
|
[h4 Median of distributions]
|
|
|
|
There are many distributions for which we have been unable to find an analytic formula,
|
|
and this has deterred us from implementing
|
|
[@http://en.wikipedia.org/wiki/Median median functions], the mid-point in a list of values.
|
|
|
|
However a useful median approximation for distribution `dist` may be available from
|
|
|
|
`quantile(dist, 0.5)`.
|
|
|
|
[@http://www.amstat.org/publications/jse/v13n2/vonhippel.html Mean, Median, and Skew, Paul T von Hippel]
|
|
|
|
[@http://documents.wolfram.co.jp/teachersedition/MathematicaBook/24.5.html Descriptive Statistics,]
|
|
|
|
[@http://documents.wolfram.co.jp/v5/Add-onsLinks/StandardPackages/Statistics/DescriptiveStatistics.html and ]
|
|
|
|
[@http://documents.wolfram.com/v5/TheMathematicaBook/AdvancedMathematicsInMathematica/NumericalOperationsOnData/3.8.1.html
|
|
Mathematica Basic Statistics.] give more detail, in particular for discrete distributions.
|
|
|
|
|
|
[h4 Handling of Floating-Point Infinity]
|
|
|
|
Some functions and distributions are well defined with + or - infinity as
|
|
argument(s), but after some experiments with handling infinite arguments
|
|
as special cases, we concluded that it was generally more useful to forbid this,
|
|
and instead to return the result of __domain_error.
|
|
|
|
Handling infinity as special cases is additionally complicated
|
|
because, unlike built-in types on most - but not all - platforms,
|
|
not all User-Defined Types are
|
|
specialized to provide `std::numeric_limits<RealType>::infinity()`
|
|
and would return zero rather than any representation of infinity.
|
|
|
|
The rationale is that non-finiteness may happen because of error
|
|
or overflow in the users code, and it will be more helpful for this
|
|
to be diagnosed promptly rather than just continuing.
|
|
The code also became much more complicated, more error-prone,
|
|
much more work to test, and much less readable.
|
|
|
|
However in a few cases, for example normal, where we felt it obvious,
|
|
we have permitted argument(s) to be infinity,
|
|
provided infinity is implemented for the realType on that implementation.
|
|
|
|
Overflow, underflow, denorm can be handled using __error_policy.
|
|
|
|
We have also tried to catch boundary cases where the mathematical specification
|
|
would result in divide by zero or overflow and signalling these similarly.
|
|
What happens at (and near), poles can be controlled through __error_policy.
|
|
|
|
[h4 Scale, Shape and Location]
|
|
|
|
We considered adding location and scale to the list of functions, for example:
|
|
|
|
template <class RealType>
|
|
inline RealType scale(const triangular_distribution<RealType>& dist)
|
|
{
|
|
RealType lower = dist.lower();
|
|
RealType mode = dist.mode();
|
|
RealType upper = dist.upper();
|
|
RealType result; // of checks.
|
|
if(false == detail::check_triangular(BOOST_CURRENT_FUNCTION, lower, mode, upper, &result))
|
|
{
|
|
return result;
|
|
}
|
|
return (upper - lower);
|
|
}
|
|
|
|
but found that these concepts are not defined (or their definition too contentious)
|
|
for too many distributions to be generally applicable.
|
|
Because they are non-member functions, they can be added if required.
|
|
|
|
[h4 Notes on Implementation of Specific Functions & Distributions]
|
|
|
|
* Default parameters for the Triangular Distribution.
|
|
We are uncertain about the best default parameters.
|
|
Some sources suggest that the Standard Triangular Distribution has
|
|
lower = 0, mode = half and upper = 1.
|
|
However as a approximation for the normal distribution,
|
|
the most common usage, lower = -1, mode = 0 and upper = 1 would be more suitable.
|
|
|
|
[h4 Rational Approximations Used]
|
|
|
|
Some of the special functions in this library are implemented via
|
|
rational approximations. These are either taken from the literature,
|
|
or devised by John Maddock using
|
|
[link math_toolkit.toolkit.internals2.minimax our Remez code].
|
|
|
|
Rational rather than Polynomial approximations are used to ensure
|
|
accuracy: polynomial approximations are often wonderful up to
|
|
a certain level of accuracy, but then quite often fail to provide much greater
|
|
accuracy no matter how many more terms are added.
|
|
|
|
Our own approximations were devised either for added accuracy
|
|
(to support 128-bit long doubles for example), or because
|
|
literature methods were unavailable or under non-BSL
|
|
compatible license. Our Remez code is known to produce good
|
|
agreement with literature results in fairly simple "toy" cases.
|
|
All approximations were checked
|
|
for convergence and to ensure that
|
|
they were not ill-conditioned (the coefficients can give a
|
|
theoretically good solution, but the resulting rational function
|
|
may be un-computable at fixed precision).
|
|
|
|
Recomputing using different
|
|
Remez implementations may well produce differing coefficients: the
|
|
problem is well known to be ill conditioned in general, and our Remez implementation
|
|
often found a broad and ill-defined minima for many of these approximations
|
|
(of course for simple "toy" examples like approximating `exp` the minima
|
|
is well defined, and the coeffiecents should agree no matter whose Remez
|
|
implementation is used). This should not in general effect the validity
|
|
of the approximations: there's good literature supporting the idea that
|
|
coefficients can be "in error" without necessarily adversely effecting
|
|
the result. Note that "in error" has a special meaning in this context,
|
|
see [@http://front.math.ucdavis.edu/0101.5042
|
|
"Approximate construction of rational approximations and the effect
|
|
of error autocorrection.", Grigori Litvinov, eprint arXiv:math/0101042].
|
|
Therefore the coefficients still need to be accurately calculated, even if they can
|
|
be in error compared to the "true" minimax solution.
|
|
|
|
[h4 Representation of Mathematical Constants]
|
|
|
|
A macro BOOST_DEFINE_MATH_CONSTANT in constants.hpp is used
|
|
to provide high accuracy constants to mathematical functions and distributions,
|
|
since it is important to provide values uniformly for both built-in
|
|
float, double and long double types,
|
|
and for User Defined types like NTL::quad_float and NTL::RR.
|
|
|
|
To permit calculations in this Math ToolKit and its tests, (and elsewhere)
|
|
at about 100 decimal digits with NTL::RR type,
|
|
it is obviously necessary to define constants to this accuracy.
|
|
|
|
However, some compilers do not accept decimal digits strings as long as this.
|
|
So the constant is split into two parts, with the 1st containing at least
|
|
long double precision, and the 2nd zero if not needed or known.
|
|
The 3rd part permits an exponent to be provided if necessary (use zero if none) -
|
|
the other two parameters may only contain decimal digits (and sign and decimal point),
|
|
and may NOT include an exponent like 1.234E99 (nor a trailing F or L).
|
|
The second digit string is only used if T is a User-Defined Type,
|
|
when the constant is converted to a long string literal and lexical_casted to type T.
|
|
(This is necessary because you can't use a numeric constant
|
|
since even a long double might not have enough digits).
|
|
|
|
For example, pi is defined:
|
|
|
|
BOOST_DEFINE_MATH_CONSTANT(pi,
|
|
3.141592653589793238462643383279502884197169399375105820974944,
|
|
5923078164062862089986280348253421170679821480865132823066470938446095505,
|
|
0)
|
|
|
|
And used thus:
|
|
|
|
using namespace boost::math::constants;
|
|
|
|
double diameter = 1.;
|
|
double radius = diameter * pi<double>();
|
|
|
|
or boost::math::constants::pi<NTL::RR>()
|
|
|
|
Note that it is necessary (if inconvenient) to specify the type explicitly.
|
|
|
|
So you cannot write
|
|
|
|
double p = boost::math::constants::pi<>(); // could not deduce template argument for 'T'
|
|
|
|
Neither can you write:
|
|
|
|
double p = boost::math::constants::pi; // Context does not allow for disambiguation of overloaded function
|
|
double p = boost::math::constants::pi(); // Context does not allow for disambiguation of overloaded function
|
|
|
|
[h4 Thread safety]
|
|
|
|
Reporting of error by setting errno should be thread safe already
|
|
(otherwise none of the std lib math functions would be thread safe?).
|
|
If you turn on reporting of errors via exceptions, errno gets left unused anyway.
|
|
|
|
Other than that, the code is intended to be thread safe *for built in
|
|
real-number types* : so float, double and long double are all thread safe.
|
|
|
|
For non-built-in types - NTL::RR for example - initialisation of the various
|
|
constants used in the implementation is potentially *not* thread safe.
|
|
This most undesiable, but it would be a signficant challenge to fix it.
|
|
Some compilers may offer the option of having
|
|
static-constants initialised in a thread safe manner (Commeau, and maybe
|
|
others?), if that's the case then the problem is solved. This is a topic of
|
|
hot debate for the next C++ std revision, so hopefully all compilers
|
|
will be required to do the right thing here at some point.
|
|
|
|
[h4 Sources of Test Data]
|
|
|
|
We found a large number of sources of test data.
|
|
We have assumed that these are /"known good"/
|
|
if they agree with the results from our test
|
|
and only consulted other sources for their /'vote'/
|
|
in the case of serious disagreement.
|
|
The accuracy, actual and claimed, vary very widely.
|
|
Only [@http://functions.wolfram.com/ Wolfram Mathematica functions]
|
|
provided a higher accuracy than
|
|
C++ double (64-bit floating-point) and was regarded as
|
|
the most-trusted source by far.
|
|
|
|
A useful index of sources is:
|
|
[@http://www.sal.hut.fi/Teaching/Resources/ProbStat/table.html
|
|
Web-oriented Teaching Resources in Probability and Statistics]
|
|
|
|
[@http://espse.ed.psu.edu/edpsych/faculty/rhale/hale/507Mat/statlets/free/pdist.htm Statlet]:
|
|
Is a Javascript application that calculates and plots probability distributions,
|
|
and provides the most complete range of distributions:
|
|
|
|
[:Bernoulli, Binomial, discrete uniform, geometric, hypergeometric,
|
|
negative binomial, Poisson, beta, Cauchy-Lorentz, chi-sequared, Erlang,
|
|
exponential, extreme value, Fisher, gamma, Laplace, logistic,
|
|
lognormal, normal, Parteo, Student's t, triangular, uniform, and Weibull.]
|
|
|
|
It calculates pdf, cdf, survivor, log survivor, hazard, tail areas,
|
|
& critical values for 5 tail values.
|
|
|
|
It is also the only independent source found for the Weibull distribution;
|
|
unfortunately it appears to suffer from very poor accuracy in areas where
|
|
the underlying special function is known to be difficult to implement.
|
|
|
|
[h4 Creating and Managing the Equations]
|
|
|
|
The primary source for the equations is now
|
|
[@http://www.w3.org/Math/ MathML]: see the
|
|
*.mml files in libs\/math\/doc\/equations\/.
|
|
|
|
These are most easily edited by a GUI editor such as
|
|
[@http://mathcast.sourceforge.net/home.html Mathcast],
|
|
please note that the equation editor supplied with Open Office
|
|
currently mangles these files and should not currently be used.
|
|
|
|
Convertion to SVG was achieved using
|
|
[@http://www.grigoriev.ru/svgmath/ SVGMath] and a command line
|
|
such as:
|
|
|
|
[pre
|
|
$for file in *.mml; do
|
|
>/cygdrive/c/Python25/python.exe 'C:\download\open\SVGMath-0.3.1\math2svg.py' \\
|
|
>>$file > $(basename $file .mml).svg
|
|
>done
|
|
]
|
|
|
|
Note that SVGMath requires that the mml files are *not* wrapped in an XHTML
|
|
XML wrapper - this is added by Mathcast by default - one workaround is to
|
|
copy an existing mml file and then edit it with Mathcast: the existing
|
|
format should then be preserved. This is a bug in the XML parser used by
|
|
SVGMath which the author is aware of.
|
|
|
|
If neccessary the XHTML wrapper can be removed with:
|
|
|
|
[pre cat filename | tr -d "\\r\\n" \| sed -e 's\/.*\\(<math\[^>\]\*>.\*<\/math>\\).\*\/\\1\/' > newfile]
|
|
|
|
Setting up fonts for SVGMath is currently rather tricky, on a windows system
|
|
JM's font setup looks like this:
|
|
|
|
[pre
|
|
<!-- MathML-to-SVG configuration file -->
|
|
<config verbose="true">
|
|
<!-- Fallback font family -->
|
|
<fallback family="Lucida Sans Unicode"\/>
|
|
|
|
<!-- Default values for MathML properties. -->
|
|
<!-- Most of these are defined in the MathML Rec - change with care -->
|
|
<defaults displaystyle="false"
|
|
mathsize="12pt"
|
|
scriptminsize="8pt"
|
|
scriptsizemultiplier="0.71"
|
|
veryverythinmathspace="0.0555556em"
|
|
verythinmathspace="0.111111em"
|
|
thinmathspace="0.166667em"
|
|
mediummathspace="0.222222em"
|
|
thickmathspace="0.277778em"
|
|
verythickmathspace="0.333333em"
|
|
veryverythickmathspace="0.388889em"
|
|
rowspacing="1.0ex"
|
|
columnspacing="0.8em"
|
|
framespacing="0.4em 0.5ex"\/>
|
|
|
|
<!-- Additional styling for individual operators -->
|
|
<!-- Make differentials italic -->
|
|
<operator-style operator="ⅅ" fontstyle="italic"\/>
|
|
<operator-style operator="ⅆ" fontstyle="italic"\/>
|
|
|
|
<!-- Font families -->
|
|
<family name="Times New Roman">
|
|
<font ttf="C:\WINDOWS\Fonts\times.ttf"\/>
|
|
<font weight="bold" ttf="C:\WINDOWS\Fonts\timesbd.ttf"\/>
|
|
<font style="italic" ttf="C:\WINDOWS\Fonts\timesi.ttf"\/>
|
|
<font weight="bold" style="italic" ttf="C:\WINDOWS\Fonts\timesbi.ttf"\/>
|
|
<\/family>
|
|
|
|
<family name="Arial">
|
|
<font ttf="C:\WINDOWS\Fonts\arial.ttf"\/>
|
|
<font weight="bold" ttf="C:\WINDOWS\Fonts\arialbd.ttf"\/>
|
|
<font style="italic" ttf="C:\WINDOWS\Fonts\ariali.ttf"\/>
|
|
<font weight="bold" style="italic" ttf="C:\WINDOWS\Fonts\arialbi.ttf"\/>
|
|
<\/family>
|
|
|
|
<family name="Courier New">
|
|
<font ttf="C:\WINDOWS\Fonts\cour.ttf"\/>
|
|
<font weight="bold" ttf="C:\WINDOWS\Fonts\courbd.ttf"\/>
|
|
<font style="italic" ttf="C:\WINDOWS\Fonts\couri.ttf"\/>
|
|
<font weight="bold" style="italic" ttf="C:\WINDOWS\Fonts\courbi.ttf"\/>
|
|
<\/family>
|
|
|
|
<family name="Euclid Fraktur">
|
|
<font ttf="C:\WINDOWS\Fonts\eufrak.ttf"\/>
|
|
<font weight="bold" ttf="C:\WINDOWS\Fonts\eufrakb.ttf"\/>
|
|
<\/family>
|
|
|
|
<family name="Monotype Corsiva">
|
|
<font ttf="C:\WINDOWS\Fonts\mtcorsva.ttf"\/>
|
|
<\/family>
|
|
|
|
<family name="Lucida Sans Unicode">
|
|
<font ttf="C:\WINDOWS\Fonts\lsansuni.ttf"\/>
|
|
<\/family>
|
|
|
|
<!-- Math variant definitions -->
|
|
<!-- Serif -->
|
|
<mathvariant name="normal"
|
|
family="Times New Roman, Lucida Sans Unicode"\/>
|
|
<mathvariant name="bold"
|
|
family="Times New Roman, Lucida Sans Unicode" weight="bold"\/>
|
|
<mathvariant name="italic"
|
|
family="Times New Roman, Lucida Sans Unicode" style="italic"\/>
|
|
<mathvariant name="bold-italic"
|
|
family="Times New Roman, Lucida Sans Unicode" weight="bold" style="italic"\/>
|
|
|
|
<!-- Sans-Serif -->
|
|
<mathvariant name="sans-serif"
|
|
family="Arial, Lucida Sans Unicode"\/>
|
|
<mathvariant name="bold-sans-serif"
|
|
family="Arial, Lucida Sans Unicode" weight="bold"\/>
|
|
<mathvariant name="sans-serif-italic"
|
|
family="Arial, Lucida Sans Unicode" style="italic"\/>
|
|
<mathvariant name="sans-serif-bold-italic"
|
|
family="Arial, Lucida Sans Unicode" weight="bold" style="italic"\/>
|
|
|
|
<!-- Fraktur -->
|
|
<mathvariant name="fraktur"
|
|
family="Euclid Fraktur, Lucida Sans Unicode"\/>
|
|
<mathvariant name="bold-fraktur"
|
|
family="Euclid Fraktur, Lucida Sans Unicode" weight="bold"\/>
|
|
|
|
<!-- Script -->
|
|
<mathvariant name="script"
|
|
family="Monotype Corsiva, Lucida Sans Unicode"\/>
|
|
<mathvariant name="bold-script"
|
|
family="Monotype Corsiva, Lucida Sans Unicode" weight="bold"\/>
|
|
|
|
<!-- Monospace -->
|
|
<mathvariant name="monospace" family="Courier New, Lucida Sans Unicode"\/>
|
|
|
|
<!-- Double-struck -->
|
|
<mathvariant name="double-struck" family="Lucida Sans Unicode"\/>
|
|
<\/config>
|
|
]
|
|
|
|
Note that unlike the sample config file supplied with SVGMath this does not
|
|
make use of the Mathematica 7 font as this lacks sufficient Unicode information
|
|
for it to be used with either SVGMath or XEP "as is".
|
|
|
|
Also note that the SVG files in the repository are almost certainly
|
|
Windows-specific since they reference various Windows Fonts.
|
|
|
|
PNG files can be created from the SVG's using
|
|
[@http://xmlgraphics.apache.org/batik/tools/rasterizer.html Batik]
|
|
and a command such as:
|
|
|
|
[pre java -jar 'C:\download\open\batik-1.7\batik-rasterizer.jar' -dpi 120 *.svg]
|
|
|
|
The PDF is generated using:
|
|
|
|
[pre $bjam -a pdf xsl:param=admon.graphics.extension=".svg" \
|
|
>xsl:param=use.role.for.mediaobject=1 xsl:param=preferred.mediaobject.role=print]
|
|
|
|
Note that XEP will have to be configured to *use and embed*
|
|
whatever fonts are used by the SVG equations. JM's XEP
|
|
config file looks like:
|
|
|
|
[pre
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<config>
|
|
|
|
<!-- ======================================================= -->
|
|
<!-- Formatter options -->
|
|
<!-- ======================================================= -->
|
|
<options>
|
|
<option name="LICENSE" value="license.xml"\/>
|
|
<option name="TMPDIR" value="none"\/>
|
|
<option name="BROKENIMAGE" value="images\/404.gif"\/>
|
|
<option name="LOGO" value="images\/logo-renderx.svg"\/>
|
|
|
|
<!-- Backend options -->
|
|
<generator-options format="PDF">
|
|
<!-- <option name="COMPRESS" value="false"\/> -->
|
|
<!-- <option name="PDF_VERSION" value="1.3"\/> -->
|
|
<\/generator-options>
|
|
|
|
<generator-options format="PostScript">
|
|
<!-- <option name="LANGUAGE_LEVEL" value="2"\/> -->
|
|
<!-- <option name="CLONE_EPS" value="true"\/> -->
|
|
<\/generator-options>
|
|
|
|
<generator-options format="AFP">
|
|
<option name="AFPCodepageTxt" value="Cp500"\/>
|
|
<option name="AFPCodepage" value="T1V10500"\/>
|
|
<option name="AFPLogLevel" value="0"\/>
|
|
<option name="USE_PTOCA_LEVEL" value="3"\/>
|
|
<option name="USE_BCOCA_LEVEL" value="1"\/>
|
|
<option name="USE_GOCA_LEVEL" value="1"\/>
|
|
<option name="RESOLUTION" value="1440"\/>
|
|
<!-- <option name="AFPGrayImage" value="yes"\/> -->
|
|
<option name="USE_SHADING_PATTERNS" value="yes"\/>
|
|
<option name="USE_REPLICATE_AND_TRIM" value="yes"\/>
|
|
<option name="SHADING_PATTERN_RESOLUTION" value="0.25"\/>
|
|
<option name="TRY_USING_TIFF_COMPRESSION" value="yes"\/>
|
|
<option name="AFPFont,Helvetica" value="C0H200.0, C0H300.0, C0H400.0, C0H500.0, C0H201.0, C0H301.0, C0H401.0, C0H501.0, 278"\/>
|
|
<option name="AFPFont,Times" value="C0N200.0, C0N300.0, C0N400.0, C0N500.0, C0N201.0, C0N301.0, C0N401.0, C0N501.0, 250"\/>
|
|
<option name="AFPFont,Courier" value="C04200.0, C04300.0, C04400.0, C04500.0, C04201.0, C04301.0, C04401.0, C04501.0, 600"\/>
|
|
<option name="AFPFont,Arial" value="C0H200.0, C0H300.0, C0H400.0, C0H500.0, C0H201.0, C0H301.0, C0H401.0, C0H501.0, 278"\/>
|
|
<option name="AFPFont,Times New Roman" value="C0N200.0, C0N300.0, C0N400.0, C0N500.0, C0N201.0, C0N301.0, C0N401.0, C0N501.0, 250"\/>
|
|
<option name="AFPFont,Verdana" value="C0VE0.0, C0VEI.0, C0VEB.0, C0VEZ.0, C0H201.0, C0H301.0, C0H401.0, C0H501.0,278"\/>
|
|
<option name="AFPFont,Interstate" value="C0IS0.0, C0ISB.0, C0IS0.0, C0ISB.0, C0H201.0, C0H301.0, C0H401.0, C0H501.0, 278"\/>
|
|
<\/generator-options>
|
|
<\/options>
|
|
|
|
<!-- ======================================================= -->
|
|
<!-- Fonts -->
|
|
<!-- ======================================================= -->
|
|
|
|
<fonts xml:base="fonts\/" default-family="Helvetica">
|
|
|
|
<!-- Base Adobe fonts. -->
|
|
<font-group label="Base 14" embed="false">
|
|
<font-family name="Courier">
|
|
<font><font-data afm="Courier.afm"\/><\/font>
|
|
<font style="oblique"><font-data afm="Courier-Oblique.afm"\/><\/font>
|
|
<font weight="bold"><font-data afm="Courier-Bold.afm"\/><\/font>
|
|
<font weight="bold" style="oblique"><font-data afm="Courier-BoldOblique.afm"\/><\/font>
|
|
<\/font-family>
|
|
|
|
<font-family name="Helvetica">
|
|
<font><font-data afm="Helvetica.afm"\/><\/font>
|
|
<font style="oblique"><font-data afm="Helvetica-Oblique.afm"\/><\/font>
|
|
<font weight="bold"><font-data afm="Helvetica-Bold.afm"\/><\/font>
|
|
<font weight="bold" style="oblique"><font-data afm="Helvetica-BoldOblique.afm"\/><\/font>
|
|
<\/font-family>
|
|
|
|
<font-family name="Times" ligatures="fi fl">
|
|
<font><font-data afm="Times-Roman.afm"\/><\/font>
|
|
<font style="italic"><font-data afm="Times-Italic.afm"\/><\/font>
|
|
<font weight="bold"><font-data afm="Times-Bold.afm"\/><\/font>
|
|
<font weight="bold" style="italic"><font-data afm="Times-BoldItalic.afm"\/><\/font>
|
|
<\/font-family>
|
|
|
|
<font-family name="Symbol">
|
|
<font><font-data afm="Symbol.afm"\/><\/font>
|
|
<\/font-family>
|
|
|
|
<font-family name="ZapfDingbats">
|
|
<font><font-data afm="ZapfDingbats.afm"\/><\/font>
|
|
<\/font-family>
|
|
<\/font-group>
|
|
|
|
<!-- Other Type1 fonts -->
|
|
<font-group label="Assorted Type 1" embed="true">
|
|
<font-family name="OmegaSerifIPA">
|
|
<font><font-data afm="IPA.afm" pfa="IPA.pfa" glyph-list="IPA.glyphs"\/><\/font>
|
|
<\/font-family>
|
|
<font-alias name="OmegaIPA" value="OmegaSerifIPA"\/>
|
|
<font-alias name="Phonetic" value="OmegaSerifIPA"\/>
|
|
<\/font-group>
|
|
|
|
<!-- Sample configuration for Windows TrueType fonts. -->
|
|
|
|
<font-group xml:base="file:\/C:\/Windows\/Fonts\/" label="Windows TrueType" embed="true" subset="true">
|
|
<font-family name="Arial">
|
|
<font><font-data ttf="arial.ttf"\/><\/font>
|
|
<font style="oblique"><font-data ttf="ariali.ttf"\/><\/font>
|
|
<font weight="bold"><font-data ttf="arialbd.ttf"\/><\/font>
|
|
<font weight="bold" style="oblique"><font-data ttf="arialbi.ttf"\/><\/font>
|
|
<\/font-family>
|
|
|
|
<font-family name="Times New Roman" ligatures="fi fl">
|
|
<font><font-data ttf="times.ttf"\/><\/font>
|
|
<font style="italic"><font-data ttf="timesi.ttf"\/><\/font>
|
|
<font weight="bold"><font-data ttf="timesbd.ttf"\/><\/font>
|
|
<font weight="bold" style="italic"><font-data ttf="timesbi.ttf"\/><\/font>
|
|
<\/font-family>
|
|
|
|
<font-family name="Courier New">
|
|
<font><font-data ttf="cour.ttf"\/><\/font>
|
|
<font style="oblique"><font-data ttf="couri.ttf"\/><\/font>
|
|
<font weight="bold"><font-data ttf="courbd.ttf"\/><\/font>
|
|
<font weight="bold" style="oblique"><font-data ttf="courbi.ttf"\/><\/font>
|
|
<\/font-family>
|
|
|
|
<font-family name="Tahoma" embed="true">
|
|
<font><font-data ttf="tahoma.ttf"\/><\/font>
|
|
<font weight="bold"><font-data ttf="tahomabd.ttf"\/><\/font>
|
|
<\/font-family>
|
|
|
|
<font-family name="Verdana" embed="true">
|
|
<font><font-data ttf="verdana.ttf"\/><\/font>
|
|
<font style="oblique"><font-data ttf="verdanai.ttf"\/><\/font>
|
|
<font weight="bold"><font-data ttf="verdanab.ttf"\/><\/font>
|
|
<font weight="bold" style="oblique"><font-data ttf="verdanaz.ttf"\/><\/font>
|
|
<\/font-family>
|
|
|
|
<font-family name="Palatino" embed="true" ligatures="ff fi fl ffi ffl">
|
|
<font><font-data ttf="pala.ttf"\/><\/font>
|
|
<font style="italic"><font-data ttf="palai.ttf"\/><\/font>
|
|
<font weight="bold"><font-data ttf="palab.ttf"\/><\/font>
|
|
<font weight="bold" style="italic"><font-data ttf="palabi.ttf"\/><\/font>
|
|
<\/font-family>
|
|
|
|
<font-family name="Lucida Sans Unicode">
|
|
<font><font-data ttf="lsansuni.ttf"\/><\/font>
|
|
<\/font-family>
|
|
|
|
<\/font-group>
|
|
|
|
<!-- Required aliases -->
|
|
<font-alias name="monospace" value="Courier"\/>
|
|
<font-alias name="sans-serif" value="Helvetica"\/>
|
|
<font-alias name="serif" value="Times"\/>
|
|
<font-alias name="cursive" value="Times"\/>
|
|
<font-alias name="fantasy" value="Times"\/>
|
|
<\/fonts>
|
|
|
|
<!-- ======================================================= -->
|
|
<!-- Language-specific data: hyphenation, line breaking, etc -->
|
|
<!-- ======================================================= -->
|
|
<languages default-language="en-US" xml:base="hyphen\/">
|
|
|
|
<language name="English (US)" codes="none en-US eng-US">
|
|
<hyphenation pattern="hyphen.tex"\/>
|
|
<\/language>
|
|
|
|
<language name="English (UK)" codes="en-GB eng-GB en eng">
|
|
<hyphenation pattern="ukhyphen.tex"\/>
|
|
<\/language>
|
|
|
|
<language name="Russian" codes="ru rus">
|
|
<hyphenation pattern="ruhyphal.tex" encoding="koi8-r"\/>
|
|
<\/language>
|
|
|
|
<language name="French" codes="fr fra fre">
|
|
<hyphenation pattern="frhyph_rx.tex"\/>
|
|
<\/language>
|
|
|
|
<language name="German" codes="de deu ger">
|
|
<hyphenation pattern="dehyph_rx.tex"\/>
|
|
<\/language>
|
|
|
|
<language name="Spanish" codes="es esl spa">
|
|
<hyphenation pattern="eshyph_rx.tex"\/>
|
|
<\/language>
|
|
|
|
<language name="Polish" codes="pl pol">
|
|
<hyphenation pattern="plhyph_rx.tex"\/>
|
|
<\/language>
|
|
|
|
<\/languages>
|
|
|
|
<\/config>
|
|
]
|
|
|
|
XZ authored his equations using the venerable Latex, JM converted these to
|
|
MathML using [@http://gentoo-wiki.com/HOWTO_Convert_LaTeX_to_HTML_with_MathML mxlatex].
|
|
This process is currently unreliable and required some manual intervention:
|
|
consequently Latex source is not considered a viable route for the automatic
|
|
production of SVG versions of equations.
|
|
|
|
Equations are embedded in the quickbook source using the /equation/
|
|
template defined in math.qbk. This outputs Docbook XML that looks like:
|
|
|
|
[pre
|
|
<inlinemediaobject>
|
|
<imageobject role="html">
|
|
<imagedata fileref="../equations/myfile.png"></imagedata>
|
|
</imageobject>
|
|
<imageobject role="print">
|
|
<imagedata fileref="../equations/myfile.svg"></imagedata>
|
|
</imageobject>
|
|
</inlinemediaobject>
|
|
]
|
|
|
|
MathML is not currently present in the Docbook output, or in the
|
|
generated HTML: this needs further investigation.
|
|
|
|
[endsect][/section:implementation Implementation Notes]
|
|
|
|
[/
|
|
Copyright 2006 John Maddock and Paul A. Bristow.
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file LICENSE_1_0.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt).
|
|
]
|