ilt-inversion 0.1.2__tar.gz

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 (348) hide show
  1. ilt_inversion-0.1.2/.github/workflows/build-wheels.yml +127 -0
  2. ilt_inversion-0.1.2/.gitignore +23 -0
  3. ilt_inversion-0.1.2/Cargo.lock +230 -0
  4. ilt_inversion-0.1.2/Cargo.toml +21 -0
  5. ilt_inversion-0.1.2/PKG-INFO +147 -0
  6. ilt_inversion-0.1.2/README.md +121 -0
  7. ilt_inversion-0.1.2/build_pure_python.py +67 -0
  8. ilt_inversion-0.1.2/pyproject.toml +41 -0
  9. ilt_inversion-0.1.2/python/ilt/__init__.py +237 -0
  10. ilt_inversion-0.1.2/python/ilt/_backends.py +137 -0
  11. ilt_inversion-0.1.2/python/ilt/_bessel.py +52 -0
  12. ilt_inversion-0.1.2/python/ilt/_gwr.py +161 -0
  13. ilt_inversion-0.1.2/python/ilt/_parallel.py +56 -0
  14. ilt_inversion-0.1.2/python/ilt/_talbot.py +16 -0
  15. ilt_inversion-0.1.2/src/bessel.rs +198 -0
  16. ilt_inversion-0.1.2/src/gwr.rs +178 -0
  17. ilt_inversion-0.1.2/src/lib.rs +12 -0
  18. ilt_inversion-0.1.2/target/.rustc_info.json +1 -0
  19. ilt_inversion-0.1.2/target/release/.cargo-lock +0 -0
  20. ilt_inversion-0.1.2/target/release/.fingerprint/autocfg-50cc232bf4095b5c/dep-lib-autocfg +0 -0
  21. ilt_inversion-0.1.2/target/release/.fingerprint/autocfg-50cc232bf4095b5c/invoked.timestamp +1 -0
  22. ilt_inversion-0.1.2/target/release/.fingerprint/autocfg-50cc232bf4095b5c/lib-autocfg +1 -0
  23. ilt_inversion-0.1.2/target/release/.fingerprint/autocfg-50cc232bf4095b5c/lib-autocfg.json +1 -0
  24. ilt_inversion-0.1.2/target/release/.fingerprint/az-bda0b4d01a15b607/dep-lib-az +0 -0
  25. ilt_inversion-0.1.2/target/release/.fingerprint/az-bda0b4d01a15b607/invoked.timestamp +1 -0
  26. ilt_inversion-0.1.2/target/release/.fingerprint/az-bda0b4d01a15b607/lib-az +1 -0
  27. ilt_inversion-0.1.2/target/release/.fingerprint/az-bda0b4d01a15b607/lib-az.json +1 -0
  28. ilt_inversion-0.1.2/target/release/.fingerprint/cfg-if-aa4e316ed40820f8/dep-lib-cfg_if +0 -0
  29. ilt_inversion-0.1.2/target/release/.fingerprint/cfg-if-aa4e316ed40820f8/invoked.timestamp +1 -0
  30. ilt_inversion-0.1.2/target/release/.fingerprint/cfg-if-aa4e316ed40820f8/lib-cfg_if +1 -0
  31. ilt_inversion-0.1.2/target/release/.fingerprint/cfg-if-aa4e316ed40820f8/lib-cfg_if.json +1 -0
  32. ilt_inversion-0.1.2/target/release/.fingerprint/gmp-mpfr-sys-8d640562ddb08dff/dep-lib-gmp_mpfr_sys +0 -0
  33. ilt_inversion-0.1.2/target/release/.fingerprint/gmp-mpfr-sys-8d640562ddb08dff/invoked.timestamp +1 -0
  34. ilt_inversion-0.1.2/target/release/.fingerprint/gmp-mpfr-sys-8d640562ddb08dff/lib-gmp_mpfr_sys +1 -0
  35. ilt_inversion-0.1.2/target/release/.fingerprint/gmp-mpfr-sys-8d640562ddb08dff/lib-gmp_mpfr_sys.json +1 -0
  36. ilt_inversion-0.1.2/target/release/.fingerprint/gmp-mpfr-sys-ac103911bac5b099/run-build-script-build-script-build +1 -0
  37. ilt_inversion-0.1.2/target/release/.fingerprint/gmp-mpfr-sys-ac103911bac5b099/run-build-script-build-script-build.json +1 -0
  38. ilt_inversion-0.1.2/target/release/.fingerprint/gmp-mpfr-sys-d34de8c81a1e3e2e/build-script-build-script-build +1 -0
  39. ilt_inversion-0.1.2/target/release/.fingerprint/gmp-mpfr-sys-d34de8c81a1e3e2e/build-script-build-script-build.json +1 -0
  40. ilt_inversion-0.1.2/target/release/.fingerprint/gmp-mpfr-sys-d34de8c81a1e3e2e/dep-build-script-build-script-build +0 -0
  41. ilt_inversion-0.1.2/target/release/.fingerprint/gmp-mpfr-sys-d34de8c81a1e3e2e/invoked.timestamp +1 -0
  42. ilt_inversion-0.1.2/target/release/.fingerprint/heck-5dc7f4317c48936c/dep-lib-heck +0 -0
  43. ilt_inversion-0.1.2/target/release/.fingerprint/heck-5dc7f4317c48936c/invoked.timestamp +1 -0
  44. ilt_inversion-0.1.2/target/release/.fingerprint/heck-5dc7f4317c48936c/lib-heck +1 -0
  45. ilt_inversion-0.1.2/target/release/.fingerprint/heck-5dc7f4317c48936c/lib-heck.json +1 -0
  46. ilt_inversion-0.1.2/target/release/.fingerprint/ilt-native-3378ccfc3ac3204d/dep-lib-_native +0 -0
  47. ilt_inversion-0.1.2/target/release/.fingerprint/ilt-native-3378ccfc3ac3204d/invoked.timestamp +1 -0
  48. ilt_inversion-0.1.2/target/release/.fingerprint/ilt-native-3378ccfc3ac3204d/lib-_native +1 -0
  49. ilt_inversion-0.1.2/target/release/.fingerprint/ilt-native-3378ccfc3ac3204d/lib-_native.json +1 -0
  50. ilt_inversion-0.1.2/target/release/.fingerprint/indoc-879a93f3157cff50/dep-lib-indoc +0 -0
  51. ilt_inversion-0.1.2/target/release/.fingerprint/indoc-879a93f3157cff50/invoked.timestamp +1 -0
  52. ilt_inversion-0.1.2/target/release/.fingerprint/indoc-879a93f3157cff50/lib-indoc +1 -0
  53. ilt_inversion-0.1.2/target/release/.fingerprint/indoc-879a93f3157cff50/lib-indoc.json +1 -0
  54. ilt_inversion-0.1.2/target/release/.fingerprint/libc-2adfdf8733aa3c49/dep-lib-libc +0 -0
  55. ilt_inversion-0.1.2/target/release/.fingerprint/libc-2adfdf8733aa3c49/invoked.timestamp +1 -0
  56. ilt_inversion-0.1.2/target/release/.fingerprint/libc-2adfdf8733aa3c49/lib-libc +1 -0
  57. ilt_inversion-0.1.2/target/release/.fingerprint/libc-2adfdf8733aa3c49/lib-libc.json +1 -0
  58. ilt_inversion-0.1.2/target/release/.fingerprint/libc-6c2da274434cce6b/run-build-script-build-script-build +1 -0
  59. ilt_inversion-0.1.2/target/release/.fingerprint/libc-6c2da274434cce6b/run-build-script-build-script-build.json +1 -0
  60. ilt_inversion-0.1.2/target/release/.fingerprint/libc-83ad38f308fff90d/build-script-build-script-build +1 -0
  61. ilt_inversion-0.1.2/target/release/.fingerprint/libc-83ad38f308fff90d/build-script-build-script-build.json +1 -0
  62. ilt_inversion-0.1.2/target/release/.fingerprint/libc-83ad38f308fff90d/dep-build-script-build-script-build +0 -0
  63. ilt_inversion-0.1.2/target/release/.fingerprint/libc-83ad38f308fff90d/invoked.timestamp +1 -0
  64. ilt_inversion-0.1.2/target/release/.fingerprint/libm-847e5c1ab8d7b98d/build-script-build-script-build +1 -0
  65. ilt_inversion-0.1.2/target/release/.fingerprint/libm-847e5c1ab8d7b98d/build-script-build-script-build.json +1 -0
  66. ilt_inversion-0.1.2/target/release/.fingerprint/libm-847e5c1ab8d7b98d/dep-build-script-build-script-build +0 -0
  67. ilt_inversion-0.1.2/target/release/.fingerprint/libm-847e5c1ab8d7b98d/invoked.timestamp +1 -0
  68. ilt_inversion-0.1.2/target/release/.fingerprint/libm-a2bc1f4e616a9eee/dep-lib-libm +0 -0
  69. ilt_inversion-0.1.2/target/release/.fingerprint/libm-a2bc1f4e616a9eee/invoked.timestamp +1 -0
  70. ilt_inversion-0.1.2/target/release/.fingerprint/libm-a2bc1f4e616a9eee/lib-libm +1 -0
  71. ilt_inversion-0.1.2/target/release/.fingerprint/libm-a2bc1f4e616a9eee/lib-libm.json +1 -0
  72. ilt_inversion-0.1.2/target/release/.fingerprint/libm-da7358a3be7058b1/run-build-script-build-script-build +1 -0
  73. ilt_inversion-0.1.2/target/release/.fingerprint/libm-da7358a3be7058b1/run-build-script-build-script-build.json +1 -0
  74. ilt_inversion-0.1.2/target/release/.fingerprint/memoffset-04cdf5627a421592/dep-lib-memoffset +0 -0
  75. ilt_inversion-0.1.2/target/release/.fingerprint/memoffset-04cdf5627a421592/invoked.timestamp +1 -0
  76. ilt_inversion-0.1.2/target/release/.fingerprint/memoffset-04cdf5627a421592/lib-memoffset +1 -0
  77. ilt_inversion-0.1.2/target/release/.fingerprint/memoffset-04cdf5627a421592/lib-memoffset.json +1 -0
  78. ilt_inversion-0.1.2/target/release/.fingerprint/memoffset-0a01b37ba977c671/build-script-build-script-build +1 -0
  79. ilt_inversion-0.1.2/target/release/.fingerprint/memoffset-0a01b37ba977c671/build-script-build-script-build.json +1 -0
  80. ilt_inversion-0.1.2/target/release/.fingerprint/memoffset-0a01b37ba977c671/dep-build-script-build-script-build +0 -0
  81. ilt_inversion-0.1.2/target/release/.fingerprint/memoffset-0a01b37ba977c671/invoked.timestamp +1 -0
  82. ilt_inversion-0.1.2/target/release/.fingerprint/memoffset-df3e07e3a70e56f0/run-build-script-build-script-build +1 -0
  83. ilt_inversion-0.1.2/target/release/.fingerprint/memoffset-df3e07e3a70e56f0/run-build-script-build-script-build.json +1 -0
  84. ilt_inversion-0.1.2/target/release/.fingerprint/once_cell-6d12b3fd7eb02e69/dep-lib-once_cell +0 -0
  85. ilt_inversion-0.1.2/target/release/.fingerprint/once_cell-6d12b3fd7eb02e69/invoked.timestamp +1 -0
  86. ilt_inversion-0.1.2/target/release/.fingerprint/once_cell-6d12b3fd7eb02e69/lib-once_cell +1 -0
  87. ilt_inversion-0.1.2/target/release/.fingerprint/once_cell-6d12b3fd7eb02e69/lib-once_cell.json +1 -0
  88. ilt_inversion-0.1.2/target/release/.fingerprint/once_cell-a4b668872013ad95/dep-lib-once_cell +0 -0
  89. ilt_inversion-0.1.2/target/release/.fingerprint/once_cell-a4b668872013ad95/invoked.timestamp +1 -0
  90. ilt_inversion-0.1.2/target/release/.fingerprint/once_cell-a4b668872013ad95/lib-once_cell +1 -0
  91. ilt_inversion-0.1.2/target/release/.fingerprint/once_cell-a4b668872013ad95/lib-once_cell.json +1 -0
  92. ilt_inversion-0.1.2/target/release/.fingerprint/proc-macro2-a4ae1b7f808ac62a/run-build-script-build-script-build +1 -0
  93. ilt_inversion-0.1.2/target/release/.fingerprint/proc-macro2-a4ae1b7f808ac62a/run-build-script-build-script-build.json +1 -0
  94. ilt_inversion-0.1.2/target/release/.fingerprint/proc-macro2-c6dc7f1a9d5a937a/dep-lib-proc_macro2 +0 -0
  95. ilt_inversion-0.1.2/target/release/.fingerprint/proc-macro2-c6dc7f1a9d5a937a/invoked.timestamp +1 -0
  96. ilt_inversion-0.1.2/target/release/.fingerprint/proc-macro2-c6dc7f1a9d5a937a/lib-proc_macro2 +1 -0
  97. ilt_inversion-0.1.2/target/release/.fingerprint/proc-macro2-c6dc7f1a9d5a937a/lib-proc_macro2.json +1 -0
  98. ilt_inversion-0.1.2/target/release/.fingerprint/proc-macro2-c8a3c3766780cf04/build-script-build-script-build +1 -0
  99. ilt_inversion-0.1.2/target/release/.fingerprint/proc-macro2-c8a3c3766780cf04/build-script-build-script-build.json +1 -0
  100. ilt_inversion-0.1.2/target/release/.fingerprint/proc-macro2-c8a3c3766780cf04/dep-build-script-build-script-build +0 -0
  101. ilt_inversion-0.1.2/target/release/.fingerprint/proc-macro2-c8a3c3766780cf04/invoked.timestamp +1 -0
  102. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-100d5c185eb0b24e/run-build-script-build-script-build +1 -0
  103. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-100d5c185eb0b24e/run-build-script-build-script-build.json +1 -0
  104. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-8cf1d85e34bdd655/build-script-build-script-build +1 -0
  105. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-8cf1d85e34bdd655/build-script-build-script-build.json +1 -0
  106. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-8cf1d85e34bdd655/dep-build-script-build-script-build +0 -0
  107. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-8cf1d85e34bdd655/invoked.timestamp +1 -0
  108. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-a0dfb6e3ee0cde3a/dep-lib-pyo3 +0 -0
  109. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-a0dfb6e3ee0cde3a/invoked.timestamp +1 -0
  110. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-a0dfb6e3ee0cde3a/lib-pyo3 +1 -0
  111. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-a0dfb6e3ee0cde3a/lib-pyo3.json +1 -0
  112. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-build-config-7e90a94e1c1a7cf8/run-build-script-build-script-build +1 -0
  113. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-build-config-7e90a94e1c1a7cf8/run-build-script-build-script-build.json +1 -0
  114. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-build-config-c1cb7955e14a6fee/build-script-build-script-build +1 -0
  115. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-build-config-c1cb7955e14a6fee/build-script-build-script-build.json +1 -0
  116. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-build-config-c1cb7955e14a6fee/dep-build-script-build-script-build +0 -0
  117. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-build-config-c1cb7955e14a6fee/invoked.timestamp +1 -0
  118. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-build-config-f65a826ddbf36c59/dep-lib-pyo3_build_config +0 -0
  119. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-build-config-f65a826ddbf36c59/invoked.timestamp +1 -0
  120. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-build-config-f65a826ddbf36c59/lib-pyo3_build_config +1 -0
  121. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-build-config-f65a826ddbf36c59/lib-pyo3_build_config.json +1 -0
  122. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-ffi-2c8cbde79a622c8a/run-build-script-build-script-build +1 -0
  123. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-ffi-2c8cbde79a622c8a/run-build-script-build-script-build.json +1 -0
  124. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-ffi-601592a92c7776c5/build-script-build-script-build +1 -0
  125. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-ffi-601592a92c7776c5/build-script-build-script-build.json +1 -0
  126. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-ffi-601592a92c7776c5/dep-build-script-build-script-build +0 -0
  127. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-ffi-601592a92c7776c5/invoked.timestamp +1 -0
  128. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-ffi-ce66a5849929e42b/dep-lib-pyo3_ffi +0 -0
  129. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-ffi-ce66a5849929e42b/invoked.timestamp +1 -0
  130. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-ffi-ce66a5849929e42b/lib-pyo3_ffi +1 -0
  131. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-ffi-ce66a5849929e42b/lib-pyo3_ffi.json +1 -0
  132. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-macros-b93689a95840e633/dep-lib-pyo3_macros +0 -0
  133. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-macros-b93689a95840e633/invoked.timestamp +1 -0
  134. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-macros-b93689a95840e633/lib-pyo3_macros +1 -0
  135. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-macros-b93689a95840e633/lib-pyo3_macros.json +1 -0
  136. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-macros-backend-305ff5ab4ffa2832/dep-lib-pyo3_macros_backend +0 -0
  137. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-macros-backend-305ff5ab4ffa2832/invoked.timestamp +1 -0
  138. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-macros-backend-305ff5ab4ffa2832/lib-pyo3_macros_backend +1 -0
  139. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-macros-backend-305ff5ab4ffa2832/lib-pyo3_macros_backend.json +1 -0
  140. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-macros-backend-69536423206fab36/build-script-build-script-build +1 -0
  141. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-macros-backend-69536423206fab36/build-script-build-script-build.json +1 -0
  142. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-macros-backend-69536423206fab36/dep-build-script-build-script-build +0 -0
  143. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-macros-backend-69536423206fab36/invoked.timestamp +1 -0
  144. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-macros-backend-7cb10c9d33dafe97/run-build-script-build-script-build +1 -0
  145. ilt_inversion-0.1.2/target/release/.fingerprint/pyo3-macros-backend-7cb10c9d33dafe97/run-build-script-build-script-build.json +1 -0
  146. ilt_inversion-0.1.2/target/release/.fingerprint/quote-05cbc1ac2323f30b/dep-lib-quote +0 -0
  147. ilt_inversion-0.1.2/target/release/.fingerprint/quote-05cbc1ac2323f30b/invoked.timestamp +1 -0
  148. ilt_inversion-0.1.2/target/release/.fingerprint/quote-05cbc1ac2323f30b/lib-quote +1 -0
  149. ilt_inversion-0.1.2/target/release/.fingerprint/quote-05cbc1ac2323f30b/lib-quote.json +1 -0
  150. ilt_inversion-0.1.2/target/release/.fingerprint/quote-c2cdc7a8dc22bf92/build-script-build-script-build +1 -0
  151. ilt_inversion-0.1.2/target/release/.fingerprint/quote-c2cdc7a8dc22bf92/build-script-build-script-build.json +1 -0
  152. ilt_inversion-0.1.2/target/release/.fingerprint/quote-c2cdc7a8dc22bf92/dep-build-script-build-script-build +0 -0
  153. ilt_inversion-0.1.2/target/release/.fingerprint/quote-c2cdc7a8dc22bf92/invoked.timestamp +1 -0
  154. ilt_inversion-0.1.2/target/release/.fingerprint/quote-f050940e9638289a/run-build-script-build-script-build +1 -0
  155. ilt_inversion-0.1.2/target/release/.fingerprint/quote-f050940e9638289a/run-build-script-build-script-build.json +1 -0
  156. ilt_inversion-0.1.2/target/release/.fingerprint/rug-1886ebe4ea7a76f3/build-script-build-script-build +1 -0
  157. ilt_inversion-0.1.2/target/release/.fingerprint/rug-1886ebe4ea7a76f3/build-script-build-script-build.json +1 -0
  158. ilt_inversion-0.1.2/target/release/.fingerprint/rug-1886ebe4ea7a76f3/dep-build-script-build-script-build +0 -0
  159. ilt_inversion-0.1.2/target/release/.fingerprint/rug-1886ebe4ea7a76f3/invoked.timestamp +1 -0
  160. ilt_inversion-0.1.2/target/release/.fingerprint/rug-19ce01283dcd66c8/run-build-script-build-script-build +1 -0
  161. ilt_inversion-0.1.2/target/release/.fingerprint/rug-19ce01283dcd66c8/run-build-script-build-script-build.json +1 -0
  162. ilt_inversion-0.1.2/target/release/.fingerprint/rug-c8468e662205f3d6/dep-lib-rug +0 -0
  163. ilt_inversion-0.1.2/target/release/.fingerprint/rug-c8468e662205f3d6/invoked.timestamp +1 -0
  164. ilt_inversion-0.1.2/target/release/.fingerprint/rug-c8468e662205f3d6/lib-rug +1 -0
  165. ilt_inversion-0.1.2/target/release/.fingerprint/rug-c8468e662205f3d6/lib-rug.json +1 -0
  166. ilt_inversion-0.1.2/target/release/.fingerprint/syn-d1334b4aa99317c9/dep-lib-syn +0 -0
  167. ilt_inversion-0.1.2/target/release/.fingerprint/syn-d1334b4aa99317c9/invoked.timestamp +1 -0
  168. ilt_inversion-0.1.2/target/release/.fingerprint/syn-d1334b4aa99317c9/lib-syn +1 -0
  169. ilt_inversion-0.1.2/target/release/.fingerprint/syn-d1334b4aa99317c9/lib-syn.json +1 -0
  170. ilt_inversion-0.1.2/target/release/.fingerprint/target-lexicon-0ea54c073f110143/run-build-script-build-script-build +1 -0
  171. ilt_inversion-0.1.2/target/release/.fingerprint/target-lexicon-0ea54c073f110143/run-build-script-build-script-build.json +1 -0
  172. ilt_inversion-0.1.2/target/release/.fingerprint/target-lexicon-4d05354579b49180/dep-lib-target_lexicon +0 -0
  173. ilt_inversion-0.1.2/target/release/.fingerprint/target-lexicon-4d05354579b49180/invoked.timestamp +1 -0
  174. ilt_inversion-0.1.2/target/release/.fingerprint/target-lexicon-4d05354579b49180/lib-target_lexicon +1 -0
  175. ilt_inversion-0.1.2/target/release/.fingerprint/target-lexicon-4d05354579b49180/lib-target_lexicon.json +1 -0
  176. ilt_inversion-0.1.2/target/release/.fingerprint/target-lexicon-682796117b645382/build-script-build-script-build +1 -0
  177. ilt_inversion-0.1.2/target/release/.fingerprint/target-lexicon-682796117b645382/build-script-build-script-build.json +1 -0
  178. ilt_inversion-0.1.2/target/release/.fingerprint/target-lexicon-682796117b645382/dep-build-script-build-script-build +0 -0
  179. ilt_inversion-0.1.2/target/release/.fingerprint/target-lexicon-682796117b645382/invoked.timestamp +1 -0
  180. ilt_inversion-0.1.2/target/release/.fingerprint/unicode-ident-d49005d3adcbc7b3/dep-lib-unicode_ident +0 -0
  181. ilt_inversion-0.1.2/target/release/.fingerprint/unicode-ident-d49005d3adcbc7b3/invoked.timestamp +1 -0
  182. ilt_inversion-0.1.2/target/release/.fingerprint/unicode-ident-d49005d3adcbc7b3/lib-unicode_ident +1 -0
  183. ilt_inversion-0.1.2/target/release/.fingerprint/unicode-ident-d49005d3adcbc7b3/lib-unicode_ident.json +1 -0
  184. ilt_inversion-0.1.2/target/release/.fingerprint/unindent-bde6a2bf09f33e8f/dep-lib-unindent +0 -0
  185. ilt_inversion-0.1.2/target/release/.fingerprint/unindent-bde6a2bf09f33e8f/invoked.timestamp +1 -0
  186. ilt_inversion-0.1.2/target/release/.fingerprint/unindent-bde6a2bf09f33e8f/lib-unindent +1 -0
  187. ilt_inversion-0.1.2/target/release/.fingerprint/unindent-bde6a2bf09f33e8f/lib-unindent.json +1 -0
  188. ilt_inversion-0.1.2/target/release/build/gmp-mpfr-sys-ac103911bac5b099/invoked.timestamp +1 -0
  189. ilt_inversion-0.1.2/target/release/build/gmp-mpfr-sys-ac103911bac5b099/out/gmp_h.rs +8 -0
  190. ilt_inversion-0.1.2/target/release/build/gmp-mpfr-sys-ac103911bac5b099/out/include/gmp.h +2344 -0
  191. ilt_inversion-0.1.2/target/release/build/gmp-mpfr-sys-ac103911bac5b099/out/include/mpfr.h +1269 -0
  192. ilt_inversion-0.1.2/target/release/build/gmp-mpfr-sys-ac103911bac5b099/out/lib/libgmp.a +0 -0
  193. ilt_inversion-0.1.2/target/release/build/gmp-mpfr-sys-ac103911bac5b099/out/lib/libmpfr.a +0 -0
  194. ilt_inversion-0.1.2/target/release/build/gmp-mpfr-sys-ac103911bac5b099/out/mpfr_h.rs +4 -0
  195. ilt_inversion-0.1.2/target/release/build/gmp-mpfr-sys-ac103911bac5b099/output +19 -0
  196. ilt_inversion-0.1.2/target/release/build/gmp-mpfr-sys-ac103911bac5b099/root-output +1 -0
  197. ilt_inversion-0.1.2/target/release/build/gmp-mpfr-sys-ac103911bac5b099/stderr +0 -0
  198. ilt_inversion-0.1.2/target/release/build/gmp-mpfr-sys-d34de8c81a1e3e2e/build-script-build +0 -0
  199. ilt_inversion-0.1.2/target/release/build/gmp-mpfr-sys-d34de8c81a1e3e2e/build_script_build-d34de8c81a1e3e2e +0 -0
  200. ilt_inversion-0.1.2/target/release/build/gmp-mpfr-sys-d34de8c81a1e3e2e/build_script_build-d34de8c81a1e3e2e.d +5 -0
  201. ilt_inversion-0.1.2/target/release/build/libc-6c2da274434cce6b/invoked.timestamp +1 -0
  202. ilt_inversion-0.1.2/target/release/build/libc-6c2da274434cce6b/output +25 -0
  203. ilt_inversion-0.1.2/target/release/build/libc-6c2da274434cce6b/root-output +1 -0
  204. ilt_inversion-0.1.2/target/release/build/libc-6c2da274434cce6b/stderr +0 -0
  205. ilt_inversion-0.1.2/target/release/build/libc-83ad38f308fff90d/build-script-build +0 -0
  206. ilt_inversion-0.1.2/target/release/build/libc-83ad38f308fff90d/build_script_build-83ad38f308fff90d +0 -0
  207. ilt_inversion-0.1.2/target/release/build/libc-83ad38f308fff90d/build_script_build-83ad38f308fff90d.d +5 -0
  208. ilt_inversion-0.1.2/target/release/build/libm-847e5c1ab8d7b98d/build-script-build +0 -0
  209. ilt_inversion-0.1.2/target/release/build/libm-847e5c1ab8d7b98d/build_script_build-847e5c1ab8d7b98d +0 -0
  210. ilt_inversion-0.1.2/target/release/build/libm-847e5c1ab8d7b98d/build_script_build-847e5c1ab8d7b98d.d +6 -0
  211. ilt_inversion-0.1.2/target/release/build/libm-da7358a3be7058b1/invoked.timestamp +1 -0
  212. ilt_inversion-0.1.2/target/release/build/libm-da7358a3be7058b1/output +14 -0
  213. ilt_inversion-0.1.2/target/release/build/libm-da7358a3be7058b1/root-output +1 -0
  214. ilt_inversion-0.1.2/target/release/build/libm-da7358a3be7058b1/stderr +0 -0
  215. ilt_inversion-0.1.2/target/release/build/memoffset-0a01b37ba977c671/build-script-build +0 -0
  216. ilt_inversion-0.1.2/target/release/build/memoffset-0a01b37ba977c671/build_script_build-0a01b37ba977c671 +0 -0
  217. ilt_inversion-0.1.2/target/release/build/memoffset-0a01b37ba977c671/build_script_build-0a01b37ba977c671.d +5 -0
  218. ilt_inversion-0.1.2/target/release/build/memoffset-df3e07e3a70e56f0/invoked.timestamp +1 -0
  219. ilt_inversion-0.1.2/target/release/build/memoffset-df3e07e3a70e56f0/output +7 -0
  220. ilt_inversion-0.1.2/target/release/build/memoffset-df3e07e3a70e56f0/root-output +1 -0
  221. ilt_inversion-0.1.2/target/release/build/memoffset-df3e07e3a70e56f0/stderr +0 -0
  222. ilt_inversion-0.1.2/target/release/build/proc-macro2-a4ae1b7f808ac62a/invoked.timestamp +1 -0
  223. ilt_inversion-0.1.2/target/release/build/proc-macro2-a4ae1b7f808ac62a/output +23 -0
  224. ilt_inversion-0.1.2/target/release/build/proc-macro2-a4ae1b7f808ac62a/root-output +1 -0
  225. ilt_inversion-0.1.2/target/release/build/proc-macro2-a4ae1b7f808ac62a/stderr +0 -0
  226. ilt_inversion-0.1.2/target/release/build/proc-macro2-c8a3c3766780cf04/build-script-build +0 -0
  227. ilt_inversion-0.1.2/target/release/build/proc-macro2-c8a3c3766780cf04/build_script_build-c8a3c3766780cf04 +0 -0
  228. ilt_inversion-0.1.2/target/release/build/proc-macro2-c8a3c3766780cf04/build_script_build-c8a3c3766780cf04.d +5 -0
  229. ilt_inversion-0.1.2/target/release/build/pyo3-100d5c185eb0b24e/invoked.timestamp +1 -0
  230. ilt_inversion-0.1.2/target/release/build/pyo3-100d5c185eb0b24e/output +32 -0
  231. ilt_inversion-0.1.2/target/release/build/pyo3-100d5c185eb0b24e/root-output +1 -0
  232. ilt_inversion-0.1.2/target/release/build/pyo3-100d5c185eb0b24e/stderr +0 -0
  233. ilt_inversion-0.1.2/target/release/build/pyo3-8cf1d85e34bdd655/build-script-build +0 -0
  234. ilt_inversion-0.1.2/target/release/build/pyo3-8cf1d85e34bdd655/build_script_build-8cf1d85e34bdd655 +0 -0
  235. ilt_inversion-0.1.2/target/release/build/pyo3-8cf1d85e34bdd655/build_script_build-8cf1d85e34bdd655.d +5 -0
  236. ilt_inversion-0.1.2/target/release/build/pyo3-build-config-7e90a94e1c1a7cf8/invoked.timestamp +1 -0
  237. ilt_inversion-0.1.2/target/release/build/pyo3-build-config-7e90a94e1c1a7cf8/out/pyo3-build-config-file.txt +0 -0
  238. ilt_inversion-0.1.2/target/release/build/pyo3-build-config-7e90a94e1c1a7cf8/out/pyo3-build-config.txt +11 -0
  239. ilt_inversion-0.1.2/target/release/build/pyo3-build-config-7e90a94e1c1a7cf8/output +5 -0
  240. ilt_inversion-0.1.2/target/release/build/pyo3-build-config-7e90a94e1c1a7cf8/root-output +1 -0
  241. ilt_inversion-0.1.2/target/release/build/pyo3-build-config-7e90a94e1c1a7cf8/stderr +0 -0
  242. ilt_inversion-0.1.2/target/release/build/pyo3-build-config-c1cb7955e14a6fee/build-script-build +0 -0
  243. ilt_inversion-0.1.2/target/release/build/pyo3-build-config-c1cb7955e14a6fee/build_script_build-c1cb7955e14a6fee +0 -0
  244. ilt_inversion-0.1.2/target/release/build/pyo3-build-config-c1cb7955e14a6fee/build_script_build-c1cb7955e14a6fee.d +9 -0
  245. ilt_inversion-0.1.2/target/release/build/pyo3-ffi-2c8cbde79a622c8a/invoked.timestamp +1 -0
  246. ilt_inversion-0.1.2/target/release/build/pyo3-ffi-2c8cbde79a622c8a/output +34 -0
  247. ilt_inversion-0.1.2/target/release/build/pyo3-ffi-2c8cbde79a622c8a/root-output +1 -0
  248. ilt_inversion-0.1.2/target/release/build/pyo3-ffi-2c8cbde79a622c8a/stderr +0 -0
  249. ilt_inversion-0.1.2/target/release/build/pyo3-ffi-601592a92c7776c5/build-script-build +0 -0
  250. ilt_inversion-0.1.2/target/release/build/pyo3-ffi-601592a92c7776c5/build_script_build-601592a92c7776c5 +0 -0
  251. ilt_inversion-0.1.2/target/release/build/pyo3-ffi-601592a92c7776c5/build_script_build-601592a92c7776c5.d +5 -0
  252. ilt_inversion-0.1.2/target/release/build/pyo3-macros-backend-69536423206fab36/build-script-build +0 -0
  253. ilt_inversion-0.1.2/target/release/build/pyo3-macros-backend-69536423206fab36/build_script_build-69536423206fab36 +0 -0
  254. ilt_inversion-0.1.2/target/release/build/pyo3-macros-backend-69536423206fab36/build_script_build-69536423206fab36.d +5 -0
  255. ilt_inversion-0.1.2/target/release/build/pyo3-macros-backend-7cb10c9d33dafe97/invoked.timestamp +1 -0
  256. ilt_inversion-0.1.2/target/release/build/pyo3-macros-backend-7cb10c9d33dafe97/output +24 -0
  257. ilt_inversion-0.1.2/target/release/build/pyo3-macros-backend-7cb10c9d33dafe97/root-output +1 -0
  258. ilt_inversion-0.1.2/target/release/build/pyo3-macros-backend-7cb10c9d33dafe97/stderr +0 -0
  259. ilt_inversion-0.1.2/target/release/build/quote-c2cdc7a8dc22bf92/build-script-build +0 -0
  260. ilt_inversion-0.1.2/target/release/build/quote-c2cdc7a8dc22bf92/build_script_build-c2cdc7a8dc22bf92 +0 -0
  261. ilt_inversion-0.1.2/target/release/build/quote-c2cdc7a8dc22bf92/build_script_build-c2cdc7a8dc22bf92.d +5 -0
  262. ilt_inversion-0.1.2/target/release/build/quote-f050940e9638289a/invoked.timestamp +1 -0
  263. ilt_inversion-0.1.2/target/release/build/quote-f050940e9638289a/output +2 -0
  264. ilt_inversion-0.1.2/target/release/build/quote-f050940e9638289a/root-output +1 -0
  265. ilt_inversion-0.1.2/target/release/build/quote-f050940e9638289a/stderr +0 -0
  266. ilt_inversion-0.1.2/target/release/build/rug-1886ebe4ea7a76f3/build-script-build +0 -0
  267. ilt_inversion-0.1.2/target/release/build/rug-1886ebe4ea7a76f3/build_script_build-1886ebe4ea7a76f3 +0 -0
  268. ilt_inversion-0.1.2/target/release/build/rug-1886ebe4ea7a76f3/build_script_build-1886ebe4ea7a76f3.d +5 -0
  269. ilt_inversion-0.1.2/target/release/build/rug-19ce01283dcd66c8/invoked.timestamp +1 -0
  270. ilt_inversion-0.1.2/target/release/build/rug-19ce01283dcd66c8/output +3 -0
  271. ilt_inversion-0.1.2/target/release/build/rug-19ce01283dcd66c8/root-output +1 -0
  272. ilt_inversion-0.1.2/target/release/build/rug-19ce01283dcd66c8/stderr +0 -0
  273. ilt_inversion-0.1.2/target/release/build/target-lexicon-0ea54c073f110143/invoked.timestamp +1 -0
  274. ilt_inversion-0.1.2/target/release/build/target-lexicon-0ea54c073f110143/out/host.rs +74 -0
  275. ilt_inversion-0.1.2/target/release/build/target-lexicon-0ea54c073f110143/output +1 -0
  276. ilt_inversion-0.1.2/target/release/build/target-lexicon-0ea54c073f110143/root-output +1 -0
  277. ilt_inversion-0.1.2/target/release/build/target-lexicon-0ea54c073f110143/stderr +0 -0
  278. ilt_inversion-0.1.2/target/release/build/target-lexicon-682796117b645382/build-script-build +0 -0
  279. ilt_inversion-0.1.2/target/release/build/target-lexicon-682796117b645382/build_script_build-682796117b645382 +0 -0
  280. ilt_inversion-0.1.2/target/release/build/target-lexicon-682796117b645382/build_script_build-682796117b645382.d +8 -0
  281. ilt_inversion-0.1.2/target/release/deps/_native.d +7 -0
  282. ilt_inversion-0.1.2/target/release/deps/autocfg-50cc232bf4095b5c.d +10 -0
  283. ilt_inversion-0.1.2/target/release/deps/az-bda0b4d01a15b607.d +9 -0
  284. ilt_inversion-0.1.2/target/release/deps/cfg_if-aa4e316ed40820f8.d +7 -0
  285. ilt_inversion-0.1.2/target/release/deps/gmp_mpfr_sys-8d640562ddb08dff.d +64 -0
  286. ilt_inversion-0.1.2/target/release/deps/heck-5dc7f4317c48936c.d +15 -0
  287. ilt_inversion-0.1.2/target/release/deps/indoc-879a93f3157cff50.d +8 -0
  288. ilt_inversion-0.1.2/target/release/deps/libautocfg-50cc232bf4095b5c.rlib +0 -0
  289. ilt_inversion-0.1.2/target/release/deps/libautocfg-50cc232bf4095b5c.rmeta +0 -0
  290. ilt_inversion-0.1.2/target/release/deps/libaz-bda0b4d01a15b607.rlib +0 -0
  291. ilt_inversion-0.1.2/target/release/deps/libaz-bda0b4d01a15b607.rmeta +0 -0
  292. ilt_inversion-0.1.2/target/release/deps/libc-2adfdf8733aa3c49.d +46 -0
  293. ilt_inversion-0.1.2/target/release/deps/libcfg_if-aa4e316ed40820f8.rlib +0 -0
  294. ilt_inversion-0.1.2/target/release/deps/libcfg_if-aa4e316ed40820f8.rmeta +0 -0
  295. ilt_inversion-0.1.2/target/release/deps/libgmp_mpfr_sys-8d640562ddb08dff.rlib +0 -0
  296. ilt_inversion-0.1.2/target/release/deps/libgmp_mpfr_sys-8d640562ddb08dff.rmeta +0 -0
  297. ilt_inversion-0.1.2/target/release/deps/libheck-5dc7f4317c48936c.rlib +0 -0
  298. ilt_inversion-0.1.2/target/release/deps/libheck-5dc7f4317c48936c.rmeta +0 -0
  299. ilt_inversion-0.1.2/target/release/deps/liblibc-2adfdf8733aa3c49.rlib +0 -0
  300. ilt_inversion-0.1.2/target/release/deps/liblibc-2adfdf8733aa3c49.rmeta +0 -0
  301. ilt_inversion-0.1.2/target/release/deps/liblibm-a2bc1f4e616a9eee.rlib +0 -0
  302. ilt_inversion-0.1.2/target/release/deps/liblibm-a2bc1f4e616a9eee.rmeta +0 -0
  303. ilt_inversion-0.1.2/target/release/deps/libm-a2bc1f4e616a9eee.d +148 -0
  304. ilt_inversion-0.1.2/target/release/deps/libmemoffset-04cdf5627a421592.rlib +0 -0
  305. ilt_inversion-0.1.2/target/release/deps/libmemoffset-04cdf5627a421592.rmeta +0 -0
  306. ilt_inversion-0.1.2/target/release/deps/libonce_cell-6d12b3fd7eb02e69.rlib +0 -0
  307. ilt_inversion-0.1.2/target/release/deps/libonce_cell-6d12b3fd7eb02e69.rmeta +0 -0
  308. ilt_inversion-0.1.2/target/release/deps/libonce_cell-a4b668872013ad95.rlib +0 -0
  309. ilt_inversion-0.1.2/target/release/deps/libonce_cell-a4b668872013ad95.rmeta +0 -0
  310. ilt_inversion-0.1.2/target/release/deps/libproc_macro2-c6dc7f1a9d5a937a.rlib +0 -0
  311. ilt_inversion-0.1.2/target/release/deps/libproc_macro2-c6dc7f1a9d5a937a.rmeta +0 -0
  312. ilt_inversion-0.1.2/target/release/deps/libpyo3-a0dfb6e3ee0cde3a.rlib +0 -0
  313. ilt_inversion-0.1.2/target/release/deps/libpyo3-a0dfb6e3ee0cde3a.rmeta +0 -0
  314. ilt_inversion-0.1.2/target/release/deps/libpyo3_build_config-f65a826ddbf36c59.rlib +0 -0
  315. ilt_inversion-0.1.2/target/release/deps/libpyo3_build_config-f65a826ddbf36c59.rmeta +0 -0
  316. ilt_inversion-0.1.2/target/release/deps/libpyo3_ffi-ce66a5849929e42b.rlib +0 -0
  317. ilt_inversion-0.1.2/target/release/deps/libpyo3_ffi-ce66a5849929e42b.rmeta +0 -0
  318. ilt_inversion-0.1.2/target/release/deps/libpyo3_macros_backend-305ff5ab4ffa2832.rlib +0 -0
  319. ilt_inversion-0.1.2/target/release/deps/libpyo3_macros_backend-305ff5ab4ffa2832.rmeta +0 -0
  320. ilt_inversion-0.1.2/target/release/deps/libquote-05cbc1ac2323f30b.rlib +0 -0
  321. ilt_inversion-0.1.2/target/release/deps/libquote-05cbc1ac2323f30b.rmeta +0 -0
  322. ilt_inversion-0.1.2/target/release/deps/librug-c8468e662205f3d6.rlib +0 -0
  323. ilt_inversion-0.1.2/target/release/deps/librug-c8468e662205f3d6.rmeta +0 -0
  324. ilt_inversion-0.1.2/target/release/deps/libsyn-d1334b4aa99317c9.rlib +0 -0
  325. ilt_inversion-0.1.2/target/release/deps/libsyn-d1334b4aa99317c9.rmeta +0 -0
  326. ilt_inversion-0.1.2/target/release/deps/libtarget_lexicon-4d05354579b49180.rlib +0 -0
  327. ilt_inversion-0.1.2/target/release/deps/libtarget_lexicon-4d05354579b49180.rmeta +0 -0
  328. ilt_inversion-0.1.2/target/release/deps/libunicode_ident-d49005d3adcbc7b3.rlib +0 -0
  329. ilt_inversion-0.1.2/target/release/deps/libunicode_ident-d49005d3adcbc7b3.rmeta +0 -0
  330. ilt_inversion-0.1.2/target/release/deps/libunindent-bde6a2bf09f33e8f.rlib +0 -0
  331. ilt_inversion-0.1.2/target/release/deps/libunindent-bde6a2bf09f33e8f.rmeta +0 -0
  332. ilt_inversion-0.1.2/target/release/deps/memoffset-04cdf5627a421592.d +10 -0
  333. ilt_inversion-0.1.2/target/release/deps/once_cell-6d12b3fd7eb02e69.d +9 -0
  334. ilt_inversion-0.1.2/target/release/deps/once_cell-a4b668872013ad95.d +9 -0
  335. ilt_inversion-0.1.2/target/release/deps/proc_macro2-c6dc7f1a9d5a937a.d +17 -0
  336. ilt_inversion-0.1.2/target/release/deps/pyo3-a0dfb6e3ee0cde3a.d +124 -0
  337. ilt_inversion-0.1.2/target/release/deps/pyo3_build_config-f65a826ddbf36c59.d +14 -0
  338. ilt_inversion-0.1.2/target/release/deps/pyo3_ffi-ce66a5849929e42b.d +96 -0
  339. ilt_inversion-0.1.2/target/release/deps/pyo3_macros-b93689a95840e633.d +7 -0
  340. ilt_inversion-0.1.2/target/release/deps/pyo3_macros_backend-305ff5ab4ffa2832.d +25 -0
  341. ilt_inversion-0.1.2/target/release/deps/quote-05cbc1ac2323f30b.d +13 -0
  342. ilt_inversion-0.1.2/target/release/deps/rug-c8468e662205f3d6.d +23 -0
  343. ilt_inversion-0.1.2/target/release/deps/syn-d1334b4aa99317c9.d +57 -0
  344. ilt_inversion-0.1.2/target/release/deps/target_lexicon-4d05354579b49180.d +15 -0
  345. ilt_inversion-0.1.2/target/release/deps/unicode_ident-d49005d3adcbc7b3.d +8 -0
  346. ilt_inversion-0.1.2/target/release/deps/unindent-bde6a2bf09f33e8f.d +8 -0
  347. ilt_inversion-0.1.2/target/release/lib_native.d +1 -0
  348. ilt_inversion-0.1.2/target/wheels/ilt_inversion-0.1.0-cp310-cp310-linux_x86_64.whl +0 -0
