boost.cxx 0.0.2 → 1.90.1

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.
Files changed (327) hide show
  1. package/README.md +29 -2
  2. package/boost/cast.hpp +20 -0
  3. package/boost/numeric/conversion/bounds.hpp +24 -0
  4. package/boost/numeric/conversion/cast.hpp +61 -0
  5. package/boost/numeric/conversion/conversion_traits.hpp +32 -0
  6. package/boost/numeric/conversion/converter.hpp +68 -0
  7. package/boost/numeric/conversion/converter_policies.hpp +194 -0
  8. package/boost/numeric/conversion/detail/bounds.hpp +58 -0
  9. package/boost/numeric/conversion/detail/conversion_traits.hpp +97 -0
  10. package/boost/numeric/conversion/detail/converter.hpp +593 -0
  11. package/boost/numeric/conversion/detail/int_float_mixture.hpp +72 -0
  12. package/boost/numeric/conversion/detail/is_subranged.hpp +234 -0
  13. package/boost/numeric/conversion/detail/meta.hpp +120 -0
  14. package/boost/numeric/conversion/detail/numeric_cast_traits.hpp +138 -0
  15. package/boost/numeric/conversion/detail/old_numeric_cast.hpp +308 -0
  16. package/boost/numeric/conversion/detail/preprocessed/numeric_cast_traits_common.hpp +1741 -0
  17. package/boost/numeric/conversion/detail/preprocessed/numeric_cast_traits_long_long.hpp +347 -0
  18. package/boost/numeric/conversion/detail/sign_mixture.hpp +72 -0
  19. package/boost/numeric/conversion/detail/udt_builtin_mixture.hpp +69 -0
  20. package/boost/numeric/conversion/int_float_mixture.hpp +30 -0
  21. package/boost/numeric/conversion/int_float_mixture_enum.hpp +29 -0
  22. package/boost/numeric/conversion/is_subranged.hpp +27 -0
  23. package/boost/numeric/conversion/numeric_cast_traits.hpp +31 -0
  24. package/boost/numeric/conversion/sign_mixture.hpp +30 -0
  25. package/boost/numeric/conversion/sign_mixture_enum.hpp +29 -0
  26. package/boost/numeric/conversion/udt_builtin_mixture.hpp +28 -0
  27. package/boost/numeric/conversion/udt_builtin_mixture_enum.hpp +26 -0
  28. package/boost/numeric/interval/arith.hpp +305 -0
  29. package/boost/numeric/interval/arith2.hpp +304 -0
  30. package/boost/numeric/interval/arith3.hpp +69 -0
  31. package/boost/numeric/interval/checking.hpp +130 -0
  32. package/boost/numeric/interval/compare/certain.hpp +113 -0
  33. package/boost/numeric/interval/compare/explicit.hpp +248 -0
  34. package/boost/numeric/interval/compare/lexicographic.hpp +122 -0
  35. package/boost/numeric/interval/compare/possible.hpp +113 -0
  36. package/boost/numeric/interval/compare/set.hpp +101 -0
  37. package/boost/numeric/interval/compare/tribool.hpp +138 -0
  38. package/boost/numeric/interval/compare.hpp +19 -0
  39. package/boost/numeric/interval/constants.hpp +85 -0
  40. package/boost/numeric/interval/detail/alpha_rounding_control.hpp +113 -0
  41. package/boost/numeric/interval/detail/bcc_rounding_control.hpp +57 -0
  42. package/boost/numeric/interval/detail/bugs.hpp +48 -0
  43. package/boost/numeric/interval/detail/c99_rounding_control.hpp +50 -0
  44. package/boost/numeric/interval/detail/c99sub_rounding_control.hpp +43 -0
  45. package/boost/numeric/interval/detail/division.hpp +194 -0
  46. package/boost/numeric/interval/detail/ia64_rounding_control.hpp +83 -0
  47. package/boost/numeric/interval/detail/interval_prototype.hpp +41 -0
  48. package/boost/numeric/interval/detail/msvc_rounding_control.hpp +113 -0
  49. package/boost/numeric/interval/detail/ppc_rounding_control.hpp +99 -0
  50. package/boost/numeric/interval/detail/sparc_rounding_control.hpp +112 -0
  51. package/boost/numeric/interval/detail/test_input.hpp +76 -0
  52. package/boost/numeric/interval/detail/x86_rounding_control.hpp +108 -0
  53. package/boost/numeric/interval/detail/x86gcc_rounding_control.hpp +51 -0
  54. package/boost/numeric/interval/ext/integer.hpp +70 -0
  55. package/boost/numeric/interval/ext/x86_fast_rounding_control.hpp +70 -0
  56. package/boost/numeric/interval/hw_rounding.hpp +73 -0
  57. package/boost/numeric/interval/interval.hpp +450 -0
  58. package/boost/numeric/interval/io.hpp +41 -0
  59. package/boost/numeric/interval/limits.hpp +49 -0
  60. package/boost/numeric/interval/policies.hpp +75 -0
  61. package/boost/numeric/interval/rounded_arith.hpp +120 -0
  62. package/boost/numeric/interval/rounded_transc.hpp +140 -0
  63. package/boost/numeric/interval/rounding.hpp +101 -0
  64. package/boost/numeric/interval/transc.hpp +232 -0
  65. package/boost/numeric/interval/utility.hpp +335 -0
  66. package/boost/numeric/interval/utility_fwd.hpp +172 -0
  67. package/boost/numeric/interval.hpp +32 -0
  68. package/boost/numeric/odeint/algebra/algebra_dispatcher.hpp +86 -0
  69. package/boost/numeric/odeint/algebra/array_algebra.hpp +293 -0
  70. package/boost/numeric/odeint/algebra/default_operations.hpp +599 -0
  71. package/boost/numeric/odeint/algebra/detail/extract_value_type.hpp +51 -0
  72. package/boost/numeric/odeint/algebra/detail/for_each.hpp +165 -0
  73. package/boost/numeric/odeint/algebra/detail/macros.hpp +35 -0
  74. package/boost/numeric/odeint/algebra/detail/norm_inf.hpp +46 -0
  75. package/boost/numeric/odeint/algebra/fusion_algebra.hpp +216 -0
  76. package/boost/numeric/odeint/algebra/fusion_algebra_dispatcher.hpp +48 -0
  77. package/boost/numeric/odeint/algebra/multi_array_algebra.hpp +146 -0
  78. package/boost/numeric/odeint/algebra/norm_result_type.hpp +33 -0
  79. package/boost/numeric/odeint/algebra/operations_dispatcher.hpp +41 -0
  80. package/boost/numeric/odeint/algebra/range_algebra.hpp +142 -0
  81. package/boost/numeric/odeint/algebra/vector_space_algebra.hpp +175 -0
  82. package/boost/numeric/odeint/config.hpp +53 -0
  83. package/boost/numeric/odeint/external/blaze/blaze_algebra_dispatcher.hpp +55 -0
  84. package/boost/numeric/odeint/external/blaze/blaze_resize.hpp +64 -0
  85. package/boost/numeric/odeint/external/compute/compute.hpp +27 -0
  86. package/boost/numeric/odeint/external/compute/compute_algebra.hpp +65 -0
  87. package/boost/numeric/odeint/external/compute/compute_algebra_dispatcher.hpp +41 -0
  88. package/boost/numeric/odeint/external/compute/compute_operations.hpp +198 -0
  89. package/boost/numeric/odeint/external/compute/compute_operations_dispatcher.hpp +44 -0
  90. package/boost/numeric/odeint/external/compute/compute_resize.hpp +92 -0
  91. package/boost/numeric/odeint/external/eigen/eigen.hpp +27 -0
  92. package/boost/numeric/odeint/external/eigen/eigen_algebra.hpp +98 -0
  93. package/boost/numeric/odeint/external/eigen/eigen_algebra_dispatcher.hpp +49 -0
  94. package/boost/numeric/odeint/external/eigen/eigen_resize.hpp +103 -0
  95. package/boost/numeric/odeint/external/gsl/gsl_wrapper.hpp +228 -0
  96. package/boost/numeric/odeint/external/mkl/mkl_operations.hpp +181 -0
  97. package/boost/numeric/odeint/external/mpi/mpi.hpp +25 -0
  98. package/boost/numeric/odeint/external/mpi/mpi_nested_algebra.hpp +62 -0
  99. package/boost/numeric/odeint/external/mpi/mpi_state.hpp +113 -0
  100. package/boost/numeric/odeint/external/mpi/mpi_vector_state.hpp +95 -0
  101. package/boost/numeric/odeint/external/mtl4/implicit_euler_mtl4.hpp +161 -0
  102. package/boost/numeric/odeint/external/mtl4/mtl4.hpp +23 -0
  103. package/boost/numeric/odeint/external/mtl4/mtl4_algebra_dispatcher.hpp +99 -0
  104. package/boost/numeric/odeint/external/mtl4/mtl4_resize.hpp +134 -0
  105. package/boost/numeric/odeint/external/nt2/nt2_algebra_dispatcher.hpp +25 -0
  106. package/boost/numeric/odeint/external/nt2/nt2_copy.hpp +33 -0
  107. package/boost/numeric/odeint/external/nt2/nt2_norm_inf.hpp +31 -0
  108. package/boost/numeric/odeint/external/nt2/nt2_resize.hpp +54 -0
  109. package/boost/numeric/odeint/external/openmp/openmp.hpp +31 -0
  110. package/boost/numeric/odeint/external/openmp/openmp_nested_algebra.hpp +281 -0
  111. package/boost/numeric/odeint/external/openmp/openmp_range_algebra.hpp +276 -0
  112. package/boost/numeric/odeint/external/openmp/openmp_state.hpp +172 -0
  113. package/boost/numeric/odeint/external/thrust/thrust.hpp +27 -0
  114. package/boost/numeric/odeint/external/thrust/thrust_algebra.hpp +217 -0
  115. package/boost/numeric/odeint/external/thrust/thrust_algebra_dispatcher.hpp +118 -0
  116. package/boost/numeric/odeint/external/thrust/thrust_operations.hpp +233 -0
  117. package/boost/numeric/odeint/external/thrust/thrust_operations_dispatcher.hpp +118 -0
  118. package/boost/numeric/odeint/external/thrust/thrust_resize.hpp +197 -0
  119. package/boost/numeric/odeint/external/vexcl/vexcl.hpp +28 -0
  120. package/boost/numeric/odeint/external/vexcl/vexcl_abs.hpp +61 -0
  121. package/boost/numeric/odeint/external/vexcl/vexcl_algebra_dispatcher.hpp +51 -0
  122. package/boost/numeric/odeint/external/vexcl/vexcl_copy.hpp +55 -0
  123. package/boost/numeric/odeint/external/vexcl/vexcl_norm_inf.hpp +68 -0
  124. package/boost/numeric/odeint/external/vexcl/vexcl_resize.hpp +96 -0
  125. package/boost/numeric/odeint/external/vexcl/vexcl_same_instance.hpp +58 -0
  126. package/boost/numeric/odeint/external/viennacl/viennacl_operations.hpp +226 -0
  127. package/boost/numeric/odeint/external/viennacl/viennacl_resize.hpp +68 -0
  128. package/boost/numeric/odeint/integrate/check_adapter.hpp +222 -0
  129. package/boost/numeric/odeint/integrate/detail/functors.hpp +70 -0
  130. package/boost/numeric/odeint/integrate/detail/integrate_adaptive.hpp +161 -0
  131. package/boost/numeric/odeint/integrate/detail/integrate_const.hpp +167 -0
  132. package/boost/numeric/odeint/integrate/detail/integrate_n_steps.hpp +161 -0
  133. package/boost/numeric/odeint/integrate/detail/integrate_times.hpp +179 -0
  134. package/boost/numeric/odeint/integrate/integrate.hpp +133 -0
  135. package/boost/numeric/odeint/integrate/integrate_adaptive.hpp +127 -0
  136. package/boost/numeric/odeint/integrate/integrate_const.hpp +195 -0
  137. package/boost/numeric/odeint/integrate/integrate_n_steps.hpp +178 -0
  138. package/boost/numeric/odeint/integrate/integrate_times.hpp +220 -0
  139. package/boost/numeric/odeint/integrate/max_step_checker.hpp +114 -0
  140. package/boost/numeric/odeint/integrate/null_observer.hpp +38 -0
  141. package/boost/numeric/odeint/integrate/observer_collection.hpp +55 -0
  142. package/boost/numeric/odeint/iterator/adaptive_iterator.hpp +183 -0
  143. package/boost/numeric/odeint/iterator/adaptive_time_iterator.hpp +175 -0
  144. package/boost/numeric/odeint/iterator/const_step_iterator.hpp +180 -0
  145. package/boost/numeric/odeint/iterator/const_step_time_iterator.hpp +173 -0
  146. package/boost/numeric/odeint/iterator/detail/ode_iterator_base.hpp +199 -0
  147. package/boost/numeric/odeint/iterator/impl/adaptive_iterator_impl.hpp +251 -0
  148. package/boost/numeric/odeint/iterator/impl/const_step_iterator_impl.hpp +228 -0
  149. package/boost/numeric/odeint/iterator/impl/n_step_iterator_impl.hpp +239 -0
  150. package/boost/numeric/odeint/iterator/impl/times_iterator_impl.hpp +369 -0
  151. package/boost/numeric/odeint/iterator/integrate/detail/functors.hpp +70 -0
  152. package/boost/numeric/odeint/iterator/integrate/detail/integrate_adaptive.hpp +121 -0
  153. package/boost/numeric/odeint/iterator/integrate/detail/integrate_const.hpp +111 -0
  154. package/boost/numeric/odeint/iterator/integrate/detail/integrate_n_steps.hpp +107 -0
  155. package/boost/numeric/odeint/iterator/integrate/detail/integrate_times.hpp +67 -0
  156. package/boost/numeric/odeint/iterator/integrate/integrate.hpp +111 -0
  157. package/boost/numeric/odeint/iterator/integrate/integrate_adaptive.hpp +127 -0
  158. package/boost/numeric/odeint/iterator/integrate/integrate_const.hpp +158 -0
  159. package/boost/numeric/odeint/iterator/integrate/integrate_n_steps.hpp +123 -0
  160. package/boost/numeric/odeint/iterator/integrate/integrate_times.hpp +131 -0
  161. package/boost/numeric/odeint/iterator/integrate/null_observer.hpp +38 -0
  162. package/boost/numeric/odeint/iterator/integrate/observer_collection.hpp +55 -0
  163. package/boost/numeric/odeint/iterator/n_step_iterator.hpp +168 -0
  164. package/boost/numeric/odeint/iterator/n_step_time_iterator.hpp +169 -0
  165. package/boost/numeric/odeint/iterator/times_iterator.hpp +189 -0
  166. package/boost/numeric/odeint/iterator/times_time_iterator.hpp +193 -0
  167. package/boost/numeric/odeint/stepper/adams_bashforth.hpp +418 -0
  168. package/boost/numeric/odeint/stepper/adams_bashforth_moulton.hpp +313 -0
  169. package/boost/numeric/odeint/stepper/adams_moulton.hpp +201 -0
  170. package/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp +237 -0
  171. package/boost/numeric/odeint/stepper/base/algebra_stepper_base.hpp +91 -0
  172. package/boost/numeric/odeint/stepper/base/explicit_error_stepper_base.hpp +588 -0
  173. package/boost/numeric/odeint/stepper/base/explicit_error_stepper_fsal_base.hpp +677 -0
  174. package/boost/numeric/odeint/stepper/base/explicit_stepper_base.hpp +415 -0
  175. package/boost/numeric/odeint/stepper/base/symplectic_rkn_stepper_base.hpp +431 -0
  176. package/boost/numeric/odeint/stepper/bulirsch_stoer.hpp +642 -0
  177. package/boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp +838 -0
  178. package/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp +322 -0
  179. package/boost/numeric/odeint/stepper/controlled_runge_kutta.hpp +1018 -0
  180. package/boost/numeric/odeint/stepper/controlled_step_result.hpp +42 -0
  181. package/boost/numeric/odeint/stepper/dense_output_runge_kutta.hpp +476 -0
  182. package/boost/numeric/odeint/stepper/detail/adams_bashforth_call_algebra.hpp +148 -0
  183. package/boost/numeric/odeint/stepper/detail/adams_bashforth_coefficients.hpp +168 -0
  184. package/boost/numeric/odeint/stepper/detail/adams_moulton_call_algebra.hpp +148 -0
  185. package/boost/numeric/odeint/stepper/detail/adams_moulton_coefficients.hpp +168 -0
  186. package/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp +207 -0
  187. package/boost/numeric/odeint/stepper/detail/generic_rk_algorithm.hpp +247 -0
  188. package/boost/numeric/odeint/stepper/detail/generic_rk_call_algebra.hpp +263 -0
  189. package/boost/numeric/odeint/stepper/detail/generic_rk_operations.hpp +252 -0
  190. package/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp +199 -0
  191. package/boost/numeric/odeint/stepper/detail/pid_step_adjuster_coefficients.hpp +180 -0
  192. package/boost/numeric/odeint/stepper/detail/rotating_buffer.hpp +84 -0
  193. package/boost/numeric/odeint/stepper/euler.hpp +166 -0
  194. package/boost/numeric/odeint/stepper/explicit_error_generic_rk.hpp +255 -0
  195. package/boost/numeric/odeint/stepper/explicit_generic_rk.hpp +246 -0
  196. package/boost/numeric/odeint/stepper/extrapolation_stepper.hpp +288 -0
  197. package/boost/numeric/odeint/stepper/generation/generation_controlled_adams_bashforth_moulton.hpp +59 -0
  198. package/boost/numeric/odeint/stepper/generation/generation_controlled_runge_kutta.hpp +61 -0
  199. package/boost/numeric/odeint/stepper/generation/generation_dense_output_runge_kutta.hpp +65 -0
  200. package/boost/numeric/odeint/stepper/generation/generation_rosenbrock4.hpp +79 -0
  201. package/boost/numeric/odeint/stepper/generation/generation_runge_kutta_cash_karp54.hpp +47 -0
  202. package/boost/numeric/odeint/stepper/generation/generation_runge_kutta_cash_karp54_classic.hpp +48 -0
  203. package/boost/numeric/odeint/stepper/generation/generation_runge_kutta_dopri5.hpp +56 -0
  204. package/boost/numeric/odeint/stepper/generation/generation_runge_kutta_fehlberg78.hpp +46 -0
  205. package/boost/numeric/odeint/stepper/generation/make_controlled.hpp +103 -0
  206. package/boost/numeric/odeint/stepper/generation/make_dense_output.hpp +100 -0
  207. package/boost/numeric/odeint/stepper/generation.hpp +37 -0
  208. package/boost/numeric/odeint/stepper/implicit_euler.hpp +170 -0
  209. package/boost/numeric/odeint/stepper/modified_midpoint.hpp +315 -0
  210. package/boost/numeric/odeint/stepper/rosenbrock4.hpp +346 -0
  211. package/boost/numeric/odeint/stepper/rosenbrock4_controller.hpp +240 -0
  212. package/boost/numeric/odeint/stepper/rosenbrock4_dense_output.hpp +204 -0
  213. package/boost/numeric/odeint/stepper/runge_kutta4.hpp +181 -0
  214. package/boost/numeric/odeint/stepper/runge_kutta4_classic.hpp +232 -0
  215. package/boost/numeric/odeint/stepper/runge_kutta_cash_karp54.hpp +231 -0
  216. package/boost/numeric/odeint/stepper/runge_kutta_cash_karp54_classic.hpp +289 -0
  217. package/boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp +403 -0
  218. package/boost/numeric/odeint/stepper/runge_kutta_fehlberg78.hpp +374 -0
  219. package/boost/numeric/odeint/stepper/stepper_categories.hpp +66 -0
  220. package/boost/numeric/odeint/stepper/symplectic_euler.hpp +136 -0
  221. package/boost/numeric/odeint/stepper/symplectic_rkn_sb3a_m4_mclachlan.hpp +160 -0
  222. package/boost/numeric/odeint/stepper/symplectic_rkn_sb3a_mclachlan.hpp +162 -0
  223. package/boost/numeric/odeint/stepper/velocity_verlet.hpp +375 -0
  224. package/boost/numeric/odeint/tools/assert.hpp +30 -0
  225. package/boost/numeric/odeint/tools/is_standalone.hpp +21 -0
  226. package/boost/numeric/odeint/tools/traits.hpp +39 -0
  227. package/boost/numeric/odeint/util/bind.hpp +35 -0
  228. package/boost/numeric/odeint/util/copy.hpp +88 -0
  229. package/boost/numeric/odeint/util/detail/is_range.hpp +127 -0
  230. package/boost/numeric/odeint/util/detail/less_with_sign.hpp +78 -0
  231. package/boost/numeric/odeint/util/is_pair.hpp +42 -0
  232. package/boost/numeric/odeint/util/is_resizeable.hpp +84 -0
  233. package/boost/numeric/odeint/util/multi_array_adaption.hpp +131 -0
  234. package/boost/numeric/odeint/util/n_ary_helper.hpp +96 -0
  235. package/boost/numeric/odeint/util/odeint_error.hpp +77 -0
  236. package/boost/numeric/odeint/util/resize.hpp +120 -0
  237. package/boost/numeric/odeint/util/resizer.hpp +94 -0
  238. package/boost/numeric/odeint/util/same_instance.hpp +56 -0
  239. package/boost/numeric/odeint/util/same_size.hpp +117 -0
  240. package/boost/numeric/odeint/util/split.hpp +64 -0
  241. package/boost/numeric/odeint/util/split_adaptor.hpp +103 -0
  242. package/boost/numeric/odeint/util/state_wrapper.hpp +50 -0
  243. package/boost/numeric/odeint/util/stepper_traits.hpp +63 -0
  244. package/boost/numeric/odeint/util/ublas_matrix_expression.patch +6 -0
  245. package/boost/numeric/odeint/util/ublas_wrapper.hpp +297 -0
  246. package/boost/numeric/odeint/util/unit_helper.hpp +151 -0
  247. package/boost/numeric/odeint/util/unwrap_reference.hpp +141 -0
  248. package/boost/numeric/odeint/version.hpp +55 -0
  249. package/boost/numeric/odeint.hpp +87 -0
  250. package/boost/numeric/ublas/assignment.hpp +1288 -0
  251. package/boost/numeric/ublas/banded.hpp +2372 -0
  252. package/boost/numeric/ublas/blas.hpp +499 -0
  253. package/boost/numeric/ublas/detail/concepts.hpp +1465 -0
  254. package/boost/numeric/ublas/detail/config.hpp +304 -0
  255. package/boost/numeric/ublas/detail/definitions.hpp +212 -0
  256. package/boost/numeric/ublas/detail/documentation.hpp +33 -0
  257. package/boost/numeric/ublas/detail/duff.hpp +56 -0
  258. package/boost/numeric/ublas/detail/iterator.hpp +1448 -0
  259. package/boost/numeric/ublas/detail/matrix_assign.hpp +1785 -0
  260. package/boost/numeric/ublas/detail/raw.hpp +878 -0
  261. package/boost/numeric/ublas/detail/returntype_deduction.hpp +174 -0
  262. package/boost/numeric/ublas/detail/temporary.hpp +33 -0
  263. package/boost/numeric/ublas/detail/vector_assign.hpp +609 -0
  264. package/boost/numeric/ublas/doxydoc.hpp +58 -0
  265. package/boost/numeric/ublas/exception.hpp +297 -0
  266. package/boost/numeric/ublas/experimental/sparse_view.hpp +317 -0
  267. package/boost/numeric/ublas/expression_types.hpp +506 -0
  268. package/boost/numeric/ublas/functional.hpp +2112 -0
  269. package/boost/numeric/ublas/fwd.hpp +229 -0
  270. package/boost/numeric/ublas/hermitian.hpp +2633 -0
  271. package/boost/numeric/ublas/io.hpp +355 -0
  272. package/boost/numeric/ublas/lu.hpp +350 -0
  273. package/boost/numeric/ublas/matrix.hpp +6013 -0
  274. package/boost/numeric/ublas/matrix_expression.hpp +5693 -0
  275. package/boost/numeric/ublas/matrix_proxy.hpp +5457 -0
  276. package/boost/numeric/ublas/matrix_sparse.hpp +5773 -0
  277. package/boost/numeric/ublas/matrix_vector.hpp +406 -0
  278. package/boost/numeric/ublas/opencl/elementwise.hpp +508 -0
  279. package/boost/numeric/ublas/opencl/library.hpp +38 -0
  280. package/boost/numeric/ublas/opencl/matrix.hpp +123 -0
  281. package/boost/numeric/ublas/opencl/misc.hpp +182 -0
  282. package/boost/numeric/ublas/opencl/operations.hpp +18 -0
  283. package/boost/numeric/ublas/opencl/prod.hpp +364 -0
  284. package/boost/numeric/ublas/opencl/transpose.hpp +142 -0
  285. package/boost/numeric/ublas/opencl/vector.hpp +90 -0
  286. package/boost/numeric/ublas/opencl.hpp +16 -0
  287. package/boost/numeric/ublas/operation/begin.hpp +318 -0
  288. package/boost/numeric/ublas/operation/c_array.hpp +41 -0
  289. package/boost/numeric/ublas/operation/end.hpp +318 -0
  290. package/boost/numeric/ublas/operation/num_columns.hpp +45 -0
  291. package/boost/numeric/ublas/operation/num_rows.hpp +44 -0
  292. package/boost/numeric/ublas/operation/size.hpp +350 -0
  293. package/boost/numeric/ublas/operation.hpp +830 -0
  294. package/boost/numeric/ublas/operation_blocked.hpp +266 -0
  295. package/boost/numeric/ublas/operation_sparse.hpp +198 -0
  296. package/boost/numeric/ublas/operations.hpp +26 -0
  297. package/boost/numeric/ublas/storage.hpp +2131 -0
  298. package/boost/numeric/ublas/storage_sparse.hpp +578 -0
  299. package/boost/numeric/ublas/symmetric.hpp +2309 -0
  300. package/boost/numeric/ublas/tags.hpp +37 -0
  301. package/boost/numeric/ublas/tensor/algorithms.hpp +345 -0
  302. package/boost/numeric/ublas/tensor/expression.hpp +181 -0
  303. package/boost/numeric/ublas/tensor/expression_evaluation.hpp +288 -0
  304. package/boost/numeric/ublas/tensor/extents.hpp +335 -0
  305. package/boost/numeric/ublas/tensor/functions.hpp +558 -0
  306. package/boost/numeric/ublas/tensor/index.hpp +89 -0
  307. package/boost/numeric/ublas/tensor/multi_index.hpp +110 -0
  308. package/boost/numeric/ublas/tensor/multi_index_utility.hpp +364 -0
  309. package/boost/numeric/ublas/tensor/multiplication.hpp +945 -0
  310. package/boost/numeric/ublas/tensor/operators_arithmetic.hpp +244 -0
  311. package/boost/numeric/ublas/tensor/operators_comparison.hpp +175 -0
  312. package/boost/numeric/ublas/tensor/ostream.hpp +122 -0
  313. package/boost/numeric/ublas/tensor/storage_traits.hpp +84 -0
  314. package/boost/numeric/ublas/tensor/strides.hpp +251 -0
  315. package/boost/numeric/ublas/tensor/tensor.hpp +734 -0
  316. package/boost/numeric/ublas/tensor.hpp +26 -0
  317. package/boost/numeric/ublas/traits/c_array.hpp +110 -0
  318. package/boost/numeric/ublas/traits/const_iterator_type.hpp +127 -0
  319. package/boost/numeric/ublas/traits/iterator_type.hpp +126 -0
  320. package/boost/numeric/ublas/traits.hpp +753 -0
  321. package/boost/numeric/ublas/triangular.hpp +2775 -0
  322. package/boost/numeric/ublas/vector.hpp +2947 -0
  323. package/boost/numeric/ublas/vector_expression.hpp +1762 -0
  324. package/boost/numeric/ublas/vector_of_vector.hpp +1347 -0
  325. package/boost/numeric/ublas/vector_proxy.hpp +1697 -0
  326. package/boost/numeric/ublas/vector_sparse.hpp +2246 -0
  327. package/package.json +3 -7
