mqt-core 3.3.2__cp313-cp313t-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mqt/core/__init__.py +89 -0
- mqt/core/__main__.py +55 -0
- mqt/core/_commands.py +52 -0
- mqt/core/_compat/__init__.py +11 -0
- mqt/core/_compat/typing.py +29 -0
- mqt/core/_version.py +34 -0
- mqt/core/_version.pyi +12 -0
- mqt/core/bin/mqt-core-algorithms.dll +0 -0
- mqt/core/bin/mqt-core-circuit-optimizer.dll +0 -0
- mqt/core/bin/mqt-core-dd.dll +0 -0
- mqt/core/bin/mqt-core-ds.dll +0 -0
- mqt/core/bin/mqt-core-fomac.dll +0 -0
- mqt/core/bin/mqt-core-ir.dll +0 -0
- mqt/core/bin/mqt-core-na-fomac.dll +0 -0
- mqt/core/bin/mqt-core-na.dll +0 -0
- mqt/core/bin/mqt-core-qasm.dll +0 -0
- mqt/core/bin/mqt-core-qdmi-driver.dll +0 -0
- mqt/core/bin/mqt-core-qdmi-na-device.dll +0 -0
- mqt/core/bin/mqt-core-zx.dll +0 -0
- mqt/core/dd.cp313t-win_amd64.pyd +0 -0
- mqt/core/dd.pyi +1016 -0
- mqt/core/dd_evaluation.py +368 -0
- mqt/core/fomac.cp313t-win_amd64.pyd +0 -0
- mqt/core/fomac.pyi +125 -0
- mqt/core/include/mqt-core/algorithms/BernsteinVazirani.hpp +39 -0
- mqt/core/include/mqt-core/algorithms/GHZState.hpp +18 -0
- mqt/core/include/mqt-core/algorithms/Grover.hpp +33 -0
- mqt/core/include/mqt-core/algorithms/QFT.hpp +21 -0
- mqt/core/include/mqt-core/algorithms/QPE.hpp +30 -0
- mqt/core/include/mqt-core/algorithms/RandomCliffordCircuit.hpp +22 -0
- mqt/core/include/mqt-core/algorithms/StatePreparation.hpp +43 -0
- mqt/core/include/mqt-core/algorithms/WState.hpp +18 -0
- mqt/core/include/mqt-core/algorithms/mqt_core_algorithms_export.h +43 -0
- mqt/core/include/mqt-core/boost/config/abi/borland_prefix.hpp +27 -0
- mqt/core/include/mqt-core/boost/config/abi/borland_suffix.hpp +12 -0
- mqt/core/include/mqt-core/boost/config/abi/msvc_prefix.hpp +22 -0
- mqt/core/include/mqt-core/boost/config/abi/msvc_suffix.hpp +8 -0
- mqt/core/include/mqt-core/boost/config/abi_prefix.hpp +25 -0
- mqt/core/include/mqt-core/boost/config/abi_suffix.hpp +25 -0
- mqt/core/include/mqt-core/boost/config/assert_cxx03.hpp +211 -0
- mqt/core/include/mqt-core/boost/config/assert_cxx11.hpp +212 -0
- mqt/core/include/mqt-core/boost/config/assert_cxx14.hpp +47 -0
- mqt/core/include/mqt-core/boost/config/assert_cxx17.hpp +65 -0
- mqt/core/include/mqt-core/boost/config/assert_cxx20.hpp +59 -0
- mqt/core/include/mqt-core/boost/config/assert_cxx23.hpp +41 -0
- mqt/core/include/mqt-core/boost/config/assert_cxx98.hpp +23 -0
- mqt/core/include/mqt-core/boost/config/auto_link.hpp +525 -0
- mqt/core/include/mqt-core/boost/config/compiler/borland.hpp +342 -0
- mqt/core/include/mqt-core/boost/config/compiler/clang.hpp +370 -0
- mqt/core/include/mqt-core/boost/config/compiler/clang_version.hpp +89 -0
- mqt/core/include/mqt-core/boost/config/compiler/codegear.hpp +389 -0
- mqt/core/include/mqt-core/boost/config/compiler/comeau.hpp +59 -0
- mqt/core/include/mqt-core/boost/config/compiler/common_edg.hpp +185 -0
- mqt/core/include/mqt-core/boost/config/compiler/compaq_cxx.hpp +19 -0
- mqt/core/include/mqt-core/boost/config/compiler/cray.hpp +446 -0
- mqt/core/include/mqt-core/boost/config/compiler/diab.hpp +26 -0
- mqt/core/include/mqt-core/boost/config/compiler/digitalmars.hpp +146 -0
- mqt/core/include/mqt-core/boost/config/compiler/gcc.hpp +386 -0
- mqt/core/include/mqt-core/boost/config/compiler/gcc_xml.hpp +115 -0
- mqt/core/include/mqt-core/boost/config/compiler/greenhills.hpp +28 -0
- mqt/core/include/mqt-core/boost/config/compiler/hp_acc.hpp +153 -0
- mqt/core/include/mqt-core/boost/config/compiler/intel.hpp +577 -0
- mqt/core/include/mqt-core/boost/config/compiler/kai.hpp +33 -0
- mqt/core/include/mqt-core/boost/config/compiler/metrowerks.hpp +201 -0
- mqt/core/include/mqt-core/boost/config/compiler/mpw.hpp +143 -0
- mqt/core/include/mqt-core/boost/config/compiler/nvcc.hpp +64 -0
- mqt/core/include/mqt-core/boost/config/compiler/pathscale.hpp +141 -0
- mqt/core/include/mqt-core/boost/config/compiler/pgi.hpp +23 -0
- mqt/core/include/mqt-core/boost/config/compiler/sgi_mipspro.hpp +29 -0
- mqt/core/include/mqt-core/boost/config/compiler/sunpro_cc.hpp +225 -0
- mqt/core/include/mqt-core/boost/config/compiler/vacpp.hpp +189 -0
- mqt/core/include/mqt-core/boost/config/compiler/visualc.hpp +398 -0
- mqt/core/include/mqt-core/boost/config/compiler/xlcpp.hpp +303 -0
- mqt/core/include/mqt-core/boost/config/compiler/xlcpp_zos.hpp +174 -0
- mqt/core/include/mqt-core/boost/config/detail/cxx_composite.hpp +218 -0
- mqt/core/include/mqt-core/boost/config/detail/posix_features.hpp +95 -0
- mqt/core/include/mqt-core/boost/config/detail/select_compiler_config.hpp +157 -0
- mqt/core/include/mqt-core/boost/config/detail/select_platform_config.hpp +147 -0
- mqt/core/include/mqt-core/boost/config/detail/select_stdlib_config.hpp +121 -0
- mqt/core/include/mqt-core/boost/config/detail/suffix.hpp +1334 -0
- mqt/core/include/mqt-core/boost/config/header_deprecated.hpp +26 -0
- mqt/core/include/mqt-core/boost/config/helper_macros.hpp +37 -0
- mqt/core/include/mqt-core/boost/config/no_tr1/cmath.hpp +28 -0
- mqt/core/include/mqt-core/boost/config/no_tr1/complex.hpp +28 -0
- mqt/core/include/mqt-core/boost/config/no_tr1/functional.hpp +28 -0
- mqt/core/include/mqt-core/boost/config/no_tr1/memory.hpp +28 -0
- mqt/core/include/mqt-core/boost/config/no_tr1/utility.hpp +28 -0
- mqt/core/include/mqt-core/boost/config/platform/aix.hpp +33 -0
- mqt/core/include/mqt-core/boost/config/platform/amigaos.hpp +15 -0
- mqt/core/include/mqt-core/boost/config/platform/beos.hpp +26 -0
- mqt/core/include/mqt-core/boost/config/platform/bsd.hpp +83 -0
- mqt/core/include/mqt-core/boost/config/platform/cloudabi.hpp +18 -0
- mqt/core/include/mqt-core/boost/config/platform/cray.hpp +18 -0
- mqt/core/include/mqt-core/boost/config/platform/cygwin.hpp +71 -0
- mqt/core/include/mqt-core/boost/config/platform/haiku.hpp +31 -0
- mqt/core/include/mqt-core/boost/config/platform/hpux.hpp +87 -0
- mqt/core/include/mqt-core/boost/config/platform/irix.hpp +31 -0
- mqt/core/include/mqt-core/boost/config/platform/linux.hpp +106 -0
- mqt/core/include/mqt-core/boost/config/platform/macos.hpp +87 -0
- mqt/core/include/mqt-core/boost/config/platform/qnxnto.hpp +31 -0
- mqt/core/include/mqt-core/boost/config/platform/solaris.hpp +31 -0
- mqt/core/include/mqt-core/boost/config/platform/symbian.hpp +97 -0
- mqt/core/include/mqt-core/boost/config/platform/vms.hpp +25 -0
- mqt/core/include/mqt-core/boost/config/platform/vxworks.hpp +422 -0
- mqt/core/include/mqt-core/boost/config/platform/wasm.hpp +23 -0
- mqt/core/include/mqt-core/boost/config/platform/win32.hpp +90 -0
- mqt/core/include/mqt-core/boost/config/platform/zos.hpp +32 -0
- mqt/core/include/mqt-core/boost/config/pragma_message.hpp +31 -0
- mqt/core/include/mqt-core/boost/config/requires_threads.hpp +92 -0
- mqt/core/include/mqt-core/boost/config/stdlib/dinkumware.hpp +324 -0
- mqt/core/include/mqt-core/boost/config/stdlib/libcomo.hpp +93 -0
- mqt/core/include/mqt-core/boost/config/stdlib/libcpp.hpp +180 -0
- mqt/core/include/mqt-core/boost/config/stdlib/libstdcpp3.hpp +482 -0
- mqt/core/include/mqt-core/boost/config/stdlib/modena.hpp +79 -0
- mqt/core/include/mqt-core/boost/config/stdlib/msl.hpp +98 -0
- mqt/core/include/mqt-core/boost/config/stdlib/roguewave.hpp +208 -0
- mqt/core/include/mqt-core/boost/config/stdlib/sgi.hpp +168 -0
- mqt/core/include/mqt-core/boost/config/stdlib/stlport.hpp +258 -0
- mqt/core/include/mqt-core/boost/config/stdlib/vacpp.hpp +74 -0
- mqt/core/include/mqt-core/boost/config/stdlib/xlcpp_zos.hpp +61 -0
- mqt/core/include/mqt-core/boost/config/user.hpp +133 -0
- mqt/core/include/mqt-core/boost/config/warning_disable.hpp +47 -0
- mqt/core/include/mqt-core/boost/config/workaround.hpp +305 -0
- mqt/core/include/mqt-core/boost/config.hpp +67 -0
- mqt/core/include/mqt-core/boost/cstdint.hpp +556 -0
- mqt/core/include/mqt-core/boost/cxx11_char_types.hpp +70 -0
- mqt/core/include/mqt-core/boost/detail/workaround.hpp +10 -0
- mqt/core/include/mqt-core/boost/limits.hpp +146 -0
- mqt/core/include/mqt-core/boost/multiprecision/complex128.hpp +24 -0
- mqt/core/include/mqt-core/boost/multiprecision/complex_adaptor.hpp +1046 -0
- mqt/core/include/mqt-core/boost/multiprecision/concepts/mp_number_archetypes.hpp +257 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_bin_float/io.hpp +698 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_bin_float/transcendental.hpp +157 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_bin_float.hpp +2297 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_complex.hpp +12 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_dec_float.hpp +3690 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/add.hpp +368 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/add_unsigned.hpp +387 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/bitwise.hpp +889 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/checked.hpp +178 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/comparison.hpp +374 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/cpp_int_config.hpp +161 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/divide.hpp +703 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/import_export.hpp +248 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/intel_intrinsics.hpp +138 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/limits.hpp +282 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/literals.hpp +295 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/misc.hpp +1457 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/multiply.hpp +848 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/serialize.hpp +211 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/value_pack.hpp +42 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int.hpp +2360 -0
- mqt/core/include/mqt-core/boost/multiprecision/debug_adaptor.hpp +760 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/assert.hpp +29 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/atomic.hpp +62 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/bitscan.hpp +317 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/check_cpp11_config.hpp +64 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/constexpr.hpp +88 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/default_ops.hpp +4052 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/digits.hpp +49 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/dynamic_array.hpp +44 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/empty_value.hpp +87 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/endian.hpp +35 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/et_ops.hpp +1831 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/float128_functions.hpp +95 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/float_string_cvt.hpp +333 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/fpclassify.hpp +101 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/functions/constants.hpp +288 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/functions/pow.hpp +905 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/functions/trig.hpp +1058 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/functions/trunc.hpp +82 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/generic_interconvert.hpp +687 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/hash.hpp +56 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/integer_ops.hpp +474 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/itos.hpp +39 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/min_max.hpp +106 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/no_et_ops.hpp +661 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/no_exceptions_support.hpp +55 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/number_base.hpp +1656 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/number_compare.hpp +848 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/precision.hpp +313 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/rebind.hpp +19 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/standalone_config.hpp +148 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/static_array.hpp +42 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/string_helpers.hpp +48 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/tables.hpp +80 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/ublas_interop.hpp +75 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/uniform_int_distribution.hpp +212 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/utype_helper.hpp +374 -0
- mqt/core/include/mqt-core/boost/multiprecision/eigen.hpp +248 -0
- mqt/core/include/mqt-core/boost/multiprecision/float128.hpp +920 -0
- mqt/core/include/mqt-core/boost/multiprecision/fwd.hpp +268 -0
- mqt/core/include/mqt-core/boost/multiprecision/gmp.hpp +4060 -0
- mqt/core/include/mqt-core/boost/multiprecision/integer.hpp +363 -0
- mqt/core/include/mqt-core/boost/multiprecision/logged_adaptor.hpp +834 -0
- mqt/core/include/mqt-core/boost/multiprecision/miller_rabin.hpp +221 -0
- mqt/core/include/mqt-core/boost/multiprecision/mpc.hpp +1721 -0
- mqt/core/include/mqt-core/boost/multiprecision/mpfi.hpp +2559 -0
- mqt/core/include/mqt-core/boost/multiprecision/mpfr.hpp +3644 -0
- mqt/core/include/mqt-core/boost/multiprecision/number.hpp +2500 -0
- mqt/core/include/mqt-core/boost/multiprecision/random.hpp +23 -0
- mqt/core/include/mqt-core/boost/multiprecision/rational_adaptor.hpp +1289 -0
- mqt/core/include/mqt-core/boost/multiprecision/tommath.hpp +1034 -0
- mqt/core/include/mqt-core/boost/multiprecision/traits/explicit_conversion.hpp +67 -0
- mqt/core/include/mqt-core/boost/multiprecision/traits/extract_exponent_type.hpp +28 -0
- mqt/core/include/mqt-core/boost/multiprecision/traits/is_backend.hpp +91 -0
- mqt/core/include/mqt-core/boost/multiprecision/traits/is_byte_container.hpp +51 -0
- mqt/core/include/mqt-core/boost/multiprecision/traits/is_complex.hpp +22 -0
- mqt/core/include/mqt-core/boost/multiprecision/traits/is_convertible_arithmetic.hpp +51 -0
- mqt/core/include/mqt-core/boost/multiprecision/traits/is_restricted_conversion.hpp +47 -0
- mqt/core/include/mqt-core/boost/multiprecision/traits/is_variable_precision.hpp +25 -0
- mqt/core/include/mqt-core/boost/multiprecision/traits/max_digits10.hpp +79 -0
- mqt/core/include/mqt-core/boost/multiprecision/traits/std_integer_traits.hpp +90 -0
- mqt/core/include/mqt-core/boost/multiprecision/traits/transcendental_reduction_type.hpp +21 -0
- mqt/core/include/mqt-core/boost/version.hpp +32 -0
- mqt/core/include/mqt-core/circuit_optimizer/CircuitOptimizer.hpp +119 -0
- mqt/core/include/mqt-core/circuit_optimizer/mqt_core_circuit_optimizer_export.h +43 -0
- mqt/core/include/mqt-core/datastructures/DirectedAcyclicGraph.hpp +117 -0
- mqt/core/include/mqt-core/datastructures/DirectedGraph.hpp +158 -0
- mqt/core/include/mqt-core/datastructures/DisjointSet.hpp +50 -0
- mqt/core/include/mqt-core/datastructures/Layer.hpp +172 -0
- mqt/core/include/mqt-core/datastructures/SymmetricMatrix.hpp +57 -0
- mqt/core/include/mqt-core/datastructures/UndirectedGraph.hpp +227 -0
- mqt/core/include/mqt-core/datastructures/mqt_core_ds_export.h +43 -0
- mqt/core/include/mqt-core/dd/Approximation.hpp +45 -0
- mqt/core/include/mqt-core/dd/CachedEdge.hpp +174 -0
- mqt/core/include/mqt-core/dd/Complex.hpp +165 -0
- mqt/core/include/mqt-core/dd/ComplexNumbers.hpp +150 -0
- mqt/core/include/mqt-core/dd/ComplexValue.hpp +184 -0
- mqt/core/include/mqt-core/dd/ComputeTable.hpp +183 -0
- mqt/core/include/mqt-core/dd/DDDefinitions.hpp +139 -0
- mqt/core/include/mqt-core/dd/DDpackageConfig.hpp +104 -0
- mqt/core/include/mqt-core/dd/DensityNoiseTable.hpp +114 -0
- mqt/core/include/mqt-core/dd/Edge.hpp +416 -0
- mqt/core/include/mqt-core/dd/Export.hpp +438 -0
- mqt/core/include/mqt-core/dd/FunctionalityConstruction.hpp +75 -0
- mqt/core/include/mqt-core/dd/GateMatrixDefinitions.hpp +43 -0
- mqt/core/include/mqt-core/dd/LinkedListBase.hpp +45 -0
- mqt/core/include/mqt-core/dd/MemoryManager.hpp +193 -0
- mqt/core/include/mqt-core/dd/Node.hpp +223 -0
- mqt/core/include/mqt-core/dd/NoiseFunctionality.hpp +144 -0
- mqt/core/include/mqt-core/dd/Operations.hpp +306 -0
- mqt/core/include/mqt-core/dd/Package.hpp +2036 -0
- mqt/core/include/mqt-core/dd/Package_fwd.hpp +22 -0
- mqt/core/include/mqt-core/dd/RealNumber.hpp +255 -0
- mqt/core/include/mqt-core/dd/RealNumberUniqueTable.hpp +217 -0
- mqt/core/include/mqt-core/dd/Simulation.hpp +98 -0
- mqt/core/include/mqt-core/dd/StateGeneration.hpp +143 -0
- mqt/core/include/mqt-core/dd/StochasticNoiseOperationTable.hpp +88 -0
- mqt/core/include/mqt-core/dd/UnaryComputeTable.hpp +121 -0
- mqt/core/include/mqt-core/dd/UniqueTable.hpp +243 -0
- mqt/core/include/mqt-core/dd/mqt_core_dd_export.h +43 -0
- mqt/core/include/mqt-core/dd/statistics/MemoryManagerStatistics.hpp +84 -0
- mqt/core/include/mqt-core/dd/statistics/PackageStatistics.hpp +55 -0
- mqt/core/include/mqt-core/dd/statistics/Statistics.hpp +48 -0
- mqt/core/include/mqt-core/dd/statistics/TableStatistics.hpp +79 -0
- mqt/core/include/mqt-core/dd/statistics/UniqueTableStatistics.hpp +31 -0
- mqt/core/include/mqt-core/fomac/FoMaC.hpp +568 -0
- mqt/core/include/mqt-core/ir/Definitions.hpp +108 -0
- mqt/core/include/mqt-core/ir/Permutation.hpp +213 -0
- mqt/core/include/mqt-core/ir/QuantumComputation.hpp +596 -0
- mqt/core/include/mqt-core/ir/Register.hpp +125 -0
- mqt/core/include/mqt-core/ir/mqt_core_ir_export.h +43 -0
- mqt/core/include/mqt-core/ir/operations/AodOperation.hpp +92 -0
- mqt/core/include/mqt-core/ir/operations/CompoundOperation.hpp +212 -0
- mqt/core/include/mqt-core/ir/operations/Control.hpp +142 -0
- mqt/core/include/mqt-core/ir/operations/Expression.hpp +847 -0
- mqt/core/include/mqt-core/ir/operations/IfElseOperation.hpp +169 -0
- mqt/core/include/mqt-core/ir/operations/NonUnitaryOperation.hpp +118 -0
- mqt/core/include/mqt-core/ir/operations/OpType.hpp +120 -0
- mqt/core/include/mqt-core/ir/operations/OpType.inc +76 -0
- mqt/core/include/mqt-core/ir/operations/Operation.hpp +247 -0
- mqt/core/include/mqt-core/ir/operations/StandardOperation.hpp +140 -0
- mqt/core/include/mqt-core/ir/operations/SymbolicOperation.hpp +144 -0
- mqt/core/include/mqt-core/mqt_na_qdmi/device.h +602 -0
- mqt/core/include/mqt-core/mqt_na_qdmi/types.h +78 -0
- mqt/core/include/mqt-core/na/NAComputation.hpp +185 -0
- mqt/core/include/mqt-core/na/device/Device.hpp +410 -0
- mqt/core/include/mqt-core/na/device/DeviceMemberInitializers.hpp +724 -0
- mqt/core/include/mqt-core/na/device/Generator.hpp +447 -0
- mqt/core/include/mqt-core/na/entities/Atom.hpp +62 -0
- mqt/core/include/mqt-core/na/entities/Location.hpp +154 -0
- mqt/core/include/mqt-core/na/entities/Zone.hpp +95 -0
- mqt/core/include/mqt-core/na/fomac/Device.hpp +169 -0
- mqt/core/include/mqt-core/na/mqt_core_na_export.h +43 -0
- mqt/core/include/mqt-core/na/operations/GlobalCZOp.hpp +38 -0
- mqt/core/include/mqt-core/na/operations/GlobalOp.hpp +58 -0
- mqt/core/include/mqt-core/na/operations/GlobalRYOp.hpp +42 -0
- mqt/core/include/mqt-core/na/operations/LoadOp.hpp +89 -0
- mqt/core/include/mqt-core/na/operations/LocalOp.hpp +56 -0
- mqt/core/include/mqt-core/na/operations/LocalRZOp.hpp +42 -0
- mqt/core/include/mqt-core/na/operations/LocalUOp.hpp +49 -0
- mqt/core/include/mqt-core/na/operations/MoveOp.hpp +66 -0
- mqt/core/include/mqt-core/na/operations/Op.hpp +62 -0
- mqt/core/include/mqt-core/na/operations/ShuttlingOp.hpp +51 -0
- mqt/core/include/mqt-core/na/operations/StoreOp.hpp +87 -0
- mqt/core/include/mqt-core/qasm3/Exception.hpp +85 -0
- mqt/core/include/mqt-core/qasm3/Gate.hpp +65 -0
- mqt/core/include/mqt-core/qasm3/Importer.hpp +192 -0
- mqt/core/include/mqt-core/qasm3/InstVisitor.hpp +145 -0
- mqt/core/include/mqt-core/qasm3/NestedEnvironment.hpp +41 -0
- mqt/core/include/mqt-core/qasm3/Parser.hpp +170 -0
- mqt/core/include/mqt-core/qasm3/Scanner.hpp +73 -0
- mqt/core/include/mqt-core/qasm3/Statement.hpp +486 -0
- mqt/core/include/mqt-core/qasm3/Statement_fwd.hpp +39 -0
- mqt/core/include/mqt-core/qasm3/StdGates.hpp +232 -0
- mqt/core/include/mqt-core/qasm3/Token.hpp +198 -0
- mqt/core/include/mqt-core/qasm3/Types.hpp +238 -0
- mqt/core/include/mqt-core/qasm3/Types_fwd.hpp +22 -0
- mqt/core/include/mqt-core/qasm3/mqt_core_qasm_export.h +43 -0
- mqt/core/include/mqt-core/qasm3/passes/CompilerPass.hpp +22 -0
- mqt/core/include/mqt-core/qasm3/passes/ConstEvalPass.hpp +102 -0
- mqt/core/include/mqt-core/qasm3/passes/TypeCheckPass.hpp +124 -0
- mqt/core/include/mqt-core/qdmi/Driver.hpp +431 -0
- mqt/core/include/mqt-core/zx/FunctionalityConstruction.hpp +125 -0
- mqt/core/include/mqt-core/zx/Rational.hpp +318 -0
- mqt/core/include/mqt-core/zx/Rules.hpp +132 -0
- mqt/core/include/mqt-core/zx/Simplify.hpp +182 -0
- mqt/core/include/mqt-core/zx/Utils.hpp +212 -0
- mqt/core/include/mqt-core/zx/ZXDefinitions.hpp +93 -0
- mqt/core/include/mqt-core/zx/ZXDiagram.hpp +480 -0
- mqt/core/include/mqt-core/zx/mqt_core_zx_export.h +43 -0
- mqt/core/include/nlohmann/adl_serializer.hpp +55 -0
- mqt/core/include/nlohmann/byte_container_with_subtype.hpp +103 -0
- mqt/core/include/nlohmann/detail/abi_macros.hpp +111 -0
- mqt/core/include/nlohmann/detail/conversions/from_json.hpp +577 -0
- mqt/core/include/nlohmann/detail/conversions/to_chars.hpp +1118 -0
- mqt/core/include/nlohmann/detail/conversions/to_json.hpp +479 -0
- mqt/core/include/nlohmann/detail/exceptions.hpp +291 -0
- mqt/core/include/nlohmann/detail/hash.hpp +129 -0
- mqt/core/include/nlohmann/detail/input/binary_reader.hpp +3068 -0
- mqt/core/include/nlohmann/detail/input/input_adapters.hpp +549 -0
- mqt/core/include/nlohmann/detail/input/json_sax.hpp +986 -0
- mqt/core/include/nlohmann/detail/input/lexer.hpp +1643 -0
- mqt/core/include/nlohmann/detail/input/parser.hpp +519 -0
- mqt/core/include/nlohmann/detail/input/position_t.hpp +37 -0
- mqt/core/include/nlohmann/detail/iterators/internal_iterator.hpp +35 -0
- mqt/core/include/nlohmann/detail/iterators/iter_impl.hpp +760 -0
- mqt/core/include/nlohmann/detail/iterators/iteration_proxy.hpp +235 -0
- mqt/core/include/nlohmann/detail/iterators/iterator_traits.hpp +61 -0
- mqt/core/include/nlohmann/detail/iterators/json_reverse_iterator.hpp +130 -0
- mqt/core/include/nlohmann/detail/iterators/primitive_iterator.hpp +132 -0
- mqt/core/include/nlohmann/detail/json_custom_base_class.hpp +39 -0
- mqt/core/include/nlohmann/detail/json_pointer.hpp +988 -0
- mqt/core/include/nlohmann/detail/json_ref.hpp +78 -0
- mqt/core/include/nlohmann/detail/macro_scope.hpp +595 -0
- mqt/core/include/nlohmann/detail/macro_unscope.hpp +46 -0
- mqt/core/include/nlohmann/detail/meta/call_std/begin.hpp +17 -0
- mqt/core/include/nlohmann/detail/meta/call_std/end.hpp +17 -0
- mqt/core/include/nlohmann/detail/meta/cpp_future.hpp +171 -0
- mqt/core/include/nlohmann/detail/meta/detected.hpp +70 -0
- mqt/core/include/nlohmann/detail/meta/identity_tag.hpp +21 -0
- mqt/core/include/nlohmann/detail/meta/is_sax.hpp +159 -0
- mqt/core/include/nlohmann/detail/meta/std_fs.hpp +29 -0
- mqt/core/include/nlohmann/detail/meta/type_traits.hpp +795 -0
- mqt/core/include/nlohmann/detail/meta/void_t.hpp +24 -0
- mqt/core/include/nlohmann/detail/output/binary_writer.hpp +1850 -0
- mqt/core/include/nlohmann/detail/output/output_adapters.hpp +147 -0
- mqt/core/include/nlohmann/detail/output/serializer.hpp +988 -0
- mqt/core/include/nlohmann/detail/string_concat.hpp +146 -0
- mqt/core/include/nlohmann/detail/string_escape.hpp +72 -0
- mqt/core/include/nlohmann/detail/string_utils.hpp +37 -0
- mqt/core/include/nlohmann/detail/value_t.hpp +118 -0
- mqt/core/include/nlohmann/json.hpp +5306 -0
- mqt/core/include/nlohmann/json_fwd.hpp +75 -0
- mqt/core/include/nlohmann/ordered_map.hpp +359 -0
- mqt/core/include/nlohmann/thirdparty/hedley/hedley.hpp +2045 -0
- mqt/core/include/nlohmann/thirdparty/hedley/hedley_undef.hpp +158 -0
- mqt/core/include/qdmi/qdmi/client.h +990 -0
- mqt/core/include/qdmi/qdmi/constants.h +1139 -0
- mqt/core/include/qdmi/qdmi/device.h +602 -0
- mqt/core/include/qdmi/qdmi/types.h +78 -0
- mqt/core/include/spdlog/async.h +99 -0
- mqt/core/include/spdlog/async_logger-inl.h +84 -0
- mqt/core/include/spdlog/async_logger.h +74 -0
- mqt/core/include/spdlog/cfg/argv.h +40 -0
- mqt/core/include/spdlog/cfg/env.h +36 -0
- mqt/core/include/spdlog/cfg/helpers-inl.h +107 -0
- mqt/core/include/spdlog/cfg/helpers.h +29 -0
- mqt/core/include/spdlog/common-inl.h +68 -0
- mqt/core/include/spdlog/common.h +406 -0
- mqt/core/include/spdlog/details/backtracer-inl.h +63 -0
- mqt/core/include/spdlog/details/backtracer.h +45 -0
- mqt/core/include/spdlog/details/circular_q.h +115 -0
- mqt/core/include/spdlog/details/console_globals.h +28 -0
- mqt/core/include/spdlog/details/file_helper-inl.h +153 -0
- mqt/core/include/spdlog/details/file_helper.h +61 -0
- mqt/core/include/spdlog/details/fmt_helper.h +141 -0
- mqt/core/include/spdlog/details/log_msg-inl.h +44 -0
- mqt/core/include/spdlog/details/log_msg.h +40 -0
- mqt/core/include/spdlog/details/log_msg_buffer-inl.h +54 -0
- mqt/core/include/spdlog/details/log_msg_buffer.h +32 -0
- mqt/core/include/spdlog/details/mpmc_blocking_q.h +177 -0
- mqt/core/include/spdlog/details/null_mutex.h +35 -0
- mqt/core/include/spdlog/details/os-inl.h +606 -0
- mqt/core/include/spdlog/details/os.h +127 -0
- mqt/core/include/spdlog/details/periodic_worker-inl.h +26 -0
- mqt/core/include/spdlog/details/periodic_worker.h +58 -0
- mqt/core/include/spdlog/details/registry-inl.h +270 -0
- mqt/core/include/spdlog/details/registry.h +131 -0
- mqt/core/include/spdlog/details/synchronous_factory.h +22 -0
- mqt/core/include/spdlog/details/tcp_client-windows.h +135 -0
- mqt/core/include/spdlog/details/tcp_client.h +127 -0
- mqt/core/include/spdlog/details/thread_pool-inl.h +126 -0
- mqt/core/include/spdlog/details/thread_pool.h +117 -0
- mqt/core/include/spdlog/details/udp_client-windows.h +98 -0
- mqt/core/include/spdlog/details/udp_client.h +81 -0
- mqt/core/include/spdlog/details/windows_include.h +11 -0
- mqt/core/include/spdlog/fmt/bin_to_hex.h +224 -0
- mqt/core/include/spdlog/fmt/bundled/args.h +220 -0
- mqt/core/include/spdlog/fmt/bundled/base.h +2989 -0
- mqt/core/include/spdlog/fmt/bundled/chrono.h +2330 -0
- mqt/core/include/spdlog/fmt/bundled/color.h +637 -0
- mqt/core/include/spdlog/fmt/bundled/compile.h +539 -0
- mqt/core/include/spdlog/fmt/bundled/core.h +5 -0
- mqt/core/include/spdlog/fmt/bundled/fmt.license.rst +27 -0
- mqt/core/include/spdlog/fmt/bundled/format-inl.h +1948 -0
- mqt/core/include/spdlog/fmt/bundled/format.h +4244 -0
- mqt/core/include/spdlog/fmt/bundled/os.h +427 -0
- mqt/core/include/spdlog/fmt/bundled/ostream.h +167 -0
- mqt/core/include/spdlog/fmt/bundled/printf.h +633 -0
- mqt/core/include/spdlog/fmt/bundled/ranges.h +850 -0
- mqt/core/include/spdlog/fmt/bundled/std.h +728 -0
- mqt/core/include/spdlog/fmt/bundled/xchar.h +369 -0
- mqt/core/include/spdlog/fmt/chrono.h +23 -0
- mqt/core/include/spdlog/fmt/compile.h +23 -0
- mqt/core/include/spdlog/fmt/fmt.h +30 -0
- mqt/core/include/spdlog/fmt/ostr.h +23 -0
- mqt/core/include/spdlog/fmt/ranges.h +23 -0
- mqt/core/include/spdlog/fmt/std.h +24 -0
- mqt/core/include/spdlog/fmt/xchar.h +23 -0
- mqt/core/include/spdlog/formatter.h +17 -0
- mqt/core/include/spdlog/fwd.h +18 -0
- mqt/core/include/spdlog/logger-inl.h +198 -0
- mqt/core/include/spdlog/logger.h +379 -0
- mqt/core/include/spdlog/mdc.h +52 -0
- mqt/core/include/spdlog/pattern_formatter-inl.h +1340 -0
- mqt/core/include/spdlog/pattern_formatter.h +118 -0
- mqt/core/include/spdlog/sinks/android_sink.h +137 -0
- mqt/core/include/spdlog/sinks/ansicolor_sink-inl.h +142 -0
- mqt/core/include/spdlog/sinks/ansicolor_sink.h +116 -0
- mqt/core/include/spdlog/sinks/base_sink-inl.h +59 -0
- mqt/core/include/spdlog/sinks/base_sink.h +51 -0
- mqt/core/include/spdlog/sinks/basic_file_sink-inl.h +48 -0
- mqt/core/include/spdlog/sinks/basic_file_sink.h +66 -0
- mqt/core/include/spdlog/sinks/callback_sink.h +56 -0
- mqt/core/include/spdlog/sinks/daily_file_sink.h +254 -0
- mqt/core/include/spdlog/sinks/dist_sink.h +81 -0
- mqt/core/include/spdlog/sinks/dup_filter_sink.h +91 -0
- mqt/core/include/spdlog/sinks/hourly_file_sink.h +193 -0
- mqt/core/include/spdlog/sinks/kafka_sink.h +119 -0
- mqt/core/include/spdlog/sinks/mongo_sink.h +108 -0
- mqt/core/include/spdlog/sinks/msvc_sink.h +68 -0
- mqt/core/include/spdlog/sinks/null_sink.h +41 -0
- mqt/core/include/spdlog/sinks/ostream_sink.h +43 -0
- mqt/core/include/spdlog/sinks/qt_sinks.h +304 -0
- mqt/core/include/spdlog/sinks/ringbuffer_sink.h +67 -0
- mqt/core/include/spdlog/sinks/rotating_file_sink-inl.h +179 -0
- mqt/core/include/spdlog/sinks/rotating_file_sink.h +93 -0
- mqt/core/include/spdlog/sinks/sink-inl.h +22 -0
- mqt/core/include/spdlog/sinks/sink.h +34 -0
- mqt/core/include/spdlog/sinks/stdout_color_sinks-inl.h +38 -0
- mqt/core/include/spdlog/sinks/stdout_color_sinks.h +49 -0
- mqt/core/include/spdlog/sinks/stdout_sinks-inl.h +127 -0
- mqt/core/include/spdlog/sinks/stdout_sinks.h +84 -0
- mqt/core/include/spdlog/sinks/syslog_sink.h +104 -0
- mqt/core/include/spdlog/sinks/systemd_sink.h +121 -0
- mqt/core/include/spdlog/sinks/tcp_sink.h +75 -0
- mqt/core/include/spdlog/sinks/udp_sink.h +69 -0
- mqt/core/include/spdlog/sinks/win_eventlog_sink.h +260 -0
- mqt/core/include/spdlog/sinks/wincolor_sink-inl.h +172 -0
- mqt/core/include/spdlog/sinks/wincolor_sink.h +82 -0
- mqt/core/include/spdlog/spdlog-inl.h +96 -0
- mqt/core/include/spdlog/spdlog.h +357 -0
- mqt/core/include/spdlog/stopwatch.h +66 -0
- mqt/core/include/spdlog/tweakme.h +148 -0
- mqt/core/include/spdlog/version.h +11 -0
- mqt/core/ir/__init__.pyi +2078 -0
- mqt/core/ir/operations.pyi +1011 -0
- mqt/core/ir/registers.pyi +91 -0
- mqt/core/ir/symbolic.pyi +177 -0
- mqt/core/ir.cp313t-win_amd64.pyd +0 -0
- mqt/core/lib/mqt-core-algorithms.lib +0 -0
- mqt/core/lib/mqt-core-circuit-optimizer.lib +0 -0
- mqt/core/lib/mqt-core-dd.lib +0 -0
- mqt/core/lib/mqt-core-ds.lib +0 -0
- mqt/core/lib/mqt-core-fomac.lib +0 -0
- mqt/core/lib/mqt-core-ir.lib +0 -0
- mqt/core/lib/mqt-core-na-fomac.lib +0 -0
- mqt/core/lib/mqt-core-na.lib +0 -0
- mqt/core/lib/mqt-core-qasm.lib +0 -0
- mqt/core/lib/mqt-core-qdmi-driver.lib +0 -0
- mqt/core/lib/mqt-core-qdmi-na-device-gen.lib +0 -0
- mqt/core/lib/mqt-core-qdmi-na-device.lib +0 -0
- mqt/core/lib/mqt-core-zx.lib +0 -0
- mqt/core/lib/pkgconfig/spdlog.pc +13 -0
- mqt/core/lib/spdlog.lib +0 -0
- mqt/core/na/__init__.py +12 -0
- mqt/core/na/fomac.cp313t-win_amd64.pyd +0 -0
- mqt/core/na/fomac.pyi +117 -0
- mqt/core/nlohmann_json.natvis +278 -0
- mqt/core/plugins/__init__.py +9 -0
- mqt/core/plugins/qiskit/__init__.py +19 -0
- mqt/core/plugins/qiskit/mqt_to_qiskit.py +420 -0
- mqt/core/plugins/qiskit/qiskit_to_mqt.py +562 -0
- mqt/core/py.typed +2 -0
- mqt/core/share/cmake/mqt-core/AddMQTPythonBinding.cmake +55 -0
- mqt/core/share/cmake/mqt-core/Cache.cmake +33 -0
- mqt/core/share/cmake/mqt-core/FindGMP.cmake +103 -0
- mqt/core/share/cmake/mqt-core/PackageAddTest.cmake +46 -0
- mqt/core/share/cmake/mqt-core/PreventInSourceBuilds.cmake +25 -0
- mqt/core/share/cmake/mqt-core/StandardProjectSettings.cmake +87 -0
- mqt/core/share/cmake/mqt-core/mqt-core-config-version.cmake +85 -0
- mqt/core/share/cmake/mqt-core/mqt-core-config.cmake +52 -0
- mqt/core/share/cmake/mqt-core/mqt-core-targets-release.cmake +141 -0
- mqt/core/share/cmake/mqt-core/mqt-core-targets.cmake +445 -0
- mqt/core/share/cmake/nlohmann_json/nlohmann_jsonConfig.cmake +15 -0
- mqt/core/share/cmake/nlohmann_json/nlohmann_jsonConfigVersion.cmake +20 -0
- mqt/core/share/cmake/nlohmann_json/nlohmann_jsonTargets.cmake +110 -0
- mqt/core/share/cmake/qdmi/Cache.cmake +44 -0
- mqt/core/share/cmake/qdmi/PrefixHandling.cmake +78 -0
- mqt/core/share/cmake/qdmi/prefix_defs.txt +26 -0
- mqt/core/share/cmake/qdmi/qdmi-config-version.cmake +85 -0
- mqt/core/share/cmake/qdmi/qdmi-config.cmake +42 -0
- mqt/core/share/cmake/qdmi/qdmi-targets.cmake +129 -0
- mqt/core/share/cmake/spdlog/spdlogConfig.cmake +44 -0
- mqt/core/share/cmake/spdlog/spdlogConfigTargets-release.cmake +19 -0
- mqt/core/share/cmake/spdlog/spdlogConfigTargets.cmake +121 -0
- mqt/core/share/cmake/spdlog/spdlogConfigVersion.cmake +65 -0
- mqt/core/share/pkgconfig/nlohmann_json.pc +7 -0
- mqt_core-3.3.2.dist-info/DELVEWHEEL +2 -0
- mqt_core-3.3.2.dist-info/METADATA +210 -0
- mqt_core-3.3.2.dist-info/RECORD +537 -0
- mqt_core-3.3.2.dist-info/WHEEL +5 -0
- mqt_core-3.3.2.dist-info/entry_points.txt +4 -0
- mqt_core-3.3.2.dist-info/licenses/LICENSE.md +22 -0
- mqt_core.libs/msvcp140.dll +0 -0
|
@@ -0,0 +1,1058 @@
|
|
|
1
|
+
|
|
2
|
+
// Copyright Christopher Kormanyos 2002 - 2011.
|
|
3
|
+
// Copyright 2011 John Maddock.
|
|
4
|
+
// Distributed under the Boost Software License, Version 1.0.
|
|
5
|
+
// (See accompanying file LICENSE_1_0.txt or copy at
|
|
6
|
+
// http://www.boost.org/LICENSE_1_0.txt)
|
|
7
|
+
|
|
8
|
+
// This work is based on an earlier work:
|
|
9
|
+
// "Algorithm 910: A Portable C++ Multiple-Precision System for Special-Function Calculations",
|
|
10
|
+
// in ACM TOMS, {VOL 37, ISSUE 4, (February 2011)} (C) ACM, 2011. http://doi.acm.org/10.1145/1916461.1916469
|
|
11
|
+
//
|
|
12
|
+
// This file has no include guards or namespaces - it's expanded inline inside default_ops.hpp
|
|
13
|
+
//
|
|
14
|
+
|
|
15
|
+
#include <boost/multiprecision/detail/standalone_config.hpp>
|
|
16
|
+
#include <boost/multiprecision/detail/no_exceptions_support.hpp>
|
|
17
|
+
#include <boost/multiprecision/detail/assert.hpp>
|
|
18
|
+
|
|
19
|
+
#ifdef BOOST_MSVC
|
|
20
|
+
#pragma warning(push)
|
|
21
|
+
#pragma warning(disable : 6326) // comparison of two constants
|
|
22
|
+
#pragma warning(disable : 4127) // conditional expression is constant
|
|
23
|
+
#endif
|
|
24
|
+
|
|
25
|
+
template <class T>
|
|
26
|
+
void hyp0F1(T& result, const T& b, const T& x)
|
|
27
|
+
{
|
|
28
|
+
using si_type = typename boost::multiprecision::detail::canonical<std::int32_t, T>::type ;
|
|
29
|
+
using ui_type = typename boost::multiprecision::detail::canonical<std::uint32_t, T>::type;
|
|
30
|
+
|
|
31
|
+
// Compute the series representation of Hypergeometric0F1 taken from
|
|
32
|
+
// http://functions.wolfram.com/HypergeometricFunctions/Hypergeometric0F1/06/01/01/
|
|
33
|
+
// There are no checks on input range or parameter boundaries.
|
|
34
|
+
|
|
35
|
+
T x_pow_n_div_n_fact(x);
|
|
36
|
+
T pochham_b(b);
|
|
37
|
+
T bp(b);
|
|
38
|
+
|
|
39
|
+
eval_divide(result, x_pow_n_div_n_fact, pochham_b);
|
|
40
|
+
eval_add(result, ui_type(1));
|
|
41
|
+
|
|
42
|
+
si_type n;
|
|
43
|
+
|
|
44
|
+
T tol;
|
|
45
|
+
tol = ui_type(1);
|
|
46
|
+
eval_ldexp(tol, tol, 1 - boost::multiprecision::detail::digits2<number<T, et_on> >::value());
|
|
47
|
+
eval_multiply(tol, result);
|
|
48
|
+
if (eval_get_sign(tol) < 0)
|
|
49
|
+
tol.negate();
|
|
50
|
+
T term;
|
|
51
|
+
|
|
52
|
+
const int series_limit =
|
|
53
|
+
boost::multiprecision::detail::digits2<number<T, et_on> >::value() < 100
|
|
54
|
+
? 100
|
|
55
|
+
: boost::multiprecision::detail::digits2<number<T, et_on> >::value();
|
|
56
|
+
// Series expansion of hyperg_0f1(; b; x).
|
|
57
|
+
for (n = 2; n < series_limit; ++n)
|
|
58
|
+
{
|
|
59
|
+
eval_multiply(x_pow_n_div_n_fact, x);
|
|
60
|
+
eval_divide(x_pow_n_div_n_fact, n);
|
|
61
|
+
eval_increment(bp);
|
|
62
|
+
eval_multiply(pochham_b, bp);
|
|
63
|
+
|
|
64
|
+
eval_divide(term, x_pow_n_div_n_fact, pochham_b);
|
|
65
|
+
eval_add(result, term);
|
|
66
|
+
|
|
67
|
+
bool neg_term = eval_get_sign(term) < 0;
|
|
68
|
+
if (neg_term)
|
|
69
|
+
term.negate();
|
|
70
|
+
if (term.compare(tol) <= 0)
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (n >= series_limit)
|
|
75
|
+
BOOST_MP_THROW_EXCEPTION(std::runtime_error("H0F1 Failed to Converge"));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
template <class T, unsigned N, bool b = boost::multiprecision::detail::is_variable_precision<boost::multiprecision::number<T> >::value>
|
|
79
|
+
struct scoped_N_precision
|
|
80
|
+
{
|
|
81
|
+
template <class U>
|
|
82
|
+
scoped_N_precision(U const&) {}
|
|
83
|
+
template <class U>
|
|
84
|
+
void reduce(U&) {}
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
template <class T, unsigned N>
|
|
88
|
+
struct scoped_N_precision<T, N, true>
|
|
89
|
+
{
|
|
90
|
+
unsigned old_precision, old_arg_precision;
|
|
91
|
+
scoped_N_precision(T& arg)
|
|
92
|
+
{
|
|
93
|
+
old_precision = T::thread_default_precision();
|
|
94
|
+
old_arg_precision = arg.precision();
|
|
95
|
+
T::thread_default_precision(old_arg_precision * N);
|
|
96
|
+
arg.precision(old_arg_precision * N);
|
|
97
|
+
}
|
|
98
|
+
~scoped_N_precision()
|
|
99
|
+
{
|
|
100
|
+
T::thread_default_precision(old_precision);
|
|
101
|
+
}
|
|
102
|
+
void reduce(T& arg)
|
|
103
|
+
{
|
|
104
|
+
arg.precision(old_arg_precision);
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
template <class T>
|
|
109
|
+
void reduce_n_half_pi(T& arg, const T& n, bool go_down)
|
|
110
|
+
{
|
|
111
|
+
//
|
|
112
|
+
// We need to perform argument reduction at 3 times the precision of arg
|
|
113
|
+
// in order to ensure a correct result up to arg = 1/epsilon. Beyond that
|
|
114
|
+
// the value of n will have been incorrectly calculated anyway since it will
|
|
115
|
+
// have a value greater than 1/epsilon and no longer be an exact integer value.
|
|
116
|
+
//
|
|
117
|
+
// More information in ARGUMENT REDUCTION FOR HUGE ARGUMENTS. K C Ng.
|
|
118
|
+
//
|
|
119
|
+
// There are two mutually exclusive ways to achieve this, both of which are
|
|
120
|
+
// supported here:
|
|
121
|
+
// 1) To define a fixed precision type with 3 times the precision for the calculation.
|
|
122
|
+
// 2) To dynamically increase the precision of the variables.
|
|
123
|
+
//
|
|
124
|
+
using reduction_type = typename boost::multiprecision::detail::transcendental_reduction_type<T>::type;
|
|
125
|
+
//
|
|
126
|
+
// Make a copy of the arg at higher precision:
|
|
127
|
+
//
|
|
128
|
+
reduction_type big_arg(arg);
|
|
129
|
+
//
|
|
130
|
+
// Dynamically increase precision when supported, this increases the default
|
|
131
|
+
// and ups the precision of big_arg to match:
|
|
132
|
+
//
|
|
133
|
+
scoped_N_precision<T, 3> scoped_precision(big_arg);
|
|
134
|
+
//
|
|
135
|
+
// High precision PI:
|
|
136
|
+
//
|
|
137
|
+
reduction_type reduction = get_constant_pi<reduction_type>();
|
|
138
|
+
eval_ldexp(reduction, reduction, -1); // divide by 2
|
|
139
|
+
eval_multiply(reduction, n);
|
|
140
|
+
|
|
141
|
+
BOOST_MATH_INSTRUMENT_CODE(big_arg.str(10, std::ios_base::scientific));
|
|
142
|
+
BOOST_MATH_INSTRUMENT_CODE(reduction.str(10, std::ios_base::scientific));
|
|
143
|
+
|
|
144
|
+
if (go_down)
|
|
145
|
+
eval_subtract(big_arg, reduction, big_arg);
|
|
146
|
+
else
|
|
147
|
+
eval_subtract(big_arg, reduction);
|
|
148
|
+
arg = T(big_arg);
|
|
149
|
+
//
|
|
150
|
+
// If arg is a variable precision type, then we have just copied the
|
|
151
|
+
// precision of big_arg s well it's value. Reduce the precision now:
|
|
152
|
+
//
|
|
153
|
+
scoped_precision.reduce(arg);
|
|
154
|
+
BOOST_MATH_INSTRUMENT_CODE(big_arg.str(10, std::ios_base::scientific));
|
|
155
|
+
BOOST_MATH_INSTRUMENT_CODE(arg.str(10, std::ios_base::scientific));
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
template <class T>
|
|
159
|
+
void eval_sin(T& result, const T& x)
|
|
160
|
+
{
|
|
161
|
+
static_assert(number_category<T>::value == number_kind_floating_point, "The sin function is only valid for floating point types.");
|
|
162
|
+
BOOST_MATH_INSTRUMENT_CODE(x.str(0, std::ios_base::scientific));
|
|
163
|
+
if (&result == &x)
|
|
164
|
+
{
|
|
165
|
+
T temp;
|
|
166
|
+
eval_sin(temp, x);
|
|
167
|
+
result = temp;
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
using si_type = typename boost::multiprecision::detail::canonical<std::int32_t, T>::type ;
|
|
172
|
+
using ui_type = typename boost::multiprecision::detail::canonical<std::uint32_t, T>::type;
|
|
173
|
+
using fp_type = typename std::tuple_element<0, typename T::float_types>::type ;
|
|
174
|
+
|
|
175
|
+
switch (eval_fpclassify(x))
|
|
176
|
+
{
|
|
177
|
+
case FP_INFINITE:
|
|
178
|
+
case FP_NAN:
|
|
179
|
+
BOOST_IF_CONSTEXPR(std::numeric_limits<number<T, et_on> >::has_quiet_NaN)
|
|
180
|
+
{
|
|
181
|
+
result = std::numeric_limits<number<T, et_on> >::quiet_NaN().backend();
|
|
182
|
+
errno = EDOM;
|
|
183
|
+
}
|
|
184
|
+
else
|
|
185
|
+
BOOST_MP_THROW_EXCEPTION(std::domain_error("Result is undefined or complex and there is no NaN for this number type."));
|
|
186
|
+
return;
|
|
187
|
+
case FP_ZERO:
|
|
188
|
+
result = x;
|
|
189
|
+
return;
|
|
190
|
+
default:;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Local copy of the argument
|
|
194
|
+
T xx = x;
|
|
195
|
+
|
|
196
|
+
// Analyze and prepare the phase of the argument.
|
|
197
|
+
// Make a local, positive copy of the argument, xx.
|
|
198
|
+
// The argument xx will be reduced to 0 <= xx <= pi/2.
|
|
199
|
+
bool b_negate_sin = false;
|
|
200
|
+
|
|
201
|
+
if (eval_get_sign(x) < 0)
|
|
202
|
+
{
|
|
203
|
+
xx.negate();
|
|
204
|
+
b_negate_sin = !b_negate_sin;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
T n_pi, t;
|
|
208
|
+
T half_pi = get_constant_pi<T>();
|
|
209
|
+
eval_ldexp(half_pi, half_pi, -1); // divide by 2
|
|
210
|
+
// Remove multiples of pi/2.
|
|
211
|
+
if (xx.compare(half_pi) > 0)
|
|
212
|
+
{
|
|
213
|
+
eval_divide(n_pi, xx, half_pi);
|
|
214
|
+
eval_trunc(n_pi, n_pi);
|
|
215
|
+
t = ui_type(4);
|
|
216
|
+
eval_fmod(t, n_pi, t);
|
|
217
|
+
bool b_go_down = false;
|
|
218
|
+
if (t.compare(ui_type(1)) == 0)
|
|
219
|
+
{
|
|
220
|
+
b_go_down = true;
|
|
221
|
+
}
|
|
222
|
+
else if (t.compare(ui_type(2)) == 0)
|
|
223
|
+
{
|
|
224
|
+
b_negate_sin = !b_negate_sin;
|
|
225
|
+
}
|
|
226
|
+
else if (t.compare(ui_type(3)) == 0)
|
|
227
|
+
{
|
|
228
|
+
b_negate_sin = !b_negate_sin;
|
|
229
|
+
b_go_down = true;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
if (b_go_down)
|
|
233
|
+
eval_increment(n_pi);
|
|
234
|
+
//
|
|
235
|
+
// If n_pi is > 1/epsilon, then it is no longer an exact integer value
|
|
236
|
+
// but an approximation. As a result we can no longer reliably reduce
|
|
237
|
+
// xx to 0 <= xx < pi/2, nor can we tell the sign of the result as we need
|
|
238
|
+
// n_pi % 4 for that, but that will always be zero in this situation.
|
|
239
|
+
// We could use a higher precision type for n_pi, along with division at
|
|
240
|
+
// higher precision, but that's rather expensive. So for now we do not support
|
|
241
|
+
// this, and will see if anyone complains and has a legitimate use case.
|
|
242
|
+
//
|
|
243
|
+
if (n_pi.compare(get_constant_one_over_epsilon<T>()) > 0)
|
|
244
|
+
{
|
|
245
|
+
result = ui_type(0);
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
reduce_n_half_pi(xx, n_pi, b_go_down);
|
|
250
|
+
//
|
|
251
|
+
// Post reduction we may be a few ulp below zero or above pi/2
|
|
252
|
+
// given that n_pi was calculated at working precision and not
|
|
253
|
+
// at the higher precision used for reduction. Correct that now:
|
|
254
|
+
//
|
|
255
|
+
if (eval_get_sign(xx) < 0)
|
|
256
|
+
{
|
|
257
|
+
xx.negate();
|
|
258
|
+
b_negate_sin = !b_negate_sin;
|
|
259
|
+
}
|
|
260
|
+
if (xx.compare(half_pi) > 0)
|
|
261
|
+
{
|
|
262
|
+
eval_ldexp(half_pi, half_pi, 1);
|
|
263
|
+
eval_subtract(xx, half_pi, xx);
|
|
264
|
+
eval_ldexp(half_pi, half_pi, -1);
|
|
265
|
+
b_go_down = !b_go_down;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
BOOST_MATH_INSTRUMENT_CODE(xx.str(0, std::ios_base::scientific));
|
|
269
|
+
BOOST_MATH_INSTRUMENT_CODE(n_pi.str(0, std::ios_base::scientific));
|
|
270
|
+
BOOST_MP_ASSERT(xx.compare(half_pi) <= 0);
|
|
271
|
+
BOOST_MP_ASSERT(xx.compare(ui_type(0)) >= 0);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
t = half_pi;
|
|
275
|
+
eval_subtract(t, xx);
|
|
276
|
+
|
|
277
|
+
const bool b_zero = eval_get_sign(xx) == 0;
|
|
278
|
+
const bool b_pi_half = eval_get_sign(t) == 0;
|
|
279
|
+
|
|
280
|
+
BOOST_MATH_INSTRUMENT_CODE(xx.str(0, std::ios_base::scientific));
|
|
281
|
+
BOOST_MATH_INSTRUMENT_CODE(t.str(0, std::ios_base::scientific));
|
|
282
|
+
|
|
283
|
+
// Check if the reduced argument is very close to 0 or pi/2.
|
|
284
|
+
const bool b_near_zero = xx.compare(fp_type(1e-1)) < 0;
|
|
285
|
+
const bool b_near_pi_half = t.compare(fp_type(1e-1)) < 0;
|
|
286
|
+
|
|
287
|
+
if (b_zero)
|
|
288
|
+
{
|
|
289
|
+
result = ui_type(0);
|
|
290
|
+
}
|
|
291
|
+
else if (b_pi_half)
|
|
292
|
+
{
|
|
293
|
+
result = ui_type(1);
|
|
294
|
+
}
|
|
295
|
+
else if (b_near_zero)
|
|
296
|
+
{
|
|
297
|
+
eval_multiply(t, xx, xx);
|
|
298
|
+
eval_divide(t, si_type(-4));
|
|
299
|
+
T t2;
|
|
300
|
+
t2 = fp_type(1.5);
|
|
301
|
+
hyp0F1(result, t2, t);
|
|
302
|
+
BOOST_MATH_INSTRUMENT_CODE(result.str(0, std::ios_base::scientific));
|
|
303
|
+
eval_multiply(result, xx);
|
|
304
|
+
}
|
|
305
|
+
else if (b_near_pi_half)
|
|
306
|
+
{
|
|
307
|
+
eval_multiply(t, t);
|
|
308
|
+
eval_divide(t, si_type(-4));
|
|
309
|
+
T t2;
|
|
310
|
+
t2 = fp_type(0.5);
|
|
311
|
+
hyp0F1(result, t2, t);
|
|
312
|
+
BOOST_MATH_INSTRUMENT_CODE(result.str(0, std::ios_base::scientific));
|
|
313
|
+
}
|
|
314
|
+
else
|
|
315
|
+
{
|
|
316
|
+
// Scale to a small argument for an efficient Taylor series,
|
|
317
|
+
// implemented as a hypergeometric function. Use a standard
|
|
318
|
+
// divide by three identity a certain number of times.
|
|
319
|
+
// Here we use division by 3^9 --> (19683 = 3^9).
|
|
320
|
+
|
|
321
|
+
constexpr si_type n_scale = 9;
|
|
322
|
+
constexpr si_type n_three_pow_scale = static_cast<si_type>(19683L);
|
|
323
|
+
|
|
324
|
+
eval_divide(xx, n_three_pow_scale);
|
|
325
|
+
|
|
326
|
+
// Now with small arguments, we are ready for a series expansion.
|
|
327
|
+
eval_multiply(t, xx, xx);
|
|
328
|
+
eval_divide(t, si_type(-4));
|
|
329
|
+
T t2;
|
|
330
|
+
t2 = fp_type(1.5);
|
|
331
|
+
hyp0F1(result, t2, t);
|
|
332
|
+
BOOST_MATH_INSTRUMENT_CODE(result.str(0, std::ios_base::scientific));
|
|
333
|
+
eval_multiply(result, xx);
|
|
334
|
+
|
|
335
|
+
// Convert back using multiple angle identity.
|
|
336
|
+
for (std::int32_t k = static_cast<std::int32_t>(0); k < n_scale; k++)
|
|
337
|
+
{
|
|
338
|
+
// Rescale the cosine value using the multiple angle identity.
|
|
339
|
+
eval_multiply(t2, result, ui_type(3));
|
|
340
|
+
eval_multiply(t, result, result);
|
|
341
|
+
eval_multiply(t, result);
|
|
342
|
+
eval_multiply(t, ui_type(4));
|
|
343
|
+
eval_subtract(result, t2, t);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
if (b_negate_sin)
|
|
348
|
+
result.negate();
|
|
349
|
+
BOOST_MATH_INSTRUMENT_CODE(result.str(0, std::ios_base::scientific));
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
template <class T>
|
|
353
|
+
void eval_cos(T& result, const T& x)
|
|
354
|
+
{
|
|
355
|
+
static_assert(number_category<T>::value == number_kind_floating_point, "The cos function is only valid for floating point types.");
|
|
356
|
+
if (&result == &x)
|
|
357
|
+
{
|
|
358
|
+
T temp;
|
|
359
|
+
eval_cos(temp, x);
|
|
360
|
+
result = temp;
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
using si_type = typename boost::multiprecision::detail::canonical<std::int32_t, T>::type ;
|
|
365
|
+
using ui_type = typename boost::multiprecision::detail::canonical<std::uint32_t, T>::type;
|
|
366
|
+
|
|
367
|
+
switch (eval_fpclassify(x))
|
|
368
|
+
{
|
|
369
|
+
case FP_INFINITE:
|
|
370
|
+
case FP_NAN:
|
|
371
|
+
BOOST_IF_CONSTEXPR(std::numeric_limits<number<T, et_on> >::has_quiet_NaN)
|
|
372
|
+
{
|
|
373
|
+
result = std::numeric_limits<number<T, et_on> >::quiet_NaN().backend();
|
|
374
|
+
errno = EDOM;
|
|
375
|
+
}
|
|
376
|
+
else
|
|
377
|
+
BOOST_MP_THROW_EXCEPTION(std::domain_error("Result is undefined or complex and there is no NaN for this number type."));
|
|
378
|
+
return;
|
|
379
|
+
case FP_ZERO:
|
|
380
|
+
result = ui_type(1);
|
|
381
|
+
return;
|
|
382
|
+
default:;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
// Local copy of the argument
|
|
386
|
+
T xx = x;
|
|
387
|
+
|
|
388
|
+
// Analyze and prepare the phase of the argument.
|
|
389
|
+
// Make a local, positive copy of the argument, xx.
|
|
390
|
+
// The argument xx will be reduced to 0 <= xx <= pi/2.
|
|
391
|
+
bool b_negate_cos = false;
|
|
392
|
+
|
|
393
|
+
if (eval_get_sign(x) < 0)
|
|
394
|
+
{
|
|
395
|
+
xx.negate();
|
|
396
|
+
}
|
|
397
|
+
BOOST_MATH_INSTRUMENT_CODE(xx.str(0, std::ios_base::scientific));
|
|
398
|
+
|
|
399
|
+
T n_pi, t;
|
|
400
|
+
T half_pi = get_constant_pi<T>();
|
|
401
|
+
eval_ldexp(half_pi, half_pi, -1); // divide by 2
|
|
402
|
+
// Remove even multiples of pi.
|
|
403
|
+
if (xx.compare(half_pi) > 0)
|
|
404
|
+
{
|
|
405
|
+
eval_divide(t, xx, half_pi);
|
|
406
|
+
eval_trunc(n_pi, t);
|
|
407
|
+
//
|
|
408
|
+
// If n_pi is > 1/epsilon, then it is no longer an exact integer value
|
|
409
|
+
// but an approximation. As a result we can no longer reliably reduce
|
|
410
|
+
// xx to 0 <= xx < pi/2, nor can we tell the sign of the result as we need
|
|
411
|
+
// n_pi % 4 for that, but that will always be zero in this situation.
|
|
412
|
+
// We could use a higher precision type for n_pi, along with division at
|
|
413
|
+
// higher precision, but that's rather expensive. So for now we do not support
|
|
414
|
+
// this, and will see if anyone complains and has a legitimate use case.
|
|
415
|
+
//
|
|
416
|
+
if (n_pi.compare(get_constant_one_over_epsilon<T>()) > 0)
|
|
417
|
+
{
|
|
418
|
+
result = ui_type(1);
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
BOOST_MATH_INSTRUMENT_CODE(n_pi.str(0, std::ios_base::scientific));
|
|
422
|
+
t = ui_type(4);
|
|
423
|
+
eval_fmod(t, n_pi, t);
|
|
424
|
+
|
|
425
|
+
bool b_go_down = false;
|
|
426
|
+
if (t.compare(ui_type(0)) == 0)
|
|
427
|
+
{
|
|
428
|
+
b_go_down = true;
|
|
429
|
+
}
|
|
430
|
+
else if (t.compare(ui_type(1)) == 0)
|
|
431
|
+
{
|
|
432
|
+
b_negate_cos = true;
|
|
433
|
+
}
|
|
434
|
+
else if (t.compare(ui_type(2)) == 0)
|
|
435
|
+
{
|
|
436
|
+
b_go_down = true;
|
|
437
|
+
b_negate_cos = true;
|
|
438
|
+
}
|
|
439
|
+
else
|
|
440
|
+
{
|
|
441
|
+
BOOST_MP_ASSERT(t.compare(ui_type(3)) == 0);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
if (b_go_down)
|
|
445
|
+
eval_increment(n_pi);
|
|
446
|
+
|
|
447
|
+
reduce_n_half_pi(xx, n_pi, b_go_down);
|
|
448
|
+
//
|
|
449
|
+
// Post reduction we may be a few ulp below zero or above pi/2
|
|
450
|
+
// given that n_pi was calculated at working precision and not
|
|
451
|
+
// at the higher precision used for reduction. Correct that now:
|
|
452
|
+
//
|
|
453
|
+
if (eval_get_sign(xx) < 0)
|
|
454
|
+
{
|
|
455
|
+
xx.negate();
|
|
456
|
+
b_negate_cos = !b_negate_cos;
|
|
457
|
+
}
|
|
458
|
+
if (xx.compare(half_pi) > 0)
|
|
459
|
+
{
|
|
460
|
+
eval_ldexp(half_pi, half_pi, 1);
|
|
461
|
+
eval_subtract(xx, half_pi, xx);
|
|
462
|
+
eval_ldexp(half_pi, half_pi, -1);
|
|
463
|
+
}
|
|
464
|
+
BOOST_MP_ASSERT(xx.compare(half_pi) <= 0);
|
|
465
|
+
BOOST_MP_ASSERT(xx.compare(ui_type(0)) >= 0);
|
|
466
|
+
}
|
|
467
|
+
else
|
|
468
|
+
{
|
|
469
|
+
n_pi = ui_type(1);
|
|
470
|
+
reduce_n_half_pi(xx, n_pi, true);
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
const bool b_zero = eval_get_sign(xx) == 0;
|
|
474
|
+
|
|
475
|
+
if (b_zero)
|
|
476
|
+
{
|
|
477
|
+
result = si_type(0);
|
|
478
|
+
}
|
|
479
|
+
else
|
|
480
|
+
{
|
|
481
|
+
eval_sin(result, xx);
|
|
482
|
+
}
|
|
483
|
+
if (b_negate_cos)
|
|
484
|
+
result.negate();
|
|
485
|
+
BOOST_MATH_INSTRUMENT_CODE(result.str(0, std::ios_base::scientific));
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
template <class T>
|
|
489
|
+
void eval_tan(T& result, const T& x)
|
|
490
|
+
{
|
|
491
|
+
static_assert(number_category<T>::value == number_kind_floating_point, "The tan function is only valid for floating point types.");
|
|
492
|
+
if (&result == &x)
|
|
493
|
+
{
|
|
494
|
+
T temp;
|
|
495
|
+
eval_tan(temp, x);
|
|
496
|
+
result = temp;
|
|
497
|
+
return;
|
|
498
|
+
}
|
|
499
|
+
T t;
|
|
500
|
+
eval_sin(result, x);
|
|
501
|
+
eval_cos(t, x);
|
|
502
|
+
eval_divide(result, t);
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
template <class T>
|
|
506
|
+
void hyp2F1(T& result, const T& a, const T& b, const T& c, const T& x)
|
|
507
|
+
{
|
|
508
|
+
// Compute the series representation of hyperg_2f1 taken from
|
|
509
|
+
// Abramowitz and Stegun 15.1.1.
|
|
510
|
+
// There are no checks on input range or parameter boundaries.
|
|
511
|
+
|
|
512
|
+
using ui_type = typename boost::multiprecision::detail::canonical<std::uint32_t, T>::type;
|
|
513
|
+
|
|
514
|
+
T x_pow_n_div_n_fact(x);
|
|
515
|
+
T pochham_a(a);
|
|
516
|
+
T pochham_b(b);
|
|
517
|
+
T pochham_c(c);
|
|
518
|
+
T ap(a);
|
|
519
|
+
T bp(b);
|
|
520
|
+
T cp(c);
|
|
521
|
+
|
|
522
|
+
eval_multiply(result, pochham_a, pochham_b);
|
|
523
|
+
eval_divide(result, pochham_c);
|
|
524
|
+
eval_multiply(result, x_pow_n_div_n_fact);
|
|
525
|
+
eval_add(result, ui_type(1));
|
|
526
|
+
|
|
527
|
+
T lim;
|
|
528
|
+
eval_ldexp(lim, result, 1 - boost::multiprecision::detail::digits2<number<T, et_on> >::value());
|
|
529
|
+
|
|
530
|
+
if (eval_get_sign(lim) < 0)
|
|
531
|
+
lim.negate();
|
|
532
|
+
|
|
533
|
+
ui_type n;
|
|
534
|
+
T term;
|
|
535
|
+
|
|
536
|
+
const unsigned series_limit =
|
|
537
|
+
boost::multiprecision::detail::digits2<number<T, et_on> >::value() < 100
|
|
538
|
+
? 100
|
|
539
|
+
: boost::multiprecision::detail::digits2<number<T, et_on> >::value();
|
|
540
|
+
// Series expansion of hyperg_2f1(a, b; c; x).
|
|
541
|
+
for (n = 2; n < series_limit; ++n)
|
|
542
|
+
{
|
|
543
|
+
eval_multiply(x_pow_n_div_n_fact, x);
|
|
544
|
+
eval_divide(x_pow_n_div_n_fact, n);
|
|
545
|
+
|
|
546
|
+
eval_increment(ap);
|
|
547
|
+
eval_multiply(pochham_a, ap);
|
|
548
|
+
eval_increment(bp);
|
|
549
|
+
eval_multiply(pochham_b, bp);
|
|
550
|
+
eval_increment(cp);
|
|
551
|
+
eval_multiply(pochham_c, cp);
|
|
552
|
+
|
|
553
|
+
eval_multiply(term, pochham_a, pochham_b);
|
|
554
|
+
eval_divide(term, pochham_c);
|
|
555
|
+
eval_multiply(term, x_pow_n_div_n_fact);
|
|
556
|
+
eval_add(result, term);
|
|
557
|
+
|
|
558
|
+
if (eval_get_sign(term) < 0)
|
|
559
|
+
term.negate();
|
|
560
|
+
if (lim.compare(term) >= 0)
|
|
561
|
+
break;
|
|
562
|
+
}
|
|
563
|
+
if (n > series_limit)
|
|
564
|
+
BOOST_MP_THROW_EXCEPTION(std::runtime_error("H2F1 failed to converge."));
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
template <class T>
|
|
568
|
+
void eval_asin(T& result, const T& x)
|
|
569
|
+
{
|
|
570
|
+
static_assert(number_category<T>::value == number_kind_floating_point, "The asin function is only valid for floating point types.");
|
|
571
|
+
using ui_type = typename boost::multiprecision::detail::canonical<std::uint32_t, T>::type;
|
|
572
|
+
using fp_type = typename std::tuple_element<0, typename T::float_types>::type ;
|
|
573
|
+
|
|
574
|
+
if (&result == &x)
|
|
575
|
+
{
|
|
576
|
+
T t(x);
|
|
577
|
+
eval_asin(result, t);
|
|
578
|
+
return;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
switch (eval_fpclassify(x))
|
|
582
|
+
{
|
|
583
|
+
case FP_NAN:
|
|
584
|
+
case FP_INFINITE:
|
|
585
|
+
BOOST_IF_CONSTEXPR(std::numeric_limits<number<T, et_on> >::has_quiet_NaN)
|
|
586
|
+
{
|
|
587
|
+
result = std::numeric_limits<number<T, et_on> >::quiet_NaN().backend();
|
|
588
|
+
errno = EDOM;
|
|
589
|
+
}
|
|
590
|
+
else
|
|
591
|
+
BOOST_MP_THROW_EXCEPTION(std::domain_error("Result is undefined or complex and there is no NaN for this number type."));
|
|
592
|
+
return;
|
|
593
|
+
case FP_ZERO:
|
|
594
|
+
result = x;
|
|
595
|
+
return;
|
|
596
|
+
default:;
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
const bool b_neg = eval_get_sign(x) < 0;
|
|
600
|
+
|
|
601
|
+
T xx(x);
|
|
602
|
+
if (b_neg)
|
|
603
|
+
xx.negate();
|
|
604
|
+
|
|
605
|
+
int c = xx.compare(ui_type(1));
|
|
606
|
+
if (c > 0)
|
|
607
|
+
{
|
|
608
|
+
BOOST_IF_CONSTEXPR(std::numeric_limits<number<T, et_on> >::has_quiet_NaN)
|
|
609
|
+
{
|
|
610
|
+
result = std::numeric_limits<number<T, et_on> >::quiet_NaN().backend();
|
|
611
|
+
errno = EDOM;
|
|
612
|
+
}
|
|
613
|
+
else
|
|
614
|
+
BOOST_MP_THROW_EXCEPTION(std::domain_error("Result is undefined or complex and there is no NaN for this number type."));
|
|
615
|
+
return;
|
|
616
|
+
}
|
|
617
|
+
else if (c == 0)
|
|
618
|
+
{
|
|
619
|
+
result = get_constant_pi<T>();
|
|
620
|
+
eval_ldexp(result, result, -1);
|
|
621
|
+
if (b_neg)
|
|
622
|
+
result.negate();
|
|
623
|
+
return;
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
if (xx.compare(fp_type(1e-3)) < 0)
|
|
627
|
+
{
|
|
628
|
+
// http://functions.wolfram.com/ElementaryFunctions/ArcSin/26/01/01/
|
|
629
|
+
eval_multiply(xx, xx);
|
|
630
|
+
T t1, t2;
|
|
631
|
+
t1 = fp_type(0.5f);
|
|
632
|
+
t2 = fp_type(1.5f);
|
|
633
|
+
hyp2F1(result, t1, t1, t2, xx);
|
|
634
|
+
eval_multiply(result, x);
|
|
635
|
+
return;
|
|
636
|
+
}
|
|
637
|
+
else if (xx.compare(fp_type(1 - 5e-2f)) > 0)
|
|
638
|
+
{
|
|
639
|
+
// http://functions.wolfram.com/ElementaryFunctions/ArcSin/26/01/01/
|
|
640
|
+
// This branch is simlilar in complexity to Newton iterations down to
|
|
641
|
+
// the above limit. It is *much* more accurate.
|
|
642
|
+
T dx1;
|
|
643
|
+
T t1, t2;
|
|
644
|
+
eval_subtract(dx1, ui_type(1), xx);
|
|
645
|
+
t1 = fp_type(0.5f);
|
|
646
|
+
t2 = fp_type(1.5f);
|
|
647
|
+
eval_ldexp(dx1, dx1, -1);
|
|
648
|
+
hyp2F1(result, t1, t1, t2, dx1);
|
|
649
|
+
eval_ldexp(dx1, dx1, 2);
|
|
650
|
+
eval_sqrt(t1, dx1);
|
|
651
|
+
eval_multiply(result, t1);
|
|
652
|
+
eval_ldexp(t1, get_constant_pi<T>(), -1);
|
|
653
|
+
result.negate();
|
|
654
|
+
eval_add(result, t1);
|
|
655
|
+
if (b_neg)
|
|
656
|
+
result.negate();
|
|
657
|
+
return;
|
|
658
|
+
}
|
|
659
|
+
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
|
|
660
|
+
using guess_type = typename boost::multiprecision::detail::canonical<long double, T>::type;
|
|
661
|
+
#else
|
|
662
|
+
using guess_type = fp_type;
|
|
663
|
+
#endif
|
|
664
|
+
// Get initial estimate using standard math function asin.
|
|
665
|
+
guess_type dd;
|
|
666
|
+
eval_convert_to(&dd, xx);
|
|
667
|
+
|
|
668
|
+
result = (guess_type)(std::asin(dd));
|
|
669
|
+
|
|
670
|
+
// Newton-Raphson iteration, we should double our precision with each iteration,
|
|
671
|
+
// in practice this seems to not quite work in all cases... so terminate when we
|
|
672
|
+
// have at least 2/3 of the digits correct on the assumption that the correction
|
|
673
|
+
// we've just added will finish the job...
|
|
674
|
+
|
|
675
|
+
std::intmax_t current_precision = eval_ilogb(result);
|
|
676
|
+
std::intmax_t target_precision = std::numeric_limits<number<T> >::is_specialized ?
|
|
677
|
+
current_precision - 1 - (std::numeric_limits<number<T> >::digits * 2) / 3
|
|
678
|
+
: current_precision - 1 - (boost::multiprecision::detail::digits2<number<T> >::value() * 2) / 3;
|
|
679
|
+
|
|
680
|
+
// Newton-Raphson iteration
|
|
681
|
+
while (current_precision > target_precision)
|
|
682
|
+
{
|
|
683
|
+
T sine, cosine;
|
|
684
|
+
eval_sin(sine, result);
|
|
685
|
+
eval_cos(cosine, result);
|
|
686
|
+
eval_subtract(sine, xx);
|
|
687
|
+
eval_divide(sine, cosine);
|
|
688
|
+
eval_subtract(result, sine);
|
|
689
|
+
current_precision = eval_ilogb(sine);
|
|
690
|
+
if (current_precision <= (std::numeric_limits<typename T::exponent_type>::min)() + 1)
|
|
691
|
+
break;
|
|
692
|
+
}
|
|
693
|
+
if (b_neg)
|
|
694
|
+
result.negate();
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
template <class T>
|
|
698
|
+
inline void eval_acos(T& result, const T& x)
|
|
699
|
+
{
|
|
700
|
+
static_assert(number_category<T>::value == number_kind_floating_point, "The acos function is only valid for floating point types.");
|
|
701
|
+
using ui_type = typename boost::multiprecision::detail::canonical<std::uint32_t, T>::type;
|
|
702
|
+
|
|
703
|
+
switch (eval_fpclassify(x))
|
|
704
|
+
{
|
|
705
|
+
case FP_NAN:
|
|
706
|
+
case FP_INFINITE:
|
|
707
|
+
BOOST_IF_CONSTEXPR(std::numeric_limits<number<T, et_on> >::has_quiet_NaN)
|
|
708
|
+
{
|
|
709
|
+
result = std::numeric_limits<number<T, et_on> >::quiet_NaN().backend();
|
|
710
|
+
errno = EDOM;
|
|
711
|
+
}
|
|
712
|
+
else
|
|
713
|
+
BOOST_MP_THROW_EXCEPTION(std::domain_error("Result is undefined or complex and there is no NaN for this number type."));
|
|
714
|
+
return;
|
|
715
|
+
case FP_ZERO:
|
|
716
|
+
result = get_constant_pi<T>();
|
|
717
|
+
eval_ldexp(result, result, -1); // divide by two.
|
|
718
|
+
return;
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
T xx;
|
|
722
|
+
eval_abs(xx, x);
|
|
723
|
+
int c = xx.compare(ui_type(1));
|
|
724
|
+
|
|
725
|
+
if (c > 0)
|
|
726
|
+
{
|
|
727
|
+
BOOST_IF_CONSTEXPR(std::numeric_limits<number<T, et_on> >::has_quiet_NaN)
|
|
728
|
+
{
|
|
729
|
+
result = std::numeric_limits<number<T, et_on> >::quiet_NaN().backend();
|
|
730
|
+
errno = EDOM;
|
|
731
|
+
}
|
|
732
|
+
else
|
|
733
|
+
BOOST_MP_THROW_EXCEPTION(std::domain_error("Result is undefined or complex and there is no NaN for this number type."));
|
|
734
|
+
return;
|
|
735
|
+
}
|
|
736
|
+
else if (c == 0)
|
|
737
|
+
{
|
|
738
|
+
if (eval_get_sign(x) < 0)
|
|
739
|
+
result = get_constant_pi<T>();
|
|
740
|
+
else
|
|
741
|
+
result = ui_type(0);
|
|
742
|
+
return;
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
using fp_type = typename std::tuple_element<0, typename T::float_types>::type;
|
|
746
|
+
|
|
747
|
+
if (xx.compare(fp_type(1e-3)) < 0)
|
|
748
|
+
{
|
|
749
|
+
// https://functions.wolfram.com/ElementaryFunctions/ArcCos/26/01/01/
|
|
750
|
+
eval_multiply(xx, xx);
|
|
751
|
+
T t1, t2;
|
|
752
|
+
t1 = fp_type(0.5f);
|
|
753
|
+
t2 = fp_type(1.5f);
|
|
754
|
+
hyp2F1(result, t1, t1, t2, xx);
|
|
755
|
+
eval_multiply(result, x);
|
|
756
|
+
eval_ldexp(t1, get_constant_pi<T>(), -1);
|
|
757
|
+
result.negate();
|
|
758
|
+
eval_add(result, t1);
|
|
759
|
+
return;
|
|
760
|
+
}
|
|
761
|
+
if (eval_get_sign(x) < 0)
|
|
762
|
+
{
|
|
763
|
+
eval_acos(result, xx);
|
|
764
|
+
result.negate();
|
|
765
|
+
eval_add(result, get_constant_pi<T>());
|
|
766
|
+
return;
|
|
767
|
+
}
|
|
768
|
+
else if (xx.compare(fp_type(0.85)) > 0)
|
|
769
|
+
{
|
|
770
|
+
// https://functions.wolfram.com/ElementaryFunctions/ArcCos/26/01/01/
|
|
771
|
+
// This branch is simlilar in complexity to Newton iterations down to
|
|
772
|
+
// the above limit. It is *much* more accurate.
|
|
773
|
+
T dx1;
|
|
774
|
+
T t1, t2;
|
|
775
|
+
eval_subtract(dx1, ui_type(1), xx);
|
|
776
|
+
t1 = fp_type(0.5f);
|
|
777
|
+
t2 = fp_type(1.5f);
|
|
778
|
+
eval_ldexp(dx1, dx1, -1);
|
|
779
|
+
hyp2F1(result, t1, t1, t2, dx1);
|
|
780
|
+
eval_ldexp(dx1, dx1, 2);
|
|
781
|
+
eval_sqrt(t1, dx1);
|
|
782
|
+
eval_multiply(result, t1);
|
|
783
|
+
return;
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
|
|
787
|
+
using guess_type = typename boost::multiprecision::detail::canonical<long double, T>::type;
|
|
788
|
+
#else
|
|
789
|
+
using guess_type = fp_type;
|
|
790
|
+
#endif
|
|
791
|
+
// Get initial estimate using standard math function asin.
|
|
792
|
+
guess_type dd;
|
|
793
|
+
eval_convert_to(&dd, xx);
|
|
794
|
+
|
|
795
|
+
result = (guess_type)(std::acos(dd));
|
|
796
|
+
|
|
797
|
+
// Newton-Raphson iteration, we should double our precision with each iteration,
|
|
798
|
+
// in practice this seems to not quite work in all cases... so terminate when we
|
|
799
|
+
// have at least 2/3 of the digits correct on the assumption that the correction
|
|
800
|
+
// we've just added will finish the job...
|
|
801
|
+
|
|
802
|
+
std::intmax_t current_precision = eval_ilogb(result);
|
|
803
|
+
std::intmax_t target_precision = std::numeric_limits<number<T> >::is_specialized ?
|
|
804
|
+
current_precision - 1 - (std::numeric_limits<number<T> >::digits * 2) / 3
|
|
805
|
+
: current_precision - 1 - (boost::multiprecision::detail::digits2<number<T> >::value() * 2) / 3;
|
|
806
|
+
|
|
807
|
+
// Newton-Raphson iteration
|
|
808
|
+
while (current_precision > target_precision)
|
|
809
|
+
{
|
|
810
|
+
T sine, cosine;
|
|
811
|
+
eval_sin(sine, result);
|
|
812
|
+
eval_cos(cosine, result);
|
|
813
|
+
eval_subtract(cosine, xx);
|
|
814
|
+
cosine.negate();
|
|
815
|
+
eval_divide(cosine, sine);
|
|
816
|
+
eval_subtract(result, cosine);
|
|
817
|
+
current_precision = eval_ilogb(cosine);
|
|
818
|
+
if (current_precision <= (std::numeric_limits<typename T::exponent_type>::min)() + 1)
|
|
819
|
+
break;
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
template <class T>
|
|
824
|
+
void eval_atan(T& result, const T& x)
|
|
825
|
+
{
|
|
826
|
+
static_assert(number_category<T>::value == number_kind_floating_point, "The atan function is only valid for floating point types.");
|
|
827
|
+
using si_type = typename boost::multiprecision::detail::canonical<std::int32_t, T>::type ;
|
|
828
|
+
using ui_type = typename boost::multiprecision::detail::canonical<std::uint32_t, T>::type;
|
|
829
|
+
using fp_type = typename std::tuple_element<0, typename T::float_types>::type ;
|
|
830
|
+
|
|
831
|
+
switch (eval_fpclassify(x))
|
|
832
|
+
{
|
|
833
|
+
case FP_NAN:
|
|
834
|
+
result = x;
|
|
835
|
+
errno = EDOM;
|
|
836
|
+
return;
|
|
837
|
+
case FP_ZERO:
|
|
838
|
+
result = x;
|
|
839
|
+
return;
|
|
840
|
+
case FP_INFINITE:
|
|
841
|
+
if (eval_get_sign(x) < 0)
|
|
842
|
+
{
|
|
843
|
+
eval_ldexp(result, get_constant_pi<T>(), -1);
|
|
844
|
+
result.negate();
|
|
845
|
+
}
|
|
846
|
+
else
|
|
847
|
+
eval_ldexp(result, get_constant_pi<T>(), -1);
|
|
848
|
+
return;
|
|
849
|
+
default:;
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
const bool b_neg = eval_get_sign(x) < 0;
|
|
853
|
+
|
|
854
|
+
T xx(x);
|
|
855
|
+
if (b_neg)
|
|
856
|
+
xx.negate();
|
|
857
|
+
|
|
858
|
+
if (xx.compare(fp_type(0.1)) < 0)
|
|
859
|
+
{
|
|
860
|
+
T t1, t2, t3;
|
|
861
|
+
t1 = ui_type(1);
|
|
862
|
+
t2 = fp_type(0.5f);
|
|
863
|
+
t3 = fp_type(1.5f);
|
|
864
|
+
eval_multiply(xx, xx);
|
|
865
|
+
xx.negate();
|
|
866
|
+
hyp2F1(result, t1, t2, t3, xx);
|
|
867
|
+
eval_multiply(result, x);
|
|
868
|
+
return;
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
if (xx.compare(fp_type(10)) > 0)
|
|
872
|
+
{
|
|
873
|
+
T t1, t2, t3;
|
|
874
|
+
t1 = fp_type(0.5f);
|
|
875
|
+
t2 = ui_type(1u);
|
|
876
|
+
t3 = fp_type(1.5f);
|
|
877
|
+
eval_multiply(xx, xx);
|
|
878
|
+
eval_divide(xx, si_type(-1), xx);
|
|
879
|
+
hyp2F1(result, t1, t2, t3, xx);
|
|
880
|
+
eval_divide(result, x);
|
|
881
|
+
if (!b_neg)
|
|
882
|
+
result.negate();
|
|
883
|
+
eval_ldexp(t1, get_constant_pi<T>(), -1);
|
|
884
|
+
eval_add(result, t1);
|
|
885
|
+
if (b_neg)
|
|
886
|
+
result.negate();
|
|
887
|
+
return;
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
// Get initial estimate using standard math function atan.
|
|
891
|
+
fp_type d;
|
|
892
|
+
eval_convert_to(&d, xx);
|
|
893
|
+
result = fp_type(std::atan(d));
|
|
894
|
+
|
|
895
|
+
// Newton-Raphson iteration, we should double our precision with each iteration,
|
|
896
|
+
// in practice this seems to not quite work in all cases... so terminate when we
|
|
897
|
+
// have at least 2/3 of the digits correct on the assumption that the correction
|
|
898
|
+
// we've just added will finish the job...
|
|
899
|
+
|
|
900
|
+
std::intmax_t current_precision = eval_ilogb(result);
|
|
901
|
+
std::intmax_t target_precision = std::numeric_limits<number<T> >::is_specialized ?
|
|
902
|
+
current_precision - 1 - (std::numeric_limits<number<T> >::digits * 2) / 3
|
|
903
|
+
: current_precision - 1 - (boost::multiprecision::detail::digits2<number<T> >::value() * 2) / 3;
|
|
904
|
+
|
|
905
|
+
T s, c, t;
|
|
906
|
+
while (current_precision > target_precision)
|
|
907
|
+
{
|
|
908
|
+
eval_sin(s, result);
|
|
909
|
+
eval_cos(c, result);
|
|
910
|
+
eval_multiply(t, xx, c);
|
|
911
|
+
eval_subtract(t, s);
|
|
912
|
+
eval_multiply(s, t, c);
|
|
913
|
+
eval_add(result, s);
|
|
914
|
+
current_precision = eval_ilogb(s);
|
|
915
|
+
if (current_precision <= (std::numeric_limits<typename T::exponent_type>::min)() + 1)
|
|
916
|
+
break;
|
|
917
|
+
}
|
|
918
|
+
if (b_neg)
|
|
919
|
+
result.negate();
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
template <class T>
|
|
923
|
+
void eval_atan2(T& result, const T& y, const T& x)
|
|
924
|
+
{
|
|
925
|
+
static_assert(number_category<T>::value == number_kind_floating_point, "The atan2 function is only valid for floating point types.");
|
|
926
|
+
if (&result == &y)
|
|
927
|
+
{
|
|
928
|
+
T temp(y);
|
|
929
|
+
eval_atan2(result, temp, x);
|
|
930
|
+
return;
|
|
931
|
+
}
|
|
932
|
+
else if (&result == &x)
|
|
933
|
+
{
|
|
934
|
+
T temp(x);
|
|
935
|
+
eval_atan2(result, y, temp);
|
|
936
|
+
return;
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
using ui_type = typename boost::multiprecision::detail::canonical<std::uint32_t, T>::type;
|
|
940
|
+
|
|
941
|
+
switch (eval_fpclassify(y))
|
|
942
|
+
{
|
|
943
|
+
case FP_NAN:
|
|
944
|
+
result = y;
|
|
945
|
+
errno = EDOM;
|
|
946
|
+
return;
|
|
947
|
+
case FP_ZERO:
|
|
948
|
+
{
|
|
949
|
+
if (eval_signbit(x))
|
|
950
|
+
{
|
|
951
|
+
result = get_constant_pi<T>();
|
|
952
|
+
if (eval_signbit(y))
|
|
953
|
+
result.negate();
|
|
954
|
+
}
|
|
955
|
+
else
|
|
956
|
+
{
|
|
957
|
+
result = y; // Note we allow atan2(0,0) to be +-zero, even though it's mathematically undefined
|
|
958
|
+
}
|
|
959
|
+
return;
|
|
960
|
+
}
|
|
961
|
+
case FP_INFINITE:
|
|
962
|
+
{
|
|
963
|
+
if (eval_fpclassify(x) == FP_INFINITE)
|
|
964
|
+
{
|
|
965
|
+
if (eval_signbit(x))
|
|
966
|
+
{
|
|
967
|
+
// 3Pi/4
|
|
968
|
+
eval_ldexp(result, get_constant_pi<T>(), -2);
|
|
969
|
+
eval_subtract(result, get_constant_pi<T>());
|
|
970
|
+
if (eval_get_sign(y) >= 0)
|
|
971
|
+
result.negate();
|
|
972
|
+
}
|
|
973
|
+
else
|
|
974
|
+
{
|
|
975
|
+
// Pi/4
|
|
976
|
+
eval_ldexp(result, get_constant_pi<T>(), -2);
|
|
977
|
+
if (eval_get_sign(y) < 0)
|
|
978
|
+
result.negate();
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
else
|
|
982
|
+
{
|
|
983
|
+
eval_ldexp(result, get_constant_pi<T>(), -1);
|
|
984
|
+
if (eval_get_sign(y) < 0)
|
|
985
|
+
result.negate();
|
|
986
|
+
}
|
|
987
|
+
return;
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
switch (eval_fpclassify(x))
|
|
992
|
+
{
|
|
993
|
+
case FP_NAN:
|
|
994
|
+
result = x;
|
|
995
|
+
errno = EDOM;
|
|
996
|
+
return;
|
|
997
|
+
case FP_ZERO:
|
|
998
|
+
{
|
|
999
|
+
eval_ldexp(result, get_constant_pi<T>(), -1);
|
|
1000
|
+
if (eval_get_sign(y) < 0)
|
|
1001
|
+
result.negate();
|
|
1002
|
+
return;
|
|
1003
|
+
}
|
|
1004
|
+
case FP_INFINITE:
|
|
1005
|
+
if (eval_get_sign(x) > 0)
|
|
1006
|
+
result = ui_type(0);
|
|
1007
|
+
else
|
|
1008
|
+
result = get_constant_pi<T>();
|
|
1009
|
+
if (eval_get_sign(y) < 0)
|
|
1010
|
+
result.negate();
|
|
1011
|
+
return;
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
T xx;
|
|
1015
|
+
eval_divide(xx, y, x);
|
|
1016
|
+
if (eval_get_sign(xx) < 0)
|
|
1017
|
+
xx.negate();
|
|
1018
|
+
|
|
1019
|
+
eval_atan(result, xx);
|
|
1020
|
+
|
|
1021
|
+
// Determine quadrant (sign) based on signs of x, y
|
|
1022
|
+
const bool y_neg = eval_get_sign(y) < 0;
|
|
1023
|
+
const bool x_neg = eval_get_sign(x) < 0;
|
|
1024
|
+
|
|
1025
|
+
if (y_neg != x_neg)
|
|
1026
|
+
result.negate();
|
|
1027
|
+
|
|
1028
|
+
if (x_neg)
|
|
1029
|
+
{
|
|
1030
|
+
if (y_neg)
|
|
1031
|
+
eval_subtract(result, get_constant_pi<T>());
|
|
1032
|
+
else
|
|
1033
|
+
eval_add(result, get_constant_pi<T>());
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
template <class T, class A>
|
|
1037
|
+
inline typename std::enable_if<boost::multiprecision::detail::is_arithmetic<A>::value, void>::type eval_atan2(T& result, const T& x, const A& a)
|
|
1038
|
+
{
|
|
1039
|
+
using canonical_type = typename boost::multiprecision::detail::canonical<A, T>::type ;
|
|
1040
|
+
using cast_type = typename std::conditional<std::is_same<A, canonical_type>::value, T, canonical_type>::type;
|
|
1041
|
+
cast_type c;
|
|
1042
|
+
c = a;
|
|
1043
|
+
eval_atan2(result, x, c);
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
template <class T, class A>
|
|
1047
|
+
inline typename std::enable_if<boost::multiprecision::detail::is_arithmetic<A>::value, void>::type eval_atan2(T& result, const A& x, const T& a)
|
|
1048
|
+
{
|
|
1049
|
+
using canonical_type = typename boost::multiprecision::detail::canonical<A, T>::type ;
|
|
1050
|
+
using cast_type = typename std::conditional<std::is_same<A, canonical_type>::value, T, canonical_type>::type;
|
|
1051
|
+
cast_type c;
|
|
1052
|
+
c = x;
|
|
1053
|
+
eval_atan2(result, c, a);
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
#ifdef BOOST_MSVC
|
|
1057
|
+
#pragma warning(pop)
|
|
1058
|
+
#endif
|