@@ -0,0 +1,127 @@
1
+ name: Build and publish wheels
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+ workflow_dispatch:
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ jobs:
13
+ # ── Build Rust-accelerated wheels for each platform ──────────────────
14
+ build-wheels:
15
+ name: Build wheels (${{ matrix.os }})
16
+ runs-on: ${{ matrix.os }}
17
+ strategy:
18
+ fail-fast: false
19
+ matrix:
20
+ # Windows excluded: GMP/MPFR won't compile under MSVC.
21
+ # Pure-Python fallback wheel covers Windows and other platforms.
22
+ os: [ubuntu-latest, macos-14]
23
+ steps:
24
+ - uses: actions/checkout@v4
25
+
26
+ - uses: actions/setup-python@v5
27
+ with:
28
+ python-version: "3.12"
29
+
30
+ - name: Install Rust toolchain
31
+ uses: dtolnay/rust-toolchain@stable
32
+ with:
33
+ targets: ${{ matrix.os == 'macos-14' && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }}
34
+
35
+ - name: Build wheels via cibuildwheel
36
+ uses: pypa/cibuildwheel@v2.21
37
+ env:
38
+ CIBW_BUILD_FRONTEND: "build"
39
+ CIBW_BUILD: "cp310-* cp311-* cp312-* cp313-*"
40
+ CIBW_SKIP: "*-win32 *-manylinux_i686 *-musllinux*"
41
+ CIBW_BEFORE_ALL_LINUX: >
42
+ yum install -y m4 diffutils &&
43
+ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
44
+ CIBW_ENVIRONMENT_LINUX: 'PATH="$HOME/.cargo/bin:$PATH"'
45
+ CIBW_ARCHS_MACOS: "arm64"
46
+ # aarch64 excluded: QEMU cross-compilation of GMP takes too long
47
+ CIBW_ARCHS_LINUX: "x86_64"
48
+ CIBW_ENVIRONMENT_MACOS: >
49
+ CARGO_BUILD_TARGET="aarch64-apple-darwin"
50
+ CIBW_TEST_COMMAND: >
51
+ python -c "from ilt._native import gwr_rust; print('Rust extension loaded OK')"
52
+ CIBW_TEST_REQUIRES: "mpmath numpy"
53
+ CIBW_TEST_SKIP: "*-manylinux* *-macosx_x86_64"
54
+
55
+ - uses: actions/upload-artifact@v4
56
+ with:
57
+ name: wheels-${{ matrix.os }}
58
+ path: ./wheelhouse/*.whl
59
+
60
+ # ── Build pure-Python fallback wheel ─────────────────────────────────
61
+ build-pure-python:
62
+ name: Build pure-Python wheel
63
+ runs-on: ubuntu-latest
64
+ steps:
65
+ - uses: actions/checkout@v4
66
+
67
+ - uses: actions/setup-python@v5
68
+ with:
69
+ python-version: "3.12"
70
+
71
+ - name: Install build tools
72
+ run: pip install build wheel setuptools
73
+
74
+ - name: Build pure-Python wheel
75
+ run: python build_pure_python.py
76
+
77
+ - uses: actions/upload-artifact@v4
78
+ with:
79
+ name: wheels-pure-python
80
+ path: ./dist/*.whl
81
+
82
+ # ── Build sdist ──────────────────────────────────────────────────────
83
+ build-sdist:
84
+ name: Build source distribution
85
+ runs-on: ubuntu-latest
86
+ steps:
87
+ - uses: actions/checkout@v4
88
+
89
+ - uses: actions/setup-python@v5
90
+ with:
91
+ python-version: "3.12"
92
+
93
+ - name: Install Rust toolchain
94
+ uses: dtolnay/rust-toolchain@stable
95
+
96
+ - name: Install maturin
97
+ run: pip install maturin
98
+
99
+ - name: Build sdist
100
+ run: maturin sdist --out dist
101
+
102
+ - uses: actions/upload-artifact@v4
103
+ with:
104
+ name: sdist
105
+ path: ./dist/*.tar.gz
106
+
107
+ # ── Publish to PyPI on tag push ──────────────────────────────────────
108
+ publish:
109
+ name: Publish to PyPI
110
+ needs: [build-wheels, build-pure-python, build-sdist]
111
+ runs-on: ubuntu-latest
112
+ if: startsWith(github.ref, 'refs/tags/v')
113
+ environment:
114
+ name: pypi
115
+ url: https://pypi.org/project/ilt-inversion/
116
+ permissions:
117
+ id-token: write
118
+ steps:
119
+ - uses: actions/download-artifact@v4
120
+ with:
121
+ path: dist
122
+ merge-multiple: true
123
+
124
+ - name: Publish to PyPI
125
+ uses: pypa/gh-action-pypi-publish@release/v1
126
+ with:
127
+ packages-dir: dist/
@@ -0,0 +1,23 @@
1
+ # Rust build artifacts
2
+ target/
3
+
4
+ # Python
5
+ __pycache__/
6
+ *.pyc
7
+ *.pyo
8
+ *.egg-info/
9
+ dist/
10
+ build/
11
+ *.so
12
+ *.pyd
13
+
14
+ # IDE
15
+ .vscode/
16
+ .idea/
17
+
18
+ # OS
19
+ .DS_Store
20
+ Thumbs.db
21
+
22
+ # Maturin
23
+ *.whl
@@ -0,0 +1,230 @@
1
+ # This file is automatically @generated by Cargo.
2
+ # It is not intended for manual editing.
3
+ version = 4
4
+
5
+ [[package]]
6
+ name = "autocfg"
7
+ version = "1.5.0"
8
+ source = "registry+https://github.com/rust-lang/crates.io-index"
9
+ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
10
+
11
+ [[package]]
12
+ name = "az"
13
+ version = "1.3.0"
14
+ source = "registry+https://github.com/rust-lang/crates.io-index"
15
+ checksum = "be5eb007b7cacc6c660343e96f650fedf4b5a77512399eb952ca6642cf8d13f7"
16
+
17
+ [[package]]
18
+ name = "cfg-if"
19
+ version = "1.0.4"
20
+ source = "registry+https://github.com/rust-lang/crates.io-index"
21
+ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
22
+
23
+ [[package]]
24
+ name = "gmp-mpfr-sys"
25
+ version = "1.7.0"
26
+ source = "registry+https://github.com/rust-lang/crates.io-index"
27
+ checksum = "8cfc928d8ff4ab3767a3674cf55f81186436fb6070866bb1443ffe65a640d2d6"
28
+ dependencies = [
29
+ "libc",
30
+ "windows-sys",
31
+ ]
32
+
33
+ [[package]]
34
+ name = "heck"
35
+ version = "0.5.0"
36
+ source = "registry+https://github.com/rust-lang/crates.io-index"
37
+ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
38
+
39
+ [[package]]
40
+ name = "ilt-native"
41
+ version = "0.1.2"
42
+ dependencies = [
43
+ "pyo3",
44
+ "rug",
45
+ ]
46
+
47
+ [[package]]
48
+ name = "indoc"
49
+ version = "2.0.7"
50
+ source = "registry+https://github.com/rust-lang/crates.io-index"
51
+ checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706"
52
+ dependencies = [
53
+ "rustversion",
54
+ ]
55
+
56
+ [[package]]
57
+ name = "libc"
58
+ version = "0.2.184"
59
+ source = "registry+https://github.com/rust-lang/crates.io-index"
60
+ checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af"
61
+
62
+ [[package]]
63
+ name = "libm"
64
+ version = "0.2.16"
65
+ source = "registry+https://github.com/rust-lang/crates.io-index"
66
+ checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
67
+
68
+ [[package]]
69
+ name = "memoffset"
70
+ version = "0.9.1"
71
+ source = "registry+https://github.com/rust-lang/crates.io-index"
72
+ checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
73
+ dependencies = [
74
+ "autocfg",
75
+ ]
76
+
77
+ [[package]]
78
+ name = "once_cell"
79
+ version = "1.21.4"
80
+ source = "registry+https://github.com/rust-lang/crates.io-index"
81
+ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
82
+
83
+ [[package]]
84
+ name = "portable-atomic"
85
+ version = "1.13.1"
86
+ source = "registry+https://github.com/rust-lang/crates.io-index"
87
+ checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49"
88
+
89
+ [[package]]
90
+ name = "proc-macro2"
91
+ version = "1.0.106"
92
+ source = "registry+https://github.com/rust-lang/crates.io-index"
93
+ checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
94
+ dependencies = [
95
+ "unicode-ident",
96
+ ]
97
+
98
+ [[package]]
99
+ name = "pyo3"
100
+ version = "0.23.5"
101
+ source = "registry+https://github.com/rust-lang/crates.io-index"
102
+ checksum = "7778bffd85cf38175ac1f545509665d0b9b92a198ca7941f131f85f7a4f9a872"
103
+ dependencies = [
104
+ "cfg-if",
105
+ "indoc",
106
+ "libc",
107
+ "memoffset",
108
+ "once_cell",
109
+ "portable-atomic",
110
+ "pyo3-build-config",
111
+ "pyo3-ffi",
112
+ "pyo3-macros",
113
+ "unindent",
114
+ ]
115
+
116
+ [[package]]
117
+ name = "pyo3-build-config"
118
+ version = "0.23.5"
119
+ source = "registry+https://github.com/rust-lang/crates.io-index"
120
+ checksum = "94f6cbe86ef3bf18998d9df6e0f3fc1050a8c5efa409bf712e661a4366e010fb"
121
+ dependencies = [
122
+ "once_cell",
123
+ "target-lexicon",
124
+ ]
125
+
126
+ [[package]]
127
+ name = "pyo3-ffi"
128
+ version = "0.23.5"
129
+ source = "registry+https://github.com/rust-lang/crates.io-index"
130
+ checksum = "e9f1b4c431c0bb1c8fb0a338709859eed0d030ff6daa34368d3b152a63dfdd8d"
131
+ dependencies = [
132
+ "libc",
133
+ "pyo3-build-config",
134
+ ]
135
+
136
+ [[package]]
137
+ name = "pyo3-macros"
138
+ version = "0.23.5"
139
+ source = "registry+https://github.com/rust-lang/crates.io-index"
140
+ checksum = "fbc2201328f63c4710f68abdf653c89d8dbc2858b88c5d88b0ff38a75288a9da"
141
+ dependencies = [
142
+ "proc-macro2",
143
+ "pyo3-macros-backend",
144
+ "quote",
145
+ "syn",
146
+ ]
147
+
148
+ [[package]]
149
+ name = "pyo3-macros-backend"
150
+ version = "0.23.5"
151
+ source = "registry+https://github.com/rust-lang/crates.io-index"
152
+ checksum = "fca6726ad0f3da9c9de093d6f116a93c1a38e417ed73bf138472cf4064f72028"
153
+ dependencies = [
154
+ "heck",
155
+ "proc-macro2",
156
+ "pyo3-build-config",
157
+ "quote",
158
+ "syn",
159
+ ]
160
+
161
+ [[package]]
162
+ name = "quote"
163
+ version = "1.0.45"
164
+ source = "registry+https://github.com/rust-lang/crates.io-index"
165
+ checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
166
+ dependencies = [
167
+ "proc-macro2",
168
+ ]
169
+
170
+ [[package]]
171
+ name = "rug"
172
+ version = "1.29.0"
173
+ source = "registry+https://github.com/rust-lang/crates.io-index"
174
+ checksum = "25f6c8f906c90b48e0c1745c9f814c3a31c5eba847043b05c3e9a934dec7c4b3"
175
+ dependencies = [
176
+ "az",
177
+ "gmp-mpfr-sys",
178
+ "libc",
179
+ "libm",
180
+ ]
181
+
182
+ [[package]]
183
+ name = "rustversion"
184
+ version = "1.0.22"
185
+ source = "registry+https://github.com/rust-lang/crates.io-index"
186
+ checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
187
+
188
+ [[package]]
189
+ name = "syn"
190
+ version = "2.0.117"
191
+ source = "registry+https://github.com/rust-lang/crates.io-index"
192
+ checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
193
+ dependencies = [
194
+ "proc-macro2",
195
+ "quote",
196
+ "unicode-ident",
197
+ ]
198
+
199
+ [[package]]
200
+ name = "target-lexicon"
201
+ version = "0.12.16"
202
+ source = "registry+https://github.com/rust-lang/crates.io-index"
203
+ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
204
+
205
+ [[package]]
206
+ name = "unicode-ident"
207
+ version = "1.0.24"
208
+ source = "registry+https://github.com/rust-lang/crates.io-index"
209
+ checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
210
+
211
+ [[package]]
212
+ name = "unindent"
213
+ version = "0.2.4"
214
+ source = "registry+https://github.com/rust-lang/crates.io-index"
215
+ checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3"
216
+
217
+ [[package]]
218
+ name = "windows-link"
219
+ version = "0.2.1"
220
+ source = "registry+https://github.com/rust-lang/crates.io-index"
221
+ checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
222
+
223
+ [[package]]
224
+ name = "windows-sys"
225
+ version = "0.61.2"
226
+ source = "registry+https://github.com/rust-lang/crates.io-index"
227
+ checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
228
+ dependencies = [
229
+ "windows-link",
230
+ ]
@@ -0,0 +1,21 @@
1
+ [package]
2
+ name = "ilt-native"
3
+ version = "0.1.2"
4
+ edition = "2021"
5
+ license = "GPL-3.0-or-later"
6
+ description = "Rust/MPFR acceleration for ilt-inversion"
7
+ readme = "README.md"
8
+
9
+ [lib]
10
+ name = "_native"
11
+ crate-type = ["cdylib"]
12
+
13
+ [dependencies]
14
+ pyo3 = { version = "0.23", features = ["extension-module"] }
15
+ rug = { version = "1", default-features = false, features = ["float"] }
16
+
17
+ [profile.release]
18
+ opt-level = 3
19
+ lto = "fat"
20
+ codegen-units = 1
21
+ strip = true
@@ -0,0 +1,147 @@
1
+ Metadata-Version: 2.4
2
+ Name: ilt-inversion
3
+ Version: 0.1.2
4
+ Classifier: Development Status :: 4 - Beta
5
+ Classifier: Intended Audience :: Science/Research
6
+ Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: Programming Language :: Rust
9
+ Classifier: Topic :: Scientific/Engineering :: Mathematics
10
+ Classifier: Topic :: Scientific/Engineering :: Physics
11
+ Requires-Dist: mpmath>=1.3
12
+ Requires-Dist: numpy>=1.21
13
+ Requires-Dist: gmpy2>=2.1 ; extra == 'fast'
14
+ Requires-Dist: python-flint>=0.4 ; extra == 'flint'
15
+ Provides-Extra: fast
16
+ Provides-Extra: flint
17
+ Summary: Fast numerical inverse Laplace transforms: GWR (arbitrary precision) + Fixed Talbot, with optional Rust/MPFR acceleration
18
+ Keywords: laplace,inverse-laplace,gwr,gaver-wynn-rho,numerical-inversion,pressure-transient,reservoir-engineering
19
+ Author-email: Mark Burgoyne <mark.burgoyne@gmail.com>
20
+ License: GPL-3.0-or-later
21
+ Requires-Python: >=3.10
22
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
23
+ Project-URL: Homepage, https://github.com/mwburgoyne/ilt-inversion
24
+ Project-URL: Repository, https://github.com/mwburgoyne/ilt-inversion
25
+
26
+ # ilt-inversion
27
+
28
+ Numerical inverse Laplace transforms for Python.
29
+
30
+ ## Why?
31
+
32
+ If you've ever needed to numerically invert a Laplace transform in Python, you've probably discovered that the standard tools either don't exist or fall over quietly when things get difficult.
33
+
34
+ **NumPy and SciPy don't have one.** There's no `numpy.inverse_laplace` or `scipy.special.ilt`. The standard scientific Python stack just doesn't cover this.
35
+
36
+ **SymPy tries, but it's symbolic.** `inverse_laplace_transform` attempts to find a closed-form `f(t)` via pattern matching and table lookups. That works for textbook problems - rational functions, simple exponentials - but hand it a Bessel-function ratio or anything defined by a numerical subroutine and it silently returns an unevaluated integral. You can't pass it a Python function that calls a numerical solver.
37
+
38
+ **mpmath has `invertlaplace`**, and it's actually decent. Three methods: de Hoog, Fixed Talbot, and Stehfest. But mpmath doesn't implement GWR, and its de Hoog and Talbot methods evaluate `F(s)` at *complex* values of `s`. That's a problem when your `F(s)` only works on the real axis - common in reservoir engineering where you're dealing with real-valued Bessel function ratios or feeding in results from a numerical ODE solver. GWR only needs `F(s)` at real, positive points.
39
+
40
+ **Stehfest** is the one everyone implements first, because it's simple and works at f64 precision. Handles smooth, monotonic transforms fine, but give it anything oscillatory or steep and it falls apart. The fixed-precision coefficients hit catastrophic cancellation at higher orders, capping you at ~6-8 significant figures no matter how many terms you throw at it.
41
+
42
+ **David Fulford's [`gwr_inversion`](https://github.com/petbox-dev/gwr)** is the package that got this right in Python. It implements GWR with arbitrary precision via mpmath and optional gmpy2 acceleration (~10x speedup) - a clean, correct implementation that made GWR accessible to the Python community. For most general-purpose ILT work, `gwr_inversion` is all you need and this library owes a debt to it.
43
+
44
+ ## Where this library adds value
45
+
46
+ For straightforward `gwr(my_function, times)` calls, this library's Python path is essentially the same algorithm as Fulford's, with the same gmpy2 acceleration option. If that's your use case, either package will serve you well.
47
+
48
+ The differences show up in two specific areas:
49
+
50
+ **Bulk inversion with simple callables.** When `M` is small enough that f64 precision suffices (M <= 7, covering ~15 significant figures), the Rust/MPFR backend bypasses Python entirely and runs the full GWR algorithm in compiled code. That's a ~15x speedup per call, which adds up if you're inverting across large parameter sweeps or Monte Carlo runs. For higher M, the Rust path can't help with a general Python callable (the f64 boundary at the Python-Rust interface becomes the bottleneck), and the Python path with gmpy2 is the right choice - same as Fulford's package.
51
+
52
+ **Bessel-function Laplace domains at full MPFR precision.** For Laplace-domain functions built from modified Bessel functions (pressure transient analysis, radial diffusion, heat conduction), the library includes MPFR-precision implementations of I_0, I_1, K_0, K_1 with numerical safeguards that matter when you're evaluating these functions across a wide range of arguments:
53
+
54
+ - Dynamic guard bits on the K_0 power series to compensate for catastrophic cancellation between the `-(ln(x/2) + gamma) * I_0(x)` term and the harmonic series. At `x = 20`, that's ~18 digits of cancellation that silently corrupts the result if you compute at working precision.
55
+ - Exponentially-scaled forms (`I_ne(x) = I_n(x) * exp(-x)`, `K_ne(x) = K_n(x) * exp(x)`) that stay O(1) for all `x`, avoiding the overflow/underflow that hits f64 past `x > 700`.
56
+ - Optimal truncation of asymptotic expansions for large arguments, switching from the power series at `x = 25`.
57
+
58
+ When the Laplace-domain function is implemented entirely in Rust using these Bessel functions (as it is for the Van Everdingen-Hurst radial flow solution in [pyResToolbox](https://github.com/mwburgoyne/pyResToolbox)), the full pipeline - Bessel evaluation, GWR coefficients, Wynn-rho acceleration - runs in compiled MPFR precision without crossing the Python boundary. That's where the ~70x number comes from.
59
+
60
+ ## How GWR works
61
+
62
+ GWR (Valko & Abate, 2004) is a three-stage process. Evaluate `F(s)` at `2M` points along the real axis and combine with pre-computed factorial/binomial coefficients (the Gaver functionals). Apply Wynn-rho sequence acceleration to improve convergence. Extract the best estimate from odd levels of the acceleration tableau.
63
+
64
+ The factorial coefficients grow as `(2M)!` and the alternating sums produce catastrophic cancellation. With `M=32`, the coefficients reach ~10^67 while the result is O(1) - so you need at least 67 decimal digits of working precision, or the answer is pure noise. Standard f64 gives you 15.9 digits. Even quad precision only gets you 33.
65
+
66
+ The library automatically computes `ceil(2.1 * M)` decimal digits of working precision to guarantee enough significant figures survive.
67
+
68
+ ## Performance tiers
69
+
70
+ The library picks the fastest backend that will give correct results:
71
+
72
+ | Tier | Backend | Speedup | When used |
73
+ |------|---------|---------|-----------|
74
+ | 1 | Rust/MPFR | ~15-70x | M <= 7 (general callables) or internal Bessel evaluation (any M) |
75
+ | 2 | gmpy2 | ~10x | M > 7 with general Python callables |
76
+ | 3 | mpmath | baseline | Always available |
77
+
78
+ The gmpy2 tier is the same acceleration that Fulford's `gwr_inversion` already provides - we inherited that design. The Rust/MPFR tier is what's new.
79
+
80
+ ## Installation
81
+
82
+ ```bash
83
+ pip install ilt-inversion
84
+ ```
85
+
86
+ Binary wheels include the Rust/MPFR extension for Linux, macOS, and Windows. If no binary wheel is available for your platform, the pure-Python fallback installs automatically and the Rust acceleration is simply absent.
87
+
88
+ Optional accelerators for the Python path:
89
+
90
+ ```bash
91
+ pip install gmpy2 # ~10x faster GWR for high-M
92
+ pip install python-flint # ~15x faster Bessel functions via ARB
93
+ ```
94
+
95
+ ## Quick start
96
+
97
+ ```python
98
+ from ilt import gwr, talbot
99
+
100
+ # L{e^(-t)} = 1/(s+1)
101
+ def F(s):
102
+ return 1 / (s + 1)
103
+
104
+ # Single time point
105
+ result = gwr(F, 1.0) # 0.36787944... = e^(-1)
106
+
107
+ # Multiple time points
108
+ results = gwr(F, [0.1, 1.0, 10.0])
109
+
110
+ # Higher accuracy
111
+ results = gwr(F, [1.0], M=64)
112
+
113
+ # Fixed Talbot - faster for well-behaved transforms
114
+ result = talbot(F, 1.0)
115
+
116
+ # Parallel evaluation (fn must be picklable - module-level, not a lambda)
117
+ results = gwr(F, times, workers=4)
118
+ ```
119
+
120
+ ## API
121
+
122
+ **`gwr(fn, time, M=32, precin=None, backend='auto', workers=1, as_float=True)`**
123
+
124
+ Inverse Laplace transform via Gaver-Wynn-Rho. `fn` is your Laplace-domain function `F(s)` or `F(s, prec)`. `time` accepts a scalar, list, or numpy array (must be > 0). `M` controls accuracy - 6-12 for smooth transforms, 32 for general use, 768+ for hard oscillatory cases. `precin` overrides the automatic precision (`round(2.1 * M)` decimal digits). `backend` can be `'auto'`, `'rust'`, `'gmpy2'`, or `'mpmath'`. `workers` sets the number of parallel processes for array inputs (default 1 = sequential) - each time point is inverted independently, so this parallelises well, but `fn` must be picklable (a module-level function, not a lambda or closure). Set `as_float=False` to get mpmath.mpf values at full precision.
125
+
126
+ **`talbot(fn, time, degree=32, as_float=True)`**
127
+
128
+ Inverse Laplace transform via Fixed Talbot. Good for well-behaved, non-oscillatory transforms where moderate precision suffices.
129
+
130
+ **`besselk(n, x)` / `besseli(n, x)`**
131
+
132
+ Modified Bessel functions K_n(x) and I_n(x) with automatic python-flint/ARB acceleration when available.
133
+
134
+ ## Acknowledgements
135
+
136
+ The GWR algorithm implementation builds on David S. Fulford's [`gwr_inversion`](https://github.com/petbox-dev/gwr) package, which made a clean and correct GWR available to the Python community.
137
+
138
+ ## References
139
+
140
+ - Valko, P.P. & Abate, J. (2004), "Comparison of Sequence Accelerators for the Gaver Method of Numerical Laplace Transform Inversion", *Computers and Mathematics with Applications* 48(3): 629-636.
141
+ - Abramowitz, M. & Stegun, I.A. (1964), *Handbook of Mathematical Functions*, National Bureau of Standards.
142
+ - Van Everdingen, A.F. & Hurst, W. (1949), "The Application of the Laplace Transformation to Flow Problems in Reservoirs", SPE-949305-G.
143
+
144
+ ## Licence
145
+
146
+ GPL-3.0-or-later
147
+
@@ -0,0 +1,121 @@
1
+ # ilt-inversion
2
+
3
+ Numerical inverse Laplace transforms for Python.
4
+
5
+ ## Why?
6
+
7
+ If you've ever needed to numerically invert a Laplace transform in Python, you've probably discovered that the standard tools either don't exist or fall over quietly when things get difficult.
8
+
9
+ **NumPy and SciPy don't have one.** There's no `numpy.inverse_laplace` or `scipy.special.ilt`. The standard scientific Python stack just doesn't cover this.
10
+
11
+ **SymPy tries, but it's symbolic.** `inverse_laplace_transform` attempts to find a closed-form `f(t)` via pattern matching and table lookups. That works for textbook problems - rational functions, simple exponentials - but hand it a Bessel-function ratio or anything defined by a numerical subroutine and it silently returns an unevaluated integral. You can't pass it a Python function that calls a numerical solver.
12
+
13
+ **mpmath has `invertlaplace`**, and it's actually decent. Three methods: de Hoog, Fixed Talbot, and Stehfest. But mpmath doesn't implement GWR, and its de Hoog and Talbot methods evaluate `F(s)` at *complex* values of `s`. That's a problem when your `F(s)` only works on the real axis - common in reservoir engineering where you're dealing with real-valued Bessel function ratios or feeding in results from a numerical ODE solver. GWR only needs `F(s)` at real, positive points.
14
+
15
+ **Stehfest** is the one everyone implements first, because it's simple and works at f64 precision. Handles smooth, monotonic transforms fine, but give it anything oscillatory or steep and it falls apart. The fixed-precision coefficients hit catastrophic cancellation at higher orders, capping you at ~6-8 significant figures no matter how many terms you throw at it.
16
+
17
+ **David Fulford's [`gwr_inversion`](https://github.com/petbox-dev/gwr)** is the package that got this right in Python. It implements GWR with arbitrary precision via mpmath and optional gmpy2 acceleration (~10x speedup) - a clean, correct implementation that made GWR accessible to the Python community. For most general-purpose ILT work, `gwr_inversion` is all you need and this library owes a debt to it.
18
+
19
+ ## Where this library adds value
20
+
21
+ For straightforward `gwr(my_function, times)` calls, this library's Python path is essentially the same algorithm as Fulford's, with the same gmpy2 acceleration option. If that's your use case, either package will serve you well.
22
+
23
+ The differences show up in two specific areas:
24
+
25
+ **Bulk inversion with simple callables.** When `M` is small enough that f64 precision suffices (M <= 7, covering ~15 significant figures), the Rust/MPFR backend bypasses Python entirely and runs the full GWR algorithm in compiled code. That's a ~15x speedup per call, which adds up if you're inverting across large parameter sweeps or Monte Carlo runs. For higher M, the Rust path can't help with a general Python callable (the f64 boundary at the Python-Rust interface becomes the bottleneck), and the Python path with gmpy2 is the right choice - same as Fulford's package.
26
+
27
+ **Bessel-function Laplace domains at full MPFR precision.** For Laplace-domain functions built from modified Bessel functions (pressure transient analysis, radial diffusion, heat conduction), the library includes MPFR-precision implementations of I_0, I_1, K_0, K_1 with numerical safeguards that matter when you're evaluating these functions across a wide range of arguments:
28
+
29
+ - Dynamic guard bits on the K_0 power series to compensate for catastrophic cancellation between the `-(ln(x/2) + gamma) * I_0(x)` term and the harmonic series. At `x = 20`, that's ~18 digits of cancellation that silently corrupts the result if you compute at working precision.
30
+ - Exponentially-scaled forms (`I_ne(x) = I_n(x) * exp(-x)`, `K_ne(x) = K_n(x) * exp(x)`) that stay O(1) for all `x`, avoiding the overflow/underflow that hits f64 past `x > 700`.
31
+ - Optimal truncation of asymptotic expansions for large arguments, switching from the power series at `x = 25`.
32
+
33
+ When the Laplace-domain function is implemented entirely in Rust using these Bessel functions (as it is for the Van Everdingen-Hurst radial flow solution in [pyResToolbox](https://github.com/mwburgoyne/pyResToolbox)), the full pipeline - Bessel evaluation, GWR coefficients, Wynn-rho acceleration - runs in compiled MPFR precision without crossing the Python boundary. That's where the ~70x number comes from.
34
+
35
+ ## How GWR works
36
+
37
+ GWR (Valko & Abate, 2004) is a three-stage process. Evaluate `F(s)` at `2M` points along the real axis and combine with pre-computed factorial/binomial coefficients (the Gaver functionals). Apply Wynn-rho sequence acceleration to improve convergence. Extract the best estimate from odd levels of the acceleration tableau.
38
+
39
+ The factorial coefficients grow as `(2M)!` and the alternating sums produce catastrophic cancellation. With `M=32`, the coefficients reach ~10^67 while the result is O(1) - so you need at least 67 decimal digits of working precision, or the answer is pure noise. Standard f64 gives you 15.9 digits. Even quad precision only gets you 33.
40
+
41
+ The library automatically computes `ceil(2.1 * M)` decimal digits of working precision to guarantee enough significant figures survive.
42
+
43
+ ## Performance tiers
44
+
45
+ The library picks the fastest backend that will give correct results:
46
+
47
+ | Tier | Backend | Speedup | When used |
48
+ |------|---------|---------|-----------|
49
+ | 1 | Rust/MPFR | ~15-70x | M <= 7 (general callables) or internal Bessel evaluation (any M) |
50
+ | 2 | gmpy2 | ~10x | M > 7 with general Python callables |
51
+ | 3 | mpmath | baseline | Always available |
52
+
53
+ The gmpy2 tier is the same acceleration that Fulford's `gwr_inversion` already provides - we inherited that design. The Rust/MPFR tier is what's new.
54
+
55
+ ## Installation
56
+
57
+ ```bash
58
+ pip install ilt-inversion
59
+ ```
60
+
61
+ Binary wheels include the Rust/MPFR extension for Linux, macOS, and Windows. If no binary wheel is available for your platform, the pure-Python fallback installs automatically and the Rust acceleration is simply absent.
62
+
63
+ Optional accelerators for the Python path:
64
+
65
+ ```bash
66
+ pip install gmpy2 # ~10x faster GWR for high-M
67
+ pip install python-flint # ~15x faster Bessel functions via ARB
68
+ ```
69
+
70
+ ## Quick start
71
+
72
+ ```python
73
+ from ilt import gwr, talbot
74
+
75
+ # L{e^(-t)} = 1/(s+1)
76
+ def F(s):
77
+ return 1 / (s + 1)
78
+
79
+ # Single time point
80
+ result = gwr(F, 1.0) # 0.36787944... = e^(-1)
81
+
82
+ # Multiple time points
83
+ results = gwr(F, [0.1, 1.0, 10.0])
84
+
85
+ # Higher accuracy
86
+ results = gwr(F, [1.0], M=64)
87
+
88
+ # Fixed Talbot - faster for well-behaved transforms
89
+ result = talbot(F, 1.0)
90
+
91
+ # Parallel evaluation (fn must be picklable - module-level, not a lambda)
92
+ results = gwr(F, times, workers=4)
93
+ ```
94
+
95
+ ## API
96
+
97
+ **`gwr(fn, time, M=32, precin=None, backend='auto', workers=1, as_float=True)`**
98
+
99
+ Inverse Laplace transform via Gaver-Wynn-Rho. `fn` is your Laplace-domain function `F(s)` or `F(s, prec)`. `time` accepts a scalar, list, or numpy array (must be > 0). `M` controls accuracy - 6-12 for smooth transforms, 32 for general use, 768+ for hard oscillatory cases. `precin` overrides the automatic precision (`round(2.1 * M)` decimal digits). `backend` can be `'auto'`, `'rust'`, `'gmpy2'`, or `'mpmath'`. `workers` sets the number of parallel processes for array inputs (default 1 = sequential) - each time point is inverted independently, so this parallelises well, but `fn` must be picklable (a module-level function, not a lambda or closure). Set `as_float=False` to get mpmath.mpf values at full precision.
100
+
101
+ **`talbot(fn, time, degree=32, as_float=True)`**
102
+
103
+ Inverse Laplace transform via Fixed Talbot. Good for well-behaved, non-oscillatory transforms where moderate precision suffices.
104
+
105
+ **`besselk(n, x)` / `besseli(n, x)`**
106
+
107
+ Modified Bessel functions K_n(x) and I_n(x) with automatic python-flint/ARB acceleration when available.
108
+
109
+ ## Acknowledgements
110
+
111
+ The GWR algorithm implementation builds on David S. Fulford's [`gwr_inversion`](https://github.com/petbox-dev/gwr) package, which made a clean and correct GWR available to the Python community.
112
+
113
+ ## References
114
+
115
+ - Valko, P.P. & Abate, J. (2004), "Comparison of Sequence Accelerators for the Gaver Method of Numerical Laplace Transform Inversion", *Computers and Mathematics with Applications* 48(3): 629-636.
116
+ - Abramowitz, M. & Stegun, I.A. (1964), *Handbook of Mathematical Functions*, National Bureau of Standards.
117
+ - Van Everdingen, A.F. & Hurst, W. (1949), "The Application of the Laplace Transformation to Flow Problems in Reservoirs", SPE-949305-G.
118
+
119
+ ## Licence
120
+
121
+ GPL-3.0-or-later