@@ -0,0 +1,945 @@
1
+ //
2
+ // Copyright (c) 2018-2019, Cem Bassoy, cem.bassoy@gmail.com
3
+ //
4
+ // Distributed under the Boost Software License, Version 1.0. (See
5
+ // accompanying file LICENSE_1_0.txt or copy at
6
+ // http://www.boost.org/LICENSE_1_0.txt)
7
+ //
8
+ // The authors gratefully acknowledge the support of
9
+ // Fraunhofer IOSB, Ettlingen, Germany
10
+ //
11
+
12
+
13
+ #ifndef BOOST_UBLAS_TENSOR_MULTIPLICATION
14
+ #define BOOST_UBLAS_TENSOR_MULTIPLICATION
15
+
16
+ #include <cassert>
17
+
18
+ namespace boost {
19
+ namespace numeric {
20
+ namespace ublas {
21
+ namespace detail {
22
+ namespace recursive {
23
+
24
+
25
+ /** @brief Computes the tensor-times-tensor product for q contraction modes
26
+ *
27
+ * Implements C[i1,...,ir,j1,...,js] = sum( A[i1,...,ir+q] * B[j1,...,js+q] )
28
+ *
29
+ * nc[x] = na[phia[x] ] for 1 <= x <= r
30
+ * nc[r+x] = nb[phib[x] ] for 1 <= x <= s
31
+ * na[phia[r+x]] = nb[phib[s+x]] for 1 <= x <= q
32
+ *
33
+ * @note is used in function ttt
34
+ *
35
+ * @param k zero-based recursion level starting with 0
36
+ * @param r number of non-contraction indices of A
37
+ * @param s number of non-contraction indices of B
38
+ * @param q number of contraction indices with q > 0
39
+ * @param phia pointer to the permutation tuple of length q+r for A
40
+ * @param phib pointer to the permutation tuple of length q+s for B
41
+ * @param c pointer to the output tensor C with rank(A)=r+s
42
+ * @param nc pointer to the extents of tensor C
43
+ * @param wc pointer to the strides of tensor C
44
+ * @param a pointer to the first input tensor with rank(A)=r+q
45
+ * @param na pointer to the extents of the first input tensor A
46
+ * @param wa pointer to the strides of the first input tensor A
47
+ * @param b pointer to the second input tensor B with rank(B)=s+q
48
+ * @param nb pointer to the extents of the second input tensor B
49
+ * @param wb pointer to the strides of the second input tensor B
50
+ */
51
+
52
+ template <class PointerOut, class PointerIn1, class PointerIn2, class SizeType>
53
+ void ttt(SizeType const k,
54
+ SizeType const r, SizeType const s, SizeType const q,
55
+ SizeType const*const phia, SizeType const*const phib,
56
+ PointerOut c, SizeType const*const nc, SizeType const*const wc,
57
+ PointerIn1 a, SizeType const*const na, SizeType const*const wa,
58
+ PointerIn2 b, SizeType const*const nb, SizeType const*const wb)
59
+ {
60
+ if(k < r)
61
+ {
62
+ assert(nc[k] == na[phia[k]-1]);
63
+ for(size_t ic = 0u; ic < nc[k]; a += wa[phia[k]-1], c += wc[k], ++ic)
64
+ ttt(k+1, r, s, q, phia,phib, c, nc, wc, a, na, wa, b, nb, wb);
65
+ }
66
+ else if(k < r+s)
67
+ {
68
+ assert(nc[k] == nb[phib[k-r]-1]);
69
+ for(size_t ic = 0u; ic < nc[k]; b += wb[phib[k-r]-1], c += wc[k], ++ic)
70
+ ttt(k+1, r, s, q, phia, phib, c, nc, wc, a, na, wa, b, nb, wb);
71
+ }
72
+ else if(k < r+s+q-1)
73
+ {
74
+ assert(na[phia[k-s]-1] == nb[phib[k-r]-1]);
75
+ for(size_t ia = 0u; ia < na[phia[k-s]-1]; a += wa[phia[k-s]-1], b += wb[phib[k-r]-1], ++ia)
76
+ ttt(k+1, r, s, q, phia, phib, c, nc, wc, a, na, wa, b, nb, wb);
77
+ }
78
+ else
79
+ {
80
+ assert(na[phia[k-s]-1] == nb[phib[k-r]-1]);
81
+ for(size_t ia = 0u; ia < na[phia[k-s]-1]; a += wa[phia[k-s]-1], b += wb[phib[k-r]-1], ++ia)
82
+ *c += *a * *b;
83
+ }
84
+ }
85
+
86
+
87
+
88
+
89
+ /** @brief Computes the tensor-times-tensor product for q contraction modes
90
+ *
91
+ * Implements C[i1,...,ir,j1,...,js] = sum( A[i1,...,ir+q] * B[j1,...,js+q] )
92
+ *
93
+ * @note no permutation tuple is used
94
+ *
95
+ * nc[x] = na[x ] for 1 <= x <= r
96
+ * nc[r+x] = nb[x ] for 1 <= x <= s
97
+ * na[r+x] = nb[s+x] for 1 <= x <= q
98
+ *
99
+ * @note is used in function ttt
100
+ *
101
+ * @param k zero-based recursion level starting with 0
102
+ * @param r number of non-contraction indices of A
103
+ * @param s number of non-contraction indices of B
104
+ * @param q number of contraction indices with q > 0
105
+ * @param c pointer to the output tensor C with rank(A)=r+s
106
+ * @param nc pointer to the extents of tensor C
107
+ * @param wc pointer to the strides of tensor C
108
+ * @param a pointer to the first input tensor with rank(A)=r+q
109
+ * @param na pointer to the extents of the first input tensor A
110
+ * @param wa pointer to the strides of the first input tensor A
111
+ * @param b pointer to the second input tensor B with rank(B)=s+q
112
+ * @param nb pointer to the extents of the second input tensor B
113
+ * @param wb pointer to the strides of the second input tensor B
114
+ */
115
+
116
+ template <class PointerOut, class PointerIn1, class PointerIn2, class SizeType>
117
+ void ttt(SizeType const k,
118
+ SizeType const r, SizeType const s, SizeType const q,
119
+ PointerOut c, SizeType const*const nc, SizeType const*const wc,
120
+ PointerIn1 a, SizeType const*const na, SizeType const*const wa,
121
+ PointerIn2 b, SizeType const*const nb, SizeType const*const wb)
122
+ {
123
+ if(k < r)
124
+ {
125
+ assert(nc[k] == na[k]);
126
+ for(size_t ic = 0u; ic < nc[k]; a += wa[k], c += wc[k], ++ic)
127
+ ttt(k+1, r, s, q, c, nc, wc, a, na, wa, b, nb, wb);
128
+ }
129
+ else if(k < r+s)
130
+ {
131
+ assert(nc[k] == nb[k-r]);
132
+ for(size_t ic = 0u; ic < nc[k]; b += wb[k-r], c += wc[k], ++ic)
133
+ ttt(k+1, r, s, q, c, nc, wc, a, na, wa, b, nb, wb);
134
+ }
135
+ else if(k < r+s+q-1)
136
+ {
137
+ assert(na[k-s] == nb[k-r]);
138
+ for(size_t ia = 0u; ia < na[k-s]; a += wa[k-s], b += wb[k-r], ++ia)
139
+ ttt(k+1, r, s, q, c, nc, wc, a, na, wa, b, nb, wb);
140
+ }
141
+ else
142
+ {
143
+ assert(na[k-s] == nb[k-r]);
144
+ for(size_t ia = 0u; ia < na[k-s]; a += wa[k-s], b += wb[k-r], ++ia)
145
+ *c += *a * *b;
146
+ }
147
+ }
148
+
149
+
150
+ /** @brief Computes the tensor-times-matrix product for the contraction mode m > 0
151
+ *
152
+ * Implements C[i1,i2,...,im-1,j,im+1,...,ip] = sum(A[i1,i2,...,im,...,ip] * B[j,im])
153
+ *
154
+ * @note is used in function ttm
155
+ *
156
+ * @param m zero-based contraction mode with 0<m<p
157
+ * @param r zero-based recursion level starting with p-1
158
+ * @param c pointer to the output tensor
159
+ * @param nc pointer to the extents of tensor c
160
+ * @param wc pointer to the strides of tensor c
161
+ * @param a pointer to the first input tensor
162
+ * @param na pointer to the extents of input tensor a
163
+ * @param wa pointer to the strides of input tensor a
164
+ * @param b pointer to the second input tensor
165
+ * @param nb pointer to the extents of input tensor b
166
+ * @param wb pointer to the strides of input tensor b
167
+ */
168
+
169
+ template <class PointerOut, class PointerIn1, class PointerIn2, class SizeType>
170
+ void ttm(SizeType const m, SizeType const r,
171
+ PointerOut c, SizeType const*const nc, SizeType const*const wc,
172
+ PointerIn1 a, SizeType const*const na, SizeType const*const wa,
173
+ PointerIn2 b, SizeType const*const nb, SizeType const*const wb)
174
+ {
175
+
176
+ if(r == m) {
177
+ ttm(m, r-1, c, nc, wc, a, na, wa, b, nb, wb);
178
+ }
179
+ else if(r == 0){
180
+ for(auto i0 = 0ul; i0 < nc[0]; c += wc[0], a += wa[0], ++i0) {
181
+ auto cm = c;
182
+ auto b0 = b;
183
+ for(auto i0 = 0ul; i0 < nc[m]; cm += wc[m], b0 += wb[0], ++i0){
184
+ auto am = a;
185
+ auto b1 = b0;
186
+ for(auto i1 = 0ul; i1 < nb[1]; am += wa[m], b1 += wb[1], ++i1)
187
+ *cm += *am * *b1;
188
+ }
189
+ }
190
+ }
191
+
192
+ else{
193
+ for(auto i = 0ul; i < na[r]; c += wc[r], a += wa[r], ++i)
194
+ ttm(m, r-1, c, nc, wc, a, na, wa, b, nb, wb);
195
+ }
196
+ }
197
+
198
+ /** @brief Computes the tensor-times-matrix product for the contraction mode m = 0
199
+ *
200
+ * Implements C[j,i2,...,ip] = sum(A[i1,i2,...,ip] * B[j,i1])
201
+ *
202
+ * @note is used in function ttm
203
+ *
204
+ * @param m zero-based contraction mode with 0<m<p
205
+ * @param r zero-based recursion level starting with p-1
206
+ * @param c pointer to the output tensor
207
+ * @param nc pointer to the extents of tensor c
208
+ * @param wc pointer to the strides of tensor c
209
+ * @param a pointer to the first input tensor
210
+ * @param na pointer to the extents of input tensor a
211
+ * @param wa pointer to the strides of input tensor a
212
+ * @param b pointer to the second input tensor
213
+ * @param nb pointer to the extents of input tensor b
214
+ * @param wb pointer to the strides of input tensor b
215
+ */
216
+ template <class PointerOut, class PointerIn1, class PointerIn2, class SizeType>
217
+ void ttm0( SizeType const r,
218
+ PointerOut c, SizeType const*const nc, SizeType const*const wc,
219
+ PointerIn1 a, SizeType const*const na, SizeType const*const wa,
220
+ PointerIn2 b, SizeType const*const nb, SizeType const*const wb)
221
+ {
222
+
223
+ if(r > 1){
224
+ for(auto i = 0ul; i < na[r]; c += wc[r], a += wa[r], ++i)
225
+ ttm0(r-1, c, nc, wc, a, na, wa, b, nb, wb);
226
+ }
227
+ else{
228
+ for(auto i1 = 0ul; i1 < nc[1]; c += wc[1], a += wa[1], ++i1) {
229
+ auto cm = c;
230
+ auto b0 = b;
231
+ // r == m == 0
232
+ for(auto i0 = 0ul; i0 < nc[0]; cm += wc[0], b0 += wb[0], ++i0){
233
+
234
+ auto am = a;
235
+ auto b1 = b0;
236
+ for(auto i1 = 0u; i1 < nb[1]; am += wa[0], b1 += wb[1], ++i1){
237
+
238
+ *cm += *am * *b1;
239
+ }
240
+ }
241
+ }
242
+ }
243
+ }
244
+
245
+
246
+ //////////////////////////////////////////////////////////////////////////////////////////
247
+ //////////////////////////////////////////////////////////////////////////////////////////
248
+ //////////////////////////////////////////////////////////////////////////////////////////
249
+ //////////////////////////////////////////////////////////////////////////////////////////
250
+
251
+
252
+ /** @brief Computes the tensor-times-vector product for the contraction mode m > 0
253
+ *
254
+ * Implements C[i1,i2,...,im-1,im+1,...,ip] = sum(A[i1,i2,...,im,...,ip] * b[im])
255
+ *
256
+ * @note is used in function ttv
257
+ *
258
+ * @param m zero-based contraction mode with 0<m<p
259
+ * @param r zero-based recursion level starting with p-1 for tensor A
260
+ * @param q zero-based recursion level starting with p-1 for tensor C
261
+ * @param c pointer to the output tensor
262
+ * @param nc pointer to the extents of tensor c
263
+ * @param wc pointer to the strides of tensor c
264
+ * @param a pointer to the first input tensor
265
+ * @param na pointer to the extents of input tensor a
266
+ * @param wa pointer to the strides of input tensor a
267
+ * @param b pointer to the second input tensor
268
+ */
269
+
270
+ template <class PointerOut, class PointerIn1, class PointerIn2, class SizeType>
271
+ void ttv( SizeType const m, SizeType const r, SizeType const q,
272
+ PointerOut c, SizeType const*const nc, SizeType const*const wc,
273
+ PointerIn1 a, SizeType const*const na, SizeType const*const wa,
274
+ PointerIn2 b)
275
+ {
276
+
277
+ if(r == m) {
278
+ ttv(m, r-1, q, c, nc, wc, a, na, wa, b);
279
+ }
280
+ else if(r == 0){
281
+ for(auto i0 = 0u; i0 < na[0]; c += wc[0], a += wa[0], ++i0) {
282
+ auto c1 = c; auto a1 = a; auto b1 = b;
283
+ for(auto im = 0u; im < na[m]; a1 += wa[m], ++b1, ++im)
284
+ *c1 += *a1 * *b1;
285
+ }
286
+ }
287
+ else{
288
+ for(auto i = 0u; i < na[r]; c += wc[q], a += wa[r], ++i)
289
+ ttv(m, r-1, q-1, c, nc, wc, a, na, wa, b);
290
+ }
291
+ }
292
+
293
+
294
+ /** @brief Computes the tensor-times-vector product for the contraction mode m = 0
295
+ *
296
+ * Implements C[i2,...,ip] = sum(A[i1,...,ip] * b[i1])
297
+ *
298
+ * @note is used in function ttv
299
+ *
300
+ * @param m zero-based contraction mode with m=0
301
+ * @param r zero-based recursion level starting with p-1
302
+ * @param c pointer to the output tensor
303
+ * @param nc pointer to the extents of tensor c
304
+ * @param wc pointer to the strides of tensor c
305
+ * @param a pointer to the first input tensor
306
+ * @param na pointer to the extents of input tensor a
307
+ * @param wa pointer to the strides of input tensor a
308
+ * @param b pointer to the second input tensor
309
+ */
310
+ template <class PointerOut, class PointerIn1, class PointerIn2, class SizeType>
311
+ void ttv0(SizeType const r,
312
+ PointerOut c, SizeType const*const nc, SizeType const*const wc,
313
+ PointerIn1 a, SizeType const*const na, SizeType const*const wa,
314
+ PointerIn2 b)
315
+ {
316
+
317
+ if(r > 1){
318
+ for(auto i = 0u; i < na[r]; c += wc[r-1], a += wa[r], ++i)
319
+ ttv0(r-1, c, nc, wc, a, na, wa, b);
320
+ }
321
+ else{
322
+ for(auto i1 = 0u; i1 < na[1]; c += wc[0], a += wa[1], ++i1)
323
+ {
324
+ auto c1 = c; auto a1 = a; auto b1 = b;
325
+ for(auto i0 = 0u; i0 < na[0]; a1 += wa[0], ++b1, ++i0)
326
+ *c1 += *a1 * *b1;
327
+ }
328
+ }
329
+ }
330
+
331
+
332
+ /** @brief Computes the matrix-times-vector product
333
+ *
334
+ * Implements C[i1] = sum(A[i1,i2] * b[i2]) or C[i2] = sum(A[i1,i2] * b[i1])
335
+ *
336
+ * @note is used in function ttv
337
+ *
338
+ * @param[in] m zero-based contraction mode with m=0 or m=1
339
+ * @param[out] c pointer to the output tensor C
340
+ * @param[in] nc pointer to the extents of tensor C
341
+ * @param[in] wc pointer to the strides of tensor C
342
+ * @param[in] a pointer to the first input tensor A
343
+ * @param[in] na pointer to the extents of input tensor A
344
+ * @param[in] wa pointer to the strides of input tensor A
345
+ * @param[in] b pointer to the second input tensor B
346
+ */
347
+ template <class PointerOut, class PointerIn1, class PointerIn2, class SizeType>
348
+ void mtv(SizeType const m,
349
+ PointerOut c, SizeType const*const , SizeType const*const wc,
350
+ PointerIn1 a, SizeType const*const na, SizeType const*const wa,
351
+ PointerIn2 b)
352
+ {
353
+ // decides whether matrix multiplied with vector or vector multiplied with matrix
354
+ const auto o = (m == 0) ? 1 : 0;
355
+
356
+ for(auto io = 0u; io < na[o]; c += wc[o], a += wa[o], ++io) {
357
+ auto c1 = c; auto a1 = a; auto b1 = b;
358
+ for(auto im = 0u; im < na[m]; a1 += wa[m], ++b1, ++im)
359
+ *c1 += *a1 * *b1;
360
+ }
361
+ }
362
+
363
+
364
+ /** @brief Computes the matrix-times-matrix product
365
+ *
366
+ * Implements C[i1,i3] = sum(A[i1,i2] * B[i2,i3])
367
+ *
368
+ * @note is used in function ttm
369
+ *
370
+ * @param[out] c pointer to the output tensor C
371
+ * @param[in] nc pointer to the extents of tensor C
372
+ * @param[in] wc pointer to the strides of tensor C
373
+ * @param[in] a pointer to the first input tensor A
374
+ * @param[in] na pointer to the extents of input tensor A
375
+ * @param[in] wa pointer to the strides of input tensor A
376
+ * @param[in] b pointer to the second input tensor B
377
+ * @param[in] nb pointer to the extents of input tensor B
378
+ * @param[in] wb pointer to the strides of input tensor B
379
+ */
380
+ template <class PointerOut, class PointerIn1, class PointerIn2, class SizeType>
381
+ void mtm(PointerOut c, SizeType const*const nc, SizeType const*const wc,
382
+ PointerIn1 a, SizeType const*const na, SizeType const*const wa,
383
+ PointerIn2 b, SizeType const*const nb, SizeType const*const wb)
384
+ {
385
+
386
+ // C(i,j) = A(i,k) * B(k,j)
387
+
388
+ assert(nc[0] == na[0]);
389
+ assert(nc[1] == nb[1]);
390
+ assert(na[1] == nb[0]);
391
+
392
+ auto cj = c; auto bj = b;
393
+ for(auto j = 0u; j < nc[1]; cj += wc[1], bj += wb[1], ++j) {
394
+
395
+ auto bk = bj; auto ak = a;
396
+ for(auto k = 0u; k < na[1]; ak += wa[1], bk += wb[0], ++k) {
397
+
398
+ auto ci = cj; auto ai = ak;
399
+ for(auto i = 0u; i < na[0]; ai += wa[0], ci += wc[0], ++i){
400
+ *ci += *ai * *bk;
401
+ }
402
+
403
+ }
404
+
405
+ }
406
+ }
407
+
408
+
409
+
410
+ /** @brief Computes the inner product of two tensors
411
+ *
412
+ * Implements c = sum(A[i1,i2,...,ip] * B[i1,i2,...,ip])
413
+ *
414
+ * @note is used in function inner
415
+ *
416
+ * @param r zero-based recursion level starting with p-1
417
+ * @param n pointer to the extents of input or output tensor
418
+ * @param a pointer to the first input tensor
419
+ * @param wa pointer to the strides of input tensor a
420
+ * @param b pointer to the second input tensor
421
+ * @param wb pointer to the strides of tensor b
422
+ * @param v previously computed value (start with v = 0).
423
+ * @return inner product of two tensors.
424
+ */
425
+ template <class PointerIn1, class PointerIn2, class value_t, class SizeType>
426
+ value_t inner(SizeType const r, SizeType const*const n,
427
+ PointerIn1 a, SizeType const*const wa,
428
+ PointerIn2 b, SizeType const*const wb,
429
+ value_t v)
430
+ {
431
+ if(r == 0)
432
+ for(auto i0 = 0u; i0 < n[0]; a += wa[0], b += wb[0], ++i0)
433
+ v += *a * *b;
434
+ else
435
+ for(auto ir = 0u; ir < n[r]; a += wa[r], b += wb[r], ++ir)
436
+ v = inner(r-1, n, a, wa, b, wb, v);
437
+ return v;
438
+ }
439
+
440
+
441
+ template <class PointerOut, class PointerIn1, class PointerIn2, class SizeType>
442
+ void outer_2x2(SizeType const pa,
443
+ PointerOut c, SizeType const*const , SizeType const*const wc,
444
+ PointerIn1 a, SizeType const*const na, SizeType const*const wa,
445
+ PointerIn2 b, SizeType const*const nb, SizeType const*const wb)
446
+ {
447
+ // assert(rc == 3);
448
+ // assert(ra == 1);
449
+ // assert(rb == 1);
450
+
451
+ for(auto ib1 = 0u; ib1 < nb[1]; b += wb[1], c += wc[pa+1], ++ib1) {
452
+ auto c2 = c;
453
+ auto b0 = b;
454
+ for(auto ib0 = 0u; ib0 < nb[0]; b0 += wb[0], c2 += wc[pa], ++ib0) {
455
+ const auto b = *b0;
456
+ auto c1 = c2;
457
+ auto a1 = a;
458
+ for(auto ia1 = 0u; ia1 < na[1]; a1 += wa[1], c1 += wc[1], ++ia1) {
459
+ auto a0 = a1;
460
+ auto c0 = c1;
461
+ for(SizeType ia0 = 0u; ia0 < na[0]; a0 += wa[0], c0 += wc[0], ++ia0)
462
+ *c0 = *a0 * b;
463
+ }
464
+ }
465
+ }
466
+ }
467
+
468
+ /** @brief Computes the outer product of two tensors
469
+ *
470
+ * Implements C[i1,...,ip,j1,...,jq] = A[i1,i2,...,ip] * B[j1,j2,...,jq]
471
+ *
472
+ * @note called by outer
473
+ *
474
+ *
475
+ * @param[in] pa number of dimensions (rank) of the first input tensor A with pa > 0
476
+ *
477
+ * @param[in] rc recursion level for C that starts with pc-1
478
+ * @param[out] c pointer to the output tensor
479
+ * @param[in] nc pointer to the extents of output tensor c
480
+ * @param[in] wc pointer to the strides of output tensor c
481
+ *
482
+ * @param[in] ra recursion level for A that starts with pa-1
483
+ * @param[in] a pointer to the first input tensor
484
+ * @param[in] na pointer to the extents of the first input tensor a
485
+ * @param[in] wa pointer to the strides of the first input tensor a
486
+ *
487
+ * @param[in] rb recursion level for B that starts with pb-1
488
+ * @param[in] b pointer to the second input tensor
489
+ * @param[in] nb pointer to the extents of the second input tensor b
490
+ * @param[in] wb pointer to the strides of the second input tensor b
491
+ */
492
+ template<class PointerOut, class PointerIn1, class PointerIn2, class SizeType>
493
+ void outer(SizeType const pa,
494
+ SizeType const rc, PointerOut c, SizeType const*const nc, SizeType const*const wc,
495
+ SizeType const ra, PointerIn1 a, SizeType const*const na, SizeType const*const wa,
496
+ SizeType const rb, PointerIn2 b, SizeType const*const nb, SizeType const*const wb)
497
+ {
498
+ if(rb > 1)
499
+ for(auto ib = 0u; ib < nb[rb]; b += wb[rb], c += wc[rc], ++ib)
500
+ outer(pa, rc-1, c, nc, wc, ra, a, na, wa, rb-1, b, nb, wb);
501
+ else if(ra > 1)
502
+ for(auto ia = 0u; ia < na[ra]; a += wa[ra], c += wc[ra], ++ia)
503
+ outer(pa, rc-1, c, nc, wc, ra-1, a, na, wa, rb, b, nb, wb);
504
+ else
505
+ outer_2x2(pa, c, nc, wc, a, na, wa, b, nb, wb); //assert(ra==1 && rb==1 && rc==3);
506
+ }
507
+
508
+
509
+
510
+
511
+ /** @brief Computes the outer product with permutation tuples
512
+ *
513
+ * Implements C[i1,...,ir,j1,...,js] = sum( A[i1,...,ir] * B[j1,...,js] )
514
+ *
515
+ * nc[x] = na[phia[x]] for 1 <= x <= r
516
+ * nc[r+x] = nb[phib[x]] for 1 <= x <= s
517
+ *
518
+ * @note maybe called by ttt function
519
+ *
520
+ * @param k zero-based recursion level starting with 0
521
+ * @param r number of non-contraction indices of A
522
+ * @param s number of non-contraction indices of B
523
+ * @param phia pointer to the permutation tuple of length r for A
524
+ * @param phib pointer to the permutation tuple of length s for B
525
+ * @param c pointer to the output tensor C with rank(A)=r+s
526
+ * @param nc pointer to the extents of tensor C
527
+ * @param wc pointer to the strides of tensor C
528
+ * @param a pointer to the first input tensor with rank(A)=r
529
+ * @param na pointer to the extents of the first input tensor A
530
+ * @param wa pointer to the strides of the first input tensor A
531
+ * @param b pointer to the second input tensor B with rank(B)=s
532
+ * @param nb pointer to the extents of the second input tensor B
533
+ * @param wb pointer to the strides of the second input tensor B
534
+ */
535
+
536
+ template <class PointerOut, class PointerIn1, class PointerIn2, class SizeType>
537
+ void outer(SizeType const k,
538
+ SizeType const r, SizeType const s,
539
+ SizeType const*const phia, SizeType const*const phib,
540
+ PointerOut c, SizeType const*const nc, SizeType const*const wc,
541
+ PointerIn1 a, SizeType const*const na, SizeType const*const wa,
542
+ PointerIn2 b, SizeType const*const nb, SizeType const*const wb)
543
+ {
544
+ if(k < r)
545
+ {
546
+ assert(nc[k] == na[phia[k]-1]);
547
+ for(size_t ic = 0u; ic < nc[k]; a += wa[phia[k]-1], c += wc[k], ++ic)
548
+ outer(k+1, r, s, phia,phib, c, nc, wc, a, na, wa, b, nb, wb);
549
+ }
550
+ else if(k < r+s-1)
551
+ {
552
+ assert(nc[k] == nb[phib[k-r]-1]);
553
+ for(size_t ic = 0u; ic < nc[k]; b += wb[phib[k-r]-1], c += wc[k], ++ic)
554
+ outer(k+1, r, s, phia, phib, c, nc, wc, a, na, wa, b, nb, wb);
555
+ }
556
+ else
557
+ {
558
+ assert(nc[k] == nb[phib[k-r]-1]);
559
+ for(size_t ic = 0u; ic < nc[k]; b += wb[phib[k-r]-1], c += wc[k], ++ic)
560
+ *c = *a * *b;
561
+ }
562
+ }
563
+
564
+
565
+ } // namespace recursive
566
+ } // namespace detail
567
+ } // namespace ublas
568
+ } // namespace numeric
569
+ } // namespace boost
570
+
571
+
572
+
573
+
574
+ //////////////////////////////////////////////////////////////////////////////////////////
575
+ //////////////////////////////////////////////////////////////////////////////////////////
576
+ //////////////////////////////////////////////////////////////////////////////////////////
577
+ //////////////////////////////////////////////////////////////////////////////////////////
578
+
579
+ //////////////////////////////////////////////////////////////////////////////////////////
580
+ //////////////////////////////////////////////////////////////////////////////////////////
581
+ //////////////////////////////////////////////////////////////////////////////////////////
582
+ //////////////////////////////////////////////////////////////////////////////////////////
583
+
584
+
585
+ #include <stdexcept>
586
+
587
+ namespace boost {
588
+ namespace numeric {
589
+ namespace ublas {
590
+
591
+ /** @brief Computes the tensor-times-vector product
592
+ *
593
+ * Implements
594
+ * C[i1,i2,...,im-1,im+1,...,ip] = sum(A[i1,i2,...,im,...,ip] * b[im]) for m>1 and
595
+ * C[i2,...,ip] = sum(A[i1,...,ip] * b[i1]) for m=1
596
+ *
597
+ * @note calls detail::ttv, detail::ttv0 or detail::mtv
598
+ *
599
+ * @param[in] m contraction mode with 0 < m <= p
600
+ * @param[in] p number of dimensions (rank) of the first input tensor with p > 0
601
+ * @param[out] c pointer to the output tensor with rank p-1
602
+ * @param[in] nc pointer to the extents of tensor c
603
+ * @param[in] wc pointer to the strides of tensor c
604
+ * @param[in] a pointer to the first input tensor
605
+ * @param[in] na pointer to the extents of input tensor a
606
+ * @param[in] wa pointer to the strides of input tensor a
607
+ * @param[in] b pointer to the second input tensor
608
+ * @param[in] nb pointer to the extents of input tensor b
609
+ * @param[in] wb pointer to the strides of input tensor b
610
+ */
611
+ template <class PointerOut, class PointerIn1, class PointerIn2, class SizeType>
612
+ void ttv(SizeType const m, SizeType const p,
613
+ PointerOut c, SizeType const*const nc, SizeType const*const wc,
614
+ const PointerIn1 a, SizeType const*const na, SizeType const*const wa,
615
+ const PointerIn2 b, SizeType const*const nb, SizeType const*const wb)
616
+ {
617
+ static_assert( std::is_pointer<PointerOut>::value & std::is_pointer<PointerIn1>::value & std::is_pointer<PointerIn2>::value,
618
+ "Static error in boost::numeric::ublas::ttv: Argument types for pointers are not pointer types.");
619
+
620
+ if( m == 0)
621
+ throw std::length_error("Error in boost::numeric::ublas::ttv: Contraction mode must be greater than zero.");
622
+
623
+ if( p < m )
624
+ throw std::length_error("Error in boost::numeric::ublas::ttv: Rank must be greater equal the modus.");
625
+
626
+ if( p == 0)
627
+ throw std::length_error("Error in boost::numeric::ublas::ttv: Rank must be greater than zero.");
628
+
629
+ if(c == nullptr || a == nullptr || b == nullptr)
630
+ throw std::length_error("Error in boost::numeric::ublas::ttv: Pointers shall not be null pointers.");
631
+
632
+ for(auto i = 0u; i < m-1; ++i)
633
+ if(na[i] != nc[i])
634
+ throw std::length_error("Error in boost::numeric::ublas::ttv: Extents (except of dimension mode) of A and C must be equal.");
635
+
636
+ for(auto i = m; i < p; ++i)
637
+ if(na[i] != nc[i-1])
638
+ throw std::length_error("Error in boost::numeric::ublas::ttv: Extents (except of dimension mode) of A and C must be equal.");
639
+
640
+ const auto max = std::max(nb[0], nb[1]);
641
+ if( na[m-1] != max)
642
+ throw std::length_error("Error in boost::numeric::ublas::ttv: Extent of dimension mode of A and b must be equal.");
643
+
644
+
645
+ if((m != 1) && (p > 2))
646
+ detail::recursive::ttv(m-1, p-1, p-2, c, nc, wc, a, na, wa, b);
647
+ else if ((m == 1) && (p > 2))
648
+ detail::recursive::ttv0(p-1, c, nc, wc, a, na, wa, b);
649
+ else if( p == 2 )
650
+ detail::recursive::mtv(m-1, c, nc, wc, a, na, wa, b);
651
+ else /*if( p == 1 )*/{
652
+ auto v = std::remove_pointer_t<std::remove_cv_t<PointerOut>>{};
653
+ *c = detail::recursive::inner(SizeType(0), na, a, wa, b, wb, v);
654
+ }
655
+
656
+ }
657
+
658
+
659
+
660
+ /** @brief Computes the tensor-times-matrix product
661
+ *
662
+ * Implements
663
+ * C[i1,i2,...,im-1,j,im+1,...,ip] = sum(A[i1,i2,...,im,...,ip] * B[j,im]) for m>1 and
664
+ * C[j,i2,...,ip] = sum(A[i1,i2,...,ip] * B[j,i1]) for m=1
665
+ *
666
+ * @note calls detail::ttm or detail::ttm0
667
+ *
668
+ * @param[in] m contraction mode with 0 < m <= p
669
+ * @param[in] p number of dimensions (rank) of the first input tensor with p > 0
670
+ * @param[out] c pointer to the output tensor with rank p-1
671
+ * @param[in] nc pointer to the extents of tensor c
672
+ * @param[in] wc pointer to the strides of tensor c
673
+ * @param[in] a pointer to the first input tensor
674
+ * @param[in] na pointer to the extents of input tensor a
675
+ * @param[in] wa pointer to the strides of input tensor a
676
+ * @param[in] b pointer to the second input tensor
677
+ * @param[in] nb pointer to the extents of input tensor b
678
+ * @param[in] wb pointer to the strides of input tensor b
679
+ */
680
+
681
+ template <class PointerIn1, class PointerIn2, class PointerOut, class SizeType>
682
+ void ttm(SizeType const m, SizeType const p,
683
+ PointerOut c, SizeType const*const nc, SizeType const*const wc,
684
+ const PointerIn1 a, SizeType const*const na, SizeType const*const wa,
685
+ const PointerIn2 b, SizeType const*const nb, SizeType const*const wb)
686
+ {
687
+
688
+ static_assert( std::is_pointer<PointerOut>::value & std::is_pointer<PointerIn1>::value & std::is_pointer<PointerIn2>::value,
689
+ "Static error in boost::numeric::ublas::ttm: Argument types for pointers are not pointer types.");
690
+
691
+ if( m == 0 )
692
+ throw std::length_error("Error in boost::numeric::ublas::ttm: Contraction mode must be greater than zero.");
693
+
694
+ if( p < m )
695
+ throw std::length_error("Error in boost::numeric::ublas::ttm: Rank must be greater equal than the specified mode.");
696
+
697
+ if( p == 0)
698
+ throw std::length_error("Error in boost::numeric::ublas::ttm:Rank must be greater than zero.");
699
+
700
+ if(c == nullptr || a == nullptr || b == nullptr)
701
+ throw std::length_error("Error in boost::numeric::ublas::ttm: Pointers shall not be null pointers.");
702
+
703
+ for(auto i = 0u; i < m-1; ++i)
704
+ if(na[i] != nc[i])
705
+ throw std::length_error("Error in boost::numeric::ublas::ttm: Extents (except of dimension mode) of A and C must be equal.");
706
+
707
+ for(auto i = m; i < p; ++i)
708
+ if(na[i] != nc[i])
709
+ throw std::length_error("Error in boost::numeric::ublas::ttm: Extents (except of dimension mode) of A and C must be equal.");
710
+
711
+ if(na[m-1] != nb[1])
712
+ throw std::length_error("Error in boost::numeric::ublas::ttm: 2nd Extent of B and M-th Extent of A must be the equal.");
713
+
714
+ if(nc[m-1] != nb[0])
715
+ throw std::length_error("Error in boost::numeric::ublas::ttm: 1nd Extent of B and M-th Extent of C must be the equal.");
716
+
717
+ if ( m != 1 )
718
+ detail::recursive::ttm (m-1, p-1, c, nc, wc, a, na, wa, b, nb, wb);
719
+ else /*if (m == 1 && p > 2)*/
720
+ detail::recursive::ttm0( p-1, c, nc, wc, a, na, wa, b, nb, wb);
721
+
722
+ }
723
+
724
+
725
+ /** @brief Computes the tensor-times-tensor product
726
+ *
727
+ * Implements C[i1,...,ir,j1,...,js] = sum( A[i1,...,ir+q] * B[j1,...,js+q] )
728
+ *
729
+ * @note calls detail::recursive::ttt or ttm or ttv or inner or outer
730
+ *
731
+ * nc[x] = na[phia[x] ] for 1 <= x <= r
732
+ * nc[r+x] = nb[phib[x] ] for 1 <= x <= s
733
+ * na[phia[r+x]] = nb[phib[s+x]] for 1 <= x <= q
734
+ *
735
+ * @param[in] pa number of dimensions (rank) of the first input tensor a with pa > 0
736
+ * @param[in] pb number of dimensions (rank) of the second input tensor b with pb > 0
737
+ * @param[in] q number of contraction dimensions with pa >= q and pb >= q and q >= 0
738
+ * @param[in] phia pointer to a permutation tuple for the first input tensor a
739
+ * @param[in] phib pointer to a permutation tuple for the second input tensor b
740
+ * @param[out] c pointer to the output tensor with rank p-1
741
+ * @param[in] nc pointer to the extents of tensor c
742
+ * @param[in] wc pointer to the strides of tensor c
743
+ * @param[in] a pointer to the first input tensor
744
+ * @param[in] na pointer to the extents of input tensor a
745
+ * @param[in] wa pointer to the strides of input tensor a
746
+ * @param[in] b pointer to the second input tensor
747
+ * @param[in] nb pointer to the extents of input tensor b
748
+ * @param[in] wb pointer to the strides of input tensor b
749
+ */
750
+
751
+ template <class PointerIn1, class PointerIn2, class PointerOut, class SizeType>
752
+ void ttt(SizeType const pa, SizeType const pb, SizeType const q,
753
+ SizeType const*const phia, SizeType const*const phib,
754
+ PointerOut c, SizeType const*const nc, SizeType const*const wc,
755
+ PointerIn1 a, SizeType const*const na, SizeType const*const wa,
756
+ PointerIn2 b, SizeType const*const nb, SizeType const*const wb)
757
+ {
758
+ static_assert( std::is_pointer<PointerOut>::value & std::is_pointer<PointerIn1>::value & std::is_pointer<PointerIn2>::value,
759
+ "Static error in boost::numeric::ublas::ttm: Argument types for pointers are not pointer types.");
760
+
761
+ if( pa == 0 || pb == 0)
762
+ throw std::length_error("Error in boost::numeric::ublas::ttt: tensor order must be greater zero.");
763
+
764
+ if( q > pa && q > pb)
765
+ throw std::length_error("Error in boost::numeric::ublas::ttt: number of contraction must be smaller than or equal to the tensor order.");
766
+
767
+
768
+ SizeType const r = pa - q;
769
+ SizeType const s = pb - q;
770
+
771
+ if(c == nullptr || a == nullptr || b == nullptr)
772
+ throw std::length_error("Error in boost::numeric::ublas::ttm: Pointers shall not be null pointers.");
773
+
774
+ for(auto i = 0ul; i < r; ++i)
775
+ if( na[phia[i]-1] != nc[i] )
776
+ throw std::length_error("Error in boost::numeric::ublas::ttt: dimensions of lhs and res tensor not correct.");
777
+
778
+ for(auto i = 0ul; i < s; ++i)
779
+ if( nb[phib[i]-1] != nc[r+i] )
780
+ throw std::length_error("Error in boost::numeric::ublas::ttt: dimensions of rhs and res not correct.");
781
+
782
+ for(auto i = 0ul; i < q; ++i)
783
+ if( nb[phib[s+i]-1] != na[phia[r+i]-1] )
784
+ throw std::length_error("Error in boost::numeric::ublas::ttt: dimensions of lhs and rhs not correct.");
785
+
786
+
787
+ if(q == 0ul)
788
+ detail::recursive::outer(SizeType{0},r,s, phia,phib, c,nc,wc, a,na,wa, b,nb,wb);
789
+ else
790
+ detail::recursive::ttt(SizeType{0},r,s,q, phia,phib, c,nc,wc, a,na,wa, b,nb,wb);
791
+ }
792
+
793
+
794
+
795
+ /** @brief Computes the tensor-times-tensor product
796
+ *
797
+ * Implements C[i1,...,ir,j1,...,js] = sum( A[i1,...,ir+q] * B[j1,...,js+q] )
798
+ *
799
+ * @note calls detail::recursive::ttt or ttm or ttv or inner or outer
800
+ *
801
+ * nc[x] = na[x ] for 1 <= x <= r
802
+ * nc[r+x] = nb[x ] for 1 <= x <= s
803
+ * na[r+x] = nb[s+x] for 1 <= x <= q
804
+ *
805
+ * @param[in] pa number of dimensions (rank) of the first input tensor a with pa > 0
806
+ * @param[in] pb number of dimensions (rank) of the second input tensor b with pb > 0
807
+ * @param[in] q number of contraction dimensions with pa >= q and pb >= q and q >= 0
808
+ * @param[out] c pointer to the output tensor with rank p-1
809
+ * @param[in] nc pointer to the extents of tensor c
810
+ * @param[in] wc pointer to the strides of tensor c
811
+ * @param[in] a pointer to the first input tensor
812
+ * @param[in] na pointer to the extents of input tensor a
813
+ * @param[in] wa pointer to the strides of input tensor a
814
+ * @param[in] b pointer to the second input tensor
815
+ * @param[in] nb pointer to the extents of input tensor b
816
+ * @param[in] wb pointer to the strides of input tensor b
817
+ */
818
+
819
+ template <class PointerIn1, class PointerIn2, class PointerOut, class SizeType>
820
+ void ttt(SizeType const pa, SizeType const pb, SizeType const q,
821
+ PointerOut c, SizeType const*const nc, SizeType const*const wc,
822
+ PointerIn1 a, SizeType const*const na, SizeType const*const wa,
823
+ PointerIn2 b, SizeType const*const nb, SizeType const*const wb)
824
+ {
825
+ static_assert( std::is_pointer<PointerOut>::value & std::is_pointer<PointerIn1>::value & std::is_pointer<PointerIn2>::value,
826
+ "Static error in boost::numeric::ublas::ttm: Argument types for pointers are not pointer types.");
827
+
828
+ if( pa == 0 || pb == 0)
829
+ throw std::length_error("Error in boost::numeric::ublas::ttt: tensor order must be greater zero.");
830
+
831
+ if( q > pa && q > pb)
832
+ throw std::length_error("Error in boost::numeric::ublas::ttt: number of contraction must be smaller than or equal to the tensor order.");
833
+
834
+
835
+ SizeType const r = pa - q;
836
+ SizeType const s = pb - q;
837
+ SizeType const pc = r+s;
838
+
839
+ if(c == nullptr || a == nullptr || b == nullptr)
840
+ throw std::length_error("Error in boost::numeric::ublas::ttm: Pointers shall not be null pointers.");
841
+
842
+ for(auto i = 0ul; i < r; ++i)
843
+ if( na[i] != nc[i] )
844
+ throw std::length_error("Error in boost::numeric::ublas::ttt: dimensions of lhs and res tensor not correct.");
845
+
846
+ for(auto i = 0ul; i < s; ++i)
847
+ if( nb[i] != nc[r+i] )
848
+ throw std::length_error("Error in boost::numeric::ublas::ttt: dimensions of rhs and res not correct.");
849
+
850
+ for(auto i = 0ul; i < q; ++i)
851
+ if( nb[s+i] != na[r+i] )
852
+ throw std::length_error("Error in boost::numeric::ublas::ttt: dimensions of lhs and rhs not correct.");
853
+
854
+ using value_type = std::decay_t<decltype(*c)>;
855
+
856
+
857
+
858
+ if(q == 0ul)
859
+ detail::recursive::outer(pa, pc-1, c,nc,wc, pa-1, a,na,wa, pb-1, b,nb,wb);
860
+ else if(r == 0ul && s == 0ul)
861
+ *c = detail::recursive::inner(q-1, na, a,wa, b,wb, value_type(0) );
862
+ else
863
+ detail::recursive::ttt(SizeType{0},r,s,q, c,nc,wc, a,na,wa, b,nb,wb);
864
+ }
865
+
866
+
867
+ /** @brief Computes the inner product of two tensors
868
+ *
869
+ * Implements c = sum(A[i1,i2,...,ip] * B[i1,i2,...,ip])
870
+ *
871
+ * @note calls detail::inner
872
+ *
873
+ * @param[in] p number of dimensions (rank) of the first input tensor with p > 0
874
+ * @param[in] n pointer to the extents of input or output tensor
875
+ * @param[in] a pointer to the first input tensor
876
+ * @param[in] wa pointer to the strides of input tensor a
877
+ * @param[in] b pointer to the second input tensor
878
+ * @param[in] wb pointer to the strides of input tensor b
879
+ * @param[in] v inital value
880
+ *
881
+ * @return inner product of two tensors.
882
+ */
883
+ template <class PointerIn1, class PointerIn2, class value_t, class SizeType>
884
+ auto inner(const SizeType p, SizeType const*const n,
885
+ const PointerIn1 a, SizeType const*const wa,
886
+ const PointerIn2 b, SizeType const*const wb,
887
+ value_t v)
888
+ {
889
+ static_assert( std::is_pointer<PointerIn1>::value && std::is_pointer<PointerIn2>::value,
890
+ "Static error in boost::numeric::ublas::inner: Argument types for pointers must be pointer types.");
891
+ if(p<2)
892
+ throw std::length_error("Error in boost::numeric::ublas::inner: Rank must be greater than zero.");
893
+ if(a == nullptr || b == nullptr)
894
+ throw std::length_error("Error in boost::numeric::ublas::inner: Pointers shall not be null pointers.");
895
+
896
+ return detail::recursive::inner(p-1, n, a, wa, b, wb, v);
897
+
898
+ }
899
+
900
+
901
+ /** @brief Computes the outer product of two tensors
902
+ *
903
+ * Implements C[i1,...,ip,j1,...,jq] = A[i1,i2,...,ip] * B[j1,j2,...,jq]
904
+ *
905
+ * @note calls detail::outer
906
+ *
907
+ * @param[out] c pointer to the output tensor
908
+ * @param[in] pc number of dimensions (rank) of the output tensor c with pc > 0
909
+ * @param[in] nc pointer to the extents of output tensor c
910
+ * @param[in] wc pointer to the strides of output tensor c
911
+ * @param[in] a pointer to the first input tensor
912
+ * @param[in] pa number of dimensions (rank) of the first input tensor a with pa > 0
913
+ * @param[in] na pointer to the extents of the first input tensor a
914
+ * @param[in] wa pointer to the strides of the first input tensor a
915
+ * @param[in] b pointer to the second input tensor
916
+ * @param[in] pb number of dimensions (rank) of the second input tensor b with pb > 0
917
+ * @param[in] nb pointer to the extents of the second input tensor b
918
+ * @param[in] wb pointer to the strides of the second input tensor b
919
+ */
920
+ template <class PointerOut, class PointerIn1, class PointerIn2, class SizeType>
921
+ void outer(PointerOut c, SizeType const pc, SizeType const*const nc, SizeType const*const wc,
922
+ const PointerIn1 a, SizeType const pa, SizeType const*const na, SizeType const*const wa,
923
+ const PointerIn2 b, SizeType const pb, SizeType const*const nb, SizeType const*const wb)
924
+ {
925
+ static_assert( std::is_pointer<PointerIn1>::value & std::is_pointer<PointerIn2>::value & std::is_pointer<PointerOut>::value,
926
+ "Static error in boost::numeric::ublas::outer: argument types for pointers must be pointer types.");
927
+ if(pa < 2u || pb < 2u)
928
+ throw std::length_error("Error in boost::numeric::ublas::outer: number of extents of lhs and rhs tensor must be equal or greater than two.");
929
+ if((pa + pb) != pc)
930
+ throw std::length_error("Error in boost::numeric::ublas::outer: number of extents of lhs plus rhs tensor must be equal to the number of extents of C.");
931
+ if(a == nullptr || b == nullptr || c == nullptr)
932
+ throw std::length_error("Error in boost::numeric::ublas::outer: pointers shall not be null pointers.");
933
+
934
+ detail::recursive::outer(pa, pc-1, c, nc, wc, pa-1, a, na, wa, pb-1, b, nb, wb);
935
+
936
+ }
937
+
938
+
939
+
940
+
941
+ }
942
+ }
943
+ }
944
+
945
+ #endif