comnum 0.2.0__tar.gz → 0.3.1__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 (388) hide show
  1. {comnum-0.2.0 → comnum-0.3.1}/Cargo.lock +16 -16
  2. {comnum-0.2.0 → comnum-0.3.1}/Cargo.toml +15 -15
  3. {comnum-0.2.0 → comnum-0.3.1}/PKG-INFO +10 -6
  4. {comnum-0.2.0/crates/comnum → comnum-0.3.1}/README.md +9 -5
  5. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/ais.rs +4 -4
  6. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/fiber.rs +50 -12
  7. {comnum-0.2.0 → comnum-0.3.1/crates/comnum}/README.md +9 -5
  8. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-channel/src/multipath/mod.rs +24 -0
  9. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-channel/src/optical/fiber.rs +13 -3
  10. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-dsp/src/compensation/dbp.rs +150 -8
  11. comnum-0.3.1/crates/comnum-dsp/src/compensation/iq.rs +122 -0
  12. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-dsp/src/compensation/mod.rs +4 -1
  13. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-dsp/src/sync/timing.rs +49 -0
  14. comnum-0.3.1/crates/comnum-fec/src/density_evolution.rs +561 -0
  15. comnum-0.3.1/crates/comnum-fec/src/exit.rs +268 -0
  16. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-fec/src/lib.rs +4 -0
  17. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-mapping/src/lib.rs +2 -0
  18. comnum-0.3.1/crates/comnum-mapping/src/link_adaptation.rs +232 -0
  19. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-mapping/src/source.rs +1 -1
  20. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-math/src/lib.rs +5 -3
  21. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-math/src/nlse/manakov.rs +65 -14
  22. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-math/src/nlse/mod.rs +351 -27
  23. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-math/src/quadrature.rs +19 -0
  24. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-math/src/special.rs +49 -1
  25. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-mimo/src/lib.rs +2 -0
  26. comnum-0.3.1/crates/comnum-mimo/src/noma.rs +255 -0
  27. comnum-0.3.1/crates/comnum-spec/GUIDE_AGENTS.md +127 -0
  28. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/blocks/fiber.rs +30 -3
  29. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/blocks/optical.rs +4 -2
  30. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/blocks/tests.rs +4 -0
  31. comnum-0.3.1/crates/comnum-spec/src/cli/agent.rs +287 -0
  32. comnum-0.2.0/crates/comnum-spec/src/cli.rs → comnum-0.3.1/crates/comnum-spec/src/cli/mod.rs +167 -29
  33. comnum-0.3.1/crates/comnum-spec/tests/cli_json.rs +95 -0
  34. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-systems/src/ais/message.rs +5 -5
  35. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-systems/src/ais/mod.rs +8 -8
  36. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-waveform/src/fbmc/mod.rs +112 -0
  37. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-waveform/src/lib.rs +2 -0
  38. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-waveform/src/ofdm/budget.rs +27 -0
  39. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-waveform/src/ofdm/mod.rs +24 -0
  40. comnum-0.3.1/crates/comnum-waveform/src/sir.rs +334 -0
  41. {comnum-0.2.0 → comnum-0.3.1}/python/comnum/_comnum.pyi +11 -1
  42. {comnum-0.2.0 → comnum-0.3.1}/python/comnum/blocks.py +36 -3
  43. {comnum-0.2.0 → comnum-0.3.1}/LICENSE-APACHE +0 -0
  44. {comnum-0.2.0 → comnum-0.3.1}/LICENSE-MIT +0 -0
  45. {comnum-0.2.0 → comnum-0.3.1}/THIRD_PARTY.md +0 -0
  46. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/Cargo.toml +0 -0
  47. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/amplifier.rs +0 -0
  48. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/blind.rs +0 -0
  49. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/cdl.rs +0 -0
  50. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/chain.rs +0 -0
  51. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/comm/closed_forms.rs +0 -0
  52. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/comm/constellation.rs +0 -0
  53. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/comm/generators.rs +0 -0
  54. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/comm/measures.rs +0 -0
  55. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/comm/mod.rs +0 -0
  56. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/comm/shaping.rs +0 -0
  57. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/converter.rs +0 -0
  58. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/devices.rs +0 -0
  59. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/differential.rs +0 -0
  60. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/dsp.rs +0 -0
  61. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/fec/ccsds.rs +0 -0
  62. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/fec/conv.rs +0 -0
  63. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/fec/crc.rs +0 -0
  64. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/fec/ldpc_code.rs +0 -0
  65. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/fec/limits.rs +0 -0
  66. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/fec/mod.rs +0 -0
  67. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/fec/nr.rs +0 -0
  68. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/fec/polar_code.rs +0 -0
  69. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/fec_codes.rs +0 -0
  70. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/fm.rs +0 -0
  71. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/gn.rs +0 -0
  72. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/lib.rs +0 -0
  73. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/link_theory.rs +0 -0
  74. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/lte.rs +0 -0
  75. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/math.rs +0 -0
  76. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/mimo/amp.rs +0 -0
  77. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/mimo/estimation.rs +0 -0
  78. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/mimo/mod.rs +0 -0
  79. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/multicarrier.rs +0 -0
  80. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/nr.rs +0 -0
  81. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/nr_pdsch.rs +0 -0
  82. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/ofdm.rs +0 -0
  83. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/ofdm_link.rs +0 -0
  84. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/otfs.rs +0 -0
  85. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/owc.rs +0 -0
  86. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/pathloss.rs +0 -0
  87. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/rng.rs +0 -0
  88. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/sim.rs +0 -0
  89. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/spec.rs +0 -0
  90. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/spectrum.rs +0 -0
  91. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/systems.rs +0 -0
  92. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/verify.rs +0 -0
  93. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/waveform/ce_ofdm.rs +0 -0
  94. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/waveform/continuous_phase.rs +0 -0
  95. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/waveform/css.rs +0 -0
  96. {comnum-0.2.0 → comnum-0.3.1}/bindings/comnum-py/src/waveform/mod.rs +0 -0
  97. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum/Cargo.toml +0 -0
  98. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum/LICENSE-APACHE +0 -0
  99. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum/LICENSE-MIT +0 -0
  100. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum/katex-header.html +0 -0
  101. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum/src/lib.rs +0 -0
  102. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum/tests/links.rs +0 -0
  103. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum/tests/simulation.rs +0 -0
  104. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-channel/Cargo.toml +0 -0
  105. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-channel/LICENSE-APACHE +0 -0
  106. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-channel/LICENSE-MIT +0 -0
  107. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-channel/README.md +0 -0
  108. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-channel/THIRD_PARTY.md +0 -0
  109. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-channel/katex-header.html +0 -0
  110. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-channel/src/awgn.rs +0 -0
  111. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-channel/src/cdl/array.rs +0 -0
  112. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-channel/src/cdl/mod.rs +0 -0
  113. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-channel/src/cdl/tables.rs +0 -0
  114. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-channel/src/fading.rs +0 -0
  115. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-channel/src/lib.rs +0 -0
  116. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-channel/src/multipath/delay_doppler.rs +0 -0
  117. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-channel/src/multipath/echoes.rs +0 -0
  118. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-channel/src/multipath/taps.rs +0 -0
  119. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-channel/src/multipath/tdl.rs +0 -0
  120. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-channel/src/optical/edfa.rs +0 -0
  121. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-channel/src/optical/gn.rs +0 -0
  122. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-channel/src/optical/manakov.rs +0 -0
  123. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-channel/src/optical/mod.rs +0 -0
  124. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-channel/src/optical/pmd.rs +0 -0
  125. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-channel/src/optical/raman/gain.rs +0 -0
  126. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-channel/src/optical/raman/mod.rs +0 -0
  127. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-channel/src/optical/raman/solver.rs +0 -0
  128. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-channel/src/owc/atmospheric.rs +0 -0
  129. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-channel/src/owc/indoor.rs +0 -0
  130. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-channel/src/owc/mod.rs +0 -0
  131. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-channel/src/pathloss.rs +0 -0
  132. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-channel/src/ris.rs +0 -0
  133. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-channel/src/spatial.rs +0 -0
  134. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-core/Cargo.toml +0 -0
  135. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-core/LICENSE-APACHE +0 -0
  136. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-core/LICENSE-MIT +0 -0
  137. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-core/README.md +0 -0
  138. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-core/katex-header.html +0 -0
  139. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-core/src/channel.rs +0 -0
  140. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-core/src/error.rs +0 -0
  141. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-core/src/lib.rs +0 -0
  142. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-core/src/rng.rs +0 -0
  143. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-core/src/signal.rs +0 -0
  144. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-core/src/traits.rs +0 -0
  145. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-core/src/units.rs +0 -0
  146. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-dsp/Cargo.toml +0 -0
  147. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-dsp/LICENSE-APACHE +0 -0
  148. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-dsp/LICENSE-MIT +0 -0
  149. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-dsp/README.md +0 -0
  150. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-dsp/katex-header.html +0 -0
  151. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-dsp/src/adaptive.rs +0 -0
  152. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-dsp/src/compensation/cd.rs +0 -0
  153. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-dsp/src/compensation/dpd.rs +0 -0
  154. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-dsp/src/cyclo.rs +0 -0
  155. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-dsp/src/equalizer.rs +0 -0
  156. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-dsp/src/estimation.rs +0 -0
  157. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-dsp/src/filter.rs +0 -0
  158. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-dsp/src/fm.rs +0 -0
  159. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-dsp/src/frontend.rs +0 -0
  160. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-dsp/src/interpolation.rs +0 -0
  161. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-dsp/src/lib.rs +0 -0
  162. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-dsp/src/nonlinear.rs +0 -0
  163. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-dsp/src/resample.rs +0 -0
  164. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-dsp/src/signal.rs +0 -0
  165. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-dsp/src/spectrum.rs +0 -0
  166. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-dsp/src/sync/carrier.rs +0 -0
  167. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-dsp/src/sync/frame.rs +0 -0
  168. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-dsp/src/sync/mod.rs +0 -0
  169. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-dsp/src/window.rs +0 -0
  170. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-fec/Cargo.toml +0 -0
  171. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-fec/LICENSE-APACHE +0 -0
  172. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-fec/LICENSE-MIT +0 -0
  173. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-fec/README.md +0 -0
  174. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-fec/katex-header.html +0 -0
  175. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-fec/src/algebraic.rs +0 -0
  176. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-fec/src/bch.rs +0 -0
  177. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-fec/src/block.rs +0 -0
  178. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-fec/src/bounds.rs +0 -0
  179. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-fec/src/ccdm.rs +0 -0
  180. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-fec/src/ccsds/ldpc.rs +0 -0
  181. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-fec/src/ccsds/mod.rs +0 -0
  182. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-fec/src/ccsds/turbo.rs +0 -0
  183. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-fec/src/conv.rs +0 -0
  184. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-fec/src/crc.rs +0 -0
  185. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-fec/src/interleaving.rs +0 -0
  186. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-fec/src/ldpc.rs +0 -0
  187. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-fec/src/nr/ldpc.rs +0 -0
  188. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-fec/src/nr/mod.rs +0 -0
  189. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-fec/src/nr/polar.rs +0 -0
  190. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-fec/src/nr/tables.rs +0 -0
  191. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-fec/src/polar.rs +0 -0
  192. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-fec/src/puncture.rs +0 -0
  193. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-fec/src/rs.rs +0 -0
  194. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-fec/src/scrambling.rs +0 -0
  195. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-fec/src/turbo.rs +0 -0
  196. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-hardware/Cargo.toml +0 -0
  197. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-hardware/LICENSE-APACHE +0 -0
  198. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-hardware/LICENSE-MIT +0 -0
  199. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-hardware/README.md +0 -0
  200. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-hardware/katex-header.html +0 -0
  201. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-hardware/src/amplifier.rs +0 -0
  202. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-hardware/src/converter.rs +0 -0
  203. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-hardware/src/iq.rs +0 -0
  204. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-hardware/src/lib.rs +0 -0
  205. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-hardware/src/optical.rs +0 -0
  206. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-hardware/src/oscillator.rs +0 -0
  207. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-mapping/Cargo.toml +0 -0
  208. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-mapping/LICENSE-APACHE +0 -0
  209. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-mapping/LICENSE-MIT +0 -0
  210. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-mapping/README.md +0 -0
  211. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-mapping/katex-header.html +0 -0
  212. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-mapping/src/bicm.rs +0 -0
  213. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-mapping/src/constellation.rs +0 -0
  214. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-mapping/src/demapper.rs +0 -0
  215. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-mapping/src/differential.rs +0 -0
  216. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-mapping/src/imperfect_csi.rs +0 -0
  217. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-mapping/src/theory.rs +0 -0
  218. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-math/Cargo.toml +0 -0
  219. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-math/LICENSE-APACHE +0 -0
  220. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-math/LICENSE-MIT +0 -0
  221. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-math/README.md +0 -0
  222. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-math/katex-header.html +0 -0
  223. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-math/src/bigint.rs +0 -0
  224. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-math/src/bits.rs +0 -0
  225. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-math/src/fft.rs +0 -0
  226. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-math/src/geometry.rs +0 -0
  227. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-math/src/gf2.rs +0 -0
  228. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-math/src/gf2m.rs +0 -0
  229. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-math/src/linalg.rs +0 -0
  230. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-math/src/log_domain.rs +0 -0
  231. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-math/src/nearest.rs +0 -0
  232. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-math/src/search.rs +0 -0
  233. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-math/src/sequences.rs +0 -0
  234. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-math/src/stats.rs +0 -0
  235. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-metrics/Cargo.toml +0 -0
  236. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-metrics/LICENSE-APACHE +0 -0
  237. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-metrics/LICENSE-MIT +0 -0
  238. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-metrics/README.md +0 -0
  239. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-metrics/katex-header.html +0 -0
  240. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-metrics/src/blind.rs +0 -0
  241. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-metrics/src/errors.rs +0 -0
  242. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-metrics/src/information.rs +0 -0
  243. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-metrics/src/lib.rs +0 -0
  244. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-metrics/src/posterior.rs +0 -0
  245. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-metrics/src/spectrum.rs +0 -0
  246. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-metrics/src/stability.rs +0 -0
  247. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-mimo/Cargo.toml +0 -0
  248. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-mimo/LICENSE-APACHE +0 -0
  249. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-mimo/LICENSE-MIT +0 -0
  250. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-mimo/README.md +0 -0
  251. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-mimo/katex-header.html +0 -0
  252. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-mimo/src/capacity.rs +0 -0
  253. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-mimo/src/detection.rs +0 -0
  254. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-mimo/src/estimation.rs +0 -0
  255. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-mimo/src/massive.rs +0 -0
  256. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-mimo/src/message_passing.rs +0 -0
  257. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-mimo/src/precoding.rs +0 -0
  258. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-mimo/src/receiver.rs +0 -0
  259. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-mimo/src/stbc.rs +0 -0
  260. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-sim/Cargo.toml +0 -0
  261. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-sim/LICENSE-APACHE +0 -0
  262. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-sim/LICENSE-MIT +0 -0
  263. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-sim/README.md +0 -0
  264. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-sim/build.rs +0 -0
  265. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-sim/katex-header.html +0 -0
  266. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-sim/src/callbacks.rs +0 -0
  267. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-sim/src/grid.rs +0 -0
  268. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-sim/src/json.rs +0 -0
  269. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-sim/src/lib.rs +0 -0
  270. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-sim/src/loggers.rs +0 -0
  271. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-sim/src/runner.rs +0 -0
  272. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-sim/src/scenario.rs +0 -0
  273. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-sim/src/stats.rs +0 -0
  274. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-sim/src/stopping.rs +0 -0
  275. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/Cargo.toml +0 -0
  276. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/LICENSE-APACHE +0 -0
  277. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/LICENSE-MIT +0 -0
  278. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/README.md +0 -0
  279. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/katex-header.html +0 -0
  280. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/bin/comnum.rs +0 -0
  281. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/blocks/analysis.rs +0 -0
  282. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/blocks/ce_ofdm.rs +0 -0
  283. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/blocks/channel.rs +0 -0
  284. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/blocks/coding/codes.rs +0 -0
  285. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/blocks/coding/fec.rs +0 -0
  286. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/blocks/coding/map.rs +0 -0
  287. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/blocks/coding/mod.rs +0 -0
  288. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/blocks/coding/pas.rs +0 -0
  289. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/blocks/coding/tests.rs +0 -0
  290. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/blocks/context.rs +0 -0
  291. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/blocks/cpm.rs +0 -0
  292. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/blocks/dsp.rs +0 -0
  293. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/blocks/frame.rs +0 -0
  294. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/blocks/mod.rs +0 -0
  295. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/blocks/per_pol.rs +0 -0
  296. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/blocks/registry.rs +0 -0
  297. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/blocks/schema/fact.rs +0 -0
  298. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/blocks/schema/json_schema.rs +0 -0
  299. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/blocks/schema/macros.rs +0 -0
  300. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/blocks/schema/mod.rs +0 -0
  301. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/blocks/schema/param.rs +0 -0
  302. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/blocks/source.rs +0 -0
  303. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/blocks/systems.rs +0 -0
  304. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/blocks/wireless/fading.rs +0 -0
  305. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/blocks/wireless/mimo.rs +0 -0
  306. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/blocks/wireless/mod.rs +0 -0
  307. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/blocks/wireless/ofdm.rs +0 -0
  308. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/blocks/wireless/tests.rs +0 -0
  309. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/io/datatype.rs +0 -0
  310. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/io/npy.rs +0 -0
  311. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/io/raw.rs +0 -0
  312. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/io/sigmf.rs +0 -0
  313. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/io.rs +0 -0
  314. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/lib.rs +0 -0
  315. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/link.rs +0 -0
  316. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/metrics.rs +0 -0
  317. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/params.rs +0 -0
  318. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/run.rs +0 -0
  319. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/search.rs +0 -0
  320. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/spec.rs +0 -0
  321. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/verify/theory.rs +0 -0
  322. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/src/verify.rs +0 -0
  323. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-spec/tests/extension.rs +0 -0
  324. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-systems/Cargo.toml +0 -0
  325. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-systems/LICENSE-APACHE +0 -0
  326. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-systems/LICENSE-MIT +0 -0
  327. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-systems/README.md +0 -0
  328. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-systems/katex-header.html +0 -0
  329. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-systems/src/ais/nmea.rs +0 -0
  330. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-systems/src/ccsds.rs +0 -0
  331. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-systems/src/dvb.rs +0 -0
  332. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-systems/src/dvbs.rs +0 -0
  333. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-systems/src/dvbs2/fec.rs +0 -0
  334. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-systems/src/dvbs2/mod.rs +0 -0
  335. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-systems/src/dvbs2/tables.rs +0 -0
  336. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-systems/src/dvbt.rs +0 -0
  337. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-systems/src/fm/mod.rs +0 -0
  338. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-systems/src/fm/mpx.rs +0 -0
  339. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-systems/src/fm/rds.rs +0 -0
  340. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-systems/src/hdlc.rs +0 -0
  341. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-systems/src/lib.rs +0 -0
  342. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-systems/src/lte/bch.rs +0 -0
  343. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-systems/src/lte/cell.rs +0 -0
  344. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-systems/src/lte/mib.rs +0 -0
  345. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-systems/src/lte/mod.rs +0 -0
  346. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-systems/src/lte/search.rs +0 -0
  347. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-systems/src/nr/mcs.rs +0 -0
  348. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-systems/src/nr/mod.rs +0 -0
  349. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-systems/src/nr/modulation.rs +0 -0
  350. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-systems/src/nr/pdsch.rs +0 -0
  351. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-systems/src/nr/transport.rs +0 -0
  352. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-systems/src/pas.rs +0 -0
  353. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-systems/src/wdm.rs +0 -0
  354. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-waveform/Cargo.toml +0 -0
  355. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-waveform/LICENSE-APACHE +0 -0
  356. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-waveform/LICENSE-MIT +0 -0
  357. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-waveform/README.md +0 -0
  358. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-waveform/katex-header.html +0 -0
  359. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-waveform/src/ce_ofdm/gamp.rs +0 -0
  360. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-waveform/src/ce_ofdm/mod.rs +0 -0
  361. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-waveform/src/ce_ofdm/theory.rs +0 -0
  362. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-waveform/src/cpm/detection.rs +0 -0
  363. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-waveform/src/cpm/mod.rs +0 -0
  364. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-waveform/src/cpm/pulse.rs +0 -0
  365. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-waveform/src/css/mod.rs +0 -0
  366. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-waveform/src/css/theory.rs +0 -0
  367. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-waveform/src/ofdm/correction.rs +0 -0
  368. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-waveform/src/ofdm/detection.rs +0 -0
  369. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-waveform/src/ofdm/dvbt.rs +0 -0
  370. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-waveform/src/ofdm/estimation.rs +0 -0
  371. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-waveform/src/ofdm/grid.rs +0 -0
  372. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-waveform/src/ofdm/link.rs +0 -0
  373. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-waveform/src/ofdm/lte.rs +0 -0
  374. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-waveform/src/ofdm/nr.rs +0 -0
  375. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-waveform/src/ofdm/sync.rs +0 -0
  376. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-waveform/src/ofdm/wiener.rs +0 -0
  377. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-waveform/src/otfs.rs +0 -0
  378. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-waveform/src/papr.rs +0 -0
  379. {comnum-0.2.0 → comnum-0.3.1}/crates/comnum-waveform/src/ufmc.rs +0 -0
  380. {comnum-0.2.0 → comnum-0.3.1}/pyproject.toml +0 -0
  381. {comnum-0.2.0 → comnum-0.3.1}/python/comnum/__init__.py +0 -0
  382. {comnum-0.2.0 → comnum-0.3.1}/python/comnum/block.py +0 -0
  383. {comnum-0.2.0 → comnum-0.3.1}/python/comnum/chain.py +0 -0
  384. {comnum-0.2.0 → comnum-0.3.1}/python/comnum/plot.py +0 -0
  385. {comnum-0.2.0 → comnum-0.3.1}/python/comnum/py.typed +0 -0
  386. {comnum-0.2.0 → comnum-0.3.1}/python/comnum/results.py +0 -0
  387. {comnum-0.2.0 → comnum-0.3.1}/python/comnum/sim.py +0 -0
  388. {comnum-0.2.0 → comnum-0.3.1}/python/comnum/spec.py +0 -0
@@ -95,7 +95,7 @@ checksum = "1c133bc6a41be0d194c306b5506d15e6feeea7b1d6604bd3f8310dfb2ca96486"
95
95
 
96
96
  [[package]]
97
97
  name = "comnum"
98
- version = "0.2.0"
98
+ version = "0.3.1"
99
99
  dependencies = [
100
100
  "comnum-channel",
101
101
  "comnum-core",
@@ -116,7 +116,7 @@ dependencies = [
116
116
 
117
117
  [[package]]
118
118
  name = "comnum-channel"
119
- version = "0.2.0"
119
+ version = "0.3.1"
120
120
  dependencies = [
121
121
  "comnum-core",
122
122
  "comnum-dsp",
@@ -127,7 +127,7 @@ dependencies = [
127
127
 
128
128
  [[package]]
129
129
  name = "comnum-core"
130
- version = "0.2.0"
130
+ version = "0.3.1"
131
131
  dependencies = [
132
132
  "ndarray",
133
133
  "num-complex",
@@ -136,7 +136,7 @@ dependencies = [
136
136
 
137
137
  [[package]]
138
138
  name = "comnum-dsp"
139
- version = "0.2.0"
139
+ version = "0.3.1"
140
140
  dependencies = [
141
141
  "comnum-core",
142
142
  "comnum-math",
@@ -145,7 +145,7 @@ dependencies = [
145
145
 
146
146
  [[package]]
147
147
  name = "comnum-fec"
148
- version = "0.2.0"
148
+ version = "0.3.1"
149
149
  dependencies = [
150
150
  "comnum-core",
151
151
  "comnum-math",
@@ -153,7 +153,7 @@ dependencies = [
153
153
 
154
154
  [[package]]
155
155
  name = "comnum-hardware"
156
- version = "0.2.0"
156
+ version = "0.3.1"
157
157
  dependencies = [
158
158
  "comnum-core",
159
159
  "comnum-dsp",
@@ -162,7 +162,7 @@ dependencies = [
162
162
 
163
163
  [[package]]
164
164
  name = "comnum-mapping"
165
- version = "0.2.0"
165
+ version = "0.3.1"
166
166
  dependencies = [
167
167
  "comnum-core",
168
168
  "comnum-math",
@@ -171,7 +171,7 @@ dependencies = [
171
171
 
172
172
  [[package]]
173
173
  name = "comnum-math"
174
- version = "0.2.0"
174
+ version = "0.3.1"
175
175
  dependencies = [
176
176
  "comnum-core",
177
177
  "ndarray",
@@ -181,7 +181,7 @@ dependencies = [
181
181
 
182
182
  [[package]]
183
183
  name = "comnum-metrics"
184
- version = "0.2.0"
184
+ version = "0.3.1"
185
185
  dependencies = [
186
186
  "comnum-core",
187
187
  "comnum-dsp",
@@ -191,7 +191,7 @@ dependencies = [
191
191
 
192
192
  [[package]]
193
193
  name = "comnum-mimo"
194
- version = "0.2.0"
194
+ version = "0.3.1"
195
195
  dependencies = [
196
196
  "comnum-core",
197
197
  "comnum-mapping",
@@ -201,7 +201,7 @@ dependencies = [
201
201
 
202
202
  [[package]]
203
203
  name = "comnum-py"
204
- version = "0.2.0"
204
+ version = "0.3.1"
205
205
  dependencies = [
206
206
  "comnum",
207
207
  "ndarray",
@@ -214,7 +214,7 @@ dependencies = [
214
214
 
215
215
  [[package]]
216
216
  name = "comnum-sim"
217
- version = "0.2.0"
217
+ version = "0.3.1"
218
218
  dependencies = [
219
219
  "comnum-channel",
220
220
  "comnum-core",
@@ -226,7 +226,7 @@ dependencies = [
226
226
 
227
227
  [[package]]
228
228
  name = "comnum-spec"
229
- version = "0.2.0"
229
+ version = "0.3.1"
230
230
  dependencies = [
231
231
  "comnum-channel",
232
232
  "comnum-core",
@@ -249,7 +249,7 @@ dependencies = [
249
249
 
250
250
  [[package]]
251
251
  name = "comnum-systems"
252
- version = "0.2.0"
252
+ version = "0.3.1"
253
253
  dependencies = [
254
254
  "comnum-core",
255
255
  "comnum-dsp",
@@ -262,7 +262,7 @@ dependencies = [
262
262
 
263
263
  [[package]]
264
264
  name = "comnum-validation"
265
- version = "0.2.0"
265
+ version = "0.3.1"
266
266
  dependencies = [
267
267
  "comnum",
268
268
  "ndarray",
@@ -271,7 +271,7 @@ dependencies = [
271
271
 
272
272
  [[package]]
273
273
  name = "comnum-waveform"
274
- version = "0.2.0"
274
+ version = "0.3.1"
275
275
  dependencies = [
276
276
  "comnum-core",
277
277
  "comnum-dsp",
@@ -4,7 +4,7 @@ resolver = "3"
4
4
  members = ["crates/comnum-core", "crates/comnum-math", "crates/comnum-dsp", "crates/comnum-fec", "crates/comnum-mapping", "crates/comnum-waveform", "crates/comnum-mimo", "crates/comnum-channel", "crates/comnum-hardware", "crates/comnum-metrics", "crates/comnum-sim", "crates/comnum-spec", "crates/comnum-systems", "crates/comnum", "bindings/comnum-py"]
5
5
 
6
6
  [workspace.package]
7
- version = "0.2.0"
7
+ version = "0.3.1"
8
8
  edition = "2024"
9
9
  rust-version = "1.85" # MSRV, tested in CI
10
10
  license = "MIT OR Apache-2.0"
@@ -17,20 +17,20 @@ categories = ["science", "simulation"]
17
17
 
18
18
  [workspace.dependencies]
19
19
  # the crates of the workspace (one version, released together)
20
- comnum-core = { path = "crates/comnum-core", version = "0.2.0" }
21
- comnum-math = { path = "crates/comnum-math", version = "0.2.0" }
22
- comnum-dsp = { path = "crates/comnum-dsp", version = "0.2.0" }
23
- comnum-fec = { path = "crates/comnum-fec", version = "0.2.0" }
24
- comnum-mapping = { path = "crates/comnum-mapping", version = "0.2.0" }
25
- comnum-waveform = { path = "crates/comnum-waveform", version = "0.2.0" }
26
- comnum-mimo = { path = "crates/comnum-mimo", version = "0.2.0" }
27
- comnum-channel = { path = "crates/comnum-channel", version = "0.2.0" }
28
- comnum-hardware = { path = "crates/comnum-hardware", version = "0.2.0" }
29
- comnum-metrics = { path = "crates/comnum-metrics", version = "0.2.0" }
30
- comnum-sim = { path = "crates/comnum-sim", version = "0.2.0" }
31
- comnum-spec = { path = "crates/comnum-spec", version = "0.2.0" }
32
- comnum-systems = { path = "crates/comnum-systems", version = "0.2.0" }
33
- comnum = { path = "crates/comnum", version = "0.2.0", default-features = false }
20
+ comnum-core = { path = "crates/comnum-core", version = "0.3.1" }
21
+ comnum-math = { path = "crates/comnum-math", version = "0.3.1" }
22
+ comnum-dsp = { path = "crates/comnum-dsp", version = "0.3.1" }
23
+ comnum-fec = { path = "crates/comnum-fec", version = "0.3.1" }
24
+ comnum-mapping = { path = "crates/comnum-mapping", version = "0.3.1" }
25
+ comnum-waveform = { path = "crates/comnum-waveform", version = "0.3.1" }
26
+ comnum-mimo = { path = "crates/comnum-mimo", version = "0.3.1" }
27
+ comnum-channel = { path = "crates/comnum-channel", version = "0.3.1" }
28
+ comnum-hardware = { path = "crates/comnum-hardware", version = "0.3.1" }
29
+ comnum-metrics = { path = "crates/comnum-metrics", version = "0.3.1" }
30
+ comnum-sim = { path = "crates/comnum-sim", version = "0.3.1" }
31
+ comnum-spec = { path = "crates/comnum-spec", version = "0.3.1" }
32
+ comnum-systems = { path = "crates/comnum-systems", version = "0.3.1" }
33
+ comnum = { path = "crates/comnum", version = "0.3.1", default-features = false }
34
34
  # third-party
35
35
  num-complex = "0.4"
36
36
  ndarray = "0.16"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: comnum
3
- Version: 0.2.0
3
+ Version: 0.3.1
4
4
  Classifier: Development Status :: 3 - Alpha
5
5
  Classifier: Intended Audience :: Science/Research
6
6
  Classifier: Topic :: Scientific/Engineering
@@ -47,8 +47,8 @@ the literature.
47
47
  <!-- highlights: generated by tools/highlights.py, do not edit -->
48
48
  - **Lightweight**: one run-time dependency in Python (numpy), 9 direct crates in Rust and no C, C++ or Fortran library to build; 27 MB installed with its dependencies (the benchmark's environment: komm 22 MB, OptiCommPy 321 MB, Sionna 1004 MB).
49
49
  - **Fast**: compiled Rust, Monte Carlo runs on every core; on one CPU thread, the links of the benchmark take 2.1 to 33 times as long with komm, 2.3 to 4.7 times as long with OptiCommPy and 1.1 to 7.4 times as long with Sionna as with comnum.
50
- - **Safe**: `unsafe` code forbidden in every crate, invalid inputs are errors (one error type), results independent of the thread count; 717 unit tests, 187 validation tests, 272 Python tests.
51
- - **Validated**: compared with 130 papers, standards and reference tools (82 fully reproduced, 44 partly), 100 inconsistencies found in them; 93 validation cards rerun a comparison without the paper.
50
+ - **Safe**: `unsafe` code forbidden in every crate, invalid inputs are errors (one error type), results independent of the thread count; 749 unit tests, 198 validation tests, 272 Python tests.
51
+ - **Validated**: compared with 139 papers, standards and reference tools (88 fully reproduced, 47 partly), 120 inconsistencies found in them; 104 validation cards rerun a comparison without the paper.
52
52
 
53
53
  The numbers are recomputed by `tools/highlights.py` from the recorded benchmark and the validation files; the details are on the page [Why comnum](https://com-rs.github.io/comnum/why.html).
54
54
  <!-- highlights:end -->
@@ -175,7 +175,7 @@ gives the tests behind every grade and the regimes not covered).
175
175
 
176
176
  <!-- generated by tools/maturity_table.py from validation/maturity.yaml: do not edit -->
177
177
 
178
- Summary: 71 modules: 66 at A, 3 at B, 2 at C.
178
+ Summary: 75 modules: 70 at A, 3 at B, 2 at C.
179
179
 
180
180
  **Foundations**
181
181
 
@@ -183,6 +183,7 @@ Summary: 71 modules: 66 at A, 3 at B, 2 at C.
183
183
  |---|---|---|
184
184
  | Constellations, mapping, demapping and closed-form error rates | A | OptiCommPy outputs; closed forms of Proakis & Salehi |
185
185
  | Capacity and cutoff rate of CM and BICM | A | Caire, Taricco & Biglieri 1998 Figs. 4–7 |
186
+ | Adaptive MQAM over fading | A | Goldsmith & Chua 1997 Figs. 3, 5, 10, Table II |
186
187
  | Sources (bits, PRBS, uniform and shaped symbols) | A | ITU-T O.150 Sec. 5 and Table 1, exact |
187
188
  | Differential PSK | A | Pawula, Rice & Roberts 1982 Sec. IV-A; closed forms of Proakis & Salehi |
188
189
  | Error rates with an imperfect channel estimate and over Jakes' fading | A | Chang & Su 2002 eqs. 31–53, Figs. 3–4 |
@@ -195,6 +196,8 @@ Summary: 71 modules: 66 at A, 3 at B, 2 at C.
195
196
  | Puncturing | A | Yasuda et al. Table I; patterns of IEEE 802.11 and EN 300 421 |
196
197
  | Turbo codes (LTE) | A | AFF3CT, K = 40 and 1024 |
197
198
  | LDPC codes | A | AFF3CT, PEG and DVB-S2 short code; Hu et al. 2005 |
199
+ | Density evolution of LDPC ensembles | A | Richardson & Urbanke 2001 Tables I-II |
200
+ | EXIT charts of parallel concatenated codes | A | ten Brink 2001 Tables II and IV |
198
201
  | Polar codes (SC, CA-SCL) | A | AFF3CT, SC and CA-SCL |
199
202
  | 5G NR channel codes: LDPC and polar with rate matching | A | Sionna vectors bit for bit; TS 38.212 tables |
200
203
  | Reed–Solomon codes | A | AFF3CT; Lin & Costello; ETSI EN 300 744, CCSDS 131.0-B |
@@ -214,7 +217,7 @@ Summary: 71 modules: 66 at A, 3 at B, 2 at C.
214
217
  | Constant-envelope OFDM | A | Thompson et al. 2008 eq. (15); Guerreiro et al. 2016 Fig. 1; López Morales et al. 2022 Fig. 3; Pacheco & Hatzinakos 2006 Fig. 1 |
215
218
  | Chirp spread spectrum (LoRa modulation) | A | Chiani & Elzanaty 2019 Table I; Afisiadis et al. 2020 Figs. 2, 7; Vangelista 2017 Fig. 1 |
216
219
  | Continuous-phase modulation | A | Murota & Hirade 1981 Table I and Fig. 5; Sundberg 1986 Fig. 5; MSK of Proakis & Salehi |
217
- | FBMC/OQAM | A | Bouhadda et al. 2014 Table 1, Figs. 7, 10, 11; Nissel & Rupp 2017 eq. (17) |
220
+ | FBMC/OQAM | A | Bouhadda et al. 2014 Table 1, Figs. 7, 10, 11; Nissel & Rupp 2017 eq. (17); Nissel, Schwarz & Rupp 2017 eqs. (13), (17), Figs. 5-8 |
218
221
  | UFMC | A | Vakilian et al. 2013 Fig. 3(b) |
219
222
  | OTFS and the delay–Doppler channel | A | Raviteja et al. 2019 Theorem 1 and its example; Hadani et al. 2017 Fig. 5 qualitatively |
220
223
 
@@ -228,6 +231,7 @@ Summary: 71 modules: 66 at A, 3 at B, 2 at C.
228
231
  | Capacity and precoding | A | Telatar 1999 Theorem 2, eqs. (13), (16)–(18), Figs. 1–4 |
229
232
  | MIMO channel estimation | A | Biguesh & Gershman 2006 Figs. 1–4, eqs. (12)–(59) |
230
233
  | Multi-user massive MIMO | A | Ngo, Larsson & Marzetta 2013 Props. 1–3, 5–7, Figs. 1 and 4 |
234
+ | Downlink NOMA | A | Ding et al. 2014 Fig. 3 table, Fig. 1(a) |
231
235
 
232
236
  **Wireless channels**
233
237
 
@@ -243,7 +247,7 @@ Summary: 71 modules: 66 at A, 3 at B, 2 at C.
243
247
 
244
248
  | Module | Level | Strongest evidence |
245
249
  |---|---|---|
246
- | Fibre: linear, split-step Fourier, Manakov, back-propagation | A | OptiCommPy outputs; Häger & Pfister 2021 Fig. 5; Ip & Kahn 2008 Fig. 12 (in part) |
250
+ | Fibre: linear, split-step Fourier, Manakov, back-propagation | A | OptiCommPy outputs; Häger & Pfister 2021 Figs. 5 and 8; Ip & Kahn 2008 Fig. 12 (in part) |
247
251
  | GN and EGN models | A | Carena et al. 2014 Fig. 1(a); GNPy outputs; Semrau, Killey & Bayvel 2019 Figs. 4a, 4b, 5 |
248
252
  | Raman amplification and ISRS | A | Bromage 2004 eqs. (3)–(5), Figs. 7–8; Hu et al. 2004 eq. (2); GNPy outputs; Semrau & Bayvel 2018 eq. (10) |
249
253
  | EDFA and PMD | A | the Maxwellian DGD of Foschini & Poole 1991 Fig. 3; the accumulated ASE |
@@ -16,8 +16,8 @@ the literature.
16
16
  <!-- highlights: generated by tools/highlights.py, do not edit -->
17
17
  - **Lightweight**: one run-time dependency in Python (numpy), 9 direct crates in Rust and no C, C++ or Fortran library to build; 27 MB installed with its dependencies (the benchmark's environment: komm 22 MB, OptiCommPy 321 MB, Sionna 1004 MB).
18
18
  - **Fast**: compiled Rust, Monte Carlo runs on every core; on one CPU thread, the links of the benchmark take 2.1 to 33 times as long with komm, 2.3 to 4.7 times as long with OptiCommPy and 1.1 to 7.4 times as long with Sionna as with comnum.
19
- - **Safe**: `unsafe` code forbidden in every crate, invalid inputs are errors (one error type), results independent of the thread count; 717 unit tests, 187 validation tests, 272 Python tests.
20
- - **Validated**: compared with 130 papers, standards and reference tools (82 fully reproduced, 44 partly), 100 inconsistencies found in them; 93 validation cards rerun a comparison without the paper.
19
+ - **Safe**: `unsafe` code forbidden in every crate, invalid inputs are errors (one error type), results independent of the thread count; 749 unit tests, 198 validation tests, 272 Python tests.
20
+ - **Validated**: compared with 139 papers, standards and reference tools (88 fully reproduced, 47 partly), 120 inconsistencies found in them; 104 validation cards rerun a comparison without the paper.
21
21
 
22
22
  The numbers are recomputed by `tools/highlights.py` from the recorded benchmark and the validation files; the details are on the page [Why comnum](https://com-rs.github.io/comnum/why.html).
23
23
  <!-- highlights:end -->
@@ -144,7 +144,7 @@ gives the tests behind every grade and the regimes not covered).
144
144
 
145
145
  <!-- generated by tools/maturity_table.py from validation/maturity.yaml: do not edit -->
146
146
 
147
- Summary: 71 modules: 66 at A, 3 at B, 2 at C.
147
+ Summary: 75 modules: 70 at A, 3 at B, 2 at C.
148
148
 
149
149
  **Foundations**
150
150
 
@@ -152,6 +152,7 @@ Summary: 71 modules: 66 at A, 3 at B, 2 at C.
152
152
  |---|---|---|
153
153
  | Constellations, mapping, demapping and closed-form error rates | A | OptiCommPy outputs; closed forms of Proakis & Salehi |
154
154
  | Capacity and cutoff rate of CM and BICM | A | Caire, Taricco & Biglieri 1998 Figs. 4–7 |
155
+ | Adaptive MQAM over fading | A | Goldsmith & Chua 1997 Figs. 3, 5, 10, Table II |
155
156
  | Sources (bits, PRBS, uniform and shaped symbols) | A | ITU-T O.150 Sec. 5 and Table 1, exact |
156
157
  | Differential PSK | A | Pawula, Rice & Roberts 1982 Sec. IV-A; closed forms of Proakis & Salehi |
157
158
  | Error rates with an imperfect channel estimate and over Jakes' fading | A | Chang & Su 2002 eqs. 31–53, Figs. 3–4 |
@@ -164,6 +165,8 @@ Summary: 71 modules: 66 at A, 3 at B, 2 at C.
164
165
  | Puncturing | A | Yasuda et al. Table I; patterns of IEEE 802.11 and EN 300 421 |
165
166
  | Turbo codes (LTE) | A | AFF3CT, K = 40 and 1024 |
166
167
  | LDPC codes | A | AFF3CT, PEG and DVB-S2 short code; Hu et al. 2005 |
168
+ | Density evolution of LDPC ensembles | A | Richardson & Urbanke 2001 Tables I-II |
169
+ | EXIT charts of parallel concatenated codes | A | ten Brink 2001 Tables II and IV |
167
170
  | Polar codes (SC, CA-SCL) | A | AFF3CT, SC and CA-SCL |
168
171
  | 5G NR channel codes: LDPC and polar with rate matching | A | Sionna vectors bit for bit; TS 38.212 tables |
169
172
  | Reed–Solomon codes | A | AFF3CT; Lin & Costello; ETSI EN 300 744, CCSDS 131.0-B |
@@ -183,7 +186,7 @@ Summary: 71 modules: 66 at A, 3 at B, 2 at C.
183
186
  | Constant-envelope OFDM | A | Thompson et al. 2008 eq. (15); Guerreiro et al. 2016 Fig. 1; López Morales et al. 2022 Fig. 3; Pacheco & Hatzinakos 2006 Fig. 1 |
184
187
  | Chirp spread spectrum (LoRa modulation) | A | Chiani & Elzanaty 2019 Table I; Afisiadis et al. 2020 Figs. 2, 7; Vangelista 2017 Fig. 1 |
185
188
  | Continuous-phase modulation | A | Murota & Hirade 1981 Table I and Fig. 5; Sundberg 1986 Fig. 5; MSK of Proakis & Salehi |
186
- | FBMC/OQAM | A | Bouhadda et al. 2014 Table 1, Figs. 7, 10, 11; Nissel & Rupp 2017 eq. (17) |
189
+ | FBMC/OQAM | A | Bouhadda et al. 2014 Table 1, Figs. 7, 10, 11; Nissel & Rupp 2017 eq. (17); Nissel, Schwarz & Rupp 2017 eqs. (13), (17), Figs. 5-8 |
187
190
  | UFMC | A | Vakilian et al. 2013 Fig. 3(b) |
188
191
  | OTFS and the delay–Doppler channel | A | Raviteja et al. 2019 Theorem 1 and its example; Hadani et al. 2017 Fig. 5 qualitatively |
189
192
 
@@ -197,6 +200,7 @@ Summary: 71 modules: 66 at A, 3 at B, 2 at C.
197
200
  | Capacity and precoding | A | Telatar 1999 Theorem 2, eqs. (13), (16)–(18), Figs. 1–4 |
198
201
  | MIMO channel estimation | A | Biguesh & Gershman 2006 Figs. 1–4, eqs. (12)–(59) |
199
202
  | Multi-user massive MIMO | A | Ngo, Larsson & Marzetta 2013 Props. 1–3, 5–7, Figs. 1 and 4 |
203
+ | Downlink NOMA | A | Ding et al. 2014 Fig. 3 table, Fig. 1(a) |
200
204
 
201
205
  **Wireless channels**
202
206
 
@@ -212,7 +216,7 @@ Summary: 71 modules: 66 at A, 3 at B, 2 at C.
212
216
 
213
217
  | Module | Level | Strongest evidence |
214
218
  |---|---|---|
215
- | Fibre: linear, split-step Fourier, Manakov, back-propagation | A | OptiCommPy outputs; Häger & Pfister 2021 Fig. 5; Ip & Kahn 2008 Fig. 12 (in part) |
219
+ | Fibre: linear, split-step Fourier, Manakov, back-propagation | A | OptiCommPy outputs; Häger & Pfister 2021 Figs. 5 and 8; Ip & Kahn 2008 Fig. 12 (in part) |
216
220
  | GN and EGN models | A | Carena et al. 2014 Fig. 1(a); GNPy outputs; Semrau, Killey & Bayvel 2019 Figs. 4a, 4b, 5 |
217
221
  | Raman amplification and ISRS | A | Bromage 2004 eqs. (3)–(5), Figs. 7–8; Hu et al. 2004 eq. (2); GNPy outputs; Semrau & Bayvel 2018 eq. (10) |
218
222
  | EDFA and PMD | A | the Maxwellian DGD of Foschini & Poole 1991 Fig. 3; the accumulated ASE |
@@ -134,10 +134,10 @@ fn message_dict<'py>(py: Python<'py>, m: &Message) -> PyResult<Bound<'py, PyDict
134
134
  ///
135
135
  /// Examples:
136
136
  /// >>> import comnum
137
- /// >>> bits = comnum.ais_position_report(227000001, lat_deg=48.38, lon_deg=-4.49, sog_knots=8.0)
137
+ /// >>> bits = comnum.ais_position_report(200000001, lat_deg=46.12, lon_deg=-9.88, sog_knots=8.0)
138
138
  /// >>> m = comnum.ais_decode(bits)
139
139
  /// >>> m["msg_type"], m["mmsi"], round(m["position"]["lat_deg"], 2)
140
- /// (1, 227000001, 48.38)
140
+ /// (1, 200000001, 46.12)
141
141
  #[pyfunction]
142
142
  fn ais_decode<'py>(py: Python<'py>, bits: &Bound<'py, PyAny>) -> PyResult<Bound<'py, PyDict>> {
143
143
  message_dict(py, &message::decode(&bvec(bits)?).py()?)
@@ -266,10 +266,10 @@ fn ais_transmit<'py>(py: Python<'py>, messages: Vec<Bound<'py, PyAny>>, fs: f64)
266
266
  /// Examples:
267
267
  /// >>> import comnum
268
268
  /// >>> fs = comnum.ais_front_end_rate()
269
- /// >>> bits = comnum.ais_position_report(227000001, lat_deg=48.38, lon_deg=-4.49)
269
+ /// >>> bits = comnum.ais_position_report(200000001, lat_deg=46.12, lon_deg=-9.88)
270
270
  /// >>> x = comnum.ais_transmit([bits], fs)
271
271
  /// >>> [p["message"]["mmsi"] for p in comnum.ais_receive(x, fs)]
272
- /// [227000001]
272
+ /// [200000001]
273
273
  #[pyfunction]
274
274
  fn ais_receive<'py>(py: Python<'py>, x: &Bound<'py, PyAny>, fs: f64) -> PyResult<Bound<'py, PyList>> {
275
275
  let v = cvec(x)?;
@@ -10,7 +10,8 @@ use comnum::channel::optical::manakov::ManakovSsfm;
10
10
  use comnum::channel::optical::pmd::{ManakovPmd, PmdLink};
11
11
  use comnum::channel::optical::raman::Raman;
12
12
  use comnum::core::signal::DualPol;
13
- use comnum::math::nlse::{NonlinearStep, StepRule, StepUpdate};
13
+ use comnum::dsp::compensation::dbp::{Dbp, NonlinearLength};
14
+ use comnum::math::nlse::{NonlinearStep, StepDistribution, StepRule, StepUpdate};
14
15
  use comnum::spec::blocks::BuildContext;
15
16
  use pyo3::exceptions::PyValueError;
16
17
  use pyo3::prelude::*;
@@ -325,6 +326,10 @@ pub(crate) fn raman(py: Python<'_>, v: Option<&Bound<'_, PyAny>>) -> PyResult<Op
325
326
  /// Args:
326
327
  /// fiber (FiberParams): the link.
327
328
  /// step_km (float): step size `h` (km).
329
+ /// steps_per_span (int, optional): this number of logarithmic steps per span
330
+ /// instead of `step_km` (Bosco et al., IEEE PTL 12(5), 2000, eq. (6)): every step
331
+ /// carries the same integrated power, short at the start of the span; double
332
+ /// precision only.
328
333
  /// amplification (str): `"edfa"`, `"ideal"` or `"none"`.
329
334
  /// raman (dict, optional): Raman pumps and ISRS in every span, the keys of
330
335
  /// ``fiber.raman`` in a specification (see :func:`raman_profile`); the amplifier
@@ -349,32 +354,39 @@ impl PySsfm {
349
354
  fn __repr__(&self) -> String {
350
355
  let s = &self.inner;
351
356
  format!(
352
- "Ssfm(n_spans={}, span_km={}, step_km={}, amplification='{}', raman={})",
357
+ "Ssfm(n_spans={}, span_km={}, {}, amplification='{}', raman={})",
353
358
  s.fiber.n_spans,
354
359
  s.fiber.span_km,
355
- s.step_km,
360
+ match s.rule {
361
+ Some(StepRule::Logarithmic(n)) => format!("steps_per_span={n}"),
362
+ _ => format!("step_km={}", s.step_km),
363
+ },
356
364
  format!("{:?}", s.amplification).to_lowercase(),
357
365
  py_bool(s.raman.is_some())
358
366
  )
359
367
  }
360
368
 
361
369
  #[new]
362
- #[pyo3(signature = (fiber, *, step_km = 1.0, amplification = "edfa", raman = None, check_sampling = true))]
370
+ #[pyo3(signature = (fiber, *, step_km = 1.0, steps_per_span = None, amplification = "edfa", raman = None, check_sampling = true))]
363
371
  fn new(
364
372
  py: Python<'_>,
365
373
  fiber: &PyFiber,
366
374
  step_km: f64,
375
+ steps_per_span: Option<usize>,
367
376
  amplification: &str,
368
377
  raman: Option<&Bound<'_, PyAny>>,
369
378
  check_sampling: bool,
370
379
  ) -> PyResult<Self> {
380
+ if steps_per_span == Some(0) {
381
+ return Err(PyValueError::new_err("steps_per_span must be at least 1"));
382
+ }
371
383
  Ok(PySsfm {
372
384
  inner: Ssfm {
373
385
  fiber: fiber.inner.clone(),
374
386
  step_km,
375
387
  amplification: amplification.parse::<Amplification>().py()?,
376
388
  raman: self::raman(py, raman)?,
377
- rule: None,
389
+ rule: steps_per_span.map(StepRule::Logarithmic),
378
390
  check_sampling,
379
391
  },
380
392
  })
@@ -437,13 +449,23 @@ impl PySsfm {
437
449
  /// nonlinear_scale (float): ξ, multiplies the nonlinear phase (the optimised DBP
438
450
  /// with few steps per span, Ip & Kahn 2008; 0 gives the linear
439
451
  /// back-propagation).
452
+ /// step_distribution (str): ``"uniform"`` (equal steps), ``"logarithmic"`` (Bosco
453
+ /// et al. 2000: every step carries the same integrated power of the forward
454
+ /// span, applied from its end; better with 2 to 8 steps per span, worse with
455
+ /// many) or ``"modified_logarithmic"`` (Zhang et al. 2013: the attenuation
456
+ /// times ``step_factor``).
457
+ /// step_factor (float): the adjusting factor of the modified logarithmic steps.
458
+ /// nonlinear_length (str): ``"effective"``, the effective length of a coarse step
459
+ /// (the power integrated over it), or ``"step"``, the step itself (the
460
+ /// midpoint rule of Häger & Pfister 2021).
440
461
  ///
441
462
  /// Returns:
442
463
  /// numpy.ndarray: the back-propagated field (complex128).
443
464
  ///
444
465
  /// Raises:
445
466
  /// ValueError: for an invalid parameter or input (the message names it).
446
- #[pyo3(signature = (x, fs, *, steps_per_span = 1, nonlinear_scale = 1.0))]
467
+ #[pyo3(signature = (x, fs, *, steps_per_span = 1, nonlinear_scale = 1.0, step_distribution = "uniform", step_factor = 0.4, nonlinear_length = "effective"))]
468
+ #[allow(clippy::too_many_arguments, reason = "the settings of the back-propagation, by keyword")]
447
469
  fn backpropagate<'py>(
448
470
  &self,
449
471
  py: Python<'py>,
@@ -451,10 +473,21 @@ impl PySsfm {
451
473
  fs: f64,
452
474
  steps_per_span: usize,
453
475
  nonlinear_scale: f64,
476
+ step_distribution: &str,
477
+ step_factor: f64,
478
+ nonlinear_length: &str,
454
479
  ) -> PyResult<CArr<'py>> {
455
480
  let x = cvec(x)?;
456
- let s = &self.inner;
457
- Ok(carr(py, py.detach(|| s.backpropagate_scaled(&x, fs, steps_per_span, nonlinear_scale)).py()?))
481
+ let distribution = match step_distribution.parse::<StepDistribution>().py()? {
482
+ StepDistribution::ModifiedLogarithmic(_) => StepDistribution::ModifiedLogarithmic(step_factor),
483
+ d => d,
484
+ };
485
+ let dbp = Dbp {
486
+ distribution,
487
+ nonlinear_length: nonlinear_length.parse::<NonlinearLength>().py()?,
488
+ ..self.inner.dbp(steps_per_span, nonlinear_scale)
489
+ };
490
+ Ok(carr(py, py.detach(|| dbp.run(&x, fs)).py()?))
458
491
  }
459
492
  }
460
493
 
@@ -590,8 +623,11 @@ impl PyManakov {
590
623
  /// step_rule (str): ``"fwm"``, the rule of Musetti et al. (2018): the first step of a
591
624
  /// span bounds the four-wave-mixing phase across the signal bandwidth to
592
625
  /// ``fwm_phase``, the next ones grow with the loss (about 0.01 dB of error on the
593
- /// SNR at 20 rad, whatever the power); or ``"nonlinear_phase"``, OptiCommPy's
594
- /// ``max_nl_phase`` per step.
626
+ /// SNR at 20 rad, whatever the power); ``"nonlinear_phase"``, OptiCommPy's
627
+ /// ``max_nl_phase`` per step; or ``"logarithmic"``, ``steps_per_span``
628
+ /// logarithmic steps (Bosco et al. 2000).
629
+ /// steps_per_span (int): logarithmic steps per span, with
630
+ /// ``step_rule="logarithmic"``.
595
631
  /// fwm_phase (float): the four-wave-mixing phase of the first step (rad).
596
632
  /// bandwidth_hz (float, optional): the signal bandwidth of the rule ``"fwm"``
597
633
  /// (measured on the launched field if None).
@@ -635,7 +671,7 @@ impl PyManakovSsfm {
635
671
  }
636
672
 
637
673
  #[new]
638
- #[pyo3(signature = (fiber, *, step_rule = "fwm", fwm_phase = 20.0, bandwidth_hz = None, max_nl_phase = 2e-2, step_km = None, nonlinear_step = "midpoint", max_iterations = 10, tolerance = 1e-5, amplification = "edfa", raman = None, check_sampling = true))]
674
+ #[pyo3(signature = (fiber, *, step_rule = "fwm", fwm_phase = 20.0, bandwidth_hz = None, max_nl_phase = 2e-2, steps_per_span = 100, step_km = None, nonlinear_step = "midpoint", max_iterations = 10, tolerance = 1e-5, amplification = "edfa", raman = None, check_sampling = true))]
639
675
  #[allow(clippy::too_many_arguments, reason = "the settings of the solver, by keyword")]
640
676
  fn new(
641
677
  py: Python<'_>,
@@ -644,6 +680,7 @@ impl PyManakovSsfm {
644
680
  fwm_phase: f64,
645
681
  bandwidth_hz: Option<f64>,
646
682
  max_nl_phase: f64,
683
+ steps_per_span: usize,
647
684
  step_km: Option<f64>,
648
685
  nonlinear_step: &str,
649
686
  max_iterations: usize,
@@ -661,9 +698,10 @@ impl PyManakovSsfm {
661
698
  max_nl_phase_rad: Some(max_nl_phase),
662
699
  },
663
700
  (None, "nonlinear_phase") => StepRule::NonlinearPhase(max_nl_phase),
701
+ (None, "logarithmic") => StepRule::Logarithmic(steps_per_span),
664
702
  (None, other) => {
665
703
  return Err(PyValueError::new_err(format!(
666
- "step_rule must be 'fwm' or 'nonlinear_phase', got {other:?}"
704
+ "step_rule must be 'fwm', 'nonlinear_phase' or 'logarithmic', got {other:?}"
667
705
  )));
668
706
  }
669
707
  };
@@ -16,8 +16,8 @@ the literature.
16
16
  <!-- highlights: generated by tools/highlights.py, do not edit -->
17
17
  - **Lightweight**: one run-time dependency in Python (numpy), 9 direct crates in Rust and no C, C++ or Fortran library to build; 27 MB installed with its dependencies (the benchmark's environment: komm 22 MB, OptiCommPy 321 MB, Sionna 1004 MB).
18
18
  - **Fast**: compiled Rust, Monte Carlo runs on every core; on one CPU thread, the links of the benchmark take 2.1 to 33 times as long with komm, 2.3 to 4.7 times as long with OptiCommPy and 1.1 to 7.4 times as long with Sionna as with comnum.
19
- - **Safe**: `unsafe` code forbidden in every crate, invalid inputs are errors (one error type), results independent of the thread count; 717 unit tests, 187 validation tests, 272 Python tests.
20
- - **Validated**: compared with 130 papers, standards and reference tools (82 fully reproduced, 44 partly), 100 inconsistencies found in them; 93 validation cards rerun a comparison without the paper.
19
+ - **Safe**: `unsafe` code forbidden in every crate, invalid inputs are errors (one error type), results independent of the thread count; 749 unit tests, 198 validation tests, 272 Python tests.
20
+ - **Validated**: compared with 139 papers, standards and reference tools (88 fully reproduced, 47 partly), 120 inconsistencies found in them; 104 validation cards rerun a comparison without the paper.
21
21
 
22
22
  The numbers are recomputed by `tools/highlights.py` from the recorded benchmark and the validation files; the details are on the page [Why comnum](https://com-rs.github.io/comnum/why.html).
23
23
  <!-- highlights:end -->
@@ -144,7 +144,7 @@ gives the tests behind every grade and the regimes not covered).
144
144
 
145
145
  <!-- generated by tools/maturity_table.py from validation/maturity.yaml: do not edit -->
146
146
 
147
- Summary: 71 modules: 66 at A, 3 at B, 2 at C.
147
+ Summary: 75 modules: 70 at A, 3 at B, 2 at C.
148
148
 
149
149
  **Foundations**
150
150
 
@@ -152,6 +152,7 @@ Summary: 71 modules: 66 at A, 3 at B, 2 at C.
152
152
  |---|---|---|
153
153
  | Constellations, mapping, demapping and closed-form error rates | A | OptiCommPy outputs; closed forms of Proakis & Salehi |
154
154
  | Capacity and cutoff rate of CM and BICM | A | Caire, Taricco & Biglieri 1998 Figs. 4–7 |
155
+ | Adaptive MQAM over fading | A | Goldsmith & Chua 1997 Figs. 3, 5, 10, Table II |
155
156
  | Sources (bits, PRBS, uniform and shaped symbols) | A | ITU-T O.150 Sec. 5 and Table 1, exact |
156
157
  | Differential PSK | A | Pawula, Rice & Roberts 1982 Sec. IV-A; closed forms of Proakis & Salehi |
157
158
  | Error rates with an imperfect channel estimate and over Jakes' fading | A | Chang & Su 2002 eqs. 31–53, Figs. 3–4 |
@@ -164,6 +165,8 @@ Summary: 71 modules: 66 at A, 3 at B, 2 at C.
164
165
  | Puncturing | A | Yasuda et al. Table I; patterns of IEEE 802.11 and EN 300 421 |
165
166
  | Turbo codes (LTE) | A | AFF3CT, K = 40 and 1024 |
166
167
  | LDPC codes | A | AFF3CT, PEG and DVB-S2 short code; Hu et al. 2005 |
168
+ | Density evolution of LDPC ensembles | A | Richardson & Urbanke 2001 Tables I-II |
169
+ | EXIT charts of parallel concatenated codes | A | ten Brink 2001 Tables II and IV |
167
170
  | Polar codes (SC, CA-SCL) | A | AFF3CT, SC and CA-SCL |
168
171
  | 5G NR channel codes: LDPC and polar with rate matching | A | Sionna vectors bit for bit; TS 38.212 tables |
169
172
  | Reed–Solomon codes | A | AFF3CT; Lin & Costello; ETSI EN 300 744, CCSDS 131.0-B |
@@ -183,7 +186,7 @@ Summary: 71 modules: 66 at A, 3 at B, 2 at C.
183
186
  | Constant-envelope OFDM | A | Thompson et al. 2008 eq. (15); Guerreiro et al. 2016 Fig. 1; López Morales et al. 2022 Fig. 3; Pacheco & Hatzinakos 2006 Fig. 1 |
184
187
  | Chirp spread spectrum (LoRa modulation) | A | Chiani & Elzanaty 2019 Table I; Afisiadis et al. 2020 Figs. 2, 7; Vangelista 2017 Fig. 1 |
185
188
  | Continuous-phase modulation | A | Murota & Hirade 1981 Table I and Fig. 5; Sundberg 1986 Fig. 5; MSK of Proakis & Salehi |
186
- | FBMC/OQAM | A | Bouhadda et al. 2014 Table 1, Figs. 7, 10, 11; Nissel & Rupp 2017 eq. (17) |
189
+ | FBMC/OQAM | A | Bouhadda et al. 2014 Table 1, Figs. 7, 10, 11; Nissel & Rupp 2017 eq. (17); Nissel, Schwarz & Rupp 2017 eqs. (13), (17), Figs. 5-8 |
187
190
  | UFMC | A | Vakilian et al. 2013 Fig. 3(b) |
188
191
  | OTFS and the delay–Doppler channel | A | Raviteja et al. 2019 Theorem 1 and its example; Hadani et al. 2017 Fig. 5 qualitatively |
189
192
 
@@ -197,6 +200,7 @@ Summary: 71 modules: 66 at A, 3 at B, 2 at C.
197
200
  | Capacity and precoding | A | Telatar 1999 Theorem 2, eqs. (13), (16)–(18), Figs. 1–4 |
198
201
  | MIMO channel estimation | A | Biguesh & Gershman 2006 Figs. 1–4, eqs. (12)–(59) |
199
202
  | Multi-user massive MIMO | A | Ngo, Larsson & Marzetta 2013 Props. 1–3, 5–7, Figs. 1 and 4 |
203
+ | Downlink NOMA | A | Ding et al. 2014 Fig. 3 table, Fig. 1(a) |
200
204
 
201
205
  **Wireless channels**
202
206
 
@@ -212,7 +216,7 @@ Summary: 71 modules: 66 at A, 3 at B, 2 at C.
212
216
 
213
217
  | Module | Level | Strongest evidence |
214
218
  |---|---|---|
215
- | Fibre: linear, split-step Fourier, Manakov, back-propagation | A | OptiCommPy outputs; Häger & Pfister 2021 Fig. 5; Ip & Kahn 2008 Fig. 12 (in part) |
219
+ | Fibre: linear, split-step Fourier, Manakov, back-propagation | A | OptiCommPy outputs; Häger & Pfister 2021 Figs. 5 and 8; Ip & Kahn 2008 Fig. 12 (in part) |
216
220
  | GN and EGN models | A | Carena et al. 2014 Fig. 1(a); GNPy outputs; Semrau, Killey & Bayvel 2019 Figs. 4a, 4b, 5 |
217
221
  | Raman amplification and ISRS | A | Bromage 2004 eqs. (3)–(5), Figs. 7–8; Hu et al. 2004 eq. (2); GNPy outputs; Semrau & Bayvel 2018 eq. (10) |
218
222
  | EDFA and PMD | A | the Maxwellian DGD of Foschini & Poole 1991 Fig. 3; the accumulated ASE |
@@ -97,6 +97,30 @@ pub fn max_doppler_hz(speed_mps: f64, fc_hz: f64) -> f64 {
97
97
  speed_mps * fc_hz / SPEED_OF_LIGHT
98
98
  }
99
99
 
100
+ /// The level-crossing rate (crossings per second, in one direction) of a Rayleigh fading
101
+ /// envelope with the Clarke/Jakes spectrum of maximum Doppler shift `doppler_hz`, at the
102
+ /// level $\rho$ = `rho` relative to its RMS value (Zheng & Xiao 2003, eq. (19a)):
103
+ /// $$L = \sqrt{2\pi}\, f_{D}\, \rho\, e^{-\rho^{2}}.$$
104
+ ///
105
+ /// # Examples
106
+ /// ```
107
+ /// use comnum_channel::multipath::rayleigh_level_crossing_rate;
108
+ /// // the largest rate, at rho = 1/sqrt(2): sqrt(pi) e^{-1/2} f_D
109
+ /// let l = rayleigh_level_crossing_rate(0.5f64.sqrt(), 1.0);
110
+ /// assert!((l - std::f64::consts::PI.sqrt() * (-0.5f64).exp()).abs() < 1e-15);
111
+ /// ```
112
+ pub fn rayleigh_level_crossing_rate(rho: f64, doppler_hz: f64) -> f64 {
113
+ (2.0 * std::f64::consts::PI).sqrt() * doppler_hz * rho * (-rho * rho).exp()
114
+ }
115
+
116
+ /// The average fade duration (s) of a Rayleigh fading envelope below the level $\rho$ =
117
+ /// `rho` relative to its RMS value, maximum Doppler shift `doppler_hz` (Zheng & Xiao 2003,
118
+ /// eq. (19b)): the probability of the fade $1 - e^{-\rho^{2}}$ over the level-crossing rate,
119
+ /// $$T = \frac{e^{\rho^{2}} - 1}{\rho f_{D}\sqrt{2\pi}}.$$
120
+ pub fn rayleigh_average_fade_duration(rho: f64, doppler_hz: f64) -> f64 {
121
+ ((rho * rho).exp() - 1.0) / (rho * doppler_hz * (2.0 * std::f64::consts::PI).sqrt())
122
+ }
123
+
100
124
  /// The Doppler shift of the specular component of a Ricean tap relative to the maximum
101
125
  /// Doppler shift, $f_{S} / f_{D} = 0.7$ (TR 38.901 §7.7.2, for TDL-D and TDL-E).
102
126
  pub const LOS_DOPPLER_RATIO: f64 = 0.7;
@@ -375,8 +375,10 @@ pub struct Ssfm {
375
375
  pub raman: Option<Raman>,
376
376
  /// Another step rule than the fixed steps of `step_km` (OptiCommPy's): the rule of
377
377
  /// every propagator of the engine (`docs/adr/0014-one-fibre-propagator.md`), such as
378
- /// `StepRule::FWM_DEFAULT`; the back-propagation and the single-precision path keep
379
- /// the fixed steps.
378
+ /// `StepRule::FWM_DEFAULT` or the logarithmic steps of Bosco et al.,
379
+ /// `StepRule::Logarithmic(n)`; the back-propagation keeps its own steps
380
+ /// ([`Ssfm::dbp`]), and the single-precision path the fixed steps (it refuses the
381
+ /// logarithmic ones).
380
382
  pub rule: Option<StepRule>,
381
383
  /// Refuse a field whose sampling rate or block cannot hold the four-wave mixing and
382
384
  /// the walk-off of the link ([`SamplingCheck`]); `false` runs anyway.
@@ -479,7 +481,12 @@ impl Ssfm {
479
481
  /// of the lumped amplifiers: [`Ssfm::raman`] is ignored.
480
482
  pub fn dbp(&self, steps_per_span: usize, xi: f64) -> Dbp {
481
483
  let f = &self.fiber;
482
- let forward = self.steps().ok().map(|(n, h)| Steps::new(n, h));
484
+ // the steps of the forward model, only when they are the fixed steps of step_km
485
+ // (another rule propagates with other steps: no exact inverse)
486
+ let forward = match self.rule {
487
+ None => self.steps().ok().map(|(n, h)| Steps::new(n, h)),
488
+ Some(_) => None,
489
+ };
483
490
  let mut dbp = Dbp { steps_per_span, xi, forward, ..Dbp::new(f.medium(), f.span_km, f.n_spans, 1.0) };
484
491
  dbp.span_gain = self.amplification.field_gain(f, steps_per_span as f64 * dbp.step_km());
485
492
  dbp
@@ -515,6 +522,9 @@ impl Ssfm {
515
522
  /// precision only).
516
523
  pub fn propagate_f32(&self, x: &mut Vec<C64>, fs: f64, rng: Option<&mut Rng>) -> Result<()> {
517
524
  ensure(self.raman.is_none(), || "the Raman amplification is simulated in double precision only".into())?;
525
+ ensure(!matches!(self.rule, Some(StepRule::Logarithmic(_))), || {
526
+ "the logarithmic steps are simulated in double precision only".into()
527
+ })?;
518
528
  let (n_steps, h) = self.steps()?;
519
529
  let n = x.len();
520
530
  if n == 0 {