malachite-base-0.4.16/.cargo_vcs_info.json0000644000000001540000000000100137630ustar { "git": { "sha1": "48e6f04610f9f462f87dd0b3f53841c98568a392" }, "path_in_vcs": "malachite-base" }malachite-base-0.4.16/.gitignore000064400000000000000000000000311046102023000145350ustar 00000000000000target *.bk .idea* *.iml malachite-base-0.4.16/Cargo.lock0000644000000413740000000000100117470ustar # This file is automatically @generated by Cargo. # It is not intended for manual editing. version = 3 [[package]] name = "ahash" version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", "once_cell", "version_check", "zerocopy", ] [[package]] name = "ansi_term" version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" dependencies = [ "winapi", ] [[package]] name = "atty" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ "hermit-abi", "libc", "winapi", ] [[package]] name = "bitflags" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "block-buffer" version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ "generic-array", ] [[package]] name = "bumpalo" version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "byteorder" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" version = "2.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" dependencies = [ "ansi_term", "atty", "bitflags", "strsim", "textwrap", "unicode-width", "vec_map", ] [[package]] name = "cpufeatures" version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad" dependencies = [ "libc", ] [[package]] name = "crypto-common" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", "typenum", ] [[package]] name = "deranged" version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ "powerfmt", ] [[package]] name = "digest" version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", "crypto-common", ] [[package]] name = "either" version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "generic-array" version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", ] [[package]] name = "getrandom" version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "js-sys", "libc", "wasi", "wasm-bindgen", ] [[package]] name = "gnuplot" version = "0.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2529467b8aef62bdf0c97dc984ca33244b84f8b5eb9517328f24bbb9afa0fb31" dependencies = [ "byteorder", ] [[package]] name = "hashbrown" version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ "ahash", ] [[package]] name = "hermit-abi" version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" dependencies = [ "libc", ] [[package]] name = "itertools" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" dependencies = [ "either", ] [[package]] name = "js-sys" version = "0.3.70" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" dependencies = [ "wasm-bindgen", ] [[package]] name = "keccak" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" dependencies = [ "cpufeatures", ] [[package]] name = "libc" version = "0.2.158" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" [[package]] name = "libm" version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" [[package]] name = "log" version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "malachite-base" version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5f8d7930df6fcb9c86761ca0999ba484d7b6469c81cee4a7d38da5386440f96" dependencies = [ "clap", "getrandom", "gnuplot", "hashbrown", "itertools", "libm", "rand", "rand_chacha", "ryu", "sha3", "time", ] [[package]] name = "malachite-base" version = "0.4.16" dependencies = [ "clap", "getrandom", "gnuplot", "hashbrown", "itertools", "libm", "malachite-base 0.4.15", "maplit", "rand", "rand_chacha", "ryu", "sha3", "time", "walkdir", ] [[package]] name = "maplit" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" [[package]] name = "num-conv" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" [[package]] name = "once_cell" version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "powerfmt" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" dependencies = [ "zerocopy", ] [[package]] name = "proc-macro2" version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] [[package]] name = "rand" version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "rand_core", ] [[package]] name = "rand_chacha" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", "rand_core", ] [[package]] name = "rand_core" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" [[package]] name = "ryu" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "same-file" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" dependencies = [ "winapi-util", ] [[package]] name = "serde" version = "1.0.209" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" version = "1.0.209" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "sha3" version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" dependencies = [ "digest", "keccak", ] [[package]] name = "strsim" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "syn" version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] [[package]] name = "textwrap" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" dependencies = [ "unicode-width", ] [[package]] name = "time" version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "num-conv", "powerfmt", "serde", "time-core", ] [[package]] name = "time-core" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "typenum" version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-width" version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" [[package]] name = "vec_map" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" [[package]] name = "version_check" version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "walkdir" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", "winapi-util", ] [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" dependencies = [ "cfg-if", "once_cell", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" dependencies = [ "quote", "wasm-bindgen-macro-support", ] [[package]] name = "wasm-bindgen-macro-support" version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" [[package]] name = "winapi" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" dependencies = [ "winapi-i686-pc-windows-gnu", "winapi-x86_64-pc-windows-gnu", ] [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ "windows-sys", ] [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-sys" version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ "windows-targets", ] [[package]] name = "windows-targets" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", "windows_i686_gnu", "windows_i686_gnullvm", "windows_i686_msvc", "windows_x86_64_gnu", "windows_x86_64_gnullvm", "windows_x86_64_msvc", ] [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "zerocopy" version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ "byteorder", "zerocopy-derive", ] [[package]] name = "zerocopy-derive" version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", "syn", ] malachite-base-0.4.16/Cargo.toml0000644000000051270000000000100117660ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2021" rust-version = "1.74.0" name = "malachite-base" version = "0.4.16" authors = ["Mikhail Hogrefe "] build = false autobins = false autoexamples = false autotests = false autobenches = false description = "A collection of utilities, including new arithmetic traits and iterators that generate all values of a type" homepage = "https://malachite.rs/" readme = "README.md" keywords = [ "mathematics", "math", "numerics", "testing", ] categories = [ "mathematics", "development-tools::testing", ] license = "LGPL-3.0-only" repository = "https://github.com/mhogrefe/malachite" [package.metadata.docs.rs] rustdoc-args = [ "--html-in-header", "katex-header.html", ] [lib] name = "malachite_base" path = "src/lib.rs" [[bin]] name = "malachite_base_main" path = "src/bin.rs" test = false [[test]] name = "lib" path = "tests/lib.rs" [dependencies.clap] version = "2.33.1" optional = true [dependencies.getrandom] version = "0.2" features = ["js"] optional = true default-features = false [dependencies.gnuplot] version = "0.0.39" optional = true [dependencies.hashbrown] version = "0.14" features = [ "ahash", "inline-more", ] default-features = false [dependencies.itertools] version = "0.11.0" features = ["use_alloc"] default-features = false [dependencies.libm] version = "0.2.8" default-features = false [dependencies.rand] version = "0.8.5" optional = true default-features = false [dependencies.rand_chacha] version = "0.3.1" optional = true default-features = false [dependencies.ryu] version = "1.0.15" default-features = false [dependencies.sha3] version = "0.10.8" optional = true default-features = false [dependencies.time] version = "0.3.28" optional = true [dependencies.walkdir] version = "2.3.3" optional = true [dev-dependencies.malachite-base] version = "0.4.15" features = ["test_build"] [dev-dependencies.maplit] version = "1.0.2" [features] bin_build = [ "walkdir", "test_build", ] random = [ "sha3", "rand", "rand_chacha", "getrandom", ] test_build = [ "gnuplot", "time", "clap", "random", "itertools/use_std", ] malachite-base-0.4.16/Cargo.toml.orig000064400000000000000000000034721046102023000154500ustar 00000000000000[package] name = "malachite-base" version = "0.4.16" authors = ["Mikhail Hogrefe "] rust-version.workspace = true edition.workspace = true description = "A collection of utilities, including new arithmetic traits and iterators that generate all values of a type" readme = "README.md" homepage = "https://malachite.rs/" repository = "https://github.com/mhogrefe/malachite" license = "LGPL-3.0-only" keywords = ["mathematics", "math", "numerics", "testing"] categories = ["mathematics", "development-tools::testing"] [lib] name = "malachite_base" path = "src/lib.rs" [[bin]] name = "malachite_base_main" path = "src/bin.rs" test = false [dependencies] itertools = { version = "0.11.0", default-features = false, features = ["use_alloc"] } ryu = { version = "1.0.15", default-features = false } hashbrown = { version = "0.14", default-features = false, features = ["ahash", "inline-more"] } libm = { version = "0.2.8", default-features = false } sha3 = { version = "0.10.8", optional = true, default-features = false } rand = { version = "0.8.5", optional = true, default-features = false } rand_chacha = { version = "0.3.1", optional = true, default-features = false } getrandom = { version = "0.2", default-features = false, features = ["js"], optional = true } clap = { version = "2.33.1", optional = true } gnuplot = { version = "0.0.39", optional = true } time = { version = "0.3.28", optional = true } walkdir = { version = "2.3.3", optional = true } [features] random = ["sha3", "rand", "rand_chacha", "getrandom"] test_build = ["gnuplot", "time", "clap", "random", "itertools/use_std"] bin_build = ["walkdir", "test_build"] [dev-dependencies] malachite-base = { workspace = true, features = ["test_build"] } maplit = "1.0.2" [package.metadata.docs.rs] rustdoc-args = [ "--html-in-header", "katex-header.html" ] malachite-base-0.4.16/README.md000064400000000000000000000126061046102023000140370ustar 00000000000000- [crates.io](https://crates.io/crates/malachite-base) - [docs.rs](https://docs.rs/malachite-base/latest/malachite_base/) Rather than using this crate directly, use the [`malachite`](https://crates.io/crates/malachite) meta-crate. It re-exports all of this crate's public members. In `malachite-base`'s doctests you will frequently see import paths beginning with `malachite_base::`. When using the `malachite` crate, replace this part of the paths with `malachite::`. # malachite-base This crate contains many utilities that are used by the [`malachite-nz`](https://crates.io/crates/malachite-nz) and [`malachite-q`](https://crates.io/crates/malachite-q) crates. These utilities include - Traits that wrap functions from the standard library, like [`CheckedAdd`](https://docs.rs/malachite-base/latest/malachite_base/num/arithmetic/traits/trait.CheckedAdd.html). - Traits that give extra functionality to primitive types, like [`Gcd`](https://docs.rs/malachite-base/latest/malachite_base/num/arithmetic/traits/trait.Gcd.html), [`FloorSqrt`](https://docs.rs/malachite-base/latest/malachite_base/num/arithmetic/traits/trait.FloorSqrt.html), and [`BitAccess`](https://docs.rs/malachite-base/latest/malachite_base/num/logic/traits/trait.BitAccess.html). - Iterator-producing functions that let you generate values for testing. Here's an example of an iterator that produces all pairs of [`u32`](https://doc.rust-lang.org/nightly/std/primitive.u32.html)s: ``` use malachite_base::num::exhaustive::exhaustive_unsigneds; use malachite_base::tuples::exhaustive::exhaustive_pairs_from_single; let mut pairs = exhaustive_pairs_from_single(exhaustive_unsigneds::()); assert_eq!( pairs.take(20).collect::>(), &[ (0, 0), (0, 1), (1, 0), (1, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 0), (2, 1), (3, 0), (3, 1), (2, 2), (2, 3), (3, 2), (3, 3), (0, 4), (0, 5), (1, 4), (1, 5) ] ); ``` - The [`RoundingMode`](https://docs.rs/malachite-base/latest/malachite_base/rounding_modes/enum.RoundingMode.html) enum, which allows you to specify the rounding behavior of various functions. - The [`NiceFloat`](https://docs.rs/malachite-base/latest/malachite_base/num/float/struct.NiceFloat.html) wrapper, which provides alternative implementations of [`Eq`](https://doc.rust-lang.org/nightly/core/cmp/trait.Eq.html), [`Ord`](https://doc.rust-lang.org/nightly/core/cmp/trait.Ord.html), and [`Display`](https://doc.rust-lang.org/nightly/core/fmt/trait.Display.html) for floating-point values which are in some ways nicer than the defaults. # Demos and benchmarks This crate comes with a `bin` target that can be used for running demos and benchmarks. - Almost all of the public functions in this crate have an associated demo. Running a demo shows you a function's behavior on a large number of inputs. For example, to demo the [`mod_pow`](https://docs.rs/malachite-base/latest/malachite_base/num/arithmetic/traits/trait.ModPow.html#tymethod.mod_pow) function on [`u32`](https://doc.rust-lang.org/nightly/std/primitive.u32.html)s, you can use the following command: ``` cargo run --features bin_build --release -- -l 10000 -m exhaustive -d demo_mod_pow_u32 ``` This command uses the `exhaustive` mode, which generates every possible input, generally starting with the simplest input and progressing to more complex ones. Another mode is `random`. The `-l` flag specifies how many inputs should be generated. - You can use a similar command to run benchmarks. The following command benchmarks various GCD algorithms for [`u64`](https://doc.rust-lang.org/nightly/std/primitive.u64.html)s: ```text cargo run --features bin_build --release -- -l 1000000 -m random -b \ benchmark_gcd_algorithms_u64 -o gcd-bench.gp ``` This creates a file called gcd-bench.gp. You can use gnuplot to create an SVG from it like so: ```text gnuplot -e "set terminal svg; l \"gcd-bench.gp\"" > gcd-bench.svg ``` The list of available demos and benchmarks is not documented anywhere; you must find them by browsing through [`bin_util/demo_and_bench`](https://github.com/mhogrefe/malachite/tree/master/malachite-base/src/bin_util/demo_and_bench). # Features - `random`: This feature provides some functions for randomly generating values. It is off by default to avoid pulling in some extra dependencies. - `test_build`: A large proportion of the code in this crate is only used for testing. For a typical user, building this code would result in an unnecessarily long compilation time and an unnecessarily large binary. Much of it is also used for testing [`malachite-nz`](https://crates.io/crates/malachite-nz) and [`malachite-q`](https://crates.io/crates/malachite-q), so it can't just be confined to the `tests` directory. My solution is to only build this code when the `test_build` feature is enabled. If you want to run unit tests, you must enable `test_build`. However, doctests don't require it, since they only test the public interface. Enabling this feature also enables `random`. - `bin_build`: This feature is used to build the code for demos and benchmarks, which also takes a long time to build. Enabling this feature also enables `test_build` and `random`. Malachite is developed by Mikhail Hogrefe. Thanks to b4D8, florian1345, konstin, Rowan Hart, YunWon Jeong, Park Joon-Kyu, Antonio Mamić, OliverNChalk, and shekohex for additional contributions. Copyright © 2024 Mikhail Hogrefe malachite-base-0.4.16/katex-header.html000064400000000000000000000020201046102023000157750ustar 00000000000000 malachite-base-0.4.16/rustfmt.toml000064400000000000000000000000421046102023000151500ustar 00000000000000max_width = 100 array_width = 100 malachite-base-0.4.16/src/bin.rs000064400000000000000000000063671046102023000144740ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . #![allow( unstable_name_collisions, clippy::assertions_on_constants, clippy::cognitive_complexity, clippy::many_single_char_names, clippy::range_plus_one, clippy::suspicious_arithmetic_impl, clippy::suspicious_op_assign_impl, clippy::too_many_arguments, clippy::type_complexity, clippy::upper_case_acronyms )] #![warn( clippy::cast_lossless, clippy::explicit_into_iter_loop, clippy::explicit_iter_loop, clippy::filter_map_next, clippy::large_digit_groups, clippy::manual_filter_map, clippy::manual_find_map, clippy::map_flatten, clippy::map_unwrap_or, clippy::match_same_arms, clippy::missing_const_for_fn, clippy::mut_mut, clippy::needless_borrow, clippy::needless_continue, clippy::needless_pass_by_value, clippy::redundant_closure_for_method_calls, clippy::single_match_else, clippy::trait_duplication_in_bounds, clippy::type_repetition_in_bounds, clippy::uninlined_format_args, clippy::unused_self )] #[cfg(feature = "bin_build")] extern crate itertools; #[cfg(feature = "bin_build")] #[macro_use] extern crate malachite_base; #[cfg(feature = "bin_build")] extern crate walkdir; #[cfg(feature = "bin_build")] use bin_util::demo_and_bench::register; #[cfg(feature = "bin_build")] use bin_util::generate::max_base::generate_max_base; #[cfg(feature = "bin_build")] use bin_util::generate::rle::generate_rle_encoding; #[cfg(feature = "bin_build")] use bin_util::generate::tuning_manager::{build_reference_data, test}; #[cfg(feature = "bin_build")] use malachite_base::test_util::runner::cmd::read_command_line_arguments; #[cfg(feature = "bin_build")] use malachite_base::test_util::runner::Runner; // Examples: // // ``` // cargo run --features bin_build -- -g max_base // cargo run --features bin_build --release -- -l 10000 -m exhaustive -d demo_mod_pow_u32 // ``` #[cfg(feature = "bin_build")] fn main() { let args = read_command_line_arguments("malachite-base"); let mut runner = Runner::new(); register(&mut runner); if let Some(demo_key) = args.demo_key { runner.run_demo(&demo_key, args.generation_mode, &args.config, args.limit); } else if let Some(bench_key) = args.bench_key { runner.run_bench( &bench_key, args.generation_mode, &args.config, args.limit, &args.out, ); } else { let codegen_key = args.codegen_key.unwrap(); match codegen_key.as_str() { "max_base" => generate_max_base(), "rle_encode" => generate_rle_encoding(), "tm_build_reference_data" => build_reference_data(), "tm_test" => test(), _ => panic!("Invalid codegen key: {codegen_key}"), } } } #[cfg(not(feature = "bin_build"))] fn main() {} #[cfg(feature = "bin_build")] pub mod bin_util { pub mod demo_and_bench; pub mod generate; } malachite-base-0.4.16/src/bin_util/demo_and_bench/bools/mod.rs000064400000000000000000000010131046102023000223120ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { not_assign::register(runner); } mod not_assign; malachite-base-0.4.16/src/bin_util/demo_and_bench/bools/not_assign.rs000064400000000000000000000016611046102023000237100ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::logic::traits::NotAssign; use malachite_base::test_util::generators::bool_gen; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_bool_not_assign); } fn demo_bool_not_assign(gm: GenMode, config: &GenConfig, limit: usize) { for mut b in bool_gen().get(gm, config).take(limit) { let b_old = b; b.not_assign(); println!("b := {b_old}; b.not_assign(); b = {b}"); } } malachite-base-0.4.16/src/bin_util/demo_and_bench/chars/crement/char_to_contiguous_range.rs000064400000000000000000000031171046102023000302330ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::chars::crement::char_to_contiguous_range; use malachite_base::test_util::bench::bucketers::char_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::char_gen; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_char_to_contiguous_range); register_bench!(runner, benchmark_char_to_contiguous_range); } fn demo_char_to_contiguous_range(gm: GenMode, config: &GenConfig, limit: usize) { for c in char_gen().get(gm, config).take(limit) { println!( "char_to_contiguous_range({:?}) = {}", c, char_to_contiguous_range(c) ); } } fn benchmark_char_to_contiguous_range( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( "char_to_contiguous_range(char)", BenchmarkType::Single, char_gen().get(gm, config), gm.name(), limit, file_name, &char_bucketer(), &mut [("Malachite", &mut |c| no_out!(char_to_contiguous_range(c)))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/chars/crement/contiguous_range_to_char.rs000064400000000000000000000031601046102023000302310ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::chars::crement::contiguous_range_to_char; use malachite_base::test_util::bench::bucketers::unsigned_direct_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_gen; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_contiguous_range_to_char); register_bench!(runner, benchmark_contiguous_range_to_char); } fn demo_contiguous_range_to_char(gm: GenMode, config: &GenConfig, limit: usize) { for u in unsigned_gen().get(gm, config).take(limit) { println!( "contiguous_range_to_char({}) = {:?}", u, contiguous_range_to_char(u) ); } } fn benchmark_contiguous_range_to_char( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( "contiguous_range_to_char(u32)", BenchmarkType::Single, unsigned_gen().get(gm, config), gm.name(), limit, file_name, &unsigned_direct_bucketer(), &mut [("Malachite", &mut |u| no_out!(contiguous_range_to_char(u)))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/chars/crement/crement.rs000064400000000000000000000044361046102023000246230ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::chars::crement::{decrement_char, increment_char}; use malachite_base::test_util::bench::bucketers::char_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{char_gen_var_1, char_gen_var_2}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_increment_char); register_demo!(runner, demo_decrement_char); register_bench!(runner, benchmark_increment_char); register_bench!(runner, benchmark_decrement_char); } fn demo_increment_char(gm: GenMode, config: &GenConfig, limit: usize) { for mut c in char_gen_var_1().get(gm, config).take(limit) { let c_old = c; increment_char(&mut c); println!("c := {c_old:?}; increment_char(&mut c); c = {c:?}"); } } fn demo_decrement_char(gm: GenMode, config: &GenConfig, limit: usize) { for mut c in char_gen_var_2().get(gm, config).take(limit) { let c_old = c; increment_char(&mut c); println!("c := {c_old:?}; decrement_char(&mut c); c = {c:?}"); } } fn benchmark_increment_char(gm: GenMode, config: &GenConfig, limit: usize, file_name: &str) { run_benchmark( "increment_char(&mut char)", BenchmarkType::Single, char_gen_var_1().get(gm, config), gm.name(), limit, file_name, &char_bucketer(), &mut [("Malachite", &mut |mut c| increment_char(&mut c))], ); } fn benchmark_decrement_char(gm: GenMode, config: &GenConfig, limit: usize, file_name: &str) { run_benchmark( "decrement_char(&mut char)", BenchmarkType::Single, char_gen_var_2().get(gm, config), gm.name(), limit, file_name, &char_bucketer(), &mut [("Malachite", &mut |mut c| decrement_char(&mut c))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/chars/crement/mod.rs000064400000000000000000000013201046102023000237320ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { char_to_contiguous_range::register(runner); contiguous_range_to_char::register(runner); crement::register(runner); } pub mod char_to_contiguous_range; pub mod contiguous_range_to_char; #[allow(clippy::module_inception)] pub mod crement; malachite-base-0.4.16/src/bin_util/demo_and_bench/chars/mod.rs000064400000000000000000000010051046102023000222750ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { crement::register(runner); } mod crement; malachite-base-0.4.16/src/bin_util/demo_and_bench/comparison/macros.rs000064400000000000000000000115201046102023000240570ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::bench::bucketers::{ pair_max_bit_bucketer, triple_max_bit_bucketer, unsigned_bit_bucketer, }; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ unsigned_gen, unsigned_pair_gen_var_27, unsigned_triple_gen_var_19, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_max_1); register_demo!(runner, demo_max_2); register_demo!(runner, demo_max_3); register_demo!(runner, demo_min_1); register_demo!(runner, demo_min_2); register_demo!(runner, demo_min_3); register_bench!(runner, benchmark_max_1); register_bench!(runner, benchmark_max_2); register_bench!(runner, benchmark_max_3); register_bench!(runner, benchmark_min_1); register_bench!(runner, benchmark_min_2); register_bench!(runner, benchmark_min_3); } fn demo_max_1(gm: GenMode, config: &GenConfig, limit: usize) { for x in unsigned_gen::().get(gm, config).take(limit) { println!("max!({}) = {}", x, max!(x)); } } fn demo_max_2(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in unsigned_pair_gen_var_27::().get(gm, config).take(limit) { println!("max!({}, {}) = {}", x, y, max!(x, y)); } } fn demo_max_3(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y, z) in unsigned_triple_gen_var_19::() .get(gm, config) .take(limit) { println!("max!({}, {}, {}) = {}", x, y, z, max!(x, y, z)); } } fn demo_min_1(gm: GenMode, config: &GenConfig, limit: usize) { for x in unsigned_gen::().get(gm, config).take(limit) { println!("min!({}) = {}", x, min!(x)); } } fn demo_min_2(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in unsigned_pair_gen_var_27::().get(gm, config).take(limit) { println!("min!({}, {}) = {}", x, y, min!(x, y)); } } fn demo_min_3(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y, z) in unsigned_triple_gen_var_19::() .get(gm, config) .take(limit) { println!("min!({}, {}, {}) = {}", x, y, z, min!(x, y, z)); } } fn benchmark_max_1(gm: GenMode, config: &GenConfig, limit: usize, file_name: &str) { run_benchmark( "max!(T)", BenchmarkType::Single, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [("Malachite", &mut |x| no_out!(max!(x)))], ); } fn benchmark_max_2(gm: GenMode, config: &GenConfig, limit: usize, file_name: &str) { run_benchmark( "max!(T, T)", BenchmarkType::Single, unsigned_pair_gen_var_27::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(max!(x, y)))], ); } fn benchmark_max_3(gm: GenMode, config: &GenConfig, limit: usize, file_name: &str) { run_benchmark( "max!(T, T, T)", BenchmarkType::Single, unsigned_triple_gen_var_19::().get(gm, config), gm.name(), limit, file_name, &triple_max_bit_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(x, y, z)| no_out!(max!(x, y, z)))], ); } fn benchmark_min_1(gm: GenMode, config: &GenConfig, limit: usize, file_name: &str) { run_benchmark( "min!(T)", BenchmarkType::Single, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [("Malachite", &mut |x| no_out!(min!(x)))], ); } fn benchmark_min_2(gm: GenMode, config: &GenConfig, limit: usize, file_name: &str) { run_benchmark( "min!(T, T)", BenchmarkType::Single, unsigned_pair_gen_var_27::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(min!(x, y)))], ); } fn benchmark_min_3(gm: GenMode, config: &GenConfig, limit: usize, file_name: &str) { run_benchmark( "min!(T, T, T)", BenchmarkType::Single, unsigned_triple_gen_var_19::().get(gm, config), gm.name(), limit, file_name, &triple_max_bit_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(x, y, z)| no_out!(min!(x, y, z)))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/comparison/mod.rs000064400000000000000000000010031046102023000233450ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { macros::register(runner); } mod macros; malachite-base-0.4.16/src/bin_util/demo_and_bench/mod.rs000064400000000000000000000054671046102023000212150ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::runner::Runner; macro_rules! unsigned_single_arg_demo { ($name: ident, $f: ident) => { fn $name(gm: GenMode, config: &GenConfig, limit: usize) { for u in unsigned_gen::().get(gm, config).take(limit) { println!(concat!("{}.", stringify!($f), "() = {}"), u, u.$f()); } } }; } macro_rules! signed_single_arg_demo { ($name: ident, $f: ident) => { fn $name(gm: GenMode, config: &GenConfig, limit: usize) { for i in signed_gen::().get(gm, config).take(limit) { println!(concat!("({}).", stringify!($f), "() = {}"), i, i.$f()); } } }; } macro_rules! unsigned_single_arg_bench { ($name: ident, $f: ident) => { fn $name( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!(concat!("{}.", stringify!($f), "()"), T::NAME), BenchmarkType::Single, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [("Malachite", &mut |u| no_out!(u.$f()))], ); } }; } macro_rules! signed_single_arg_bench { ($name: ident, $f: ident) => { fn $name( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!(concat!("{}.", stringify!($f), "()"), T::NAME), BenchmarkType::Single, signed_gen::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [("Malachite", &mut |i| no_out!(i.$f()))], ); } }; } pub(crate) fn register(runner: &mut Runner) { bools::register(runner); chars::register(runner); comparison::register(runner); num::register(runner); rational_sequences::register(runner); rounding_modes::register(runner); slices::register(runner); strings::register(runner); vecs::register(runner); } mod bools; mod chars; mod comparison; mod num; mod rational_sequences; mod rounding_modes; mod slices; mod strings; mod vecs; malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/abs.rs000064400000000000000000000053511046102023000241230ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::bench::bucketers::{primitive_float_bucketer, signed_bit_bucketer}; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{primitive_float_gen, signed_gen_var_1}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_signed_demos!(runner, demo_abs_assign_signed); register_primitive_float_demos!(runner, demo_abs_assign_primitive_float); register_signed_benches!(runner, benchmark_abs_assign_signed); register_primitive_float_benches!(runner, benchmark_abs_assign_primitive_float); } fn demo_abs_assign_signed(gm: GenMode, config: &GenConfig, limit: usize) { for mut i in signed_gen_var_1::().get(gm, config).take(limit) { let old_i = i; i.abs_assign(); println!("i := {old_i}; i.abs_assign(); i = {i}"); } } fn demo_abs_assign_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, ) { for mut f in primitive_float_gen::().get(gm, config).take(limit) { let old_f = f; f.abs_assign(); println!( "i := {}; i.abs_assign(); i = {}", NiceFloat(old_f), NiceFloat(f) ); } } fn benchmark_abs_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.abs_assign()", T::NAME), BenchmarkType::Single, signed_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [("Malachite", &mut |mut i| i.abs_assign())], ); } fn benchmark_abs_assign_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.abs_assign()", T::NAME), BenchmarkType::Single, primitive_float_gen::().get(gm, config), gm.name(), limit, file_name, &primitive_float_bucketer("f"), &mut [("Malachite", &mut |mut f| f.abs_assign())], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/abs_diff.rs000064400000000000000000000033051046102023000251100ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::pair_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_pair_gen_var_27; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_abs_diff_assign); register_unsigned_benches!(runner, benchmark_abs_diff_assign); } fn demo_abs_diff_assign(gm: GenMode, config: &GenConfig, limit: usize) { for (mut x, y) in unsigned_pair_gen_var_27::().get(gm, config).take(limit) { let old_x = x; x.abs_diff_assign(y); println!("x := {old_x}; x.abs_diff_assign({y}); x = {x}"); } } fn benchmark_abs_diff_assign( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.abs_diff_assign({})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_27::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y)| x.abs_diff_assign(y))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/add_mul.rs000064400000000000000000000156311046102023000247650ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::bench::bucketers::{ triple_max_bit_bucketer, triple_max_primitive_float_bucketer, }; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ primitive_float_triple_gen, signed_triple_gen_var_1, unsigned_triple_gen_var_1, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_add_mul_unsigned); register_signed_demos!(runner, demo_add_mul_signed); register_primitive_float_demos!(runner, demo_add_mul_primitive_float); register_unsigned_demos!(runner, demo_add_mul_assign_unsigned); register_signed_demos!(runner, demo_add_mul_assign_signed); register_primitive_float_demos!(runner, demo_add_mul_assign_primitive_float); register_unsigned_benches!(runner, benchmark_add_mul_unsigned); register_signed_benches!(runner, benchmark_add_mul_signed); register_primitive_float_benches!(runner, benchmark_add_mul_primitive_float); register_unsigned_benches!(runner, benchmark_add_mul_assign_unsigned); register_signed_benches!(runner, benchmark_add_mul_assign_signed); register_primitive_float_benches!(runner, benchmark_add_mul_assign_primitive_float); } fn demo_add_mul_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y, z) in unsigned_triple_gen_var_1::().get(gm, config).take(limit) { println!("{}.add_mul({}, {}) = {}", x, y, z, x.add_mul(y, z)); } } fn demo_add_mul_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y, z) in signed_triple_gen_var_1::().get(gm, config).take(limit) { println!("({}).add_mul({}, {}) = {}", x, y, z, x.add_mul(y, z)); } } fn demo_add_mul_primitive_float(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y, z) in primitive_float_triple_gen::() .get(gm, config) .take(limit) { println!( "({}).add_mul({}, {}) = {}", NiceFloat(x), NiceFloat(y), NiceFloat(z), NiceFloat(x.add_mul(y, z)) ); } } fn demo_add_mul_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y, z) in unsigned_triple_gen_var_1::().get(gm, config).take(limit) { let old_x = x; x.add_mul_assign(y, z); println!("x := {old_x}; x.add_mul_assign({y}, {z}); x = {x}"); } } fn demo_add_mul_assign_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (mut x, y, z) in signed_triple_gen_var_1::().get(gm, config).take(limit) { let old_x = x; x.add_mul_assign(y, z); println!("x := {old_x}; x.add_mul_assign({y}, {z}); x = {x}"); } } fn demo_add_mul_assign_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y, z) in primitive_float_triple_gen::() .get(gm, config) .take(limit) { let old_x = x; x.add_mul_assign(y, z); println!( "x := {}; x.add_mul_assign({}, {}); x = {}", NiceFloat(old_x), NiceFloat(y), NiceFloat(z), NiceFloat(x) ); } } fn benchmark_add_mul_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.add_mul({}, {})", T::NAME, T::NAME, T::NAME), BenchmarkType::Single, unsigned_triple_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &triple_max_bit_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(x, y, z)| no_out!(x.add_mul(y, z)))], ); } fn benchmark_add_mul_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.add_mul({}, {})", T::NAME, T::NAME, T::NAME), BenchmarkType::Single, signed_triple_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &triple_max_bit_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(x, y, z)| no_out!(x.add_mul(y, z)))], ); } fn benchmark_add_mul_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.add_mul({}, {})", T::NAME, T::NAME, T::NAME), BenchmarkType::Single, primitive_float_triple_gen::().get(gm, config), gm.name(), limit, file_name, &triple_max_primitive_float_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(x, y, z)| no_out!(x.add_mul(y, z)))], ); } fn benchmark_add_mul_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.add_mul_assign({}, {})", T::NAME, T::NAME, T::NAME), BenchmarkType::Single, unsigned_triple_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &triple_max_bit_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(mut x, y, z)| x.add_mul_assign(y, z))], ); } fn benchmark_add_mul_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.add_mul_assign({}, {})", T::NAME, T::NAME, T::NAME), BenchmarkType::Single, signed_triple_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &triple_max_bit_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(mut x, y, z)| x.add_mul_assign(y, z))], ); } fn benchmark_add_mul_assign_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.add_mul_assign({}, {})", T::NAME, T::NAME, T::NAME), BenchmarkType::Single, primitive_float_triple_gen::().get(gm, config), gm.name(), limit, file_name, &triple_max_primitive_float_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(mut x, y, z)| x.add_mul_assign(y, z))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/arithmetic_checked_shl.rs000064400000000000000000000142751046102023000300300ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::{ArithmeticCheckedShl, UnsignedAbs}; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::{pair_2_bucketer, pair_2_unsigned_abs_bucketer}; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ signed_pair_gen_var_2, signed_unsigned_pair_gen_var_1, unsigned_pair_gen_var_2, unsigned_signed_pair_gen_var_1, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_unsigned_demos!(runner, demo_arithmetic_checked_shl_unsigned_unsigned); register_unsigned_signed_demos!(runner, demo_arithmetic_checked_shl_unsigned_signed); register_signed_unsigned_demos!(runner, demo_arithmetic_checked_shl_signed_unsigned); register_signed_signed_demos!(runner, demo_arithmetic_checked_shl_signed_signed); register_unsigned_unsigned_benches!(runner, benchmark_arithmetic_checked_shl_unsigned_unsigned); register_unsigned_signed_benches!(runner, benchmark_arithmetic_checked_shl_unsigned_signed); register_signed_unsigned_benches!(runner, benchmark_arithmetic_checked_shl_signed_unsigned); register_signed_signed_benches!(runner, benchmark_arithmetic_checked_shl_signed_signed); } fn demo_arithmetic_checked_shl_unsigned_unsigned< T: ArithmeticCheckedShl + PrimitiveUnsigned, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (n, u) in unsigned_pair_gen_var_2::() .get(gm, config) .take(limit) { println!( "{}.arithmetic_checked_shl({}) = {:?}", n, u, n.arithmetic_checked_shl(u) ); } } fn demo_arithmetic_checked_shl_unsigned_signed< T: ArithmeticCheckedShl + PrimitiveUnsigned, U: PrimitiveSigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (n, i) in unsigned_signed_pair_gen_var_1::() .get(gm, config) .take(limit) { println!( "{}.arithmetic_checked_shl({}) = {:?}", n, i, n.arithmetic_checked_shl(i) ); } } fn demo_arithmetic_checked_shl_signed_unsigned< T: ArithmeticCheckedShl + PrimitiveSigned, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (n, u) in signed_unsigned_pair_gen_var_1::() .get(gm, config) .take(limit) { println!( "({}).arithmetic_checked_shl({}) = {:?}", n, u, n.arithmetic_checked_shl(u) ); } } fn demo_arithmetic_checked_shl_signed_signed< T: ArithmeticCheckedShl + PrimitiveSigned, U: PrimitiveSigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (n, i) in signed_pair_gen_var_2::().get(gm, config).take(limit) { println!( "({}).arithmetic_checked_shl({}) = {:?}", n, i, n.arithmetic_checked_shl(i) ); } } fn benchmark_arithmetic_checked_shl_unsigned_unsigned< T: ArithmeticCheckedShl + PrimitiveUnsigned, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where usize: TryFrom, { run_benchmark( &format!("{}.arithmetic_checked_shl({})", T::NAME, U::NAME), BenchmarkType::Single, unsigned_pair_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &pair_2_bucketer("other"), &mut [("Malachite", &mut |(x, y)| { no_out!(x.arithmetic_checked_shl(y)) })], ); } fn benchmark_arithmetic_checked_shl_unsigned_signed< T: ArithmeticCheckedShl + PrimitiveUnsigned, U: PrimitiveSigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where usize: TryFrom<::Output>, { run_benchmark( &format!("{}.arithmetic_checked_shl({})", T::NAME, U::NAME), BenchmarkType::Single, unsigned_signed_pair_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &pair_2_unsigned_abs_bucketer("other"), &mut [("Malachite", &mut |(x, y)| { no_out!(x.arithmetic_checked_shl(y)) })], ); } fn benchmark_arithmetic_checked_shl_signed_unsigned< T: ArithmeticCheckedShl + PrimitiveSigned, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where usize: TryFrom, { run_benchmark( &format!("{}.arithmetic_checked_shl({})", T::NAME, U::NAME), BenchmarkType::Single, signed_unsigned_pair_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &pair_2_bucketer("other"), &mut [("Malachite", &mut |(x, y)| { no_out!(x.arithmetic_checked_shl(y)) })], ); } fn benchmark_arithmetic_checked_shl_signed_signed< T: ArithmeticCheckedShl + PrimitiveSigned, U: PrimitiveSigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where usize: TryFrom<::Output>, { run_benchmark( &format!("{}.arithmetic_checked_shl({})", T::NAME, U::NAME), BenchmarkType::Single, signed_pair_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &pair_2_unsigned_abs_bucketer("other"), &mut [("Malachite", &mut |(x, y)| { no_out!(x.arithmetic_checked_shl(y)) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/arithmetic_checked_shr.rs000064400000000000000000000070651046102023000300350ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::{ArithmeticCheckedShr, UnsignedAbs}; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::pair_2_unsigned_abs_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ signed_pair_gen_var_2, unsigned_signed_pair_gen_var_1, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_signed_demos!(runner, demo_arithmetic_checked_shr_unsigned_signed); register_signed_signed_demos!(runner, demo_arithmetic_checked_shr_signed_signed); register_unsigned_signed_benches!(runner, benchmark_arithmetic_checked_shr_unsigned_signed); register_signed_signed_benches!(runner, benchmark_arithmetic_checked_shr_signed_signed); } fn demo_arithmetic_checked_shr_unsigned_signed< T: ArithmeticCheckedShr + PrimitiveUnsigned, U: PrimitiveSigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (n, i) in unsigned_signed_pair_gen_var_1::() .get(gm, config) .take(limit) { println!( "{}.arithmetic_checked_shr({}) = {:?}", n, i, n.arithmetic_checked_shr(i) ); } } fn demo_arithmetic_checked_shr_signed_signed< T: ArithmeticCheckedShr + PrimitiveSigned, U: PrimitiveSigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (n, i) in signed_pair_gen_var_2::().get(gm, config).take(limit) { println!( "({}).arithmetic_checked_shr({}) = {:?}", n, i, n.arithmetic_checked_shr(i) ); } } fn benchmark_arithmetic_checked_shr_unsigned_signed< T: ArithmeticCheckedShr + PrimitiveUnsigned, U: PrimitiveSigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where usize: TryFrom<::Output>, { run_benchmark( &format!("{}.arithmetic_checked_shr({})", T::NAME, U::NAME), BenchmarkType::Single, unsigned_signed_pair_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &pair_2_unsigned_abs_bucketer("other"), &mut [("Malachite", &mut |(x, y)| { no_out!(x.arithmetic_checked_shr(y)) })], ); } fn benchmark_arithmetic_checked_shr_signed_signed< T: ArithmeticCheckedShr + PrimitiveSigned, U: PrimitiveSigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where usize: TryFrom<::Output>, { run_benchmark( &format!("{}.arithmetic_checked_shr({})", T::NAME, U::NAME), BenchmarkType::Single, signed_pair_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &pair_2_unsigned_abs_bucketer("other"), &mut [("Malachite", &mut |(x, y)| { no_out!(x.arithmetic_checked_shr(y)) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/binomial_coefficient.rs000064400000000000000000000131561046102023000275100ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::UnsignedAbs; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::{ abs_usize_convertible_pair_max_bucketer, usize_convertible_pair_max_bucketer, }; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ signed_pair_gen_var_11, signed_pair_gen_var_12, unsigned_pair_gen_var_28, unsigned_pair_gen_var_44, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_binomial_coefficient_unsigned); register_signed_demos!(runner, demo_binomial_coefficient_signed); register_unsigned_demos!(runner, demo_checked_binomial_coefficient_unsigned); register_signed_demos!(runner, demo_checked_binomial_coefficient_signed); register_unsigned_benches!(runner, benchmark_binomial_coefficient_unsigned); register_signed_benches!(runner, benchmark_binomial_coefficient_signed); register_unsigned_benches!(runner, benchmark_checked_binomial_coefficient_unsigned); register_signed_benches!(runner, benchmark_checked_binomial_coefficient_signed); } fn demo_binomial_coefficient_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (n, k) in unsigned_pair_gen_var_44().get(gm, config).take(limit) { println!("C({}, {}) = {}", n, k, T::binomial_coefficient(n, k)); } } fn demo_binomial_coefficient_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for (n, k) in signed_pair_gen_var_12().get(gm, config).take(limit) { println!("C({}, {}) = {}", n, k, T::binomial_coefficient(n, k)); } } fn demo_checked_binomial_coefficient_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (n, k) in unsigned_pair_gen_var_28().get(gm, config).take(limit) { println!( "C({}, {}) = {:?}", n, k, T::checked_binomial_coefficient(n, k) ); } } fn demo_checked_binomial_coefficient_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for (n, k) in signed_pair_gen_var_11().get(gm, config).take(limit) { println!( "C({}, {}) = {:?}", n, k, T::checked_binomial_coefficient(n, k) ); } } fn benchmark_binomial_coefficient_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where usize: TryFrom, { run_benchmark( &format!( "{}::binomial_coefficient({}, {})", T::NAME, T::NAME, T::NAME ), BenchmarkType::Single, unsigned_pair_gen_var_44().get(gm, config), gm.name(), limit, file_name, &usize_convertible_pair_max_bucketer("n", "k"), &mut [("Malachite", &mut |(n, k)| { no_out!(T::binomial_coefficient(n, k)) })], ); } fn benchmark_binomial_coefficient_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where usize: TryFrom<::Output>, ::Output: Ord, { run_benchmark( &format!( "{}::binomial_coefficient({}, {})", T::NAME, T::NAME, T::NAME ), BenchmarkType::Single, signed_pair_gen_var_12().get(gm, config), gm.name(), limit, file_name, &abs_usize_convertible_pair_max_bucketer("n", "k"), &mut [("Malachite", &mut |(n, k)| { no_out!(T::binomial_coefficient(n, k)) })], ); } fn benchmark_checked_binomial_coefficient_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where usize: TryFrom, { run_benchmark( &format!( "{}::checked_binomial_coefficient({}, {})", T::NAME, T::NAME, T::NAME ), BenchmarkType::Single, unsigned_pair_gen_var_28().get(gm, config), gm.name(), limit, file_name, &usize_convertible_pair_max_bucketer("n", "k"), &mut [("Malachite", &mut |(n, k)| { no_out!(T::checked_binomial_coefficient(n, k)) })], ); } fn benchmark_checked_binomial_coefficient_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where usize: TryFrom<::Output>, ::Output: Ord, { run_benchmark( &format!( "{}::checked_binomial_coefficient({}, {})", T::NAME, T::NAME, T::NAME ), BenchmarkType::Single, signed_pair_gen_var_11().get(gm, config), gm.name(), limit, file_name, &abs_usize_convertible_pair_max_bucketer("n", "k"), &mut [("Malachite", &mut |(n, k)| { no_out!(T::checked_binomial_coefficient(n, k)) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/ceiling.rs000064400000000000000000000034121046102023000247640ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::bench::bucketers::primitive_float_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::primitive_float_gen; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_primitive_float_demos!(runner, demo_ceiling_assign); register_primitive_float_benches!(runner, benchmark_ceiling_assign); } fn demo_ceiling_assign(gm: GenMode, config: &GenConfig, limit: usize) { for mut f in primitive_float_gen::().get(gm, config).take(limit) { let old_f = f; f.ceiling_assign(); println!( "i := {}; i.ceiling_assign(); i = {}", NiceFloat(old_f), NiceFloat(f) ); } } fn benchmark_ceiling_assign( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.ceiling_assign()", T::NAME), BenchmarkType::Single, primitive_float_gen::().get(gm, config), gm.name(), limit, file_name, &primitive_float_bucketer("f"), &mut [("Malachite", &mut |mut f| f.ceiling_assign())], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/checked_add_mul.rs000064400000000000000000000056731046102023000264400ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::triple_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_triple_gen, unsigned_triple_gen_var_19}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_checked_add_mul_unsigned); register_signed_demos!(runner, demo_checked_add_mul_signed); register_unsigned_benches!(runner, benchmark_checked_add_mul_unsigned); register_signed_benches!(runner, benchmark_checked_add_mul_signed); } fn demo_checked_add_mul_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, y, z) in unsigned_triple_gen_var_19::() .get(gm, config) .take(limit) { println!( "{}.checked_add_mul({}, {}) = {:?}", x, y, z, x.checked_add_mul(y, z) ); } } fn demo_checked_add_mul_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y, z) in signed_triple_gen::().get(gm, config).take(limit) { println!( "({}).checked_add_mul({}, {}) = {:?}", x, y, z, x.checked_add_mul(y, z) ); } } fn benchmark_checked_add_mul_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.checked_add_mul({}, {})", T::NAME, T::NAME, T::NAME), BenchmarkType::Single, unsigned_triple_gen_var_19::().get(gm, config), gm.name(), limit, file_name, &triple_max_bit_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(x, y, z)| { no_out!(x.checked_add_mul(y, z)) })], ); } fn benchmark_checked_add_mul_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.checked_add_mul({}, {})", T::NAME, T::NAME, T::NAME), BenchmarkType::Single, signed_triple_gen::().get(gm, config), gm.name(), limit, file_name, &triple_max_bit_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(x, y, z)| { no_out!(x.checked_add_mul(y, z)) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/checked_square.rs000064400000000000000000000050261046102023000263230ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::{signed_bit_bucketer, unsigned_bit_bucketer}; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_gen, unsigned_gen}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_checked_square_unsigned); register_signed_demos!(runner, demo_checked_square_signed); register_unsigned_benches!(runner, benchmark_checked_square_unsigned); register_signed_benches!(runner, benchmark_checked_square_signed); } fn demo_checked_square_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for x in unsigned_gen::().get(gm, config).take(limit) { println!("{}.checked_square() = {:?}", x, x.checked_square()); } } fn demo_checked_square_signed(gm: GenMode, config: &GenConfig, limit: usize) { for x in signed_gen::().get(gm, config).take(limit) { println!("({}).checked_square() = {:?}", x, x.checked_square()); } } fn benchmark_checked_square_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.checked_square()", T::NAME), BenchmarkType::Single, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [("Malachite", &mut |x| no_out!(x.checked_square()))], ); } fn benchmark_checked_square_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.checked_square()", T::NAME), BenchmarkType::Single, signed_gen::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [("Malachite", &mut |x| no_out!(x.checked_square()))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/checked_sub_mul.rs000064400000000000000000000056731046102023000265010ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::triple_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_triple_gen, unsigned_triple_gen_var_19}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_checked_sub_mul_unsigned); register_signed_demos!(runner, demo_checked_sub_mul_signed); register_unsigned_benches!(runner, benchmark_checked_sub_mul_unsigned); register_signed_benches!(runner, benchmark_checked_sub_mul_signed); } fn demo_checked_sub_mul_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, y, z) in unsigned_triple_gen_var_19::() .get(gm, config) .take(limit) { println!( "{}.checked_sub_mul({}, {}) = {:?}", x, y, z, x.checked_sub_mul(y, z) ); } } fn demo_checked_sub_mul_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y, z) in signed_triple_gen::().get(gm, config).take(limit) { println!( "({}).checked_sub_mul({}, {}) = {:?}", x, y, z, x.checked_sub_mul(y, z) ); } } fn benchmark_checked_sub_mul_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.checked_sub_mul({}, {})", T::NAME, T::NAME, T::NAME), BenchmarkType::Single, unsigned_triple_gen_var_19::().get(gm, config), gm.name(), limit, file_name, &triple_max_bit_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(x, y, z)| { no_out!(x.checked_sub_mul(y, z)) })], ); } fn benchmark_checked_sub_mul_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.checked_sub_mul({}, {})", T::NAME, T::NAME, T::NAME), BenchmarkType::Single, signed_triple_gen::().get(gm, config), gm.name(), limit, file_name, &triple_max_bit_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(x, y, z)| { no_out!(x.checked_sub_mul(y, z)) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/coprime_with.rs000064400000000000000000000047041046102023000260500ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::coprime_with::{ coprime_with_check_2, coprime_with_check_2_3, coprime_with_check_2_3_5, }; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::pair_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_pair_gen_var_27; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_coprime_with); register_unsigned_benches!(runner, benchmark_coprime_with_algorithms); } fn demo_coprime_with(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in unsigned_pair_gen_var_27::().get(gm, config).take(limit) { if x.coprime_with(y) { println!("{x} is coprime with {y}"); } else { println!("{x} is not coprime with {y}"); } } } #[allow(clippy::unnecessary_operation, unused_must_use)] fn benchmark_coprime_with_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.coprime_with({})", T::NAME, T::NAME), BenchmarkType::Algorithms, unsigned_pair_gen_var_27::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [ ("default", &mut |(x, y)| no_out!(x.coprime_with(y))), ("no divisibility check", &mut |(x, y)| { no_out!(x.gcd(y) == T::ONE) }), ("check divisibility by 2", &mut |(x, y)| { no_out!(coprime_with_check_2(x, y)) }), ("check divisibility by 2 and 3", &mut |(x, y)| { no_out!(coprime_with_check_2_3(x, y)) }), ("check divisibility by 2, 3, and 5", &mut |(x, y)| { no_out!(coprime_with_check_2_3_5(x, y)) }), ], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/div_exact.rs000064400000000000000000000106431046102023000253240ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::pair_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_pair_gen_var_3, unsigned_pair_gen_var_11}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_div_exact_unsigned); register_signed_demos!(runner, demo_div_exact_signed); register_unsigned_demos!(runner, demo_div_exact_assign_unsigned); register_signed_demos!(runner, demo_div_exact_assign_signed); register_unsigned_benches!(runner, benchmark_div_exact_unsigned); register_signed_benches!(runner, benchmark_div_exact_signed); register_unsigned_benches!(runner, benchmark_div_exact_assign_unsigned); register_signed_benches!(runner, benchmark_div_exact_assign_signed); } fn demo_div_exact_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in unsigned_pair_gen_var_11::().get(gm, config).take(limit) { println!("{}.div_exact({}) = {}", x, y, x.div_exact(y)); } } fn demo_div_exact_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in signed_pair_gen_var_3::().get(gm, config).take(limit) { println!("({}).div_exact({}) = {}", x, y, x.div_exact(y)); } } fn demo_div_exact_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y) in unsigned_pair_gen_var_11::().get(gm, config).take(limit) { let old_x = x; x.div_exact_assign(y); println!("x := {old_x}; x.div_exact_assign({y}); x = {x}"); } } fn demo_div_exact_assign_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (mut x, y) in signed_pair_gen_var_3::().get(gm, config).take(limit) { let old_x = x; x.div_exact_assign(y); println!("x := {old_x}; x.div_exact_assign({y}); x = {x}"); } } fn benchmark_div_exact_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.div_exact({})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_11::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.div_exact(y)))], ); } fn benchmark_div_exact_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.div_exact({})", T::NAME, T::NAME), BenchmarkType::Single, signed_pair_gen_var_3::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.div_exact(y)))], ); } fn benchmark_div_exact_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.div_exact_assign({})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_11::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y)| x.div_exact_assign(y))], ); } fn benchmark_div_exact_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.div_exact_assign({})", T::NAME, T::NAME), BenchmarkType::Single, signed_pair_gen_var_3::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y)| x.div_exact_assign(y))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/div_mod.rs000064400000000000000000000323171046102023000250010ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::rounding_modes::RoundingMode::*; use malachite_base::test_util::bench::bucketers::pair_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_pair_gen_var_4, unsigned_pair_gen_var_12}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_div_mod_unsigned); register_signed_demos!(runner, demo_div_mod_signed); register_unsigned_demos!(runner, demo_div_assign_mod_unsigned); register_signed_demos!(runner, demo_div_assign_mod_signed); register_unsigned_demos!(runner, demo_div_rem_unsigned); register_signed_demos!(runner, demo_div_rem_signed); register_unsigned_demos!(runner, demo_div_assign_rem_unsigned); register_signed_demos!(runner, demo_div_assign_rem_signed); register_unsigned_demos!(runner, demo_ceiling_div_neg_mod); register_unsigned_demos!(runner, demo_ceiling_div_assign_neg_mod); register_signed_demos!(runner, demo_ceiling_div_mod); register_signed_demos!(runner, demo_ceiling_div_assign_mod); register_unsigned_benches!(runner, benchmark_div_mod_unsigned_algorithms); register_signed_benches!(runner, benchmark_div_mod_signed_algorithms); register_unsigned_benches!(runner, benchmark_div_assign_mod_unsigned); register_signed_benches!(runner, benchmark_div_assign_mod_signed); register_unsigned_benches!(runner, benchmark_div_rem_unsigned_algorithms); register_signed_benches!(runner, benchmark_div_rem_signed_algorithms); register_unsigned_benches!(runner, benchmark_div_assign_rem_unsigned); register_signed_benches!(runner, benchmark_div_assign_rem_signed); register_unsigned_benches!(runner, benchmark_ceiling_div_neg_mod_algorithms); register_unsigned_benches!(runner, benchmark_ceiling_div_assign_neg_mod); register_signed_benches!(runner, benchmark_ceiling_div_mod_algorithms); register_signed_benches!(runner, benchmark_ceiling_div_assign_mod); } fn demo_div_mod_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in unsigned_pair_gen_var_12::() .get(gm, config) .take(limit) { println!("{}.div_mod({}) = {:?}", x, y, x.div_mod(y)); } } fn demo_div_mod_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in signed_pair_gen_var_4::().get(gm, config).take(limit) { println!("({}).div_mod({}) = {:?}", x, y, x.div_mod(y)); } } fn demo_div_assign_mod_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y) in unsigned_pair_gen_var_12::() .get(gm, config) .take(limit) { let old_x = x; let r = x.div_assign_mod(y); println!("x := {old_x}; x.div_assign_mod({y}) = {r}; x = {x}"); } } fn demo_div_assign_mod_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (mut x, y) in signed_pair_gen_var_4::().get(gm, config).take(limit) { let old_x = x; let r = x.div_assign_mod(y); println!("x := {old_x}; x.div_assign_mod({y}) = {r}; x = {x}"); } } fn demo_div_rem_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in unsigned_pair_gen_var_12::() .get(gm, config) .take(limit) { println!("{}.div_rem({}) = {:?}", x, y, x.div_rem(y)); } } fn demo_div_rem_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in signed_pair_gen_var_4::().get(gm, config).take(limit) { println!("({}).div_rem({}) = {:?}", x, y, x.div_rem(y)); } } fn demo_div_assign_rem_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y) in unsigned_pair_gen_var_12::() .get(gm, config) .take(limit) { let old_x = x; let r = x.div_assign_rem(y); println!("x := {old_x}; x.div_assign_rem({y}) = {r}; x = {x}"); } } fn demo_div_assign_rem_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (mut x, y) in signed_pair_gen_var_4::().get(gm, config).take(limit) { let old_x = x; let r = x.div_assign_rem(y); println!("x := {old_x}; x.div_assign_rem({y}) = {r}; x = {x}"); } } fn demo_ceiling_div_neg_mod(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in unsigned_pair_gen_var_12::() .get(gm, config) .take(limit) { println!( "{}.ceiling_div_neg_mod({}) = {:?}", x, y, x.ceiling_div_neg_mod(y) ); } } fn demo_ceiling_div_assign_neg_mod( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y) in unsigned_pair_gen_var_12::() .get(gm, config) .take(limit) { let old_x = x; let r = x.ceiling_div_assign_neg_mod(y); println!("x := {old_x}; x.ceiling_div_assign_neg_mod({y}) = {r}; x = {x}"); } } fn demo_ceiling_div_mod(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in signed_pair_gen_var_4::().get(gm, config).take(limit) { println!( "({}).ceiling_div_mod({}) = {:?}", x, y, x.ceiling_div_mod(y) ); } } fn demo_ceiling_div_assign_mod(gm: GenMode, config: &GenConfig, limit: usize) { for (mut x, y) in signed_pair_gen_var_4::().get(gm, config).take(limit) { let old_x = x; let r = x.ceiling_div_assign_mod(y); println!("x := {old_x}; x.ceiling_div_assign_mod({y}) = {r}; x = {x}"); } } #[allow(clippy::no_effect)] fn benchmark_div_mod_unsigned_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.div_mod({})", T::NAME, T::NAME), BenchmarkType::Algorithms, unsigned_pair_gen_var_12::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [ ("using div_mod", &mut |(x, y)| no_out!(x.div_mod(y))), ("using / and %", &mut |(x, y)| no_out!((x / y, x % y))), ], ); } #[allow(clippy::unnecessary_operation)] fn benchmark_div_mod_signed_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.div_mod({})", T::NAME, T::NAME), BenchmarkType::Algorithms, signed_pair_gen_var_4::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [ ("using div_mod", &mut |(x, y)| no_out!(x.div_mod(y))), ("using div_round and mod_op", &mut |(x, y)| { no_out!((x.div_round(y, Floor), x.mod_op(y))) }), ], ); } fn benchmark_div_assign_mod_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.div_assign_mod({})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_12::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y)| no_out!(x.div_assign_mod(y)))], ); } fn benchmark_div_assign_mod_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.div_assign_mod({})", T::NAME, T::NAME), BenchmarkType::Single, signed_pair_gen_var_4::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y)| no_out!(x.div_assign_mod(y)))], ); } #[allow(clippy::no_effect)] fn benchmark_div_rem_unsigned_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.div_rem({})", T::NAME, T::NAME), BenchmarkType::Algorithms, unsigned_pair_gen_var_12::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [ ("using div_rem", &mut |(x, y)| no_out!(x.div_rem(y))), ("using / and %", &mut |(x, y)| no_out!((x / y, x % y))), ], ); } #[allow(clippy::no_effect)] fn benchmark_div_rem_signed_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.div_rem({})", T::NAME, T::NAME), BenchmarkType::Algorithms, signed_pair_gen_var_4::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [ ("using div_rem", &mut |(x, y)| no_out!(x.div_rem(y))), ("using / and %", &mut |(x, y)| no_out!((x / y, x % y))), ], ); } fn benchmark_div_assign_rem_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.div_assign_rem({})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_12::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y)| no_out!(x.div_assign_rem(y)))], ); } fn benchmark_div_assign_rem_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.div_assign_rem({})", T::NAME, T::NAME), BenchmarkType::Single, signed_pair_gen_var_4::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y)| no_out!(x.div_assign_rem(y)))], ); } #[allow(clippy::unnecessary_operation)] fn benchmark_ceiling_div_neg_mod_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.ceiling_div_neg_mod({})", T::NAME, T::NAME), BenchmarkType::Algorithms, unsigned_pair_gen_var_12::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [ ("using ceiling_div_neg_mod", &mut |(x, y)| { no_out!(x.ceiling_div_neg_mod(y)) }), ("using div_round and neg_mod", &mut |(x, y)| { no_out!((x.div_round(y, Ceiling), x.neg_mod(y))) }), ], ); } #[allow(clippy::unnecessary_operation)] fn benchmark_ceiling_div_mod_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.ceiling_div_mod({})", T::NAME, T::NAME), BenchmarkType::Algorithms, signed_pair_gen_var_4::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [ ("using ceiling_div_mod", &mut |(x, y)| { no_out!(x.ceiling_div_mod(y)) }), ("using div_round and ceiling_mod", &mut |(x, y)| { no_out!((x.div_round(y, Ceiling), x.ceiling_mod(y))) }), ], ); } fn benchmark_ceiling_div_assign_neg_mod( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.ceiling_div_assign_neg_mod({})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_12::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y)| { no_out!(x.ceiling_div_assign_neg_mod(y)) })], ); } fn benchmark_ceiling_div_assign_mod( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.ceiling_div_assign_mod({})", T::NAME, T::NAME), BenchmarkType::Single, signed_pair_gen_var_4::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y)| { no_out!(x.ceiling_div_assign_mod(y)) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/div_round.rs000064400000000000000000000121131046102023000253410ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::triple_1_2_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ signed_signed_rounding_mode_triple_gen_var_1, unsigned_unsigned_rounding_mode_triple_gen_var_1, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_div_round_unsigned); register_signed_demos!(runner, demo_div_round_signed); register_unsigned_demos!(runner, demo_div_round_assign_unsigned); register_signed_demos!(runner, demo_div_round_assign_signed); register_unsigned_benches!(runner, benchmark_div_round_unsigned); register_signed_benches!(runner, benchmark_div_round_signed); register_unsigned_benches!(runner, benchmark_div_round_assign_unsigned); register_signed_benches!(runner, benchmark_div_round_assign_signed); } fn demo_div_round_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y, rm) in unsigned_unsigned_rounding_mode_triple_gen_var_1::() .get(gm, config) .take(limit) { println!("{}.div_round({}, {}) = {:?}", x, y, rm, x.div_round(y, rm)); } } fn demo_div_round_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y, rm) in signed_signed_rounding_mode_triple_gen_var_1::() .get(gm, config) .take(limit) { println!( "({}).div_round({}, {}) = {:?}", x, y, rm, x.div_round(y, rm) ); } } fn demo_div_round_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y, rm) in unsigned_unsigned_rounding_mode_triple_gen_var_1::() .get(gm, config) .take(limit) { let old_x = x; let o = x.div_round_assign(y, rm); println!("x := {old_x}; x.div_round_assign({y}, {rm}) = {o:?}; x = {x}"); } } fn demo_div_round_assign_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (mut x, y, rm) in signed_signed_rounding_mode_triple_gen_var_1::() .get(gm, config) .take(limit) { let old_x = x; let o = x.div_round_assign(y, rm); println!("x := {old_x}; x.div_round_assign({y}, {rm}) = {o:?}; x = {x}"); } } fn benchmark_div_round_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.div_round({}, RoundingMode)", T::NAME, T::NAME), BenchmarkType::Single, unsigned_unsigned_rounding_mode_triple_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &triple_1_2_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y, rm)| no_out!(x.div_round(y, rm)))], ); } fn benchmark_div_round_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.div_round({}, RoundingMode)", T::NAME, T::NAME), BenchmarkType::Single, signed_signed_rounding_mode_triple_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &triple_1_2_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y, rm)| no_out!(x.div_round(y, rm)))], ); } fn benchmark_div_round_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.div_round_assign({}, RoundingMode)", T::NAME, T::NAME), BenchmarkType::Single, unsigned_unsigned_rounding_mode_triple_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &triple_1_2_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y, rm)| { no_out!(x.div_round_assign(y, rm)) })], ); } fn benchmark_div_round_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.div_round_assign({}, RoundingMode)", T::NAME, T::NAME), BenchmarkType::Single, signed_signed_rounding_mode_triple_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &triple_1_2_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y, rm)| { no_out!(x.div_round_assign(y, rm)) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/divisible_by.rs000064400000000000000000000053721046102023000260250ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::pair_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_pair_gen, unsigned_pair_gen_var_27}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_divisible_by_unsigned); register_signed_demos!(runner, demo_divisible_by_signed); register_unsigned_benches!(runner, benchmark_divisible_by_unsigned); register_signed_benches!(runner, benchmark_divisible_by_signed); } fn demo_divisible_by_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in unsigned_pair_gen_var_27::().get(gm, config).take(limit) { if x.divisible_by(y) { println!("{x} is divisible by {y}"); } else { println!("{x} is not divisible by {y}"); } } } fn demo_divisible_by_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in signed_pair_gen::().get(gm, config).take(limit) { if x.divisible_by(y) { println!("{x} is divisible by {y}"); } else { println!("{x} is not divisible by {y}"); } } } fn benchmark_divisible_by_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.divisible_by({})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_27::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.divisible_by(y)))], ); } fn benchmark_divisible_by_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.divisible_by({})", T::NAME, T::NAME), BenchmarkType::Single, signed_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.divisible_by(y)))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/divisible_by_power_of_2.rs000064400000000000000000000061131046102023000301400ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::pair_1_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ signed_unsigned_pair_gen_var_1, unsigned_pair_gen_var_2, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_divisible_by_power_of_2_unsigned); register_signed_demos!(runner, demo_divisible_by_power_of_2_signed); register_unsigned_benches!(runner, benchmark_divisible_by_power_of_2_unsigned); register_signed_benches!(runner, benchmark_divisible_by_power_of_2_signed); } fn demo_divisible_by_power_of_2_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (u, pow) in unsigned_pair_gen_var_2::() .get(gm, config) .take(limit) { if u.divisible_by_power_of_2(pow) { println!("{u} is divisible by 2^{pow}"); } else { println!("{u} is not divisible by 2^{pow}"); } } } fn demo_divisible_by_power_of_2_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for (i, pow) in signed_unsigned_pair_gen_var_1::() .get(gm, config) .take(limit) { if i.divisible_by_power_of_2(pow) { println!("{i} is divisible by 2^{pow}"); } else { println!("{i} is not divisible by 2^{pow}"); } } } fn benchmark_divisible_by_power_of_2_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.divisible_by_power_of_2(u64)", T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("u"), &mut [("Malachite", &mut |(x, y)| { no_out!(x.divisible_by_power_of_2(y)) })], ); } fn benchmark_divisible_by_power_of_2_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.divisible_by_power_of_2(u64)", T::NAME), BenchmarkType::Single, signed_unsigned_pair_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("i"), &mut [("Malachite", &mut |(x, y)| { no_out!(x.divisible_by_power_of_2(y)) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/eq_mod.rs000064400000000000000000000054321046102023000246220ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::triple_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_triple_gen, unsigned_triple_gen_var_19}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_eq_mod_unsigned); register_signed_demos!(runner, demo_eq_mod_signed); register_unsigned_benches!(runner, benchmark_eq_mod_unsigned); register_signed_benches!(runner, benchmark_eq_mod_signed); } fn demo_eq_mod_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y, z) in unsigned_triple_gen_var_19::() .get(gm, config) .take(limit) { if x.eq_mod(y, z) { println!("{x} is equal to {y} mod {z}"); } else { println!("{x} is not equal to {y} mod {z}"); } } } fn demo_eq_mod_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y, z) in signed_triple_gen::().get(gm, config).take(limit) { if x.eq_mod(y, z) { println!("{x} is equal to {y} mod {z}"); } else { println!("{x} is not equal to {y} mod {z}"); } } } fn benchmark_eq_mod_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.eq_mod({}, {})", T::NAME, T::NAME, T::NAME), BenchmarkType::Single, unsigned_triple_gen_var_19::().get(gm, config), gm.name(), limit, file_name, &triple_max_bit_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(x, y, z)| no_out!(x.eq_mod(y, z)))], ); } fn benchmark_eq_mod_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.eq_mod({}, {})", T::NAME, T::NAME, T::NAME), BenchmarkType::Single, signed_triple_gen::().get(gm, config), gm.name(), limit, file_name, &triple_max_bit_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(x, y, z)| no_out!(x.eq_mod(y, z)))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/eq_mod_power_of_2.rs000064400000000000000000000062041046102023000267410ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::triple_1_2_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ signed_signed_unsigned_triple_gen_var_2, unsigned_triple_gen_var_4, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_eq_mod_power_of_2_unsigned); register_signed_demos!(runner, demo_eq_mod_power_of_2_signed); register_unsigned_benches!(runner, benchmark_eq_mod_power_of_2_unsigned); register_signed_benches!(runner, benchmark_eq_mod_power_of_2_signed); } fn demo_eq_mod_power_of_2_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, y, pow) in unsigned_triple_gen_var_4::() .get(gm, config) .take(limit) { if x.eq_mod_power_of_2(y, pow) { println!("{x} is equal to {y} mod 2^{pow}"); } else { println!("{x} is not equal to {y} mod 2^{pow}"); } } } fn demo_eq_mod_power_of_2_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, y, pow) in signed_signed_unsigned_triple_gen_var_2::() .get(gm, config) .take(limit) { if x.eq_mod_power_of_2(y, pow) { println!("{x} is equal to {y} mod 2^{pow}"); } else { println!("{x} is not equal to {y} mod 2^{pow}"); } } } fn benchmark_eq_mod_power_of_2_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.eq_mod_power_of_2({}, u64)", T::NAME, T::NAME), BenchmarkType::Single, unsigned_triple_gen_var_4::().get(gm, config), gm.name(), limit, file_name, &triple_1_2_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y, pow)| { no_out!(x.eq_mod_power_of_2(y, pow)) })], ); } fn benchmark_eq_mod_power_of_2_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.eq_mod_power_of_2({}, u64)", T::NAME, T::NAME), BenchmarkType::Single, signed_signed_unsigned_triple_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &triple_1_2_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y, pow)| { no_out!(x.eq_mod_power_of_2(y, pow)) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/extended_gcd.rs000064400000000000000000000066141046102023000257760ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::extended_gcd::extended_gcd_unsigned_binary; use malachite_base::num::arithmetic::traits::ExtendedGcd; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::WrappingFrom; use malachite_base::test_util::bench::bucketers::pair_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_pair_gen, unsigned_pair_gen_var_27}; use malachite_base::test_util::num::arithmetic::extended_gcd::extended_gcd_unsigned_euclidean; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_signed_match_demos!(runner, demo_extended_gcd_unsigned); register_unsigned_signed_match_demos!(runner, demo_extended_gcd_signed); register_unsigned_signed_match_benches!(runner, benchmark_extended_gcd_algorithms_unsigned); register_signed_benches!(runner, benchmark_extended_gcd_signed); } fn demo_extended_gcd_unsigned< U: ExtendedGcd + PrimitiveUnsigned, S: PrimitiveSigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, y) in unsigned_pair_gen_var_27::().get(gm, config).take(limit) { println!("{}.extended_gcd({}) = {:?}", x, y, x.extended_gcd(y)); } } fn demo_extended_gcd_signed + PrimitiveSigned>( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, y) in signed_pair_gen::().get(gm, config).take(limit) { println!("{}.extended_gcd({}) = {:?}", x, y, x.extended_gcd(y)); } } fn benchmark_extended_gcd_algorithms_unsigned< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.extended_gcd({})", U::NAME, U::NAME), BenchmarkType::Algorithms, unsigned_pair_gen_var_27::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [ ("default", &mut |(x, y)| no_out!(x.extended_gcd(y))), ("Euclidean", &mut |(x, y)| { no_out!(extended_gcd_unsigned_euclidean::(x, y)) }), ("binary", &mut |(x, y)| { no_out!(extended_gcd_unsigned_binary::(x, y)) }), ], ); } fn benchmark_extended_gcd_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.extended_gcd({})", T::NAME, T::NAME), BenchmarkType::Single, signed_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("default", &mut |(x, y)| no_out!(x.extended_gcd(y)))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/factorial.rs000064400000000000000000000216501046102023000253220ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::factorial::checked_multifactorial_naive; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::{ unsigned_direct_bucketer, usize_convertible_pair_max_bucketer, }; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ unsigned_gen, unsigned_gen_var_23, unsigned_gen_var_24, unsigned_gen_var_25, unsigned_pair_gen_var_12, unsigned_pair_gen_var_43, }; use malachite_base::test_util::num::arithmetic::factorial::{ checked_double_factorial_naive, checked_factorial_naive, checked_subfactorial_naive, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_factorial); register_unsigned_demos!(runner, demo_checked_factorial); register_unsigned_demos!(runner, demo_double_factorial); register_unsigned_demos!(runner, demo_checked_double_factorial); register_unsigned_demos!(runner, demo_multifactorial); register_unsigned_demos!(runner, demo_checked_multifactorial); register_unsigned_demos!(runner, demo_subfactorial); register_unsigned_demos!(runner, demo_checked_subfactorial); register_unsigned_benches!(runner, benchmark_factorial_algorithms); register_unsigned_benches!(runner, benchmark_checked_factorial); register_unsigned_benches!(runner, benchmark_double_factorial_algorithms); register_unsigned_benches!(runner, benchmark_checked_double_factorial); register_unsigned_benches!(runner, benchmark_multifactorial_algorithms); register_unsigned_benches!(runner, benchmark_checked_multifactorial); register_unsigned_benches!(runner, benchmark_subfactorial_algorithms); register_unsigned_benches!(runner, benchmark_checked_subfactorial); } fn demo_factorial(gm: GenMode, config: &GenConfig, limit: usize) { for n in unsigned_gen_var_23::().get(gm, config).take(limit) { println!("{}! = {}", n, T::factorial(n)); } } fn demo_checked_factorial(gm: GenMode, config: &GenConfig, limit: usize) { for n in unsigned_gen().get(gm, config).take(limit) { println!("{}! = {:?}", n, T::checked_factorial(n)); } } fn demo_double_factorial(gm: GenMode, config: &GenConfig, limit: usize) { for n in unsigned_gen_var_24::().get(gm, config).take(limit) { println!("{}!! = {}", n, T::double_factorial(n)); } } fn demo_checked_double_factorial( gm: GenMode, config: &GenConfig, limit: usize, ) { for n in unsigned_gen().get(gm, config).take(limit) { println!("{}!! = {:?}", n, T::checked_double_factorial(n)); } } fn demo_multifactorial(gm: GenMode, config: &GenConfig, limit: usize) { for (n, m) in unsigned_pair_gen_var_43::().get(gm, config).take(limit) { if m <= 5 { print!("{n}"); for _ in 0..m { print!("!"); } println!(" = {}", T::multifactorial(n, m)); } else { println!("{}[!^{}] = {}", n, m, T::multifactorial(n, m)); } } } fn demo_checked_multifactorial( gm: GenMode, config: &GenConfig, limit: usize, ) { for (n, m) in unsigned_pair_gen_var_12::() .get(gm, config) .take(limit) { if m <= 5 { print!("{n}"); for _ in 0..m { print!("!"); } println!(" = {:?}", T::checked_multifactorial(n, m)); } else { println!("{}[!^{}] = {:?}", n, m, T::checked_multifactorial(n, m)); } } } fn demo_subfactorial(gm: GenMode, config: &GenConfig, limit: usize) { for n in unsigned_gen_var_25::().get(gm, config).take(limit) { println!("!{} = {}", n, T::subfactorial(n)); } } fn demo_checked_subfactorial(gm: GenMode, config: &GenConfig, limit: usize) { for n in unsigned_gen().get(gm, config).take(limit) { println!("!{} = {:?}", n, T::checked_subfactorial(n)); } } fn benchmark_factorial_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}::factorial(u64)", T::NAME), BenchmarkType::Algorithms, unsigned_gen_var_23::().get(gm, config), gm.name(), limit, file_name, &unsigned_direct_bucketer(), &mut [ ("default", &mut |n| no_out!(T::factorial(n))), ("naive", &mut |n| { no_out!(checked_factorial_naive::(n).unwrap()) }), ], ); } fn benchmark_checked_factorial( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}::checked_factorial(u64)", T::NAME), BenchmarkType::Single, unsigned_gen().get(gm, config), gm.name(), limit, file_name, &unsigned_direct_bucketer(), &mut [("Malachite", &mut |n| no_out!(T::checked_factorial(n)))], ); } fn benchmark_double_factorial_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}::double_factorial(u64)", T::NAME), BenchmarkType::Algorithms, unsigned_gen_var_24::().get(gm, config), gm.name(), limit, file_name, &unsigned_direct_bucketer(), &mut [ ("default", &mut |n| no_out!(T::double_factorial(n))), ("naive", &mut |n| { no_out!(checked_double_factorial_naive::(n).unwrap()) }), ], ); } fn benchmark_checked_double_factorial( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}::checked_double_factorial(u64)", T::NAME), BenchmarkType::Single, unsigned_gen().get(gm, config), gm.name(), limit, file_name, &unsigned_direct_bucketer(), &mut [("Malachite", &mut |n| { no_out!(T::checked_double_factorial(n)) })], ); } fn benchmark_multifactorial_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}::multifactorial(u64, u64)", T::NAME), BenchmarkType::Algorithms, unsigned_pair_gen_var_43::().get(gm, config), gm.name(), limit, file_name, &usize_convertible_pair_max_bucketer("n", "m"), &mut [ ("default", &mut |(n, m)| no_out!(T::multifactorial(n, m))), ("naive", &mut |(n, m)| { no_out!(checked_multifactorial_naive::(n, m).unwrap()) }), ], ); } fn benchmark_checked_multifactorial( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}::checked_multifactorial(u64, u64)", T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_12().get(gm, config), gm.name(), limit, file_name, &usize_convertible_pair_max_bucketer("n", "m"), &mut [("Malachite", &mut |(n, m)| { no_out!(T::checked_multifactorial(n, m)) })], ); } fn benchmark_subfactorial_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}::subfactorial(u64)", T::NAME), BenchmarkType::Algorithms, unsigned_gen_var_25::().get(gm, config), gm.name(), limit, file_name, &unsigned_direct_bucketer(), &mut [ ("default", &mut |n| no_out!(T::subfactorial(n))), ("naive", &mut |n| { no_out!(checked_subfactorial_naive::(n).unwrap()) }), ], ); } fn benchmark_checked_subfactorial( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}::checked_subfactorial(u64)", T::NAME), BenchmarkType::Single, unsigned_gen().get(gm, config), gm.name(), limit, file_name, &unsigned_direct_bucketer(), &mut [("Malachite", &mut |n| no_out!(T::checked_subfactorial(n)))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/floor.rs000064400000000000000000000033721046102023000245000ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::bench::bucketers::primitive_float_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::primitive_float_gen; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_primitive_float_demos!(runner, demo_floor_assign); register_primitive_float_benches!(runner, benchmark_floor_assign); } fn demo_floor_assign(gm: GenMode, config: &GenConfig, limit: usize) { for mut f in primitive_float_gen::().get(gm, config).take(limit) { let old_f = f; f.floor_assign(); println!( "i := {}; i.floor_assign(); i = {}", NiceFloat(old_f), NiceFloat(f) ); } } fn benchmark_floor_assign( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.floor_assign()", T::NAME), BenchmarkType::Single, primitive_float_gen::().get(gm, config), gm.name(), limit, file_name, &primitive_float_bucketer("f"), &mut [("Malachite", &mut |mut f| f.floor_assign())], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/gcd.rs000064400000000000000000000054771046102023000241240ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::gcd::{gcd_binary, gcd_euclidean, gcd_fast_a, gcd_fast_b}; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::pair_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_pair_gen_var_27; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_gcd); register_unsigned_demos!(runner, demo_gcd_assign); register_unsigned_benches!(runner, benchmark_gcd_algorithms); register_unsigned_benches!(runner, benchmark_gcd_assign); } fn demo_gcd(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in unsigned_pair_gen_var_27::().get(gm, config).take(limit) { println!("{}.gcd({}) = {}", x, y, x.gcd(y)); } } fn demo_gcd_assign(gm: GenMode, config: &GenConfig, limit: usize) { for (mut x, y) in unsigned_pair_gen_var_27::().get(gm, config).take(limit) { let old_x = x; x.gcd_assign(y); println!("x := {old_x}; x.gcd_assign({y}); x = {x}"); } } fn benchmark_gcd_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.gcd({})", T::NAME, T::NAME), BenchmarkType::Algorithms, unsigned_pair_gen_var_27::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [ ("default", &mut |(x, y)| no_out!(x.gcd(y))), ("Euclidean", &mut |(x, y)| no_out!(gcd_euclidean(x, y))), ("binary", &mut |(x, y)| no_out!(gcd_binary(x, y))), ("fast A", &mut |(x, y)| no_out!(gcd_fast_a(x, y))), ("fast B", &mut |(x, y)| no_out!(gcd_fast_b(x, y))), ], ); } fn benchmark_gcd_assign( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.gcd_assign({})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_27::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y)| x.gcd_assign(y))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/is_power_of_2.rs000064400000000000000000000033751046102023000261160ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::bench::bucketers::primitive_float_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::primitive_float_gen; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_primitive_float_demos!(runner, demo_is_power_of_2); register_primitive_float_benches!(runner, benchmark_is_power_of_2); } fn demo_is_power_of_2(gm: GenMode, config: &GenConfig, limit: usize) { for f in primitive_float_gen::().get(gm, config).take(limit) { if f.is_power_of_2() { println!("{} is a power of 2", NiceFloat(f)); } else { println!("{} is not a power of 2", NiceFloat(f)); } } } fn benchmark_is_power_of_2( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.is_power_of_2()", T::NAME), BenchmarkType::Single, primitive_float_gen::().get(gm, config), gm.name(), limit, file_name, &primitive_float_bucketer("f"), &mut [("Malachite", &mut |f| no_out!(f.is_power_of_2()))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/kronecker_symbol.rs000064400000000000000000000206311046102023000267240ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::kronecker_symbol::{ jacobi_symbol_unsigned_double_fast_2, jacobi_symbol_unsigned_simple, }; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::{HasHalf, JoinHalves, WrappingFrom}; use malachite_base::test_util::bench::bucketers::{ pair_max_bit_bucketer, quadruple_max_bit_bucketer, }; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ signed_pair_gen, signed_pair_gen_var_8, unsigned_pair_gen_var_27, unsigned_pair_gen_var_40, unsigned_quadruple_gen_var_12, }; use malachite_base::test_util::num::arithmetic::kronecker_symbol::{ jacobi_symbol_unsigned_double_fast_1, jacobi_symbol_unsigned_double_simple, jacobi_symbol_unsigned_fast_1, jacobi_symbol_unsigned_fast_2_1, jacobi_symbol_unsigned_fast_2_2, jacobi_symbol_unsigned_fast_2_3, jacobi_symbol_unsigned_fast_2_4, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_jacobi_symbol_unsigned_double_fast_1); register_unsigned_demos!(runner, demo_jacobi_symbol_unsigned_double_fast_2); register_unsigned_demos!(runner, demo_jacobi_symbol_unsigned); register_unsigned_signed_match_demos!(runner, demo_jacobi_symbol_signed); register_unsigned_demos!(runner, demo_kronecker_symbol_unsigned); register_signed_demos!(runner, demo_kronecker_symbol_signed); register_generic_benches_2!( runner, benchmark_jacobi_symbol_unsigned_double_algorithms, [u8, u16], [u16, u32], [u32, u64], [u64, u128] ); register_unsigned_benches!(runner, benchmark_jacobi_symbol_unsigned_algorithms); register_unsigned_signed_match_benches!(runner, benchmark_jacobi_symbol_signed); register_unsigned_benches!(runner, benchmark_kronecker_symbol_unsigned); register_signed_benches!(runner, benchmark_kronecker_symbol_signed); } fn demo_jacobi_symbol_unsigned_double_fast_1( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x1, x0, y1, y0) in unsigned_quadruple_gen_var_12::() .get(gm, config) .take(limit) { println!( "jacobi_symbol_unsigned_double_fast_1({}, {}, {}, {}) = {}", x1, x0, y1, y0, jacobi_symbol_unsigned_double_fast_1(x1, x0, y1, y0) ); } } fn demo_jacobi_symbol_unsigned_double_fast_2( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x1, x0, y1, y0) in unsigned_quadruple_gen_var_12::() .get(gm, config) .take(limit) { println!( "jacobi_symbol_unsigned_double_fast_1({}, {}, {}, {}) = {}", x1, x0, y1, y0, jacobi_symbol_unsigned_double_fast_2(x1, x0, y1, y0) ); } } fn demo_jacobi_symbol_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, y) in unsigned_pair_gen_var_40::().get(gm, config).take(limit) { println!("{}.jacobi_symbol({}) = {}", x, y, x.jacobi_symbol(y)); } } fn demo_jacobi_symbol_signed< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, y) in signed_pair_gen_var_8::().get(gm, config).take(limit) { println!("({}).jacobi_symbol({}) = {}", x, y, x.jacobi_symbol(y)); } } fn demo_kronecker_symbol_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, y) in unsigned_pair_gen_var_27::().get(gm, config).take(limit) { println!("{}.kronecker_symbol({}) = {}", x, y, x.kronecker_symbol(y)); } } fn demo_kronecker_symbol_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in signed_pair_gen::().get(gm, config).take(limit) { println!( "({}).kronecker_symbol({}) = {}", x, y, x.kronecker_symbol(y) ); } } fn benchmark_jacobi_symbol_unsigned_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.jacobi_symbol({})", T::NAME, T::NAME), BenchmarkType::Algorithms, unsigned_pair_gen_var_40::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [ ("default", &mut |(x, y)| no_out!(x.jacobi_symbol(y))), ("simple", &mut |(x, y)| { no_out!(jacobi_symbol_unsigned_simple(x, y)) }), ("fast 1", &mut |(x, y)| { no_out!(jacobi_symbol_unsigned_fast_1(x, y)) }), ("fast 2.1", &mut |(x, y)| { no_out!(jacobi_symbol_unsigned_fast_2_1(x, y)) }), ("fast 2.2", &mut |(x, y)| { no_out!(jacobi_symbol_unsigned_fast_2_2(x, y)) }), ("fast 2.3", &mut |(x, y)| { no_out!(jacobi_symbol_unsigned_fast_2_3(x, y)) }), ("fast 2.4", &mut |(x, y)| { no_out!(jacobi_symbol_unsigned_fast_2_4(x, y)) }), ], ); } fn benchmark_jacobi_symbol_unsigned_double_algorithms< T: PrimitiveUnsigned, D: HasHalf + JoinHalves + PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!( "jacobi_symbol_unsigned_double({}, {}, {}, {})", T::NAME, T::NAME, T::NAME, T::NAME ), BenchmarkType::Algorithms, unsigned_quadruple_gen_var_12::().get(gm, config), gm.name(), limit, file_name, &quadruple_max_bit_bucketer("x1", "x0", "y1", "y0"), &mut [ ("simple", &mut |(x1, x0, y1, y0)| { no_out!(jacobi_symbol_unsigned_double_simple::(x1, x0, y1, y0)) }), ("fast 1", &mut |(x1, x0, y1, y0)| { no_out!(jacobi_symbol_unsigned_double_fast_1(x1, x0, y1, y0)) }), ("fast 2", &mut |(x1, x0, y1, y0)| { no_out!(jacobi_symbol_unsigned_double_fast_2(x1, x0, y1, y0)) }), ], ); } fn benchmark_jacobi_symbol_signed< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.jacobi_symbol({})", S::NAME, S::NAME), BenchmarkType::Single, signed_pair_gen_var_8::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("default", &mut |(x, y)| no_out!(x.jacobi_symbol(y)))], ); } fn benchmark_kronecker_symbol_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.kronecker_symbol({})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_27::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.kronecker_symbol(y)))], ); } fn benchmark_kronecker_symbol_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.kronecker_symbol({})", T::NAME, T::NAME), BenchmarkType::Single, signed_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("default", &mut |(x, y)| no_out!(x.kronecker_symbol(y)))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/lcm.rs000064400000000000000000000064161046102023000241340ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::pair_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{unsigned_pair_gen_var_33, unsigned_pair_gen_var_34}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_lcm); register_unsigned_demos!(runner, demo_lcm_assign); register_unsigned_demos!(runner, demo_checked_lcm); register_unsigned_benches!(runner, benchmark_lcm); register_unsigned_benches!(runner, benchmark_lcm_assign); register_unsigned_benches!(runner, benchmark_checked_lcm); } fn demo_lcm(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in unsigned_pair_gen_var_34::().get(gm, config).take(limit) { println!("{}.lcm({}) = {}", x, y, x.lcm(y)); } } fn demo_lcm_assign(gm: GenMode, config: &GenConfig, limit: usize) { for (mut x, y) in unsigned_pair_gen_var_34::().get(gm, config).take(limit) { let old_x = x; x.lcm_assign(y); println!("x := {old_x}; x.lcm_assign({y}); x = {x}"); } } fn demo_checked_lcm(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in unsigned_pair_gen_var_33::().get(gm, config).take(limit) { println!("{}.checked_lcm({}) = {:?}", x, y, x.checked_lcm(y)); } } fn benchmark_lcm( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.lcm({})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_34::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.lcm(y)))], ); } fn benchmark_lcm_assign( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.lcm_assign({})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_34::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y)| x.lcm_assign(y))], ); } fn benchmark_checked_lcm( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.checked_lcm({})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_33::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.checked_lcm(y)))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/log_base.rs000064400000000000000000000100441046102023000251240ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::log_base::{ceiling_log_base_naive, checked_log_base_naive}; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::pair_1_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_pair_gen_var_24; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_floor_log_base); register_unsigned_demos!(runner, demo_ceiling_log_base); register_unsigned_demos!(runner, demo_checked_log_base); register_unsigned_benches!(runner, benchmark_floor_log_base); register_unsigned_benches!(runner, benchmark_ceiling_log_base_algorithms); register_unsigned_benches!(runner, benchmark_checked_log_base_algorithms); } fn demo_floor_log_base(gm: GenMode, config: &GenConfig, limit: usize) { for (n, b) in unsigned_pair_gen_var_24::() .get(gm, config) .take(limit) { println!("{}.floor_log_base({}) = {}", n, b, n.floor_log_base(b)); } } fn demo_ceiling_log_base(gm: GenMode, config: &GenConfig, limit: usize) { for (n, b) in unsigned_pair_gen_var_24::() .get(gm, config) .take(limit) { println!("{}.ceiling_log_base({}) = {}", n, b, n.ceiling_log_base(b)); } } fn demo_checked_log_base(gm: GenMode, config: &GenConfig, limit: usize) { for (n, b) in unsigned_pair_gen_var_24::() .get(gm, config) .take(limit) { println!( "{}.checked_log_base({}) = {:?}", n, b, n.checked_log_base(b) ); } } fn benchmark_floor_log_base( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.floor_log_base({})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_24::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("n"), &mut [( "Malachite", &mut |(n, base)| no_out!(n.floor_log_base(base)), )], ); } fn benchmark_ceiling_log_base_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.ceiling_log_base({})", T::NAME, T::NAME), BenchmarkType::Algorithms, unsigned_pair_gen_var_24::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("n"), &mut [ ( "default", &mut |(n, base)| no_out!(n.ceiling_log_base(base)), ), ("naive", &mut |(n, base)| { no_out!(ceiling_log_base_naive(n, base)) }), ], ); } fn benchmark_checked_log_base_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.checked_log_base({})", T::NAME, T::NAME), BenchmarkType::Algorithms, unsigned_pair_gen_var_24::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("n"), &mut [ ( "default", &mut |(n, base)| no_out!(n.checked_log_base(base)), ), ("naive", &mut |(n, base)| { no_out!(checked_log_base_naive(n, base)) }), ], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/log_base_2.rs000064400000000000000000000151731046102023000253550ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::bench::bucketers::{ primitive_float_bucketer, primitive_int_bit_bucketer, }; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{primitive_float_gen_var_18, unsigned_gen_var_1}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_floor_log_base_2_unsigned); register_unsigned_demos!(runner, demo_ceiling_log_base_2_unsigned); register_unsigned_demos!(runner, demo_checked_log_base_2_unsigned); register_primitive_float_demos!(runner, demo_floor_log_base_2_primitive_float); register_primitive_float_demos!(runner, demo_ceiling_log_base_2_primitive_float); register_primitive_float_demos!(runner, demo_checked_log_base_2_primitive_float); register_unsigned_benches!(runner, benchmark_floor_log_base_2_unsigned); register_unsigned_benches!(runner, benchmark_ceiling_log_base_2_unsigned); register_unsigned_benches!(runner, benchmark_checked_log_base_2_unsigned); register_primitive_float_benches!(runner, benchmark_floor_log_base_2_primitive_float); register_primitive_float_benches!(runner, benchmark_ceiling_log_base_2_primitive_float); register_primitive_float_benches!(runner, benchmark_checked_log_base_2_primitive_float); } fn demo_floor_log_base_2_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for n in unsigned_gen_var_1::().get(gm, config).take(limit) { println!("{}.floor_log_base_2() = {}", n, n.floor_log_base_2()); } } fn demo_ceiling_log_base_2_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for n in unsigned_gen_var_1::().get(gm, config).take(limit) { println!("{}.ceiling_log_base_2() = {}", n, n.ceiling_log_base_2()); } } fn demo_checked_log_base_2_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for n in unsigned_gen_var_1::().get(gm, config).take(limit) { println!("{}.checked_log_base_2() = {:?}", n, n.checked_log_base_2()); } } fn demo_floor_log_base_2_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, ) { for n in primitive_float_gen_var_18::() .get(gm, config) .take(limit) { println!( "{}.floor_log_base_2() = {}", NiceFloat(n), n.floor_log_base_2() ); } } fn demo_ceiling_log_base_2_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, ) { for n in primitive_float_gen_var_18::() .get(gm, config) .take(limit) { println!( "{}.ceiling_log_base_2() = {}", NiceFloat(n), n.ceiling_log_base_2() ); } } fn demo_checked_log_base_2_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, ) { for n in primitive_float_gen_var_18::() .get(gm, config) .take(limit) { println!( "{}.checked_log_base_2() = {:?}", NiceFloat(n), n.checked_log_base_2() ); } } fn benchmark_floor_log_base_2_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.floor_log_base_2()", T::NAME), BenchmarkType::Single, unsigned_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &primitive_int_bit_bucketer(), &mut [("Malachite", &mut |n| no_out!(n.floor_log_base_2()))], ); } fn benchmark_ceiling_log_base_2_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.ceiling_log_base_2()", T::NAME), BenchmarkType::Single, unsigned_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &primitive_int_bit_bucketer(), &mut [("Malachite", &mut |n| no_out!(n.ceiling_log_base_2()))], ); } fn benchmark_checked_log_base_2_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.checked_log_base_2()", T::NAME), BenchmarkType::Single, unsigned_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &primitive_int_bit_bucketer(), &mut [("Malachite", &mut |n| no_out!(n.checked_log_base_2()))], ); } fn benchmark_floor_log_base_2_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.floor_log_base_2()", T::NAME), BenchmarkType::Single, primitive_float_gen_var_18::().get(gm, config), gm.name(), limit, file_name, &primitive_float_bucketer("x"), &mut [("Malachite", &mut |n| no_out!(n.floor_log_base_2()))], ); } fn benchmark_ceiling_log_base_2_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.ceiling_log_base_2()", T::NAME), BenchmarkType::Single, primitive_float_gen_var_18::().get(gm, config), gm.name(), limit, file_name, &primitive_float_bucketer("x"), &mut [("Malachite", &mut |n| no_out!(n.ceiling_log_base_2()))], ); } fn benchmark_checked_log_base_2_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.checked_log_base_2()", T::NAME), BenchmarkType::Single, primitive_float_gen_var_18::().get(gm, config), gm.name(), limit, file_name, &primitive_float_bucketer("x"), &mut [("Malachite", &mut |n| no_out!(n.checked_log_base_2()))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/log_base_power_of_2.rs000064400000000000000000000202461046102023000272520ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::log_base_power_of_2::ceiling_log_base_power_of_2_naive; use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::bench::bucketers::{ pair_1_bit_bucketer, pair_1_primitive_float_bucketer, }; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ primitive_float_unsigned_pair_gen_var_3, unsigned_pair_gen_var_21, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_floor_log_base_power_of_2_unsigned); register_primitive_float_demos!(runner, demo_floor_log_base_power_of_2_primitive_float); register_unsigned_demos!(runner, demo_ceiling_log_base_power_of_2_unsigned); register_primitive_float_demos!(runner, demo_ceiling_log_base_power_of_2_primitive_float); register_unsigned_demos!(runner, demo_checked_log_base_power_of_2_unsigned); register_primitive_float_demos!(runner, demo_checked_log_base_power_of_2_primitive_float); register_unsigned_benches!(runner, benchmark_floor_log_base_power_of_2_unsigned); register_primitive_float_benches!(runner, benchmark_floor_log_base_power_of_2_primitive_float); register_unsigned_benches!( runner, benchmark_ceiling_log_base_power_of_2_algorithms_unsigned ); register_primitive_float_benches!( runner, benchmark_ceiling_log_base_power_of_2_primitive_float ); register_unsigned_benches!(runner, benchmark_checked_log_base_power_of_2_unsigned); register_primitive_float_benches!( runner, benchmark_checked_log_base_power_of_2_primitive_float ); } fn demo_floor_log_base_power_of_2_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (n, pow) in unsigned_pair_gen_var_21::() .get(gm, config) .take(limit) { println!( "{}.floor_log_base_power_of_2({}) = {}", n, pow, n.floor_log_base_power_of_2(pow) ); } } fn demo_floor_log_base_power_of_2_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, ) { for (n, pow) in primitive_float_unsigned_pair_gen_var_3::() .get(gm, config) .take(limit) { println!( "{}.floor_log_base_power_of_2({}) = {}", NiceFloat(n), pow, n.floor_log_base_power_of_2(pow) ); } } fn demo_ceiling_log_base_power_of_2_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (n, pow) in unsigned_pair_gen_var_21::() .get(gm, config) .take(limit) { println!( "{}.ceiling_log_base_power_of_2({}) = {}", n, pow, n.ceiling_log_base_power_of_2(pow) ); } } fn demo_ceiling_log_base_power_of_2_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, ) { for (n, pow) in primitive_float_unsigned_pair_gen_var_3::() .get(gm, config) .take(limit) { println!( "{}.ceiling_log_base_power_of_2({}) = {}", NiceFloat(n), pow, n.ceiling_log_base_power_of_2(pow) ); } } fn demo_checked_log_base_power_of_2_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (n, pow) in unsigned_pair_gen_var_21::() .get(gm, config) .take(limit) { println!( "{}.checked_log_base_power_of_2({}) = {:?}", n, pow, n.checked_log_base_power_of_2(pow) ); } } fn demo_checked_log_base_power_of_2_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, ) { for (n, pow) in primitive_float_unsigned_pair_gen_var_3::() .get(gm, config) .take(limit) { println!( "{}.checked_log_base_power_of_2({}) = {:?}", NiceFloat(n), pow, n.checked_log_base_power_of_2(pow) ); } } fn benchmark_floor_log_base_power_of_2_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.floor_log_base_power_of_2(u64)", T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_21::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("n"), &mut [("Malachite", &mut |(n, pow)| { no_out!(n.floor_log_base_power_of_2(pow)) })], ); } fn benchmark_floor_log_base_power_of_2_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.floor_log_base_power_of_2(u64)", T::NAME), BenchmarkType::Single, primitive_float_unsigned_pair_gen_var_3::().get(gm, config), gm.name(), limit, file_name, &pair_1_primitive_float_bucketer("x"), &mut [("Malachite", &mut |(n, pow)| { no_out!(n.floor_log_base_power_of_2(pow)) })], ); } fn benchmark_ceiling_log_base_power_of_2_algorithms_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.ceiling_log_base_power_of_2(u64)", T::NAME), BenchmarkType::Algorithms, unsigned_pair_gen_var_21::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("n"), &mut [ ("default", &mut |(n, pow)| { no_out!(n.ceiling_log_base_power_of_2(pow)) }), ("naive", &mut |(n, pow)| { no_out!(ceiling_log_base_power_of_2_naive(n, pow)) }), ], ); } fn benchmark_ceiling_log_base_power_of_2_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.ceiling_log_base_power_of_2(u64)", T::NAME), BenchmarkType::Single, primitive_float_unsigned_pair_gen_var_3::().get(gm, config), gm.name(), limit, file_name, &pair_1_primitive_float_bucketer("x"), &mut [("Malachite", &mut |(n, pow)| { no_out!(n.ceiling_log_base_power_of_2(pow)) })], ); } fn benchmark_checked_log_base_power_of_2_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.checked_log_base_power_of_2(u64)", T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_21::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("n"), &mut [("Malachite", &mut |(n, pow)| { no_out!(n.checked_log_base_power_of_2(pow)) })], ); } fn benchmark_checked_log_base_power_of_2_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.checked_log_base_power_of_2(u64)", T::NAME), BenchmarkType::Single, primitive_float_unsigned_pair_gen_var_3::().get(gm, config), gm.name(), limit, file_name, &pair_1_primitive_float_bucketer("x"), &mut [("Malachite", &mut |(n, pow)| { no_out!(n.checked_log_base_power_of_2(pow)) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/mod.rs000064400000000000000000000141031046102023000241300ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { abs::register(runner); abs_diff::register(runner); add_mul::register(runner); arithmetic_checked_shl::register(runner); arithmetic_checked_shr::register(runner); binomial_coefficient::register(runner); ceiling::register(runner); checked_add_mul::register(runner); checked_square::register(runner); checked_sub_mul::register(runner); coprime_with::register(runner); div_exact::register(runner); div_mod::register(runner); div_round::register(runner); divisible_by::register(runner); divisible_by_power_of_2::register(runner); eq_mod::register(runner); eq_mod_power_of_2::register(runner); extended_gcd::register(runner); factorial::register(runner); floor::register(runner); gcd::register(runner); is_power_of_2::register(runner); kronecker_symbol::register(runner); lcm::register(runner); log_base::register(runner); log_base_2::register(runner); log_base_power_of_2::register(runner); mod_inverse::register(runner); mod_is_reduced::register(runner); mod_add::register(runner); mod_mul::register(runner); mod_neg::register(runner); mod_op::register(runner); mod_pow::register(runner); mod_power_of_2::register(runner); mod_power_of_2_add::register(runner); mod_power_of_2_inverse::register(runner); mod_power_of_2_is_reduced::register(runner); mod_power_of_2_mul::register(runner); mod_power_of_2_pow::register(runner); mod_power_of_2_shl::register(runner); mod_power_of_2_shr::register(runner); mod_power_of_2_square::register(runner); mod_power_of_2_neg::register(runner); mod_power_of_2_sub::register(runner); mod_shl::register(runner); mod_shr::register(runner); mod_square::register(runner); mod_sub::register(runner); neg::register(runner); next_power_of_2::register(runner); overflowing_abs::register(runner); overflowing_add::register(runner); overflowing_add_mul::register(runner); overflowing_div::register(runner); overflowing_mul::register(runner); overflowing_neg::register(runner); overflowing_pow::register(runner); overflowing_square::register(runner); overflowing_sub::register(runner); overflowing_sub_mul::register(runner); parity::register(runner); pow::register(runner); power_of_2::register(runner); primorial::register(runner); reciprocal::register(runner); root::register(runner); rotate::register(runner); round_to_multiple::register(runner); round_to_multiple_of_power_of_2::register(runner); saturating_abs::register(runner); saturating_add::register(runner); saturating_add_mul::register(runner); saturating_mul::register(runner); saturating_neg::register(runner); saturating_pow::register(runner); saturating_square::register(runner); saturating_sub::register(runner); saturating_sub_mul::register(runner); shl_round::register(runner); shr_round::register(runner); sign::register(runner); sqrt::register(runner); square::register(runner); sub_mul::register(runner); wrapping_abs::register(runner); wrapping_add::register(runner); wrapping_add_mul::register(runner); wrapping_div::register(runner); wrapping_mul::register(runner); wrapping_neg::register(runner); wrapping_pow::register(runner); wrapping_square::register(runner); wrapping_sub::register(runner); wrapping_sub_mul::register(runner); x_mul_y_to_zz::register(runner); xx_add_yy_to_zz::register(runner); xx_div_mod_y_to_qr::register(runner); xx_sub_yy_to_zz::register(runner); xxx_add_yyy_to_zzz::register(runner); xxx_sub_yyy_to_zzz::register(runner); xxxx_add_yyyy_to_zzzz::register(runner); } mod abs; mod abs_diff; mod add_mul; mod arithmetic_checked_shl; mod arithmetic_checked_shr; mod binomial_coefficient; mod ceiling; mod checked_add_mul; mod checked_square; mod checked_sub_mul; mod coprime_with; mod div_exact; mod div_mod; mod div_round; mod divisible_by; mod divisible_by_power_of_2; mod eq_mod; mod eq_mod_power_of_2; mod extended_gcd; mod factorial; mod floor; mod gcd; mod is_power_of_2; mod kronecker_symbol; mod lcm; mod log_base; mod log_base_2; mod log_base_power_of_2; mod mod_add; mod mod_inverse; mod mod_is_reduced; mod mod_mul; mod mod_neg; mod mod_op; mod mod_pow; mod mod_power_of_2; mod mod_power_of_2_add; mod mod_power_of_2_inverse; mod mod_power_of_2_is_reduced; mod mod_power_of_2_mul; mod mod_power_of_2_neg; mod mod_power_of_2_pow; mod mod_power_of_2_shl; mod mod_power_of_2_shr; mod mod_power_of_2_square; mod mod_power_of_2_sub; mod mod_shl; mod mod_shr; mod mod_square; mod mod_sub; mod neg; mod next_power_of_2; mod overflowing_abs; mod overflowing_add; mod overflowing_add_mul; mod overflowing_div; mod overflowing_mul; mod overflowing_neg; mod overflowing_pow; mod overflowing_square; mod overflowing_sub; mod overflowing_sub_mul; mod parity; mod pow; mod power_of_2; mod primorial; mod reciprocal; mod root; mod rotate; mod round_to_multiple; mod round_to_multiple_of_power_of_2; mod saturating_abs; mod saturating_add; mod saturating_add_mul; mod saturating_mul; mod saturating_neg; mod saturating_pow; mod saturating_square; mod saturating_sub; mod saturating_sub_mul; mod shl_round; mod shr_round; mod sign; mod sqrt; mod square; mod sub_mul; mod wrapping_abs; mod wrapping_add; mod wrapping_add_mul; mod wrapping_div; mod wrapping_mul; mod wrapping_neg; mod wrapping_pow; mod wrapping_square; mod wrapping_sub; mod wrapping_sub_mul; mod x_mul_y_to_zz; mod xx_add_yy_to_zz; mod xx_div_mod_y_to_qr; mod xx_sub_yy_to_zz; mod xxx_add_yyy_to_zzz; mod xxx_sub_yyy_to_zzz; mod xxxx_add_yyyy_to_zzzz; malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/mod_add.rs000064400000000000000000000051071046102023000247440ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::triple_3_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_triple_gen_var_12; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_mod_add); register_unsigned_demos!(runner, demo_mod_add_assign); register_unsigned_benches!(runner, benchmark_mod_add); register_unsigned_benches!(runner, benchmark_mod_add_assign); } fn demo_mod_add(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y, m) in unsigned_triple_gen_var_12::() .get(gm, config) .take(limit) { println!("{} + {} ≡ {} mod {}", x, y, x.mod_add(y, m), m); } } fn demo_mod_add_assign(gm: GenMode, config: &GenConfig, limit: usize) { for (mut x, y, m) in unsigned_triple_gen_var_12::() .get(gm, config) .take(limit) { let old_x = x; x.mod_add_assign(y, m); println!("x := {old_x}; x.mod_add_assign({y}, {m}); x = {x}"); } } fn benchmark_mod_add( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_add({}, {})", T::NAME, T::NAME, T::NAME), BenchmarkType::Single, unsigned_triple_gen_var_12::().get(gm, config), gm.name(), limit, file_name, &triple_3_bit_bucketer("m"), &mut [("Malachite", &mut |(x, y, m)| no_out!(x.mod_add(y, m)))], ); } fn benchmark_mod_add_assign( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_add({}, {})", T::NAME, T::NAME, T::NAME), BenchmarkType::Single, unsigned_triple_gen_var_12::().get(gm, config), gm.name(), limit, file_name, &triple_3_bit_bucketer("m"), &mut [("Malachite", &mut |(mut x, y, m)| x.mod_add_assign(y, m))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/mod_inverse.rs000064400000000000000000000045371046102023000256750ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::mod_inverse::mod_inverse_binary; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::WrappingFrom; use malachite_base::test_util::bench::bucketers::pair_2_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_pair_gen_var_38; use malachite_base::test_util::num::arithmetic::mod_inverse::mod_inverse_euclidean; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_mod_inverse); register_unsigned_signed_match_benches!(runner, benchmark_mod_inverse_algorithms); } fn demo_mod_inverse(gm: GenMode, config: &GenConfig, limit: usize) { for (n, m) in unsigned_pair_gen_var_38::().get(gm, config).take(limit) { if let Some(inverse) = n.mod_inverse(m) { println!("{n}⁻¹ ≡ {inverse} mod {m}"); } else { println!("{n} is not invertible mod {m}"); } } } fn benchmark_mod_inverse_algorithms< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_inverse({})", U::NAME, U::NAME), BenchmarkType::Algorithms, unsigned_pair_gen_var_38::().get(gm, config), gm.name(), limit, file_name, &pair_2_bit_bucketer("m"), &mut [ ("default", &mut |(n, m)| no_out!(n.mod_inverse(m))), ("Euclidean", &mut |(n, m)| { no_out!(mod_inverse_euclidean::(n, m)) }), ("binary", &mut |(n, m)| { no_out!(mod_inverse_binary::(n, m)) }), ], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/mod_is_reduced.rs000064400000000000000000000033761046102023000263300ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::pair_2_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_pair_gen_var_12; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_mod_is_reduced); register_unsigned_benches!(runner, benchmark_mod_is_reduced); } fn demo_mod_is_reduced(gm: GenMode, config: &GenConfig, limit: usize) { for (n, m) in unsigned_pair_gen_var_12::() .get(gm, config) .take(limit) { if n.mod_is_reduced(&m) { println!("{n} is reduced mod {m}"); } else { println!("{n} is not reduced mod {m}"); } } } fn benchmark_mod_is_reduced( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_is_reduced(&{})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_12::().get(gm, config), gm.name(), limit, file_name, &pair_2_bit_bucketer("m"), &mut [("Malachite", &mut |(n, m)| no_out!(n.mod_is_reduced(&m)))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/mod_mul.rs000064400000000000000000000217741046102023000250210ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::mod_mul::{ fast_mod_mul, limbs_invert_limb_u32, limbs_invert_limb_u64, limbs_mod_preinverted, naive_mod_mul, }; use malachite_base::num::arithmetic::traits::ModMulPrecomputed; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::{HasHalf, JoinHalves, SplitInHalf}; use malachite_base::test_util::bench::bucketers::{ ignore_highest_bit_unsigned_bit_bucketer, quadruple_1_2_bit_bucketer, triple_3_bit_bucketer, }; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ unsigned_gen_var_12, unsigned_quadruple_gen_var_5, unsigned_triple_gen_var_12, }; use malachite_base::test_util::num::arithmetic::mod_mul::limbs_invert_limb_naive; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_limbs_invert_limb_u32); register_demo!(runner, demo_limbs_invert_limb_u64); register_generic_demos_2!( runner, demo_limbs_mod_preinverted, [u8, u16], [u16, u32], [u32, u64], [u64, u128] ); register_unsigned_demos!(runner, demo_mod_mul); register_unsigned_demos!(runner, demo_mod_mul_assign); register_bench!(runner, benchmark_limbs_invert_limb_u32_algorithms); register_bench!(runner, benchmark_limbs_invert_limb_u64_algorithms); register_generic_benches_2!( runner, benchmark_limbs_mod_preinverted_algorithms, [u8, u16], [u16, u32], [u32, u64], [u64, u128] ); register_generic_benches!(runner, benchmark_mod_mul_algorithms, u8, u16, u128, usize); register_generic_benches_2!( runner, benchmark_mod_mul_algorithms_with_fast, [u32, u64], [u64, u128] ); register_unsigned_benches!(runner, benchmark_mod_mul_assign); register_unsigned_benches!(runner, benchmark_mod_mul_precomputed_algorithms); } fn demo_limbs_invert_limb_u32(gm: GenMode, config: &GenConfig, limit: usize) { for x in unsigned_gen_var_12().get(gm, config).take(limit) { println!( "limbs_invert_limb_u32({}) = {}", x, limbs_invert_limb_u32(x) ); } } fn demo_limbs_invert_limb_u64(gm: GenMode, config: &GenConfig, limit: usize) { for x in unsigned_gen_var_12().get(gm, config).take(limit) { println!( "limbs_invert_limb_u64({}) = {}", x, limbs_invert_limb_u64(x) ); } } fn demo_limbs_mod_preinverted< T: TryFrom
+ PrimitiveUnsigned, DT: From + HasHalf + JoinHalves + PrimitiveUnsigned + SplitInHalf, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x_1, x_0, m, inv) in unsigned_quadruple_gen_var_5::() .get(gm, config) .take(limit) { println!( "limbs_mod_preinverted({}, {}, {}, {}) = {}", x_1, x_0, m, inv, limbs_mod_preinverted::(x_1, x_0, m, inv) ); } } fn demo_mod_mul(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y, m) in unsigned_triple_gen_var_12::() .get(gm, config) .take(limit) { println!("{} * {} ≡ {} mod {}", x, y, x.mod_mul(y, m), m); } } fn demo_mod_mul_assign(gm: GenMode, config: &GenConfig, limit: usize) { for (mut x, y, m) in unsigned_triple_gen_var_12::() .get(gm, config) .take(limit) { let old_x = x; x.mod_mul_assign(y, m); println!("x := {old_x}; x.mod_mul_assign({y}, {m}); x = {x}"); } } fn benchmark_limbs_invert_limb_u32_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( "limbs_invert_limb_u32(u32)", BenchmarkType::Algorithms, unsigned_gen_var_12().get(gm, config), gm.name(), limit, file_name, &ignore_highest_bit_unsigned_bit_bucketer("m"), &mut [ ("default", &mut |x| no_out!(limbs_invert_limb_u32(x))), ("naive", &mut |x| { no_out!(limbs_invert_limb_naive::(x)) }), ], ); } fn benchmark_limbs_invert_limb_u64_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( "limbs_invert_limb_u64(u64)", BenchmarkType::Algorithms, unsigned_gen_var_12().get(gm, config), gm.name(), limit, file_name, &ignore_highest_bit_unsigned_bit_bucketer("m"), &mut [ ("default", &mut |x| no_out!(limbs_invert_limb_u64(x))), ("naive", &mut |x| { no_out!(limbs_invert_limb_naive::(x)) }), ], ); } fn benchmark_limbs_mod_preinverted_algorithms< T: TryFrom
+ PrimitiveUnsigned, DT: From + HasHalf + JoinHalves + PrimitiveUnsigned + SplitInHalf, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!( "limbs_mod_preinverted({}, {}, {}, {})", T::NAME, T::NAME, T::NAME, T::NAME ), BenchmarkType::Algorithms, unsigned_quadruple_gen_var_5::().get(gm, config), gm.name(), limit, file_name, &quadruple_1_2_bit_bucketer("x"), &mut [ ("default", &mut |(x_1, x_0, d, d_inv)| { no_out!(limbs_mod_preinverted::(x_1, x_0, d, d_inv)) }), ("naive", &mut |(x_1, x_0, d, _)| { no_out!(T::exact_from(DT::join_halves(x_1, x_0) % DT::from(d))) }), ], ); } fn benchmark_mod_mul_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_mul({}, {})", T::NAME, T::NAME, T::NAME), BenchmarkType::Algorithms, unsigned_triple_gen_var_12::().get(gm, config), gm.name(), limit, file_name, &triple_3_bit_bucketer("m"), &mut [ ("default", &mut |(x, y, m)| no_out!(x.mod_mul(y, m))), ("naive", &mut |(x, y, m)| no_out!(naive_mod_mul(x, y, m))), ], ); } fn benchmark_mod_mul_algorithms_with_fast< T: ModMulPrecomputed + PrimitiveUnsigned, DT: From + HasHalf + JoinHalves + PrimitiveUnsigned + SplitInHalf, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_mul({}, {})", T::NAME, T::NAME, T::NAME), BenchmarkType::Algorithms, unsigned_triple_gen_var_12::().get(gm, config), gm.name(), limit, file_name, &triple_3_bit_bucketer("m"), &mut [ ("default", &mut |(x, y, m)| no_out!(x.mod_mul(y, m))), ("naive", &mut |(x, y, m)| no_out!(naive_mod_mul(x, y, m))), ("fast", &mut |(x, y, m)| { no_out!(fast_mod_mul::( x, y, m, T::precompute_mod_mul_data(&m) )) }), ], ); } fn benchmark_mod_mul_assign( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_mul({}, {})", T::NAME, T::NAME, T::NAME), BenchmarkType::Single, unsigned_triple_gen_var_12::().get(gm, config), gm.name(), limit, file_name, &triple_3_bit_bucketer("m"), &mut [("Malachite", &mut |(mut x, y, m)| x.mod_mul_assign(y, m))], ); } fn benchmark_mod_mul_precomputed_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_mul({}, {})", T::NAME, T::NAME, T::NAME), BenchmarkType::Algorithms, unsigned_triple_gen_var_12::().get(gm, config), gm.name(), limit, file_name, &triple_3_bit_bucketer("m"), &mut [ ("default", &mut |(x, y, m)| { for _ in 0..10 { x.mod_mul(y, m); } }), ("precomputed", &mut |(x, y, m)| { let data = T::precompute_mod_mul_data(&m); for _ in 0..10 { x.mod_mul_precomputed(y, m, &data); } }), ], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/mod_neg.rs000064400000000000000000000047151046102023000247710ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::pair_2_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_pair_gen_var_16; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_mod_neg); register_unsigned_demos!(runner, demo_mod_neg_assign); register_unsigned_benches!(runner, benchmark_mod_neg); register_unsigned_benches!(runner, benchmark_mod_neg_assign); } fn demo_mod_neg(gm: GenMode, config: &GenConfig, limit: usize) { for (n, m) in unsigned_pair_gen_var_16::().get(gm, config).take(limit) { println!("-{} ≡ {} mod {}", n, n.mod_neg(m), m); } } fn demo_mod_neg_assign(gm: GenMode, config: &GenConfig, limit: usize) { for (mut n, m) in unsigned_pair_gen_var_16::().get(gm, config).take(limit) { let old_n = n; n.mod_neg_assign(m); println!("n := {old_n}; n.mod_neg_assign({m}); n = {n}"); } } fn benchmark_mod_neg( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_neg({})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_16::().get(gm, config), gm.name(), limit, file_name, &pair_2_bit_bucketer("m"), &mut [("Malachite", &mut |(n, m)| no_out!(n.mod_neg(m)))], ); } fn benchmark_mod_neg_assign( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_neg({})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_16::().get(gm, config), gm.name(), limit, file_name, &pair_2_bit_bucketer("m"), &mut [("Malachite", &mut |(mut n, m)| n.mod_neg_assign(m))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/mod_op.rs000064400000000000000000000207561046102023000246410ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::pair_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ signed_pair_gen_var_4, signed_pair_gen_var_6, unsigned_pair_gen_var_12, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_mod_unsigned); register_signed_demos!(runner, demo_mod_signed); register_unsigned_demos!(runner, demo_mod_assign_unsigned); register_signed_demos!(runner, demo_mod_assign_signed); register_unsigned_demos!(runner, demo_neg_mod); register_unsigned_demos!(runner, demo_neg_mod_assign); register_signed_demos!(runner, demo_ceiling_mod); register_signed_demos!(runner, demo_ceiling_mod_assign); register_unsigned_benches!(runner, benchmark_mod_unsigned_algorithms); register_signed_benches!(runner, benchmark_mod_signed_algorithms); register_unsigned_benches!(runner, benchmark_mod_assign_unsigned); register_signed_benches!(runner, benchmark_mod_assign_signed); register_unsigned_benches!(runner, benchmark_neg_mod_algorithms); register_unsigned_benches!(runner, benchmark_neg_mod_assign); register_signed_benches!(runner, benchmark_ceiling_mod_algorithms); register_signed_benches!(runner, benchmark_ceiling_mod_assign); } fn demo_mod_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in unsigned_pair_gen_var_12::() .get(gm, config) .take(limit) { println!("{}.mod_op({}) = {}", x, y, x.mod_op(y)); } } fn demo_mod_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in signed_pair_gen_var_6::().get(gm, config).take(limit) { println!("({}).mod_op({}) = {}", x, y, x.mod_op(y)); } } fn demo_mod_assign_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for (mut x, y) in unsigned_pair_gen_var_12::() .get(gm, config) .take(limit) { let old_x = x; x.mod_assign(y); println!("x := {old_x}; x.mod_assign({y}); x = {x}"); } } fn demo_mod_assign_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (mut x, y) in signed_pair_gen_var_6::().get(gm, config).take(limit) { let old_x = x; x.mod_assign(y); println!("x := {old_x}; x.mod_assign({y}); x = {x}"); } } fn demo_neg_mod(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in unsigned_pair_gen_var_12::() .get(gm, config) .take(limit) { println!("{}.neg_mod({}) = {}", x, y, x.neg_mod(y)); } } fn demo_neg_mod_assign(gm: GenMode, config: &GenConfig, limit: usize) { for (mut x, y) in unsigned_pair_gen_var_12::() .get(gm, config) .take(limit) { let old_x = x; x.neg_mod_assign(y); println!("x := {old_x}; x.neg_mod_assign({y}); x = {x}"); } } fn demo_ceiling_mod(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in signed_pair_gen_var_6::().get(gm, config).take(limit) { println!("({}).ceiling_mod({}) = {}", x, y, x.ceiling_mod(y)); } } fn demo_ceiling_mod_assign(gm: GenMode, config: &GenConfig, limit: usize) { for (mut x, y) in signed_pair_gen_var_6::().get(gm, config).take(limit) { let old_x = x; x.ceiling_mod_assign(y); println!("x := {old_x}; x.ceiling_mod_assign({y}); x = {x}"); } } #[allow(clippy::unnecessary_operation)] fn benchmark_mod_unsigned_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod({})", T::NAME, T::NAME), BenchmarkType::Algorithms, unsigned_pair_gen_var_12::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [ ("using mod", &mut |(x, y)| no_out!(x.mod_op(y))), ("using div_mod", &mut |(x, y)| no_out!(x.div_mod(y).1)), ], ); } #[allow(clippy::unnecessary_operation)] fn benchmark_mod_signed_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod({})", T::NAME, T::NAME), BenchmarkType::Algorithms, signed_pair_gen_var_4::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [ ("using mod", &mut |(x, y)| no_out!(x.mod_op(y))), ("using div_mod", &mut |(x, y)| no_out!(x.div_mod(y).1)), ], ); } fn benchmark_mod_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_assign({})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_12::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y)| x.mod_assign(y))], ); } fn benchmark_mod_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_assign({})", T::NAME, T::NAME), BenchmarkType::Single, signed_pair_gen_var_6::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y)| x.mod_assign(y))], ); } #[allow(clippy::unnecessary_operation)] fn benchmark_neg_mod_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.neg_mod({})", T::NAME, T::NAME), BenchmarkType::Algorithms, unsigned_pair_gen_var_12::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [ ("using neg_mod", &mut |(x, y)| no_out!(x.neg_mod(y))), ("using ceiling_div_mod", &mut |(x, y)| { no_out!(x.ceiling_div_neg_mod(y).1) }), ], ); } fn benchmark_neg_mod_assign( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.neg_mod_assign({})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_12::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y)| x.neg_mod_assign(y))], ); } #[allow(clippy::unnecessary_operation)] fn benchmark_ceiling_mod_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.ceiling_mod({})", T::NAME, T::NAME), BenchmarkType::Algorithms, signed_pair_gen_var_4::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [ ("using ceiling_mod", &mut |(x, y)| no_out!(x.ceiling_mod(y))), ("using ceiling_div_mod", &mut |(x, y)| { no_out!(x.ceiling_div_mod(y).1) }), ], ); } fn benchmark_ceiling_mod_assign( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.ceiling_mod_assign({})", T::NAME, T::NAME), BenchmarkType::Single, signed_pair_gen_var_6::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y)| x.ceiling_mod_assign(y))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/mod_pow.rs000064400000000000000000000113531046102023000250210ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::mod_pow::simple_binary_mod_pow; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::triple_2_3_product_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ unsigned_triple_gen_var_14, unsigned_triple_gen_var_15, }; use malachite_base::test_util::num::arithmetic::mod_pow::naive_mod_pow; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_mod_pow); register_unsigned_demos!(runner, demo_mod_pow_assign); register_unsigned_benches!(runner, benchmark_mod_pow_algorithms); register_unsigned_benches!(runner, benchmark_mod_pow_naive_algorithms); register_unsigned_benches!(runner, benchmark_mod_pow_assign); register_unsigned_benches!(runner, benchmark_mod_pow_precomputed_algorithms); } fn demo_mod_pow(gm: GenMode, config: &GenConfig, limit: usize) { for (x, exp, m) in unsigned_triple_gen_var_15::() .get(gm, config) .take(limit) { println!("{}.pow({}) ≡ {} mod {}", x, exp, x.mod_pow(exp, m), m); } } fn demo_mod_pow_assign(gm: GenMode, config: &GenConfig, limit: usize) { for (mut x, exp, m) in unsigned_triple_gen_var_15::() .get(gm, config) .take(limit) { let old_x = x; x.mod_pow_assign(exp, m); println!("x := {old_x}; x.mod_pow_assign({exp}, {m}); x = {x}"); } } fn benchmark_mod_pow_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_pow(u64, {})", T::NAME, T::NAME), BenchmarkType::Algorithms, unsigned_triple_gen_var_15::().get(gm, config), gm.name(), limit, file_name, &triple_2_3_product_bit_bucketer("exp", "m"), &mut [ ("default", &mut |(x, exp, m)| no_out!(x.mod_pow(exp, m))), ("simple binary", &mut |(x, exp, m)| { no_out!(simple_binary_mod_pow(x, exp, m)) }), ], ); } fn benchmark_mod_pow_naive_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_pow(u64, {})", T::NAME, T::NAME), BenchmarkType::Algorithms, unsigned_triple_gen_var_14::().get(gm, config), gm.name(), limit, file_name, &triple_2_3_product_bit_bucketer("exp", "m"), &mut [ ("default", &mut |(x, exp, m)| no_out!(x.mod_pow(exp, m))), ("naive", &mut |(x, exp, m)| { no_out!(naive_mod_pow(x, exp, m)) }), ("simple binary", &mut |(x, exp, m)| { no_out!(simple_binary_mod_pow(x, exp, m)) }), ], ); } fn benchmark_mod_pow_assign( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_pow_assign(u64, {})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_triple_gen_var_15::().get(gm, config), gm.name(), limit, file_name, &triple_2_3_product_bit_bucketer("exp", "m"), &mut [("Malachite", &mut |(mut x, exp, m)| x.mod_pow_assign(exp, m))], ); } fn benchmark_mod_pow_precomputed_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_pow(u64, {})", T::NAME, T::NAME), BenchmarkType::Algorithms, unsigned_triple_gen_var_15::().get(gm, config), gm.name(), limit, file_name, &triple_2_3_product_bit_bucketer("exp", "m"), &mut [ ("default", &mut |(x, exp, m)| { for _ in 0..10 { x.mod_pow(exp, m); } }), ("precomputed", &mut |(x, exp, m)| { let data = T::precompute_mod_pow_data(&m); for _ in 0..10 { x.mod_pow_precomputed(exp, m, &data); } }), ], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/mod_power_of_2.rs000064400000000000000000000330031046102023000262510ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::ModPowerOf2; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::WrappingFrom; use malachite_base::test_util::bench::bucketers::pair_1_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ signed_unsigned_pair_gen_var_1, signed_unsigned_pair_gen_var_10, signed_unsigned_pair_gen_var_11, signed_unsigned_pair_gen_var_4, unsigned_pair_gen_var_2, unsigned_pair_gen_var_20, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_mod_power_of_2_unsigned); register_signed_demos!(runner, demo_mod_power_of_2_signed); register_unsigned_demos!(runner, demo_mod_power_of_2_assign_unsigned); register_signed_demos!(runner, demo_mod_power_of_2_assign_signed); register_unsigned_demos!(runner, demo_rem_power_of_2_unsigned); register_signed_demos!(runner, demo_rem_power_of_2_signed); register_unsigned_demos!(runner, demo_rem_power_of_2_assign_unsigned); register_signed_demos!(runner, demo_rem_power_of_2_assign_signed); register_unsigned_demos!(runner, demo_neg_mod_power_of_2); register_unsigned_demos!(runner, demo_neg_mod_power_of_2_assign); register_unsigned_signed_match_demos!(runner, demo_ceiling_mod_power_of_2); register_unsigned_signed_match_demos!(runner, demo_ceiling_mod_power_of_2_assign); register_unsigned_benches!(runner, benchmark_mod_power_of_2_unsigned); register_signed_benches!(runner, benchmark_mod_power_of_2_signed); register_unsigned_benches!(runner, benchmark_mod_power_of_2_assign_unsigned); register_signed_benches!(runner, benchmark_mod_power_of_2_assign_signed); register_unsigned_benches!(runner, benchmark_rem_power_of_2_unsigned); register_signed_benches!(runner, benchmark_rem_power_of_2_signed); register_unsigned_benches!(runner, benchmark_rem_power_of_2_assign_unsigned); register_signed_benches!(runner, benchmark_rem_power_of_2_assign_signed); register_unsigned_benches!(runner, benchmark_neg_mod_power_of_2); register_unsigned_benches!(runner, benchmark_neg_mod_power_of_2_assign); register_unsigned_signed_match_benches!(runner, benchmark_ceiling_mod_power_of_2); register_unsigned_signed_match_benches!(runner, benchmark_ceiling_mod_power_of_2_assign); } fn demo_mod_power_of_2_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (n, pow) in unsigned_pair_gen_var_2::() .get(gm, config) .take(limit) { println!("{} ≡ {} mod 2^{}", n, n.mod_power_of_2(pow), pow); } } fn demo_mod_power_of_2_signed(gm: GenMode, config: &GenConfig, limit: usize) where ::Output: PrimitiveUnsigned, { for (n, pow) in signed_unsigned_pair_gen_var_10::() .get(gm, config) .take(limit) { println!("{} ≡ {} mod 2^{}", n, n.mod_power_of_2(pow), pow); } } fn demo_mod_power_of_2_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut n, pow) in unsigned_pair_gen_var_2::() .get(gm, config) .take(limit) { let old_n = n; n.mod_power_of_2_assign(pow); println!("n := {old_n}; n.mod_power_of_2_assign({pow}); n = {n}"); } } fn demo_mod_power_of_2_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, ) where ::Output: PrimitiveUnsigned, { for (mut n, pow) in signed_unsigned_pair_gen_var_4::() .get(gm, config) .take(limit) { let old_n = n; n.mod_power_of_2_assign(pow); println!("n := {old_n}; n.mod_power_of_2_assign({pow}); n = {n}"); } } fn demo_rem_power_of_2_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (n, pow) in unsigned_pair_gen_var_2::() .get(gm, config) .take(limit) { println!("{}.rem_power_of_2({}) = {}", n, pow, n.rem_power_of_2(pow)); } } fn demo_rem_power_of_2_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (n, pow) in signed_unsigned_pair_gen_var_1::() .get(gm, config) .take(limit) { println!("{}.rem_power_of_2({}) = {}", n, pow, n.rem_power_of_2(pow)); } } fn demo_rem_power_of_2_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut n, pow) in unsigned_pair_gen_var_2::() .get(gm, config) .take(limit) { let old_n = n; n.rem_power_of_2_assign(pow); println!("n := {old_n}; n.rem_power_of_2_assign({pow}); n = {n}"); } } fn demo_rem_power_of_2_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut n, pow) in signed_unsigned_pair_gen_var_1::() .get(gm, config) .take(limit) { let old_n = n; n.rem_power_of_2_assign(pow); println!("n := {old_n}; n.rem_power_of_2_assign({pow}); n = {n}"); } } fn demo_neg_mod_power_of_2(gm: GenMode, config: &GenConfig, limit: usize) { for (n, pow) in unsigned_pair_gen_var_20::().get(gm, config).take(limit) { println!( "{}.neg_mod_power_of_2({}) = {}", n, pow, n.neg_mod_power_of_2(pow) ); } } fn demo_neg_mod_power_of_2_assign( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut n, pow) in unsigned_pair_gen_var_20::().get(gm, config).take(limit) { let old_n = n; n.neg_mod_power_of_2_assign(pow); println!("n := {old_n}; n.neg_mod_power_of_2_assign({pow}); n = {n}"); } } fn demo_ceiling_mod_power_of_2< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (n, pow) in signed_unsigned_pair_gen_var_11::() .get(gm, config) .take(limit) { println!( "({}).ceiling_mod_power_of_2({}) = {}", n, pow, n.ceiling_mod_power_of_2(pow) ); } } fn demo_ceiling_mod_power_of_2_assign< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut n, pow) in signed_unsigned_pair_gen_var_11::() .get(gm, config) .take(limit) { let old_n = n; n.ceiling_mod_power_of_2_assign(pow); println!("n := {old_n}; n.ceiling_mod_power_of_2_assign({pow}); n = {n}"); } } fn benchmark_mod_power_of_2_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_power_of_2(u64)", T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("n"), &mut [("Malachite", &mut |(n, pow)| no_out!(n.mod_power_of_2(pow)))], ); } fn benchmark_mod_power_of_2_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where ::Output: PrimitiveUnsigned, { run_benchmark( &format!("{}.mod_power_of_2(u64)", T::NAME), BenchmarkType::Single, signed_unsigned_pair_gen_var_10::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("n"), &mut [("Malachite", &mut |(n, pow)| no_out!(n.mod_power_of_2(pow)))], ); } fn benchmark_mod_power_of_2_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_power_of_2_assign(u64)", T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("n"), &mut [("Malachite", &mut |(mut n, pow)| { n.mod_power_of_2_assign(pow) })], ); } fn benchmark_mod_power_of_2_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_power_of_2_assign(u64)", T::NAME), BenchmarkType::Single, signed_unsigned_pair_gen_var_4::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("n"), &mut [("Malachite", &mut |(mut n, pow)| { n.mod_power_of_2_assign(pow) })], ); } fn benchmark_rem_power_of_2_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.rem_power_of_2(u64)", T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("n"), &mut [("Malachite", &mut |(n, pow)| no_out!(n.rem_power_of_2(pow)))], ); } fn benchmark_rem_power_of_2_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where ::Output: PrimitiveUnsigned, { run_benchmark( &format!("{}.rem_power_of_2(u64)", T::NAME), BenchmarkType::Single, signed_unsigned_pair_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("n"), &mut [("Malachite", &mut |(n, pow)| no_out!(n.rem_power_of_2(pow)))], ); } fn benchmark_rem_power_of_2_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.rem_power_of_2_assign(u64)", T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("n"), &mut [("Malachite", &mut |(mut n, pow)| { n.rem_power_of_2_assign(pow) })], ); } fn benchmark_rem_power_of_2_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.rem_power_of_2_assign(u64)", T::NAME), BenchmarkType::Single, signed_unsigned_pair_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("n"), &mut [("Malachite", &mut |(mut n, pow)| { n.rem_power_of_2_assign(pow) })], ); } fn benchmark_neg_mod_power_of_2( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.neg_mod_power_of_2(u64)", T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_20::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("n"), &mut [("Malachite", &mut |(n, pow)| { no_out!(n.neg_mod_power_of_2(pow)) })], ); } fn benchmark_neg_mod_power_of_2_assign( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.neg_mod_power_of_2_assign(u64)", T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_20::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("n"), &mut [("Malachite", &mut |(mut n, pow)| { n.neg_mod_power_of_2_assign(pow) })], ); } fn benchmark_ceiling_mod_power_of_2< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.ceiling_mod_power_of_2(u64)", S::NAME), BenchmarkType::Single, signed_unsigned_pair_gen_var_11::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("n"), &mut [("Malachite", &mut |(n, pow)| { no_out!(n.ceiling_mod_power_of_2(pow)) })], ); } fn benchmark_ceiling_mod_power_of_2_assign< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.ceiling_mod_power_of_2_assign(u64)", S::NAME), BenchmarkType::Single, signed_unsigned_pair_gen_var_11::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("n"), &mut [("Malachite", &mut |(mut n, pow)| { n.ceiling_mod_power_of_2_assign(pow) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/mod_power_of_2_add.rs000064400000000000000000000055661046102023000270760ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::triple_3_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_triple_gen_var_11; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_mod_power_of_2_add); register_unsigned_demos!(runner, demo_mod_power_of_2_add_assign); register_unsigned_benches!(runner, benchmark_mod_power_of_2_add); register_unsigned_benches!(runner, benchmark_mod_power_of_2_add_assign); } fn demo_mod_power_of_2_add(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y, pow) in unsigned_triple_gen_var_11::() .get(gm, config) .take(limit) { println!( "{} + {} ≡ {} mod 2^{}", x, y, x.mod_power_of_2_add(y, pow), pow ); } } fn demo_mod_power_of_2_add_assign( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y, pow) in unsigned_triple_gen_var_11::() .get(gm, config) .take(limit) { let old_x = x; x.mod_power_of_2_add_assign(y, pow); println!("x := {old_x}; x.mod_power_of_2_add_assign({y}, {pow}); x = {x}"); } } fn benchmark_mod_power_of_2_add( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_power_of_2_add({}, u64)", T::NAME, T::NAME), BenchmarkType::Single, unsigned_triple_gen_var_11::().get(gm, config), gm.name(), limit, file_name, &triple_3_bucketer("pow"), &mut [("Malachite", &mut |(x, y, pow)| { no_out!(x.mod_power_of_2_add(y, pow)) })], ); } fn benchmark_mod_power_of_2_add_assign( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_power_of_2_add_assign({}, u64)", T::NAME, T::NAME), BenchmarkType::Single, unsigned_triple_gen_var_11::().get(gm, config), gm.name(), limit, file_name, &triple_3_bucketer("pow"), &mut [("Malachite", &mut |(mut x, y, pow)| { x.mod_power_of_2_add_assign(y, pow) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/mod_power_of_2_inverse.rs000064400000000000000000000047721046102023000300170ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::mod_power_of_2_inverse::mod_power_of_2_inverse_fast; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::WrappingFrom; use malachite_base::test_util::bench::bucketers::pair_2_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_pair_gen_var_39; use malachite_base::test_util::num::arithmetic::mod_power_of_2_inverse::*; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_mod_power_of_2_inverse); register_unsigned_signed_match_benches!(runner, benchmark_mod_power_of_2_inverse_algorithms); } fn demo_mod_power_of_2_inverse( gm: GenMode, config: &GenConfig, limit: usize, ) { for (n, pow) in unsigned_pair_gen_var_39::().get(gm, config).take(limit) { if let Some(inverse) = n.mod_power_of_2_inverse(pow) { println!("{n}⁻¹ ≡ {inverse} mod 2^{pow}"); } else { println!("{n} is not invertible mod 2^{pow}"); } } } fn benchmark_mod_power_of_2_inverse_algorithms< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_power_of_2_inverse(u64)", U::NAME), BenchmarkType::Algorithms, unsigned_pair_gen_var_39::().get(gm, config), gm.name(), limit, file_name, &pair_2_bucketer("pow"), &mut [ ("default", &mut |(n, pow)| { no_out!(n.mod_power_of_2_inverse(pow)) }), ("Euclidean", &mut |(n, pow)| { no_out!(mod_power_of_2_inverse_euclidean::(n, pow)) }), ("fast", &mut |(n, pow)| { no_out!(mod_power_of_2_inverse_fast(n, pow)) }), ], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/mod_power_of_2_is_reduced.rs000064400000000000000000000035621046102023000304460ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::pair_2_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_pair_gen_var_2; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_mod_power_of_2_is_reduced); register_unsigned_benches!(runner, benchmark_mod_power_of_2_is_reduced); } fn demo_mod_power_of_2_is_reduced( gm: GenMode, config: &GenConfig, limit: usize, ) { for (n, pow) in unsigned_pair_gen_var_2::() .get(gm, config) .take(limit) { if n.mod_power_of_2_is_reduced(pow) { println!("{n} is reduced mod 2^{pow}"); } else { println!("{n} is not reduced mod 2^{pow}"); } } } fn benchmark_mod_power_of_2_is_reduced( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_power_of_2_is_reduced(u64)", T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &pair_2_bucketer("pow"), &mut [("Malachite", &mut |(n, pow)| { no_out!(n.mod_power_of_2_is_reduced(pow)) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/mod_power_of_2_mul.rs000064400000000000000000000055661046102023000271430ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::triple_3_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_triple_gen_var_11; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_mod_power_of_2_mul); register_unsigned_demos!(runner, demo_mod_power_of_2_mul_assign); register_unsigned_benches!(runner, benchmark_mod_power_of_2_mul); register_unsigned_benches!(runner, benchmark_mod_power_of_2_mul_assign); } fn demo_mod_power_of_2_mul(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y, pow) in unsigned_triple_gen_var_11::() .get(gm, config) .take(limit) { println!( "{} * {} ≡ {} mod 2^{}", x, y, x.mod_power_of_2_mul(y, pow), pow ); } } fn demo_mod_power_of_2_mul_assign( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y, pow) in unsigned_triple_gen_var_11::() .get(gm, config) .take(limit) { let old_x = x; x.mod_power_of_2_mul_assign(y, pow); println!("x := {old_x}; x.mod_power_of_2_mul_assign({y}, {pow}); x = {x}"); } } fn benchmark_mod_power_of_2_mul( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_power_of_2_mul({}, u64)", T::NAME, T::NAME), BenchmarkType::Single, unsigned_triple_gen_var_11::().get(gm, config), gm.name(), limit, file_name, &triple_3_bucketer("pow"), &mut [("Malachite", &mut |(x, y, pow)| { no_out!(x.mod_power_of_2_mul(y, pow)) })], ); } fn benchmark_mod_power_of_2_mul_assign( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_power_of_2_mul_assign({}, u64)", T::NAME, T::NAME), BenchmarkType::Single, unsigned_triple_gen_var_11::().get(gm, config), gm.name(), limit, file_name, &triple_3_bucketer("pow"), &mut [("Malachite", &mut |(mut x, y, pow)| { x.mod_power_of_2_mul_assign(y, pow) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/mod_power_of_2_neg.rs000064400000000000000000000052661046102023000271140ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::pair_2_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_pair_gen_var_17; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_mod_power_of_2_neg); register_unsigned_demos!(runner, demo_mod_power_of_2_neg_assign); register_unsigned_benches!(runner, benchmark_mod_power_of_2_neg); register_unsigned_benches!(runner, benchmark_mod_power_of_2_neg_assign); } fn demo_mod_power_of_2_neg(gm: GenMode, config: &GenConfig, limit: usize) { for (n, pow) in unsigned_pair_gen_var_17::().get(gm, config).take(limit) { println!("-{} ≡ {} mod 2^{}", n, n.mod_power_of_2_neg(pow), pow); } } fn demo_mod_power_of_2_neg_assign( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut n, pow) in unsigned_pair_gen_var_17::().get(gm, config).take(limit) { let old_n = n; n.mod_power_of_2_neg_assign(pow); println!("n := {old_n}; n.mod_power_of_2_neg_assign({pow}); n = {n}"); } } fn benchmark_mod_power_of_2_neg( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_power_of_2_neg(u64)", T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_17::().get(gm, config), gm.name(), limit, file_name, &pair_2_bucketer("pow"), &mut [("Malachite", &mut |(n, pow)| { no_out!(n.mod_power_of_2_neg(pow)) })], ); } fn benchmark_mod_power_of_2_neg_assign( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_power_of_2_neg_assign(u64)", T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_17::().get(gm, config), gm.name(), limit, file_name, &pair_2_bucketer("pow"), &mut [("Malachite", &mut |(mut n, pow)| { n.mod_power_of_2_neg_assign(pow) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/mod_power_of_2_pow.rs000064400000000000000000000056311046102023000271440ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::triple_3_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_triple_gen_var_16; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_mod_power_of_2_pow); register_unsigned_demos!(runner, demo_mod_power_of_2_pow_assign); register_unsigned_benches!(runner, benchmark_mod_power_of_2_pow); register_unsigned_benches!(runner, benchmark_mod_power_of_2_pow_assign); } fn demo_mod_power_of_2_pow(gm: GenMode, config: &GenConfig, limit: usize) { for (x, exp, pow) in unsigned_triple_gen_var_16::() .get(gm, config) .take(limit) { println!( "{}.pow({}) ≡ {} mod 2^{}", x, exp, x.mod_power_of_2_pow(exp, pow), pow ); } } fn demo_mod_power_of_2_pow_assign( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, exp, pow) in unsigned_triple_gen_var_16::() .get(gm, config) .take(limit) { let old_x = x; x.mod_power_of_2_pow_assign(exp, pow); println!("x := {old_x}; x.mod_power_of_2_pow_assign({exp}, {pow}); x = {x}"); } } fn benchmark_mod_power_of_2_pow( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_power_of_2_pow(u64, u64)", T::NAME), BenchmarkType::Single, unsigned_triple_gen_var_16::().get(gm, config), gm.name(), limit, file_name, &triple_3_bucketer("pow"), &mut [("Malachite", &mut |(x, exp, pow)| { no_out!(x.mod_power_of_2_pow(exp, pow)) })], ); } fn benchmark_mod_power_of_2_pow_assign( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_power_of_2_pow_assign({}, u64)", T::NAME, T::NAME), BenchmarkType::Single, unsigned_triple_gen_var_16::().get(gm, config), gm.name(), limit, file_name, &triple_3_bucketer("pow"), &mut [("Malachite", &mut |(mut x, exp, pow)| { x.mod_power_of_2_pow_assign(exp, pow) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/mod_power_of_2_shl.rs000064400000000000000000000141261046102023000271240ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::{ModPowerOf2Shl, ModPowerOf2ShlAssign}; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::triple_3_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ unsigned_signed_unsigned_triple_gen_var_1, unsigned_triple_gen_var_17, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_unsigned_demos!(runner, demo_mod_power_of_2_shl_unsigned_unsigned); register_unsigned_signed_demos!(runner, demo_mod_power_of_2_shl_unsigned_signed); register_unsigned_unsigned_demos!(runner, demo_mod_power_of_2_shl_assign_unsigned_unsigned); register_unsigned_signed_demos!(runner, demo_mod_power_of_2_shl_assign_unsigned_signed); register_unsigned_unsigned_benches!(runner, benchmark_mod_power_of_2_shl_unsigned_unsigned); register_unsigned_signed_benches!(runner, benchmark_mod_power_of_2_shl_unsigned_signed); register_unsigned_unsigned_benches!( runner, benchmark_mod_power_of_2_shl_assign_unsigned_unsigned ); register_unsigned_signed_benches!(runner, benchmark_mod_power_of_2_shl_assign_unsigned_signed); } fn demo_mod_power_of_2_shl_unsigned_unsigned< T: ModPowerOf2Shl + PrimitiveUnsigned, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (n, u, pow) in unsigned_triple_gen_var_17::() .get(gm, config) .take(limit) { println!( "{}.mod_power_of_2_shl({}, {}) = {}", n, u, pow, n.mod_power_of_2_shl(u, pow) ); } } fn demo_mod_power_of_2_shl_unsigned_signed< T: ModPowerOf2Shl + PrimitiveUnsigned, U: PrimitiveSigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (n, u, pow) in unsigned_signed_unsigned_triple_gen_var_1::() .get(gm, config) .take(limit) { println!( "{}.mod_power_of_2_shl({}, {}) = {}", n, u, pow, n.mod_power_of_2_shl(u, pow) ); } } fn demo_mod_power_of_2_shl_assign_unsigned_unsigned< T: ModPowerOf2ShlAssign + PrimitiveUnsigned, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut n, u, pow) in unsigned_triple_gen_var_17::() .get(gm, config) .take(limit) { let old_n = n; n.mod_power_of_2_shl_assign(u, pow); println!("x := {old_n}; x.mod_power_of_2_shl_assign({u}, {pow}); x = {n}"); } } fn demo_mod_power_of_2_shl_assign_unsigned_signed< T: ModPowerOf2ShlAssign + PrimitiveUnsigned, U: PrimitiveSigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut n, u, pow) in unsigned_signed_unsigned_triple_gen_var_1::() .get(gm, config) .take(limit) { let old_n = n; n.mod_power_of_2_shl_assign(u, pow); println!("x := {old_n}; x.mod_power_of_2_shl_assign({u}, {pow}); x = {n}"); } } fn benchmark_mod_power_of_2_shl_unsigned_unsigned< T: ModPowerOf2Shl + PrimitiveUnsigned, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_power_of_2_shl({}, u64)", T::NAME, U::NAME), BenchmarkType::Single, unsigned_triple_gen_var_17::().get(gm, config), gm.name(), limit, file_name, &triple_3_bucketer("pow"), &mut [("Malachite", &mut |(x, y, pow)| { no_out!(x.mod_power_of_2_shl(y, pow)) })], ); } fn benchmark_mod_power_of_2_shl_unsigned_signed< T: ModPowerOf2Shl + PrimitiveUnsigned, U: PrimitiveSigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_power_of_2_shl({}, u64)", T::NAME, U::NAME), BenchmarkType::Single, unsigned_signed_unsigned_triple_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &triple_3_bucketer("pow"), &mut [("Malachite", &mut |(x, y, pow)| { no_out!(x.mod_power_of_2_shl(y, pow)) })], ); } fn benchmark_mod_power_of_2_shl_assign_unsigned_unsigned< T: ModPowerOf2ShlAssign + PrimitiveUnsigned, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_power_of_2_shl_assign({}, u64)", T::NAME, U::NAME), BenchmarkType::Single, unsigned_triple_gen_var_17::().get(gm, config), gm.name(), limit, file_name, &triple_3_bucketer("pow"), &mut [("Malachite", &mut |(mut x, y, pow)| { x.mod_power_of_2_shl_assign(y, pow) })], ); } fn benchmark_mod_power_of_2_shl_assign_unsigned_signed< T: ModPowerOf2ShlAssign + PrimitiveUnsigned, U: PrimitiveSigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_power_of_2_shl_assign({}, u64)", T::NAME, U::NAME), BenchmarkType::Single, unsigned_signed_unsigned_triple_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &triple_3_bucketer("pow"), &mut [("Malachite", &mut |(mut x, y, pow)| { x.mod_power_of_2_shl_assign(y, pow) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/mod_power_of_2_shr.rs000064400000000000000000000066031046102023000271330ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::{ModPowerOf2Shr, ModPowerOf2ShrAssign}; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::triple_3_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_signed_unsigned_triple_gen_var_1; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_signed_demos!(runner, demo_mod_power_of_2_shr); register_unsigned_signed_demos!(runner, demo_mod_power_of_2_shr_assign); register_unsigned_signed_benches!(runner, benchmark_mod_power_of_2_shr); register_unsigned_signed_benches!(runner, benchmark_mod_power_of_2_shr_assign); } fn demo_mod_power_of_2_shr< T: ModPowerOf2Shr + PrimitiveUnsigned, U: PrimitiveSigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (n, u, pow) in unsigned_signed_unsigned_triple_gen_var_1::() .get(gm, config) .take(limit) { println!( "{}.mod_power_of_2_shr({}, {}) = {}", n, u, pow, n.mod_power_of_2_shr(u, pow) ); } } fn demo_mod_power_of_2_shr_assign< T: ModPowerOf2ShrAssign + PrimitiveUnsigned, U: PrimitiveSigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut n, u, pow) in unsigned_signed_unsigned_triple_gen_var_1::() .get(gm, config) .take(limit) { let old_n = n; n.mod_power_of_2_shr_assign(u, pow); println!("x := {old_n}; x.mod_power_of_2_shr_assign({u}, {pow}); x = {n}"); } } fn benchmark_mod_power_of_2_shr< T: ModPowerOf2Shr + PrimitiveUnsigned, U: PrimitiveSigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_power_of_2_shr({}, u64)", T::NAME, U::NAME), BenchmarkType::Single, unsigned_signed_unsigned_triple_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &triple_3_bucketer("pow"), &mut [("Malachite", &mut |(x, y, pow)| { no_out!(x.mod_power_of_2_shr(y, pow)) })], ); } fn benchmark_mod_power_of_2_shr_assign< T: ModPowerOf2ShrAssign + PrimitiveUnsigned, U: PrimitiveSigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_power_of_2_shr_assign({}, u64)", T::NAME, U::NAME), BenchmarkType::Single, unsigned_signed_unsigned_triple_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &triple_3_bucketer("pow"), &mut [("Malachite", &mut |(mut x, y, pow)| { x.mod_power_of_2_shr_assign(y, pow) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/mod_power_of_2_square.rs000064400000000000000000000054451046102023000276420ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::pair_2_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_pair_gen_var_17; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_mod_power_of_2_square); register_unsigned_demos!(runner, demo_mod_power_of_2_square_assign); register_unsigned_benches!(runner, benchmark_mod_power_of_2_square); register_unsigned_benches!(runner, benchmark_mod_power_of_2_square_assign); } fn demo_mod_power_of_2_square(gm: GenMode, config: &GenConfig, limit: usize) { for (n, pow) in unsigned_pair_gen_var_17::().get(gm, config).take(limit) { println!( "{}.square() ≡ {} mod 2^{}", n, n.mod_power_of_2_square(pow), pow ); } } fn demo_mod_power_of_2_square_assign( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut n, pow) in unsigned_pair_gen_var_17::().get(gm, config).take(limit) { let old_n = n; n.mod_power_of_2_square_assign(pow); println!("n := {old_n}; n.mod_power_of_2_square_assign({pow}); n = {n}"); } } fn benchmark_mod_power_of_2_square( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_power_of_2_square(u64)", T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_17::().get(gm, config), gm.name(), limit, file_name, &pair_2_bucketer("pow"), &mut [("Malachite", &mut |(n, pow)| { no_out!(n.mod_power_of_2_square(pow)) })], ); } fn benchmark_mod_power_of_2_square_assign( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_power_of_2_square_assign(u64)", T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_17::().get(gm, config), gm.name(), limit, file_name, &pair_2_bucketer("pow"), &mut [("Malachite", &mut |(mut n, pow)| { n.mod_power_of_2_square_assign(pow) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/mod_power_of_2_sub.rs000064400000000000000000000055661046102023000271370ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::triple_3_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_triple_gen_var_11; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_mod_power_of_2_sub); register_unsigned_demos!(runner, demo_mod_power_of_2_sub_assign); register_unsigned_benches!(runner, benchmark_mod_power_of_2_sub); register_unsigned_benches!(runner, benchmark_mod_power_of_2_sub_assign); } fn demo_mod_power_of_2_sub(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y, pow) in unsigned_triple_gen_var_11::() .get(gm, config) .take(limit) { println!( "{} - {} ≡ {} mod 2^{}", x, y, x.mod_power_of_2_sub(y, pow), pow ); } } fn demo_mod_power_of_2_sub_assign( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y, pow) in unsigned_triple_gen_var_11::() .get(gm, config) .take(limit) { let old_x = x; x.mod_power_of_2_sub_assign(y, pow); println!("x := {old_x}; x.mod_power_of_2_sub_assign({y}, {pow}); x = {x}"); } } fn benchmark_mod_power_of_2_sub( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_power_of_2_sub({}, u64)", T::NAME, T::NAME), BenchmarkType::Single, unsigned_triple_gen_var_11::().get(gm, config), gm.name(), limit, file_name, &triple_3_bucketer("pow"), &mut [("Malachite", &mut |(x, y, pow)| { no_out!(x.mod_power_of_2_sub(y, pow)) })], ); } fn benchmark_mod_power_of_2_sub_assign( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_power_of_2_sub_assign({}, u64)", T::NAME, T::NAME), BenchmarkType::Single, unsigned_triple_gen_var_11::().get(gm, config), gm.name(), limit, file_name, &triple_3_bucketer("pow"), &mut [("Malachite", &mut |(mut x, y, pow)| { x.mod_power_of_2_sub_assign(y, pow) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/mod_shl.rs000064400000000000000000000135611046102023000250050ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::{ModShl, ModShlAssign}; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::WrappingFrom; use malachite_base::test_util::bench::bucketers::triple_2_3_product_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ unsigned_signed_unsigned_triple_gen_var_2, unsigned_triple_gen_var_18, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_unsigned_demos!(runner, demo_mod_shl_unsigned_unsigned); register_unsigned_unsigned_signed_match_demos!(runner, demo_mod_shl_unsigned_signed); register_unsigned_unsigned_demos!(runner, demo_mod_shl_assign_unsigned_unsigned); register_unsigned_unsigned_signed_match_demos!(runner, demo_mod_shl_assign_unsigned_signed); register_unsigned_unsigned_benches!(runner, benchmark_mod_shl_unsigned_unsigned); register_unsigned_unsigned_signed_match_benches!(runner, benchmark_mod_shl_unsigned_signed); register_unsigned_unsigned_benches!(runner, benchmark_mod_shl_assign_unsigned_unsigned); register_unsigned_unsigned_signed_match_benches!( runner, benchmark_mod_shl_assign_unsigned_signed ); } fn demo_mod_shl_unsigned_unsigned< T: ModShl + PrimitiveUnsigned, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, u, m) in unsigned_triple_gen_var_18::() .get(gm, config) .take(limit) { println!("{} << {} ≡ {} mod {}", x, u, x.mod_shl(u, m), m); } } fn demo_mod_shl_unsigned_signed< T: ModShl + PrimitiveUnsigned, U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, u, m) in unsigned_signed_unsigned_triple_gen_var_2::() .get(gm, config) .take(limit) { println!("{} << {} ≡ {} mod {}", x, u, x.mod_shl(u, m), m); } } fn demo_mod_shl_assign_unsigned_unsigned< T: ModShlAssign + PrimitiveUnsigned, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, u, m) in unsigned_triple_gen_var_18::() .get(gm, config) .take(limit) { let old_x = x; x.mod_shl_assign(u, m); println!("x := {old_x}; x.mod_shl_assign({u}, {m}); x = {x}"); } } fn demo_mod_shl_assign_unsigned_signed< T: ModShlAssign + PrimitiveUnsigned, U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, u, m) in unsigned_signed_unsigned_triple_gen_var_2::() .get(gm, config) .take(limit) { let old_x = x; x.mod_shl_assign(u, m); println!("x := {old_x}; x.mod_shl_assign({u}, {m}); x = {x}"); } } fn benchmark_mod_shl_unsigned_unsigned< T: ModShl + PrimitiveUnsigned, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_shl({}, {})", T::NAME, U::NAME, T::NAME), BenchmarkType::Single, unsigned_triple_gen_var_18::().get(gm, config), gm.name(), limit, file_name, &triple_2_3_product_bit_bucketer("u", "m"), &mut [("Malachite", &mut |(x, pow, m)| no_out!(x.mod_shl(pow, m)))], ); } fn benchmark_mod_shl_unsigned_signed< T: ModShl + PrimitiveUnsigned, U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_shl({}, {})", T::NAME, S::NAME, T::NAME), BenchmarkType::Single, unsigned_signed_unsigned_triple_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &triple_2_3_product_bit_bucketer("u", "m"), &mut [("Malachite", &mut |(x, u, m)| no_out!(x.mod_shl(u, m)))], ); } fn benchmark_mod_shl_assign_unsigned_unsigned< T: ModShlAssign + PrimitiveUnsigned, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_shl_assign({}, u64)", T::NAME, U::NAME), BenchmarkType::Single, unsigned_triple_gen_var_18::().get(gm, config), gm.name(), limit, file_name, &triple_2_3_product_bit_bucketer("u", "m"), &mut [("Malachite", &mut |(mut x, u, m)| x.mod_shl_assign(u, m))], ); } fn benchmark_mod_shl_assign_unsigned_signed< T: ModShlAssign + PrimitiveUnsigned, U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_shl_assign({}, u64)", T::NAME, S::NAME), BenchmarkType::Single, unsigned_signed_unsigned_triple_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &triple_2_3_product_bit_bucketer("u", "m"), &mut [("Malachite", &mut |(mut x, u, m)| x.mod_shl_assign(u, m))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/mod_shr.rs000064400000000000000000000067131046102023000250140ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::{ModShr, ModShrAssign}; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::WrappingFrom; use malachite_base::test_util::bench::bucketers::triple_2_3_product_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_signed_unsigned_triple_gen_var_2; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_unsigned_signed_match_demos!(runner, demo_mod_shr); register_unsigned_unsigned_signed_match_demos!(runner, demo_mod_shr_assign); register_unsigned_unsigned_signed_match_benches!(runner, benchmark_mod_shr); register_unsigned_unsigned_signed_match_benches!(runner, benchmark_mod_shr_assign); } fn demo_mod_shr< T: ModShr + PrimitiveUnsigned, U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, u, m) in unsigned_signed_unsigned_triple_gen_var_2::() .get(gm, config) .take(limit) { println!("{} >> {} ≡ {} mod {}", x, u, x.mod_shr(u, m), m); } } fn demo_mod_shr_assign< T: ModShrAssign + PrimitiveUnsigned, U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, u, m) in unsigned_signed_unsigned_triple_gen_var_2::() .get(gm, config) .take(limit) { let old_x = x; x.mod_shr_assign(u, m); println!("x := {old_x}; x.mod_shr_assign({u}, {m}); x = {x}"); } } fn benchmark_mod_shr< T: ModShr + PrimitiveUnsigned, U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_shr({}, {})", T::NAME, S::NAME, T::NAME), BenchmarkType::Single, unsigned_signed_unsigned_triple_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &triple_2_3_product_bit_bucketer("u", "m"), &mut [("Malachite", &mut |(x, u, m)| no_out!(x.mod_shr(u, m)))], ); } fn benchmark_mod_shr_assign< T: ModShrAssign + PrimitiveUnsigned, U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_shr_assign({}, u64)", T::NAME, S::NAME), BenchmarkType::Single, unsigned_signed_unsigned_triple_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &triple_2_3_product_bit_bucketer("u", "m"), &mut [("Malachite", &mut |(mut x, u, m)| x.mod_shr_assign(u, m))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/mod_square.rs000064400000000000000000000066071046102023000255220ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::pair_2_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_pair_gen_var_16; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_mod_square); register_unsigned_demos!(runner, demo_mod_square_assign); register_unsigned_benches!(runner, benchmark_mod_square); register_unsigned_benches!(runner, benchmark_mod_square_assign); register_unsigned_benches!(runner, benchmark_mod_square_precomputed_algorithms); } fn demo_mod_square(gm: GenMode, config: &GenConfig, limit: usize) { for (x, m) in unsigned_pair_gen_var_16::().get(gm, config).take(limit) { println!("{}.square() ≡ {} mod {}", x, x.mod_square(m), m); } } fn demo_mod_square_assign(gm: GenMode, config: &GenConfig, limit: usize) { for (mut x, m) in unsigned_pair_gen_var_16::().get(gm, config).take(limit) { let old_x = x; x.mod_square_assign(m); println!("x := {old_x}; x.mod_square_assign({m}); x = {x}"); } } fn benchmark_mod_square( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_square({})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_16::().get(gm, config), gm.name(), limit, file_name, &pair_2_bit_bucketer("m"), &mut [("Malachite", &mut |(x, m)| no_out!(x.mod_square(m)))], ); } fn benchmark_mod_square_assign( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_square({})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_16::().get(gm, config), gm.name(), limit, file_name, &pair_2_bit_bucketer("m"), &mut [("Malachite", &mut |(mut x, m)| x.mod_square_assign(m))], ); } fn benchmark_mod_square_precomputed_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_square({})", T::NAME, T::NAME), BenchmarkType::Algorithms, unsigned_pair_gen_var_16::().get(gm, config), gm.name(), limit, file_name, &pair_2_bit_bucketer("m"), &mut [ ("default", &mut |(x, m)| { for _ in 0..10 { x.mod_square(m); } }), ("precomputed", &mut |(x, m)| { let data = T::precompute_mod_pow_data(&m); for _ in 0..10 { x.mod_square_precomputed(m, &data); } }), ], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/mod_sub.rs000064400000000000000000000051071046102023000250050ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::triple_3_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_triple_gen_var_12; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_mod_sub); register_unsigned_demos!(runner, demo_mod_sub_assign); register_unsigned_benches!(runner, benchmark_mod_sub); register_unsigned_benches!(runner, benchmark_mod_sub_assign); } fn demo_mod_sub(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y, m) in unsigned_triple_gen_var_12::() .get(gm, config) .take(limit) { println!("{} - {} ≡ {} mod {}", x, y, x.mod_sub(y, m), m); } } fn demo_mod_sub_assign(gm: GenMode, config: &GenConfig, limit: usize) { for (mut x, y, m) in unsigned_triple_gen_var_12::() .get(gm, config) .take(limit) { let old_x = x; x.mod_sub_assign(y, m); println!("x := {old_x}; x.mod_sub_assign({y}, {m}); x = {x}"); } } fn benchmark_mod_sub( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_sub({}, {})", T::NAME, T::NAME, T::NAME), BenchmarkType::Single, unsigned_triple_gen_var_12::().get(gm, config), gm.name(), limit, file_name, &triple_3_bit_bucketer("m"), &mut [("Malachite", &mut |(x, y, m)| no_out!(x.mod_sub(y, m)))], ); } fn benchmark_mod_sub_assign( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.mod_sub({}, {})", T::NAME, T::NAME, T::NAME), BenchmarkType::Single, unsigned_triple_gen_var_12::().get(gm, config), gm.name(), limit, file_name, &triple_3_bit_bucketer("m"), &mut [("Malachite", &mut |(mut x, y, m)| x.mod_sub_assign(y, m))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/neg.rs000064400000000000000000000053521046102023000241300ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::bench::bucketers::{primitive_float_bucketer, signed_bit_bucketer}; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{primitive_float_gen, signed_gen_var_1}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_signed_demos!(runner, demo_neg_assign_signed); register_primitive_float_demos!(runner, demo_neg_assign_primitive_float); register_signed_benches!(runner, benchmark_neg_assign_signed); register_primitive_float_benches!(runner, benchmark_neg_assign_primitive_float); } fn demo_neg_assign_signed(gm: GenMode, config: &GenConfig, limit: usize) { for mut i in signed_gen_var_1::().get(gm, config).take(limit) { let old_i = i; i.neg_assign(); println!("i := {old_i}; i.neg_assign(); i = {i}"); } } fn demo_neg_assign_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, ) { for mut x in primitive_float_gen::().get(gm, config).take(limit) { let old_x = x; x.neg_assign(); println!( "x := {}; x.neg_assign(); x = {}", NiceFloat(old_x), NiceFloat(x) ); } } fn benchmark_neg_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.neg_assign()", T::NAME), BenchmarkType::Single, signed_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [("Malachite", &mut |mut i| i.neg_assign())], ); } fn benchmark_neg_assign_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.neg_assign()", T::NAME), BenchmarkType::Single, primitive_float_gen::().get(gm, config), gm.name(), limit, file_name, &primitive_float_bucketer("x"), &mut [("Malachite", &mut |mut x| x.neg_assign())], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/next_power_of_2.rs000064400000000000000000000100141046102023000264450ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::bench::bucketers::{ primitive_float_bucketer, unsigned_bit_bucketer, }; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{primitive_float_gen_var_19, unsigned_gen_var_14}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_primitive_float_demos!(runner, demo_next_power_of_2_primitive_float); register_unsigned_demos!(runner, demo_next_power_of_2_assign_unsigned); register_primitive_float_demos!(runner, demo_next_power_of_2_assign_primitive_float); register_primitive_float_benches!(runner, benchmark_next_power_of_2_primitive_float); register_unsigned_benches!(runner, benchmark_next_power_of_2_assign_unsigned); register_primitive_float_benches!(runner, benchmark_next_power_of_2_assign_primitive_float); } fn demo_next_power_of_2_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, ) { for n in primitive_float_gen_var_19::() .get(gm, config) .take(limit) { println!( "{}.next_power_of_2() = {}", NiceFloat(n), NiceFloat(n.next_power_of_2()) ); } } fn demo_next_power_of_2_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for mut n in unsigned_gen_var_14::().get(gm, config).take(limit) { let old_n = n; n.next_power_of_2_assign(); println!("n := {old_n}; n.next_power_of_2_assign(); n = {n}"); } } fn demo_next_power_of_2_assign_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, ) { for mut n in primitive_float_gen_var_19::() .get(gm, config) .take(limit) { let old_n = n; n.next_power_of_2_assign(); println!( "n := {}; n.next_power_of_2_assign(); n = {}", NiceFloat(old_n), NiceFloat(n) ); } } fn benchmark_next_power_of_2_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.next_power_of_2()", T::NAME), BenchmarkType::Single, primitive_float_gen_var_19::().get(gm, config), gm.name(), limit, file_name, &primitive_float_bucketer("x"), &mut [("Malachite", &mut |n| no_out!(n.next_power_of_2()))], ); } fn benchmark_next_power_of_2_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.next_power_of_2_assign()", T::NAME), BenchmarkType::Single, unsigned_gen_var_14::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [("Malachite", &mut |mut n| n.next_power_of_2_assign())], ); } fn benchmark_next_power_of_2_assign_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.next_power_of_2_assign()", T::NAME), BenchmarkType::Single, primitive_float_gen_var_19::().get(gm, config), gm.name(), limit, file_name, &primitive_float_bucketer("x"), &mut [("Malachite", &mut |mut n| n.next_power_of_2_assign())], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/overflowing_abs.rs000064400000000000000000000033511046102023000265420ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::test_util::bench::bucketers::signed_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::signed_gen; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_signed_demos!(runner, demo_overflowing_abs_assign); register_signed_benches!(runner, benchmark_overflowing_abs_assign); } fn demo_overflowing_abs_assign(gm: GenMode, config: &GenConfig, limit: usize) { for mut i in signed_gen::().get(gm, config).take(limit) { let old_i = i; let overflow = i.overflowing_abs_assign(); println!("i := {old_i}; i.overflowing_abs_assign() = {overflow}; i = {i}"); } } fn benchmark_overflowing_abs_assign( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.overflowing_abs_assign()", T::NAME), BenchmarkType::Single, signed_gen::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [( "Malachite", &mut |mut i| no_out!(i.overflowing_abs_assign()), )], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/overflowing_add.rs000064400000000000000000000114331046102023000265250ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::pair_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_pair_gen, unsigned_pair_gen_var_27}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_overflowing_add_unsigned); register_signed_demos!(runner, demo_overflowing_add_signed); register_unsigned_demos!(runner, demo_overflowing_add_assign_unsigned); register_signed_demos!(runner, demo_overflowing_add_assign_signed); register_unsigned_benches!(runner, benchmark_overflowing_add_unsigned); register_signed_benches!(runner, benchmark_overflowing_add_signed); register_unsigned_benches!(runner, benchmark_overflowing_add_assign_unsigned); register_signed_benches!(runner, benchmark_overflowing_add_assign_signed); } fn demo_overflowing_add_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, y) in unsigned_pair_gen_var_27::().get(gm, config).take(limit) { println!("{}.overflowing_add({}) = {:?}", x, y, x.overflowing_add(y)); } } fn demo_overflowing_add_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in signed_pair_gen::().get(gm, config).take(limit) { println!( "({}).overflowing_add({}) = {:?}", x, y, x.overflowing_add(y) ); } } fn demo_overflowing_add_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y) in unsigned_pair_gen_var_27::().get(gm, config).take(limit) { let old_x = x; let overflow = x.overflowing_add_assign(y); println!("x := {old_x}; x.overflowing_add_assign({y}) = {overflow}; x = {x}"); } } fn demo_overflowing_add_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y) in signed_pair_gen::().get(gm, config).take(limit) { let old_x = x; let overflow = x.overflowing_add_assign(y); println!("x := {old_x}; x.overflowing_add_assign({y}) = {overflow}; x = {x}"); } } fn benchmark_overflowing_add_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.overflowing_add({})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_27::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.overflowing_add(y)))], ); } fn benchmark_overflowing_add_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.overflowing_add({})", T::NAME, T::NAME), BenchmarkType::Single, signed_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.overflowing_add(y)))], ); } fn benchmark_overflowing_add_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.overflowing_add_assign({})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_27::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y)| { no_out!(x.overflowing_add_assign(y)) })], ); } fn benchmark_overflowing_add_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.overflowing_add_assign({})", T::NAME, T::NAME), BenchmarkType::Single, signed_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y)| { no_out!(x.overflowing_add_assign(y)) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/overflowing_add_mul.rs000064400000000000000000000125701046102023000274050ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::triple_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_triple_gen, unsigned_triple_gen_var_19}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_overflowing_add_mul_unsigned); register_signed_demos!(runner, demo_overflowing_add_mul_signed); register_unsigned_demos!(runner, demo_overflowing_add_mul_assign_unsigned); register_signed_demos!(runner, demo_overflowing_add_mul_assign_signed); register_unsigned_benches!(runner, benchmark_overflowing_add_mul_unsigned); register_signed_benches!(runner, benchmark_overflowing_add_mul_signed); register_unsigned_benches!(runner, benchmark_overflowing_add_mul_assign_unsigned); register_signed_benches!(runner, benchmark_overflowing_add_mul_assign_signed); } fn demo_overflowing_add_mul_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, y, z) in unsigned_triple_gen_var_19::() .get(gm, config) .take(limit) { println!( "{}.overflowing_add_mul({}, {}) = {:?}", x, y, z, x.overflowing_add_mul(y, z) ); } } fn demo_overflowing_add_mul_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, y, z) in signed_triple_gen::().get(gm, config).take(limit) { println!( "{}.overflowing_add_mul({}, {}) = {:?}", x, y, z, x.overflowing_add_mul(y, z) ); } } fn demo_overflowing_add_mul_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y, z) in unsigned_triple_gen_var_19::() .get(gm, config) .take(limit) { let old_x = x; let overflow = x.overflowing_add_mul_assign(y, z); println!("x := {old_x}; x.overflowing_add_mul_assign({y}, {z}) = {overflow}; x = {x}"); } } fn demo_overflowing_add_mul_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y, z) in signed_triple_gen::().get(gm, config).take(limit) { let old_x = x; let overflow = x.overflowing_add_mul_assign(y, z); println!("x := {old_x}; x.overflowing_add_mul_assign({y}, {z}) = {overflow}; x = {x}"); } } fn benchmark_overflowing_add_mul_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.overflowing_add_mul({}, {})", T::NAME, T::NAME, T::NAME), BenchmarkType::Single, unsigned_triple_gen_var_19::().get(gm, config), gm.name(), limit, file_name, &triple_max_bit_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(x, y, z)| { no_out!(x.overflowing_add_mul(y, z)) })], ); } fn benchmark_overflowing_add_mul_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.overflowing_add_mul({}, {})", T::NAME, T::NAME, T::NAME), BenchmarkType::Single, signed_triple_gen::().get(gm, config), gm.name(), limit, file_name, &triple_max_bit_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(x, y, z)| { no_out!(x.overflowing_add_mul(y, z)) })], ); } fn benchmark_overflowing_add_mul_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!( "{}.overflowing_add_mul_assign({}, {})", T::NAME, T::NAME, T::NAME ), BenchmarkType::Single, unsigned_triple_gen_var_19::().get(gm, config), gm.name(), limit, file_name, &triple_max_bit_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(mut x, y, z)| { no_out!(x.overflowing_add_mul_assign(y, z)) })], ); } fn benchmark_overflowing_add_mul_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!( "{}.overflowing_add_mul_assign({}, {})", T::NAME, T::NAME, T::NAME ), BenchmarkType::Single, signed_triple_gen::().get(gm, config), gm.name(), limit, file_name, &triple_max_bit_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(mut x, y, z)| { no_out!(x.overflowing_add_mul_assign(y, z)) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/overflowing_div.rs000064400000000000000000000115611046102023000265610ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::pair_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_pair_gen_var_6, unsigned_pair_gen_var_12}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_overflowing_div_unsigned); register_signed_demos!(runner, demo_overflowing_div_signed); register_unsigned_demos!(runner, demo_overflowing_div_assign_unsigned); register_signed_demos!(runner, demo_overflowing_div_assign_signed); register_unsigned_benches!(runner, benchmark_overflowing_div_unsigned); register_signed_benches!(runner, benchmark_overflowing_div_signed); register_unsigned_benches!(runner, benchmark_overflowing_div_assign_unsigned); register_signed_benches!(runner, benchmark_overflowing_div_assign_signed); } fn demo_overflowing_div_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, y) in unsigned_pair_gen_var_12::() .get(gm, config) .take(limit) { println!("{}.overflowing_div({}) = {:?}", x, y, x.overflowing_div(y)); } } fn demo_overflowing_div_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in signed_pair_gen_var_6::().get(gm, config).take(limit) { println!( "({}).overflowing_div({}) = {:?}", x, y, x.overflowing_div(y) ); } } fn demo_overflowing_div_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y) in unsigned_pair_gen_var_12::() .get(gm, config) .take(limit) { let old_x = x; let overflow = x.overflowing_div_assign(y); println!("x := {old_x}; x.overflowing_div_assign({y}) = {overflow}; x = {x}"); } } fn demo_overflowing_div_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y) in signed_pair_gen_var_6::().get(gm, config).take(limit) { let old_x = x; let overflow = x.overflowing_div_assign(y); println!("x := {old_x}; x.overflowing_div_assign({y}) = {overflow}; x = {x}"); } } fn benchmark_overflowing_div_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.overflowing_div({})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_12::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.overflowing_div(y)))], ); } fn benchmark_overflowing_div_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.overflowing_div({})", T::NAME, T::NAME), BenchmarkType::Single, signed_pair_gen_var_6::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.overflowing_div(y)))], ); } fn benchmark_overflowing_div_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.overflowing_div_assign({})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_12::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y)| { no_out!(x.overflowing_div_assign(y)) })], ); } fn benchmark_overflowing_div_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.overflowing_div_assign({})", T::NAME, T::NAME), BenchmarkType::Single, signed_pair_gen_var_6::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y)| { no_out!(x.overflowing_div_assign(y)) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/overflowing_mul.rs000064400000000000000000000114331046102023000265720ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::pair_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_pair_gen, unsigned_pair_gen_var_27}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_overflowing_mul_unsigned); register_signed_demos!(runner, demo_overflowing_mul_signed); register_unsigned_demos!(runner, demo_overflowing_mul_assign_unsigned); register_signed_demos!(runner, demo_overflowing_mul_assign_signed); register_unsigned_benches!(runner, benchmark_overflowing_mul_unsigned); register_signed_benches!(runner, benchmark_overflowing_mul_signed); register_unsigned_benches!(runner, benchmark_overflowing_mul_assign_unsigned); register_signed_benches!(runner, benchmark_overflowing_mul_assign_signed); } fn demo_overflowing_mul_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, y) in unsigned_pair_gen_var_27::().get(gm, config).take(limit) { println!("{}.overflowing_mul({}) = {:?}", x, y, x.overflowing_mul(y)); } } fn demo_overflowing_mul_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in signed_pair_gen::().get(gm, config).take(limit) { println!( "({}).overflowing_mul({}) = {:?}", x, y, x.overflowing_mul(y) ); } } fn demo_overflowing_mul_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y) in unsigned_pair_gen_var_27::().get(gm, config).take(limit) { let old_x = x; let overflow = x.overflowing_mul_assign(y); println!("x := {old_x}; x.overflowing_mul_assign({y}) = {overflow}; x = {x}"); } } fn demo_overflowing_mul_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y) in signed_pair_gen::().get(gm, config).take(limit) { let old_x = x; let overflow = x.overflowing_mul_assign(y); println!("x := {old_x}; x.overflowing_mul_assign({y}) = {overflow}; x = {x}"); } } fn benchmark_overflowing_mul_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.overflowing_mul({})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_27::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.overflowing_mul(y)))], ); } fn benchmark_overflowing_mul_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.overflowing_mul({})", T::NAME, T::NAME), BenchmarkType::Single, signed_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.overflowing_mul(y)))], ); } fn benchmark_overflowing_mul_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.overflowing_mul_assign({})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_27::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y)| { no_out!(x.overflowing_mul_assign(y)) })], ); } fn benchmark_overflowing_mul_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.overflowing_mul_assign({})", T::NAME, T::NAME), BenchmarkType::Single, signed_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y)| { no_out!(x.overflowing_mul_assign(y)) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/overflowing_neg.rs000064400000000000000000000056071046102023000265540ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::{signed_bit_bucketer, unsigned_bit_bucketer}; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_gen, unsigned_gen}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_overflowing_neg_assign_unsigned); register_signed_demos!(runner, demo_overflowing_neg_assign_signed); register_unsigned_benches!(runner, benchmark_overflowing_neg_assign_unsigned); register_signed_benches!(runner, benchmark_overflowing_neg_assign_signed); } fn demo_overflowing_neg_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for mut u in unsigned_gen::().get(gm, config).take(limit) { let old_u = u; let overflow = u.overflowing_neg_assign(); println!("u := {old_u}; u.overflowing_neg_assign() = {overflow}; u = {u}"); } } fn demo_overflowing_neg_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for mut i in signed_gen::().get(gm, config).take(limit) { let old_i = i; let overflow = i.overflowing_neg_assign(); println!("i := {old_i}; i.overflowing_neg_assign() = {overflow}; i = {i}"); } } fn benchmark_overflowing_neg_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.overflowing_neg_assign()", T::NAME), BenchmarkType::Single, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [( "Malachite", &mut |mut i| no_out!(i.overflowing_neg_assign()), )], ); } fn benchmark_overflowing_neg_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.overflowing_neg_assign()", T::NAME), BenchmarkType::Single, signed_gen::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [( "Malachite", &mut |mut i| no_out!(i.overflowing_neg_assign()), )], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/overflowing_pow.rs000064400000000000000000000057631046102023000266130ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::pair_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_unsigned_pair_gen, unsigned_pair_gen}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_overflowing_pow_assign_unsigned); register_signed_demos!(runner, demo_overflowing_pow_assign_signed); register_unsigned_benches!(runner, benchmark_overflowing_pow_assign_unsigned); register_signed_benches!(runner, benchmark_overflowing_pow_assign_signed); } fn demo_overflowing_pow_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y) in unsigned_pair_gen::().get(gm, config).take(limit) { let old_x = x; let overflow = x.overflowing_pow_assign(y); println!("x := {old_x}; x.overflowing_pow_assign({y}) = {overflow}; x = {x}"); } } fn demo_overflowing_pow_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y) in signed_unsigned_pair_gen::() .get(gm, config) .take(limit) { let old_x = x; let overflow = x.overflowing_pow_assign(y); println!("x := {old_x}; x.overflowing_pow_assign({y}) = {overflow}; x = {x}"); } } fn benchmark_overflowing_pow_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.overflowing_pow_assign(u64)", T::NAME), BenchmarkType::Single, unsigned_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y)| { no_out!(x.overflowing_pow_assign(y)) })], ); } fn benchmark_overflowing_pow_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.overflowing_pow_assign(u64)", T::NAME), BenchmarkType::Single, signed_unsigned_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y)| { no_out!(x.overflowing_pow_assign(y)) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/overflowing_square.rs000064400000000000000000000112001046102023000272650ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::{signed_bit_bucketer, unsigned_bit_bucketer}; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_gen, unsigned_gen}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_overflowing_square_unsigned); register_signed_demos!(runner, demo_overflowing_square_signed); register_unsigned_demos!(runner, demo_overflowing_square_assign_unsigned); register_signed_demos!(runner, demo_overflowing_square_assign_signed); register_unsigned_benches!(runner, benchmark_overflowing_square_unsigned); register_signed_benches!(runner, benchmark_overflowing_square_signed); register_unsigned_benches!(runner, benchmark_overflowing_square_assign_unsigned); register_signed_benches!(runner, benchmark_overflowing_square_assign_signed); } fn demo_overflowing_square_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for x in unsigned_gen::().get(gm, config).take(limit) { println!("{}.overflowing_square() = {:?}", x, x.overflowing_square()); } } fn demo_overflowing_square_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for x in signed_gen::().get(gm, config).take(limit) { println!("{}.overflowing_square() = {:?}", x, x.overflowing_square()); } } fn demo_overflowing_square_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for mut x in unsigned_gen::().get(gm, config).take(limit) { let old_x = x; let overflow = x.overflowing_square_assign(); println!("x := {old_x}; x.overflowing_square_assign() = {overflow}; x = {x}"); } } fn demo_overflowing_square_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for mut x in signed_gen::().get(gm, config).take(limit) { let old_x = x; let overflow = x.overflowing_square_assign(); println!("x := {old_x}; x.overflowing_square_assign() = {overflow}; x = {x}"); } } fn benchmark_overflowing_square_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.overflowing_square()", T::NAME), BenchmarkType::Single, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [("Malachite", &mut |x| no_out!(x.overflowing_square()))], ); } fn benchmark_overflowing_square_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.overflowing_square()", T::NAME), BenchmarkType::Single, signed_gen::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [("Malachite", &mut |x| no_out!(x.overflowing_square()))], ); } fn benchmark_overflowing_square_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.overflowing_square_assign()", T::NAME), BenchmarkType::Single, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [("Malachite", &mut |mut x| { no_out!(x.overflowing_square_assign()) })], ); } fn benchmark_overflowing_square_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.overflowing_square_assign()", T::NAME), BenchmarkType::Single, signed_gen::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [("Malachite", &mut |mut x| { no_out!(x.overflowing_square_assign()) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/overflowing_sub.rs000064400000000000000000000114331046102023000265660ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::pair_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_pair_gen, unsigned_pair_gen_var_27}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_overflowing_sub_unsigned); register_signed_demos!(runner, demo_overflowing_sub_signed); register_unsigned_demos!(runner, demo_overflowing_sub_assign_unsigned); register_signed_demos!(runner, demo_overflowing_sub_assign_signed); register_unsigned_benches!(runner, benchmark_overflowing_sub_unsigned); register_signed_benches!(runner, benchmark_overflowing_sub_signed); register_unsigned_benches!(runner, benchmark_overflowing_sub_assign_unsigned); register_signed_benches!(runner, benchmark_overflowing_sub_assign_signed); } fn demo_overflowing_sub_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, y) in unsigned_pair_gen_var_27::().get(gm, config).take(limit) { println!("{}.overflowing_sub({}) = {:?}", x, y, x.overflowing_sub(y)); } } fn demo_overflowing_sub_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in signed_pair_gen::().get(gm, config).take(limit) { println!( "({}).overflowing_sub({}) = {:?}", x, y, x.overflowing_sub(y) ); } } fn demo_overflowing_sub_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y) in unsigned_pair_gen_var_27::().get(gm, config).take(limit) { let old_x = x; let overflow = x.overflowing_sub_assign(y); println!("x := {old_x}; x.overflowing_sub_assign({y}) = {overflow}; x = {x}"); } } fn demo_overflowing_sub_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y) in signed_pair_gen::().get(gm, config).take(limit) { let old_x = x; let overflow = x.overflowing_sub_assign(y); println!("x := {old_x}; x.overflowing_sub_assign({y}) = {overflow}; x = {x}"); } } fn benchmark_overflowing_sub_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.overflowing_sub({})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_27::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.overflowing_sub(y)))], ); } fn benchmark_overflowing_sub_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.overflowing_sub({})", T::NAME, T::NAME), BenchmarkType::Single, signed_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.overflowing_sub(y)))], ); } fn benchmark_overflowing_sub_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.overflowing_sub_assign({})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_27::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y)| { no_out!(x.overflowing_sub_assign(y)) })], ); } fn benchmark_overflowing_sub_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.overflowing_sub_assign({})", T::NAME, T::NAME), BenchmarkType::Single, signed_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y)| { no_out!(x.overflowing_sub_assign(y)) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/overflowing_sub_mul.rs000064400000000000000000000125701046102023000274460ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::triple_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_triple_gen, unsigned_triple_gen_var_19}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_overflowing_sub_mul_unsigned); register_signed_demos!(runner, demo_overflowing_sub_mul_signed); register_unsigned_demos!(runner, demo_overflowing_sub_mul_assign_unsigned); register_signed_demos!(runner, demo_overflowing_sub_mul_assign_signed); register_unsigned_benches!(runner, benchmark_overflowing_sub_mul_unsigned); register_signed_benches!(runner, benchmark_overflowing_sub_mul_signed); register_unsigned_benches!(runner, benchmark_overflowing_sub_mul_assign_unsigned); register_signed_benches!(runner, benchmark_overflowing_sub_mul_assign_signed); } fn demo_overflowing_sub_mul_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, y, z) in unsigned_triple_gen_var_19::() .get(gm, config) .take(limit) { println!( "{}.overflowing_sub_mul({}, {}) = {:?}", x, y, z, x.overflowing_sub_mul(y, z) ); } } fn demo_overflowing_sub_mul_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, y, z) in signed_triple_gen::().get(gm, config).take(limit) { println!( "{}.overflowing_sub_mul({}, {}) = {:?}", x, y, z, x.overflowing_sub_mul(y, z) ); } } fn demo_overflowing_sub_mul_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y, z) in unsigned_triple_gen_var_19::() .get(gm, config) .take(limit) { let old_x = x; let overflow = x.overflowing_sub_mul_assign(y, z); println!("x := {old_x}; x.overflowing_sub_mul_assign({y}, {z}) = {overflow}; x = {x}"); } } fn demo_overflowing_sub_mul_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y, z) in signed_triple_gen::().get(gm, config).take(limit) { let old_x = x; let overflow = x.overflowing_sub_mul_assign(y, z); println!("x := {old_x}; x.overflowing_sub_mul_assign({y}, {z}) = {overflow}; x = {x}"); } } fn benchmark_overflowing_sub_mul_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.overflowing_sub_mul({}, {})", T::NAME, T::NAME, T::NAME), BenchmarkType::Single, unsigned_triple_gen_var_19::().get(gm, config), gm.name(), limit, file_name, &triple_max_bit_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(x, y, z)| { no_out!(x.overflowing_sub_mul(y, z)) })], ); } fn benchmark_overflowing_sub_mul_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.overflowing_sub_mul({}, {})", T::NAME, T::NAME, T::NAME), BenchmarkType::Single, signed_triple_gen::().get(gm, config), gm.name(), limit, file_name, &triple_max_bit_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(x, y, z)| { no_out!(x.overflowing_sub_mul(y, z)) })], ); } fn benchmark_overflowing_sub_mul_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!( "{}.overflowing_sub_mul_assign({}, {})", T::NAME, T::NAME, T::NAME ), BenchmarkType::Single, unsigned_triple_gen_var_19::().get(gm, config), gm.name(), limit, file_name, &triple_max_bit_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(mut x, y, z)| { no_out!(x.overflowing_sub_mul_assign(y, z)) })], ); } fn benchmark_overflowing_sub_mul_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!( "{}.overflowing_sub_mul_assign({}, {})", T::NAME, T::NAME, T::NAME ), BenchmarkType::Single, signed_triple_gen::().get(gm, config), gm.name(), limit, file_name, &triple_max_bit_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(mut x, y, z)| { no_out!(x.overflowing_sub_mul_assign(y, z)) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/parity.rs000064400000000000000000000101441046102023000246620ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::{signed_bit_bucketer, unsigned_bit_bucketer}; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_gen, unsigned_gen}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_even_unsigned); register_signed_demos!(runner, demo_even_signed); register_unsigned_demos!(runner, demo_odd_unsigned); register_signed_demos!(runner, demo_odd_signed); register_unsigned_benches!(runner, benchmark_even_unsigned); register_signed_benches!(runner, benchmark_even_signed); register_unsigned_benches!(runner, benchmark_odd_unsigned); register_signed_benches!(runner, benchmark_odd_signed); } fn demo_even_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for u in unsigned_gen::().get(gm, config).take(limit) { if u.even() { println!("{u} is even"); } else { println!("{u} is not even"); } } } fn demo_even_signed(gm: GenMode, config: &GenConfig, limit: usize) { for i in signed_gen::().get(gm, config).take(limit) { if i.even() { println!("{i} is even"); } else { println!("{i} is not even"); } } } fn demo_odd_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for u in unsigned_gen::().get(gm, config).take(limit) { if u.odd() { println!("{u} is odd"); } else { println!("{u} is not odd"); } } } fn demo_odd_signed(gm: GenMode, config: &GenConfig, limit: usize) { for i in signed_gen::().get(gm, config).take(limit) { if i.odd() { println!("{i} is odd"); } else { println!("{i} is not odd"); } } } fn benchmark_even_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.even()", T::NAME), BenchmarkType::Single, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [("Malachite", &mut |u| no_out!(u.even()))], ); } fn benchmark_even_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.even()", T::NAME), BenchmarkType::Single, signed_gen::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [("Malachite", &mut |i| no_out!(i.even()))], ); } fn benchmark_odd_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.odd()", T::NAME), BenchmarkType::Single, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [("Malachite", &mut |u| no_out!(u.odd()))], ); } fn benchmark_odd_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.odd()", T::NAME), BenchmarkType::Single, signed_gen::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [("Malachite", &mut |i| no_out!(i.odd()))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/pow.rs000064400000000000000000000120601046102023000241560ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::bench::bucketers::{ pair_1_bit_bucketer, pair_1_primitive_float_bucketer, }; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ primitive_float_pair_gen, primitive_float_signed_pair_gen, signed_unsigned_pair_gen_var_15, unsigned_pair_gen_var_29, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_pow_assign_unsigned); register_signed_demos!(runner, demo_pow_assign_signed); register_primitive_float_demos!(runner, demo_pow_assign_i64_primitive_float); register_primitive_float_demos!(runner, demo_pow_assign_primitive_float_primitive_float); register_unsigned_benches!(runner, benchmark_pow_assign_unsigned); register_signed_benches!(runner, benchmark_pow_assign_signed); register_primitive_float_benches!(runner, benchmark_pow_assign_i64_primitive_float); register_primitive_float_benches!(runner, benchmark_pow_assign_primitive_float_primitive_float); } fn demo_pow_assign_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for (mut x, y) in unsigned_pair_gen_var_29::().get(gm, config).take(limit) { let old_x = x; x.pow_assign(y); println!("x := {old_x}; x.pow_assign({y}); x = {x}"); } } fn demo_pow_assign_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (mut x, y) in signed_unsigned_pair_gen_var_15::() .get(gm, config) .take(limit) { let old_x = x; x.pow_assign(y); println!("x := {old_x}; x.pow_assign({y}); x = {x}"); } } fn demo_pow_assign_i64_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y) in primitive_float_signed_pair_gen::() .get(gm, config) .take(limit) { let old_x = x; x.pow_assign(y); println!( "x := {}; x.pow_assign({}); x = {}", NiceFloat(old_x), y, NiceFloat(x) ); } } fn demo_pow_assign_primitive_float_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y) in primitive_float_pair_gen::().get(gm, config).take(limit) { let old_x = x; x.pow_assign(y); println!( "x := {}; x.pow_assign({}); x = {}", NiceFloat(old_x), NiceFloat(y), NiceFloat(x) ); } } fn benchmark_pow_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.pow_assign(u64)", T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_29::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("x"), &mut [("Malachite", &mut |(mut x, y)| x.pow_assign(y))], ); } fn benchmark_pow_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.pow_assign(u64)", T::NAME), BenchmarkType::Single, signed_unsigned_pair_gen_var_15::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("x"), &mut [("Malachite", &mut |(mut x, y)| x.pow_assign(y))], ); } fn benchmark_pow_assign_i64_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.pow_assign(i64)", T::NAME), BenchmarkType::Single, primitive_float_signed_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_1_primitive_float_bucketer("x"), &mut [("Malachite", &mut |(mut x, y)| x.pow_assign(y))], ); } fn benchmark_pow_assign_primitive_float_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.pow_assign({})", T::NAME, T::NAME), BenchmarkType::Single, primitive_float_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_1_primitive_float_bucketer("x"), &mut [("Malachite", &mut |(mut x, y)| x.pow_assign(y))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/power_of_2.rs000064400000000000000000000070011046102023000254110ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::bench::bucketers::{signed_abs_bucketer, unsigned_direct_bucketer}; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ signed_gen_var_11, unsigned_gen_var_15, unsigned_gen_var_16, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_power_of_2_unsigned); register_signed_demos!(runner, demo_power_of_2_signed); register_primitive_float_demos!(runner, demo_power_of_2_primitive_float); register_unsigned_benches!(runner, benchmark_power_of_2_unsigned); register_signed_benches!(runner, benchmark_power_of_2_signed); register_primitive_float_benches!(runner, benchmark_power_of_2_primitive_float); } fn demo_power_of_2_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for pow in unsigned_gen_var_15::().get(gm, config).take(limit) { println!("2^{} = {}", pow, T::power_of_2(pow)); } } fn demo_power_of_2_signed(gm: GenMode, config: &GenConfig, limit: usize) { for pow in unsigned_gen_var_16::().get(gm, config).take(limit) { println!("2^{} = {}", pow, T::power_of_2(pow)); } } fn demo_power_of_2_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, ) { for pow in signed_gen_var_11::().get(gm, config).take(limit) { println!("2^({}) = {}", pow, NiceFloat(T::power_of_2(pow))); } } fn benchmark_power_of_2_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.power_of_2(u64)", T::NAME), BenchmarkType::Single, unsigned_gen_var_15::().get(gm, config), gm.name(), limit, file_name, &unsigned_direct_bucketer(), &mut [("Malachite", &mut |pow| no_out!(T::power_of_2(pow)))], ); } fn benchmark_power_of_2_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.power_of_2(u64)", T::NAME), BenchmarkType::Single, unsigned_gen_var_16::().get(gm, config), gm.name(), limit, file_name, &unsigned_direct_bucketer(), &mut [("Malachite", &mut |pow| no_out!(T::power_of_2(pow)))], ); } fn benchmark_power_of_2_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.power_of_2(i64)", T::NAME), BenchmarkType::Single, signed_gen_var_11::().get(gm, config), gm.name(), limit, file_name, &signed_abs_bucketer("pow"), &mut [("Malachite", &mut |pow| no_out!(T::power_of_2(pow)))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/primorial.rs000064400000000000000000000113011046102023000253440ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::unsigned_direct_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ unsigned_gen, unsigned_gen_var_27, unsigned_gen_var_28, }; use malachite_base::test_util::num::arithmetic::primorial::{ checked_primorial_naive, checked_product_of_first_n_primes_naive, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_primorial); register_unsigned_demos!(runner, demo_checked_primorial); register_unsigned_demos!(runner, demo_product_of_first_n_primes); register_unsigned_demos!(runner, demo_checked_product_of_first_n_primes); register_unsigned_benches!(runner, benchmark_primorial_algorithms); register_unsigned_benches!(runner, benchmark_checked_primorial); register_unsigned_benches!(runner, benchmark_product_of_first_n_primes_algorithms); register_unsigned_benches!(runner, benchmark_checked_product_of_first_n_primes); } fn demo_primorial(gm: GenMode, config: &GenConfig, limit: usize) { for n in unsigned_gen_var_27::().get(gm, config).take(limit) { println!("{}# = {}", n, T::primorial(n)); } } fn demo_checked_primorial(gm: GenMode, config: &GenConfig, limit: usize) { for n in unsigned_gen().get(gm, config).take(limit) { println!("{}# = {:?}", n, T::checked_primorial(n)); } } fn demo_product_of_first_n_primes( gm: GenMode, config: &GenConfig, limit: usize, ) { for n in unsigned_gen_var_28::().get(gm, config).take(limit) { println!("p_{}# = {}", n, T::product_of_first_n_primes(n)); } } fn demo_checked_product_of_first_n_primes( gm: GenMode, config: &GenConfig, limit: usize, ) { for n in unsigned_gen().get(gm, config).take(limit) { println!("p_{}# = {:?}", n, T::checked_product_of_first_n_primes(n)); } } fn benchmark_primorial_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}::primorial(u64)", T::NAME), BenchmarkType::Algorithms, unsigned_gen_var_27::().get(gm, config), gm.name(), limit, file_name, &unsigned_direct_bucketer(), &mut [ ("default", &mut |n| no_out!(T::primorial(n))), ("naive", &mut |n| { no_out!(checked_primorial_naive::(n).unwrap()) }), ], ); } fn benchmark_checked_primorial( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}::checked_primorial(u64)", T::NAME), BenchmarkType::Single, unsigned_gen().get(gm, config), gm.name(), limit, file_name, &unsigned_direct_bucketer(), &mut [("Malachite", &mut |n| no_out!(T::checked_primorial(n)))], ); } fn benchmark_product_of_first_n_primes_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}::product_of_first_n_primes(u64)", T::NAME), BenchmarkType::Algorithms, unsigned_gen_var_28::().get(gm, config), gm.name(), limit, file_name, &unsigned_direct_bucketer(), &mut [ ("default", &mut |n| no_out!(T::product_of_first_n_primes(n))), ("naive", &mut |n| { no_out!(checked_product_of_first_n_primes_naive::(n).unwrap()) }), ], ); } fn benchmark_checked_product_of_first_n_primes( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}::checked_product_of_first_n_primes(u64)", T::NAME), BenchmarkType::Single, unsigned_gen().get(gm, config), gm.name(), limit, file_name, &unsigned_direct_bucketer(), &mut [("Malachite", &mut |n| { no_out!(T::checked_product_of_first_n_primes(n)) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/reciprocal.rs000064400000000000000000000054501046102023000255010ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::bench::bucketers::primitive_float_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::primitive_float_gen; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_primitive_float_demos!(runner, demo_reciprocal_primitive_float); register_primitive_float_demos!(runner, demo_reciprocal_assign_primitive_float); register_primitive_float_benches!(runner, benchmark_reciprocal_primitive_float); register_primitive_float_benches!(runner, benchmark_reciprocal_assign_primitive_float); } fn demo_reciprocal_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, ) { for f in primitive_float_gen::().get(gm, config).take(limit) { println!( "({}).reciprocal() = {}", NiceFloat(f), NiceFloat(f.reciprocal()) ); } } fn demo_reciprocal_assign_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, ) { for mut f in primitive_float_gen::().get(gm, config).take(limit) { let old_f = f; f.reciprocal_assign(); println!( "f := {}; f.reciprocal_assign(); x = {}", NiceFloat(old_f), NiceFloat(f) ); } } fn benchmark_reciprocal_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.reciprocal()", T::NAME), BenchmarkType::Single, primitive_float_gen::().get(gm, config), gm.name(), limit, file_name, &primitive_float_bucketer("f"), &mut [("Malachite", &mut |f| no_out!(f.reciprocal()))], ); } fn benchmark_reciprocal_assign_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.reciprocal_assign()", T::NAME), BenchmarkType::Single, primitive_float_gen::().get(gm, config), gm.name(), limit, file_name, &primitive_float_bucketer("f"), &mut [("Malachite", &mut |mut f| f.reciprocal_assign())], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/root.rs000064400000000000000000001046431046102023000243450ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::named::Named; use malachite_base::num::arithmetic::root::{ cbrt_chebyshev_approx_u32, cbrt_chebyshev_approx_u64, fast_ceiling_root_u32, fast_ceiling_root_u64, fast_checked_root_u32, fast_checked_root_u64, fast_floor_cbrt_u32, fast_floor_cbrt_u64, fast_floor_root_u32, fast_floor_root_u64, fast_root_rem_u32, fast_root_rem_u64, floor_root_approx_and_refine, }; use malachite_base::num::arithmetic::root::{ ceiling_root_binary, checked_root_binary, floor_root_binary, root_rem_binary, }; use malachite_base::num::arithmetic::traits::{CeilingRoot, CheckedRoot, FloorRoot, RootRem}; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::{ pair_1_bit_bucketer, signed_bit_bucketer, unsigned_bit_bucketer, }; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ signed_gen, signed_unsigned_pair_gen_var_18, unsigned_gen, unsigned_gen_var_1, unsigned_pair_gen_var_32, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_floor_cbrt_unsigned); register_signed_demos!(runner, demo_floor_cbrt_signed); register_unsigned_demos!(runner, demo_floor_cbrt_assign_unsigned); register_signed_demos!(runner, demo_floor_cbrt_assign_signed); register_unsigned_demos!(runner, demo_ceiling_cbrt_unsigned); register_signed_demos!(runner, demo_ceiling_cbrt_signed); register_unsigned_demos!(runner, demo_ceiling_cbrt_assign_unsigned); register_signed_demos!(runner, demo_ceiling_cbrt_assign_signed); register_unsigned_demos!(runner, demo_checked_cbrt_unsigned); register_signed_demos!(runner, demo_checked_cbrt_signed); register_unsigned_demos!(runner, demo_cbrt_rem); register_unsigned_demos!(runner, demo_cbrt_assign_rem); register_unsigned_demos!(runner, demo_floor_root_unsigned); register_signed_demos!(runner, demo_floor_root_signed); register_unsigned_demos!(runner, demo_floor_root_assign_unsigned); register_signed_demos!(runner, demo_floor_root_assign_signed); register_unsigned_demos!(runner, demo_ceiling_root_unsigned); register_signed_demos!(runner, demo_ceiling_root_signed); register_unsigned_demos!(runner, demo_ceiling_root_assign_unsigned); register_signed_demos!(runner, demo_ceiling_root_assign_signed); register_unsigned_demos!(runner, demo_checked_root_unsigned); register_signed_demos!(runner, demo_checked_root_signed); register_unsigned_demos!(runner, demo_root_rem); register_unsigned_demos!(runner, demo_root_assign_rem); register_bench!(runner, benchmark_floor_cbrt_algorithms_unsigned_u8); register_bench!(runner, benchmark_floor_cbrt_algorithms_unsigned_u16); register_bench!(runner, benchmark_floor_cbrt_algorithms_unsigned_u32); register_bench!(runner, benchmark_floor_cbrt_algorithms_unsigned_u64); register_bench!(runner, benchmark_floor_cbrt_algorithms_unsigned_u128); register_bench!(runner, benchmark_floor_cbrt_algorithms_unsigned_usize); register_signed_benches!(runner, benchmark_floor_cbrt_signed); register_unsigned_benches!(runner, benchmark_floor_cbrt_assign_unsigned); register_signed_benches!(runner, benchmark_floor_cbrt_assign_signed); register_unsigned_benches!(runner, benchmark_ceiling_cbrt_algorithms_unsigned); register_signed_benches!(runner, benchmark_ceiling_cbrt_signed); register_unsigned_benches!(runner, benchmark_ceiling_cbrt_assign_unsigned); register_signed_benches!(runner, benchmark_ceiling_cbrt_assign_signed); register_unsigned_benches!(runner, benchmark_checked_cbrt_algorithms_unsigned); register_signed_benches!(runner, benchmark_checked_cbrt_signed); register_unsigned_benches!(runner, benchmark_cbrt_rem_algorithms); register_unsigned_benches!(runner, benchmark_cbrt_assign_rem); register_bench!(runner, benchmark_floor_root_algorithms_unsigned_u8); register_bench!(runner, benchmark_floor_root_algorithms_unsigned_u16); register_bench!(runner, benchmark_floor_root_algorithms_unsigned_u32); register_bench!(runner, benchmark_floor_root_algorithms_unsigned_u64); register_bench!(runner, benchmark_floor_root_algorithms_unsigned_u128); register_bench!(runner, benchmark_floor_root_algorithms_unsigned_usize); register_signed_benches!(runner, benchmark_floor_root_signed); register_unsigned_benches!(runner, benchmark_floor_root_assign_unsigned); register_signed_benches!(runner, benchmark_floor_root_assign_signed); register_unsigned_benches!(runner, benchmark_ceiling_root_algorithms_unsigned); register_signed_benches!(runner, benchmark_ceiling_root_signed); register_unsigned_benches!(runner, benchmark_ceiling_root_assign_unsigned); register_signed_benches!(runner, benchmark_ceiling_root_assign_signed); register_unsigned_benches!(runner, benchmark_checked_root_algorithms_unsigned); register_signed_benches!(runner, benchmark_checked_root_signed); register_unsigned_benches!(runner, benchmark_root_rem_algorithms); register_unsigned_benches!(runner, benchmark_root_assign_rem); register_bench!(runner, benchmark_floor_cbrt_algorithms_2_u32); register_bench!(runner, benchmark_floor_cbrt_algorithms_2_u64); register_bench!(runner, benchmark_floor_root_algorithms_2_u32); register_bench!(runner, benchmark_floor_root_algorithms_2_u64); register_bench!(runner, benchmark_ceiling_root_algorithms_2_u32); register_bench!(runner, benchmark_ceiling_root_algorithms_2_u64); register_bench!(runner, benchmark_checked_root_algorithms_2_u32); register_bench!(runner, benchmark_checked_root_algorithms_2_u64); register_bench!(runner, benchmark_root_rem_algorithms_2_u32); register_bench!(runner, benchmark_root_rem_algorithms_2_u64); } fn demo_floor_cbrt_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for n in unsigned_gen::().get(gm, config).take(limit) { println!("floor_root({}, 3) = {}", n, n.floor_root(3)); } } fn demo_floor_cbrt_signed(gm: GenMode, config: &GenConfig, limit: usize) { for n in signed_gen::().get(gm, config).take(limit) { println!("floor_root({}, 3) = {}", n, n.floor_root(3)); } } fn demo_floor_cbrt_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for mut n in unsigned_gen::().get(gm, config).take(limit) { let old_n = n; n.floor_root_assign(3); println!("n := {old_n}; n.floor_root_assign(3); n = {n}"); } } fn demo_floor_cbrt_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for mut n in signed_gen::().get(gm, config).take(limit) { let old_n = n; n.floor_root_assign(3); println!("n := {old_n}; n.floor_root_assign(3); n = {n}"); } } fn demo_ceiling_cbrt_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for n in unsigned_gen::().get(gm, config).take(limit) { println!("ceiling_root({}, 3) = {}", n, n.ceiling_root(3)); } } fn demo_ceiling_cbrt_signed(gm: GenMode, config: &GenConfig, limit: usize) { for n in signed_gen::().get(gm, config).take(limit) { println!("ceiling_root({}, 3) = {}", n, n.ceiling_root(3)); } } fn demo_ceiling_cbrt_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for mut n in unsigned_gen::().get(gm, config).take(limit) { let old_n = n; n.ceiling_root_assign(3); println!("n := {old_n}; n.ceiling_root_assign(3); n = {n}"); } } fn demo_ceiling_cbrt_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for mut n in signed_gen::().get(gm, config).take(limit) { let old_n = n; n.ceiling_root_assign(3); println!("n := {old_n}; n.ceiling_root_assign(3); n = {n}"); } } fn demo_checked_cbrt_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for n in unsigned_gen::().get(gm, config).take(limit) { println!("checked_root({}, 3) = {:?}", n, n.checked_root(3)); } } fn demo_checked_cbrt_signed(gm: GenMode, config: &GenConfig, limit: usize) { for n in signed_gen::().get(gm, config).take(limit) { println!("checked_root({}, 3) = {:?}", n, n.checked_root(3)); } } fn demo_cbrt_rem(gm: GenMode, config: &GenConfig, limit: usize) { for n in unsigned_gen::().get(gm, config).take(limit) { println!("root_rem({}, 3) = {:?}", n, n.root_rem(3)); } } fn demo_cbrt_assign_rem(gm: GenMode, config: &GenConfig, limit: usize) { for mut n in unsigned_gen::().get(gm, config).take(limit) { let old_n = n; let rem = n.root_assign_rem(3); println!("n := {old_n}; n.root_assign_rem(3) = {rem}; n = {n}"); } } fn demo_floor_root_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for (n, exp) in unsigned_pair_gen_var_32::() .get(gm, config) .take(limit) { println!("floor_root({}, {}) = {}", n, exp, n.floor_root(exp)); } } fn demo_floor_root_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (n, exp) in signed_unsigned_pair_gen_var_18::() .get(gm, config) .take(limit) { println!("floor_root({}, {}) = {}", n, exp, n.floor_root(exp)); } } fn demo_floor_root_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut n, exp) in unsigned_pair_gen_var_32::() .get(gm, config) .take(limit) { let old_n = n; n.floor_root_assign(exp); println!("n := {old_n}; n.floor_root_assign({exp}); n = {n}"); } } fn demo_floor_root_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut n, exp) in signed_unsigned_pair_gen_var_18::() .get(gm, config) .take(limit) { let old_n = n; n.floor_root_assign(exp); println!("n := {old_n}; n.floor_root_assign({exp}); n = {n}"); } } fn demo_ceiling_root_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for (n, exp) in unsigned_pair_gen_var_32::() .get(gm, config) .take(limit) { println!("ceiling_root({}, {}) = {}", n, exp, n.ceiling_root(exp)); } } fn demo_ceiling_root_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (n, exp) in signed_unsigned_pair_gen_var_18::() .get(gm, config) .take(limit) { println!("ceiling_root({}, {}) = {}", n, exp, n.ceiling_root(exp)); } } fn demo_ceiling_root_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut n, exp) in unsigned_pair_gen_var_32::() .get(gm, config) .take(limit) { let old_n = n; n.floor_root_assign(exp); println!("n := {old_n}; n.ceiling_root_assign({exp}); n = {n}"); } } fn demo_ceiling_root_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut n, exp) in signed_unsigned_pair_gen_var_18::() .get(gm, config) .take(limit) { let old_n = n; n.floor_root_assign(exp); println!("n := {old_n}; n.ceiling_root_assign({exp}); n = {n}"); } } fn demo_checked_root_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for (n, exp) in unsigned_pair_gen_var_32::() .get(gm, config) .take(limit) { println!("checked_root({}, {}) = {:?}", n, exp, n.checked_root(exp)); } } fn demo_checked_root_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (n, exp) in signed_unsigned_pair_gen_var_18::() .get(gm, config) .take(limit) { println!("checked_root({}, {}) = {:?}", n, exp, n.checked_root(exp)); } } fn demo_root_rem(gm: GenMode, config: &GenConfig, limit: usize) { for (n, exp) in unsigned_pair_gen_var_32::() .get(gm, config) .take(limit) { println!("root_rem({}, {}) = {:?}", n, exp, n.root_rem(exp)); } } fn demo_root_assign_rem(gm: GenMode, config: &GenConfig, limit: usize) { for (mut n, exp) in unsigned_pair_gen_var_32::() .get(gm, config) .take(limit) { let old_n = n; let rem = n.root_assign_rem(exp); println!("n := {old_n}; n.root_assign_rem({exp}) = {rem}; n = {n}"); } } macro_rules! benchmark_floor_cbrt_algorithms_unsigned { ($t:ident, $f:ident) => { fn $f(gm: GenMode, config: &GenConfig, limit: usize, file_name: &str) { #[allow(clippy::cast_lossless)] run_benchmark( &format!("{}.floor_root(3)", $t::NAME), BenchmarkType::Algorithms, unsigned_gen::<$t>().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [ ("default", &mut |n| no_out!(n.floor_root(3))), ("binary", &mut |n| no_out!(floor_root_binary(n, 3))), ("approx and refine", &mut |n| { no_out!(floor_root_approx_and_refine( |x| x as f64, |f| f as $t, n, 3 )) }), ], ); } }; } benchmark_floor_cbrt_algorithms_unsigned!(u8, benchmark_floor_cbrt_algorithms_unsigned_u8); benchmark_floor_cbrt_algorithms_unsigned!(u16, benchmark_floor_cbrt_algorithms_unsigned_u16); benchmark_floor_cbrt_algorithms_unsigned!(u32, benchmark_floor_cbrt_algorithms_unsigned_u32); benchmark_floor_cbrt_algorithms_unsigned!(u64, benchmark_floor_cbrt_algorithms_unsigned_u64); benchmark_floor_cbrt_algorithms_unsigned!(u128, benchmark_floor_cbrt_algorithms_unsigned_u128); benchmark_floor_cbrt_algorithms_unsigned!(usize, benchmark_floor_cbrt_algorithms_unsigned_usize); fn benchmark_floor_cbrt_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.floor_root(3)", T::NAME), BenchmarkType::Single, signed_gen::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [("Malachite", &mut |n| no_out!(n.floor_root(3)))], ); } fn benchmark_floor_cbrt_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.floor_root_assign(3)", T::NAME), BenchmarkType::Single, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [("Malachite", &mut |mut n| n.floor_root_assign(3))], ); } fn benchmark_floor_cbrt_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.floor_cbrt_assign(3)", T::NAME), BenchmarkType::Single, signed_gen::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [("Malachite", &mut |mut n| n.floor_root_assign(3))], ); } fn benchmark_ceiling_cbrt_algorithms_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.ceiling_root(3)", T::NAME), BenchmarkType::Algorithms, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [ ("default", &mut |n| no_out!(n.ceiling_root(3))), ("binary", &mut |n| no_out!(ceiling_root_binary(n, 3))), ], ); } fn benchmark_ceiling_cbrt_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.ceiling_root(3)", T::NAME), BenchmarkType::Single, signed_gen::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [("Malachite", &mut |n| no_out!(n.ceiling_root(3)))], ); } fn benchmark_ceiling_cbrt_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.ceiling_root_assign(3)", T::NAME), BenchmarkType::Single, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [("Malachite", &mut |mut n| n.ceiling_root_assign(3))], ); } fn benchmark_ceiling_cbrt_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.ceiling_cbrt_assign(3)", T::NAME), BenchmarkType::Single, signed_gen::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [("Malachite", &mut |mut n| n.ceiling_root_assign(3))], ); } fn benchmark_checked_cbrt_algorithms_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.checked_root(3)", T::NAME), BenchmarkType::Algorithms, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [ ("default", &mut |n| no_out!(n.checked_root(3))), ("binary", &mut |n| no_out!(checked_root_binary(n, 3))), ], ); } fn benchmark_checked_cbrt_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.checked_roor(3)", T::NAME), BenchmarkType::Single, signed_gen::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [("Malachite", &mut |n| no_out!(n.checked_root(3)))], ); } fn benchmark_cbrt_rem_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.root_rem(3)", T::NAME), BenchmarkType::Algorithms, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [ ("default", &mut |n| no_out!(n.root_rem(3))), ("binary", &mut |n| no_out!(root_rem_binary(n, 3))), ], ); } fn benchmark_cbrt_assign_rem( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.root_assign_rem(3)", T::NAME), BenchmarkType::Single, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [("Malachite", &mut |mut n| no_out!(n.root_assign_rem(3)))], ); } macro_rules! benchmark_floor_root_algorithms_unsigned { ($t:ident, $f:ident) => { fn $f(gm: GenMode, config: &GenConfig, limit: usize, file_name: &str) { #[allow(clippy::cast_lossless)] run_benchmark( &format!("{}.floor_root(u64)", $t::NAME), BenchmarkType::Algorithms, unsigned_pair_gen_var_32::<$t, u64>().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("x"), &mut [ ("default", &mut |(n, exp)| no_out!(n.floor_root(exp))), ("binary", &mut |(n, exp)| no_out!(floor_root_binary(n, exp))), ("approx and refine", &mut |(n, exp)| { no_out!(floor_root_approx_and_refine( |x| x as f64, |f| f as $t, n, exp )) }), ], ); } }; } benchmark_floor_root_algorithms_unsigned!(u8, benchmark_floor_root_algorithms_unsigned_u8); benchmark_floor_root_algorithms_unsigned!(u16, benchmark_floor_root_algorithms_unsigned_u16); benchmark_floor_root_algorithms_unsigned!(u32, benchmark_floor_root_algorithms_unsigned_u32); benchmark_floor_root_algorithms_unsigned!(u64, benchmark_floor_root_algorithms_unsigned_u64); benchmark_floor_root_algorithms_unsigned!(u128, benchmark_floor_root_algorithms_unsigned_u128); benchmark_floor_root_algorithms_unsigned!(usize, benchmark_floor_root_algorithms_unsigned_usize); fn benchmark_floor_root_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.floor_root(u64)", T::NAME), BenchmarkType::Single, signed_unsigned_pair_gen_var_18::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("x"), &mut [("Malachite", &mut |(n, exp)| no_out!(n.floor_root(exp)))], ); } fn benchmark_floor_root_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.floor_root_assign(u64)", T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_32::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("x"), &mut [("Malachite", &mut |(mut n, exp)| n.floor_root_assign(exp))], ); } fn benchmark_floor_root_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.floor_root_assign(u64)", T::NAME), BenchmarkType::Single, signed_unsigned_pair_gen_var_18::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("x"), &mut [("Malachite", &mut |(mut n, exp)| n.floor_root_assign(exp))], ); } fn benchmark_ceiling_root_algorithms_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.ceiling_root(u64)", T::NAME), BenchmarkType::Algorithms, unsigned_pair_gen_var_32::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("x"), &mut [ ("default", &mut |(n, exp)| no_out!(n.ceiling_root(exp))), ("binary", &mut |(n, exp)| { no_out!(ceiling_root_binary(n, exp)) }), ], ); } fn benchmark_ceiling_root_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.ceiling_root(u64)", T::NAME), BenchmarkType::Single, signed_unsigned_pair_gen_var_18::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("x"), &mut [("Malachite", &mut |(n, exp)| no_out!(n.ceiling_root(exp)))], ); } fn benchmark_ceiling_root_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.ceiling_root_assign(u64)", T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_32::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("x"), &mut [("Malachite", &mut |(mut n, exp)| n.ceiling_root_assign(exp))], ); } fn benchmark_ceiling_root_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.ceiling_root_assign(u64)", T::NAME), BenchmarkType::Single, signed_unsigned_pair_gen_var_18::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("x"), &mut [("Malachite", &mut |(mut n, exp)| n.ceiling_root_assign(exp))], ); } fn benchmark_checked_root_algorithms_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.checked_root(u64)", T::NAME), BenchmarkType::Algorithms, unsigned_pair_gen_var_32::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("x"), &mut [ ("default", &mut |(n, exp)| no_out!(n.checked_root(exp))), ("binary", &mut |(n, exp)| { no_out!(checked_root_binary(n, exp)) }), ], ); } fn benchmark_checked_root_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.checked_root(u64)", T::NAME), BenchmarkType::Single, signed_unsigned_pair_gen_var_18::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("x"), &mut [("Malachite", &mut |(n, exp)| no_out!(n.checked_root(exp)))], ); } fn benchmark_root_rem_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.root_rem(u64)", T::NAME), BenchmarkType::Algorithms, unsigned_pair_gen_var_32::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("x"), &mut [ ("default", &mut |(n, exp)| no_out!(n.root_rem(exp))), ("binary", &mut |(n, exp)| no_out!(root_rem_binary(n, exp))), ], ); } fn benchmark_root_assign_rem( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.root_assign_rem(u64)", T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_32::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("x"), &mut [("Malachite", &mut |(mut n, exp)| { no_out!(n.root_assign_rem(exp)) })], ); } fn benchmark_floor_cbrt_algorithms_2_u32( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( "u32.floor_root(3)", BenchmarkType::Algorithms, unsigned_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [ ("default", &mut |n| no_out!(n.floor_root(3))), ("binary", &mut |n| no_out!(floor_root_binary(n, 3))), ("fast", &mut |n| no_out!(fast_floor_cbrt_u32(n))), ("Chebyshev", &mut |n| no_out!(cbrt_chebyshev_approx_u32(n))), ("approx and refine", &mut |n| { no_out!(floor_root_approx_and_refine(f64::from, |f| f as u32, n, 3)) }), ], ); } fn benchmark_floor_cbrt_algorithms_2_u64( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( "u64.floor_root(3)", BenchmarkType::Algorithms, unsigned_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [ ("default", &mut |n| no_out!(n.floor_root(3))), ("binary", &mut |n| no_out!(floor_root_binary(n, 3))), ("fast", &mut |n| no_out!(fast_floor_cbrt_u64(n))), ("Chebyshev", &mut |n| no_out!(cbrt_chebyshev_approx_u64(n))), ("approx and refine", &mut |n| { no_out!(floor_root_approx_and_refine( |x| x as f64, |f| f as u64, n, 3 )) }), ], ); } fn benchmark_floor_root_algorithms_2_u32( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( "u32.floor_root(u64)", BenchmarkType::Algorithms, unsigned_pair_gen_var_32::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("x"), &mut [ ("default", &mut |(n, exp)| no_out!(n.floor_root(exp))), ("binary", &mut |(n, exp)| no_out!(floor_root_binary(n, exp))), ("fast", &mut |(n, exp)| no_out!(fast_floor_root_u32(n, exp))), ("approx and refine", &mut |(n, exp)| { no_out!(floor_root_approx_and_refine( f64::from, |f| f as u32, n, exp )) }), ], ); } fn benchmark_floor_root_algorithms_2_u64( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( "u64.floor_root(u64)", BenchmarkType::Algorithms, unsigned_pair_gen_var_32::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("x"), &mut [ ("default", &mut |(n, exp)| no_out!(n.floor_root(exp))), ("binary", &mut |(n, exp)| no_out!(floor_root_binary(n, exp))), ("fast", &mut |(n, exp)| no_out!(fast_floor_root_u64(n, exp))), ("approx and refine", &mut |(n, exp)| { no_out!(floor_root_approx_and_refine( |x| x as f64, |f| f as u64, n, exp )) }), ], ); } fn benchmark_ceiling_root_algorithms_2_u32( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( "u32.ceiling_root(u64)", BenchmarkType::Algorithms, unsigned_pair_gen_var_32::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("x"), &mut [ ("default", &mut |(n, exp)| no_out!(n.ceiling_root(exp))), ("binary", &mut |(n, exp)| { no_out!(ceiling_root_binary(n, exp)) }), ("fast", &mut |(n, exp)| { no_out!(fast_ceiling_root_u32(n, exp)) }), ], ); } fn benchmark_ceiling_root_algorithms_2_u64( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( "u64.ceiling_root(u64)", BenchmarkType::Algorithms, unsigned_pair_gen_var_32::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("x"), &mut [ ("default", &mut |(n, exp)| no_out!(n.ceiling_root(exp))), ("binary", &mut |(n, exp)| { no_out!(ceiling_root_binary(n, exp)) }), ("fast", &mut |(n, exp)| { no_out!(fast_ceiling_root_u64(n, exp)) }), ], ); } fn benchmark_checked_root_algorithms_2_u32( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( "u32.checked_root(u64)", BenchmarkType::Algorithms, unsigned_pair_gen_var_32::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("x"), &mut [ ("default", &mut |(n, exp)| no_out!(n.checked_root(exp))), ("binary", &mut |(n, exp)| { no_out!(checked_root_binary(n, exp)) }), ("fast", &mut |(n, exp)| { no_out!(fast_checked_root_u32(n, exp)) }), ], ); } fn benchmark_checked_root_algorithms_2_u64( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( "u64.checked_root(u64)", BenchmarkType::Algorithms, unsigned_pair_gen_var_32::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("x"), &mut [ ("default", &mut |(n, exp)| no_out!(n.checked_root(exp))), ("binary", &mut |(n, exp)| { no_out!(checked_root_binary(n, exp)) }), ("fast", &mut |(n, exp)| { no_out!(fast_checked_root_u64(n, exp)) }), ], ); } fn benchmark_root_rem_algorithms_2_u32( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( "u32.root_rem(u64)", BenchmarkType::Algorithms, unsigned_pair_gen_var_32::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("x"), &mut [ ("default", &mut |(n, exp)| no_out!(n.root_rem(exp))), ("binary", &mut |(n, exp)| no_out!(root_rem_binary(n, exp))), ("fast", &mut |(n, exp)| no_out!(fast_root_rem_u32(n, exp))), ], ); } fn benchmark_root_rem_algorithms_2_u64( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( "u64.root_rem(u64)", BenchmarkType::Algorithms, unsigned_pair_gen_var_32::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("x"), &mut [ ("default", &mut |(n, exp)| no_out!(n.root_rem(exp))), ("binary", &mut |(n, exp)| no_out!(root_rem_binary(n, exp))), ("fast", &mut |(n, exp)| no_out!(fast_root_rem_u64(n, exp))), ], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/rotate.rs000064400000000000000000000113441046102023000246530ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::pair_1_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_unsigned_pair_gen, unsigned_pair_gen}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_rotate_left_assign_unsigned); register_signed_demos!(runner, demo_rotate_left_assign_signed); register_unsigned_demos!(runner, demo_rotate_right_assign_unsigned); register_signed_demos!(runner, demo_rotate_right_assign_signed); register_unsigned_benches!(runner, benchmark_rotate_left_assign_unsigned); register_signed_benches!(runner, benchmark_rotate_left_assign_signed); register_unsigned_benches!(runner, benchmark_rotate_right_assign_unsigned); register_signed_benches!(runner, benchmark_rotate_right_assign_signed); } fn demo_rotate_left_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut u, n) in unsigned_pair_gen::().get(gm, config).take(limit) { let old_u = u; u.rotate_left_assign(n); println!("u := {old_u}; u.rotate_left_assign({n}); u = {u}"); } } fn demo_rotate_left_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut i, n) in signed_unsigned_pair_gen::() .get(gm, config) .take(limit) { let old_i = i; i.rotate_left_assign(n); println!("i := {old_i}; i.rotate_left_assign({n}); i = {i}"); } } fn demo_rotate_right_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut u, n) in unsigned_pair_gen::().get(gm, config).take(limit) { let old_u = u; u.rotate_right_assign(n); println!("u := {old_u}; u.rotate_right_assign({n}); u = {u}"); } } fn demo_rotate_right_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut i, n) in signed_unsigned_pair_gen::() .get(gm, config) .take(limit) { let old_i = i; i.rotate_right_assign(n); println!("i := {old_i}; i.rotate_right_assign({n}); i = {i}"); } } fn benchmark_rotate_left_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.rotate_left_assign(u64)", T::NAME), BenchmarkType::Single, unsigned_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("u"), &mut [("Malachite", &mut |(mut u, n)| u.rotate_left_assign(n))], ); } fn benchmark_rotate_left_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.rotate_left_assign(u64)", T::NAME), BenchmarkType::Single, signed_unsigned_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("i"), &mut [("Malachite", &mut |(mut i, n)| i.rotate_left_assign(n))], ); } fn benchmark_rotate_right_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.rotate_right_assign(u64)", T::NAME), BenchmarkType::Single, unsigned_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("u"), &mut [("Malachite", &mut |(mut u, n)| u.rotate_right_assign(n))], ); } fn benchmark_rotate_right_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.rotate_right_assign(u64)", T::NAME), BenchmarkType::Single, signed_unsigned_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("i"), &mut [("Malachite", &mut |(mut i, n)| i.rotate_right_assign(n))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/round_to_multiple.rs000064400000000000000000000141761046102023000271270ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::UnsignedAbs; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::ConvertibleFrom; use malachite_base::test_util::bench::bucketers::triple_1_2_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ signed_signed_rounding_mode_triple_gen_var_2, unsigned_unsigned_rounding_mode_triple_gen_var_2, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_round_to_multiple_unsigned); register_unsigned_demos!(runner, demo_round_to_multiple_assign_unsigned); register_signed_unsigned_match_demos!(runner, demo_round_to_multiple_signed); register_signed_unsigned_match_demos!(runner, demo_round_to_multiple_assign_signed); register_unsigned_benches!(runner, benchmark_round_to_multiple_unsigned); register_unsigned_benches!(runner, benchmark_round_to_multiple_assign_unsigned); register_signed_unsigned_match_benches!(runner, benchmark_round_to_multiple_signed); register_signed_unsigned_match_benches!(runner, benchmark_round_to_multiple_assign_signed); } fn demo_round_to_multiple_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, y, rm) in unsigned_unsigned_rounding_mode_triple_gen_var_2::() .get(gm, config) .take(limit) { println!( "{}.round_to_multiple({}, {}) = {:?}", x, y, rm, x.round_to_multiple(y, rm) ); } } fn demo_round_to_multiple_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y, rm) in unsigned_unsigned_rounding_mode_triple_gen_var_2::() .get(gm, config) .take(limit) { let old_x = x; let o = x.round_to_multiple_assign(y, rm); println!("x := {old_x}; x.round_to_multiple_assign({y}, {rm}) = {o:?}; x = {x}"); } } fn demo_round_to_multiple_signed< S: TryFrom + ConvertibleFrom + PrimitiveSigned + UnsignedAbs, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, y, rm) in signed_signed_rounding_mode_triple_gen_var_2::() .get(gm, config) .take(limit) { println!( "({}).round_to_multiple({}, {}) = {:?}", x, y, rm, x.round_to_multiple(y, rm) ); } } fn demo_round_to_multiple_assign_signed< S: TryFrom + ConvertibleFrom + PrimitiveSigned + UnsignedAbs, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y, rm) in signed_signed_rounding_mode_triple_gen_var_2::() .get(gm, config) .take(limit) { let old_x = x; let o = x.round_to_multiple_assign(y, rm); println!("x := {old_x}; x.round_to_multiple_assign({y}, {rm}) = {o:?}; x = {x}"); } } fn benchmark_round_to_multiple_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.round_to_multiple({}, RoundingMode)", T::NAME, T::NAME), BenchmarkType::Single, unsigned_unsigned_rounding_mode_triple_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &triple_1_2_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y, rm)| { no_out!(x.round_to_multiple(y, rm)) })], ); } fn benchmark_round_to_multiple_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!( "{}.round_to_multiple_assign({}, RoundingMode)", T::NAME, T::NAME ), BenchmarkType::Single, unsigned_unsigned_rounding_mode_triple_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &triple_1_2_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y, rm)| { no_out!(x.round_to_multiple_assign(y, rm)) })], ); } fn benchmark_round_to_multiple_signed< S: TryFrom + ConvertibleFrom + PrimitiveSigned + UnsignedAbs, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.round_to_multiple({}, RoundingMode)", S::NAME, S::NAME), BenchmarkType::Single, signed_signed_rounding_mode_triple_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &triple_1_2_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y, rm)| { no_out!(x.round_to_multiple(y, rm)) })], ); } fn benchmark_round_to_multiple_assign_signed< S: TryFrom + ConvertibleFrom + PrimitiveSigned + UnsignedAbs, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!( "{}.round_to_multiple_assign({}, RoundingMode)", S::NAME, S::NAME ), BenchmarkType::Single, signed_signed_rounding_mode_triple_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &triple_1_2_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y, rm)| { no_out!(x.round_to_multiple_assign(y, rm)) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/round_to_multiple_of_power_of_2.rs000064400000000000000000000142621046102023000317300ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::triple_1_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ signed_unsigned_rounding_mode_triple_gen_var_1, unsigned_unsigned_rounding_mode_triple_gen_var_3, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_round_to_multiple_of_power_of_2_unsigned); register_unsigned_demos!(runner, demo_round_to_multiple_of_power_of_2_assign_unsigned); register_signed_demos!(runner, demo_round_to_multiple_of_power_of_2_signed); register_signed_demos!(runner, demo_round_to_multiple_of_power_of_2_assign_signed); register_unsigned_benches!(runner, benchmark_round_to_multiple_of_power_of_2_unsigned); register_unsigned_benches!( runner, benchmark_round_to_multiple_of_power_of_2_assign_unsigned ); register_signed_benches!(runner, benchmark_round_to_multiple_of_power_of_2_signed); register_signed_benches!( runner, benchmark_round_to_multiple_of_power_of_2_assign_signed ); } fn demo_round_to_multiple_of_power_of_2_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, pow, rm) in unsigned_unsigned_rounding_mode_triple_gen_var_3::() .get(gm, config) .take(limit) { println!( "{}.round_to_multiple_of_power_of_2({}, {}) = {:?}", x, pow, rm, x.round_to_multiple_of_power_of_2(pow, rm) ); } } fn demo_round_to_multiple_of_power_of_2_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, pow, rm) in unsigned_unsigned_rounding_mode_triple_gen_var_3::() .get(gm, config) .take(limit) { let old_x = x; let o = x.round_to_multiple_of_power_of_2_assign(pow, rm); println!( "x := {old_x}; x.round_to_multiple_of_power_of_2_assign({pow}, {rm}) = {o:?}; x = {x}" ); } } fn demo_round_to_multiple_of_power_of_2_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, pow, rm) in signed_unsigned_rounding_mode_triple_gen_var_1::() .get(gm, config) .take(limit) { println!( "({}).round_to_multiple_of_power_of_2({}, {}) = {:?}", x, pow, rm, x.round_to_multiple_of_power_of_2(pow, rm) ); } } fn demo_round_to_multiple_of_power_of_2_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, pow, rm) in signed_unsigned_rounding_mode_triple_gen_var_1::() .get(gm, config) .take(limit) { let old_x = x; let o = x.round_to_multiple_of_power_of_2_assign(pow, rm); println!( "x := {old_x}; x.round_to_multiple_of_power_of_2_assign({pow}, {rm}) = {o:?}; x = {x}" ); } } fn benchmark_round_to_multiple_of_power_of_2_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!( "{}.round_to_multiple_of_power_of_2({}, RoundingMode)", T::NAME, T::NAME ), BenchmarkType::Single, unsigned_unsigned_rounding_mode_triple_gen_var_3::().get(gm, config), gm.name(), limit, file_name, &triple_1_bit_bucketer("x"), &mut [("Malachite", &mut |(x, y, rm)| { no_out!(x.round_to_multiple_of_power_of_2(y, rm)) })], ); } fn benchmark_round_to_multiple_of_power_of_2_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!( "{}.round_to_multiple_of_power_of_2_assign({}, RoundingMode)", T::NAME, T::NAME ), BenchmarkType::Single, unsigned_unsigned_rounding_mode_triple_gen_var_3::().get(gm, config), gm.name(), limit, file_name, &triple_1_bit_bucketer("x"), &mut [("Malachite", &mut |(mut x, y, rm)| { no_out!(x.round_to_multiple_of_power_of_2_assign(y, rm)) })], ); } fn benchmark_round_to_multiple_of_power_of_2_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!( "{}.round_to_multiple_of_power_of_2({}, RoundingMode)", T::NAME, T::NAME ), BenchmarkType::Single, signed_unsigned_rounding_mode_triple_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &triple_1_bit_bucketer("x"), &mut [("Malachite", &mut |(x, y, rm)| { no_out!(x.round_to_multiple_of_power_of_2(y, rm)) })], ); } fn benchmark_round_to_multiple_of_power_of_2_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!( "{}.round_to_multiple_of_power_of_2_assign({}, RoundingMode)", T::NAME, T::NAME ), BenchmarkType::Single, signed_unsigned_rounding_mode_triple_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &triple_1_bit_bucketer("x"), &mut [("Malachite", &mut |(mut x, y, rm)| { no_out!(x.round_to_multiple_of_power_of_2_assign(y, rm)) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/saturating_abs.rs000064400000000000000000000032311046102023000263570ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::test_util::bench::bucketers::signed_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::signed_gen; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_signed_demos!(runner, demo_saturating_abs_assign); register_signed_benches!(runner, benchmark_saturating_abs_assign); } fn demo_saturating_abs_assign(gm: GenMode, config: &GenConfig, limit: usize) { for mut i in signed_gen::().get(gm, config).take(limit) { let old_i = i; i.saturating_abs_assign(); println!("i := {old_i}; i.saturating_abs_assign(); i = {i}"); } } fn benchmark_saturating_abs_assign( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.saturating_abs_assign()", T::NAME), BenchmarkType::Single, signed_gen::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [("Malachite", &mut |mut i| i.saturating_abs_assign())], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/saturating_add.rs000064400000000000000000000111031046102023000263370ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::pair_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_pair_gen, unsigned_pair_gen_var_27}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_saturating_add_unsigned); register_signed_demos!(runner, demo_saturating_add_signed); register_unsigned_demos!(runner, demo_saturating_add_assign_unsigned); register_signed_demos!(runner, demo_saturating_add_assign_signed); register_unsigned_benches!(runner, benchmark_saturating_add_unsigned); register_signed_benches!(runner, benchmark_saturating_add_signed); register_unsigned_benches!(runner, benchmark_saturating_add_assign_unsigned); register_signed_benches!(runner, benchmark_saturating_add_assign_signed); } fn demo_saturating_add_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, y) in unsigned_pair_gen_var_27::().get(gm, config).take(limit) { println!("{}.saturating_add({}) = {}", x, y, x.saturating_add(y)); } } fn demo_saturating_add_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in signed_pair_gen::().get(gm, config).take(limit) { println!("({}).saturating_add({}) = {}", x, y, x.saturating_add(y)); } } fn demo_saturating_add_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y) in unsigned_pair_gen_var_27::().get(gm, config).take(limit) { let old_x = x; x.saturating_add_assign(y); println!("x := {old_x}; x.saturating_add_assign({y}); x = {x}"); } } fn demo_saturating_add_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y) in signed_pair_gen::().get(gm, config).take(limit) { let old_x = x; x.saturating_add_assign(y); println!("x := {old_x}; x.saturating_add_assign({y}); x = {x}"); } } fn benchmark_saturating_add_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.saturating_add({})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_27::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.saturating_add(y)))], ); } fn benchmark_saturating_add_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.saturating_add({})", T::NAME, T::NAME), BenchmarkType::Single, signed_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.saturating_add(y)))], ); } fn benchmark_saturating_add_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.saturating_add_assign({})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_27::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y)| x.saturating_add_assign(y))], ); } fn benchmark_saturating_add_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.saturating_add_assign({})", T::NAME, T::NAME), BenchmarkType::Single, signed_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y)| x.saturating_add_assign(y))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/saturating_add_mul.rs000064400000000000000000000124121046102023000272200ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::triple_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_triple_gen, unsigned_triple_gen_var_19}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_saturating_add_mul_unsigned); register_signed_demos!(runner, demo_saturating_add_mul_signed); register_unsigned_demos!(runner, demo_saturating_add_mul_assign_unsigned); register_signed_demos!(runner, demo_saturating_add_mul_assign_signed); register_unsigned_benches!(runner, benchmark_saturating_add_mul_unsigned); register_signed_benches!(runner, benchmark_saturating_add_mul_signed); register_unsigned_benches!(runner, benchmark_saturating_add_mul_assign_unsigned); register_signed_benches!(runner, benchmark_saturating_add_mul_assign_signed); } fn demo_saturating_add_mul_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, y, z) in unsigned_triple_gen_var_19::() .get(gm, config) .take(limit) { println!( "{}.saturating_add_mul({}, {}) = {}", x, y, z, x.saturating_add_mul(y, z) ); } } fn demo_saturating_add_mul_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, y, z) in signed_triple_gen::().get(gm, config).take(limit) { println!( "{}.saturating_add_mul({}, {}) = {}", x, y, z, x.saturating_add_mul(y, z) ); } } fn demo_saturating_add_mul_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y, z) in unsigned_triple_gen_var_19::() .get(gm, config) .take(limit) { let old_x = x; x.saturating_add_mul_assign(y, z); println!("x := {old_x}; x.saturating_add_mul_assign({y}, {z}); x = {x}"); } } fn demo_saturating_add_mul_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y, z) in signed_triple_gen::().get(gm, config).take(limit) { let old_x = x; x.saturating_add_mul_assign(y, z); println!("x := {old_x}; x.saturating_add_mul_assign({y}, {z}); x = {x}"); } } fn benchmark_saturating_add_mul_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.saturating_add_mul({}, {})", T::NAME, T::NAME, T::NAME), BenchmarkType::Single, unsigned_triple_gen_var_19::().get(gm, config), gm.name(), limit, file_name, &triple_max_bit_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(x, y, z)| { no_out!(x.saturating_add_mul(y, z)) })], ); } fn benchmark_saturating_add_mul_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.saturating_add_mul({}, {})", T::NAME, T::NAME, T::NAME), BenchmarkType::Single, signed_triple_gen::().get(gm, config), gm.name(), limit, file_name, &triple_max_bit_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(x, y, z)| { no_out!(x.saturating_add_mul(y, z)) })], ); } fn benchmark_saturating_add_mul_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!( "{}.saturating_add_mul_assign({}, {})", T::NAME, T::NAME, T::NAME ), BenchmarkType::Single, unsigned_triple_gen_var_19::().get(gm, config), gm.name(), limit, file_name, &triple_max_bit_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(mut x, y, z)| { x.saturating_add_mul_assign(y, z) })], ); } fn benchmark_saturating_add_mul_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!( "{}.saturating_add_mul_assign({}, {})", T::NAME, T::NAME, T::NAME ), BenchmarkType::Single, signed_triple_gen::().get(gm, config), gm.name(), limit, file_name, &triple_max_bit_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(mut x, y, z)| { x.saturating_add_mul_assign(y, z) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/saturating_mul.rs000064400000000000000000000111031046102023000264040ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::pair_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_pair_gen, unsigned_pair_gen_var_27}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_saturating_mul_unsigned); register_signed_demos!(runner, demo_saturating_mul_signed); register_unsigned_demos!(runner, demo_saturating_mul_assign_unsigned); register_signed_demos!(runner, demo_saturating_mul_assign_signed); register_unsigned_benches!(runner, benchmark_saturating_mul_unsigned); register_signed_benches!(runner, benchmark_saturating_mul_signed); register_unsigned_benches!(runner, benchmark_saturating_mul_assign_unsigned); register_signed_benches!(runner, benchmark_saturating_mul_assign_signed); } fn demo_saturating_mul_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, y) in unsigned_pair_gen_var_27::().get(gm, config).take(limit) { println!("{}.saturating_mul({}) = {}", x, y, x.saturating_mul(y)); } } fn demo_saturating_mul_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in signed_pair_gen::().get(gm, config).take(limit) { println!("({}).saturating_mul({}) = {}", x, y, x.saturating_mul(y)); } } fn demo_saturating_mul_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y) in unsigned_pair_gen_var_27::().get(gm, config).take(limit) { let old_x = x; x.saturating_mul_assign(y); println!("x := {old_x}; x.saturating_mul_assign({y}); x = {x}"); } } fn demo_saturating_mul_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y) in signed_pair_gen::().get(gm, config).take(limit) { let old_x = x; x.saturating_mul_assign(y); println!("x := {old_x}; x.saturating_mul_assign({y}); x = {x}"); } } fn benchmark_saturating_mul_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.saturating_mul({})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_27::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.saturating_mul(y)))], ); } fn benchmark_saturating_mul_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.saturating_mul({})", T::NAME, T::NAME), BenchmarkType::Single, signed_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.saturating_mul(y)))], ); } fn benchmark_saturating_mul_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.saturating_mul_assign({})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_27::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y)| x.saturating_mul_assign(y))], ); } fn benchmark_saturating_mul_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.saturating_mul_assign({})", T::NAME, T::NAME), BenchmarkType::Single, signed_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y)| x.saturating_mul_assign(y))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/saturating_neg.rs000064400000000000000000000032311046102023000263630ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::test_util::bench::bucketers::signed_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::signed_gen; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_signed_demos!(runner, demo_saturating_neg_assign); register_signed_benches!(runner, benchmark_saturating_neg_assign); } fn demo_saturating_neg_assign(gm: GenMode, config: &GenConfig, limit: usize) { for mut i in signed_gen::().get(gm, config).take(limit) { let old_i = i; i.saturating_neg_assign(); println!("i := {old_i}; i.saturating_neg_assign(); i = {i}"); } } fn benchmark_saturating_neg_assign( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.saturating_neg_assign()", T::NAME), BenchmarkType::Single, signed_gen::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [("Malachite", &mut |mut i| i.saturating_neg_assign())], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/saturating_pow.rs000064400000000000000000000055511046102023000264260ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::pair_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_unsigned_pair_gen, unsigned_pair_gen}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_saturating_pow_assign_unsigned); register_signed_demos!(runner, demo_saturating_pow_assign_signed); register_unsigned_benches!(runner, benchmark_saturating_pow_assign_unsigned); register_signed_benches!(runner, benchmark_saturating_pow_assign_signed); } fn demo_saturating_pow_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y) in unsigned_pair_gen::().get(gm, config).take(limit) { let old_x = x; x.saturating_pow_assign(y); println!("x := {old_x}; x.saturating_pow_assign({y}); x = {x}"); } } fn demo_saturating_pow_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y) in signed_unsigned_pair_gen::() .get(gm, config) .take(limit) { let old_x = x; x.saturating_pow_assign(y); println!("x := {old_x}; x.saturating_pow_assign({y}); x = {x}"); } } fn benchmark_saturating_pow_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.saturating_pow_assign(u64)", T::NAME), BenchmarkType::Single, unsigned_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y)| x.saturating_pow_assign(y))], ); } fn benchmark_saturating_pow_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.saturating_pow_assign(u64)", T::NAME), BenchmarkType::Single, signed_unsigned_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y)| x.saturating_pow_assign(y))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/saturating_square.rs000064400000000000000000000107421046102023000271170ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::{signed_bit_bucketer, unsigned_bit_bucketer}; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_gen, unsigned_gen}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_saturating_square_unsigned); register_signed_demos!(runner, demo_saturating_square_signed); register_unsigned_demos!(runner, demo_saturating_square_assign_unsigned); register_signed_demos!(runner, demo_saturating_square_assign_signed); register_unsigned_benches!(runner, benchmark_saturating_square_unsigned); register_signed_benches!(runner, benchmark_saturating_square_signed); register_unsigned_benches!(runner, benchmark_saturating_square_assign_unsigned); register_signed_benches!(runner, benchmark_saturating_square_assign_signed); } fn demo_saturating_square_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for x in unsigned_gen::().get(gm, config).take(limit) { println!("{}.saturating_square() = {}", x, x.saturating_square()); } } fn demo_saturating_square_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for x in signed_gen::().get(gm, config).take(limit) { println!("{}.saturating_square() = {}", x, x.saturating_square()); } } fn demo_saturating_square_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for mut x in unsigned_gen::().get(gm, config).take(limit) { let old_x = x; x.saturating_square_assign(); println!("x := {old_x}; x.saturating_square_assign(); x = {x}"); } } fn demo_saturating_square_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for mut x in signed_gen::().get(gm, config).take(limit) { let old_x = x; x.saturating_square_assign(); println!("x := {old_x}; x.saturating_square_assign(); x = {x}"); } } fn benchmark_saturating_square_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.saturating_square()", T::NAME), BenchmarkType::Single, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [("Malachite", &mut |x| no_out!(x.saturating_square()))], ); } fn benchmark_saturating_square_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.saturating_square()", T::NAME), BenchmarkType::Single, signed_gen::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [("Malachite", &mut |x| no_out!(x.saturating_square()))], ); } fn benchmark_saturating_square_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.saturating_square_assign()", T::NAME), BenchmarkType::Single, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [("Malachite", &mut |mut x| x.saturating_square_assign())], ); } fn benchmark_saturating_square_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.saturating_square_assign()", T::NAME), BenchmarkType::Single, signed_gen::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [("Malachite", &mut |mut x| x.saturating_square_assign())], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/saturating_sub.rs000064400000000000000000000111031046102023000264000ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::pair_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_pair_gen, unsigned_pair_gen_var_27}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_saturating_sub_unsigned); register_signed_demos!(runner, demo_saturating_sub_signed); register_unsigned_demos!(runner, demo_saturating_sub_assign_unsigned); register_signed_demos!(runner, demo_saturating_sub_assign_signed); register_unsigned_benches!(runner, benchmark_saturating_sub_unsigned); register_signed_benches!(runner, benchmark_saturating_sub_signed); register_unsigned_benches!(runner, benchmark_saturating_sub_assign_unsigned); register_signed_benches!(runner, benchmark_saturating_sub_assign_signed); } fn demo_saturating_sub_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, y) in unsigned_pair_gen_var_27::().get(gm, config).take(limit) { println!("{}.saturating_sub({}) = {}", x, y, x.saturating_sub(y)); } } fn demo_saturating_sub_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in signed_pair_gen::().get(gm, config).take(limit) { println!("({}).saturating_sub({}) = {}", x, y, x.saturating_sub(y)); } } fn demo_saturating_sub_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y) in unsigned_pair_gen_var_27::().get(gm, config).take(limit) { let old_x = x; x.saturating_sub_assign(y); println!("x := {old_x}; x.saturating_sub_assign({y}); x = {x}"); } } fn demo_saturating_sub_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y) in signed_pair_gen::().get(gm, config).take(limit) { let old_x = x; x.saturating_sub_assign(y); println!("x := {old_x}; x.saturating_sub_assign({y}); x = {x}"); } } fn benchmark_saturating_sub_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.saturating_sub({})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_27::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.saturating_sub(y)))], ); } fn benchmark_saturating_sub_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.saturating_sub({})", T::NAME, T::NAME), BenchmarkType::Single, signed_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.saturating_sub(y)))], ); } fn benchmark_saturating_sub_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.saturating_sub_assign({})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_27::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y)| x.saturating_sub_assign(y))], ); } fn benchmark_saturating_sub_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.saturating_sub_assign({})", T::NAME, T::NAME), BenchmarkType::Single, signed_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y)| x.saturating_sub_assign(y))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/saturating_sub_mul.rs000064400000000000000000000124121046102023000272610ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::triple_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_triple_gen, unsigned_triple_gen_var_19}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_saturating_sub_mul_unsigned); register_signed_demos!(runner, demo_saturating_sub_mul_signed); register_unsigned_demos!(runner, demo_saturating_sub_mul_assign_unsigned); register_signed_demos!(runner, demo_saturating_sub_mul_assign_signed); register_unsigned_benches!(runner, benchmark_saturating_sub_mul_unsigned); register_signed_benches!(runner, benchmark_saturating_sub_mul_signed); register_unsigned_benches!(runner, benchmark_saturating_sub_mul_assign_unsigned); register_signed_benches!(runner, benchmark_saturating_sub_mul_assign_signed); } fn demo_saturating_sub_mul_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, y, z) in unsigned_triple_gen_var_19::() .get(gm, config) .take(limit) { println!( "{}.saturating_sub_mul({}, {}) = {}", x, y, z, x.saturating_sub_mul(y, z) ); } } fn demo_saturating_sub_mul_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, y, z) in signed_triple_gen::().get(gm, config).take(limit) { println!( "{}.saturating_sub_mul({}, {}) = {}", x, y, z, x.saturating_sub_mul(y, z) ); } } fn demo_saturating_sub_mul_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y, z) in unsigned_triple_gen_var_19::() .get(gm, config) .take(limit) { let old_x = x; x.saturating_sub_mul_assign(y, z); println!("x := {old_x}; x.saturating_sub_mul_assign({y}, {z}); x = {x}"); } } fn demo_saturating_sub_mul_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y, z) in signed_triple_gen::().get(gm, config).take(limit) { let old_x = x; x.saturating_sub_mul_assign(y, z); println!("x := {old_x}; x.saturating_sub_mul_assign({y}, {z}); x = {x}"); } } fn benchmark_saturating_sub_mul_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.saturating_sub_mul({}, {})", T::NAME, T::NAME, T::NAME), BenchmarkType::Single, unsigned_triple_gen_var_19::().get(gm, config), gm.name(), limit, file_name, &triple_max_bit_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(x, y, z)| { no_out!(x.saturating_sub_mul(y, z)) })], ); } fn benchmark_saturating_sub_mul_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.saturating_sub_mul({}, {})", T::NAME, T::NAME, T::NAME), BenchmarkType::Single, signed_triple_gen::().get(gm, config), gm.name(), limit, file_name, &triple_max_bit_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(x, y, z)| { no_out!(x.saturating_sub_mul(y, z)) })], ); } fn benchmark_saturating_sub_mul_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!( "{}.saturating_sub_mul_assign({}, {})", T::NAME, T::NAME, T::NAME ), BenchmarkType::Single, unsigned_triple_gen_var_19::().get(gm, config), gm.name(), limit, file_name, &triple_max_bit_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(mut x, y, z)| { x.saturating_sub_mul_assign(y, z) })], ); } fn benchmark_saturating_sub_mul_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!( "{}.saturating_sub_mul_assign({}, {})", T::NAME, T::NAME, T::NAME ), BenchmarkType::Single, signed_triple_gen::().get(gm, config), gm.name(), limit, file_name, &triple_max_bit_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(mut x, y, z)| { x.saturating_sub_mul_assign(y, z) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/shl_round.rs000064400000000000000000000140071046102023000253510ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::{ShlRound, ShlRoundAssign, UnsignedAbs}; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::triple_2_unsigned_abs_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ signed_signed_rounding_mode_triple_gen_var_4, unsigned_signed_rounding_mode_triple_gen_var_2, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_signed_demos!(runner, demo_shl_round_unsigned_signed); register_signed_signed_demos!(runner, demo_shl_round_signed_signed); register_unsigned_signed_demos!(runner, demo_shl_round_assign_unsigned_signed); register_signed_signed_demos!(runner, demo_shl_round_assign_signed_signed); register_unsigned_signed_benches!(runner, benchmark_shl_round_unsigned_signed); register_signed_signed_benches!(runner, benchmark_shl_round_signed_signed); register_unsigned_signed_benches!(runner, benchmark_shl_round_assign_unsigned_signed); register_signed_signed_benches!(runner, benchmark_shl_round_assign_signed_signed); } fn demo_shl_round_unsigned_signed< T: PrimitiveUnsigned + ShlRound, U: PrimitiveSigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (n, i, rm) in unsigned_signed_rounding_mode_triple_gen_var_2::() .get(gm, config) .take(limit) { println!("{}.shl_round({}, {}) = {:?}", n, i, rm, n.shl_round(i, rm)); } } fn demo_shl_round_signed_signed< T: PrimitiveSigned + ShlRound, U: PrimitiveSigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (n, i, rm) in signed_signed_rounding_mode_triple_gen_var_4::() .get(gm, config) .take(limit) { println!( "({}).shl_round({}, {}) = {:?}", n, i, rm, n.shl_round(i, rm) ); } } fn demo_shl_round_assign_unsigned_signed< T: PrimitiveUnsigned + ShlRoundAssign, U: PrimitiveSigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut n, i, rm) in unsigned_signed_rounding_mode_triple_gen_var_2::() .get(gm, config) .take(limit) { let old_n = n; let o = n.shl_round_assign(i, rm); println!("x := {old_n}; x.shl_round_assign({i}, {rm}) = {o:?}; x = {n}"); } } fn demo_shl_round_assign_signed_signed< T: PrimitiveSigned + ShlRoundAssign, U: PrimitiveSigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut n, i, rm) in signed_signed_rounding_mode_triple_gen_var_4::() .get(gm, config) .take(limit) { let old_n = n; let o = n.shl_round_assign(i, rm); println!("x := {old_n}; x.shl_round_assign({i}, {rm}) = {o:?}; x = {n}"); } } fn benchmark_shl_round_unsigned_signed< T: PrimitiveUnsigned + ShlRound, U: PrimitiveSigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where usize: TryFrom<::Output>, { run_benchmark( &format!("{}.shl_round({}, RoundingMode)", T::NAME, U::NAME), BenchmarkType::Single, unsigned_signed_rounding_mode_triple_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &triple_2_unsigned_abs_bucketer("i"), &mut [("Malachite", &mut |(n, i, rm)| no_out!(n.shl_round(i, rm)))], ); } fn benchmark_shl_round_signed_signed< T: PrimitiveSigned + ShlRound, U: PrimitiveSigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where usize: TryFrom<::Output>, { run_benchmark( &format!("{}.shl_round({}, RoundingMode)", T::NAME, U::NAME), BenchmarkType::Single, signed_signed_rounding_mode_triple_gen_var_4::().get(gm, config), gm.name(), limit, file_name, &triple_2_unsigned_abs_bucketer("i"), &mut [("Malachite", &mut |(n, i, rm)| no_out!(n.shl_round(i, rm)))], ); } fn benchmark_shl_round_assign_unsigned_signed< T: PrimitiveUnsigned + ShlRoundAssign, U: PrimitiveSigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where usize: TryFrom<::Output>, { run_benchmark( &format!("{}.shl_round_assign({}, RoundingMode)", T::NAME, U::NAME), BenchmarkType::Single, unsigned_signed_rounding_mode_triple_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &triple_2_unsigned_abs_bucketer("i"), &mut [("Malachite", &mut |(mut n, i, rm)| { no_out!(n.shl_round_assign(i, rm)) })], ); } fn benchmark_shl_round_assign_signed_signed< T: PrimitiveSigned + ShlRoundAssign, U: PrimitiveSigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where usize: TryFrom<::Output>, { run_benchmark( &format!("{}.shl_round_assign({}, RoundingMode)", T::NAME, U::NAME), BenchmarkType::Single, signed_signed_rounding_mode_triple_gen_var_4::().get(gm, config), gm.name(), limit, file_name, &triple_2_unsigned_abs_bucketer("i"), &mut [("Malachite", &mut |(mut n, i, rm)| { no_out!(n.shl_round_assign(i, rm)) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/shr_round.rs000064400000000000000000000260631046102023000253640ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::{ShrRound, ShrRoundAssign, UnsignedAbs}; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::{ triple_2_bucketer, triple_2_unsigned_abs_bucketer, }; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ signed_signed_rounding_mode_triple_gen_var_3, signed_unsigned_rounding_mode_triple_gen_var_2, unsigned_signed_rounding_mode_triple_gen_var_1, unsigned_unsigned_rounding_mode_triple_gen_var_4, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_unsigned_demos!(runner, demo_shr_round_unsigned_unsigned); register_unsigned_signed_demos!(runner, demo_shr_round_unsigned_signed); register_signed_unsigned_demos!(runner, demo_shr_round_signed_unsigned); register_signed_signed_demos!(runner, demo_shr_round_signed_signed); register_unsigned_unsigned_demos!(runner, demo_shr_round_assign_unsigned_unsigned); register_unsigned_signed_demos!(runner, demo_shr_round_assign_unsigned_signed); register_signed_unsigned_demos!(runner, demo_shr_round_assign_signed_unsigned); register_signed_signed_demos!(runner, demo_shr_round_assign_signed_signed); register_unsigned_unsigned_benches!(runner, benchmark_shr_round_unsigned_unsigned); register_unsigned_signed_benches!(runner, benchmark_shr_round_unsigned_signed); register_signed_unsigned_benches!(runner, benchmark_shr_round_signed_unsigned); register_signed_signed_benches!(runner, benchmark_shr_round_signed_signed); register_unsigned_unsigned_benches!(runner, benchmark_shr_round_assign_unsigned_unsigned); register_unsigned_signed_benches!(runner, benchmark_shr_round_assign_unsigned_signed); register_signed_unsigned_benches!(runner, benchmark_shr_round_assign_signed_unsigned); register_signed_signed_benches!(runner, benchmark_shr_round_assign_signed_signed); } fn demo_shr_round_unsigned_unsigned< T: PrimitiveUnsigned + ShrRound, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (n, u, rm) in unsigned_unsigned_rounding_mode_triple_gen_var_4::() .get(gm, config) .take(limit) { println!("{}.shr_round({}, {}) = {:?}", n, u, rm, n.shr_round(u, rm)); } } fn demo_shr_round_unsigned_signed< T: PrimitiveUnsigned + ShrRound, U: PrimitiveSigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (n, i, rm) in unsigned_signed_rounding_mode_triple_gen_var_1::() .get(gm, config) .take(limit) { println!("{}.shr_round({}, {}) = {:?}", n, i, rm, n.shr_round(i, rm)); } } fn demo_shr_round_signed_unsigned< T: PrimitiveSigned + ShrRound, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (n, u, rm) in signed_unsigned_rounding_mode_triple_gen_var_2::() .get(gm, config) .take(limit) { println!( "({}).shr_round({}, {}) = {:?}", n, u, rm, n.shr_round(u, rm) ); } } fn demo_shr_round_signed_signed< T: PrimitiveSigned + ShrRound, U: PrimitiveSigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (n, i, rm) in signed_signed_rounding_mode_triple_gen_var_3::() .get(gm, config) .take(limit) { println!( "({}).shr_round({}, {}) = {:?}", n, i, rm, n.shr_round(i, rm) ); } } fn demo_shr_round_assign_unsigned_unsigned< T: PrimitiveUnsigned + ShrRoundAssign, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut n, u, rm) in unsigned_unsigned_rounding_mode_triple_gen_var_4::() .get(gm, config) .take(limit) { let old_n = n; let o = n.shr_round_assign(u, rm); println!("x := {old_n}; x.shr_round_assign({u}, {rm}) = {o:?}; x = {n}"); } } fn demo_shr_round_assign_unsigned_signed< T: PrimitiveUnsigned + ShrRoundAssign, U: PrimitiveSigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut n, i, rm) in unsigned_signed_rounding_mode_triple_gen_var_1::() .get(gm, config) .take(limit) { let old_n = n; let o = n.shr_round_assign(i, rm); println!("x := {old_n}; x.shr_round_assign({i}, {rm}) = {o:?}; x = {n}"); } } fn demo_shr_round_assign_signed_unsigned< T: PrimitiveSigned + ShrRoundAssign, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut n, u, rm) in signed_unsigned_rounding_mode_triple_gen_var_2::() .get(gm, config) .take(limit) { let old_n = n; let o = n.shr_round_assign(u, rm); println!("x := {old_n}; x.shr_round_assign({u}, {rm}) = {o:?}; x = {n}"); } } fn demo_shr_round_assign_signed_signed< T: PrimitiveSigned + ShrRoundAssign, U: PrimitiveSigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut n, i, rm) in signed_signed_rounding_mode_triple_gen_var_3::() .get(gm, config) .take(limit) { let old_n = n; let o = n.shr_round_assign(i, rm); println!("x := {old_n}; x.shr_round_assign({i}, {rm}) = {o:?}; x = {n}"); } } fn benchmark_shr_round_unsigned_unsigned< T: PrimitiveUnsigned + ShrRound, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where usize: TryFrom, { run_benchmark( &format!("{}.shr_round({}, RoundingMode)", T::NAME, U::NAME), BenchmarkType::Single, unsigned_unsigned_rounding_mode_triple_gen_var_4::().get(gm, config), gm.name(), limit, file_name, &triple_2_bucketer("u"), &mut [("Malachite", &mut |(n, u, rm)| no_out!(n.shr_round(u, rm)))], ); } fn benchmark_shr_round_unsigned_signed< T: PrimitiveUnsigned + ShrRound, U: PrimitiveSigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where usize: TryFrom<::Output>, { run_benchmark( &format!("{}.shr_round({}, RoundingMode)", T::NAME, U::NAME), BenchmarkType::Single, unsigned_signed_rounding_mode_triple_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &triple_2_unsigned_abs_bucketer("i"), &mut [("Malachite", &mut |(n, i, rm)| no_out!(n.shr_round(i, rm)))], ); } fn benchmark_shr_round_signed_unsigned< T: PrimitiveSigned + ShrRound, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where usize: TryFrom, { run_benchmark( &format!("{}.shr_round({}, RoundingMode)", T::NAME, U::NAME), BenchmarkType::Single, signed_unsigned_rounding_mode_triple_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &triple_2_bucketer("u"), &mut [("Malachite", &mut |(n, u, rm)| no_out!(n.shr_round(u, rm)))], ); } fn benchmark_shr_round_signed_signed< T: PrimitiveSigned + ShrRound, U: PrimitiveSigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where usize: TryFrom<::Output>, { run_benchmark( &format!("{}.shr_round({}, RoundingMode)", T::NAME, U::NAME), BenchmarkType::Single, signed_signed_rounding_mode_triple_gen_var_3::().get(gm, config), gm.name(), limit, file_name, &triple_2_unsigned_abs_bucketer("i"), &mut [("Malachite", &mut |(n, i, rm)| no_out!(n.shr_round(i, rm)))], ); } fn benchmark_shr_round_assign_unsigned_unsigned< T: PrimitiveUnsigned + ShrRoundAssign, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where usize: TryFrom, { run_benchmark( &format!("{}.shr_round_assign({}, RoundingMode)", T::NAME, U::NAME), BenchmarkType::Single, unsigned_unsigned_rounding_mode_triple_gen_var_4::().get(gm, config), gm.name(), limit, file_name, &triple_2_bucketer("u"), &mut [("Malachite", &mut |(mut n, u, rm)| { no_out!(n.shr_round_assign(u, rm)) })], ); } fn benchmark_shr_round_assign_unsigned_signed< T: PrimitiveUnsigned + ShrRoundAssign, U: PrimitiveSigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where usize: TryFrom<::Output>, { run_benchmark( &format!("{}.shr_round_assign({}, RoundingMode)", T::NAME, U::NAME), BenchmarkType::Single, unsigned_signed_rounding_mode_triple_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &triple_2_unsigned_abs_bucketer("i"), &mut [("Malachite", &mut |(mut n, i, rm)| { no_out!(n.shr_round_assign(i, rm)) })], ); } fn benchmark_shr_round_assign_signed_unsigned< T: PrimitiveSigned + ShrRoundAssign, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where usize: TryFrom, { run_benchmark( &format!("{}.shr_round_assign({}, RoundingMode)", T::NAME, U::NAME), BenchmarkType::Single, signed_unsigned_rounding_mode_triple_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &triple_2_bucketer("u"), &mut [("Malachite", &mut |(mut n, u, rm)| { no_out!(n.shr_round_assign(u, rm)) })], ); } fn benchmark_shr_round_assign_signed_signed< T: PrimitiveSigned + ShrRoundAssign, U: PrimitiveSigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where usize: TryFrom<::Output>, { run_benchmark( &format!("{}.shr_round_assign({}, RoundingMode)", T::NAME, U::NAME), BenchmarkType::Single, signed_signed_rounding_mode_triple_gen_var_3::().get(gm, config), gm.name(), limit, file_name, &triple_2_unsigned_abs_bucketer("i"), &mut [("Malachite", &mut |(mut n, i, rm)| { no_out!(n.shr_round_assign(i, rm)) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/sign.rs000064400000000000000000000064771046102023000243300ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::bench::bucketers::{ primitive_float_bucketer, signed_bit_bucketer, unsigned_bit_bucketer, }; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{primitive_float_gen, signed_gen, unsigned_gen}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_sign_unsigned); register_signed_demos!(runner, demo_sign_signed); register_primitive_float_demos!(runner, demo_sign_primitive_float); register_unsigned_benches!(runner, benchmark_sign_unsigned); register_signed_benches!(runner, benchmark_sign_signed); register_primitive_float_benches!(runner, benchmark_sign_primitive_float); } fn demo_sign_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for u in unsigned_gen::().get(gm, config).take(limit) { println!("{}.sign() = {:?}", u, u.sign()); } } fn demo_sign_signed(gm: GenMode, config: &GenConfig, limit: usize) { for i in signed_gen::().get(gm, config).take(limit) { println!("{}.sign() = {:?}", i, i.sign()); } } fn demo_sign_primitive_float(gm: GenMode, config: &GenConfig, limit: usize) { for f in primitive_float_gen::().get(gm, config).take(limit) { println!("({}).sign() = {:?}", NiceFloat(f), f.sign()); } } fn benchmark_sign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.sign()", T::NAME), BenchmarkType::Single, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [("Malachite", &mut |u| no_out!(u.sign()))], ); } fn benchmark_sign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.sign()", T::NAME), BenchmarkType::Single, signed_gen::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [("Malachite", &mut |i| no_out!(i.sign()))], ); } fn benchmark_sign_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.sign()", T::NAME), BenchmarkType::Single, primitive_float_gen::().get(gm, config), gm.name(), limit, file_name, &primitive_float_bucketer("f"), &mut [("Malachite", &mut |f| no_out!(f.sign()))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/sqrt.rs000064400000000000000000000331271046102023000243510ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::sqrt::{ ceiling_sqrt_binary, checked_sqrt_binary, floor_sqrt_binary, sqrt_rem_binary, sqrt_rem_newton, }; use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::WrappingFrom; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::bench::bucketers::{ primitive_float_bucketer, signed_bit_bucketer, unsigned_bit_bucketer, }; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ primitive_float_gen, signed_gen_var_2, unsigned_gen, unsigned_gen_var_17, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_floor_sqrt_unsigned); register_signed_demos!(runner, demo_floor_sqrt_signed); register_unsigned_demos!(runner, demo_floor_sqrt_assign_unsigned); register_signed_demos!(runner, demo_floor_sqrt_assign_signed); register_unsigned_demos!(runner, demo_ceiling_sqrt_unsigned); register_signed_demos!(runner, demo_ceiling_sqrt_signed); register_unsigned_demos!(runner, demo_ceiling_sqrt_assign_unsigned); register_signed_demos!(runner, demo_ceiling_sqrt_assign_signed); register_unsigned_demos!(runner, demo_checked_sqrt_unsigned); register_signed_demos!(runner, demo_checked_sqrt_signed); register_unsigned_demos!(runner, demo_sqrt_rem); register_unsigned_demos!(runner, demo_sqrt_assign_rem); register_primitive_float_demos!(runner, demo_sqrt_assign); register_unsigned_benches!(runner, benchmark_floor_sqrt_algorithms_unsigned); register_signed_benches!(runner, benchmark_floor_sqrt_signed); register_unsigned_benches!(runner, benchmark_floor_sqrt_assign_unsigned); register_signed_benches!(runner, benchmark_floor_sqrt_assign_signed); register_unsigned_benches!(runner, benchmark_ceiling_sqrt_algorithms_unsigned); register_signed_benches!(runner, benchmark_ceiling_sqrt_signed); register_unsigned_benches!(runner, benchmark_ceiling_sqrt_assign_unsigned); register_signed_benches!(runner, benchmark_ceiling_sqrt_assign_signed); register_unsigned_benches!(runner, benchmark_checked_sqrt_algorithms_unsigned); register_signed_benches!(runner, benchmark_checked_sqrt_signed); register_unsigned_benches!(runner, benchmark_sqrt_rem_algorithms); register_generic_benches_2_only_first_in_key!( runner, benchmark_sqrt_rem_algorithms_2, [u32, i32], [u64, i64] ); register_unsigned_benches!(runner, benchmark_sqrt_assign_rem); register_primitive_float_benches!(runner, benchmark_sqrt_assign); } fn demo_floor_sqrt_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for n in unsigned_gen::().get(gm, config).take(limit) { println!("floor_sqrt({}) = {}", n, n.floor_sqrt()); } } fn demo_floor_sqrt_signed(gm: GenMode, config: &GenConfig, limit: usize) { for n in signed_gen_var_2::().get(gm, config).take(limit) { println!("floor_sqrt({}) = {}", n, n.floor_sqrt()); } } fn demo_floor_sqrt_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for mut n in unsigned_gen::().get(gm, config).take(limit) { let old_n = n; n.floor_sqrt_assign(); println!("n := {old_n}; n.floor_sqrt_assign(); n = {n}"); } } fn demo_floor_sqrt_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for mut n in signed_gen_var_2::().get(gm, config).take(limit) { let old_n = n; n.floor_sqrt_assign(); println!("n := {old_n}; n.floor_sqrt_assign(); n = {n}"); } } fn demo_ceiling_sqrt_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for n in unsigned_gen::().get(gm, config).take(limit) { println!("ceiling_sqrt({}) = {}", n, n.ceiling_sqrt()); } } fn demo_ceiling_sqrt_signed(gm: GenMode, config: &GenConfig, limit: usize) { for n in signed_gen_var_2::().get(gm, config).take(limit) { println!("ceiling_sqrt({}) = {}", n, n.ceiling_sqrt()); } } fn demo_ceiling_sqrt_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for mut n in unsigned_gen::().get(gm, config).take(limit) { let old_n = n; n.ceiling_sqrt_assign(); println!("n := {old_n}; n.ceiling_sqrt_assign(); n = {n}"); } } fn demo_ceiling_sqrt_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for mut n in signed_gen_var_2::().get(gm, config).take(limit) { let old_n = n; n.ceiling_sqrt_assign(); println!("n := {old_n}; n.ceiling_sqrt_assign(); n = {n}"); } } fn demo_checked_sqrt_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for n in unsigned_gen::().get(gm, config).take(limit) { println!("checked_sqrt({}) = {:?}", n, n.checked_sqrt()); } } fn demo_checked_sqrt_signed(gm: GenMode, config: &GenConfig, limit: usize) { for n in signed_gen_var_2::().get(gm, config).take(limit) { println!("checked_sqrt({}) = {:?}", n, n.checked_sqrt()); } } fn demo_sqrt_rem(gm: GenMode, config: &GenConfig, limit: usize) { for n in unsigned_gen::().get(gm, config).take(limit) { let (sqrt, rem) = n.sqrt_rem(); println!("{n} = {sqrt} ^ 2 + {rem}"); } } fn demo_sqrt_assign_rem(gm: GenMode, config: &GenConfig, limit: usize) { for mut n in unsigned_gen::().get(gm, config).take(limit) { let old_n = n; let rem = n.sqrt_assign_rem(); println!("n := {old_n}; n.sqrt_assign() = {rem}; n = {n}"); } } fn demo_sqrt_assign(gm: GenMode, config: &GenConfig, limit: usize) { for mut f in primitive_float_gen::().get(gm, config).take(limit) { let old_f = f; f.sqrt_assign(); println!( "i := {}; i.sqrt_assign(); i = {}", NiceFloat(old_f), NiceFloat(f) ); } } fn benchmark_floor_sqrt_algorithms_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.floor_sqrt()", T::NAME), BenchmarkType::Algorithms, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [ ("default", &mut |n| no_out!(n.floor_sqrt())), ("binary", &mut |n| no_out!(floor_sqrt_binary(n))), ], ); } fn benchmark_floor_sqrt_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.floor_sqrt()", T::NAME), BenchmarkType::Algorithms, signed_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [("Malachite", &mut |n| no_out!(n.floor_sqrt()))], ); } fn benchmark_floor_sqrt_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.floor_sqrt_assign()", T::NAME), BenchmarkType::Single, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [("Malachite", &mut |mut n| n.floor_sqrt_assign())], ); } fn benchmark_floor_sqrt_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.floor_sqrt_assign()", T::NAME), BenchmarkType::Single, signed_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [("Malachite", &mut |mut n| n.floor_sqrt_assign())], ); } fn benchmark_ceiling_sqrt_algorithms_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.ceiling_sqrt()", T::NAME), BenchmarkType::Algorithms, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [ ("default", &mut |n| no_out!(n.ceiling_sqrt())), ("binary", &mut |n| no_out!(ceiling_sqrt_binary(n))), ], ); } fn benchmark_ceiling_sqrt_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.ceiling_sqrt()", T::NAME), BenchmarkType::Single, signed_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [("Malachite", &mut |n| no_out!(n.ceiling_sqrt()))], ); } fn benchmark_ceiling_sqrt_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.ceiling_sqrt_assign()", T::NAME), BenchmarkType::Single, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [("Malachite", &mut |mut n| n.ceiling_sqrt_assign())], ); } fn benchmark_ceiling_sqrt_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.ceiling_sqrt_assign()", T::NAME), BenchmarkType::Single, signed_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [("Malachite", &mut |mut n| n.ceiling_sqrt_assign())], ); } fn benchmark_checked_sqrt_algorithms_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.checked_sqrt()", T::NAME), BenchmarkType::Algorithms, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [ ("default", &mut |n| no_out!(n.checked_sqrt())), ("binary", &mut |n| no_out!(checked_sqrt_binary(n))), ], ); } fn benchmark_checked_sqrt_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.checked_sqrt()", T::NAME), BenchmarkType::Single, signed_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [("Malachite", &mut |n| no_out!(n.checked_sqrt()))], ); } fn benchmark_sqrt_rem_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.sqrt_rem()", T::NAME), BenchmarkType::Algorithms, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [ ("default", &mut |n| no_out!(n.sqrt_rem())), ("binary", &mut |n| no_out!(sqrt_rem_binary(n))), ], ); } #[allow(clippy::unnecessary_operation)] fn benchmark_sqrt_rem_algorithms_2< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.sqrt_assign_rem()", U::NAME), BenchmarkType::Algorithms, unsigned_gen_var_17::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [ ("default", &mut |n| { for _ in 0..10 { n.sqrt_rem().0; } }), ("Newton's method", &mut |n| { for _ in 0..10 { sqrt_rem_newton::(n).0; } }), ], ); } fn benchmark_sqrt_assign_rem( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.sqrt_assign_rem()", T::NAME), BenchmarkType::Single, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [("Malachite", &mut |mut n| no_out!(n.sqrt_assign_rem()))], ); } fn benchmark_sqrt_assign( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.sqrt_assign()", T::NAME), BenchmarkType::Single, primitive_float_gen::().get(gm, config), gm.name(), limit, file_name, &primitive_float_bucketer("f"), &mut [("Malachite", &mut |mut f| f.sqrt_assign())], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/square.rs000064400000000000000000000151051046102023000246540ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::WrappingFrom; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::bench::bucketers::{ primitive_float_bucketer, signed_bit_bucketer, unsigned_bit_bucketer, }; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ primitive_float_gen, signed_gen_var_10, unsigned_gen_var_21, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_square_unsigned); register_unsigned_demos!(runner, demo_square_assign_unsigned); register_signed_unsigned_match_demos!(runner, demo_square_signed); register_signed_unsigned_match_demos!(runner, demo_square_assign_signed); register_primitive_float_demos!(runner, demo_square_primitive_float); register_primitive_float_demos!(runner, demo_square_assign_primitive_float); register_unsigned_benches!(runner, benchmark_square_unsigned); register_unsigned_benches!(runner, benchmark_square_assign_unsigned); register_signed_unsigned_match_benches!(runner, benchmark_square_signed); register_signed_unsigned_match_benches!(runner, benchmark_square_assign_signed); register_primitive_float_benches!(runner, benchmark_square_primitive_float); register_primitive_float_benches!(runner, benchmark_square_assign_primitive_float); } fn demo_square_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for u in unsigned_gen_var_21::().get(gm, config).take(limit) { println!("{}.square() = {}", u, u.square()); } } fn demo_square_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for mut u in unsigned_gen_var_21::().get(gm, config).take(limit) { let old_u = u; u.square_assign(); println!("u := {old_u}; u.square_assign(); u = {u}"); } } fn demo_square_signed< S: PrimitiveSigned + WrappingFrom, U: PrimitiveUnsigned + WrappingFrom, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for i in signed_gen_var_10::().get(gm, config).take(limit) { println!("{}.square() = {}", i, i.square()); } } fn demo_square_assign_signed< S: PrimitiveSigned + WrappingFrom, U: PrimitiveUnsigned + WrappingFrom, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for mut i in signed_gen_var_10::().get(gm, config).take(limit) { let old_i = i; i.square_assign(); println!("i := {old_i}; i.square_assign(); i = {i}"); } } fn demo_square_primitive_float(gm: GenMode, config: &GenConfig, limit: usize) { for f in primitive_float_gen::().get(gm, config).take(limit) { println!("({}).square() = {}", NiceFloat(f), NiceFloat(f.square())); } } fn demo_square_assign_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, ) { for mut f in primitive_float_gen::().get(gm, config).take(limit) { let old_f = f; f.square_assign(); println!( "f := {}; f.square_assign(); x = {}", NiceFloat(old_f), NiceFloat(f) ); } } fn benchmark_square_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.square()", T::NAME), BenchmarkType::Single, unsigned_gen_var_21::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [("Malachite", &mut |u| no_out!(u.square()))], ); } fn benchmark_square_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.square_assign()", T::NAME), BenchmarkType::Single, unsigned_gen_var_21::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [("Malachite", &mut |mut u| u.square_assign())], ); } fn benchmark_square_signed< S: PrimitiveSigned + WrappingFrom, U: PrimitiveUnsigned + WrappingFrom, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.square()", S::NAME), BenchmarkType::Single, signed_gen_var_10::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [("Malachite", &mut |i| no_out!(i.square()))], ); } fn benchmark_square_assign_signed< S: PrimitiveSigned + WrappingFrom, U: PrimitiveUnsigned + WrappingFrom, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.square_assign()", S::NAME), BenchmarkType::Single, signed_gen_var_10::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [("Malachite", &mut |mut i| i.square_assign())], ); } fn benchmark_square_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.square()", T::NAME), BenchmarkType::Single, primitive_float_gen::().get(gm, config), gm.name(), limit, file_name, &primitive_float_bucketer("f"), &mut [("Malachite", &mut |f| no_out!(f.square()))], ); } fn benchmark_square_assign_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.square_assign()", T::NAME), BenchmarkType::Single, primitive_float_gen::().get(gm, config), gm.name(), limit, file_name, &primitive_float_bucketer("f"), &mut [("Malachite", &mut |mut f| f.square_assign())], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/sub_mul.rs000064400000000000000000000156311046102023000250260ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::bench::bucketers::{ triple_max_bit_bucketer, triple_max_primitive_float_bucketer, }; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ primitive_float_triple_gen, signed_triple_gen_var_2, unsigned_triple_gen_var_2, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_sub_mul_unsigned); register_signed_demos!(runner, demo_sub_mul_signed); register_primitive_float_demos!(runner, demo_sub_mul_primitive_float); register_unsigned_demos!(runner, demo_sub_mul_assign_unsigned); register_signed_demos!(runner, demo_sub_mul_assign_signed); register_primitive_float_demos!(runner, demo_sub_mul_assign_primitive_float); register_unsigned_benches!(runner, benchmark_sub_mul_unsigned); register_signed_benches!(runner, benchmark_sub_mul_signed); register_primitive_float_benches!(runner, benchmark_sub_mul_primitive_float); register_unsigned_benches!(runner, benchmark_sub_mul_assign_unsigned); register_signed_benches!(runner, benchmark_sub_mul_assign_signed); register_primitive_float_benches!(runner, benchmark_sub_mul_assign_primitive_float); } fn demo_sub_mul_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y, z) in unsigned_triple_gen_var_2::().get(gm, config).take(limit) { println!("{}.sub_mul({}, {}) = {}", x, y, z, x.sub_mul(y, z)); } } fn demo_sub_mul_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y, z) in signed_triple_gen_var_2::().get(gm, config).take(limit) { println!("({}).sub_mul({}, {}) = {}", x, y, z, x.sub_mul(y, z)); } } fn demo_sub_mul_primitive_float(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y, z) in primitive_float_triple_gen::() .get(gm, config) .take(limit) { println!( "({}).sub_mul({}, {}) = {}", NiceFloat(x), NiceFloat(y), NiceFloat(z), NiceFloat(x.sub_mul(y, z)) ); } } fn demo_sub_mul_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y, z) in unsigned_triple_gen_var_2::().get(gm, config).take(limit) { let old_x = x; x.sub_mul_assign(y, z); println!("x := {old_x}; x.sub_mul_assign({y}, {z}); x = {x}"); } } fn demo_sub_mul_assign_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (mut x, y, z) in signed_triple_gen_var_2::().get(gm, config).take(limit) { let old_x = x; x.sub_mul_assign(y, z); println!("x := {old_x}; x.sub_mul_assign({y}, {z}); x = {x}"); } } fn demo_sub_mul_assign_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y, z) in primitive_float_triple_gen::() .get(gm, config) .take(limit) { let old_x = x; x.sub_mul_assign(y, z); println!( "x := {}; x.sub_mul_assign({}, {}); x = {}", NiceFloat(old_x), NiceFloat(y), NiceFloat(z), NiceFloat(x) ); } } fn benchmark_sub_mul_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.sub_mul({}, {})", T::NAME, T::NAME, T::NAME), BenchmarkType::Single, unsigned_triple_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &triple_max_bit_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(x, y, z)| no_out!(x.sub_mul(y, z)))], ); } fn benchmark_sub_mul_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.sub_mul({}, {})", T::NAME, T::NAME, T::NAME), BenchmarkType::Single, signed_triple_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &triple_max_bit_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(x, y, z)| no_out!(x.sub_mul(y, z)))], ); } fn benchmark_sub_mul_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.sub_mul({}, {})", T::NAME, T::NAME, T::NAME), BenchmarkType::Single, primitive_float_triple_gen::().get(gm, config), gm.name(), limit, file_name, &triple_max_primitive_float_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(x, y, z)| no_out!(x.sub_mul(y, z)))], ); } fn benchmark_sub_mul_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.sub_mul_assign({}, {})", T::NAME, T::NAME, T::NAME), BenchmarkType::Single, unsigned_triple_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &triple_max_bit_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(mut x, y, z)| x.sub_mul_assign(y, z))], ); } fn benchmark_sub_mul_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.sub_mul_assign({}, {})", T::NAME, T::NAME, T::NAME), BenchmarkType::Single, signed_triple_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &triple_max_bit_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(mut x, y, z)| x.sub_mul_assign(y, z))], ); } fn benchmark_sub_mul_assign_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.sub_mul_assign({}, {})", T::NAME, T::NAME, T::NAME), BenchmarkType::Single, primitive_float_triple_gen::().get(gm, config), gm.name(), limit, file_name, &triple_max_primitive_float_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(mut x, y, z)| x.sub_mul_assign(y, z))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/wrapping_abs.rs000064400000000000000000000032111046102023000260230ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::test_util::bench::bucketers::signed_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::signed_gen; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_signed_demos!(runner, demo_wrapping_abs_assign); register_signed_benches!(runner, benchmark_wrapping_abs_assign); } fn demo_wrapping_abs_assign(gm: GenMode, config: &GenConfig, limit: usize) { for mut i in signed_gen::().get(gm, config).take(limit) { let old_i = i; i.wrapping_abs_assign(); println!("i := {old_i}; i.wrapping_abs_assign(); i = {i}"); } } fn benchmark_wrapping_abs_assign( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.wrapping_abs_assign()", T::NAME), BenchmarkType::Single, signed_gen::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [("Malachite", &mut |mut i| i.wrapping_abs_assign())], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/wrapping_add.rs000064400000000000000000000107641046102023000260210ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::pair_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_pair_gen, unsigned_pair_gen_var_27}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_wrapping_add_unsigned); register_signed_demos!(runner, demo_wrapping_add_signed); register_unsigned_demos!(runner, demo_wrapping_add_assign_unsigned); register_signed_demos!(runner, demo_wrapping_add_assign_signed); register_unsigned_benches!(runner, benchmark_wrapping_add_unsigned); register_signed_benches!(runner, benchmark_wrapping_add_signed); register_unsigned_benches!(runner, benchmark_wrapping_add_assign_unsigned); register_signed_benches!(runner, benchmark_wrapping_add_assign_signed); } fn demo_wrapping_add_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in unsigned_pair_gen_var_27::().get(gm, config).take(limit) { println!("{}.wrapping_add({}) = {}", x, y, x.wrapping_add(y)); } } fn demo_wrapping_add_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in signed_pair_gen::().get(gm, config).take(limit) { println!("({}).wrapping_add({}) = {}", x, y, x.wrapping_add(y)); } } fn demo_wrapping_add_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y) in unsigned_pair_gen_var_27::().get(gm, config).take(limit) { let old_x = x; x.wrapping_add_assign(y); println!("x := {old_x}; x.wrapping_add_assign({y}); x = {x}"); } } fn demo_wrapping_add_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y) in signed_pair_gen::().get(gm, config).take(limit) { let old_x = x; x.wrapping_add_assign(y); println!("x := {old_x}; x.wrapping_add_assign({y}); x = {x}"); } } fn benchmark_wrapping_add_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.wrapping_add({})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_27::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.wrapping_add(y)))], ); } fn benchmark_wrapping_add_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.wrapping_add({})", T::NAME, T::NAME), BenchmarkType::Single, signed_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.wrapping_add(y)))], ); } fn benchmark_wrapping_add_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.wrapping_add_assign({})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_27::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y)| x.wrapping_add_assign(y))], ); } fn benchmark_wrapping_add_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.wrapping_add_assign({})", T::NAME, T::NAME), BenchmarkType::Single, signed_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y)| x.wrapping_add_assign(y))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/wrapping_add_mul.rs000064400000000000000000000122731046102023000266730ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::triple_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_triple_gen, unsigned_triple_gen_var_19}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_wrapping_add_mul_unsigned); register_signed_demos!(runner, demo_wrapping_add_mul_signed); register_unsigned_demos!(runner, demo_wrapping_add_mul_assign_unsigned); register_signed_demos!(runner, demo_wrapping_add_mul_assign_signed); register_unsigned_benches!(runner, benchmark_wrapping_add_mul_unsigned); register_signed_benches!(runner, benchmark_wrapping_add_mul_signed); register_unsigned_benches!(runner, benchmark_wrapping_add_mul_assign_unsigned); register_signed_benches!(runner, benchmark_wrapping_add_mul_assign_signed); } fn demo_wrapping_add_mul_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, y, z) in unsigned_triple_gen_var_19::() .get(gm, config) .take(limit) { println!( "{}.wrapping_add_mul({}, {}) = {}", x, y, z, x.wrapping_add_mul(y, z) ); } } fn demo_wrapping_add_mul_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y, z) in signed_triple_gen::().get(gm, config).take(limit) { println!( "{}.wrapping_add_mul({}, {}) = {}", x, y, z, x.wrapping_add_mul(y, z) ); } } fn demo_wrapping_add_mul_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y, z) in unsigned_triple_gen_var_19::() .get(gm, config) .take(limit) { let old_x = x; x.wrapping_add_mul_assign(y, z); println!("x := {old_x}; x.wrapping_add_mul_assign({y}, {z}); x = {x}"); } } fn demo_wrapping_add_mul_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y, z) in signed_triple_gen::().get(gm, config).take(limit) { let old_x = x; x.wrapping_add_mul_assign(y, z); println!("x := {old_x}; x.wrapping_add_mul_assign({y}, {z}); x = {x}"); } } fn benchmark_wrapping_add_mul_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.wrapping_add_mul({}, {})", T::NAME, T::NAME, T::NAME), BenchmarkType::Single, unsigned_triple_gen_var_19::().get(gm, config), gm.name(), limit, file_name, &triple_max_bit_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(x, y, z)| { no_out!(x.wrapping_add_mul(y, z)) })], ); } fn benchmark_wrapping_add_mul_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.wrapping_add_mul({}, {})", T::NAME, T::NAME, T::NAME), BenchmarkType::Single, signed_triple_gen::().get(gm, config), gm.name(), limit, file_name, &triple_max_bit_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(x, y, z)| { no_out!(x.wrapping_add_mul(y, z)) })], ); } fn benchmark_wrapping_add_mul_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!( "{}.wrapping_add_mul_assign({}, {})", T::NAME, T::NAME, T::NAME ), BenchmarkType::Single, unsigned_triple_gen_var_19::().get(gm, config), gm.name(), limit, file_name, &triple_max_bit_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(mut x, y, z)| { x.wrapping_add_mul_assign(y, z) })], ); } fn benchmark_wrapping_add_mul_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!( "{}.wrapping_add_mul_assign({}, {})", T::NAME, T::NAME, T::NAME ), BenchmarkType::Single, signed_triple_gen::().get(gm, config), gm.name(), limit, file_name, &triple_max_bit_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(mut x, y, z)| { x.wrapping_add_mul_assign(y, z) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/wrapping_div.rs000064400000000000000000000111121046102023000260370ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::pair_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_pair_gen_var_6, unsigned_pair_gen_var_12}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_wrapping_div_unsigned); register_signed_demos!(runner, demo_wrapping_div_signed); register_unsigned_demos!(runner, demo_wrapping_div_assign_unsigned); register_signed_demos!(runner, demo_wrapping_div_assign_signed); register_unsigned_benches!(runner, benchmark_wrapping_div_unsigned); register_signed_benches!(runner, benchmark_wrapping_div_signed); register_unsigned_benches!(runner, benchmark_wrapping_div_assign_unsigned); register_signed_benches!(runner, benchmark_wrapping_div_assign_signed); } fn demo_wrapping_div_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in unsigned_pair_gen_var_12::() .get(gm, config) .take(limit) { println!("{}.wrapping_div({}) = {}", x, y, x.wrapping_div(y)); } } fn demo_wrapping_div_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in signed_pair_gen_var_6::().get(gm, config).take(limit) { println!("({}).wrapping_div({}) = {}", x, y, x.wrapping_div(y)); } } fn demo_wrapping_div_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y) in unsigned_pair_gen_var_12::() .get(gm, config) .take(limit) { let old_x = x; x.wrapping_div_assign(y); println!("x := {old_x}; x.wrapping_div_assign({y}); x = {x}"); } } fn demo_wrapping_div_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y) in signed_pair_gen_var_6::().get(gm, config).take(limit) { let old_x = x; x.wrapping_div_assign(y); println!("x := {old_x}; x.wrapping_div_assign({y}); x = {x}"); } } fn benchmark_wrapping_div_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.wrapping_div({})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_12::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.wrapping_div(y)))], ); } fn benchmark_wrapping_div_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.wrapping_div({})", T::NAME, T::NAME), BenchmarkType::Single, signed_pair_gen_var_6::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.wrapping_div(y)))], ); } fn benchmark_wrapping_div_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.wrapping_div_assign({})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_12::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y)| x.wrapping_div_assign(y))], ); } fn benchmark_wrapping_div_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.wrapping_div_assign({})", T::NAME, T::NAME), BenchmarkType::Single, signed_pair_gen_var_6::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y)| x.wrapping_div_assign(y))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/wrapping_mul.rs000064400000000000000000000107641046102023000260660ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::pair_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_pair_gen, unsigned_pair_gen_var_27}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_wrapping_mul_unsigned); register_signed_demos!(runner, demo_wrapping_mul_signed); register_unsigned_demos!(runner, demo_wrapping_mul_assign_unsigned); register_signed_demos!(runner, demo_wrapping_mul_assign_signed); register_unsigned_benches!(runner, benchmark_wrapping_mul_unsigned); register_signed_benches!(runner, benchmark_wrapping_mul_signed); register_unsigned_benches!(runner, benchmark_wrapping_mul_assign_unsigned); register_signed_benches!(runner, benchmark_wrapping_mul_assign_signed); } fn demo_wrapping_mul_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in unsigned_pair_gen_var_27::().get(gm, config).take(limit) { println!("{}.wrapping_mul({}) = {}", x, y, x.wrapping_mul(y)); } } fn demo_wrapping_mul_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in signed_pair_gen::().get(gm, config).take(limit) { println!("({}).wrapping_mul({}) = {}", x, y, x.wrapping_mul(y)); } } fn demo_wrapping_mul_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y) in unsigned_pair_gen_var_27::().get(gm, config).take(limit) { let old_x = x; x.wrapping_mul_assign(y); println!("x := {old_x}; x.wrapping_mul_assign({y}); x = {x}"); } } fn demo_wrapping_mul_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y) in signed_pair_gen::().get(gm, config).take(limit) { let old_x = x; x.wrapping_mul_assign(y); println!("x := {old_x}; x.wrapping_mul_assign({y}); x = {x}"); } } fn benchmark_wrapping_mul_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.wrapping_mul({})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_27::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.wrapping_mul(y)))], ); } fn benchmark_wrapping_mul_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.wrapping_mul({})", T::NAME, T::NAME), BenchmarkType::Single, signed_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.wrapping_mul(y)))], ); } fn benchmark_wrapping_mul_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.wrapping_mul_assign({})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_27::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y)| x.wrapping_mul_assign(y))], ); } fn benchmark_wrapping_mul_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.wrapping_mul_assign({})", T::NAME, T::NAME), BenchmarkType::Single, signed_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y)| x.wrapping_mul_assign(y))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/wrapping_neg.rs000064400000000000000000000053071046102023000260370ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::{signed_bit_bucketer, unsigned_bit_bucketer}; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_gen, unsigned_gen}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_wrapping_neg_assign_unsigned); register_signed_demos!(runner, demo_wrapping_neg_assign_signed); register_unsigned_benches!(runner, benchmark_wrapping_neg_assign_unsigned); register_signed_benches!(runner, benchmark_wrapping_neg_assign_signed); } fn demo_wrapping_neg_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for mut u in unsigned_gen::().get(gm, config).take(limit) { let old_u = u; u.wrapping_neg_assign(); println!("u := {old_u}; u.wrapping_neg_assign(); u = {u}"); } } fn demo_wrapping_neg_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for mut i in signed_gen::().get(gm, config).take(limit) { let old_i = i; i.wrapping_neg_assign(); println!("i := {old_i}; i.wrapping_neg_assign(); i = {i}"); } } fn benchmark_wrapping_neg_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.wrapping_neg_assign()", T::NAME), BenchmarkType::Single, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [("Malachite", &mut |mut i| i.wrapping_neg_assign())], ); } fn benchmark_wrapping_neg_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.wrapping_neg_assign()", T::NAME), BenchmarkType::Single, signed_gen::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [("Malachite", &mut |mut i| i.wrapping_neg_assign())], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/wrapping_pow.rs000064400000000000000000000055111046102023000260700ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::pair_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_unsigned_pair_gen, unsigned_pair_gen}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_wrapping_pow_assign_unsigned); register_signed_demos!(runner, demo_wrapping_pow_assign_signed); register_unsigned_benches!(runner, benchmark_wrapping_pow_assign_unsigned); register_signed_benches!(runner, benchmark_wrapping_pow_assign_signed); } fn demo_wrapping_pow_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y) in unsigned_pair_gen::().get(gm, config).take(limit) { let old_x = x; x.wrapping_pow_assign(y); println!("x := {old_x}; x.wrapping_pow_assign({y}); x = {x}"); } } fn demo_wrapping_pow_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y) in signed_unsigned_pair_gen::() .get(gm, config) .take(limit) { let old_x = x; x.wrapping_pow_assign(y); println!("x := {old_x}; x.wrapping_pow_assign({y}); x = {x}"); } } fn benchmark_wrapping_pow_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.wrapping_pow_assign(u64)", T::NAME), BenchmarkType::Single, unsigned_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y)| x.wrapping_pow_assign(y))], ); } fn benchmark_wrapping_pow_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.wrapping_pow_assign(u64)", T::NAME), BenchmarkType::Single, signed_unsigned_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y)| x.wrapping_pow_assign(y))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/wrapping_square.rs000064400000000000000000000106231046102023000265630ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::{signed_bit_bucketer, unsigned_bit_bucketer}; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_gen, unsigned_gen}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_wrapping_square_unsigned); register_signed_demos!(runner, demo_wrapping_square_signed); register_unsigned_demos!(runner, demo_wrapping_square_assign_unsigned); register_signed_demos!(runner, demo_wrapping_square_assign_signed); register_unsigned_benches!(runner, benchmark_wrapping_square_unsigned); register_signed_benches!(runner, benchmark_wrapping_square_signed); register_unsigned_benches!(runner, benchmark_wrapping_square_assign_unsigned); register_signed_benches!(runner, benchmark_wrapping_square_assign_signed); } fn demo_wrapping_square_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for x in unsigned_gen::().get(gm, config).take(limit) { println!("{}.wrapping_square() = {}", x, x.wrapping_square()); } } fn demo_wrapping_square_signed(gm: GenMode, config: &GenConfig, limit: usize) { for x in signed_gen::().get(gm, config).take(limit) { println!("{}.wrapping_square() = {}", x, x.wrapping_square()); } } fn demo_wrapping_square_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for mut x in unsigned_gen::().get(gm, config).take(limit) { let old_x = x; x.wrapping_square_assign(); println!("x := {old_x}; x.wrapping_square_assign(); x = {x}"); } } fn demo_wrapping_square_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for mut x in signed_gen::().get(gm, config).take(limit) { let old_x = x; x.wrapping_square_assign(); println!("x := {old_x}; x.wrapping_square_assign(); x = {x}"); } } fn benchmark_wrapping_square_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.wrapping_square()", T::NAME), BenchmarkType::Single, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [("Malachite", &mut |x| no_out!(x.wrapping_square()))], ); } fn benchmark_wrapping_square_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.wrapping_square()", T::NAME), BenchmarkType::Single, signed_gen::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [("Malachite", &mut |x| no_out!(x.wrapping_square()))], ); } fn benchmark_wrapping_square_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.wrapping_square_assign()", T::NAME), BenchmarkType::Single, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [("Malachite", &mut |mut x| x.wrapping_square_assign())], ); } fn benchmark_wrapping_square_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.wrapping_square_assign()", T::NAME), BenchmarkType::Single, signed_gen::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [("Malachite", &mut |mut x| x.wrapping_square_assign())], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/wrapping_sub.rs000064400000000000000000000107641046102023000260620ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::pair_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_pair_gen, unsigned_pair_gen_var_27}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_wrapping_sub_unsigned); register_signed_demos!(runner, demo_wrapping_sub_signed); register_unsigned_demos!(runner, demo_wrapping_sub_assign_unsigned); register_signed_demos!(runner, demo_wrapping_sub_assign_signed); register_unsigned_benches!(runner, benchmark_wrapping_sub_unsigned); register_signed_benches!(runner, benchmark_wrapping_sub_signed); register_unsigned_benches!(runner, benchmark_wrapping_sub_assign_unsigned); register_signed_benches!(runner, benchmark_wrapping_sub_assign_signed); } fn demo_wrapping_sub_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in unsigned_pair_gen_var_27::().get(gm, config).take(limit) { println!("{}.wrapping_sub({}) = {}", x, y, x.wrapping_sub(y)); } } fn demo_wrapping_sub_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in signed_pair_gen::().get(gm, config).take(limit) { println!("({}).wrapping_sub({}) = {}", x, y, x.wrapping_sub(y)); } } fn demo_wrapping_sub_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y) in unsigned_pair_gen_var_27::().get(gm, config).take(limit) { let old_x = x; x.wrapping_sub_assign(y); println!("x := {old_x}; x.wrapping_sub_assign({y}); x = {x}"); } } fn demo_wrapping_sub_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y) in signed_pair_gen::().get(gm, config).take(limit) { let old_x = x; x.wrapping_sub_assign(y); println!("x := {old_x}; x.wrapping_sub_assign({y}); x = {x}"); } } fn benchmark_wrapping_sub_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.wrapping_sub({})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_27::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.wrapping_sub(y)))], ); } fn benchmark_wrapping_sub_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.wrapping_sub({})", T::NAME, T::NAME), BenchmarkType::Single, signed_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.wrapping_sub(y)))], ); } fn benchmark_wrapping_sub_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.wrapping_sub_assign({})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_27::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y)| x.wrapping_sub_assign(y))], ); } fn benchmark_wrapping_sub_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.wrapping_sub_assign({})", T::NAME, T::NAME), BenchmarkType::Single, signed_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(mut x, y)| x.wrapping_sub_assign(y))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/wrapping_sub_mul.rs000064400000000000000000000122731046102023000267340ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::triple_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_triple_gen, unsigned_triple_gen_var_19}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_wrapping_sub_mul_unsigned); register_signed_demos!(runner, demo_wrapping_sub_mul_signed); register_unsigned_demos!(runner, demo_wrapping_sub_mul_assign_unsigned); register_signed_demos!(runner, demo_wrapping_sub_mul_assign_signed); register_unsigned_benches!(runner, benchmark_wrapping_sub_mul_unsigned); register_signed_benches!(runner, benchmark_wrapping_sub_mul_signed); register_unsigned_benches!(runner, benchmark_wrapping_sub_mul_assign_unsigned); register_signed_benches!(runner, benchmark_wrapping_sub_mul_assign_signed); } fn demo_wrapping_sub_mul_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, y, z) in unsigned_triple_gen_var_19::() .get(gm, config) .take(limit) { println!( "{}.wrapping_sub_mul({}, {}) = {}", x, y, z, x.wrapping_sub_mul(y, z) ); } } fn demo_wrapping_sub_mul_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y, z) in signed_triple_gen::().get(gm, config).take(limit) { println!( "{}.wrapping_sub_mul({}, {}) = {}", x, y, z, x.wrapping_sub_mul(y, z) ); } } fn demo_wrapping_sub_mul_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y, z) in unsigned_triple_gen_var_19::() .get(gm, config) .take(limit) { let old_x = x; x.wrapping_sub_mul_assign(y, z); println!("x := {old_x}; x.wrapping_sub_mul_assign({y}, {z}); x = {x}"); } } fn demo_wrapping_sub_mul_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut x, y, z) in signed_triple_gen::().get(gm, config).take(limit) { let old_x = x; x.wrapping_sub_mul_assign(y, z); println!("x := {old_x}; x.wrapping_sub_mul_assign({y}, {z}); x = {x}"); } } fn benchmark_wrapping_sub_mul_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.wrapping_sub_mul({}, {})", T::NAME, T::NAME, T::NAME), BenchmarkType::Single, unsigned_triple_gen_var_19::().get(gm, config), gm.name(), limit, file_name, &triple_max_bit_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(x, y, z)| { no_out!(x.wrapping_sub_mul(y, z)) })], ); } fn benchmark_wrapping_sub_mul_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.wrapping_sub_mul({}, {})", T::NAME, T::NAME, T::NAME), BenchmarkType::Single, signed_triple_gen::().get(gm, config), gm.name(), limit, file_name, &triple_max_bit_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(x, y, z)| { no_out!(x.wrapping_sub_mul(y, z)) })], ); } fn benchmark_wrapping_sub_mul_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!( "{}.wrapping_sub_mul_assign({}, {})", T::NAME, T::NAME, T::NAME ), BenchmarkType::Single, unsigned_triple_gen_var_19::().get(gm, config), gm.name(), limit, file_name, &triple_max_bit_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(mut x, y, z)| { x.wrapping_sub_mul_assign(y, z) })], ); } fn benchmark_wrapping_sub_mul_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!( "{}.wrapping_sub_mul_assign({}, {})", T::NAME, T::NAME, T::NAME ), BenchmarkType::Single, signed_triple_gen::().get(gm, config), gm.name(), limit, file_name, &triple_max_bit_bucketer("x", "y", "z"), &mut [("Malachite", &mut |(mut x, y, z)| { x.wrapping_sub_mul_assign(y, z) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/x_mul_y_to_zz.rs000064400000000000000000000036001046102023000262520ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::x_mul_y_to_zz::explicit_x_mul_y_to_zz; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::pair_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_pair_gen_var_27; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_x_mul_y_to_zz); register_unsigned_benches!(runner, benchmark_x_mul_y_to_zz_algorithms); } fn demo_x_mul_y_to_zz(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in unsigned_pair_gen_var_27::().get(gm, config).take(limit) { println!("{} * {} = {:?}", x, y, T::x_mul_y_to_zz(x, y)); } } fn benchmark_x_mul_y_to_zz_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}::x_mul_y_to_zz({}, {})", T::NAME, T::NAME, T::NAME), BenchmarkType::Algorithms, unsigned_pair_gen_var_27::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [ ("default", &mut |(x, y)| no_out!(T::x_mul_y_to_zz(x, y))), ("explicit", &mut |(x, y)| { no_out!(explicit_x_mul_y_to_zz(x, y)) }), ], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/xx_add_yy_to_zz.rs000064400000000000000000000044411046102023000265720ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::xx_add_yy_to_zz::explicit_xx_add_yy_to_zz; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::quadruple_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_quadruple_gen_var_10; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_xx_add_yy_to_zz); register_unsigned_benches!(runner, benchmark_xx_add_yy_to_zz_algorithms); } fn demo_xx_add_yy_to_zz(gm: GenMode, config: &GenConfig, limit: usize) { for (x_1, x_0, y_1, y_0) in unsigned_quadruple_gen_var_10::() .get(gm, config) .take(limit) { println!( "[{}, {}] + [{}, {}] = {:?}", x_1, x_0, y_1, y_0, T::xx_add_yy_to_zz(x_1, x_0, y_1, y_0) ); } } fn benchmark_xx_add_yy_to_zz_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!( "{}::xx_add_yy_to_zz({}, {}, {}, {})", T::NAME, T::NAME, T::NAME, T::NAME, T::NAME ), BenchmarkType::Algorithms, unsigned_quadruple_gen_var_10::().get(gm, config), gm.name(), limit, file_name, &quadruple_max_bit_bucketer("x_1", "x_0", "y_1", "y_0"), &mut [ ("default", &mut |(x_1, x_0, y_1, y_0)| { no_out!(T::xx_add_yy_to_zz(x_1, x_0, y_1, y_0)) }), ("explicit", &mut |(x_1, x_0, y_1, y_0)| { no_out!(explicit_xx_add_yy_to_zz(x_1, x_0, y_1, y_0)) }), ], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/xx_div_mod_y_to_qr.rs000064400000000000000000000043301046102023000272460ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::xx_div_mod_y_to_qr::explicit_xx_div_mod_y_to_qr; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::triple_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_triple_gen_var_15; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_xx_div_mod_y_to_qr); register_unsigned_benches!(runner, benchmark_xx_div_mod_y_to_qr_algorithms); } fn demo_xx_div_mod_y_to_qr(gm: GenMode, config: &GenConfig, limit: usize) { for (x_1, x_0, y) in unsigned_triple_gen_var_15::() .get(gm, config) .take(limit) { println!( "[{}, {}].div_mod({}) = {:?}", x_1, x_0, y, T::xx_div_mod_y_to_qr(x_1, x_0, y) ); } } fn benchmark_xx_div_mod_y_to_qr_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!( "{}::xx_div_mod_y_to_qr({}, {}, {})", T::NAME, T::NAME, T::NAME, T::NAME ), BenchmarkType::Algorithms, unsigned_triple_gen_var_15::().get(gm, config), gm.name(), limit, file_name, &triple_max_bit_bucketer("x_1", "x_0", "y"), &mut [ ("default", &mut |(x_1, x_0, y)| { no_out!(T::xx_div_mod_y_to_qr(x_1, x_0, y)) }), ("explicit", &mut |(x_1, x_0, y)| { no_out!(explicit_xx_div_mod_y_to_qr(x_1, x_0, y)) }), ], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/xx_sub_yy_to_zz.rs000064400000000000000000000044411046102023000266330ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::xx_sub_yy_to_zz::explicit_xx_sub_yy_to_zz; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::quadruple_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_quadruple_gen_var_10; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_xx_sub_yy_to_zz); register_unsigned_benches!(runner, benchmark_xx_sub_yy_to_zz_algorithms); } fn demo_xx_sub_yy_to_zz(gm: GenMode, config: &GenConfig, limit: usize) { for (x_1, x_0, y_1, y_0) in unsigned_quadruple_gen_var_10::() .get(gm, config) .take(limit) { println!( "[{}, {}] - [{}, {}] = {:?}", x_1, x_0, y_1, y_0, T::xx_sub_yy_to_zz(x_1, x_0, y_1, y_0) ); } } fn benchmark_xx_sub_yy_to_zz_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!( "{}::xx_sub_yy_to_zz({}, {}, {}, {})", T::NAME, T::NAME, T::NAME, T::NAME, T::NAME ), BenchmarkType::Algorithms, unsigned_quadruple_gen_var_10::().get(gm, config), gm.name(), limit, file_name, &quadruple_max_bit_bucketer("x_1", "x_0", "y_1", "y_0"), &mut [ ("default", &mut |(x_1, x_0, y_1, y_0)| { no_out!(T::xx_sub_yy_to_zz(x_1, x_0, y_1, y_0)) }), ("explicit", &mut |(x_1, x_0, y_1, y_0)| { no_out!(explicit_xx_sub_yy_to_zz(x_1, x_0, y_1, y_0)) }), ], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/xxx_add_yyy_to_zzz.rs000064400000000000000000000042521046102023000273450ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::sextuple_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_sextuple_gen_var_1; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_xxx_add_yyy_to_zzz); register_unsigned_benches!(runner, benchmark_xxx_add_yyy_to_zzz); } fn demo_xxx_add_yyy_to_zzz(gm: GenMode, config: &GenConfig, limit: usize) { for (x_2, x_1, x_0, y_2, y_1, y_0) in unsigned_sextuple_gen_var_1::() .get(gm, config) .take(limit) { println!( "[{}, {}, {}] + [{}, {}, {}] = {:?}", x_2, x_1, x_0, y_2, y_1, y_0, T::xxx_add_yyy_to_zzz(x_2, x_1, x_0, y_2, y_1, y_0) ); } } fn benchmark_xxx_add_yyy_to_zzz( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!( "{}::xxx_add_yyy_to_zzz({}, {}, {}, {}, {}, {})", T::NAME, T::NAME, T::NAME, T::NAME, T::NAME, T::NAME, T::NAME ), BenchmarkType::Single, unsigned_sextuple_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &sextuple_max_bit_bucketer("x_2", "x_1", "x_0", "y_2", "y_1", "y_0"), &mut [("default", &mut |(x_2, x_1, x_0, y_2, y_1, y_0)| { no_out!(T::xxx_add_yyy_to_zzz(x_2, x_1, x_0, y_2, y_1, y_0)) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/xxx_sub_yyy_to_zzz.rs000064400000000000000000000042521046102023000274060ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::sextuple_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_sextuple_gen_var_1; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_xxx_sub_yyy_to_zzz); register_unsigned_benches!(runner, benchmark_xxx_sub_yyy_to_zzz); } fn demo_xxx_sub_yyy_to_zzz(gm: GenMode, config: &GenConfig, limit: usize) { for (x_2, x_1, x_0, y_2, y_1, y_0) in unsigned_sextuple_gen_var_1::() .get(gm, config) .take(limit) { println!( "[{}, {}, {}] - [{}, {}, {}] = {:?}", x_2, x_1, x_0, y_2, y_1, y_0, T::xxx_sub_yyy_to_zzz(x_2, x_1, x_0, y_2, y_1, y_0) ); } } fn benchmark_xxx_sub_yyy_to_zzz( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!( "{}::xxx_sub_yyy_to_zzz({}, {}, {}, {}, {}, {})", T::NAME, T::NAME, T::NAME, T::NAME, T::NAME, T::NAME, T::NAME ), BenchmarkType::Single, unsigned_sextuple_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &sextuple_max_bit_bucketer("x_2", "x_1", "x_0", "y_2", "y_1", "y_0"), &mut [("default", &mut |(x_2, x_1, x_0, y_2, y_1, y_0)| { no_out!(T::xxx_sub_yyy_to_zzz(x_2, x_1, x_0, y_2, y_1, y_0)) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/arithmetic/xxxx_add_yyyy_to_zzzz.rs000064400000000000000000000047251046102023000301250ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::octuple_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_octuple_gen_var_1; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_xxxx_add_yyyy_to_zzzz); register_unsigned_benches!(runner, benchmark_xxxx_add_yyyy_to_zzzz); } fn demo_xxxx_add_yyyy_to_zzzz(gm: GenMode, config: &GenConfig, limit: usize) { for (x_3, x_2, x_1, x_0, y_3, y_2, y_1, y_0) in unsigned_octuple_gen_var_1::() .get(gm, config) .take(limit) { println!( "[{}, {}, {}, {}] + [{}, {}, {}, {}] = {:?}", x_3, x_2, x_1, x_0, y_3, y_2, y_1, y_0, T::xxxx_add_yyyy_to_zzzz(x_3, x_2, x_1, x_0, y_3, y_2, y_1, y_0) ); } } fn benchmark_xxxx_add_yyyy_to_zzzz( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!( "{}::xxxx_add_yyyy_to_zzzz({}, {}, {}, {}, {}, {}, {}, {})", T::NAME, T::NAME, T::NAME, T::NAME, T::NAME, T::NAME, T::NAME, T::NAME, T::NAME ), BenchmarkType::Single, unsigned_octuple_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &octuple_max_bit_bucketer("x_3", "x_2", "x_1", "x_0", "y_3", "y_2", "y_1", "y_0"), &mut [("default", &mut |( x_3, x_2, x_1, x_0, y_3, y_2, y_1, y_0, )| { no_out!(T::xxxx_add_yyyy_to_zzzz( x_3, x_2, x_1, x_0, y_3, y_2, y_1, y_0 )) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/comparison/cmp_abs_and_partial_cmp_abs.rs000064400000000000000000000106161046102023000310250ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::pair_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_pair_gen, unsigned_pair_gen_var_27}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_cmp_abs_unsigned); register_unsigned_demos!(runner, demo_partial_cmp_abs_unsigned); register_signed_demos!(runner, demo_cmp_abs_signed); register_signed_demos!(runner, demo_partial_cmp_abs_signed); register_unsigned_benches!(runner, benchmark_cmp_abs_unsigned); register_unsigned_benches!(runner, benchmark_partial_cmp_abs_unsigned); register_signed_benches!(runner, benchmark_cmp_abs_signed); register_signed_benches!(runner, benchmark_partial_cmp_abs_signed); } fn demo_cmp_abs_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in unsigned_pair_gen_var_27::().get(gm, config).take(limit) { println!("{}.cmp_abs(&{}) = {:?}", x, y, x.cmp_abs(&y)); } } fn demo_partial_cmp_abs_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, y) in unsigned_pair_gen_var_27::().get(gm, config).take(limit) { println!( "{}.partial_cmp_abs(&{}) = {:?}", x, y, x.partial_cmp_abs(&y) ); } } fn demo_cmp_abs_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in signed_pair_gen::().get(gm, config).take(limit) { println!("({}).cmp_abs(&{}) = {:?}", x, y, x.cmp_abs(&y)); } } fn demo_partial_cmp_abs_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in signed_pair_gen::().get(gm, config).take(limit) { println!( "({}).partial_cmp_abs(&{}) = {:?}", x, y, x.partial_cmp_abs(&y) ); } } fn benchmark_cmp_abs_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.cmp_abs(&{})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_27::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.cmp_abs(&y)))], ); } fn benchmark_partial_cmp_abs_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.partial_cmp_abs(&{})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_27::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.partial_cmp_abs(&y)))], ); } fn benchmark_cmp_abs_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.cmp_abs(&{})", T::NAME, T::NAME), BenchmarkType::Single, signed_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.cmp_abs(&y)))], ); } fn benchmark_partial_cmp_abs_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.partial_cmp_abs(&{})", T::NAME, T::NAME), BenchmarkType::Single, signed_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.partial_cmp_abs(&y)))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/comparison/eq_abs.rs000064400000000000000000000101531046102023000246250ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::pair_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_pair_gen, unsigned_pair_gen_var_27}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_eq_abs_unsigned); register_unsigned_demos!(runner, demo_ne_abs_unsigned); register_signed_demos!(runner, demo_eq_abs_signed); register_signed_demos!(runner, demo_ne_abs_signed); register_unsigned_benches!(runner, benchmark_eq_abs_unsigned); register_unsigned_benches!(runner, benchmark_ne_abs_unsigned); register_signed_benches!(runner, benchmark_eq_abs_signed); register_signed_benches!(runner, benchmark_ne_abs_signed); } fn demo_eq_abs_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in unsigned_pair_gen_var_27::().get(gm, config).take(limit) { println!("{}.eq_abs(&{}) = {:?}", x, y, x.eq_abs(&y)); } } fn demo_ne_abs_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in unsigned_pair_gen_var_27::().get(gm, config).take(limit) { println!("{}.ne_abs(&{}) = {:?}", x, y, x.ne_abs(&y)); } } fn demo_eq_abs_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in signed_pair_gen::().get(gm, config).take(limit) { println!("({}).eq_abs(&{}) = {:?}", x, y, x.eq_abs(&y)); } } fn demo_ne_abs_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in signed_pair_gen::().get(gm, config).take(limit) { println!("({}).ne_abs(&{}) = {:?}", x, y, x.ne_abs(&y)); } } fn benchmark_eq_abs_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.eq_abs(&{})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_27::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.eq_abs(&y)))], ); } fn benchmark_ne_abs_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.ne_abs(&{})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_27::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.ne_abs(&y)))], ); } fn benchmark_eq_abs_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.eq_abs(&{})", T::NAME, T::NAME), BenchmarkType::Single, signed_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.eq_abs(&y)))], ); } fn benchmark_ne_abs_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.ne_abs(&{})", T::NAME, T::NAME), BenchmarkType::Single, signed_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.ne_abs(&y)))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/comparison/mod.rs000064400000000000000000000012331046102023000241510ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { eq_abs::register(runner); cmp_abs_and_partial_cmp_abs::register(runner); ord_abs_comparators::register(runner); } mod cmp_abs_and_partial_cmp_abs; mod eq_abs; mod ord_abs_comparators; malachite-base-0.4.16/src/bin_util/demo_and_bench/num/comparison/ord_abs_comparators.rs000064400000000000000000000165071046102023000274270ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::pair_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_pair_gen, unsigned_pair_gen_var_27}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_lt_abs_unsigned); register_unsigned_demos!(runner, demo_gt_abs_unsigned); register_unsigned_demos!(runner, demo_le_abs_unsigned); register_unsigned_demos!(runner, demo_ge_abs_unsigned); register_signed_demos!(runner, demo_lt_abs_signed); register_signed_demos!(runner, demo_gt_abs_signed); register_signed_demos!(runner, demo_le_abs_signed); register_signed_demos!(runner, demo_ge_abs_signed); register_unsigned_benches!(runner, benchmark_lt_abs_unsigned); register_unsigned_benches!(runner, benchmark_gt_abs_unsigned); register_unsigned_benches!(runner, benchmark_le_abs_unsigned); register_unsigned_benches!(runner, benchmark_ge_abs_unsigned); register_signed_benches!(runner, benchmark_lt_abs_signed); register_signed_benches!(runner, benchmark_gt_abs_signed); register_signed_benches!(runner, benchmark_le_abs_signed); register_signed_benches!(runner, benchmark_ge_abs_signed); } fn demo_lt_abs_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in unsigned_pair_gen_var_27::().get(gm, config).take(limit) { println!("{}.lt_abs(&{}) = {}", x, y, x.lt_abs(&y)); } } fn demo_gt_abs_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in unsigned_pair_gen_var_27::().get(gm, config).take(limit) { println!("{}.gt_abs(&{}) = {}", x, y, x.gt_abs(&y)); } } fn demo_le_abs_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in unsigned_pair_gen_var_27::().get(gm, config).take(limit) { println!("{}.le_abs(&{}) = {}", x, y, x.le_abs(&y)); } } fn demo_ge_abs_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in unsigned_pair_gen_var_27::().get(gm, config).take(limit) { println!("{}.ge_abs(&{}) = {}", x, y, x.ge_abs(&y)); } } fn demo_lt_abs_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in signed_pair_gen::().get(gm, config).take(limit) { println!("({}).lt_abs(&{}) = {}", x, y, x.lt_abs(&y)); } } fn demo_gt_abs_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in signed_pair_gen::().get(gm, config).take(limit) { println!("({}).gt_abs(&{}) = {}", x, y, x.gt_abs(&y)); } } fn demo_le_abs_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in signed_pair_gen::().get(gm, config).take(limit) { println!("({}).le_abs(&{}) = {}", x, y, x.le_abs(&y)); } } fn demo_ge_abs_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in signed_pair_gen::().get(gm, config).take(limit) { println!("({}).ge_abs(&{}) = {}", x, y, x.ge_abs(&y)); } } fn benchmark_lt_abs_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.lt_abs(&{})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_27::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.lt_abs(&y)))], ); } fn benchmark_gt_abs_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.gt_abs(&{})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_27::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.gt_abs(&y)))], ); } fn benchmark_le_abs_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.le_abs(&{})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_27::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.le_abs(&y)))], ); } fn benchmark_ge_abs_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.ge_abs(&{})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_27::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.ge_abs(&y)))], ); } fn benchmark_lt_abs_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.lt_abs(&{})", T::NAME, T::NAME), BenchmarkType::Single, signed_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.lt_abs(&y)))], ); } fn benchmark_gt_abs_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.gt_abs(&{})", T::NAME, T::NAME), BenchmarkType::Single, signed_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.gt_abs(&y)))], ); } fn benchmark_le_abs_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.le_abs(&{})", T::NAME, T::NAME), BenchmarkType::Single, signed_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.le_abs(&y)))], ); } fn benchmark_ge_abs_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.ge_abs(&{})", T::NAME, T::NAME), BenchmarkType::Single, signed_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.ge_abs(&y)))], ); } ././@LongLink00006440000000000000000000000146000000000000007774Lustar malachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/digits/general_digits/from_digits.rsmalachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/digits/general_digits/from_digits.r000064400000000000000000000114201046102023000317720ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::{Digits, SaturatingFrom}; use malachite_base::test_util::bench::bucketers::pair_1_vec_len_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ unsigned_vec_unsigned_pair_gen_var_7, unsigned_vec_unsigned_pair_gen_var_8, unsigned_vec_unsigned_pair_gen_var_9, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_unsigned_demos!(runner, demo_from_digits_asc); register_unsigned_unsigned_demos!(runner, demo_from_digits_desc); register_unsigned_unsigned_demos!(runner, demo_from_digits_asc_targeted); register_unsigned_unsigned_demos!(runner, demo_from_digits_desc_targeted); register_unsigned_unsigned_benches!(runner, benchmark_from_digits_asc); register_unsigned_unsigned_benches!(runner, benchmark_from_digits_desc); } fn demo_from_digits_asc< T: PrimitiveUnsigned + SaturatingFrom, U: Digits + PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (xs, base) in unsigned_vec_unsigned_pair_gen_var_9::() .get(gm, config) .take(limit) { println!( "{}.from_digits_asc({}, {:?}) = {:?}", U::NAME, base, xs, U::from_digits_asc(&base, xs.iter().copied()) ); } } fn demo_from_digits_desc< T: PrimitiveUnsigned + SaturatingFrom, U: Digits + PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (xs, base) in unsigned_vec_unsigned_pair_gen_var_9::() .get(gm, config) .take(limit) { println!( "{}.from_digits_desc({}, {:?}) = {:?}", U::NAME, base, xs, U::from_digits_desc(&base, xs.iter().copied()) ); } } fn demo_from_digits_asc_targeted< T: PrimitiveUnsigned + SaturatingFrom, U: Digits + PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (xs, base) in unsigned_vec_unsigned_pair_gen_var_8::() .get(gm, config) .take(limit) { println!( "{}.from_digits_asc({}, {:?}) = {}", U::NAME, base, xs, U::from_digits_asc(&base, xs.iter().copied()).unwrap() ); } } fn demo_from_digits_desc_targeted< T: PrimitiveUnsigned + SaturatingFrom, U: Digits + PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (xs, base) in unsigned_vec_unsigned_pair_gen_var_7::() .get(gm, config) .take(limit) { println!( "{}.from_digits_desc({}, {:?}) = {}", U::NAME, base, xs, U::from_digits_desc(&base, xs.iter().copied()).unwrap() ); } } fn benchmark_from_digits_asc< T: PrimitiveUnsigned + SaturatingFrom, U: Digits + PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!( "{}.from_digits_asc({}, Iterator)", U::NAME, T::NAME, T::NAME ), BenchmarkType::Single, unsigned_vec_unsigned_pair_gen_var_8::().get(gm, config), gm.name(), limit, file_name, &pair_1_vec_len_bucketer("digits"), &mut [("Malachite", &mut |(xs, base)| { no_out!(U::from_digits_asc(&base, xs.iter().copied())) })], ); } fn benchmark_from_digits_desc< T: PrimitiveUnsigned + SaturatingFrom, U: Digits + PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!( "{}.from_digits_desc({}, Iterator)", U::NAME, T::NAME, T::NAME ), BenchmarkType::Single, unsigned_vec_unsigned_pair_gen_var_7::().get(gm, config), gm.name(), limit, file_name, &pair_1_vec_len_bucketer("digits"), &mut [("Malachite", &mut |(xs, base)| { no_out!(U::from_digits_desc(&base, xs.iter().copied())) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/digits/general_digits/mod.rs000064400000000000000000000010751046102023000304330ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { from_digits::register(runner); to_digits::register(runner); } mod from_digits; mod to_digits; malachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/digits/general_digits/to_digits.rs000064400000000000000000000061611046102023000316420ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::{Digits, SaturatingFrom}; use malachite_base::test_util::bench::bucketers::pair_1_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_pair_gen_var_6; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_unsigned_demos!(runner, demo_to_digits_asc); register_unsigned_unsigned_demos!(runner, demo_to_digits_desc); register_unsigned_unsigned_benches!(runner, benchmark_to_digits_asc); register_unsigned_unsigned_benches!(runner, benchmark_to_digits_desc); } fn demo_to_digits_asc< T: Digits + PrimitiveUnsigned, U: PrimitiveUnsigned + SaturatingFrom, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, base) in unsigned_pair_gen_var_6::() .get(gm, config) .take(limit) { println!( "{}.to_digits_asc({}) = {:?}", x, base, x.to_digits_asc(&base) ); } } fn demo_to_digits_desc< T: Digits + PrimitiveUnsigned, U: PrimitiveUnsigned + SaturatingFrom, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, base) in unsigned_pair_gen_var_6::() .get(gm, config) .take(limit) { println!( "{}.to_digits_desc({}) = {:?}", x, base, x.to_digits_desc(&base) ); } } fn benchmark_to_digits_asc< T: Digits + PrimitiveUnsigned, U: PrimitiveUnsigned + SaturatingFrom, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.to_digits_asc({})", T::NAME, U::NAME), BenchmarkType::Single, unsigned_pair_gen_var_6::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("x"), &mut [( "Malachite", &mut |(x, base)| no_out!(x.to_digits_asc(&base)), )], ); } fn benchmark_to_digits_desc< T: Digits + PrimitiveUnsigned, U: PrimitiveUnsigned + SaturatingFrom, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.to_digits_desc({})", T::NAME, U::NAME), BenchmarkType::Single, unsigned_pair_gen_var_6::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("x"), &mut [("Malachite", &mut |(x, base)| { no_out!(x.to_digits_desc(&base)) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/digits/mod.rs000064400000000000000000000011231046102023000254450ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { general_digits::register(runner); power_of_2_digits::register(runner); } mod general_digits; mod power_of_2_digits; ././@LongLink00006440000000000000000000000164000000000000007774Lustar malachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/digits/power_of_2_digits/from_power_of_2_digits.rsmalachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/digits/power_of_2_digits/from_power000064400000000000000000000117311046102023000320340ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::PowerOf2Digits; use malachite_base::test_util::bench::bucketers::pair_1_vec_len_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ unsigned_vec_unsigned_pair_gen_var_2, unsigned_vec_unsigned_pair_gen_var_3, unsigned_vec_unsigned_pair_gen_var_6, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_unsigned_demos!(runner, demo_from_power_of_2_digits_asc); register_unsigned_unsigned_demos!(runner, demo_from_power_of_2_digits_desc); register_unsigned_unsigned_demos!(runner, demo_from_power_of_2_digits_asc_targeted); register_unsigned_unsigned_demos!(runner, demo_from_power_of_2_digits_desc_targeted); register_unsigned_unsigned_benches!(runner, benchmark_from_power_of_2_digits_asc); register_unsigned_unsigned_benches!(runner, benchmark_from_power_of_2_digits_desc); } fn demo_from_power_of_2_digits_asc< T: PowerOf2Digits + PrimitiveUnsigned, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (xs, log_base) in unsigned_vec_unsigned_pair_gen_var_6::() .get(gm, config) .take(limit) { println!( "{}::from_power_of_2_digits_asc({}, {:?}) = {:?}", T::NAME, log_base, xs, T::from_power_of_2_digits_asc(log_base, xs.iter().cloned()) ); } } fn demo_from_power_of_2_digits_desc< T: PowerOf2Digits + PrimitiveUnsigned, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (xs, log_base) in unsigned_vec_unsigned_pair_gen_var_6::() .get(gm, config) .take(limit) { println!( "{}::from_power_of_2_digits_desc({}, {:?}) = {:?}", T::NAME, log_base, xs, T::from_power_of_2_digits_desc(log_base, xs.iter().cloned()) ); } } fn demo_from_power_of_2_digits_asc_targeted< T: PowerOf2Digits + PrimitiveUnsigned, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (xs, log_base) in unsigned_vec_unsigned_pair_gen_var_2::() .get(gm, config) .take(limit) { println!( "{}::from_power_of_2_digits_asc({}, {:?}) = {}", T::NAME, log_base, xs, T::from_power_of_2_digits_asc(log_base, xs.iter().cloned()).unwrap() ); } } fn demo_from_power_of_2_digits_desc_targeted< T: PowerOf2Digits + PrimitiveUnsigned, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (xs, log_base) in unsigned_vec_unsigned_pair_gen_var_3::() .get(gm, config) .take(limit) { println!( "{}::from_power_of_2_digits_desc({}, {:?}) = {}", T::NAME, log_base, xs, T::from_power_of_2_digits_desc(log_base, xs.iter().cloned()).unwrap() ); } } fn benchmark_from_power_of_2_digits_asc< T: PowerOf2Digits + PrimitiveUnsigned, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!( "{}::from_power_of_2_digits_asc>(u64, I)", T::NAME, U::NAME ), BenchmarkType::Single, unsigned_vec_unsigned_pair_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &pair_1_vec_len_bucketer("xs"), &mut [("Malachite", &mut |(xs, log_base)| { no_out!(T::from_power_of_2_digits_asc(log_base, xs.into_iter())) })], ); } fn benchmark_from_power_of_2_digits_desc< T: PowerOf2Digits + PrimitiveUnsigned, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!( "{}::from_power_of_2_digits_asc>(u64, I)", T::NAME, U::NAME ), BenchmarkType::Single, unsigned_vec_unsigned_pair_gen_var_3::().get(gm, config), gm.name(), limit, file_name, &pair_1_vec_len_bucketer("xs"), &mut [("Malachite", &mut |(xs, log_base)| { no_out!(T::from_power_of_2_digits_desc(log_base, xs.into_iter())) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/digits/power_of_2_digits/mod.rs000064400000000000000000000012711046102023000310550ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { from_power_of_2_digits::register(runner); power_of_2_digit_iterable::register(runner); to_power_of_2_digits::register(runner); } mod from_power_of_2_digits; mod power_of_2_digit_iterable; mod to_power_of_2_digits; ././@LongLink00006440000000000000000000000167000000000000007777Lustar malachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/digits/power_of_2_digits/power_of_2_digit_iterable.rsmalachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/digits/power_of_2_digits/power_of_2000064400000000000000000000130201046102023000317070ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::{ ExactFrom, PowerOf2DigitIterable, PowerOf2DigitIterator, PowerOf2Digits, }; use malachite_base::test_util::bench::bucketers::{pair_1_bit_bucketer, triple_1_bit_bucketer}; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{unsigned_pair_gen_var_4, unsigned_triple_gen_var_3}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_unsigned_demos!(runner, demo_power_of_2_digits); register_unsigned_unsigned_demos!(runner, demo_power_of_2_digits_rev); register_unsigned_unsigned_demos!(runner, demo_power_of_2_digits_size_hint); register_unsigned_unsigned_demos!(runner, demo_power_of_2_digits_get); register_unsigned_unsigned_benches!(runner, benchmark_power_of_2_digits_size_hint); register_unsigned_unsigned_benches!(runner, benchmark_power_of_2_digits_get_algorithms); } fn demo_power_of_2_digits + PrimitiveUnsigned, U: PrimitiveUnsigned>( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, log_base) in unsigned_pair_gen_var_4::() .get(gm, config) .take(limit) { println!( "power_of_2_digits({}, {}) = {:?}", x, log_base, PowerOf2DigitIterable::::power_of_2_digits(x, log_base).collect_vec() ); } } fn demo_power_of_2_digits_rev< T: PowerOf2DigitIterable + PrimitiveUnsigned, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, log_base) in unsigned_pair_gen_var_4::() .get(gm, config) .take(limit) { println!( "power_of_2_digits({}, {}).rev() = {:?}", x, log_base, PowerOf2DigitIterable::::power_of_2_digits(x, log_base) .rev() .collect_vec() ); } } fn demo_power_of_2_digits_size_hint< T: PowerOf2DigitIterable + PrimitiveUnsigned, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, log_base) in unsigned_pair_gen_var_4::() .get(gm, config) .take(limit) { println!( "power_of_2_digits({}, {}).size_hint() = {:?}", x, log_base, PowerOf2DigitIterable::::power_of_2_digits(x, log_base).size_hint() ); } } fn demo_power_of_2_digits_get< T: PowerOf2DigitIterable + PrimitiveUnsigned, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, log_base, i) in unsigned_triple_gen_var_3::() .get(gm, config) .take(limit) { println!( "power_of_2_digits({}, {}).get({}) = {:?}", x, log_base, i, PowerOf2DigitIterable::::power_of_2_digits(x, log_base).get(i) ); } } fn benchmark_power_of_2_digits_size_hint< T: PowerOf2DigitIterable + PrimitiveUnsigned, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!( "PowerOf2DigitIterable::<{}>::power_of_2_digits(&{}, u64).size_hint()", U::NAME, T::NAME ), BenchmarkType::Single, unsigned_pair_gen_var_4::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("x"), &mut [("Malachite", &mut |(x, log_base)| { no_out!(PowerOf2DigitIterable::::power_of_2_digits(x, log_base).size_hint()) })], ); } fn benchmark_power_of_2_digits_get_algorithms< T: PowerOf2DigitIterable + PowerOf2Digits + PrimitiveUnsigned, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!( "PowerOf2DigitIterable::<{}>::power_of_2_digits(&{}, u64).size_hint()", U::NAME, T::NAME ), BenchmarkType::Algorithms, unsigned_triple_gen_var_3::().get(gm, config), gm.name(), limit, file_name, &triple_1_bit_bucketer("x"), &mut [ ( &format!("power_of_2_digits({}, u64).get(u64)", T::NAME), &mut |(u, log_base, i)| { no_out!(PowerOf2DigitIterable::::power_of_2_digits(u, log_base).get(i)) }, ), ( &format!("{}.to_power_of_2_digits_asc(u64)[usize]", T::NAME), &mut |(x, log_base, i)| { let digits = PowerOf2Digits::::to_power_of_2_digits_asc(&x, log_base); let i = usize::exact_from(i); if i >= digits.len() { U::ZERO } else { digits[i] }; }, ), ], ); } ././@LongLink00006440000000000000000000000162000000000000007772Lustar malachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/digits/power_of_2_digits/to_power_of_2_digits.rsmalachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/digits/power_of_2_digits/to_power_o000064400000000000000000000105441046102023000320320ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::{PowerOf2DigitIterable, PowerOf2Digits}; use malachite_base::test_util::bench::bucketers::pair_1_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_pair_gen_var_4; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_unsigned_demos!(runner, demo_to_power_of_2_digits_asc); register_unsigned_unsigned_demos!(runner, demo_to_power_of_2_digits_desc); register_unsigned_unsigned_benches!( runner, benchmark_to_power_of_2_digits_asc_evaluation_strategy ); register_unsigned_unsigned_benches!( runner, benchmark_to_power_of_2_digits_desc_evaluation_strategy ); } fn demo_to_power_of_2_digits_asc + PrimitiveUnsigned, U: PrimitiveUnsigned>( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, log_base) in unsigned_pair_gen_var_4::() .get(gm, config) .take(limit) { println!( "{}.to_power_of_2_digits_asc({}) = {:?}", x, log_base, PowerOf2Digits::::to_power_of_2_digits_asc(&x, log_base) ); } } fn demo_to_power_of_2_digits_desc< T: PowerOf2Digits + PrimitiveUnsigned, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, log_base) in unsigned_pair_gen_var_4::() .get(gm, config) .take(limit) { println!( "{}.to_power_of_2_digits_desc({}) = {:?}", x, log_base, PowerOf2Digits::::to_power_of_2_digits_desc(&x, log_base) ); } } fn benchmark_to_power_of_2_digits_asc_evaluation_strategy< T: PowerOf2Digits + PowerOf2DigitIterable + PrimitiveUnsigned, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!( "PowerOf2Digits::<{}>::to_power_of_2_digits_asc({}, u64)", U::NAME, T::NAME ), BenchmarkType::EvaluationStrategy, unsigned_pair_gen_var_4::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("x"), &mut [ ("Malachite", &mut |(x, log_base)| { no_out!(PowerOf2Digits::::to_power_of_2_digits_asc(&x, log_base)) }), ( &format!("{}.power_of_2_digits(u64).collect_vec()", T::NAME), &mut |(x, log_base)| { PowerOf2DigitIterable::::power_of_2_digits(x, log_base).collect_vec(); }, ), ], ); } fn benchmark_to_power_of_2_digits_desc_evaluation_strategy< T: PowerOf2Digits + PowerOf2DigitIterable + PrimitiveUnsigned, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!( "PowerOf2Digits::<{}>::to_power_of_2_digits_desc({}, u64)", U::NAME, T::NAME ), BenchmarkType::EvaluationStrategy, unsigned_pair_gen_var_4::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("x"), &mut [ ("Malachite", &mut |(x, log_base)| { no_out!(PowerOf2Digits::::to_power_of_2_digits_desc(&x, log_base)) }), ( &format!("{}.power_of_2_digits(u64).rev().collect_vec()", T::NAME), &mut |(x, log_base)| { no_out!(PowerOf2DigitIterable::::power_of_2_digits(x, log_base) .rev() .collect_vec()) }, ), ], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/from/convertible_from.rs000064400000000000000000000160071046102023000277140ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::named::Named; use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::ConvertibleFrom; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::bench::bucketers::{ primitive_float_bucketer, signed_bit_bucketer, unsigned_bit_bucketer, }; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{primitive_float_gen, signed_gen, unsigned_gen}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_primitive_int_unsigned_demos!(runner, demo_primitive_int_convertible_from_unsigned); register_primitive_int_signed_demos!(runner, demo_primitive_int_convertible_from_signed); register_primitive_int_primitive_float_demos!( runner, demo_primitive_int_convertible_from_primitive_float ); register_primitive_float_unsigned_demos!( runner, demo_primitive_float_convertible_from_unsigned ); register_primitive_float_signed_demos!(runner, demo_primitive_float_convertible_from_signed); register_primitive_int_unsigned_benches!( runner, benchmark_primitive_int_convertible_from_unsigned ); register_primitive_int_signed_benches!(runner, benchmark_primitive_int_convertible_from_signed); register_primitive_int_primitive_float_benches!( runner, benchmark_primitive_int_convertible_from_primitive_float ); register_primitive_float_unsigned_benches!( runner, benchmark_primitive_float_convertible_from_unsigned ); register_primitive_float_signed_benches!( runner, benchmark_primitive_float_convertible_from_signed ); } fn demo_primitive_int_convertible_from_unsigned< T: ConvertibleFrom + Named, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for u in unsigned_gen::().get(gm, config).take(limit) { println!( "{} is {}convertible to a {}", u, if T::convertible_from(u) { "" } else { "not " }, T::NAME, ); } } fn demo_primitive_int_convertible_from_signed + Named, U: PrimitiveSigned>( gm: GenMode, config: &GenConfig, limit: usize, ) { for i in signed_gen::().get(gm, config).take(limit) { println!( "{} is {}convertible to a {}", i, if T::convertible_from(i) { "" } else { "not " }, T::NAME, ); } } fn demo_primitive_int_convertible_from_primitive_float< T: ConvertibleFrom + PrimitiveInt, U: PrimitiveFloat, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for x in primitive_float_gen::().get(gm, config).take(limit) { println!( "{} is {}convertible to a {}", NiceFloat(x), if T::convertible_from(x) { "" } else { "not " }, T::NAME, ); } } fn demo_primitive_float_convertible_from_unsigned< T: ConvertibleFrom + PrimitiveFloat, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for u in unsigned_gen::().get(gm, config).take(limit) { println!( "{} is {}convertible to a {}", u, if T::convertible_from(u) { "" } else { "not " }, T::NAME, ); } } fn demo_primitive_float_convertible_from_signed< T: ConvertibleFrom + PrimitiveFloat, U: PrimitiveSigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for i in signed_gen::().get(gm, config).take(limit) { println!( "{} is {}convertible to a {}", i, if T::convertible_from(i) { "" } else { "not " }, T::NAME, ); } } fn benchmark_primitive_int_convertible_from_unsigned< T: ConvertibleFrom + Named, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.convertible_from({})", T::NAME, U::NAME), BenchmarkType::Single, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [("Malachite", &mut |n| no_out!(T::convertible_from(n)))], ); } fn benchmark_primitive_int_convertible_from_signed< T: ConvertibleFrom + Named, U: PrimitiveSigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.convertible_from({})", T::NAME, U::NAME), BenchmarkType::Single, signed_gen::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [("Malachite", &mut |n| no_out!(T::convertible_from(n)))], ); } fn benchmark_primitive_int_convertible_from_primitive_float< T: ConvertibleFrom + PrimitiveInt, U: PrimitiveFloat, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.convertible_from({})", T::NAME, U::NAME), BenchmarkType::Single, primitive_float_gen::().get(gm, config), gm.name(), limit, file_name, &primitive_float_bucketer("x"), &mut [("Malachite", &mut |n| no_out!(T::convertible_from(n)))], ); } fn benchmark_primitive_float_convertible_from_unsigned< T: ConvertibleFrom + PrimitiveFloat, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.convertible_from({})", T::NAME, U::NAME), BenchmarkType::Single, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [("Malachite", &mut |n| no_out!(T::convertible_from(n)))], ); } fn benchmark_primitive_float_convertible_from_signed< T: ConvertibleFrom + PrimitiveFloat, U: PrimitiveSigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.convertible_from({})", T::NAME, U::NAME), BenchmarkType::Single, signed_gen::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [("Malachite", &mut |n| no_out!(T::convertible_from(n)))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/from/mod.rs000064400000000000000000000015151046102023000251320ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { convertible_from::register(runner); overflowing_from::register(runner); rounding_from::register(runner); saturating_from::register(runner); try_from_and_exact_from::register(runner); wrapping_from::register(runner); } mod convertible_from; mod overflowing_from; mod rounding_from; mod saturating_from; mod try_from_and_exact_from; mod wrapping_from; malachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/from/overflowing_from.rs000064400000000000000000000063301046102023000277370ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::named::Named; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::OverflowingFrom; use malachite_base::test_util::bench::bucketers::{signed_bit_bucketer, unsigned_bit_bucketer}; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_gen, unsigned_gen}; use malachite_base::test_util::runner::Runner; use std::fmt::Debug; pub(crate) fn register(runner: &mut Runner) { register_primitive_int_unsigned_demos!(runner, demo_primitive_int_overflowing_from_unsigned); register_primitive_int_signed_demos!(runner, demo_primitive_int_overflowing_from_signed); register_primitive_int_unsigned_benches!( runner, benchmark_primitive_int_overflowing_from_unsigned ); register_primitive_int_signed_benches!(runner, benchmark_primitive_int_overflowing_from_signed); } fn demo_primitive_int_overflowing_from_unsigned< T: Debug + OverflowingFrom + Named, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for u in unsigned_gen::().get(gm, config).take(limit) { println!( "{}::overflowing_from({}) = {:?}", T::NAME, u, T::overflowing_from(u) ); } } fn demo_primitive_int_overflowing_from_signed< T: Debug + OverflowingFrom + Named, U: PrimitiveSigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for i in signed_gen::().get(gm, config).take(limit) { println!( "{}::overflowing_from({}) = {:?}", T::NAME, i, T::overflowing_from(i) ); } } fn benchmark_primitive_int_overflowing_from_unsigned< T: OverflowingFrom + Named, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.overflowing_from({})", T::NAME, U::NAME), BenchmarkType::Single, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [("Malachite", &mut |n| no_out!(T::overflowing_from(n)))], ); } fn benchmark_primitive_int_overflowing_from_signed< T: OverflowingFrom + Named, U: PrimitiveSigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.overflowing_from({})", T::NAME, U::NAME), BenchmarkType::Single, signed_gen::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [("Malachite", &mut |n| no_out!(T::overflowing_from(n)))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/from/rounding_from.rs000064400000000000000000000123641046102023000272270ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::{ConvertibleFrom, RoundingFrom}; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::bench::bucketers::{ pair_1_bit_bucketer, pair_1_primitive_float_bucketer, }; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ primitive_float_rounding_mode_pair_gen_var_3, signed_rounding_mode_pair_gen_var_4, unsigned_rounding_mode_pair_gen_var_2, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_primitive_int_primitive_float_demos!( runner, demo_primitive_int_rounding_from_primitive_float ); register_primitive_float_unsigned_demos!(runner, demo_primitive_float_rounding_from_unsigned); register_primitive_float_signed_demos!(runner, demo_primitive_float_rounding_from_signed); register_primitive_int_primitive_float_benches!( runner, benchmark_primitive_int_rounding_from_primitive_float ); register_primitive_float_unsigned_benches!( runner, benchmark_primitive_float_rounding_from_unsigned ); register_primitive_float_signed_benches!( runner, benchmark_primitive_float_rounding_from_signed ); } fn demo_primitive_int_rounding_from_primitive_float< T: ConvertibleFrom + PrimitiveInt + RoundingFrom, U: PrimitiveFloat + RoundingFrom, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (f, rm) in primitive_float_rounding_mode_pair_gen_var_3::() .get(gm, config) .take(limit) { println!( "{}::rounding_from({}, {}) = {:?}", T::NAME, NiceFloat(f), rm, T::rounding_from(f, rm) ); } } fn demo_primitive_float_rounding_from_unsigned< T: ConvertibleFrom + PrimitiveFloat + RoundingFrom, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (u, rm) in unsigned_rounding_mode_pair_gen_var_2::() .get(gm, config) .take(limit) { let (x, o) = T::rounding_from(u, rm); println!( "{}::rounding_from({}, {}) = {:?}", T::NAME, u, rm, (NiceFloat(x), o) ); } } fn demo_primitive_float_rounding_from_signed< T: ConvertibleFrom + PrimitiveFloat + RoundingFrom, U: PrimitiveSigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (i, rm) in signed_rounding_mode_pair_gen_var_4::() .get(gm, config) .take(limit) { let (x, o) = T::rounding_from(i, rm); println!( "{}::rounding_from({}, {}) = {:?}", T::NAME, i, rm, (NiceFloat(x), o) ); } } fn benchmark_primitive_int_rounding_from_primitive_float< T: ConvertibleFrom + PrimitiveInt + RoundingFrom, U: PrimitiveFloat + RoundingFrom, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.rounding_from({})", T::NAME, U::NAME), BenchmarkType::Single, primitive_float_rounding_mode_pair_gen_var_3::().get(gm, config), gm.name(), limit, file_name, &pair_1_primitive_float_bucketer("x"), &mut [("Malachite", &mut |(f, rm)| no_out!(T::rounding_from(f, rm)))], ); } fn benchmark_primitive_float_rounding_from_unsigned< T: ConvertibleFrom + PrimitiveFloat + RoundingFrom, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.rounding_from({})", T::NAME, U::NAME), BenchmarkType::Single, unsigned_rounding_mode_pair_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("u"), &mut [("Malachite", &mut |(u, rm)| no_out!(T::rounding_from(u, rm)))], ); } fn benchmark_primitive_float_rounding_from_signed< T: ConvertibleFrom + PrimitiveFloat + RoundingFrom, U: PrimitiveSigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.rounding_from({})", T::NAME, U::NAME), BenchmarkType::Single, signed_rounding_mode_pair_gen_var_4::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("i"), &mut [("Malachite", &mut |(i, rm)| no_out!(T::rounding_from(i, rm)))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/from/saturating_from.rs000064400000000000000000000063051046102023000275610ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::named::Named; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::SaturatingFrom; use malachite_base::test_util::bench::bucketers::{signed_bit_bucketer, unsigned_bit_bucketer}; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_gen, unsigned_gen}; use malachite_base::test_util::runner::Runner; use std::fmt::Display; pub(crate) fn register(runner: &mut Runner) { register_primitive_int_unsigned_demos!(runner, demo_primitive_int_saturating_from_unsigned); register_primitive_int_signed_demos!(runner, demo_primitive_int_saturating_from_signed); register_primitive_int_unsigned_benches!( runner, benchmark_primitive_int_saturating_from_unsigned ); register_primitive_int_signed_benches!(runner, benchmark_primitive_int_saturating_from_signed); } fn demo_primitive_int_saturating_from_unsigned< T: Display + SaturatingFrom + Named, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for u in unsigned_gen::().get(gm, config).take(limit) { println!( "{}::saturating_from({}) = {}", T::NAME, u, T::saturating_from(u) ); } } fn demo_primitive_int_saturating_from_signed< T: Display + SaturatingFrom + Named, U: PrimitiveSigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for i in signed_gen::().get(gm, config).take(limit) { println!( "{}::saturating_from({}) = {}", T::NAME, i, T::saturating_from(i) ); } } fn benchmark_primitive_int_saturating_from_unsigned< T: SaturatingFrom + Named, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.saturating_from({})", T::NAME, U::NAME), BenchmarkType::Single, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [("Malachite", &mut |n| no_out!(T::saturating_from(n)))], ); } fn benchmark_primitive_int_saturating_from_signed< T: SaturatingFrom + Named, U: PrimitiveSigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.saturating_from({})", T::NAME, U::NAME), BenchmarkType::Single, signed_gen::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [("Malachite", &mut |n| no_out!(T::saturating_from(n)))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/from/try_from_and_exact_from.rs000064400000000000000000000275001046102023000312470ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::named::Named; use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::{ConvertibleFrom, ExactFrom, RoundingFrom}; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::bench::bucketers::{ primitive_float_bucketer, signed_bit_bucketer, unsigned_bit_bucketer, }; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ primitive_float_gen, primitive_float_gen_var_13, primitive_float_gen_var_14, signed_gen, signed_gen_var_2, signed_gen_var_7, unsigned_gen, unsigned_gen_var_18, }; use malachite_base::test_util::runner::Runner; use std::fmt::{Debug, Display}; pub(crate) fn register(runner: &mut Runner) { register_primitive_int_primitive_float_demos!( runner, demo_primitive_int_try_from_primitive_float ); register_unsigned_primitive_float_demos!(runner, demo_primitive_float_try_from_unsigned); register_signed_primitive_float_demos!(runner, demo_primitive_float_try_from_signed); register_primitive_int_unsigned_demos!(runner, demo_primitive_int_exact_from_unsigned); register_primitive_int_signed_demos!(runner, demo_primitive_int_exact_from_signed); register_unsigned_primitive_float_demos!(runner, demo_unsigned_exact_from_primitive_float); register_signed_primitive_float_demos!(runner, demo_signed_exact_from_primitive_float); register_primitive_float_unsigned_demos!(runner, demo_primitive_float_exact_from_unsigned); register_primitive_float_signed_demos!(runner, demo_primitive_float_exact_from_signed); register_primitive_int_primitive_float_benches!( runner, benchmark_primitive_int_try_from_primitive_float ); register_primitive_float_unsigned_benches!(runner, benchmark_primitive_float_try_from_unsigned); register_primitive_float_signed_benches!(runner, benchmark_primitive_float_try_from_signed); register_primitive_int_unsigned_benches!(runner, benchmark_primitive_int_exact_from_unsigned); register_primitive_int_signed_benches!(runner, benchmark_primitive_int_exact_from_signed); register_unsigned_primitive_float_benches!( runner, benchmark_unsigned_exact_from_primitive_float ); register_signed_primitive_float_benches!(runner, benchmark_signed_exact_from_primitive_float); register_primitive_float_unsigned_benches!( runner, benchmark_primitive_float_exact_from_unsigned ); register_primitive_float_signed_benches!(runner, benchmark_primitive_float_exact_from_signed); } fn demo_primitive_int_try_from_primitive_float< T: TryFrom> + Debug + Named, U: PrimitiveFloat, >( gm: GenMode, config: &GenConfig, limit: usize, ) where >>::Error: Debug, { for f in primitive_float_gen::().get(gm, config).take(limit) { let f = NiceFloat(f); println!("{}::try_from({}) = {:?}", T::NAME, f, T::try_from(f)); } } fn demo_primitive_float_try_from_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) where NiceFloat: TryFrom, as TryFrom>::Error: Debug, { for u in unsigned_gen::().get(gm, config).take(limit) { println!( "{}::try_from({}) = {:?}", U::NAME, u, NiceFloat::::try_from(u) ); } } fn demo_primitive_float_try_from_signed( gm: GenMode, config: &GenConfig, limit: usize, ) where NiceFloat: TryFrom, as TryFrom>::Error: Debug, { for u in signed_gen::().get(gm, config).take(limit) { println!( "{}::try_from({}) = {:?}", U::NAME, u, NiceFloat::::try_from(u) ); } } fn demo_primitive_int_exact_from_unsigned + Display + Named, U: PrimitiveUnsigned>( gm: GenMode, config: &GenConfig, limit: usize, ) { for u in unsigned_gen::().get(gm, config).take(limit) { println!("{}::exact_from({}) = {}", T::NAME, u, T::exact_from(u)); } } fn demo_primitive_int_exact_from_signed + Display + Named, U: PrimitiveSigned>( gm: GenMode, config: &GenConfig, limit: usize, ) { for i in signed_gen_var_2::().get(gm, config).take(limit) { println!("{}::exact_from({}) = {}", T::NAME, i, T::exact_from(i)); } } fn demo_unsigned_exact_from_primitive_float< T: TryFrom> + PrimitiveUnsigned, U: PrimitiveFloat + RoundingFrom, >( gm: GenMode, config: &GenConfig, limit: usize, ) where NiceFloat: TryFrom, { for f in primitive_float_gen_var_13::() .get(gm, config) .take(limit) { let f = NiceFloat(f); println!("{}::exact_from({}) = {}", T::NAME, f, T::exact_from(f)); } } fn demo_signed_exact_from_primitive_float< T: TryFrom> + PrimitiveSigned + RoundingFrom, U: PrimitiveFloat + RoundingFrom, >( gm: GenMode, config: &GenConfig, limit: usize, ) where NiceFloat: TryFrom, { for f in primitive_float_gen_var_14::() .get(gm, config) .take(limit) { let f = NiceFloat(f); println!("{}::exact_from({}) = {}", T::NAME, f, T::exact_from(f)); } } fn demo_primitive_float_exact_from_unsigned< T: ConvertibleFrom + PrimitiveFloat + RoundingFrom, U: PrimitiveUnsigned + RoundingFrom, >( gm: GenMode, config: &GenConfig, limit: usize, ) where NiceFloat: TryFrom, { for u in unsigned_gen_var_18::().get(gm, config).take(limit) { println!( "{}::exact_from({}) = {}", T::NAME, u, NiceFloat::::exact_from(u) ); } } fn demo_primitive_float_exact_from_signed< T: ConvertibleFrom + PrimitiveFloat + RoundingFrom, U: PrimitiveSigned + RoundingFrom, >( gm: GenMode, config: &GenConfig, limit: usize, ) where NiceFloat: TryFrom, { for i in signed_gen_var_7::().get(gm, config).take(limit) { println!( "{}::exact_from({}) = {}", T::NAME, i, NiceFloat::::exact_from(i) ); } } fn benchmark_primitive_int_try_from_primitive_float< T: TryFrom> + Named, U: PrimitiveFloat, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.try_from({})", T::NAME, U::NAME), BenchmarkType::Single, primitive_float_gen::().get(gm, config), gm.name(), limit, file_name, &primitive_float_bucketer("x"), &mut [( "Malachite", &mut |n| no_out!(T::try_from(NiceFloat(n)).ok()), )], ); } fn benchmark_primitive_float_try_from_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where NiceFloat: TryFrom, { run_benchmark( &format!("{}.try_from({})", T::NAME, U::NAME), BenchmarkType::Single, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [("Malachite", &mut |n| { no_out!(NiceFloat::::try_from(n).ok()) })], ); } fn benchmark_primitive_float_try_from_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where NiceFloat: TryFrom, { run_benchmark( &format!("{}.try_from({})", T::NAME, U::NAME), BenchmarkType::Single, signed_gen::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [("Malachite", &mut |n| { no_out!(NiceFloat::::try_from(n).ok()) })], ); } fn benchmark_primitive_int_exact_from_unsigned + Named, U: PrimitiveUnsigned>( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.exact_from({})", T::NAME, U::NAME), BenchmarkType::Single, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [("Malachite", &mut |n| no_out!(T::exact_from(n)))], ); } fn benchmark_primitive_int_exact_from_signed + Named, U: PrimitiveSigned>( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.exact_from({})", T::NAME, U::NAME), BenchmarkType::Single, signed_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [("Malachite", &mut |n| no_out!(T::exact_from(n)))], ); } fn benchmark_unsigned_exact_from_primitive_float< T: TryFrom> + PrimitiveUnsigned, U: PrimitiveFloat + RoundingFrom, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where NiceFloat: TryFrom, { run_benchmark( &format!("{}.exact_from({})", T::NAME, U::NAME), BenchmarkType::Single, primitive_float_gen_var_13::().get(gm, config), gm.name(), limit, file_name, &primitive_float_bucketer("x"), &mut [("Malachite", &mut |n| no_out!(T::exact_from(NiceFloat(n))))], ); } fn benchmark_signed_exact_from_primitive_float< T: TryFrom> + PrimitiveSigned, U: PrimitiveFloat + RoundingFrom, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where NiceFloat: TryFrom, { run_benchmark( &format!("{}.exact_from({})", T::NAME, U::NAME), BenchmarkType::Single, primitive_float_gen_var_14::().get(gm, config), gm.name(), limit, file_name, &primitive_float_bucketer("x"), &mut [("Malachite", &mut |n| no_out!(T::exact_from(NiceFloat(n))))], ); } fn benchmark_primitive_float_exact_from_unsigned< T: ConvertibleFrom + PrimitiveFloat + RoundingFrom, U: PrimitiveUnsigned + RoundingFrom, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where NiceFloat: TryFrom, { run_benchmark( &format!("{}.exact_from({})", T::NAME, U::NAME), BenchmarkType::Single, unsigned_gen_var_18::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [("Malachite", &mut |n| no_out!(NiceFloat::::exact_from(n)))], ); } fn benchmark_primitive_float_exact_from_signed< T: ConvertibleFrom + PrimitiveFloat + RoundingFrom, U: PrimitiveSigned + RoundingFrom, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where NiceFloat: TryFrom, { run_benchmark( &format!("{}.exact_from({})", T::NAME, U::NAME), BenchmarkType::Single, signed_gen_var_7::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [("Malachite", &mut |n| no_out!(NiceFloat::::exact_from(n)))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/from/wrapping_from.rs000064400000000000000000000062201046102023000272230ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::named::Named; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::WrappingFrom; use malachite_base::test_util::bench::bucketers::{signed_bit_bucketer, unsigned_bit_bucketer}; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_gen, unsigned_gen}; use malachite_base::test_util::runner::Runner; use std::fmt::Display; pub(crate) fn register(runner: &mut Runner) { register_primitive_int_unsigned_demos!(runner, demo_primitive_int_wrapping_from_unsigned); register_primitive_int_signed_demos!(runner, demo_primitive_int_wrapping_from_signed); register_primitive_int_unsigned_benches!( runner, benchmark_primitive_int_wrapping_from_unsigned ); register_primitive_int_signed_benches!(runner, benchmark_primitive_int_wrapping_from_signed); } fn demo_primitive_int_wrapping_from_unsigned< T: Display + WrappingFrom + Named, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for u in unsigned_gen::().get(gm, config).take(limit) { println!( "{}::wrapping_from({}) = {}", T::NAME, u, T::wrapping_from(u) ); } } fn demo_primitive_int_wrapping_from_signed< T: Display + WrappingFrom + Named, U: PrimitiveSigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for i in signed_gen::().get(gm, config).take(limit) { println!( "{}::wrapping_from({}) = {}", T::NAME, i, T::wrapping_from(i) ); } } fn benchmark_primitive_int_wrapping_from_unsigned< T: WrappingFrom + Named, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.wrapping_from({})", T::NAME, U::NAME), BenchmarkType::Single, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [("Malachite", &mut |n| no_out!(T::wrapping_from(n)))], ); } fn benchmark_primitive_int_wrapping_from_signed + Named, U: PrimitiveSigned>( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.wrapping_from({})", T::NAME, U::NAME), BenchmarkType::Single, signed_gen::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [("Malachite", &mut |n| no_out!(T::wrapping_from(n)))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/half/join_halves.rs000064400000000000000000000041051046102023000266210ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::named::Named; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::JoinHalves; use malachite_base::test_util::bench::bucketers::pair_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_pair_gen_var_27; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_generic_demos!(runner, demo_join_halves, u16, u32, u64, u128); register_generic_benches!(runner, benchmark_join_halves, u16, u32, u64, u128); } fn demo_join_halves( gm: GenMode, config: &GenConfig, limit: usize, ) where T::Half: PrimitiveUnsigned, { for (x, y) in unsigned_pair_gen_var_27::() .get(gm, config) .take(limit) { println!( "{}::join_halves({}, {}) = {}", T::NAME, x, y, T::join_halves(x, y) ); } } fn benchmark_join_halves( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where T::Half: PrimitiveUnsigned, { run_benchmark( &format!( "{}::join_halves({}, {})", T::NAME, T::Half::NAME, T::Half::NAME ), BenchmarkType::Single, unsigned_pair_gen_var_27::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(T::join_halves(x, y)))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/half/lower_half.rs000064400000000000000000000033361046102023000264470ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::SplitInHalf; use malachite_base::test_util::bench::bucketers::unsigned_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_gen; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_generic_demos!(runner, demo_lower_half, u16, u32, u64, u128); register_generic_benches!(runner, benchmark_lower_half, u16, u32, u64, u128); } fn demo_lower_half( gm: GenMode, config: &GenConfig, limit: usize, ) where T::Half: PrimitiveUnsigned, { for u in unsigned_gen::().get(gm, config).take(limit) { println!("{}.lower_half() = {}", u, u.lower_half()); } } fn benchmark_lower_half( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.lower_half()", T::NAME), BenchmarkType::Single, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [("Malachite", &mut |u| no_out!(u.lower_half()))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/half/mod.rs000064400000000000000000000012511046102023000250760ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { join_halves::register(runner); lower_half::register(runner); split_in_half::register(runner); upper_half::register(runner); } mod join_halves; mod lower_half; mod split_in_half; mod upper_half; malachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/half/split_in_half.rs000064400000000000000000000033701046102023000271360ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::SplitInHalf; use malachite_base::test_util::bench::bucketers::unsigned_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_gen; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_generic_demos!(runner, demo_split_in_half, u16, u32, u64, u128); register_generic_benches!(runner, benchmark_split_in_half, u16, u32, u64, u128); } fn demo_split_in_half( gm: GenMode, config: &GenConfig, limit: usize, ) where T::Half: PrimitiveUnsigned, { for u in unsigned_gen::().get(gm, config).take(limit) { println!("{}.split_in_half() = {:?}", u, u.split_in_half()); } } fn benchmark_split_in_half( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.split_in_half()", T::NAME), BenchmarkType::Single, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [("Malachite", &mut |u| no_out!(u.split_in_half()))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/half/upper_half.rs000064400000000000000000000033361046102023000264520ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::SplitInHalf; use malachite_base::test_util::bench::bucketers::unsigned_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_gen; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_generic_demos!(runner, demo_upper_half, u16, u32, u64, u128); register_generic_benches!(runner, benchmark_upper_half, u16, u32, u64, u128); } fn demo_upper_half( gm: GenMode, config: &GenConfig, limit: usize, ) where T::Half: PrimitiveUnsigned, { for u in unsigned_gen::().get(gm, config).take(limit) { println!("{}.upper_half() = {}", u, u.upper_half()); } } fn benchmark_upper_half( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.upper_half()", T::NAME), BenchmarkType::Single, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [("Malachite", &mut |u| no_out!(u.upper_half()))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/is_integer.rs000064400000000000000000000073401046102023000255420ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::bench::bucketers::{ primitive_float_bucketer, signed_bit_bucketer, unsigned_bit_bucketer, }; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{primitive_float_gen, signed_gen, unsigned_gen}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_is_integer_unsigned); register_signed_demos!(runner, demo_is_integer_signed); register_primitive_float_demos!(runner, demo_is_integer_primitive_float); register_unsigned_benches!(runner, benchmark_is_integer_unsigned); register_signed_benches!(runner, benchmark_is_integer_signed); register_primitive_float_benches!(runner, benchmark_is_integer_primitive_float); } fn demo_is_integer_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, ) { for x in primitive_float_gen::().get(gm, config).take(limit) { if x.is_integer() { println!("{} is an integer", NiceFloat(x)); } else { println!("{} is not an integer", NiceFloat(x)); } } } fn demo_is_integer_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for x in unsigned_gen::().get(gm, config).take(limit) { if x.is_integer() { println!("{x} is an integer"); } else { println!("{x} is not an integer"); } } } fn demo_is_integer_signed(gm: GenMode, config: &GenConfig, limit: usize) { for x in signed_gen::().get(gm, config).take(limit) { if x.is_integer() { println!("{x} is an integer"); } else { println!("{x} is not an integer"); } } } fn benchmark_is_integer_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.is_integer()", T::NAME), BenchmarkType::Single, primitive_float_gen::().get(gm, config), gm.name(), limit, file_name, &primitive_float_bucketer("x"), &mut [("Malachite", &mut |x| no_out!(x.is_integer()))], ); } fn benchmark_is_integer_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.is_integer()", T::NAME), BenchmarkType::Single, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [("Malachite", &mut |x| no_out!(x.is_integer()))], ); } fn benchmark_is_integer_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.is_integer()", T::NAME), BenchmarkType::Single, signed_gen::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [("Malachite", &mut |x| no_out!(x.is_integer()))], ); } ././@LongLink00006440000000000000000000000170000000000000007771Lustar malachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/mantissa_and_exponent/integer_mantissa_and_exponent.rsmalachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/mantissa_and_exponent/integer_manti000064400000000000000000000330511046102023000321730ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::bench::bucketers::{ pair_1_bit_bucketer, primitive_float_bucketer, unsigned_bit_bucketer, }; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ primitive_float_gen_var_12, unsigned_gen_var_1, unsigned_pair_gen_var_2, unsigned_pair_gen_var_30, unsigned_signed_pair_gen_var_1, unsigned_signed_pair_gen_var_2, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_integer_mantissa_and_exponent_unsigned); register_unsigned_demos!(runner, demo_integer_mantissa_unsigned); register_unsigned_demos!(runner, demo_integer_exponent_unsigned); register_unsigned_demos!(runner, demo_from_integer_mantissa_and_exponent_unsigned); register_unsigned_demos!( runner, demo_from_integer_mantissa_and_exponent_targeted_unsigned ); register_primitive_float_demos!(runner, demo_integer_mantissa_and_exponent_primitive_float); register_primitive_float_demos!(runner, demo_integer_mantissa_primitive_float); register_primitive_float_demos!(runner, demo_integer_exponent_primitive_float); register_primitive_float_demos!( runner, demo_from_integer_mantissa_and_exponent_primitive_float ); register_primitive_float_demos!( runner, demo_from_integer_mantissa_and_exponent_targeted_primitive_float ); register_unsigned_benches!( runner, benchmark_integer_mantissa_and_exponent_algorithms_unsigned ); register_unsigned_benches!(runner, benchmark_integer_mantissa_algorithms_unsigned); register_unsigned_benches!(runner, benchmark_integer_exponent_algorithms_unsigned); register_unsigned_benches!( runner, benchmark_from_integer_mantissa_and_exponent_unsigned ); register_unsigned_benches!( runner, benchmark_from_integer_mantissa_and_exponent_targeted_unsigned ); register_primitive_float_benches!( runner, benchmark_integer_mantissa_and_exponent_algorithms_primitive_float ); register_primitive_float_benches!( runner, benchmark_integer_mantissa_algorithms_primitive_float ); register_primitive_float_benches!( runner, benchmark_integer_exponent_algorithms_primitive_float ); register_primitive_float_benches!( runner, benchmark_from_integer_mantissa_and_exponent_primitive_float ); register_primitive_float_benches!( runner, benchmark_from_integer_mantissa_and_exponent_targeted_primitive_float ); } fn demo_integer_mantissa_and_exponent_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for x in unsigned_gen_var_1::().get(gm, config).take(limit) { println!( "integer_mantissa_and_exponent({}) = {:?}", x, x.integer_mantissa_and_exponent() ); } } fn demo_integer_mantissa_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for x in unsigned_gen_var_1::().get(gm, config).take(limit) { println!("integer_mantissa({}) = {}", x, x.integer_mantissa()); } } fn demo_integer_exponent_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for x in unsigned_gen_var_1::().get(gm, config).take(limit) { println!("integer_exponent({}) = {}", x, x.integer_exponent()); } } fn demo_from_integer_mantissa_and_exponent_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mantissa, exponent) in unsigned_pair_gen_var_2::() .get(gm, config) .take(limit) { println!( "{}::from_integer_mantissa_and_exponent({}, {}) = {:?}", T::NAME, mantissa, exponent, T::from_integer_mantissa_and_exponent(mantissa, exponent) ); } } fn demo_from_integer_mantissa_and_exponent_targeted_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mantissa, exponent) in unsigned_pair_gen_var_30::().get(gm, config).take(limit) { println!( "{}::from_integer_mantissa_and_exponent({}, {}) = {}", T::NAME, mantissa, exponent, T::from_integer_mantissa_and_exponent(mantissa, exponent).unwrap() ); } } fn demo_integer_mantissa_and_exponent_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, ) { for x in primitive_float_gen_var_12::() .get(gm, config) .take(limit) { println!( "integer_mantissa_and_exponent({}) = {:?}", NiceFloat(x), x.integer_mantissa_and_exponent() ); } } fn demo_integer_mantissa_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, ) { for x in primitive_float_gen_var_12::() .get(gm, config) .take(limit) { println!( "integer_mantissa({}) = {}", NiceFloat(x), x.integer_mantissa() ); } } fn demo_integer_exponent_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, ) { for x in primitive_float_gen_var_12::() .get(gm, config) .take(limit) { println!( "integer_exponent({}) = {}", NiceFloat(x), x.integer_exponent() ); } } fn demo_from_integer_mantissa_and_exponent_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mantissa, exponent) in unsigned_signed_pair_gen_var_1().get(gm, config).take(limit) { println!( "{}::from_integer_mantissa_and_exponent({}, {}) = {:?}", T::NAME, mantissa, exponent, T::from_integer_mantissa_and_exponent(mantissa, exponent).map(NiceFloat) ); } } fn demo_from_integer_mantissa_and_exponent_targeted_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mantissa, exponent) in unsigned_signed_pair_gen_var_2::() .get(gm, config) .take(limit) { println!( "{}::from_integer_mantissa_and_exponent({}, {}) = {}", T::NAME, mantissa, exponent, NiceFloat(T::from_integer_mantissa_and_exponent(mantissa, exponent).unwrap()) ); } } #[allow(clippy::unnecessary_operation)] fn benchmark_integer_mantissa_and_exponent_algorithms_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.integer_mantissa_and_exponent()", T::NAME), BenchmarkType::Algorithms, unsigned_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [ ("default", &mut |x| { no_out!(x.integer_mantissa_and_exponent()) }), ("alt", &mut |x| { no_out!((x.integer_mantissa(), x.integer_exponent())) }), ], ); } #[allow(clippy::unnecessary_operation)] fn benchmark_integer_mantissa_algorithms_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.integer_mantissa()", T::NAME), BenchmarkType::Algorithms, unsigned_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [ ("default", &mut |x| no_out!(x.integer_mantissa())), ("alt", &mut |x| no_out!(x.integer_mantissa_and_exponent().0)), ], ); } #[allow(clippy::unnecessary_operation)] fn benchmark_integer_exponent_algorithms_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.integer_exponent()", T::NAME), BenchmarkType::Algorithms, unsigned_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [ ("default", &mut |x| no_out!(x.integer_exponent())), ("alt", &mut |x| no_out!(x.integer_mantissa_and_exponent().1)), ], ); } fn benchmark_from_integer_mantissa_and_exponent_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!( "{}::from_integer_mantissa_and_exponent({}, u64)", T::NAME, T::NAME ), BenchmarkType::Single, unsigned_pair_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("mantissa"), &mut [("Malachite", &mut |(mantissa, exponent)| { no_out!(T::from_integer_mantissa_and_exponent(mantissa, exponent)) })], ); } fn benchmark_from_integer_mantissa_and_exponent_targeted_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!( "{}::from_integer_mantissa_and_exponent({}, u64)", T::NAME, T::NAME ), BenchmarkType::Single, unsigned_pair_gen_var_30::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("mantissa"), &mut [("Malachite", &mut |(mantissa, exponent)| { no_out!(T::from_integer_mantissa_and_exponent(mantissa, exponent)) })], ); } #[allow(clippy::unnecessary_operation)] fn benchmark_integer_mantissa_and_exponent_algorithms_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.integer_mantissa_and_exponent()", T::NAME), BenchmarkType::Algorithms, primitive_float_gen_var_12::().get(gm, config), gm.name(), limit, file_name, &primitive_float_bucketer("f"), &mut [ ("default", &mut |x| { no_out!(x.integer_mantissa_and_exponent()) }), ("alt", &mut |x| { no_out!((x.integer_mantissa(), x.integer_exponent())) }), ], ); } #[allow(clippy::unnecessary_operation)] fn benchmark_integer_mantissa_algorithms_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.integer_mantissa()", T::NAME), BenchmarkType::Algorithms, primitive_float_gen_var_12::().get(gm, config), gm.name(), limit, file_name, &primitive_float_bucketer("f"), &mut [ ("default", &mut |x| no_out!(x.integer_mantissa())), ("alt", &mut |x| no_out!(x.integer_mantissa_and_exponent().0)), ], ); } #[allow(clippy::unnecessary_operation)] fn benchmark_integer_exponent_algorithms_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.integer_exponent()", T::NAME), BenchmarkType::Algorithms, primitive_float_gen_var_12::().get(gm, config), gm.name(), limit, file_name, &primitive_float_bucketer("f"), &mut [ ("default", &mut |x| no_out!(x.integer_exponent())), ("alt", &mut |x| no_out!(x.integer_mantissa_and_exponent().1)), ], ); } fn benchmark_from_integer_mantissa_and_exponent_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}::from_integer_mantissa_and_exponent(u64, u64)", T::NAME), BenchmarkType::Single, unsigned_signed_pair_gen_var_1().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("mantissa"), &mut [("Malachite", &mut |(mantissa, exponent)| { no_out!(T::from_integer_mantissa_and_exponent(mantissa, exponent)) })], ); } fn benchmark_from_integer_mantissa_and_exponent_targeted_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}::from_integer_mantissa_and_exponent(u64, u64)", T::NAME), BenchmarkType::Single, unsigned_signed_pair_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("mantissa"), &mut [("Malachite", &mut |(mantissa, exponent)| { no_out!(T::from_integer_mantissa_and_exponent(mantissa, exponent)) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/mantissa_and_exponent/mod.rs000064400000000000000000000013211046102023000305430ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { integer_mantissa_and_exponent::register(runner); raw_mantissa_and_exponent::register(runner); sci_mantissa_and_exponent::register(runner); } mod integer_mantissa_and_exponent; mod raw_mantissa_and_exponent; mod sci_mantissa_and_exponent; ././@LongLink00006440000000000000000000000164000000000000007774Lustar malachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/mantissa_and_exponent/raw_mantissa_and_exponent.rsmalachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/mantissa_and_exponent/raw_mantissa_000064400000000000000000000122351046102023000321760ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::bench::bucketers::{pair_1_bit_bucketer, primitive_float_bucketer}; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{primitive_float_gen, unsigned_pair_gen_var_26}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_primitive_float_demos!(runner, demo_raw_mantissa_and_exponent); register_primitive_float_demos!(runner, demo_raw_mantissa); register_primitive_float_demos!(runner, demo_raw_exponent); register_primitive_float_demos!(runner, demo_from_raw_mantissa_and_exponent); register_primitive_float_benches!(runner, benchmark_raw_mantissa_and_exponent_algorithms); register_primitive_float_benches!(runner, benchmark_raw_mantissa_algorithms); register_primitive_float_benches!(runner, benchmark_raw_exponent_algorithms); register_primitive_float_benches!(runner, benchmark_from_raw_mantissa_and_exponent); } fn demo_raw_mantissa_and_exponent( gm: GenMode, config: &GenConfig, limit: usize, ) { for x in primitive_float_gen::().get(gm, config).take(limit) { println!( "raw_mantissa_and_exponent({}) = {:?}", NiceFloat(x), x.raw_mantissa_and_exponent() ); } } fn demo_raw_mantissa(gm: GenMode, config: &GenConfig, limit: usize) { for x in primitive_float_gen::().get(gm, config).take(limit) { println!("raw_mantissa({}) = {}", NiceFloat(x), x.raw_mantissa()); } } fn demo_raw_exponent(gm: GenMode, config: &GenConfig, limit: usize) { for x in primitive_float_gen::().get(gm, config).take(limit) { println!("raw_exponent({}) = {}", NiceFloat(x), x.raw_exponent()); } } fn demo_from_raw_mantissa_and_exponent( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mantissa, exponent) in unsigned_pair_gen_var_26::().get(gm, config).take(limit) { println!( "{}::from_raw_mantissa_and_exponent({}, {}) = {}", T::NAME, mantissa, exponent, NiceFloat(T::from_raw_mantissa_and_exponent(mantissa, exponent)) ); } } #[allow(clippy::unnecessary_operation)] fn benchmark_raw_mantissa_and_exponent_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.raw_mantissa_and_exponent()", T::NAME), BenchmarkType::Algorithms, primitive_float_gen::().get(gm, config), gm.name(), limit, file_name, &primitive_float_bucketer("f"), &mut [ ("default", &mut |x| no_out!(x.raw_mantissa_and_exponent())), ("alt", &mut |x| { no_out!((x.raw_mantissa(), x.raw_exponent())) }), ], ); } #[allow(clippy::unnecessary_operation)] fn benchmark_raw_mantissa_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.raw_mantissa()", T::NAME), BenchmarkType::Algorithms, primitive_float_gen::().get(gm, config), gm.name(), limit, file_name, &primitive_float_bucketer("f"), &mut [ ("default", &mut |x| no_out!(x.raw_mantissa())), ("alt", &mut |x| no_out!(x.raw_mantissa_and_exponent().0)), ], ); } #[allow(clippy::unnecessary_operation)] fn benchmark_raw_exponent_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.raw_exponent()", T::NAME), BenchmarkType::Algorithms, primitive_float_gen::().get(gm, config), gm.name(), limit, file_name, &primitive_float_bucketer("f"), &mut [ ("default", &mut |x| no_out!(x.raw_exponent())), ("alt", &mut |x| no_out!(x.raw_mantissa_and_exponent().1)), ], ); } fn benchmark_from_raw_mantissa_and_exponent( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}::from_raw_mantissa_and_exponent(u64, u64)", T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_26::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("mantissa"), &mut [("Malachite", &mut |(mantissa, exponent)| { no_out!(T::from_raw_mantissa_and_exponent(mantissa, exponent)) })], ); } ././@LongLink00006440000000000000000000000164000000000000007774Lustar malachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/mantissa_and_exponent/sci_mantissa_and_exponent.rsmalachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/mantissa_and_exponent/sci_mantissa_000064400000000000000000000456171046102023000321750ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::mantissa_and_exponent::{ from_sci_mantissa_and_exponent_round, sci_mantissa_and_exponent_round, }; use malachite_base::num::conversion::traits::SciMantissaAndExponent; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::bench::bucketers::{ pair_1_primitive_float_bucketer, primitive_float_bucketer, triple_1_primitive_float_bucketer, unsigned_bit_bucketer, }; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ primitive_float_gen_var_12, primitive_float_signed_pair_gen_var_1, primitive_float_signed_pair_gen_var_2, primitive_float_unsigned_pair_gen_var_1, primitive_float_unsigned_pair_gen_var_2, primitive_float_unsigned_rounding_mode_triple_gen_var_1, primitive_float_unsigned_rounding_mode_triple_gen_var_2, unsigned_gen_var_1, unsigned_rounding_mode_pair_gen_var_1, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_primitive_float_demos!(runner, demo_sci_mantissa_and_exponent_unsigned); register_unsigned_primitive_float_demos!(runner, demo_sci_mantissa_unsigned); register_unsigned_primitive_float_demos!(runner, demo_sci_exponent_unsigned); register_unsigned_primitive_float_demos!(runner, demo_sci_mantissa_and_exponent_round); register_unsigned_primitive_float_demos!(runner, demo_from_sci_mantissa_and_exponent_unsigned); register_unsigned_primitive_float_demos!( runner, demo_from_sci_mantissa_and_exponent_targeted_unsigned ); register_unsigned_primitive_float_demos!(runner, demo_from_sci_mantissa_and_exponent_round); register_unsigned_primitive_float_demos!( runner, demo_from_sci_mantissa_and_exponent_round_targeted ); register_primitive_float_demos!(runner, demo_sci_mantissa_and_exponent_primitive_float); register_primitive_float_demos!(runner, demo_sci_mantissa_primitive_float); register_primitive_float_demos!(runner, demo_sci_exponent_primitive_float); register_primitive_float_demos!(runner, demo_from_sci_mantissa_and_exponent_primitive_float); register_primitive_float_demos!( runner, demo_from_sci_mantissa_and_exponent_targeted_primitive_float ); register_unsigned_primitive_float_benches!( runner, benchmark_sci_mantissa_and_exponent_algorithms_unsigned ); register_unsigned_primitive_float_benches!(runner, benchmark_sci_mantissa_algorithms_unsigned); register_unsigned_primitive_float_benches!(runner, benchmark_sci_exponent_algorithms_unsigned); register_unsigned_primitive_float_benches!( runner, benchmark_from_sci_mantissa_and_exponent_unsigned ); register_unsigned_primitive_float_benches!( runner, benchmark_from_sci_mantissa_and_exponent_targeted_unsigned ); register_unsigned_primitive_float_benches!( runner, benchmark_from_sci_mantissa_and_exponent_round ); register_unsigned_primitive_float_benches!( runner, benchmark_from_sci_mantissa_and_exponent_round_targeted ); register_primitive_float_benches!( runner, benchmark_sci_mantissa_and_exponent_algorithms_primitive_float ); register_primitive_float_benches!(runner, benchmark_sci_mantissa_algorithms_primitive_float); register_primitive_float_benches!(runner, benchmark_sci_exponent_algorithms_primitive_float); register_primitive_float_benches!( runner, benchmark_from_sci_mantissa_and_exponent_primitive_float ); register_primitive_float_benches!( runner, benchmark_from_sci_mantissa_and_exponent_targeted_primitive_float ); } fn demo_sci_mantissa_and_exponent_unsigned< T: PrimitiveUnsigned + SciMantissaAndExponent, U: PrimitiveFloat, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for x in unsigned_gen_var_1::().get(gm, config).take(limit) { let (m, e): (U, u64) = x.sci_mantissa_and_exponent(); println!("sci_mantissa_and_exponent({}) = {:?}", x, (NiceFloat(m), e)); } } fn demo_sci_mantissa_unsigned< T: PrimitiveUnsigned + SciMantissaAndExponent, U: PrimitiveFloat, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for x in unsigned_gen_var_1::().get(gm, config).take(limit) { let m: U = x.sci_mantissa(); println!("sci_mantissa({}) = {}", x, NiceFloat(m)); } } fn demo_sci_exponent_unsigned< T: PrimitiveUnsigned + SciMantissaAndExponent, U: PrimitiveFloat, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for x in unsigned_gen_var_1::().get(gm, config).take(limit) { println!( "sci_exponent({}) = {}", x, SciMantissaAndExponent::::sci_exponent(x) ); } } fn demo_sci_mantissa_and_exponent_round< T: PrimitiveUnsigned + SciMantissaAndExponent, U: PrimitiveFloat, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, rm) in unsigned_rounding_mode_pair_gen_var_1::() .get(gm, config) .take(limit) { let o = sci_mantissa_and_exponent_round::(x, rm).map(|(m, e, o)| (NiceFloat(m), e, o)); println!("sci_mantissa_and_exponent_round({x}, {rm}) = {o:?}"); } } fn demo_from_sci_mantissa_and_exponent_unsigned< T: PrimitiveUnsigned + SciMantissaAndExponent, U: PrimitiveFloat, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mantissa, exponent) in primitive_float_unsigned_pair_gen_var_1::() .get(gm, config) .take(limit) { println!( "{}::from_sci_mantissa_and_exponent({}, {}) = {:?}", T::NAME, NiceFloat(mantissa), exponent, T::from_sci_mantissa_and_exponent(mantissa, exponent) ); } } fn demo_from_sci_mantissa_and_exponent_targeted_unsigned< T: PrimitiveUnsigned + SciMantissaAndExponent, U: PrimitiveFloat, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mantissa, exponent) in primitive_float_unsigned_pair_gen_var_2::() .get(gm, config) .take(limit) { println!( "{}::from_sci_mantissa_and_exponent({}, {}) = {:?}", T::NAME, NiceFloat(mantissa), exponent, T::from_sci_mantissa_and_exponent(mantissa, exponent) ); } } fn demo_from_sci_mantissa_and_exponent_round( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mantissa, exponent, rm) in primitive_float_unsigned_rounding_mode_triple_gen_var_1::() .get(gm, config) .take(limit) { println!( "from_sci_mantissa_and_exponent_round({}, {}, {}) = {:?}", NiceFloat(mantissa), exponent, rm, from_sci_mantissa_and_exponent_round::(mantissa, exponent, rm) ); } } fn demo_from_sci_mantissa_and_exponent_round_targeted( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mantissa, exponent, rm) in primitive_float_unsigned_rounding_mode_triple_gen_var_2::() .get(gm, config) .take(limit) { println!( "from_sci_mantissa_and_exponent_round({}, {}, {}) = {:?}", NiceFloat(mantissa), exponent, rm, from_sci_mantissa_and_exponent_round::(mantissa, exponent, rm) ); } } fn demo_sci_mantissa_and_exponent_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, ) { for x in primitive_float_gen_var_12::() .get(gm, config) .take(limit) { let (m, e) = x.sci_mantissa_and_exponent(); println!( "sci_mantissa_and_exponent({}) = {:?}", NiceFloat(x), (NiceFloat(m), e) ); } } fn demo_sci_mantissa_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, ) { for x in primitive_float_gen_var_12::() .get(gm, config) .take(limit) { println!( "sci_mantissa({}) = {}", NiceFloat(x), NiceFloat(x.sci_mantissa()) ); } } fn demo_sci_exponent_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, ) { for x in primitive_float_gen_var_12::() .get(gm, config) .take(limit) { println!("sci_exponent({}) = {}", NiceFloat(x), x.sci_exponent()); } } fn demo_from_sci_mantissa_and_exponent_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mantissa, exponent) in primitive_float_signed_pair_gen_var_1() .get(gm, config) .take(limit) { println!( "{}::from_sci_mantissa_and_exponent({}, {}) = {:?}", T::NAME, NiceFloat(mantissa), exponent, T::from_sci_mantissa_and_exponent(mantissa, exponent).map(NiceFloat) ); } } fn demo_from_sci_mantissa_and_exponent_targeted_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mantissa, exponent) in primitive_float_signed_pair_gen_var_2::() .get(gm, config) .take(limit) { println!( "{}::from_sci_mantissa_and_exponent({}, {}) = {}", T::NAME, NiceFloat(mantissa), exponent, NiceFloat(T::from_sci_mantissa_and_exponent(mantissa, exponent).unwrap()) ); } } #[allow(clippy::unnecessary_operation)] fn benchmark_sci_mantissa_and_exponent_algorithms_unsigned< T: PrimitiveUnsigned + SciMantissaAndExponent, U: PrimitiveFloat, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.sci_mantissa_and_exponent()", T::NAME), BenchmarkType::Algorithms, unsigned_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [ ("default", &mut |x| { no_out!(SciMantissaAndExponent::::sci_mantissa_and_exponent( x )) }), ("alt", &mut |x| { no_out!(( SciMantissaAndExponent::::sci_mantissa(x), SciMantissaAndExponent::::sci_exponent(x) )) }), ], ); } #[allow(clippy::unnecessary_operation)] fn benchmark_sci_mantissa_algorithms_unsigned< T: PrimitiveUnsigned + SciMantissaAndExponent, U: PrimitiveFloat, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.sci_mantissa()", T::NAME), BenchmarkType::Algorithms, unsigned_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [ ("default", &mut |x| { no_out!(SciMantissaAndExponent::::sci_mantissa(x)) }), ("alt", &mut |x| { no_out!(SciMantissaAndExponent::::sci_mantissa_and_exponent(x).0) }), ], ); } #[allow(clippy::unnecessary_operation)] fn benchmark_sci_exponent_algorithms_unsigned< T: PrimitiveUnsigned + SciMantissaAndExponent, U: PrimitiveFloat, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.sci_exponent()", T::NAME), BenchmarkType::Algorithms, unsigned_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [ ("default", &mut |x| { no_out!(SciMantissaAndExponent::::sci_exponent(x)) }), ("alt", &mut |x| { no_out!(SciMantissaAndExponent::::sci_mantissa_and_exponent(x).1) }), ], ); } fn benchmark_from_sci_mantissa_and_exponent_unsigned< T: PrimitiveUnsigned + SciMantissaAndExponent, U: PrimitiveFloat, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!( "{}::from_sci_mantissa_and_exponent({}, u64)", U::NAME, T::NAME ), BenchmarkType::Single, primitive_float_unsigned_pair_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &pair_1_primitive_float_bucketer("mantissa"), &mut [("Malachite", &mut |(mantissa, exponent)| { no_out!(T::from_sci_mantissa_and_exponent(mantissa, exponent)) })], ); } fn benchmark_from_sci_mantissa_and_exponent_targeted_unsigned< T: PrimitiveUnsigned + SciMantissaAndExponent, U: PrimitiveFloat, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!( "{}::from_sci_mantissa_and_exponent({}, u64)", U::NAME, T::NAME ), BenchmarkType::Single, primitive_float_unsigned_pair_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &pair_1_primitive_float_bucketer("mantissa"), &mut [("Malachite", &mut |(mantissa, exponent)| { no_out!(T::from_sci_mantissa_and_exponent(mantissa, exponent)) })], ); } fn benchmark_from_sci_mantissa_and_exponent_round( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!( "from_sci_mantissa_and_exponent_round({}, u64, RoundingMode)", U::NAME ), BenchmarkType::Single, primitive_float_unsigned_rounding_mode_triple_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &triple_1_primitive_float_bucketer("mantissa"), &mut [("Malachite", &mut |(mantissa, exponent, rm)| { no_out!(from_sci_mantissa_and_exponent_round::( mantissa, exponent, rm )) })], ); } fn benchmark_from_sci_mantissa_and_exponent_round_targeted< T: PrimitiveUnsigned, U: PrimitiveFloat, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!( "from_sci_mantissa_and_exponent_round({}, u64, RoundingMode)", U::NAME ), BenchmarkType::Single, primitive_float_unsigned_rounding_mode_triple_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &triple_1_primitive_float_bucketer("mantissa"), &mut [("Malachite", &mut |(mantissa, exponent, rm)| { no_out!(from_sci_mantissa_and_exponent_round::( mantissa, exponent, rm )) })], ); } #[allow(clippy::unnecessary_operation)] fn benchmark_sci_mantissa_and_exponent_algorithms_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.sci_mantissa_and_exponent()", T::NAME), BenchmarkType::Algorithms, primitive_float_gen_var_12::().get(gm, config), gm.name(), limit, file_name, &primitive_float_bucketer("f"), &mut [ ("default", &mut |x| no_out!(x.sci_mantissa_and_exponent())), ("alt", &mut |x| { no_out!((x.sci_mantissa(), x.sci_exponent())) }), ], ); } #[allow(clippy::unnecessary_operation)] fn benchmark_sci_mantissa_algorithms_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.sci_mantissa()", T::NAME), BenchmarkType::Algorithms, primitive_float_gen_var_12::().get(gm, config), gm.name(), limit, file_name, &primitive_float_bucketer("f"), &mut [ ("default", &mut |x| no_out!(x.sci_mantissa())), ("alt", &mut |x| no_out!(x.sci_mantissa_and_exponent().0)), ], ); } #[allow(clippy::unnecessary_operation)] fn benchmark_sci_exponent_algorithms_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.sci_exponent()", T::NAME), BenchmarkType::Algorithms, primitive_float_gen_var_12::().get(gm, config), gm.name(), limit, file_name, &primitive_float_bucketer("f"), &mut [ ("default", &mut |x| no_out!(x.sci_exponent())), ("alt", &mut |x| no_out!(x.sci_mantissa_and_exponent().1)), ], ); } fn benchmark_from_sci_mantissa_and_exponent_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!( "{}::from_sci_mantissa_and_exponent({}, u64)", T::NAME, T::NAME ), BenchmarkType::Single, primitive_float_signed_pair_gen_var_1().get(gm, config), gm.name(), limit, file_name, &pair_1_primitive_float_bucketer("mantissa"), &mut [("Malachite", &mut |(mantissa, exponent)| { no_out!(T::from_sci_mantissa_and_exponent(mantissa, exponent)) })], ); } fn benchmark_from_sci_mantissa_and_exponent_targeted_primitive_float( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!( "{}::from_sci_mantissa_and_exponent({}, u64)", T::NAME, T::NAME ), BenchmarkType::Single, primitive_float_signed_pair_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &pair_1_primitive_float_bucketer("mantissa"), &mut [("Malachite", &mut |(mantissa, exponent)| { no_out!(T::from_sci_mantissa_and_exponent(mantissa, exponent)) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/mod.rs000064400000000000000000000014331046102023000241660ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { digits::register(runner); from::register(runner); half::register(runner); is_integer::register(runner); mantissa_and_exponent::register(runner); slice::register(runner); string::register(runner); } mod digits; mod from; mod half; mod is_integer; mod mantissa_and_exponent; mod slice; mod string; malachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/slice/from_other_type_slice.rs000064400000000000000000000037471046102023000311040ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::named::Named; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::FromOtherTypeSlice; use malachite_base::test_util::bench::bucketers::vec_len_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_vec_gen; use malachite_base::test_util::runner::Runner; use std::fmt::Display; pub(crate) fn register(runner: &mut Runner) { register_unsigned_unsigned_demos!(runner, demo_from_other_type_slice); register_unsigned_unsigned_benches!(runner, benchmark_from_other_type_slice); } fn demo_from_other_type_slice + Named, U: PrimitiveUnsigned>( gm: GenMode, config: &GenConfig, limit: usize, ) { for xs in unsigned_vec_gen::().get(gm, config).take(limit) { println!( "{}::from_other_type_slice({:?}) = {}", T::NAME, xs, T::from_other_type_slice(&xs) ); } } fn benchmark_from_other_type_slice + Named, U: PrimitiveUnsigned>( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.from_other_type_slice(&[{}])", T::NAME, U::NAME), BenchmarkType::Single, unsigned_vec_gen::().get(gm, config), gm.name(), limit, file_name, &vec_len_bucketer(), &mut [("Malachite", &mut |xs| { no_out!(T::from_other_type_slice(&xs)) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/slice/mod.rs000064400000000000000000000012651046102023000252700ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { from_other_type_slice::register(runner); vec_from_other_type::register(runner); vec_from_other_type_slice::register(runner); } mod from_other_type_slice; mod vec_from_other_type; mod vec_from_other_type_slice; malachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/slice/vec_from_other_type.rs000064400000000000000000000036511046102023000305540ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::named::Named; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::VecFromOtherType; use malachite_base::test_util::bench::bucketers::unsigned_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_gen; use malachite_base::test_util::runner::Runner; use std::fmt::Debug; pub(crate) fn register(runner: &mut Runner) { register_unsigned_unsigned_demos!(runner, demo_vec_from_other_type); register_unsigned_unsigned_benches!(runner, benchmark_vec_from_other_type); } fn demo_vec_from_other_type + Named, U: PrimitiveUnsigned>( gm: GenMode, config: &GenConfig, limit: usize, ) { for u in unsigned_gen::().get(gm, config).take(limit) { println!( "{}::vec_from_other_type({}) = {:?}", T::NAME, u, T::vec_from_other_type(u) ); } } fn benchmark_vec_from_other_type + Named, U: PrimitiveUnsigned>( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.vec_from_other_type({})", T::NAME, U::NAME), BenchmarkType::Single, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [("Malachite", &mut |n| no_out!(T::vec_from_other_type(n)))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/slice/vec_from_other_type_slice.rs000064400000000000000000000040441046102023000317300ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::named::Named; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::VecFromOtherTypeSlice; use malachite_base::test_util::bench::bucketers::vec_len_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_vec_gen; use malachite_base::test_util::runner::Runner; use std::fmt::Debug; pub(crate) fn register(runner: &mut Runner) { register_unsigned_unsigned_demos!(runner, demo_vec_from_other_type_slice); register_unsigned_unsigned_benches!(runner, benchmark_vec_from_other_type_slice); } fn demo_vec_from_other_type_slice< T: Debug + VecFromOtherTypeSlice + Named, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for xs in unsigned_vec_gen::().get(gm, config).take(limit) { println!( "{}::vec_from_other_type_slice({:?}) = {:?}", T::NAME, xs, T::vec_from_other_type_slice(&xs) ); } } fn benchmark_vec_from_other_type_slice< T: VecFromOtherTypeSlice + Named, U: PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.vec_from_other_type_slice(&[{}])", T::NAME, U::NAME), BenchmarkType::Single, unsigned_vec_gen::().get(gm, config), gm.name(), limit, file_name, &vec_len_bucketer(), &mut [("Malachite", &mut |xs| { no_out!(T::vec_from_other_type_slice(&xs)) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/string/from_sci_string.rs000064400000000000000000000102311046102023000301000ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::test_util::bench::bucketers::{ pair_1_string_len_bucketer, string_len_bucketer, }; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ string_from_sci_string_options_pair_gen, string_from_sci_string_options_pair_gen_var_1, string_gen, string_gen_var_13, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_primitive_int_demos!(runner, demo_primitive_int_from_sci_string); register_primitive_int_demos!(runner, demo_primitive_int_from_sci_string_targeted); register_primitive_int_demos!(runner, demo_primitive_int_from_sci_string_with_options); register_primitive_int_demos!( runner, demo_primitive_int_from_sci_string_with_options_targeted ); register_primitive_int_benches!(runner, benchmark_primitive_int_from_sci_string); register_primitive_int_benches!(runner, benchmark_primitive_int_from_sci_string_with_options); } fn demo_primitive_int_from_sci_string( gm: GenMode, config: &GenConfig, limit: usize, ) { for s in string_gen().get(gm, config).take(limit) { println!( "{}::from_sci_string({}) = {:?}", T::NAME, s, T::from_sci_string(&s) ); } } fn demo_primitive_int_from_sci_string_targeted( gm: GenMode, config: &GenConfig, limit: usize, ) { for s in string_gen_var_13().get(gm, config).take(limit) { println!( "{}::from_sci_string({}) = {:?}", T::NAME, s, T::from_sci_string(&s) ); } } fn demo_primitive_int_from_sci_string_with_options( gm: GenMode, config: &GenConfig, limit: usize, ) { for (s, options) in string_from_sci_string_options_pair_gen() .get(gm, config) .take(limit) { println!( "{}::from_sci_string_with_options({}, {:?}) = {:?}", T::NAME, s, options, T::from_sci_string_with_options(&s, options) ); } } fn demo_primitive_int_from_sci_string_with_options_targeted( gm: GenMode, config: &GenConfig, limit: usize, ) { for (s, options) in string_from_sci_string_options_pair_gen_var_1() .get(gm, config) .take(limit) { println!( "{}::from_sci_string_with_options({}, {:?}) = {:?}", T::NAME, s, options, T::from_sci_string_with_options(&s, options) ); } } fn benchmark_primitive_int_from_sci_string( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}::from_sci_string(&str)", T::NAME), BenchmarkType::Single, string_gen_var_13().get(gm, config), gm.name(), limit, file_name, &string_len_bucketer(), &mut [("Malachite", &mut |s| no_out!(T::from_sci_string(&s)))], ); } fn benchmark_primitive_int_from_sci_string_with_options( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!( "{}::from_sci_string_with_options(&str, FromSciStringOptions)", T::NAME ), BenchmarkType::Single, string_from_sci_string_options_pair_gen_var_1().get(gm, config), gm.name(), limit, file_name, &pair_1_string_len_bucketer("s"), &mut [("Malachite", &mut |(s, options)| { no_out!(T::from_sci_string_with_options(&s, options)) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/string/from_string.rs000064400000000000000000000026121046102023000272460ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::conversion::string::from_string::digit_from_display_byte; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{unsigned_gen, unsigned_gen_var_10}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_digit_from_display_byte); register_demo!(runner, demo_digit_from_display_byte_targeted); } fn demo_digit_from_display_byte(gm: GenMode, config: &GenConfig, limit: usize) { for b in unsigned_gen().get(gm, config).take(limit) { println!( "digit_from_display_byte({}) = {:?}", b, digit_from_display_byte(b) ); } } fn demo_digit_from_display_byte_targeted(gm: GenMode, config: &GenConfig, limit: usize) { for b in unsigned_gen_var_10().get(gm, config).take(limit) { println!( "digit_from_display_byte({}) = {}", b, digit_from_display_byte(b).unwrap() ); } } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/string/mod.rs000064400000000000000000000013171046102023000254750ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { from_sci_string::register(runner); from_string::register(runner); options::register(runner); to_sci::register(runner); to_string::register(runner); } mod from_sci_string; mod from_string; mod options; mod to_sci; mod to_string; ././@LongLink00006440000000000000000000000153000000000000007772Lustar malachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/string/options/from_sci_string_options.rsmalachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/string/options/from_sci_string_opti000064400000000000000000000052251046102023000322120ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ from_sci_string_options_gen, from_sci_string_options_rounding_mode_pair_gen, from_sci_string_options_unsigned_pair_gen_var_1, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_from_sci_string_options_to_debug_string); register_demo!(runner, demo_from_sci_string_options_get_base); register_demo!(runner, demo_from_sci_string_options_get_rounding_mode); register_demo!(runner, demo_from_sci_string_options_set_base); register_demo!(runner, demo_from_sci_string_options_set_rounding_mode); } fn demo_from_sci_string_options_to_debug_string(gm: GenMode, config: &GenConfig, limit: usize) { for options in from_sci_string_options_gen().get(gm, config).take(limit) { println!("{options:?}"); } } fn demo_from_sci_string_options_get_base(gm: GenMode, config: &GenConfig, limit: usize) { for options in from_sci_string_options_gen().get(gm, config).take(limit) { println!("get_base({:?}) = {}", options, options.get_base()); } } fn demo_from_sci_string_options_get_rounding_mode(gm: GenMode, config: &GenConfig, limit: usize) { for options in from_sci_string_options_gen().get(gm, config).take(limit) { println!( "get_rounding_mode({:?}) = {}", options, options.get_rounding_mode() ); } } fn demo_from_sci_string_options_set_base(gm: GenMode, config: &GenConfig, limit: usize) { for (mut options, base) in from_sci_string_options_unsigned_pair_gen_var_1() .get(gm, config) .take(limit) { let old_options = options; options.set_base(base); println!("options := {old_options:?}; options.set_base({base}); options = {options:?}"); } } fn demo_from_sci_string_options_set_rounding_mode(gm: GenMode, config: &GenConfig, limit: usize) { for (mut options, rm) in from_sci_string_options_rounding_mode_pair_gen() .get(gm, config) .take(limit) { let old_options = options; options.set_rounding_mode(rm); println!( "options := {old_options:?}; options.set_rounding_mode({rm}); options = {options:?}", ); } } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/string/options/mod.rs000064400000000000000000000012351046102023000271670ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { from_sci_string_options::register(runner); sci_size_options::register(runner); to_sci_options::register(runner); } mod from_sci_string_options; mod sci_size_options; mod to_sci_options; malachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/string/options/sci_size_options.rs000064400000000000000000000015611046102023000317750ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::sci_size_options_gen; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_sci_size_options_to_debug_string); } fn demo_sci_size_options_to_debug_string(gm: GenMode, config: &GenConfig, limit: usize) { for options in sci_size_options_gen().get(gm, config).take(limit) { println!("{options:?}"); } } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/string/options/to_sci_options.rs000064400000000000000000000226501046102023000314470ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ to_sci_options_bool_pair_gen, to_sci_options_gen, to_sci_options_rounding_mode_pair_gen, to_sci_options_signed_pair_gen_var_1, to_sci_options_unsigned_pair_gen_var_1, to_sci_options_unsigned_pair_gen_var_2, to_sci_options_unsigned_pair_gen_var_3, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_to_sci_options_to_debug_string); register_demo!(runner, demo_to_sci_options_get_base); register_demo!(runner, demo_to_sci_options_get_rounding_mode); register_demo!(runner, demo_to_sci_options_get_size_options); register_demo!(runner, demo_to_sci_options_get_neg_exp_threshold); register_demo!(runner, demo_to_sci_options_get_lowercase); register_demo!(runner, demo_to_sci_options_get_e_lowercase); register_demo!(runner, demo_to_sci_options_get_force_exponent_plus_sign); register_demo!(runner, demo_to_sci_options_get_include_trailing_zeros); register_demo!(runner, demo_to_sci_options_set_base); register_demo!(runner, demo_to_sci_options_set_rounding_mode); register_demo!(runner, demo_to_sci_options_set_size_complete); register_demo!(runner, demo_to_sci_options_set_precision); register_demo!(runner, demo_to_sci_options_set_scale); register_demo!(runner, demo_to_sci_options_set_neg_exp_threshold); register_demo!(runner, demo_to_sci_options_set_lowercase); register_demo!(runner, demo_to_sci_options_set_uppercase); register_demo!(runner, demo_to_sci_options_set_e_lowercase); register_demo!(runner, demo_to_sci_options_set_e_uppercase); register_demo!(runner, demo_to_sci_options_set_force_exponent_plus_sign); register_demo!(runner, demo_to_sci_options_set_include_trailing_zeros); } fn demo_to_sci_options_to_debug_string(gm: GenMode, config: &GenConfig, limit: usize) { for options in to_sci_options_gen().get(gm, config).take(limit) { println!("{options:?}"); } } fn demo_to_sci_options_get_base(gm: GenMode, config: &GenConfig, limit: usize) { for options in to_sci_options_gen().get(gm, config).take(limit) { println!("get_base({:?}) = {}", options, options.get_base()); } } fn demo_to_sci_options_get_rounding_mode(gm: GenMode, config: &GenConfig, limit: usize) { for options in to_sci_options_gen().get(gm, config).take(limit) { println!( "get_rounding_mode({:?}) = {}", options, options.get_rounding_mode() ); } } fn demo_to_sci_options_get_size_options(gm: GenMode, config: &GenConfig, limit: usize) { for options in to_sci_options_gen().get(gm, config).take(limit) { println!( "get_size_options({:?}) = {:?}", options, options.get_size_options() ); } } fn demo_to_sci_options_get_neg_exp_threshold(gm: GenMode, config: &GenConfig, limit: usize) { for options in to_sci_options_gen().get(gm, config).take(limit) { println!( "get_neg_exp_threshold({:?}) = {}", options, options.get_neg_exp_threshold() ); } } fn demo_to_sci_options_get_lowercase(gm: GenMode, config: &GenConfig, limit: usize) { for options in to_sci_options_gen().get(gm, config).take(limit) { println!("get_lowercase({:?}) = {}", options, options.get_lowercase()); } } fn demo_to_sci_options_get_e_lowercase(gm: GenMode, config: &GenConfig, limit: usize) { for options in to_sci_options_gen().get(gm, config).take(limit) { println!( "get_e_lowercase({:?}) = {}", options, options.get_e_lowercase() ); } } fn demo_to_sci_options_get_force_exponent_plus_sign(gm: GenMode, config: &GenConfig, limit: usize) { for options in to_sci_options_gen().get(gm, config).take(limit) { println!( "get_force_exponent_plus_sign({:?}) = {}", options, options.get_force_exponent_plus_sign() ); } } fn demo_to_sci_options_get_include_trailing_zeros(gm: GenMode, config: &GenConfig, limit: usize) { for options in to_sci_options_gen().get(gm, config).take(limit) { println!( "get_include_trailing_zeros({:?}) = {}", options, options.get_include_trailing_zeros() ); } } fn demo_to_sci_options_set_base(gm: GenMode, config: &GenConfig, limit: usize) { for (mut options, base) in to_sci_options_unsigned_pair_gen_var_1() .get(gm, config) .take(limit) { let old_options = options; options.set_base(base); println!("options := {old_options:?}; options.set_base({base}); options = {options:?}"); } } fn demo_to_sci_options_set_rounding_mode(gm: GenMode, config: &GenConfig, limit: usize) { for (mut options, rm) in to_sci_options_rounding_mode_pair_gen() .get(gm, config) .take(limit) { let old_options = options; options.set_rounding_mode(rm); println!( "options := {old_options:?}; options.set_rounding_mode({rm}); options = {options:?}", ); } } fn demo_to_sci_options_set_size_complete(gm: GenMode, config: &GenConfig, limit: usize) { for mut options in to_sci_options_gen().get(gm, config).take(limit) { let old_options = options; options.set_size_complete(); println!("options := {old_options:?}; options.set_size_complete(); options = {options:?}"); } } fn demo_to_sci_options_set_precision(gm: GenMode, config: &GenConfig, limit: usize) { for (mut options, precision) in to_sci_options_unsigned_pair_gen_var_3() .get(gm, config) .take(limit) { let old_options = options; options.set_precision(precision); println!( "options := {old_options:?}; options.set_precision({precision}); options = {options:?}", ); } } fn demo_to_sci_options_set_scale(gm: GenMode, config: &GenConfig, limit: usize) { for (mut options, scale) in to_sci_options_unsigned_pair_gen_var_2() .get(gm, config) .take(limit) { let old_options = options; options.set_scale(scale); println!("options := {old_options:?}; options.set_scale({scale}); options = {options:?}"); } } fn demo_to_sci_options_set_neg_exp_threshold(gm: GenMode, config: &GenConfig, limit: usize) { for (mut options, neg_exp_threshold) in to_sci_options_signed_pair_gen_var_1() .get(gm, config) .take(limit) { let old_options = options; options.set_neg_exp_threshold(neg_exp_threshold); println!( "options := {old_options:?}; options.set_neg_exp_threshold({neg_exp_threshold}); \ options = {options:?}", ); } } fn demo_to_sci_options_set_lowercase(gm: GenMode, config: &GenConfig, limit: usize) { for mut options in to_sci_options_gen().get(gm, config).take(limit) { let old_options = options; options.set_lowercase(); println!("options := {old_options:?}; options.set_lowercase(); options = {options:?}"); } } fn demo_to_sci_options_set_uppercase(gm: GenMode, config: &GenConfig, limit: usize) { for mut options in to_sci_options_gen().get(gm, config).take(limit) { let old_options = options; options.set_uppercase(); println!("options := {old_options:?}; options.set_uppercase(); options = {options:?}"); } } fn demo_to_sci_options_set_e_lowercase(gm: GenMode, config: &GenConfig, limit: usize) { for mut options in to_sci_options_gen().get(gm, config).take(limit) { let old_options = options; options.set_e_lowercase(); println!("options := {old_options:?}; options.set_e_lowercase(); options = {options:?}"); } } fn demo_to_sci_options_set_e_uppercase(gm: GenMode, config: &GenConfig, limit: usize) { for mut options in to_sci_options_gen().get(gm, config).take(limit) { let old_options = options; options.set_e_uppercase(); println!("options := {old_options:?}; options.set_e_uppercase(); options = {options:?}"); } } fn demo_to_sci_options_set_force_exponent_plus_sign(gm: GenMode, config: &GenConfig, limit: usize) { for (mut options, force_exponent_plus_sign) in to_sci_options_bool_pair_gen().get(gm, config).take(limit) { let old_options = options; options.set_force_exponent_plus_sign(force_exponent_plus_sign); println!( "options := {old_options:?}; \ options.set_force_exponent_plus_sign({force_exponent_plus_sign}); \ options = {options:?}", ); } } fn demo_to_sci_options_set_include_trailing_zeros(gm: GenMode, config: &GenConfig, limit: usize) { for (mut options, include_trailing_zeros) in to_sci_options_bool_pair_gen().get(gm, config).take(limit) { let old_options = options; options.set_include_trailing_zeros(include_trailing_zeros); println!( "options := {old_options:?}; \ options.set_include_trailing_zeros({include_trailing_zeros}); options = {options:?}", ); } } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/string/to_sci.rs000064400000000000000000000156461046102023000262100ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::{ pair_1_bit_bucketer, signed_bit_bucketer, unsigned_bit_bucketer, }; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ signed_gen, signed_to_sci_options_pair_gen, signed_to_sci_options_pair_gen_var_1, unsigned_gen, unsigned_to_sci_options_pair_gen, unsigned_to_sci_options_pair_gen_var_1, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_to_sci_unsigned); register_signed_demos!(runner, demo_to_sci_signed); register_unsigned_demos!(runner, demo_fmt_sci_valid_unsigned); register_signed_demos!(runner, demo_fmt_sci_valid_signed); register_unsigned_demos!(runner, demo_to_sci_with_options_unsigned); register_signed_demos!(runner, demo_to_sci_with_options_signed); register_unsigned_benches!(runner, benchmark_to_sci_unsigned); register_signed_benches!(runner, benchmark_to_sci_signed); register_unsigned_benches!(runner, benchmark_fmt_sci_valid_unsigned); register_signed_benches!(runner, benchmark_fmt_sci_valid_signed); register_unsigned_benches!(runner, benchmark_to_sci_with_options_unsigned); register_signed_benches!(runner, benchmark_to_sci_with_options_signed); } fn demo_to_sci_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for x in unsigned_gen::().get(gm, config).take(limit) { println!("{}.to_sci() = {}", x, x.to_sci()); } } fn demo_to_sci_signed(gm: GenMode, config: &GenConfig, limit: usize) { for x in signed_gen::().get(gm, config).take(limit) { println!("{}.to_sci() = {}", x, x.to_sci()); } } fn demo_fmt_sci_valid_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, options) in unsigned_to_sci_options_pair_gen::() .get(gm, config) .take(limit) { if x.fmt_sci_valid(options) { println!("{x} can be converted to sci using {options:?}"); } else { println!("{x} cannot be converted to sci using {options:?}"); } } } fn demo_fmt_sci_valid_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (x, options) in signed_to_sci_options_pair_gen::() .get(gm, config) .take(limit) { if x.fmt_sci_valid(options) { println!("{x} can be converted to sci using {options:?}"); } else { println!("{x} cannot be converted to sci using {options:?}"); } } } fn demo_to_sci_with_options_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, options) in unsigned_to_sci_options_pair_gen_var_1::() .get(gm, config) .take(limit) { println!( "to_sci_with_options({}, {:?}) = {}", x, options, x.to_sci_with_options(options) ); } } fn demo_to_sci_with_options_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, options) in signed_to_sci_options_pair_gen_var_1::() .get(gm, config) .take(limit) { println!( "to_sci_with_options({}, {:?}) = {}", x, options, x.to_sci_with_options(options) ); } } fn benchmark_to_sci_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.to_sci()", T::NAME), BenchmarkType::Single, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [("Malachite", &mut |x| no_out!(x.to_sci().to_string()))], ); } fn benchmark_to_sci_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.to_sci()", T::NAME), BenchmarkType::Single, signed_gen::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [("Malachite", &mut |x| no_out!(x.to_sci().to_string()))], ); } fn benchmark_fmt_sci_valid_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.fmt_sci_valid(ToSciOptions)", T::NAME), BenchmarkType::Single, unsigned_to_sci_options_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("u"), &mut [("Malachite", &mut |(x, options)| { no_out!(x.fmt_sci_valid(options)) })], ); } fn benchmark_fmt_sci_valid_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.fmt_sci_valid(ToSciOptions)", T::NAME), BenchmarkType::Single, signed_to_sci_options_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("i"), &mut [("Malachite", &mut |(x, options)| { no_out!(x.fmt_sci_valid(options)) })], ); } fn benchmark_to_sci_with_options_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.to_sci_with_options(ToSciOptions)", T::NAME), BenchmarkType::Single, unsigned_to_sci_options_pair_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("u"), &mut [("Malachite", &mut |(x, options)| { no_out!(x.to_sci_with_options(options).to_string()) })], ); } fn benchmark_to_sci_with_options_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.to_sci_with_options(ToSciOptions)", T::NAME), BenchmarkType::Single, signed_to_sci_options_pair_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("u"), &mut [("Malachite", &mut |(x, options)| { no_out!(x.to_sci_with_options(options).to_string()) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/conversion/string/to_string.rs000064400000000000000000000410471046102023000267320ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::UnsignedAbs; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::string::to_string::{ digit_to_display_byte_lower, digit_to_display_byte_upper, BaseFmtWrapper, }; use malachite_base::num::conversion::traits::WrappingFrom; use malachite_base::test_util::bench::bucketers::{pair_1_bit_bucketer, triple_1_bit_bucketer}; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ signed_unsigned_pair_gen_var_5, signed_unsigned_unsigned_triple_gen_var_3, unsigned_gen, unsigned_gen_var_7, unsigned_pair_gen_var_8, unsigned_triple_gen_var_6, }; use malachite_base::test_util::num::conversion::string::to_string::{ to_string_base_signed_naive, to_string_base_unsigned_naive, }; use malachite_base::test_util::runner::Runner; use std::fmt::Display; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_digit_to_display_byte_lower); register_demo!(runner, demo_digit_to_display_byte_upper); register_demo!(runner, demo_digit_to_display_byte_lower_targeted); register_demo!(runner, demo_digit_to_display_byte_upper_targeted); register_unsigned_demos!(runner, demo_to_string_base_unsigned); register_signed_demos!(runner, demo_to_string_base_signed); register_unsigned_demos!(runner, demo_to_string_base_upper_unsigned); register_signed_demos!(runner, demo_to_string_base_upper_signed); register_unsigned_demos!(runner, demo_base_fmt_wrapper_fmt_unsigned); register_unsigned_demos!(runner, demo_base_fmt_wrapper_fmt_with_width_unsigned); register_signed_demos!(runner, demo_base_fmt_wrapper_fmt_signed); register_signed_demos!(runner, demo_base_fmt_wrapper_fmt_with_width_signed); register_unsigned_demos!(runner, demo_base_fmt_wrapper_fmt_upper_unsigned); register_unsigned_demos!(runner, demo_base_fmt_wrapper_fmt_upper_with_width_unsigned); register_signed_demos!(runner, demo_base_fmt_wrapper_fmt_upper_signed); register_signed_demos!(runner, demo_base_fmt_wrapper_fmt_upper_with_width_signed); register_unsigned_benches!(runner, benchmark_to_string_base_algorithms_unsigned); register_signed_benches!(runner, benchmark_to_string_base_algorithms_signed); register_unsigned_benches!(runner, benchmark_to_string_base_upper_algorithms_unsigned); register_signed_benches!(runner, benchmark_to_string_base_upper_algorithms_signed); register_unsigned_benches!(runner, benchmark_base_fmt_wrapper_fmt_with_width_unsigned); register_signed_benches!(runner, benchmark_base_fmt_wrapper_fmt_with_width_signed); register_unsigned_benches!( runner, benchmark_base_fmt_wrapper_fmt_upper_with_width_unsigned ); register_signed_benches!( runner, benchmark_base_fmt_wrapper_fmt_upper_with_width_signed ); } fn demo_digit_to_display_byte_lower(gm: GenMode, config: &GenConfig, limit: usize) { for b in unsigned_gen().get(gm, config).take(limit) { println!( "digit_to_display_byte_lower({}) = {:?}", b, digit_to_display_byte_lower(b) ); } } fn demo_digit_to_display_byte_upper(gm: GenMode, config: &GenConfig, limit: usize) { for b in unsigned_gen().get(gm, config).take(limit) { println!( "digit_to_display_byte_upper({}) = {:?}", b, digit_to_display_byte_upper(b) ); } } fn demo_digit_to_display_byte_lower_targeted(gm: GenMode, config: &GenConfig, limit: usize) { for b in unsigned_gen_var_7().get(gm, config).take(limit) { println!( "digit_to_display_byte_lower({}) = {}", b, digit_to_display_byte_lower(b).unwrap() ); } } fn demo_digit_to_display_byte_upper_targeted(gm: GenMode, config: &GenConfig, limit: usize) { for b in unsigned_gen_var_7().get(gm, config).take(limit) { println!( "digit_to_display_byte_upper({}) = {}", b, digit_to_display_byte_upper(b).unwrap() ); } } fn demo_to_string_base_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, base) in unsigned_pair_gen_var_8::() .get(gm, config) .take(limit) { println!( "{}.to_string_base({}) = {}", x, base, x.to_string_base(base) ); } } fn demo_to_string_base_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (x, base) in signed_unsigned_pair_gen_var_5::() .get(gm, config) .take(limit) { println!( "({}).to_string_base({}) = {}", x, base, x.to_string_base(base) ); } } fn demo_to_string_base_upper_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, base) in unsigned_pair_gen_var_8::() .get(gm, config) .take(limit) { println!( "{}.to_string_base_upper({}) = {}", x, base, x.to_string_base_upper(base) ); } } fn demo_to_string_base_upper_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, base) in signed_unsigned_pair_gen_var_5::() .get(gm, config) .take(limit) { println!( "({}).to_string_base_upper({}) = {}", x, base, x.to_string_base_upper(base) ); } } #[allow(clippy::format_in_format_args)] fn demo_base_fmt_wrapper_fmt_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) where BaseFmtWrapper: Display, { for (x, base) in unsigned_pair_gen_var_8::() .get(gm, config) .take(limit) { println!( "format!(\"{{}}\", BaseFmtWrapper::new({}, {})) = {}", x, base, format!("{}", BaseFmtWrapper::new(x, base)) ); } } #[allow(clippy::format_in_format_args)] fn demo_base_fmt_wrapper_fmt_with_width_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) where BaseFmtWrapper: Display, { for (x, base, width) in unsigned_triple_gen_var_6::() .get(gm, config) .take(limit) { println!( "format!(\"{{:0{}}}\", BaseFmtWrapper::new({}, {})) = {}", width, x, base, format!("{:0width$}", BaseFmtWrapper::new(x, base), width = width) ); } } #[allow(clippy::format_in_format_args)] fn demo_base_fmt_wrapper_fmt_signed( gm: GenMode, config: &GenConfig, limit: usize, ) where BaseFmtWrapper: Display, { for (x, base) in signed_unsigned_pair_gen_var_5::() .get(gm, config) .take(limit) { println!( "format!(\"{{}}\", BaseFmtWrapper::new({}, {})) = {}", x, base, format!("{}", BaseFmtWrapper::new(x, base)) ); } } #[allow(clippy::format_in_format_args)] fn demo_base_fmt_wrapper_fmt_with_width_signed( gm: GenMode, config: &GenConfig, limit: usize, ) where BaseFmtWrapper: Display, { for (x, base, width) in signed_unsigned_unsigned_triple_gen_var_3::() .get(gm, config) .take(limit) { println!( "format!(\"{{:0{}}}\", BaseFmtWrapper::new({}, {})) = {}", width, x, base, format!("{:0width$}", BaseFmtWrapper::new(x, base), width = width) ); } } #[allow(clippy::format_in_format_args)] fn demo_base_fmt_wrapper_fmt_upper_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) where BaseFmtWrapper: Display, { for (x, base) in unsigned_pair_gen_var_8::() .get(gm, config) .take(limit) { println!( "format!(\"{{:#}}\", BaseFmtWrapper::new({}, {})) = {}", x, base, format!("{:#}", BaseFmtWrapper::new(x, base)) ); } } #[allow(clippy::format_in_format_args)] fn demo_base_fmt_wrapper_fmt_upper_with_width_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) where BaseFmtWrapper: Display, { for (x, base, width) in unsigned_triple_gen_var_6::() .get(gm, config) .take(limit) { println!( "format!(\"{{:#0{}}}\", BaseFmtWrapper::new({}, {})) = {}", width, x, base, format!("{:#0width$}", BaseFmtWrapper::new(x, base), width = width) ); } } #[allow(clippy::format_in_format_args)] fn demo_base_fmt_wrapper_fmt_upper_signed( gm: GenMode, config: &GenConfig, limit: usize, ) where BaseFmtWrapper: Display, { for (x, base) in signed_unsigned_pair_gen_var_5::() .get(gm, config) .take(limit) { println!( "format!(\"{{:#}}\", BaseFmtWrapper::new({}, {})) = {}", x, base, format!("{:#}", BaseFmtWrapper::new(x, base)) ); } } #[allow(clippy::format_in_format_args)] fn demo_base_fmt_wrapper_fmt_upper_with_width_signed( gm: GenMode, config: &GenConfig, limit: usize, ) where BaseFmtWrapper: Display, { for (x, base, width) in signed_unsigned_unsigned_triple_gen_var_3::() .get(gm, config) .take(limit) { println!( "format!(\"{{:#0{}}}\", BaseFmtWrapper::new({}, {})) = {}", width, x, base, format!("{:#0width$}", BaseFmtWrapper::new(x, base), width = width) ); } } fn benchmark_to_string_base_algorithms_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where BaseFmtWrapper: Display, u8: WrappingFrom, { run_benchmark( &format!("{}.to_string_base(u8)", T::NAME), BenchmarkType::Algorithms, unsigned_pair_gen_var_8::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("x"), &mut [ ( "to_string", &mut |(x, base)| no_out!(x.to_string_base(base)), ), ("using fmt", &mut |(x, base)| { no_out!(format!("{}", BaseFmtWrapper::new(x, base))) }), ("naive", &mut |(x, base)| { no_out!(to_string_base_unsigned_naive(x, base)) }), ], ); } fn benchmark_to_string_base_algorithms_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where BaseFmtWrapper: Display, u8: WrappingFrom<::Output>, ::Output: PrimitiveUnsigned, { run_benchmark( &format!("{}.to_string_base(u8)", T::NAME), BenchmarkType::Algorithms, signed_unsigned_pair_gen_var_5::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("x"), &mut [ ( "to_string", &mut |(x, base)| no_out!(x.to_string_base(base)), ), ("using fmt", &mut |(x, base)| { no_out!(format!("{}", BaseFmtWrapper::new(x, base))) }), ("naive", &mut |(x, base)| { no_out!(to_string_base_signed_naive(x, base)) }), ], ); } fn benchmark_to_string_base_upper_algorithms_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where BaseFmtWrapper: Display, { run_benchmark( &format!("{}.to_string_base_upper(u8)", T::NAME), BenchmarkType::Algorithms, unsigned_pair_gen_var_8::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("x"), &mut [ ("to_string", &mut |(x, base)| { no_out!(x.to_string_base_upper(base)) }), ("using fmt", &mut |(x, base)| { no_out!(format!("{:#}", BaseFmtWrapper::new(x, base))) }), ], ); } fn benchmark_to_string_base_upper_algorithms_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where BaseFmtWrapper: Display, { run_benchmark( &format!("{}.to_string_base_upper(u8)", T::NAME), BenchmarkType::Algorithms, signed_unsigned_pair_gen_var_5::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("x"), &mut [ ( "to_string", &mut |(x, base)| no_out!(x.to_string_base(base)), ), ("using fmt", &mut |(x, base)| { no_out!(format!("{}", BaseFmtWrapper::new(x, base))) }), ], ); } fn benchmark_base_fmt_wrapper_fmt_with_width_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where BaseFmtWrapper: Display, { run_benchmark( &format!( "format!(\"{{:0usize}}\", BaseFmtWrapper::new({}, u8))", T::NAME ), BenchmarkType::Single, unsigned_triple_gen_var_6::().get(gm, config), gm.name(), limit, file_name, &triple_1_bit_bucketer("x"), &mut [("Malachite", &mut |(x, base, width)| { no_out!(format!( "{:0width$}", BaseFmtWrapper::new(x, base), width = width )) })], ); } fn benchmark_base_fmt_wrapper_fmt_with_width_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where BaseFmtWrapper: Display, { run_benchmark( &format!( "format!(\"{{:0usize}}\", BaseFmtWrapper::new({}, u8))", T::NAME ), BenchmarkType::Single, signed_unsigned_unsigned_triple_gen_var_3::().get(gm, config), gm.name(), limit, file_name, &triple_1_bit_bucketer("x"), &mut [("Malachite", &mut |(x, base, width)| { no_out!(format!( "{:0width$}", BaseFmtWrapper::new(x, base), width = width )) })], ); } fn benchmark_base_fmt_wrapper_fmt_upper_with_width_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where BaseFmtWrapper: Display, { run_benchmark( &format!( "format!(\"{{:#0usize}}\", BaseFmtWrapper::new({}, u8))", T::NAME ), BenchmarkType::Single, unsigned_triple_gen_var_6::().get(gm, config), gm.name(), limit, file_name, &triple_1_bit_bucketer("x"), &mut [("Malachite", &mut |(x, base, width)| { no_out!(format!( "{:#0width$}", BaseFmtWrapper::new(x, base), width = width )) })], ); } fn benchmark_base_fmt_wrapper_fmt_upper_with_width_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where BaseFmtWrapper: Display, { run_benchmark( &format!( "format!(\"{{:#0usize}}\", BaseFmtWrapper::new({}, u8))", T::NAME ), BenchmarkType::Single, signed_unsigned_unsigned_triple_gen_var_3::().get(gm, config), gm.name(), limit, file_name, &triple_1_bit_bucketer("x"), &mut [("Malachite", &mut |(x, base, width)| { no_out!(format!( "{:#0width$}", BaseFmtWrapper::new(x, base), width = width )) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/factorization/mod.rs000064400000000000000000000010671046102023000246600ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { primes::register(runner); prime_sieve::register(runner); } mod prime_sieve; mod primes; malachite-base-0.4.16/src/bin_util/demo_and_bench/num/factorization/prime_sieve.rs000064400000000000000000000107511046102023000264100ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::factorization::prime_sieve::{ limbs_prime_sieve_size, limbs_prime_sieve_u32, limbs_prime_sieve_u64, }; use malachite_base::test_util::bench::bucketers::unsigned_direct_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_gen_var_26; use malachite_base::test_util::num::factorization::prime_sieve::{ limbs_prime_sieve_naive_1, limbs_prime_sieve_naive_2, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_limbs_prime_sieve_u32); register_demo!(runner, demo_limbs_prime_sieve_u64); register_bench!(runner, benchmark_limbs_prime_sieve_u32_algorithms); register_bench!(runner, benchmark_limbs_prime_sieve_u64_algorithms); } fn demo_limbs_prime_sieve_u32(gm: GenMode, config: &GenConfig, limit: usize) { for n in unsigned_gen_var_26().get(gm, config).take(limit) { let len = limbs_prime_sieve_size::(n); let mut sieve = vec![0; len]; limbs_prime_sieve_u32(&mut sieve, n); print!("limbs_prime_sieve_u32({n}): "); let mut first = true; for s in sieve { if first { first = false; } else { print!(", "); } print!("{s:b}"); } println!(); } } fn demo_limbs_prime_sieve_u64(gm: GenMode, config: &GenConfig, limit: usize) { for n in unsigned_gen_var_26().get(gm, config).take(limit) { let len = limbs_prime_sieve_size::(n); let mut sieve = vec![0; len]; limbs_prime_sieve_u64(&mut sieve, n); print!("limbs_prime_sieve_u64({n}): "); let mut first = true; for s in sieve { if first { first = false; } else { print!(", "); } print!("{s:b}"); } println!(); } } fn benchmark_limbs_prime_sieve_u32_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( "limbs_prime_sieve_u32(&mut [Limb], u64)", BenchmarkType::Algorithms, unsigned_gen_var_26().get(gm, config), gm.name(), limit, file_name, &unsigned_direct_bucketer(), &mut [ ("default", &mut |n| { let len = limbs_prime_sieve_size::(n); let mut sieve = vec![0; len]; limbs_prime_sieve_u32(&mut sieve, n); }), ("test each prime separately", &mut |n| { let len = limbs_prime_sieve_size::(n); let mut sieve = vec![0; len]; limbs_prime_sieve_naive_1::(&mut sieve, n); }), ("naive sieve", &mut |n| { let len = limbs_prime_sieve_size::(n); let mut sieve = vec![0; len]; limbs_prime_sieve_naive_2::(&mut sieve, n); }), ], ); } fn benchmark_limbs_prime_sieve_u64_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( "limbs_prime_sieve_u64(&mut [Limb], u64)", BenchmarkType::Algorithms, unsigned_gen_var_26().get(gm, config), gm.name(), limit, file_name, &unsigned_direct_bucketer(), &mut [ ("default", &mut |n| { let len = limbs_prime_sieve_size::(n); let mut sieve = vec![0; len]; limbs_prime_sieve_u64(&mut sieve, n); }), ("test each prime separately", &mut |n| { let len = limbs_prime_sieve_size::(n); let mut sieve = vec![0; len]; limbs_prime_sieve_naive_1::(&mut sieve, n); }), ("naive sieve", &mut |n| { let len = limbs_prime_sieve_size::(n); let mut sieve = vec![0; len]; limbs_prime_sieve_naive_2::(&mut sieve, n); }), ], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/factorization/primes.rs000064400000000000000000000172521046102023000254030ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::factorization::primes::{ prime_indicator_sequence, prime_indicator_sequence_less_than, prime_indicator_sequence_less_than_or_equal_to, }; use malachite_base::test_util::bench::bucketers::unsigned_direct_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_gen_var_5; use malachite_base::test_util::num::factorization::primes::primes_naive; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_primes_less_than); register_unsigned_demos!(runner, demo_primes_less_than_or_equal_to); register_unsigned_demos!(runner, demo_primes); register_demo!(runner, demo_prime_indicator_sequence_less_than); register_demo!(runner, demo_prime_indicator_sequence_less_than_or_equal_to); register_demo!(runner, demo_prime_indicator_sequence); register_unsigned_benches!(runner, benchmark_primes_less_than_algorithms); register_unsigned_benches!(runner, benchmark_primes_less_than_algorithms_2); register_unsigned_benches!(runner, benchmark_primes_less_than_or_equal_to_algorithms); register_unsigned_benches!(runner, benchmark_primes_less_than_or_equal_to_algorithms_2); register_bench!(runner, benchmark_prime_indicator_sequence_less_than); register_bench!( runner, benchmark_prime_indicator_sequence_less_than_or_equal_to ); } fn demo_primes_less_than(gm: GenMode, config: &GenConfig, limit: usize) { for n in unsigned_gen_var_5::().get(gm, config).take(limit) { println!( "primes_less_than({}) = {:?}", n, T::primes_less_than(&n).collect_vec() ); } } fn demo_primes_less_than_or_equal_to( gm: GenMode, config: &GenConfig, limit: usize, ) { for n in unsigned_gen_var_5::().get(gm, config).take(limit) { println!( "primes_less_than_or_equal_to({}) = {:?}", n, T::primes_less_than_or_equal_to(&n).collect_vec() ); } } fn demo_primes(_gm: GenMode, _config: &GenConfig, limit: usize) { for p in T::primes().take(limit) { println!("{p}"); } } fn demo_prime_indicator_sequence_less_than(gm: GenMode, config: &GenConfig, limit: usize) { for n in unsigned_gen_var_5().get(gm, config).take(limit) { println!( "prime_indicator_sequence_less_than({}) = {:?}", n, prime_indicator_sequence_less_than(n).collect_vec() ); } } fn demo_prime_indicator_sequence_less_than_or_equal_to( gm: GenMode, config: &GenConfig, limit: usize, ) { for n in unsigned_gen_var_5().get(gm, config).take(limit) { println!( "prime_indicator_sequence_less_than_or_equal_to({}) = {:?}", n, prime_indicator_sequence_less_than_or_equal_to(n).collect_vec() ); } } fn demo_prime_indicator_sequence(_gm: GenMode, _config: &GenConfig, limit: usize) { for b in prime_indicator_sequence().take(limit) { println!("{b}"); } } fn benchmark_primes_less_than_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where usize: TryFrom, { run_benchmark( &format!("{}::primes_less_than({})", T::NAME, T::NAME), BenchmarkType::Algorithms, unsigned_gen_var_5::().get(gm, config), gm.name(), limit, file_name, &unsigned_direct_bucketer(), &mut [ ("default", &mut |n| no_out!(T::primes_less_than(&n).count())), ("using primes", &mut |n| { no_out!(T::primes().take_while(|&p| p < n).count()) }), ("naive", &mut |n| { no_out!(primes_naive::().take_while(|&p| p < n).count()) }), ], ); } fn benchmark_primes_less_than_algorithms_2( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where usize: TryFrom, { run_benchmark( &format!("{}::primes_less_than(&{})", T::NAME, T::NAME), BenchmarkType::Algorithms, unsigned_gen_var_5::().get(gm, config), gm.name(), limit, file_name, &unsigned_direct_bucketer(), &mut [ ("default", &mut |n| no_out!(T::primes_less_than(&n).count())), ("using primes", &mut |n| { no_out!(T::primes().take_while(|&p| p < n).count()) }), ], ); } fn benchmark_primes_less_than_or_equal_to_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where usize: TryFrom, { run_benchmark( &format!("{}::primes_less_than_or_equal_to(&{})", T::NAME, T::NAME), BenchmarkType::Algorithms, unsigned_gen_var_5::().get(gm, config), gm.name(), limit, file_name, &unsigned_direct_bucketer(), &mut [ ("default", &mut |n| { no_out!(T::primes_less_than_or_equal_to(&n).count()) }), ("using primes", &mut |n| { no_out!(T::primes().take_while(|&p| p <= n).count()) }), ("naive", &mut |n| { no_out!(primes_naive::().take_while(|&p| p <= n).count()) }), ], ); } fn benchmark_primes_less_than_or_equal_to_algorithms_2( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where usize: TryFrom, { run_benchmark( &format!("{}::primes_less_than_or_equal_to({})", T::NAME, T::NAME), BenchmarkType::Algorithms, unsigned_gen_var_5::().get(gm, config), gm.name(), limit, file_name, &unsigned_direct_bucketer(), &mut [ ("default", &mut |n| { no_out!(T::primes_less_than_or_equal_to(&n).count()) }), ("using primes", &mut |n| { no_out!(T::primes().take_while(|&p| p <= n).count()) }), ], ); } fn benchmark_prime_indicator_sequence_less_than( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( "prime_indicator_sequence_less_than(u64)", BenchmarkType::Single, unsigned_gen_var_5().get(gm, config), gm.name(), limit, file_name, &unsigned_direct_bucketer(), &mut [("Malachite", &mut |n| { no_out!(prime_indicator_sequence_less_than(n).count()) })], ); } fn benchmark_prime_indicator_sequence_less_than_or_equal_to( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( "prime_indicator_sequence_less_than_or_equal_to(u64)", BenchmarkType::Single, unsigned_gen_var_5().get(gm, config), gm.name(), limit, file_name, &unsigned_direct_bucketer(), &mut [("Malachite", &mut |n| { no_out!(prime_indicator_sequence_less_than_or_equal_to(n).count()) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/float/basic/abs_negative_zero.rs000064400000000000000000000054271046102023000271050ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::bench::bucketers::primitive_float_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::primitive_float_gen; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_primitive_float_demos!(runner, demo_abs_negative_zero); register_primitive_float_demos!(runner, demo_abs_negative_zero_assign); register_primitive_float_benches!(runner, benchmark_abs_negative_zero); register_primitive_float_benches!(runner, benchmark_abs_negative_zero_assign); } fn demo_abs_negative_zero(gm: GenMode, config: &GenConfig, limit: usize) { for x in primitive_float_gen::().get(gm, config).take(limit) { println!( "abs_negative_zero({}) = {}", NiceFloat(x), NiceFloat(x.abs_negative_zero()) ); } } fn demo_abs_negative_zero_assign(gm: GenMode, config: &GenConfig, limit: usize) { for mut x in primitive_float_gen::().get(gm, config).take(limit) { let old_x = x; x.abs_negative_zero_assign(); println!( "x := {}; x.abs_negative_zero_assign(); x = {}", NiceFloat(old_x), NiceFloat(x) ); } } fn benchmark_abs_negative_zero( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.abs_negative_zero()", T::NAME), BenchmarkType::Single, primitive_float_gen::().get(gm, config), gm.name(), limit, file_name, &primitive_float_bucketer("f"), &mut [("Malachite", &mut |x| no_out!(x.abs_negative_zero()))], ); } fn benchmark_abs_negative_zero_assign( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.abs_negative_zero_assign()", T::NAME), BenchmarkType::Single, primitive_float_gen::().get(gm, config), gm.name(), limit, file_name, &primitive_float_bucketer("f"), &mut [("Malachite", &mut |mut x| { no_out!(x.abs_negative_zero_assign()) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/float/basic/from_ordered_representation.rs000064400000000000000000000035341046102023000312050ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::bench::bucketers::unsigned_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_gen_var_13; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_primitive_float_demos!(runner, demo_from_ordered_representation); register_primitive_float_benches!(runner, benchmark_from_ordered_representation); } fn demo_from_ordered_representation( gm: GenMode, config: &GenConfig, limit: usize, ) { for x in unsigned_gen_var_13::().get(gm, config).take(limit) { println!( "from_ordered_representation({}) = {}", x, NiceFloat(T::from_ordered_representation(x)) ); } } fn benchmark_from_ordered_representation( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}::from_ordered_representation(u64)", T::NAME), BenchmarkType::Single, unsigned_gen_var_13::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [("Malachite", &mut |x| { no_out!(T::from_ordered_representation(x)) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/float/basic/is_negative_zero.rs000064400000000000000000000034241046102023000267460ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::bench::bucketers::primitive_float_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::primitive_float_gen; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_primitive_float_demos!(runner, demo_is_negative_zero); register_primitive_float_benches!(runner, benchmark_is_negative_zero); } fn demo_is_negative_zero(gm: GenMode, config: &GenConfig, limit: usize) { for x in primitive_float_gen::().get(gm, config).take(limit) { if x.is_negative_zero() { println!("{} is negative zero", NiceFloat(x)); } else { println!("{} is not negative zero", NiceFloat(x)); } } } fn benchmark_is_negative_zero( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.is_negative_zero()", T::NAME), BenchmarkType::Single, primitive_float_gen::().get(gm, config), gm.name(), limit, file_name, &primitive_float_bucketer("f"), &mut [("Malachite", &mut |x| no_out!(x.is_negative_zero()))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/float/basic/max_precision_for_sci_exponent.rs000064400000000000000000000034771046102023000317060ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::test_util::bench::bucketers::signed_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::signed_gen_var_11; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_primitive_float_demos!(runner, demo_max_precision_for_sci_exponent); register_primitive_float_benches!(runner, benchmark_max_precision_for_sci_exponent); } fn demo_max_precision_for_sci_exponent( gm: GenMode, config: &GenConfig, limit: usize, ) { for exp in signed_gen_var_11::().get(gm, config).take(limit) { println!( "{}.max_precision_for_sci_exponent() = {}", exp, T::max_precision_for_sci_exponent(exp) ); } } fn benchmark_max_precision_for_sci_exponent( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}::max_precision_for_sci_exponent(i64)", T::NAME), BenchmarkType::Single, signed_gen_var_11::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [("Malachite", &mut |exp| { no_out!(T::max_precision_for_sci_exponent(exp)) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/float/basic/mod.rs000064400000000000000000000017531046102023000241740ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { abs_negative_zero::register(runner); from_ordered_representation::register(runner); is_negative_zero::register(runner); max_precision_for_sci_exponent::register(runner); next_higher::register(runner); next_lower::register(runner); precision::register(runner); to_ordered_representation::register(runner); } mod abs_negative_zero; mod from_ordered_representation; mod is_negative_zero; mod max_precision_for_sci_exponent; mod next_higher; mod next_lower; mod precision; mod to_ordered_representation; malachite-base-0.4.16/src/bin_util/demo_and_bench/num/float/basic/next_higher.rs000064400000000000000000000033231046102023000257140ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::bench::bucketers::primitive_float_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::primitive_float_gen_var_9; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_primitive_float_demos!(runner, demo_next_higher); register_primitive_float_benches!(runner, benchmark_next_higher); } fn demo_next_higher(gm: GenMode, config: &GenConfig, limit: usize) { for x in primitive_float_gen_var_9::().get(gm, config).take(limit) { println!( "next_higher({}) = {}", NiceFloat(x), NiceFloat(x.next_higher()) ); } } fn benchmark_next_higher( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.next_higher()", T::NAME), BenchmarkType::Single, primitive_float_gen_var_9::().get(gm, config), gm.name(), limit, file_name, &primitive_float_bucketer("f"), &mut [("Malachite", &mut |x| no_out!(x.next_higher()))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/float/basic/next_lower.rs000064400000000000000000000033441046102023000256010ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::bench::bucketers::primitive_float_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::primitive_float_gen_var_10; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_primitive_float_demos!(runner, demo_next_lower); register_primitive_float_benches!(runner, benchmark_next_lower); } fn demo_next_lower(gm: GenMode, config: &GenConfig, limit: usize) { for x in primitive_float_gen_var_10::() .get(gm, config) .take(limit) { println!( "next_lower({}) = {}", NiceFloat(x), NiceFloat(x.next_lower()) ); } } fn benchmark_next_lower( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.next_lower()", T::NAME), BenchmarkType::Single, primitive_float_gen_var_10::().get(gm, config), gm.name(), limit, file_name, &primitive_float_bucketer("f"), &mut [("Malachite", &mut |x| no_out!(x.next_lower()))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/float/basic/precision.rs000064400000000000000000000032461046102023000254070ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::bench::bucketers::primitive_float_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::primitive_float_gen_var_12; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_primitive_float_demos!(runner, demo_precision); register_primitive_float_benches!(runner, benchmark_precision); } fn demo_precision(gm: GenMode, config: &GenConfig, limit: usize) { for x in primitive_float_gen_var_12::() .get(gm, config) .take(limit) { println!("({}).precision() = {}", NiceFloat(x), x.precision()); } } fn benchmark_precision( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.precision()", T::NAME), BenchmarkType::Single, primitive_float_gen_var_12::().get(gm, config), gm.name(), limit, file_name, &primitive_float_bucketer("f"), &mut [("Malachite", &mut |x| no_out!(x.precision()))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/float/basic/to_ordered_representation.rs000064400000000000000000000035401046102023000306610ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::bench::bucketers::primitive_float_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::primitive_float_gen_var_11; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_primitive_float_demos!(runner, demo_to_ordered_representation); register_primitive_float_benches!(runner, benchmark_to_ordered_representation); } fn demo_to_ordered_representation( gm: GenMode, config: &GenConfig, limit: usize, ) { for x in primitive_float_gen_var_11::() .get(gm, config) .take(limit) { println!( "to_ordered_representation({}) = {}", NiceFloat(x), x.to_ordered_representation() ); } } fn benchmark_to_ordered_representation( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.to_ordered_representation()", T::NAME), BenchmarkType::Single, primitive_float_gen_var_11::().get(gm, config), gm.name(), limit, file_name, &primitive_float_bucketer("f"), &mut [("Malachite", &mut |x| no_out!(x.to_ordered_representation()))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/float/mod.rs000064400000000000000000000010631046102023000231050ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { basic::register(runner); nice_float::register(runner); } mod basic; mod nice_float; malachite-base-0.4.16/src/bin_util/demo_and_bench/num/float/nice_float/cmp.rs000064400000000000000000000041301046102023000252060ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::bench::bucketers::pair_max_primitive_float_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::primitive_float_pair_gen; use malachite_base::test_util::runner::Runner; use std::cmp::Ordering::*; pub(crate) fn register(runner: &mut Runner) { register_primitive_float_demos!(runner, demo_nice_float_cmp); register_primitive_float_benches!(runner, benchmark_nice_float_cmp_algorithms); } fn demo_nice_float_cmp(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in primitive_float_pair_gen::().get(gm, config).take(limit) { let x = NiceFloat(x); let y = NiceFloat(y); match x.cmp(&y) { Less => println!("{x} < {y}"), Equal => println!("{x} = {y}"), Greater => println!("{x} > {y}"), } } } #[allow(unused_must_use)] fn benchmark_nice_float_cmp_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("NiceFloat<{}>.cmp(&NiceFloat<{}>)", T::NAME, T::NAME), BenchmarkType::Algorithms, primitive_float_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_max_primitive_float_bucketer("f", "g"), &mut [ ("Malachite", &mut |(x, y)| { no_out!(NiceFloat(x).cmp(&NiceFloat(y))) }), ("Rust default", &mut |(x, y)| no_out!(x.partial_cmp(&y))), ], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/float/nice_float/eq.rs000064400000000000000000000040111046102023000250320ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::bench::bucketers::pair_max_primitive_float_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::primitive_float_pair_gen; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_primitive_float_demos!(runner, demo_nice_float_eq); register_primitive_float_benches!(runner, benchmark_nice_float_eq_algorithms); } fn demo_nice_float_eq(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in primitive_float_pair_gen::().get(gm, config).take(limit) { let x = NiceFloat(x); let y = NiceFloat(y); if x == y { println!("{x} = {y}"); } else { println!("{x} ≠ {y}"); } } } #[allow(clippy::no_effect, unused_must_use)] fn benchmark_nice_float_eq_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("NiceFloat<{}> == NiceFloat<{}>", T::NAME, T::NAME), BenchmarkType::Algorithms, primitive_float_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_max_primitive_float_bucketer("f", "g"), &mut [ ("Malachite", &mut |(x, y)| { no_out!(NiceFloat(x) == NiceFloat(y)) }), ("Rust default", &mut |(x, y)| no_out!(x == y)), ], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/float/nice_float/from_str.rs000064400000000000000000000044121046102023000262650ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::bench::bucketers::string_len_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{string_gen, string_gen_var_10}; use malachite_base::test_util::runner::Runner; use std::fmt::Debug; use std::str::FromStr; pub(crate) fn register(runner: &mut Runner) { register_primitive_float_demos!(runner, demo_nice_float_from_str); register_primitive_float_demos!(runner, demo_nice_float_from_str_targeted); register_primitive_float_benches!(runner, benchmark_nice_float_from_str); } fn demo_nice_float_from_str(gm: GenMode, config: &GenConfig, limit: usize) where ::Err: Debug, { for s in string_gen().get(gm, config).take(limit) { println!( "NiceFloat::from_str({:?}) = {:?}", s, NiceFloat::::from_str(&s) ); } } fn demo_nice_float_from_str_targeted( gm: GenMode, config: &GenConfig, limit: usize, ) where ::Err: Debug, { for s in string_gen_var_10().get(gm, config).take(limit) { println!( "NiceFloat::from_str({:?}) = {:?}", s, NiceFloat::::from_str(&s) ); } } #[allow(unused_must_use)] fn benchmark_nice_float_from_str( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("NiceFloat::<{}>::from_str(&str)", T::NAME), BenchmarkType::Single, string_gen().get(gm, config), gm.name(), limit, file_name, &string_len_bucketer(), &mut [("Malachite", &mut |s| no_out!(NiceFloat::::from_str(&s)))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/float/nice_float/hash.rs000064400000000000000000000033221046102023000253540ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::bench::bucketers::primitive_float_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::primitive_float_gen; use malachite_base::test_util::hash::hash; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_primitive_float_demos!(runner, demo_nice_float_hash); register_primitive_float_benches!(runner, benchmark_nice_float_hash); } fn demo_nice_float_hash(gm: GenMode, config: &GenConfig, limit: usize) { for x in primitive_float_gen::().get(gm, config).take(limit) { let x = NiceFloat(x); println!("hash({}) = {}", x, hash(&x)); } } fn benchmark_nice_float_hash( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("hash(&NiceFloat<{}>())", T::NAME), BenchmarkType::Single, primitive_float_gen::().get(gm, config), gm.name(), limit, file_name, &primitive_float_bucketer("f"), &mut [("Malachite", &mut |x| no_out!(hash(&NiceFloat(x))))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/float/nice_float/mod.rs000064400000000000000000000012431046102023000252100ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { cmp::register(runner); eq::register(runner); from_str::register(runner); hash::register(runner); to_string::register(runner); } mod cmp; mod eq; mod from_str; mod hash; mod to_string; malachite-base-0.4.16/src/bin_util/demo_and_bench/num/float/nice_float/to_string.rs000064400000000000000000000034151046102023000264440ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::bench::bucketers::primitive_float_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::primitive_float_gen; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_primitive_float_demos!(runner, demo_nice_float_to_string); register_primitive_float_benches!(runner, benchmark_nice_float_to_string_algorithms); } fn demo_nice_float_to_string(gm: GenMode, config: &GenConfig, limit: usize) { for f in primitive_float_gen::().get(gm, config).take(limit) { println!("{}", NiceFloat(f)); } } fn benchmark_nice_float_to_string_algorithms( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("NiceFloat::<{}>.to_string()", T::NAME), BenchmarkType::Algorithms, primitive_float_gen::().get(gm, config), gm.name(), limit, file_name, &primitive_float_bucketer("f"), &mut [ ("Malachite", &mut |f| no_out!(NiceFloat(f).to_string())), ("Rust default", &mut |f| no_out!(f.to_string())), ], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/logic/bit_access/assign_bit.rs000064400000000000000000000056311046102023000265440ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::triple_2_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ signed_unsigned_bool_triple_gen_var_1, unsigned_unsigned_bool_triple_gen_var_1, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_assign_bit_unsigned); register_signed_demos!(runner, demo_assign_bit_signed); register_unsigned_benches!(runner, benchmark_assign_bit_unsigned); register_signed_benches!(runner, benchmark_assign_bit_signed); } fn demo_assign_bit_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for (mut n, index, bit) in unsigned_unsigned_bool_triple_gen_var_1::() .get(gm, config) .take(limit) { let n_old = n; n.assign_bit(index, bit); println!("x := {n_old}; x.assign_bit({index}, {bit}); x = {n}"); } } fn demo_assign_bit_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (mut n, index, bit) in signed_unsigned_bool_triple_gen_var_1::() .get(gm, config) .take(limit) { let n_old = n; n.assign_bit(index, bit); println!("x := {n_old}; x.assign_bit({index}, {bit}); x = {n}"); } } fn benchmark_assign_bit_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.assign_bit(u64, bool)", T::NAME), BenchmarkType::Single, unsigned_unsigned_bool_triple_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &triple_2_bucketer("index"), &mut [("Malachite", &mut |(mut n, index, bit)| { n.assign_bit(index, bit) })], ); } fn benchmark_assign_bit_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.assign_bit(u64, bool)", T::NAME), BenchmarkType::Single, signed_unsigned_bool_triple_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &triple_2_bucketer("index"), &mut [("Malachite", &mut |(mut n, index, bit)| { n.assign_bit(index, bit) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/logic/bit_access/clear_bit.rs000064400000000000000000000053261046102023000263470ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::pair_2_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ signed_unsigned_pair_gen_var_4, unsigned_pair_gen_var_2, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_clear_bit_unsigned); register_signed_demos!(runner, demo_clear_bit_signed); register_unsigned_benches!(runner, benchmark_clear_bit_unsigned); register_signed_benches!(runner, benchmark_clear_bit_signed); } fn demo_clear_bit_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for (mut n, index) in unsigned_pair_gen_var_2::() .get(gm, config) .take(limit) { let n_old = n; n.clear_bit(index); println!("x := {n_old}; x.clear_bit({index}); x = {n}"); } } fn demo_clear_bit_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (mut n, index) in signed_unsigned_pair_gen_var_4::() .get(gm, config) .take(limit) { let n_old = n; n.clear_bit(index); println!("x := {n_old}; x.clear_bit({index}); x = {n}"); } } fn benchmark_clear_bit_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.clear_bit(u64)", T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &pair_2_bucketer("index"), &mut [("Malachite", &mut |(mut n, index)| n.clear_bit(index))], ); } fn benchmark_clear_bit_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.clear_bit(u64)", T::NAME), BenchmarkType::Single, signed_unsigned_pair_gen_var_4::().get(gm, config), gm.name(), limit, file_name, &pair_2_bucketer("index"), &mut [("Malachite", &mut |(mut n, index)| n.clear_bit(index))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/logic/bit_access/flip_bit.rs000064400000000000000000000052461046102023000262140ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::pair_2_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ signed_unsigned_pair_gen_var_2, unsigned_pair_gen_var_3, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_flip_bit_unsigned); register_signed_demos!(runner, demo_flip_bit_signed); register_unsigned_benches!(runner, benchmark_flip_bit_unsigned); register_signed_benches!(runner, benchmark_flip_bit_signed); } fn demo_flip_bit_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for (mut n, index) in unsigned_pair_gen_var_3::().get(gm, config).take(limit) { let n_old = n; n.flip_bit(index); println!("x := {n_old}; x.flip_bit({index}); x = {n}"); } } fn demo_flip_bit_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (mut n, index) in signed_unsigned_pair_gen_var_2::() .get(gm, config) .take(limit) { let n_old = n; n.flip_bit(index); println!("x := {n_old}; x.flip_bit({index}); x = {n}"); } } fn benchmark_flip_bit_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.flip_bit(u64)", T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_3::().get(gm, config), gm.name(), limit, file_name, &pair_2_bucketer("index"), &mut [("Malachite", &mut |(mut n, index)| n.flip_bit(index))], ); } fn benchmark_flip_bit_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.flip_bit(u64)", T::NAME), BenchmarkType::Single, signed_unsigned_pair_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &pair_2_bucketer("index"), &mut [("Malachite", &mut |(mut n, index)| n.flip_bit(index))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/logic/bit_access/get_bit.rs000064400000000000000000000051461046102023000260400ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::pair_2_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ signed_unsigned_pair_gen_var_1, unsigned_pair_gen_var_2, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_get_bit_unsigned); register_signed_demos!(runner, demo_get_bit_signed); register_unsigned_benches!(runner, benchmark_get_bit_unsigned); register_signed_benches!(runner, benchmark_get_bit_signed); } fn demo_get_bit_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for (n, index) in unsigned_pair_gen_var_2::() .get(gm, config) .take(limit) { println!("get_bit({}, {}) = {}", n, index, n.get_bit(index)); } } fn demo_get_bit_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (n, index) in signed_unsigned_pair_gen_var_1::() .get(gm, config) .take(limit) { println!("get_bit({}, {}) = {}", n, index, n.get_bit(index)); } } fn benchmark_get_bit_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.get_bit(u64)", T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &pair_2_bucketer("index"), &mut [("Malachite", &mut |(n, index)| no_out!(n.get_bit(index)))], ); } fn benchmark_get_bit_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.get_bit(u64)", T::NAME), BenchmarkType::Single, signed_unsigned_pair_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &pair_2_bucketer("index"), &mut [("Malachite", &mut |(n, index)| no_out!(n.get_bit(index)))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/logic/bit_access/mod.rs000064400000000000000000000013011046102023000251670ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { assign_bit::register(runner); clear_bit::register(runner); flip_bit::register(runner); get_bit::register(runner); set_bit::register(runner); } mod assign_bit; mod clear_bit; mod flip_bit; mod get_bit; mod set_bit; malachite-base-0.4.16/src/bin_util/demo_and_bench/num/logic/bit_access/set_bit.rs000064400000000000000000000052261046102023000260530ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::pair_2_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ signed_unsigned_pair_gen_var_3, unsigned_pair_gen_var_3, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_set_bit_unsigned); register_signed_demos!(runner, demo_set_bit_signed); register_unsigned_benches!(runner, benchmark_set_bit_unsigned); register_signed_benches!(runner, benchmark_set_bit_signed); } fn demo_set_bit_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for (mut n, index) in unsigned_pair_gen_var_3::().get(gm, config).take(limit) { let n_old = n; n.set_bit(index); println!("x := {n_old}; x.set_bit({index}); x = {n}"); } } fn demo_set_bit_signed(gm: GenMode, config: &GenConfig, limit: usize) { for (mut n, index) in signed_unsigned_pair_gen_var_3::() .get(gm, config) .take(limit) { let n_old = n; n.set_bit(index); println!("x := {n_old}; x.set_bit({index}); x = {n}"); } } fn benchmark_set_bit_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.set_bit(u64)", T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_3::().get(gm, config), gm.name(), limit, file_name, &pair_2_bucketer("index"), &mut [("Malachite", &mut |(mut n, index)| n.set_bit(index))], ); } fn benchmark_set_bit_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.set_bit(u64)", T::NAME), BenchmarkType::Single, signed_unsigned_pair_gen_var_3::().get(gm, config), gm.name(), limit, file_name, &pair_2_bucketer("index"), &mut [("Malachite", &mut |(mut n, index)| n.set_bit(index))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/logic/bit_block_access/assign_bits.rs000064400000000000000000000077561046102023000301130ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::UnsignedAbs; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::logic::traits::BitBlockAccess; use malachite_base::test_util::bench::bucketers::assign_bits_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ signed_unsigned_unsigned_unsigned_quadruple_gen_var_1, unsigned_quadruple_gen_var_1, }; use malachite_base::test_util::num::logic::bit_block_access::assign_bits_naive; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_assign_bits_unsigned); register_signed_unsigned_match_demos!(runner, demo_assign_bits_signed); register_unsigned_benches!(runner, benchmark_assign_bits_algorithms_unsigned); register_signed_unsigned_match_benches!(runner, benchmark_assign_bits_algorithms_signed); } fn demo_assign_bits_unsigned(gm: GenMode, config: &GenConfig, limit: usize) where T::Bits: PrimitiveUnsigned, { for (mut n, start, end, bits) in unsigned_quadruple_gen_var_1::() .get(gm, config) .take(limit) { let old_n = n; n.assign_bits(start, end, &bits); println!("n := {old_n}; n.assign_bits({start}, {end}, &{bits}); n = {n}"); } } fn demo_assign_bits_signed< T: BitBlockAccess + PrimitiveSigned + UnsignedAbs, U: BitBlockAccess + PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, ) { for (mut n, start, end, bits) in signed_unsigned_unsigned_unsigned_quadruple_gen_var_1::() .get(gm, config) .take(limit) { let old_n = n; n.assign_bits(start, end, &bits); println!("n := {old_n}; n.assign_bits({start}, {end}, &{bits}); n = {n}"); } } fn benchmark_assign_bits_algorithms_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where T::Bits: PrimitiveUnsigned, { run_benchmark( &format!("{}.assign_bits(u64, u64, {})", T::NAME, T::NAME), BenchmarkType::Algorithms, unsigned_quadruple_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &assign_bits_bucketer(), &mut [ ("default", &mut |(mut n, start, end, bits)| { no_out!(n.assign_bits(start, end, &bits)) }), ("naive", &mut |(mut n, start, end, bits)| { no_out!(assign_bits_naive::(&mut n, start, end, &bits)) }), ], ); } fn benchmark_assign_bits_algorithms_signed< T: BitBlockAccess + PrimitiveSigned + UnsignedAbs, U: BitBlockAccess + PrimitiveUnsigned, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.assign_bits(u64, u64, {})", T::NAME, U::NAME), BenchmarkType::Algorithms, signed_unsigned_unsigned_unsigned_quadruple_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &assign_bits_bucketer(), &mut [ ("default", &mut |(mut n, start, end, bits)| { no_out!(n.assign_bits(start, end, &bits)) }), ("naive", &mut |(mut n, start, end, bits)| { no_out!(assign_bits_naive::(&mut n, start, end, &bits)) }), ], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/logic/bit_block_access/get_bits.rs000064400000000000000000000073261046102023000273770ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::WrappingFrom; use malachite_base::num::logic::traits::BitBlockAccess; use malachite_base::test_util::bench::bucketers::get_bits_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ signed_unsigned_unsigned_triple_gen_var_2, unsigned_triple_gen_var_5, }; use malachite_base::test_util::num::logic::bit_block_access::get_bits_naive; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_get_bits_unsigned); register_unsigned_signed_match_demos!(runner, demo_get_bits_signed); register_unsigned_benches!(runner, benchmark_get_bits_algorithms_unsigned); register_unsigned_signed_match_benches!(runner, benchmark_get_bits_algorithms_signed); } fn demo_get_bits_unsigned + PrimitiveUnsigned>( gm: GenMode, config: &GenConfig, limit: usize, ) { for (n, start, end) in unsigned_triple_gen_var_5::() .get(gm, config) .take(limit) { println!( "{}.get_bits({}, {}) = {}", n, start, end, n.get_bits(start, end) ); } } fn demo_get_bits_signed< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >( gm: GenMode, config: &GenConfig, limit: usize, ) where S::Bits: PrimitiveUnsigned, { for (n, start, end) in signed_unsigned_unsigned_triple_gen_var_2::() .get(gm, config) .take(limit) { println!( "({}).get_bits({}, {}) = {}", n, start, end, n.get_bits(start, end) ); } } fn benchmark_get_bits_algorithms_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.get_bits(u64, u64)", T::NAME), BenchmarkType::Algorithms, unsigned_triple_gen_var_5::().get(gm, config), gm.name(), limit, file_name, &get_bits_bucketer(), &mut [ ("default", &mut |(n, start, end)| { no_out!(n.get_bits(start, end)) }), ("naive", &mut |(n, start, end)| { no_out!(get_bits_naive::(&n, start, end)) }), ], ); } fn benchmark_get_bits_algorithms_signed< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.get_bits(u64, u64)", S::NAME), BenchmarkType::Algorithms, signed_unsigned_unsigned_triple_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &get_bits_bucketer(), &mut [ ("default", &mut |(n, start, end)| { no_out!(n.get_bits(start, end)) }), ("naive", &mut |(n, start, end)| { no_out!(get_bits_naive::(&n, start, end)) }), ], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/logic/bit_block_access/mod.rs000064400000000000000000000010731046102023000263470ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { assign_bits::register(runner); get_bits::register(runner); } mod assign_bits; mod get_bits; malachite-base-0.4.16/src/bin_util/demo_and_bench/num/logic/bit_convertible/from_bits.rs000064400000000000000000000137571046102023000274710ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::vec_len_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ bool_vec_gen_var_1, bool_vec_gen_var_2, bool_vec_gen_var_3, bool_vec_gen_var_4, }; use malachite_base::test_util::num::logic::bit_convertible::{ from_bits_asc_alt, from_bits_asc_signed_naive, from_bits_asc_unsigned_naive, from_bits_desc_alt, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_from_bits_asc_unsigned); register_signed_demos!(runner, demo_from_bits_asc_signed); register_unsigned_demos!(runner, demo_from_bits_desc_unsigned); register_signed_demos!(runner, demo_from_bits_desc_signed); register_unsigned_benches!(runner, benchmark_from_bits_asc_algorithms_unsigned); register_signed_benches!(runner, benchmark_from_bits_asc_algorithms_signed); register_unsigned_benches!(runner, benchmark_from_bits_desc_algorithms_unsigned); register_signed_benches!(runner, benchmark_from_bits_desc_algorithms_signed); } fn demo_from_bits_asc_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for bs in bool_vec_gen_var_1::().get(gm, config).take(limit) { println!( "{}::from_bits_asc({:?}) = {}", T::NAME, bs, T::from_bits_asc(bs.iter().cloned()) ); } } fn demo_from_bits_asc_signed(gm: GenMode, config: &GenConfig, limit: usize) { for bs in bool_vec_gen_var_2::().get(gm, config).take(limit) { println!( "{}::from_bits_asc({:?}) = {}", T::NAME, bs, T::from_bits_asc(bs.iter().cloned()) ); } } fn demo_from_bits_desc_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for bs in bool_vec_gen_var_3::().get(gm, config).take(limit) { println!( "{}::from_bits_desc({:?}) = {}", T::NAME, bs, T::from_bits_desc(bs.iter().cloned()) ); } } fn demo_from_bits_desc_signed(gm: GenMode, config: &GenConfig, limit: usize) { for bs in bool_vec_gen_var_4::().get(gm, config).take(limit) { println!( "{}::from_bits_desc({:?}) = {}", T::NAME, bs, T::from_bits_desc(bs.iter().cloned()) ); } } fn benchmark_from_bits_asc_algorithms_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}::from_bits_asc>(I)", T::NAME), BenchmarkType::Algorithms, bool_vec_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &vec_len_bucketer(), &mut [ ("default", &mut |ref bs| { no_out!(T::from_bits_asc(bs.iter().cloned())) }), ("alt", &mut |ref bs| { no_out!(from_bits_asc_alt::(bs.iter().cloned())) }), ("naive", &mut |ref bs| { no_out!(from_bits_asc_unsigned_naive::(bs.iter().cloned())) }), ], ); } fn benchmark_from_bits_asc_algorithms_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}::from_bits_asc>(I)", T::NAME), BenchmarkType::Algorithms, bool_vec_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &vec_len_bucketer(), &mut [ ("default", &mut |ref bs| { no_out!(T::from_bits_asc(bs.iter().cloned())) }), ("alt", &mut |ref bs| { no_out!(from_bits_asc_alt::(bs.iter().cloned())) }), ("naive", &mut |ref bs| { no_out!(from_bits_asc_signed_naive::(bs.iter().cloned())) }), ], ); } fn benchmark_from_bits_desc_algorithms_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}::from_bits_desc>(I)", T::NAME), BenchmarkType::Algorithms, bool_vec_gen_var_3::().get(gm, config), gm.name(), limit, file_name, &vec_len_bucketer(), &mut [ ("default", &mut |ref bs| { no_out!(T::from_bits_desc(bs.iter().cloned())) }), ("alt", &mut |ref bs| { no_out!(from_bits_desc_alt::(bs.iter().cloned())) }), ], ); } fn benchmark_from_bits_desc_algorithms_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}::from_bits_desc>(I)", T::NAME), BenchmarkType::Algorithms, bool_vec_gen_var_4::().get(gm, config), gm.name(), limit, file_name, &vec_len_bucketer(), &mut [ ("default", &mut |ref bs| { no_out!(T::from_bits_desc(bs.iter().cloned())) }), ("alt", &mut |ref bs| { no_out!(from_bits_desc_alt::(bs.iter().cloned())) }), ], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/logic/bit_convertible/mod.rs000064400000000000000000000010651046102023000262510ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { from_bits::register(runner); to_bits::register(runner); } mod from_bits; mod to_bits; malachite-base-0.4.16/src/bin_util/demo_and_bench/num/logic/bit_convertible/to_bits.rs000064400000000000000000000203161046102023000271350ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::{signed_bit_bucketer, unsigned_bit_bucketer}; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_gen, unsigned_gen}; use malachite_base::test_util::num::logic::bit_convertible::{ to_bits_asc_alt, to_bits_asc_signed_naive, to_bits_asc_unsigned_naive, to_bits_desc_alt, to_bits_desc_signed_naive, to_bits_desc_unsigned_naive, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_to_bits_asc_unsigned); register_signed_demos!(runner, demo_to_bits_asc_signed); register_unsigned_demos!(runner, demo_to_bits_desc_unsigned); register_signed_demos!(runner, demo_to_bits_desc_signed); register_unsigned_benches!(runner, benchmark_to_bits_asc_algorithms_unsigned); register_signed_benches!(runner, benchmark_to_bits_asc_algorithms_signed); register_unsigned_benches!(runner, benchmark_to_bits_asc_evaluation_strategy_unsigned); register_signed_benches!(runner, benchmark_to_bits_asc_evaluation_strategy_signed); register_unsigned_benches!(runner, benchmark_to_bits_desc_algorithms_unsigned); register_signed_benches!(runner, benchmark_to_bits_desc_algorithms_signed); register_unsigned_benches!(runner, benchmark_to_bits_desc_evaluation_strategy_unsigned); register_signed_benches!(runner, benchmark_to_bits_desc_evaluation_strategy_signed); } fn demo_to_bits_asc_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for u in unsigned_gen::().get(gm, config).take(limit) { println!("{}.to_bits_asc() = {:?}", u, u.to_bits_asc()); } } fn demo_to_bits_asc_signed(gm: GenMode, config: &GenConfig, limit: usize) { for i in signed_gen::().get(gm, config).take(limit) { println!("{}.to_bits_asc() = {:?}", i, i.to_bits_asc()); } } fn demo_to_bits_desc_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for u in unsigned_gen::().get(gm, config).take(limit) { println!("{}.to_bits_desc() = {:?}", u, u.to_bits_desc()); } } fn demo_to_bits_desc_signed(gm: GenMode, config: &GenConfig, limit: usize) { for i in signed_gen::().get(gm, config).take(limit) { println!("{}.to_bits_desc() = {:?}", i, i.to_bits_desc()); } } fn benchmark_to_bits_asc_algorithms_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.to_bits_asc()", T::NAME), BenchmarkType::Algorithms, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [ ("Malachite", &mut |u| no_out!(u.to_bits_asc())), ("alt", &mut |u| no_out!(to_bits_asc_alt(&u))), ("naive", &mut |u| no_out!(to_bits_asc_unsigned_naive(u))), ], ); } fn benchmark_to_bits_asc_algorithms_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.to_bits_asc()", T::NAME), BenchmarkType::Algorithms, signed_gen::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [ ("Malachite", &mut |i| no_out!(i.to_bits_asc())), ("alt", &mut |i| no_out!(to_bits_asc_alt(&i))), ("naive", &mut |i| no_out!(to_bits_asc_signed_naive(i))), ], ); } #[allow(unused_must_use)] fn benchmark_to_bits_asc_evaluation_strategy_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.to_bits_asc()", T::NAME), BenchmarkType::EvaluationStrategy, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [ (&format!("{}.to_bits_asc()", T::NAME), &mut |n| { no_out!(n.to_bits_asc()) }), (&format!("{}.bits().collect_vec()", T::NAME), &mut |n| { no_out!(n.bits().collect_vec()) }), ], ); } #[allow(unused_must_use)] fn benchmark_to_bits_asc_evaluation_strategy_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.to_bits_asc()", T::NAME), BenchmarkType::EvaluationStrategy, signed_gen::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [ (&format!("{}.to_bits_asc()", T::NAME), &mut |n| { no_out!(n.to_bits_asc()) }), (&format!("{}.bits().collect_vec()", T::NAME), &mut |n| { no_out!(n.bits().collect_vec()) }), ], ); } fn benchmark_to_bits_desc_algorithms_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.to_bits_desc()", T::NAME), BenchmarkType::Algorithms, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [ ("Malachite", &mut |u| no_out!(u.to_bits_desc())), ("alt", &mut |u| no_out!(to_bits_desc_alt(&u))), ("naive", &mut |u| no_out!(to_bits_desc_unsigned_naive(u))), ], ); } fn benchmark_to_bits_desc_algorithms_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.to_bits_desc()", T::NAME), BenchmarkType::Algorithms, signed_gen::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [ ("Malachite", &mut |i| no_out!(i.to_bits_desc())), ("alt", &mut |i| no_out!(to_bits_desc_alt(&i))), ("naive", &mut |i| no_out!(to_bits_desc_signed_naive(i))), ], ); } #[allow(unused_must_use)] fn benchmark_to_bits_desc_evaluation_strategy_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.to_bits_desc()", T::NAME), BenchmarkType::EvaluationStrategy, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [ (&format!("{}.to_bits_desc()", T::NAME), &mut |n| { no_out!(n.to_bits_desc()) }), ( &format!("{}.bits().rev().collect_vec()", T::NAME), &mut |n| no_out!(n.bits().rev().collect_vec()), ), ], ); } #[allow(unused_must_use)] fn benchmark_to_bits_desc_evaluation_strategy_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.to_bits_desc()", T::NAME), BenchmarkType::EvaluationStrategy, signed_gen::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [ (&format!("{}.to_bits_desc()", T::NAME), &mut |n| { no_out!(n.to_bits_desc()) }), ( &format!("{}.bits().rev().collect_vec()", T::NAME), &mut |n| no_out!(n.bits().rev().collect_vec()), ), ], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/logic/bit_iterable.rs000064400000000000000000000127741046102023000247560ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::ExactFrom; use malachite_base::test_util::bench::bucketers::{pair_1_bit_bucketer, unsigned_bit_bucketer}; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ signed_gen, signed_unsigned_pair_gen_var_1, unsigned_gen, unsigned_pair_gen_var_2, }; use malachite_base::test_util::runner::Runner; use std::ops::Index; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_bits_unsigned); register_signed_demos!(runner, demo_bits_signed); register_unsigned_demos!(runner, demo_bits_rev_unsigned); register_signed_demos!(runner, demo_bits_rev_signed); register_unsigned_demos!(runner, demo_bits_size_hint_unsigned); register_signed_demos!(runner, demo_bits_index_signed); register_unsigned_benches!(runner, benchmark_bits_size_hint_unsigned); register_unsigned_benches!(runner, benchmark_bits_get_algorithms_unsigned); register_signed_benches!(runner, benchmark_bits_get_algorithms_signed); } fn demo_bits_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for u in unsigned_gen::().get(gm, config).take(limit) { println!("bits({}) = {:?}", u, u.bits().collect_vec()); } } fn demo_bits_signed(gm: GenMode, config: &GenConfig, limit: usize) { for i in signed_gen::().get(gm, config).take(limit) { println!("bits({}) = {:?}", i, i.bits().collect_vec()); } } fn demo_bits_rev_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for u in unsigned_gen::().get(gm, config).take(limit) { println!("bits({}).rev() = {:?}", u, u.bits().rev().collect_vec()); } } fn demo_bits_rev_signed(gm: GenMode, config: &GenConfig, limit: usize) { for i in signed_gen::().get(gm, config).take(limit) { println!("bits({}).rev() = {:?}", i, i.bits().rev().collect_vec()); } } fn demo_bits_size_hint_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for u in unsigned_gen::().get(gm, config).take(limit) { println!("bits({}).size_hint() = {:?}", u, u.bits().size_hint()); } } fn demo_bits_index_signed(gm: GenMode, config: &GenConfig, limit: usize) where T::BitIterator: Index, { for (n, i) in signed_unsigned_pair_gen_var_1::() .get(gm, config) .take(limit) { println!("bits({})[{}] = {:?}", n, i, n.bits()[i]); } } fn benchmark_bits_size_hint_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.bits().size_hint()", T::NAME), BenchmarkType::Single, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [(&format!("{}.bits().size_hint()", T::NAME), &mut |n| { no_out!(n.bits().size_hint()) })], ); } #[allow(clippy::unnecessary_operation)] fn benchmark_bits_get_algorithms_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where T::BitIterator: Index, { run_benchmark( &format!("{}.bits()[u64]", T::NAME), BenchmarkType::Algorithms, unsigned_pair_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("n"), &mut [ (&format!("{}.bits()[u]", T::NAME), &mut |(n, u)| { no_out!(n.bits()[u]) }), (&format!("{}.to_bits_asc()[u]", T::NAME), &mut |(n, u)| { let bits = n.to_bits_asc(); let u = usize::exact_from(u); if u >= bits.len() { n < T::ZERO } else { bits[u] }; }), ], ); } #[allow(clippy::unnecessary_operation)] fn benchmark_bits_get_algorithms_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) where T::BitIterator: Index, { run_benchmark( &format!("{}.bits()[u64]", T::NAME), BenchmarkType::Algorithms, signed_unsigned_pair_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &pair_1_bit_bucketer("n"), &mut [ (&format!("{}.bits()[u]", T::NAME), &mut |(n, u)| { no_out!(n.bits()[u]) }), (&format!("{}.to_bits_asc()[u]", T::NAME), &mut |(n, u)| { let bits = n.to_bits_asc(); let u = usize::exact_from(u); if u >= bits.len() { n < T::ZERO } else { bits[u] }; }), ], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/logic/bit_scan/index_of_next_false_bit.rs000064400000000000000000000060621046102023000307450ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::pair_2_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ signed_unsigned_pair_gen_var_1, unsigned_pair_gen_var_2, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_index_of_next_false_bit_unsigned); register_signed_demos!(runner, demo_index_of_next_false_bit_signed); register_unsigned_benches!(runner, benchmark_index_of_next_false_bit_unsigned); register_signed_benches!(runner, benchmark_index_of_next_false_bit_signed); } fn demo_index_of_next_false_bit_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (n, start) in unsigned_pair_gen_var_2::() .get(gm, config) .take(limit) { println!( "{}.index_of_next_false_bit({}) = {:?}", n, start, n.index_of_next_false_bit(start) ); } } fn demo_index_of_next_false_bit_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for (n, start) in signed_unsigned_pair_gen_var_1::() .get(gm, config) .take(limit) { println!( "{}.index_of_next_false_bit({}) = {:?}", n, start, n.index_of_next_false_bit(start) ); } } fn benchmark_index_of_next_false_bit_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.index_of_next_false_bit(u64)", T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &pair_2_bucketer("start"), &mut [("Malachite", &mut |(n, start)| { no_out!(n.index_of_next_false_bit(start)) })], ); } fn benchmark_index_of_next_false_bit_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.index_of_next_false_bit(u64)", T::NAME), BenchmarkType::Single, signed_unsigned_pair_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &pair_2_bucketer("index"), &mut [("Malachite", &mut |(n, start)| { no_out!(n.index_of_next_false_bit(start)) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/logic/bit_scan/index_of_next_true_bit.rs000064400000000000000000000060421046102023000306300ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::pair_2_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ signed_unsigned_pair_gen_var_1, unsigned_pair_gen_var_2, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_index_of_next_true_bit_unsigned); register_signed_demos!(runner, demo_index_of_next_true_bit_signed); register_unsigned_benches!(runner, benchmark_index_of_next_true_bit_unsigned); register_signed_benches!(runner, benchmark_index_of_next_true_bit_signed); } fn demo_index_of_next_true_bit_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (n, start) in unsigned_pair_gen_var_2::() .get(gm, config) .take(limit) { println!( "{}.index_of_next_true_bit({}) = {:?}", n, start, n.index_of_next_true_bit(start) ); } } fn demo_index_of_next_true_bit_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for (n, start) in signed_unsigned_pair_gen_var_1::() .get(gm, config) .take(limit) { println!( "{}.index_of_next_true_bit({}) = {:?}", n, start, n.index_of_next_true_bit(start) ); } } fn benchmark_index_of_next_true_bit_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.index_of_next_true_bit(u64)", T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &pair_2_bucketer("start"), &mut [("Malachite", &mut |(n, start)| { no_out!(n.index_of_next_true_bit(start)) })], ); } fn benchmark_index_of_next_true_bit_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.index_of_next_true_bit(u64)", T::NAME), BenchmarkType::Single, signed_unsigned_pair_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &pair_2_bucketer("index"), &mut [("Malachite", &mut |(n, start)| { no_out!(n.index_of_next_true_bit(start)) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/logic/bit_scan/mod.rs000064400000000000000000000011571046102023000246630ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { index_of_next_false_bit::register(runner); index_of_next_true_bit::register(runner); } mod index_of_next_false_bit; mod index_of_next_true_bit; malachite-base-0.4.16/src/bin_util/demo_and_bench/num/logic/get_highest_bit.rs000064400000000000000000000027211046102023000254500ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::{signed_bit_bucketer, unsigned_bit_bucketer}; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_gen, unsigned_gen}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_get_highest_bit_unsigned); register_signed_demos!(runner, demo_get_highest_bit_signed); register_unsigned_benches!(runner, benchmark_get_highest_bit_unsigned); register_signed_benches!(runner, benchmark_get_highest_bit_signed); } unsigned_single_arg_demo!(demo_get_highest_bit_unsigned, get_highest_bit); signed_single_arg_demo!(demo_get_highest_bit_signed, get_highest_bit); unsigned_single_arg_bench!(benchmark_get_highest_bit_unsigned, get_highest_bit); signed_single_arg_bench!(benchmark_get_highest_bit_signed, get_highest_bit); malachite-base-0.4.16/src/bin_util/demo_and_bench/num/logic/hamming_distance.rs000064400000000000000000000054731046102023000256210ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::pair_max_bit_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_pair_gen, unsigned_pair_gen_var_27}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_hamming_distance_unsigned); register_signed_demos!(runner, demo_checked_hamming_distance_signed); register_unsigned_benches!(runner, benchmark_hamming_distance_unsigned); register_signed_benches!(runner, benchmark_checked_hamming_distance_signed); } fn demo_hamming_distance_unsigned( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, y) in unsigned_pair_gen_var_27::().get(gm, config).take(limit) { println!("{}.hamming_distance({}) = {}", x, y, x.hamming_distance(y)); } } fn demo_checked_hamming_distance_signed( gm: GenMode, config: &GenConfig, limit: usize, ) { for (x, y) in signed_pair_gen::().get(gm, config).take(limit) { println!( "({}).checked_hamming_distance({}) = {:?}", x, y, x.checked_hamming_distance(y) ); } } fn benchmark_hamming_distance_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.hamming_distance({})", T::NAME, T::NAME), BenchmarkType::Single, unsigned_pair_gen_var_27::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| no_out!(x.hamming_distance(y)))], ); } fn benchmark_checked_hamming_distance_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.checked_hamming_distance({})", T::NAME, T::NAME), BenchmarkType::Single, signed_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_max_bit_bucketer("x", "y"), &mut [("Malachite", &mut |(x, y)| { no_out!(x.checked_hamming_distance(y)) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/logic/low_mask.rs000064400000000000000000000031311046102023000241300ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::test_util::bench::bucketers::primitive_int_direct_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_gen_var_9; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_primitive_int_demos!(runner, demo_low_mask); register_primitive_int_benches!(runner, benchmark_low_mask); } fn demo_low_mask(gm: GenMode, config: &GenConfig, limit: usize) { for bits in unsigned_gen_var_9::().get(gm, config).take(limit) { println!("{}::low_mask({}) = {}", T::NAME, bits, T::low_mask(bits)); } } fn benchmark_low_mask( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.low_mask(u64)", T::NAME), BenchmarkType::Single, unsigned_gen_var_9::().get(gm, config), gm.name(), limit, file_name, &primitive_int_direct_bucketer(), &mut [("Malachite", &mut |bits| no_out!(T::low_mask(bits)))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/logic/mod.rs000064400000000000000000000020011046102023000230660ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { bit_access::register(runner); bit_block_access::register(runner); bit_convertible::register(runner); bit_iterable::register(runner); bit_scan::register(runner); get_highest_bit::register(runner); hamming_distance::register(runner); low_mask::register(runner); not_assign::register(runner); significant_bits::register(runner); } mod bit_access; mod bit_block_access; mod bit_convertible; mod bit_iterable; mod bit_scan; mod get_highest_bit; mod hamming_distance; mod low_mask; mod not_assign; mod significant_bits; malachite-base-0.4.16/src/bin_util/demo_and_bench/num/logic/not_assign.rs000064400000000000000000000050311046102023000244610ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::{signed_bit_bucketer, unsigned_bit_bucketer}; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_gen, unsigned_gen}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_not_assign_unsigned); register_signed_demos!(runner, demo_not_assign_signed); register_unsigned_benches!(runner, benchmark_not_assign_unsigned); register_signed_benches!(runner, benchmark_not_assign_signed); } fn demo_not_assign_unsigned(gm: GenMode, config: &GenConfig, limit: usize) { for mut u in unsigned_gen::().get(gm, config).take(limit) { let old_u = u; u.not_assign(); println!("u := {old_u}; u.not_assign(); u = {u}"); } } fn demo_not_assign_signed(gm: GenMode, config: &GenConfig, limit: usize) { for mut i in signed_gen::().get(gm, config).take(limit) { let old_i = i; i.not_assign(); println!("i := {old_i}; i.not_assign(); i = {i}"); } } fn benchmark_not_assign_unsigned( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.not_assign()", T::NAME), BenchmarkType::Single, unsigned_gen::().get(gm, config), gm.name(), limit, file_name, &unsigned_bit_bucketer(), &mut [("Malachite", &mut |mut u| u.not_assign())], ); } fn benchmark_not_assign_signed( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( &format!("{}.not_assign()", T::NAME), BenchmarkType::Single, signed_gen::().get(gm, config), gm.name(), limit, file_name, &signed_bit_bucketer(), &mut [("Malachite", &mut |mut i| i.not_assign())], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/num/logic/significant_bits.rs000064400000000000000000000027351046102023000256440ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::bench::bucketers::{signed_bit_bucketer, unsigned_bit_bucketer}; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{signed_gen, unsigned_gen}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_unsigned_demos!(runner, demo_significant_bits_unsigned); register_signed_demos!(runner, demo_significant_bits_signed); register_unsigned_benches!(runner, benchmark_significant_bits_unsigned); register_signed_benches!(runner, benchmark_significant_bits_signed); } unsigned_single_arg_demo!(demo_significant_bits_unsigned, significant_bits); signed_single_arg_demo!(demo_significant_bits_signed, significant_bits); unsigned_single_arg_bench!(benchmark_significant_bits_unsigned, significant_bits); signed_single_arg_bench!(benchmark_significant_bits_signed, significant_bits); malachite-base-0.4.16/src/bin_util/demo_and_bench/num/mod.rs000064400000000000000000000013671046102023000220070ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { arithmetic::register(runner); comparison::register(runner); conversion::register(runner); factorization::register(runner); float::register(runner); logic::register(runner); } mod arithmetic; mod comparison; mod conversion; mod factorization; mod float; mod logic; malachite-base-0.4.16/src/bin_util/demo_and_bench/rational_sequences/access/get.rs000064400000000000000000000051351046102023000263320ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::bench::bucketers::pair_1_rational_sequence_len_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ unsigned_rational_sequence_unsigned_pair_gen_var_1, unsigned_rational_sequence_unsigned_pair_gen_var_2, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_rational_sequence_get); register_demo!(runner, demo_rational_sequence_index); register_bench!(runner, benchmark_rational_sequence_get); register_bench!(runner, benchmark_rational_sequence_index); } fn demo_rational_sequence_get(gm: GenMode, config: &GenConfig, limit: usize) { for (xs, index) in unsigned_rational_sequence_unsigned_pair_gen_var_1::() .get(gm, config) .take(limit) { println!("{}.get({}) = {:?}", xs, index, xs.get(index)); } } fn demo_rational_sequence_index(gm: GenMode, config: &GenConfig, limit: usize) { for (xs, index) in unsigned_rational_sequence_unsigned_pair_gen_var_2::() .get(gm, config) .take(limit) { println!("{}[{}] = {}", xs, index, xs[index]); } } fn benchmark_rational_sequence_get(gm: GenMode, config: &GenConfig, limit: usize, file_name: &str) { run_benchmark( "RationalSequence.get(usize)", BenchmarkType::Single, unsigned_rational_sequence_unsigned_pair_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &pair_1_rational_sequence_len_bucketer("xs"), &mut [("Malachite", &mut |(xs, index)| no_out!(xs.get(index)))], ); } #[allow(clippy::no_effect)] fn benchmark_rational_sequence_index( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( "RationalSequence[usize]", BenchmarkType::Single, unsigned_rational_sequence_unsigned_pair_gen_var_2::().get(gm, config), gm.name(), limit, file_name, &pair_1_rational_sequence_len_bucketer("xs"), &mut [("Malachite", &mut |(xs, index)| no_out!(xs[index]))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/rational_sequences/access/mod.rs000064400000000000000000000010471046102023000263300ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { get::register(runner); mutate::register(runner); } mod get; mod mutate; malachite-base-0.4.16/src/bin_util/demo_and_bench/rational_sequences/access/mutate.rs000064400000000000000000000035401046102023000270500ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::bench::bucketers::quadruple_1_rational_sequence_len_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::large_type_gen_var_22; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_rational_sequence_mutate); register_bench!(runner, benchmark_rational_sequence_mutate); } fn demo_rational_sequence_mutate(gm: GenMode, config: &GenConfig, limit: usize) { for (mut xs, index, y, z) in large_type_gen_var_22::().get(gm, config).take(limit) { let xs_old = xs.clone(); let out = xs.mutate(index, |x| { *x = y; z }); println!("xs := {xs_old}; xs.mutate({index}, |x| {{ *x = {y}; {z} }}) = {out}; xs = {xs}"); } } fn benchmark_rational_sequence_mutate( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( "RationalSequence.mutate(usize, FnOnce(&mut T) -> U)", BenchmarkType::Single, large_type_gen_var_22::().get(gm, config), gm.name(), limit, file_name, &quadruple_1_rational_sequence_len_bucketer("xs"), &mut [("Malachite", &mut |(mut xs, index, y, z)| { no_out!(xs.mutate(index, |x| { *x = y; z })) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/rational_sequences/basic/component_len.rs000064400000000000000000000031571046102023000302350ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::bench::bucketers::rational_sequence_len_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_rational_sequence_gen; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_rational_sequence_component_len); register_bench!(runner, benchmark_rational_sequence_component_len); } fn demo_rational_sequence_component_len(gm: GenMode, config: &GenConfig, limit: usize) { for xs in unsigned_rational_sequence_gen::() .get(gm, config) .take(limit) { println!("component_len({}) = {}", xs, xs.component_len()); } } fn benchmark_rational_sequence_component_len( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( "RationalSequence.component_len()", BenchmarkType::Single, unsigned_rational_sequence_gen::().get(gm, config), gm.name(), limit, file_name, &rational_sequence_len_bucketer("xs"), &mut [("Malachite", &mut |xs| no_out!(xs.component_len()))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/rational_sequences/basic/is_empty.rs000064400000000000000000000032251046102023000272220ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::bench::bucketers::rational_sequence_len_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_rational_sequence_gen; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_rational_sequence_is_empty); register_bench!(runner, benchmark_rational_sequence_is_empty); } fn demo_rational_sequence_is_empty(gm: GenMode, config: &GenConfig, limit: usize) { for xs in unsigned_rational_sequence_gen::() .get(gm, config) .take(limit) { if xs.is_empty() { println!("{xs} is empty"); } else { println!("{xs} is not empty"); } } } fn benchmark_rational_sequence_is_empty( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( "RationalSequence.is_empty()", BenchmarkType::Single, unsigned_rational_sequence_gen::().get(gm, config), gm.name(), limit, file_name, &rational_sequence_len_bucketer("xs"), &mut [("Malachite", &mut |xs| no_out!(xs.is_empty()))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/rational_sequences/basic/is_finite.rs000064400000000000000000000032361046102023000273440ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::bench::bucketers::rational_sequence_len_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_rational_sequence_gen; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_rational_sequence_is_finite); register_bench!(runner, benchmark_rational_sequence_is_finite); } fn demo_rational_sequence_is_finite(gm: GenMode, config: &GenConfig, limit: usize) { for xs in unsigned_rational_sequence_gen::() .get(gm, config) .take(limit) { if xs.is_finite() { println!("{xs} is finite"); } else { println!("{xs} is not finite"); } } } fn benchmark_rational_sequence_is_finite( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( "RationalSequence.is_finite()", BenchmarkType::Single, unsigned_rational_sequence_gen::().get(gm, config), gm.name(), limit, file_name, &rational_sequence_len_bucketer("xs"), &mut [("Malachite", &mut |xs| no_out!(xs.is_finite()))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/rational_sequences/basic/iter.rs000064400000000000000000000033411046102023000263330ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::iterators::prefix_to_string; use malachite_base::test_util::bench::bucketers::rational_sequence_len_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_rational_sequence_gen; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_rational_sequence_iter); register_bench!(runner, benchmark_rational_sequence_iter); } fn demo_rational_sequence_iter(gm: GenMode, config: &GenConfig, limit: usize) { for xs in unsigned_rational_sequence_gen::() .get(gm, config) .take(limit) { println!("{} = {}", xs, prefix_to_string(xs.iter(), 20)); } } fn benchmark_rational_sequence_iter( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( "RationalSequence.iter()", BenchmarkType::Single, unsigned_rational_sequence_gen::().get(gm, config), gm.name(), limit, file_name, &rational_sequence_len_bucketer("xs"), &mut [( "RationalSequence.iter().take(20).collect_vec()", &mut |xs| no_out!(xs.iter().take(20).collect_vec()), )], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/rational_sequences/basic/len.rs000064400000000000000000000030161046102023000261450ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::bench::bucketers::rational_sequence_len_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_rational_sequence_gen; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_rational_sequence_len); register_bench!(runner, benchmark_rational_sequence_len); } fn demo_rational_sequence_len(gm: GenMode, config: &GenConfig, limit: usize) { for xs in unsigned_rational_sequence_gen::() .get(gm, config) .take(limit) { println!("len({}) = {:?}", xs, xs.len()); } } fn benchmark_rational_sequence_len(gm: GenMode, config: &GenConfig, limit: usize, file_name: &str) { run_benchmark( "RationalSequence.len()", BenchmarkType::Single, unsigned_rational_sequence_gen::().get(gm, config), gm.name(), limit, file_name, &rational_sequence_len_bucketer("xs"), &mut [("Malachite", &mut |xs| no_out!(xs.len()))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/rational_sequences/basic/mod.rs000064400000000000000000000012711046102023000261470ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { component_len::register(runner); is_empty::register(runner); is_finite::register(runner); iter::register(runner); len::register(runner); } mod component_len; mod is_empty; mod is_finite; mod iter; mod len; malachite-base-0.4.16/src/bin_util/demo_and_bench/rational_sequences/comparison/cmp.rs000064400000000000000000000034111046102023000272360ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::bench::bucketers::pair_rational_sequence_max_len_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_rational_sequence_pair_gen; use malachite_base::test_util::runner::Runner; use std::cmp::Ordering::*; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_rational_sequence_cmp); register_bench!(runner, benchmark_rational_sequence_cmp); } fn demo_rational_sequence_cmp(gm: GenMode, config: &GenConfig, limit: usize) { for (xs, ys) in unsigned_rational_sequence_pair_gen::() .get(gm, config) .take(limit) { match xs.cmp(&ys) { Less => println!("{xs} < {ys}"), Equal => println!("{xs} = {ys}"), Greater => println!("{xs} > {ys}"), } } } #[allow(unused_must_use)] fn benchmark_rational_sequence_cmp(gm: GenMode, config: &GenConfig, limit: usize, file_name: &str) { run_benchmark( "RationalSequence.cmp(&RationalSequence)", BenchmarkType::Single, unsigned_rational_sequence_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_rational_sequence_max_len_bucketer("xs", "ys"), &mut [("Malachite", &mut |(xs, ys)| no_out!(xs.cmp(&ys)))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/rational_sequences/comparison/eq.rs000064400000000000000000000033031046102023000270640ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::bench::bucketers::pair_rational_sequence_max_len_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_rational_sequence_pair_gen; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_rational_sequence_eq); register_bench!(runner, benchmark_rational_sequence_eq); } fn demo_rational_sequence_eq(gm: GenMode, config: &GenConfig, limit: usize) { for (xs, ys) in unsigned_rational_sequence_pair_gen::() .get(gm, config) .take(limit) { if xs == ys { println!("{xs} = {ys}"); } else { println!("{xs} ≠ {ys}"); } } } #[allow(clippy::no_effect, unused_must_use)] fn benchmark_rational_sequence_eq(gm: GenMode, config: &GenConfig, limit: usize, file_name: &str) { run_benchmark( "RationalSequence == RationalSequence", BenchmarkType::Single, unsigned_rational_sequence_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_rational_sequence_max_len_bucketer("xs", "ys"), &mut [("Malachite", &mut |(xs, ys)| no_out!(xs == ys))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/rational_sequences/comparison/hash.rs000064400000000000000000000031101046102023000273760ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::bench::bucketers::rational_sequence_len_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_rational_sequence_gen; use malachite_base::test_util::hash::hash; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_rational_sequence_hash); register_bench!(runner, benchmark_rational_sequence_hash); } fn demo_rational_sequence_hash(gm: GenMode, config: &GenConfig, limit: usize) { for xs in unsigned_rational_sequence_gen::() .get(gm, config) .take(limit) { println!("hash({}) = {}", xs, hash(&xs)); } } fn benchmark_rational_sequence_hash( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( "Rational hash", BenchmarkType::Single, unsigned_rational_sequence_gen::().get(gm, config), gm.name(), limit, file_name, &rational_sequence_len_bucketer("xs"), &mut [("Malachite", &mut |xs| no_out!(hash(&xs)))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/rational_sequences/comparison/mod.rs000064400000000000000000000011051046102023000272340ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { cmp::register(runner); eq::register(runner); hash::register(runner); } mod cmp; mod eq; mod hash; malachite-base-0.4.16/src/bin_util/demo_and_bench/rational_sequences/conversion/clone.rs000064400000000000000000000052211046102023000275730ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::bench::bucketers::{ pair_rational_sequence_max_len_bucketer, rational_sequence_len_bucketer, }; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{ unsigned_rational_sequence_gen, unsigned_rational_sequence_pair_gen, }; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_rational_sequence_clone); register_demo!(runner, demo_rational_sequence_clone_from); register_bench!(runner, benchmark_rational_sequence_clone); register_bench!(runner, benchmark_rational_sequence_clone_from); } fn demo_rational_sequence_clone(gm: GenMode, config: &GenConfig, limit: usize) { for xs in unsigned_rational_sequence_gen::() .get(gm, config) .take(limit) { println!("clone({}) = {}", xs, xs.clone()); } } fn demo_rational_sequence_clone_from(gm: GenMode, config: &GenConfig, limit: usize) { for (mut xs, ys) in unsigned_rational_sequence_pair_gen::() .get(gm, config) .take(limit) { let xs_old = xs.clone(); xs.clone_from(&ys); println!("xs := {xs_old}; xs.clone_from({ys}); xs = {xs}"); } } #[allow(clippy::redundant_clone, unused_must_use)] fn benchmark_rational_sequence_clone( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( "RationalSequence.clone()", BenchmarkType::Single, unsigned_rational_sequence_gen::().get(gm, config), gm.name(), limit, file_name, &rational_sequence_len_bucketer("xs"), &mut [("Malachite", &mut |xs| no_out!(xs.clone()))], ); } fn benchmark_rational_sequence_clone_from( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( "RationalSequence.clone_from(&RationalSequence)", BenchmarkType::Single, unsigned_rational_sequence_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_rational_sequence_max_len_bucketer("xs", "ys"), &mut [("Malachite", &mut |(mut xs, ys)| xs.clone_from(&ys))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/rational_sequences/conversion/from_vec.rs000064400000000000000000000043311046102023000302740ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::rational_sequences::RationalSequence; use malachite_base::test_util::bench::bucketers::vec_len_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_vec_gen; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_rational_sequence_from_vec); register_demo!(runner, demo_rational_sequence_from_slice); register_bench!( runner, benchmark_rational_sequence_from_vec_evaluation_strategy ); } fn demo_rational_sequence_from_vec(gm: GenMode, config: &GenConfig, limit: usize) { for xs in unsigned_vec_gen::().get(gm, config).take(limit) { println!( "from_vec({:?}) = {}", xs.clone(), RationalSequence::from_vec(xs) ); } } fn demo_rational_sequence_from_slice(gm: GenMode, config: &GenConfig, limit: usize) { for xs in unsigned_vec_gen::().get(gm, config).take(limit) { println!( "from_slice(&{:?}) = {}", xs, RationalSequence::from_slice(&xs) ); } } fn benchmark_rational_sequence_from_vec_evaluation_strategy( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( "RationalSequence::from_vec(Vec)", BenchmarkType::EvaluationStrategy, unsigned_vec_gen::().get(gm, config), gm.name(), limit, file_name, &vec_len_bucketer(), &mut [ ("from_vec", &mut |xs| { no_out!(RationalSequence::from_vec(xs)) }), ("from_slice", &mut |xs| { no_out!(RationalSequence::from_slice(&xs)) }), ], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/rational_sequences/conversion/from_vecs.rs000064400000000000000000000045771046102023000304730ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::rational_sequences::RationalSequence; use malachite_base::test_util::bench::bucketers::pair_sum_vec_len_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_vec_pair_gen; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_rational_sequence_from_vecs); register_demo!(runner, demo_rational_sequence_from_slices); register_bench!( runner, benchmark_rational_sequence_from_vecs_evaluation_strategy ); } fn demo_rational_sequence_from_vecs(gm: GenMode, config: &GenConfig, limit: usize) { for (xs, ys) in unsigned_vec_pair_gen::().get(gm, config).take(limit) { println!( "from_vecs({:?}, {:?}) = {}", xs.clone(), ys.clone(), RationalSequence::from_vecs(xs, ys) ); } } fn demo_rational_sequence_from_slices(gm: GenMode, config: &GenConfig, limit: usize) { for (xs, ys) in unsigned_vec_pair_gen::().get(gm, config).take(limit) { println!( "from_slices(&{:?}, &{:?}) = {}", xs, ys, RationalSequence::from_slices(&xs, &ys) ); } } fn benchmark_rational_sequence_from_vecs_evaluation_strategy( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( "RationalSequence::from_vecs(Vec, Vec)", BenchmarkType::EvaluationStrategy, unsigned_vec_pair_gen::().get(gm, config), gm.name(), limit, file_name, &pair_sum_vec_len_bucketer("xs", "ys"), &mut [ ("from_vecs", &mut |(xs, ys)| { no_out!(RationalSequence::from_vecs(xs, ys)) }), ("from_slices", &mut |(xs, ys)| { no_out!(RationalSequence::from_slices(&xs, &ys)) }), ], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/rational_sequences/conversion/mod.rs000064400000000000000000000012131046102023000272470ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { clone::register(runner); from_vec::register(runner); from_vecs::register(runner); to_vecs::register(runner); } mod clone; mod from_vec; mod from_vecs; mod to_vecs; malachite-base-0.4.16/src/bin_util/demo_and_bench/rational_sequences/conversion/to_vecs.rs000064400000000000000000000046631046102023000301460ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::bench::bucketers::rational_sequence_len_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_rational_sequence_gen; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_rational_sequence_to_vecs); register_demo!(runner, demo_rational_sequence_into_vecs); register_demo!(runner, demo_rational_sequence_slices_ref); register_bench!( runner, benchmark_rational_sequence_to_vecs_evaluation_strategy ); } fn demo_rational_sequence_to_vecs(gm: GenMode, config: &GenConfig, limit: usize) { for xs in unsigned_rational_sequence_gen::() .get(gm, config) .take(limit) { println!("to_vecs(&{}) = {:?}", xs, xs.to_vecs()); } } fn demo_rational_sequence_into_vecs(gm: GenMode, config: &GenConfig, limit: usize) { for xs in unsigned_rational_sequence_gen::() .get(gm, config) .take(limit) { println!("into_vecs({}) = {:?}", xs.clone(), xs.into_vecs()); } } fn demo_rational_sequence_slices_ref(gm: GenMode, config: &GenConfig, limit: usize) { for xs in unsigned_rational_sequence_gen::() .get(gm, config) .take(limit) { println!("slices_ref(&{}) = {:?}", xs, xs.slices_ref()); } } fn benchmark_rational_sequence_to_vecs_evaluation_strategy( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( "RationalSequence.to_vecs()", BenchmarkType::EvaluationStrategy, unsigned_rational_sequence_gen::().get(gm, config), gm.name(), limit, file_name, &rational_sequence_len_bucketer("xs"), &mut [ ("to_vecs", &mut |xs| no_out!(xs.to_vecs())), ("into_vecs", &mut |xs| no_out!(xs.into_vecs())), ("slices_ref", &mut |xs| no_out!(xs.slices_ref())), ], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/rational_sequences/mod.rs000064400000000000000000000012771046102023000250740ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { access::register(runner); basic::register(runner); comparison::register(runner); conversion::register(runner); to_string::register(runner); } mod access; mod basic; mod comparison; mod conversion; mod to_string; malachite-base-0.4.16/src/bin_util/demo_and_bench/rational_sequences/to_string.rs000064400000000000000000000046521046102023000263250ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::strings::ToDebugString; use malachite_base::test_util::bench::bucketers::rational_sequence_len_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_rational_sequence_gen; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_rational_sequence_to_string); register_demo!(runner, demo_rational_sequence_to_debug_string); register_bench!(runner, benchmark_rational_sequence_to_string); register_bench!(runner, benchmark_rational_sequence_to_debug_string); } fn demo_rational_sequence_to_string(gm: GenMode, config: &GenConfig, limit: usize) { for xs in unsigned_rational_sequence_gen::() .get(gm, config) .take(limit) { println!("{xs}"); } } fn demo_rational_sequence_to_debug_string(gm: GenMode, config: &GenConfig, limit: usize) { for xs in unsigned_rational_sequence_gen::() .get(gm, config) .take(limit) { println!("{xs:?}"); } } fn benchmark_rational_sequence_to_string( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( "RationalSequence.to_string()", BenchmarkType::Single, unsigned_rational_sequence_gen::().get(gm, config), gm.name(), limit, file_name, &rational_sequence_len_bucketer("xs"), &mut [("Malachite", &mut |xs| no_out!(xs.to_string()))], ); } fn benchmark_rational_sequence_to_debug_string( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( "RationalSequence.to_debug_string()", BenchmarkType::Single, unsigned_rational_sequence_gen::().get(gm, config), gm.name(), limit, file_name, &rational_sequence_len_bucketer("xs"), &mut [("Malachite", &mut |xs| no_out!(xs.to_debug_string()))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/rounding_modes/clone.rs000064400000000000000000000023131046102023000245350ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{rounding_mode_gen, rounding_mode_pair_gen}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_rounding_mode_clone); register_demo!(runner, demo_rounding_mode_clone_from); } fn demo_rounding_mode_clone(gm: GenMode, config: &GenConfig, limit: usize) { for rm in rounding_mode_gen().get(gm, config).take(limit) { println!("clone({}) = {}", rm, rm.clone()); } } fn demo_rounding_mode_clone_from(gm: GenMode, config: &GenConfig, limit: usize) { for (mut x, y) in rounding_mode_pair_gen().get(gm, config).take(limit) { let x_old = x; x.clone_from(&y); println!("x := {x_old}; x.clone_from({y}); x = {x}"); } } malachite-base-0.4.16/src/bin_util/demo_and_bench/rounding_modes/eq.rs000064400000000000000000000016521046102023000240470ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::rounding_mode_pair_gen; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_rounding_mode_eq); } fn demo_rounding_mode_eq(gm: GenMode, config: &GenConfig, limit: usize) { for (x, y) in rounding_mode_pair_gen().get(gm, config).take(limit) { if x == y { println!("{x} = {y}"); } else { println!("{x} ≠ {y}"); } } } malachite-base-0.4.16/src/bin_util/demo_and_bench/rounding_modes/from_str.rs000064400000000000000000000037501046102023000252760ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::rounding_modes::RoundingMode; use malachite_base::test_util::bench::bucketers::string_len_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{string_gen, string_gen_var_2}; use malachite_base::test_util::runner::Runner; use std::str::FromStr; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_rounding_mode_from_str); register_demo!(runner, demo_rounding_mode_from_str_targeted); register_bench!(runner, benchmark_rounding_mode_from_str); } fn demo_rounding_mode_from_str(gm: GenMode, config: &GenConfig, limit: usize) { for s in string_gen().get(gm, config).take(limit) { println!( "RoundingMode::from_str({:?}) = {:?}", s, RoundingMode::from_str(&s) ); } } fn demo_rounding_mode_from_str_targeted(gm: GenMode, config: &GenConfig, limit: usize) { for s in string_gen_var_2().get(gm, config).take(limit) { println!( "RoundingMode::from_str({:?}) = {:?}", s, RoundingMode::from_str(&s) ); } } #[allow(unused_must_use)] fn benchmark_rounding_mode_from_str( gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { run_benchmark( "from_str(&str)", BenchmarkType::Single, string_gen().get(gm, config), gm.name(), limit, file_name, &string_len_bucketer(), &mut [("Malachite", &mut |s| no_out!(RoundingMode::from_str(&s)))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/rounding_modes/hash.rs000064400000000000000000000016061046102023000243640ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::rounding_mode_gen; use malachite_base::test_util::hash::hash; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_rounding_mode_hash); } fn demo_rounding_mode_hash(gm: GenMode, config: &GenConfig, limit: usize) { for rm in rounding_mode_gen().get(gm, config).take(limit) { println!("hash({}) = {}", rm, hash(&rm)); } } malachite-base-0.4.16/src/bin_util/demo_and_bench/rounding_modes/mod.rs000064400000000000000000000013131046102023000242130ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { clone::register(runner); eq::register(runner); from_str::register(runner); hash::register(runner); neg::register(runner); to_string::register(runner); } mod clone; mod eq; mod from_str; mod hash; mod neg; mod to_string; malachite-base-0.4.16/src/bin_util/demo_and_bench/rounding_modes/neg.rs000064400000000000000000000023211046102023000242050ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::NegAssign; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::rounding_mode_gen; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_rounding_mode_neg_assign); register_demo!(runner, demo_rounding_mode_neg); } fn demo_rounding_mode_neg_assign(gm: GenMode, config: &GenConfig, limit: usize) { for mut rm in rounding_mode_gen().get(gm, config).take(limit) { let rm_old = rm; rm.neg_assign(); println!("rm := {rm_old}; r.neg_assign(); rm = {rm}"); } } fn demo_rounding_mode_neg(gm: GenMode, config: &GenConfig, limit: usize) { for rm in rounding_mode_gen().get(gm, config).take(limit) { println!("-{} = {}", rm, -rm); } } malachite-base-0.4.16/src/bin_util/demo_and_bench/rounding_modes/to_string.rs000064400000000000000000000015151046102023000254500ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::rounding_mode_gen; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_rounding_mode_to_string); } fn demo_rounding_mode_to_string(gm: GenMode, config: &GenConfig, limit: usize) { for rm in rounding_mode_gen().get(gm, config).take(limit) { println!("{rm}"); } } malachite-base-0.4.16/src/bin_util/demo_and_bench/slices/min_repeating_len.rs000064400000000000000000000030121046102023000253570ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::slices::min_repeating_len; use malachite_base::test_util::bench::bucketers::vec_len_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_vec_gen_var_4; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_min_repeating_len); register_bench!(runner, benchmark_min_repeating_len); } fn demo_min_repeating_len(gm: GenMode, config: &GenConfig, limit: usize) { for xs in unsigned_vec_gen_var_4::().get(gm, config).take(limit) { println!("min_repeating_len({:?}) = {}", xs, min_repeating_len(&xs)); } } fn benchmark_min_repeating_len(gm: GenMode, config: &GenConfig, limit: usize, file_name: &str) { run_benchmark( "min_repeating_len(&[T])", BenchmarkType::Single, unsigned_vec_gen_var_4::().get(gm, config), gm.name(), limit, file_name, &vec_len_bucketer(), &mut [("Malachite", &mut |xs| no_out!(min_repeating_len(&xs)))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/slices/mod.rs000064400000000000000000000016251046102023000224670ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { min_repeating_len::register(runner); slice_leading_zeros::register(runner); slice_move_left::register(runner); slice_set_zero::register(runner); slice_test_zero::register(runner); slice_trailing_zeros::register(runner); split_into_chunks::register(runner); } mod min_repeating_len; mod slice_leading_zeros; mod slice_move_left; mod slice_set_zero; mod slice_test_zero; mod slice_trailing_zeros; mod split_into_chunks; malachite-base-0.4.16/src/bin_util/demo_and_bench/slices/slice_leading_zeros.rs000064400000000000000000000030701046102023000257100ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::slices::slice_leading_zeros; use malachite_base::test_util::bench::bucketers::vec_len_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_vec_gen; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_slice_leading_zeros); register_bench!(runner, benchmark_slice_leading_zeros); } fn demo_slice_leading_zeros(gm: GenMode, config: &GenConfig, limit: usize) { for xs in unsigned_vec_gen::().get(gm, config).take(limit) { println!( "slice_leading_zeros({:?}) = {}", xs, slice_leading_zeros(&xs) ); } } fn benchmark_slice_leading_zeros(gm: GenMode, config: &GenConfig, limit: usize, file_name: &str) { run_benchmark( "slice_leading_zeros(&[T])", BenchmarkType::Single, unsigned_vec_gen::().get(gm, config), gm.name(), limit, file_name, &vec_len_bucketer(), &mut [("Malachite", &mut |xs| no_out!(slice_leading_zeros(&xs)))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/slices/slice_move_left.rs000064400000000000000000000033441046102023000250470ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::slices::slice_move_left; use malachite_base::test_util::bench::bucketers::pair_1_vec_len_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_vec_unsigned_pair_gen_var_1; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_slice_move_left); register_bench!(runner, benchmark_slice_move_left); } fn demo_slice_move_left(gm: GenMode, config: &GenConfig, limit: usize) { for (mut xs, amount) in unsigned_vec_unsigned_pair_gen_var_1::() .get(gm, config) .take(limit) { let old_xs = xs.clone(); slice_move_left(&mut xs, amount); println!("xs := {old_xs:?}; slice_move_left(&mut xs, {amount}); xs = {xs:?}"); } } fn benchmark_slice_move_left(gm: GenMode, config: &GenConfig, limit: usize, file_name: &str) { run_benchmark( "slice_move_left(&mut [T], usize)", BenchmarkType::Single, unsigned_vec_unsigned_pair_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &pair_1_vec_len_bucketer("xs"), &mut [("Malachite", &mut |(mut xs, amount)| { slice_move_left(&mut xs, amount) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/slices/slice_set_zero.rs000064400000000000000000000030521046102023000247150ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::slices::slice_set_zero; use malachite_base::test_util::bench::bucketers::vec_len_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_vec_gen; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_slice_set_zero); register_bench!(runner, benchmark_slice_set_zero); } fn demo_slice_set_zero(gm: GenMode, config: &GenConfig, limit: usize) { for mut xs in unsigned_vec_gen::().get(gm, config).take(limit) { let old_xs = xs.clone(); slice_set_zero(&mut xs); println!("xs := {old_xs:?}; slice_set_zero(&mut xs); xs = {xs:?}"); } } fn benchmark_slice_set_zero(gm: GenMode, config: &GenConfig, limit: usize, file_name: &str) { run_benchmark( "slice_set_zero(&mut [T])", BenchmarkType::Single, unsigned_vec_gen::().get(gm, config), gm.name(), limit, file_name, &vec_len_bucketer(), &mut [("Malachite", &mut |mut xs| slice_set_zero(&mut xs))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/slices/slice_test_zero.rs000064400000000000000000000027501046102023000251050ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::slices::slice_test_zero; use malachite_base::test_util::bench::bucketers::vec_len_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_vec_gen; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_slice_test_zero); register_bench!(runner, benchmark_slice_test_zero); } fn demo_slice_test_zero(gm: GenMode, config: &GenConfig, limit: usize) { for xs in unsigned_vec_gen::().get(gm, config).take(limit) { println!("slice_test_zero({:?}) = {:?}", xs, slice_test_zero(&xs)); } } fn benchmark_slice_test_zero(gm: GenMode, config: &GenConfig, limit: usize, file_name: &str) { run_benchmark( "slice_test_zero(&[T])", BenchmarkType::Single, unsigned_vec_gen::().get(gm, config), gm.name(), limit, file_name, &vec_len_bucketer(), &mut [("Malachite", &mut |xs| no_out!(slice_test_zero(&xs)))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/slices/slice_trailing_zeros.rs000064400000000000000000000031011046102023000261110ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::slices::slice_trailing_zeros; use malachite_base::test_util::bench::bucketers::vec_len_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_vec_gen; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_slice_trailing_zeros); register_bench!(runner, benchmark_slice_trailing_zeros); } fn demo_slice_trailing_zeros(gm: GenMode, config: &GenConfig, limit: usize) { for xs in unsigned_vec_gen::().get(gm, config).take(limit) { println!( "slice_trailing_zeros({:?}) = {}", xs, slice_trailing_zeros(&xs) ); } } fn benchmark_slice_trailing_zeros(gm: GenMode, config: &GenConfig, limit: usize, file_name: &str) { run_benchmark( "slice_trailing_zeros(&[T])", BenchmarkType::Single, unsigned_vec_gen::().get(gm, config), gm.name(), limit, file_name, &vec_len_bucketer(), &mut [("Malachite", &mut |xs| no_out!(slice_trailing_zeros(&xs)))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/slices/split_into_chunks.rs000064400000000000000000000111751046102023000254500ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::strings::ToDebugString; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_vec_unsigned_unsigned_triple_gen_var_2; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_split_into_chunks); register_demo!(runner, demo_split_into_chunks_mut); } macro_rules! split_into_chunks_helper { ($xs: expr, $len: expr, $n: expr, [$($xs_i: ident),*], $xs_last: ident) => {{ split_into_chunks!($xs, $len, [$($xs_i),*], $xs_last); let xss = &[$($xs_i,)* $xs_last]; let mut message = "xs := ".to_string(); message.push_str(&$xs.to_debug_string()); message.push_str("; split_into_chunks!(xs, "); message.push_str(&$len.to_string()); message.push_str(", ["); message.push_str(&(1..$n).map(|i| format!("xs_{}", i)).join(", ")); message.push_str("], xs_"); message.push_str(&$n.to_string()); message.push_str("); "); message.push_str(&(1..=$n).zip(xss) .map(|(i, xs)| format!("xs_{} = {:?}", i, xs)).join("; ")); println!("{}", message); }} } fn demo_split_into_chunks(gm: GenMode, config: &GenConfig, limit: usize) { for (xs, len, n) in unsigned_vec_unsigned_unsigned_triple_gen_var_2::() .get(gm, config) .take(limit) { match n { 0 => split_into_chunks_helper!(xs, len, 1, [], xs_1), 1 => split_into_chunks_helper!(xs, len, 2, [xs_1], xs_2), 2 => split_into_chunks_helper!(xs, len, 3, [xs_1, xs_2], xs_3), 3 => split_into_chunks_helper!(xs, len, 4, [xs_1, xs_2, xs_3], xs_4), 4 => split_into_chunks_helper!(xs, len, 5, [xs_1, xs_2, xs_3, xs_4], xs_5), 5 => split_into_chunks_helper!(xs, len, 6, [xs_1, xs_2, xs_3, xs_4, xs_5], xs_6), 6 => split_into_chunks_helper!(xs, len, 7, [xs_1, xs_2, xs_3, xs_4, xs_5, xs_6], xs_7), 7 => split_into_chunks_helper!( xs, len, 8, [xs_1, xs_2, xs_3, xs_4, xs_5, xs_6, xs_7], xs_8 ), _ => println!("Large number of chunks"), } } } macro_rules! split_into_chunks_mut_helper { ($xs: expr, $len: expr, $n: expr, [$($xs_i: ident),*], $xs_last: ident) => {{ split_into_chunks_mut!($xs, $len, [$($xs_i),*], $xs_last); let xss = &[$($xs_i.to_vec(),)* $xs_last.to_vec()]; let mut message = "xs := ".to_string(); message.push_str(&$xs.to_debug_string()); message.push_str("; split_into_chunks_mut!(xs, "); message.push_str(&$len.to_string()); message.push_str(", ["); message.push_str(&(1..$n).map(|i| format!("xs_{}", i)).join(", ")); message.push_str("], xs_"); message.push_str(&$n.to_string()); message.push_str("); "); message.push_str(&(1..=$n).zip(xss) .map(|(i, xs)| format!("xs_{} = {:?}", i, xs)).join("; ")); println!("{}", message); }} } fn demo_split_into_chunks_mut(gm: GenMode, config: &GenConfig, limit: usize) { for (mut xs, len, n) in unsigned_vec_unsigned_unsigned_triple_gen_var_2::() .get(gm, config) .take(limit) { match n { 0 => split_into_chunks_mut_helper!(xs, len, 1, [], xs_1), 1 => split_into_chunks_mut_helper!(xs, len, 2, [xs_1], xs_2), 2 => split_into_chunks_mut_helper!(xs, len, 3, [xs_1, xs_2], xs_3), 3 => split_into_chunks_mut_helper!(xs, len, 4, [xs_1, xs_2, xs_3], xs_4), 4 => split_into_chunks_mut_helper!(xs, len, 5, [xs_1, xs_2, xs_3, xs_4], xs_5), 5 => split_into_chunks_mut_helper!(xs, len, 6, [xs_1, xs_2, xs_3, xs_4, xs_5], xs_6), 6 => split_into_chunks_mut_helper!( xs, len, 7, [xs_1, xs_2, xs_3, xs_4, xs_5, xs_6], xs_7 ), 7 => split_into_chunks_mut_helper!( xs, len, 8, [xs_1, xs_2, xs_3, xs_4, xs_5, xs_6, xs_7], xs_8 ), _ => println!("Large number of chunks"), } } } malachite-base-0.4.16/src/bin_util/demo_and_bench/strings/mod.rs000064400000000000000000000012031046102023000226660ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { string_is_subset::register(runner); string_sort::register(runner); string_unique::register(runner); } mod string_is_subset; mod string_sort; mod string_unique; malachite-base-0.4.16/src/bin_util/demo_and_bench/strings/string_is_subset.rs000064400000000000000000000040011046102023000254740ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::strings::string_is_subset; use malachite_base::test_util::bench::bucketers::pair_string_max_len_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{string_pair_gen, string_pair_gen_var_1}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_string_is_subset); register_demo!(runner, demo_string_is_subset_ascii); register_bench!(runner, benchmark_string_is_subset); } fn demo_string_is_subset(gm: GenMode, config: &GenConfig, limit: usize) { for (s, t) in string_pair_gen().get(gm, config).take(limit) { println!( "{:?} is {}a subset of {:?}", s, if string_is_subset(&s, &t) { "" } else { "not " }, t ); } } fn demo_string_is_subset_ascii(gm: GenMode, config: &GenConfig, limit: usize) { for (s, t) in string_pair_gen_var_1().get(gm, config).take(limit) { println!( "{:?} is {}a subset of {:?}", s, if string_is_subset(&s, &t) { "" } else { "not " }, t ); } } fn benchmark_string_is_subset(gm: GenMode, config: &GenConfig, limit: usize, file_name: &str) { run_benchmark( "string_is_subset(&str, &str)", BenchmarkType::Single, string_pair_gen().get(gm, config), gm.name(), limit, file_name, &pair_string_max_len_bucketer("s", "t"), &mut [("Malachite", &mut |(s, t)| no_out!(string_is_subset(&s, &t)))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/strings/string_sort.rs000064400000000000000000000033041046102023000244700ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::strings::string_sort; use malachite_base::test_util::bench::bucketers::string_len_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{string_gen, string_gen_var_1}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_string_sort); register_demo!(runner, demo_string_sort_ascii); register_bench!(runner, benchmark_string_sort); } fn demo_string_sort(gm: GenMode, config: &GenConfig, limit: usize) { for s in string_gen().get(gm, config).take(limit) { println!("string_sort({:?}) = {:?}", s, string_sort(&s)); } } fn demo_string_sort_ascii(gm: GenMode, config: &GenConfig, limit: usize) { for s in string_gen_var_1().get(gm, config).take(limit) { println!("string_sort({:?}) = {:?}", s, string_sort(&s)); } } fn benchmark_string_sort(gm: GenMode, config: &GenConfig, limit: usize, file_name: &str) { run_benchmark( "string_sort(&str)", BenchmarkType::Single, string_gen().get(gm, config), gm.name(), limit, file_name, &string_len_bucketer(), &mut [("Malachite", &mut |s| no_out!(string_sort(&s)))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/strings/string_unique.rs000064400000000000000000000033361046102023000250140ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::strings::string_unique; use malachite_base::test_util::bench::bucketers::string_len_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::{string_gen, string_gen_var_1}; use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_string_unique); register_demo!(runner, demo_string_unique_ascii); register_bench!(runner, benchmark_string_unique); } fn demo_string_unique(gm: GenMode, config: &GenConfig, limit: usize) { for s in string_gen().get(gm, config).take(limit) { println!("string_unique({:?}) = {:?}", s, string_unique(&s)); } } fn demo_string_unique_ascii(gm: GenMode, config: &GenConfig, limit: usize) { for s in string_gen_var_1().get(gm, config).take(limit) { println!("string_unique({:?}) = {:?}", s, string_unique(&s)); } } fn benchmark_string_unique(gm: GenMode, config: &GenConfig, limit: usize, file_name: &str) { run_benchmark( "string_unique(&str)", BenchmarkType::Single, string_gen().get(gm, config), gm.name(), limit, file_name, &string_len_bucketer(), &mut [("Malachite", &mut |s| no_out!(string_unique(&s)))], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/vecs/mod.rs000064400000000000000000000011131046102023000221350ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::runner::Runner; pub(crate) fn register(runner: &mut Runner) { vec_delete_left::register(runner); vec_pad_left::register(runner); } mod vec_delete_left; mod vec_pad_left; malachite-base-0.4.16/src/bin_util/demo_and_bench/vecs/vec_delete_left.rs000064400000000000000000000033421046102023000244750ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::bench::bucketers::pair_1_vec_len_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_vec_unsigned_pair_gen_var_1; use malachite_base::test_util::runner::Runner; use malachite_base::vecs::vec_delete_left; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_vec_delete_left); register_bench!(runner, benchmark_vec_delete_left); } fn demo_vec_delete_left(gm: GenMode, config: &GenConfig, limit: usize) { for (mut xs, amount) in unsigned_vec_unsigned_pair_gen_var_1::() .get(gm, config) .take(limit) { let old_xs = xs.clone(); vec_delete_left(&mut xs, amount); println!("xs := {old_xs:?}; vec_delete_left(&mut xs, {amount}); xs = {xs:?}"); } } fn benchmark_vec_delete_left(gm: GenMode, config: &GenConfig, limit: usize, file_name: &str) { run_benchmark( "vec_delete_left(&mut [T], usize)", BenchmarkType::Single, unsigned_vec_unsigned_pair_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &pair_1_vec_len_bucketer("xs"), &mut [("Malachite", &mut |(mut xs, amount)| { vec_delete_left(&mut xs, amount) })], ); } malachite-base-0.4.16/src/bin_util/demo_and_bench/vecs/vec_pad_left.rs000064400000000000000000000035301046102023000237760ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::bench::bucketers::triple_1_vec_len_bucketer; use malachite_base::test_util::bench::{run_benchmark, BenchmarkType}; use malachite_base::test_util::generators::common::{GenConfig, GenMode}; use malachite_base::test_util::generators::unsigned_vec_unsigned_unsigned_triple_gen_var_1; use malachite_base::test_util::runner::Runner; use malachite_base::vecs::vec_pad_left; pub(crate) fn register(runner: &mut Runner) { register_demo!(runner, demo_vec_pad_left); register_bench!(runner, benchmark_vec_pad_left); } fn demo_vec_pad_left(gm: GenMode, config: &GenConfig, limit: usize) { for (mut xs, pad_size, pad_value) in unsigned_vec_unsigned_unsigned_triple_gen_var_1::() .get(gm, config) .take(limit) { let old_xs = xs.clone(); vec_pad_left(&mut xs, pad_size, pad_value); println!("xs := {old_xs:?}; vec_pad_left(&mut xs, {pad_size}, {pad_value}); xs = {xs:?}"); } } fn benchmark_vec_pad_left(gm: GenMode, config: &GenConfig, limit: usize, file_name: &str) { run_benchmark( "vec_pad_left(&mut [T], usize, T)", BenchmarkType::Single, unsigned_vec_unsigned_unsigned_triple_gen_var_1::().get(gm, config), gm.name(), limit, file_name, &triple_1_vec_len_bucketer("xs"), &mut [("Malachite", &mut |(mut xs, pad_size, pad_value)| { vec_pad_left(&mut xs, pad_size, pad_value) })], ); } malachite-base-0.4.16/src/bin_util/generate/max_base.rs000064400000000000000000000022061046102023000210660ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; fn max_base_helper() { if T::NAME == "usize" { return; } print!( "const MAX_BASE_{}: [{}; {}] = [0", T::WIDTH, T::NAME, T::WIDTH ); for exp in 1..T::WIDTH { print!(", {}", T::MAX.floor_root(exp)); } println!("];"); println!(); print!( "const MAX_POWER_{}: [{}; {}] = [0", T::WIDTH, T::NAME, T::WIDTH ); for exp in 1..T::WIDTH { print!(", {}", T::MAX.floor_root(exp).pow(exp)); } println!("];"); println!(); } pub(crate) fn generate_max_base() { println!("// This section is created by max_base.rs."); apply_fn_to_unsigneds!(max_base_helper); } malachite-base-0.4.16/src/bin_util/generate/mod.rs000064400000000000000000000006571046102023000200760ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . pub mod max_base; pub mod rle; pub mod tuning_manager; malachite-base-0.4.16/src/bin_util/generate/rle.rs000064400000000000000000000021361046102023000200730ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . fn rle_encode(xs: &[T]) -> Vec<(T, usize)> { let mut out = Vec::new(); let mut previous: Option = None; let mut count = 0; for x in xs { if let Some(p) = previous.as_ref() { if x == p { count += 1; } else { out.push((p.clone(), count)); previous = Some(x.clone()); count = 1; } } else { count = 1; previous = Some(x.clone()); } } if let Some(p) = previous { out.push((p, count)); } out } pub(crate) fn generate_rle_encoding() { // Example xs let xs = &[1, 1, 1, 0, 0, 0, 0, 0, 0, 2, 2]; println!("{:?}", rle_encode(xs)); } malachite-base-0.4.16/src/bin_util/generate/tuning_manager.rs000064400000000000000000000267111046102023000223140ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use std::collections::{BTreeMap, BTreeSet, HashSet}; use std::fs::File; use std::io::{BufRead, BufReader}; use walkdir::WalkDir; const PARENT_PATHS: [&str; 2] = ["../malachite-base/src", "../malachite-nz/src"]; fn find_all_file_paths() -> BTreeSet { let mut paths = BTreeSet::new(); for &parent_path in &PARENT_PATHS { for entry in WalkDir::new(parent_path) { let name = entry.unwrap().path().display().to_string(); // Exclude platform_64 as we'll get all the same info from _32 if name.ends_with(".rs") && !name.ends_with("/platform_64.rs") { paths.insert(name); } } } paths } fn primitive_tokenize(s: &str) -> Vec { let chars = s.chars().collect_vec(); let mut tokens = Vec::new(); let mut token = String::new(); for &c in &chars { if c.is_alphanumeric() || c == '_' { token.push(c); } else if !token.is_empty() { tokens.push(token); token = String::new(); } } if !token.is_empty() { tokens.push(token); } tokens } const FN_PREFIXES: [&str; 6] = ["pub fn ", "pub(crate) fn ", "fn ", "pub const fn ", "pub(crate) const fn ", "const fn "]; const ALLOWED_DOUBLE_NAMES: [&str; 3] = ["limbs_mod_limb", "oz_fmt", "fail_on_untested_path"]; #[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)] struct FunctionRecord { name: String, file_path: String, line_number: usize, } fn get_all_top_level_functions() -> BTreeMap { let allowed_double_names: HashSet<&str> = ALLOWED_DOUBLE_NAMES.iter().cloned().collect(); let mut fns = BTreeMap::new(); let file_paths = find_all_file_paths(); for path in &file_paths { let input = File::open(path).unwrap(); let buffered = BufReader::new(input); for (i, line) in buffered.lines().enumerate() { let line = line.unwrap(); for &prefix in &FN_PREFIXES { if let Some(fn_string) = line.strip_prefix(prefix) { let fn_name = primitive_tokenize(fn_string).swap_remove(0); if !allowed_double_names.contains(&fn_name.as_str()) && fns.contains_key(&fn_name) { panic!("Duplicate top-level function name: {fn_name}"); } fns.insert( fn_name.clone(), FunctionRecord { name: fn_name, file_path: path.to_string(), line_number: i, }, ); } } } } fns } const CONST_PREFIXES: [&str; 3] = ["pub const ", "pub(crate) const ", "const "]; fn get_all_tuneable_constants() -> BTreeMap { let file_paths = find_all_file_paths(); let mut constants = BTreeMap::new(); let mut expecting_constant = false; for path in &file_paths { let input = File::open(path).unwrap(); let buffered = BufReader::new(input); for (i, line) in buffered.lines().enumerate() { let line = line.unwrap(); if expecting_constant { if line.starts_with("//") || line.starts_with("#[") { // do nothing } else { let mut p = None; for &prefix in &CONST_PREFIXES { if line.starts_with(prefix) { p = Some(prefix); break; } } if p.is_none() { panic!("Bad const. line {i} in {path}"); } let p = p.unwrap(); let name = &line[p.len()..]; let colon_index = name.chars().position(|c| c == ':').unwrap(); let name = &name[..colon_index]; if constants.contains_key(name) { panic!("Duplicate constant name: {name}"); } constants.insert( name.to_string(), FunctionRecord { name: name.to_string(), file_path: path.to_string(), line_number: i, }, ); expecting_constant = false; } } else if line == "//TODO tune" { expecting_constant = true; } } } assert!(!expecting_constant); constants } fn extract_functions_and_constants( name: &str, lines: &[String], fns: &BTreeMap, cs: &BTreeMap, ) -> (BTreeSet, BTreeSet) { let mut matched_fns = BTreeSet::new(); let mut matched_cs = BTreeSet::new(); let mut first = true; for line in lines { for token in primitive_tokenize(line) { if fns.contains_key(&token) { if first { assert_eq!(token, name); first = false; } else { matched_fns.insert(token.clone()); } } else if cs.contains_key(&token) { if first { assert_eq!(token, name); first = false; } else { matched_cs.insert(token.clone()); } } } } (matched_fns, matched_cs) } fn get_referenced_items_for_constant( constant: &FunctionRecord, fns: &BTreeMap, cs: &BTreeMap, ) -> (BTreeSet, BTreeSet) { let input = File::open(&constant.file_path).unwrap(); let buffered = BufReader::new(input); let mut lines = Vec::new(); let mut brace_index = 0; for (i, line) in buffered.lines().enumerate() { if i < constant.line_number { continue; } let line = line.unwrap(); let mut done = false; for c in line.chars() { match c { '{' => brace_index += 1, '}' => { assert_ne!(brace_index, 0); brace_index -= 1; } ';' => { if brace_index == 0 { done = true; break; } } _ => {} } } lines.push(line); if done { break; } } extract_functions_and_constants(&constant.name, &lines, fns, cs) } fn get_referenced_items_for_function( function: &FunctionRecord, fns: &BTreeMap, cs: &BTreeMap, ) -> (BTreeSet, BTreeSet) { let input = File::open(&function.file_path).unwrap(); let buffered = BufReader::new(input); let mut lines = Vec::new(); let mut brace_index = 0; for (i, line) in buffered.lines().enumerate() { if i < function.line_number { continue; } let line = line.unwrap(); let mut done = false; for c in line.chars() { match c { '{' => brace_index += 1, '}' => { assert_ne!(brace_index, 0); brace_index -= 1; if brace_index == 0 { done = true; break; } } _ => {} } } lines.push(line); if done { break; } } extract_functions_and_constants(&function.name, &lines, fns, cs) } pub struct ReferenceData { functions: BTreeMap, constants: BTreeMap, pub constants_referencing_constants: BTreeMap>, pub constants_referencing_functions: BTreeMap>, functions_referencing_constants: BTreeMap>, pub functions_referencing_functions: BTreeMap>, } fn parse_and_get_references() -> ReferenceData { let fns = get_all_top_level_functions(); let cs = get_all_tuneable_constants(); let mut crc = BTreeMap::new(); let mut crf = BTreeMap::new(); for c in cs.values() { let (rf, rc) = get_referenced_items_for_constant(c, &fns, &cs); crc.insert(c.name.clone(), rc); crf.insert(c.name.clone(), rf); } let mut frc = BTreeMap::new(); let mut frf = BTreeMap::new(); for f in fns.values() { let (rf, rc) = get_referenced_items_for_function(f, &fns, &cs); frc.insert(f.name.clone(), rc); frf.insert(f.name.clone(), rf); } ReferenceData { functions: fns, constants: cs, constants_referencing_constants: crc, constants_referencing_functions: crf, functions_referencing_constants: frc, functions_referencing_functions: frf, } } fn invert_map(m: &BTreeMap>) -> BTreeMap> { let mut inverse = BTreeMap::new(); for (k, vs) in m { for v in vs { inverse .entry(v.clone()) .or_insert_with(BTreeSet::new) .insert(k.clone()); } } inverse } pub fn build_reference_data() { parse_and_get_references(); } fn hfdm_helper(map: &mut BTreeMap, k: &str, v: &str) { map.insert(k.to_string(), v.to_string()); } fn hardcoded_defining_function_map() -> BTreeMap { let mut m = BTreeMap::new(); hfdm_helper(&mut m, "BMOD_1_TO_MOD_1_THRESHOLD", "limbs_mod_limb_helper"); hfdm_helper( &mut m, "DC_BDIV_QR_THRESHOLD", "limbs_modular_div_mod_helper", ); hfdm_helper(&mut m, "DC_BDIV_Q_THRESHOLD", "limbs_modular_invert_small"); hfdm_helper(&mut m, "DC_DIVAPPR_Q_THRESHOLD", "limbs_div_approx_helper"); hfdm_helper(&mut m, "DC_DIV_QR_THRESHOLD", "limbs_div_dc_helper"); hfdm_helper(&mut m, "DC_DIV_Q_THRESHOLD", "limbs_div_q_dc_helper"); m } fn generate_defining_function_map(data: &ReferenceData) -> BTreeMap { let mut defining_functions = hardcoded_defining_function_map(); for (k, v) in &defining_functions { assert!(data.constants.contains_key(k)); assert!(data.functions.contains_key(v)); assert!(data.functions_referencing_constants[v].contains(k)); } for (c, fs) in invert_map(&data.functions_referencing_constants) { if defining_functions.contains_key(&c) { continue; } if fs.len() == 1 { defining_functions.insert(c.clone(), fs.iter().next().unwrap().clone()); } else { panic!("Must specify defining function for {c}. Possibilities are {fs:?}"); } } defining_functions } pub fn test() { let data = parse_and_get_references(); generate_defining_function_map(&data); } malachite-base-0.4.16/src/bools/constants.rs000064400000000000000000000012321046102023000170400ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::comparison::traits::{Max, Min}; use crate::named::Named; impl Min for bool { /// The minimum value of a [`bool`]: `false`. const MIN: bool = false; } impl Max for bool { /// The maximum value of a [`bool`]: `true`. const MAX: bool = true; } impl_named!(bool); malachite-base-0.4.16/src/bools/exhaustive.rs000064400000000000000000000020401046102023000172070ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use core::iter::Copied; use core::slice::Iter; /// An iterator that generates both [`bool`]s. /// /// This `struct` is created by [`exhaustive_bools`]; see its documentation for more. pub type ExhaustiveBools = Copied>; /// Generates both [`bool`]s. /// /// The output length is 2. /// /// # Worst-case complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::bools::exhaustive::exhaustive_bools; /// /// assert_eq!(exhaustive_bools().collect_vec(), &[false, true]); /// ``` #[inline] pub fn exhaustive_bools() -> ExhaustiveBools { [false, true].iter().copied() } malachite-base-0.4.16/src/bools/mod.rs000064400000000000000000000017251046102023000156120ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . /// Constants associated with [`bool`]s. /// /// The constants [`MIN`](crate::comparison::traits::Min::MIN) and /// [`MAX`](crate::comparison::traits::Max::MAX) are defined as for [`bool`]s as `false` and `true`, /// respectively. The constant [`NAME`](crate::named::Named::NAME) is defined as "bool". pub mod constants; /// An iterator that generates [`bool`]s without repetition. pub mod exhaustive; /// The implementation of [`NotAssign`](crate::num::logic::traits::NotAssign) for [`bool`]. pub mod not_assign; #[cfg(feature = "random")] /// Iterators that generate [`bool`]s randomly. pub mod random; malachite-base-0.4.16/src/bools/not_assign.rs000064400000000000000000000017151046102023000171760ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::logic::traits::NotAssign; impl NotAssign for bool { /// Replaces a [`bool`] by its opposite. /// /// $b \gets \lnot b$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::num::logic::traits::NotAssign; /// /// let mut b = false; /// b.not_assign(); /// assert_eq!(b, true); /// /// let mut b = true; /// b.not_assign(); /// assert_eq!(b, false); /// ``` #[inline] fn not_assign(&mut self) { *self = !*self; } } malachite-base-0.4.16/src/bools/random.rs000064400000000000000000000117511046102023000163130ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::Parity; use crate::num::random::geometric::SimpleRational; use crate::num::random::{ random_unsigneds_less_than, RandomUnsignedsLessThan, VariableRangeGenerator, }; use crate::random::Seed; use rand::Rng; use rand_chacha::ChaCha20Rng; /// Uniformly generates random [`bool`]s. /// /// This `struct` is created by [`random_bools`]; see its documentation for more. #[derive(Clone, Debug)] pub struct RandomBools { rng: ChaCha20Rng, x: u32, bits_left: u8, } impl Iterator for RandomBools { type Item = bool; #[inline] fn next(&mut self) -> Option { if self.bits_left == 0 { self.x = self.rng.gen(); self.bits_left = 31; } else { self.x >>= 1; self.bits_left -= 1; } Some(self.x.odd()) } } /// Uniformly generates random [`bool`]s. /// /// $P(\text{false}) = P(\text{true}) = \frac{1}{2}$. /// /// The output length is infinite. /// /// # Worst-case complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::bools::random::random_bools; /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string(random_bools(EXAMPLE_SEED), 10), /// "[true, false, false, false, true, true, true, false, true, true, ...]" /// ) /// ``` /// /// # Notes /// The resulting iterator uses every random bit generated by the PRNG, unlike some implementations /// which only use one bit out of 32 or 64. #[inline] pub fn random_bools(seed: Seed) -> RandomBools { RandomBools { rng: seed.get_rng(), x: 0, bits_left: 0, } } /// Generates random [`bool`]s, with a fixed probability of generating `true`. /// /// This `struct` is created by [`weighted_random_bools`]; see its documentation for more. #[derive(Clone, Debug)] pub struct WeightedRandomBools { numerator: u64, xs: RandomUnsignedsLessThan, } impl Iterator for WeightedRandomBools { type Item = bool; #[inline] fn next(&mut self) -> Option { Some(self.xs.next().unwrap() < self.numerator) } } /// Generates random [`bool`]s, with a fixed probability of generating `true`. /// /// Let $n_p$ be `p_numerator`, $d_p$ be `p_denominator`, and let $p=n_p/d_p$. Then /// /// $P(\text{true}) = p$, /// /// $P(\text{false}) = 1-p$. /// /// The output length is infinite. /// /// # Panics /// Panics if `p_denominator` is 0 or `p_numerator > p_denominator`. /// /// # Expected complexity per iteration /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ = `p_denominator.significant_bits()`. /// /// # Examples /// ``` /// use malachite_base::bools::random::weighted_random_bools; /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string(weighted_random_bools(EXAMPLE_SEED, 3, 4), 10), /// "[true, true, false, true, false, false, true, false, true, true, ...]" /// ) /// ``` pub fn weighted_random_bools( seed: Seed, p_numerator: u64, p_denominator: u64, ) -> WeightedRandomBools { assert!(p_numerator <= p_denominator); let p = SimpleRational::new(p_numerator, p_denominator); WeightedRandomBools { numerator: p.n, xs: random_unsigneds_less_than(seed, p.d), } } /// Generates a random [`bool`] with a particular probability of being `true`. /// /// Let $n_p$ be `p_numerator`, $d_p$ be `p_denominator`, and let $p=n_p/d_p$. Then /// /// $P(\text{true}) = p$, /// /// $P(\text{false}) = 1-p$. /// /// # Panics /// Panics if `p_denominator` is 0 or `p_numerator > p_denominator`. /// /// # Expected complexity /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ = `p_denominator.significant_bits()`. /// /// # Examples /// ``` /// use malachite_base::bools::random::get_weighted_random_bool; /// use malachite_base::num::random::VariableRangeGenerator; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// get_weighted_random_bool(&mut VariableRangeGenerator::new(EXAMPLE_SEED), 1, 10), /// false /// ); /// ``` pub fn get_weighted_random_bool( range_generator: &mut VariableRangeGenerator, p_numerator: u64, p_denominator: u64, ) -> bool { assert_ne!(p_denominator, 0); assert!(p_numerator <= p_denominator); if p_numerator == 0 { return false; } else if p_numerator == p_denominator { return true; } let p = SimpleRational::new(p_numerator, p_denominator); range_generator.next_less_than(p.d) < p.n } malachite-base-0.4.16/src/chars/constants.rs000064400000000000000000000040671046102023000170330ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::comparison::traits::{Max, Min}; use crate::named::Named; /// The number of [Unicode scalar values](https://www.unicode.org/glossary/#unicode_scalar_value). /// $2^{20}+2^{16}-2^{11} = \mathrm{0x10\\,f800} = 1,\\!112,\\!064$. pub const NUMBER_OF_CHARS: u32 = (1 << 20) + (1 << 16) - NUMBER_OF_SURROGATE_CODE_POINTS; /// The number of [surrogate code points](https://www.unicode.org/glossary/#surrogate_code_point); /// these are code points that do not correspond to any valid [`char`]. /// /// $2^{11} = 2,\\!048$. pub const NUMBER_OF_SURROGATE_CODE_POINTS: u32 = 1 << 11; /// The first [surrogate code point](https://www.unicode.org/glossary/#surrogate_code_point). pub const FIRST_SURROGATE_CODE_POINT: u32 = 0xd800; /// The [`char`] that comes just before the surrogate range. /// /// This happens to be an unassigned (as of Unicode 14.0) character in the [Hangul Jamo Extended-B /// block](https://www.unicode.org/charts/PDF/UD7B0.pdf). pub const CHAR_JUST_BELOW_SURROGATES: char = '\u{d7ff}'; /// The [`char`] that comes just after the surrogate range. /// /// This is a character in the [Private Use Area](https://www.unicode.org/charts/PDF/UE000.pdf). pub const CHAR_JUST_ABOVE_SURROGATES: char = '\u{e000}'; impl Min for char { /// The minimum value of a [`char`]: `'\u{0}'`. /// /// This is the famous NUL character, a [C0 /// control](https://www.unicode.org/charts/PDF/U0000.pdf). const MIN: char = '\u{0}'; } impl Max for char { /// The maximum value of a [`char`]: `'\u{10ffff}'`. /// /// This is a character in [Supplementary Private Use /// Area-B](https://www.unicode.org/charts/PDF/U10FF80.pdf). const MAX: char = core::char::MAX; } impl_named!(char); malachite-base-0.4.16/src/chars/crement.rs000064400000000000000000000102201046102023000164400ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::chars::constants::{ CHAR_JUST_BELOW_SURROGATES, FIRST_SURROGATE_CODE_POINT, NUMBER_OF_CHARS, NUMBER_OF_SURROGATE_CODE_POINTS, }; use crate::comparison::traits::Min; /// Converts a [`char`] to a [`u32`]. /// /// The conversion is done in such a way that if the next largest [`char`] after $x$ is $y$, then /// $\mathrm{char\\_to\\_contiguous\\_range(x)}+1 = \mathrm{char\\_to\\_contiguous\\_range(y)}$. /// This can't be accomplished just through casting, because there is a range of [`u32`]s (the /// [surrogate code points](https://www.unicode.org/glossary/#surrogate_code_point)) that do not /// correspond to any [`char`]. /// /// The inverse of this function is [`contiguous_range_to_char`]. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::chars::crement::char_to_contiguous_range; /// use std::char; /// /// assert_eq!(char_to_contiguous_range('\u{0}'), 0); /// assert_eq!(char_to_contiguous_range('a'), 97); /// assert_eq!(char_to_contiguous_range(char::MAX), 1112063); /// ``` pub const fn char_to_contiguous_range(c: char) -> u32 { match c { '\u{0}'..=CHAR_JUST_BELOW_SURROGATES => c as u32, _ => c as u32 - NUMBER_OF_SURROGATE_CODE_POINTS, } } /// Converts a [`u32`] to a [`char`]; if all [`char`]s were arranged in ascending order, passing $u$ /// to this function would return the $u$th [`char`]. /// /// This function is the inverse of [`char_to_contiguous_range`]. Every [`u32`] between $0$ and /// $\mathrm{NUMBER\\_OF\\_CHARS} - 1$, inclusive, is mapped to a distinct [`char`]. Passing a /// larger [`u32`] yields `None`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::chars::crement::contiguous_range_to_char; /// use std::char; /// /// assert_eq!(contiguous_range_to_char(0), Some('\u{0}')); /// assert_eq!(contiguous_range_to_char(97), Some('a')); /// assert_eq!(contiguous_range_to_char(1112063), Some(char::MAX)); /// ``` pub const fn contiguous_range_to_char(u: u32) -> Option { const ONE_BELOW_FIRST_SURROGATE_CODE_POINT: u32 = FIRST_SURROGATE_CODE_POINT - 1; const ONE_BELOW_NUMBER_OF_CHARS: u32 = NUMBER_OF_CHARS - 1; match u { 0..=ONE_BELOW_FIRST_SURROGATE_CODE_POINT => core::char::from_u32(u), FIRST_SURROGATE_CODE_POINT..=ONE_BELOW_NUMBER_OF_CHARS => { core::char::from_u32(u + NUMBER_OF_SURROGATE_CODE_POINTS) } _ => None, } } /// Increments this [`char`], skipping over the [surrogate code /// points](https://www.unicode.org/glossary/#surrogate_code_point). /// /// # Panics /// Panics if `self` is `char::MAX`. /// /// # Examples /// ``` /// use malachite_base::chars::crement::increment_char; /// /// let mut c = '\u{0}'; /// increment_char(&mut c); /// assert_eq!(c, '\u{1}'); /// /// let mut c = 'a'; /// increment_char(&mut c); /// assert_eq!(c, 'b'); /// ``` #[inline] pub fn increment_char(c: &mut char) { *c = contiguous_range_to_char(char_to_contiguous_range(*c) + 1) .expect("Cannot increment char::MAX"); } /// Decrements this [`char`], skipping over the [surrogate code /// points](https://www.unicode.org/glossary/#surrogate_code_point). /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` is `'\u{0}'`. /// /// # Examples /// ``` /// use malachite_base::chars::crement::decrement_char; /// /// let mut c = '\u{1}'; /// decrement_char(&mut c); /// assert_eq!(c, '\u{0}'); /// /// let mut c = 'b'; /// decrement_char(&mut c); /// assert_eq!(c, 'a'); /// ``` #[inline] pub fn decrement_char(c: &mut char) { if *c == char::MIN { panic!("Cannot decrement char '{}'", *c); } else { *c = contiguous_range_to_char(char_to_contiguous_range(*c) - 1).unwrap(); } } malachite-base-0.4.16/src/chars/exhaustive.rs000064400000000000000000000216411046102023000172010ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::chars::crement::increment_char; use crate::chars::CharType; use crate::comparison::traits::Min; use core::ops::RangeInclusive; /// Generates all ASCII [`char`]s, in ascending order. /// /// For a friendlier order (_e.g_. nonprintable [`char`]s coming last), try /// [`exhaustive_ascii_chars`]. /// /// The output length is 128. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::chars::exhaustive::ascii_chars_increasing; /// /// assert_eq!( /// ascii_chars_increasing().collect::(), /// "\u{0}\u{1}\u{2}\u{3}\u{4}\u{5}\u{6}\u{7}\u{8}\t\n\u{b}\u{c}\r\u{e}\u{f}\u{10}\u{11}\u{12}\ /// \u{13}\u{14}\u{15}\u{16}\u{17}\u{18}\u{19}\u{1a}\u{1b}\u{1c}\u{1d}\u{1e}\u{1f} !\"#$%&\'()*\ /// +,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u{7f}" /// ); /// ``` pub const fn ascii_chars_increasing() -> RangeInclusive { char::MIN..='\u{7f}' } /// Generates all [`char`]s, in ascending order. /// /// For a friendlier order (_e.g_. nonprintable [`char`]s coming last), try [`exhaustive_chars`]. /// /// The output length is 1,112,064. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::chars::exhaustive::chars_increasing; /// /// assert_eq!( /// chars_increasing().take(200).collect::(), /// "\u{0}\u{1}\u{2}\u{3}\u{4}\u{5}\u{6}\u{7}\u{8}\t\n\u{b}\u{c}\r\u{e}\u{f}\u{10}\u{11}\u{12}\ /// \u{13}\u{14}\u{15}\u{16}\u{17}\u{18}\u{19}\u{1a}\u{1b}\u{1c}\u{1d}\u{1e}\u{1f} !\"#$%&\'()*\ /// +,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u{7f}\ /// \u{80}\u{81}\u{82}\u{83}\u{84}\u{85}\u{86}\u{87}\u{88}\u{89}\u{8a}\u{8b}\u{8c}\u{8d}\u{8e}\ /// \u{8f}\u{90}\u{91}\u{92}\u{93}\u{94}\u{95}\u{96}\u{97}\u{98}\u{99}\u{9a}\u{9b}\u{9c}\u{9d}\ /// \u{9e}\u{9f}\u{a0}¡¢£¤¥¦§¨©ª«¬\u{ad}®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇ" /// ); /// ``` pub const fn chars_increasing() -> RangeInclusive { char::MIN..=char::MAX } /// Generates all [`char`]s, in a friendly order, so that more familiar [`char`] come first. /// /// The order is /// - Lowercase ASCII letters, /// - Uppercase ASCII letters, /// - ASCII digits, /// - Graphic ASCII [`char`]s (not alphanumeric and not control), including `' '` but no other /// whitespace, /// - (only if `ascii_only` is false) Graphic Non-ASCII [`char`]s; all non-ASCII [`char`]s whose /// [`Debug`](std::fmt::Debug) representations don't start with `'\'`, /// - All remaining [`char`]s. /// /// This `struct` is created by [`exhaustive_chars`] and [`exhaustive_ascii_chars`]; see their /// documentation for more. #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] pub struct ExhaustiveChars { ascii_only: bool, first: bool, c: char, current_type: CharType, } impl Iterator for ExhaustiveChars { type Item = char; fn next(&mut self) -> Option { if self.first { self.first = false; } else { match self.current_type { CharType::AsciiLower => { if self.c == 'z' { self.current_type = CharType::AsciiUpper; self.c = 'A'; } else { increment_char(&mut self.c); } } CharType::AsciiUpper => { if self.c == 'Z' { self.current_type = CharType::AsciiNumeric; self.c = '0'; } else { increment_char(&mut self.c); } } CharType::AsciiNumeric => { if self.c == '9' { self.current_type = CharType::AsciiNonAlphanumericGraphic; self.c = ' '; } else { increment_char(&mut self.c); } } CharType::AsciiNonAlphanumericGraphic => { if self.c == '~' { if self.ascii_only { self.current_type = CharType::NonGraphic; self.c = '\0'; } else { self.current_type = CharType::NonAsciiGraphic; self.c = '\u{a1}'; }; } else { increment_char(&mut self.c); // No control chars between ' ' and '~' while self.c.is_ascii_alphanumeric() { increment_char(&mut self.c); } } } CharType::NonAsciiGraphic => { if self.c == '\u{323af}' { self.current_type = CharType::NonGraphic; self.c = '\0'; } else { increment_char(&mut self.c); while !CharType::NonAsciiGraphic.contains(self.c) { increment_char(&mut self.c); } } } CharType::NonGraphic => { let limit = if self.ascii_only { '\u{7f}' } else { char::MAX }; if self.c == limit { return None; } increment_char(&mut self.c); while !self.c.is_ascii_control() && (self.c.is_ascii() || CharType::NonAsciiGraphic.contains(self.c)) { increment_char(&mut self.c); } } } } Some(self.c) } } /// Generates all ASCII [`char`]s, in a friendly order, so that more familiar [`char`]s come first. /// /// The order is /// - Lowercase ASCII letters, /// - Uppercase ASCII letters, /// - ASCII digits, /// - Graphic ASCII [`char`]s (not alphanumeric and not control), including `' '` but no other /// whitespace, /// - All remaining ASCII [`char`]s. /// /// Within each group, the [`char`]s are ordered according to their usual order. /// /// If you want to generate ASCII [`char`]s in their usual order, try [`ascii_chars_increasing`]. /// /// The output length is 128. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::chars::exhaustive::exhaustive_ascii_chars; /// /// assert_eq!( /// exhaustive_ascii_chars().collect::(), /// "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 !\"#$%&\'()*+,-./:;<=>?@[\\\ /// ]^_`{|}~\u{0}\u{1}\u{2}\u{3}\u{4}\u{5}\u{6}\u{7}\u{8}\t\n\u{b}\u{c}\r\u{e}\u{f}\u{10}\u{11}\ /// \u{12}\u{13}\u{14}\u{15}\u{16}\u{17}\u{18}\u{19}\u{1a}\u{1b}\u{1c}\u{1d}\u{1e}\u{1f}\u{7f}" /// ); /// ``` pub const fn exhaustive_ascii_chars() -> ExhaustiveChars { ExhaustiveChars { ascii_only: true, first: true, c: 'a', current_type: CharType::AsciiLower, } } /// Generates all [`char`]s, in a friendly order, so that more familiar [`char`]s come first. /// /// The order is /// - Lowercase ASCII letters, /// - Uppercase ASCII letters, /// - ASCII digits, /// - Graphic ASCII [`char`] (not alphanumeric and not control), including `' '` but no other /// whitespace, /// - Graphic Non-ASCII [`char`]s; all non-ASCII [`char`]s whose [`Debug`](std::fmt::Debug) /// representations don't start with `'\'`, /// - All remaining [`char`]s. /// /// Within each group, the [`char`]s are ordered according to their usual order. /// /// If you want to generate [`char`]s in their usual order, try [`chars_increasing`]. /// /// The output length is 1,112,064. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::chars::exhaustive::exhaustive_chars; /// /// assert_eq!( /// exhaustive_chars().take(200).collect::(), /// "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 !\"#$%&\'()*+,-./:;<=>?@[\\\ /// ]^_`{|}~¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóô\ /// õö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊ" /// ); /// ``` pub const fn exhaustive_chars() -> ExhaustiveChars { ExhaustiveChars { ascii_only: false, first: true, c: 'a', current_type: CharType::AsciiLower, } } malachite-base-0.4.16/src/chars/mod.rs000064400000000000000000000066711046102023000156010ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::strings::ToDebugString; #[cfg(feature = "test_build")] #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] pub enum CharType { AsciiLower, AsciiUpper, AsciiNumeric, AsciiNonAlphanumericGraphic, NonAsciiGraphic, NonGraphic, } #[cfg(not(feature = "test_build"))] #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] enum CharType { AsciiLower, AsciiUpper, AsciiNumeric, AsciiNonAlphanumericGraphic, NonAsciiGraphic, NonGraphic, } fn debug_starts_with_slash(c: char) -> bool { // Skip the first `char`, which is always a single quote c.to_debug_string().chars().nth(1) == Some('\\') } /// Determines whether a [`char`] is graphic. /// /// There is an [official Unicode /// definition](https://www.unicode.org/versions/Unicode14.0.0/ch03.pdf#G30602) of _graphic /// character_, but that definition is not followed here. In Malachite, a [`char`] is considered /// graphic if it is ASCII and not a [C0 control](https://unicode.org/charts/PDF/U0000.pdf), or /// non-ASCII and its debug string does not begin with a backslash. This function can be used as a /// guide to whether a [`char`] can be displayed on a screen without resorting to some sort of /// escape sequence. Of course, many typefaces will not be able to render many graphic [`char`]s. /// /// The ASCII space `' '` is the only graphic whitespace [`char`]. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::chars::char_is_graphic; /// /// assert_eq!(char_is_graphic('a'), true); /// assert_eq!(char_is_graphic(' '), true); /// assert_eq!(char_is_graphic('\n'), false); /// assert_eq!(char_is_graphic('ñ'), true); /// assert_eq!(char_is_graphic('\u{5f771}'), false); /// ``` pub fn char_is_graphic(c: char) -> bool { if c.is_ascii() { !c.is_ascii_control() } else { !debug_starts_with_slash(c) } } impl CharType { pub_crate_test! {contains(self, c: char) -> bool { match self { CharType::AsciiLower => c.is_ascii_lowercase(), CharType::AsciiUpper => c.is_ascii_uppercase(), CharType::AsciiNumeric => c.is_ascii_digit(), CharType::AsciiNonAlphanumericGraphic => { c.is_ascii() && !c.is_ascii_alphanumeric() && !c.is_ascii_control() } CharType::NonAsciiGraphic => !c.is_ascii() && !debug_starts_with_slash(c), CharType::NonGraphic => { c.is_ascii_control() || !c.is_ascii() && debug_starts_with_slash(c) } } }} } /// Constants associated with [`char`]s. /// /// Apart from the constants visibile on this page, the trait-based constants /// [`MIN`](crate::comparison::traits::Min::MIN), [`MAX`](crate::comparison::traits::Max::MAX), and /// [`NAME`](crate::named::Named::NAME) are also defined. pub mod constants; /// Functions for incrementing and decrementing [`char`]s. pub mod crement; /// Iterators that generate [`char`]s without repetition. pub mod exhaustive; #[cfg(feature = "random")] /// Iterators that generate [`char`]s randomly. pub mod random; malachite-base-0.4.16/src/chars/random.rs000064400000000000000000000350131046102023000162720ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::bools::random::{weighted_random_bools, WeightedRandomBools}; use crate::chars::char_is_graphic; use crate::chars::crement::{char_to_contiguous_range, contiguous_range_to_char, decrement_char}; use crate::comparison::traits::Min; use crate::num::random::{random_unsigned_inclusive_range, RandomUnsignedInclusiveRange}; use crate::random::Seed; use crate::vecs::{random_values_from_vec, RandomValuesFromVec}; /// Uniformly generates random [`char`]s in a closed interval. /// /// This `struct` is created by [`random_char_range`] and [`random_char_inclusive_range`]; see their /// documentation for more. #[derive(Clone, Debug)] pub struct RandomCharRange { chunks: RandomUnsignedInclusiveRange, } impl Iterator for RandomCharRange { type Item = char; #[inline] fn next(&mut self) -> Option { contiguous_range_to_char(self.chunks.next().unwrap()) } } /// Uniformly generates random [`char`]s in a closed interval, weighting graphic and non-graphic /// [`char`]s separately. /// /// This `struct` is created by [`graphic_weighted_random_char_range`] and /// [`graphic_weighted_random_char_inclusive_range`]; see their documentation for more. #[derive(Clone, Debug)] pub struct WeightedGraphicRandomCharRange { xs: WeightedRandomBools, graphic: RandomValuesFromVec, non_graphic: RandomValuesFromVec, } impl Iterator for WeightedGraphicRandomCharRange { type Item = char; fn next(&mut self) -> Option { if self.xs.next().unwrap() { self.graphic.next() } else { self.non_graphic.next() } } } /// Uniformly generates random [`char`]s. /// /// $P(c) = \frac{1}{2^{20}+2^{16}-2^{11}}$. /// /// The output length is infinite. /// /// # Worst-case complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::chars::random::random_chars; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// random_chars(EXAMPLE_SEED) /// .take(10) /// .collect::() /// .as_str(), /// "\u{5f771}\u{87234}\u{bcd36}\u{9e195}\u{5da07}\u{36553}\u{45028}\u{1cdfd}\u{d8530}\u{c7f2e}" /// ) /// ``` #[inline] pub fn random_chars(seed: Seed) -> RandomCharRange { random_char_inclusive_range(seed, char::MIN, char::MAX) } /// Uniformly generates random ASCII [`char`]s. /// /// $$ /// P(c) = \\begin{cases} /// 2^{-7} & \text{if} \\quad c < \\backslash\\text{u\\{0x80\\}} \\\\ /// 0 & \\text{otherwise} /// \\end{cases} /// $$ /// /// The output length is infinite. /// /// # Worst-case complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::chars::random::random_ascii_chars; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// random_ascii_chars(EXAMPLE_SEED) /// .take(20) /// .collect::() /// .as_str(), /// "q^\u{17}bF\\4T!/\u{1}q6\n/\u{11}Y\\wB" /// ) /// ``` #[inline] pub fn random_ascii_chars(seed: Seed) -> RandomCharRange { random_char_inclusive_range(seed, char::MIN, '\u{7f}') } /// Uniformly generates random [`char`]s in the half-open interval $[a, b)$. /// /// $a$ must be less than $b$. This function cannot create a range that includes `char::MAX`; for /// that, use [`random_char_inclusive_range`]. /// /// $$ /// P(x) = \\begin{cases} /// \frac{1} /// {\mathrm{char\\_to\\_contiguous\\_range(b)}-\mathrm{char\\_to\\_contiguous\\_range(a)}} & /// \text{if} \\quad a \leq x < b \\\\ /// 0 & \\text{otherwise} /// \\end{cases} /// $$ /// /// The output length is infinite. /// /// # Expected complexity per iteration /// Constant time and additional memory. /// /// # Panics /// Panics if $a \geq b$. /// /// # Examples /// ``` /// use malachite_base::chars::random::random_char_range; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// random_char_range(EXAMPLE_SEED, 'a', 'z') /// .take(50) /// .collect::() /// .as_str(), /// "rlewrsgkdlbeouylrelopxqkoonftexoshqulgvonioatekqes" /// ) /// ``` #[inline] pub fn random_char_range(seed: Seed, a: char, mut b: char) -> RandomCharRange { assert!(a < b, "a must be less than b. a: {a}, b: {b}"); decrement_char(&mut b); random_char_inclusive_range(seed, a, b) } /// Uniformly generates random [`char`]s in the closed interval $[a, b]$. /// /// $a$ must be less than or equal to $b$. /// /// $$ /// P(x) = \\begin{cases} /// \frac{1} /// {\mathrm{char\\_to\\_contiguous\\_range(b)}-\mathrm{char\\_to\\_contiguous\\_range(a)} /// +1} & /// \text{if} \\quad a \leq x < b \\\\ /// 0 & \\text{otherwise} /// \\end{cases} /// $$ /// /// The output length is infinite. /// /// # Expected complexity per iteration /// Constant time and additional memory. /// /// # Panics /// Panics if $a > b$. /// /// # Examples /// ``` /// use malachite_base::chars::random::random_char_inclusive_range; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// random_char_inclusive_range(EXAMPLE_SEED, 'a', 'z') /// .take(50) /// .collect::() /// .as_str(), /// "rlewrsgkdlbeouylrelopxqkoonftexoshqulgvonioatekqes" /// ) /// ``` #[inline] pub fn random_char_inclusive_range(seed: Seed, a: char, b: char) -> RandomCharRange { assert!(a <= b, "a must be less than or equal to b. a: {a}, b: {b}"); RandomCharRange { chunks: random_unsigned_inclusive_range( seed, char_to_contiguous_range(a), char_to_contiguous_range(b), ), } } /// Generates random [`char`]s, weighting graphic and non-graphic [`char`]s separately. /// /// See [`char_is_graphic`] for the definition of a graphic [`char`]. /// /// Let $n_p$ be `p_numerator` and $d_p$ be `p_denominator`, and let $p = p_n/p_d$. /// /// The set of graphic [`char`]s is selected with probability $p$, and the set of non-graphic /// [`char`]s with probability $1-p$. Then, a [`char`] is selected uniformly from the appropriate /// set. There are 142,523 graphic [`char`]s out of 1,112,064, so we have /// /// $$ /// P(x) = \\begin{cases} /// \frac{p}{142523} & \text{if} \\quad x \\ \\text{is} \\ \\text{graphic} \\\\ /// \frac{1-p}{969541} & \\text{otherwise} /// \\end{cases} /// $$ /// /// To recover the uniform distribution, use $p = 142523/1112064$, which is roughly $1/8$. /// /// The output length is infinite. /// /// # Expected complexity per iteration /// Constant time and additional memory. /// /// # Panics /// Panics if `p_denominator` is zero or `p_denominator > p_denominator`. /// /// # Examples /// ``` /// use malachite_base::chars::random::graphic_weighted_random_chars; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// graphic_weighted_random_chars(EXAMPLE_SEED, 10, 11) /// .take(20) /// .collect::() /// .as_str(), /// "𘋈𰒏礝깶ꅊ杽쭡𬝱╱𣑺⢍𰰬瀋\u{8daa8}𱽊ՠ𦧴\u{3805c}\u{d7447}𪂆" /// ) /// ``` #[inline] pub fn graphic_weighted_random_chars( seed: Seed, p_numerator: u64, p_denominator: u64, ) -> WeightedGraphicRandomCharRange { graphic_weighted_random_char_inclusive_range( seed, char::MIN, char::MAX, p_numerator, p_denominator, ) } /// Generates random ASCII [`char`]s, weighting graphic and non-graphic [`char`]s separately. /// /// See [`char_is_graphic`] for the definition of a graphic [`char`]. /// /// Let $n_p$ be `p_numerator` and $d_p$ be `p_denominator`, and let $p = p_n/p_d$. /// /// The set of graphic ASCII [`char`]s is selected with probability $p$, and the set of non-graphic /// ASCII [`char`]s with probability $1-p$. Then, a [`char`] is selected uniformly from the /// appropriate set. There are 95 graphic ASCII [`char`]s out of 128, so we have /// /// $$ /// P(x) = \\begin{cases} /// \frac{p}{95} & \text{if} \\quad /// x < \\backslash\\text{u\\{0x80\\}} \\ \\text{and} \\ x \\ \\text{is graphic} \\\\ /// \frac{1-p}{33} & \text{if} \\quad /// x < \\backslash\\text{u\\{0x80\\}} \\ \\text{and} \\ x \\ \\text{is not graphic} \\\\ /// 0 & \\text{otherwise} /// \\end{cases} /// $$ /// /// To recover the uniform distribution, use $p = 95/128$. /// /// The output length is infinite. /// /// # Expected complexity per iteration /// Constant time and additional memory. /// /// # Panics /// Panics if `p_denominator` is zero or `p_denominator > p_denominator`. /// /// # Examples /// ``` /// use malachite_base::chars::random::graphic_weighted_random_ascii_chars; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// graphic_weighted_random_ascii_chars(EXAMPLE_SEED, 10, 11) /// .take(40) /// .collect::() /// .as_str(), /// "x14N(bcXr$g)7\u{1b}/E+\u{8}\rf\u{2}\u{11}Y\u{11}Poo.$V2R.$V=6\u{13}\t\u{11}" /// ) /// ``` #[inline] pub fn graphic_weighted_random_ascii_chars( seed: Seed, p_numerator: u64, p_denominator: u64, ) -> WeightedGraphicRandomCharRange { graphic_weighted_random_char_inclusive_range( seed, char::MIN, '\u{7f}', p_numerator, p_denominator, ) } /// Generates random [`char`]s in the half-open interval $[a, b)$, weighting graphic and non-graphic /// [`char`]s separately. /// /// See [`char_is_graphic`] for the definition of a graphic [`char`]. /// /// Let $n_p$ be `p_numerator` and $d_p$ be `p_denominator`, and let $p = p_n/p_d$. /// /// The set of graphic [`char`]s in the specified range is selected with probability $p$, and the /// set of non-graphic [`char`]s in the range with probability $1-p$. Then, a [`char`] is selected /// uniformly from the appropriate set. /// /// $a$ must be less than $b$. Furthermore, $[a, b)$ must contain both graphic and non-graphic /// [`char`]s. This function cannot create a range that includes `char::MAX`; for that, use /// [`graphic_weighted_random_char_inclusive_range`]. /// /// Let $g$ be the number of graphic [`char`]s in $[a, b)$. Then we have /// /// $$ /// P(x) = \\begin{cases} /// \frac{p}{g} & a \leq x < b \\ \\text{and} \\ x \\ \\text{is graphic} \\\\ /// \frac{1-p}{b-a-g} & a \leq x < b \\ \\text{and} \\ x \\ \\text{is not graphic} \\\\ /// 0 & \\text{otherwise} /// \\end{cases} /// $$ /// /// To recover the uniform distribution, use $p = g/(b-a)$. /// /// The output length is infinite. /// /// # Expected complexity per iteration /// Constant time and additional memory. /// /// # Panics /// Panics if `p_denominator` is zero or `p_denominator > p_denominator`, if $a \geq b$, if $[a, b)$ /// contains no graphic [`char`]s, or if $[a, b)$ contains only graphic [`char`]s. /// /// # Examples /// ``` /// use malachite_base::chars::random::graphic_weighted_random_char_range; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// graphic_weighted_random_char_range(EXAMPLE_SEED, '\u{100}', '\u{400}', 10, 11) /// .take(30) /// .collect::() /// .as_str(), /// "ǘɂŜȢΙƘƣʅΰǟ˳ˊȇ\u{31b}ʰɥΈ\u{324}\u{35a}Ϟ\u{367}\u{337}ƃ\u{342}ʌμƢϳϪǰ" /// ) /// ``` #[inline] pub fn graphic_weighted_random_char_range( seed: Seed, a: char, mut b: char, p_numerator: u64, p_denominator: u64, ) -> WeightedGraphicRandomCharRange { assert!(a < b, "a must be less than b. a: {a}, b: {b}"); decrement_char(&mut b); graphic_weighted_random_char_inclusive_range(seed, a, b, p_numerator, p_denominator) } /// Generates random [`char`]s in the closed interval $[a, b]$, weighting graphic and non-graphic /// [`char`]s separately. /// /// See [`char_is_graphic`] for the definition of a graphic [`char`]. /// /// Let $n_p$ be `p_numerator` and $d_p$ be `p_denominator`, and let $p = p_n/p_d$. /// /// The set of graphic [`char`]s in the specified range is selected with probability $p$, and the /// set of non-graphic [`char`]s in the range with probability $1-p$. Then, a [`char`] is selected /// uniformly from the appropriate set. /// /// $a$ must be less than $b$. Furthermore, $[a, b]$ must contain both graphic and non-graphic /// [`char`]s. This function cannot create a range that includes `char::MAX`; for that, use /// [`graphic_weighted_random_char_inclusive_range`]. /// /// Let $g$ be the number of graphic [`char`]s in $[a, b]$. Then we have /// /// $$ /// P(x) = \\begin{cases} /// \frac{p}{g} & a \leq x < b \\ \\text{and} \\ x \\ \\text{is graphic} \\\\ /// \frac{1-p}{b-a-g+1} & a \leq x < b \\ \\text{and} \\ x \\ \\text{is not graphic} \\\\ /// 0 & \\text{otherwise} /// \\end{cases} /// $$ /// /// To recover the uniform distribution, use $p = g/(b-a+1)$. /// /// The output length is infinite. /// /// # Expected complexity per iteration /// Constant time and additional memory. /// /// # Panics /// Panics if `p_denominator` is zero or `p_denominator > p_denominator`, if $a > b$, if $[a, b]$ /// contains no graphic [`char`]s, or if $[a, b]$ contains only graphic [`char`]s. /// /// # Examples /// ``` /// use malachite_base::chars::random::graphic_weighted_random_char_inclusive_range; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// graphic_weighted_random_char_inclusive_range(EXAMPLE_SEED, '\u{100}', '\u{3ff}', 10, 11) /// .take(30) /// .collect::() /// .as_str(), /// "ǘɂŜȢΙƘƣʅΰǟ˳ˊȇ\u{31b}ʰɥΈ\u{324}\u{35a}Ϟ\u{367}\u{337}ƃ\u{342}ʌμƢϳϪǰ" /// ) /// ``` pub fn graphic_weighted_random_char_inclusive_range( seed: Seed, a: char, b: char, p_numerator: u64, p_denominator: u64, ) -> WeightedGraphicRandomCharRange { assert!(a <= b, "a must be less than or equal to b. a: {a}, b: {b}"); let (graphic_chars, non_graphic_chars): (Vec<_>, Vec<_>) = (a..=b).partition(|&c| char_is_graphic(c)); assert!( !graphic_chars.is_empty(), "The range {a:?}..={b:?} contains no graphic chars" ); assert!( !non_graphic_chars.is_empty(), "The range {a:?}..={b:?} only contains graphic chars" ); WeightedGraphicRandomCharRange { xs: weighted_random_bools(seed.fork("xs"), p_numerator, p_denominator), graphic: random_values_from_vec(seed.fork("graphic"), graphic_chars), non_graphic: random_values_from_vec(seed.fork("non_graphic"), non_graphic_chars), } } malachite-base-0.4.16/src/comparison/macros.rs000064400000000000000000000032771046102023000173570ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . /// Computes the minimum of a list of expressions. /// /// The list must be nonempty, the expressions must all have the same type, and that type must /// implement [`Ord`]. Each expression is only evaluated once. /// /// # Examples /// ``` /// use malachite_base::min; /// /// assert_eq!(min!(3), 3); /// assert_eq!(min!(3, 1), 1); /// assert_eq!(min!(3, 1, 4), 1); /// ``` #[macro_export] macro_rules! min { ($first: expr $(,$next: expr)*) => { { let mut min = $first; $( let next = $next; if next < min { min = next; } )* min } }; } /// Computes the maximum of a list of expressions. /// /// The list must be nonempty, the expressions must all have the same type, and that type must /// implement [`Ord`]. Each expression is only evaluated once. /// /// # Examples /// ``` /// use malachite_base::max; /// /// assert_eq!(max!(3), 3); /// assert_eq!(max!(3, 1), 3); /// assert_eq!(max!(3, 1, 4), 4); /// ``` #[macro_export] macro_rules! max { ($first: expr $(,$next: expr)*) => { { let mut max = $first; $( let next = $next; if next > max { max = next; } )* max } }; } malachite-base-0.4.16/src/comparison/mod.rs000064400000000000000000000010551046102023000166420ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . /// Macros related to comparing values. /// /// This module defines the `min` and `max` macros. #[macro_use] pub mod macros; /// Traits related to comparing values. pub mod traits; malachite-base-0.4.16/src/comparison/traits.rs000064400000000000000000000013051046102023000173670ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . /// Defines the minimum value of a type. #[allow(clippy::declare_interior_mutable_const)] pub trait Min { /// The minimum value of `Self`. const MIN: Self; } /// Defines the maximum value of a type. #[allow(clippy::declare_interior_mutable_const)] pub trait Max { /// The maximum value of `Self`. const MAX: Self; } malachite-base-0.4.16/src/iterators/bit_distributor.rs000064400000000000000000000335051046102023000211420ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::basic::integers::PrimitiveInt; use crate::num::logic::traits::{BitConvertible, NotAssign}; use alloc::vec::Vec; use core::fmt::Debug; const COUNTER_WIDTH: usize = u64::WIDTH as usize; /// This struct is used to configure [`BitDistributor`]s. /// /// See the [`BitDistributor`] documentation for more. #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] pub struct BitDistributorOutputType { weight: usize, // 0 means a tiny output_type max_bits: Option, } impl BitDistributorOutputType { /// Creates a normal output with a specified weight. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `weight` is zero. /// /// The corresponding element grows as a power of $i$. See the [`BitDistributor`] documentation /// for more. pub fn normal(weight: usize) -> BitDistributorOutputType { assert_ne!(weight, 0); BitDistributorOutputType { weight, max_bits: None, } } /// Creates a tiny output. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// The corresponding element grows logarithmically. See the [`BitDistributor`] documentation /// for more. pub const fn tiny() -> BitDistributorOutputType { BitDistributorOutputType { weight: 0, max_bits: None, } } } /// Helps generate tuples exhaustively. /// /// Think of `counter` as the bits of an integer. It's initialized to zero (all `false`s), and as /// it's repeatedly incremented, it eventually takes on every 64-bit value. /// /// `output_types` is a list of $n$ configuration structs that, together, specify how to generate an /// n-element tuple of unsigned integers. Calling `get_output` repeatedly, passing in 0 through $n - /// 1$ as `index`, distributes the bits of `counter` into a tuple. /// /// This is best shown with an example. If `output_types` is set to /// `[BitDistributorOutputType::normal(1); 2]`, the distributor will generate all pairs of unsigned /// integers. A pair may be extracted by calling `get_output(0)` and `get_output(1)`; then `counter` /// may be incremented to create the next pair. In this case, the pairs will be $(0, 0), (0, 1), (1, /// 0), (1, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 0), (2, 1), \ldots$. /// /// If you think of these pairs as coordinates in the $xy$-plane, they are traversed along a /// [Z-order curve](https://en.wikipedia.org/wiki/Z-order_curve). Every pair of unsigned integers /// will be generated exactly once. /// /// In general, setting `output_types` to `[BitDistributorOutputType::normal(1); n]` will generate /// $n$-tuples. The elements of the tuples will be very roughly the same size, in the sense that /// each element will grow as $O(\sqrt\[n\]{i})$, where $i$ is the counter. Sometimes we want the /// elements to grow at different rates. To accomplish this, we can change the weights of the output /// types. For example, if we set `output_types` to `[BitDistributorOutputType::normal(1), /// BitDistributorOutputType::normal(2)]`, the first element of the generated pairs will grow as /// $O(\sqrt\[3\]{i})$ and the second as $O(i^{2/3})$. In general, if the weights are $w_0, w_1, /// \\ldots, w_{n-1}$, then the $k$th element of the output tuples will grow as /// $O(i^{w_i/\sum_{j=0}^{n-1}w_j})$. /// /// Apart from creating _normal_ output types with different weights, we can create _tiny_ output /// types, which indicate that the corresponding tuple element should grow especially slowly. If /// `output_types` contains $m$ tiny output types, each tiny tuple element grows as /// $O(\sqrt\[m\]{\log i})$. The growth of the other elements is unaffected. Having only tiny types /// in `output_types` is disallowed. /// /// The above discussion of growth rates assumes that `max_bits` is not specified for any output /// type. But if `max_bits` is set to $b$, then the corresponding element will start growing just as /// if `max_bits` wasn't specified, but will stop growing once it reaches $2^b-1$. #[derive(Clone, Debug, Eq, PartialEq, Hash)] pub struct BitDistributor { #[cfg(feature = "test_build")] pub output_types: Vec, #[cfg(not(feature = "test_build"))] output_types: Vec, bit_map: [usize; COUNTER_WIDTH], counter: [bool; COUNTER_WIDTH], } impl BitDistributor { fn new_without_init(output_types: &[BitDistributorOutputType]) -> BitDistributor { if output_types .iter() .all(|output_type| output_type.weight == 0) { panic!("All output_types cannot be tiny"); } BitDistributor { output_types: output_types.to_vec(), bit_map: [0; COUNTER_WIDTH], counter: [false; COUNTER_WIDTH], } } /// Creates a new [`BitDistributor`]. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `output_types.len()`. /// /// # Examples /// ``` /// use malachite_base::iterators::bit_distributor::{ /// BitDistributor, BitDistributorOutputType, /// }; /// /// BitDistributor::new(&[ /// BitDistributorOutputType::normal(2), /// BitDistributorOutputType::tiny(), /// ]); /// ``` pub fn new(output_types: &[BitDistributorOutputType]) -> BitDistributor { let mut distributor = BitDistributor::new_without_init(output_types); distributor.update_bit_map(); distributor } /// Returns a reference to the internal bit map as a slice. /// /// The bit map determines which output gets each bit of the counter. For example, if the bit /// map is $[0, 1, 0, 1, 0, 1, \ldots]$, then the first element of the output pair gets the bits /// with indices $0, 2, 4, \ldots$ and the second element gets the bits with indices $1, 3, 5, /// \ldots$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::bit_distributor::{ /// BitDistributor, BitDistributorOutputType, /// }; /// /// let bd = BitDistributor::new(&[ /// BitDistributorOutputType::normal(2), /// BitDistributorOutputType::tiny(), /// ]); /// assert_eq!( /// bd.bit_map_as_slice(), /// &[ /// 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /// 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /// 0, 0, 0, 0, 0, 0, 0, 1 /// ][..] /// ); /// ``` pub fn bit_map_as_slice(&self) -> &[usize] { self.bit_map.as_ref() } fn update_bit_map(&mut self) { let (mut normal_output_type_indices, mut tiny_output_type_indices): ( Vec, Vec, ) = (0..self.output_types.len()).partition(|&i| self.output_types[i].weight != 0); let mut normal_output_types_bits_used = vec![0; normal_output_type_indices.len()]; let mut tiny_output_types_bits_used = vec![0; tiny_output_type_indices.len()]; let mut ni = normal_output_type_indices.len() - 1; let mut ti = tiny_output_type_indices.len().saturating_sub(1); let mut weight_counter = self.output_types[normal_output_type_indices[ni]].weight; for i in 0..COUNTER_WIDTH { let use_normal_output_type = !normal_output_type_indices.is_empty() && (tiny_output_type_indices.is_empty() || !usize::is_power_of_two(i + 1)); if use_normal_output_type { self.bit_map[i] = normal_output_type_indices[ni]; let output_type = self.output_types[normal_output_type_indices[ni]]; normal_output_types_bits_used[ni] += 1; weight_counter -= 1; if output_type.max_bits == Some(normal_output_types_bits_used[ni]) { normal_output_type_indices.remove(ni); normal_output_types_bits_used.remove(ni); if normal_output_type_indices.is_empty() { continue; } weight_counter = 0; } if weight_counter == 0 { if ni == 0 { ni = normal_output_type_indices.len() - 1; } else { ni -= 1; } weight_counter = self.output_types[normal_output_type_indices[ni]].weight; } } else { if tiny_output_type_indices.is_empty() { self.bit_map[i] = usize::MAX; continue; } self.bit_map[i] = tiny_output_type_indices[ti]; let output_type = self.output_types[tiny_output_type_indices[ti]]; tiny_output_types_bits_used[ti] += 1; if output_type.max_bits == Some(tiny_output_types_bits_used[ti]) { tiny_output_type_indices.remove(ti); tiny_output_types_bits_used.remove(ti); if tiny_output_type_indices.is_empty() { continue; } } if ti == 0 { ti = tiny_output_type_indices.len() - 1; } else { ti -= 1; } } } } /// Sets the maximum bits for several outputs. /// /// Given slice of output indices, sets the maximum bits for each of the outputs and rebuilds /// the bit map. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `output_type_indices.len()`. /// /// # Panics /// Panics if `max_bits` is 0 or if any index is greater than or equal to /// `self.output_types.len()`. /// /// # Examples /// ``` /// use malachite_base::iterators::bit_distributor::{ /// BitDistributor, BitDistributorOutputType, /// }; /// /// let mut bd = BitDistributor::new(&[BitDistributorOutputType::normal(2); 3]); /// assert_eq!( /// bd.bit_map_as_slice(), /// &[ /// 2, 2, 1, 1, 0, 0, 2, 2, 1, 1, 0, 0, 2, 2, 1, 1, 0, 0, 2, 2, 1, 1, 0, 0, 2, 2, 1, 1, /// 0, 0, 2, 2, 1, 1, 0, 0, 2, 2, 1, 1, 0, 0, 2, 2, 1, 1, 0, 0, 2, 2, 1, 1, 0, 0, 2, 2, /// 1, 1, 0, 0, 2, 2, 1, 1 /// ][..] /// ); /// /// bd.set_max_bits(&[0, 2], 5); /// assert_eq!( /// bd.bit_map_as_slice(), /// &[ /// 2, 2, 1, 1, 0, 0, 2, 2, 1, 1, 0, 0, 2, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /// 1, 1, 1, 1, 1, 1, 1, 1 /// ][..] /// ); /// ``` pub fn set_max_bits(&mut self, output_type_indices: &[usize], max_bits: usize) { assert_ne!(max_bits, 0); for &index in output_type_indices { self.output_types[index].max_bits = Some(max_bits); } self.update_bit_map(); } /// Increments the counter in preparation for a new set of outputs. /// /// If the counter is incremented $2^{64}$ times, it rolls back to 0. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::bit_distributor::{ /// BitDistributor, BitDistributorOutputType, /// }; /// /// let mut bd = BitDistributor::new(&[BitDistributorOutputType::normal(1)]); /// let mut outputs = Vec::new(); /// for _ in 0..20 { /// outputs.push(bd.get_output(0)); /// bd.increment_counter(); /// } /// assert_eq!( /// outputs, /// &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] /// ); /// ``` pub fn increment_counter(&mut self) { for b in &mut self.counter { b.not_assign(); if *b { break; } } } /// Gets the output at a specified index. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `index` is greater than or equal to `self.output_types.len()`. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::iterators::bit_distributor::{ /// BitDistributor, BitDistributorOutputType, /// }; /// /// let mut bd = BitDistributor::new(&[BitDistributorOutputType::normal(1); 2]); /// let mut outputs = Vec::new(); /// for _ in 0..10 { /// outputs.push((0..2).map(|i| bd.get_output(i)).collect_vec()); /// bd.increment_counter(); /// } /// let expected_outputs: &[&[usize]] = &[ /// &[0, 0], /// &[0, 1], /// &[1, 0], /// &[1, 1], /// &[0, 2], /// &[0, 3], /// &[1, 2], /// &[1, 3], /// &[2, 0], /// &[2, 1], /// ]; /// assert_eq!(outputs, expected_outputs); /// ``` pub fn get_output(&self, index: usize) -> usize { assert!(index < self.output_types.len()); usize::from_bits_asc( self.bit_map .iter() .zip(self.counter.iter()) .filter_map(|(&m, &c)| if m == index { Some(c) } else { None }), ) } } malachite-base-0.4.16/src/iterators/comparison.rs000064400000000000000000000164211046102023000201020ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use core::cmp::Ordering::{self, *}; /// An iterator that generates the [`Ordering`]s of adjacent elements of a given iterator. /// /// This `struct` is created by [`delta_directions`]; see its documentation for more. #[derive(Clone, Debug)] pub struct DeltaDirections where I::Item: Ord, { previous: Option, xs: I, } impl Iterator for DeltaDirections where I::Item: Ord, { type Item = Ordering; fn next(&mut self) -> Option { if self.previous.is_none() { if let Some(x) = self.xs.next() { self.previous = Some(x); } else { return None; } } self.xs.next().and_then(|x| { let result = Some(x.cmp(self.previous.as_ref().unwrap())); self.previous = Some(x); result }) } } /// Returns an iterator that generates the [`Ordering`]s of adjacent pairs of elements of a given /// iterator. /// /// To put it another way (at least for types where subtraction is defined), the returned iterator /// produces the signs of the finite differences of the input iterator. /// /// $f((x_k)_{k=0}^N) = (\\operatorname{cmp}(x_k, x\_{k-1}))\_{k=1}^N$, where $N$ may be $\infty$. /// /// The output length is infinite if `xs` is infinite, or $\max(n - 1, 0)$ otherwise, where $n$ is /// `xs.count()`. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::iterators::comparison::delta_directions; /// use std::cmp::Ordering::*; /// /// assert_eq!( /// delta_directions([3, 1, 4, 1, 5, 9].into_iter()).collect_vec(), /// &[Less, Greater, Less, Greater, Greater] /// ) /// ``` #[inline] pub const fn delta_directions(xs: I) -> DeltaDirections where I::Item: Ord, { DeltaDirections { previous: None, xs } } /// Determines whether each element of an iterator is greater than the preceding one. /// /// This function will hang if given an infinite strictly ascending iterator. /// /// $$ /// f((x_k)\_{k=0}^N) = \\bigwedge\_{k=1}^N{x\_k > x\_{k-1}}, /// $$ /// where $N$ may be $\infty$. /// /// # Examples /// ``` /// use malachite_base::iterators::comparison::is_strictly_ascending; /// /// assert_eq!(is_strictly_ascending([1, 2, 3, 4].into_iter()), true); /// assert_eq!(is_strictly_ascending([1, 2, 2, 4].into_iter()), false); /// ``` #[inline] pub fn is_strictly_ascending(xs: I) -> bool where I::Item: Ord, { delta_directions(xs).all(|x| x == Greater) } /// Determines whether each element of an iterator is less than the preceding one. /// /// This function will hang if given an infinite strictly descending iterator. /// /// $$ /// f((x_k)\_{k=0}^N) = \\bigwedge\_{k=1}^N{x\_k < x\_{k-1}}, /// $$ /// where $N$ may be $\infty$. /// /// # Examples /// ``` /// use malachite_base::iterators::comparison::is_strictly_descending; /// /// assert_eq!(is_strictly_descending([4, 3, 2, 1].into_iter()), true); /// assert_eq!(is_strictly_descending([4, 2, 2, 1].into_iter()), false); /// ``` #[inline] pub fn is_strictly_descending(xs: I) -> bool where I::Item: Ord, { delta_directions(xs).all(|x| x == Less) } /// Determines whether each element of an iterator is greater than or equal to the preceding one. /// /// This function will hang if given an infinite weakly ascending iterator. /// /// $$ /// f((x_k)\_{k=0}^N) = \\bigwedge\_{k=1}^N{x\_k \geq x\_{k-1}}, /// $$ /// where $N$ may be $\infty$. /// /// # Examples /// ``` /// use malachite_base::iterators::comparison::is_weakly_ascending; /// /// assert_eq!(is_weakly_ascending([1, 2, 3, 4].into_iter()), true); /// assert_eq!(is_weakly_ascending([1, 2, 2, 4].into_iter()), true); /// assert_eq!(is_weakly_ascending([1, 3, 2, 4].into_iter()), false); /// ``` #[inline] pub fn is_weakly_ascending(xs: I) -> bool where I::Item: Ord, { delta_directions(xs).all(|x| x != Less) } /// Determines whether each element of an iterator is less than or equal to the preceding one. /// /// This function will hang if given an infinite weakly descending iterator. /// /// $$ /// f((x_k)\_{k=0}^N) = \\bigwedge\_{k=1}^N{x\_k \leq x\_{k-1}}, /// $$ /// where $N$ may be $\infty$. /// /// # Examples /// ``` /// use malachite_base::iterators::comparison::is_weakly_descending; /// /// assert_eq!(is_weakly_descending([4, 3, 2, 1].into_iter()), true); /// assert_eq!(is_weakly_descending([4, 2, 2, 1].into_iter()), true); /// assert_eq!(is_weakly_descending([4, 2, 3, 1].into_iter()), false); /// ``` #[inline] pub fn is_weakly_descending(xs: I) -> bool where I::Item: Ord, { delta_directions(xs).all(|x| x != Greater) } /// Determines whether the sequence strictly zigzags. /// /// A strictly zigzagging sequence is one where every odd-indexed element is greater than its /// even-indexed neighbors, or one where every odd-indexed element is less than its even-indexed /// neighbors. /// /// This function will hang if given an infinite strictly zigzagging iterator. /// /// # Examples /// ``` /// use malachite_base::iterators::comparison::is_strictly_zigzagging; /// /// assert_eq!(is_strictly_zigzagging([1, 2, 3, 4].into_iter()), false); /// assert_eq!(is_strictly_zigzagging([4, 3, 2, 1].into_iter()), false); /// assert_eq!(is_strictly_zigzagging([1, 3, 2, 4].into_iter()), true); /// assert_eq!(is_strictly_zigzagging([1, 2, 2, 4].into_iter()), false); /// ``` pub fn is_strictly_zigzagging(xs: I) -> bool where I::Item: Ord, { let mut previous = None; for direction in delta_directions(xs) { if direction == Equal { return false; } if let Some(previous) = previous { if direction == previous { return false; } } previous = Some(direction); } true } /// Determines whether the sequence weakly zigzags. /// /// A weakly zigzagging sequence is one where every odd-indexed element is greater than or equal to /// its even-indexed neighbors, or one where every odd-indexed element is less than or equal to its /// even-indexed neighbors. /// /// This function will hang if given an infinite strictly zigzagging iterator. /// /// # Examples /// ``` /// use malachite_base::iterators::comparison::is_weakly_zigzagging; /// /// assert_eq!(is_weakly_zigzagging([1, 2, 3, 4].into_iter()), false); /// assert_eq!(is_weakly_zigzagging([4, 3, 2, 1].into_iter()), false); /// assert_eq!(is_weakly_zigzagging([1, 3, 2, 4].into_iter()), true); /// assert_eq!(is_weakly_zigzagging([1, 2, 2, 4].into_iter()), true); /// ``` pub fn is_weakly_zigzagging(xs: I) -> bool where I::Item: Ord, { let mut previous = None; for direction in delta_directions(xs) { if let Some(ref mut previous) = &mut previous { if direction == *previous { return false; } *previous = previous.reverse(); } else if direction != Equal { previous = Some(direction); } } true } malachite-base-0.4.16/src/iterators/iterator_cache.rs000064400000000000000000000117531046102023000207070ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use alloc::vec::Vec; /// Remembers values produced by an iterator. /// /// After wrapping an iterator with an `IteratorCache`, you can retrieve a reference to the $n$th /// element of an iterator, and then retrieve a reference to the $m$th element in constant time for /// any $m \leq n$ (not counting the time it took to first get the $n$th element). #[derive(Clone, Debug)] pub struct IteratorCache { xs: I, cache: Vec, done: bool, } impl IteratorCache { /// Creates a new `IteratorCache`. /// /// This function does not allocate any memory or advance the iterator. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::iterator_cache::IteratorCache; /// /// IteratorCache::new([1, 2, 3].iter()); /// ``` pub const fn new(xs: I) -> IteratorCache { IteratorCache { xs, cache: Vec::new(), done: false, } } /// Retrieves the $n$th element of an iterator. Indexing starts at 0. /// /// If the index is higher than any other previously-requested index, the iterator is advanced /// to that index, or until it runs out. If the iterator has previously been advanced past the /// index, the requested element is returned from the cache in constant time. If the iterator is /// too short to have an element at the index, `None` is returned. /// /// If you know that the element is present, and want to only take an immutable reference to /// `self`, consider using [`assert_get`](Self::assert_get) instead. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is 1 if `get` has previously been /// called with an index at least this large, or `index` otherwise. /// /// # Examples /// ``` /// use malachite_base::iterators::iterator_cache::IteratorCache; /// /// let mut xs = IteratorCache::new([1, 2, 3].iter().cloned()); /// assert_eq!(xs.get(1), Some(&2)); /// assert_eq!(xs.get(0), Some(&1)); /// assert_eq!(xs.get(3), None); /// assert_eq!(xs.get(2), Some(&3)); /// ``` pub fn get(&mut self, index: usize) -> Option<&I::Item> { if !self.done && index >= self.cache.len() { self.cache .extend((&mut self.xs).take(index - self.cache.len() + 1)); if index >= self.cache.len() { self.done = true; return None; } } self.cache.get(index) } /// Retrieves the $n$th element of an iterator, while asserting that the iterator has already /// reached that element. Indexing starts at 0. /// /// If the iterator has not advanced that far, or if it has fewer than $n + 1$ elements, this /// function panics. /// /// The purpose of this function is to allow the caller to get an element immutably, assuming /// that the caller knows that the element is present. The [`get`](Self::get) function has to /// take a mutable reference. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::iterator_cache::IteratorCache; /// /// let mut xs = IteratorCache::new([1, 2, 3].iter().cloned()); /// // Force the iterator to iterate to completion /// xs.get(3); /// assert_eq!(xs.assert_get(1), &2); /// assert_eq!(xs.assert_get(0), &1); /// assert_eq!(xs.assert_get(2), &3); /// ``` pub fn assert_get(&self, index: usize) -> &I::Item { self.cache.get(index).unwrap() } /// Returns the total number of elements in the iterator, if the iterator has been completely /// consumed. /// /// If the iterator has not been completely consumed yet, returns `None`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::iterator_cache::IteratorCache; /// /// let mut xs = IteratorCache::new([1, 2, 3].iter().cloned()); /// assert_eq!(xs.known_len(), None); /// assert_eq!(xs.get(1), Some(&2)); /// assert_eq!(xs.known_len(), None); /// assert_eq!(xs.get(0), Some(&1)); /// assert_eq!(xs.get(3), None); /// assert_eq!(xs.known_len(), Some(3)); /// assert_eq!(xs.get(2), Some(&3)); /// ``` pub fn known_len(&self) -> Option { if self.done { Some(self.cache.len()) } else { None } } } malachite-base-0.4.16/src/iterators/mod.rs000064400000000000000000000410711046102023000165060ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . #[cfg(feature = "random")] use crate::bools::random::{weighted_random_bools, WeightedRandomBools}; use crate::num::arithmetic::traits::Parity; use crate::num::basic::traits::Zero; #[cfg(feature = "random")] use crate::random::Seed; #[cfg(feature = "random")] use crate::vecs::{random_values_from_vec, RandomValuesFromVec}; use alloc::collections::VecDeque; use alloc::string::{String, ToString}; use alloc::vec::Vec; use core::fmt::Display; use core::hash::Hash; use hashbrown::HashSet; use itertools::Itertools; /// Generates all the nonzero values of a provided iterator. /// /// This `struct` is created by [`nonzero_values`]; see its documentation for more. #[derive(Clone, Debug)] pub struct NonzeroValues(I) where I::Item: PartialEq + Zero; impl Iterator for NonzeroValues where I::Item: PartialEq + Zero, { type Item = I::Item; #[inline] fn next(&mut self) -> Option { loop { let x = self.0.next(); if x != Some(I::Item::ZERO) { return x; } } } } impl DoubleEndedIterator for NonzeroValues where I::Item: PartialEq + Zero, { #[inline] fn next_back(&mut self) -> Option { loop { let x = self.0.next_back(); if x != Some(I::Item::ZERO) { return x; } } } } /// Returns an iterator that generates all the nonzero values of a provided iterator. /// /// `nonzero_values(xs)` generates the same values as `xs.filter(|x| x != I::Item::ZERO)`, but its /// type is easier to work with. /// /// This iterator will hang if given an iterator that produces an infinite suffix of zeros. /// /// The output length is the number of nonzero values produced by `xs`. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::iterators::nonzero_values; /// /// assert_eq!( /// nonzero_values([-3i8, -2, -1, 0, 1, 2, 3].iter().cloned()).collect_vec(), /// &[-3, -2, -1, 1, 2, 3] /// ) /// ``` #[inline] pub const fn nonzero_values(xs: I) -> NonzeroValues where I::Item: PartialEq + Zero, { NonzeroValues(xs) } /// Returns whether all of the values generated by an iterator are equal. /// /// `is_constant(xs)` is equivalent to `xs.unique().count() == 1` for finite nonempty iterators, but /// is more efficient, doesn't require [`Clone`] or [`Hash`] implementations, and doesn't hang if /// provided an infinite non-constant iterator. /// /// This function will hang if given an infinite constant iterator. /// /// # Examples /// ``` /// use malachite_base::iterators::is_constant; /// /// assert_eq!(is_constant([1; 4].iter()), true); /// assert_eq!(is_constant([1, 2, 3, 4].iter()), false); /// assert_eq!(is_constant(0..), false); /// ``` pub fn is_constant(xs: I) -> bool where I::Item: Eq, { let mut first = None; for x in xs { if let Some(ref first) = first { if x != *first { return false; } } else { first = Some(x); } } true } /// Returns whether an iterator returns at least some number of values. /// /// `count_is_at_least(xs, n)` is equivalent to `xs.count() >= n` for finite iterators, but doesn't /// hang if provided an infinite iterator. /// /// # Examples /// ``` /// use malachite_base::iterators::count_is_at_least; /// /// assert_eq!(count_is_at_least([1, 2, 3, 4].iter(), 3), true); /// assert_eq!(count_is_at_least([1, 2, 3, 4].iter(), 4), true); /// assert_eq!(count_is_at_least([1, 2, 3, 4].iter(), 5), false); /// assert_eq!(count_is_at_least(0.., 5), true); /// ``` #[inline] pub fn count_is_at_least(xs: I, n: usize) -> bool { xs.take(n).count() == n } /// Returns whether an iterator returns at most some number of values. /// /// `count_is_at_most(xs, n)` is equivalent to `xs.count() <= n` for finite iterators, but doesn't /// hang if provided an infinite iterator. /// /// # Examples /// ``` /// use malachite_base::iterators::count_is_at_most; /// /// assert_eq!(count_is_at_most([1, 2, 3, 4].iter(), 3), false); /// assert_eq!(count_is_at_most([1, 2, 3, 4].iter(), 4), true); /// assert_eq!(count_is_at_most([1, 2, 3, 4].iter(), 5), true); /// assert_eq!(count_is_at_most(0.., 5), false); /// ``` #[inline] pub fn count_is_at_most(xs: I, n: usize) -> bool { xs.take(n + 1).count() <= n } /// Returns whether an iterator never returns the same value twice. /// /// `is_unique(xs)` is equivalent to `xs.unique().count() <= 1` for finite iterators, but is more /// efficient and doesn't hang if provided a non-unique infinite iterator. /// /// This iterator will hang if given an infinite unique iterator. /// /// # Examples /// ``` /// use malachite_base::iterators::is_unique; /// /// let empty: [u32; 0] = []; /// assert_eq!(is_unique(empty.iter()), true); /// assert_eq!(is_unique([1, 2, 3, 4].iter()), true); /// assert_eq!(is_unique([1, 2, 3, 1].iter()), false); /// assert_eq!(is_unique((0..).map(|i| i / 2)), false); /// ``` #[inline] pub fn is_unique(xs: I) -> bool where I::Item: Eq + Hash, { let mut set = HashSet::new(); for x in xs { if !set.insert(x) { return false; } } true } /// Returns the first and last elements of an iterator, or `None` if it is empty. /// /// The iterator's elements must be cloneable, since if the iterator consists of a single element /// `x`, the result will be `(x, x)`. /// /// This iterator will hang if given an infinite iterator. /// /// # Examples /// ``` /// use malachite_base::iterators::first_and_last; /// /// let empty: [u32; 0] = []; /// assert_eq!(first_and_last(&mut empty.iter()), None); /// assert_eq!(first_and_last(&mut [1].iter().cloned()), Some((1, 1))); /// assert_eq!(first_and_last(&mut [1, 2, 3].iter().cloned()), Some((1, 3))); /// ``` pub fn first_and_last(xs: &mut I) -> Option<(I::Item, I::Item)> where I::Item: Clone, { xs.next().map(|first| { if let Some(last) = xs.last() { (first, last) } else { (first.clone(), first) } }) } /// Groups elements of an iterator into intervals of adjacent elements that match a predicate. The /// endpoints of each interval are returned. /// /// The intervals are inclusive. /// /// This iterator will hang if given an infinite iterator. /// /// # Examples /// ``` /// use malachite_base::iterators::matching_intervals_in_iterator; /// /// let xs = &[1, 2, 10, 11, 12, 7, 8, 16, 5]; /// assert_eq!( /// matching_intervals_in_iterator(xs.iter().cloned(), |&x| x >= 10).as_slice(), /// &[(10, 12), (16, 16)] /// ); /// assert_eq!( /// matching_intervals_in_iterator(xs.iter().cloned(), |&x| x < 10).as_slice(), /// &[(1, 2), (7, 8), (5, 5)] /// ); /// ``` pub fn matching_intervals_in_iterator bool>( xs: I, predicate: F, ) -> Vec<(I::Item, I::Item)> where I::Item: Clone, { xs.group_by(predicate) .into_iter() .filter_map(|(b, mut group)| if b { first_and_last(&mut group) } else { None }) .collect() } #[cfg(feature = "random")] /// An iterator that randomly produces another iterator's values, or produces a special value. /// /// This `struct` is created by [`with_special_value`]; see its documentation for more. #[derive(Clone, Debug)] pub struct WithSpecialValue where I::Item: Clone, { bs: WeightedRandomBools, special_value: I::Item, xs: I, } #[cfg(feature = "random")] impl Iterator for WithSpecialValue where I::Item: Clone, { type Item = I::Item; fn next(&mut self) -> Option { if self.bs.next().unwrap() { Some(self.special_value.clone()) } else { self.xs.next() } } } #[cfg(feature = "random")] /// An iterator that randomly produces another iterator's values, or produces a special value. /// /// Let $n_p$ be `p_numerator`, $d_p$ be `p_denominator`, and let $p=n_p/d_p$. /// /// Every time a value is to be generated, the iterator returns the special value with probability /// $p$, or else returns a value from the inner iterator. /// /// If $p > 0$, the output length is infinite. Otherwise, it is the same as the length of `xs`. /// /// # Panics /// Panics if `p_denominator` is 0 or `p_numerator` is greater than `p_denominator`. /// /// # Examples /// ``` /// use malachite_base::iterators::{prefix_to_string, with_special_value}; /// use malachite_base::num::random::random_primitive_ints; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string( /// with_special_value(EXAMPLE_SEED, -1i16, 1, 2, &random_primitive_ints::), /// 20 /// ), /// "[-1, -1, -1, 2901, -1, -14200, -1, -1, -1, -30997, -8245, -5338, -1, -1, -20007, -1, -1, \ /// -1, -1, -1, ...]" /// ); /// ``` pub fn with_special_value( seed: Seed, special_value: I::Item, p_numerator: u64, p_denominator: u64, xs_gen: &dyn Fn(Seed) -> I, ) -> WithSpecialValue where I::Item: Clone, { WithSpecialValue { bs: weighted_random_bools(seed.fork("bs"), p_numerator, p_denominator), special_value, xs: xs_gen(seed.fork("xs")), } } #[cfg(feature = "random")] /// An iterator that randomly produces another iterator's values, or samples from a [`Vec`] of /// special values. /// /// This `struct` is created by [`with_special_values`]; see its documentation for more. #[derive(Clone, Debug)] pub struct WithSpecialValues where I::Item: Clone, { bs: WeightedRandomBools, special_values: RandomValuesFromVec, xs: I, } #[cfg(feature = "random")] impl Iterator for WithSpecialValues where I::Item: Clone, { type Item = I::Item; fn next(&mut self) -> Option { if self.bs.next().unwrap() { self.special_values.next() } else { self.xs.next() } } } #[cfg(feature = "random")] /// An iterator that randomly produces another iterator's values, or produces a random special value /// from a [`Vec`]. /// /// Let $n_p$ be `p_numerator`, $d_p$ be `p_denominator`, and let $p=n_p/d_p$. /// /// Every time a value is to be generated, the iterator uniformly samples the special values [`Vec`] /// with probability $p$, or else returns a value from the inner iterator. /// /// If $p > 0$, the output length is infinite. Otherwise, it is the same as the length of `xs`. /// /// # Worst-case complexity per iteration /// Constant time and additional memory. /// /// # Panics /// Panics if `special_values` is empty, `p_denominator` is 0, or if `p_numerator` is greater than /// `p_denominator`. /// /// # Examples /// ``` /// use malachite_base::iterators::{prefix_to_string, with_special_values}; /// use malachite_base::num::random::random_primitive_ints; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string( /// with_special_values( /// EXAMPLE_SEED, /// vec![1, 2, 3], /// 1, /// 2, /// &random_primitive_ints:: /// ), /// 20, /// ), /// "[3, 1, 3, 2901, 1, -14200, 2, 3, 1, -30997, -8245, -5338, 1, 1, -20007, 3, 1, 1, 1, 1, \ /// ...]" /// ); /// ``` pub fn with_special_values( seed: Seed, special_values: Vec, p_numerator: u64, p_denominator: u64, xs_gen: &dyn Fn(Seed) -> I, ) -> WithSpecialValues where I::Item: Clone, { WithSpecialValues { bs: weighted_random_bools(seed.fork("bs"), p_numerator, p_denominator), special_values: random_values_from_vec(seed.fork("special_values"), special_values), xs: xs_gen(seed.fork("xs")), } } /// Generates sliding windows of elements from an iterator. /// /// This `struct` is created by [`iter_windows`]; see its documentation for more. #[derive(Clone, Debug)] pub struct IterWindows where I::Item: Clone, { xs: I, window: VecDeque, window_size: usize, } impl Iterator for IterWindows where I::Item: Clone, { type Item = VecDeque; fn next(&mut self) -> Option> { if self.window.len() < self.window_size { self.window = (&mut self.xs).take(self.window_size).collect(); if self.window.len() < self.window_size { None } else { Some(self.window.clone()) } } else { let x = self.xs.next()?; self.window.pop_front(); self.window.push_back(x); Some(self.window.clone()) } } } /// Returns windows of $n$ adjacent elements of an iterator, advancing the window by 1 in each /// iteration. The values are cloned each time a new window is generated. /// /// The output length is $n - k + 1$, where $n$ is `xs.count()` and $k$ is `window_size`. /// /// # Panics /// Panics if `window_size` is 0. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::iterators::iter_windows; /// /// let xs = 0..=5; /// let windows = iter_windows(3, xs) /// .map(|ws| ws.iter().cloned().collect_vec()) /// .collect_vec(); /// assert_eq!( /// windows.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[&[0, 1, 2], &[1, 2, 3], &[2, 3, 4], &[3, 4, 5]] /// ); /// ``` pub fn iter_windows(window_size: usize, xs: I) -> IterWindows where I::Item: Clone, { assert_ne!(window_size, 0); IterWindows { xs, window: VecDeque::with_capacity(window_size), window_size, } } /// Converts a prefix of an iterator to a string. /// /// Suppose the iterator generates $(a, b, c, d)$. If `max_len` is 3, this function will return the /// string `"[a, b, c, ...]"`. If `max_len` is 4 or more, this function will return `[a, b, c, d]`. /// /// This function will attempt to advance the iterator `max_len + 1` times. The extra time is used /// determine whether the output string should contain an ellipsis. /// /// # Panics /// Panics if `max_len` is 0. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// /// assert_eq!(prefix_to_string(0..10, 3), "[0, 1, 2, ...]"); /// assert_eq!(prefix_to_string(0..4, 5), "[0, 1, 2, 3]"); /// ``` pub fn prefix_to_string(mut xs: I, max_len: usize) -> String where I::Item: Display, { assert_ne!(max_len, 0); let mut s = String::new(); s.push('['); let mut first = true; let mut done = false; for _ in 0..max_len { if let Some(x) = xs.next() { if first { first = false; } else { s.push_str(", "); } s.push_str(&x.to_string()); } else { done = true; break; } } if !done && xs.next().is_some() { s.push_str(", ..."); } s.push(']'); s } /// An iterator that generates the Thue-Morse sequence. See [`thue_morse_sequence`] for more /// information. #[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)] pub struct ThueMorseSequence(u64); impl Iterator for ThueMorseSequence { type Item = bool; fn next(&mut self) -> Option { let b = self.0.count_ones().odd(); self.0 += 1; Some(b) } } /// Returns an iterator that generates the Thue-Morse sequence. /// /// The output length is infinite. /// /// # Worst-case complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::thue_morse_sequence; /// /// let s: String = thue_morse_sequence() /// .take(100) /// .map(|b| if b { '1' } else { '0' }) /// .collect(); /// assert_eq!( /// s, /// "01101001100101101001011001101001100101100110100101101001100101101001011001101001011010011\ /// 00101100110" /// ) /// ``` #[inline] pub const fn thue_morse_sequence() -> ThueMorseSequence { ThueMorseSequence(0) } /// Contains [`BitDistributor`](bit_distributor::BitDistributor), which helps generate tuples /// exhaustively. pub mod bit_distributor; /// Functions that compare adjacent iterator elements. pub mod comparison; /// Contains [`IteratorCache`](iterator_cache::IteratorCache), which remembers values produced by an /// iterator. pub mod iterator_cache; malachite-base-0.4.16/src/lib.rs000064400000000000000000000231711046102023000144620ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . //! This crate contains many utilities that are used by the //! [`malachite-nz`](https://docs.rs/malachite-nz/latest/malachite_nz/) and //! [`malachite-q`]((https://docs.rs/malachite-q/latest/malachite_q/)) crates. These utilities //! include //! - Traits that wrap functions from the standard library, like //! [`CheckedAdd`](num::arithmetic::traits::CheckedAdd). //! - Traits that give extra functionality to primitive types, like //! [`Gcd`](num::arithmetic::traits::Gcd), [`FloorSqrt`](num::arithmetic::traits::FloorSqrt), and //! [`BitAccess`](num::logic::traits::BitAccess). //! - Iterator-producing functions that let you generate values for testing. Here's an example of //! an iterator that produces all pairs of [`u32`]s: //! ``` //! use malachite_base::num::exhaustive::exhaustive_unsigneds; //! use malachite_base::tuples::exhaustive::exhaustive_pairs_from_single; //! //! let mut pairs = exhaustive_pairs_from_single(exhaustive_unsigneds::()); //! assert_eq!( //! pairs.take(20).collect::>(), //! &[ //! (0, 0), (0, 1), (1, 0), (1, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 0), (2, 1), //! (3, 0), (3, 1), (2, 2), (2, 3), (3, 2), (3, 3), (0, 4), (0, 5), (1, 4), (1, 5) //! ] //! ); //! ``` //! - The [`RoundingMode`](rounding_modes::RoundingMode) enum, which allows you to specify the //! rounding behavior of various functions. //! - The [`NiceFloat`](num::float::NiceFloat) wrapper, which provides alternative implementations //! of [`Eq`], [`Ord`], and [`Display`](std::fmt::Display) for floating-point values which are in //! some ways nicer than the defaults. //! //! # Demos and benchmarks //! This crate comes with a `bin` target that can be used for running demos and benchmarks. //! - Almost all of the public functions in this crate have an associated demo. Running a demo //! shows you a function's behavior on a large number of inputs. For example, to demo the //! [`mod_pow`](num::arithmetic::traits::ModPow::mod_pow) function on [`u32`]s, you can use the //! following command: //! ```text //! cargo run --features bin_build --release -- -l 10000 -m exhaustive -d demo_mod_pow_u32 //! ``` //! This command uses the `exhaustive` mode, which generates every possible input, generally //! starting with the simplest input and progressing to more complex ones. Another mode is //! `random`. The `-l` flag specifies how many inputs should be generated. //! - You can use a similar command to run benchmarks. The following command benchmarks various //! GCD algorithms for [`u64`]s: //! ```text //! cargo run --features bin_build --release -- -l 1000000 -m random -b \ //! benchmark_gcd_algorithms_u64 -o gcd-bench.gp //! ``` //! This creates a file called gcd-bench.gp. You can use gnuplot to create an SVG from it like //! so: //! ```text //! gnuplot -e "set terminal svg; l \"gcd-bench.gp\"" > gcd-bench.svg //! ``` //! //! The list of available demos and benchmarks is not documented anywhere; you must find them by //! browsing through //! [`bin_util/demo_and_bench`](https://github.com/mhogrefe/malachite/tree/master/malachite-base/src/bin_util/demo_and_bench). //! //! # Features //! - `test_build`: A large proportion of the code in this crate is only used for testing. For a //! typical user, building this code would result in an unnecessarily long compilation time and //! an unnecessarily large binary. Much of it is also used for testing //! [`malachite-nz`](https://docs.rs/malachite-nz/latest/malachite_nz/) and //! [`malachite-q`](https://docs.rs/malachite-q/latest/malachite_q/), so it can't just be //! confined to the `tests` directory. My solution is to only build this code when the //! `test_build` feature is enabled. If you want to run unit tests, you must enable `test_build`. //! However, doctests don't require it, since they only test the public interface. //! - `bin_build`: This feature is used to build the code for demos and benchmarks, which also //! takes a long time to build. Enabling this feature also enables `test_build`. #![warn( clippy::cast_lossless, clippy::explicit_into_iter_loop, clippy::explicit_iter_loop, clippy::filter_map_next, clippy::large_digit_groups, clippy::manual_filter_map, clippy::manual_find_map, clippy::map_flatten, clippy::map_unwrap_or, clippy::match_same_arms, clippy::missing_const_for_fn, clippy::mut_mut, clippy::needless_borrow, clippy::needless_continue, clippy::needless_pass_by_value, clippy::print_stdout, clippy::redundant_closure_for_method_calls, clippy::single_match_else, clippy::trait_duplication_in_bounds, clippy::type_repetition_in_bounds, clippy::uninlined_format_args, clippy::unused_self, clippy::if_not_else, clippy::manual_assert, clippy::range_plus_one, clippy::redundant_else, clippy::semicolon_if_nothing_returned, clippy::cloned_instead_of_copied, clippy::flat_map_option, clippy::unnecessary_wraps, clippy::unnested_or_patterns, clippy::trivially_copy_pass_by_ref )] #![allow( clippy::cognitive_complexity, clippy::float_cmp, clippy::many_single_char_names, clippy::too_many_arguments, clippy::type_complexity, clippy::upper_case_acronyms, unstable_name_collisions )] #![cfg_attr(not(any(feature = "test_build", feature = "random")), no_std)] #[macro_use] extern crate alloc; #[cfg(feature = "test_build")] #[doc(hidden)] #[inline] pub fn fail_on_untested_path(message: &str) { panic!("Untested path. {message}"); } #[cfg(not(feature = "test_build"))] #[doc(hidden)] #[inline] pub const fn fail_on_untested_path(_message: &str) {} // TODO links for malachite-nz and malachite-q /// The [`Named`](named::Named) trait, for getting a type's name. #[macro_use] pub mod named; #[doc(hidden)] #[macro_use] pub mod macros; /// Functions for working with [`bool`]s. #[macro_use] pub mod bools; /// Functions for working with [`char`]s. #[macro_use] pub mod chars; /// Macros and traits related to comparing values. pub mod comparison; /// Functions and adaptors for iterators. pub mod iterators; /// [`Never`](nevers::Never), a type that cannot be instantiated. pub mod nevers; /// Functions for working with primitive integers and floats. #[macro_use] pub mod num; /// Functions for working with [`Ordering`](std::cmp::Ordering)s. pub mod options; /// Functions for working with [`Option`]s. pub mod orderings; #[cfg(feature = "random")] /// Functions for generating random values. pub mod random; /// [`RationalSequence`](rational_sequences::RationalSequence), a type representing a sequence that /// is finite or eventually repeating, just like the digits of a rational number. pub mod rational_sequences; /// [`RoundingMode`](rounding_modes::RoundingMode), an enum used to specify rounding behavior. pub mod rounding_modes; /// Functions for working with [`HashSet`](std::collections::HashSet)s and /// [`BTreeSet`](std::collections::BTreeSet)s. pub mod sets; /// Functions for working with slices. #[macro_use] pub mod slices; /// Functions for working with [`String`]s. pub mod strings; /// Functions for working with tuples. pub mod tuples; /// Unions (sum types). These are essentially generic enums. /// /// # unwrap /// ``` /// use malachite_base::union_struct; /// use malachite_base::unions::UnionFromStrError; /// use std::fmt::{self, Display, Formatter}; /// use std::str::FromStr; /// /// union_struct!( /// (pub(crate)), /// Union3, /// Union3, /// [A, A, 'A', a], /// [B, B, 'B', b], /// [C, C, 'C', c] /// ); /// /// let mut u: Union3; /// /// u = Union3::A('a'); /// assert_eq!(u.unwrap(), 'a'); /// /// u = Union3::B('b'); /// assert_eq!(u.unwrap(), 'b'); /// /// u = Union3::C('c'); /// assert_eq!(u.unwrap(), 'c'); /// ``` /// /// # fmt /// ``` /// use malachite_base::union_struct; /// use malachite_base::unions::UnionFromStrError; /// use std::fmt::{self, Display, Formatter}; /// use std::str::FromStr; /// /// union_struct!( /// (pub(crate)), /// Union3, /// Union3, /// [A, A, 'A', a], /// [B, B, 'B', b], /// [C, C, 'C', c] /// ); /// /// let mut u: Union3; /// /// u = Union3::A('a'); /// assert_eq!(u.to_string(), "A(a)"); /// /// u = Union3::B(5); /// assert_eq!(u.to_string(), "B(5)"); /// /// u = Union3::C(false); /// assert_eq!(u.to_string(), "C(false)"); /// ``` /// /// # from_str /// ``` /// use malachite_base::union_struct; /// use malachite_base::unions::UnionFromStrError; /// use std::fmt::{self, Display, Formatter}; /// use std::str::FromStr; /// /// union_struct!( /// (pub(crate)), /// Union3, /// Union3, /// [A, A, 'A', a], /// [B, B, 'B', b], /// [C, C, 'C', c] /// ); /// /// let u3: Union3 = Union3::from_str("B(5)").unwrap(); /// assert_eq!(u3, Union3::B(5)); /// /// let result: Result, _> = Union3::from_str("xyz"); /// assert_eq!(result, Err(UnionFromStrError::Generic("xyz".to_string()))); /// /// let result: Result, _> = Union3::from_str("A(ab)"); /// if let Err(UnionFromStrError::Specific(Union3::A(_e))) = result { /// } else { /// panic!("wrong error variant") /// } /// ``` pub mod unions; /// Functions for working with [`Vec`]s. pub mod vecs; #[cfg(feature = "test_build")] pub mod test_util; malachite-base-0.4.16/src/macros/mod.rs000064400000000000000000000041511046102023000157540ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . #[doc(hidden)] #[cfg(feature = "test_build")] #[macro_export] macro_rules! pub_test { ($( #[$meta:meta] )* $name:ident $( $body:tt )*) => { $( #[$meta] )* pub fn $name $( $body )* }; } #[doc(hidden)] #[cfg(not(feature = "test_build"))] #[macro_export] macro_rules! pub_test { ($( #[$meta:meta] )* $name:ident $( $body:tt )*) => { $( #[$meta] )* fn $name $( $body )* }; } #[doc(hidden)] #[cfg(feature = "test_build")] #[macro_export] macro_rules! pub_crate_test { ($( #[$meta:meta] )* $name:ident $( $body:tt )*) => { $( #[$meta] )* pub fn $name $( $body )* }; } #[doc(hidden)] #[cfg(not(feature = "test_build"))] #[macro_export] macro_rules! pub_crate_test { ($( #[$meta:meta] )* $name:ident $( $body:tt )*) => { $( #[$meta] )* pub(crate) fn $name $( $body )* }; } #[doc(hidden)] #[cfg(feature = "test_build")] #[macro_export] macro_rules! pub_const_test { ($( #[$meta:meta] )* $name:ident $( $body:tt )*) => { $( #[$meta] )* pub const fn $name $( $body )* }; } #[doc(hidden)] #[cfg(not(feature = "test_build"))] #[macro_export] macro_rules! pub_const_test { ($( #[$meta:meta] )* $name:ident $( $body:tt )*) => { $( #[$meta] )* const fn $name $( $body )* }; } #[doc(hidden)] #[cfg(feature = "test_build")] #[macro_export] macro_rules! pub_const_crate_test { ($( #[$meta:meta] )* $name:ident $( $body:tt )*) => { $( #[$meta] )* pub const fn $name $( $body )* }; } #[doc(hidden)] #[cfg(not(feature = "test_build"))] #[macro_export] macro_rules! pub_const_crate_test { ($( #[$meta:meta] )* $name:ident $( $body:tt )*) => { $( #[$meta] )* pub(crate) const fn $name $( $body )* }; } malachite-base-0.4.16/src/named/mod.rs000064400000000000000000000023011046102023000155470ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . /// Defines the name of a type. This is useful for constructing error messages in a generic /// function. pub trait Named { /// The name of `Self`. const NAME: &'static str; } /// Automatically implements [`Named`] for a type. /// /// It doesn't work very well for types whose names contain several tokens, like `(u8, u8)`, `&str`, /// or `Vec`. /// /// # Examples /// ``` /// use malachite_base::named::Named; /// /// assert_eq!(u8::NAME, "u8"); /// assert_eq!(String::NAME, "String"); /// ``` #[macro_export] macro_rules! impl_named { ($t:ident) => { impl Named for $t { /// The name of this type, as given by the [`stringify`] macro. /// /// See the documentation for [`impl_named`] for more details. const NAME: &'static str = stringify!($t); } }; } malachite-base-0.4.16/src/nevers/mod.rs000064400000000000000000000037111046102023000157730ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use core::fmt::{Display, Formatter}; use core::iter::{empty, Empty}; use core::str::FromStr; /// `Never` is a type that cannot be instantiated. /// /// This is a [bottom type](https://en.wikipedia.org/wiki/Bottom_type). /// /// # Examples /// ``` /// use malachite_base::nevers::Never; /// /// let _x: Option = None; /// ``` #[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)] pub enum Never {} impl Display for Never { /// Would convert a [`Never`] to a [`String`]. fn fmt(&self, _f: &mut Formatter) -> core::fmt::Result { unreachable!() } } #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct NeverError; impl FromStr for Never { type Err = NeverError; /// Would convert a [`String`] to a [`Never`]. /// /// Since a [`Never`] can never be instantiated, `from_str` never succeeds. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::nevers::{Never, NeverError}; /// use std::str::FromStr; /// /// assert_eq!(Never::from_str("abc"), Err(NeverError)); /// ``` #[inline] fn from_str(_: &str) -> Result { Err(NeverError) } } /// Generates all (none) of the [`Never`]s. /// /// The output length is 0. /// /// # Worst-case complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::nevers::nevers; /// /// assert_eq!(nevers().collect_vec(), &[]); /// ``` pub const fn nevers() -> Empty { empty() } malachite-base-0.4.16/src/num/arithmetic/abs.rs000064400000000000000000000047361046102023000174170ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{Abs, AbsAssign, UnsignedAbs}; macro_rules! impl_abs_primitive_int { ($u:ident, $s:ident) => { impl Abs for $s { type Output = $s; /// This is a wrapper over the `abs` functions in the standard library, for example /// [this one](i32::abs). #[inline] fn abs(self) -> $s { $s::abs(self) } } impl AbsAssign for $s { /// Replaces a number with its absolute value. /// /// $x \gets |x|$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::abs#abs_assign). #[inline] fn abs_assign(&mut self) { *self = self.abs(); } } impl UnsignedAbs for $s { type Output = $u; /// This is a wrapper over the `unsigned_abs` functions in the standard library, for /// example [this one](i32::unsigned_abs). #[inline] fn unsigned_abs(self) -> $u { self.unsigned_abs() } } }; } apply_to_unsigned_signed_pairs!(impl_abs_primitive_int); macro_rules! impl_abs_primitive_float { ($f:ident) => { impl Abs for $f { type Output = $f; /// This is a wrapper over the `fabs` functions from [`libm`]. #[inline] fn abs(self) -> $f { libm::Libm::<$f>::fabs(self) } } impl AbsAssign for $f { /// Replaces a number with its absolute value. /// /// $x \gets |x|$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::abs#abs_assign). #[inline] fn abs_assign(&mut self) { *self = self.abs(); } } }; } apply_to_primitive_floats!(impl_abs_primitive_float); malachite-base-0.4.16/src/num/arithmetic/abs_diff.rs000064400000000000000000000035711046102023000204030ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{AbsDiff, AbsDiffAssign}; macro_rules! impl_abs_diff_unsigned { ($t:ident) => { impl AbsDiff for $t { type Output = $t; /// This is a wrapper over the `abs_diff` functions in the standard library, for example /// [this one](u32::abs_diff). #[inline] fn abs_diff(self, other: $t) -> $t { self.abs_diff(other) } } impl AbsDiffAssign for $t { /// Subtracts a number by another and takes the absolute value, in place. The output /// type is the unsigned type with the same width. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::abs_diff#abs_diff_assign). #[inline] fn abs_diff_assign(&mut self, other: $t) { *self = self.abs_diff(other); } } }; } apply_to_unsigneds!(impl_abs_diff_unsigned); macro_rules! impl_abs_diff_signed { ($u:ident, $s:ident) => { impl AbsDiff for $s { type Output = $u; /// This is a wrapper over the `abs_diff` functions in the standard library, for example /// [this one](i32::abs_diff). #[inline] fn abs_diff(self, other: $s) -> $u { self.abs_diff(other) } } }; } apply_to_unsigned_signed_pairs!(impl_abs_diff_signed); malachite-base-0.4.16/src/num/arithmetic/add_mul.rs000064400000000000000000000054001046102023000202440ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{AddMul, AddMulAssign, WrappingAddMul, WrappingAddMulAssign}; macro_rules! impl_add_mul_primitive_int { ($t:ident) => { impl AddMul for $t { type Output = $t; /// Adds a number and the product of two other numbers. /// /// $f(x, y, z) = x + yz$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::add_mul#add_mul). #[inline] fn add_mul(self, y: $t, z: $t) -> $t { self.wrapping_add_mul(y, z) } } impl AddMulAssign<$t> for $t { /// Adds the product of two other numbers to a number in place. /// /// $x \gets x + yz$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::add_mul#add_mul_assign). #[inline] fn add_mul_assign(&mut self, y: $t, z: $t) { self.wrapping_add_mul_assign(y, z) } } }; } apply_to_primitive_ints!(impl_add_mul_primitive_int); macro_rules! impl_add_mul_primitive_float { ($t:ident) => { impl AddMul for $t { type Output = $t; /// Adds a number and the product of two other numbers. /// /// $f(x, y, z) = x + yz$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::add_mul#add_mul). #[inline] fn add_mul(self, y: $t, z: $t) -> $t { self + y * z } } impl AddMulAssign<$t> for $t { /// Adds the product of two other numbers to a number in place. /// /// $x \gets x + yz$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::add_mul#add_mul_assign). #[inline] fn add_mul_assign(&mut self, y: $t, z: $t) { *self += y * z; } } }; } apply_to_primitive_floats!(impl_add_mul_primitive_float); malachite-base-0.4.16/src/num/arithmetic/arithmetic_checked_shl.rs000064400000000000000000000241731046102023000233140ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{ArithmeticCheckedShl, UnsignedAbs}; use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::WrappingFrom; use core::ops::{Shl, Shr}; fn arithmetic_checked_shl_unsigned_unsigned< T: PrimitiveUnsigned + Shl + Shr, U: Copy + Ord + WrappingFrom, >( x: T, bits: U, ) -> Option { if x == T::ZERO { Some(x) } else if bits >= U::wrapping_from(T::WIDTH) { None } else { let result = x << bits; if result >> bits == x { Some(result) } else { None } } } macro_rules! impl_arithmetic_checked_shl_unsigned_unsigned { ($t:ident) => { macro_rules! impl_arithmetic_checked_shl_unsigned_unsigned_inner { ($u:ident) => { impl ArithmeticCheckedShl<$u> for $t { type Output = $t; /// Left-shifts a number (multiplies it by a power of 2). If the result is too /// large to be represented, `None` is returned. /// /// Zero may be shifted by any amount. /// /// $$ /// f(x, b) = \\begin{cases} /// \operatorname{Some}(2^b x) & \text{if} \\quad 2^b x < 2^W, \\\\ /// \operatorname{None} & \text{if} \\quad 2^b x \geq 2^W, /// \\end{cases} /// $$ /// where $W$ is `Self::WIDTH`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::arithmetic_checked_shl#arithmetic_checked_shl). #[inline] fn arithmetic_checked_shl(self, bits: $u) -> Option<$t> { arithmetic_checked_shl_unsigned_unsigned(self, bits) } } }; } apply_to_unsigneds!(impl_arithmetic_checked_shl_unsigned_unsigned_inner); }; } apply_to_unsigneds!(impl_arithmetic_checked_shl_unsigned_unsigned); fn arithmetic_checked_shl_unsigned_signed< T: ArithmeticCheckedShl + PrimitiveUnsigned + Shr, U: PrimitiveUnsigned, S: PrimitiveSigned + UnsignedAbs, >( x: T, bits: S, ) -> Option { if bits >= S::ZERO { x.arithmetic_checked_shl(bits.unsigned_abs()) } else { let abs_bits = bits.unsigned_abs(); Some(if abs_bits >= U::wrapping_from(T::WIDTH) { T::ZERO } else { x >> abs_bits }) } } macro_rules! impl_arithmetic_checked_shl_unsigned_signed { ($t:ident) => { macro_rules! impl_arithmetic_checked_shl_unsigned_signed_inner { ($u:ident) => { impl ArithmeticCheckedShl<$u> for $t { type Output = $t; /// Left-shifts a number (multiplies it by a power of 2). If the result is too /// large to be represented, `None` is returned. /// /// Zero may be shifted by any amount, and any number may be shifted by any /// negative amount; shifting by a negative amount with a high absolute value /// returns `Some(0)`. /// /// $$ /// f(x, b) = \\begin{cases} /// \operatorname{Some}(2^b x) & /// \text{if} \\quad b \geq 0 \\ \mathrm{and}\\ 2^b x < 2^W, \\\\ /// \operatorname{None} & /// \text{if} \\quad b \geq 0 \\ \mathrm{and} \\ 2^b x \geq 2^W, \\\\ /// \operatorname{Some}(\lfloor x/2^{-b} \rfloor) & /// \text{if} \\quad b < 0, /// \\end{cases} /// $$ /// where $W$ is `Self::WIDTH`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::arithmetic_checked_shl#arithmetic_checked_shl). #[inline] fn arithmetic_checked_shl(self, bits: $u) -> Option<$t> { arithmetic_checked_shl_unsigned_signed(self, bits) } } }; } apply_to_signeds!(impl_arithmetic_checked_shl_unsigned_signed_inner); }; } apply_to_unsigneds!(impl_arithmetic_checked_shl_unsigned_signed); fn arithmetic_checked_shl_signed_unsigned< U: ArithmeticCheckedShl + PrimitiveUnsigned, S: TryFrom + PrimitiveSigned + UnsignedAbs, B, >( x: S, bits: B, ) -> Option { let abs = x.unsigned_abs(); if x >= S::ZERO { abs.arithmetic_checked_shl(bits) .and_then(|x| S::try_from(x).ok()) } else { abs.arithmetic_checked_shl(bits).and_then(|x| { if x == S::MIN.unsigned_abs() { Some(S::MIN) } else { S::try_from(x).ok().map(|y| -y) } }) } } macro_rules! impl_arithmetic_checked_shl_signed_unsigned { ($t:ident) => { macro_rules! impl_arithmetic_checked_shl_signed_unsigned_inner { ($u:ident) => { impl ArithmeticCheckedShl<$u> for $t { type Output = $t; /// Left-shifts a number (multiplies it by a power of 2). If the result is too /// large to be represented, `None` is returned. /// /// Zero may be shifted by any amount. /// /// $$ /// f(x, b) = \\begin{cases} /// \operatorname{Some}(2^b x) & /// \text{if} \\quad -2^{W-1} \leq 2^b x < 2^{W-1}, \\\\ /// \operatorname{None} & /// \text{if} \\quad 2^b x < -2^{W-1} \\ \mathrm{or} /// \\ 2^b x \geq 2^{W-1}, \\\\ /// \\end{cases} /// $$ /// where $W$ is `Self::WIDTH`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::arithmetic_checked_shl#arithmetic_checked_shl). #[inline] fn arithmetic_checked_shl(self, bits: $u) -> Option<$t> { arithmetic_checked_shl_signed_unsigned(self, bits) } } }; } apply_to_unsigneds!(impl_arithmetic_checked_shl_signed_unsigned_inner); }; } apply_to_signeds!(impl_arithmetic_checked_shl_signed_unsigned); fn arithmetic_checked_shl_signed_signed< T: ArithmeticCheckedShl + PrimitiveSigned + Shr, U: PrimitiveUnsigned, S: PrimitiveSigned + UnsignedAbs, >( x: T, bits: S, ) -> Option { if bits >= S::ZERO { x.arithmetic_checked_shl(bits.unsigned_abs()) } else { let width = U::wrapping_from(T::WIDTH); let abs_bits = bits.unsigned_abs(); Some(if width != U::ZERO && abs_bits >= width { -T::from(x < T::ZERO) } else { x >> abs_bits }) } } macro_rules! impl_arithmetic_checked_shl_signed_signed { ($t:ident) => { macro_rules! impl_arithmetic_checked_shl_signed_signed_inner { ($u:ident) => { impl ArithmeticCheckedShl<$u> for $t { type Output = $t; /// Left-shifts a number (multiplies it by a power of 2). If the result is too /// large to be represented, `None` is returned. /// /// Zero may be shifted by any amount, and any number may be shifted by any /// negative amount; shifting by a negative amount with a high absolute value /// returns `Some(0)` if `self` is positive, and `Some(-1)` if `self` is /// negative. /// /// $$ /// f(x, b) = \\begin{cases} /// \operatorname{Some}(2^b x) & /// \text{if} \\quad b \geq 0 \\ \mathrm{and} /// \\ -2^{W-1} \leq 2^b x < 2^{W-1}, \\\\ /// \operatorname{None} & /// \text{if} \\quad b \geq 0 \\ \mathrm{and} /// \\ (2^b x < -2^{W-1} \\ \mathrm{or} \\ 2^b x \geq 2^{W-1}), \\\\ /// \operatorname{Some}(\lfloor x/2^{-b} \rfloor) & \text{if} \\quad b < 0, /// \\end{cases} /// $$ /// where $W$ is `Self::WIDTH`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::arithmetic_checked_shl#arithmetic_checked_shl). fn arithmetic_checked_shl(self, bits: $u) -> Option<$t> { arithmetic_checked_shl_signed_signed(self, bits) } } }; } apply_to_signeds!(impl_arithmetic_checked_shl_signed_signed_inner); }; } apply_to_signeds!(impl_arithmetic_checked_shl_signed_signed); malachite-base-0.4.16/src/num/arithmetic/arithmetic_checked_shr.rs000064400000000000000000000134221046102023000233150ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{ArithmeticCheckedShl, ArithmeticCheckedShr, UnsignedAbs}; use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use core::ops::Shr; fn arithmetic_checked_shr_unsigned_signed< T: ArithmeticCheckedShl + PrimitiveUnsigned + Shr, U: PrimitiveUnsigned, S: PrimitiveSigned + UnsignedAbs, >( x: T, bits: S, ) -> Option { if bits < S::ZERO { x.arithmetic_checked_shl(bits.unsigned_abs()) } else { let abs_bits = bits.unsigned_abs(); Some(if abs_bits >= U::wrapping_from(T::WIDTH) { T::ZERO } else { x >> abs_bits }) } } macro_rules! impl_arithmetic_checked_shr_unsigned_signed { ($t:ident) => { macro_rules! impl_arithmetic_checked_shr_unsigned_signed_inner { ($u:ident) => { impl ArithmeticCheckedShr<$u> for $t { type Output = $t; /// Shifts a number right (divides it by a power of 2). If the result is too /// large to be represented, `None` is returned. /// /// Zero may be shifted by any amount, and any number may be shifted by any /// non-negative amount; shifting by a large amount returns `Some(0)`. /// /// $$ /// f(x, b) = \\begin{cases} /// \operatorname{Some}(\lfloor x/2^b \rfloor) & /// \text{if} \\quad b \geq 0, \\\\ /// \operatorname{Some}(2^{-b} x) & /// \text{if} \\quad b < 0 \\ \mathrm{and} \\ 2^{-b} x < 2^W, \\\\ /// \operatorname{None} & /// \text{if} \\quad b < 0 \\ \mathrm{and} \\ 2^{-b} x \geq 2^W, \\\\ /// \\end{cases} /// $$ /// where $W$ is `Self::WIDTH`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::arithmetic_checked_shr#arithmetic_checked_shr). #[inline] fn arithmetic_checked_shr(self, bits: $u) -> Option<$t> { arithmetic_checked_shr_unsigned_signed(self, bits) } } }; } apply_to_signeds!(impl_arithmetic_checked_shr_unsigned_signed_inner); }; } apply_to_unsigneds!(impl_arithmetic_checked_shr_unsigned_signed); fn arithmetic_checked_shr_signed_signed< T: ArithmeticCheckedShl + PrimitiveSigned + Shr, U: PrimitiveUnsigned, S: PrimitiveSigned + UnsignedAbs, >( x: T, bits: S, ) -> Option { if bits < S::ZERO { x.arithmetic_checked_shl(bits.unsigned_abs()) } else { let width = U::wrapping_from(T::WIDTH); let abs_bits = bits.unsigned_abs(); Some(if width != U::ZERO && abs_bits >= width { -T::from(x < T::ZERO) } else { x >> abs_bits }) } } macro_rules! impl_arithmetic_checked_shr_signed_signed { ($t:ident) => { macro_rules! impl_arithmetic_checked_shr_signed_signed_inner { ($u:ident) => { impl ArithmeticCheckedShr<$u> for $t { type Output = $t; /// Shifts a number right (divides it by a power of 2). If the result is too /// large to be represented, `None` is returned. /// /// Zero may be shifted by any amount, and any number may be shifted by any /// non-negative amount; shifting by a large amount returns `Some(0)` if `self` /// is positive, and `Some(-1)` if `self` is negative. /// /// $$ /// f(x, b) = \\begin{cases} /// \operatorname{Some}(\lfloor x/2^b \rfloor) & /// \text{if} \\quad b \geq 0, \\\\ /// \operatorname{Some}(2^{-b} x) & /// \text{if} \\quad b < 0 \\ \mathrm{and} /// \\ -2^{W-1} \leq 2^{-b} x < 2^{W-1}, \\\\ /// \operatorname{None} & /// \text{if} \\quad b < 0 \\ \mathrm{and} /// \\ (2^{-b} x < -2^{W-1} \\ \mathrm{or} /// \\ 2^{-b} x \geq 2^{W-1}), \\\\ /// \\end{cases} /// $$ /// where $W$ is `Self::WIDTH`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::arithmetic_checked_shr#arithmetic_checked_shr). #[inline] fn arithmetic_checked_shr(self, bits: $u) -> Option<$t> { arithmetic_checked_shr_signed_signed(self, bits) } } }; } apply_to_signeds!(impl_arithmetic_checked_shr_signed_signed_inner); }; } apply_to_signeds!(impl_arithmetic_checked_shr_signed_signed); malachite-base-0.4.16/src/num/arithmetic/binomial_coefficient.rs000064400000000000000000000151671046102023000230020ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{ BinomialCoefficient, CheckedBinomialCoefficient, UnsignedAbs, }; use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::OverflowingFrom; use crate::num::exhaustive::primitive_int_increasing_inclusive_range; use core::cmp::min; fn checked_binomial_coefficient_unsigned(n: T, mut k: T) -> Option { if k > n { return Some(T::ZERO); } k = min(k, n - k); if k == T::ZERO { Some(T::ONE) } else if k == T::ONE { Some(n) } else if k == T::TWO { (if n.even() { n - T::ONE } else { n }).checked_mul(n >> 1) } else { // Some binomial coefficient algorithms have intermediate results greater than the final // result, risking overflow. This one does not. let mut product = n - k + T::ONE; let mut numerator = product; for i in primitive_int_increasing_inclusive_range(T::TWO, k) { numerator += T::ONE; let gcd = numerator.gcd(i); product /= i / gcd; product = product.checked_mul(numerator / gcd)?; } Some(product) } } fn checked_binomial_coefficient_signed< U: PrimitiveUnsigned, S: OverflowingFrom + PrimitiveSigned + TryFrom + UnsignedAbs, >( n: S, k: S, ) -> Option { if k < S::ZERO { return None; } if n >= S::ZERO { S::try_from(U::checked_binomial_coefficient( n.unsigned_abs(), k.unsigned_abs(), )?) .ok() } else { let k = k.unsigned_abs(); let b = U::checked_binomial_coefficient(n.unsigned_abs() + k - U::ONE, k)?; if k.even() { S::try_from(b).ok() } else { let (b, overflow) = S::overflowing_from(b); if overflow { if b == S::MIN { Some(S::MIN) } else { None } } else { Some(-b) } } } } macro_rules! impl_binomial_coefficient_unsigned { ($t:ident) => { impl CheckedBinomialCoefficient for $t { /// Computes the binomial coefficient of two numbers. If the inputs are too large, the /// function returns `None`. /// /// $$ /// f(n, k) = \\begin{cases} /// \operatorname{Some}(\binom{n}{k}) & \text{if} \\quad \binom{n}{k} < 2^W, \\\\ /// \operatorname{None} & \text{if} \\quad \binom{n}{k} \geq 2^W, /// \\end{cases} /// $$ /// where $W$ is `Self::WIDTH`. /// /// # Worst-case complexity /// $T(k) = O(k)$ /// /// $M(k) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $k$ is `k`. /// /// # Examples /// See [here](super::binomial_coefficient#checked_binomial_coefficient). #[inline] fn checked_binomial_coefficient(n: $t, k: $t) -> Option<$t> { checked_binomial_coefficient_unsigned(n, k) } } }; } apply_to_unsigneds!(impl_binomial_coefficient_unsigned); macro_rules! impl_binomial_coefficient_signed { ($t:ident) => { impl CheckedBinomialCoefficient for $t { /// Computes the binomial coefficient of two numbers. If the inputs are too large, the /// function returns `None`. /// /// The second argument must be non-negative, but the first may be negative. If it is, /// the identity $\binom{-n}{k} = (-1)^k \binom{n+k-1}{k}$ is used. /// /// $$ /// f(n, k) = \\begin{cases} /// \operatorname{Some}(\binom{n}{k}) & \text{if} \\quad n \geq 0 \\ \text{and} /// \\ -2^{W-1} \leq \binom{n}{k} < 2^{W-1}, \\\\ /// \operatorname{Some}((-1)^k \binom{-n+k-1}{k}) & \text{if} \\quad n < 0 /// \\ \text{and} \\ -2^{W-1} \leq \binom{n}{k} < 2^{W-1}, \\\\ /// \operatorname{None} & \\quad \\text{otherwise}, /// \\end{cases} /// $$ /// where $W$ is `Self::WIDTH`. /// /// # Worst-case complexity /// $T(k) = O(k)$ /// /// $M(k) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $k$ is `k.abs()`. /// /// # Examples /// See [here](super::binomial_coefficient#checked_binomial_coefficient). #[inline] fn checked_binomial_coefficient(n: $t, k: $t) -> Option<$t> { checked_binomial_coefficient_signed(n, k) } } }; } apply_to_signeds!(impl_binomial_coefficient_signed); macro_rules! impl_binomial_coefficient_primitive_int { ($t:ident) => { impl BinomialCoefficient for $t { /// Computes the binomial coefficient of two numbers. If the inputs are too large, the /// function panics. /// /// The second argument must be non-negative, but the first may be negative. If it is, /// the identity $\binom{-n}{k} = (-1)^k \binom{n+k-1}{k}$ is used. /// /// $$ /// f(n, k) = \\begin{cases} /// \binom{n}{k} & \text{if} \\quad n \geq 0, \\\\ /// (-1)^k \binom{-n+k-1}{k} & \text{if} \\quad n < 0. /// \\end{cases} /// $$ /// /// # Worst-case complexity /// $T(k) = O(k)$ /// /// $M(k) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $k$ is `k.abs()`. /// /// # Panics /// Panics if the result is not representable by this type, or if $k$ is negative. /// /// # Examples /// See [here](super::binomial_coefficient#binomial_coefficient). #[inline] fn binomial_coefficient(n: $t, k: $t) -> $t { $t::checked_binomial_coefficient(n, k).unwrap() } } }; } apply_to_primitive_ints!(impl_binomial_coefficient_primitive_int); malachite-base-0.4.16/src/num/arithmetic/ceiling.rs000064400000000000000000000025671046102023000202640ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{Ceiling, CeilingAssign}; macro_rules! impl_ceiling { ($f:ident) => { impl Ceiling for $f { type Output = $f; /// This is a wrapper over the `ceil` functions in [`libm`] #[inline] fn ceiling(self) -> $f { libm::Libm::<$f>::ceil(self) } } impl CeilingAssign for $f { /// Replaces a number with its ceiling. /// /// A number's ceiling is the smallest integer greater than or equal to the number. /// /// $x \gets \lceil x \rceil$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::ceiling#ceiling_assign). #[inline] fn ceiling_assign(&mut self) { *self = self.ceiling(); } } }; } apply_to_primitive_floats!(impl_ceiling); malachite-base-0.4.16/src/num/arithmetic/checked_abs.rs000064400000000000000000000015461046102023000210610ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::CheckedAbs; macro_rules! impl_checked_abs { ($t:ident) => { impl CheckedAbs for $t { type Output = $t; /// This is a wrapper over the `checked_abs` functions in the standard library, for /// example [this one](i32::checked_abs). #[inline] fn checked_abs(self) -> Option<$t> { $t::checked_abs(self) } } }; } apply_to_signeds!(impl_checked_abs); malachite-base-0.4.16/src/num/arithmetic/checked_add.rs000064400000000000000000000016031046102023000210360ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::CheckedAdd; macro_rules! impl_checked_add { ($t:ident) => { impl CheckedAdd<$t> for $t { type Output = $t; /// This is a wrapper over the `checked_add` functions in the standard library, for /// example [this one](u32::checked_add). #[inline] fn checked_add(self, other: $t) -> Option<$t> { $t::checked_add(self, other) } } }; } apply_to_primitive_ints!(impl_checked_add); malachite-base-0.4.16/src/num/arithmetic/checked_add_mul.rs000064400000000000000000000072371046102023000217240ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{CheckedAddMul, UnsignedAbs}; use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::WrappingFrom; fn checked_add_mul_unsigned(x: T, y: T, z: T) -> Option { y.checked_mul(z).and_then(|yz| x.checked_add(yz)) } macro_rules! impl_checked_add_mul_unsigned { ($t:ident) => { impl CheckedAddMul<$t> for $t { type Output = $t; /// Adds a number and the product of two other numbers, returning `None` if the result /// cannot be represented. /// /// $$ /// f(x, y, z) = \\begin{cases} /// \operatorname{Some}(x + yz) & \text{if} \\quad x + yz < 2^W, \\\\ /// \operatorname{None} & \text{if} \\quad x + yz \geq 2^W, /// \\end{cases} /// $$ /// where $W$ is `Self::WIDTH`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::checked_add_mul#checked_add_mul). #[inline] fn checked_add_mul(self, y: $t, z: $t) -> Option<$t> { checked_add_mul_unsigned(self, y, z) } } }; } apply_to_unsigneds!(impl_checked_add_mul_unsigned); fn checked_add_mul_signed< U: PrimitiveUnsigned, T: PrimitiveSigned + UnsignedAbs + WrappingFrom, >( x: T, y: T, z: T, ) -> Option { if y == T::ZERO || z == T::ZERO { return Some(x); } let x_sign = x >= T::ZERO; if x_sign == ((y >= T::ZERO) == (z >= T::ZERO)) { x.checked_add(y.checked_mul(z)?) } else { let x = x.unsigned_abs(); let product = y.unsigned_abs().checked_mul(z.unsigned_abs())?; let result = T::wrapping_from(if x_sign { x.wrapping_sub(product) } else { product.wrapping_sub(x) }); if x >= product || (x_sign == (result < T::ZERO)) { Some(result) } else { None } } } macro_rules! impl_checked_add_mul_signed { ($t:ident) => { impl CheckedAddMul<$t> for $t { type Output = $t; /// Adds a number and the product of two other numbers, returning `None` if the result /// cannot be represented. /// /// $$ /// f(x, y, z) = \\begin{cases} /// \operatorname{Some}(x + yz) & /// \text{if} \\quad -2^{W-1} \leq x + yz < 2^{W-1}, \\\\ /// \operatorname{None} & /// \text{if} \\quad x + yz < -2^{W-1} \\ \mathrm{or} /// \\ x + yz \geq 2^{W-1}, \\\\ /// \\end{cases} /// $$ /// where $W$ is `Self::WIDTH`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::checked_add_mul#checked_add_mul). #[inline] fn checked_add_mul(self, y: $t, z: $t) -> Option<$t> { checked_add_mul_signed(self, y, z) } } }; } apply_to_signeds!(impl_checked_add_mul_signed); malachite-base-0.4.16/src/num/arithmetic/checked_div.rs000064400000000000000000000016031046102023000210700ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::CheckedDiv; macro_rules! impl_checked_div { ($t:ident) => { impl CheckedDiv<$t> for $t { type Output = $t; /// This is a wrapper over the `checked_div` functions in the standard library, for /// example [this one](u32::checked_div). #[inline] fn checked_div(self, other: $t) -> Option<$t> { $t::checked_div(self, other) } } }; } apply_to_primitive_ints!(impl_checked_div); malachite-base-0.4.16/src/num/arithmetic/checked_mul.rs000064400000000000000000000016031046102023000211030ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::CheckedMul; macro_rules! impl_checked_mul { ($t:ident) => { impl CheckedMul<$t> for $t { type Output = $t; /// This is a wrapper over the `checked_mul` functions in the standard library, for /// example [this one](u32::checked_mul). #[inline] fn checked_mul(self, other: $t) -> Option<$t> { $t::checked_mul(self, other) } } }; } apply_to_primitive_ints!(impl_checked_mul); malachite-base-0.4.16/src/num/arithmetic/checked_neg.rs000064400000000000000000000015551046102023000210650ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::CheckedNeg; macro_rules! impl_checked_neg { ($t:ident) => { impl CheckedNeg for $t { type Output = $t; /// This is a wrapper over the `checked_neg` functions in the standard library, for /// example [this one](u32::checked_neg). #[inline] fn checked_neg(self) -> Option<$t> { $t::checked_neg(self) } } }; } apply_to_primitive_ints!(impl_checked_neg); malachite-base-0.4.16/src/num/arithmetic/checked_next_power_of_2.rs000064400000000000000000000017101046102023000234040ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::CheckedNextPowerOf2; macro_rules! impl_checked_next_power_of_2 { ($t:ident) => { impl CheckedNextPowerOf2 for $t { type Output = $t; /// This is a wrapper over the `checked_next_power_of_two` functions in the standard /// library, for example [this one](u32::checked_next_power_of_two). #[inline] fn checked_next_power_of_2(self) -> Option<$t> { $t::checked_next_power_of_two(self) } } }; } apply_to_unsigneds!(impl_checked_next_power_of_2); malachite-base-0.4.16/src/num/arithmetic/checked_pow.rs000064400000000000000000000035411046102023000211160ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{CheckedPow, Parity}; macro_rules! impl_checked_pow_unsigned { ($t:ident) => { impl CheckedPow for $t { type Output = $t; /// This is a wrapper over the `checked_pow` functions in the standard library, for /// example [this one](u32::checked_pow). #[inline] fn checked_pow(self, exp: u64) -> Option<$t> { if exp == 0 { Some(1) } else if self < 2 { Some(self) } else { self.checked_pow(u32::try_from(exp).ok()?) } } } }; } apply_to_unsigneds!(impl_checked_pow_unsigned); macro_rules! impl_checked_pow_signed { ($t:ident) => { impl CheckedPow for $t { type Output = $t; /// This is a wrapper over the `checked_pow` functions in the standard library, for /// example [this one](i32::checked_pow). #[inline] fn checked_pow(self, exp: u64) -> Option<$t> { if exp == 0 { Some(1) } else if self == 0 || self == 1 { Some(self) } else if self == -1 { Some(if exp.even() { 1 } else { -1 }) } else { self.checked_pow(u32::try_from(exp).ok()?) } } } }; } apply_to_signeds!(impl_checked_pow_signed); malachite-base-0.4.16/src/num/arithmetic/checked_square.rs000064400000000000000000000025271046102023000216140ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::CheckedSquare; macro_rules! impl_checked_square { ($t:ident) => { impl CheckedSquare for $t { type Output = $t; /// Squares a number, returning `None` if the result cannot be represented. /// /// $$ /// f(x) = \\begin{cases} /// \operatorname{Some}(x^2) & \text{if} \\quad x^2 < 2^W, \\\\ /// \operatorname{None} & \text{if} \\quad x^2 \geq 2^W, /// \\end{cases} /// $$ /// where $W$ is `Self::WIDTH`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::checked_square#checked_square). #[inline] fn checked_square(self) -> Option<$t> { self.checked_mul(self) } } }; } apply_to_primitive_ints!(impl_checked_square); malachite-base-0.4.16/src/num/arithmetic/checked_sub.rs000064400000000000000000000016031046102023000210770ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::CheckedSub; macro_rules! impl_checked_sub { ($t:ident) => { impl CheckedSub<$t> for $t { type Output = $t; /// This is a wrapper over the `checked_sub` functions in the standard library, for /// example [this one](u32::checked_sub). #[inline] fn checked_sub(self, other: $t) -> Option<$t> { $t::checked_sub(self, other) } } }; } apply_to_primitive_ints!(impl_checked_sub); malachite-base-0.4.16/src/num/arithmetic/checked_sub_mul.rs000064400000000000000000000072411046102023000217600ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{CheckedSubMul, UnsignedAbs}; use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::WrappingFrom; fn checked_sub_mul_unsigned(x: T, y: T, z: T) -> Option { y.checked_mul(z).and_then(|yz| x.checked_sub(yz)) } macro_rules! impl_checked_sub_mul_unsigned { ($t:ident) => { impl CheckedSubMul<$t> for $t { type Output = $t; /// Subtracts a number by the product of two other numbers, returning `None` if the /// result cannot be represented. /// /// $$ /// f(x, y, z) = \\begin{cases} /// \operatorname{Some}(x - yz) & \text{if} \\quad x \geq yz, \\\\ /// \operatorname{None} & \text{if} \\quad x < yz, /// \\end{cases} /// $$ /// where $W$ is `Self::WIDTH`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::checked_sub_mul#checked_sub_mul). #[inline] fn checked_sub_mul(self, y: $t, z: $t) -> Option<$t> { checked_sub_mul_unsigned(self, y, z) } } }; } apply_to_unsigneds!(impl_checked_sub_mul_unsigned); fn checked_sub_mul_signed< U: Ord + PrimitiveUnsigned, T: PrimitiveSigned + UnsignedAbs + WrappingFrom, >( x: T, y: T, z: T, ) -> Option { if y == T::ZERO || z == T::ZERO { return Some(x); } let x_sign = x >= T::ZERO; if x_sign == ((y >= T::ZERO) != (z >= T::ZERO)) { x.checked_sub(y.checked_mul(z)?) } else { let x = x.unsigned_abs(); let product = y.unsigned_abs().checked_mul(z.unsigned_abs())?; let result = T::wrapping_from(if x_sign { x.wrapping_sub(product) } else { product.wrapping_sub(x) }); if x >= product || (x_sign == (result < T::ZERO)) { Some(result) } else { None } } } macro_rules! impl_checked_sub_mul_signed { ($t:ident) => { impl CheckedSubMul<$t> for $t { type Output = $t; /// Subtracts a number by the product of two other numbers, returning `None` if the /// result cannot be represented. /// /// $$ /// f(x, y, z) = \\begin{cases} /// \operatorname{Some}(x - yz) & /// \text{if} \\quad -2^{W-1} \leq x - yz < 2^{W-1}, \\\\ /// \operatorname{None} & /// \text{if} \\quad x - yz < -2^{W-1} \\ \mathrm{or} /// \\ xy - z \geq 2^{W-1}, \\\\ /// \\end{cases} /// $$ /// where $W$ is `Self::WIDTH`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::checked_sub_mul#checked_sub_mul). #[inline] fn checked_sub_mul(self, y: $t, z: $t) -> Option<$t> { checked_sub_mul_signed(self, y, z) } } }; } apply_to_signeds!(impl_checked_sub_mul_signed); malachite-base-0.4.16/src/num/arithmetic/coprime_with.rs000064400000000000000000000053331046102023000213350ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::CoprimeWith; use crate::num::basic::unsigneds::PrimitiveUnsigned; pub_test! {coprime_with_check_2(x: T, y: T) -> bool { (x.odd() || y.odd()) && x.gcd(y) == T::ONE }} #[cfg(feature = "test_build")] pub fn coprime_with_check_2_3(x: T, y: T) -> bool { (x.odd() || y.odd()) && (!x.divisible_by(T::from(3u8)) || !y.divisible_by(T::from(3u8))) && x.gcd(y) == T::ONE } #[cfg(feature = "test_build")] pub fn coprime_with_check_2_3_5(x: T, y: T) -> bool { if x.even() && y.even() { false } else { let c15 = T::from(15u8); let c3 = T::from(3u8); let c6 = T::from(6u8); let c9 = T::from(9u8); let c12 = T::from(12u8); let c5 = T::from(5u8); let c10 = T::from(10u8); let x15 = x % c15; let y15 = y % c15; if (x15 == T::ZERO || x15 == c3 || x15 == c6 || x15 == c9 || x15 == c12) && (y15 == T::ZERO || y15 == c3 || y15 == c6 || y15 == c9 || y15 == c12) { return false; } if (x15 == T::ZERO || x15 == c5 || x15 == c10) && (y15 == T::ZERO || y15 == c5 || y15 == c10) { return false; } x.gcd(y) == T::ONE } } macro_rules! impl_coprime_with { ($t:ident) => { impl CoprimeWith<$t> for $t { /// Returns whether two numbers are coprime; that is, whether they have no common factor /// other than 1. /// /// Every number is coprime with 1. No number is coprime with 0, except 1. /// /// $f(x, y) = (\gcd(x, y) = 1)$. /// /// $f(x, y) = ((k,m,n \in \N \land x=km \land y=kn) \implies k=1)$. /// /// # Worst-case complexity /// $T(n) = O(n^2)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is /// `max(self.significant_bits(), other.significant_bits())`. /// /// # Examples /// See [here](super::coprime_with#coprime_with). #[inline] fn coprime_with(self, other: $t) -> bool { coprime_with_check_2(self, other) } } }; } apply_to_unsigneds!(impl_coprime_with); malachite-base-0.4.16/src/num/arithmetic/div_exact.rs000064400000000000000000000060541046102023000206130ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{DivExact, DivExactAssign}; macro_rules! impl_div_exact { ($t:ident) => { impl DivExact<$t> for $t { type Output = $t; /// Divides a value by another value. The first value must be exactly divisible by the /// second. /// /// If `self` is not exactly divisible by `other`, this function may panic or return a /// meaningless result. /// /// $$ /// f(x, y) = \frac{x}{y}. /// $$ /// /// If you are unsure whether the division will be exact, use `self / other` instead. If /// you're unsure and you want to know, use `self.div_mod(other)` and check whether the /// remainder is zero. If you want a function that panics if the division is not exact, /// use `self.div_round(other, Exact)`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `other` is zero or if `self` is `Self::MIN` and other is -1. /// /// # Examples /// See [here](super::div_exact#div_exact). #[inline] fn div_exact(self, other: $t) -> $t { self / other } } impl DivExactAssign<$t> for $t { /// Divides a value by another value in place. The value being assigned to must be /// exactly divisible by the value on the right-hand side. /// /// If `self` is not exactly divisible by `other`, this function may panic or return a /// meaningless result. /// /// $$ /// x \gets \frac{x}{y}. /// $$ /// /// If you are unsure whether the division will be exact, use `self /= other` instead. /// If you're unsure and you want to know, use `self.div_assign_mod(other)` and check /// whether the remainder is zero. If you want a function that panics if the division is /// not exact, use `self.div_round_assign(other, Exact)`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `other` is zero or if `self` is `Self::MIN` and other is -1. /// /// # Examples /// See [here](super::div_exact#div_exact_assign). #[inline] fn div_exact_assign(&mut self, other: $t) { *self /= other; } } }; } apply_to_primitive_ints!(impl_div_exact); malachite-base-0.4.16/src/num/arithmetic/div_mod.rs000064400000000000000000000410611046102023000202630ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{ CeilingDivAssignMod, CeilingDivAssignNegMod, CeilingDivMod, CeilingDivNegMod, DivAssignMod, DivAssignRem, DivMod, DivRem, UnsignedAbs, }; use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::{ExactFrom, WrappingFrom}; fn div_mod_unsigned(x: T, other: T) -> (T, T) { let q = x / other; (q, x - q * other) } fn div_assign_mod_unsigned(x: &mut T, other: T) -> T { let original = *x; *x /= other; original - *x * other } fn ceiling_div_neg_mod_unsigned(x: T, other: T) -> (T, T) { let (quotient, remainder) = x.div_mod(other); if remainder == T::ZERO { (quotient, T::ZERO) } else { // Here remainder != 0, so other > 1, so quotient < T::MAX. (quotient + T::ONE, other - remainder) } } fn ceiling_div_assign_neg_mod_unsigned(x: &mut T, other: T) -> T { let remainder = x.div_assign_mod(other); if remainder == T::ZERO { T::ZERO } else { // Here remainder != 0, so other > 1, so self < T::MAX. *x += T::ONE; other - remainder } } macro_rules! impl_div_mod_unsigned { ($t:ident) => { impl DivMod<$t> for $t { type DivOutput = $t; type ModOutput = $t; /// Divides a number by another number, returning the quotient and remainder. The /// quotient is rounded towards negative infinity. /// /// The quotient and remainder satisfy $x = qy + r$ and $0 \leq r < y$. /// /// $$ /// f(x, y) = \left ( \left \lfloor \frac{x}{y} \right \rfloor, \space /// x - y\left \lfloor \frac{x}{y} \right \rfloor \right ). /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `other` is 0. /// /// # Examples /// See [here](super::div_mod#div_mod). #[inline] fn div_mod(self, other: $t) -> ($t, $t) { div_mod_unsigned(self, other) } } impl DivAssignMod<$t> for $t { type ModOutput = $t; /// Divides a number by another number in place, returning the remainder. The quotient /// is rounded towards negative infinity. /// /// The quotient and remainder satisfy $x = qy + r$ and $0 \leq r < y$. /// /// $$ /// f(x, y) = x - y\left \lfloor \frac{x}{y} \right \rfloor, /// $$ /// $$ /// x \gets \left \lfloor \frac{x}{y} \right \rfloor. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `other` is 0. /// /// # Examples /// See [here](super::div_mod#div_assign_mod). #[inline] fn div_assign_mod(&mut self, other: $t) -> $t { div_assign_mod_unsigned(self, other) } } impl DivRem<$t> for $t { type DivOutput = $t; type RemOutput = $t; /// Divides a number by another number, returning the quotient and remainder. The /// quotient is rounded towards zero. /// /// The quotient and remainder satisfy $x = qy + r$ and $0 \leq r < y$. /// /// $$ /// f(x, y) = \left ( \left \lfloor \frac{x}{y} \right \rfloor, \space /// x - y\left \lfloor \frac{x}{y} \right \rfloor \right ). /// $$ /// /// For unsigned integers, `div_rem` is equivalent to `div_mod`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `other` is 0. /// /// # Examples /// See [here](super::div_mod#div_rem). #[inline] fn div_rem(self, other: $t) -> ($t, $t) { self.div_mod(other) } } impl DivAssignRem<$t> for $t { type RemOutput = $t; /// Divides a number by another number in place, returning the remainder. The quotient /// is rounded towards zero. /// /// The quotient and remainder satisfy $x = qy + r$ and $0 \leq r < y$. /// /// $$ /// f(x, y) = x - y\left \lfloor \frac{x}{y} \right \rfloor, /// $$ /// $$ /// x \gets \left \lfloor \frac{x}{y} \right \rfloor. /// $$ /// /// For unsigned integers, `div_assign_rem` is equivalent to `div_assign_mod`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `other` is 0. /// /// # Examples /// See [here](super::div_mod#div_assign_rem). #[inline] fn div_assign_rem(&mut self, other: $t) -> $t { self.div_assign_mod(other) } } impl CeilingDivNegMod<$t> for $t { type DivOutput = $t; type ModOutput = $t; /// Divides a number by another number, returning the ceiling of the quotient and the /// remainder of the negative of the first number divided by the second. /// /// The quotient and remainder satisfy $x = qy - r$ and $0 \leq r < y$. /// /// $$ /// f(x, y) = \left ( \left \lceil \frac{x}{y} \right \rceil, \space /// y\left \lceil \frac{x}{y} \right \rceil - x \right ). /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `other` is 0. /// /// # Examples /// See [here](super::div_mod#ceiling_div_neg_mod). #[inline] fn ceiling_div_neg_mod(self, other: $t) -> ($t, $t) { ceiling_div_neg_mod_unsigned(self, other) } } impl CeilingDivAssignNegMod<$t> for $t { type ModOutput = $t; /// Divides a number by another number in place, returning the remainder of the negative /// of the first number divided by the second. /// /// The quotient and remainder satisfy $x = qy - r$ and $0 \leq r < y$. /// /// $$ /// f(x, y) = y\left \lceil \frac{x}{y} \right \rceil - x, /// $$ /// $$ /// x \gets \left \lceil \frac{x}{y} \right \rceil. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `other` is 0. /// /// # Examples /// See [here](super::div_mod#ceiling_div_assign_neg_mod). #[inline] fn ceiling_div_assign_neg_mod(&mut self, other: $t) -> $t { ceiling_div_assign_neg_mod_unsigned(self, other) } } }; } apply_to_unsigneds!(impl_div_mod_unsigned); fn div_mod_signed< U: PrimitiveUnsigned, S: PrimitiveSigned + ExactFrom + UnsignedAbs + WrappingFrom, >( x: S, other: S, ) -> (S, S) { let (quotient, remainder) = if (x >= S::ZERO) == (other >= S::ZERO) { let (quotient, remainder) = x.unsigned_abs().div_mod(other.unsigned_abs()); (S::exact_from(quotient), remainder) } else { let (quotient, remainder) = x.unsigned_abs().ceiling_div_neg_mod(other.unsigned_abs()); (S::wrapping_from(quotient).wrapping_neg(), remainder) }; ( quotient, if other >= S::ZERO { S::exact_from(remainder) } else { -S::exact_from(remainder) }, ) } fn div_rem_signed(x: T, other: T) -> (T, T) { let q = x.checked_div(other).unwrap(); (q, x - q * other) } fn div_assign_rem_signed(x: &mut T, other: T) -> T { let original = *x; *x = x.checked_div(other).unwrap(); original - *x * other } fn ceiling_div_mod_signed< U: PrimitiveUnsigned, T: PrimitiveSigned + ExactFrom + UnsignedAbs + WrappingFrom, >( x: T, other: T, ) -> (T, T) { let (quotient, remainder) = if (x >= T::ZERO) == (other >= T::ZERO) { let (quotient, remainder) = x.unsigned_abs().ceiling_div_neg_mod(other.unsigned_abs()); (T::exact_from(quotient), remainder) } else { let (quotient, remainder) = x.unsigned_abs().div_mod(other.unsigned_abs()); (T::wrapping_from(quotient).wrapping_neg(), remainder) }; ( quotient, if other >= T::ZERO { -T::exact_from(remainder) } else { T::exact_from(remainder) }, ) } macro_rules! impl_div_mod_signed { ($t:ident) => { impl DivMod<$t> for $t { type DivOutput = $t; type ModOutput = $t; /// Divides a number by another number, returning the quotient and remainder. The /// quotient is rounded towards negative infinity, and the remainder has the same sign /// as the second number. /// /// The quotient and remainder satisfy $x = qy + r$ and $0 \leq |r| < |y|$. /// /// $$ /// f(x, y) = \left ( \left \lfloor \frac{x}{y} \right \rfloor, \space /// x - y\left \lfloor \frac{x}{y} \right \rfloor \right ). /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `other` is 0, or if `self` is `$t::MIN` and `other` is -1. /// /// # Examples /// See [here](super::div_mod#div_mod). #[inline] fn div_mod(self, other: $t) -> ($t, $t) { div_mod_signed(self, other) } } impl DivAssignMod<$t> for $t { type ModOutput = $t; /// Divides a number by another number in place, returning the remainder. The quotient /// is rounded towards negative infinity, and the remainder has the same sign as the /// second number. /// /// The quotient and remainder satisfy $x = qy + r$ and $0 \leq |r| < |y|$. /// /// $$ /// f(x, y) = x - y\left \lfloor \frac{x}{y} \right \rfloor, /// $$ /// $$ /// x \gets \left \lfloor \frac{x}{y} \right \rfloor. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `other` is 0, or if `self` is `$t::MIN` and `other` is -1. /// /// # Examples /// See [here](super::div_mod#div_assign_mod). #[inline] fn div_assign_mod(&mut self, other: $t) -> $t { let (q, r) = self.div_mod(other); *self = q; r } } impl DivRem<$t> for $t { type DivOutput = $t; type RemOutput = $t; /// Divides a number by another number, returning the quotient and remainder. The /// quotient is rounded towards zero and the remainder has the same sign as the /// dividend. /// /// The quotient and remainder satisfy $x = qy + r$ and $0 \leq |r| < |y|$. /// /// $$ /// f(x, y) = \left ( \operatorname{sgn}(xy) \left \lfloor \left | \frac{x}{y} \right | /// \right \rfloor, \space /// x - y \operatorname{sgn}(xy) /// \left \lfloor \left | \frac{x}{y} \right | \right \rfloor \right ). /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `other` is 0, or if `self` is `$t::MIN` and `other` is -1. /// /// # Examples /// See [here](super::div_mod#div_rem). #[inline] fn div_rem(self, other: $t) -> ($t, $t) { div_rem_signed(self, other) } } impl DivAssignRem<$t> for $t { type RemOutput = $t; /// Divides a number by another number in place, returning the remainder. The quotient /// is rounded towards zero and the remainder has the same sign as the dividend. /// /// The quotient and remainder satisfy $x = qy + r$ and $0 \leq |r| < |y|$. /// /// $$ /// f(x, y) = x - y \operatorname{sgn}(xy) /// \left \lfloor \left | \frac{x}{y} \right | \right \rfloor, /// $$ /// $$ /// x \gets \operatorname{sgn}(xy) \left \lfloor \left | \frac{x}{y} \right | /// \right \rfloor. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `other` is 0, or if `self` is `$t::MIN` and `other` is -1. /// /// # Examples /// See [here](super::div_mod#div_assign_rem). #[inline] fn div_assign_rem(&mut self, other: $t) -> $t { div_assign_rem_signed(self, other) } } impl CeilingDivMod<$t> for $t { type DivOutput = $t; type ModOutput = $t; /// Divides a number by another number, returning the quotient and remainder. The /// quotient is rounded towards positive infinity and the remainder has the opposite /// sign as the second number. /// /// The quotient and remainder satisfy $x = qy + r$ and $0 \leq |r| < |y|$. /// /// $$ /// f(x, y) = \left ( \left \lceil \frac{x}{y} \right \rceil, \space /// x - y\left \lceil \frac{x}{y} \right \rceil \right ). /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `other` is 0, or if `self` is `$t::MIN` and `other` is -1. /// /// # Examples /// See [here](super::div_mod#ceiling_div_mod). #[inline] fn ceiling_div_mod(self, other: $t) -> ($t, $t) { ceiling_div_mod_signed(self, other) } } impl CeilingDivAssignMod<$t> for $t { type ModOutput = $t; /// Divides a number by another number in place, returning the remainder. The quotient /// is rounded towards positive infinity and the remainder has the opposite sign as the /// second number. /// /// The quotient and remainder satisfy $x = qy + r$ and $0 \leq |r| < |y|$. /// /// $$ /// f(x, y) = x - y\left \lceil\frac{x}{y} \right \rceil, /// $$ /// $$ /// x \gets \left \lceil \frac{x}{y} \right \rceil. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `other` is 0, or if `self` is `$t::MIN` and `other` is -1. /// /// # Examples /// See [here](super::div_mod#ceiling_div_assign_mod). #[inline] fn ceiling_div_assign_mod(&mut self, other: $t) -> $t { let (q, r) = self.ceiling_div_mod(other); *self = q; r } } }; } apply_to_signeds!(impl_div_mod_signed); malachite-base-0.4.16/src/num/arithmetic/div_round.rs000064400000000000000000000215421046102023000206350ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{DivRound, DivRoundAssign, UnsignedAbs}; use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::{ExactFrom, WrappingFrom}; use crate::rounding_modes::RoundingMode::{self, *}; use core::cmp::Ordering::{self, *}; fn div_round_unsigned(x: T, other: T, rm: RoundingMode) -> (T, Ordering) { let quotient = x / other; let remainder = x - quotient * other; match rm { _ if remainder == T::ZERO => (quotient, Equal), Down | Floor => (quotient, Less), Up | Ceiling => (quotient + T::ONE, Greater), Nearest => { let shifted_other = other >> 1; if remainder > shifted_other || remainder == shifted_other && other.even() && quotient.odd() { (quotient + T::ONE, Greater) } else { (quotient, Less) } } Exact => { panic!("Division is not exact: {x} / {other}"); } } } macro_rules! impl_div_round_unsigned { ($t:ident) => { impl DivRound<$t> for $t { type Output = $t; /// Divides a value by another value and rounds according to a specified rounding mode. /// An [`Ordering`] is also returned, indicating whether the returned value is less /// than, equal to, or greater than the exact value. /// /// Let $q = \frac{x}{y}$, and let $g$ be the function that just returns the first /// element of the pair, without the [`Ordering`]: /// /// $$ /// g(x, y, \mathrm{Down}) = g(x, y, \mathrm{Floor}) = \lfloor q \rfloor. /// $$ /// /// $$ /// g(x, y, \mathrm{Up}) = g(x, y, \mathrm{Ceiling}) = \lceil q \rceil. /// $$ /// /// $$ /// g(x, y, \mathrm{Nearest}) = \begin{cases} /// \lfloor q \rfloor & \text{if} \\quad q - \lfloor q \rfloor < \frac{1}{2}, \\\\ /// \lceil q \rceil & \text{if} \\quad q - \lfloor q \rfloor > \frac{1}{2}, \\\\ /// \lfloor q \rfloor & /// \text{if} \\quad q - \lfloor q \rfloor = \frac{1}{2} /// \\ \text{and} \\ \lfloor q \rfloor \\ \text{is even}, \\\\ /// \lceil q \rceil & /// \text{if} \\quad q - \lfloor q \rfloor = \frac{1}{2} /// \\ \text{and} \\ \lfloor q \rfloor \\ \text{is odd.} /// \end{cases} /// $$ /// /// $g(x, y, \mathrm{Exact}) = q$, but panics if $q \notin \N$. /// /// Then /// /// $f(x, y, r) = (g(x, y, r), \operatorname{cmp}(g(x, y, r), q))$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `other` is zero, or if `rm` is `Exact` but `self` is not divisible by /// `other`. /// /// # Examples /// See [here](super::div_round#div_round). #[inline] fn div_round(self, other: $t, rm: RoundingMode) -> ($t, Ordering) { div_round_unsigned(self, other, rm) } } impl DivRoundAssign<$t> for $t { /// Divides a value by another value in place and rounds according to a specified /// rounding mode. An [`Ordering`] is returned, indicating whether the assigned value is /// less than, equal to, or greater than the exact value. /// /// See the [`DivRound`] documentation for details. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `other` is zero, or if `rm` is `Exact` but `self` is not divisible by /// `other`. /// /// # Examples /// See [here](super::div_round#div_round_assign). #[inline] fn div_round_assign(&mut self, other: $t, rm: RoundingMode) -> Ordering { let o; (*self, o) = self.div_round(other, rm); o } } }; } apply_to_unsigneds!(impl_div_round_unsigned); fn div_round_signed< U: PrimitiveUnsigned, S: ExactFrom + PrimitiveSigned + UnsignedAbs + WrappingFrom, >( x: S, other: S, rm: RoundingMode, ) -> (S, Ordering) { if (x >= S::ZERO) == (other >= S::ZERO) { let (q, o) = x.unsigned_abs().div_round(other.unsigned_abs(), rm); (S::exact_from(q), o) } else { // Has to be wrapping so that (self, other) == (T::MIN, 1) works let (q, o) = x.unsigned_abs().div_round(other.unsigned_abs(), -rm); (S::wrapping_from(q).wrapping_neg(), o.reverse()) } } macro_rules! impl_div_round_signed { ($t:ident) => { impl DivRound<$t> for $t { type Output = $t; /// Divides a value by another value and rounds according to a specified rounding mode. /// An [`Ordering`] is also returned, indicating whether the returned value is less /// than, equal to, or greater than the exact value. /// /// Let $q = \frac{x}{y}$, and let $g$ be the function that just returns the first /// element of the pair, without the [`Ordering`]: /// /// $$ /// g(x, y, \mathrm{Down}) = \operatorname{sgn}(q) \lfloor |q| \rfloor. /// $$ /// /// $$ /// g(x, y, \mathrm{Up}) = \operatorname{sgn}(q) \lceil |q| \rceil. /// $$ /// /// $$ /// g(x, y, \mathrm{Floor}) = \lfloor q \rfloor. /// $$ /// /// $$ /// g(x, y, \mathrm{Ceiling}) = \lceil q \rceil. /// $$ /// /// $$ /// g(x, y, \mathrm{Nearest}) = \begin{cases} /// \lfloor q \rfloor & \text{if} \\quad q - \lfloor q \rfloor < \frac{1}{2}, \\\\ /// \lceil q \rceil & q - \lfloor q \rfloor > \frac{1}{2}, \\\\ /// \lfloor q \rfloor & /// \text{if} \\quad q - \lfloor q \rfloor = \frac{1}{2} \\ \text{and} /// \\ \lfloor q \rfloor \\ \text{is even}, \\\\ /// \lceil q \rceil & /// \text{if} \\quad q - \lfloor q \rfloor = \frac{1}{2} \\ \text{and} /// \\ \lfloor q \rfloor \\ \text{is odd.} /// \end{cases} /// $$ /// /// $g(x, y, \mathrm{Exact}) = q$, but panics if $q \notin \Z$. /// /// Then /// /// $f(x, y, r) = (g(x, y, r), \operatorname{cmp}(g(x, y, r), q))$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `other` is zero, if `self` is `Self::MIN` and `other` is `-1`, or if `rm` /// is `Exact` but `self` is not divisible by `other`. /// /// # Examples /// See [here](super::div_round#div_round). fn div_round(self, other: $t, rm: RoundingMode) -> ($t, Ordering) { div_round_signed(self, other, rm) } } impl DivRoundAssign<$t> for $t { /// Divides a value by another value in place and rounds according to a specified /// rounding mode. An [`Ordering`] is returned, indicating whether the assigned value is /// less than, equal to, or greater than the exact value. /// /// See the [`DivRound`] documentation for details. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `other` is zero, if `self` is `Self::MIN` and `other` is `-1`, or if `rm` /// is `Exact` but `self` is not divisible by `other`. /// /// # Examples /// See [here](super::div_round#div_round_assign). #[inline] fn div_round_assign(&mut self, other: $t, rm: RoundingMode) -> Ordering { let o; (*self, o) = self.div_round(other, rm); o } } }; } apply_to_signeds!(impl_div_round_signed); malachite-base-0.4.16/src/num/arithmetic/divisible_by.rs000064400000000000000000000053461046102023000213140ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::DivisibleBy; use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; fn divisible_by_unsigned(x: T, other: T) -> bool { x == T::ZERO || other != T::ZERO && x % other == T::ZERO } macro_rules! impl_divisible_by_unsigned { ($t:ident) => { impl DivisibleBy<$t> for $t { /// Returns whether a number is divisible by another number; in other words, whether the /// first number is a multiple of the second. /// /// This means that zero is divisible by any number, including zero; but a nonzero /// number is never divisible by zero. /// /// $f(x, m) = (m|x)$. /// /// $f(x, m) = (\exists k \in \N : x = km)$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::divisible_by#divisible_by). #[inline] fn divisible_by(self, other: $t) -> bool { divisible_by_unsigned(self, other) } } }; } apply_to_unsigneds!(impl_divisible_by_unsigned); fn divisible_by_signed(x: T, other: T) -> bool { x == T::ZERO || x == T::MIN && other == T::NEGATIVE_ONE || other != T::ZERO && x % other == T::ZERO } macro_rules! impl_divisible_by_signed { ($t:ident) => { impl DivisibleBy<$t> for $t { /// Returns whether a number is divisible by another number; in other words, whether the /// first number is a multiple of the second. /// /// This means that zero is divisible by any number, including zero; but a nonzero /// number is never divisible by zero. /// /// $f(x, m) = (m|x)$. /// /// $f(x, m) = (\exists k \in \Z : \ x = km)$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::divisible_by#divisible_by). #[inline] fn divisible_by(self, other: $t) -> bool { divisible_by_signed(self, other) } } }; } apply_to_signeds!(impl_divisible_by_signed); malachite-base-0.4.16/src/num/arithmetic/divisible_by_power_of_2.rs000064400000000000000000000040411046102023000234240ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{DivisibleByPowerOf2, ModPowerOf2}; use crate::num::conversion::traits::WrappingFrom; macro_rules! impl_divisible_by_power_of_2_unsigned { ($t:ident) => { impl DivisibleByPowerOf2 for $t { /// Returns whether a number is divisible by $2^k$. /// /// $f(x, k) = (2^k|x)$. /// /// $f(x, k) = (\exists n \in \N : \ x = n2^k)$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::divisible_by_power_of_2#divisible_by_power_of_2). #[inline] fn divisible_by_power_of_2(self, pow: u64) -> bool { self.mod_power_of_2(pow) == 0 } } }; } apply_to_unsigneds!(impl_divisible_by_power_of_2_unsigned); macro_rules! impl_divisible_by_power_of_2_signed { ($u:ident, $s:ident) => { impl DivisibleByPowerOf2 for $s { /// Returns whether a number is divisible by $2^k$. /// /// $f(x, k) = (2^k|x)$. /// /// $f(x, k) = (\exists n \in \N : x = n2^k)$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::divisible_by_power_of_2#divisible_by_power_of_2). #[inline] fn divisible_by_power_of_2(self, pow: u64) -> bool { $u::wrapping_from(self).divisible_by_power_of_2(pow) } } }; } apply_to_unsigned_signed_pairs!(impl_divisible_by_power_of_2_signed); malachite-base-0.4.16/src/num/arithmetic/eq_mod.rs000064400000000000000000000027651046102023000201160ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{EqMod, Mod}; use crate::num::basic::traits::Zero; fn eq_mod + Zero>(x: S, other: S, m: S) -> bool { x == other || m != S::ZERO && x.mod_op(m) == other.mod_op(m) } macro_rules! impl_eq_mod { ($t:ident) => { impl EqMod<$t> for $t { /// Returns whether a number is equivalent to another number modulo a third; that is, /// whether the difference between the first two is a multiple of the third. /// /// Two numbers are equal to each other modulo 0 iff they are equal. /// /// $f(x, y, m) = (x \equiv y \mod m)$. /// /// $f(x, y, m) = (\exists k \in \Z : x - y = km)$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::eq_mod#eq_mod). #[inline] fn eq_mod(self, other: $t, m: $t) -> bool { eq_mod(self, other, m) } } }; } apply_to_primitive_ints!(impl_eq_mod); malachite-base-0.4.16/src/num/arithmetic/eq_mod_power_of_2.rs000064400000000000000000000023251046102023000222270ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{DivisibleByPowerOf2, EqModPowerOf2}; macro_rules! impl_eq_mod_power_of_2 { ($t:ident) => { impl EqModPowerOf2<$t> for $t { /// Returns whether one number is equal to another modulo $2^k$. /// /// $f(x, y, k) = (x \equiv y \mod 2^k)$. /// /// $f(x, y, k) = (\exists n \in \Z : x - y = n2^k)$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::eq_mod_power_of_2#eq_mod_power_of_2). #[inline] fn eq_mod_power_of_2(self, other: $t, pow: u64) -> bool { (self ^ other).divisible_by_power_of_2(pow) } } }; } apply_to_primitive_ints!(impl_eq_mod_power_of_2); malachite-base-0.4.16/src/num/arithmetic/extended_gcd.rs000064400000000000000000000203731046102023000212620ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // Uses code adopted from the FLINT Library. // // Copyright © 2009, 2016 William Hart // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::ExtendedGcd; use crate::num::arithmetic::traits::UnsignedAbs; use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::WrappingFrom; use crate::rounding_modes::RoundingMode::*; use core::mem::swap; fn extended_gcd_signed< U: ExtendedGcd + PrimitiveUnsigned, S: PrimitiveSigned + UnsignedAbs + WrappingFrom, >( a: S, b: S, ) -> (U, S, S) { let (gcd, mut x, mut y) = a.unsigned_abs().extended_gcd(b.unsigned_abs()); if a < S::ZERO { x = x.checked_neg().unwrap(); } if b < S::ZERO { y = y.checked_neg().unwrap(); } (gcd, x, y) } // This is equivalent to `n_xgcd` from `ulong_extras/xgcd.c`, FLINT 2.7.1, with an adjustment to // find the minimal cofactors. pub_test! {extended_gcd_unsigned_binary< U: WrappingFrom + PrimitiveUnsigned, S: PrimitiveSigned + WrappingFrom, >( mut a: U, mut b: U, ) -> (U, S, S) { if a == U::ZERO && b == U::ZERO { return (U::ZERO, S::ZERO, S::ZERO); } else if a == b || a == U::ZERO { return (b, S::ZERO, S::ONE); } else if b == U::ZERO { return (a, S::ONE, S::ZERO); } let mut swapped = false; if a < b { swap(&mut a, &mut b); swapped = true; } let mut u1 = S::ONE; let mut v2 = S::ONE; let mut u2 = S::ZERO; let mut v1 = S::ZERO; let mut u3 = a; let mut v3 = b; let mut d; let mut t2; let mut t1; if (a & b).get_highest_bit() { d = u3 - v3; t2 = v2; t1 = u2; u2 = u1 - u2; u1 = t1; u3 = v3; v2 = v1 - v2; v1 = t2; v3 = d; } while v3.get_bit(U::WIDTH - 2) { d = u3 - v3; if d < v3 { // quot = 1 t2 = v2; t1 = u2; u2 = u1 - u2; u1 = t1; u3 = v3; v2 = v1 - v2; v1 = t2; v3 = d; } else if d < (v3 << 1) { // quot = 2 t1 = u2; u2 = u1 - (u2 << 1); u1 = t1; u3 = v3; t2 = v2; v2 = v1 - (v2 << 1); v1 = t2; v3 = d - u3; } else { // quot = 3 t1 = u2; u2 = u1 - S::wrapping_from(3) * u2; u1 = t1; u3 = v3; t2 = v2; v2 = v1 - S::wrapping_from(3) * v2; v1 = t2; v3 = d - (u3 << 1); } } while v3 != U::ZERO { d = u3 - v3; // overflow not possible, top 2 bits of v3 not set if u3 < (v3 << 2) { if d < v3 { // quot = 1 t2 = v2; t1 = u2; u2 = u1 - u2; u1 = t1; u3 = v3; v2 = v1 - v2; v1 = t2; v3 = d; } else if d < (v3 << 1) { // quot = 2 t1 = u2; u2 = u1.wrapping_sub(u2 << 1); u1 = t1; u3 = v3; t2 = v2; v2 = v1.wrapping_sub(v2 << 1); v1 = t2; v3 = d - u3; } else { // quot = 3 t1 = u2; u2 = u1.wrapping_sub(S::wrapping_from(3).wrapping_mul(u2)); u1 = t1; u3 = v3; t2 = v2; v2 = v1.wrapping_sub(S::wrapping_from(3).wrapping_mul(v2)); v1 = t2; v3 = d.wrapping_sub(u3 << 1); } } else { let (quot, rem) = u3.div_rem(v3); t1 = u2; u2 = u1.wrapping_sub(S::wrapping_from(quot).wrapping_mul(u2)); u1 = t1; u3 = v3; t2 = v2; v2 = v1.wrapping_sub(S::wrapping_from(quot).wrapping_mul(v2)); v1 = t2; v3 = rem; } } // Remarkably, |u1| < x/2, thus comparison with 0 is valid if u1 <= S::ZERO { u1.wrapping_add_assign(S::wrapping_from(b)); v1.wrapping_sub_assign(S::wrapping_from(a)); } // The cofactors at this point are not necessarily minimal, so we may need to adjust. let gcd = u3; let mut x = U::wrapping_from(u1); let mut y = U::wrapping_from(v1); let two_limit_a = a / gcd; let two_limit_b = b / gcd; let limit_b = two_limit_b >> 1; if x > limit_b { let k = (x - limit_b).div_round(two_limit_b, Ceiling).0; x.wrapping_sub_assign(two_limit_b.wrapping_mul(k)); y.wrapping_add_assign(two_limit_a.wrapping_mul(k)); } if swapped { swap(&mut x, &mut y); } (gcd, S::wrapping_from(x), S::wrapping_from(y)) }} macro_rules! impl_extended_gcd { ($u:ident, $s:ident) => { impl ExtendedGcd<$u> for $u { type Gcd = $u; type Cofactor = $s; /// Computes the GCD (greatest common divisor) of two numbers $a$ and $b$, and also the /// coefficients $x$ and $y$ in Bézout's identity $ax+by=\gcd(a,b)$. /// /// The are infinitely many $x$, $y$ that satisfy the identity for any $a$, $b$, so the /// full specification is more detailed: /// /// - $f(0, 0) = (0, 0, 0)$. /// - $f(a, ak) = (a, 1, 0)$ if $a > 0$ and $k \neq 1$. /// - $f(bk, b) = (b, 0, 1)$ if $b > 0$. /// - $f(a, b) = (g, x, y)$ if $a \neq 0$ and $b \neq 0$ and $\gcd(a, b) \neq \min(a, /// b)$, where $g = \gcd(a, b) \geq 0$, $ax + by = g$, $x \leq \lfloor b/g \rfloor$, /// and $y \leq \lfloor a/g \rfloor$. /// /// # Worst-case complexity /// $T(n) = O(n^2)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is /// `max(self.significant_bits(), other.significant_bits())`. /// /// # Examples /// See [here](super::extended_gcd#extended_gcd). #[inline] fn extended_gcd(self, other: $u) -> ($u, $s, $s) { extended_gcd_unsigned_binary(self, other) } } impl ExtendedGcd<$s> for $s { type Gcd = $u; type Cofactor = $s; /// Computes the GCD (greatest common divisor) of two numbers $a$ and $b$, and also the /// coefficients $x$ and $y$ in Bézout's identity $ax+by=\gcd(a,b)$. /// /// The are infinitely many $x$, $y$ that satisfy the identity for any $a$, $b$, so the /// full specification is more detailed: /// /// - $f(0, 0) = (0, 0, 0)$. /// - $f(a, ak) = (a, 1, 0)$ if $a > 0$ and $k \neq 1$. /// - $f(a, ak) = (-a, -1, 0)$ if $a < 0$ and $k \neq 1$. /// - $f(bk, b) = (b, 0, 1)$ if $b > 0$. /// - $f(bk, b) = (-b, 0, -1)$ if $b < 0$. /// - $f(a, b) = (g, x, y)$ if $a \neq 0$ and $b \neq 0$ and $\gcd(a, b) \neq \min(|a|, /// |b|)$, where $g = \gcd(a, b) \geq 0$, $ax + by = g$, $x \leq \lfloor b/g \rfloor$, /// and $y \leq \lfloor a/g \rfloor$. /// /// # Worst-case complexity /// $T(n) = O(n^2)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is /// `max(self.significant_bits(), other.significant_bits())`. /// /// # Examples /// See [here](super::extended_gcd#extended_gcd). #[inline] fn extended_gcd(self, other: $s) -> ($u, $s, $s) { extended_gcd_signed(self, other) } } }; } apply_to_unsigned_signed_pairs!(impl_extended_gcd); malachite-base-0.4.16/src/num/arithmetic/factorial.rs000064400000000000000000000421521046102023000206100ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{ CheckedDoubleFactorial, CheckedFactorial, CheckedMultifactorial, CheckedSubfactorial, DoubleFactorial, Factorial, Multifactorial, Parity, Subfactorial, }; use crate::num::basic::integers::PrimitiveInt; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::WrappingFrom; pub_test! {checked_multifactorial_naive(n: u64, m: u64) -> Option { assert_ne!(m, 0); let mut f = T::ONE; let mut n = T::try_from(n).ok()?; let m = T::saturating_from(m); while n != T::ZERO { f = f.checked_mul(n)?; n.saturating_sub_assign(m); } Some(f) }} const FACTORIALS_U8: [u8; 6] = [1, 1, 2, 6, 24, 120]; const FACTORIALS_U16: [u16; 9] = [1, 1, 2, 6, 24, 120, 720, 5040, 40320]; const FACTORIALS_U32: [u32; 13] = [1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600]; const FACTORIALS_U64: [u64; 21] = [ 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600, 6227020800, 87178291200, 1307674368000, 20922789888000, 355687428096000, 6402373705728000, 121645100408832000, 2432902008176640000, ]; const FACTORIALS_U128: [u128; 35] = [ 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600, 6227020800, 87178291200, 1307674368000, 20922789888000, 355687428096000, 6402373705728000, 121645100408832000, 2432902008176640000, 51090942171709440000, 1124000727777607680000, 25852016738884976640000, 620448401733239439360000, 15511210043330985984000000, 403291461126605635584000000, 10888869450418352160768000000, 304888344611713860501504000000, 8841761993739701954543616000000, 265252859812191058636308480000000, 8222838654177922817725562880000000, 263130836933693530167218012160000000, 8683317618811886495518194401280000000, 295232799039604140847618609643520000000, ]; const ODD_DOUBLE_FACTORIALS_U8: [u8; 4] = [1, 3, 15, 105]; const ODD_DOUBLE_FACTORIALS_U16: [u16; 6] = [1, 3, 15, 105, 945, 10395]; const ODD_DOUBLE_FACTORIALS_U32: [u32; 10] = [1, 3, 15, 105, 945, 10395, 135135, 2027025, 34459425, 654729075]; const ODD_DOUBLE_FACTORIALS_U64: [u64; 17] = [ 1, 3, 15, 105, 945, 10395, 135135, 2027025, 34459425, 654729075, 13749310575, 316234143225, 7905853580625, 213458046676875, 6190283353629375, 191898783962510625, 6332659870762850625, ]; const ODD_DOUBLE_FACTORIALS_U128: [u128; 28] = [ 1, 3, 15, 105, 945, 10395, 135135, 2027025, 34459425, 654729075, 13749310575, 316234143225, 7905853580625, 213458046676875, 6190283353629375, 191898783962510625, 6332659870762850625, 221643095476699771875, 8200794532637891559375, 319830986772877770815625, 13113070457687988603440625, 563862029680583509947946875, 25373791335626257947657609375, 1192568192774434123539907640625, 58435841445947272053455474390625, 2980227913743310874726229193921875, 157952079428395476360490147277859375, 8687364368561751199826958100282265625, ]; const SUBFACTORIALS_U8: [u8; 6] = [1, 0, 1, 2, 9, 44]; const SUBFACTORIALS_U16: [u16; 9] = [1, 0, 1, 2, 9, 44, 265, 1854, 14833]; const SUBFACTORIALS_U32: [u32; 14] = [1, 0, 1, 2, 9, 44, 265, 1854, 14833, 133496, 1334961, 14684570, 176214841, 2290792932]; const SUBFACTORIALS_U64: [u64; 21] = [ 1, 0, 1, 2, 9, 44, 265, 1854, 14833, 133496, 1334961, 14684570, 176214841, 2290792932, 32071101049, 481066515734, 7697064251745, 130850092279664, 2355301661033953, 44750731559645106, 895014631192902121, ]; const SUBFACTORIALS_U128: [u128; 35] = [ 1, 0, 1, 2, 9, 44, 265, 1854, 14833, 133496, 1334961, 14684570, 176214841, 2290792932, 32071101049, 481066515734, 7697064251745, 130850092279664, 2355301661033953, 44750731559645106, 895014631192902121, 18795307255050944540, 413496759611120779881, 9510425471055777937262, 228250211305338670494289, 5706255282633466762357224, 148362637348470135821287825, 4005791208408693667174771274, 112162153835443422680893595673, 3252702461227859257745914274516, 97581073836835777732377428235481, 3025013288941909109703700275299910, 96800425246141091510518408809597121, 3194414033122656019847107490716704992, 108610077126170304674801654684367969729, ]; macro_rules! impl_factorials_a { ($t:ident, $fs:ident, $odfs:ident, $sfs:ident, $df_limit:expr) => { impl CheckedFactorial for $t { /// Computes the factorial of a number. /// /// If the input is too large, the function returns `None`. /// /// $$ /// f(n) = \\begin{cases} /// \operatorname{Some}(n!) & \text{if} \\quad n! < 2^W, \\\\ /// \operatorname{None} & \text{if} \\quad n! \geq 2^W, /// \\end{cases} /// $$ /// where $W$ is `Self::WIDTH`. /// /// $n! = O(\sqrt{n}(n/e)^n)$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::factorial#checked_factorial). #[inline] fn checked_factorial(n: u64) -> Option<$t> { $fs.get(usize::try_from(n).ok()?).copied() } } impl CheckedDoubleFactorial for $t { /// Computes the double factorial of a number. /// /// If the input is too large, the function returns `None`. /// /// $$ /// f(n) = \\begin{cases} /// \operatorname{Some}(n!!) & \text{if} \\quad n!! < 2^W, \\\\ /// \operatorname{None} & \text{if} \\quad n!! \geq 2^W, /// \\end{cases} /// $$ /// where $W$ is `Self::WIDTH`. /// /// $n!! = O(\sqrt{n}(n/e)^{n/2})$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::factorial#checked_double_factorial). #[inline] fn checked_double_factorial(n: u64) -> Option<$t> { if n > $df_limit { None } else if n.odd() { $odfs.get(usize::try_from(n >> 1).ok()?).copied() } else { let half = n >> 1; $fs.get(usize::try_from(half).ok()?).map(|&f| f << half) } } } impl CheckedSubfactorial for $t { /// Computes the subfactorial of a number. /// /// The subfactorial of $n$ counts the number of derangements of a set of size $n$; a /// derangement is a permutation with no fixed points. /// /// If the input is too large, the function returns `None`. /// /// $$ /// f(n) = \\begin{cases} /// \operatorname{Some}(!n) & \text{if} \\quad !n < 2^W, \\\\ /// \operatorname{None} & \text{if} \\quad !n \geq 2^W, /// \\end{cases} /// $$ /// where $W$ is `Self::WIDTH`. /// /// $!n = O(n!) = O(\sqrt{n}(n/e)^n)$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::factorial#checked_subfactorial). #[inline] fn checked_subfactorial(n: u64) -> Option<$t> { $sfs.get(usize::try_from(n).ok()?).copied() } } }; } impl_factorials_a!( u8, FACTORIALS_U8, ODD_DOUBLE_FACTORIALS_U8, SUBFACTORIALS_U8, 7 ); impl_factorials_a!( u16, FACTORIALS_U16, ODD_DOUBLE_FACTORIALS_U16, SUBFACTORIALS_U16, 12 ); impl_factorials_a!( u32, FACTORIALS_U32, ODD_DOUBLE_FACTORIALS_U32, SUBFACTORIALS_U32, 20 ); impl_factorials_a!( u64, FACTORIALS_U64, ODD_DOUBLE_FACTORIALS_U64, SUBFACTORIALS_U64, 33 ); impl_factorials_a!( u128, FACTORIALS_U128, ODD_DOUBLE_FACTORIALS_U128, SUBFACTORIALS_U128, 56 ); impl CheckedFactorial for usize { /// Computes the factorial of a [`usize`]. /// /// If the input is too large, the function returns `None`. /// /// $$ /// f(n) = \\begin{cases} /// \operatorname{Some}(n!) & \text{if} \\quad n! < 2^W, \\\\ /// \operatorname{None} & \text{if} \\quad n! \geq 2^W, /// \\end{cases} /// $$ /// where $W$ is `usize::WIDTH`. /// /// $n! = O(\sqrt{n}(n/e)^n)$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::factorial#checked_factorial). #[inline] fn checked_factorial(n: u64) -> Option { FACTORIALS_U64 .get(usize::try_from(n).ok()?) .and_then(|&f| usize::try_from(f).ok()) } } impl CheckedSubfactorial for usize { /// Computes the subfactorial of a [`usize`]. /// /// The subfactorial of $n$ counts the number of derangements of a set of size $n$; a /// derangement is a permutation with no fixed points. /// /// If the input is too large, the function returns `None`. /// /// $$ /// f(n) = \\begin{cases} /// \operatorname{Some}(!n) & \text{if} \\quad !n < 2^W, \\\\ /// \operatorname{None} & \text{if} \\quad !n \geq 2^W, /// \\end{cases} /// $$ /// where $W$ is `usize::WIDTH`. /// /// $!n = O(n!) = O(\sqrt{n}(n/e)^n)$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::factorial#checked_subfactorial). #[inline] fn checked_subfactorial(n: u64) -> Option { SUBFACTORIALS_U64 .get(usize::try_from(n).ok()?) .and_then(|&f| usize::try_from(f).ok()) } } impl CheckedDoubleFactorial for usize { /// Computes the double factorial of a [`usize`]. /// /// If the input is too large, the function returns `None`. /// /// $$ /// f(n) = \\begin{cases} /// \operatorname{Some}(n!!) & \text{if} \\quad n!! < 2^W, \\\\ /// \operatorname{None} & \text{if} \\quad n!! \geq 2^W, /// \\end{cases} /// $$ /// where $W$ is `usize::WIDTH`. /// /// $n!! = O(\sqrt{n}(n/e)^{n/2})$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::factorial#checked_double_factorial). #[inline] fn checked_double_factorial(n: u64) -> Option { match usize::WIDTH { u32::WIDTH => u32::checked_double_factorial(n).map(usize::wrapping_from), u64::WIDTH => u64::checked_double_factorial(n).map(usize::wrapping_from), _ => panic!("Unexpected usize width: {}", usize::WIDTH), } } } macro_rules! impl_factorials_b { ($t:ident) => { impl Factorial for $t { /// Computes the factorial of a number. /// /// If the input is too large, the function panics. For a function that returns `None` /// instead, try [`checked_factorial`](CheckedFactorial::checked_factorial). /// /// $$ /// f(n) = n! = 1 \times 2 \times 3 \times \cdots \times n. /// $$ /// /// $n! = O(\sqrt{n}(n/e)^n)$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if the output is too large to be represented. /// /// # Examples /// See [here](super::factorial#factorial). #[inline] fn factorial(n: u64) -> $t { $t::checked_factorial(n).unwrap() } } impl DoubleFactorial for $t { /// Computes the double factorial of a number. /// /// If the input is too large, the function panics. For a function that returns `None` /// instead, try /// [`checked_double_factorial`](CheckedDoubleFactorial::checked_double_factorial). /// /// $$ /// f(n) = n!! = n \times (n - 2) \times (n - 4) \times \cdots \times i, /// $$ /// where $i$ is 1 if $n$ is odd and $2$ if $n$ is even. /// /// $n!! = O(\sqrt{n}(n/e)^{n/2})$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if the output is too large to be represented. /// /// # Examples /// See [here](super::factorial#double_factorial). #[inline] fn double_factorial(n: u64) -> $t { $t::checked_double_factorial(n).unwrap() } } impl Multifactorial for $t { /// Computes a multifactorial of a number. /// /// If the input is too large, the function panics. For a function that returns `None` /// instead, try /// [`checked_multifactorial`](CheckedMultifactorial::checked_multifactorial). /// /// $$ /// f(n, m) = n!^{(m)} = n \times (n - m) \times (n - 2m) \times \cdots \times i. /// $$ /// If $n$ is divisible by $m$, then $i$ is $m$; otherwise, $i$ is the remainder when /// $n$ is divided by $m$. /// /// $n!^{(m)} = O(\sqrt{n}(n/e)^{n/m})$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if the output is too large to be represented. /// /// # Examples /// See [here](super::factorial#multifactorial). #[inline] fn multifactorial(n: u64, m: u64) -> $t { $t::checked_multifactorial(n, m).unwrap() } } impl CheckedMultifactorial for $t { /// Computes a multifactorial of a number. /// /// If the input is too large, the function returns `None`. /// /// $$ /// f(n, m) = \\begin{cases} /// \operatorname{Some}(n!^{(m)}) & \text{if} \\quad n!^{(m)} < 2^W, \\\\ /// \operatorname{None} & \text{if} \\quad n!^{(m)} \geq 2^W, /// \\end{cases} /// $$ /// where $W$ is `Self::WIDTH`. /// /// $n!^{(m)} = O(\sqrt{n}(n/e)^{n/m})$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::factorial#checked_multifactorial). #[inline] fn checked_multifactorial(n: u64, m: u64) -> Option<$t> { assert_ne!(m, 0); if m == 1 { $t::checked_factorial(n) } else if m == 2 { $t::checked_double_factorial(n) } else { checked_multifactorial_naive(n, m) } } } impl Subfactorial for $t { /// Computes the subfactorial of a number. /// /// The subfactorial of $n$ counts the number of derangements of a set of size $n$; a /// derangement is a permutation with no fixed points. /// /// If the input is too large, the function panics. For a function that returns `None` /// instead, try [`checked_subfactorial`](CheckedSubfactorial::checked_subfactorial). /// /// $$ /// f(n) = \\ !n = \lfloor n!/e \rfloor. /// $$ /// /// $!n = O(n!) = O(\sqrt{n}(n/e)^n)$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if the output is too large to be represented. /// /// # Examples /// See [here](super::factorial#subfactorial). #[inline] fn subfactorial(n: u64) -> $t { $t::checked_subfactorial(n).unwrap() } } }; } apply_to_unsigneds!(impl_factorials_b); malachite-base-0.4.16/src/num/arithmetic/floor.rs000064400000000000000000000025361046102023000177670ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{Floor, FloorAssign}; macro_rules! impl_floor { ($f:ident) => { impl Floor for $f { type Output = $f; /// This is a wrapper over the `floor` functions in [`libm`]. #[inline] fn floor(self) -> $f { libm::Libm::<$f>::floor(self) } } impl FloorAssign for $f { /// Replaces a number with its floor. /// /// A number's floor is the largest integer less than or equal to the number. /// /// $x \gets \lfloor x \rfloor$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::floor#floor_assign). #[inline] fn floor_assign(&mut self) { *self = self.floor(); } } }; } apply_to_primitive_floats!(impl_floor); malachite-base-0.4.16/src/num/arithmetic/gcd.rs000064400000000000000000000116461046102023000174050ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // Uses code adopted from the FLINT Library. // // Copyright © 2009, 2016 William Hart // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{Gcd, GcdAssign}; use crate::num::basic::unsigneds::PrimitiveUnsigned; use core::cmp::min; #[cfg(feature = "test_build")] pub fn gcd_euclidean(x: T, y: T) -> T { if y == T::ZERO { x } else { gcd_euclidean(y, x % y) } } #[cfg(feature = "test_build")] pub fn gcd_binary(x: T, y: T) -> T { if x == y { x } else if x == T::ZERO { y } else if y == T::ZERO { x } else if x.even() { if y.odd() { gcd_binary(x >> 1, y) } else { gcd_binary(x >> 1, y >> 1) << 1 } } else if y.even() { gcd_binary(x, y >> 1) } else if x > y { gcd_binary((x - y) >> 1, y) } else { gcd_binary((y - x) >> 1, x) } } pub_test! {gcd_fast_a(mut x: T, mut y: T) -> T { if x == T::ZERO { return y; } if y == T::ZERO { return x; } let x_zeros = x.trailing_zeros(); let y_zeros = y.trailing_zeros(); let f = min(x_zeros, y_zeros); x >>= x_zeros; y >>= y_zeros; while x != y { if x < y { y -= x; y >>= y.trailing_zeros(); } else { x -= y; x >>= x.trailing_zeros(); } } x << f }} #[cfg(feature = "test_build")] // This is a modified version of `n_xgcd` from `ulong_extras/xgcd.c`, FLINT 2.7.1. pub fn gcd_fast_b(mut x: T, y: T) -> T { let mut v; if x >= y { v = y; } else { v = x; x = y; } let mut d; // x and y both have their top bit set. if (x & v).get_highest_bit() { d = x - v; x = v; v = d; } // The second value has its second-highest set. while (v << 1u32).get_highest_bit() { d = x - v; x = v; if d < v { v = d; } else if d < (v << 1) { v = d - x; } else { v = d - (x << 1); } } while v != T::ZERO { // Overflow is not possible due to top 2 bits of v not being set. Avoid divisions when // quotient < 4. if x < (v << 2) { d = x - v; x = v; if d < v { v = d; } else if d < (v << 1) { v = d - x; } else { v = d - (x << 1); } } else { let rem = x % v; x = v; v = rem; } } x } macro_rules! impl_gcd { ($t:ident) => { impl Gcd<$t> for $t { type Output = $t; /// Computes the GCD (greatest common divisor) of two numbers. /// /// The GCD of 0 and $n$, for any $n$, is 0. In particular, $\gcd(0, 0) = 0$, which /// makes sense if we interpret "greatest" to mean "greatest by the divisibility order". /// /// $$ /// f(x, y) = \gcd(x, y). /// $$ /// /// # Worst-case complexity /// $T(n) = O(n^2)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is /// `max(self.significant_bits(), other.significant_bits())`. /// /// # Examples /// See [here](super::gcd#gcd). #[inline] fn gcd(self, other: $t) -> $t { gcd_fast_a(self, other) } } impl GcdAssign<$t> for $t { /// Replaces another with the GCD (greatest common divisor) of it and another number. /// /// The GCD of 0 and $n$, for any $n$, is 0. In particular, $\gcd(0, 0) = 0$, which /// makes sense if we interpret "greatest" to mean "greatest by the divisibility order". /// /// $$ /// x \gets \gcd(x, y). /// $$ /// /// # Worst-case complexity /// $T(n) = O(n^2)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is /// `max(self.significant_bits(), other.significant_bits())`. /// /// # Examples /// See [here](super::gcd#gcd_assign). #[inline] fn gcd_assign(&mut self, other: $t) { *self = gcd_fast_a(*self, other); } } }; } apply_to_unsigneds!(impl_gcd); malachite-base-0.4.16/src/num/arithmetic/is_power_of_2.rs000064400000000000000000000031531046102023000213760ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::IsPowerOf2; use crate::num::conversion::traits::IntegerMantissaAndExponent; macro_rules! impl_is_power_of_2_unsigned { ($t:ident) => { impl IsPowerOf2 for $t { /// This is a wrapper over the `is_power_of_two` functions in the standard library, for /// example [this one](u32::is_power_of_two). #[inline] fn is_power_of_2(&self) -> bool { $t::is_power_of_two(*self) } } }; } apply_to_unsigneds!(impl_is_power_of_2_unsigned); macro_rules! impl_is_power_of_2_primitive_float { ($t:ident) => { impl IsPowerOf2 for $t { /// Determines whether a number is an integer power of 2. /// /// $f(x) = (\exists n \in \Z : 2^n = x)$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::is_power_of_2#is_power_of_2). #[inline] fn is_power_of_2(&self) -> bool { self.is_finite() && *self > 0.0 && self.integer_mantissa() == 1 } } }; } apply_to_primitive_floats!(impl_is_power_of_2_primitive_float); malachite-base-0.4.16/src/num/arithmetic/kronecker_symbol.rs000064400000000000000000000367261046102023000222260ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // Uses code adopted from the GNU MP Library. // // Copyright © 1996, 1998, 2000-2004, 2008, 2010 Free Software Foundation, Inc. // // Uses code adopted from the FLINT Library. // // Copyright © 2008 Peter Shrimpton // // Copyright © 2009 William Hart // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::fail_on_untested_path; use crate::num::arithmetic::traits::{ JacobiSymbol, KroneckerSymbol, LegendreSymbol, ModPowerOf2, NegAssign, Parity, UnsignedAbs, }; use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::SplitInHalf; use crate::num::logic::traits::NotAssign; use core::mem::swap; pub_test! {jacobi_symbol_unsigned_simple(mut a: T, mut n: T) -> i8 { assert_ne!(n, T::ZERO); assert!(n.odd()); a %= n; let mut t = 1i8; while a != T::ZERO { while a.even() { a >>= 1; let r: u8 = n.mod_power_of_2(3).wrapping_into(); if r == 3 || r == 5 { t.neg_assign(); } } swap(&mut a, &mut n); if (a & n).get_bit(1) { t.neg_assign(); } a %= n; } if n == T::ONE { t } else { 0 } }} // Computes (a / b) where b is odd, and a and b are otherwise arbitrary two-limb numbers. // // This is equivalent to `mpn_jacobi_2` from `mpn/jacobi_2.c`, GMP 6.2.1, where `JACOBI_2_METHOD == // 2` and `bit` is 0. pub_test! {jacobi_symbol_unsigned_double_fast_2( mut x_1: T, mut x_0: T, mut y_1: T, mut y_0: T, ) -> i8 { assert!(y_0.odd()); if y_1 == T::ZERO && y_0 == T::ONE { // (x|1) = 1 return 1; } let mut bit = false; if x_0 == T::ZERO { if x_1 == T::ZERO { // (0|y) = 0, y > 1 return 0; } let c = x_1.trailing_zeros(); if c.odd() && (y_0 ^ (y_0 >> 1)).get_bit(1) { bit.not_assign(); } x_0 = y_0; y_0 = x_1 >> c; if y_0 == T::ONE { // (1|y) = 1 return if bit { -1 } else { 1 }; } x_1 = y_1; if (x_0 & y_0).get_bit(1) { bit.not_assign(); } } else { if x_0.even() { let c = x_0.trailing_zeros(); x_0 = (x_1 << (T::WIDTH - c)) | (x_0 >> c); x_1 >>= c; if c.odd() && (y_0 ^ (y_0 >> 1)).get_bit(1) { bit.not_assign(); } } let mut skip_loop = false; if x_1 == T::ZERO { if y_1 == T::ZERO { assert!(y_0.odd()); assert!(y_0 > T::ONE); let j = x_0.jacobi_symbol(y_0); return if bit { -j } else { j }; } if (x_0 & y_0).get_bit(1) { bit.not_assign(); } swap(&mut x_0, &mut y_0); x_1 = y_1; skip_loop = true; } if !skip_loop { 'outer: while y_1 != T::ZERO { // Compute (x|y) while x_1 > y_1 { (x_1, x_0) = T::xx_sub_yy_to_zz(x_1, x_0, y_1, y_0); if x_0 == T::ZERO { let c = x_1.trailing_zeros(); if c.odd() && (y_0 ^ (y_0 >> 1)).get_bit(1) { bit.not_assign(); } x_0 = y_0; y_0 = x_1 >> c; x_1 = y_1; if (x_0 & y_0).get_bit(1) { bit.not_assign(); } break 'outer; } let c = x_0.trailing_zeros(); if c.odd() && (y_0 ^ (y_0 >> 1)).get_bit(1) { bit.not_assign(); } x_0 = (x_1 << (T::WIDTH - c)) | (x_0 >> c); x_1 >>= c; } if x_1 != y_1 { if x_1 == T::ZERO { if (x_0 & y_0).get_bit(1) { bit.not_assign(); } swap(&mut x_0, &mut y_0); x_1 = y_1; break; } if (x_0 & y_0).get_bit(1) { bit.not_assign(); } // Compute (y|x) while y_1 > x_1 { (y_1, y_0) = T::xx_sub_yy_to_zz(y_1, y_0, x_1, x_0); if y_0 == T::ZERO { let c = y_1.trailing_zeros(); if c.odd() & (x_0 ^ (x_0 >> 1)).get_bit(1) { bit.not_assign(); } y_0 = y_1 >> c; if (x_0 & y_0).get_bit(1) { bit.not_assign(); } break 'outer; } let c = y_0.trailing_zeros(); if c.odd() & (x_0 ^ (x_0 >> 1)).get_bit(1) { bit.not_assign(); } y_0 = (y_1 << (T::WIDTH - c)) | (y_0 >> c); y_1 >>= c; } if (x_0 & y_0).get_bit(1) { bit.not_assign(); } } // Compute (x|y) if x_1 == y_1 { if x_0 < y_0 { swap(&mut x_0, &mut y_0); if (x_0 & y_0).get_bit(1) { bit.not_assign(); } } x_0 -= y_0; if x_0 == T::ZERO { return 0; } let c = x_0.trailing_zeros(); if c.odd() & (y_0 ^ (y_0 >> 1)).get_bit(1) { bit.not_assign(); } x_0 >>= c; if x_0 == T::ONE { return if bit { -1 } else { 1 }; } swap(&mut x_0, &mut y_0); if (x_0 & y_0).get_bit(1) { bit.not_assign(); } break; } } } } // Compute (x|y), with y a single limb. assert!(y_0.odd()); if y_0 == T::ONE { // (x|1) = 1 return if bit { -1 } else { 1 }; } while x_1 != T::ZERO { x_1 -= if x_0 < y_0 { T::ONE } else { T::ZERO }; x_0.wrapping_sub_assign(y_0); if x_0 == T::ZERO { if x_1 == T::ZERO { fail_on_untested_path( "jacobi_symbol_unsigned_double_fast_2, x_1 == T::ZERO fourth time", ); return 0; } let c = x_1.trailing_zeros(); if c.odd() && (y_0 ^ (y_0 >> 1)).get_bit(1) { bit.not_assign(); } x_0 = x_1 >> c; break; } let c = x_0.trailing_zeros(); x_0 = (x_1 << (T::WIDTH - c)) | (x_0 >> c); x_1 >>= c; if c.odd() && (y_0 ^ (y_0 >> 1)).get_bit(1) { bit.not_assign(); } } assert!(y_0.odd()); assert!(y_0 > T::ONE); let j = x_0.jacobi_symbol(y_0); if bit { -j } else { j } }} fn jacobi_symbol_signed< U: PrimitiveUnsigned, S: ModPowerOf2 + PrimitiveSigned + UnsignedAbs, >( a: S, n: S, ) -> i8 { assert!(n > S::ZERO); assert!(n.odd()); let s = a.unsigned_abs().jacobi_symbol(n.unsigned_abs()); if a < S::ZERO && n.get_bit(1) { -s } else { s } } fn kronecker_symbol_unsigned(a: T, b: T) -> i8 { if b == T::ZERO { i8::from(a == T::ONE) } else if a.even() && b.even() { 0 } else { let b_twos = b.trailing_zeros(); let mut s = a.jacobi_symbol(b >> b_twos); if b_twos.odd() { let m: u32 = a.mod_power_of_2(3).wrapping_into(); if m == 3 || m == 5 { s.neg_assign(); } } s } } fn kronecker_symbol_signed + PrimitiveSigned>( a: S, b: S, ) -> i8 { if b == S::ZERO { i8::from(a == S::ONE || a == S::NEGATIVE_ONE) } else if a.even() && b.even() { 0 } else { let b_twos = b.trailing_zeros(); let mut s = a.jacobi_symbol((b >> b_twos).abs()); if a < S::ZERO && b < S::ZERO { s.neg_assign(); } if b_twos.odd() { let m: u32 = a.mod_power_of_2(3).wrapping_into(); if m == 3 || m == 5 { s.neg_assign(); } } s } } macro_rules! impl_symbols { ($u:ident, $s:ident) => { impl LegendreSymbol<$u> for $u { /// Computes the Legendre symbol of two numbers. /// /// This implementation is identical to that of [`JacobiSymbol`], since there is no /// computational benefit to requiring that the denominator be prime. /// /// $$ /// f(x, y) = \left ( \frac{x}{y} \right ). /// $$ /// /// # Worst-case complexity /// $T(n) = O(n^2)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is /// `max(self.significant_bits(), other.significant_bits())`. /// /// # Panics /// Panics if `n` is even. /// /// # Examples /// See [here](super::kronecker_symbol#legendre_symbol). #[inline] fn legendre_symbol(self, n: $u) -> i8 { self.jacobi_symbol(n) } } impl LegendreSymbol<$s> for $s { /// Computes the Legendre symbol of two numbers. /// /// This implementation is identical to that of [`JacobiSymbol`], since there is no /// computational benefit to requiring that the denominator be prime. /// /// $$ /// f(x, y) = \left ( \frac{x}{y} \right ). /// $$ /// /// # Worst-case complexity /// $T(n) = O(n^2)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is /// `max(self.significant_bits(), other.significant_bits())`. /// /// # Panics /// Panics if `n` is even or negative. /// /// # Examples /// See [here](super::kronecker_symbol#legendre_symbol). #[inline] fn legendre_symbol(self, n: $s) -> i8 { self.jacobi_symbol(n) } } impl JacobiSymbol<$s> for $s { /// Computes the Jacobi symbol of two numbers. /// /// $$ /// f(x, y) = \left ( \frac{x}{y} \right ). /// $$ /// /// # Worst-case complexity /// $T(n) = O(n^2)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is /// `max(self.significant_bits(), other.significant_bits())`. /// /// # Panics /// Panics if `n` is even. /// /// # Examples /// See [here](super::kronecker_symbol#jacobi_symbol). #[inline] fn jacobi_symbol(self, n: $s) -> i8 { jacobi_symbol_signed::<$u, $s>(self, n) } } impl KroneckerSymbol<$u> for $u { /// Computes the Kronecker symbol of two numbers. /// /// $$ /// f(x, y) = \left ( \frac{x}{y} \right ). /// $$ /// /// # Worst-case complexity /// $T(n) = O(n^2)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is /// `max(self.significant_bits(), other.significant_bits())`. /// /// # Examples /// See [here](super::kronecker_symbol#kronecker_symbol). #[inline] fn kronecker_symbol(self, n: $u) -> i8 { kronecker_symbol_unsigned(self, n) } } impl KroneckerSymbol<$s> for $s { /// Computes the Kronecker symbol of two numbers. /// /// $$ /// f(x, y) = \left ( \frac{x}{y} \right ). /// $$ /// /// # Worst-case complexity /// $T(n) = O(n^2)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is /// `max(self.significant_bits(), other.significant_bits())`. /// /// # Examples /// See [here](super::kronecker_symbol#kronecker_symbol). #[inline] fn kronecker_symbol(self, n: $s) -> i8 { kronecker_symbol_signed::<$u, $s>(self, n) } } }; } apply_to_unsigned_signed_pairs!(impl_symbols); macro_rules! impl_jacobi_symbol_unsigned { ($u:ident) => { /// Computes the Jacobi symbol of two numbers. /// /// $$ /// f(x, y) = \left ( \frac{x}{y} \right ). /// $$ /// /// # Worst-case complexity /// $T(n) = O(n^2)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(), /// other.significant_bits())`. /// /// # Panics /// Panics if `n` is even or negative. /// /// # Examples /// See [here](super::kronecker_symbol#jacobi_symbol). impl JacobiSymbol<$u> for $u { #[inline] fn jacobi_symbol(self, n: $u) -> i8 { jacobi_symbol_unsigned_simple(self, n) } } }; } impl_jacobi_symbol_unsigned!(u8); impl_jacobi_symbol_unsigned!(u16); impl_jacobi_symbol_unsigned!(u32); impl_jacobi_symbol_unsigned!(u64); impl_jacobi_symbol_unsigned!(usize); impl JacobiSymbol for u128 { /// Computes the Jacobi symbol of two `u128`s. /// /// $$ /// f(x, y) = \left ( \frac{x}{y} \right ). /// $$ /// /// # Worst-case complexity /// $T(n) = O(n^2)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(), /// other.significant_bits())`. /// /// # Examples /// See [here](super::kronecker_symbol#jacobi_symbol). #[inline] fn jacobi_symbol(self, n: u128) -> i8 { let (x_1, x_0) = self.split_in_half(); let (y_1, y_0) = n.split_in_half(); jacobi_symbol_unsigned_double_fast_2(x_1, x_0, y_1, y_0) } } malachite-base-0.4.16/src/num/arithmetic/lcm.rs000064400000000000000000000072471046102023000174250ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{CheckedLcm, Lcm, LcmAssign}; use crate::num::basic::unsigneds::PrimitiveUnsigned; #[inline] fn lcm(x: T, y: T) -> T { checked_lcm(x, y).unwrap() } fn checked_lcm(x: T, y: T) -> Option { if x == T::ZERO && y == T::ZERO { Some(T::ZERO) } else { (x / x.gcd(y)).checked_mul(y) } } macro_rules! impl_lcm { ($t:ident) => { impl Lcm<$t> for $t { type Output = $t; /// Computes the LCM (least common multiple) of two numbers. /// /// $$ /// f(x, y) = \operatorname{lcm}(x, y). /// $$ /// /// # Worst-case complexity /// $T(n) = O(n^2)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is /// `max(self.significant_bits(), other.significant_bits())`. /// /// # Panics /// Panics if the result is too large to be represented. /// /// # Examples /// See [here](super::lcm#lcm). #[inline] fn lcm(self, other: $t) -> $t { lcm(self, other) } } impl LcmAssign<$t> for $t { /// Replaces a number with the LCM (least common multiple) of it and another number. /// /// $$ /// x \gets \operatorname{lcm}(x, y). /// $$ /// /// # Worst-case complexity /// $T(n) = O(n^2)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is /// `max(self.significant_bits(), other.significant_bits())`. /// /// # Panics /// Panics if the result is too large to be represented. /// /// # Examples /// See [here](super::lcm#lcm_assign). #[inline] fn lcm_assign(&mut self, other: $t) { *self = lcm(*self, other); } } impl CheckedLcm<$t> for $t { type Output = $t; /// Computes the LCM (least common multiple) of two numbers, returning `None` if the /// result is too large to represent. /// /// $$ /// f(x, y) = \\begin{cases} /// \operatorname{Some}(\operatorname{lcm}(x, y)) & /// \text{if} \\quad \operatorname{lcm}(x, y) < 2^W, \\\\ /// \operatorname{None} & \text{if} \\quad \operatorname{lcm}(x, y) \geq 2^W, /// \\end{cases} /// $$ /// where $W$ is `Self::WIDTH`. /// /// # Worst-case complexity /// $T(n) = O(n^2)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is /// `max(self.significant_bits(), other.significant_bits())`. /// /// # Examples /// See [here](super::lcm#checked_lcm). #[inline] fn checked_lcm(self, other: $t) -> Option<$t> { checked_lcm(self, other) } } }; } apply_to_unsigneds!(impl_lcm); malachite-base-0.4.16/src/num/arithmetic/log_base.rs000064400000000000000000000125141046102023000204160ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{CeilingLogBase, CheckedLogBase, FloorLogBase}; use crate::num::basic::unsigneds::PrimitiveUnsigned; fn floor_log_base_naive(x: T, base: T) -> u64 { assert_ne!(x, T::ZERO); assert!(base > T::ONE); let mut result = 0; let mut p = T::ONE; // loop always executes at least once while p <= x { result += 1; if let Some(next_p) = p.checked_mul(base) { p = next_p; } else { break; } } result - 1 } pub_test! {ceiling_log_base_naive(x: T, base: T) -> u64 { assert_ne!(x, T::ZERO); assert!(base > T::ONE); let mut result = 0; let mut p = T::ONE; while p < x { result += 1; if let Some(next_p) = p.checked_mul(base) { p = next_p; } else { break; } } result }} pub_test! {checked_log_base_naive(x: T, base: T) -> Option { assert_ne!(x, T::ZERO); assert!(base > T::ONE); let mut result = 0; let mut p = T::ONE; while p < x { result += 1; if let Some(next_p) = p.checked_mul(base) { p = next_p; } else { return None; } } if p == x { Some(result) } else { None } }} fn floor_log_base(x: T, base: T) -> u64 { if let Some(log_base) = base.checked_log_base_2() { x.floor_log_base_power_of_2(log_base) } else { floor_log_base_naive(x, base) } } fn ceiling_log_base(x: T, base: T) -> u64 { if let Some(log_base) = base.checked_log_base_2() { x.ceiling_log_base_power_of_2(log_base) } else { ceiling_log_base_naive(x, base) } } fn checked_log_base(x: T, base: T) -> Option { if let Some(log_base) = base.checked_log_base_2() { x.checked_log_base_power_of_2(log_base) } else { checked_log_base_naive(x, base) } } macro_rules! impl_log_base_unsigned { ($t:ident) => { impl FloorLogBase for $t { type Output = u64; /// Returns the floor of the base-$b$ logarithm of a positive integer. /// /// $f(x, b) = \lfloor\log_b x\rfloor$. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits() / /// base.significant_bits()`. /// /// # Panics /// Panics if `self` is 0 or `base` is less than 2. /// /// # Examples /// See [here](super::log_base#floor_log_base). #[inline] fn floor_log_base(self, base: $t) -> u64 { // TODO use ilog once stabilized floor_log_base(self, base) } } impl CeilingLogBase for $t { type Output = u64; /// Returns the ceiling of the base-$b$ logarithm of a positive integer. /// /// $f(x, b) = \lceil\log_b x\rceil$. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits() / /// base.significant_bits()`. /// /// # Panics /// Panics if `self` is 0 or `base` is less than 2. /// /// # Examples /// See [here](super::log_base#ceiling_log_base). #[inline] fn ceiling_log_base(self, base: $t) -> u64 { ceiling_log_base(self, base) } } impl CheckedLogBase for $t { type Output = u64; /// Returns the base-$b$ logarithm of a positive integer. If the integer is not a power /// of $b$, `None` is returned. /// /// $$ /// f(x, b) = \\begin{cases} /// \operatorname{Some}(\log_b x) & \text{if} \\quad \log_b x \in \Z, \\\\ /// \operatorname{None} & \textrm{otherwise}. /// \\end{cases} /// $$ /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits() / /// base.significant_bits()`. /// /// # Panics /// Panics if `self` is 0 or `base` is less than 2. /// /// # Examples /// See [here](super::log_base#checked_log_base). #[inline] fn checked_log_base(self, base: $t) -> Option { checked_log_base(self, base) } } }; } apply_to_unsigneds!(impl_log_base_unsigned); malachite-base-0.4.16/src/num/arithmetic/log_base_2.rs000064400000000000000000000151411046102023000206360ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{CeilingLogBase2, CheckedLogBase2, FloorLogBase2}; use crate::num::basic::integers::PrimitiveInt; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::SciMantissaAndExponent; use crate::num::logic::traits::{LeadingZeros, TrailingZeros}; fn floor_log_base_2(x: T) -> u64 { assert!(x != T::ZERO, "Cannot take the base-2 logarithm of 0."); x.significant_bits() - 1 } fn ceiling_log_base_2(x: T) -> u64 { let floor_log_base_2 = x.floor_log_base_2(); if x.is_power_of_2() { floor_log_base_2 } else { floor_log_base_2 + 1 } } fn checked_log_base_2(x: T) -> Option { assert!(x != T::ZERO, "Cannot take the base-2 logarithm of 0."); let leading_zeros = LeadingZeros::leading_zeros(x); let trailing_zeros = TrailingZeros::trailing_zeros(x); if leading_zeros + trailing_zeros == T::WIDTH - 1 { Some(trailing_zeros) } else { None } } macro_rules! impl_log_base_2_unsigned { ($t:ident) => { impl FloorLogBase2 for $t { type Output = u64; /// Returns the floor of the base-2 logarithm of a positive integer. /// /// $f(x) = \lfloor\log_2 x\rfloor$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` is 0. /// /// # Examples /// See [here](super::log_base_2#floor_log_base_2). #[inline] fn floor_log_base_2(self) -> u64 { // TODO use ilog2 once stabilized floor_log_base_2(self) } } impl CeilingLogBase2 for $t { type Output = u64; /// Returns the ceiling of the base-2 logarithm of a positive integer. /// /// $f(x) = \lceil\log_2 x\rceil$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` is 0. /// /// # Examples /// See [here](super::log_base_2#ceiling_log_base_2). #[inline] fn ceiling_log_base_2(self) -> u64 { ceiling_log_base_2(self) } } impl CheckedLogBase2 for $t { type Output = u64; /// Returns the base-2 logarithm of a positive integer. If the integer is not a power of /// 2, `None` is returned. /// /// $$ /// f(x) = \\begin{cases} /// \operatorname{Some}(\log_2 x) & \text{if} \\quad \log_2 x \in \Z, \\\\ /// \operatorname{None} & \textrm{otherwise}. /// \\end{cases} /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` is 0. /// /// # Examples /// See [here](super::log_base_2#checked_log_base_2). #[inline] fn checked_log_base_2(self) -> Option { checked_log_base_2(self) } } }; } apply_to_unsigneds!(impl_log_base_2_unsigned); macro_rules! impl_log_base_2_primitive_float { ($t:ident) => { impl FloorLogBase2 for $t { type Output = i64; /// Returns the floor of the base-2 logarithm of a positive float. /// /// $f(x) = \lfloor\log_2 x\rfloor$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` is infinite, `NaN`, or less than or equal to zero. /// /// # Examples /// See [here](super::log_base_2#floor_log_base_2). #[inline] fn floor_log_base_2(self) -> i64 { assert!(self > 0.0); self.sci_exponent() } } impl CeilingLogBase2 for $t { type Output = i64; /// Returns the ceiling of the base-2 logarithm of a positive float. /// /// $f(x) = \lceil\log_2 x\rceil$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` is infinite, `NaN`, or less than or equal to zero. /// /// # Examples /// See [here](super::log_base_2#ceiling_log_base_2). #[inline] fn ceiling_log_base_2(self) -> i64 { assert!(self > 0.0); let (mantissa, exponent) = self.sci_mantissa_and_exponent(); if mantissa == 1.0 { exponent } else { exponent + 1 } } } impl CheckedLogBase2 for $t { type Output = i64; /// Returns the base-2 logarithm of a positive float If the float is not a power of 2, /// `None` is returned. /// /// $$ /// f(x) = \\begin{cases} /// \operatorname{Some}(\log_2 x) & \text{if} \\quad \log_2 x \in \Z, \\\\ /// \operatorname{None} & \textrm{otherwise}. /// \\end{cases} /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` is infinite, `NaN`, or less than or equal to zero. /// /// # Examples /// See [here](super::log_base_2#checked_log_base_2). #[inline] fn checked_log_base_2(self) -> Option { assert!(self > 0.0); let (mantissa, exponent) = self.sci_mantissa_and_exponent(); if mantissa == 1.0 { Some(exponent) } else { None } } } }; } apply_to_primitive_floats!(impl_log_base_2_primitive_float); malachite-base-0.4.16/src/num/arithmetic/log_base_power_of_2.rs000064400000000000000000000200361046102023000225350ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{ CeilingLogBasePowerOf2, CheckedLogBasePowerOf2, DivMod, DivRound, FloorLogBasePowerOf2, }; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::{ExactFrom, SciMantissaAndExponent}; use crate::rounding_modes::RoundingMode::*; #[cfg(feature = "test_build")] pub fn ceiling_log_base_power_of_2_naive(x: T, pow: u64) -> u64 { assert_ne!(x, T::ZERO); assert_ne!(pow, 0); if pow >= T::WIDTH { return u64::from(x != T::ONE); } let mut result = 0; let mut p = T::ONE; while p < x { let highest_possible = p.leading_zeros() < pow; result += 1; if highest_possible { break; } p <<= pow; } result } fn floor_log_base_power_of_2(x: T, pow: u64) -> u64 { assert!(x != T::ZERO, "Cannot take the base-2 logarithm of 0."); assert_ne!(pow, 0); (x.significant_bits() - 1) / pow } fn ceiling_log_base_power_of_2(x: T, pow: u64) -> u64 { assert!(x != T::ZERO, "Cannot take the base-2 logarithm of 0."); assert_ne!(pow, 0); let (floor_log, rem) = (x.significant_bits() - 1).div_mod(pow); if rem == 0 && T::is_power_of_2(&x) { floor_log } else { floor_log + 1 } } fn checked_log_base_power_of_2(x: T, pow: u64) -> Option { assert!(x != T::ZERO, "Cannot take the base-2 logarithm of 0."); assert_ne!(pow, 0); let (floor_log, rem) = (x.significant_bits() - 1).div_mod(pow); if rem == 0 && T::is_power_of_2(&x) { Some(floor_log) } else { None } } macro_rules! impl_log_base_power_of_2_unsigned { ($t:ident) => { impl FloorLogBasePowerOf2 for $t { type Output = u64; /// Returns the floor of the base-$2^k$ logarithm of a positive integer. /// /// $f(x, k) = \lfloor\log_{2^k} x\rfloor$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` is infinite, `NaN`, or less than or equal to zero, or if `pow` is /// zero. /// /// # Examples /// See [here](super::log_base_power_of_2#floor_log_base_power_of_2). #[inline] fn floor_log_base_power_of_2(self, pow: u64) -> u64 { floor_log_base_power_of_2(self, pow) } } impl CeilingLogBasePowerOf2 for $t { type Output = u64; /// Returns the ceiling of the base-$2^k$ logarithm of a positive integer. /// /// $f(x, k) = \lceil\log_{2^k} x\rceil$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` is infinite, `NaN`, or less than or equal to zero, or if `pow` is /// zero. /// /// # Examples /// See [here](super::log_base_power_of_2#ceiling_log_base_power_of_2). #[inline] fn ceiling_log_base_power_of_2(self, pow: u64) -> u64 { ceiling_log_base_power_of_2(self, pow) } } impl CheckedLogBasePowerOf2 for $t { type Output = u64; /// Returns the base-$2^k$ logarithm of a positive integer. If the integer is not a /// power of $2^k$, `None` is returned. /// /// $$ /// f(x, k) = \\begin{cases} /// \operatorname{Some}(\log_{2^k} x) & \text{if} \\quad \log_{2^k} x \in \Z, \\\\ /// \operatorname{None} & \textrm{otherwise}. /// \\end{cases} /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` is infinite, `NaN`, or less than or equal to zero, or if `pow` is /// zero. /// /// # Examples /// See [here](super::log_base_power_of_2#ceiling_log_base_power_of_2). #[inline] fn checked_log_base_power_of_2(self, pow: u64) -> Option { checked_log_base_power_of_2(self, pow) } } }; } apply_to_unsigneds!(impl_log_base_power_of_2_unsigned); macro_rules! impl_log_base_power_of_2_primitive_float { ($t:ident) => { impl FloorLogBasePowerOf2 for $t { type Output = i64; /// Returns the floor of the base-$2^k$ logarithm of a positive float. /// /// $f(x, k) = \lfloor\log_{2^k} x\rfloor$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` or `pow` are 0. /// /// # Examples /// See [here](super::log_base_power_of_2#floor_log_base_power_of_2). #[inline] fn floor_log_base_power_of_2(self, pow: u64) -> i64 { assert!(self > 0.0); self.sci_exponent().div_round(i64::exact_from(pow), Floor).0 } } impl CeilingLogBasePowerOf2 for $t { type Output = i64; /// Returns the ceiling of the base-$2^k$ logarithm of a positive float. /// /// $f(x, k) = \lceil\log_{2^k} x\rceil$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` or `pow` are 0. /// /// # Examples /// See [here](super::log_base_power_of_2#ceiling_log_base_power_of_2). #[inline] fn ceiling_log_base_power_of_2(self, pow: u64) -> i64 { assert!(self > 0.0); let (mantissa, exponent) = self.sci_mantissa_and_exponent(); let exact = mantissa == 1.0; let (q, r) = exponent.div_mod(i64::exact_from(pow)); if exact && r == 0 { q } else { q + 1 } } } impl CheckedLogBasePowerOf2 for $t { type Output = i64; /// Returns the base-$2^k$ logarithm of a positive float. If the float is not a power of /// $2^k$, `None` is returned. /// /// $$ /// f(x, k) = \\begin{cases} /// \operatorname{Some}(\log_{2^k} x) & \text{if} \\quad \log_{2^k} x \in \Z, \\\\ /// \operatorname{None} & \textrm{otherwise}. /// \\end{cases} /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` or `pow` are 0. /// /// # Examples /// See [here](super::log_base_power_of_2#checked_log_base_power_of_2). #[inline] fn checked_log_base_power_of_2(self, pow: u64) -> Option { assert!(self > 0.0); let (mantissa, exponent) = self.sci_mantissa_and_exponent(); if mantissa != 1.0 { return None; } let (q, r) = exponent.div_mod(i64::exact_from(pow)); if r == 0 { Some(q) } else { None } } } }; } apply_to_primitive_floats!(impl_log_base_power_of_2_primitive_float); malachite-base-0.4.16/src/num/arithmetic/mod.rs000064400000000000000000003601601046102023000174250ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . /// [`Abs`](traits::Abs), [`AbsAssign`](traits::AbsAssign), and /// [`UnsignedAbs`](traits::UnsignedAbs), traits for getting the absolute value of a number. /// /// # abs_assign /// ``` /// use malachite_base::num::arithmetic::traits::AbsAssign; /// use malachite_base::num::basic::traits::NegativeInfinity; /// use malachite_base::num::float::NiceFloat; /// /// let mut x = 0i8; /// x.abs_assign(); /// assert_eq!(x, 0i8); /// /// let mut x = 100i64; /// x.abs_assign(); /// assert_eq!(x, 100i64); /// /// let mut x = -100i64; /// x.abs_assign(); /// assert_eq!(x, 100i64); /// /// let mut x = -0.0; /// x.abs_assign(); /// assert_eq!(NiceFloat(x), NiceFloat(0.0)); /// /// let mut x = f64::NEGATIVE_INFINITY; /// x.abs_assign(); /// assert_eq!(NiceFloat(x), NiceFloat(f64::INFINITY)); /// /// let mut x = 100.0; /// x.abs_assign(); /// assert_eq!(NiceFloat(x), NiceFloat(100.0)); /// /// let mut x = -100.0; /// x.abs_assign(); /// assert_eq!(NiceFloat(x), NiceFloat(100.0)); /// ``` pub mod abs; /// [`AbsDiff`](traits::AbsDiff) and [`AbsDiffAssign`](traits::AbsDiffAssign), traits for getting /// the absolute value of the difference between two numbers. /// /// # abs_diff /// ``` /// assert_eq!(10u8.abs_diff(20u8), 10u8); /// assert_eq!(10i8.abs_diff(-10i8), 20u8); /// ``` /// /// # abs_diff_assign /// ``` /// use malachite_base::num::arithmetic::traits::AbsDiffAssign; /// /// let mut x = 10u8; /// x.abs_diff_assign(20u8); /// assert_eq!(x, 10); /// ``` pub mod abs_diff; /// [`AddMul`](traits::AddMul) and [`AddMulAssign`](traits::AddMulAssign), traits for adding a /// number and the product of two other numbers. /// /// # add_mul /// ``` /// use malachite_base::num::arithmetic::traits::AddMul; /// /// assert_eq!(2u8.add_mul(3, 7), 23); /// assert_eq!(127i8.add_mul(-2, 100), -73); /// assert_eq!(1.0f32.add_mul(2.0, 3.0), 7.0); /// ``` /// /// # add_mul_assign /// ``` /// use malachite_base::num::arithmetic::traits::AddMulAssign; /// /// let mut x = 2u8; /// x.add_mul_assign(3, 7); /// assert_eq!(x, 23); /// /// let mut x = 127i8; /// x.add_mul_assign(-2, 100); /// assert_eq!(x, -73); /// /// let mut x = 1.0f32; /// x.add_mul_assign(2.0, 3.0); /// assert_eq!(x, 7.0); /// ``` pub mod add_mul; /// [`ArithmeticCheckedShl`](traits::ArithmeticCheckedShl), a trait for left-shifting a number and /// checking whether the result is representable. /// /// # arithmetic_checked_shl /// ``` /// use malachite_base::num::arithmetic::traits::ArithmeticCheckedShl; /// /// assert_eq!(3u8.arithmetic_checked_shl(6), Some(192u8)); /// assert_eq!(3u8.arithmetic_checked_shl(7), None); /// assert_eq!(3u8.arithmetic_checked_shl(100), None); /// assert_eq!(0u8.arithmetic_checked_shl(100), Some(0u8)); /// /// assert_eq!(3u8.arithmetic_checked_shl(6), Some(192u8)); /// assert_eq!(3u8.arithmetic_checked_shl(7), None); /// assert_eq!(3u8.arithmetic_checked_shl(100), None); /// assert_eq!(0u8.arithmetic_checked_shl(100), Some(0u8)); /// assert_eq!(100u8.arithmetic_checked_shl(-3), Some(12u8)); /// assert_eq!(100u8.arithmetic_checked_shl(-100), Some(0u8)); /// /// assert_eq!(3i8.arithmetic_checked_shl(5), Some(96i8)); /// assert_eq!(3i8.arithmetic_checked_shl(6), None); /// assert_eq!((-3i8).arithmetic_checked_shl(5), Some(-96i8)); /// assert_eq!((-3i8).arithmetic_checked_shl(6), None); /// assert_eq!(3i8.arithmetic_checked_shl(100), None); /// assert_eq!((-3i8).arithmetic_checked_shl(100), None); /// assert_eq!(0i8.arithmetic_checked_shl(100), Some(0i8)); /// /// assert_eq!(3i8.arithmetic_checked_shl(5), Some(96i8)); /// assert_eq!(3i8.arithmetic_checked_shl(6), None); /// assert_eq!((-3i8).arithmetic_checked_shl(5), Some(-96i8)); /// assert_eq!((-3i8).arithmetic_checked_shl(6), None); /// assert_eq!(3i8.arithmetic_checked_shl(100), None); /// assert_eq!((-3i8).arithmetic_checked_shl(100), None); /// assert_eq!(0i8.arithmetic_checked_shl(100), Some(0i8)); /// assert_eq!(100i8.arithmetic_checked_shl(-3), Some(12i8)); /// assert_eq!((-100i8).arithmetic_checked_shl(-3), Some(-13i8)); /// assert_eq!(100i8.arithmetic_checked_shl(-100), Some(0i8)); /// assert_eq!((-100i8).arithmetic_checked_shl(-100), Some(-1i8)); /// ``` pub mod arithmetic_checked_shl; /// [`ArithmeticCheckedShr`](traits::ArithmeticCheckedShr), a trait for right-shifting a number and /// checking whether the result is representable. /// /// # arithmetic_checked_shr /// ``` /// use malachite_base::num::arithmetic::traits::ArithmeticCheckedShr; /// /// assert_eq!(100u8.arithmetic_checked_shr(3), Some(12u8)); /// assert_eq!(100u8.arithmetic_checked_shr(100), Some(0u8)); /// assert_eq!(3u8.arithmetic_checked_shr(-6), Some(192u8)); /// assert_eq!(3u8.arithmetic_checked_shr(-7), None); /// assert_eq!(3u8.arithmetic_checked_shr(-100), None); /// assert_eq!(0u8.arithmetic_checked_shr(-100), Some(0u8)); /// /// assert_eq!(100i8.arithmetic_checked_shr(3), Some(12i8)); /// assert_eq!((-100i8).arithmetic_checked_shr(3), Some(-13i8)); /// assert_eq!(100i8.arithmetic_checked_shr(100), Some(0i8)); /// assert_eq!((-100i8).arithmetic_checked_shr(100), Some(-1i8)); /// assert_eq!(3i8.arithmetic_checked_shr(-5), Some(96i8)); /// assert_eq!(3i8.arithmetic_checked_shr(-6), None); /// assert_eq!((-3i8).arithmetic_checked_shr(-5), Some(-96i8)); /// assert_eq!((-3i8).arithmetic_checked_shr(-6), None); /// assert_eq!(3i8.arithmetic_checked_shr(-100), None); /// assert_eq!((-3i8).arithmetic_checked_shr(-100), None); /// assert_eq!(0i8.arithmetic_checked_shr(-100), Some(0i8)); /// ``` pub mod arithmetic_checked_shr; /// Traits for computing the binomial coefficient of two numbers. There is a trait whose /// implementations panic if the result cannot be represented, and a checked trait whose /// implementations return `None` in that case: [`BinomialCoefficient`](traits::BinomialCoefficient) /// and [`CheckedBinomialCoefficient`](traits::CheckedBinomialCoefficient). /// /// # binomial_coefficient /// ``` /// use malachite_base::num::arithmetic::traits::BinomialCoefficient; /// /// assert_eq!(u8::binomial_coefficient(3, 0), 1); /// assert_eq!(u8::binomial_coefficient(3, 1), 3); /// assert_eq!(u8::binomial_coefficient(3, 2), 3); /// assert_eq!(u8::binomial_coefficient(3, 3), 1); /// assert_eq!(u8::binomial_coefficient(10, 5), 252); /// /// assert_eq!(i8::binomial_coefficient(-3, 0), 1); /// assert_eq!(i8::binomial_coefficient(-3, 1), -3); /// assert_eq!(i8::binomial_coefficient(-3, 2), 6); /// assert_eq!(i8::binomial_coefficient(-3, 3), -10); /// ``` /// /// # checked_binomial_coefficient /// ``` /// use malachite_base::num::arithmetic::traits::CheckedBinomialCoefficient; /// /// assert_eq!(u8::checked_binomial_coefficient(3, 0), Some(1)); /// assert_eq!(u8::checked_binomial_coefficient(3, 1), Some(3)); /// assert_eq!(u8::checked_binomial_coefficient(3, 2), Some(3)); /// assert_eq!(u8::checked_binomial_coefficient(3, 3), Some(1)); /// assert_eq!(u8::checked_binomial_coefficient(10, 5), Some(252)); /// assert_eq!(u8::checked_binomial_coefficient(11, 5), None); /// /// assert_eq!(i8::checked_binomial_coefficient(-3, 0), Some(1)); /// assert_eq!(i8::checked_binomial_coefficient(-3, 1), Some(-3)); /// assert_eq!(i8::checked_binomial_coefficient(-3, 2), Some(6)); /// assert_eq!(i8::checked_binomial_coefficient(-3, 3), Some(-10)); /// assert_eq!(i8::checked_binomial_coefficient(-3, -3), None); /// assert_eq!(i8::checked_binomial_coefficient(11, 5), None); /// ``` pub mod binomial_coefficient; /// [`Ceiling`](traits::Ceiling) and [`CeilingAssign`](traits::CeilingAssign), traits for computing /// the ceiling of a number. /// /// # ceiling /// ``` /// use malachite_base::num::arithmetic::traits::CeilingAssign; /// /// let mut x = 1.5f32; /// x.ceiling_assign(); /// assert_eq!(x, 2.0); /// /// let mut x = -1.5f32; /// x.ceiling_assign(); /// assert_eq!(x, -1.0); /// ``` pub mod ceiling; /// [`CheckedAbs`](traits::CheckedAbs), a trait for computing the absolute value of number and /// checking whether the result is representable. pub mod checked_abs; /// [`CheckedAdd`](traits::CheckedAdd), a trait for adding two numbers and checking whether the /// result is representable. pub mod checked_add; /// [`CheckedAddMul`](traits::CheckedAddMul), a trait for adding a number and the product of two /// other numbers, and checking whether the result is representable. /// /// # checked_add_mul /// ``` /// use malachite_base::num::arithmetic::traits::CheckedAddMul; /// /// assert_eq!(2u8.checked_add_mul(3, 7), Some(23)); /// assert_eq!(2u8.checked_add_mul(20, 20), None); /// /// assert_eq!(127i8.checked_add_mul(-2, 100), Some(-73)); /// assert_eq!((-127i8).checked_add_mul(-2, 100), None); /// ``` pub mod checked_add_mul; /// [`CheckedDiv`](traits::CheckedDiv), a trait for dividing two numbers and checking whether the /// result is representable. pub mod checked_div; /// [`CheckedMul`](traits::CheckedMul), a trait for multiplying two numbers and checking whether the /// result is representable. pub mod checked_mul; /// [`CheckedNeg`](traits::CheckedNeg), a trait for negating a number and checking whether the /// result is representable. pub mod checked_neg; /// [`CheckedNextPowerOf2`](traits::CheckedNextPowerOf2), a trait for getting the next-highest power /// of 2, if it's representable. pub mod checked_next_power_of_2; /// [`CheckedPow`](traits::CheckedPow), a trait for raising a number to the power of a [`u64`] and /// checking whether the result is representable. pub mod checked_pow; /// [`CheckedSquare`](traits::CheckedSquare), a trait for squaring a number and checking whether the /// result is representable. /// /// # checked_square /// ``` /// use malachite_base::num::arithmetic::traits::CheckedSquare; /// /// assert_eq!(3u8.checked_square(), Some(9)); /// assert_eq!((-1000i32).checked_square(), Some(1000000)); /// assert_eq!((1000u16).checked_square(), None); /// ``` pub mod checked_square; /// [`CheckedSub`](traits::CheckedSub), a trait for subtracting two numbers and checking whether the /// result is representable. pub mod checked_sub; /// [`CheckedSubMul`](traits::CheckedSubMul), a trait for subtracting the product of two numbers /// from another number, and checking whether the result is representable. /// /// # checked_sub_mul /// ``` /// use malachite_base::num::arithmetic::traits::CheckedSubMul; /// /// assert_eq!(60u8.checked_sub_mul(5, 10), Some(10)); /// assert_eq!(2u8.checked_sub_mul(10, 5), None); /// /// assert_eq!(127i8.checked_sub_mul(2, 100), Some(-73)); /// assert_eq!((-127i8).checked_sub_mul(2, 100), None); /// ``` pub mod checked_sub_mul; /// [`CoprimeWith`](traits::CoprimeWith), a trait for determining whether two numbers are coprime. /// /// # coprime_with /// ``` /// use malachite_base::num::arithmetic::traits::CoprimeWith; /// /// assert_eq!(0u8.coprime_with(0), false); /// assert_eq!(0u8.coprime_with(1), true); /// assert_eq!(6u8.coprime_with(1), true); /// assert_eq!(3u8.coprime_with(5), true); /// assert_eq!(6u8.coprime_with(4), false); /// assert_eq!(6u8.coprime_with(35), true); /// ``` pub mod coprime_with; /// [`DivExact`](traits::DivExact) and [`DivExactAssign`](traits::DivExactAssign), traits for /// dividing two numbers when it's known that the division is exact. /// /// # div_exact /// ``` /// use malachite_base::num::arithmetic::traits::DivExact; /// /// // 123 * 456 = 56088 /// assert_eq!(56088u32.div_exact(456), 123); /// /// // -123 * -456 = 56088 /// assert_eq!(56088i64.div_exact(-456), -123); /// ``` /// /// # div_exact_assign /// ``` /// use malachite_base::num::arithmetic::traits::DivExactAssign; /// /// // 123 * 456 = 56088 /// let mut x = 56088u32; /// x.div_exact_assign(456); /// assert_eq!(x, 123); /// /// // -123 * -456 = 56088 /// let mut x = 56088i64; /// x.div_exact_assign(-456); /// assert_eq!(x, -123); /// ``` pub mod div_exact; /// Traits for simultaneously finding the quotient and remainder of two numbers, subject to various /// rounding rules. /// /// These are the traits: /// /// | rounding | by value or reference | by mutable reference (assignment) | /// |--------------|---------------------------------|----------------------------------------| /// | towards $-\infty$ | [`DivMod`](traits::DivMod) | [`DivAssignMod`](traits::DivAssignMod) | /// | towards 0 | [`DivRem`](traits::DivRem) | [`DivAssignRem`](traits::DivAssignRem) | /// | towards $\infty$ | [`CeilingDivMod`](traits::CeilingDivMod) | [`CeilingDivAssignMod`](traits::CeilingDivAssignMod) | /// | towards $\infty$ | [`CeilingDivNegMod`](traits::CeilingDivNegMod) | [`CeilingDivAssignNegMod`](traits::CeilingDivAssignNegMod) | /// /// [`CeilingDivMod`](traits::CeilingDivMod) and [`CeilingDivNegMod`](traits::CeilingDivNegMod) are /// similar. The difference is that [`CeilingDivMod`](traits::CeilingDivMod) returns a remainder /// less than or equal to 0, so that the usual relation $x = qy + r$ is satisfied, while /// [`CeilingDivNegMod`](traits::CeilingDivNegMod) returns a remainder greater than or equal to /// zero. This allows the remainder to have an unsigned type, but modifies the relation to $x = qy /// - r$. /// /// # div_mod /// ``` /// use malachite_base::num::arithmetic::traits::DivMod; /// /// // 2 * 10 + 3 = 23 /// assert_eq!(23u8.div_mod(10), (2, 3)); /// /// // 9 * 5 + 0 = 45 /// assert_eq!(45u32.div_mod(5), (9, 0)); /// /// // 2 * 10 + 3 = 23 /// assert_eq!(23i8.div_mod(10), (2, 3)); /// /// // -3 * -10 + -7 = 23 /// assert_eq!(23i16.div_mod(-10), (-3, -7)); /// /// // -3 * 10 + 7 = -23 /// assert_eq!((-23i32).div_mod(10), (-3, 7)); /// /// // 2 * -10 + -3 = -23 /// assert_eq!((-23i64).div_mod(-10), (2, -3)); /// ``` /// /// # div_assign_mod /// ``` /// use malachite_base::num::arithmetic::traits::DivAssignMod; /// /// // 2 * 10 + 3 = 23 /// let mut x = 23u8; /// assert_eq!(x.div_assign_mod(10), 3); /// assert_eq!(x, 2); /// /// // 9 * 5 + 0 = 45 /// let mut x = 45u32; /// assert_eq!(x.div_assign_mod(5), 0); /// assert_eq!(x, 9); /// /// // 2 * 10 + 3 = 23 /// let mut x = 23i8; /// assert_eq!(x.div_assign_mod(10), 3); /// assert_eq!(x, 2); /// /// // -3 * -10 + -7 = 23 /// let mut x = 23i16; /// assert_eq!(x.div_assign_mod(-10), -7); /// assert_eq!(x, -3); /// /// // -3 * 10 + 7 = -23 /// let mut x = -23i32; /// assert_eq!(x.div_assign_mod(10), 7); /// assert_eq!(x, -3); /// /// // 2 * -10 + -3 = -23 /// let mut x = -23i64; /// assert_eq!(x.div_assign_mod(-10), -3); /// assert_eq!(x, 2); /// ``` /// /// # div_rem /// ``` /// use malachite_base::num::arithmetic::traits::DivRem; /// /// // 2 * 10 + 3 = 23 /// assert_eq!(23u8.div_rem(10), (2, 3)); /// /// // 9 * 5 + 0 = 45 /// assert_eq!(45u32.div_rem(5), (9, 0)); /// /// // 2 * 10 + 3 = 23 /// assert_eq!(23i8.div_rem(10), (2, 3)); /// /// // -2 * -10 + 3 = 23 /// assert_eq!(23i16.div_rem(-10), (-2, 3)); /// /// // -2 * 10 + -3 = -23 /// assert_eq!((-23i32).div_rem(10), (-2, -3)); /// /// // 2 * -10 + -3 = -23 /// assert_eq!((-23i64).div_rem(-10), (2, -3)); /// ``` /// /// # div_assign_rem /// ``` /// use malachite_base::num::arithmetic::traits::DivAssignRem; /// /// // 2 * 10 + 3 = 23 /// let mut x = 23u8; /// assert_eq!(x.div_assign_rem(10), 3); /// assert_eq!(x, 2); /// /// // 9 * 5 + 0 = 45 /// let mut x = 45u32; /// assert_eq!(x.div_assign_rem(5), 0); /// assert_eq!(x, 9); /// /// // 2 * 10 + 3 = 23 /// let mut x = 23i8; /// assert_eq!(x.div_assign_rem(10), 3); /// assert_eq!(x, 2); /// /// // -2 * -10 + 3 = 23 /// let mut x = 23i16; /// assert_eq!(x.div_assign_rem(-10), 3); /// assert_eq!(x, -2); /// /// // -2 * 10 + -3 = -23 /// let mut x = -23i32; /// assert_eq!(x.div_assign_rem(10), -3); /// assert_eq!(x, -2); /// /// // 2 * -10 + -3 = -23 /// let mut x = -23i64; /// assert_eq!(x.div_assign_rem(-10), -3); /// assert_eq!(x, 2); /// ``` /// /// # ceiling_div_neg_mod /// ``` /// use malachite_base::num::arithmetic::traits::CeilingDivNegMod; /// /// // 3 * 10 - 7 = 23 /// assert_eq!(23u8.ceiling_div_neg_mod(10), (3, 7)); /// /// // 9 * 5 + 0 = 45 /// assert_eq!(45u32.ceiling_div_neg_mod(5), (9, 0)); /// ``` /// /// # ceiling_div_assign_neg_mod /// ``` /// use malachite_base::num::arithmetic::traits::CeilingDivAssignNegMod; /// /// // 3 * 10 - 7 = 23 /// let mut x = 23u8; /// assert_eq!(x.ceiling_div_assign_neg_mod(10), 7); /// assert_eq!(x, 3); /// /// // 9 * 5 + 0 = 45 /// let mut x = 45u32; /// assert_eq!(x.ceiling_div_assign_neg_mod(5), 0); /// assert_eq!(x, 9); /// ``` /// /// # ceiling_div_mod /// ``` /// use malachite_base::num::arithmetic::traits::CeilingDivMod; /// /// // 3 * 10 + -7 = 23 /// assert_eq!(23i8.ceiling_div_mod(10), (3, -7)); /// /// // -2 * -10 + 3 = 23 /// assert_eq!(23i16.ceiling_div_mod(-10), (-2, 3)); /// /// // -2 * 10 + -3 = -23 /// assert_eq!((-23i32).ceiling_div_mod(10), (-2, -3)); /// /// // 3 * -10 + 7 = -23 /// assert_eq!((-23i64).ceiling_div_mod(-10), (3, 7)); /// ``` /// /// # ceiling_div_assign_mod /// ``` /// use malachite_base::num::arithmetic::traits::CeilingDivAssignMod; /// /// // 3 * 10 + -7 = 23 /// let mut x = 23i8; /// assert_eq!(x.ceiling_div_assign_mod(10), -7); /// assert_eq!(x, 3); /// /// // -2 * -10 + 3 = 23 /// let mut x = 23i16; /// assert_eq!(x.ceiling_div_assign_mod(-10), 3); /// assert_eq!(x, -2); /// /// // -2 * 10 + -3 = -23 /// let mut x = -23i32; /// assert_eq!(x.ceiling_div_assign_mod(10), -3); /// assert_eq!(x, -2); /// /// // 3 * -10 + 7 = -23 /// let mut x = -23i64; /// assert_eq!(x.ceiling_div_assign_mod(-10), 7); /// assert_eq!(x, 3); /// ``` pub mod div_mod; /// [`DivRound`](traits::DivRound) and [`DivExactAssign`](traits::DivRoundAssign), traits for /// dividing two numbers according to a specified /// [`RoundingMode`](crate::rounding_modes::RoundingMode). /// /// # div_round /// ``` /// use malachite_base::num::arithmetic::traits::DivRound; /// use malachite_base::rounding_modes::RoundingMode::*; /// use std::cmp::Ordering::*; /// /// assert_eq!(10u8.div_round(4, Down), (2, Less)); /// assert_eq!(10u16.div_round(4, Up), (3, Greater)); /// assert_eq!(10u32.div_round(5, Exact), (2, Equal)); /// assert_eq!(10u64.div_round(3, Nearest), (3, Less)); /// assert_eq!(20u128.div_round(3, Nearest), (7, Greater)); /// assert_eq!(10usize.div_round(4, Nearest), (2, Less)); /// assert_eq!(14u8.div_round(4, Nearest), (4, Greater)); /// /// assert_eq!((-10i8).div_round(4, Down), (-2, Greater)); /// assert_eq!((-10i16).div_round(4, Up), (-3, Less)); /// assert_eq!((-10i32).div_round(5, Exact), (-2, Equal)); /// assert_eq!((-10i64).div_round(3, Nearest), (-3, Greater)); /// assert_eq!((-20i128).div_round(3, Nearest), (-7, Less)); /// assert_eq!((-10isize).div_round(4, Nearest), (-2, Greater)); /// assert_eq!((-14i8).div_round(4, Nearest), (-4, Less)); /// /// assert_eq!((-10i16).div_round(-4, Down), (2, Less)); /// assert_eq!((-10i32).div_round(-4, Up), (3, Greater)); /// assert_eq!((-10i64).div_round(-5, Exact), (2, Equal)); /// assert_eq!((-10i128).div_round(-3, Nearest), (3, Less)); /// assert_eq!((-20isize).div_round(-3, Nearest), (7, Greater)); /// assert_eq!((-10i8).div_round(-4, Nearest), (2, Less)); /// assert_eq!((-14i16).div_round(-4, Nearest), (4, Greater)); /// ``` /// /// # div_round_assign /// ``` /// use malachite_base::num::arithmetic::traits::DivRoundAssign; /// use malachite_base::rounding_modes::RoundingMode::*; /// use std::cmp::Ordering::*; /// /// let mut x = 10u8; /// assert_eq!(x.div_round_assign(4, Down), Less); /// assert_eq!(x, 2); /// /// let mut x = 10u16; /// assert_eq!(x.div_round_assign(4, Up), Greater); /// assert_eq!(x, 3); /// /// let mut x = 10u32; /// assert_eq!(x.div_round_assign(5, Exact), Equal); /// assert_eq!(x, 2); /// /// let mut x = 10u64; /// assert_eq!(x.div_round_assign(3, Nearest), Less); /// assert_eq!(x, 3); /// /// let mut x = 20u128; /// assert_eq!(x.div_round_assign(3, Nearest), Greater); /// assert_eq!(x, 7); /// /// let mut x = 10usize; /// assert_eq!(x.div_round_assign(4, Nearest), Less); /// assert_eq!(x, 2); /// /// let mut x = 14u8; /// assert_eq!(x.div_round_assign(4, Nearest), Greater); /// assert_eq!(x, 4); /// /// let mut x = -10i8; /// assert_eq!(x.div_round_assign(4, Down), Greater); /// assert_eq!(x, -2); /// /// let mut x = -10i16; /// assert_eq!(x.div_round_assign(4, Up), Less); /// assert_eq!(x, -3); /// /// let mut x = -10i32; /// assert_eq!(x.div_round_assign(5, Exact), Equal); /// assert_eq!(x, -2); /// /// let mut x = -10i64; /// assert_eq!(x.div_round_assign(3, Nearest), Greater); /// assert_eq!(x, -3); /// /// let mut x = -20i128; /// assert_eq!(x.div_round_assign(3, Nearest), Less); /// assert_eq!(x, -7); /// /// let mut x = -10isize; /// assert_eq!(x.div_round_assign(4, Nearest), Greater); /// assert_eq!(x, -2); /// /// let mut x = -14i8; /// assert_eq!(x.div_round_assign(4, Nearest), Less); /// assert_eq!(x, -4); /// /// let mut x = -10i16; /// assert_eq!(x.div_round_assign(-4, Down), Less); /// assert_eq!(x, 2); /// /// let mut x = -10i32; /// assert_eq!(x.div_round_assign(-4, Up), Greater); /// assert_eq!(x, 3); /// /// let mut x = -10i64; /// assert_eq!(x.div_round_assign(-5, Exact), Equal); /// assert_eq!(x, 2); /// /// let mut x = -10i128; /// assert_eq!(x.div_round_assign(-3, Nearest), Less); /// assert_eq!(x, 3); /// /// let mut x = -20isize; /// assert_eq!(x.div_round_assign(-3, Nearest), Greater); /// assert_eq!(x, 7); /// /// let mut x = -10i8; /// assert_eq!(x.div_round_assign(-4, Nearest), Less); /// assert_eq!(x, 2); /// /// let mut x = -14i16; /// assert_eq!(x.div_round_assign(-4, Nearest), Greater); /// assert_eq!(x, 4); /// ``` pub mod div_round; /// [`DivisibleBy`](traits::DivisibleBy), a trait for determining whether one number is divisible by /// another. /// /// # divisible_by /// ``` /// use malachite_base::num::arithmetic::traits::DivisibleBy; /// /// assert_eq!(0u8.divisible_by(0), true); /// assert_eq!(100u16.divisible_by(3), false); /// assert_eq!(102u32.divisible_by(3), true); /// /// assert_eq!(0i8.divisible_by(0), true); /// assert_eq!((-100i16).divisible_by(-3), false); /// assert_eq!(102i32.divisible_by(-3), true); /// ``` pub mod divisible_by; /// [`DivisibleByPowerOf2`](traits::DivisibleByPowerOf2), a trait for determining whether a number /// is divisible by $2^k$. /// /// # divisible_by_power_of_2 /// ``` /// use malachite_base::num::arithmetic::traits::DivisibleByPowerOf2; /// /// assert_eq!(0u8.divisible_by_power_of_2(100), true); /// assert_eq!(96u16.divisible_by_power_of_2(5), true); /// assert_eq!(96u32.divisible_by_power_of_2(6), false); /// /// assert_eq!(0i8.divisible_by_power_of_2(100), true); /// assert_eq!((-96i16).divisible_by_power_of_2(5), true); /// assert_eq!(96i32.divisible_by_power_of_2(6), false); /// ``` pub mod divisible_by_power_of_2; /// [`EqMod`](traits::EqMod), a trait for determining whether one number is equal by another modulo /// a third. /// /// # eq_mod /// ``` /// use malachite_base::num::arithmetic::traits::EqMod; /// /// assert_eq!(123u16.eq_mod(223, 100), true); /// assert_eq!((-123i32).eq_mod(277, 100), true); /// assert_eq!((-123i64).eq_mod(278, 100), false); /// ``` pub mod eq_mod; /// [`EqModPowerOf2`](traits::EqModPowerOf2), a trait for determining whether one number is equal to /// another modulo $2^k$. /// /// # eq_mod_power_of_2 /// ``` /// use malachite_base::num::arithmetic::traits::EqModPowerOf2; /// /// assert_eq!(0u16.eq_mod_power_of_2(256, 8), true); /// assert_eq!((-0b1101i32).eq_mod_power_of_2(0b11011, 3), true); /// assert_eq!((-0b1101i64).eq_mod_power_of_2(0b11011, 4), false); /// ``` pub mod eq_mod_power_of_2; /// [`ExtendedGcd`](traits::ExtendedGcd), a trait for computing the GCD (greatest common divisor) of /// two numbers as well as the coefficients of Bézout's identity $ax+by=\gcd(a,b)$. /// /// # extended_gcd /// ``` /// use malachite_base::num::arithmetic::traits::ExtendedGcd; /// /// assert_eq!(3u8.extended_gcd(5), (1, 2, -1)); /// assert_eq!(240u16.extended_gcd(46), (2, -9, 47)); /// assert_eq!((-111i16).extended_gcd(300), (3, 27, 10)); /// ``` pub mod extended_gcd; /// Traits for computing the factorial, double factorial, multifactorial, and subfactorial. Each /// function has a trait whose implementations panic if the result cannot be represented, and a /// checked trait whose implementations return `None` in that case. The traits are /// [`Factorial`](traits::Factorial), [`DoubleFactorial`](traits::DoubleFactorial), /// [`Multifactorial`](traits::Multifactorial), [`Subfactorial`](traits::Subfactorial), /// [`CheckedFactorial`](traits::CheckedFactorial), /// [`CheckedDoubleFactorial`](traits::CheckedDoubleFactorial), /// [`CheckedMultifactorial`](traits::CheckedMultifactorial), and /// [`CheckedSubfactorial`](traits::CheckedSubfactorial). /// /// # factorial /// ``` /// use malachite_base::num::arithmetic::traits::Factorial; /// /// assert_eq!(u8::factorial(0), 1); /// assert_eq!(u8::factorial(1), 1); /// assert_eq!(u8::factorial(2), 2); /// assert_eq!(u8::factorial(3), 6); /// assert_eq!(u8::factorial(4), 24); /// assert_eq!(u8::factorial(5), 120); /// assert_eq!(u32::factorial(10), 3628800); /// ``` /// /// # checked_factorial /// ``` /// use malachite_base::num::arithmetic::traits::CheckedFactorial; /// /// assert_eq!(u8::checked_factorial(0), Some(1)); /// assert_eq!(u8::checked_factorial(1), Some(1)); /// assert_eq!(u8::checked_factorial(2), Some(2)); /// assert_eq!(u8::checked_factorial(3), Some(6)); /// assert_eq!(u8::checked_factorial(4), Some(24)); /// assert_eq!(u8::checked_factorial(5), Some(120)); /// assert_eq!(u8::checked_factorial(6), None); /// assert_eq!(u32::checked_factorial(10), Some(3628800)); /// assert_eq!(u32::checked_factorial(100), None); /// ``` /// /// # double_factorial /// ``` /// use malachite_base::num::arithmetic::traits::DoubleFactorial; /// /// assert_eq!(u8::double_factorial(0), 1); /// assert_eq!(u8::double_factorial(1), 1); /// assert_eq!(u8::double_factorial(2), 2); /// assert_eq!(u8::double_factorial(3), 3); /// assert_eq!(u8::double_factorial(4), 8); /// assert_eq!(u8::double_factorial(5), 15); /// assert_eq!(u8::double_factorial(6), 48); /// assert_eq!(u8::double_factorial(7), 105); /// assert_eq!(u32::double_factorial(19), 654729075); /// assert_eq!(u32::double_factorial(20), 3715891200); /// ``` /// /// # checked_double_factorial /// ``` /// use malachite_base::num::arithmetic::traits::CheckedDoubleFactorial; /// /// assert_eq!(u8::checked_double_factorial(0), Some(1)); /// assert_eq!(u8::checked_double_factorial(1), Some(1)); /// assert_eq!(u8::checked_double_factorial(2), Some(2)); /// assert_eq!(u8::checked_double_factorial(3), Some(3)); /// assert_eq!(u8::checked_double_factorial(4), Some(8)); /// assert_eq!(u8::checked_double_factorial(5), Some(15)); /// assert_eq!(u8::checked_double_factorial(6), Some(48)); /// assert_eq!(u8::checked_double_factorial(7), Some(105)); /// assert_eq!(u8::checked_double_factorial(8), None); /// assert_eq!(u32::checked_double_factorial(19), Some(654729075)); /// assert_eq!(u32::checked_double_factorial(20), Some(3715891200)); /// assert_eq!(u32::checked_double_factorial(100), None); /// ``` /// /// # multifactorial /// ``` /// use malachite_base::num::arithmetic::traits::Multifactorial; /// /// assert_eq!(u8::multifactorial(0, 1), 1); /// assert_eq!(u8::multifactorial(1, 1), 1); /// assert_eq!(u8::multifactorial(2, 1), 2); /// assert_eq!(u8::multifactorial(3, 1), 6); /// assert_eq!(u8::multifactorial(4, 1), 24); /// assert_eq!(u8::multifactorial(5, 1), 120); /// /// assert_eq!(u8::multifactorial(0, 2), 1); /// assert_eq!(u8::multifactorial(1, 2), 1); /// assert_eq!(u8::multifactorial(2, 2), 2); /// assert_eq!(u8::multifactorial(3, 2), 3); /// assert_eq!(u8::multifactorial(4, 2), 8); /// assert_eq!(u8::multifactorial(5, 2), 15); /// assert_eq!(u8::multifactorial(6, 2), 48); /// assert_eq!(u8::multifactorial(7, 2), 105); /// /// assert_eq!(u8::multifactorial(0, 3), 1); /// assert_eq!(u8::multifactorial(1, 3), 1); /// assert_eq!(u8::multifactorial(2, 3), 2); /// assert_eq!(u8::multifactorial(3, 3), 3); /// assert_eq!(u8::multifactorial(4, 3), 4); /// assert_eq!(u8::multifactorial(5, 3), 10); /// assert_eq!(u8::multifactorial(6, 3), 18); /// assert_eq!(u8::multifactorial(7, 3), 28); /// assert_eq!(u8::multifactorial(8, 3), 80); /// assert_eq!(u8::multifactorial(9, 3), 162); /// /// assert_eq!(u32::multifactorial(10, 1), 3628800); /// assert_eq!(u32::multifactorial(20, 2), 3715891200); /// assert_eq!(u32::multifactorial(25, 3), 608608000); /// ``` /// /// # checked_multifactorial /// ``` /// use malachite_base::num::arithmetic::traits::CheckedMultifactorial; /// /// assert_eq!(u8::checked_multifactorial(0, 1), Some(1)); /// assert_eq!(u8::checked_multifactorial(1, 1), Some(1)); /// assert_eq!(u8::checked_multifactorial(2, 1), Some(2)); /// assert_eq!(u8::checked_multifactorial(3, 1), Some(6)); /// assert_eq!(u8::checked_multifactorial(4, 1), Some(24)); /// assert_eq!(u8::checked_multifactorial(5, 1), Some(120)); /// assert_eq!(u8::checked_multifactorial(6, 1), None); /// /// assert_eq!(u8::checked_multifactorial(0, 2), Some(1)); /// assert_eq!(u8::checked_multifactorial(1, 2), Some(1)); /// assert_eq!(u8::checked_multifactorial(2, 2), Some(2)); /// assert_eq!(u8::checked_multifactorial(3, 2), Some(3)); /// assert_eq!(u8::checked_multifactorial(4, 2), Some(8)); /// assert_eq!(u8::checked_multifactorial(5, 2), Some(15)); /// assert_eq!(u8::checked_multifactorial(6, 2), Some(48)); /// assert_eq!(u8::checked_multifactorial(7, 2), Some(105)); /// assert_eq!(u8::checked_multifactorial(8, 2), None); /// /// assert_eq!(u8::checked_multifactorial(0, 3), Some(1)); /// assert_eq!(u8::checked_multifactorial(1, 3), Some(1)); /// assert_eq!(u8::checked_multifactorial(2, 3), Some(2)); /// assert_eq!(u8::checked_multifactorial(3, 3), Some(3)); /// assert_eq!(u8::checked_multifactorial(4, 3), Some(4)); /// assert_eq!(u8::checked_multifactorial(5, 3), Some(10)); /// assert_eq!(u8::checked_multifactorial(6, 3), Some(18)); /// assert_eq!(u8::checked_multifactorial(7, 3), Some(28)); /// assert_eq!(u8::checked_multifactorial(8, 3), Some(80)); /// assert_eq!(u8::checked_multifactorial(9, 3), Some(162)); /// assert_eq!(u8::checked_multifactorial(10, 3), None); /// /// assert_eq!(u32::checked_multifactorial(10, 1), Some(3628800)); /// assert_eq!(u32::checked_multifactorial(20, 2), Some(3715891200)); /// assert_eq!(u32::checked_multifactorial(25, 3), Some(608608000)); /// assert_eq!(u32::checked_multifactorial(100, 1), None); /// assert_eq!(u32::checked_multifactorial(100, 2), None); /// assert_eq!(u32::checked_multifactorial(100, 3), None); /// ``` /// /// # subfactorial /// ``` /// use malachite_base::num::arithmetic::traits::Subfactorial; /// /// assert_eq!(u8::subfactorial(0), 1); /// assert_eq!(u8::subfactorial(1), 0); /// assert_eq!(u8::subfactorial(2), 1); /// assert_eq!(u8::subfactorial(3), 2); /// assert_eq!(u8::subfactorial(4), 9); /// assert_eq!(u8::subfactorial(5), 44); /// assert_eq!(u32::subfactorial(10), 1334961); /// ``` /// /// # checked_subfactorial /// ``` /// use malachite_base::num::arithmetic::traits::CheckedSubfactorial; /// /// assert_eq!(u8::checked_subfactorial(0), Some(1)); /// assert_eq!(u8::checked_subfactorial(1), Some(0)); /// assert_eq!(u8::checked_subfactorial(2), Some(1)); /// assert_eq!(u8::checked_subfactorial(3), Some(2)); /// assert_eq!(u8::checked_subfactorial(4), Some(9)); /// assert_eq!(u8::checked_subfactorial(5), Some(44)); /// assert_eq!(u8::checked_subfactorial(6), None); /// assert_eq!(u32::checked_subfactorial(10), Some(1334961)); /// assert_eq!(u32::checked_subfactorial(100), None); /// ``` pub mod factorial; /// [`Floor`](traits::Floor) and [`FloorAssign`](traits::FloorAssign), traits for computing the /// floor of a number. /// /// # floor_assign /// ``` /// use malachite_base::num::arithmetic::traits::FloorAssign; /// /// let mut x = 1.5f32; /// x.floor_assign(); /// assert_eq!(x, 1.0); /// /// let mut x = -1.5f32; /// x.floor_assign(); /// assert_eq!(x, -2.0); /// ``` pub mod floor; /// [`Gcd`](traits::Gcd) and [`GcdAssign`](traits::GcdAssign), traits for computing the GCD /// (greatest common divisor) of two numbers. /// /// # gcd /// ``` /// use malachite_base::num::arithmetic::traits::Gcd; /// /// assert_eq!(3u8.gcd(5), 1); /// assert_eq!(12u16.gcd(90), 6); /// ``` /// /// # gcd_assign /// ``` /// use malachite_base::num::arithmetic::traits::GcdAssign; /// /// let mut x = 3u8; /// x.gcd_assign(5); /// assert_eq!(x, 1); /// /// let mut x = 12u16; /// x.gcd_assign(90); /// assert_eq!(x, 6); /// ``` pub mod gcd; /// [`IsPowerOf2`](traits::IsPowerOf2), a trait for determining whether a number is an integer power /// of 2. /// /// # is_power_of_2 /// ``` /// use malachite_base::num::arithmetic::traits::IsPowerOf2; /// /// assert_eq!(4.0.is_power_of_2(), true); /// assert_eq!(0.25.is_power_of_2(), true); /// assert_eq!(0.2.is_power_of_2(), false); /// assert_eq!((-4.0).is_power_of_2(), false); /// ``` pub mod is_power_of_2; /// [`LegendreSymbol`](traits::LegendreSymbol), [`JacobiSymbol`](traits::JacobiSymbol), and /// [`KroneckerSymbol`](traits::KroneckerSymbol), traits for computing the Legendre, Jacobi, and /// Kronecker symbols of two numbers. /// /// # legendre_symbol /// ``` /// use malachite_base::num::arithmetic::traits::LegendreSymbol; /// /// assert_eq!(10u8.legendre_symbol(5), 0); /// assert_eq!(7u8.legendre_symbol(5), -1); /// assert_eq!(11u8.legendre_symbol(5), 1); /// /// assert_eq!((-7i8).legendre_symbol(5), -1); /// assert_eq!((-11i8).legendre_symbol(5), 1); /// ``` /// /// # jacobi_symbol /// ``` /// use malachite_base::num::arithmetic::traits::JacobiSymbol; /// /// assert_eq!(10u8.jacobi_symbol(5), 0); /// assert_eq!(7u8.jacobi_symbol(5), -1); /// assert_eq!(11u8.jacobi_symbol(5), 1); /// assert_eq!(11u8.jacobi_symbol(9), 1); /// /// assert_eq!((-7i8).jacobi_symbol(5), -1); /// assert_eq!((-11i8).jacobi_symbol(5), 1); /// assert_eq!((-11i8).jacobi_symbol(9), 1); /// ``` /// /// # kronecker_symbol /// ``` /// use malachite_base::num::arithmetic::traits::KroneckerSymbol; /// /// assert_eq!(10u8.kronecker_symbol(5), 0); /// assert_eq!(7u8.kronecker_symbol(5), -1); /// assert_eq!(11u8.kronecker_symbol(5), 1); /// assert_eq!(11u8.kronecker_symbol(9), 1); /// assert_eq!(11u8.kronecker_symbol(8), -1); /// /// assert_eq!((-7i8).kronecker_symbol(5), -1); /// assert_eq!((-11i8).kronecker_symbol(5), 1); /// assert_eq!((-11i8).kronecker_symbol(9), 1); /// assert_eq!((-11i8).kronecker_symbol(8), -1); /// assert_eq!((-11i8).kronecker_symbol(-8), 1); /// ``` pub mod kronecker_symbol; /// [`Lcm`](traits::Lcm), [`LcmAssign`](traits::LcmAssign), and [`CheckedLcm`](traits::CheckedLcm), /// traits for computing the LCM (least common multiple) of two numbers. /// /// # lcm /// ``` /// use malachite_base::num::arithmetic::traits::Lcm; /// /// assert_eq!(3u8.lcm(5), 15); /// assert_eq!(12u16.lcm(90), 180); /// ``` /// /// # lcm_assign /// ``` /// use malachite_base::num::arithmetic::traits::LcmAssign; /// /// let mut x = 3u8; /// x.lcm_assign(5); /// assert_eq!(x, 15); /// /// let mut x = 12u16; /// x.lcm_assign(90); /// assert_eq!(x, 180); /// ``` /// /// # checked_lcm /// ``` /// use malachite_base::num::arithmetic::traits::CheckedLcm; /// /// assert_eq!(3u8.checked_lcm(5), Some(15)); /// assert_eq!(12u16.checked_lcm(90), Some(180)); /// assert_eq!(120u8.checked_lcm(90), None); /// ``` pub mod lcm; /// Traits for taking the base-$b$ logarithm of a number. /// /// The traits are [`FloorLogBase`](traits::FloorLogBase), /// [`CeilingLogBase`](traits::CeilingLogBase), and [`CheckedLogBase`](traits::CheckedLogBase). /// /// # floor_log_base /// ``` /// use malachite_base::num::arithmetic::traits::FloorLogBase; /// /// assert_eq!(1u8.floor_log_base(5), 0); /// assert_eq!(125u8.floor_log_base(5), 3); /// assert_eq!(99u64.floor_log_base(10), 1); /// assert_eq!(100u64.floor_log_base(10), 2); /// assert_eq!(101u64.floor_log_base(10), 2); /// ``` /// /// # ceiling_log_base /// ``` /// use malachite_base::num::arithmetic::traits::CeilingLogBase; /// /// assert_eq!(1u8.ceiling_log_base(5), 0); /// assert_eq!(125u8.ceiling_log_base(5), 3); /// assert_eq!(99u64.ceiling_log_base(10), 2); /// assert_eq!(100u64.ceiling_log_base(10), 2); /// assert_eq!(101u64.ceiling_log_base(10), 3); /// ``` /// /// # checked_log_base /// ``` /// use malachite_base::num::arithmetic::traits::CheckedLogBase; /// /// assert_eq!(1u8.checked_log_base(5), Some(0)); /// assert_eq!(125u8.checked_log_base(5), Some(3)); /// assert_eq!(99u64.checked_log_base(10), None); /// assert_eq!(100u64.checked_log_base(10), Some(2)); /// assert_eq!(101u64.checked_log_base(10), None); /// ``` pub mod log_base; /// Traits for taking the base-2 logarithm of a number. /// /// The traits are [`FloorLogBase2`](traits::FloorLogBase2), /// [`CeilingLogBase2`](traits::CeilingLogBase2), and [`CheckedLogBase2`](traits::CheckedLogBase2). /// /// # floor_log_base_2 /// ``` /// use malachite_base::num::arithmetic::traits::FloorLogBase2; /// /// assert_eq!(1u8.floor_log_base_2(), 0); /// assert_eq!(100u64.floor_log_base_2(), 6); /// /// assert_eq!(1.0f32.floor_log_base_2(), 0); /// assert_eq!(100.0f32.floor_log_base_2(), 6); /// assert_eq!(0.1f32.floor_log_base_2(), -4); /// ``` /// /// # ceiling_log_base_2 /// ``` /// use malachite_base::num::arithmetic::traits::CeilingLogBase2; /// /// assert_eq!(1u8.ceiling_log_base_2(), 0); /// assert_eq!(100u64.ceiling_log_base_2(), 7); /// /// assert_eq!(1.0f32.ceiling_log_base_2(), 0); /// assert_eq!(100.0f32.ceiling_log_base_2(), 7); /// assert_eq!(0.1f32.ceiling_log_base_2(), -3); /// ``` /// /// # checked_log_base_2 /// ``` /// use malachite_base::num::arithmetic::traits::CheckedLogBase2; /// /// assert_eq!(1u8.checked_log_base_2(), Some(0)); /// assert_eq!(100u64.checked_log_base_2(), None); /// assert_eq!(128u64.checked_log_base_2(), Some(7)); /// /// assert_eq!(1.0f32.checked_log_base_2(), Some(0)); /// assert_eq!(100.0f32.checked_log_base_2(), None); /// assert_eq!(128.0f32.checked_log_base_2(), Some(7)); /// assert_eq!(0.1f32.checked_log_base_2(), None); /// assert_eq!(0.0625f32.checked_log_base_2(), Some(-4)); /// ``` pub mod log_base_2; /// Traits for taking the base-$2^k$ logarithm of a number. /// /// The traits are [`FloorLogBasePowerOf2`](traits::FloorLogBasePowerOf2), /// [`CeilingLogBasePowerOf2`](traits::CeilingLogBasePowerOf2), and /// [`CheckedLogBasePowerOf2`](traits::CheckedLogBasePowerOf2). /// /// # floor_log_base_power_of_2 /// ``` /// use malachite_base::num::arithmetic::traits::FloorLogBasePowerOf2; /// /// assert_eq!(1u8.floor_log_base_power_of_2(4), 0); /// assert_eq!(100u64.floor_log_base_power_of_2(2), 3); /// /// assert_eq!(0.1f32.floor_log_base_power_of_2(2), -2); /// ``` /// /// # ceiling_log_base_power_of_2 /// ``` /// use malachite_base::num::arithmetic::traits::CeilingLogBasePowerOf2; /// /// assert_eq!(1u8.ceiling_log_base_power_of_2(4), 0); /// assert_eq!(100u64.ceiling_log_base_power_of_2(2), 4); /// /// assert_eq!(0.1f32.ceiling_log_base_power_of_2(2), -1); /// ``` /// /// # checked_log_base_power_of_2 /// ``` /// use malachite_base::num::arithmetic::traits::CheckedLogBasePowerOf2; /// /// assert_eq!(1u8.checked_log_base_power_of_2(4), Some(0)); /// assert_eq!(100u64.checked_log_base_power_of_2(4), None); /// assert_eq!(256u64.checked_log_base_power_of_2(4), Some(2)); /// /// assert_eq!(0.1f32.checked_log_base_power_of_2(2), None); /// assert_eq!(0.0625f32.checked_log_base_power_of_2(2), Some(-2)); /// ``` pub mod log_base_power_of_2; /// [`ModAdd`](traits::ModAdd) and [`ModAddAssign`](traits::ModAddAssign), traits for adding two /// numbers modulo another number. /// /// # mod_add /// ``` /// use malachite_base::num::arithmetic::traits::ModAdd; /// /// assert_eq!(0u8.mod_add(3, 5), 3); /// assert_eq!(7u32.mod_add(5, 10), 2); /// ``` /// /// # mod_add_assign /// ``` /// use malachite_base::num::arithmetic::traits::ModAddAssign; /// /// let mut n = 0u8; /// n.mod_add_assign(3, 5); /// assert_eq!(n, 3); /// /// let mut n = 7u32; /// n.mod_add_assign(5, 10); /// assert_eq!(n, 2); /// ``` pub mod mod_add; /// [`ModInverse`](traits::ModInverse), a trait for finding the multiplicative inverse of a number /// modulo another number. /// /// # mod_inverse /// ``` /// use malachite_base::num::arithmetic::traits::ModInverse; /// /// assert_eq!(7u8.mod_inverse(10), Some(3)); /// assert_eq!(8u8.mod_inverse(10), None); /// assert_eq!(123u32.mod_inverse(4567), Some(854)); /// ``` pub mod mod_inverse; /// [`ModIsReduced`](traits::ModIsReduced), a trait for checking whether a number is reduced modulo /// another number. /// /// # mod_is_reduced /// ``` /// use malachite_base::num::arithmetic::traits::ModIsReduced; /// /// assert_eq!(0u8.mod_is_reduced(&5), true); /// assert_eq!(100u64.mod_is_reduced(&100), false); /// assert_eq!(100u16.mod_is_reduced(&101), true); /// ``` pub mod mod_is_reduced; /// Traits for multiplying two numbers modulo another number. /// /// The traits are [`ModMul`](traits::ModMul), [`ModMulAssign`](traits::ModMulAssign), /// [`ModMulPrecomputed`](traits::ModMulPrecomputed), and /// [`ModMulPrecomputedAssign`](traits::ModMulPrecomputedAssign). /// [`ModMulPrecomputed`](traits::ModMulPrecomputed) and /// [`ModMulPrecomputedAssign`](traits::ModMulPrecomputedAssign) are useful when having to make /// several multiplications modulo the same modulus. /// /// # mod_mul /// ``` /// use malachite_base::num::arithmetic::traits::ModMul; /// /// assert_eq!(2u8.mod_mul(3, 7), 6); /// assert_eq!(7u32.mod_mul(3, 10), 1); /// ``` /// /// # mod_mul_assign /// ``` /// use malachite_base::num::arithmetic::traits::ModMulAssign; /// /// let mut n = 2u8; /// n.mod_mul_assign(3, 7); /// assert_eq!(n, 6); /// /// let mut n = 7u32; /// n.mod_mul_assign(3, 10); /// assert_eq!(n, 1); /// ``` /// /// # mod_mul_precomputed /// ``` /// use malachite_base::num::arithmetic::traits::ModMulPrecomputed; /// /// let data = u32::precompute_mod_mul_data(&7); /// assert_eq!(2u32.mod_mul_precomputed(3, 7, &data), 6); /// assert_eq!(5u32.mod_mul_precomputed(3, 7, &data), 1); /// assert_eq!(4u32.mod_mul_precomputed(4, 7, &data), 2); /// /// let data = u64::precompute_mod_mul_data(&10); /// assert_eq!(7u64.mod_mul_precomputed(3, 10, &data), 1); /// assert_eq!(4u64.mod_mul_precomputed(9, 10, &data), 6); /// assert_eq!(5u64.mod_mul_precomputed(8, 10, &data), 0); /// /// let data = u8::precompute_mod_mul_data(&7); /// assert_eq!(2u8.mod_mul_precomputed(3, 7, &data), 6); /// assert_eq!(5u8.mod_mul_precomputed(3, 7, &data), 1); /// assert_eq!(4u8.mod_mul_precomputed(4, 7, &data), 2); /// /// let data = u16::precompute_mod_mul_data(&10); /// assert_eq!(7u16.mod_mul_precomputed(3, 10, &data), 1); /// assert_eq!(4u16.mod_mul_precomputed(9, 10, &data), 6); /// assert_eq!(5u16.mod_mul_precomputed(8, 10, &data), 0); /// /// let data = u128::precompute_mod_mul_data(&7); /// assert_eq!(2u128.mod_mul_precomputed(3, 7, &data), 6); /// assert_eq!(5u128.mod_mul_precomputed(3, 7, &data), 1); /// assert_eq!(4u128.mod_mul_precomputed(4, 7, &data), 2); /// /// let data = u128::precompute_mod_mul_data(&10); /// assert_eq!(7u128.mod_mul_precomputed(3, 10, &data), 1); /// assert_eq!(4u128.mod_mul_precomputed(9, 10, &data), 6); /// assert_eq!(5u128.mod_mul_precomputed(8, 10, &data), 0); /// ``` /// /// # mod_mul_precomputed_assign /// ``` /// use malachite_base::num::arithmetic::traits::{ModMulPrecomputed, ModMulPrecomputedAssign}; /// /// let data = u8::precompute_mod_mul_data(&7); /// /// let mut x = 2u8; /// x.mod_mul_precomputed_assign(3, 7, &data); /// assert_eq!(x, 6); /// /// let mut x = 5u8; /// x.mod_mul_precomputed_assign(3, 7, &data); /// assert_eq!(x, 1); /// /// let mut x = 4u8; /// x.mod_mul_precomputed_assign(4, 7, &data); /// assert_eq!(x, 2); /// /// let data = u32::precompute_mod_mul_data(&10); /// /// let mut x = 7u32; /// x.mod_mul_precomputed_assign(3, 10, &data); /// assert_eq!(x, 1); /// /// let mut x = 4u32; /// x.mod_mul_precomputed_assign(9, 10, &data); /// assert_eq!(x, 6); /// /// let mut x = 5u32; /// x.mod_mul_precomputed_assign(8, 10, &data); /// assert_eq!(x, 0); /// ``` pub mod mod_mul; /// [`ModNeg`](traits::ModNeg) and [`ModNegAssign`](traits::ModNegAssign), traits for negating a /// number modulo another number. /// /// # mod_neg /// ``` /// use malachite_base::num::arithmetic::traits::ModNeg; /// /// assert_eq!(0u8.mod_neg(5), 0); /// assert_eq!(7u32.mod_neg(10), 3); /// assert_eq!(100u16.mod_neg(101), 1); /// ``` /// /// # mod_neg_assign /// ``` /// use malachite_base::num::arithmetic::traits::ModNegAssign; /// /// let mut n = 0u8; /// n.mod_neg_assign(5); /// assert_eq!(n, 0); /// /// let mut n = 7u32; /// n.mod_neg_assign(10); /// assert_eq!(n, 3); /// /// let mut n = 100u16; /// n.mod_neg_assign(101); /// assert_eq!(n, 1); /// ``` pub mod mod_neg; /// Traits for finding the remainder of two numbers, subject to various rounding rules. /// /// These are the traits: /// /// | rounding | by value or reference | by mutable reference (assignment) | /// |-------------------|----------------------------|----------------------------------------| /// | towards $-\infty$ | [`Mod`](traits::Mod) | [`ModAssign`](traits::ModAssign) | /// | towards $\infty$ | [`CeilingMod`](traits::CeilingMod) | [`CeilingModAssign`](traits::CeilingModAssign) | /// | towards $\infty$ | [`NegMod`](traits::NegMod) | [`NegModAssign`](traits::NegModAssign) | /// /// [`CeilingMod`](traits::CeilingMod) and [`NegMod`](traits::NegMod) are similar. The difference is /// that [`CeilingMod`](traits::CeilingMod) returns a remainder less than or equal to 0, so that the /// usual relation $x = qy + r$ is satisfied, while [`NegMod`](traits::NegMod) returns a remainder /// greater than or equal to zero. This allows the remainder to have an unsigned type, but modifies /// the relation to $x = qy - r$. /// /// The [`Rem`](std::ops::Rem) trait in the standard library rounds towards 0. /// /// # mod_op /// ``` /// use malachite_base::num::arithmetic::traits::Mod; /// /// // 2 * 10 + 3 = 23 /// assert_eq!(23u8.mod_op(10), 3); /// /// // 9 * 5 + 0 = 45 /// assert_eq!(45u32.mod_op(5), 0); /// /// // 2 * 10 + 3 = 23 /// assert_eq!(23i8.mod_op(10), 3); /// /// // -3 * -10 + -7 = 23 /// assert_eq!(23i16.mod_op(-10), -7); /// /// // -3 * 10 + 7 = -23 /// assert_eq!((-23i32).mod_op(10), 7); /// /// // 2 * -10 + -3 = -23 /// assert_eq!((-23i64).mod_op(-10), -3); /// ``` /// /// # mod_assign /// ``` /// use malachite_base::num::arithmetic::traits::ModAssign; /// /// // 2 * 10 + 3 = 23 /// let mut x = 23u8; /// x.mod_assign(10); /// assert_eq!(x, 3); /// /// // 9 * 5 + 0 = 45 /// let mut x = 45u32; /// x.mod_assign(5); /// assert_eq!(x, 0); /// /// // 2 * 10 + 3 = 23 /// let mut x = 23i8; /// x.mod_assign(10); /// assert_eq!(x, 3); /// /// // -3 * -10 + -7 = 23 /// let mut x = 23i16; /// x.mod_assign(-10); /// assert_eq!(x, -7); /// /// // -3 * 10 + 7 = -23 /// let mut x = -23i32; /// x.mod_assign(10); /// assert_eq!(x, 7); /// /// // 2 * -10 + -3 = -23 /// let mut x = -23i64; /// x.mod_assign(-10); /// assert_eq!(x, -3); /// ``` /// /// # neg_mod /// ``` /// use malachite_base::num::arithmetic::traits::NegMod; /// /// // 3 * 10 - 7 = 23 /// assert_eq!(23u8.neg_mod(10), 7); /// /// // 9 * 5 + 0 = 45 /// assert_eq!(45u32.neg_mod(5), 0); /// ``` /// /// # neg_mod_assign /// ``` /// use malachite_base::num::arithmetic::traits::NegModAssign; /// /// // 3 * 10 - 7 = 23 /// let mut x = 23u8; /// x.neg_mod_assign(10); /// assert_eq!(x, 7); /// /// // 9 * 5 + 0 = 45 /// let mut x = 45u32; /// x.neg_mod_assign(5); /// assert_eq!(x, 0); /// ``` /// /// # ceiling_mod /// ``` /// use malachite_base::num::arithmetic::traits::CeilingMod; /// /// // 3 * 10 + -7 = 23 /// assert_eq!(23i8.ceiling_mod(10), -7); /// /// // -2 * -10 + 3 = 23 /// assert_eq!(23i16.ceiling_mod(-10), 3); /// /// // -2 * 10 + -3 = -23 /// assert_eq!((-23i32).ceiling_mod(10), -3); /// /// // 3 * -10 + 7 = -23 /// assert_eq!((-23i64).ceiling_mod(-10), 7); /// ``` /// /// # ceiling_mod_assign /// ``` /// use malachite_base::num::arithmetic::traits::CeilingModAssign; /// /// // 3 * 10 + -7 = 23 /// let mut x = 23i8; /// x.ceiling_mod_assign(10); /// assert_eq!(x, -7); /// /// // -2 * -10 + 3 = 23 /// let mut x = 23i16; /// x.ceiling_mod_assign(-10); /// assert_eq!(x, 3); /// /// // -2 * 10 + -3 = -23 /// let mut x = -23i32; /// x.ceiling_mod_assign(10); /// assert_eq!(x, -3); /// /// // 3 * -10 + 7 = -23 /// let mut x = -23i64; /// x.ceiling_mod_assign(-10); /// assert_eq!(x, 7); /// ``` pub mod mod_op; /// Traits for raising a number to a power modulo another number. /// /// The traits are [`ModPow`](traits::ModPow), [`ModPowAssign`](traits::ModPowAssign), and /// [`ModPowPrecomputed`](traits::ModPowPrecomputed). /// [`ModPowPrecomputed`](traits::ModPowPrecomputed) is useful when having to make several /// exponentiations modulo the same modulus. /// /// # mod_pow /// ``` /// use malachite_base::num::arithmetic::traits::ModPow; /// /// assert_eq!(4u16.mod_pow(13, 497), 445); /// assert_eq!(10u32.mod_pow(1000, 30), 10); /// ``` /// /// # mod_pow_assign /// ``` /// use malachite_base::num::arithmetic::traits::ModPowAssign; /// /// let mut n = 4u16; /// n.mod_pow_assign(13, 497); /// assert_eq!(n, 445); /// /// let mut n = 10u32; /// n.mod_pow_assign(1000, 30); /// assert_eq!(n, 10); /// ``` /// /// # mod_pow_precomputed /// ``` /// use malachite_base::num::arithmetic::traits::ModPowPrecomputed; /// /// let data = u32::precompute_mod_pow_data(&497); /// assert_eq!(4u32.mod_pow_precomputed(13, 497, &data), 445); /// assert_eq!(5u32.mod_pow_precomputed(3, 497, &data), 125); /// assert_eq!(4u32.mod_pow_precomputed(100, 497, &data), 116); /// /// let data = u64::precompute_mod_pow_data(&30); /// assert_eq!(10u64.mod_pow_precomputed(1000, 30, &data), 10); /// assert_eq!(4u64.mod_pow_precomputed(9, 30, &data), 4); /// assert_eq!(5u64.mod_pow_precomputed(8, 30, &data), 25); /// /// let data = u16::precompute_mod_pow_data(&497); /// assert_eq!(4u16.mod_pow_precomputed(13, 497, &data), 445); /// assert_eq!(5u16.mod_pow_precomputed(3, 497, &data), 125); /// assert_eq!(4u16.mod_pow_precomputed(100, 497, &data), 116); /// /// let data = u8::precompute_mod_pow_data(&30); /// assert_eq!(10u8.mod_pow_precomputed(1000, 30, &data), 10); /// assert_eq!(4u8.mod_pow_precomputed(9, 30, &data), 4); /// assert_eq!(5u8.mod_pow_precomputed(8, 30, &data), 25); /// /// let data = u128::precompute_mod_pow_data(&497); /// assert_eq!(4u128.mod_pow_precomputed(13, 497, &data), 445); /// assert_eq!(5u128.mod_pow_precomputed(3, 497, &data), 125); /// assert_eq!(4u128.mod_pow_precomputed(100, 497, &data), 116); /// /// let data = u128::precompute_mod_pow_data(&30); /// assert_eq!(10u128.mod_pow_precomputed(1000, 30, &data), 10); /// assert_eq!(4u128.mod_pow_precomputed(9, 30, &data), 4); /// assert_eq!(5u128.mod_pow_precomputed(8, 30, &data), 25); /// ``` /// /// # mod_pow_precomputed_assign /// ``` /// use malachite_base::num::arithmetic::traits::{ModPowPrecomputed, ModPowPrecomputedAssign}; /// /// let data = u32::precompute_mod_pow_data(&497); /// /// let mut x = 4u32; /// x.mod_pow_precomputed_assign(13, 497, &data); /// assert_eq!(x, 445); /// /// let mut x = 5u32; /// x.mod_pow_precomputed_assign(3, 497, &data); /// assert_eq!(x, 125); /// /// let mut x = 4u32; /// x.mod_pow_precomputed_assign(100, 497, &data); /// assert_eq!(x, 116); /// /// let data = u64::precompute_mod_pow_data(&30); /// /// let mut x = 10u64; /// x.mod_pow_precomputed_assign(1000, 30, &data); /// assert_eq!(x, 10); /// /// let mut x = 4u64; /// x.mod_pow_precomputed_assign(9, 30, &data); /// assert_eq!(x, 4); /// /// let mut x = 5u64; /// x.mod_pow_precomputed_assign(8, 30, &data); /// assert_eq!(x, 25); /// ``` pub mod mod_pow; /// Traits for finding the remainder of a number divided by $2^k$, subject to various rounding /// rules. /// /// These are the traits: /// /// | rounding | by value or reference | by mutable reference (assignment) | /// |----------|-----------------------|-----------------------------------| /// | towards $-\infty$ | [`ModPowerOf2`](traits::ModPowerOf2) | [`ModPowerOf2Assign`](traits::ModPowerOf2Assign) | /// | towards 0 | [`RemPowerOf2`](traits::RemPowerOf2) | [`RemPowerOf2Assign`](traits::RemPowerOf2Assign) | /// | towards $\infty$ | [`CeilingModPowerOf2`](traits::CeilingModPowerOf2) | [`CeilingModPowerOf2Assign`](traits::CeilingModPowerOf2Assign) | /// | towards $\infty$ | [`NegModPowerOf2`](traits::NegModPowerOf2) | [`NegModPowerOf2Assign`](traits::NegModPowerOf2Assign) | /// /// [`CeilingModPowerOf2`](traits::CeilingModPowerOf2) and /// [`NegModPowerOf2`](traits::NegModPowerOf2) are similar. The difference is that /// [`CeilingModPowerOf2`](traits::CeilingModPowerOf2) returns a remainder less than or equal to 0, /// so that the usual relation $x = q2^k + r$ is satisfied, while /// [`NegModPowerOf2`](traits::NegModPowerOf2) returns a remainder greater than or equal to zero. /// This allows the remainder to have an unsigned type, but modifies the relation to $x = q2^k - r$. /// /// # mod_power_of_2 /// ``` /// use malachite_base::num::arithmetic::traits::ModPowerOf2; /// /// // 1 * 2^8 + 4 = 260 /// assert_eq!(260u16.mod_power_of_2(8), 4); /// /// // 100 * 2^4 + 11 = 1611 /// assert_eq!(1611u32.mod_power_of_2(4), 11); /// /// // 1 * 2^8 + 4 = 260 /// assert_eq!(260i16.mod_power_of_2(8), 4); /// /// // -101 * 2^4 + 5 = -1611 /// assert_eq!((-1611i32).mod_power_of_2(4), 5); /// ``` /// /// # mod_power_of_2_assign /// ``` /// use malachite_base::num::arithmetic::traits::ModPowerOf2Assign; /// /// // 1 * 2^8 + 4 = 260 /// let mut x = 260u16; /// x.mod_power_of_2_assign(8); /// assert_eq!(x, 4); /// /// // 100 * 2^4 + 11 = 1611 /// let mut x = 1611u32; /// x.mod_power_of_2_assign(4); /// assert_eq!(x, 11); /// /// // 1 * 2^8 + 4 = 260 /// let mut x = 260i16; /// x.mod_power_of_2_assign(8); /// assert_eq!(x, 4); /// /// // -101 * 2^4 + 5 = -1611 /// let mut x = -1611i32; /// x.mod_power_of_2_assign(4); /// assert_eq!(x, 5); /// ``` /// /// # rem_power_of_2 /// ``` /// use malachite_base::num::arithmetic::traits::RemPowerOf2; /// /// // 1 * 2^8 + 4 = 260 /// assert_eq!(260u16.rem_power_of_2(8), 4); /// /// // 100 * 2^4 + 11 = 1611 /// assert_eq!(1611u32.rem_power_of_2(4), 11); /// /// // 1 * 2^8 + 4 = 260 /// assert_eq!(260i16.rem_power_of_2(8), 4); /// /// // -100 * 2^4 + -11 = -1611 /// assert_eq!((-1611i32).rem_power_of_2(4), -11); /// ``` /// /// # rem_power_of_2_assign /// ``` /// use malachite_base::num::arithmetic::traits::RemPowerOf2Assign; /// /// // 1 * 2^8 + 4 = 260 /// let mut x = 260u16; /// x.rem_power_of_2_assign(8); /// assert_eq!(x, 4); /// /// // 100 * 2^4 + 11 = 1611 /// let mut x = 1611u32; /// x.rem_power_of_2_assign(4); /// assert_eq!(x, 11); /// /// // 1 * 2^8 + 4 = 260 /// let mut x = 260i16; /// x.rem_power_of_2_assign(8); /// assert_eq!(x, 4); /// /// // -100 * 2^4 + -11 = -1611 /// let mut x = -1611i32; /// x.rem_power_of_2_assign(4); /// assert_eq!(x, -11); /// ``` /// /// # neg_mod_power_of_2 /// ``` /// use malachite_base::num::arithmetic::traits::NegModPowerOf2; /// /// // 2 * 2^8 - 252 = 260 /// assert_eq!(260u16.neg_mod_power_of_2(8), 252); /// /// // 101 * 2^4 - 5 = 1611 /// assert_eq!(1611u32.neg_mod_power_of_2(4), 5); /// ``` /// /// # neg_mod_power_of_2_assign /// ``` /// use malachite_base::num::arithmetic::traits::NegModPowerOf2Assign; /// /// // 2 * 2^8 - 252 = 260 /// let mut x = 260u16; /// x.neg_mod_power_of_2_assign(8); /// assert_eq!(x, 252); /// /// // 101 * 2^4 - 5 = 1611 /// let mut x = 1611u32; /// x.neg_mod_power_of_2_assign(4); /// assert_eq!(x, 5); /// ``` /// /// # ceiling_mod_power_of_2 /// ``` /// use malachite_base::num::arithmetic::traits::CeilingModPowerOf2; /// /// // 2 * 2^8 + -252 = 260 /// assert_eq!(260i16.ceiling_mod_power_of_2(8), -252); /// /// // -100 * 2^4 + -11 = -1611 /// assert_eq!((-1611i32).ceiling_mod_power_of_2(4), -11); /// ``` /// /// # ceiling_mod_power_of_2_assign /// ``` /// use malachite_base::num::arithmetic::traits::CeilingModPowerOf2Assign; /// /// // 2 * 2^8 + -252 = 260 /// let mut x = 260i16; /// x.ceiling_mod_power_of_2_assign(8); /// assert_eq!(x, -252); /// /// // -100 * 2^4 + -11 = -1611 /// let mut x = -1611i32; /// x.ceiling_mod_power_of_2_assign(4); /// assert_eq!(x, -11); /// ``` pub mod mod_power_of_2; /// [`ModPowerOf2Add`](traits::ModPowerOf2Add) and /// [`ModPowerOf2AddAssign`](traits::ModPowerOf2AddAssign), traits for adding two numbers modulo /// $2^k$. /// /// # mod_power_of_2_add /// ``` /// use malachite_base::num::arithmetic::traits::ModPowerOf2Add; /// /// assert_eq!(0u8.mod_power_of_2_add(2, 5), 2); /// assert_eq!(10u32.mod_power_of_2_add(14, 4), 8); /// ``` /// /// # mod_power_of_2_add_assign /// ``` /// use malachite_base::num::arithmetic::traits::ModPowerOf2AddAssign; /// /// let mut n = 0u8; /// n.mod_power_of_2_add_assign(2, 5); /// assert_eq!(n, 2); /// /// let mut n = 10u32; /// n.mod_power_of_2_add_assign(14, 4); /// assert_eq!(n, 8); /// ``` pub mod mod_power_of_2_add; /// [`ModPowerOf2Inverse`](traits::ModPowerOf2Inverse), a trait for finding the multiplicative /// inverse of a number modulo $2^k$. /// /// # mod_inverse /// ``` /// use malachite_base::num::arithmetic::traits::ModPowerOf2Inverse; /// /// assert_eq!(7u8.mod_power_of_2_inverse(4), Some(7)); /// assert_eq!(8u8.mod_power_of_2_inverse(4), None); /// assert_eq!(123u32.mod_power_of_2_inverse(7), Some(51)); /// ``` pub mod mod_power_of_2_inverse; /// [`ModPowerOf2IsReduced`](traits::ModPowerOf2IsReduced), a trait for checking whether a number is /// reduced modulo $2^k$. /// /// # mod_power_of_2_is_reduced /// ``` /// use malachite_base::num::arithmetic::traits::ModPowerOf2IsReduced; /// /// assert_eq!(0u8.mod_power_of_2_is_reduced(5), true); /// assert_eq!(100u64.mod_power_of_2_is_reduced(5), false); /// assert_eq!(100u16.mod_power_of_2_is_reduced(8), true); /// ``` pub mod mod_power_of_2_is_reduced; /// [`ModPowerOf2Mul`](traits::ModPowerOf2Mul) and /// [`ModPowerOf2MulAssign`](traits::ModPowerOf2MulAssign), traits for multiplying two numbers /// modulo $2^k$. /// /// # mod_power_of_2_mul /// ``` /// use malachite_base::num::arithmetic::traits::ModPowerOf2Mul; /// /// assert_eq!(3u8.mod_power_of_2_mul(2, 5), 6); /// assert_eq!(10u32.mod_power_of_2_mul(14, 4), 12); /// ``` /// /// # mod_power_of_2_mul_assign /// ``` /// use malachite_base::num::arithmetic::traits::ModPowerOf2MulAssign; /// /// let mut n = 3u8; /// n.mod_power_of_2_mul_assign(2, 5); /// assert_eq!(n, 6); /// /// let mut n = 10u32; /// n.mod_power_of_2_mul_assign(14, 4); /// assert_eq!(n, 12); /// ``` pub mod mod_power_of_2_mul; /// [`ModPowerOf2Neg`](traits::ModPowerOf2Neg) and /// [`ModPowerOf2NegAssign`](traits::ModPowerOf2NegAssign), traits for negating a number modulo /// $2^k$. /// /// # mod_power_of_2_neg /// ``` /// use malachite_base::num::arithmetic::traits::ModPowerOf2Neg; /// /// assert_eq!(0u8.mod_power_of_2_neg(5), 0); /// assert_eq!(10u32.mod_power_of_2_neg(4), 6); /// assert_eq!(100u16.mod_power_of_2_neg(8), 156); /// ``` /// /// # mod_power_of_2_neg_assign /// ``` /// use malachite_base::num::arithmetic::traits::ModPowerOf2NegAssign; /// /// let mut n = 0u8; /// n.mod_power_of_2_neg_assign(5); /// assert_eq!(n, 0); /// /// let mut n = 10u32; /// n.mod_power_of_2_neg_assign(4); /// assert_eq!(n, 6); /// /// let mut n = 100u16; /// n.mod_power_of_2_neg_assign(8); /// assert_eq!(n, 156); /// ``` pub mod mod_power_of_2_neg; /// [`ModPowerOf2Pow`](traits::ModPowerOf2Pow) and /// [`ModPowerOf2PowAssign`](traits::ModPowerOf2PowAssign), traits for raising a number to a power /// modulo $2^k$. /// /// # mod_power_of_2_pow /// ``` /// use malachite_base::num::arithmetic::traits::ModPowerOf2Pow; /// /// assert_eq!(5u8.mod_power_of_2_pow(13, 3), 5); /// assert_eq!(7u32.mod_power_of_2_pow(1000, 6), 1); /// ``` /// /// # mod_power_of_2_pow_assign /// ``` /// use malachite_base::num::arithmetic::traits::ModPowerOf2PowAssign; /// /// let mut n = 5u8; /// n.mod_power_of_2_pow_assign(13, 3); /// assert_eq!(n, 5); /// /// let mut n = 7u32; /// n.mod_power_of_2_pow_assign(1000, 6); /// assert_eq!(n, 1); /// ``` pub mod mod_power_of_2_pow; /// [`ModPowerOf2Shl`](traits::ModPowerOf2Shl) and /// [`ModPowerOf2ShlAssign`](traits::ModPowerOf2ShlAssign), traits for left-shifting a number modulo /// $2^k$. /// /// # mod_power_of_2_shl /// ``` /// use malachite_base::num::arithmetic::traits::ModPowerOf2Shl; /// /// assert_eq!(12u32.mod_power_of_2_shl(2u8, 5), 16); /// assert_eq!(10u8.mod_power_of_2_shl(100u64, 4), 0); /// /// assert_eq!(12u32.mod_power_of_2_shl(2i8, 5), 16); /// assert_eq!(10u8.mod_power_of_2_shl(-2i64, 4), 2); /// ``` /// /// # mod_power_of_2_shl_assign /// ``` /// use malachite_base::num::arithmetic::traits::ModPowerOf2ShlAssign; /// /// let mut n = 12u32; /// n.mod_power_of_2_shl_assign(2u8, 5); /// assert_eq!(n, 16); /// /// let mut n = 10u8; /// n.mod_power_of_2_shl_assign(100u64, 4); /// assert_eq!(n, 0); /// /// let mut n = 12u32; /// n.mod_power_of_2_shl_assign(2i8, 5); /// assert_eq!(n, 16); /// /// let mut n = 10u8; /// n.mod_power_of_2_shl_assign(-2i64, 4); /// assert_eq!(n, 2); /// ``` pub mod mod_power_of_2_shl; /// [`ModPowerOf2Shr`](traits::ModPowerOf2Shr) and /// [`ModPowerOf2ShrAssign`](traits::ModPowerOf2ShrAssign), traits for right-shifting a number /// modulo $2^k$. /// /// # mod_power_of_2_shr /// ``` /// use malachite_base::num::arithmetic::traits::ModPowerOf2Shr; /// /// assert_eq!(10u8.mod_power_of_2_shr(2i64, 4), 2); /// assert_eq!(12u32.mod_power_of_2_shr(-2i8, 5), 16); /// ``` /// /// # mod_power_of_2_shr_assign /// ``` /// use malachite_base::num::arithmetic::traits::ModPowerOf2ShrAssign; /// /// let mut n = 10u8; /// n.mod_power_of_2_shr_assign(2i64, 4); /// assert_eq!(n, 2); /// /// let mut n = 12u32; /// n.mod_power_of_2_shr_assign(-2i8, 5); /// assert_eq!(n, 16); /// ``` pub mod mod_power_of_2_shr; /// [`ModPowerOf2Square`](traits::ModPowerOf2Square) and /// [`ModPowerOf2SquareAssign`](traits::ModPowerOf2SquareAssign), traits for squaring a number /// modulo $2^k$. /// /// # mod_power_of_2_square /// ``` /// use malachite_base::num::arithmetic::traits::ModPowerOf2Square; /// /// assert_eq!(5u8.mod_power_of_2_square(3), 1); /// assert_eq!(100u32.mod_power_of_2_square(8), 16); /// ``` /// /// # mod_power_of_2_square_assign /// ``` /// use malachite_base::num::arithmetic::traits::ModPowerOf2SquareAssign; /// /// let mut n = 5u8; /// n.mod_power_of_2_square_assign(3); /// assert_eq!(n, 1); /// /// let mut n = 100u32; /// n.mod_power_of_2_square_assign(8); /// assert_eq!(n, 16); /// ``` pub mod mod_power_of_2_square; /// [`ModPowerOf2Sub`](traits::ModPowerOf2Sub) and /// [`ModPowerOf2SubAssign`](traits::ModPowerOf2SubAssign), traits for subtracting one number by /// another modulo $2^k$. /// /// # mod_power_of_2_sub /// ``` /// use malachite_base::num::arithmetic::traits::ModPowerOf2Sub; /// /// assert_eq!(5u8.mod_power_of_2_sub(2, 5), 3); /// assert_eq!(10u32.mod_power_of_2_sub(14, 4), 12); /// ``` /// /// # mod_power_of_2_sub_assign /// ``` /// use malachite_base::num::arithmetic::traits::ModPowerOf2SubAssign; /// /// let mut n = 5u8; /// n.mod_power_of_2_sub_assign(2, 5); /// assert_eq!(n, 3); /// /// let mut n = 10u32; /// n.mod_power_of_2_sub_assign(14, 4); /// assert_eq!(n, 12); /// ``` pub mod mod_power_of_2_sub; /// [`ModShl`](traits::ModShl) and [`ModShlAssign`](traits::ModShlAssign), traits for left-shifting /// a number modulo another number. /// /// # mod_shl /// ``` /// use malachite_base::num::arithmetic::traits::ModShl; /// /// assert_eq!(8u32.mod_shl(2u8, 10), 2); /// assert_eq!(10u8.mod_shl(100u64, 17), 7); /// /// assert_eq!(8u32.mod_shl(2i8, 10), 2); /// assert_eq!(10u8.mod_shl(-2i64, 15), 2); /// ``` /// /// # mod_shl_assign /// ``` /// use malachite_base::num::arithmetic::traits::ModShlAssign; /// /// let mut n = 8u32; /// n.mod_shl_assign(2u8, 10); /// assert_eq!(n, 2); /// /// let mut n = 10u8; /// n.mod_shl_assign(100u64, 17); /// assert_eq!(n, 7); /// /// let mut n = 8u32; /// n.mod_shl_assign(2i8, 10); /// assert_eq!(n, 2); /// /// let mut n = 10u8; /// n.mod_shl_assign(-2i64, 15); /// assert_eq!(n, 2); /// ``` pub mod mod_shl; /// [`ModShr`](traits::ModShr) and [`ModShrAssign`](traits::ModShrAssign), traits for right-shifting /// a number modulo another number. /// /// # mod_shr /// ``` /// use malachite_base::num::arithmetic::traits::ModShr; /// /// assert_eq!(10u8.mod_shr(2i64, 15), 2); /// assert_eq!(8u32.mod_shr(-2i8, 10), 2); /// ``` /// /// # mod_shr_assign /// ``` /// use malachite_base::num::arithmetic::traits::ModShrAssign; /// /// let mut n = 10u8; /// n.mod_shr_assign(2i64, 15); /// assert_eq!(n, 2); /// /// let mut n = 8u32; /// n.mod_shr_assign(-2i8, 10); /// assert_eq!(n, 2); /// ``` pub mod mod_shr; /// Traits for squaring a number modulo another number. /// /// The traits are [`ModSquare`](traits::ModSquare), [`ModSquareAssign`](traits::ModSquareAssign), /// and [`ModSquarePrecomputed`](traits::ModSquarePrecomputed). /// [`ModSquarePrecomputed`](traits::ModSquarePrecomputed) is useful when having to make several /// squarings modulo the same modulus. /// /// # mod_square /// ``` /// use malachite_base::num::arithmetic::traits::ModSquare; /// /// assert_eq!(2u8.mod_square(10), 4); /// assert_eq!(100u32.mod_square(497), 60); /// ``` /// /// # mod_square_assign /// ``` /// use malachite_base::num::arithmetic::traits::ModSquareAssign; /// /// let mut n = 2u8; /// n.mod_square_assign(10); /// assert_eq!(n, 4); /// /// let mut n = 100u32; /// n.mod_square_assign(497); /// assert_eq!(n, 60); /// ``` /// /// # mod_square_precomputed /// ``` /// use malachite_base::num::arithmetic::traits::{ModPowPrecomputed, ModSquarePrecomputed}; /// /// let data = u16::precompute_mod_pow_data(&497); /// assert_eq!(100u16.mod_square_precomputed(497, &data), 60); /// assert_eq!(200u16.mod_square_precomputed(497, &data), 240); /// assert_eq!(300u16.mod_square_precomputed(497, &data), 43); /// ``` /// /// # mod_square_precomputed_assign /// ``` /// use malachite_base::num::arithmetic::traits::{ModPowPrecomputed, ModSquarePrecomputedAssign}; /// /// let data = u32::precompute_mod_pow_data(&497); /// /// let mut x = 100u32; /// x.mod_square_precomputed_assign(497, &data); /// assert_eq!(x, 60); /// /// let mut x = 200u32; /// x.mod_square_precomputed_assign(497, &data); /// assert_eq!(x, 240); /// /// let mut x = 300u32; /// x.mod_square_precomputed_assign(497, &data); /// assert_eq!(x, 43); /// ``` pub mod mod_square; /// [`ModSub`](traits::ModSub) and [`ModSubAssign`](traits::ModSubAssign), traits for subtracting /// two numbers modulo another number. /// /// # mod_sub /// ``` /// use malachite_base::num::arithmetic::traits::ModSub; /// /// assert_eq!(4u8.mod_sub(3, 5), 1); /// assert_eq!(7u32.mod_sub(9, 10), 8); /// ``` /// /// # mod_sub_assign /// ``` /// use malachite_base::num::arithmetic::traits::ModSubAssign; /// /// let mut n = 4u8; /// n.mod_sub_assign(3, 5); /// assert_eq!(n, 1); /// /// let mut n = 7u32; /// n.mod_sub_assign(9, 10); /// assert_eq!(n, 8); /// ``` pub mod mod_sub; /// [`NegAssign`](traits::NegAssign), a trait for negating a number in place. /// /// # neg_assign /// ``` /// use malachite_base::num::arithmetic::traits::NegAssign; /// /// let mut x = 0i8; /// x.neg_assign(); /// assert_eq!(x, 0i8); /// /// let mut x = 100i64; /// x.neg_assign(); /// assert_eq!(x, -100i64); /// /// let mut x = -100i64; /// x.neg_assign(); /// assert_eq!(x, 100i64); /// /// let mut x = 1.2f32; /// x.neg_assign(); /// assert_eq!(x, -1.2f32); /// ``` pub mod neg; /// [`NextPowerOf2`](traits::NextPowerOf2) and [`NextPowerOf2Assign`](traits::NextPowerOf2Assign), /// traits for getting the next-highest power of 2. /// /// # next_power_of_2 /// ``` /// use malachite_base::num::arithmetic::traits::NextPowerOf2; /// /// assert_eq!(100.0f32.next_power_of_2(), 128.0); /// assert_eq!(0.01f32.next_power_of_2(), 0.015625); /// ``` /// /// # next_power_of_2_assign /// ``` /// use malachite_base::num::arithmetic::traits::NextPowerOf2Assign; /// /// let mut x = 0u8; /// x.next_power_of_2_assign(); /// assert_eq!(x, 1); /// /// let mut x = 4u16; /// x.next_power_of_2_assign(); /// assert_eq!(x, 4); /// /// let mut x = 10u32; /// x.next_power_of_2_assign(); /// assert_eq!(x, 16); /// /// let mut x = (1u64 << 40) - 5; /// x.next_power_of_2_assign(); /// assert_eq!(x, 1 << 40); /// /// let mut x = 100.0f32; /// x.next_power_of_2_assign(); /// assert_eq!(x, 128.0); /// /// let mut x = 0.01f32; /// x.next_power_of_2_assign(); /// assert_eq!(x, 0.015625); /// ``` pub mod next_power_of_2; /// [`OverflowingAbs`](traits::OverflowingAbs) and /// [`OverflowingAbsAssign`](traits::OverflowingAbsAssign), traits for taking the absolute value of /// a number and returning a boolean indicating whether an overflow occurred. /// /// # overflowing_abs_assign /// ``` /// use malachite_base::num::arithmetic::traits::OverflowingAbsAssign; /// /// let mut x = 0i8; /// assert_eq!(x.overflowing_abs_assign(), false); /// assert_eq!(x, 0); /// /// let mut x = 100i64; /// assert_eq!(x.overflowing_abs_assign(), false); /// assert_eq!(x, 100); /// /// let mut x = -100i64; /// assert_eq!(x.overflowing_abs_assign(), false); /// assert_eq!(x, 100); /// /// let mut x = -128i8; /// assert_eq!(x.overflowing_abs_assign(), true); /// assert_eq!(x, -128); /// ``` pub mod overflowing_abs; /// [`OverflowingAdd`](traits::OverflowingAdd) and /// [`OverflowingAddAssign`](traits::OverflowingAddAssign), traits for adding two numbers and /// returning a boolean indicating whether an overflow occurred. /// /// # overflowing_add_assign /// ``` /// use malachite_base::num::arithmetic::traits::OverflowingAddAssign; /// /// let mut x = 123u16; /// assert_eq!(x.overflowing_add_assign(456), false); /// assert_eq!(x, 579); /// /// let mut x = 123u8; /// assert_eq!(x.overflowing_add_assign(200), true); /// assert_eq!(x, 67); /// ``` pub mod overflowing_add; /// [`OverflowingAddMul`](traits::OverflowingAddMul) and /// [`OverflowingAddMulAssign`](traits::OverflowingAddMulAssign), traits for adding the product of /// two other numbers to a number and returning a boolean indicating whether an overflow occurred. /// /// # overflowing_add_mul /// ``` /// use malachite_base::num::arithmetic::traits::OverflowingAddMul; /// /// assert_eq!(2u8.overflowing_add_mul(3, 7), (23, false)); /// assert_eq!(2u8.overflowing_add_mul(20, 20), (146, true)); /// /// assert_eq!(127i8.overflowing_add_mul(-2, 100), (-73, false)); /// assert_eq!((-127i8).overflowing_add_mul(-2, 100), (-71, true)); /// ``` /// /// # overflowing_add_mul_assign /// ``` /// use malachite_base::num::arithmetic::traits::OverflowingAddMulAssign; /// /// let mut x = 2u8; /// assert_eq!(x.overflowing_add_mul_assign(3, 7), false); /// assert_eq!(x, 23); /// /// let mut x = 2u8; /// assert_eq!(x.overflowing_add_mul_assign(20, 20), true); /// assert_eq!(x, 146); /// /// let mut x = 127i8; /// assert_eq!(x.overflowing_add_mul_assign(-2, 100), false); /// assert_eq!(x, -73); /// /// let mut x = -127i8; /// assert_eq!(x.overflowing_add_mul_assign(-2, 100), true); /// assert_eq!(x, -71); /// ``` pub mod overflowing_add_mul; /// [`OverflowingDiv`](traits::OverflowingDiv) and /// [`OverflowingDivAssign`](traits::OverflowingDivAssign), traits for dividing two numbers and /// returning a boolean indicating whether an overflow occurred. /// /// # overflowing_div_assign /// ``` /// use malachite_base::num::arithmetic::traits::OverflowingDivAssign; /// /// let mut x = 100u16; /// assert_eq!(x.overflowing_div_assign(3), false); /// assert_eq!(x, 33); /// /// let mut x = -128i8; /// assert_eq!(x.overflowing_div_assign(-1), true); /// assert_eq!(x, -128); /// ``` pub mod overflowing_div; /// [`OverflowingMul`](traits::OverflowingMul) and /// [`OverflowingMulAssign`](traits::OverflowingMulAssign), traits for multiplying two numbers and /// returning a boolean indicating whether an overflow occurred. /// /// # overflowing_mul_assign /// ``` /// use malachite_base::num::arithmetic::traits::OverflowingMulAssign; /// /// let mut x = 123u16; /// assert_eq!(x.overflowing_mul_assign(456), false); /// assert_eq!(x, 56088); /// /// let mut x = 123u8; /// assert_eq!(x.overflowing_mul_assign(200), true); /// assert_eq!(x, 24); /// ``` pub mod overflowing_mul; /// [`OverflowingNeg`](traits::OverflowingNeg) and /// [`OverflowingNegAssign`](traits::OverflowingNegAssign), traits for negating a number and /// returning a boolean indicating whether an overflow occurred. /// /// # overflowing_neg_assign /// ``` /// use malachite_base::num::arithmetic::traits::OverflowingNegAssign; /// /// let mut x = 0i8; /// assert_eq!(x.overflowing_neg_assign(), false); /// assert_eq!(x, 0); /// /// let mut x = 100u64; /// assert_eq!(x.overflowing_neg_assign(), true); /// assert_eq!(x, 18446744073709551516); /// /// let mut x = -100i64; /// assert_eq!(x.overflowing_neg_assign(), false); /// assert_eq!(x, 100); /// /// let mut x = -128i8; /// assert_eq!(x.overflowing_neg_assign(), true); /// assert_eq!(x, -128); /// ``` pub mod overflowing_neg; /// [`OverflowingPow`](traits::OverflowingPow) and /// [`OverflowingPowAssign`](traits::OverflowingPowAssign), traits for raising a number to a power /// and returning a boolean indicating whether an overflow occurred. /// /// # overflowing_pow_assign /// ``` /// use malachite_base::num::arithmetic::traits::OverflowingPowAssign; /// /// let mut x = 3u8; /// assert_eq!(x.overflowing_pow_assign(3), false); /// assert_eq!(x, 27); /// /// let mut x = -10i32; /// assert_eq!(x.overflowing_pow_assign(9), false); /// assert_eq!(x, -1000000000); /// /// let mut x = -10i16; /// assert_eq!(x.overflowing_pow_assign(9), true); /// assert_eq!(x, 13824); /// ``` pub mod overflowing_pow; /// [`OverflowingSquare`](traits::OverflowingSquare) and /// [`OverflowingSquareAssign`](traits::OverflowingSquareAssign), traits for squaring a number and /// returning a boolean indicating whether an overflow occurred. /// /// # overflowing_square_assign /// ``` /// use malachite_base::num::arithmetic::traits::OverflowingSquareAssign; /// /// let mut x = 3u8; /// assert_eq!(x.overflowing_square_assign(), false); /// assert_eq!(x, 9); /// /// let mut x = -1000i32; /// assert_eq!(x.overflowing_square_assign(), false); /// assert_eq!(x, 1000000); /// /// let mut x = 1000u16; /// assert_eq!(x.overflowing_square_assign(), true); /// assert_eq!(x, 16960); /// ``` pub mod overflowing_square; /// [`OverflowingSub`](traits::OverflowingSub) and /// [`OverflowingSubAssign`](traits::OverflowingSubAssign), traits for subtracting two numbers and /// returning a boolean indicating whether an overflow occurred. /// /// # overflowing_sub /// ``` /// use malachite_base::num::arithmetic::traits::OverflowingSquare; /// /// assert_eq!(3u8.overflowing_square(), (9, false)); /// assert_eq!((-1000i32).overflowing_square(), (1000000, false)); /// assert_eq!(1000u16.overflowing_square(), (16960, true)); /// ``` /// /// # overflowing_sub_assign /// ``` /// use malachite_base::num::arithmetic::traits::OverflowingSubAssign; /// /// let mut x = 456u16; /// assert_eq!(x.overflowing_sub_assign(123), false); /// assert_eq!(x, 333); /// /// let mut x = 123u16; /// assert_eq!(x.overflowing_sub_assign(456), true); /// assert_eq!(x, 65203); /// ``` pub mod overflowing_sub; /// [`OverflowingSubMul`](traits::OverflowingSubMul) and /// [`OverflowingSubMulAssign`](traits::OverflowingSubMulAssign), traits for subtracting the product /// of two other numbers from a number and returning a boolean indicating whether an overflow /// occurred. /// /// # overflowing_sub_mul /// ``` /// use malachite_base::num::arithmetic::traits::OverflowingSubMul; /// /// assert_eq!(60u8.overflowing_sub_mul(5, 10), (10, false)); /// assert_eq!(2u8.overflowing_sub_mul(10, 5), (208, true)); /// /// assert_eq!(127i8.overflowing_sub_mul(2, 100), (-73, false)); /// assert_eq!((-127i8).overflowing_sub_mul(2, 100), (-71, true)); /// ``` /// /// # overflowing_sub_mul_assign /// ``` /// use malachite_base::num::arithmetic::traits::OverflowingSubMulAssign; /// /// let mut x = 60u8; /// assert_eq!(x.overflowing_sub_mul_assign(5, 10), false); /// assert_eq!(x, 10); /// /// let mut x = 2u8; /// assert_eq!(x.overflowing_sub_mul_assign(10, 5), true); /// assert_eq!(x, 208); /// /// let mut x = 127i8; /// assert_eq!(x.overflowing_sub_mul_assign(2, 100), false); /// assert_eq!(x, -73); /// /// let mut x = -127i8; /// assert_eq!(x.overflowing_sub_mul_assign(2, 100), true); /// assert_eq!(x, -71); /// ``` pub mod overflowing_sub_mul; /// [`Parity`](traits::Parity), a trait for determining whether a number is even or odd. /// /// # even /// ``` /// use malachite_base::num::arithmetic::traits::Parity; /// /// assert_eq!(0u8.even(), true); /// assert_eq!((-5i16).even(), false); /// assert_eq!(4u32.even(), true); /// ``` /// /// # odd /// ``` /// use malachite_base::num::arithmetic::traits::Parity; /// /// assert_eq!(0u8.odd(), false); /// assert_eq!((-5i16).odd(), true); /// assert_eq!(4u32.odd(), false); /// ``` pub mod parity; /// [`Pow`](traits::Pow) and [`PowAssign`](traits::PowAssign), traits for raising a number to a /// power. /// /// # pow_assign /// ``` /// use malachite_base::num::arithmetic::traits::PowAssign; /// /// let mut x = 3u8; /// x.pow_assign(3); /// assert_eq!(x, 27); /// /// let mut x = -10i32; /// x.pow_assign(9); /// assert_eq!(x, -1000000000); /// /// let mut x = 2.0f32; /// x.pow_assign(5); /// assert_eq!(x, 32.0); /// /// let mut x = 2.0f32; /// x.pow_assign(5.0); /// assert_eq!(x, 32.0); /// ``` pub mod pow; /// [`PowerOf2`](traits::PowerOf2), a trait for computing a power of 2. /// /// # power_of_2 /// ``` /// use malachite_base::num::arithmetic::traits::PowerOf2; /// /// assert_eq!(u16::power_of_2(0), 1); /// assert_eq!(u8::power_of_2(3), 8); /// assert_eq!(u64::power_of_2(40), 1 << 40); /// /// assert_eq!(i16::power_of_2(0), 1); /// assert_eq!(i8::power_of_2(3), 8); /// assert_eq!(i64::power_of_2(40), 1 << 40); /// /// assert_eq!(f32::power_of_2(0), 1.0); /// assert_eq!(f32::power_of_2(3), 8.0); /// assert_eq!(f32::power_of_2(-3), 0.125); /// ``` pub mod power_of_2; /// Traits for computing the primorial and the product of the first $n$ primes. There is a trait /// whose implementations panic if the result cannot be represented, and a checked trait whose /// implementations return `None` in that case: [`Primorial`](traits::Primorial) and /// [`CheckedPrimorial`](traits::CheckedPrimorial). /// /// # primorial /// ``` /// use malachite_base::num::arithmetic::traits::Primorial; /// /// assert_eq!(u8::primorial(0), 1); /// assert_eq!(u8::primorial(1), 1); /// assert_eq!(u8::primorial(2), 2); /// assert_eq!(u8::primorial(3), 6); /// assert_eq!(u8::primorial(4), 6); /// assert_eq!(u8::primorial(5), 30); /// assert_eq!(u32::primorial(20), 9699690); /// ``` /// /// # product_of_first_n_primes /// ``` /// use malachite_base::num::arithmetic::traits::Primorial; /// /// assert_eq!(u8::product_of_first_n_primes(0), 1); /// assert_eq!(u8::product_of_first_n_primes(1), 2); /// assert_eq!(u8::product_of_first_n_primes(2), 6); /// assert_eq!(u8::product_of_first_n_primes(3), 30); /// assert_eq!(u8::product_of_first_n_primes(4), 210); /// assert_eq!(u32::product_of_first_n_primes(9), 223092870); /// ``` /// /// # checked_primorial /// ``` /// use malachite_base::num::arithmetic::traits::CheckedPrimorial; /// /// assert_eq!(u8::checked_primorial(0), Some(1)); /// assert_eq!(u8::checked_primorial(1), Some(1)); /// assert_eq!(u8::checked_primorial(2), Some(2)); /// assert_eq!(u8::checked_primorial(3), Some(6)); /// assert_eq!(u8::checked_primorial(4), Some(6)); /// assert_eq!(u8::checked_primorial(5), Some(30)); /// /// assert_eq!(u8::checked_primorial(11), None); /// assert_eq!(u32::checked_primorial(20), Some(9699690)); /// assert_eq!(u32::checked_primorial(100), None); /// ``` /// /// # checked_product_of_first_n_primes /// ``` /// use malachite_base::num::arithmetic::traits::CheckedPrimorial; /// /// assert_eq!(u8::checked_product_of_first_n_primes(0), Some(1)); /// assert_eq!(u8::checked_product_of_first_n_primes(1), Some(2)); /// assert_eq!(u8::checked_product_of_first_n_primes(2), Some(6)); /// assert_eq!(u8::checked_product_of_first_n_primes(3), Some(30)); /// assert_eq!(u8::checked_product_of_first_n_primes(4), Some(210)); /// assert_eq!(u32::checked_product_of_first_n_primes(9), Some(223092870)); /// /// assert_eq!(u8::checked_product_of_first_n_primes(5), None); /// assert_eq!(u32::checked_product_of_first_n_primes(100), None); /// ``` pub mod primorial; /// [`Reciprocal`](traits::Reciprocal) and [`ReciprocalAssign`](traits::ReciprocalAssign), traits /// for computing the reciprocal (multiplicative inverse) of a number. /// /// # reciprocal /// ``` /// use malachite_base::num::arithmetic::traits::Reciprocal; /// /// assert_eq!(0.0f32.reciprocal(), f32::INFINITY); /// assert_eq!(1.5f32.reciprocal(), 0.6666667); /// ``` /// /// # reciprocal_assign /// ``` /// use malachite_base::num::arithmetic::traits::ReciprocalAssign; /// /// let mut x = 0.0f32; /// x.reciprocal_assign(); /// assert_eq!(x, f32::INFINITY); /// /// let mut x = 1.5f32; /// x.reciprocal_assign(); /// assert_eq!(x, 0.6666667); /// ``` pub mod reciprocal; /// Traits for taking the $n$th root of a number. /// /// The traits are [`FloorRoot`](traits::FloorRoot), [`FloorRootAssign`](traits::FloorRootAssign), /// [`CeilingRoot`](traits::CeilingRoot), [`CeilingRootAssign`](traits::CeilingRootAssign), /// [`CheckedRoot`](traits::CheckedRoot), [`RootRem`](traits::RootRem), and /// [`RootAssignRem`](traits::RootAssignRem). /// /// # floor_root /// ``` /// use malachite_base::num::arithmetic::traits::FloorRoot; /// /// assert_eq!(999u16.floor_root(3), 9); /// assert_eq!(1000u16.floor_root(3), 10); /// assert_eq!(1001u16.floor_root(3), 10); /// assert_eq!(100000000000i64.floor_root(5), 158); /// assert_eq!((-100000000000i64).floor_root(5), -159); /// ``` /// /// # floor_root_assign /// ``` /// use malachite_base::num::arithmetic::traits::FloorRootAssign; /// /// let mut x = 999u16; /// x.floor_root_assign(3); /// assert_eq!(x, 9); /// /// let mut x = 1000u16; /// x.floor_root_assign(3); /// assert_eq!(x, 10); /// /// let mut x = 1001u16; /// x.floor_root_assign(3); /// assert_eq!(x, 10); /// /// let mut x = 100000000000i64; /// x.floor_root_assign(5); /// assert_eq!(x, 158); /// /// let mut x = -100000000000i64; /// x.floor_root_assign(5); /// assert_eq!(x, -159); /// ``` /// /// # ceiling_root /// ``` /// use malachite_base::num::arithmetic::traits::CeilingRoot; /// /// assert_eq!(999u16.ceiling_root(3), 10); /// assert_eq!(1000u16.ceiling_root(3), 10); /// assert_eq!(1001u16.ceiling_root(3), 11); /// assert_eq!(100000000000i64.ceiling_root(5), 159); /// assert_eq!((-100000000000i64).ceiling_root(5), -158); /// ``` /// /// # ceiling_root_assign /// ``` /// use malachite_base::num::arithmetic::traits::CeilingRootAssign; /// /// let mut x = 999u16; /// x.ceiling_root_assign(3); /// assert_eq!(x, 10); /// /// let mut x = 1000u16; /// x.ceiling_root_assign(3); /// assert_eq!(x, 10); /// /// let mut x = 1001u16; /// x.ceiling_root_assign(3); /// assert_eq!(x, 11); /// /// let mut x = 100000000000i64; /// x.ceiling_root_assign(5); /// assert_eq!(x, 159); /// /// let mut x = -100000000000i64; /// x.ceiling_root_assign(5); /// assert_eq!(x, -158); /// ``` /// /// # checked_root /// ``` /// use malachite_base::num::arithmetic::traits::CheckedRoot; /// /// assert_eq!(999u16.checked_root(3), None); /// assert_eq!(1000u16.checked_root(3), Some(10)); /// assert_eq!(1001u16.checked_root(3), None); /// assert_eq!(100000000000i64.checked_root(5), None); /// assert_eq!((-100000000000i64).checked_root(5), None); /// assert_eq!(10000000000i64.checked_root(5), Some(100)); /// assert_eq!((-10000000000i64).checked_root(5), Some(-100)); /// ``` /// /// # root_rem /// ``` /// use malachite_base::num::arithmetic::traits::RootRem; /// /// assert_eq!(999u16.root_rem(3), (9, 270)); /// assert_eq!(1000u16.root_rem(3), (10, 0)); /// assert_eq!(1001u16.root_rem(3), (10, 1)); /// assert_eq!(100000000000u64.root_rem(5), (158, 1534195232)); /// ``` /// /// # root_assign_rem /// ``` /// use malachite_base::num::arithmetic::traits::RootAssignRem; /// /// let mut x = 999u16; /// assert_eq!(x.root_assign_rem(3), 270); /// assert_eq!(x, 9); /// /// let mut x = 1000u16; /// assert_eq!(x.root_assign_rem(3), 0); /// assert_eq!(x, 10); /// /// let mut x = 1001u16; /// assert_eq!(x.root_assign_rem(3), 1); /// assert_eq!(x, 10); /// /// let mut x = 100000000000u64; /// assert_eq!(x.root_assign_rem(5), 1534195232); /// assert_eq!(x, 158); /// ``` pub mod root; /// [`RotateLeft`](traits::RotateLeft), [`RotateLeftAssign`](traits::RotateLeftAssign), /// [`RotateRight`](traits::RotateRight), and [`RotateRightAssign`](traits::RotateRightAssign), /// traits for rotating a number's bits. /// /// # rotate_left_assign /// ``` /// use malachite_base::num::arithmetic::traits::RotateLeftAssign; /// /// let mut x: u32 = 0xabcd6789; /// x.rotate_left_assign(4); /// assert_eq!(x, 0xbcd6789a); /// /// x = 0xabcd6789; /// x.rotate_left_assign(32); /// assert_eq!(x, 0xabcd6789); /// /// x = 0xabcd6789; /// x.rotate_left_assign(36); /// assert_eq!(x, 0xbcd6789a); /// ``` /// /// # rotate_right_assign /// ``` /// use malachite_base::num::arithmetic::traits::RotateRightAssign; /// /// let mut x: u32 = 0xabcd6789; /// x.rotate_right_assign(4); /// assert_eq!(x, 0x9abcd678); /// /// x = 0xabcd6789; /// x.rotate_right_assign(32); /// assert_eq!(x, 0xabcd6789); /// /// x = 0xabcd6789; /// x.rotate_right_assign(36); /// assert_eq!(x, 0x9abcd678); /// ``` pub mod rotate; /// [`RoundToMultiple`](traits::RoundToMultiple) and /// [`RoundToMultipleAssign`](traits::RoundToMultipleAssign), traits for rounding a number to a /// multiple of another number. /// /// # round_to_multiple /// ``` /// use malachite_base::num::arithmetic::traits::RoundToMultiple; /// use malachite_base::rounding_modes::RoundingMode::*; /// use std::cmp::Ordering::*; /// /// assert_eq!(5u32.round_to_multiple(0, Down), (0, Less)); /// /// assert_eq!(10u8.round_to_multiple(4, Down), (8, Less)); /// assert_eq!(10u16.round_to_multiple(4, Up), (12, Greater)); /// assert_eq!(10u32.round_to_multiple(5, Exact), (10, Equal)); /// assert_eq!(10u64.round_to_multiple(3, Nearest), (9, Less)); /// assert_eq!(20u128.round_to_multiple(3, Nearest), (21, Greater)); /// assert_eq!(10usize.round_to_multiple(4, Nearest), (8, Less)); /// assert_eq!(14u8.round_to_multiple(4, Nearest), (16, Greater)); /// /// assert_eq!((-5i32).round_to_multiple(0, Down), (0, Greater)); /// /// assert_eq!((-10i8).round_to_multiple(4, Down), (-8, Greater)); /// assert_eq!((-10i16).round_to_multiple(4, Up), (-12, Less)); /// assert_eq!((-10i32).round_to_multiple(5, Exact), (-10, Equal)); /// assert_eq!((-10i64).round_to_multiple(3, Nearest), (-9, Greater)); /// assert_eq!((-20i128).round_to_multiple(3, Nearest), (-21, Less)); /// assert_eq!((-10isize).round_to_multiple(4, Nearest), (-8, Greater)); /// assert_eq!((-14i8).round_to_multiple(4, Nearest), (-16, Less)); /// /// assert_eq!((-10i16).round_to_multiple(-4, Down), (-8, Greater)); /// assert_eq!((-10i32).round_to_multiple(-4, Up), (-12, Less)); /// assert_eq!((-10i64).round_to_multiple(-5, Exact), (-10, Equal)); /// assert_eq!((-10i128).round_to_multiple(-3, Nearest), (-9, Greater)); /// assert_eq!((-20isize).round_to_multiple(-3, Nearest), (-21, Less)); /// assert_eq!((-10i8).round_to_multiple(-4, Nearest), (-8, Greater)); /// assert_eq!((-14i16).round_to_multiple(-4, Nearest), (-16, Less)); /// ``` /// /// # round_to_multiple_assign /// ``` /// use malachite_base::num::arithmetic::traits::RoundToMultipleAssign; /// use malachite_base::rounding_modes::RoundingMode::*; /// use std::cmp::Ordering::*; /// /// let mut x = 5u32; /// assert_eq!(x.round_to_multiple_assign(0, Down), Less); /// assert_eq!(x, 0); /// /// let mut x = 10u8; /// assert_eq!(x.round_to_multiple_assign(4, Down), Less); /// assert_eq!(x, 8); /// /// let mut x = 10u16; /// assert_eq!(x.round_to_multiple_assign(4, Up), Greater); /// assert_eq!(x, 12); /// /// let mut x = 10u32; /// assert_eq!(x.round_to_multiple_assign(5, Exact), Equal); /// assert_eq!(x, 10); /// /// let mut x = 10u64; /// assert_eq!(x.round_to_multiple_assign(3, Nearest), Less); /// assert_eq!(x, 9); /// /// let mut x = 20u128; /// assert_eq!(x.round_to_multiple_assign(3, Nearest), Greater); /// assert_eq!(x, 21); /// /// let mut x = 10usize; /// assert_eq!(x.round_to_multiple_assign(4, Nearest), Less); /// assert_eq!(x, 8); /// /// let mut x = 14u8; /// assert_eq!(x.round_to_multiple_assign(4, Nearest), Greater); /// assert_eq!(x, 16); /// /// let mut x = -5i32; /// assert_eq!(x.round_to_multiple_assign(0, Down), Greater); /// assert_eq!(x, 0); /// /// let mut x = -10i8; /// assert_eq!(x.round_to_multiple_assign(4, Down), Greater); /// assert_eq!(x, -8); /// /// let mut x = -10i16; /// assert_eq!(x.round_to_multiple_assign(4, Up), Less); /// assert_eq!(x, -12); /// /// let mut x = -10i32; /// assert_eq!(x.round_to_multiple_assign(5, Exact), Equal); /// assert_eq!(x, -10); /// /// let mut x = -10i64; /// assert_eq!(x.round_to_multiple_assign(3, Nearest), Greater); /// assert_eq!(x, -9); /// /// let mut x = -20i128; /// assert_eq!(x.round_to_multiple_assign(3, Nearest), Less); /// assert_eq!(x, -21); /// /// let mut x = -10isize; /// assert_eq!(x.round_to_multiple_assign(4, Nearest), Greater); /// assert_eq!(x, -8); /// /// let mut x = -14i8; /// assert_eq!(x.round_to_multiple_assign(4, Nearest), Less); /// assert_eq!(x, -16); /// /// let mut x = -10i16; /// assert_eq!(x.round_to_multiple_assign(-4, Down), Greater); /// assert_eq!(x, -8); /// /// let mut x = -10i32; /// assert_eq!(x.round_to_multiple_assign(-4, Up), Less); /// assert_eq!(x, -12); /// /// let mut x = -10i64; /// assert_eq!(x.round_to_multiple_assign(-5, Exact), Equal); /// assert_eq!(x, -10); /// /// let mut x = -10i128; /// assert_eq!(x.round_to_multiple_assign(-3, Nearest), Greater); /// assert_eq!(x, -9); /// /// let mut x = -20isize; /// assert_eq!(x.round_to_multiple_assign(-3, Nearest), Less); /// assert_eq!(x, -21); /// /// let mut x = -10i8; /// assert_eq!(x.round_to_multiple_assign(-4, Nearest), Greater); /// assert_eq!(x, -8); /// /// let mut x = -14i16; /// assert_eq!(x.round_to_multiple_assign(-4, Nearest), Less); /// assert_eq!(x, -16); /// ``` pub mod round_to_multiple; /// [`RoundToMultipleOfPowerOf2`](traits::RoundToMultipleOfPowerOf2) and /// [`RoundToMultipleOfPowerOf2Assign`](traits::RoundToMultipleOfPowerOf2Assign), traits for /// rounding a number to a multiple of a power of 2. /// /// # round_to_multiple_of_power_of_2 /// ``` /// use malachite_base::num::arithmetic::traits::RoundToMultipleOfPowerOf2; /// use malachite_base::rounding_modes::RoundingMode::*; /// use std::cmp::Ordering::*; /// /// assert_eq!(10u8.round_to_multiple_of_power_of_2(2, Floor), (8, Less)); /// assert_eq!( /// 10u8.round_to_multiple_of_power_of_2(2, Ceiling), /// (12, Greater) /// ); /// assert_eq!(10u8.round_to_multiple_of_power_of_2(2, Down), (8, Less)); /// assert_eq!(10u8.round_to_multiple_of_power_of_2(2, Up), (12, Greater)); /// assert_eq!(10u8.round_to_multiple_of_power_of_2(2, Nearest), (8, Less)); /// assert_eq!(12u8.round_to_multiple_of_power_of_2(2, Exact), (12, Equal)); /// /// assert_eq!( /// (-10i8).round_to_multiple_of_power_of_2(2, Floor), /// (-12, Less) /// ); /// assert_eq!( /// (-10i8).round_to_multiple_of_power_of_2(2, Ceiling), /// (-8, Greater) /// ); /// assert_eq!( /// (-10i8).round_to_multiple_of_power_of_2(2, Down), /// (-8, Greater) /// ); /// assert_eq!((-10i8).round_to_multiple_of_power_of_2(2, Up), (-12, Less)); /// assert_eq!( /// (-10i8).round_to_multiple_of_power_of_2(2, Nearest), /// (-8, Greater) /// ); /// assert_eq!( /// (-12i8).round_to_multiple_of_power_of_2(2, Exact), /// (-12, Equal) /// ); /// ``` /// /// # round_to_multiple_of_power_of_2_assign /// ``` /// use malachite_base::num::arithmetic::traits::RoundToMultipleOfPowerOf2Assign; /// use malachite_base::rounding_modes::RoundingMode::*; /// use std::cmp::Ordering::*; /// /// let mut x = 10u8; /// assert_eq!(x.round_to_multiple_of_power_of_2_assign(2, Floor), Less); /// assert_eq!(x, 8); /// /// let mut x = 10u8; /// assert_eq!( /// x.round_to_multiple_of_power_of_2_assign(2, Ceiling), /// Greater /// ); /// assert_eq!(x, 12); /// /// let mut x = 10u8; /// assert_eq!(x.round_to_multiple_of_power_of_2_assign(2, Down), Less); /// assert_eq!(x, 8); /// /// let mut x = 10u8; /// assert_eq!(x.round_to_multiple_of_power_of_2_assign(2, Up), Greater); /// assert_eq!(x, 12); /// /// let mut x = 10u8; /// assert_eq!(x.round_to_multiple_of_power_of_2_assign(2, Nearest), Less); /// assert_eq!(x, 8); /// /// let mut x = 12u8; /// assert_eq!(x.round_to_multiple_of_power_of_2_assign(2, Exact), Equal); /// assert_eq!(x, 12); /// /// let mut x = -10i8; /// assert_eq!(x.round_to_multiple_of_power_of_2_assign(2, Floor), Less); /// assert_eq!(x, -12); /// /// let mut x = -10i8; /// assert_eq!( /// x.round_to_multiple_of_power_of_2_assign(2, Ceiling), /// Greater /// ); /// assert_eq!(x, -8); /// /// let mut x = -10i8; /// assert_eq!(x.round_to_multiple_of_power_of_2_assign(2, Down), Greater); /// assert_eq!(x, -8); /// /// let mut x = -10i8; /// assert_eq!(x.round_to_multiple_of_power_of_2_assign(2, Up), Less); /// assert_eq!(x, -12); /// /// let mut x = -10i8; /// assert_eq!( /// x.round_to_multiple_of_power_of_2_assign(2, Nearest), /// Greater /// ); /// assert_eq!(x, -8); /// /// let mut x = -12i8; /// assert_eq!(x.round_to_multiple_of_power_of_2_assign(2, Exact), Equal); /// assert_eq!(x, -12); /// ``` pub mod round_to_multiple_of_power_of_2; /// [`SaturatingAbs`](traits::SaturatingAbs) and /// [`SaturatingAbsAssign`](traits::SaturatingAbsAssign), traits for taking the absolute value of a /// number and saturating at numeric bounds instead of overflowing. /// /// # saturating_abs_assign /// ``` /// use malachite_base::num::arithmetic::traits::SaturatingAbsAssign; /// /// let mut x = 0i8; /// x.saturating_abs_assign(); /// assert_eq!(x, 0); /// /// let mut x = 100i64; /// x.saturating_abs_assign(); /// assert_eq!(x, 100); /// /// let mut x = -100i64; /// x.saturating_abs_assign(); /// assert_eq!(x, 100); /// /// let mut x = -128i8; /// x.saturating_abs_assign(); /// assert_eq!(x, 127); /// ``` pub mod saturating_abs; /// [`SaturatingAdd`](traits::SaturatingAdd) and /// [`SaturatingAddAssign`](traits::SaturatingAddAssign), traits for adding two numbers and /// saturating at numeric bounds instead of overflowing. /// /// # saturating_add_assign /// ``` /// use malachite_base::num::arithmetic::traits::SaturatingAddAssign; /// /// let mut x = 123u16; /// x.saturating_add_assign(456); /// assert_eq!(x, 579); /// /// let mut x = 123u8; /// x.saturating_add_assign(200); /// assert_eq!(x, 255); /// ``` pub mod saturating_add; /// [`SaturatingAddMul`](traits::SaturatingAddMul) and /// [`SaturatingAddMulAssign`](traits::SaturatingAddMulAssign), traits for adding the product of two /// numbers to a number and saturating at numeric bounds instead of overflowing. /// /// # saturating_add_mul /// ``` /// use malachite_base::num::arithmetic::traits::SaturatingAddMul; /// /// assert_eq!(2u8.saturating_add_mul(3, 7), 23); /// assert_eq!(2u8.saturating_add_mul(20, 20), 255); /// /// assert_eq!(127i8.saturating_add_mul(-2, 100), -73); /// assert_eq!((-127i8).saturating_add_mul(-2, 100), -128); /// ``` /// /// # saturating_add_mul_assign /// ``` /// use malachite_base::num::arithmetic::traits::SaturatingAddMulAssign; /// /// let mut x = 2u8; /// x.saturating_add_mul_assign(3, 7); /// assert_eq!(x, 23); /// /// let mut x = 2u8; /// x.saturating_add_mul_assign(20, 20); /// assert_eq!(x, 255); /// /// let mut x = 127i8; /// x.saturating_add_mul_assign(-2, 100); /// assert_eq!(x, -73); /// /// let mut x = -127i8; /// x.saturating_add_mul_assign(-2, 100); /// assert_eq!(x, -128); /// ``` pub mod saturating_add_mul; /// [`SaturatingMul`](traits::SaturatingMul) and /// [`SaturatingMulAssign`](traits::SaturatingMulAssign), traits for multiplying two numbers and /// saturating at numeric bounds instead of overflowing. /// /// # saturating_mul_assign /// ``` /// use malachite_base::num::arithmetic::traits::SaturatingMulAssign; /// /// let mut x = 123u16; /// x.saturating_mul_assign(456); /// assert_eq!(x, 56088); /// /// let mut x = 123u8; /// x.saturating_mul_assign(200); /// assert_eq!(x, 255); /// ``` pub mod saturating_mul; /// [`SaturatingNeg`](traits::SaturatingNeg) and /// [`SaturatingNegAssign`](traits::SaturatingNegAssign), traits for negating a number and /// saturating at numeric bounds instead of overflowing. /// /// # saturating_neg_assign /// ``` /// use malachite_base::num::arithmetic::traits::SaturatingNegAssign; /// /// let mut x = 0i8; /// x.saturating_neg_assign(); /// assert_eq!(x, 0); /// /// let mut x = 100i64; /// x.saturating_neg_assign(); /// assert_eq!(x, -100); /// /// let mut x = -100i64; /// x.saturating_neg_assign(); /// assert_eq!(x, 100); /// /// let mut x = -128i8; /// x.saturating_neg_assign(); /// assert_eq!(x, 127); /// ``` pub mod saturating_neg; /// [`SaturatingPow`](traits::SaturatingPow) and /// [`SaturatingPowAssign`](traits::SaturatingPowAssign), traits for raising a number to a power and /// saturating at numeric bounds instead of overflowing. /// /// # saturating_pow_assign /// ``` /// use malachite_base::num::arithmetic::traits::SaturatingPowAssign; /// /// let mut x = 3u8; /// x.saturating_pow_assign(3); /// assert_eq!(x, 27); /// /// let mut x = -10i32; /// x.saturating_pow_assign(9); /// assert_eq!(x, -1000000000); /// /// let mut x = -10i16; /// x.saturating_pow_assign(9); /// assert_eq!(x, -32768); /// ``` pub mod saturating_pow; /// [`SaturatingSquare`](traits::SaturatingSquare) and /// [`SaturatingSquareAssign`](traits::SaturatingSquareAssign), traits for squaring a number and /// saturating at numeric bounds instead of overflowing. /// /// # saturating_square /// ``` /// use malachite_base::num::arithmetic::traits::SaturatingSquare; /// /// assert_eq!(3u8.saturating_square(), 9); /// assert_eq!((-1000i32).saturating_square(), 1000000); /// assert_eq!(1000u16.saturating_square(), u16::MAX); /// ``` /// /// # saturating_square_assign /// ``` /// use malachite_base::num::arithmetic::traits::SaturatingSquareAssign; /// /// let mut x = 3u8; /// x.saturating_square_assign(); /// assert_eq!(x, 9); /// /// let mut x = -1000i32; /// x.saturating_square_assign(); /// assert_eq!(x, 1000000); /// /// let mut x = 1000u16; /// x.saturating_square_assign(); /// assert_eq!(x, u16::MAX); /// ``` pub mod saturating_square; /// [`SaturatingSub`](traits::SaturatingSub) and /// [`SaturatingSubAssign`](traits::SaturatingSubAssign), traits for subtracting two numbers and /// saturating at numeric bounds instead of overflowing. /// /// # saturating_sub_assign /// ``` /// use malachite_base::num::arithmetic::traits::SaturatingSubAssign; /// /// let mut x = 456u16; /// x.saturating_sub_assign(123); /// assert_eq!(x, 333); /// /// let mut x = 123u16; /// x.saturating_sub_assign(456); /// assert_eq!(x, 0); /// ``` pub mod saturating_sub; /// [`SaturatingSubMul`](traits::SaturatingSubMul) and /// [`SaturatingSubMulAssign`](traits::SaturatingSubMulAssign), traits for subtracting a number by /// the product of two numbers and saturating at numeric bounds instead of overflowing. /// /// # saturating_sub_mul /// ``` /// use malachite_base::num::arithmetic::traits::SaturatingSubMul; /// /// assert_eq!(60u8.saturating_sub_mul(5, 10), 10); /// assert_eq!(2u8.saturating_sub_mul(10, 5), 0); /// /// assert_eq!(127i8.saturating_sub_mul(2, 100), -73); /// assert_eq!((-127i8).saturating_sub_mul(2, 100), -128); /// ``` /// /// # saturating_sub_mul_assign /// ``` /// use malachite_base::num::arithmetic::traits::SaturatingSubMulAssign; /// /// let mut x = 60u8; /// x.saturating_sub_mul_assign(5, 10); /// assert_eq!(x, 10); /// /// let mut x = 2u8; /// x.saturating_sub_mul_assign(10, 5); /// assert_eq!(x, 0); /// /// let mut x = 127i8; /// x.saturating_sub_mul_assign(2, 100); /// assert_eq!(x, -73); /// /// let mut x = -127i8; /// x.saturating_sub_mul_assign(2, 100); /// assert_eq!(x, -128); /// ``` pub mod saturating_sub_mul; /// [`ShlRound`](traits::ShlRound) and [`ShlRoundAssign`](traits::ShlRoundAssign), traits for /// multiplying a number by a power of 2 and rounding according to a specified /// [`RoundingMode`](crate::rounding_modes::RoundingMode). /// /// # shl_round /// ``` /// use malachite_base::num::arithmetic::traits::ShlRound; /// use malachite_base::rounding_modes::RoundingMode::*; /// use std::cmp::Ordering::*; /// /// assert_eq!(0x101u16.shl_round(-8i8, Down), (1, Less)); /// assert_eq!(0x101u32.shl_round(-8i16, Up), (2, Greater)); /// /// assert_eq!((-0x101i16).shl_round(-9i32, Down), (0, Greater)); /// assert_eq!((-0x101i32).shl_round(-9i64, Up), (-1, Less)); /// assert_eq!((-0x101i64).shl_round(-9i8, Nearest), (-1, Less)); /// assert_eq!((-0xffi32).shl_round(-9i16, Nearest), (0, Greater)); /// assert_eq!((-0x100i16).shl_round(-9i32, Nearest), (0, Greater)); /// /// assert_eq!(0x100u64.shl_round(-8i64, Exact), (1, Equal)); /// ``` /// /// # shl_round_assign /// ``` /// use malachite_base::num::arithmetic::traits::ShlRoundAssign; /// use malachite_base::rounding_modes::RoundingMode::*; /// use std::cmp::Ordering::*; /// /// let mut x = 0x101u16; /// assert_eq!(x.shl_round_assign(-8i8, Down), Less); /// assert_eq!(x, 1); /// /// let mut x = 0x101u32; /// assert_eq!(x.shl_round_assign(-8i16, Up), Greater); /// assert_eq!(x, 2); /// /// let mut x = -0x101i16; /// assert_eq!(x.shl_round_assign(-9i32, Down), Greater); /// assert_eq!(x, 0); /// /// let mut x = -0x101i32; /// assert_eq!(x.shl_round_assign(-9i64, Up), Less); /// assert_eq!(x, -1); /// /// let mut x = -0x101i64; /// assert_eq!(x.shl_round_assign(-9i8, Nearest), Less); /// assert_eq!(x, -1); /// /// let mut x = -0xffi32; /// assert_eq!(x.shl_round_assign(-9i16, Nearest), Greater); /// assert_eq!(x, 0); /// /// let mut x = -0x100i16; /// assert_eq!(x.shl_round_assign(-9i32, Nearest), Greater); /// assert_eq!(x, 0); /// /// let mut x = 0x100u64; /// assert_eq!(x.shl_round_assign(-8i64, Exact), Equal); /// assert_eq!(x, 1); /// ``` pub mod shl_round; /// [`ShrRound`](traits::ShrRound) and [`ShrRoundAssign`](traits::ShrRoundAssign), traits for /// dividing a number by a power of 2 and rounding according to a specified /// [`RoundingMode`](crate::rounding_modes::RoundingMode). /// /// # shr_round /// ``` /// use malachite_base::num::arithmetic::traits::ShrRound; /// use malachite_base::rounding_modes::RoundingMode::*; /// use std::cmp::Ordering::*; /// /// assert_eq!(0x101u32.shr_round(8u8, Down), (1, Less)); /// assert_eq!(0x101u16.shr_round(8u16, Up), (2, Greater)); /// /// assert_eq!(0x101u64.shr_round(9u32, Down), (0, Less)); /// assert_eq!(0x101u32.shr_round(9u64, Up), (1, Greater)); /// assert_eq!(0x101u16.shr_round(9u8, Nearest), (1, Greater)); /// assert_eq!(0xffu8.shr_round(9u16, Nearest), (0, Less)); /// assert_eq!(0x100u32.shr_round(9u32, Nearest), (0, Less)); /// /// assert_eq!(0x100u32.shr_round(8u64, Exact), (1, Equal)); /// /// assert_eq!(0x101i32.shr_round(8u8, Down), (1, Less)); /// assert_eq!(0x101i16.shr_round(8u16, Up), (2, Greater)); /// /// assert_eq!((-0x101i32).shr_round(9u32, Down), (0, Greater)); /// assert_eq!((-0x101i64).shr_round(9u64, Up), (-1, Less)); /// assert_eq!((-0x101i16).shr_round(9u8, Nearest), (-1, Less)); /// assert_eq!((-0xffi32).shr_round(9u16, Nearest), (0, Greater)); /// assert_eq!((-0x100i64).shr_round(9u32, Nearest), (0, Greater)); /// /// assert_eq!(0x100i32.shr_round(8u64, Exact), (1, Equal)); /// /// assert_eq!(0x101u32.shr_round(8i8, Down), (1, Less)); /// assert_eq!(0x101u16.shr_round(8i16, Up), (2, Greater)); /// /// assert_eq!((-0x101i32).shr_round(9i32, Down), (0, Greater)); /// assert_eq!((-0x101i64).shr_round(9i64, Up), (-1, Less)); /// assert_eq!((-0x101i16).shr_round(9i8, Nearest), (-1, Less)); /// assert_eq!((-0xffi32).shr_round(9i16, Nearest), (0, Greater)); /// assert_eq!((-0x100i64).shr_round(9i32, Nearest), (0, Greater)); /// /// assert_eq!(0x100u32.shr_round(8i64, Exact), (1, Equal)); /// ``` /// /// # shr_round_assign /// ``` /// use malachite_base::num::arithmetic::traits::ShrRoundAssign; /// use malachite_base::rounding_modes::RoundingMode::*; /// use std::cmp::Ordering::*; /// /// let mut x = 0x101u32; /// assert_eq!(x.shr_round_assign(8u8, Down), Less); /// assert_eq!(x, 1); /// /// let mut x = 0x101u16; /// assert_eq!(x.shr_round_assign(8u16, Up), Greater); /// assert_eq!(x, 2); /// /// let mut x = 0x101u64; /// assert_eq!(x.shr_round_assign(9u32, Down), Less); /// assert_eq!(x, 0); /// /// let mut x = 0x101u32; /// assert_eq!(x.shr_round_assign(9u64, Up), Greater); /// assert_eq!(x, 1); /// /// let mut x = 0x101u16; /// assert_eq!(x.shr_round_assign(9u8, Nearest), Greater); /// assert_eq!(x, 1); /// /// let mut x = 0xffu8; /// assert_eq!(x.shr_round_assign(9u16, Nearest), Less); /// assert_eq!(x, 0); /// /// let mut x = 0x100u32; /// assert_eq!(x.shr_round_assign(9u32, Nearest), Less); /// assert_eq!(x, 0); /// /// let mut x = 0x100u32; /// assert_eq!(x.shr_round_assign(8u64, Exact), Equal); /// assert_eq!(x, 1); /// /// let mut x = 0x101i32; /// assert_eq!(x.shr_round_assign(8u8, Down), Less); /// assert_eq!(x, 1); /// /// let mut x = 0x101i16; /// assert_eq!(x.shr_round_assign(8u16, Up), Greater); /// assert_eq!(x, 2); /// /// let mut x = -0x101i32; /// assert_eq!(x.shr_round_assign(9u32, Down), Greater); /// assert_eq!(x, 0); /// /// let mut x = -0x101i64; /// assert_eq!(x.shr_round_assign(9u64, Up), Less); /// assert_eq!(x, -1); /// /// let mut x = -0x101i16; /// assert_eq!(x.shr_round_assign(9u8, Nearest), Less); /// assert_eq!(x, -1); /// /// let mut x = -0xffi32; /// assert_eq!(x.shr_round_assign(9u16, Nearest), Greater); /// assert_eq!(x, 0); /// /// let mut x = -0x100i64; /// assert_eq!(x.shr_round_assign(9u32, Nearest), Greater); /// assert_eq!(x, 0); /// /// let mut x = 0x100u32; /// assert_eq!(x.shr_round_assign(8i64, Exact), Equal); /// assert_eq!(x, 1); /// /// let mut x = 0x101u32; /// assert_eq!(x.shr_round_assign(8i8, Down), Less); /// assert_eq!(x, 1); /// /// let mut x = 0x101u16; /// assert_eq!(x.shr_round_assign(8i16, Up), Greater); /// assert_eq!(x, 2); /// /// let mut x = -0x101i32; /// assert_eq!(x.shr_round_assign(9i32, Down), Greater); /// assert_eq!(x, 0); /// /// let mut x = -0x101i64; /// assert_eq!(x.shr_round_assign(9i64, Up), Less); /// assert_eq!(x, -1); /// /// let mut x = -0x101i16; /// assert_eq!(x.shr_round_assign(9i8, Nearest), Less); /// assert_eq!(x, -1); /// /// let mut x = -0xffi32; /// assert_eq!(x.shr_round_assign(9i16, Nearest), Greater); /// assert_eq!(x, 0); /// /// let mut x = -0x100i64; /// assert_eq!(x.shr_round_assign(9i32, Nearest), Greater); /// assert_eq!(x, 0); /// /// let mut x = 0x100u32; /// assert_eq!(x.shr_round_assign(8i64, Exact), Equal); /// assert_eq!(x, 1); /// ``` pub mod shr_round; /// [`Sign`](traits::Sign), a trait for determining the sign of a number. /// /// # sign /// ``` /// use malachite_base::num::arithmetic::traits::Sign; /// use malachite_base::num::basic::traits::NegativeInfinity; /// use std::cmp::Ordering::*; /// /// assert_eq!(0u8.sign(), Equal); /// assert_eq!(100u64.sign(), Greater); /// assert_eq!((-100i16).sign(), Less); /// /// assert_eq!(0.0.sign(), Greater); /// assert_eq!(1.0.sign(), Greater); /// assert_eq!(f64::INFINITY.sign(), Greater); /// /// assert_eq!((-0.0).sign(), Less); /// assert_eq!((-1.0).sign(), Less); /// assert_eq!(f64::NEGATIVE_INFINITY.sign(), Less); /// /// assert_eq!(f64::NAN.sign(), Equal); /// ``` pub mod sign; /// Traits for taking the square root of a number. /// /// The traits are [`FloorSqrt`](traits::FloorSqrt), [`FloorSqrtAssign`](traits::FloorSqrtAssign), /// [`CeilingSqrt`](traits::CeilingSqrt), [`CeilingSqrtAssign`](traits::CeilingSqrtAssign), /// [`CheckedSqrt`](traits::CheckedSqrt), [`SqrtRem`](traits::SqrtRem), /// [`SqrtAssignRem`](traits::SqrtAssignRem), and [`SqrtAssign`](traits::SqrtAssign). /// /// # floor_sqrt /// ``` /// use malachite_base::num::arithmetic::traits::FloorSqrt; /// /// assert_eq!(99u8.floor_sqrt(), 9); /// assert_eq!(100u8.floor_sqrt(), 10); /// assert_eq!(101u8.floor_sqrt(), 10); /// assert_eq!(1000000000i32.floor_sqrt(), 31622); /// assert_eq!(10000000000i64.floor_sqrt(), 100000); /// ``` /// /// # floor_sqrt_assign /// ``` /// use malachite_base::num::arithmetic::traits::FloorSqrtAssign; /// /// let mut x = 99u8; /// x.floor_sqrt_assign(); /// assert_eq!(x, 9); /// /// let mut x = 100u8; /// x.floor_sqrt_assign(); /// assert_eq!(x, 10); /// /// let mut x = 101u8; /// x.floor_sqrt_assign(); /// assert_eq!(x, 10); /// /// let mut x = 1000000000i32; /// x.floor_sqrt_assign(); /// assert_eq!(x, 31622); /// /// let mut x = 10000000000i64; /// x.floor_sqrt_assign(); /// assert_eq!(x, 100000); /// ``` /// /// # ceiling_sqrt /// ``` /// use malachite_base::num::arithmetic::traits::CeilingSqrt; /// /// assert_eq!(99u8.ceiling_sqrt(), 10); /// assert_eq!(100u8.ceiling_sqrt(), 10); /// assert_eq!(101u8.ceiling_sqrt(), 11); /// assert_eq!(1000000000u32.ceiling_sqrt(), 31623); /// assert_eq!(10000000000u64.ceiling_sqrt(), 100000); /// ``` /// /// # ceiling_sqrt_assign /// ``` /// use malachite_base::num::arithmetic::traits::CeilingSqrtAssign; /// /// let mut x = 99u8; /// x.ceiling_sqrt_assign(); /// assert_eq!(x, 10); /// /// let mut x = 100u8; /// x.ceiling_sqrt_assign(); /// assert_eq!(x, 10); /// /// let mut x = 101u8; /// x.ceiling_sqrt_assign(); /// assert_eq!(x, 11); /// /// let mut x = 1000000000i32; /// x.ceiling_sqrt_assign(); /// assert_eq!(x, 31623); /// /// let mut x = 10000000000i64; /// x.ceiling_sqrt_assign(); /// assert_eq!(x, 100000); /// ``` /// /// # checked_sqrt /// ``` /// use malachite_base::num::arithmetic::traits::CheckedSqrt; /// /// assert_eq!(99u8.checked_sqrt(), None); /// assert_eq!(100u8.checked_sqrt(), Some(10)); /// assert_eq!(101u8.checked_sqrt(), None); /// assert_eq!(1000000000i32.checked_sqrt(), None); /// assert_eq!(10000000000i64.checked_sqrt(), Some(100000)); /// ``` /// /// # sqrt_rem /// ``` /// use malachite_base::num::arithmetic::traits::SqrtRem; /// /// assert_eq!(99u8.sqrt_rem(), (9, 18)); /// assert_eq!(100u8.sqrt_rem(), (10, 0)); /// assert_eq!(101u8.sqrt_rem(), (10, 1)); /// assert_eq!(1000000000u32.sqrt_rem(), (31622, 49116)); /// assert_eq!(10000000000u64.sqrt_rem(), (100000, 0)); /// ``` /// /// # sqrt_assign_rem /// ``` /// use malachite_base::num::arithmetic::traits::SqrtAssignRem; /// /// let mut x = 99u8; /// assert_eq!(x.sqrt_assign_rem(), 18); /// assert_eq!(x, 9); /// /// let mut x = 100u8; /// assert_eq!(x.sqrt_assign_rem(), 0); /// assert_eq!(x, 10); /// /// let mut x = 101u8; /// assert_eq!(x.sqrt_assign_rem(), 1); /// assert_eq!(x, 10); /// /// let mut x = 1000000000u32; /// assert_eq!(x.sqrt_assign_rem(), 49116); /// assert_eq!(x, 31622); /// /// let mut x = 10000000000u64; /// assert_eq!(x.sqrt_assign_rem(), 0); /// assert_eq!(x, 100000); /// ``` /// /// # sqrt_assign /// ``` /// use malachite_base::num::arithmetic::traits::SqrtAssign; /// use malachite_base::num::float::NiceFloat; /// /// let mut x = 4.0f64; /// x.sqrt_assign(); /// assert_eq!(NiceFloat(x), NiceFloat(2.0)); /// /// let mut x = 2.0f64; /// x.sqrt_assign(); /// assert_eq!(NiceFloat(x), NiceFloat(std::f64::consts::SQRT_2)); /// ``` pub mod sqrt; /// [`Square`](traits::Square) and [`SquareAssign`](traits::SquareAssign), traits for squaring a /// number. /// /// # square /// ``` /// use malachite_base::num::arithmetic::traits::Square; /// /// assert_eq!(3u8.square(), 9); /// assert_eq!((-1000i32).square(), 1000000); /// assert_eq!(1.5f32.square(), 2.25); /// ``` /// /// # square_assign /// ``` /// use malachite_base::num::arithmetic::traits::SquareAssign; /// /// let mut x = 3u8; /// x.square_assign(); /// assert_eq!(x, 9); /// /// let mut x = -1000i32; /// x.square_assign(); /// assert_eq!(x, 1000000); /// /// let mut x = 1.5f32; /// x.square_assign(); /// assert_eq!(x, 2.25); /// ``` pub mod square; /// [`SubMul`](traits::SubMul) and [`SubMulAssign`](traits::SubMulAssign), traits for subtracting /// the product of two numbers from a number. /// /// # sub_mul /// ``` /// use malachite_base::num::arithmetic::traits::SubMul; /// /// assert_eq!(60u32.sub_mul(5, 10), 10); /// assert_eq!(127i8.sub_mul(2, 100), -73); /// assert_eq!(1.0f32.sub_mul(2.0, 3.0), -5.0); /// ``` /// /// # sub_mul_assign /// ``` /// use malachite_base::num::arithmetic::traits::SubMulAssign; /// /// let mut x = 60u32; /// x.sub_mul_assign(5, 10); /// assert_eq!(x, 10); /// /// let mut x = 127i8; /// x.sub_mul_assign(2, 100); /// assert_eq!(x, -73); /// /// let mut x = 1.0f32; /// x.sub_mul_assign(2.0, 3.0); /// assert_eq!(x, -5.0); /// ``` pub mod sub_mul; /// Various traits for performing arithmetic operations on numbers. pub mod traits; /// [`WrappingAbs`](traits::WrappingAbs) and [`WrappingAbsAssign`](traits::WrappingAbsAssign), /// traits for computing the absolute value of a number and wrapping at the boundary of the type. /// /// # wrapping_abs_assign /// ``` /// use malachite_base::num::arithmetic::traits::WrappingAbsAssign; /// /// let mut x = 0i8; /// x.wrapping_abs_assign(); /// assert_eq!(x, 0); /// /// let mut x = 100i64; /// x.wrapping_abs_assign(); /// assert_eq!(x, 100); /// /// let mut x = -100i64; /// x.wrapping_abs_assign(); /// assert_eq!(x, 100); /// /// let mut x = -128i8; /// x.wrapping_abs_assign(); /// assert_eq!(x, -128); /// ``` pub mod wrapping_abs; /// [`WrappingAdd`](traits::WrappingAdd) and [`WrappingAddAssign`](traits::WrappingAddAssign), /// traits for adding two numbers and wrapping at the boundary of the type. /// /// # wrapping_add_assign /// ``` /// use malachite_base::num::arithmetic::traits::WrappingAddAssign; /// /// let mut x = 123u16; /// x.wrapping_add_assign(456); /// assert_eq!(x, 579); /// /// let mut x = 123u8; /// x.wrapping_add_assign(200); /// assert_eq!(x, 67); /// ``` pub mod wrapping_add; /// [`WrappingAddMul`](traits::WrappingAddMul) and /// [`WrappingAddMulAssign`](traits::WrappingAddMulAssign), traits for adding the product of two /// numbers to a third and wrapping at the boundary of the type. /// /// # wrapping_add_mul /// ``` /// use malachite_base::num::arithmetic::traits::WrappingAddMul; /// /// assert_eq!(2u8.wrapping_add_mul(3, 7), 23); /// assert_eq!((-127i8).wrapping_add_mul(-2, 100), -71); /// ``` /// /// # wrapping_add_mul_assign /// ``` /// use malachite_base::num::arithmetic::traits::WrappingAddMulAssign; /// /// let mut x = 2u8; /// x.wrapping_add_mul_assign(3, 7); /// assert_eq!(x, 23); /// /// let mut x = -127i8; /// x.wrapping_add_mul_assign(-2, 100); /// assert_eq!(x, -71); /// ``` pub mod wrapping_add_mul; /// [`WrappingDiv`](traits::WrappingDiv) and [`WrappingDivAssign`](traits::WrappingDivAssign), /// traits for dividing two numbers and wrapping at the boundary of the type. /// /// # wrapping_div_assign /// ``` /// use malachite_base::num::arithmetic::traits::WrappingDivAssign; /// /// let mut x = 100u16; /// x.wrapping_div_assign(3); /// assert_eq!(x, 33); /// /// let mut x = -128i8; /// x.wrapping_div_assign(-1); /// assert_eq!(x, -128); /// ``` pub mod wrapping_div; /// [`WrappingMul`](traits::WrappingMul) and [`WrappingMulAssign`](traits::WrappingMulAssign), /// traits for multiplying two numbers and wrapping at the boundary of the type. /// /// # wrapping_mul_assign /// ``` /// use malachite_base::num::arithmetic::traits::WrappingMulAssign; /// /// let mut x = 123u16; /// x.wrapping_mul_assign(456); /// assert_eq!(x, 56088); /// /// let mut x = 123u8; /// x.wrapping_mul_assign(200); /// assert_eq!(x, 24); /// ``` pub mod wrapping_mul; /// [`WrappingNeg`](traits::WrappingNeg) and [`WrappingNegAssign`](traits::WrappingNegAssign) for /// negating a number and wrapping at the boundary of the type. /// /// # wrapping_neg_assign /// ``` /// use malachite_base::num::arithmetic::traits::WrappingNegAssign; /// /// let mut x = 0i8; /// x.wrapping_neg_assign(); /// assert_eq!(x, 0); /// /// let mut x = 100u64; /// x.wrapping_neg_assign(); /// assert_eq!(x, 18446744073709551516); /// /// let mut x = -100i64; /// x.wrapping_neg_assign(); /// assert_eq!(x, 100); /// /// let mut x = -128i8; /// x.wrapping_neg_assign(); /// assert_eq!(x, -128); /// ``` pub mod wrapping_neg; /// [`WrappingPow`](traits::WrappingPow) and [`WrappingPowAssign`](traits::WrappingPowAssign), /// traits for raising a number to a power and wrapping at the boundary of the type. /// /// # wrapping_pow_assign /// ``` /// use malachite_base::num::arithmetic::traits::WrappingPowAssign; /// /// let mut x = 3u8; /// x.wrapping_pow_assign(3); /// assert_eq!(x, 27); /// /// let mut x = -10i32; /// x.wrapping_pow_assign(9); /// assert_eq!(x, -1000000000); /// /// let mut x = -10i16; /// x.wrapping_pow_assign(9); /// assert_eq!(x, 13824); /// ``` pub mod wrapping_pow; /// [`WrappingSquare`](traits::WrappingSquare) and /// [`WrappingSquareAssign`](traits::WrappingAbsAssign), traits for squaring a number and wrapping /// at the boundary of the type. /// /// # wrapping_square /// ``` /// use malachite_base::num::arithmetic::traits::WrappingSquare; /// /// assert_eq!(3u8.wrapping_square(), 9); /// assert_eq!((-1000i32).wrapping_square(), 1000000); /// assert_eq!(1000u16.wrapping_square(), 16960); /// ``` /// /// # wrapping_square_assign /// ``` /// use malachite_base::num::arithmetic::traits::WrappingSquareAssign; /// /// let mut x = 3u8; /// x.wrapping_square_assign(); /// assert_eq!(x, 9); /// /// let mut x = -1000i32; /// x.wrapping_square_assign(); /// assert_eq!(x, 1000000); /// /// let mut x = 1000u16; /// x.wrapping_square_assign(); /// assert_eq!(x, 16960); /// ``` pub mod wrapping_square; /// [`WrappingSub`](traits::WrappingSub) and [`WrappingSubAssign`](traits::WrappingSubAssign), /// traits for subtracting two numbers and wrapping at the boundary of the type. /// /// # wrapping_sub_assign /// ``` /// use malachite_base::num::arithmetic::traits::WrappingSubAssign; /// /// let mut x = 456u16; /// x.wrapping_sub_assign(123); /// assert_eq!(x, 333); /// /// let mut x = 123u16; /// x.wrapping_sub_assign(456); /// assert_eq!(x, 65203); /// ``` pub mod wrapping_sub; /// [`WrappingSubMul`](traits::WrappingSubMul) and /// [`WrappingSubMulAssign`](traits::WrappingSubMulAssign), traits for subtracting a number by the /// product of two other numbers and wrapping at the boundary of the type. /// /// # wrapping_sub_mul /// ``` /// use malachite_base::num::arithmetic::traits::WrappingSubMul; /// /// assert_eq!(127i8.wrapping_sub_mul(2, 100), -73); /// assert_eq!((-127i8).wrapping_sub_mul(2, 100), -71); /// ``` /// /// # wrapping_sub_mul_assign /// ``` /// use malachite_base::num::arithmetic::traits::WrappingAddMulAssign; /// /// let mut x = 2u8; /// x.wrapping_add_mul_assign(3, 7); /// assert_eq!(x, 23); /// /// let mut x = -127i8; /// x.wrapping_add_mul_assign(-2, 100); /// assert_eq!(x, -71); /// ``` pub mod wrapping_sub_mul; /// [`XMulYToZZ`](traits::XMulYToZZ), a trait for multiplying two numbers and returning the result /// as a double-width number. /// /// # x_mul_y_to_zz /// ``` /// use malachite_base::num::arithmetic::traits::XMulYToZZ; /// /// assert_eq!(u64::x_mul_y_to_zz(15, 3), (0, 45)); /// assert_eq!(u8::x_mul_y_to_zz(0x78, 0x9a), (0x48, 0x30)); /// ``` pub mod x_mul_y_to_zz; /// [`XXAddYYToZZ`](traits::XXAddYYToZZ), a trait for adding two double-width numbers and returning /// the result as a double-width number. /// /// # xx_add_yy_to_zz /// ``` /// use malachite_base::num::arithmetic::traits::XXAddYYToZZ; /// /// assert_eq!(u64::xx_add_yy_to_zz(0x12, 0x34, 0x33, 0x33), (0x45, 0x67)); /// assert_eq!(u8::xx_add_yy_to_zz(0x78, 0x9a, 0xbc, 0xde), (0x35, 0x78)); /// ``` pub mod xx_add_yy_to_zz; /// [`XXDivModYToQR`](traits::XXDivModYToQR), a trait for dividing a double-width number by a /// single-width number and returning the quotient and remainder. /// /// # xx_div_mod_y_to_qr /// ``` /// use malachite_base::num::arithmetic::traits::XXDivModYToQR; /// /// assert_eq!( /// u64::xx_div_mod_y_to_qr(0x12, 0x34, 0x33), /// (0x5a5a5a5a5a5a5a5b, 0x13) /// ); /// assert_eq!(u8::xx_div_mod_y_to_qr(0x78, 0x9a, 0xbc), (0xa4, 0x2a)); /// ``` pub mod xx_div_mod_y_to_qr; /// [`XXSubYYToZZ`](traits::XXSubYYToZZ), a trait for subtracting two double-width numbers and /// returning the result as a double-width number. /// /// # xx_sub_yy_to_zz /// ``` /// use malachite_base::num::arithmetic::traits::XXSubYYToZZ; /// /// assert_eq!(u64::xx_sub_yy_to_zz(0x67, 0x89, 0x33, 0x33), (0x34, 0x56)); /// assert_eq!(u8::xx_sub_yy_to_zz(0x78, 0x9a, 0xbc, 0xde), (0xbb, 0xbc)); /// ``` pub mod xx_sub_yy_to_zz; /// [`XXXAddYYYToZZZ`](traits::XXXAddYYYToZZZ), a trait for adding two triple-width numbers and /// returning the result as a triple-width number. /// /// # xxx_add_yyy_to_zzz /// ``` /// use malachite_base::num::arithmetic::traits::XXXAddYYYToZZZ; /// /// assert_eq!( /// u64::xxx_add_yyy_to_zzz(0x12, 0x34, 0x56, 0x33, 0x33, 0x33), /// (0x45, 0x67, 0x89) /// ); /// assert_eq!( /// u8::xxx_add_yyy_to_zzz(0x78, 0x9a, 0xbc, 0xde, 0xfe, 0xdc), /// (0x57, 0x99, 0x98) /// ); /// ``` pub mod xxx_add_yyy_to_zzz; /// [`XXXSubYYYToZZZ`](traits::XXXSubYYYToZZZ), a trait for subtracting two triple-width numbers and /// returning the result as a triple-width number. /// /// # xxx_sub_yyy_to_zzz /// ``` /// use malachite_base::num::arithmetic::traits::XXXSubYYYToZZZ; /// /// assert_eq!( /// u64::xxx_sub_yyy_to_zzz(0x67, 0x89, 0xab, 0x33, 0x33, 0x33), /// (0x34, 0x56, 0x78) /// ); /// assert_eq!( /// u8::xxx_sub_yyy_to_zzz(0x78, 0x9a, 0xbc, 0xde, 0xfe, 0xdc), /// (0x99, 0x9b, 0xe0) /// ); /// ``` pub mod xxx_sub_yyy_to_zzz; /// [`XXXXAddYYYYToZZZZ`](traits::XXXXAddYYYYToZZZZ), a trait for adding two quadruple-width numbers /// and returning the result as a quadruple-width number. /// /// # xxxx_add_yyyy_to_zzzz /// ``` /// use malachite_base::num::arithmetic::traits::XXXXAddYYYYToZZZZ; /// /// assert_eq!( /// u64::xxxx_add_yyyy_to_zzzz(0x12, 0x34, 0x56, 0x78, 0x33, 0x33, 0x33, 0x33), /// (0x45, 0x67, 0x89, 0xab) /// ); /// assert_eq!( /// u8::xxxx_add_yyyy_to_zzzz(0x78, 0x9a, 0xbc, 0xde, 0xfe, 0xdc, 0xba, 0x98), /// (0x77, 0x77, 0x77, 0x76) /// ); /// ``` pub mod xxxx_add_yyyy_to_zzzz; malachite-base-0.4.16/src/num/arithmetic/mod_add.rs000064400000000000000000000057221046102023000202350ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // Uses code adopted from the FLINT Library. // // Copyright © 2010 William Hart // // Copyright © 2021 Fredrik Johansson // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{ModAdd, ModAddAssign}; use crate::num::basic::unsigneds::PrimitiveUnsigned; fn mod_add(x: T, y: T, m: T) -> T { assert!(x < m, "x must be reduced mod m, but {x} >= {m}"); assert!(y < m, "y must be reduced mod m, but {y} >= {m}"); let neg = m - x; if neg > y { x + y } else { y - neg } } fn mod_add_assign(x: &mut T, y: T, m: T) { assert!(*x < m, "x must be reduced mod m, but {x} >= {m}"); assert!(y < m, "y must be reduced mod m, but {y} >= {m}"); let neg = m - *x; if neg > y { *x += y; } else { *x = y - neg; } } macro_rules! impl_mod_add { ($t:ident) => { impl ModAdd<$t> for $t { type Output = $t; /// Adds two numbers modulo a third number $m$. The inputs must be already reduced /// modulo $m$. /// /// $f(x, y, m) = z$, where $x, y, z < m$ and $x + y \equiv z \mod m$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` or `other` are greater than or equal to `m`. /// /// # Examples /// See [here](super::mod_add#mod_add). /// /// This is equivalent to `nmod_add` from `nmod.h`, FLINT 2.7.1. #[inline] fn mod_add(self, other: $t, m: $t) -> $t { mod_add(self, other, m) } } impl ModAddAssign<$t> for $t { /// Adds two numbers modulo a third number $m$, in place. The inputs must be already /// reduced modulo $m$. /// /// $x \gets z$, where $x, y, z < m$ and $x + y \equiv z \mod m$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` or `other` are greater than or equal to `m`. /// /// # Examples /// See [here](super::mod_add#mod_add_assign). /// /// This is equivalent to `nmod_add` from `nmod.h`, FLINT 2.7.1, where the result is /// assigned to `a`. #[inline] fn mod_add_assign(&mut self, other: $t, m: $t) { mod_add_assign(self, other, m); } } }; } apply_to_unsigneds!(impl_mod_add); malachite-base-0.4.16/src/num/arithmetic/mod_inverse.rs000064400000000000000000000123641046102023000211600ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // Uses code adopted from the FLINT Library. // // Copyright © 2009, 2016 William Hart // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::ModInverse; use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::WrappingFrom; use crate::rounding_modes::RoundingMode::*; // This is a variation of `n_xgcd` from `ulong_extras/xgcd.c`, FLINT 2.7.1. pub_test! {mod_inverse_binary< U: WrappingFrom + PrimitiveUnsigned, S: PrimitiveSigned + WrappingFrom, >( x: U, m: U, ) -> Option { assert_ne!(x, U::ZERO); assert!(x < m, "x must be reduced mod m, but {x} >= {m}"); let mut u1 = S::ONE; let mut v2 = S::ONE; let mut u2 = S::ZERO; let mut v1 = S::ZERO; let mut u3 = m; let mut v3 = x; let mut d; let mut t2; let mut t1; if (m & x).get_highest_bit() { d = u3 - v3; t2 = v2; t1 = u2; u2 = u1 - u2; u1 = t1; u3 = v3; v2 = v1 - v2; v1 = t2; v3 = d; } while v3.get_bit(U::WIDTH - 2) { d = u3 - v3; if d < v3 { // quot = 1 t2 = v2; t1 = u2; u2 = u1 - u2; u1 = t1; u3 = v3; v2 = v1 - v2; v1 = t2; v3 = d; } else if d < (v3 << 1) { // quot = 2 t1 = u2; u2 = u1 - (u2 << 1); u1 = t1; u3 = v3; t2 = v2; v2 = v1 - (v2 << 1); v1 = t2; v3 = d - u3; } else { // quot = 3 t1 = u2; u2 = u1 - S::wrapping_from(3) * u2; u1 = t1; u3 = v3; t2 = v2; v2 = v1 - S::wrapping_from(3) * v2; v1 = t2; v3 = d - (u3 << 1); } } while v3 != U::ZERO { d = u3 - v3; // overflow not possible, top 2 bits of v3 not set if u3 < (v3 << 2) { if d < v3 { // quot = 1 t2 = v2; t1 = u2; u2 = u1 - u2; u1 = t1; u3 = v3; v2 = v1 - v2; v1 = t2; v3 = d; } else if d < (v3 << 1) { // quot = 2 t1 = u2; u2 = u1.wrapping_sub(u2 << 1); u1 = t1; u3 = v3; t2 = v2; v2 = v1.wrapping_sub(v2 << 1); v1 = t2; v3 = d - u3; } else { // quot = 3 t1 = u2; u2 = u1.wrapping_sub(S::wrapping_from(3).wrapping_mul(u2)); u1 = t1; u3 = v3; t2 = v2; v2 = v1.wrapping_sub(S::wrapping_from(3).wrapping_mul(v2)); v1 = t2; v3 = d.wrapping_sub(u3 << 1); } } else { let (quot, rem) = u3.div_rem(v3); t1 = u2; u2 = u1.wrapping_sub(S::wrapping_from(quot).wrapping_mul(u2)); u1 = t1; u3 = v3; t2 = v2; v2 = v1.wrapping_sub(S::wrapping_from(quot).wrapping_mul(v2)); v1 = t2; v3 = rem; } } if u3 != U::ONE { return None; } let mut inverse = U::wrapping_from(v1); if u1 <= S::ZERO { inverse.wrapping_sub_assign(m); } let limit = (m >> 1u32).wrapping_neg(); if inverse < limit { let k = (limit - inverse).div_round(m, Ceiling).0; inverse.wrapping_add_assign(m.wrapping_mul(k)); } Some(if inverse.get_highest_bit() { inverse.wrapping_add(m) } else { inverse }) }} macro_rules! impl_mod_inverse { ($u:ident, $s:ident) => { impl ModInverse<$u> for $u { type Output = $u; /// Computes the multiplicative inverse of a number modulo another number $m$. The input /// must be already reduced modulo $m$. /// /// Returns `None` if $x$ and $m$ are not coprime. /// /// $f(x, m) = y$, where $x, y < m$, $\gcd(x, y) = 1$, and $xy \equiv 1 \mod m$. /// /// # Worst-case complexity /// $T(n) = O(n^2)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is /// `max(self.significant_bits(), m.significant_bits())`. /// /// # Panics /// Panics if `self` is greater than or equal to `m`. /// /// # Examples /// See [here](super::mod_inverse#mod_inverse). #[inline] fn mod_inverse(self, m: $u) -> Option<$u> { mod_inverse_binary::<$u, $s>(self, m) } } }; } apply_to_unsigned_signed_pairs!(impl_mod_inverse); malachite-base-0.4.16/src/num/arithmetic/mod_is_reduced.rs000064400000000000000000000023251046102023000216070ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::ModIsReduced; macro_rules! impl_mod_is_reduced { ($t:ident) => { impl ModIsReduced for $t { /// Returns whether a number is reduced modulo another number $m$; in other words, /// whether it is less than $m$. $m$ cannot be zero. /// /// $f(x, m) = (x < m)$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if $m$ is 0. /// /// # Examples /// See [here](super::mod_is_reduced#mod_is_reduced). #[inline] fn mod_is_reduced(&self, m: &$t) -> bool { assert_ne!(*m, 0); self < m } } }; } apply_to_unsigneds!(impl_mod_is_reduced); malachite-base-0.4.16/src/num/arithmetic/mod_mul.rs000064400000000000000000000551231046102023000203020ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // Uses code adopted from the FLINT Library. // // Copyright © 1991, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2005 // Free Software Foundation, Inc. // // Copyright © 2006, 2007, 2008, 2009, 2010, 2015, 2016 William Hart // // Copyright © 2010, 2011, 2021 Fredrik Johansson // // Copyright © 2008, Peter Shrimpton // // Copyright © 2009, Tom Boothby // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{ ModMul, ModMulAssign, ModMulPrecomputed, ModMulPrecomputedAssign, Parity, PowerOf2, WrappingSubAssign, }; use crate::num::basic::integers::PrimitiveInt; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::{ExactFrom, HasHalf, JoinHalves, SplitInHalf, WrappingFrom}; use crate::num::logic::traits::LeadingZeros; pub_test! {naive_mod_mul(x: T, y: T, m: T) -> T { assert!(x < m, "x must be reduced mod m, but {x} >= {m}"); assert!(y < m, "y must be reduced mod m, but {y} >= {m}"); let (product_1, product_0) = T::x_mul_y_to_zz(x, y); T::xx_div_mod_y_to_qr(product_1, product_0, m).1 }} const INVERT_U32_TABLE_LOG_SIZE: u64 = 9; const INVERT_U32_TABLE_SIZE: usize = 1 << INVERT_U32_TABLE_LOG_SIZE; // INVERT_U32_TABLE[i] = floor((2^24 - 2^14 + 2^9) / (2^9 + i)) const INVERT_U32_TABLE: [u32; INVERT_U32_TABLE_SIZE] = [ 32737, 32673, 32609, 32546, 32483, 32420, 32357, 32295, 32233, 32171, 32109, 32048, 31987, 31926, 31865, 31805, 31744, 31684, 31625, 31565, 31506, 31447, 31388, 31329, 31271, 31212, 31154, 31097, 31039, 30982, 30924, 30868, 30811, 30754, 30698, 30642, 30586, 30530, 30475, 30419, 30364, 30309, 30255, 30200, 30146, 30092, 30038, 29984, 29930, 29877, 29824, 29771, 29718, 29666, 29613, 29561, 29509, 29457, 29405, 29354, 29303, 29251, 29200, 29150, 29099, 29049, 28998, 28948, 28898, 28849, 28799, 28750, 28700, 28651, 28602, 28554, 28505, 28457, 28409, 28360, 28313, 28265, 28217, 28170, 28123, 28075, 28029, 27982, 27935, 27889, 27842, 27796, 27750, 27704, 27658, 27613, 27568, 27522, 27477, 27432, 27387, 27343, 27298, 27254, 27209, 27165, 27121, 27078, 27034, 26990, 26947, 26904, 26861, 26818, 26775, 26732, 26690, 26647, 26605, 26563, 26521, 26479, 26437, 26395, 26354, 26312, 26271, 26230, 26189, 26148, 26108, 26067, 26026, 25986, 25946, 25906, 25866, 25826, 25786, 25747, 25707, 25668, 25628, 25589, 25550, 25511, 25473, 25434, 25395, 25357, 25319, 25281, 25242, 25205, 25167, 25129, 25091, 25054, 25016, 24979, 24942, 24905, 24868, 24831, 24794, 24758, 24721, 24685, 24649, 24612, 24576, 24540, 24504, 24469, 24433, 24397, 24362, 24327, 24291, 24256, 24221, 24186, 24151, 24117, 24082, 24047, 24013, 23979, 23944, 23910, 23876, 23842, 23808, 23774, 23741, 23707, 23674, 23640, 23607, 23574, 23541, 23508, 23475, 23442, 23409, 23377, 23344, 23312, 23279, 23247, 23215, 23183, 23151, 23119, 23087, 23055, 23023, 22992, 22960, 22929, 22898, 22866, 22835, 22804, 22773, 22742, 22711, 22681, 22650, 22619, 22589, 22559, 22528, 22498, 22468, 22438, 22408, 22378, 22348, 22318, 22289, 22259, 22229, 22200, 22171, 22141, 22112, 22083, 22054, 22025, 21996, 21967, 21938, 21910, 21881, 21853, 21824, 21796, 21767, 21739, 21711, 21683, 21655, 21627, 21599, 21571, 21544, 21516, 21488, 21461, 21433, 21406, 21379, 21352, 21324, 21297, 21270, 21243, 21216, 21190, 21163, 21136, 21110, 21083, 21056, 21030, 21004, 20977, 20951, 20925, 20899, 20873, 20847, 20821, 20795, 20769, 20744, 20718, 20693, 20667, 20642, 20616, 20591, 20566, 20540, 20515, 20490, 20465, 20440, 20415, 20390, 20366, 20341, 20316, 20292, 20267, 20243, 20218, 20194, 20170, 20145, 20121, 20097, 20073, 20049, 20025, 20001, 19977, 19953, 19930, 19906, 19882, 19859, 19835, 19812, 19789, 19765, 19742, 19719, 19696, 19672, 19649, 19626, 19603, 19581, 19558, 19535, 19512, 19489, 19467, 19444, 19422, 19399, 19377, 19354, 19332, 19310, 19288, 19265, 19243, 19221, 19199, 19177, 19155, 19133, 19112, 19090, 19068, 19046, 19025, 19003, 18982, 18960, 18939, 18917, 18896, 18875, 18854, 18832, 18811, 18790, 18769, 18748, 18727, 18706, 18686, 18665, 18644, 18623, 18603, 18582, 18561, 18541, 18520, 18500, 18479, 18459, 18439, 18419, 18398, 18378, 18358, 18338, 18318, 18298, 18278, 18258, 18238, 18218, 18199, 18179, 18159, 18139, 18120, 18100, 18081, 18061, 18042, 18022, 18003, 17984, 17964, 17945, 17926, 17907, 17888, 17869, 17850, 17831, 17812, 17793, 17774, 17755, 17736, 17718, 17699, 17680, 17662, 17643, 17624, 17606, 17587, 17569, 17551, 17532, 17514, 17496, 17477, 17459, 17441, 17423, 17405, 17387, 17369, 17351, 17333, 17315, 17297, 17279, 17261, 17244, 17226, 17208, 17191, 17173, 17155, 17138, 17120, 17103, 17085, 17068, 17051, 17033, 17016, 16999, 16982, 16964, 16947, 16930, 16913, 16896, 16879, 16862, 16845, 16828, 16811, 16794, 16778, 16761, 16744, 16727, 16711, 16694, 16677, 16661, 16644, 16628, 16611, 16595, 16578, 16562, 16546, 16529, 16513, 16497, 16481, 16464, 16448, 16432, 16416, 16400, 16384, ]; #[cfg(feature = "test_build")] pub fn test_invert_u32_table() { for (i, &x) in INVERT_U32_TABLE.iter().enumerate() { let value = (u32::power_of_2(24) - u32::power_of_2(14) + u32::power_of_2(9)) / (u32::power_of_2(9) + u32::exact_from(i)); assert_eq!( x, value, "INVERT_U32_TABLE gives incorrect value, {x}, for index {i}" ); } } // Computes // $$ // f(x) = \left \lfloor \frac{2^{64} - 2^{32}x - 1}{x} \right \rfloor = // \left \lfloor \frac{2^{64}-1}{x}-2^{32} \right \rfloor. // $$ // // The highest bit of `x` must be set. // // # Worst-case complexity // Constant time and additional memory. // // This is equivalent to `invert_limb` from `longlong.h`, FLINT 2.7.1, when `GMP_LIMB_BITS == 32`. pub_crate_test! {limbs_invert_limb_u32(x: u32) -> u32 { assert!(x.get_highest_bit()); let a = INVERT_U32_TABLE[usize::exact_from(x << 1 >> 23)]; let b = (a << 4) .wrapping_sub((u64::from(a * a) * u64::from((x >> 11) + 1)).upper_half()) .wrapping_sub(1); let mut c = b.wrapping_mul(x >> 1).wrapping_neg(); if x.odd() { c.wrapping_sub_assign(b.wrapping_sub(b >> 1)); } let d = (b << 15).wrapping_add((u64::from(b) * u64::from(c)).upper_half() >> 1); d.wrapping_sub( (u64::from(d) * u64::from(x)) .wrapping_add(u64::from(x)) .upper_half() .wrapping_add(x), ) }} const INVERT_U64_TABLE_LOG_SIZE: u64 = 8; const INVERT_U64_TABLE_SIZE: usize = 1 << INVERT_U64_TABLE_LOG_SIZE; // INVERT_U32_TABLE[i] = floor((2^19 - 3*2^8) / (2^8 + i)) const INVERT_U64_TABLE: [u64; INVERT_U64_TABLE_SIZE] = [ 2045, 2037, 2029, 2021, 2013, 2005, 1998, 1990, 1983, 1975, 1968, 1960, 1953, 1946, 1938, 1931, 1924, 1917, 1910, 1903, 1896, 1889, 1883, 1876, 1869, 1863, 1856, 1849, 1843, 1836, 1830, 1824, 1817, 1811, 1805, 1799, 1792, 1786, 1780, 1774, 1768, 1762, 1756, 1750, 1745, 1739, 1733, 1727, 1722, 1716, 1710, 1705, 1699, 1694, 1688, 1683, 1677, 1672, 1667, 1661, 1656, 1651, 1646, 1641, 1636, 1630, 1625, 1620, 1615, 1610, 1605, 1600, 1596, 1591, 1586, 1581, 1576, 1572, 1567, 1562, 1558, 1553, 1548, 1544, 1539, 1535, 1530, 1526, 1521, 1517, 1513, 1508, 1504, 1500, 1495, 1491, 1487, 1483, 1478, 1474, 1470, 1466, 1462, 1458, 1454, 1450, 1446, 1442, 1438, 1434, 1430, 1426, 1422, 1418, 1414, 1411, 1407, 1403, 1399, 1396, 1392, 1388, 1384, 1381, 1377, 1374, 1370, 1366, 1363, 1359, 1356, 1352, 1349, 1345, 1342, 1338, 1335, 1332, 1328, 1325, 1322, 1318, 1315, 1312, 1308, 1305, 1302, 1299, 1295, 1292, 1289, 1286, 1283, 1280, 1276, 1273, 1270, 1267, 1264, 1261, 1258, 1255, 1252, 1249, 1246, 1243, 1240, 1237, 1234, 1231, 1228, 1226, 1223, 1220, 1217, 1214, 1211, 1209, 1206, 1203, 1200, 1197, 1195, 1192, 1189, 1187, 1184, 1181, 1179, 1176, 1173, 1171, 1168, 1165, 1163, 1160, 1158, 1155, 1153, 1150, 1148, 1145, 1143, 1140, 1138, 1135, 1133, 1130, 1128, 1125, 1123, 1121, 1118, 1116, 1113, 1111, 1109, 1106, 1104, 1102, 1099, 1097, 1095, 1092, 1090, 1088, 1086, 1083, 1081, 1079, 1077, 1074, 1072, 1070, 1068, 1066, 1064, 1061, 1059, 1057, 1055, 1053, 1051, 1049, 1047, 1044, 1042, 1040, 1038, 1036, 1034, 1032, 1030, 1028, 1026, 1024, ]; /// Tests that `INVERT_U64_TABLE` is correct. #[cfg(feature = "test_build")] pub fn test_invert_u64_table() { for (i, &x) in INVERT_U64_TABLE.iter().enumerate() { let value = (u64::power_of_2(19) - 3 * u64::power_of_2(8)) / (u64::power_of_2(8) + u64::exact_from(i)); assert_eq!( x, value, "INVERT_U64_TABLE gives incorrect value, {x}, for index {i}" ); } } // Computes // $$ // f(x) = \left \lfloor \frac{2^{128} - 2^{64}x - 1}{x} \right \rfloor = // \left \lfloor \frac{2^{128}-1}{x}-2^{64} \right \rfloor. // $$ // // The highest bit of `x` must be set. // // # Worst-case complexity // Constant time and additional memory. // // This is equivalent to `invert_limb` from `longlong.h`, FLINT 2.7.1, when `GMP_LIMB_BITS == 64`. pub_crate_test! {limbs_invert_limb_u64(x: u64) -> u64 { assert!(x.get_highest_bit()); let a = (x >> 24) + 1; let b = INVERT_U64_TABLE[usize::exact_from(x << 1 >> 56)]; let c = (b << 11).wrapping_sub(((b * b).wrapping_mul(a) >> 40) + 1); let d = (c.wrapping_mul(u64::power_of_2(60).wrapping_sub(c.wrapping_mul(a))) >> 47) .wrapping_add(c << 13); let mut e = d.wrapping_mul(x >> 1).wrapping_neg(); if x.odd() { e.wrapping_sub_assign(d.wrapping_sub(d >> 1)); } let f = (d << 31).wrapping_add((u128::from(d) * u128::from(e)).upper_half() >> 1); f.wrapping_sub( (u128::from(f) * u128::from(x)) .wrapping_add(u128::from(x)) .upper_half() .wrapping_add(x), ) }} // This is equivalent to `n_ll_mod_preinv` from `ulong_extras/ll_mod_preinv.c`, FLINT 2.7.1. pub_test! {limbs_mod_preinverted< T: PrimitiveUnsigned, DT: From + HasHalf + JoinHalves + PrimitiveUnsigned + SplitInHalf, >( mut x_1: T, x_0: T, d: T, d_inv: T, ) -> T { assert_ne!(d, T::ZERO); let d_inv = DT::from(d_inv); let shift = LeadingZeros::leading_zeros(d); if shift == 0 { if x_1 >= d { x_1 -= d; } let (q_1, q_0) = (d_inv * DT::from(x_1)) .wrapping_add(DT::join_halves(x_1, x_0)) .split_in_half(); let mut r = x_0.wrapping_sub(q_1.wrapping_add(T::ONE).wrapping_mul(d)); if r > q_0 { r.wrapping_add_assign(d); } if r < d { r } else { r - d } } else { let mut d = d; if x_1 >= d { let y_1 = x_1 >> (T::WIDTH - shift); let y_0 = x_1 << shift; d <<= shift; let (q1, q0) = (d_inv * DT::from(y_1)) .wrapping_add(DT::join_halves(y_1, y_0)) .split_in_half(); x_1 = y_0.wrapping_sub(q1.wrapping_add(T::ONE).wrapping_mul(d)); if x_1 > q0 { x_1.wrapping_add_assign(d); } if x_1 >= d { x_1 -= d; } } else { d <<= shift; x_1 <<= shift; } let y_1 = x_1.wrapping_add(x_0 >> (T::WIDTH - shift)); let y_0 = x_0 << shift; let (q_1, q_0) = (d_inv * DT::from(y_1)) .wrapping_add(DT::join_halves(y_1, y_0)) .split_in_half(); let mut r = y_0.wrapping_sub(q_1.wrapping_add(T::ONE).wrapping_mul(d)); if r > q_0 { r.wrapping_add_assign(d); } if r < d { r >> shift } else { (r - d) >> shift } } }} // This is equivalent to `n_mulmod2_preinv` from `ulong_extras.h`, FLINT 2.7.1. pub_test! {fast_mod_mul< T: PrimitiveUnsigned, DT: From + HasHalf + JoinHalves + PrimitiveUnsigned + SplitInHalf, >( x: T, y: T, m: T, inv: T, ) -> T { assert!(x < m, "x must be reduced mod m, but {x} >= {m}"); assert!(y < m, "y must be reduced mod m, but {y} >= {m}"); let (product_1, product_0) = (DT::from(x) * DT::from(y)).split_in_half(); limbs_mod_preinverted::(product_1, product_0, m, inv) }} macro_rules! impl_mod_mul_precomputed_fast { ($t:ident, $dt:ident, $invert_limb:ident) => { impl ModMulPrecomputed<$t, $t> for $t { type Output = $t; type Data = $t; /// Precomputes data for modular multiplication. See `mod_mul_precomputed` and /// [`mod_mul_precomputed_assign`](super::traits::ModMulPrecomputedAssign). /// /// # Worst-case complexity /// Constant time and additional memory. /// /// This is equivalent to `n_preinvert_limb` from `ulong_extras.h`, FLINT 2.7.1. fn precompute_mod_mul_data(&m: &$t) -> $t { $invert_limb(m << LeadingZeros::leading_zeros(m)) } /// Multiplies two numbers modulo a third number $m$. The inputs must be already reduced /// modulo $m$. /// /// Some precomputed data is provided; this speeds up computations involving several /// modular multiplications with the same modulus. The precomputed data should be /// obtained using /// [`precompute_mod_mul_data`](ModMulPrecomputed::precompute_mod_mul_data). /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` or `other` are greater than or equal to `m`. /// /// # Examples /// See [here](super::mod_mul#mod_mul_precomputed). /// /// This is equivalent to `n_mulmod2_preinv` from `ulong_extras.h`, FLINT 2.7.1. fn mod_mul_precomputed(self, other: $t, m: $t, data: &$t) -> $t { fast_mod_mul::<$t, $dt>(self, other, m, *data) } } }; } impl_mod_mul_precomputed_fast!(u32, u64, limbs_invert_limb_u32); impl_mod_mul_precomputed_fast!(u64, u128, limbs_invert_limb_u64); macro_rules! impl_mod_mul_precomputed_promoted { ($t:ident) => { impl ModMulPrecomputed<$t, $t> for $t { type Output = $t; type Data = u32; /// Precomputes data for modular multiplication. See `mod_mul_precomputed` and /// [`mod_mul_precomputed_assign`](super::traits::ModMulPrecomputedAssign). /// /// # Worst-case complexity /// Constant time and additional memory. /// /// This is equivalent to `n_preinvert_limb` from `ulong_extras.h`, FLINT 2.7.1. fn precompute_mod_mul_data(&m: &$t) -> u32 { u32::precompute_mod_mul_data(&u32::from(m)) } /// Multiplies two numbers modulo a third number $m$. The inputs must be already reduced /// modulo $m$. /// /// Some precomputed data is provided; this speeds up computations involving several /// modular multiplications with the same modulus. The precomputed data should be /// obtained using /// [`precompute_mod_mul_data`](ModMulPrecomputed::precompute_mod_mul_data). /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` or `other` are greater than or equal to `m`. /// /// # Examples /// See [here](super::mod_mul#mod_mul_precomputed). /// /// This is equivalent to `n_mulmod2_preinv` from `ulong_extras.h`, FLINT 2.7.1. fn mod_mul_precomputed(self, other: $t, m: $t, data: &u32) -> $t { $t::wrapping_from(u32::from(self).mod_mul_precomputed( u32::from(other), u32::from(m), data, )) } } }; } impl_mod_mul_precomputed_promoted!(u8); impl_mod_mul_precomputed_promoted!(u16); impl ModMulPrecomputed for u128 { type Output = u128; type Data = (); /// Precomputes data for modular multiplication. See `mod_mul_precomputed` and /// [`mod_mul_precomputed_assign`](super::traits::ModMulPrecomputedAssign). /// /// # Worst-case complexity /// Constant time and additional memory. fn precompute_mod_mul_data(_m: &u128) {} /// Multiplies two numbers modulo a third number $m$. The inputs must be already reduced modulo /// $m$. /// /// Some precomputed data is provided; this speeds up computations involving several modular /// multiplications with the same modulus. The precomputed data should be obtained using /// [`precompute_mod_mul_data`](ModMulPrecomputed::precompute_mod_mul_data). /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` or `other` are greater than or equal to `m`. /// /// # Examples /// See [here](super::mod_mul#mod_mul_precomputed). /// /// This is equivalent to `n_mulmod2_preinv` from `ulong_extras.h`, FLINT 2.7.1. #[inline] fn mod_mul_precomputed(self, other: u128, m: u128, _data: &()) -> u128 { naive_mod_mul(self, other, m) } } impl ModMulPrecomputed for usize { type Output = usize; type Data = usize; /// Precomputes data for modular multiplication. See `mod_mul_precomputed` and /// [`mod_mul_precomputed_assign`](super::traits::ModMulPrecomputedAssign). /// /// # Worst-case complexity /// Constant time and additional memory. /// /// This is equivalent to `n_preinvert_limb` from `ulong_extras.h`, FLINT 2.7.1. fn precompute_mod_mul_data(&m: &usize) -> usize { if usize::WIDTH == u32::WIDTH { usize::wrapping_from(u32::precompute_mod_mul_data(&u32::wrapping_from(m))) } else { usize::wrapping_from(u64::precompute_mod_mul_data(&u64::wrapping_from(m))) } } /// Multiplies two numbers modulo a third number $m$. The inputs must be already reduced modulo /// $m$. /// /// Some precomputed data is provided; this speeds up computations involving several modular /// multiplications with the same modulus. The precomputed data should be obtained using /// `precompute_mod_mul_data`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` or `other` are greater than or equal to `m`. /// /// # Examples /// See [here](super::mod_mul#mod_mul_precomputed). /// /// This is equivalent to `n_mulmod2_preinv` from `ulong_extras.h`, FLINT 2.7.1. fn mod_mul_precomputed(self, other: usize, m: usize, data: &usize) -> usize { if usize::WIDTH == u32::WIDTH { usize::wrapping_from(u32::wrapping_from(self).mod_mul_precomputed( u32::wrapping_from(other), u32::wrapping_from(m), &u32::wrapping_from(*data), )) } else { usize::wrapping_from(u64::wrapping_from(self).mod_mul_precomputed( u64::wrapping_from(other), u64::wrapping_from(m), &u64::wrapping_from(*data), )) } } } macro_rules! impl_mod_mul { ($t:ident) => { impl ModMulPrecomputedAssign<$t, $t> for $t { /// Multiplies two numbers modulo a third number $m$, in place. The inputs must be /// already reduced modulo $m$. /// /// Some precomputed data is provided; this speeds up computations involving several /// modular multiplications with the same modulus. The precomputed data should be /// obtained using /// [`precompute_mod_mul_data`](ModMulPrecomputed::precompute_mod_mul_data). /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` or `other` are greater than or equal to `m`. /// /// # Examples /// See [here](super::mod_mul#mod_mul_precomputed_assign). /// /// This is equivalent to `n_mulmod2_preinv` from `ulong_extras.h`, FLINT 2.7.1, where /// the return value is assigned to `a`. #[inline] fn mod_mul_precomputed_assign(&mut self, other: $t, m: $t, data: &Self::Data) { *self = self.mod_mul_precomputed(other, m, data); } } impl ModMul<$t> for $t { type Output = $t; /// Multiplies two numbers modulo a third number $m$. The inputs must be already reduced /// modulo $m$. /// /// $f(x, y, m) = z$, where $x, y, z < m$ and $xy \equiv z \mod m$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` or `other` are greater than or equal to `m`. /// /// # Examples /// See [here](super::mod_mul#mod_mul). /// /// This is equivalent to `nmod_mul` from `nmod.h`, FLINT 2.7.1. #[inline] fn mod_mul(self, other: $t, m: $t) -> $t { naive_mod_mul(self, other, m) } } impl ModMulAssign<$t> for $t { /// Multiplies two numbers modulo a third number $m$, in place. The inputs must be /// already reduced modulo $m$. /// /// $x \gets z$, where $x, y, z < m$ and $xy \equiv z \mod m$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::mod_mul#mod_mul_assign). /// /// # Panics /// Panics if `self` or `other` are greater than or equal to `m`. /// /// This is equivalent to `nmod_mul` from `nmod.h`, FLINT 2.7.1, where the result is /// assigned to `a`. #[inline] fn mod_mul_assign(&mut self, other: $t, m: $t) { *self = naive_mod_mul(*self, other, m); } } }; } apply_to_unsigneds!(impl_mod_mul); malachite-base-0.4.16/src/num/arithmetic/mod_neg.rs000064400000000000000000000047351046102023000202610ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // Uses code adopted from the FLINT Library. // // Copyright © 2010 William Hart // // Copyright © 2021 Fredrik Johansson // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{ModNeg, ModNegAssign}; use crate::num::basic::unsigneds::PrimitiveUnsigned; fn mod_neg(x: T, m: T) -> T { assert!(x < m, "x must be reduced mod m, but {x} >= {m}"); if x == T::ZERO { T::ZERO } else { m - x } } fn mod_neg_assign(x: &mut T, m: T) { assert!(*x < m, "x must be reduced mod m, but {x} >= {m}"); if *x != T::ZERO { *x = m - *x; } } macro_rules! impl_mod_neg { ($t:ident) => { impl ModNeg for $t { type Output = $t; /// Negates a number modulo another number $m$, in place. The input must be already /// reduced modulo $m$. /// /// $f(x, m) = y$, where $x, y < m$ and $-x \equiv y \mod m$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::mod_neg#mod_neg). /// /// This is equivalent to `nmod_neg` from `nmod.h`, FLINT 2.7.1. #[inline] fn mod_neg(self, m: $t) -> $t { mod_neg(self, m) } } impl ModNegAssign for $t { /// Negates a number modulo another number $m$. The input must be already reduced modulo /// $m$. /// /// $x \gets y$, where $x, y < m$ and $-x \equiv y \mod m$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::mod_neg#mod_neg_assign). /// /// This is equivalent to `nmod_neg` from `nmod.h`, FLINT 2.7.1, where the output is /// assigned to `a`. #[inline] fn mod_neg_assign(&mut self, m: $t) { mod_neg_assign(self, m) } } }; } apply_to_unsigneds!(impl_mod_neg); malachite-base-0.4.16/src/num/arithmetic/mod_op.rs000064400000000000000000000222741046102023000201240ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{ CeilingMod, CeilingModAssign, Mod, ModAssign, NegMod, NegModAssign, UnsignedAbs, }; use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::ExactFrom; fn neg_mod_unsigned(x: T, other: T) -> T { let remainder = x % other; if remainder == T::ZERO { T::ZERO } else { other - remainder } } fn neg_mod_assign_unsigned(x: &mut T, other: T) { *x %= other; if *x != T::ZERO { *x = other - *x; } } macro_rules! impl_mod_unsigned { ($t:ident) => { impl Mod<$t> for $t { type Output = $t; /// Divides a number by another number, returning just the remainder. /// /// If the quotient were computed, the quotient and remainder would satisfy $x = qy + r$ /// and $0 \leq r < y$. /// /// $$ /// f(x, y) = x - y\left \lfloor \frac{x}{y} \right \rfloor. /// $$ /// /// This function is called `mod_op` rather than `mod` because `mod` is a Rust keyword. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `other` is 0. /// /// # Examples /// See [here](super::mod_op#mod_op). #[inline] fn mod_op(self, other: $t) -> $t { self % other } } impl ModAssign<$t> for $t { /// Divides a number by another number, replacing the first number by the remainder. /// /// If the quotient were computed, he quotient and remainder would satisfy $x = qy + r$ /// and $0 \leq r < y$. /// /// $$ /// x \gets x - y\left \lfloor \frac{x}{y} \right \rfloor. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `other` is 0. /// /// # Examples /// See [here](super::mod_op#mod_assign). #[inline] fn mod_assign(&mut self, other: $t) { *self %= other; } } impl NegMod<$t> for $t { type Output = $t; /// Divides the negative of a number by another number, returning just the remainder. /// /// If the quotient were computed, the quotient and remainder would satisfy $x = qy - r$ /// and $0 \leq r < y$. /// /// $$ /// f(x, y) = y\left \lceil \frac{x}{y} \right \rceil - x. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `other` is 0. /// /// # Examples /// See [here](super::mod_op#neg_mod). #[inline] fn neg_mod(self, other: $t) -> $t { neg_mod_unsigned(self, other) } } impl NegModAssign<$t> for $t { /// Divides the negative of a number by another number, returning just the remainder. /// /// If the quotient were computed, the quotient and remainder would satisfy $x = qy - r$ /// and $0 \leq r < y$. /// /// $$ /// x \gets y\left \lceil \frac{x}{y} \right \rceil - x. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `other` is 0. /// /// # Examples /// See [here](super::mod_op#neg_mod_assign). #[inline] fn neg_mod_assign(&mut self, other: $t) { neg_mod_assign_unsigned(self, other); } } }; } apply_to_unsigneds!(impl_mod_unsigned); fn mod_op_signed< U: PrimitiveUnsigned, S: ExactFrom + PrimitiveSigned + UnsignedAbs, >( x: S, other: S, ) -> S { let remainder = if (x >= S::ZERO) == (other >= S::ZERO) { x.unsigned_abs() % other.unsigned_abs() } else { x.unsigned_abs().neg_mod(other.unsigned_abs()) }; if other >= S::ZERO { S::exact_from(remainder) } else { -S::exact_from(remainder) } } fn ceiling_mod_signed< U: PrimitiveUnsigned, S: ExactFrom + PrimitiveSigned + UnsignedAbs, >( x: S, other: S, ) -> S { let remainder = if (x >= S::ZERO) == (other >= S::ZERO) { x.unsigned_abs().neg_mod(other.unsigned_abs()) } else { x.unsigned_abs() % other.unsigned_abs() }; if other >= S::ZERO { -S::exact_from(remainder) } else { S::exact_from(remainder) } } macro_rules! impl_mod_signed { ($t:ident) => { impl Mod<$t> for $t { type Output = $t; /// Divides a number by another number, returning just the remainder. The remainder has /// the same sign as the second number. /// /// If the quotient were computed, the quotient and remainder would satisfy $x = qy + r$ /// and $0 \leq |r| < |y|$. /// /// $$ /// f(x, y) = x - y\left \lfloor \frac{x}{y} \right \rfloor. /// $$ /// /// This function is called `mod_op` rather than `mod` because `mod` is a Rust keyword. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `other` is 0. /// /// # Examples /// See [here](super::mod_op#mod_op). #[inline] fn mod_op(self, other: $t) -> $t { mod_op_signed(self, other) } } impl ModAssign<$t> for $t { /// Divides a number by another number, replacing the first number by the remainder. The /// remainder has the same sign as the second number. /// /// If the quotient were computed, he quotient and remainder would satisfy $x = qy + r$ /// and $0 \leq |r| < |y|$. /// /// $$ /// x \gets x - y\left \lfloor \frac{x}{y} \right \rfloor. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `other` is 0. /// /// # Examples /// See [here](super::mod_op#mod_assign). #[inline] fn mod_assign(&mut self, other: $t) { *self = self.mod_op(other); } } impl CeilingMod<$t> for $t { type Output = $t; /// Divides a number by another number, returning just the remainder. The remainder has /// the opposite sign as the second number. /// /// If the quotient were computed, the quotient and remainder would satisfy $x = qy + r$ /// and $0 \leq |r| < |y|$. /// /// $$ /// f(x, y) = x - y\left \lceil \frac{x}{y} \right \rceil. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `other` is 0. /// /// # Examples /// See [here](super::mod_op#ceiling_mod). #[inline] fn ceiling_mod(self, other: $t) -> $t { ceiling_mod_signed(self, other) } } impl CeilingModAssign<$t> for $t { /// Divides a number by another number, replacing the first number by the remainder. The /// remainder has the opposite sign as the second number. /// /// If the quotient were computed, the quotient and remainder would satisfy $x = qy + r$ /// and $0 \leq |r| < |y|$. /// /// $$ /// x \gets x - y\left \lceil\frac{x}{y} \right \rceil. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `other` is 0. /// /// # Examples /// See [here](super::mod_op#ceiling_mod_assign). #[inline] fn ceiling_mod_assign(&mut self, other: $t) { *self = self.ceiling_mod(other); } } }; } apply_to_signeds!(impl_mod_signed); malachite-base-0.4.16/src/num/arithmetic/mod_pow.rs000064400000000000000000000322461046102023000203130ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // Uses code adopted from the FLINT Library. // // Copyright © 2009, 2010, 2012, 2016 William Hart // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::mod_mul::{limbs_invert_limb_u32, limbs_invert_limb_u64}; use crate::num::arithmetic::traits::{ ModPow, ModPowAssign, ModPowPrecomputed, ModPowPrecomputedAssign, }; use crate::num::basic::integers::PrimitiveInt; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::WrappingFrom; use crate::num::conversion::traits::{HasHalf, JoinHalves, SplitInHalf}; use crate::num::logic::traits::{BitIterable, LeadingZeros}; pub_test! {simple_binary_mod_pow(x: T, exp: u64, m: T) -> T { assert!(x < m, "x must be reduced mod m, but {x} >= {m}"); if m == T::ONE { return T::ZERO; } let data = T::precompute_mod_mul_data(&m); let mut out = T::ONE; for bit in exp.bits().rev() { out.mod_mul_precomputed_assign(out, m, &data); if bit { out.mod_mul_precomputed_assign(x, m, &data); } } out }} // m.get_highest_bit(), x < m, y < m // // This is equivalent to `n_mulmod_preinv` from `ulong_extras/mulmod_preinv.c`, FLINT 2.7.1. fn mul_mod_helper< T: PrimitiveUnsigned, DT: From + HasHalf + JoinHalves + PrimitiveUnsigned + SplitInHalf, >( mut x: T, y: T, m: T, inverse: T, shift: u64, ) -> T { x >>= shift; let p = DT::from(x) * DT::from(y); let (p_hi, p_lo) = p.split_in_half(); let (q_1, q_0) = (DT::from(p_hi) * DT::from(inverse)) .wrapping_add(p) .split_in_half(); let mut r = p_lo.wrapping_sub(q_1.wrapping_add(T::ONE).wrapping_mul(m)); if r > q_0 { r.wrapping_add_assign(m); } if r < m { r } else { r.wrapping_sub(m) } } // m.get_highest_bit(), x < m // // This is equivalent to `n_powmod_ui_preinv` from ulong_extras/powmod_ui_preinv.c, FLINT 2.7.1. fn fast_mod_pow< T: PrimitiveUnsigned, DT: From + HasHalf + JoinHalves + PrimitiveUnsigned + SplitInHalf, >( mut x: T, exp: u64, m: T, inverse: T, shift: u64, ) -> T { assert!(x < m, "x must be reduced mod m, but {x} >= {m}"); if exp == 0 { let x = T::power_of_2(shift); if x == m { T::ZERO } else { x } } else if x == T::ZERO { T::ZERO } else { let mut bits = exp.bits(); let mut out = if bits.next().unwrap() { x } else { T::power_of_2(shift) }; for bit in bits { x = mul_mod_helper::(x, x, m, inverse, shift); if bit { out = mul_mod_helper::(out, x, m, inverse, shift); } } out } } macro_rules! impl_mod_pow_precomputed_fast { ($t:ident, $dt:ident, $invert_limb:ident) => { impl ModPowPrecomputed for $t { type Output = $t; type Data = ($t, u64); /// Precomputes data for modular exponentiation. /// /// See `mod_pow_precomputed` and /// [`mod_pow_precomputed_assign`](super::traits::ModPowPrecomputedAssign). /// /// # Worst-case complexity /// Constant time and additional memory. fn precompute_mod_pow_data(&m: &$t) -> ($t, u64) { let leading_zeros = LeadingZeros::leading_zeros(m); ($invert_limb(m << leading_zeros), leading_zeros) } /// Raises a number to a power modulo another number $m$. The base must be already /// reduced modulo $m$. /// /// Some precomputed data is provided; this speeds up computations involving several /// modular exponentiations with the same modulus. The precomputed data should be /// obtained using /// [`precompute_mod_pow_data`](ModPowPrecomputed::precompute_mod_pow_data). /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `exp.significant_bits()`. /// /// # Panics /// Panics if `self` is greater than or equal to `m`. /// /// # Examples /// See [here](super::mod_pow#mod_pow_precomputed). fn mod_pow_precomputed(self, exp: u64, m: $t, data: &($t, u64)) -> $t { let (inverse, shift) = *data; fast_mod_pow::<$t, $dt>(self << shift, exp, m << shift, inverse, shift) >> shift } } }; } impl_mod_pow_precomputed_fast!(u32, u64, limbs_invert_limb_u32); impl_mod_pow_precomputed_fast!(u64, u128, limbs_invert_limb_u64); macro_rules! impl_mod_pow_precomputed_promoted { ($t:ident) => { impl ModPowPrecomputed for $t { type Output = $t; type Data = (u32, u64); /// Precomputes data for modular exponentiation. /// /// See `mod_pow_precomputed` and /// [`mod_pow_precomputed_assign`](super::traits::ModPowPrecomputedAssign). /// /// # Worst-case complexity /// Constant time and additional memory. fn precompute_mod_pow_data(&m: &$t) -> (u32, u64) { u32::precompute_mod_pow_data(&u32::from(m)) } /// Raises a number to a power modulo another number $m$. The base must be already /// reduced modulo $m$. /// /// Some precomputed data is provided; this speeds up computations involving several /// modular exponentiations with the same modulus. The precomputed data should be /// obtained using /// [`precompute_mod_pow_data`](ModPowPrecomputed::precompute_mod_pow_data). /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `exp.significant_bits()`. /// /// # Panics /// Panics if `self` is greater than or equal to `m`. /// /// # Examples /// See [here](super::mod_pow#mod_pow_precomputed). fn mod_pow_precomputed(self, exp: u64, m: $t, data: &(u32, u64)) -> $t { $t::wrapping_from(u32::from(self).mod_pow_precomputed(exp, u32::from(m), data)) } } }; } impl_mod_pow_precomputed_promoted!(u8); impl_mod_pow_precomputed_promoted!(u16); impl ModPowPrecomputed for u128 { type Output = u128; type Data = (); /// Precomputes data for modular exponentiation. /// /// See `mod_pow_precomputed` and /// [`mod_pow_precomputed_assign`](super::traits::ModPowPrecomputedAssign). /// /// # Worst-case complexity /// Constant time and additional memory. fn precompute_mod_pow_data(_m: &u128) {} /// Raises a number to a power modulo another number $m$. The base must be already reduced /// modulo $m$. /// /// Some precomputed data is provided; this speeds up computations involving several modular /// exponentiations with the same modulus. The precomputed data should be obtained using /// [`precompute_mod_pow_data`](ModPowPrecomputed::precompute_mod_pow_data). /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `exp.significant_bits()`. /// /// # Panics /// Panics if `self` is greater than or equal to `m`. /// /// # Examples /// See [here](super::mod_pow#mod_pow_precomputed). #[inline] fn mod_pow_precomputed(self, exp: u64, m: u128, _data: &()) -> u128 { simple_binary_mod_pow(self, exp, m) } } impl ModPowPrecomputed for usize { type Output = usize; type Data = (usize, u64); /// Precomputes data for modular exponentiation. /// /// See `mod_pow_precomputed` and /// [`mod_pow_precomputed_assign`](super::traits::ModPowPrecomputedAssign). /// /// # Worst-case complexity /// Constant time and additional memory. fn precompute_mod_pow_data(&m: &usize) -> (usize, u64) { if usize::WIDTH == u32::WIDTH { let (inverse, shift) = u32::precompute_mod_pow_data(&u32::wrapping_from(m)); (usize::wrapping_from(inverse), shift) } else { let (inverse, shift) = u64::precompute_mod_pow_data(&u64::wrapping_from(m)); (usize::wrapping_from(inverse), shift) } } /// Raises a number to a power modulo another number $m$. The base must be already reduced /// modulo $m$. /// /// Some precomputed data is provided; this speeds up computations involving several modular /// exponentiations with the same modulus. The precomputed data should be obtained using /// [`precompute_mod_pow_data`](ModPowPrecomputed::precompute_mod_pow_data). /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `exp.significant_bits()`. /// /// # Panics /// Panics if `self` is greater than or equal to `m`. /// /// # Examples /// See [here](super::mod_pow#mod_pow_precomputed). fn mod_pow_precomputed(self, exp: u64, m: usize, data: &(usize, u64)) -> usize { let (inverse, shift) = *data; if usize::WIDTH == u32::WIDTH { usize::wrapping_from(u32::wrapping_from(self).mod_pow_precomputed( exp, u32::wrapping_from(m), &(u32::wrapping_from(inverse), shift), )) } else { usize::wrapping_from(u64::wrapping_from(self).mod_pow_precomputed( exp, u64::wrapping_from(m), &(u64::wrapping_from(inverse), shift), )) } } } macro_rules! impl_mod_pow { ($t:ident) => { impl ModPowPrecomputedAssign for $t { /// Raises a number to a power modulo another number $m$, in place. The base must be /// already reduced modulo $m$. /// /// Some precomputed data is provided; this speeds up computations involving several /// modular exponentiations with the same modulus. The precomputed data should be /// obtained using /// [`precompute_mod_pow_data`](ModPowPrecomputed::precompute_mod_pow_data). /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `exp.significant_bits()`. /// /// # Examples /// See [here](super::mod_pow#mod_pow_precomputed_assign). #[inline] fn mod_pow_precomputed_assign(&mut self, exp: u64, m: $t, data: &Self::Data) { *self = self.mod_pow_precomputed(exp, m, data); } } impl ModPow for $t { type Output = $t; /// Raises a number to a power modulo another number $m$. The base must be already /// reduced modulo $m$. /// /// $f(x, n, m) = y$, where $x, y < m$ and $x^n \equiv y \mod m$. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `exp.significant_bits()`. /// /// # Panics /// Panics if `self` is greater than or equal to `m`. /// /// # Examples /// See [here](super::mod_pow#mod_pow). #[inline] fn mod_pow(self, exp: u64, m: $t) -> $t { simple_binary_mod_pow(self, exp, m) } } impl ModPowAssign for $t { /// Raises a number to a power modulo another number $m$, in place. The base must be /// already reduced modulo $m$. /// /// $x \gets y$, where $x, y < m$ and $x^n \equiv y \mod m$. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `exp.significant_bits()`. /// /// # Panics /// Panics if `self` is greater than or equal to `m`. /// /// # Examples /// See [here](super::mod_pow#mod_pow_assign). #[inline] fn mod_pow_assign(&mut self, exp: u64, m: $t) { *self = simple_binary_mod_pow(*self, exp, m); } } }; } apply_to_unsigneds!(impl_mod_pow); malachite-base-0.4.16/src/num/arithmetic/mod_power_of_2.rs000064400000000000000000000334271046102023000215510ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{ CeilingModPowerOf2, CeilingModPowerOf2Assign, ModPowerOf2, ModPowerOf2Assign, NegModPowerOf2, NegModPowerOf2Assign, RemPowerOf2, RemPowerOf2Assign, }; use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::WrappingFrom; use core::fmt::Debug; const ERROR_MESSAGE: &str = "Result exceeds width of output type"; fn mod_power_of_2_unsigned(x: T, pow: u64) -> T { if x == T::ZERO || pow >= T::WIDTH { x } else { x & T::low_mask(pow) } } fn mod_power_of_2_assign_unsigned(x: &mut T, pow: u64) { if *x != T::ZERO && pow < T::WIDTH { *x &= T::low_mask(pow); } } #[inline] fn neg_mod_power_of_2_unsigned(x: T, pow: u64) -> T { assert!(x == T::ZERO || pow <= T::WIDTH, "{ERROR_MESSAGE}"); x.wrapping_neg().mod_power_of_2(pow) } macro_rules! impl_mod_power_of_2_unsigned { ($s:ident) => { impl ModPowerOf2 for $s { type Output = $s; /// Divides a number by $2^k$, returning just the remainder. /// /// If the quotient were computed, the quotient and remainder would satisfy $x = q2^k + /// r$ and $0 \leq r < 2^k$. /// /// $$ /// f(x, k) = x - 2^k\left \lfloor \frac{x}{2^k} \right \rfloor. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::mod_power_of_2#mod_power_of_2). #[inline] fn mod_power_of_2(self, pow: u64) -> $s { mod_power_of_2_unsigned(self, pow) } } impl ModPowerOf2Assign for $s { /// Divides a number by $2^k$, replacing the first number by the remainder. /// /// If the quotient were computed, the quotient and remainder would satisfy $x = q2^k + /// r$ and $0 \leq r < 2^k$. /// /// $$ /// x \gets x - 2^k\left \lfloor \frac{x}{2^k} \right \rfloor. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::mod_power_of_2#mod_power_of_2_assign). #[inline] fn mod_power_of_2_assign(&mut self, pow: u64) { mod_power_of_2_assign_unsigned(self, pow); } } impl RemPowerOf2 for $s { type Output = $s; /// Divides a number by $2^k$, returning just the remainder. For unsigned integers, /// `rem_power_of_2` is equivalent to [`mod_power_of_2`](super::traits::ModPowerOf2). /// /// If the quotient were computed, the quotient and remainder would satisfy $x = q2^k + /// r$ and $0 \leq r < 2^k$. /// /// $$ /// f(x, k) = x - 2^k\left \lfloor \frac{x}{2^k} \right \rfloor. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::mod_power_of_2#rem_power_of_2). #[inline] fn rem_power_of_2(self, pow: u64) -> $s { self.mod_power_of_2(pow) } } impl RemPowerOf2Assign for $s { /// Divides a number by $2^k$, replacing the first number by the remainder. For unsigned /// integers, `rem_power_of_2_assign` is equivalent to /// [`mod_power_of_2_assign`](super::traits::ModPowerOf2Assign). /// /// If the quotient were computed, the quotient and remainder would satisfy $x = q2^k + /// r$ and $0 \leq r < 2^k$. /// /// $$ /// x \gets x - 2^k\left \lfloor \frac{x}{2^k} \right \rfloor. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::mod_power_of_2#rem_power_of_2_assign). #[inline] fn rem_power_of_2_assign(&mut self, pow: u64) { self.mod_power_of_2_assign(pow) } } impl NegModPowerOf2 for $s { type Output = $s; /// Divides the negative of a number by a $2^k$, returning just the remainder. /// /// If the quotient were computed, the quotient and remainder would satisfy $x = q2^k - /// r$ and $0 \leq r < 2^k$. /// /// $$ /// f(x, k) = 2^k\left \lceil \frac{x}{2^k} \right \rceil - x. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` is nonzero and `pow` is greater than `Self::WIDTH`. /// /// # Examples /// See [here](super::mod_power_of_2#neg_mod_power_of_2). #[inline] fn neg_mod_power_of_2(self, pow: u64) -> $s { neg_mod_power_of_2_unsigned(self, pow) } } impl NegModPowerOf2Assign for $s { /// Divides the negative of a number by $2^k$, returning just the remainder. /// /// If the quotient were computed, the quotient and remainder would satisfy $x = q2^k - /// r$ and $0 \leq r < 2^k$. /// /// $$ /// x \gets 2^k\left \lceil \frac{x}{2^k} \right \rceil - x. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` is nonzero and `pow` is greater than `Self::WIDTH`. /// /// # Examples /// See [here](super::mod_power_of_2#neg_mod_power_of_2_assign). #[inline] fn neg_mod_power_of_2_assign(&mut self, pow: u64) { *self = self.neg_mod_power_of_2(pow) } } }; } apply_to_unsigneds!(impl_mod_power_of_2_unsigned); fn mod_power_of_2_signed, S: PrimitiveSigned>( x: S, pow: u64, ) -> U { assert!(x >= S::ZERO || pow <= S::WIDTH, "{ERROR_MESSAGE}"); U::wrapping_from(x).mod_power_of_2(pow) } fn mod_power_of_2_assign_signed + ModPowerOf2 + PrimitiveSigned>( x: &mut S, pow: u64, ) where >::Error: Debug, { *x = S::try_from(x.mod_power_of_2(pow)).expect(ERROR_MESSAGE); } fn rem_power_of_2_signed< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >( x: S, pow: u64, ) -> S { if x >= S::ZERO { S::wrapping_from(U::wrapping_from(x).mod_power_of_2(pow)) } else { S::wrapping_from(U::wrapping_from(x.wrapping_neg()).mod_power_of_2(pow)).wrapping_neg() } } fn ceiling_mod_power_of_2_signed< U: PrimitiveUnsigned + WrappingFrom, S: TryFrom + PrimitiveSigned, >( x: S, pow: u64, ) -> S where >::Error: Debug, { let abs_result = if x >= S::ZERO { U::wrapping_from(x).neg_mod_power_of_2(pow) } else { U::wrapping_from(x.wrapping_neg()).mod_power_of_2(pow) }; S::try_from(abs_result) .expect(ERROR_MESSAGE) .checked_neg() .expect(ERROR_MESSAGE) } macro_rules! impl_mod_power_of_2_signed { ($u:ident, $s:ident) => { impl ModPowerOf2 for $s { type Output = $u; /// Divides a number by $2^k$, returning just the remainder. The remainder is /// non-negative. /// /// If the quotient were computed, the quotient and remainder would satisfy $x = q2^k + /// r$ and $0 \leq r < 2^k$. /// /// $$ /// f(x, k) = x - 2^k\left \lfloor \frac{x}{2^k} \right \rfloor. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` is negative and `pow` is greater than `Self::WIDTH`. /// /// # Examples /// See [here](super::mod_power_of_2#mod_power_of_2). #[inline] fn mod_power_of_2(self, pow: u64) -> $u { mod_power_of_2_signed(self, pow) } } impl ModPowerOf2Assign for $s { /// Divides a number by $2^k$, replacing the first number by the remainder. The /// remainder is non-negative. /// /// If the quotient were computed, he quotient and remainder would satisfy $x = q2^k + /// r$ and $0 \leq r < 2^k$. /// /// $$ /// x \gets x - 2^k\left \lfloor \frac{x}{2^k} \right \rfloor. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` is negative and `pow` is greater than or equal to `Self::WIDTH`. /// /// # Examples /// See [here](super::mod_power_of_2#mod_power_of_2_assign). #[inline] fn mod_power_of_2_assign(&mut self, pow: u64) { mod_power_of_2_assign_signed(self, pow); } } impl RemPowerOf2 for $s { type Output = $s; /// Divides a number by $2^k$, returning just the remainder. The remainder has the same /// sign as the first number. /// /// If the quotient were computed, the quotient and remainder would satisfy $x = q2^k + /// r$ and $0 \leq |r| < 2^k$. /// /// $$ /// f(x, k) = x - 2^k\operatorname{sgn}(x)\left \lfloor \frac{|x|}{2^k} \right \rfloor. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::mod_power_of_2#rem_power_of_2). #[inline] fn rem_power_of_2(self, pow: u64) -> $s { rem_power_of_2_signed::<$u, $s>(self, pow) } } impl RemPowerOf2Assign for $s { /// Divides a number by $2^k$, replacing the first number by the remainder. The /// remainder has the same sign as the first number. /// /// If the quotient were computed, he quotient and remainder would satisfy $x = q2^k + /// r$ and $0 \leq r < 2^k$. /// /// $$ /// x \gets x - 2^k\operatorname{sgn}(x)\left \lfloor \frac{|x|}{2^k} \right \rfloor. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::mod_power_of_2#rem_power_of_2_assign). #[inline] fn rem_power_of_2_assign(&mut self, pow: u64) { *self = self.rem_power_of_2(pow) } } impl CeilingModPowerOf2 for $s { type Output = $s; /// Divides a number by $2^k$, returning just the remainder. The remainder is /// non-positive. /// /// If the quotient were computed, the quotient and remainder would satisfy $x = q2^k + /// r$ and $0 \leq -r < 2^k$. /// /// $$ /// f(x, y) = x - 2^k\left \lceil \frac{x}{2^k} \right \rceil. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` is positive or `Self::MIN`, and `pow` is greater than or equal to /// `Self::WIDTH`. /// /// # Examples /// See [here](super::mod_power_of_2#ceiling_mod_power_of_2). #[inline] fn ceiling_mod_power_of_2(self, pow: u64) -> $s { ceiling_mod_power_of_2_signed::<$u, $s>(self, pow) } } impl CeilingModPowerOf2Assign for $s { /// Divides a number by $2^k$, replacing the first number by the remainder. The /// remainder is non-positive. /// /// If the quotient were computed, the quotient and remainder would satisfy $x = q2^k + /// r$ and $0 \leq -r < 2^k$. /// /// $$ /// x \gets x - 2^k\left \lceil\frac{x}{2^k} \right \rceil. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` is positive or `Self::MIN`, and `pow` is greater than or equal to /// `Self::WIDTH`. /// /// # Examples /// See [here](super::mod_power_of_2#ceiling_mod_power_of_2_assign). #[inline] fn ceiling_mod_power_of_2_assign(&mut self, pow: u64) { *self = self.ceiling_mod_power_of_2(pow) } } }; } apply_to_unsigned_signed_pairs!(impl_mod_power_of_2_signed); malachite-base-0.4.16/src/num/arithmetic/mod_power_of_2_add.rs000064400000000000000000000061251046102023000223540ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{ModPowerOf2Add, ModPowerOf2AddAssign}; use crate::num::basic::unsigneds::PrimitiveUnsigned; fn mod_power_of_2_add(x: T, y: T, pow: u64) -> T { assert!(pow <= T::WIDTH); assert!( x.significant_bits() <= pow, "x must be reduced mod 2^pow, but {x} >= 2^{pow}" ); assert!( y.significant_bits() <= pow, "y must be reduced mod 2^pow, but {y} >= 2^{pow}" ); x.wrapping_add(y).mod_power_of_2(pow) } fn mod_power_of_2_add_assign(x: &mut T, y: T, pow: u64) { assert!(pow <= T::WIDTH); assert!( x.significant_bits() <= pow, "x must be reduced mod 2^pow, but {x} >= 2^{pow}" ); assert!( y.significant_bits() <= pow, "y must be reduced mod 2^pow, but {y} >= 2^{pow}" ); x.wrapping_add_assign(y); x.mod_power_of_2_assign(pow); } macro_rules! impl_mod_power_of_2_add { ($t:ident) => { impl ModPowerOf2Add<$t> for $t { type Output = $t; /// Adds two numbers modulo a third number $2^k$. The inputs must be already reduced /// modulo $2^k$. /// /// $f(x, y, k) = z$, where $x, y, z < 2^k$ and $x + y \equiv z \mod 2^k$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `pow` is greater than `Self::WIDTH` or if `self` or `other` are greater /// than or equal to $2^k$. /// /// # Examples /// See [here](super::mod_power_of_2_add#mod_power_of_2_add). #[inline] fn mod_power_of_2_add(self, other: $t, pow: u64) -> $t { mod_power_of_2_add(self, other, pow) } } impl ModPowerOf2AddAssign<$t> for $t { /// Adds two numbers modulo a third number $2^k$, in place. The inputs must be already /// reduced modulo $2^k$. /// /// $x \gets z$, where $x, y, z < 2^k$ and $x + y \equiv z \mod 2^k$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `pow` is greater than `Self::WIDTH` or if `self` or `other` are greater /// than or equal to $2^k$. /// /// # Examples /// See [here](super::mod_power_of_2_add#mod_power_of_2_add_assign). #[inline] fn mod_power_of_2_add_assign(&mut self, other: $t, pow: u64) { mod_power_of_2_add_assign(self, other, pow); } } }; } apply_to_unsigneds!(impl_mod_power_of_2_add); malachite-base-0.4.16/src/num/arithmetic/mod_power_of_2_inverse.rs000064400000000000000000000052151046102023000232760ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::ModPowerOf2Inverse; use crate::num::basic::unsigneds::PrimitiveUnsigned; // Uses Newton's method, as described by Colin Plumb in // https://groups.google.com/g/sci.crypt/c/UI-UMbUnYGk/m/hX2-wQVyE3oJ. pub_test! {mod_power_of_2_inverse_fast(x: T, pow: u64) -> Option { assert_ne!(x, T::ZERO); assert!(pow <= T::WIDTH); assert!(x.significant_bits() <= pow, "x must be reduced mod 2^pow, but {x} >= 2^{pow}"); if x.even() { return None; } else if x == T::ONE { return Some(T::ONE); } let mut small_pow = 2; let mut inverse = x.mod_power_of_2(2); while small_pow < pow { small_pow <<= 1; if small_pow > pow { small_pow = pow; } // inverse <- inverse * (2 - inverse * x) mod 2^small_pow inverse.mod_power_of_2_mul_assign( T::TWO.mod_power_of_2_sub( inverse.mod_power_of_2_mul(x.mod_power_of_2(small_pow), small_pow), small_pow, ), small_pow, ); } Some(inverse) }} macro_rules! impl_mod_power_of_2_inverse { ($u:ident) => { impl ModPowerOf2Inverse for $u { type Output = $u; /// Computes the multiplicative inverse of a number modulo $2^k$. The input must be /// already reduced modulo $2^k$. /// /// Returns `None` if $x$ is even. /// /// $f(x, k) = y$, where $x, y < 2^k$, $x$ is odd, and $xy \equiv 1 \mod 2^k$. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `pow`. /// /// # Panics /// Panics if `pow` is greater than `Self::WIDTH`, if `self` is zero, or if `self` is /// greater than or equal to $2^k$. /// /// # Examples /// See [here](super::mod_power_of_2_inverse#mod_power_of_2_inverse). #[inline] fn mod_power_of_2_inverse(self, pow: u64) -> Option<$u> { mod_power_of_2_inverse_fast(self, pow) } } }; } apply_to_unsigneds!(impl_mod_power_of_2_inverse); malachite-base-0.4.16/src/num/arithmetic/mod_power_of_2_is_reduced.rs000064400000000000000000000023711046102023000237310ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::ModPowerOf2IsReduced; use crate::num::logic::traits::SignificantBits; macro_rules! impl_mod_power_of_2_is_reduced { ($t:ident) => { impl ModPowerOf2IsReduced for $t { /// Returns whether a number is reduced modulo another number $2^k$; in other words, /// whether it has no more than $k$ significant bits. /// /// $f(x, k) = (x < 2^k)$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::mod_power_of_2_is_reduced#mod_power_of_2_is_reduced). #[inline] fn mod_power_of_2_is_reduced(&self, pow: u64) -> bool { self.significant_bits() <= pow } } }; } apply_to_unsigneds!(impl_mod_power_of_2_is_reduced); malachite-base-0.4.16/src/num/arithmetic/mod_power_of_2_mul.rs000064400000000000000000000061441046102023000224220ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{ModPowerOf2Mul, ModPowerOf2MulAssign}; use crate::num::basic::unsigneds::PrimitiveUnsigned; fn mod_power_of_2_mul(x: T, y: T, pow: u64) -> T { assert!(pow <= T::WIDTH); assert!( x.significant_bits() <= pow, "x must be reduced mod 2^pow, but {x} >= 2^{pow}" ); assert!( y.significant_bits() <= pow, "y must be reduced mod 2^pow, but {y} >= 2^{pow}" ); x.wrapping_mul(y).mod_power_of_2(pow) } #[inline] fn mod_power_of_2_mul_assign(x: &mut T, y: T, pow: u64) { assert!(pow <= T::WIDTH); assert!( x.significant_bits() <= pow, "x must be reduced mod 2^pow, but {x} >= 2^{pow}" ); assert!( y.significant_bits() <= pow, "y must be reduced mod 2^pow, but {y} >= 2^{pow}" ); x.wrapping_mul_assign(y); x.mod_power_of_2_assign(pow); } macro_rules! impl_mod_power_of_2_mul { ($t:ident) => { impl ModPowerOf2Mul<$t> for $t { type Output = $t; /// Multiplies two numbers modulo a third number $2^k$. The inputs must be already /// reduced modulo $2^k$. /// /// $f(x, y, k) = z$, where $x, y, z < 2^k$ and $xy \equiv z \mod 2^k$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `pow` is greater than `Self::WIDTH` or if `self` or `other` are greater /// than or equal to $2^k$. /// /// # Examples /// See [here](super::mod_power_of_2_mul#mod_power_of_2_mul). #[inline] fn mod_power_of_2_mul(self, other: $t, pow: u64) -> $t { mod_power_of_2_mul(self, other, pow) } } impl ModPowerOf2MulAssign<$t> for $t { /// Multiplies two numbers modulo a third number $2^k$, in place. The inputs must be /// already reduced modulo $2^k$. /// /// $x \gets z$, where $x, y, z < 2^k$ and $xy \equiv z \mod 2^k$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `pow` is greater than `Self::WIDTH` or if `self` or `other` are greater /// than or equal to $2^k$. /// /// # Examples /// See [here](super::mod_power_of_2_mul#mod_power_of_2_mul_assign). #[inline] fn mod_power_of_2_mul_assign(&mut self, other: $t, pow: u64) { mod_power_of_2_mul_assign(self, other, pow) } } }; } apply_to_unsigneds!(impl_mod_power_of_2_mul); malachite-base-0.4.16/src/num/arithmetic/mod_power_of_2_neg.rs000064400000000000000000000054141046102023000223750ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{ModPowerOf2Neg, ModPowerOf2NegAssign}; use crate::num::basic::unsigneds::PrimitiveUnsigned; fn mod_power_of_2_neg(x: T, pow: u64) -> T { assert!(pow <= T::WIDTH); assert!( x.significant_bits() <= pow, "x must be reduced mod 2^pow, but {x} >= 2^{pow}" ); x.wrapping_neg().mod_power_of_2(pow) } fn mod_power_of_2_neg_assign(x: &mut T, pow: u64) { assert!(pow <= T::WIDTH); assert!( x.significant_bits() <= pow, "x must be reduced mod 2^pow, but {x} >= 2^{pow}" ); x.wrapping_neg_assign(); x.mod_power_of_2_assign(pow); } macro_rules! impl_mod_power_of_2_neg { ($t:ident) => { impl ModPowerOf2Neg for $t { type Output = $t; /// Negates a number modulo another number $2^k$. The input must be already reduced /// modulo $2^k$. /// /// $f(x, k) = y$, where $x, y < 2^k$ and $-x \equiv y \mod 2^k$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `pow` is greater than `Self::WIDTH` or if `self` is greater than or equal /// to $2^k$. /// /// # Examples /// See [here](super::mod_power_of_2_neg#mod_power_of_2_neg). #[inline] fn mod_power_of_2_neg(self, pow: u64) -> $t { mod_power_of_2_neg(self, pow) } } impl ModPowerOf2NegAssign for $t { /// Negates a number modulo another number $2^k$, in place. The input must be already /// reduced modulo $2^k$. /// /// $x \gets y$, where $x, y < 2^k$ and $-x \equiv y \mod 2^k$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `pow` is greater than `Self::WIDTH` or if `self` is greater than or equal /// to $2^k$. /// /// # Examples /// See [here](super::mod_power_of_2_neg#mod_power_of_2_neg_assign). #[inline] fn mod_power_of_2_neg_assign(&mut self, pow: u64) { mod_power_of_2_neg_assign(self, pow); } } }; } apply_to_unsigneds!(impl_mod_power_of_2_neg); malachite-base-0.4.16/src/num/arithmetic/mod_power_of_2_pow.rs000064400000000000000000000061061046102023000224300ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{ModPowerOf2Pow, ModPowerOf2PowAssign}; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::logic::traits::BitIterable; fn mod_power_of_2_pow(x: T, exp: u64, pow: u64) -> T { assert!(pow <= T::WIDTH); assert!( x.significant_bits() <= pow, "x must be reduced mod 2^pow, but {x} >= 2^{pow}" ); if pow == 0 { return T::ZERO; } let mut out = T::ONE; for bit in exp.bits().rev() { out.mod_power_of_2_mul_assign(out, pow); if bit { out.mod_power_of_2_mul_assign(x, pow); } } out } macro_rules! impl_mod_power_of_2_pow { ($t:ident) => { impl ModPowerOf2Pow for $t { type Output = $t; /// Raises a number to a power modulo another number $2^k$. The base must be already /// reduced modulo $2^k$. /// /// $f(x, n, k) = y$, where $x, y < 2^k$ and $x^n \equiv y \mod 2^k$. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `exp.significant_bits()`. /// /// # Panics /// Panics if `pow` is greater than `Self::WIDTH` or if `self` is greater than or equal /// to $2^k$. /// /// # Examples /// See [here](super::mod_power_of_2_pow#mod_power_of_2_pow). #[inline] fn mod_power_of_2_pow(self, exp: u64, pow: u64) -> $t { mod_power_of_2_pow(self, exp, pow) } } impl ModPowerOf2PowAssign for $t { /// Raises a number to a power modulo another number $2^k$, in place. The base must be /// already reduced modulo $2^k$. /// /// $x \gets y$, where $x, y < 2^k$ and $x^n \equiv y \mod 2^k$. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `exp.significant_bits()`. /// /// # Panics /// Panics if `pow` is greater than `Self::WIDTH` or if `self` is greater than or equal /// to $2^k$. /// /// # Examples /// See [here](super::mod_power_of_2_pow#mod_power_of_2_pow_assign). #[inline] fn mod_power_of_2_pow_assign(&mut self, exp: u64, pow: u64) { *self = self.mod_power_of_2_pow(exp, pow); } } }; } apply_to_unsigneds!(impl_mod_power_of_2_pow); malachite-base-0.4.16/src/num/arithmetic/mod_power_of_2_shl.rs000064400000000000000000000171751046102023000224210ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{ModPowerOf2Shl, ModPowerOf2ShlAssign, UnsignedAbs}; use crate::num::basic::integers::PrimitiveInt; use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use core::ops::{Shl, ShlAssign, Shr, ShrAssign}; fn mod_power_of_2_shl_unsigned, U: PrimitiveUnsigned>( x: T, other: U, pow: u64, ) -> T { assert!(pow <= T::WIDTH); assert!( x.significant_bits() <= pow, "x must be reduced mod 2^pow, but {x} >= 2^{pow}" ); if other >= U::exact_from(T::WIDTH) { T::ZERO } else { (x << other).mod_power_of_2(pow) } } fn mod_power_of_2_shl_assign_unsigned, U: PrimitiveUnsigned>( x: &mut T, other: U, pow: u64, ) { assert!(pow <= T::WIDTH); assert!( x.significant_bits() <= pow, "x must be reduced mod 2^pow, but {x} >= 2^{pow}" ); if other >= U::exact_from(T::WIDTH) { *x = T::ZERO; } else { *x <<= other; x.mod_power_of_2_assign(pow); } } macro_rules! impl_mod_power_of_2_shl_unsigned { ($t:ident) => { macro_rules! impl_mod_power_of_2_shl_unsigned_inner { ($u:ident) => { impl ModPowerOf2Shl<$u> for $t { type Output = $t; /// Left-shifts a number (multiplies it by a power of 2) modulo $2^k$. The /// number must be already reduced modulo $2^k$. /// /// $f(x, n, k) = y$, where $x, y < 2^k$ and $2^nx \equiv y \mod 2^k$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `pow` is greater than `Self::WIDTH` or if `self` is greater than /// or equal to $2^k$. /// /// # Examples /// See [here](super::mod_power_of_2_shl#mod_power_of_2_shl). #[inline] fn mod_power_of_2_shl(self, other: $u, pow: u64) -> $t { mod_power_of_2_shl_unsigned(self, other, pow) } } impl ModPowerOf2ShlAssign<$u> for $t { /// Left-shifts a number (multiplies it by a power of 2) modulo $2^k$, in place. /// The number must be already reduced modulo $2^k$. /// /// $x \gets y$, where $x, y < 2^k$ and $2^nx \equiv y \mod 2^k$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `pow` is greater than `Self::WIDTH` or if `self` is greater than /// or equal to $2^k$. /// /// # Examples /// See [here](super::mod_power_of_2_shl#mod_power_of_2_shl_assign). #[inline] fn mod_power_of_2_shl_assign(&mut self, other: $u, pow: u64) { mod_power_of_2_shl_assign_unsigned(self, other, pow); } } }; } apply_to_unsigneds!(impl_mod_power_of_2_shl_unsigned_inner); }; } apply_to_unsigneds!(impl_mod_power_of_2_shl_unsigned); fn mod_power_of_2_shl_signed< T: ModPowerOf2Shl + PrimitiveInt + Shr, U: PrimitiveUnsigned, S: PrimitiveSigned + UnsignedAbs, >( x: T, other: S, pow: u64, ) -> T { assert!(pow <= T::WIDTH); assert!( x.significant_bits() <= pow, "x must be reduced mod 2^pow, but {x} >= 2^{pow}" ); let other_abs = other.unsigned_abs(); if other >= S::ZERO { x.mod_power_of_2_shl(other_abs, pow) } else { let width = U::wrapping_from(T::WIDTH); if width != U::ZERO && other_abs >= width { T::ZERO } else { x >> other_abs } } } fn mod_power_of_2_shl_assign_signed< T: ModPowerOf2ShlAssign + PrimitiveInt + ShrAssign, U: PrimitiveUnsigned, S: PrimitiveSigned + UnsignedAbs, >( x: &mut T, other: S, pow: u64, ) { assert!(pow <= T::WIDTH); assert!( x.significant_bits() <= pow, "x must be reduced mod 2^pow, but {x} >= 2^{pow}" ); let other_abs = other.unsigned_abs(); if other >= S::ZERO { x.mod_power_of_2_shl_assign(other_abs, pow); } else { let width = U::wrapping_from(T::WIDTH); if width != U::ZERO && other_abs >= width { *x = T::ZERO; } else { *x >>= other_abs; } } } macro_rules! impl_mod_power_of_2_shl_signed { ($t:ident) => { macro_rules! impl_mod_power_of_2_shl_signed_inner { ($u:ident) => { impl ModPowerOf2Shl<$u> for $t { type Output = $t; /// Left-shifts a number (multiplies it by a power of 2) modulo $2^k$. The /// number must be already reduced modulo $2^k$. /// /// $f(x, n, k) = y$, where $x, y < 2^k$ and $\lfloor 2^nx \rfloor \equiv y \mod /// 2^k$. /// /// # Panics /// Panics if `pow` is greater than `Self::WIDTH` or if `self` is greater than /// or equal to $2^k$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::mod_power_of_2_shl#mod_power_of_2_shl). #[inline] fn mod_power_of_2_shl(self, other: $u, pow: u64) -> $t { mod_power_of_2_shl_signed(self, other, pow) } } impl ModPowerOf2ShlAssign<$u> for $t { /// Left-shifts a number (multiplies it by a power of 2) modulo $2^k$, in place. /// The number must be already reduced modulo $2^k$. /// /// $x \gets y$, where $x, y < 2^k$ and $\lfloor 2^nx \rfloor \equiv y \mod /// 2^k$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `pow` is greater than `Self::WIDTH` or if `self` is greater than /// or equal to $2^k$. /// /// # Examples /// See [here](super::mod_power_of_2_shl#mod_power_of_2_shl_assign). #[inline] fn mod_power_of_2_shl_assign(&mut self, other: $u, pow: u64) { mod_power_of_2_shl_assign_signed(self, other, pow); } } }; } apply_to_signeds!(impl_mod_power_of_2_shl_signed_inner); }; } apply_to_unsigneds!(impl_mod_power_of_2_shl_signed); malachite-base-0.4.16/src/num/arithmetic/mod_power_of_2_shr.rs000064400000000000000000000107241046102023000224200ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{ ModPowerOf2Shl, ModPowerOf2ShlAssign, ModPowerOf2Shr, ModPowerOf2ShrAssign, UnsignedAbs, }; use crate::num::basic::integers::PrimitiveInt; use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use core::ops::{Shr, ShrAssign}; fn mod_power_of_2_shr_signed< T: ModPowerOf2Shl + PrimitiveInt + Shr, U: PrimitiveUnsigned, S: PrimitiveSigned + UnsignedAbs, >( x: T, other: S, pow: u64, ) -> T { assert!(pow <= T::WIDTH); assert!( x.significant_bits() <= pow, "x must be reduced mod 2^pow, but {x} >= 2^{pow}" ); let other_abs = other.unsigned_abs(); if other >= S::ZERO { let width = U::wrapping_from(T::WIDTH); if width != U::ZERO && other_abs >= width { T::ZERO } else { x >> other_abs } } else { x.mod_power_of_2_shl(other_abs, pow) } } fn mod_power_of_2_shr_assign_signed< T: ModPowerOf2ShlAssign + PrimitiveInt + ShrAssign, U: PrimitiveUnsigned, S: PrimitiveSigned + UnsignedAbs, >( x: &mut T, other: S, pow: u64, ) { assert!(pow <= T::WIDTH); assert!( x.significant_bits() <= pow, "x must be reduced mod 2^pow, but {x} >= 2^{pow}" ); let other_abs = other.unsigned_abs(); if other >= S::ZERO { let width = U::wrapping_from(T::WIDTH); if width != U::ZERO && other_abs >= width { *x = T::ZERO; } else { *x >>= other_abs; } } else { x.mod_power_of_2_shl_assign(other_abs, pow); } } macro_rules! impl_mod_power_of_2_shr_signed { ($t:ident) => { macro_rules! impl_mod_power_of_2_shr_signed_inner { ($u:ident) => { impl ModPowerOf2Shr<$u> for $t { type Output = $t; /// Right-shifts a number (divides it by a power of 2) modulo $2^k$. The number /// must be already reduced modulo $2^k$. /// /// $f(x, n, k) = y$, where $x, y < 2^k$ and $\lfloor 2^{-n}x \rfloor \equiv y /// \mod 2^k$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `pow` is greater than `Self::WIDTH` or if `self` is greater than /// or equal to $2^k$. /// /// # Examples /// See [here](super::mod_power_of_2_shr#mod_power_of_2_shr). #[inline] fn mod_power_of_2_shr(self, other: $u, pow: u64) -> $t { mod_power_of_2_shr_signed(self, other, pow) } } impl ModPowerOf2ShrAssign<$u> for $t { /// Right-shifts a number (divides it by a power of 2) modulo $2^k$, in place. /// The number must be already reduced modulo $2^k$. /// /// $x \gets y$, where $x, y < 2^k$ and $\lfloor 2^{-n}x \rfloor \equiv y \mod /// 2^k$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `pow` is greater than `Self::WIDTH` or if `self` is greater than /// or equal to $2^k$. /// /// # Examples /// See [here](super::mod_power_of_2_shr#mod_power_of_2_shr_assign). #[inline] fn mod_power_of_2_shr_assign(&mut self, other: $u, pow: u64) { mod_power_of_2_shr_assign_signed(self, other, pow) } } }; } apply_to_signeds!(impl_mod_power_of_2_shr_signed_inner); }; } apply_to_unsigneds!(impl_mod_power_of_2_shr_signed); malachite-base-0.4.16/src/num/arithmetic/mod_power_of_2_square.rs000064400000000000000000000044301046102023000231210ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{ ModPowerOf2Mul, ModPowerOf2MulAssign, ModPowerOf2Square, ModPowerOf2SquareAssign, }; macro_rules! impl_mod_power_of_2_square { ($t:ident) => { impl ModPowerOf2Square for $t { type Output = $t; /// Squares a number modulo another number $2^k$. The input must be already reduced /// modulo $2^k$. /// /// $f(x, k) = y$, where $x, y < 2^k$ and $x^2 \equiv y \mod 2^k$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `pow` is greater than `Self::WIDTH` or if `self` is greater than or equal /// to $2^k$. /// /// # Examples /// See [here](super::mod_power_of_2_square#mod_power_of_2_square). #[inline] fn mod_power_of_2_square(self, pow: u64) -> $t { self.mod_power_of_2_mul(self, pow) } } impl ModPowerOf2SquareAssign for $t { /// Squares a number modulo another number $2^k$, in place. The input must be already /// reduced modulo $2^k$. /// /// $x \gets y$, where $x, y < 2^k$ and $x^2 \equiv y \mod 2^k$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `pow` is greater than `Self::WIDTH` or if `self` is greater than or equal /// to $2^k$. /// /// # Examples /// See [here](super::mod_power_of_2_square#mod_power_of_2_square_assign). #[inline] fn mod_power_of_2_square_assign(&mut self, pow: u64) { self.mod_power_of_2_mul_assign(*self, pow); } } }; } apply_to_unsigneds!(impl_mod_power_of_2_square); malachite-base-0.4.16/src/num/arithmetic/mod_power_of_2_sub.rs000064400000000000000000000061371046102023000224200ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{ModPowerOf2Sub, ModPowerOf2SubAssign}; use crate::num::basic::unsigneds::PrimitiveUnsigned; fn mod_power_of_2_sub(x: T, y: T, pow: u64) -> T { assert!(pow <= T::WIDTH); assert!( x.significant_bits() <= pow, "x must be reduced mod 2^pow, but {x} >= 2^{pow}" ); assert!( y.significant_bits() <= pow, "y must be reduced mod 2^pow, but {y} >= 2^{pow}" ); x.wrapping_sub(y).mod_power_of_2(pow) } fn mod_power_of_2_sub_assign(x: &mut T, y: T, pow: u64) { assert!(pow <= T::WIDTH); assert!( x.significant_bits() <= pow, "x must be reduced mod 2^pow, but {x} >= 2^{pow}" ); assert!( y.significant_bits() <= pow, "y must be reduced mod 2^pow, but {y} >= 2^{pow}" ); x.wrapping_sub_assign(y); x.mod_power_of_2_assign(pow); } macro_rules! impl_mod_power_of_2_sub { ($t:ident) => { impl ModPowerOf2Sub<$t> for $t { type Output = $t; /// Subtracts two numbers modulo a third number $2^k$. The inputs must be already /// reduced modulo $2^k$. /// /// $f(x, y, k) = z$, where $x, y, z < 2^k$ and $x - y \equiv z \mod 2^k$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `pow` is greater than `Self::WIDTH` or if `self` or `other` are greater /// than or equal to $2^k$. /// /// # Examples /// See [here](super::mod_power_of_2_sub#mod_power_of_2_sub). #[inline] fn mod_power_of_2_sub(self, other: $t, pow: u64) -> $t { mod_power_of_2_sub(self, other, pow) } } impl ModPowerOf2SubAssign<$t> for $t { /// Subtracts two numbers modulo a third number $2^k$, in place. The inputs must be /// already reduced modulo $2^k$. /// /// $x \gets z$, where $x, y, z < 2^k$ and $x - y \equiv z \mod 2^k$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `pow` is greater than `Self::WIDTH` or if `self` or `other` are greater /// than or equal to $2^k$. /// /// # Examples /// See [here](super::mod_power_of_2_sub#mod_power_of_2_sub_assign). #[inline] fn mod_power_of_2_sub_assign(&mut self, other: $t, pow: u64) { mod_power_of_2_sub_assign(self, other, pow); } } }; } apply_to_unsigneds!(impl_mod_power_of_2_sub); malachite-base-0.4.16/src/num/arithmetic/mod_shl.rs000064400000000000000000000170021046102023000202650ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{ModShl, ModShlAssign, UnsignedAbs}; use crate::num::basic::integers::PrimitiveInt; use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::ExactFrom; use core::ops::{Shr, ShrAssign}; fn mod_shl_unsigned(x: T, other: U, m: T) -> T where u64: ExactFrom, { assert!(x < m, "x must be reduced mod m, but {x} >= {m}"); if other == U::ZERO { x } else if m == T::ONE || m == T::TWO { T::ZERO } else { x.mod_mul(T::TWO.mod_pow(u64::exact_from(other), m), m) } } fn mod_shl_assign_unsigned(x: &mut T, other: U, m: T) where u64: ExactFrom, { assert!(*x < m, "x must be reduced mod m, but {x} >= {m}"); if other == U::ZERO { } else if m == T::ONE || m == T::TWO { *x = T::ZERO; } else { x.mod_mul_assign(T::TWO.mod_pow(u64::exact_from(other), m), m); } } macro_rules! impl_mod_shl_unsigned { ($t:ident) => { macro_rules! impl_mod_shl_unsigned_inner { ($u:ident) => { impl ModShl<$u, $t> for $t { type Output = $t; /// Left-shifts a number (multiplies it by a power of 2) modulo a number $m$. /// The number must be already reduced modulo $m$. /// /// $f(x, n, m) = y$, where $x, y < m$ and $2^nx \equiv y \mod m$. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is /// `other.significant_bits()`. /// /// # Panics /// Panics if `self` is greater than or equal to `m`. /// /// # Examples /// See [here](super::mod_shl#mod_shl). #[inline] fn mod_shl(self, other: $u, m: $t) -> $t { mod_shl_unsigned(self, other, m) } } impl ModShlAssign<$u, $t> for $t { /// Left-shifts a number (multiplies it by a power of 2) modulo a number $m$, in /// place. The number must be already reduced modulo $m$. /// /// $x \gets y$, where $x, y < m$ and $2^nx \equiv y \mod m$. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is /// `other.significant_bits()`. /// /// # Panics /// Panics if `self` is greater than or equal to `m`. /// /// # Examples /// See [here](super::mod_shl#mod_shl_assign). #[inline] fn mod_shl_assign(&mut self, other: $u, m: $t) { mod_shl_assign_unsigned(self, other, m); } } }; } apply_to_unsigneds!(impl_mod_shl_unsigned_inner); }; } apply_to_unsigneds!(impl_mod_shl_unsigned); fn mod_shl_signed< T: ModShl + PrimitiveInt + Shr, U: PrimitiveUnsigned, S: PrimitiveSigned + UnsignedAbs, >( x: T, other: S, m: T, ) -> T { assert!(x < m, "x must be reduced mod m, but {x} >= {m}"); let other_abs = other.unsigned_abs(); if other >= S::ZERO { x.mod_shl(other_abs, m) } else { let width = U::wrapping_from(T::WIDTH); if width != U::ZERO && other_abs >= width { T::ZERO } else { x >> other_abs } } } fn mod_shl_assign_signed< T: ModShlAssign + PrimitiveUnsigned + ShrAssign, U: PrimitiveUnsigned, S: PrimitiveSigned + UnsignedAbs, >( x: &mut T, other: S, m: T, ) { assert!(*x < m, "x must be reduced mod m, but {x} >= {m}"); let other_abs = other.unsigned_abs(); if other >= S::ZERO { x.mod_shl_assign(other_abs, m); } else { let width = U::wrapping_from(T::WIDTH); if width != U::ZERO && other_abs >= width { *x = T::ZERO; } else { *x >>= other_abs; } } } macro_rules! impl_mod_shl_signed { ($t:ident) => { macro_rules! impl_mod_shl_signed_inner { ($u:ident) => { impl ModShl<$u, $t> for $t { type Output = $t; /// Left-shifts a number (multiplies it by a power of 2) modulo a number $m$. /// The number must be already reduced modulo $m$. /// /// $f(x, n, m) = y$, where $x, y < m$ and $\lfloor 2^nx \rfloor \equiv y \mod /// m$. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is /// `other.significant_bits()`. /// /// # Panics /// Panics if `self` is greater than or equal to `m`. /// /// # Examples /// See [here](super::mod_shl#mod_shl). #[inline] fn mod_shl(self, other: $u, m: $t) -> $t { mod_shl_signed(self, other, m) } } impl ModShlAssign<$u, $t> for $t { /// Left-shifts a number (multiplies it by a power of 2) modulo a number $m$, in /// place. The number must be already reduced modulo $m$. /// /// $x \gets y$, where $x, y < m$ and $\lfloor 2^nx \rfloor \equiv y \mod m$. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is /// `other.significant_bits()`. /// /// # Panics /// Panics if `self` is greater than or equal to `m`. /// /// # Examples /// See [here](super::mod_shl#mod_shl_assign). #[inline] fn mod_shl_assign(&mut self, other: $u, m: $t) { mod_shl_assign_signed(self, other, m); } } }; } apply_to_signeds!(impl_mod_shl_signed_inner); }; } apply_to_unsigneds!(impl_mod_shl_signed); malachite-base-0.4.16/src/num/arithmetic/mod_shr.rs000064400000000000000000000103561046102023000203000ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{ModShl, ModShlAssign, ModShr, ModShrAssign, UnsignedAbs}; use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use core::ops::{Shr, ShrAssign}; fn mod_shr_signed< T: ModShl + PrimitiveUnsigned + Shr, U: PrimitiveUnsigned, S: PrimitiveSigned + UnsignedAbs, >( x: T, other: S, m: T, ) -> T { assert!(x < m, "x must be reduced mod m, but {x} >= {m}"); let other_abs = other.unsigned_abs(); if other >= S::ZERO { let width = U::wrapping_from(T::WIDTH); if width != U::ZERO && other_abs >= width { T::ZERO } else { x >> other_abs } } else { x.mod_shl(other_abs, m) } } fn mod_shr_assign_signed< T: ModShlAssign + PrimitiveUnsigned + ShrAssign, U: PrimitiveUnsigned, S: PrimitiveSigned + UnsignedAbs, >( x: &mut T, other: S, m: T, ) { assert!(*x < m, "x must be reduced mod m, but {x} >= {m}"); let other_abs = other.unsigned_abs(); if other >= S::ZERO { let width = U::wrapping_from(T::WIDTH); if width != U::ZERO && other_abs >= width { *x = T::ZERO; } else { *x >>= other_abs; } } else { x.mod_shl_assign(other_abs, m); } } macro_rules! impl_mod_shr_signed { ($t:ident) => { macro_rules! impl_mod_shr_signed_inner { ($u:ident) => { impl ModShr<$u, $t> for $t { type Output = $t; /// Right-shifts a number (divides it by a power of 2) modulo a number $m$. The /// number must be already reduced modulo $m$. /// /// $f(x, n, m) = y$, where $x, y < m$ and $\lfloor 2^{-n}x \rfloor \equiv y /// \mod m$. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is /// `other.significant_bits()`. /// /// # Panics /// Panics if `self` is greater than or equal to `m`. /// /// # Examples /// See [here](super::mod_shr#mod_shr). #[inline] fn mod_shr(self, other: $u, m: $t) -> $t { mod_shr_signed(self, other, m) } } impl ModShrAssign<$u, $t> for $t { /// Right-shifts a number (divides it by a power of 2) modulo a number $m$, in /// place. The number must be already reduced modulo $m$. /// /// $x \gets y$, where $x, y < m$ and $\lfloor 2^{-n}x \rfloor \equiv y \mod m$. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is /// `other.significant_bits()`. /// /// # Panics /// Panics if `self` is greater than or equal to `m`. /// /// # Examples /// See [here](super::mod_shr#mod_shr). #[inline] fn mod_shr_assign(&mut self, other: $u, m: $t) { mod_shr_assign_signed(self, other, m) } } }; } apply_to_signeds!(impl_mod_shr_signed_inner); }; } apply_to_unsigneds!(impl_mod_shr_signed); malachite-base-0.4.16/src/num/arithmetic/mod_square.rs000064400000000000000000000100221046102023000207720ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{ ModPow, ModPowAssign, ModPowPrecomputed, ModPowPrecomputedAssign, ModSquare, ModSquareAssign, ModSquarePrecomputed, ModSquarePrecomputedAssign, }; macro_rules! impl_mod_square { ($t:ident) => { impl ModSquare for $t { type Output = $t; /// Squares a number modulo another number $m$. The input must be already reduced modulo /// $m$. /// /// $f(x, m) = y$, where $x, y < m$ and $x^2 \equiv y \mod m$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` is greater than or equal to `m`. /// /// # Examples /// See [here](super::mod_square#mod_square). #[inline] fn mod_square(self, m: $t) -> $t { self.mod_pow(2, m) } } impl ModSquareAssign for $t { /// Squares a number modulo another number $m$, in place. The input must be already /// reduced modulo $m$. /// /// $x \gets y$, where $x, y < m$ and $x^2 \equiv y \mod m$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` is greater than or equal to `m`. /// /// # Examples /// See [here](super::mod_square#mod_square_assign). #[inline] fn mod_square_assign(&mut self, m: $t) { self.mod_pow_assign(2, m); } } impl ModSquarePrecomputed for $t { /// Squares a number modulo another number $m$. The input must be already reduced modulo /// $m$. /// /// Some precomputed data is provided; this speeds up computations involving several /// modular squarings with the same modulus. The precomputed data should be obtained /// using [`precompute_mod_pow_data`](super::traits::ModPowPrecomputed). /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` is greater than or equal to `m`. /// /// # Examples /// See [here](super::mod_square#mod_square_precomputed). #[inline] fn mod_square_precomputed(self, m: $t, data: &Self::Data) -> Self::Output { self.mod_pow_precomputed(2, m, data) } } impl ModSquarePrecomputedAssign for $t { /// Squares a number modulo another number $m$, in place. The input must be already /// reduced modulo $m$. /// /// Some precomputed data is provided; this speeds up computations involving several /// modular squarings with the same modulus. The precomputed data should be obtained /// using [`precompute_mod_pow_data`](super::traits::ModPowPrecomputed). /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` is greater than or equal to `m`. /// /// # Examples /// See [here](super::mod_square#mod_square_precomputed_assign). #[inline] fn mod_square_precomputed_assign(&mut self, m: $t, data: &Self::Data) { self.mod_pow_precomputed_assign(2, m, data); } } }; } apply_to_unsigneds!(impl_mod_square); malachite-base-0.4.16/src/num/arithmetic/mod_sub.rs000064400000000000000000000053171046102023000202760ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // Uses code adopted from the FLINT Library. // // Copyright © 2010 William Hart // // Copyright © 2021 Fredrik Johansson // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{ModSub, ModSubAssign}; use crate::num::basic::unsigneds::PrimitiveUnsigned; fn mod_sub(x: T, y: T, m: T) -> T { assert!(x < m, "x must be reduced mod m, but {x} >= {m}"); assert!(y < m, "y must be reduced mod m, but {y} >= {m}"); let diff = x.wrapping_sub(y); if x < y { m.wrapping_add(diff) } else { diff } } macro_rules! impl_mod_sub { ($t:ident) => { impl ModSub<$t> for $t { type Output = $t; /// Subtracts two numbers modulo a third number $m$. The inputs must be already reduced /// modulo $m$. /// /// $f(x, y, m) = z$, where $x, y, z < m$ and $x - y \equiv z \mod m$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` or `other` are greater than or equal to `m`. /// /// # Examples /// See [here](super::mod_sub#mod_sub). /// /// This is equivalent to `nmod_sub` from `nmod.h`, FLINT 2.7.1. #[inline] fn mod_sub(self, other: $t, m: $t) -> $t { mod_sub(self, other, m) } } impl ModSubAssign<$t> for $t { /// Subtracts two numbers modulo a third number $m$, in place. The inputs must be /// already reduced modulo $m$. /// /// $x \gets z$, where $x, y, z < m$ and $x - y \equiv z \mod m$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` or `other` are greater than or equal to `m`. /// /// # Examples /// See [here](super::mod_sub#mod_sub_assign). /// /// This is equivalent to `nmod_sub` from `nmod.h`, FLINT 2.7.1, where the result is /// assigned to `a`. #[inline] fn mod_sub_assign(&mut self, other: $t, m: $t) { *self = self.mod_sub(other, m); } } }; } apply_to_unsigneds!(impl_mod_sub); malachite-base-0.4.16/src/num/arithmetic/neg.rs000064400000000000000000000031761046102023000174200ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::NegAssign; macro_rules! impl_neg_signed { ($t:ident) => { impl NegAssign for $t { /// Negates a number in place. /// /// Assumes that the negative can be represented. /// /// $x \gets -x$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::neg#neg_assign). #[inline] fn neg_assign(&mut self) { *self = -*self; } } }; } apply_to_signeds!(impl_neg_signed); macro_rules! impl_neg_float { ($t:ident) => { impl NegAssign for $t { /// Negates a number in place. /// /// Assumes that the negative can be represented. /// /// $x \gets -x$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::neg#neg_assign). #[inline] fn neg_assign(&mut self) { *self = -*self; } } }; } apply_to_primitive_floats!(impl_neg_float); malachite-base-0.4.16/src/num/arithmetic/next_power_of_2.rs000064400000000000000000000076071046102023000217510ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{NextPowerOf2, NextPowerOf2Assign, PowerOf2, Sign}; use crate::num::basic::floats::PrimitiveFloat; use crate::num::conversion::traits::SciMantissaAndExponent; use core::cmp::Ordering::*; macro_rules! impl_next_power_of_2_unsigned { ($t:ident) => { impl NextPowerOf2 for $t { type Output = $t; /// This is a wrapper over the `next_power_of_two` functions in the standard library, /// for example [this one](u32::next_power_of_two). #[inline] fn next_power_of_2(self) -> $t { $t::next_power_of_two(self) } } impl NextPowerOf2Assign for $t { /// Replaces a number with the smallest power of 2 greater than or equal to it. /// /// $x \gets 2^{\lceil \log_2 x \rceil}$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if the next power of 2 is greater than the type's maximum value. /// /// # Examples /// See [here](super::next_power_of_2#next_power_of_2_assign). #[inline] fn next_power_of_2_assign(&mut self) { *self = $t::next_power_of_2(*self); } } }; } apply_to_unsigneds!(impl_next_power_of_2_unsigned); macro_rules! impl_next_power_of_2_primitive_float { ($t:ident) => { impl NextPowerOf2 for $t { type Output = $t; /// Finds the smallest power of 2 greater than or equal to a number. /// /// $x \gets 2^{\lceil \log_2 x \rceil}$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` has a negative sign (positive zero is allowed, but negative zero is /// not), or if the next power of 2 is greater than the type's maximum value. /// /// # Examples /// See [here](super::next_power_of_2#next_power_of_2). #[inline] fn next_power_of_2(self) -> $t { assert_eq!(self.sign(), Greater); assert!(self.is_finite()); if self == 0.0 { return $t::MIN_POSITIVE_SUBNORMAL; } let (mantissa, exponent) = self.sci_mantissa_and_exponent(); if mantissa == 1.0 { self } else if exponent == $t::MAX_EXPONENT { panic!("Next power of 2 is too large to represent"); } else { $t::power_of_2(exponent + 1) } } } impl NextPowerOf2Assign for $t { /// Replaces a number with the smallest power of 2 greater than or equal to it. /// /// $x \gets 2^{\lceil \log_2 x \rceil}$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if the next power of 2 is greater than the type's maximum value. /// /// # Examples /// See [here](super::next_power_of_2#next_power_of_2_assign). #[inline] fn next_power_of_2_assign(&mut self) { *self = $t::next_power_of_2(*self); } } }; } apply_to_primitive_floats!(impl_next_power_of_2_primitive_float); malachite-base-0.4.16/src/num/arithmetic/overflowing_abs.rs000064400000000000000000000031671046102023000220350ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{OverflowingAbs, OverflowingAbsAssign}; macro_rules! impl_overflowing_abs { ($t:ident) => { impl OverflowingAbs for $t { type Output = $t; /// This is a wrapper over the `overflowing_abs` functions in the standard library, for /// example [this one](i32::overflowing_abs). #[inline] fn overflowing_abs(self) -> ($t, bool) { $t::overflowing_abs(self) } } impl OverflowingAbsAssign for $t { /// Replaces a number with its absolute value. /// /// Returns a boolean indicating whether an arithmetic overflow occurred. If an overflow /// occurred, then the wrapped value is assigned. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::overflowing_abs#overflowing_abs_assign). #[inline] fn overflowing_abs_assign(&mut self) -> bool { let overflow; (*self, overflow) = self.overflowing_abs(); overflow } } }; } apply_to_signeds!(impl_overflowing_abs); malachite-base-0.4.16/src/num/arithmetic/overflowing_add.rs000064400000000000000000000032501046102023000220110ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{OverflowingAdd, OverflowingAddAssign}; macro_rules! impl_overflowing_add { ($t:ident) => { impl OverflowingAdd<$t> for $t { type Output = $t; /// This is a wrapper over the `overflowing_add` functions in the standard library, for /// example [this one](u32::overflowing_add). #[inline] fn overflowing_add(self, other: $t) -> ($t, bool) { $t::overflowing_add(self, other) } } impl OverflowingAddAssign<$t> for $t { /// Adds a number to another number, in place. /// /// Returns a boolean indicating whether an arithmetic overflow occurred. If an overflow /// occurred, then the wrapped value is assigned. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::overflowing_add#overflowing_add_assign). #[inline] fn overflowing_add_assign(&mut self, other: $t) -> bool { let overflow; (*self, overflow) = self.overflowing_add(other); overflow } } }; } apply_to_primitive_ints!(impl_overflowing_add); malachite-base-0.4.16/src/num/arithmetic/overflowing_add_mul.rs000064400000000000000000000122551046102023000226730ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{ OverflowingAddAssign, OverflowingAddMul, OverflowingAddMulAssign, UnsignedAbs, }; use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; fn overflowing_add_mul_unsigned(x: T, y: T, z: T) -> (T, bool) { let (product, overflow_1) = y.overflowing_mul(z); let (result, overflow_2) = x.overflowing_add(product); (result, overflow_1 | overflow_2) } macro_rules! impl_overflowing_add_mul_unsigned { ($t:ident) => { impl OverflowingAddMul<$t> for $t { type Output = $t; /// Adds a number and the product of two other numbers. /// /// Returns a tuple containing the result and a boolean indicating whether an arithmetic /// overflow occured. If an overflow occurred, then the wrapped value is returned. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::overflowing_add_mul#overflowing_add_mul). #[inline] fn overflowing_add_mul(self, y: $t, z: $t) -> ($t, bool) { overflowing_add_mul_unsigned(self, y, z) } } impl OverflowingAddMulAssign<$t> for $t { /// Adds a number and the product of two other numbers, in place. /// /// Returns a boolean indicating whether an arithmetic overflow occurred. If an overflow /// occurred, then the wrapped value is assigned. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::overflowing_add_mul#overflowing_add_mul_assign). #[inline] fn overflowing_add_mul_assign(&mut self, y: $t, z: $t) -> bool { let (product, overflow) = y.overflowing_mul(z); self.overflowing_add_assign(product) | overflow } } }; } apply_to_unsigneds!(impl_overflowing_add_mul_unsigned); fn overflowing_add_mul_signed< U: PrimitiveUnsigned, S: PrimitiveSigned + UnsignedAbs, >( x: S, y: S, z: S, ) -> (S, bool) { if y == S::ZERO || z == S::ZERO { return (x, false); } let x_sign = x >= S::ZERO; if x_sign == ((y >= S::ZERO) == (z >= S::ZERO)) { let (product, overflow_1) = y.overflowing_mul(z); let (result, overflow_2) = x.overflowing_add(product); (result, overflow_1 | overflow_2) } else { let result = x.wrapping_add(y.wrapping_mul(z)); let overflow = { let x = x.unsigned_abs(); match y.unsigned_abs().checked_mul(z.unsigned_abs()) { Some(product) => { x < product && if x_sign { !x.wrapping_sub(product).get_highest_bit() } else { product.wrapping_sub(x).get_highest_bit() } } None => true, } }; (result, overflow) } } macro_rules! impl_overflowing_add_mul_signed { ($t:ident) => { impl OverflowingAddMul<$t> for $t { type Output = $t; /// Adds a number and the product of two other numbers. /// /// Returns a tuple containing the result and a boolean indicating whether an arithmetic /// overflow occurred. If an overflow occurred, then the wrapped value is returned. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::overflowing_add_mul#overflowing_add_mul). #[inline] fn overflowing_add_mul(self, y: $t, z: $t) -> ($t, bool) { overflowing_add_mul_signed(self, y, z) } } impl OverflowingAddMulAssign<$t> for $t { /// Adds a number and the product of two other numbers, in place. /// /// Returns a boolean indicating whether an arithmetic overflow occurred. If an overflow /// occurred, then the wrapped value is assigned. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::overflowing_add_mul#overflowing_add_mul_assign). #[inline] fn overflowing_add_mul_assign(&mut self, y: $t, z: $t) -> bool { let overflow; (*self, overflow) = self.overflowing_add_mul(y, z); overflow } } }; } apply_to_signeds!(impl_overflowing_add_mul_signed); malachite-base-0.4.16/src/num/arithmetic/overflowing_div.rs000064400000000000000000000035751046102023000220550ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{OverflowingDiv, OverflowingDivAssign}; macro_rules! impl_overflowing_div { ($t:ident) => { impl OverflowingDiv<$t> for $t { type Output = $t; /// This is a wrapper over the `overflowing_div` functions in the standard library, for /// example [this one](u32::overflowing_div). #[inline] fn overflowing_div(self, other: $t) -> ($t, bool) { $t::overflowing_div(self, other) } } impl OverflowingDivAssign<$t> for $t { /// Divides a number by another number, in place. /// /// Returns a boolean indicating whether an arithmetic overflow occurred. If an overflow /// occurred, then the wrapped value is assigned. Overflow only occurs when `Self` is /// signed, `self` is `Self::MIN`, and `other` is -1. The "actual" result, `-Self::MIN`, /// can't be represented and is wrapped back to `Self::MIN`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::overflowing_div#overflowing_div_assign). #[inline] fn overflowing_div_assign(&mut self, other: $t) -> bool { let overflow; (*self, overflow) = self.overflowing_div(other); overflow } } }; } apply_to_primitive_ints!(impl_overflowing_div); malachite-base-0.4.16/src/num/arithmetic/overflowing_mul.rs000064400000000000000000000032561046102023000220640ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{OverflowingMul, OverflowingMulAssign}; macro_rules! impl_overflowing_mul { ($t:ident) => { impl OverflowingMul<$t> for $t { type Output = $t; /// This is a wrapper over the `overflowing_mul` functions in the standard library, for /// example [this one](u32::overflowing_mul). #[inline] fn overflowing_mul(self, other: $t) -> ($t, bool) { $t::overflowing_mul(self, other) } } impl OverflowingMulAssign<$t> for $t { /// Multiplies a number by another number, in place. /// /// Returns a boolean indicating whether an arithmetic overflow occurred. If an overflow /// occurred, then the wrapped value is assigned. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::overflowing_mul#overflowing_mul_assign). #[inline] fn overflowing_mul_assign(&mut self, other: $t) -> bool { let overflow; (*self, overflow) = self.overflowing_mul(other); overflow } } }; } apply_to_primitive_ints!(impl_overflowing_mul); malachite-base-0.4.16/src/num/arithmetic/overflowing_neg.rs000064400000000000000000000031561046102023000220370ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{OverflowingNeg, OverflowingNegAssign}; macro_rules! impl_overflowing_neg { ($t:ident) => { impl OverflowingNeg for $t { type Output = $t; /// This is a wrapper over the `overflowing_neg` functions in the standard library, for /// example [this one](u32::overflowing_neg). #[inline] fn overflowing_neg(self) -> ($t, bool) { $t::overflowing_neg(self) } } impl OverflowingNegAssign for $t { /// Negates a number in place. /// /// Returns a boolean indicating whether an arithmetic overflow occurred. If an overflow /// occurred, then the wrapped value is assigned. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::overflowing_neg#overflowing_neg_assign). #[inline] fn overflowing_neg_assign(&mut self) -> bool { let overflow; (*self, overflow) = self.overflowing_neg(); overflow } } }; } apply_to_primitive_ints!(impl_overflowing_neg); malachite-base-0.4.16/src/num/arithmetic/overflowing_pow.rs000064400000000000000000000076211046102023000220740ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{OverflowingPow, OverflowingPowAssign, Parity, UnsignedAbs}; use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::OverflowingFrom; use crate::num::logic::traits::BitIterable; fn overflowing_pow_unsigned(x: T, exp: u64) -> (T, bool) { if exp == 0 { (T::ONE, false) } else if x < T::TWO { (x, false) } else { let (mut power, mut overflow) = (x, false); for bit in exp.bits().rev().skip(1) { overflow |= power.overflowing_square_assign(); if bit { overflow |= power.overflowing_mul_assign(x); } } (power, overflow) } } fn overflowing_unsigned_to_signed_neg< U: PrimitiveUnsigned, S: OverflowingFrom + PrimitiveSigned, >( x: U, ) -> (S, bool) { let (signed_x, overflow) = S::overflowing_from(x); if signed_x == S::MIN { (signed_x, false) } else { (signed_x.wrapping_neg(), overflow) } } fn overflowing_pow_signed< U: PrimitiveUnsigned, S: OverflowingFrom + PrimitiveSigned + UnsignedAbs, >( x: S, exp: u64, ) -> (S, bool) { let (p_abs, overflow) = OverflowingPow::overflowing_pow(x.unsigned_abs(), exp); let (p, overflow_2) = if x >= S::ZERO || exp.even() { S::overflowing_from(p_abs) } else { overflowing_unsigned_to_signed_neg(p_abs) }; (p, overflow || overflow_2) } macro_rules! impl_overflowing_pow_unsigned { ($t:ident) => { impl OverflowingPow for $t { type Output = $t; /// This is a wrapper over the `overflowing_pow` functions in the standard library, for /// example [this one](u32::overflowing_pow). #[inline] fn overflowing_pow(self, exp: u64) -> ($t, bool) { overflowing_pow_unsigned(self, exp) } } }; } apply_to_unsigneds!(impl_overflowing_pow_unsigned); macro_rules! impl_overflowing_pow_signed { ($t:ident) => { impl OverflowingPow for $t { type Output = $t; /// This is a wrapper over the `overflowing_pow` functions in the standard library, for /// example [this one](i32::overflowing_pow). #[inline] fn overflowing_pow(self, exp: u64) -> ($t, bool) { overflowing_pow_signed(self, exp) } } }; } apply_to_signeds!(impl_overflowing_pow_signed); macro_rules! impl_overflowing_pow_primitive_int { ($t:ident) => { impl OverflowingPowAssign for $t { /// Raises a number to a power, in place. /// /// Returns a boolean indicating whether an arithmetic overflow occurred. If an overflow /// occurred, then the wrapped value is assigned. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `exp.significant_bits()`. /// /// # Examples /// See [here](super::overflowing_pow#overflowing_pow_assign). #[inline] fn overflowing_pow_assign(&mut self, exp: u64) -> bool { let overflow; (*self, overflow) = OverflowingPow::overflowing_pow(*self, exp); overflow } } }; } apply_to_primitive_ints!(impl_overflowing_pow_primitive_int); malachite-base-0.4.16/src/num/arithmetic/overflowing_square.rs000064400000000000000000000036341046102023000225670ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{ OverflowingMulAssign, OverflowingSquare, OverflowingSquareAssign, }; macro_rules! impl_overflowing_square { ($t:ident) => { impl OverflowingSquare for $t { type Output = $t; /// Squares a number. /// /// Returns a tuple containing the result and a boolean indicating whether an arithmetic /// occurred. If an overflow occurred, then the wrapped value is returned. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::overflowing_square#overflowing_square). #[inline] fn overflowing_square(self) -> ($t, bool) { self.overflowing_mul(self) } } impl OverflowingSquareAssign for $t { /// Squares a number in place. /// /// Returns a boolean indicating whether an arithmetic overflow occurred. If an overflow /// occurred, then the wrapped value is assigned. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::overflowing_square#overflowing_square_assign). #[inline] fn overflowing_square_assign(&mut self) -> bool { self.overflowing_mul_assign(*self) } } }; } apply_to_primitive_ints!(impl_overflowing_square); malachite-base-0.4.16/src/num/arithmetic/overflowing_sub.rs000064400000000000000000000032551046102023000220570ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{OverflowingSub, OverflowingSubAssign}; macro_rules! impl_overflowing_sub { ($t:ident) => { impl OverflowingSub<$t> for $t { type Output = $t; /// This is a wrapper over the `overflowing_sub` functions in the standard library, for /// example [this one](u32::overflowing_sub). #[inline] fn overflowing_sub(self, other: $t) -> ($t, bool) { $t::overflowing_sub(self, other) } } impl OverflowingSubAssign<$t> for $t { /// Subtracts a number by another number, in place. /// /// Returns a boolean indicating whether an arithmetic overflow occurred. If an overflow /// occurred, then the wrapped value is assigned. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::overflowing_sub#overflowing_sub_assign). #[inline] fn overflowing_sub_assign(&mut self, other: $t) -> bool { let overflow; (*self, overflow) = self.overflowing_sub(other); overflow } } }; } apply_to_primitive_ints!(impl_overflowing_sub); malachite-base-0.4.16/src/num/arithmetic/overflowing_sub_mul.rs000064400000000000000000000123371046102023000227350ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{ OverflowingSubAssign, OverflowingSubMul, OverflowingSubMulAssign, UnsignedAbs, }; use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; fn overflowing_sub_mul_unsigned(x: T, y: T, z: T) -> (T, bool) { let (product, overflow_1) = y.overflowing_mul(z); let (result, overflow_2) = x.overflowing_sub(product); (result, overflow_1 | overflow_2) } macro_rules! impl_overflowing_sub_mul_unsigned { ($t:ident) => { impl OverflowingSubMul<$t> for $t { type Output = $t; /// Subtracts a number by the product of two other numbers. /// /// Returns a tuple containing the result and a boolean indicating whether an arithmetic /// overflow would occur. If an overflow would have occurred, then the wrapped value is /// returned. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::overflowing_sub_mul#overflowing_sub_mul). #[inline] fn overflowing_sub_mul(self, y: $t, z: $t) -> ($t, bool) { overflowing_sub_mul_unsigned(self, y, z) } } impl OverflowingSubMulAssign<$t> for $t { /// Subtracts a number by the product of two other numbers, in place. /// /// Returns a boolean indicating whether an arithmetic overflow would occur. If an /// overflow would have occurred, then the wrapped value is assigned. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::overflowing_sub_mul#overflowing_sub_mul_assign). #[inline] fn overflowing_sub_mul_assign(&mut self, y: $t, z: $t) -> bool { let (product, overflow) = y.overflowing_mul(z); self.overflowing_sub_assign(product) | overflow } } }; } apply_to_unsigneds!(impl_overflowing_sub_mul_unsigned); fn overflowing_sub_mul>( x: S, y: S, z: S, ) -> (S, bool) { if y == S::ZERO || z == S::ZERO { return (x, false); } let x_sign = x >= S::ZERO; if x_sign == ((y >= S::ZERO) != (z >= S::ZERO)) { let (product, overflow_1) = y.overflowing_mul(z); let (result, overflow_2) = x.overflowing_sub(product); (result, overflow_1 | overflow_2) } else { let result = x.wrapping_sub(y.wrapping_mul(z)); let overflow = { let x = x.unsigned_abs(); match y.unsigned_abs().checked_mul(z.unsigned_abs()) { Some(product) => { x < product && if x_sign { !x.wrapping_sub(product).get_highest_bit() } else { product.wrapping_sub(x).get_highest_bit() } } None => true, } }; (result, overflow) } } macro_rules! impl_overflowing_sub_mul_signed { ($t:ident) => { impl OverflowingSubMul<$t> for $t { type Output = $t; /// Subtracts a number by the product of two other numbers. /// /// Returns a tuple containing the result and a boolean indicating whether an arithmetic /// overflow occurred. If an overflow occurred, then the wrapped value is returned. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::overflowing_sub_mul#overflowing_sub_mul). #[inline] fn overflowing_sub_mul(self, y: $t, z: $t) -> ($t, bool) { overflowing_sub_mul(self, y, z) } } impl OverflowingSubMulAssign<$t> for $t { /// Subtracts a number by the product of two other numbers, in place. /// /// Returns a boolean indicating whether an arithmetic overflow would occur. If an /// overflow would have occurred, then the wrapped value is assigned. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::overflowing_sub_mul#overflowing_sub_mul_assign). #[inline] fn overflowing_sub_mul_assign(&mut self, y: $t, z: $t) -> bool { let overflow; (*self, overflow) = self.overflowing_sub_mul(y, z); overflow } } }; } apply_to_signeds!(impl_overflowing_sub_mul_signed); malachite-base-0.4.16/src/num/arithmetic/parity.rs000064400000000000000000000027341046102023000201560ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::Parity; macro_rules! impl_parity { ($t:ident) => { impl Parity for $t { /// Tests whether a number is even. /// /// $f(x) = (2|x)$. /// /// $f(x) = (\exists k \in \N \ x = 2k)$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::parity#even). #[inline] fn even(self) -> bool { (self & 1) == 0 } /// Tests whether a number is odd. /// /// $f(x) = (2\nmid x)$. /// /// $f(x) = (\exists k \in \N \ x = 2k+1)$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::parity#odd). #[inline] fn odd(self) -> bool { (self & 1) != 0 } } }; } apply_to_primitive_ints!(impl_parity); malachite-base-0.4.16/src/num/arithmetic/pow.rs000064400000000000000000000102411046102023000174430ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{Parity, Pow, PowAssign}; use crate::num::conversion::traits::ExactFrom; macro_rules! impl_pow_unsigned { ($t:ident) => { impl Pow for $t { type Output = $t; /// This is a wrapper over the `pow` functions in the standard library, for example /// [this one](u32::pow). #[inline] fn pow(self, exp: u64) -> $t { if exp == 0 { 1 } else if self < 2 { self } else { self.pow(u32::exact_from(exp)) } } } }; } apply_to_unsigneds!(impl_pow_unsigned); macro_rules! impl_pow_signed { ($t:ident) => { impl Pow for $t { type Output = $t; /// This is a wrapper over the `pow` functions in the standard library, for example /// [this one](i32::pow). #[inline] fn pow(self, exp: u64) -> $t { if exp == 0 { 1 } else if self == 0 || self == 1 { self } else if self == -1 { if exp.even() { 1 } else { -1 } } else { self.pow(u32::exact_from(exp)) } } } }; } apply_to_signeds!(impl_pow_signed); macro_rules! impl_pow_primitive_int { ($t:ident) => { impl PowAssign for $t { /// Raises a number to a power, in place. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `exp.significant_bits()`. /// /// # Examples /// See [here](super::pow#pow_assign). #[inline] fn pow_assign(&mut self, exp: u64) { *self = Pow::pow(*self, exp); } } }; } apply_to_primitive_ints!(impl_pow_primitive_int); macro_rules! impl_pow_primitive_float { ($t:ident) => { impl Pow for $t { type Output = $t; /// This is a wrapper over the `powi` functions in the standard library, for example /// [this one](f32::powi). #[inline] fn pow(self, exp: i64) -> $t { libm::Libm::<$t>::pow(self, exp as $t) } } impl PowAssign for $t { /// Raises a number to a power, in place. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::pow#pow_assign). #[inline] fn pow_assign(&mut self, exp: i64) { *self = libm::Libm::<$t>::pow(*self, exp as $t); } } impl Pow<$t> for $t { type Output = $t; /// This is a wrapper over the `powf` functions in the standard library, for example /// [this one](f32::powf). #[inline] fn pow(self, exp: $t) -> $t { libm::Libm::<$t>::pow(self, exp) } } impl PowAssign<$t> for $t { /// Raises a number to a power, in place. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::pow#pow_assign). #[inline] fn pow_assign(&mut self, exp: $t) { *self = libm::Libm::<$t>::pow(*self, exp); } } }; } apply_to_primitive_floats!(impl_pow_primitive_float); malachite-base-0.4.16/src/num/arithmetic/power_of_2.rs000064400000000000000000000056461046102023000207140ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::PowerOf2; use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::IntegerMantissaAndExponent; fn power_of_2_unsigned(pow: u64) -> T { assert!(pow < T::WIDTH); T::ONE << pow } macro_rules! impl_power_of_2_unsigned { ($t:ident) => { impl PowerOf2 for $t { /// Raises 2 to an integer power. /// /// $f(k) = 2^k$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if the result is not representable. /// /// # Examples /// See [here](super::power_of_2#power_of_2). #[inline] fn power_of_2(pow: u64) -> $t { power_of_2_unsigned(pow) } } }; } apply_to_unsigneds!(impl_power_of_2_unsigned); fn power_of_2_signed(pow: u64) -> T { assert!(pow < T::WIDTH - 1); T::ONE << pow } macro_rules! impl_power_of_2_signed { ($t:ident) => { impl PowerOf2 for $t { /// Raises 2 to an integer power. /// /// $f(k) = 2^k$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if the result is not representable. /// /// # Examples /// See [here](super::power_of_2#power_of_2). #[inline] fn power_of_2(pow: u64) -> $t { power_of_2_signed(pow) } } }; } apply_to_signeds!(impl_power_of_2_signed); macro_rules! impl_power_of_2_primitive_float { ($t:ident) => { impl PowerOf2 for $t { /// Raises 2 to an integer power. /// /// $f(k) = 2^k$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if the power is smaller than `Self::MIN_EXPONENT` or greater than /// `Self::MAX_EXPONENT`. /// /// # Examples /// See [here](super::power_of_2#power_of_2). #[inline] fn power_of_2(pow: i64) -> $t { $t::from_integer_mantissa_and_exponent(1, pow).unwrap() } } }; } apply_to_primitive_floats!(impl_power_of_2_primitive_float); malachite-base-0.4.16/src/num/arithmetic/primorial.rs000064400000000000000000000233351046102023000206440ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{CheckedPrimorial, Primorial}; use crate::num::basic::integers::PrimitiveInt; use crate::num::conversion::traits::WrappingFrom; const PRIMORIALS_U8: [u8; 5] = [1, 2, 6, 30, 210]; const PRIMORIALS_U16: [u16; 7] = [1, 2, 6, 30, 210, 2310, 30030]; const PRIMORIALS_U32: [u32; 10] = [1, 2, 6, 30, 210, 2310, 30030, 510510, 9699690, 223092870]; const PRIMORIALS_U64: [u64; 16] = [ 1, 2, 6, 30, 210, 2310, 30030, 510510, 9699690, 223092870, 6469693230, 200560490130, 7420738134810, 304250263527210, 13082761331670030, 614889782588491410, ]; const PRIMORIALS_U128: [u128; 27] = [ 1, 2, 6, 30, 210, 2310, 30030, 510510, 9699690, 223092870, 6469693230, 200560490130, 7420738134810, 304250263527210, 13082761331670030, 614889782588491410, 32589158477190044730, 1922760350154212639070, 117288381359406970983270, 7858321551080267055879090, 557940830126698960967415390, 40729680599249024150621323470, 3217644767340672907899084554130, 267064515689275851355624017992790, 23768741896345550770650537601358310, 2305567963945518424753102147331756070, 232862364358497360900063316880507363070, ]; const PRIMORIAL_PRIMES_U8: [u64; 5] = [2, 3, 5, 7, 11]; const PRIMORIAL_PRIMES_U16: [u64; 7] = [2, 3, 5, 7, 11, 13, 17]; const PRIMORIAL_PRIMES_U32: [u64; 10] = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]; const PRIMORIAL_PRIMES_U64: [u64; 16] = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53]; const PRIMORIAL_PRIMES_U128: [u64; 27] = [ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, ]; macro_rules! impl_primorials_a { ($t:ident, $ps:ident, $pps:ident) => { impl CheckedPrimorial for $t { /// Computes the primorial of a number: the product of all primes less than or equal to /// it. /// /// The /// [`checked_product_of_first_n_primes`](CheckedPrimorial::checked_product_of_first_n_primes) /// function is similar; it computes the primorial of the $n$th prime. /// /// If the input is too large, the function returns `None`. /// /// $$ /// f(n) = \\begin{cases} /// \operatorname{Some}(n\\#) & \text{if} \\quad n\\# < 2^W, \\\\ /// \operatorname{None} & \text{if} \\quad n\\# \geq 2^W, /// \\end{cases} /// $$ /// where $W$ is `Self::WIDTH`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::primorial#checked_primorial). #[inline] fn checked_primorial(n: u64) -> Option<$t> { let i = match $pps.binary_search(&n) { Ok(i) => i + 1, Err(i) => i, }; $ps.get(i).copied() } /// Computes the product of the first $n$ primes. /// /// The [`checked_primorial`](CheckedPrimorial::checked_primorial) function is similar; /// it computes the product of all primes less than or equal to $n$. /// /// If the input is too large, the function returns `None`. /// /// $$ /// f(n) = \\begin{cases} /// \operatorname{Some}(p_n\\#) & \text{if} \\quad p_n\\# < 2^W, \\\\ /// \operatorname{None} & \text{if} \\quad p_n\\# \geq 2^W, /// \\end{cases} /// $$ /// where $W$ is `Self::WIDTH`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::primorial#checked_product_of_first_n_primes). #[inline] fn checked_product_of_first_n_primes(n: u64) -> Option<$t> { $ps.get(usize::try_from(n).ok()?).copied() } } }; } impl_primorials_a!(u8, PRIMORIALS_U8, PRIMORIAL_PRIMES_U8); impl_primorials_a!(u16, PRIMORIALS_U16, PRIMORIAL_PRIMES_U16); impl_primorials_a!(u32, PRIMORIALS_U32, PRIMORIAL_PRIMES_U32); impl_primorials_a!(u64, PRIMORIALS_U64, PRIMORIAL_PRIMES_U64); impl_primorials_a!(u128, PRIMORIALS_U128, PRIMORIAL_PRIMES_U128); impl CheckedPrimorial for usize { /// Computes the primorial of a [`usize`]: the product of all primes less than or equal to it. /// /// The /// [`checked_product_of_first_n_primes`](CheckedPrimorial::checked_product_of_first_n_primes) /// function is similar; it computes the primorial of the $n$th prime. /// /// If the input is too large, the function returns `None`. /// /// $$ /// f(n) = \\begin{cases} /// \operatorname{Some}(n\\#) & \text{if} \\quad n\\# < 2^W, \\\\ /// \operatorname{None} & \text{if} \\quad n\\# \geq 2^W, /// \\end{cases} /// $$ /// where $W$ is `usize::WIDTH`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::primorial#checked_primorial). #[inline] fn checked_primorial(n: u64) -> Option { match usize::WIDTH { u32::WIDTH => u32::checked_primorial(n).map(usize::wrapping_from), u64::WIDTH => u64::checked_primorial(n).map(usize::wrapping_from), _ => panic!("Unexpected usize width: {}", usize::WIDTH), } } /// Computes the product of the first $n$ primes. /// /// The [`checked_primorial`](CheckedPrimorial::checked_primorial) function is similar; it /// computes the product of all primes less than or equal to $n$. /// /// If the input is too large, the function returns `None`. /// /// $$ /// f(n) = \\begin{cases} /// \operatorname{Some}(p_n\\#) & \text{if} \\quad p_n\\# < 2^W, \\\\ /// \operatorname{None} & \text{if} \\quad p_n\\# \geq 2^W, /// \\end{cases} /// $$ /// where $W$ is `usize::WIDTH`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::primorial#checked_product_of_first_n_primes). #[inline] fn checked_product_of_first_n_primes(n: u64) -> Option { match usize::WIDTH { u32::WIDTH => u32::checked_product_of_first_n_primes(n).map(usize::wrapping_from), u64::WIDTH => u64::checked_product_of_first_n_primes(n).map(usize::wrapping_from), _ => panic!("Unexpected usize width: {}", usize::WIDTH), } } } macro_rules! impl_primorials_b { ($t:ident) => { impl Primorial for $t { /// Computes the primorial of a number: the product of all primes less than or equal to /// it. /// /// The [`product_of_first_n_primes`](Primorial::product_of_first_n_primes) function is /// similar; it computes the primorial of the $n$th prime. /// /// If the input is too large, the function panics. For a function that returns `None` /// instead, try [`checked_primorial`](CheckedPrimorial::checked_primorial). /// /// $$ /// f(n) = n\\# = \prod_{p \leq n \atop p \\ \\text {prime}} p. /// $$ /// /// $n\\# = O(e^{(1+o(1))n})$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if the output is too large to be represented. /// /// # Examples /// See [here](super::primorial#primorial). #[inline] fn primorial(n: u64) -> $t { $t::checked_primorial(n).unwrap() } /// Computes the product of the first $n$ primes. /// /// The [`primorial`](Primorial::primorial) function is similar; it computes the product /// of all primes less than or equal to $n$. /// /// If the input is too large, the function panics. For a function that returns `None` /// instead, try /// [`checked_product_of_first_n_primes`](CheckedPrimorial::checked_product_of_first_n_primes). /// /// $$ /// f(n) = p_n\\# = \prod_{k=1}^n p_n, /// $$ /// where $p_n$ is the $n$th prime number. /// /// $p_n\\# = O\left ( \left ( \frac{1}{e}k\log k\left ( \frac{\log k}{e^2}k \right /// )^{1/\log k} \right )^k \omega(1)\right )$. /// /// This asymptotic approximation is due to [Bart /// Michels](https://math.stackexchange.com/a/1594930). /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if the output is too large to be represented. /// /// # Examples /// See [here](super::primorial#product_of_first_n_primes). #[inline] fn product_of_first_n_primes(n: u64) -> $t { $t::checked_product_of_first_n_primes(n).unwrap() } } }; } apply_to_unsigneds!(impl_primorials_b); malachite-base-0.4.16/src/num/arithmetic/reciprocal.rs000064400000000000000000000061301046102023000207630ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{Reciprocal, ReciprocalAssign}; macro_rules! impl_reciprocal { ($t:ident) => { impl Reciprocal for $t { type Output = $t; /// Takes the reciprocal of a floating-point number. /// /// $$ /// f(x) = 1/x+\varepsilon. /// $$ /// Let $p$ be the precision of the input float (typically 24 for `f32`s and 53 for /// `f64`s, unless the float is subnormal). /// - If $1/x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to /// be 0. /// - If $1/x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| < /// 2^{\lfloor\log_2 |1/x|\rfloor-p+1}$. /// - If $1/x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| < /// 2^{\lfloor\log_2 |1/x|\rfloor-p}$. /// /// If the output has a precision, it is `prec`. /// /// Special cases: /// - $f(\text{NaN})=\text{NaN}$ /// - $f(\infty)=0.0$ /// - $f(-\infty)=-0.0$ /// - $f(0.0)=\infty$ /// - $f(-0.0)=-\infty$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::reciprocal#reciprocal). #[inline] fn reciprocal(self) -> $t { 1.0 / self } } impl ReciprocalAssign for $t { /// Takes the reciprocal of a floating-point number, in place. /// /// $x \gets 1/x+\varepsilon$. Let $p$ be the precision of the input float (typically 24 /// for `f32`s and 53 for `f64`s, unless the float is subnormal). /// - If $1/x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to /// be 0. /// - If $1/x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| < /// 2^{\lfloor\log_2 |1/x|\rfloor-p+1}$. /// - If $1/x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| < /// 2^{\lfloor\log_2 |1/x|\rfloor-p}$. /// /// See the `reciprocal` documentation for information on special cases. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::reciprocal#reciprocal_assign). #[inline] fn reciprocal_assign(&mut self) { *self = 1.0 / *self; } } }; } apply_to_primitive_floats!(impl_reciprocal); malachite-base-0.4.16/src/num/arithmetic/root.rs000064400000000000000000002012251046102023000176250ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // Uses code adopted from the FLINT Library. // // Copyright © 2015 William Hart // // Copyright © 2015 Fredrik Johansson // // Copyright © 2015 Kushagra Singh // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . #[cfg(feature = "test_build")] use crate::num::arithmetic::sqrt::floor_inverse_checked_binary; #[cfg(feature = "test_build")] use crate::num::arithmetic::traits::DivRound; use crate::num::arithmetic::traits::{ CeilingRoot, CeilingRootAssign, CeilingSqrt, CheckedRoot, CheckedSqrt, DivMod, FloorRoot, FloorRootAssign, FloorSqrt, Parity, Pow, PowerOf2, RootAssignRem, RootRem, SqrtRem, XMulYToZZ, }; use crate::num::basic::floats::PrimitiveFloat; use crate::num::basic::integers::PrimitiveInt; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::{ RawMantissaAndExponent, RoundingFrom, SaturatingFrom, WrappingFrom, }; use crate::num::logic::traits::{LowMask, SignificantBits}; use crate::rounding_modes::RoundingMode::*; use core::cmp::Ordering::*; const U8_CUBES: [u8; 7] = [0, 1, 8, 27, 64, 125, 216]; // This section is created by max_base.rs. const MAX_BASE_8: [u8; 8] = [0, 255, 15, 6, 3, 3, 2, 2]; const MAX_POWER_8: [u8; 8] = [0, 255, 225, 216, 81, 243, 64, 128]; const MAX_BASE_16: [u16; 16] = [0, 65535, 255, 40, 15, 9, 6, 4, 3, 3, 3, 2, 2, 2, 2, 2]; const MAX_POWER_16: [u16; 16] = [ 0, 65535, 65025, 64000, 50625, 59049, 46656, 16384, 6561, 19683, 59049, 2048, 4096, 8192, 16384, 32768, ]; const MAX_BASE_32: [u32; 32] = [ 0, 4294967295, 65535, 1625, 255, 84, 40, 23, 15, 11, 9, 7, 6, 5, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ]; const MAX_POWER_32: [u32; 32] = [ 0, 4294967295, 4294836225, 4291015625, 4228250625, 4182119424, 4096000000, 3404825447, 2562890625, 2357947691, 3486784401, 1977326743, 2176782336, 1220703125, 268435456, 1073741824, 43046721, 129140163, 387420489, 1162261467, 3486784401, 2097152, 4194304, 8388608, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824, 2147483648, ]; const MAX_BASE_64: [u64; 64] = [ 0, 18446744073709551615, 4294967295, 2642245, 65535, 7131, 1625, 565, 255, 138, 84, 56, 40, 30, 23, 19, 15, 13, 11, 10, 9, 8, 7, 6, 6, 5, 5, 5, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ]; const MAX_POWER_64: [u64; 64] = [ 0, 18446744073709551615, 18446744065119617025, 18446724184312856125, 18445618199572250625, 18439629140666724651, 18412815093994140625, 18379730316001328125, 17878103347812890625, 18151468971815029248, 17490122876598091776, 16985107389382393856, 16777216000000000000, 15943230000000000000, 11592836324538749809, 15181127029874798299, 6568408355712890625, 8650415919381337933, 5559917313492231481, 10000000000000000000, 12157665459056928801, 9223372036854775808, 3909821048582988049, 789730223053602816, 4738381338321616896, 298023223876953125, 1490116119384765625, 7450580596923828125, 72057594037927936, 288230376151711744, 1152921504606846976, 4611686018427387904, 1853020188851841, 5559060566555523, 16677181699666569, 50031545098999707, 150094635296999121, 450283905890997363, 1350851717672992089, 4052555153018976267, 12157665459056928801, 2199023255552, 4398046511104, 8796093022208, 17592186044416, 35184372088832, 70368744177664, 140737488355328, 281474976710656, 562949953421312, 1125899906842624, 2251799813685248, 4503599627370496, 9007199254740992, 18014398509481984, 36028797018963968, 72057594037927936, 144115188075855872, 288230376151711744, 576460752303423488, 1152921504606846976, 2305843009213693952, 4611686018427387904, 9223372036854775808, ]; const MAX_BASE_128: [u128; 128] = [ 0, 340282366920938463463374607431768211455, 18446744073709551615, 6981463658331, 4294967295, 50859008, 2642245, 319557, 65535, 19112, 7131, 3183, 1625, 920, 565, 370, 255, 184, 138, 106, 84, 68, 56, 47, 40, 34, 30, 26, 23, 21, 19, 17, 15, 14, 13, 12, 11, 11, 10, 9, 9, 8, 8, 7, 7, 7, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ]; const MAX_POWER_128: [u128; 128] = [ 0, 340282366920938463463374607431768211455, 340282366920938463426481119284349108225, 340282366920856711588743492508790678691, 340282366604025813516997721482669850625, 340282351457171161640582485552312352768, 340281633132112807150397932954950015625, 340281506971235808117106851925354131693, 340240830764391036687105719527812890625, 340216388952569572744243119867142602752, 340019922845325450206316382040251071801, 339784078391451014674643196649809097167, 339031759685618453659117221832275390625, 338253076642491662461829120000000000000, 337814486488938281014651876763916015625, 333446267951815307088493000000000000000, 319626579315078487616775634918212890625, 317616452802997733092688724349413228544, 329475825834763755052723200291095445504, 302559950208758936970093677790372560896, 305904398238499908683087849324518834176, 303869538891536196286006028740295917568, 288493873028852398739253829029106548736, 287243845682065590744605010781602099023, 281474976710656000000000000000000000000, 193630125104980427932766033374162714624, 254186582832900000000000000000000000000, 160059109085386090080713531498405298176, 134393854047545109686936775588697536481, 220983347100817338120002444455525554981, 230466617897195215045509519405933293401, 139288917338851014461418017489467720433, 43143988327398919500410556793212890625, 66408730383449729837806206197059026944, 74829695578286078013428929473144712489, 59066822915424320448445358917464096768, 30912680532870672635673352936887453361, 340039485861577398992406882305761986971, 100000000000000000000000000000000000000, 16423203268260658146231467800709255289, 147808829414345923316083210206383297601, 10633823966279326983230456482242756608, 85070591730234615865843651857942052864, 2183814375991796599109312252753832343, 15286700631942576193765185769276826401, 107006904423598033356356300384937784807, 623673825204293256669089197883129856, 3742042951225759540014535187298779136, 22452257707354557240087211123792674816, 134713546244127343440523266742756048896, 88817841970012523233890533447265625, 444089209850062616169452667236328125, 2220446049250313080847263336181640625, 11102230246251565404236316680908203125, 55511151231257827021181583404541015625, 277555756156289135105907917022705078125, 5192296858534827628530496329220096, 20769187434139310514121985316880384, 83076749736557242056487941267521536, 332306998946228968225951765070086144, 1329227995784915872903807060280344576, 5316911983139663491615228241121378304, 21267647932558653966460912964485513216, 85070591730234615865843651857942052864, 3433683820292512484657849089281, 10301051460877537453973547267843, 30903154382632612361920641803529, 92709463147897837085761925410587, 278128389443693511257285776231761, 834385168331080533771857328695283, 2503155504993241601315571986085849, 7509466514979724803946715958257547, 22528399544939174411840147874772641, 67585198634817523235520443624317923, 202755595904452569706561330872953769, 608266787713357709119683992618861307, 1824800363140073127359051977856583921, 5474401089420219382077155933569751763, 16423203268260658146231467800709255289, 49269609804781974438694403402127765867, 147808829414345923316083210206383297601, 2417851639229258349412352, 4835703278458516698824704, 9671406556917033397649408, 19342813113834066795298816, 38685626227668133590597632, 77371252455336267181195264, 154742504910672534362390528, 309485009821345068724781056, 618970019642690137449562112, 1237940039285380274899124224, 2475880078570760549798248448, 4951760157141521099596496896, 9903520314283042199192993792, 19807040628566084398385987584, 39614081257132168796771975168, 79228162514264337593543950336, 158456325028528675187087900672, 316912650057057350374175801344, 633825300114114700748351602688, 1267650600228229401496703205376, 2535301200456458802993406410752, 5070602400912917605986812821504, 10141204801825835211973625643008, 20282409603651670423947251286016, 40564819207303340847894502572032, 81129638414606681695789005144064, 162259276829213363391578010288128, 324518553658426726783156020576256, 649037107316853453566312041152512, 1298074214633706907132624082305024, 2596148429267413814265248164610048, 5192296858534827628530496329220096, 10384593717069655257060992658440192, 20769187434139310514121985316880384, 41538374868278621028243970633760768, 83076749736557242056487941267521536, 166153499473114484112975882535043072, 332306998946228968225951765070086144, 664613997892457936451903530140172288, 1329227995784915872903807060280344576, 2658455991569831745807614120560689152, 5316911983139663491615228241121378304, 10633823966279326983230456482242756608, 21267647932558653966460912964485513216, 42535295865117307932921825928971026432, 85070591730234615865843651857942052864, 170141183460469231731687303715884105728, ]; pub_test! {floor_root_approx_and_refine f64, G: Fn(f64) -> T>( f: F, g: G, x: T, exp: u64, ) -> T { assert_ne!(exp, 0); if x == T::ZERO || exp == 1 { return x; } if exp >= T::WIDTH { return T::ONE; } let exp_usize = usize::wrapping_from(exp); let max_root = match T::WIDTH { u8::WIDTH => T::wrapping_from(MAX_BASE_8[exp_usize]), u16::WIDTH => T::wrapping_from(MAX_BASE_16[exp_usize]), u32::WIDTH => T::wrapping_from(MAX_BASE_32[exp_usize]), u64::WIDTH => T::wrapping_from(MAX_BASE_64[exp_usize]), u128::WIDTH => T::wrapping_from(MAX_BASE_128[exp_usize]), _ => unreachable!(), }; let max_pow = match T::WIDTH { u8::WIDTH => T::wrapping_from(MAX_POWER_8[exp_usize]), u16::WIDTH => T::wrapping_from(MAX_POWER_16[exp_usize]), u32::WIDTH => T::wrapping_from(MAX_POWER_32[exp_usize]), u64::WIDTH => T::wrapping_from(MAX_POWER_64[exp_usize]), u128::WIDTH => T::wrapping_from(MAX_POWER_128[exp_usize]), _ => unreachable!(), }; if x >= max_pow { return max_root; } let mut root = g(f(x).pow(1.0 / (exp as f64))); let mut pow = if let Some(pow) = root.checked_pow(exp) { pow } else { // set to max possible pow root = max_root; max_pow }; match pow.cmp(&x) { Equal => root, Less => loop { root += T::ONE; pow = root.pow(exp); match pow.cmp(&x) { Equal => return root, Less => {} Greater => return root - T::ONE, } }, Greater => loop { root -= T::ONE; pow = root.pow(exp); if pow <= x { return root; } }, } }} // Coefficients of Chebyshev's approximation polynomial (deg 2) {c0, c1, c2} splitting 0.5 to 1 into // 8 equal intervals // // Values of these coefficients of Chebyshev's approximation polynomial have been calculated from // the python module, "mpmath" - http://mpmath.org/ function call: mpmath.chebyfit(lambda x: // mpmath.root(x,3), [i, j], 3, error=True) where (i, j) is the range. // // ``` // c0 c1 c2 range // 0.445434042 0.864136635 -0.335205926 [0.50000, 0.53125] // 0.454263239 0.830878907 -0.303884962 [0.53125, 0.56250] // 0.462761624 0.800647514 -0.276997626 [0.56250, 0.59375] // 0.470958569 0.773024522 -0.253724515 [0.59375, 0.62500] // 0.478879482 0.747667468 -0.233429710 [0.62500, 0.65625] // 0.486546506 0.724292830 -0.215613166 [0.65625, 0.68750] // 0.493979069 0.702663686 -0.199877008 [0.68750, 0.71875] // 0.501194325 0.682580388 -0.185901247 [0.71875, 0.75000] // 0.508207500 0.663873398 -0.173426009 [0.75000, 0.78125] // 0.515032183 0.646397742 -0.162238357 [0.78125, 0.81250] // 0.521680556 0.630028647 -0.152162376 [0.81250, 0.84375] // 0.528163588 0.614658092 -0.143051642 [0.84375, 0.87500] // 0.534491194 0.600192044 -0.134783425 [0.87500, 0.90625] // 0.540672371 0.586548233 -0.127254189 [0.90625, 0.93750] // 0.546715310 0.573654340 -0.120376066 [0.93750, 0.96875] // 0.552627494 0.561446514 -0.114074068 [0.96875, 1.00000] // ``` // // 1^(1/3), 2^(1/3), 4^(1/3) const FACTOR_TABLE: [f32; 3] = [1.000000, 1.259921, 1.587401]; #[allow(clippy::excessive_precision)] const COEFF: [[f32; 3]; 16] = [ [0.445434042, 0.864136635, -0.335205926], [0.454263239, 0.830878907, -0.303884962], [0.462761624, 0.800647514, -0.276997626], [0.470958569, 0.773024522, -0.253724515], [0.478879482, 0.747667468, -0.233429710], [0.486546506, 0.724292830, -0.215613166], [0.493979069, 0.702663686, -0.199877008], [0.501194325, 0.682580388, -0.185901247], [0.508207500, 0.663873398, -0.173426009], [0.515032183, 0.646397742, -0.162238357], [0.521680556, 0.630028647, -0.152162376], [0.528163588, 0.614658092, -0.143051642], [0.534491194, 0.600192044, -0.134783425], [0.540672371, 0.586548233, -0.127254189], [0.546715310, 0.573654340, -0.120376066], [0.552627494, 0.561446514, -0.114074068], ]; // n cannot be 0 // // This is equivalent to `n_cbrt_chebyshev_approx` from // `ulong_extras/cbrt_chebyshev_approximation.c`, FLINT 2.7.1, where `FLINT64` is `false`. pub_test! {cbrt_chebyshev_approx_u32(n: u32) -> u32 { // UPPER_LIMIT is the max cube root possible for one word const UPPER_LIMIT: u32 = 1625; // 1625 < (2^32)^(1/3) const BIAS_HEX: u32 = 0x3f000000; const BIAS: u32 = 126; let (mantissa, exponent) = (n as f32).raw_mantissa_and_exponent(); let mut mantissa = u32::wrapping_from(mantissa); let table_index = usize::wrapping_from(mantissa >> (f32::MANTISSA_WIDTH - 4)); mantissa |= BIAS_HEX; let (exponent_over_3, exponent_rem) = (u32::wrapping_from(exponent) - BIAS).div_mod(3); // Calculating cube root of dec using Chebyshev approximation polynomial // // Evaluating approx polynomial at (dec) by Estrin's scheme let x = f32::from_bits(mantissa); let row = COEFF[table_index]; let mut cbrt = ((row[0] + row[1] * x + row[2] * (x * x)) * f32::power_of_2(i64::wrapping_from(exponent_over_3)) * FACTOR_TABLE[usize::wrapping_from(exponent_rem)]) as u32; const MAX_CUBE: u32 = UPPER_LIMIT * UPPER_LIMIT * UPPER_LIMIT; if cbrt >= UPPER_LIMIT { if n >= MAX_CUBE { return UPPER_LIMIT; } cbrt = UPPER_LIMIT - 1; } while cbrt * cbrt * cbrt <= n { cbrt += 1; if cbrt == UPPER_LIMIT { break; } } while cbrt * cbrt * cbrt > n { cbrt -= 1; } cbrt }} // n cannot be 0 // // This is equivalent to `n_cbrt_chebyshev_approx` from // `ulong_extras/cbrt_chebyshev_approximation.c`, FLINT 2.7.1, where `FLINT64` is `true`. pub_test! {cbrt_chebyshev_approx_u64(n: u64) -> u64 { // UPPER_LIMIT is the max cube root possible for one word const UPPER_LIMIT: u64 = 2642245; // 2642245 < (2^64)^(1/3) const BIAS_HEX: u64 = 0x3fe0000000000000; const BIAS: u64 = 1022; let (mut mantissa, exponent) = (n as f64).raw_mantissa_and_exponent(); let table_index = usize::wrapping_from(mantissa >> (f64::MANTISSA_WIDTH - 4)); mantissa |= BIAS_HEX; let (exponent_over_3, exponent_rem) = (exponent - BIAS).div_mod(3); // Calculating cube root of dec using Chebyshev approximation polynomial // // Evaluating approx polynomial at x by Estrin's scheme let x = f64::from_bits(mantissa); let row = COEFF[table_index]; let mut cbrt = ((f64::from(row[0]) + f64::from(row[1]) * x + f64::from(row[2]) * (x * x)) * f64::power_of_2(i64::wrapping_from(exponent_over_3)) * f64::from(FACTOR_TABLE[usize::wrapping_from(exponent_rem)])) as u64; const MAX_CUBE: u64 = UPPER_LIMIT * UPPER_LIMIT * UPPER_LIMIT; if cbrt >= UPPER_LIMIT { if n >= MAX_CUBE { return UPPER_LIMIT; } cbrt = UPPER_LIMIT - 1; } while cbrt * cbrt * cbrt <= n { cbrt += 1; if cbrt == UPPER_LIMIT { break; } } while cbrt * cbrt * cbrt > n { cbrt -= 1; } cbrt }} // This is equivalent to `n_cbrt_estimate` from `ulong_extras/n_cbrt_estimate.c`, FLINT 2.7.1, where // `FLINT64` is `true`. #[cfg(feature = "test_build")] fn cbrt_estimate_f64(a: f64) -> f64 { const S: u64 = 4607182418800017408; // ((1 << 10) - 1) << 52 f64::from_bits( u64::wrapping_from((u128::from(a.to_bits() - S) * 6148914691236517205) >> 64) + S, ) } // This is equivalent to `n_cbrt` from `ulong_extras/cbrt.c`, FLINT 2.7.1, where `FLINT64` is // `false`. #[cfg(feature = "test_build")] pub fn fast_floor_cbrt_u32(n: u32) -> u32 { // Taking care of smaller roots if n < 125 { return if n >= 64 { 4 } else if n >= 27 { 3 } else if n >= 8 { 2 } else { u32::from(n >= 1) }; } if n < 1331 { return if n >= 1000 { 10 } else if n >= 729 { 9 } else if n >= 512 { 8 } else if n >= 343 { 7 } else if n >= 216 { 6 } else { 5 }; } if n < 4913 { return if n >= 4096 { 16 } else if n >= 3375 { 15 } else if n >= 2744 { 14 } else if n >= 2197 { 13 } else if n >= 1728 { 12 } else { 11 }; } let val = f64::from(n); const UPPER_LIMIT: u32 = 1625; // 1625 < (2^32)^(1/3) let mut x = cbrt_estimate_f64(val); // Kahan's iterations to get cube root let xcub = x * x * x; let num = (xcub - val) * x; let den = xcub + xcub + val; x -= num / den; let mut ret = x as u32; const UPPER_LIMIT_CUBE: u32 = UPPER_LIMIT * UPPER_LIMIT * UPPER_LIMIT; // In case ret ^ 3 or (ret + 1) ^ 3 will cause overflow if ret >= UPPER_LIMIT { if n >= UPPER_LIMIT_CUBE { return UPPER_LIMIT; } ret = UPPER_LIMIT - 1; } while ret * ret * ret <= n { ret += 1; if ret == UPPER_LIMIT { break; } } while ret * ret * ret > n { ret -= 1; } ret } // TODO tune #[cfg(feature = "test_build")] const CBRT_CHEBYSHEV_THRESHOLD: u64 = 10; // This is equivalent to `n_cbrt` from `ulong_extras/cbrt.c`, FLINT 2.7.1, where `FLINT64` is // `true`. #[cfg(feature = "test_build")] pub fn fast_floor_cbrt_u64(n: u64) -> u64 { // Taking care of smaller roots if n < 125 { return if n >= 64 { 4 } else if n >= 27 { 3 } else if n >= 8 { 2 } else { u64::from(n >= 1) }; } if n < 1331 { return if n >= 1000 { 10 } else if n >= 729 { 9 } else if n >= 512 { 8 } else if n >= 343 { 7 } else if n >= 216 { 6 } else { 5 }; } if n < 4913 { return if n >= 4096 { 16 } else if n >= 3375 { 15 } else if n >= 2744 { 14 } else if n >= 2197 { 13 } else if n >= 1728 { 12 } else { 11 }; } if n.significant_bits() > CBRT_CHEBYSHEV_THRESHOLD { return cbrt_chebyshev_approx_u64(n); } let val = n as f64; const UPPER_LIMIT: u64 = 2642245; // 2642245 < (2^64)^(1/3) let mut x = cbrt_estimate_f64(val); // Kahan's iterations to get cube root let xcub = x * x * x; let num = (xcub - val) * x; let den = xcub + xcub + val; x -= num / den; let mut ret = x as u64; const UPPER_LIMIT_CUBE: u64 = UPPER_LIMIT * UPPER_LIMIT * UPPER_LIMIT; // In case ret ^ 3 or (ret + 1) ^ 3 will cause overflow if ret >= UPPER_LIMIT { if n >= UPPER_LIMIT_CUBE { return UPPER_LIMIT; } ret = UPPER_LIMIT - 1; } while ret * ret * ret <= n { ret += 1; if ret == UPPER_LIMIT { break; } } while ret * ret * ret > n { ret -= 1; } ret } // this table contains the value of UWORD_MAX / n, for n in range [1, 32] const MUL_FACTOR_32: [u32; 33] = [ 0, u32::MAX, 2147483647, 1431655765, 1073741823, 858993459, 715827882, 613566756, 536870911, 477218588, 429496729, 390451572, 357913941, 330382099, 306783378, 286331153, 268435455, 252645135, 238609294, 226050910, 214748364, 204522252, 195225786, 186737708, 178956970, 171798691, 165191049, 159072862, 153391689, 148102320, 143165576, 138547332, 134217727, ]; // this table contains the value of UWORD_MAX / n, for n in range [1, 64] const MUL_FACTOR_64: [u64; 65] = [ 0, u64::MAX, 9223372036854775807, 6148914691236517205, 4611686018427387903, 3689348814741910323, 3074457345618258602, 2635249153387078802, 2305843009213693951, 2049638230412172401, 1844674407370955161, 1676976733973595601, 1537228672809129301, 1418980313362273201, 1317624576693539401, 1229782938247303441, 1152921504606846975, 1085102592571150095, 1024819115206086200, 970881267037344821, 922337203685477580, 878416384462359600, 838488366986797800, 802032351030850070, 768614336404564650, 737869762948382064, 709490156681136600, 683212743470724133, 658812288346769700, 636094623231363848, 614891469123651720, 595056260442243600, 576460752303423487, 558992244657865200, 542551296285575047, 527049830677415760, 512409557603043100, 498560650640798692, 485440633518672410, 472993437787424400, 461168601842738790, 449920587163647600, 439208192231179800, 428994048225803525, 419244183493398900, 409927646082434480, 401016175515425035, 392483916461905353, 384307168202282325, 376464164769582686, 368934881474191032, 361700864190383365, 354745078340568300, 348051774975651917, 341606371735362066, 335395346794719120, 329406144173384850, 323627089012448273, 318047311615681924, 312656679215416129, 307445734561825860, 302405640552615600, 297528130221121800, 292805461487453200, 288230376151711743, ]; // This is equivalent to `n_root_estimate` from `ulong_extras/root_estimate.c`, FLINT 2.7.1, where // `FLINT64` is `false`. fn root_estimate_32(a: f64, n: usize) -> u32 { let s = u32::low_mask(f32::EXPONENT_WIDTH - 1) << f32::MANTISSA_WIDTH; f32::from_bits(u32::x_mul_y_to_zz((a as f32).to_bits() - s, MUL_FACTOR_32[n]).0 + s) as u32 } // This is equivalent to `n_root_estimate` from `ulong_extras/root_estimate.c`, FLINT 2.7.1, where // `FLINT64` is `true`. fn root_estimate_64(a: f64, n: usize) -> u64 { let s = u64::low_mask(f64::EXPONENT_WIDTH - 1) << f64::MANTISSA_WIDTH; f64::from_bits(u64::x_mul_y_to_zz(a.to_bits() - s, MUL_FACTOR_64[n]).0 + s) as u64 } const INV_TABLE: [f64; 65] = [ 0.000000000000000, 1.000000000000000, 0.500000000000000, 0.333333333333333, 0.250000000000000, 0.200000000000000, 0.166666666666667, 0.142857142857143, 0.125000000000000, 0.111111111111111, 0.100000000000000, 0.090909090909091, 0.083333333333333, 0.076923076923077, 0.071428571428571, 0.066666666666667, 0.062500000000000, 0.058823529411765, 0.055555555555556, 0.052631578947368, 0.050000000000000, 0.047619047619048, 0.045454545454545, 0.043478260869565, 0.041666666666667, 0.040000000000000, 0.038461538461538, 0.037037037037037, 0.035714285714286, 0.034482758620690, 0.033333333333333, 0.032258064516129, 0.031250000000000, 0.030303030303030, 0.029411764705882, 0.028571428571429, 0.027777777777778, 0.027027027027027, 0.026315789473684, 0.025641025641026, 0.025000000000000, 0.024390243902439, 0.023809523809524, 0.023255813953488, 0.022727272727273, 0.022222222222222, 0.021739130434783, 0.021276595744681, 0.020833333333333, 0.020408163265306, 0.020000000000000, 0.019607843137255, 0.019230769230769, 0.018867924528302, 0.018518518518519, 0.018181818181818, 0.017857142857143, 0.017543859649123, 0.017241379310345, 0.016949152542373, 0.016666666666667, 0.016393442622951, 0.016129032258065, 0.015873015873016, 0.015625000000000, ]; // This is equivalent to `n_root` from `ulong_extras/root.c`, FLINT 2.7.1, where `FLINT64` is // `false` and `root` is nonzero. pub_test! {fast_floor_root_u32(n: u32, exp: u64) -> u32 { assert_ne!(exp, 0); if n < 2 || exp == 1 { return n; } if exp >= u32::WIDTH || n.significant_bits() <= exp { return 1; } if exp == 2 { return n.floor_sqrt(); } if exp == 3 { return cbrt_chebyshev_approx_u32(n); } let exp = u32::wrapping_from(exp); let exp_usize = usize::wrapping_from(exp); let upper_limit = MAX_BASE_32[exp_usize]; // n <= upper_limit ^ exp let x = root_estimate_32(f64::from(n), exp_usize); // one round of Newton iteration let mut root = u32::rounding_from( (f64::from(n / x.pow(exp - 1)) - f64::from(x)) * INV_TABLE[exp_usize], Down, ).0; if root >= upper_limit { root = upper_limit - 1; } let mut pow = root.pow(exp); if pow == n { return root; } while pow <= n { root += 1; pow = root.pow(exp); if root == upper_limit { break; } } while pow > n { root -= 1; pow = root.pow(exp); } root }} // This is equivalent to `n_root` from `ulong_extras/root.c`, FLINT 2.7.1, where `FLINT64` is `true` // and `root` is nonzero. pub_test! {fast_floor_root_u64(n: u64, exp: u64) -> u64 { assert_ne!(exp, 0); if n < 2 || exp == 1 { return n; } if exp == 2 { return n.floor_sqrt(); } if exp == 3 { return cbrt_chebyshev_approx_u64(n); } if exp >= u64::WIDTH || (1 << exp) > n { return 1; } let exp = u32::wrapping_from(exp); let exp_usize = usize::wrapping_from(exp); let upper_limit = MAX_BASE_64[exp_usize]; // n <= upper_limit ^ exp let x = root_estimate_64(n as f64, exp_usize); // one round of Newton iteration let mut root = u64::rounding_from( (((n / x.saturating_pow(exp - 1)) as f64) - x as f64) * INV_TABLE[exp_usize], Down, ).0; if root >= upper_limit { root = upper_limit - 1; } let mut pow = root.pow(exp); if pow == n { return root; } while pow <= n { root += 1; pow = root.pow(exp); if root == upper_limit { break; } } while pow > n { root -= 1; pow = root.pow(exp); } root }} pub_test! {fast_ceiling_root_u32(n: u32, exp: u64) -> u32 { assert_ne!(exp, 0); if n < 2 || exp == 1 { return n; } if exp >= u32::WIDTH || n.significant_bits() <= exp { return 2; } if exp == 2 { return n.ceiling_sqrt(); } if exp == 3 { let root = cbrt_chebyshev_approx_u32(n); return if root.pow(3) == n { root } else { root + 1 }; } let exp = u32::wrapping_from(exp); let exp_usize = usize::wrapping_from(exp); let upper_limit = MAX_BASE_32[exp_usize]; // n <= upper_limit ^ exp let x = root_estimate_32(f64::from(n), exp_usize); // one round of Newton iteration let mut root = u32::rounding_from( (f64::from(n / x.pow(exp - 1)) - f64::from(x)) * INV_TABLE[exp_usize], Down, ).0; if root >= upper_limit { root = upper_limit - 1; } let mut pow = root.pow(exp); if pow == n { return root; } while pow <= n { root += 1; pow = root.pow(exp); if root == upper_limit { break; } } while pow > n { root -= 1; pow = root.pow(exp); } if pow == n { root } else { root + 1 } }} pub_test! {fast_ceiling_root_u64(n: u64, exp: u64) -> u64 { assert_ne!(exp, 0); if n < 2 || exp == 1 { return n; } if exp >= u64::WIDTH || n.significant_bits() <= exp { return 2; } if exp == 2 { return n.ceiling_sqrt(); } if exp == 3 { let root = cbrt_chebyshev_approx_u64(n); return if root.pow(3) == n { root } else { root + 1 }; } let exp = u32::wrapping_from(exp); let exp_usize = usize::wrapping_from(exp); let upper_limit = MAX_BASE_64[exp_usize]; // n <= upper_limit ^ root let x = root_estimate_64(n as f64, exp_usize); // one round of Newton iteration let mut root = u64::rounding_from( (((n / x.pow(exp - 1)) as f64) - x as f64) * INV_TABLE[exp_usize], Down, ).0; if root >= upper_limit { root = upper_limit - 1; } let mut pow = root.pow(exp); if pow == n { return root; } while pow <= n { root += 1; pow = root.pow(exp); if root == upper_limit { break; } } while pow > n { root -= 1; pow = root.pow(exp); } if pow == n { root } else { root + 1 } }} pub_test! {fast_checked_root_u32(n: u32, exp: u64) -> Option { assert_ne!(exp, 0); if n < 2 || exp == 1 { return Some(n); } if exp >= u32::WIDTH || n.significant_bits() <= exp { return None; } if exp == 2 { return n.checked_sqrt(); } if exp == 3 { let root = cbrt_chebyshev_approx_u32(n); return if root.pow(3) == n { Some(root) } else { None }; } let exp = u32::wrapping_from(exp); let exp_usize = usize::wrapping_from(exp); let upper_limit = MAX_BASE_32[exp_usize]; // n <= upper_limit ^ exp let x = root_estimate_32(f64::from(n), exp_usize); // one round of Newton iteration let mut root = u32::rounding_from( (f64::from(n / x.pow(exp - 1)) - f64::from(x)) * INV_TABLE[exp_usize], Down, ).0; if root >= upper_limit { root = upper_limit - 1; } let mut pow = root.pow(exp); if pow == n { return Some(root); } while pow <= n { root += 1; pow = root.pow(exp); if root == upper_limit { break; } } while pow > n { root -= 1; pow = root.pow(exp); } if pow == n { Some(root) } else { None } }} pub_test! {fast_checked_root_u64(n: u64, exp: u64) -> Option { assert_ne!(exp, 0); if n < 2 || exp == 1 { return Some(n); } if exp >= u64::WIDTH || n.significant_bits() <= exp { return None; } if exp == 2 { return n.checked_sqrt(); } if exp == 3 { let root = cbrt_chebyshev_approx_u64(n); return if root.pow(3) == n { Some(root) } else { None }; } let exp = u32::wrapping_from(exp); let exp_usize = usize::wrapping_from(exp); let upper_limit = MAX_BASE_64[exp_usize]; // n <= upper_limit ^ root let x = root_estimate_64(n as f64, exp_usize); // one round of Newton iteration let mut root = u64::rounding_from( (((n / x.pow(exp - 1)) as f64) - x as f64) * INV_TABLE[exp_usize], Down, ).0; if root >= upper_limit { root = upper_limit - 1; } let mut pow = root.pow(exp); if pow == n { return Some(root); } while pow <= n { root += 1; pow = root.pow(exp); if root == upper_limit { break; } } while pow > n { root -= 1; pow = root.pow(exp); } if pow == n { Some(root) } else { None } }} pub_test! {fast_root_rem_u32(n: u32, exp: u64) -> (u32, u32) { assert_ne!(exp, 0); if n < 2 || exp == 1 { return (n, 0); } if exp >= u32::WIDTH || n.significant_bits() <= exp { return (1, n - 1); } if exp == 2 { return n.sqrt_rem(); } if exp == 3 { let root = cbrt_chebyshev_approx_u32(n); let pow = root.pow(3); return (root, n - pow); } let exp = u32::wrapping_from(exp); let exp_usize = usize::wrapping_from(exp); let upper_limit = MAX_BASE_32[exp_usize]; // n <= upper_limit ^ exp let x = root_estimate_32(f64::from(n), exp_usize); // one round of Newton iteration let mut root = u32::rounding_from( (f64::from(n / x.pow(exp - 1)) - f64::from(x)) * INV_TABLE[exp_usize], Down, ).0; if root >= upper_limit { root = upper_limit - 1; } let mut pow = root.pow(exp); if pow == n { return (root, 0); } while pow <= n { root += 1; pow = root.pow(exp); if root == upper_limit { break; } } while pow > n { root -= 1; pow = root.pow(exp); } (root, n - pow) }} pub_test! {fast_root_rem_u64(n: u64, exp: u64) -> (u64, u64) { assert_ne!(exp, 0); if n < 2 || exp == 1 { return (n, 0); } if exp >= u64::WIDTH || n.significant_bits() <= exp { return (1, n - 1); } if exp == 2 { return n.sqrt_rem(); } if exp == 3 { let root = cbrt_chebyshev_approx_u64(n); let pow = root.pow(3); return (root, n - pow); } let exp = u32::wrapping_from(exp); let exp_usize = usize::wrapping_from(exp); let upper_limit = MAX_BASE_64[exp_usize]; // n <= upper_limit ^ root let x = root_estimate_64(n as f64, exp_usize); // one round of Newton iteration let mut root = u64::rounding_from( (((n / x.pow(exp - 1)) as f64) - x as f64) * INV_TABLE[exp_usize], Down, ).0; if root >= upper_limit { root = upper_limit - 1; } let mut pow = root.pow(exp); if pow == n { return (root, 0); } while pow <= n { root += 1; pow = root.pow(exp); if root == upper_limit { break; } } while pow > n { root -= 1; pow = root.pow(exp); } (root, n - pow) }} #[cfg(feature = "test_build")] pub fn floor_root_binary(x: T, exp: u64) -> T { if exp == 0 { panic!("Cannot take 0th root"); } else if exp == 1 || x < T::TWO { x } else { let bits = x.significant_bits(); if bits <= exp { T::ONE } else { let p = T::power_of_2(bits.div_round(exp, Ceiling).0); floor_inverse_checked_binary(|i| i.checked_pow(exp), x, p >> 1, p) } } } #[cfg(feature = "test_build")] pub fn ceiling_root_binary(x: T, exp: u64) -> T { let floor_root = floor_root_binary(x, exp); if floor_root.pow(exp) == x { floor_root } else { floor_root + T::ONE } } #[cfg(feature = "test_build")] pub fn checked_root_binary(x: T, exp: u64) -> Option { let floor_root = floor_root_binary(x, exp); if floor_root.pow(exp) == x { Some(floor_root) } else { None } } #[cfg(feature = "test_build")] pub fn root_rem_binary(x: T, exp: u64) -> (T, T) { let floor_root = floor_root_binary(x, exp); (floor_root, x - floor_root.pow(exp)) } impl FloorRoot for u8 { type Output = u8; /// Returns the floor of the $n$th root of a [`u8`]. /// /// $f(x, n) = \lfloor\sqrt\[n\]{x}\rfloor$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `exp` is zero. /// /// # Examples /// See [here](super::root#floor_root). /// /// # Notes /// The [`u8`] implementation uses lookup tables. #[inline] fn floor_root(self, exp: u64) -> u8 { match (self, exp) { (_, 0) => panic!(), (0 | 1, _) | (_, 1) => self, (_, 8..=u64::MAX) => 1, (x, 2) => x.floor_sqrt(), (x, 3) => u8::wrapping_from(match U8_CUBES.binary_search(&x) { Ok(i) => i, Err(i) => i - 1, }), (x, 4) if x < 16 => 1, (x, 4) if x < 81 => 2, (x, 5) if x < 32 => 1, (x, 5) if x < 243 => 2, (_, 4 | 5) => 3, (x, 6) if x < 64 => 1, (x, 7) if x < 128 => 1, (_, 6 | 7) => 2, } } } impl CeilingRoot for u8 { type Output = u8; /// Returns the ceiling of the $n$th root of a [`u8`]. /// /// $f(x, n) = \lceil\sqrt\[n\]{x}\rceil$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `exp` is zero. /// /// # Examples /// See [here](super::root#ceiling_root). /// /// # Notes /// The [`u8`] implementation uses lookup tables. fn ceiling_root(self, exp: u64) -> u8 { match (self, exp) { (_, 0) => panic!(), (0 | 1, _) | (_, 1) => self, (_, 8..=u64::MAX) => 2, (x, 2) => x.ceiling_sqrt(), (x, 3) => u8::wrapping_from(match U8_CUBES.binary_search(&x) { Ok(i) | Err(i) => i, }), (x, 4) if x <= 16 => 2, (x, 4) if x <= 81 => 3, (x, 5) if x <= 32 => 2, (x, 5) if x <= 243 => 3, (_, 4 | 5) => 4, (x, 6) if x <= 64 => 2, (x, 7) if x <= 128 => 2, (_, 6 | 7) => 3, } } } impl CheckedRoot for u8 { type Output = u8; /// Returns the the $n$th root of a [`u8`], or `None` if the [`u8`] is not a perfect $n$th /// power. /// /// $$ /// f(x, n) = \\begin{cases} /// \operatorname{Some}(sqrt\[n\]{x}) & \text{if} \\quad \sqrt\[n\]{x} \in \Z, \\\\ /// \operatorname{None} & \textrm{otherwise}. /// \\end{cases} /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `exp` is zero. /// /// # Examples /// See [here](super::root#checked_root). /// /// # Notes /// The [`u8`] implementation uses lookup tables. fn checked_root(self, exp: u64) -> Option { match (self, exp) { (_, 0) => panic!(), (0 | 1, _) | (_, 1) => Some(self), (x, 2) => x.checked_sqrt(), (x, 3) => U8_CUBES.binary_search(&x).ok().map(u8::wrapping_from), (16, 4) | (32, 5) | (64, 6) | (128, 7) => Some(2), (81, 4) | (243, 5) => Some(3), _ => None, } } } impl RootRem for u8 { type RootOutput = u8; type RemOutput = u8; /// Returns the floor of the $n$th root of a [`u8`], and the remainder (the difference between /// the [`u8`] and the $n$th power of the floor). /// /// $f(x, n) = (\lfloor\sqrt\[n\]{x}\rfloor, x - \lfloor\sqrt\[n\]{x}\rfloor^2)$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `exp` is zero. /// /// # Examples /// See [here](super::root#root_rem). /// /// # Notes /// The [`u8`] implementation uses lookup tables. fn root_rem(self, exp: u64) -> (u8, u8) { match (self, exp) { (_, 0) => panic!(), (0 | 1, _) | (_, 1) => (self, 0), (x, 8..=u64::MAX) => (1, x - 1), (x, 2) => x.sqrt_rem(), (x, 3) => match U8_CUBES.binary_search(&x) { Ok(i) => (u8::wrapping_from(i), 0), Err(i) => (u8::wrapping_from(i - 1), x - U8_CUBES[i - 1]), }, (x, 4) if x < 16 => (1, x - 1), (x, 4) if x < 81 => (2, x - 16), (x, 4) => (3, x - 81), (x, 5) if x < 32 => (1, x - 1), (x, 5) if x < 243 => (2, x - 32), (x, 5) => (3, x - 243), (x, 6) if x < 64 => (1, x - 1), (x, 6) => (2, x - 64), (x, 7) if x < 128 => (1, x - 1), (x, 7) => (2, x - 128), } } } impl FloorRoot for u16 { type Output = u16; /// Returns the floor of the $n$th root of a [`u16`]. /// /// $f(x, n) = \lfloor\sqrt\[n\]{x}\rfloor$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `exp` is zero. /// /// # Examples /// See [here](super::root#checked_root). /// /// # Notes /// The [`u16`] implementation calls the implementation for [`u32`]s. #[inline] fn floor_root(self, exp: u64) -> u16 { u16::wrapping_from(u32::from(self).floor_root(exp)) } } impl CeilingRoot for u16 { type Output = u16; /// Returns the ceiling of the $n$th root of a [`u16`]. /// /// $f(x, n) = \lceil\sqrt\[n\]{x}\rceil$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `exp` is zero. /// /// # Examples /// See [here](super::root#ceiling_root). /// /// # Notes /// The [`u16`] implementation calls the implementation for [`u32`]s. #[inline] fn ceiling_root(self, exp: u64) -> u16 { u16::wrapping_from(u32::from(self).ceiling_root(exp)) } } impl CheckedRoot for u16 { type Output = u16; /// Returns the the $n$th root of a [`u16`], or `None` if the [`u16`] is not a perfect $n$th /// power. /// /// $$ /// f(x, n) = \\begin{cases} /// \operatorname{Some}(sqrt\[n\]{x}) & \text{if} \\quad \sqrt\[n\]{x} \in \Z, \\\\ /// \operatorname{None} & \textrm{otherwise}. /// \\end{cases} /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `exp` is zero. /// /// # Examples /// See [here](super::root#checked_root). /// /// # Notes /// The [`u16`] implementation calls the implementation for [`u32`]s. #[inline] fn checked_root(self, exp: u64) -> Option { u32::from(self).checked_root(exp).map(u16::wrapping_from) } } impl RootRem for u16 { type RootOutput = u16; type RemOutput = u16; /// Returns the floor of the $n$th root of a [`u16`], and the remainder (the difference between /// the [`u16`] and the $n$th power of the floor). /// /// $f(x, n) = (\lfloor\sqrt\[n\]{x}\rfloor, x - \lfloor\sqrt\[n\]{x}\rfloor^2)$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `exp` is zero. /// /// # Examples /// See [here](super::root#root_rem). /// /// # Notes /// The [`u16`] implementation calls the implementation for [`u32`]s. #[inline] fn root_rem(self, exp: u64) -> (u16, u16) { let (sqrt, rem) = u32::from(self).root_rem(exp); (u16::wrapping_from(sqrt), u16::wrapping_from(rem)) } } impl FloorRoot for u32 { type Output = u32; /// Returns the floor of the $n$th root of a [`u32`]. /// /// $f(x, n) = \lfloor\sqrt\[n\]{x}\rfloor$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `exp` is zero. /// /// # Examples /// See [here](super::root#floor_root). /// /// # Notes /// For cube roots, the [`u32`] implementation uses a piecewise Chebyshev approximation. For /// other roots, it uses Newton's method. In both implementations, the result of these /// approximations is adjusted afterwards to account for error. #[inline] fn floor_root(self, exp: u64) -> u32 { fast_floor_root_u32(self, exp) } } impl CeilingRoot for u32 { type Output = u32; /// Returns the ceiling of the $n$th root of a [`u32`]. /// /// $f(x, n) = \lceil\sqrt\[n\]{x}\rceil$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `exp` is zero. /// /// # Examples /// See [here](super::root#ceiling_root). /// /// # Notes /// For cube roots, the [`u32`] implementation uses a piecewise Chebyshev approximation. For /// other roots, it uses Newton's method. In both implementations, the result of these /// approximations is adjusted afterwards to account for error. #[inline] fn ceiling_root(self, exp: u64) -> u32 { fast_ceiling_root_u32(self, exp) } } impl CheckedRoot for u32 { type Output = u32; /// Returns the the $n$th root of a [`u32`], or `None` if the [`u32`] is not a perfect $n$th /// power. /// /// $$ /// f(x, n) = \\begin{cases} /// \operatorname{Some}(sqrt\[n\]{x}) & \text{if} \\quad \sqrt\[n\]{x} \in \Z, \\\\ /// \operatorname{None} & \textrm{otherwise}. /// \\end{cases} /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `exp` is zero. /// /// # Examples /// See [here](super::root#checked_root). /// /// # Notes /// For cube roots, the [`u32`] implementation uses a piecewise Chebyshev approximation. For /// other roots, it uses Newton's method. In both implementations, the result of these /// approximations is adjusted afterwards to account for error. #[inline] fn checked_root(self, exp: u64) -> Option { fast_checked_root_u32(self, exp) } } impl RootRem for u32 { type RootOutput = u32; type RemOutput = u32; /// Returns the floor of the $n$th root of a [`u32`], and the remainder (the difference between /// the [`u32`] and the $n$th power of the floor). /// /// $f(x, n) = (\lfloor\sqrt\[n\]{x}\rfloor, x - \lfloor\sqrt\[n\]{x}\rfloor^2)$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `exp` is zero. /// /// # Examples /// See [here](super::root#root_rem). /// /// # Notes /// For cube roots, the [`u32`] implementation uses a piecewise Chebyshev approximation. For /// other roots, it uses Newton's method. In both implementations, the result of these /// approximations is adjusted afterwards to account for error. #[inline] fn root_rem(self, exp: u64) -> (u32, u32) { fast_root_rem_u32(self, exp) } } impl FloorRoot for u64 { type Output = u64; /// Returns the floor of the $n$th root of a [`u64`]. /// /// $f(x, n) = \lfloor\sqrt\[n\]{x}\rfloor$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `exp` is zero. /// /// # Examples /// See [here](super::root#floor_root). /// /// # Notes /// For cube roots, the [`u64`] implementation uses a piecewise Chebyshev approximation. For /// other roots, it uses Newton's method. In both implementations, the result of these /// approximations is adjusted afterwards to account for error. #[inline] fn floor_root(self, exp: u64) -> u64 { fast_floor_root_u64(self, exp) } } impl CeilingRoot for u64 { type Output = u64; /// Returns the ceiling of the $n$th root of a [`u64`]. /// /// $f(x, n) = \lceil\sqrt\[n\]{x}\rceil$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `exp` is zero. /// /// # Examples /// See [here](super::root#ceiling_root). /// /// # Notes /// For cube roots, the [`u64`] implementation uses a piecewise Chebyshev approximation. For /// other roots, it uses Newton's method. In both implementations, the result of these /// approximations is adjusted afterwards to account for error. #[inline] fn ceiling_root(self, exp: u64) -> u64 { fast_ceiling_root_u64(self, exp) } } impl CheckedRoot for u64 { type Output = u64; /// Returns the the $n$th root of a [`u64`], or `None` if the [`u64`] is not a perfect $n$th /// power. /// /// $$ /// f(x, n) = \\begin{cases} /// \operatorname{Some}(sqrt\[n\]{x}) & \text{if} \\quad \sqrt\[n\]{x} \in \Z, \\\\ /// \operatorname{None} & \textrm{otherwise}. /// \\end{cases} /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `exp` is zero. /// /// # Examples /// See [here](super::root#checked_root). /// /// # Notes /// For cube roots, the [`u64`] implementation uses a piecewise Chebyshev approximation. For /// other roots, it uses Newton's method. In both implementations, the result of these /// approximations is adjusted afterwards to account for error. #[inline] fn checked_root(self, exp: u64) -> Option { fast_checked_root_u64(self, exp) } } impl RootRem for u64 { type RootOutput = u64; type RemOutput = u64; /// Returns the floor of the $n$th root of a [`u64`], and the remainder (the difference between /// the [`u64`] and the $n$th power of the floor). /// /// $f(x, n) = (\lfloor\sqrt\[n\]{x}\rfloor, x - \lfloor\sqrt\[n\]{x}\rfloor^2)$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `exp` is zero. /// /// # Examples /// See [here](super::root#root_rem). /// /// # Notes /// For cube roots, the [`u64`] implementation uses a piecewise Chebyshev approximation. For /// other roots, it uses Newton's method. In both implementations, the result of these /// approximations is adjusted afterwards to account for error. #[inline] fn root_rem(self, exp: u64) -> (u64, u64) { fast_root_rem_u64(self, exp) } } impl FloorRoot for usize { type Output = usize; /// Returns the floor of the $n$th root of a [`usize`]. /// /// $f(x, n) = \lfloor\sqrt\[n\]{x}\rfloor$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `exp` is zero. /// /// # Examples /// See [here](super::root#floor_root). /// /// # Notes /// The [`usize`] implementation calls the [`u32`] or [`u64`] implementations. #[inline] fn floor_root(self, exp: u64) -> usize { match usize::WIDTH { u32::WIDTH => usize::wrapping_from(u32::wrapping_from(self).floor_root(exp)), u64::WIDTH => usize::wrapping_from(u64::wrapping_from(self).floor_root(exp)), _ => panic!("Unsupported usize size"), } } } impl CeilingRoot for usize { type Output = usize; /// Returns the ceiling of the $n$th root of a [`usize`]. /// /// $f(x, n) = \lceil\sqrt\[n\]{x}\rceil$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `exp` is zero. /// /// # Examples /// See [here](super::root#ceiling_root). /// /// # Notes /// The [`usize`] implementation calls the [`u32`] or [`u64`] implementations. #[inline] fn ceiling_root(self, exp: u64) -> usize { match usize::WIDTH { u32::WIDTH => usize::wrapping_from(u32::wrapping_from(self).ceiling_root(exp)), u64::WIDTH => usize::wrapping_from(u64::wrapping_from(self).ceiling_root(exp)), _ => panic!("Unsupported usize size"), } } } impl CheckedRoot for usize { type Output = usize; /// Returns the the $n$th root of a [`usize`], or `None` if the [`usize`] is not a perfect $n$th /// power. /// /// $$ /// f(x, n) = \\begin{cases} /// \operatorname{Some}(sqrt\[n\]{x}) & \text{if} \\quad \sqrt\[n\]{x} \in \Z, \\\\ /// \operatorname{None} & \textrm{otherwise}. /// \\end{cases} /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `exp` is zero. /// /// # Examples /// See [here](super::root#checked_root). /// /// # Notes /// The [`usize`] implementation calls the [`u32`] or [`u64`] implementations. #[inline] fn checked_root(self, exp: u64) -> Option { match usize::WIDTH { u32::WIDTH => u32::wrapping_from(self) .checked_root(exp) .map(usize::wrapping_from), u64::WIDTH => u64::wrapping_from(self) .checked_root(exp) .map(usize::wrapping_from), _ => panic!("Unsupported usize size"), } } } impl RootRem for usize { type RootOutput = usize; type RemOutput = usize; /// Returns the floor of the $n$th root of a [`usize`], and the remainder (the difference /// between the [`usize`] and the $n$th power of the floor). /// /// $f(x, n) = (\lfloor\sqrt\[n\]{x}\rfloor, x - \lfloor\sqrt\[n\]{x}\rfloor^2)$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `exp` is zero. /// /// # Examples /// See [here](super::root#root_rem). /// /// # Notes /// The [`usize`] implementation calls the [`u32`] or [`u64`] implementations. #[inline] fn root_rem(self, exp: u64) -> (usize, usize) { match usize::WIDTH { u32::WIDTH => { let (sqrt, rem) = u32::wrapping_from(self).root_rem(exp); (usize::wrapping_from(sqrt), usize::wrapping_from(rem)) } u64::WIDTH => { let (sqrt, rem) = u64::wrapping_from(self).root_rem(exp); (usize::wrapping_from(sqrt), usize::wrapping_from(rem)) } _ => panic!("Unsupported usize size"), } } } impl FloorRoot for u128 { type Output = u128; /// Returns the floor of the $n$th root of a [`u128`]. /// /// $f(x, n) = \lfloor\sqrt\[n\]{x}\rfloor$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `exp` is zero. /// /// # Examples /// See [here](super::root#floor_root). /// /// # Notes /// The [`u128`] implementation computes the root using floating-point arithmetic. The /// approximate result is adjusted afterwards to account for error. fn floor_root(self, exp: u64) -> u128 { if exp == 2 { return self.floor_sqrt(); } floor_root_approx_and_refine(|x| x as f64, |x| x as u128, self, exp) } } impl CeilingRoot for u128 { type Output = u128; /// Returns the ceiling of the $n$th root of a [`u128`]. /// /// $f(x, n) = \lceil\sqrt\[n\]{x}\rceil$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `exp` is zero. /// /// # Examples /// See [here](super::root#ceiling_root). /// /// # Notes /// The [`u128`] implementation computes the root using floating-point arithmetic. The /// approximate result is adjusted afterwards to account for error. fn ceiling_root(self, exp: u64) -> u128 { if exp == 2 { return self.ceiling_sqrt(); } let root = floor_root_approx_and_refine(|x| x as f64, |x| x as u128, self, exp); if root.pow(u32::saturating_from(exp)) == self { root } else { root + 1 } } } impl CheckedRoot for u128 { type Output = u128; /// Returns the the $n$th root of a [`u128`], or `None` if the [`u128`] is not a perfect $n$th /// power. /// /// $$ /// f(x, n) = \\begin{cases} /// \operatorname{Some}(sqrt\[n\]{x}) & \text{if} \\quad \sqrt\[n\]{x} \in \Z, \\\\ /// \operatorname{None} & \textrm{otherwise}. /// \\end{cases} /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `exp` is zero. /// /// # Examples /// See [here](super::root#checked_root). /// /// # Notes /// The [`u128`] implementation computes the root using floating-point arithmetic. The /// approximate result is adjusted afterwards to account for error. fn checked_root(self, exp: u64) -> Option { if exp == 2 { return self.checked_sqrt(); } let root = floor_root_approx_and_refine(|x| x as f64, |x| x as u128, self, exp); if root.pow(u32::saturating_from(exp)) == self { Some(root) } else { None } } } impl RootRem for u128 { type RootOutput = u128; type RemOutput = u128; /// Returns the floor of the $n$th root of a [`u128`], and the remainder (the difference between /// the [`u128`] and the $n$th power of the floor). /// /// $f(x, n) = (\lfloor\sqrt\[n\]{x}\rfloor, x - \lfloor\sqrt\[n\]{x}\rfloor^n)$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `exp` is zero. /// /// # Examples /// See [here](super::root#root_rem). /// /// # Notes /// The [`u128`] implementation computes the root using floating-point arithmetic. The /// approximate result is adjusted afterwards to account for error. fn root_rem(self, exp: u64) -> (u128, u128) { if exp == 2 { return self.sqrt_rem(); } let root = floor_root_approx_and_refine(|x| x as f64, |x| x as u128, self, exp); (root, self - root.pow(u32::saturating_from(exp))) } } macro_rules! impl_root_assign_rem { ($t: ident) => { impl RootAssignRem for $t { type RemOutput = $t; /// Replaces an integer with the floor of its $n$th root, and returns the remainder (the /// difference between the original integer and the $n$th power of the floor). /// /// $f(x, n) = x - \lfloor\sqrt\[n\]{x}\rfloor^n$, /// /// $x \gets \lfloor\sqrt\[n\]{x}\rfloor$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `exp` is zero. /// /// # Examples /// See [here](super::root#root_assign_rem). #[inline] fn root_assign_rem(&mut self, exp: u64) -> $t { let rem; (*self, rem) = self.root_rem(exp); rem } } }; } apply_to_unsigneds!(impl_root_assign_rem); macro_rules! impl_root_signed { ($t: ident) => { impl FloorRoot for $t { type Output = $t; /// Returns the floor of the $n$th root of an integer. /// /// $f(x, n) = \lfloor\sqrt\[n\]{x}\rfloor$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `exp` is zero, or if `self` is negative and `exp` is even. /// /// # Examples /// See [here](super::root#floor_root). #[inline] fn floor_root(self, exp: u64) -> $t { if self >= 0 { $t::wrapping_from(self.unsigned_abs().floor_root(exp)) } else if exp.odd() { $t::wrapping_from(self.unsigned_abs().ceiling_root(exp)).wrapping_neg() } else { panic!("Cannot take even root of a negative number"); } } } impl CeilingRoot for $t { type Output = $t; /// Returns the ceiling of the $n$th root of an integer. /// /// $f(x, n) = \lceil\sqrt\[n\]{x}\rceil$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `exp` is zero, or if `self` is negative and `exp` is even. /// /// # Examples /// See [here](super::root#ceiling_root). #[inline] fn ceiling_root(self, exp: u64) -> $t { if self >= 0 { $t::wrapping_from(self.unsigned_abs().ceiling_root(exp)) } else if exp.odd() { $t::wrapping_from(self.unsigned_abs().floor_root(exp)).wrapping_neg() } else { panic!("Cannot take even root of a negative number"); } } } impl CheckedRoot for $t { type Output = $t; /// Returns the the $n$th root of an integer, or `None` if the integer is not a perfect /// $n$th power. /// /// $$ /// f(x, n) = \\begin{cases} /// \operatorname{Some}(sqrt\[n\]{x}) & \text{if} \\quad \sqrt\[n\]{x} \in \Z, \\\\ /// \operatorname{None} & \textrm{otherwise}. /// \\end{cases} /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `exp` is zero, or if `self` is negative and `exp` is even. /// /// # Examples /// See [here](super::root#checked_root). #[inline] fn checked_root(self, exp: u64) -> Option<$t> { if self >= 0 { self.unsigned_abs().checked_root(exp).map($t::wrapping_from) } else if exp.odd() { self.unsigned_abs() .checked_root(exp) .map(|x| $t::wrapping_from(x).wrapping_neg()) } else { panic!("Cannot take even root of a negative number"); } } } }; } apply_to_signeds!(impl_root_signed); macro_rules! impl_root_primitive_int { ($t: ident) => { impl FloorRootAssign for $t { /// Replaces an integer with the floor of its $n$th root. /// /// $x \gets \lfloor\sqrt\[n\]{x}\rfloor$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `exp` is zero, or if `self` is negative and `exp` is even. /// /// # Examples /// See [here](super::root#floor_root_assign). #[inline] fn floor_root_assign(&mut self, exp: u64) { *self = self.floor_root(exp); } } impl CeilingRootAssign for $t { /// Replaces an integer with the ceiling of its $n$th root. /// /// $x \gets \lceil\sqrt\[n\]{x}\rceil$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `exp` is zero, or if `self` is negative and `exp` is even. /// /// # Examples /// See [here](super::root#ceiling_root_assign). #[inline] fn ceiling_root_assign(&mut self, exp: u64) { *self = self.ceiling_root(exp); } } }; } apply_to_primitive_ints!(impl_root_primitive_int); malachite-base-0.4.16/src/num/arithmetic/rotate.rs000064400000000000000000000044161046102023000201430ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{ RotateLeft, RotateLeftAssign, RotateRight, RotateRightAssign, }; use crate::num::conversion::traits::WrappingFrom; macro_rules! impl_rotate { ($t:ident) => { impl RotateLeft for $t { type Output = $t; /// This is a wrapper over the `rotate_left` functions in the standard library, for /// example [this one](u32::rotate_left). #[inline] fn rotate_left(self, n: u64) -> $t { $t::rotate_left(self, u32::wrapping_from(n)) } } impl RotateLeftAssign for $t { /// Rotates a number left, in place. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::rotate#rotate_left_assign). #[inline] fn rotate_left_assign(&mut self, n: u64) { *self = self.rotate_left(u32::wrapping_from(n)); } } impl RotateRight for $t { type Output = $t; /// This is a wrapper over the `rotate_right` functions in the standard library, for /// example [this one](u32::rotate_right). #[inline] fn rotate_right(self, n: u64) -> $t { $t::rotate_right(self, u32::wrapping_from(n)) } } impl RotateRightAssign for $t { /// Rotates a number right, in place. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::rotate#rotate_right_assign). #[inline] fn rotate_right_assign(&mut self, n: u64) { *self = self.rotate_right(u32::wrapping_from(n)); } } }; } apply_to_primitive_ints!(impl_rotate); malachite-base-0.4.16/src/num/arithmetic/round_to_multiple.rs000064400000000000000000000276271046102023000224220ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{RoundToMultiple, RoundToMultipleAssign, UnsignedAbs}; use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::ExactFrom; use crate::rounding_modes::RoundingMode::{self, *}; use core::cmp::Ordering::{self, *}; fn round_to_multiple_unsigned( x: T, other: T, rm: RoundingMode, ) -> (T, Ordering) { match (x, other) { (x, y) if x == y => (x, Equal), (x, y) if y == T::ZERO => match rm { Down | Floor | Nearest => (T::ZERO, Less), _ => panic!("Cannot round {x} to zero using RoundingMode {rm}"), }, (x, y) => { let r = x % y; if r == T::ZERO { (x, Equal) } else { let floor = x - r; match rm { Down | Floor => (floor, Less), Up | Ceiling => (floor.checked_add(y).unwrap(), Greater), Nearest => { match r.cmp(&(y >> 1)) { Less => (floor, Less), Greater => (floor.checked_add(y).unwrap(), Greater), Equal => { if y.odd() { (floor, Less) } else { // The even multiple of y will have more trailing zeros. let (ceiling, overflow) = floor.overflowing_add(y); if floor.trailing_zeros() > ceiling.trailing_zeros() { (floor, Less) } else if overflow { panic!("Cannot round {x} to {y} using RoundingMode {rm}"); } else { (ceiling, Greater) } } } } } Exact => { panic!("Cannot round {x} to {y} using RoundingMode {rm}") } } } } } } macro_rules! impl_round_to_multiple_unsigned { ($t:ident) => { impl RoundToMultiple<$t> for $t { type Output = $t; /// Rounds a number to a multiple of another number, according to a specified rounding /// mode. An [`Ordering`] is also returned, indicating whether the returned value is /// less than, equal to, or greater than the original value. /// /// The only rounding modes that are guaranteed to return without a panic are `Down` and /// `Floor`. /// /// Let $q = \frac{x}{y}$: /// /// $f(x, y, \mathrm{Down}) = f(x, y, \mathrm{Floor}) = y \lfloor q \rfloor.$ /// /// $f(x, y, \mathrm{Up}) = f(x, y, \mathrm{Ceiling}) = y \lceil q \rceil.$ /// /// $$ /// f(x, y, \mathrm{Nearest}) = \begin{cases} /// y \lfloor q \rfloor & \text{if} \\quad /// q - \lfloor q \rfloor < \frac{1}{2} \\\\ /// y \lceil q \rceil & \text{if} \\quad q - \lfloor q \rfloor > \frac{1}{2} \\\\ /// y \lfloor q \rfloor & /// \text{if} \\quad q - \lfloor q \rfloor = /// \frac{1}{2} \\ \text{and} \\ \lfloor q \rfloor /// \\ \text{is even} \\\\ /// y \lceil q \rceil & /// \text{if} \\quad q - \lfloor q \rfloor = \frac{1}{2} /// \\ \text{and} \\ \lfloor q \rfloor \\ \text{is odd.} /// \end{cases} /// $$ /// /// $f(x, y, \mathrm{Exact}) = x$, but panics if $q \notin \N$. /// /// The following two expressions are equivalent: /// - `x.round_to_multiple(other, Exact)` /// - `{ assert!(x.divisible_by(other)); x }` /// /// but the latter should be used as it is clearer and more efficient. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// - If `rm` is `Exact`, but `self` is not a multiple of `other`. /// - If the multiple is outside the representable range. /// - If `self` is nonzero, `other` is zero, and `rm` is trying to round away from zero. /// /// # Examples /// See [here](super::round_to_multiple#round_to_multiple). #[inline] fn round_to_multiple(self, other: $t, rm: RoundingMode) -> ($t, Ordering) { round_to_multiple_unsigned(self, other, rm) } } impl RoundToMultipleAssign<$t> for $t { /// Rounds a number to a multiple of another number in place, according to a specified /// rounding mode. An [`Ordering`] is returned, indicating whether the returned value is /// less than, equal to, or greater than the original value. /// /// The only rounding modes that are guaranteed to return without a panic are `Down` and /// `Floor`. /// /// See the [`RoundToMultiple`] documentation for details. /// /// The following two expressions are equivalent: /// - `x.round_to_multiple_assign(other, Exact);` /// - `assert!(x.divisible_by(other));` /// /// but the latter should be used as it is clearer and more efficient. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// - If `rm` is `Exact`, but `self` is not a multiple of `other`. /// - If the multiple is outside the representable range. /// - If `self` is nonzero, `other` is zero, and `rm` is trying to round away from zero. /// /// # Examples /// See [here](super::round_to_multiple#round_to_multiple_assign). #[inline] fn round_to_multiple_assign(&mut self, other: $t, rm: RoundingMode) -> Ordering { let o; (*self, o) = self.round_to_multiple(other, rm); o } } }; } apply_to_unsigneds!(impl_round_to_multiple_unsigned); fn round_to_multiple_signed< U: PrimitiveUnsigned, S: ExactFrom + PrimitiveSigned + UnsignedAbs, >( x: S, other: S, rm: RoundingMode, ) -> (S, Ordering) { if x >= S::ZERO { let (m, o) = x.unsigned_abs().round_to_multiple(other.unsigned_abs(), rm); (S::exact_from(m), o) } else { let (abs_result, o) = x .unsigned_abs() .round_to_multiple(other.unsigned_abs(), -rm); ( if abs_result == S::MIN.unsigned_abs() { S::MIN } else { S::exact_from(abs_result).checked_neg().unwrap() }, o.reverse(), ) } } macro_rules! impl_round_to_multiple_signed { ($t:ident) => { impl RoundToMultiple<$t> for $t { type Output = $t; /// Rounds a number to a multiple of another number, according to a specified rounding /// mode. An [`Ordering`] is also returned, indicating whether the returned value is /// less than, equal to, or greater than the original value. /// /// The only rounding mode that is guaranteed to return without a panic is `Down`. /// /// Let $q = \frac{x}{|y|}$: /// /// $f(x, y, \mathrm{Down}) = \operatorname{sgn}(q) |y| \lfloor |q| \rfloor.$ /// /// $f(x, y, \mathrm{Up}) = \operatorname{sgn}(q) |y| \lceil |q| \rceil.$ /// /// $f(x, y, \mathrm{Floor}) = |y| \lfloor q \rfloor.$ /// /// $f(x, y, \mathrm{Ceiling}) = |y| \lceil q \rceil.$ /// /// $$ /// f(x, y, \mathrm{Nearest}) = \begin{cases} /// y \lfloor q \rfloor & \text{if} \\quad /// q - \lfloor q \rfloor < \frac{1}{2} \\\\ /// y \lceil q \rceil & \text{if} \\quad q - \lfloor q \rfloor > \frac{1}{2} \\\\ /// y \lfloor q \rfloor & /// \text{if} \\quad q - \lfloor q \rfloor = /// \frac{1}{2} \\ \text{and} \\ \lfloor q \rfloor /// \\ \text{is even} \\\\ /// y \lceil q \rceil & /// \text{if} \\quad q - \lfloor q \rfloor = \frac{1}{2} /// \\ \text{and} \\ \lfloor q \rfloor \\ \text{is odd.} /// \end{cases} /// $$ /// /// $f(x, y, \mathrm{Exact}) = q$, but panics if $q \notin \Z$. /// /// The following two expressions are equivalent: /// - `x.round_to_multiple(other, Exact)` /// - `{ assert!(x.divisible_by(other)); x }` /// /// but the latter should be used as it is clearer and more efficient. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// - If `rm` is `Exact`, but `self` is not a multiple of `other`. /// - If the multiple is outside the representable range. /// - If `self` is nonzero, `other` is zero, and `rm` is trying to round away from zero. /// /// # Examples /// See [here](super::round_to_multiple#round_to_multiple). #[inline] fn round_to_multiple(self, other: $t, rm: RoundingMode) -> ($t, Ordering) { round_to_multiple_signed(self, other, rm) } } impl RoundToMultipleAssign<$t> for $t { /// Rounds a number to a multiple of another number in place, according to a specified /// rounding mode. An [`Ordering`] is returned, indicating whether the returned value is /// less than, equal to, or greater than the original value. /// /// The only rounding mode that is guaranteed to return without a panic is `Down`. /// /// See the [`RoundToMultiple`] documentation for details. /// /// The following two expressions are equivalent: /// - `x.round_to_multiple_assign(other, Exact);` /// - `assert!(x.divisible_by(other));` /// /// but the latter should be used as it is clearer and more efficient. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// - If `rm` is `Exact`, but `self` is not a multiple of `other`. /// - If the multiple is outside the representable range. /// - If `self` is nonzero, `other` is zero, and `rm` is trying to round away from zero. /// /// # Examples /// See [here](super::round_to_multiple#round_to_multiple_assign). #[inline] fn round_to_multiple_assign(&mut self, other: $t, rm: RoundingMode) -> Ordering { let o; (*self, o) = self.round_to_multiple(other, rm); o } } }; } apply_to_signeds!(impl_round_to_multiple_signed); malachite-base-0.4.16/src/num/arithmetic/round_to_multiple_of_power_of_2.rs000064400000000000000000000141271046102023000252160ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{RoundToMultipleOfPowerOf2, RoundToMultipleOfPowerOf2Assign}; use crate::num::basic::integers::PrimitiveInt; use crate::rounding_modes::RoundingMode; use core::cmp::Ordering; fn round_to_multiple_of_power_of_2( x: T, pow: u64, rm: RoundingMode, ) -> (T, Ordering) { let (s, o) = x.shr_round(pow, rm); (s.arithmetic_checked_shl(pow).unwrap(), o) } macro_rules! impl_round_to_multiple_of_power_of_2 { ($t:ident) => { impl RoundToMultipleOfPowerOf2 for $t { type Output = $t; /// Rounds a number to a multiple of $2^k$ according to a specified rounding mode. An /// [`Ordering`] is also returned, indicating whether the returned value is less than, /// equal to, or greater than the original value. /// /// The only rounding mode that is guaranteed to return without a panic is `Down`. /// /// Let $q = \frac{x}{2^k}$: /// /// $f(x, k, \mathrm{Down}) = 2^k \operatorname{sgn}(q) \lfloor |q| \rfloor.$ /// /// $f(x, k, \mathrm{Up}) = 2^k \operatorname{sgn}(q) \lceil |q| \rceil.$ /// /// $f(x, k, \mathrm{Floor}) = 2^k \lfloor q \rfloor.$ /// /// $f(x, k, \mathrm{Ceiling}) = 2^k \lceil q \rceil.$ /// /// $$ /// f(x, k, \mathrm{Nearest}) = \begin{cases} /// 2^k \lfloor q \rfloor & \text{if} \\quad /// q - \lfloor q \rfloor < \frac{1}{2} \\\\ /// 2^k \lceil q \rceil & \text{if} \\quad q - \lfloor q \rfloor > \frac{1}{2} \\\\ /// 2^k \lfloor q \rfloor & /// \text{if} \\quad q - \lfloor q \rfloor = /// \frac{1}{2} \\ \text{and} \\ \lfloor q \rfloor /// \\ \text{is even} \\\\ /// 2^k \lceil q \rceil & /// \text{if} \\quad q - \lfloor q \rfloor = /// \frac{1}{2} \\ \text{and} \\ \lfloor q \rfloor \\ \text{is odd.} /// \end{cases} /// $$ /// /// $f(x, k, \mathrm{Exact}) = 2^k q$, but panics if $q \notin \Z$. /// /// The following two expressions are equivalent: /// - `x.round_to_multiple_of_power_of_2(pow, Exact)` /// - `{ assert!(x.divisible_by_power_of_2(pow)); x }` /// /// but the latter should be used as it is clearer and more efficient. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// - If `rm` is `Exact`, but `self` is not a multiple of the power of 2. /// - If `rm` is `Floor`, but `self` is negative with a too-large absolute value to /// round to the next lowest multiple. /// - If `rm` is `Ceiling`, but `self` is too large to round to the next highest /// multiple. /// - If `rm` is `Up`, but `self` has too large an absolute value to round to the next /// multiple with a greater absolute value. /// - If `rm` is `Nearest`, but the nearest multiple is outside the representable range. /// /// # Examples /// See [here](super::round_to_multiple_of_power_of_2#round_to_multiple_of_power_of_2). #[inline] fn round_to_multiple_of_power_of_2(self, pow: u64, rm: RoundingMode) -> ($t, Ordering) { round_to_multiple_of_power_of_2(self, pow, rm) } } impl RoundToMultipleOfPowerOf2Assign for $t { /// Rounds a number to a multiple of $2^k$ in place, according to a specified rounding /// mode. An [`Ordering`] is returned, indicating whether the returned value is less /// than, equal to, or greater than the original value. /// /// The only rounding mode that is guaranteed to return without a panic is `Down`. /// /// See the [`RoundToMultipleOfPowerOf2`] documentation for details. /// /// The following two expressions are equivalent: /// - `x.round_to_multiple_of_power_of_2_assign(pow, Exact);` /// - `assert!(x.divisible_by_power_of_2(pow));` /// /// but the latter should be used as it is clearer and more efficient. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// - If `rm` is `Exact`, but `self` is not a multiple of the power of 2. /// - If `rm` is `Floor`, but `self` is negative with a too-large absolute value to /// round to the next lowest multiple. /// - If `rm` is `Ceiling`, but `self` is too large to round to the next highest /// multiple. /// - If `rm` is `Up`, but `self` has too large an absolute value to round to the next /// multiple with a greater absolute value. /// - If `rm` is `Nearest`, but the nearest multiple is outside the representable range. /// /// # Examples /// See /// [here](super::round_to_multiple_of_power_of_2#round_to_multiple_of_power_of_2_assign). #[inline] fn round_to_multiple_of_power_of_2_assign( &mut self, pow: u64, rm: RoundingMode, ) -> Ordering { let o; (*self, o) = self.round_to_multiple_of_power_of_2(pow, rm); o } } }; } apply_to_primitive_ints!(impl_round_to_multiple_of_power_of_2); malachite-base-0.4.16/src/num/arithmetic/saturating_abs.rs000064400000000000000000000033211046102023000216450ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{SaturatingAbs, SaturatingAbsAssign}; macro_rules! impl_saturating_abs { ($t:ident) => { impl SaturatingAbs for $t { type Output = $t; /// This is a wrapper over the `saturating_abs` functions in the standard library, for /// example [this one](i32::saturating_abs). #[inline] fn saturating_abs(self) -> $t { $t::saturating_abs(self) } } impl SaturatingAbsAssign for $t { /// Replaces a number with its absolute value, saturating at the numeric bounds instead /// of overflowing. /// /// $$ /// x \gets \\begin{cases} /// |x| & \text{if} \\quad x > -2^{W-1}, \\\\ /// 2^{W-1} - 1 & \text{if} \\quad x = -2^{W-1}, /// \\end{cases} /// $$ /// where $W$ is `Self::WIDTH`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::saturating_abs#saturating_abs_assign). #[inline] fn saturating_abs_assign(&mut self) { *self = self.saturating_abs(); } } }; } apply_to_signeds!(impl_saturating_abs); malachite-base-0.4.16/src/num/arithmetic/saturating_add.rs000064400000000000000000000035141046102023000216340ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{SaturatingAdd, SaturatingAddAssign}; macro_rules! impl_saturating_add { ($t:ident) => { impl SaturatingAdd<$t> for $t { type Output = $t; /// This is a wrapper over the `saturating_add` functions in the standard library, for /// example [this one](i32::saturating_add). #[inline] fn saturating_add(self, other: $t) -> $t { $t::saturating_add(self, other) } } impl SaturatingAddAssign<$t> for $t { /// Adds a number to another number, in place, saturating at the numeric bounds instead /// of overflowing. /// /// $$ /// x \gets \\begin{cases} /// x + y & \text{if} \\quad m \leq x + y \leq M, \\\\ /// M & \text{if} \\quad x + y > M, \\\\ /// m & \text{if} \\quad x + y < m, /// \\end{cases} /// $$ /// where $m$ is `Self::MIN` and $M$ is `Self::MAX`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::saturating_add#saturating_add_assign). #[inline] fn saturating_add_assign(&mut self, other: $t) { *self = self.saturating_add(other); } } }; } apply_to_primitive_ints!(impl_saturating_add); malachite-base-0.4.16/src/num/arithmetic/saturating_add_mul.rs000064400000000000000000000135541046102023000225160ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{SaturatingAddMul, SaturatingAddMulAssign, UnsignedAbs}; use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::WrappingFrom; fn saturating_add_mul_unsigned(x: T, y: T, z: T) -> T { x.saturating_add(y.saturating_mul(z)) } fn saturating_add_mul_assign_unsigned(x: &mut T, y: T, z: T) { x.saturating_add_assign(y.saturating_mul(z)); } macro_rules! impl_saturating_add_mul_unsigned { ($t:ident) => { impl SaturatingAddMul<$t> for $t { type Output = $t; /// Adds a number and the product of two other numbers, saturating at the numeric bounds /// instead of overflowing. /// /// $$ /// f(x, y, z) = \\begin{cases} /// x + yz & \text{if} \\quad m \leq x + yz \leq M, \\\\ /// M & \text{if} \\quad x + yz > M, \\\\ /// m & \text{if} \\quad x + yz < m, /// \\end{cases} /// $$ /// where $m$ is `Self::MIN` and $M$ is `Self::MAX`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::saturating_add_mul#saturating_add_mul). #[inline] fn saturating_add_mul(self, y: $t, z: $t) -> $t { saturating_add_mul_unsigned(self, y, z) } } impl SaturatingAddMulAssign<$t> for $t { /// Adds a number and the product of two other numbers in place, saturating at the /// numeric bounds instead of overflowing. /// /// $$ /// x \gets \\begin{cases} /// x + yz & \text{if} \\quad m \leq x + yz \leq M, \\\\ /// M & \text{if} \\quad x + yz > M, \\\\ /// m & \text{if} \\quad x + yz < m, /// \\end{cases} /// $$ /// where $m$ is `Self::MIN` and $M$ is `Self::MAX`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::saturating_add#saturating_add_mul_assign). #[inline] fn saturating_add_mul_assign(&mut self, y: $t, z: $t) { saturating_add_mul_assign_unsigned(self, y, z); } } }; } apply_to_unsigneds!(impl_saturating_add_mul_unsigned); fn saturating_add_mul_signed< U: PrimitiveUnsigned, S: PrimitiveSigned + UnsignedAbs + WrappingFrom, >( x: S, y: S, z: S, ) -> S { if y == S::ZERO || z == S::ZERO { return x; } let x_sign = x >= S::ZERO; if x_sign == ((y >= S::ZERO) == (z >= S::ZERO)) { x.saturating_add(y.saturating_mul(z)) } else { let x = x.unsigned_abs(); let product = if let Some(product) = y.unsigned_abs().checked_mul(z.unsigned_abs()) { product } else { return if x_sign { S::MIN } else { S::MAX }; }; let result = S::wrapping_from(if x_sign { x.wrapping_sub(product) } else { product.wrapping_sub(x) }); if x >= product || (x_sign == (result < S::ZERO)) { result } else if x_sign { S::MIN } else { S::MAX } } } macro_rules! impl_saturating_add_mul_signed { ($t:ident) => { impl SaturatingAddMul<$t> for $t { type Output = $t; /// Adds a number and the product of two other numbers, saturating at the numeric bounds /// instead of overflowing. /// /// $$ /// f(x, y, z) = \\begin{cases} /// x + yz & \text{if} \\quad m \leq x + yz \leq M, \\\\ /// M & \text{if} \\quad x + yz > M, \\\\ /// m & \text{if} \\quad x + yz < m, /// \\end{cases} /// $$ /// where $m$ is `Self::MIN` and $M$ is `Self::MAX`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::saturating_add_mul#saturating_add_mul_assign). #[inline] fn saturating_add_mul(self, y: $t, z: $t) -> $t { saturating_add_mul_signed(self, y, z) } } impl SaturatingAddMulAssign<$t> for $t { /// Adds a number and the product of two other numbers in place, saturating at the /// numeric bounds instead of overflowing. /// /// $$ /// x \gets \\begin{cases} /// x + yz & \text{if} \\quad m \leq x + yz \leq M, \\\\ /// M & \text{if} \\quad x + yz > M, \\\\ /// m & \text{if} \\quad x + yz < m, /// \\end{cases} /// $$ /// where $m$ is `Self::MIN` and $M$ is `Self::MAX`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::saturating_add_mul#saturating_add_mul_assign). #[inline] fn saturating_add_mul_assign(&mut self, y: $t, z: $t) { *self = self.saturating_add_mul(y, z); } } }; } apply_to_signeds!(impl_saturating_add_mul_signed); malachite-base-0.4.16/src/num/arithmetic/saturating_mul.rs000064400000000000000000000035061046102023000217020ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{SaturatingMul, SaturatingMulAssign}; macro_rules! impl_saturating_mul { ($t:ident) => { impl SaturatingMul<$t> for $t { type Output = $t; /// This is a wrapper over the `saturating_mul` functions in the standard library, for /// example [this one](i32::saturating_mul). #[inline] fn saturating_mul(self, other: $t) -> $t { $t::saturating_mul(self, other) } } impl SaturatingMulAssign<$t> for $t { /// Multiplies a number by another number, in place, saturating at the numeric bounds /// instead of overflowing. /// /// $$ /// x \gets \\begin{cases} /// xy & \text{if} \\quad m \leq xy \leq M, \\\\ /// M & \text{if} \\quad xy > M, \\\\ /// m & \text{if} \\quad xy < m, /// \\end{cases} /// $$ /// where $m$ is `Self::MIN` and $M$ is `Self::MAX`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::saturating_mul#saturating_mul_assign). #[inline] fn saturating_mul_assign(&mut self, other: $t) { *self = self.saturating_mul(other); } } }; } apply_to_primitive_ints!(impl_saturating_mul); malachite-base-0.4.16/src/num/arithmetic/saturating_neg.rs000064400000000000000000000032621046102023000216550ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{SaturatingNeg, SaturatingNegAssign}; macro_rules! impl_saturating_neg { ($t:ident) => { impl SaturatingNeg for $t { type Output = $t; /// This is a wrapper over the `saturating_neg` functions in the standard library, for /// example [this one](i32::saturating_neg). #[inline] fn saturating_neg(self) -> $t { $t::saturating_neg(self) } } impl SaturatingNegAssign for $t { /// Negates a number in place, saturating at the numeric bounds instead of overflowing. /// /// $$ /// x \gets \\begin{cases} /// -x & \text{if} \\quad x^2 > -2^{W-1}, \\\\ /// 2^{W-1} - 1 & \text{if} \\quad x = -2^{W-1}, /// \\end{cases} /// $$ /// where $W$ is `Self::WIDTH`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::saturating_neg#saturating_neg_assign). #[inline] fn saturating_neg_assign(&mut self) { *self = self.saturating_neg(); } } }; } apply_to_signeds!(impl_saturating_neg); malachite-base-0.4.16/src/num/arithmetic/saturating_pow.rs000064400000000000000000000063601046102023000217130ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{Parity, SaturatingPow, SaturatingPowAssign}; use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; fn saturating_pow_unsigned(x: T, exp: u64) -> T { if exp == 0 { T::ONE } else if x < T::TWO { x } else if let Some(p) = x.checked_pow(exp) { p } else { T::MAX } } fn saturating_pow_signed(x: T, exp: u64) -> T { if exp == 0 { T::ONE } else if x == T::ZERO || x == T::ONE { x } else if x == T::NEGATIVE_ONE { if exp.even() { T::ONE } else { T::NEGATIVE_ONE } } else if let Some(p) = x.checked_pow(exp) { p } else if x > T::ZERO || exp.even() { T::MAX } else { T::MIN } } macro_rules! impl_saturating_pow_unsigned { ($t:ident) => { impl SaturatingPow for $t { type Output = $t; /// This is a wrapper over the `saturating_pow` functions in the standard library, for /// example [this one](u32::saturating_pow). #[inline] fn saturating_pow(self, exp: u64) -> $t { saturating_pow_unsigned(self, exp) } } }; } apply_to_unsigneds!(impl_saturating_pow_unsigned); macro_rules! impl_saturating_pow_signed { ($t:ident) => { impl SaturatingPow for $t { type Output = $t; /// This is a wrapper over the `saturating_pow` functions in the standard library, for /// example [this one](i32::saturating_pow). #[inline] fn saturating_pow(self, exp: u64) -> $t { saturating_pow_signed(self, exp) } } }; } apply_to_signeds!(impl_saturating_pow_signed); macro_rules! impl_saturating_pow_primitive_int { ($t:ident) => { impl SaturatingPowAssign for $t { /// Raises a number to a power, in place, saturating at the numeric bounds instead of /// overflowing. /// /// $$ /// x \gets \\begin{cases} /// x^y & \text{if} \\quad m \leq x^y \leq M, \\\\ /// M & \text{if} \\quad x^y > M, \\\\ /// m & \text{if} \\quad x^y < m, /// \\end{cases} /// $$ /// where $m$ is `Self::MIN` and $M$ is `Self::MAX`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::saturating_pow#saturating_pow_assign). #[inline] fn saturating_pow_assign(&mut self, exp: u64) { *self = SaturatingPow::saturating_pow(*self, exp); } } }; } apply_to_primitive_ints!(impl_saturating_pow_primitive_int); malachite-base-0.4.16/src/num/arithmetic/saturating_square.rs000064400000000000000000000042241046102023000224030ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{ SaturatingMulAssign, SaturatingSquare, SaturatingSquareAssign, }; macro_rules! impl_saturating_square { ($t:ident) => { impl SaturatingSquare for $t { type Output = $t; /// Squares a number, saturating at the numeric bounds instead of overflowing. /// /// $$ /// f(x) = \\begin{cases} /// x^2 & \text{if} \\quad x^2 \leq M, \\\\ /// M & \text{if} \\quad x^2 > M, /// \\end{cases} /// $$ /// where $M$ is `Self::MAX`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::saturating_square#saturating_square). #[inline] fn saturating_square(self) -> $t { self.saturating_mul(self) } } impl SaturatingSquareAssign for $t { /// Squares a number in place, saturating at the numeric bounds instead of overflowing. /// /// $$ /// x \gets \\begin{cases} /// x^2 & \text{if} \\quad x^2 \leq M, \\\\ /// M & \text{if} \\quad x^2 > M, /// \\end{cases} /// $$ /// where $M$ is `Self::MAX`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::saturating_square#saturating_square_assign). #[inline] fn saturating_square_assign(&mut self) { self.saturating_mul_assign(*self); } } }; } apply_to_primitive_ints!(impl_saturating_square); malachite-base-0.4.16/src/num/arithmetic/saturating_sub.rs000064400000000000000000000035201046102023000216720ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{SaturatingSub, SaturatingSubAssign}; macro_rules! impl_saturating_sub { ($t:ident) => { impl SaturatingSub<$t> for $t { type Output = $t; /// This is a wrapper over the `saturating_sub` functions in the standard library, for /// example [this one](i32::saturating_sub). #[inline] fn saturating_sub(self, other: $t) -> $t { $t::saturating_sub(self, other) } } impl SaturatingSubAssign<$t> for $t { /// Subtracts a number by another number in place, saturating at the numeric bounds /// instead of overflowing. /// /// $$ /// x \gets \\begin{cases} /// x - y & \text{if} \\quad m \leq x - y \leq M, \\\\ /// M & \text{if} \\quad x - y > M, \\\\ /// m & \text{if} \\quad x - y < m, /// \\end{cases} /// $$ /// where $m$ is `Self::MIN` and $M$ is `Self::MAX`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::saturating_sub#saturating_sub_assign). #[inline] fn saturating_sub_assign(&mut self, other: $t) { *self = self.saturating_sub(other); } } }; } apply_to_primitive_ints!(impl_saturating_sub); malachite-base-0.4.16/src/num/arithmetic/saturating_sub_mul.rs000064400000000000000000000136001046102023000225470ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{SaturatingSubMul, SaturatingSubMulAssign, UnsignedAbs}; use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::WrappingFrom; fn saturating_sub_mul_unsigned(x: T, y: T, z: T) -> T { x.saturating_sub(y.saturating_mul(z)) } fn saturating_sub_mul_assign_unsigned(x: &mut T, y: T, z: T) { x.saturating_sub_assign(y.saturating_mul(z)); } macro_rules! impl_saturating_sub_mul_unsigned { ($t:ident) => { impl SaturatingSubMul<$t> for $t { type Output = $t; /// Subtracts a number by the product of two other numbers, saturating at the numeric /// bounds instead of overflowing. /// /// $$ /// f(x, y, z) = \\begin{cases} /// x - yz & \text{if} \\quad m \leq x - yz \leq M, \\\\ /// M & \text{if} \\quad x - yz > M, \\\\ /// m & \text{if} \\quad x - yz < m, /// \\end{cases} /// $$ /// where $m$ is `Self::MIN` and $M$ is `Self::MAX`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::saturating_sub_mul#saturating_sub_mul_assign). #[inline] fn saturating_sub_mul(self, y: $t, z: $t) -> $t { saturating_sub_mul_unsigned(self, y, z) } } impl SaturatingSubMulAssign<$t> for $t { /// Subtracts a number by the product of two other numbers in place, saturating at the /// numeric bounds instead of overflowing. /// /// $$ /// x \gets \\begin{cases} /// x - yz & \text{if} \\quad m \leq x - yz \leq M, \\\\ /// M & \text{if} \\quad x - yz > M, \\\\ /// m & \text{if} \\quad x - yz < m, /// \\end{cases} /// $$ /// where $m$ is `Self::MIN` and $M$ is `Self::MAX`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::saturating_sub_mul#saturating_sub_mul_assign). #[inline] fn saturating_sub_mul_assign(&mut self, y: $t, z: $t) { saturating_sub_mul_assign_unsigned(self, y, z); } } }; } apply_to_unsigneds!(impl_saturating_sub_mul_unsigned); fn saturating_sub_mul_signed< U: PrimitiveUnsigned, S: PrimitiveSigned + UnsignedAbs + WrappingFrom, >( x: S, y: S, z: S, ) -> S { if y == S::ZERO || z == S::ZERO { return x; } let x_sign = x >= S::ZERO; if x_sign == ((y >= S::ZERO) != (z >= S::ZERO)) { x.saturating_sub(y.saturating_mul(z)) } else { let x = x.unsigned_abs(); let product = if let Some(product) = y.unsigned_abs().checked_mul(z.unsigned_abs()) { product } else { return if x_sign { S::MIN } else { S::MAX }; }; let result = S::wrapping_from(if x_sign { x.wrapping_sub(product) } else { product.wrapping_sub(x) }); if x >= product || (x_sign == (result < S::ZERO)) { result } else if x_sign { S::MIN } else { S::MAX } } } macro_rules! impl_saturating_sub_mul_signed { ($t:ident) => { impl SaturatingSubMul<$t> for $t { type Output = $t; /// Subtracts a number by the product of two other numbers, saturating at the numeric /// bounds instead of overflowing. /// /// $$ /// f(x, y, z) = \\begin{cases} /// x - yz & \text{if} \\quad m \leq x - yz \leq M, \\\\ /// M & \text{if} \\quad x - yz > M, \\\\ /// m & \text{if} \\quad x - yz < m, /// \\end{cases} /// $$ /// where $m$ is `Self::MIN` and $M$ is `Self::MAX`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::saturating_sub_mul#saturating_sub_mul). #[inline] fn saturating_sub_mul(self, y: $t, z: $t) -> $t { saturating_sub_mul_signed(self, y, z) } } impl SaturatingSubMulAssign<$t> for $t { /// Subtracts a number by the product of two other numbers in place, saturating at the /// numeric bounds instead of overflowing. /// /// $$ /// x \gets \\begin{cases} /// x - yz & \text{if} \\quad m \leq x - yz \leq M, \\\\ /// M & \text{if} \\quad x - yz > M, \\\\ /// m & \text{if} \\quad x - yz < m, /// \\end{cases} /// $$ /// where $m$ is `Self::MIN` and $M$ is `Self::MAX`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::saturating_sub_mul#saturating_sub_mul_assign). #[inline] fn saturating_sub_mul_assign(&mut self, y: $t, z: $t) { *self = self.saturating_sub_mul(y, z); } } }; } apply_to_signeds!(impl_saturating_sub_mul_signed); malachite-base-0.4.16/src/num/arithmetic/shl_round.rs000064400000000000000000000152741046102023000206460ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{ ShlRound, ShlRoundAssign, ShrRound, ShrRoundAssign, UnsignedAbs, }; use crate::num::basic::integers::PrimitiveInt; use crate::num::basic::signeds::PrimitiveSigned; use crate::rounding_modes::RoundingMode; use core::cmp::Ordering::{self, *}; use core::ops::{Shl, ShlAssign}; fn shl_round< T: PrimitiveInt + Shl + ShrRound, U, S: PrimitiveSigned + UnsignedAbs, >( x: T, bits: S, rm: RoundingMode, ) -> (T, Ordering) { if bits >= S::ZERO { let width = S::wrapping_from(T::WIDTH); ( if width >= S::ZERO && bits >= width { T::ZERO } else { x << bits.unsigned_abs() }, Equal, ) } else { x.shr_round(bits.unsigned_abs(), rm) } } fn shl_round_assign< T: PrimitiveInt + ShlAssign + ShrRoundAssign, U, S: PrimitiveSigned + UnsignedAbs, >( x: &mut T, bits: S, rm: RoundingMode, ) -> Ordering { if bits >= S::ZERO { let width = S::wrapping_from(T::WIDTH); if width >= S::ZERO && bits >= width { *x = T::ZERO; } else { *x <<= bits.unsigned_abs(); } Equal } else { x.shr_round_assign(bits.unsigned_abs(), rm) } } macro_rules! impl_shl_round { ($t:ident) => { macro_rules! impl_shl_round_inner { ($u:ident) => { impl ShlRound<$u> for $t { type Output = $t; /// Left-shifts a number (multiplies it by a power of 2 or divides it by a power /// of 2 and takes the floor) and rounds according to the specified rounding /// mode. An [`Ordering`] is also returned, indicating whether the returned /// value is less than, equal to, or greater than the exact value. If `bits` is /// non-negative, then the returned [`Ordering`] is always `Equal`, even if the /// higher bits of the result are lost. /// /// Passing `Floor` or `Down` is equivalent to using `>>`. To test whether /// `Exact` can be passed, use `bits > 0 || self.divisible_by_power_of_2(bits)`. /// Rounding might only be necessary if `bits` is negative. /// /// Let $q = x2^k$, and let $g$ be the function that just returns the first /// element of the pair, without the [`Ordering`]: /// /// $g(x, k, \mathrm{Down}) = g(x, y, \mathrm{Floor}) = \lfloor q \rfloor.$ /// /// $g(x, k, \mathrm{Up}) = g(x, y, \mathrm{Ceiling}) = \lceil q \rceil.$ /// /// $$ /// g(x, k, \mathrm{Nearest}) = \begin{cases} /// \lfloor q \rfloor & \text{if} /// \\quad q - \lfloor q \rfloor < \frac{1}{2}, \\\\ /// \lceil q \rceil & \text{if} /// \\quad q - \lfloor q \rfloor > \frac{1}{2}, \\\\ /// \lfloor q \rfloor & \text{if} \\quad q - \lfloor q \rfloor = /// \frac{1}{2} \\ \text{and} \\ \lfloor q \rfloor /// \\ \text{is even}, \\\\ /// \lceil q \rceil & /// \text{if} \\quad q - \lfloor q \rfloor = \frac{1}{2} \\ \text{and} /// \\ \lfloor q \rfloor \\ \text{is odd}. /// \end{cases} /// $$ /// /// $g(x, k, \mathrm{Exact}) = q$, but panics if $q \notin \N$. /// /// Then /// /// $f(x, k, r) = (g(x, k, r), \operatorname{cmp}(g(x, k, r), q))$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `bits` is positive and `rm` is `Exact` but `self` is not divisible /// by $2^b$. /// /// # Examples /// See [here](super::shl_round#shl_round). #[inline] fn shl_round(self, bits: $u, rm: RoundingMode) -> ($t, Ordering) { shl_round(self, bits, rm) } } impl ShlRoundAssign<$u> for $t { /// Left-shifts a number (multiplies it by a power of 2 or divides it by a power /// of 2 and takes the floor) and rounds according to the specified rounding /// mode, in place. An [`Ordering`] is returned, indicating whether the assigned /// value is less than, equal to, or greater than the exact value. If `bits` is /// non-negative, then the returned [`Ordering`] is always `Equal`, even if the /// higher bits of the result are lost. /// /// Passing `Floor` or `Down` is equivalent to using `>>`. To test whether /// `Exact` can be passed, use `bits > 0 || self.divisible_by_power_of_2(bits)`. /// Rounding might only be necessary if `bits` is negative. /// /// See the [`ShlRound`] documentation for details. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `bits` is positive and `rm` is `Exact` but `self` is not divisible /// by $2^b$. /// /// # Examples /// See [here](super::shl_round#shl_round_assign). #[inline] fn shl_round_assign(&mut self, bits: $u, rm: RoundingMode) -> Ordering { shl_round_assign(self, bits, rm) } } }; } apply_to_signeds!(impl_shl_round_inner); }; } apply_to_primitive_ints!(impl_shl_round); malachite-base-0.4.16/src/num/arithmetic/shr_round.rs000064400000000000000000000512441046102023000206510ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{ShrRound, ShrRoundAssign, UnsignedAbs}; use crate::num::basic::integers::PrimitiveInt; use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::WrappingFrom; use crate::rounding_modes::RoundingMode::{self, *}; use core::cmp::Ordering::{self, *}; use core::ops::{Shl, ShlAssign, Shr, ShrAssign}; fn shr_round_unsigned_unsigned< T: PrimitiveUnsigned + Shl + Shr, U: PrimitiveUnsigned, >( x: T, bits: U, rm: RoundingMode, ) -> (T, Ordering) { if bits == U::ZERO || x == T::ZERO { return (x, Equal); } let width = U::wrapping_from(T::WIDTH); match rm { Down | Floor if bits >= width => (T::ZERO, Less), Down | Floor => { let shifted = x >> bits; (shifted, if shifted << bits == x { Equal } else { Less }) } Up | Ceiling if bits >= width => (T::ONE, Greater), Up | Ceiling => { let shifted = x >> bits; if shifted << bits == x { (shifted, Equal) } else { (shifted + T::ONE, Greater) } } Nearest if bits == width && x > T::power_of_2(T::WIDTH - 1) => (T::ONE, Greater), Nearest if bits >= width => (T::ZERO, Less), Nearest => { let bm1 = bits - U::ONE; let mostly_shifted = x >> bm1; let bm1_zeros = mostly_shifted << bm1 == x; if mostly_shifted.even() { // round down (mostly_shifted >> 1, if bm1_zeros { Equal } else { Less }) } else if !bm1_zeros { // round up ((mostly_shifted >> 1) + T::ONE, Greater) } else { // result is half-integer; round to even let shifted: T = mostly_shifted >> 1; if shifted.even() { (shifted, Less) } else { (shifted + T::ONE, Greater) } } } Exact if bits >= width => { panic!("Right shift is not exact: {x} >> {bits}"); } Exact => { let shifted = x >> bits; assert!( shifted << bits == x, "Right shift is not exact: {x} >> {bits}" ); (shifted, Equal) } } } fn shr_round_assign_unsigned_unsigned< T: PrimitiveUnsigned + Shl + ShrAssign, U: PrimitiveUnsigned, >( x: &mut T, bits: U, rm: RoundingMode, ) -> Ordering { if bits == U::ZERO || *x == T::ZERO { return Equal; } let width = U::wrapping_from(T::WIDTH); match rm { Down | Floor if bits >= width => { *x = T::ZERO; Less } Down | Floor => { let original = *x; *x >>= bits; if *x << bits == original { Equal } else { Less } } Up | Ceiling if bits >= width => { *x = T::ONE; Greater } Up | Ceiling => { let original = *x; *x >>= bits; if *x << bits == original { Equal } else { *x += T::ONE; Greater } } Nearest if bits == width && *x > T::power_of_2(T::WIDTH - 1) => { *x = T::ONE; Greater } Nearest if bits >= width => { *x = T::ZERO; Less } Nearest => { let original = *x; let bm1 = bits - U::ONE; *x >>= bm1; let bm1_zeros = *x << bm1 == original; let old_x = *x; *x >>= 1; if old_x.even() { // round down if bm1_zeros { Equal } else { Less } } else if !bm1_zeros { // round up *x += T::ONE; Greater } else { // result is half-integer; round to even if x.even() { Less } else { *x += T::ONE; Greater } } } Exact if bits >= width => { panic!("Right shift is not exact: {} >>= {}", *x, bits); } Exact => { let original = *x; *x >>= bits; assert!( *x << bits == original, "Right shift is not exact: {original} >>= {bits}" ); Equal } } } macro_rules! impl_shr_round_unsigned_unsigned { ($t:ident) => { macro_rules! impl_shr_round_unsigned_unsigned_inner { ($u:ident) => { impl ShrRound<$u> for $t { type Output = $t; /// Shifts a number right (divides it by a power of 2) and rounds according to /// the specified rounding mode. An [`Ordering`] is also returned, indicating /// whether the returned value is less than, equal to, or greater than the exact /// value. /// /// Passing `Floor` or `Down` is equivalent to using `>>`. To test whether /// `Exact` can be passed, use `self.divisible_by_power_of_2(bits)`. /// /// Let $q = \frac{x}{2^k}$, and let $g$ be the function that just returns the /// first element of the pair, without the [`Ordering`]: /// /// $g(x, k, \mathrm{Down}) = g(x, y, \mathrm{Floor}) = \lfloor q \rfloor.$ /// /// $g(x, k, \mathrm{Up}) = g(x, y, \mathrm{Ceiling}) = \lceil q \rceil.$ /// /// $$ /// g(x, k, \mathrm{Nearest}) = \begin{cases} /// \lfloor q \rfloor & \text{if} /// \\quad q - \lfloor q \rfloor < \frac{1}{2}, \\\\ /// \lceil q \rceil & \text{if} /// \\quad q - \lfloor q \rfloor > \frac{1}{2}, \\\\ /// \lfloor q \rfloor & \text{if} \\quad q - \lfloor q \rfloor = /// \frac{1}{2} \\ \text{and} \\ \lfloor q \rfloor /// \\ \text{is even}, \\\\ /// \lceil q \rceil & /// \text{if} \\quad q - \lfloor q \rfloor = \frac{1}{2} \\ \text{and} /// \\ \lfloor q \rfloor \\ \text{is odd}. /// \end{cases} /// $$ /// /// $g(x, k, \mathrm{Exact}) = q$, but panics if $q \notin \N$. /// /// Then /// /// $f(x, k, r) = (g(x, k, r), \operatorname{cmp}(g(x, k, r), q))$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `rm` is `Exact` but `self` is not divisible by $2^b$. /// /// # Examples /// See [here](super::shr_round#shr_round). #[inline] fn shr_round(self, bits: $u, rm: RoundingMode) -> ($t, Ordering) { shr_round_unsigned_unsigned(self, bits, rm) } } impl ShrRoundAssign<$u> for $t { /// Shifts a number right (divides it by a power of 2) and rounds according to /// the specified rounding mode, in place. An [`Ordering`] is returned, /// indicating whether the assigned value is less than, equal to, or greater /// than the exact value. /// /// Passing `Floor` or `Down` is equivalent to using `>>`. To test whether /// `Exact` can be passed, use `self.divisible_by_power_of_2(bits)`. /// /// See the [`ShrRound`] documentation for details. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `rm` is `Exact` but `self` is not divisible by $2^b$. /// /// # Examples /// See [here](super::shr_round#shr_round_assign). #[inline] fn shr_round_assign(&mut self, bits: $u, rm: RoundingMode) -> Ordering { shr_round_assign_unsigned_unsigned(self, bits, rm) } } }; } apply_to_unsigneds!(impl_shr_round_unsigned_unsigned_inner); }; } apply_to_unsigneds!(impl_shr_round_unsigned_unsigned); fn shr_round_signed_unsigned< U: PrimitiveUnsigned + ShrRound, S: PrimitiveSigned + UnsignedAbs + WrappingFrom, B, >( x: S, bits: B, rm: RoundingMode, ) -> (S, Ordering) { let abs = x.unsigned_abs(); if x >= S::ZERO { let (abs_shifted, o) = abs.shr_round(bits, rm); (S::wrapping_from(abs_shifted), o) } else { let (abs_shifted, o) = abs.shr_round(bits, -rm); ( if abs_shifted == U::ZERO { S::ZERO } else if abs_shifted == S::MIN.unsigned_abs() { S::MIN } else { -S::wrapping_from(abs_shifted) }, o.reverse(), ) } } macro_rules! impl_shr_round_signed_unsigned { ($t:ident) => { macro_rules! impl_shr_round_signed_unsigned_inner { ($u:ident) => { impl ShrRound<$u> for $t { type Output = $t; /// Shifts a number right (divides it by a power of 2) and rounds according to /// the specified rounding mode. An [`Ordering`] is also returned, indicating /// whether the returned value is less than, equal to, or greater than the exact /// value. /// /// Passing `Floor` or `Down` is equivalent to using `>>`. To test whether /// `Exact` can be passed, use `self.divisible_by_power_of_2(bits)`. /// /// Let $q = \frac{x}{2^k}$, and let $g$ be the function that just returns the /// first element of the pair, without the [`Ordering`]: /// /// $g(x, k, \mathrm{Down}) = g(x, y, \mathrm{Floor}) = \lfloor q \rfloor.$ /// /// $g(x, k, \mathrm{Up}) = g(x, y, \mathrm{Ceiling}) = \lceil q \rceil.$ /// /// $$ /// g(x, k, \mathrm{Nearest}) = \begin{cases} /// \lfloor q \rfloor & \text{if} /// \\quad q - \lfloor q \rfloor < \frac{1}{2}, \\\\ /// \lceil q \rceil & \text{if} /// \\quad q - \lfloor q \rfloor > \frac{1}{2}, \\\\ /// \lfloor q \rfloor & \text{if} \\quad q - \lfloor q \rfloor = /// \frac{1}{2} \\ \text{and} \\ \lfloor q \rfloor /// \\ \text{is even}, \\\\ /// \lceil q \rceil & /// \text{if} \\quad q - \lfloor q \rfloor = \frac{1}{2} \\ \text{and} /// \\ \lfloor q \rfloor \\ \text{is odd}. /// \end{cases} /// $$ /// /// $g(x, k, \mathrm{Exact}) = q$, but panics if $q \notin \N$. /// /// Then /// /// $f(x, k, r) = (g(x, k, r), \operatorname{cmp}(g(x, k, r), q))$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `rm` is `Exact` but `self` is not divisible by $2^b$. /// /// # Examples /// See [here](super::shr_round#shr_round). #[inline] fn shr_round(self, bits: $u, rm: RoundingMode) -> ($t, Ordering) { shr_round_signed_unsigned(self, bits, rm) } } impl ShrRoundAssign<$u> for $t { /// Shifts a number right (divides it by a power of 2) and rounds according to /// the specified rounding mode, in place. An [`Ordering`] isreturned, /// indicating whether the assigned value is less than, equal to, or greater /// than the exact value. /// /// Passing `Floor` or `Down` is equivalent to using `>>`. To test whether /// `Exact` can be passed, use `self.divisible_by_power_of_2(bits)`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `rm` is `Exact` but `self` is not divisible by $2^b$. /// /// # Examples /// See [here](super::shr_round#shr_round_assign). #[inline] fn shr_round_assign(&mut self, bits: $u, rm: RoundingMode) -> Ordering { let o; (*self, o) = self.shr_round(bits, rm); o } } }; } apply_to_unsigneds!(impl_shr_round_signed_unsigned_inner); }; } apply_to_signeds!(impl_shr_round_signed_unsigned); fn shr_round_primitive_signed< T: PrimitiveInt + Shl + ShrRound, U: PrimitiveUnsigned, S: PrimitiveSigned + UnsignedAbs, >( x: T, bits: S, rm: RoundingMode, ) -> (T, Ordering) { if bits >= S::ZERO { x.shr_round(bits.unsigned_abs(), rm) } else { let abs = bits.unsigned_abs(); ( if abs >= U::wrapping_from(T::WIDTH) { T::ZERO } else { x << bits.unsigned_abs() }, Equal, ) } } fn shr_round_assign_primitive_signed< T: PrimitiveInt + ShlAssign + ShrRoundAssign, U: PrimitiveUnsigned, S: PrimitiveSigned + UnsignedAbs, >( x: &mut T, bits: S, rm: RoundingMode, ) -> Ordering { if bits >= S::ZERO { x.shr_round_assign(bits.unsigned_abs(), rm) } else { let abs = bits.unsigned_abs(); if abs >= U::wrapping_from(T::WIDTH) { *x = T::ZERO; } else { *x <<= bits.unsigned_abs(); } Equal } } macro_rules! impl_shr_round_primitive_signed { ($t:ident) => { macro_rules! impl_shr_round_primitive_signed_inner { ($u:ident) => { impl ShrRound<$u> for $t { type Output = $t; /// Shifts a number right (divides it by a power of 2) and rounds according to /// the specified rounding mode. An [`Ordering`] is also returned, indicating /// whether the returned value is less than, equal to, or greater than the exact /// value. If `bits` is negative, then the returned [`Ordering`] is always /// `Equal`, even if the higher bits of the result are lost. /// /// Passing `Floor` or `Down` is equivalent to using `>>`. To test whether /// `Exact` can be passed, use `self.divisible_by_power_of_2(bits)`. Rounding /// might only be necessary if `bits` is non-negative. /// /// Let $q = \frac{x}{2^k}$, and let $g$ be the function that just returns the /// first element of the pair, without the [`Ordering`]: /// /// $g(x, k, \mathrm{Down}) = \operatorname{sgn}(q) \lfloor |q| \rfloor.$ /// /// $g(x, k, \mathrm{Up}) = \operatorname{sgn}(q) \lceil |q| \rceil.$ /// /// $g(x, k, \mathrm{Floor}) = \lfloor q \rfloor.$ /// /// $g(x, k, \mathrm{Ceiling}) = \lceil q \rceil.$ /// /// $$ /// g(x, k, \mathrm{Nearest}) = \begin{cases} /// \lfloor q \rfloor & \text{if} /// \\quad q - \lfloor q \rfloor < \frac{1}{2}, \\\\ /// \lceil q \rceil & \text{if} /// \\quad q - \lfloor q \rfloor > \frac{1}{2}, \\\\ /// \lfloor q \rfloor & \text{if} \\quad q - \lfloor q \rfloor = /// \frac{1}{2} \\ \text{and} \\ \lfloor q \rfloor /// \\ \text{is even}, \\\\ /// \lceil q \rceil & /// \text{if} \\quad q - \lfloor q \rfloor = \frac{1}{2} \\ \text{and} /// \\ \lfloor q \rfloor \\ \text{is odd}. /// \end{cases} /// $$ /// /// $g(x, k, \mathrm{Exact}) = q$, but panics if $q \notin \Z$. /// /// Then /// /// $f(x, k, r) = (g(x, k, r), \operatorname{cmp}(g(x, k, r), q))$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `bits` is positive and `rm` is `Exact` but `self` is not divisible /// by $2^b$. /// /// # Examples /// See [here](super::shr_round#shr_round). #[inline] fn shr_round(self, bits: $u, rm: RoundingMode) -> ($t, Ordering) { shr_round_primitive_signed(self, bits, rm) } } impl ShrRoundAssign<$u> for $t { /// Shifts a number right (divides it by a power of 2) and rounds according to /// the specified rounding mode, in place. An [`Ordering`] is returned, /// indicating whether the assigned value is less than, equal to, or greater /// than the exact value. If `bits` is negative, then the returned [`Ordering`] /// is always `Equal`, even if the higher bits of the result are lost. /// /// Passing `Floor` or `Down` is equivalent to using `>>`. To test whether /// `Exact` can be passed, use `self.divisible_by_power_of_2(bits)`. Rounding /// might only be necessary if `bits` is non-negative. /// /// See the [`ShrRound`] documentation for details. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `bits` is positive and `rm` is `Exact` but `self` is not divisible /// by $2^b$. /// /// # Examples /// See [here](super::shr_round#shr_round_assign). #[inline] fn shr_round_assign(&mut self, bits: $u, rm: RoundingMode) -> Ordering { shr_round_assign_primitive_signed(self, bits, rm) } } }; } apply_to_signeds!(impl_shr_round_primitive_signed_inner); }; } apply_to_primitive_ints!(impl_shr_round_primitive_signed); malachite-base-0.4.16/src/num/arithmetic/sign.rs000064400000000000000000000040261046102023000176020ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::Sign; use core::cmp::Ordering::{self, *}; macro_rules! impl_sign_primitive_int { ($t:ident) => { impl Sign for $t { /// Compares a number to zero. /// /// Returns `Greater`, `Equal`, or `Less`, depending on whether the number is positive, /// zero, or negative, respectively. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::sign#sign). #[inline] fn sign(&self) -> Ordering { self.cmp(&0) } } }; } apply_to_primitive_ints!(impl_sign_primitive_int); macro_rules! impl_sign_primitive_float { ($t:ident) => { impl Sign for $t { /// Compares a number to zero. /// /// - Positive finite numbers, positive zero, and positive infinity have sign `Greater`. /// - Negative finite numbers, negative zero, and negative infinity have sign `Less`. /// - `NaN` has sign `Equal`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::sign#sign). #[inline] fn sign(&self) -> Ordering { if self.is_nan() { Equal } else if self.is_sign_positive() { Greater } else { Less } } } }; } apply_to_primitive_floats!(impl_sign_primitive_float); malachite-base-0.4.16/src/num/arithmetic/sqrt.rs000064400000000000000000001150521046102023000176350ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // Uses code adopted from the GNU MP Library. // // `mpn_sqrtrem1` contributed to the GNU project by Torbjörn Granlund. // // Copyright © 1999-2002, 2004, 2005, 2008, 2010, 2012, 2015, 2017 Free Software Foundation, // Inc. // // Uses code adopted from the FLINT Library. // // Copyright © 2009 William Hart // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{ CeilingSqrt, CeilingSqrtAssign, CheckedSqrt, FloorSqrt, FloorSqrtAssign, Ln, RoundToMultipleOfPowerOf2, ShrRound, Sqrt, SqrtAssign, SqrtAssignRem, SqrtRem, }; use crate::num::basic::integers::PrimitiveInt; use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::WrappingFrom; use crate::num::logic::traits::SignificantBits; use crate::rounding_modes::RoundingMode::*; use core::cmp::Ordering::*; const U8_SQUARES: [u8; 16] = [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225]; impl FloorSqrt for u8 { type Output = u8; /// Returns the floor of the square root of a [`u8`]. /// /// $f(x) = \lfloor\sqrt{x}\rfloor$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::sqrt#floor_sqrt). /// /// # Notes /// The [`u8`] implementation uses a lookup table. fn floor_sqrt(self) -> u8 { u8::wrapping_from(match U8_SQUARES.binary_search(&self) { Ok(i) => i, Err(i) => i - 1, }) } } impl CeilingSqrt for u8 { type Output = u8; /// Returns the ceiling of the square root of a [`u8`]. /// /// $f(x) = \lceil\sqrt{x}\rceil$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::sqrt#ceiling_sqrt). /// /// # Notes /// The [`u8`] implementation uses a lookup table. fn ceiling_sqrt(self) -> u8 { u8::wrapping_from(match U8_SQUARES.binary_search(&self) { Ok(i) | Err(i) => i, }) } } impl CheckedSqrt for u8 { type Output = u8; /// Returns the the square root of a [`u8`], or `None` if the [`u8`] is not a perfect square. /// /// $$ /// f(x) = \\begin{cases} /// \operatorname{Some}(sqrt{x}) & \text{if} \\quad \sqrt{x} \in \Z, \\\\ /// \operatorname{None} & \textrm{otherwise}. /// \\end{cases} /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::sqrt#checked_sqrt). /// /// # Notes /// The [`u8`] implementation uses a lookup table. fn checked_sqrt(self) -> Option { U8_SQUARES.binary_search(&self).ok().map(u8::wrapping_from) } } impl SqrtRem for u8 { type SqrtOutput = u8; type RemOutput = u8; /// Returns the floor of the square root of a [`u8`], and the remainder (the difference between /// the [`u8`] and the square of the floor). /// /// $f(x) = (\lfloor\sqrt{x}\rfloor, x - \lfloor\sqrt{x}\rfloor^2)$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::sqrt#sqrt_rem). /// /// # Notes /// The [`u8`] implementation uses a lookup table. fn sqrt_rem(self) -> (u8, u8) { match U8_SQUARES.binary_search(&self) { Ok(i) => (u8::wrapping_from(i), 0), Err(i) => (u8::wrapping_from(i - 1), self - U8_SQUARES[i - 1]), } } } pub(crate) fn floor_inverse_checked_binary Option>( f: F, x: T, mut low: T, mut high: T, ) -> T { loop { if high <= low { return low; } let mid: T = low.checked_add(high).unwrap().shr_round(1, Ceiling).0; match f(mid).map(|mid| mid.cmp(&x)) { Some(Equal) => return mid, Some(Less) => low = mid, Some(Greater) | None => high = mid - T::ONE, } } } pub_test! {floor_sqrt_binary(x: T) -> T { if x < T::TWO { x } else { let p = T::power_of_2(x.significant_bits().shr_round(1, Ceiling).0); floor_inverse_checked_binary(T::checked_square, x, p >> 1, p) } }} pub_test! {ceiling_sqrt_binary(x: T) -> T { let floor_sqrt = floor_sqrt_binary(x); if floor_sqrt.square() == x { floor_sqrt } else { floor_sqrt + T::ONE } }} pub_test! {checked_sqrt_binary(x: T) -> Option { let floor_sqrt = floor_sqrt_binary(x); if floor_sqrt.square() == x { Some(floor_sqrt) } else { None } }} pub_test! {sqrt_rem_binary(x: T) -> (T, T) { let floor_sqrt = floor_sqrt_binary(x); (floor_sqrt, x - floor_sqrt.square()) }} const INV_SQRT_TAB: [u16; 384] = [ 0xff, 0xfd, 0xfb, 0xf9, 0xf7, 0xf5, 0xf3, 0xf2, 0xf0, 0xee, 0xec, 0xea, 0xe9, 0xe7, 0xe5, 0xe4, 0xe2, 0xe0, 0xdf, 0xdd, 0xdb, 0xda, 0xd8, 0xd7, 0xd5, 0xd4, 0xd2, 0xd1, 0xcf, 0xce, 0xcc, 0xcb, 0xc9, 0xc8, 0xc6, 0xc5, 0xc4, 0xc2, 0xc1, 0xc0, 0xbe, 0xbd, 0xbc, 0xba, 0xb9, 0xb8, 0xb7, 0xb5, 0xb4, 0xb3, 0xb2, 0xb0, 0xaf, 0xae, 0xad, 0xac, 0xaa, 0xa9, 0xa8, 0xa7, 0xa6, 0xa5, 0xa4, 0xa3, 0xa2, 0xa0, 0x9f, 0x9e, 0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, 0x97, 0x96, 0x95, 0x94, 0x93, 0x92, 0x91, 0x90, 0x8f, 0x8e, 0x8d, 0x8c, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86, 0x85, 0x84, 0x83, 0x83, 0x82, 0x81, 0x80, 0x7f, 0x7e, 0x7e, 0x7d, 0x7c, 0x7b, 0x7a, 0x79, 0x79, 0x78, 0x77, 0x76, 0x76, 0x75, 0x74, 0x73, 0x72, 0x72, 0x71, 0x70, 0x6f, 0x6f, 0x6e, 0x6d, 0x6d, 0x6c, 0x6b, 0x6a, 0x6a, 0x69, 0x68, 0x68, 0x67, 0x66, 0x66, 0x65, 0x64, 0x64, 0x63, 0x62, 0x62, 0x61, 0x60, 0x60, 0x5f, 0x5e, 0x5e, 0x5d, 0x5c, 0x5c, 0x5b, 0x5a, 0x5a, 0x59, 0x59, 0x58, 0x57, 0x57, 0x56, 0x56, 0x55, 0x54, 0x54, 0x53, 0x53, 0x52, 0x52, 0x51, 0x50, 0x50, 0x4f, 0x4f, 0x4e, 0x4e, 0x4d, 0x4d, 0x4c, 0x4b, 0x4b, 0x4a, 0x4a, 0x49, 0x49, 0x48, 0x48, 0x47, 0x47, 0x46, 0x46, 0x45, 0x45, 0x44, 0x44, 0x43, 0x43, 0x42, 0x42, 0x41, 0x41, 0x40, 0x40, 0x3f, 0x3f, 0x3e, 0x3e, 0x3d, 0x3d, 0x3c, 0x3c, 0x3b, 0x3b, 0x3a, 0x3a, 0x39, 0x39, 0x39, 0x38, 0x38, 0x37, 0x37, 0x36, 0x36, 0x35, 0x35, 0x35, 0x34, 0x34, 0x33, 0x33, 0x32, 0x32, 0x32, 0x31, 0x31, 0x30, 0x30, 0x2f, 0x2f, 0x2f, 0x2e, 0x2e, 0x2d, 0x2d, 0x2d, 0x2c, 0x2c, 0x2b, 0x2b, 0x2b, 0x2a, 0x2a, 0x29, 0x29, 0x29, 0x28, 0x28, 0x27, 0x27, 0x27, 0x26, 0x26, 0x26, 0x25, 0x25, 0x24, 0x24, 0x24, 0x23, 0x23, 0x23, 0x22, 0x22, 0x21, 0x21, 0x21, 0x20, 0x20, 0x20, 0x1f, 0x1f, 0x1f, 0x1e, 0x1e, 0x1e, 0x1d, 0x1d, 0x1d, 0x1c, 0x1c, 0x1b, 0x1b, 0x1b, 0x1a, 0x1a, 0x1a, 0x19, 0x19, 0x19, 0x18, 0x18, 0x18, 0x18, 0x17, 0x17, 0x17, 0x16, 0x16, 0x16, 0x15, 0x15, 0x15, 0x14, 0x14, 0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10, 0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 0x0d, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, ]; // This is equivalent to `mpn_sqrtrem1` from `mpn/generic/sqrtrem.c`, GMP 6.2.1, where both the // square root and the remainder are returned. #[doc(hidden)] pub fn sqrt_rem_newton< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >( n: U, ) -> (U, U) { let magic = match U::WIDTH { u32::WIDTH => { U::wrapping_from(0x100000u32) // 0xfee6f < MAGIC < 0x29cbc8 } u64::WIDTH => { U::wrapping_from(0x10000000000u64) // 0xffe7debbfc < magic < 0x232b1850f410 } _ => panic!(), }; assert!(n.leading_zeros() < 2); // Use Newton iterations for approximating 1/sqrt(a) instead of sqrt(a), since we can do the // former without division. As part of the last iteration convert from 1/sqrt(a) to sqrt(a). let i: usize = (n >> (U::WIDTH - 9)).wrapping_into(); // extract bits for table lookup let mut inv_sqrt = U::wrapping_from(INV_SQRT_TAB[i - 0x80]); inv_sqrt.set_bit(8); // initial 1/sqrt(a) let mut sqrt: U = match U::WIDTH { u32::WIDTH => { let p = inv_sqrt * (n >> 8); let t: U = p >> 13; let a: U = n << 6; let t = S::wrapping_from(a.wrapping_sub(t.wrapping_square()).wrapping_sub(magic)) >> 8; p.wrapping_add(U::wrapping_from((S::wrapping_from(inv_sqrt) * t) >> 7)) >> 16 } u64::WIDTH => { let a1 = n >> (U::WIDTH - 33); let t = (S::wrapping_from(0x2000000000000u64 - 0x30000) - S::wrapping_from(a1 * inv_sqrt.square())) >> 16; let a: U = inv_sqrt << 16; inv_sqrt = a.wrapping_add(U::wrapping_from((S::wrapping_from(inv_sqrt) * t) >> 18)); let p = inv_sqrt * (n >> 24); let t: U = p >> 25; let a: U = n << 14; let t = S::wrapping_from(a.wrapping_sub(t.wrapping_square()).wrapping_sub(magic)) >> 24; p.wrapping_add(U::wrapping_from((S::wrapping_from(inv_sqrt) * t) >> 15)) >> 32 } _ => unreachable!(), }; // x0 is now a full limb approximation of sqrt(a0) let mut square = sqrt.square(); if square + (sqrt << 1) < n { square += (sqrt << 1) + U::ONE; sqrt += U::ONE; } (sqrt, n - square) } // This is equivalent to `n_sqrt` from `ulong_extras/sqrt.c`, FLINT 2.7.1. fn floor_sqrt_approx_and_refine f64, G: Fn(f64) -> T>( f: F, g: G, max_square: T, x: T, ) -> T { if x >= max_square { return T::low_mask(T::WIDTH >> 1); } let mut sqrt = g(f(x).sqrt()); let mut square = if let Some(square) = sqrt.checked_square() { square } else { // set to max possible sqrt sqrt = T::low_mask(T::WIDTH >> 1); sqrt.square() }; match square.cmp(&x) { Equal => sqrt, Less => loop { square = square.checked_add((sqrt << 1) + T::ONE).unwrap(); sqrt += T::ONE; match square.cmp(&x) { Equal => return sqrt, Less => {} Greater => return sqrt - T::ONE, } }, Greater => loop { square -= (sqrt << 1) - T::ONE; sqrt -= T::ONE; if square <= x { return sqrt; } }, } } fn ceiling_sqrt_approx_and_refine f64, G: Fn(f64) -> T>( f: F, g: G, max_square: T, x: T, ) -> T { if x > max_square { return T::power_of_2(T::WIDTH >> 1); } let mut sqrt = g(f(x).sqrt()); let mut square = if let Some(square) = sqrt.checked_square() { square } else { // set to max possible sqrt sqrt = T::low_mask(T::WIDTH >> 1); sqrt.square() }; match square.cmp(&x) { Equal => sqrt, Less => loop { square = square.checked_add((sqrt << 1) + T::ONE).unwrap(); sqrt += T::ONE; if square >= x { return sqrt; } }, Greater => loop { square -= (sqrt << 1) - T::ONE; sqrt -= T::ONE; match square.cmp(&x) { Equal => return sqrt, Greater => {} Less => return sqrt + T::ONE, } }, } } fn checked_sqrt_approx_and_refine f64, G: Fn(f64) -> T>( f: F, g: G, max_square: T, x: T, ) -> Option { if x > max_square { return None; } let mut sqrt = g(f(x).sqrt()); let mut square = if let Some(square) = sqrt.checked_square() { square } else { // set to max possible sqrt sqrt = T::low_mask(T::WIDTH >> 1); sqrt.square() }; match square.cmp(&x) { Equal => Some(sqrt), Less => loop { square = square.checked_add((sqrt << 1) + T::ONE).unwrap(); sqrt += T::ONE; match square.cmp(&x) { Equal => return Some(sqrt), Less => {} Greater => return None, } }, Greater => loop { square -= (sqrt << 1) - T::ONE; sqrt -= T::ONE; match square.cmp(&x) { Equal => return Some(sqrt), Less => return None, Greater => {} } }, } } // This is equivalent to `n_sqrtrem` from `ulong_extras/sqrtrem.c`, FLINT 2.7.1. fn sqrt_rem_approx_and_refine f64, G: Fn(f64) -> T>( f: F, g: G, max_square: T, x: T, ) -> (T, T) { if x >= max_square { return (T::low_mask(T::WIDTH >> 1), x - max_square); } let mut sqrt = g(f(x).sqrt()); let mut square = if let Some(square) = sqrt.checked_square() { square } else { // set to max possible sqrt sqrt = T::low_mask(T::WIDTH >> 1); sqrt.square() }; match square.cmp(&x) { Equal => (sqrt, T::ZERO), Less => loop { square = square.checked_add((sqrt << 1) + T::ONE).unwrap(); sqrt += T::ONE; match square.cmp(&x) { Equal => return (sqrt, T::ZERO), Less => {} Greater => { square -= (sqrt << 1) - T::ONE; sqrt -= T::ONE; return (sqrt, x - square); } } }, Greater => loop { square -= (sqrt << 1) - T::ONE; sqrt -= T::ONE; if square <= x { return (sqrt, x - square); } }, } } fn floor_sqrt_newton_helper< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >( x: U, ) -> U { if x == U::ZERO { return U::ZERO; } let shift = x .leading_zeros() .round_to_multiple_of_power_of_2(1, Floor) .0; sqrt_rem_newton::(x << shift).0 >> (shift >> 1) } fn ceiling_sqrt_newton_helper< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >( x: U, ) -> U { if x == U::ZERO { return U::ZERO; } let shift = x .leading_zeros() .round_to_multiple_of_power_of_2(1, Floor) .0; let (mut sqrt, rem) = sqrt_rem_newton::(x << shift); sqrt >>= shift >> 1; if rem != U::ZERO { sqrt += U::ONE; } sqrt } fn checked_sqrt_newton_helper< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >( x: U, ) -> Option { if x == U::ZERO { return Some(U::ZERO); } let shift = x .leading_zeros() .round_to_multiple_of_power_of_2(1, Floor) .0; let (sqrt, rem) = sqrt_rem_newton::(x << shift); if rem == U::ZERO { Some(sqrt >> (shift >> 1)) } else { None } } fn sqrt_rem_newton_helper< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >( x: U, ) -> (U, U) { if x == U::ZERO { return (U::ZERO, U::ZERO); } let shift = x .leading_zeros() .round_to_multiple_of_power_of_2(1, Floor) .0; let (mut sqrt, rem) = sqrt_rem_newton::(x << shift); if shift == 0 { (sqrt, rem) } else { sqrt >>= shift >> 1; (sqrt, x - sqrt.square()) } } macro_rules! impl_sqrt_newton { ($u: ident, $s: ident) => { impl FloorSqrt for $u { type Output = $u; /// Returns the floor of the square root of an integer. /// /// $f(x) = \lfloor\sqrt{x}\rfloor$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::sqrt#floor_sqrt). /// /// # Notes /// For [`u32`] and [`u64`], the square root is computed using Newton's method. #[inline] fn floor_sqrt(self) -> $u { floor_sqrt_newton_helper::<$u, $s>(self) } } impl CeilingSqrt for $u { type Output = $u; /// Returns the ceiling of the square root of an integer. /// /// $f(x) = \lceil\sqrt{x}\rceil$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::sqrt#ceiling_sqrt). /// /// # Notes /// For [`u32`] and [`u64`], the square root is computed using Newton's method. #[inline] fn ceiling_sqrt(self) -> $u { ceiling_sqrt_newton_helper::<$u, $s>(self) } } impl CheckedSqrt for $u { type Output = $u; /// Returns the the square root of an integer, or `None` if the integer is not a perfect /// square. /// /// $$ /// f(x) = \\begin{cases} /// \operatorname{Some}(sqrt{x}) & \text{if} \\quad \sqrt{x} \in \Z, \\\\ /// \operatorname{None} & \textrm{otherwise}. /// \\end{cases} /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::sqrt#checked_sqrt). /// /// # Notes /// For [`u32`] and [`u64`], the square root is computed using Newton's method. #[inline] fn checked_sqrt(self) -> Option<$u> { checked_sqrt_newton_helper::<$u, $s>(self) } } impl SqrtRem for $u { type SqrtOutput = $u; type RemOutput = $u; /// Returns the floor of the square root of an integer, and the remainder (the /// difference between the integer and the square of the floor). /// /// $f(x) = (\lfloor\sqrt{x}\rfloor, x - \lfloor\sqrt{x}\rfloor^2)$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::sqrt#sqrt_rem). /// /// # Notes /// For [`u32`] and [`u64`], the square root is computed using Newton's method. #[inline] fn sqrt_rem(self) -> ($u, $u) { sqrt_rem_newton_helper::<$u, $s>(self) } } }; } impl_sqrt_newton!(u32, i32); impl_sqrt_newton!(u64, i64); impl FloorSqrt for u16 { type Output = u16; /// Returns the floor of the square root of a [`u16`]. /// /// $f(x) = \lfloor\sqrt{x}\rfloor$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::sqrt#floor_sqrt). /// /// # Notes /// The [`u16`] implementation calls the implementation for [`u32`]s. #[inline] fn floor_sqrt(self) -> u16 { u16::wrapping_from(u32::from(self).floor_sqrt()) } } impl CeilingSqrt for u16 { type Output = u16; /// Returns the ceiling of the square root of a [`u16`]. /// /// $f(x) = \lceil\sqrt{x}\rceil$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::sqrt#ceiling_sqrt). /// /// # Notes /// The [`u16`] implementation calls the implementation for [`u32`]s. #[inline] fn ceiling_sqrt(self) -> u16 { u16::wrapping_from(u32::from(self).ceiling_sqrt()) } } impl CheckedSqrt for u16 { type Output = u16; /// Returns the the square root of a [`u16`], or `None` if the integer is not a perfect square. /// /// $$ /// f(x) = \\begin{cases} /// \operatorname{Some}(sqrt{x}) & \text{if} \\quad \sqrt{x} \in \Z, \\\\ /// \operatorname{None} & \textrm{otherwise}. /// \\end{cases} /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::sqrt#checked_sqrt). /// /// # Notes /// The [`u16`] implementation calls the implementation for [`u32`]s. #[inline] fn checked_sqrt(self) -> Option { u32::from(self).checked_sqrt().map(u16::wrapping_from) } } impl SqrtRem for u16 { type SqrtOutput = u16; type RemOutput = u16; /// Returns the floor of the square root of a [`u16`], and the remainder (the difference between /// the [`u16`] and the square of the floor). /// /// $f(x) = (\lfloor\sqrt{x}\rfloor, x - \lfloor\sqrt{x}\rfloor^2)$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::sqrt#sqrt_rem). /// /// # Notes /// The [`u16`] implementation calls the implementation for [`u32`]s. #[inline] fn sqrt_rem(self) -> (u16, u16) { let (sqrt, rem) = u32::from(self).sqrt_rem(); (u16::wrapping_from(sqrt), u16::wrapping_from(rem)) } } impl FloorSqrt for usize { type Output = usize; /// Returns the floor of the square root of a [`usize`]. /// /// $f(x) = \lfloor\sqrt{x}\rfloor$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::sqrt#floor_sqrt). /// /// # Notes /// The [`usize`] implementation calls the [`u32`] or [`u64`] implementations. #[inline] fn floor_sqrt(self) -> usize { match usize::WIDTH { u32::WIDTH => usize::wrapping_from(u32::wrapping_from(self).floor_sqrt()), u64::WIDTH => usize::wrapping_from(u64::wrapping_from(self).floor_sqrt()), _ => panic!("Unsupported usize size"), } } } impl CeilingSqrt for usize { type Output = usize; /// Returns the ceiling of the square root of a [`usize`]. /// /// $f(x) = \lceil\sqrt{x}\rceil$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::sqrt#ceiling_sqrt). /// /// # Notes /// The [`usize`] implementation calls the [`u32`] or [`u64`] implementations. #[inline] fn ceiling_sqrt(self) -> usize { match usize::WIDTH { u32::WIDTH => usize::wrapping_from(u32::wrapping_from(self).ceiling_sqrt()), u64::WIDTH => usize::wrapping_from(u64::wrapping_from(self).ceiling_sqrt()), _ => panic!("Unsupported usize size"), } } } impl CheckedSqrt for usize { type Output = usize; /// Returns the the square root of a [`usize`], or `None` if the [`usize`] is not a perfect /// square. /// /// $$ /// f(x) = \\begin{cases} /// \operatorname{Some}(sqrt{x}) & \text{if} \\quad \sqrt{x} \in \Z, \\\\ /// \operatorname{None} & \textrm{otherwise}. /// \\end{cases} /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::sqrt#checked_sqrt). /// /// # Notes /// The [`usize`] implementation calls the [`u32`] or [`u64`] implementations. #[inline] fn checked_sqrt(self) -> Option { match usize::WIDTH { u32::WIDTH => u32::wrapping_from(self) .checked_sqrt() .map(usize::wrapping_from), u64::WIDTH => u64::wrapping_from(self) .checked_sqrt() .map(usize::wrapping_from), _ => panic!("Unsupported usize size"), } } } impl SqrtRem for usize { type SqrtOutput = usize; type RemOutput = usize; /// Returns the floor of the square root of a [`usize`], and the remainder (the difference /// between the [`usize`] and the square of the floor). /// /// $f(x) = (\lfloor\sqrt{x}\rfloor, x - \lfloor\sqrt{x}\rfloor^2)$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::sqrt#sqrt_rem). /// /// # Notes /// The [`usize`] implementation calls the [`u32`] or [`u64`] implementations. #[inline] fn sqrt_rem(self) -> (usize, usize) { match usize::WIDTH { u32::WIDTH => { let (sqrt, rem) = u32::wrapping_from(self).sqrt_rem(); (usize::wrapping_from(sqrt), usize::wrapping_from(rem)) } u64::WIDTH => { let (sqrt, rem) = u64::wrapping_from(self).sqrt_rem(); (usize::wrapping_from(sqrt), usize::wrapping_from(rem)) } _ => panic!("Unsupported usize size"), } } } // TODO tune const U128_SQRT_THRESHOLD: u64 = 125; const U128_MAX_SQUARE: u128 = 0xfffffffffffffffe0000000000000001; impl FloorSqrt for u128 { type Output = u128; /// Returns the floor of the square root of a [`u128`]. /// /// $f(x) = \lfloor\sqrt{x}\rfloor$. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`. /// /// # Examples /// See [here](super::sqrt#floor_sqrt). /// /// # Notes /// For [`u128`], using a floating-point approximation and refining the result works, but the /// number of necessary adjustments becomes large for large [`u128`]s. To overcome this, large /// [`u128`]s switch to a binary search algorithm. To get decent starting bounds, the following /// fact is used: /// /// If $x$ is nonzero and has $b$ significant bits, then /// /// $2^{b-1} \leq x \leq 2^b-1$, /// /// $2^{b-1} \leq x \leq 2^b$, /// /// $2^{2\lfloor (b-1)/2 \rfloor} \leq x \leq 2^{2\lceil b/2 \rceil}$, /// /// $2^{2(\lceil b/2 \rceil-1)} \leq x \leq 2^{2\lceil b/2 \rceil}$, /// /// $\lfloor\sqrt{2^{2(\lceil b/2 \rceil-1)}}\rfloor \leq \lfloor\sqrt{x}\rfloor \leq /// \lfloor\sqrt{2^{2\lceil b/2 \rceil}}\rfloor$, since $x \mapsto \lfloor\sqrt{x}\rfloor$ is /// weakly increasing, /// /// $2^{\lceil b/2 \rceil-1} \leq \lfloor\sqrt{x}\rfloor \leq 2^{\lceil b/2 \rceil}$. /// /// For example, since $10^9$ has 30 significant bits, we know that $2^{14} \leq /// \lfloor\sqrt{10^9}\rfloor \leq 2^{15}$. fn floor_sqrt(self) -> u128 { if self.significant_bits() < U128_SQRT_THRESHOLD { floor_sqrt_approx_and_refine(|x| x as f64, |x| x as u128, U128_MAX_SQUARE, self) } else { floor_sqrt_binary(self) } } } impl CeilingSqrt for u128 { type Output = u128; /// Returns the ceiling of the square root of a [`u128`]. /// /// $f(x) = \lceil\sqrt{x}\rceil$. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`. /// /// # Examples /// See [here](super::sqrt#ceiling_sqrt). /// /// # Notes /// For [`u128`], using a floating-point approximation and refining the result works, but the /// number of necessary adjustments becomes large for large [`u128`]s. To overcome this, large /// [`u128`]s switch to a binary search algorithm. To get decent starting bounds, the following /// fact is used: /// /// If $x$ is nonzero and has $b$ significant bits, then /// /// $2^{b-1} \leq x \leq 2^b-1$, /// /// $2^{b-1} \leq x \leq 2^b$, /// /// $2^{2\lfloor (b-1)/2 \rfloor} \leq x \leq 2^{2\lceil b/2 \rceil}$, /// /// $2^{2(\lceil b/2 \rceil-1)} \leq x \leq 2^{2\lceil b/2 \rceil}$, /// /// $\lfloor\sqrt{2^{2(\lceil b/2 \rceil-1)}}\rfloor \leq \lfloor\sqrt{x}\rfloor \leq /// \lfloor\sqrt{2^{2\lceil b/2 \rceil}}\rfloor$, since $x \mapsto \lfloor\sqrt{x}\rfloor$ is /// weakly increasing, /// /// $2^{\lceil b/2 \rceil-1} \leq \lfloor\sqrt{x}\rfloor \leq 2^{\lceil b/2 \rceil}$. /// /// For example, since $10^9$ has 30 significant bits, we know that $2^{14} \leq /// \lfloor\sqrt{10^9}\rfloor \leq 2^{15}$. fn ceiling_sqrt(self) -> u128 { if self.significant_bits() < U128_SQRT_THRESHOLD { ceiling_sqrt_approx_and_refine(|x| x as f64, |x| x as u128, U128_MAX_SQUARE, self) } else { ceiling_sqrt_binary(self) } } } impl CheckedSqrt for u128 { type Output = u128; /// Returns the the square root of a [`u128`], or `None` if the [`u128`] is not a perfect /// square. /// /// $$ /// f(x) = \\begin{cases} /// \operatorname{Some}(sqrt{x}) & \text{if} \\quad \sqrt{x} \in \Z, \\\\ /// \operatorname{None} & \textrm{otherwise}. /// \\end{cases} /// $$ /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`. /// /// # Examples /// See [here](super::sqrt#checked_sqrt). /// /// # Notes /// For [`u128`], using a floating-point approximation and refining the result works, but the /// number of necessary adjustments becomes large for large [`u128`]s. To overcome this, large /// [`u128`]s switch to a binary search algorithm. To get decent starting bounds, the following /// fact is used: /// /// If $x$ is nonzero and has $b$ significant bits, then /// /// $2^{b-1} \leq x \leq 2^b-1$, /// /// $2^{b-1} \leq x \leq 2^b$, /// /// $2^{2\lfloor (b-1)/2 \rfloor} \leq x \leq 2^{2\lceil b/2 \rceil}$, /// /// $2^{2(\lceil b/2 \rceil-1)} \leq x \leq 2^{2\lceil b/2 \rceil}$, /// /// $\lfloor\sqrt{2^{2(\lceil b/2 \rceil-1)}}\rfloor \leq \lfloor\sqrt{x}\rfloor \leq /// \lfloor\sqrt{2^{2\lceil b/2 \rceil}}\rfloor$, since $x \mapsto \lfloor\sqrt{x}\rfloor$ is /// weakly increasing, /// /// $2^{\lceil b/2 \rceil-1} \leq \lfloor\sqrt{x}\rfloor \leq 2^{\lceil b/2 \rceil}$. /// /// For example, since $10^9$ has 30 significant bits, we know that $2^{14} \leq /// \lfloor\sqrt{10^9}\rfloor \leq 2^{15}$. fn checked_sqrt(self) -> Option { if self.significant_bits() < U128_SQRT_THRESHOLD { checked_sqrt_approx_and_refine(|x| x as f64, |x| x as u128, U128_MAX_SQUARE, self) } else { checked_sqrt_binary(self) } } } impl SqrtRem for u128 { type SqrtOutput = u128; type RemOutput = u128; /// Returns the floor of the square root of a [`u128`], and the remainder (the difference /// between the [`u128`] and the square of the floor). /// /// $f(x) = (\lfloor\sqrt{x}\rfloor, x - \lfloor\sqrt{x}\rfloor^2)$. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`. /// /// # Examples /// See [here](super::sqrt#sqrt_rem). /// /// # Notes /// For [`u128`], using a floating-point approximation and refining the result works, but the /// number of necessary adjustments becomes large for large [`u128`]s. To overcome this, large /// [`u128`]s switch to a binary search algorithm. To get decent starting bounds, the following /// fact is used: /// /// If $x$ is nonzero and has $b$ significant bits, then /// /// $2^{b-1} \leq x \leq 2^b-1$, /// /// $2^{b-1} \leq x \leq 2^b$, /// /// $2^{2\lfloor (b-1)/2 \rfloor} \leq x \leq 2^{2\lceil b/2 \rceil}$, /// /// $2^{2(\lceil b/2 \rceil-1)} \leq x \leq 2^{2\lceil b/2 \rceil}$, /// /// $\lfloor\sqrt{2^{2(\lceil b/2 \rceil-1)}}\rfloor \leq \lfloor\sqrt{x}\rfloor \leq /// \lfloor\sqrt{2^{2\lceil b/2 \rceil}}\rfloor$, since $x \mapsto \lfloor\sqrt{x}\rfloor$ is /// weakly increasing, /// /// $2^{\lceil b/2 \rceil-1} \leq \lfloor\sqrt{x}\rfloor \leq 2^{\lceil b/2 \rceil}$. /// /// For example, since $10^9$ has 30 significant bits, we know that $2^{14} \leq /// \lfloor\sqrt{10^9}\rfloor \leq 2^{15}$. fn sqrt_rem(self) -> (u128, u128) { if self.significant_bits() < U128_SQRT_THRESHOLD { sqrt_rem_approx_and_refine(|x| x as f64, |x| x as u128, U128_MAX_SQUARE, self) } else { sqrt_rem_binary(self) } } } macro_rules! impl_sqrt_signed { ($u: ident, $s: ident) => { impl FloorSqrt for $s { type Output = $s; /// Returns the floor of the square root of an integer. /// /// $f(x) = \lfloor\sqrt{x}\rfloor$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` is negative. /// /// # Examples /// See [here](super::sqrt#floor_sqrt). #[inline] fn floor_sqrt(self) -> Self { if self >= 0 { $s::wrapping_from(self.unsigned_abs().floor_sqrt()) } else { panic!("Cannot take square root of {}", self) } } } impl CeilingSqrt for $s { type Output = $s; /// Returns the ceiling of the square root of an integer. /// /// $f(x) = \lceil\sqrt{x}\rceil$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` is negative. /// /// # Examples /// See [here](super::sqrt#ceiling_sqrt). #[inline] fn ceiling_sqrt(self) -> $s { if self >= 0 { $s::wrapping_from(self.unsigned_abs().ceiling_sqrt()) } else { panic!("Cannot take square root of {}", self) } } } impl CheckedSqrt for $s { type Output = $s; /// Returns the the square root of an integer, or `None` if the integer is not a perfect /// square. /// /// $$ /// f(x) = \\begin{cases} /// \operatorname{Some}(sqrt{x}) & \text{if} \\quad \sqrt{x} \in \Z, \\\\ /// \operatorname{None} & \textrm{otherwise}. /// \\end{cases} /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` is negative. /// /// # Examples /// See [here](super::sqrt#checked_sqrt). #[inline] fn checked_sqrt(self) -> Option<$s> { if self >= 0 { self.unsigned_abs().checked_sqrt().map($s::wrapping_from) } else { panic!("Cannot take square root of {}", self) } } } }; } apply_to_unsigned_signed_pairs!(impl_sqrt_signed); macro_rules! impl_sqrt_assign_rem_unsigned { ($t: ident) => { impl SqrtAssignRem for $t { type RemOutput = $t; /// Replaces an integer with the floor of its square root, and returns the remainder /// (the difference between the original integer and the square of the floor). /// /// $f(x) = x - \lfloor\sqrt{x}\rfloor^2$, /// /// $x \gets \lfloor\sqrt{x}\rfloor$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::sqrt#sqrt_assign_rem). #[inline] fn sqrt_assign_rem(&mut self) -> $t { let rem; (*self, rem) = self.sqrt_rem(); rem } } }; } apply_to_unsigneds!(impl_sqrt_assign_rem_unsigned); macro_rules! impl_sqrt_assign { ($t: ident) => { impl FloorSqrtAssign for $t { /// Replaces an integer with the floor of its square root. /// /// $x \gets \lfloor\sqrt{x}\rfloor$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` is negative. /// /// # Examples /// See [here](super::sqrt#floor_sqrt_assign). #[inline] fn floor_sqrt_assign(&mut self) { *self = self.floor_sqrt(); } } impl CeilingSqrtAssign for $t { /// Replaces an integer with the ceiling of its square root. /// /// $x \gets \lceil\sqrt{x}\rceil$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` is negative. /// /// # Examples /// See [here](super::sqrt#ceiling_sqrt_assign). #[inline] fn ceiling_sqrt_assign(&mut self) { *self = self.ceiling_sqrt(); } } }; } apply_to_primitive_ints!(impl_sqrt_assign); macro_rules! impl_sqrt_primitive_float { ($f:ident) => { impl Sqrt for $f { type Output = Self; #[inline] fn sqrt(self) -> $f { libm::Libm::<$f>::sqrt(self) } } // TODO move to better location impl Ln for $f { type Output = Self; #[inline] fn ln(self) -> $f { libm::Libm::<$f>::log(self) } } impl SqrtAssign for $f { /// Replaces a number with its square root. /// /// $x \gets \sqrt x$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::sqrt#sqrt_assign). #[inline] fn sqrt_assign(&mut self) { *self = self.sqrt(); } } }; } apply_to_primitive_floats!(impl_sqrt_primitive_float); malachite-base-0.4.16/src/num/arithmetic/square.rs000064400000000000000000000027101046102023000201400ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{Square, SquareAssign}; macro_rules! impl_square { ($t:ident) => { impl Square for $t { type Output = $t; /// Squares a number. /// /// $f(x) = x^2$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::square#square). #[inline] fn square(self) -> $t { self * self } } impl SquareAssign for $t { /// Squares a number in place. /// /// $x \gets x^2$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::square#square_assign). #[inline] fn square_assign(&mut self) { *self *= *self; } } }; } apply_to_primitive_ints!(impl_square); apply_to_primitive_floats!(impl_square); malachite-base-0.4.16/src/num/arithmetic/sub_mul.rs000064400000000000000000000054271046102023000203160ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{SubMul, SubMulAssign, WrappingSubMul, WrappingSubMulAssign}; macro_rules! impl_sub_mul_primitive_int { ($t:ident) => { impl SubMul<$t> for $t { type Output = $t; /// Subtracts a number by the product of two other numbers. /// /// $f(x, y, z) = x - yz$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::sub_mul#sub_mul). #[inline] fn sub_mul(self, y: $t, z: $t) -> $t { self.wrapping_sub_mul(y, z) } } impl SubMulAssign<$t> for $t { /// Subtracts a number by the product of two other numbers in place. /// /// $x \gets x - yz$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::sub_mul#sub_mul_assign). #[inline] fn sub_mul_assign(&mut self, y: $t, z: $t) { self.wrapping_sub_mul_assign(y, z); } } }; } apply_to_primitive_ints!(impl_sub_mul_primitive_int); macro_rules! impl_sub_mul_primitive_float { ($t:ident) => { impl SubMul for $t { type Output = $t; /// Subtracts a number by the product of two other numbers. /// /// $f(x, y, z) = x - yz$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::sub_mul#sub_mul). #[inline] fn sub_mul(self, y: $t, z: $t) -> $t { self - y * z } } impl SubMulAssign<$t> for $t { /// Subtracts a number by the product of two other numbers in place. /// /// $x \gets x - yz$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::sub_mul#sub_mul_assign). #[inline] fn sub_mul_assign(&mut self, y: $t, z: $t) { *self -= y * z; } } }; } apply_to_primitive_floats!(impl_sub_mul_primitive_float); malachite-base-0.4.16/src/num/arithmetic/traits.rs000064400000000000000000001621031046102023000201510ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::basic::traits::Two; use crate::rounding_modes::RoundingMode; use core::cmp::Ordering; /// Takes the absolute value of a number. Assumes that the number has a representable absolute /// number. pub trait Abs { type Output; fn abs(self) -> Self::Output; } /// Replaces a number with its absolute value. Assumes that the number has a representable absolute /// number. pub trait AbsAssign { fn abs_assign(&mut self); } /// Takes the absolute value of a number and converts to the unsigned equivalent. pub trait UnsignedAbs { type Output; fn unsigned_abs(self) -> Self::Output; } /// Subtracts two numbers and takes the absolute value of the difference. pub trait AbsDiff { type Output; fn abs_diff(self, other: RHS) -> Self::Output; } /// Replaces a number with the absolute value of its difference with another number. pub trait AbsDiffAssign { fn abs_diff_assign(&mut self, other: RHS); } /// Adds a number and the product of two other numbers. pub trait AddMul { type Output; fn add_mul(self, y: Y, z: Z) -> Self::Output; } /// Adds a number and the product of two other numbers, in place. pub trait AddMulAssign { fn add_mul_assign(&mut self, y: Y, z: Z); } /// Left-shifts a number (multiplies it by a power of 2), returning `None` if the result is not /// representable. pub trait ArithmeticCheckedShl { type Output; fn arithmetic_checked_shl(self, other: RHS) -> Option; } /// Right-shifts a number (divides it by a power of 2), returning `None` if the result is not /// representable. pub trait ArithmeticCheckedShr { type Output; fn arithmetic_checked_shr(self, other: RHS) -> Option; } pub trait BinomialCoefficient { fn binomial_coefficient(n: T, k: T) -> Self; } pub trait CheckedBinomialCoefficient: Sized { fn checked_binomial_coefficient(n: T, k: T) -> Option; } /// Takes the ceiling of a number. pub trait Ceiling { type Output; fn ceiling(self) -> Self::Output; } /// Replaces a number with its ceiling. pub trait CeilingAssign { fn ceiling_assign(&mut self); } /// Takes the absolute valie of a number, returning `None` if the result is not representable. pub trait CheckedAbs { type Output; fn checked_abs(self) -> Option; } /// Adds two numbers, returning `None` if the result is not representable. pub trait CheckedAdd { type Output; fn checked_add(self, other: RHS) -> Option; } /// Adds a number and the product of two other numbers, returning `None` if the result is not /// representable. pub trait CheckedAddMul { type Output; fn checked_add_mul(self, y: Y, z: Z) -> Option; } /// Divides two numbers, returning `None` if the result is not representable. pub trait CheckedDiv { type Output; fn checked_div(self, other: RHS) -> Option; } /// Multiplies two numbers, returning `None` if the result is not representable. pub trait CheckedMul { type Output; fn checked_mul(self, other: RHS) -> Option; } /// Negates a number, returning `None` if the result is not representable. pub trait CheckedNeg { type Output; fn checked_neg(self) -> Option; } /// Finds the smallest integer power of 2 greater than or equal to a number, returning `None` if the /// result is not representable. pub trait CheckedNextPowerOf2 { type Output; fn checked_next_power_of_2(self) -> Option; } /// Raises a number to a power, returning `None` if the result is not representable. pub trait CheckedPow { type Output; fn checked_pow(self, exp: RHS) -> Option; } /// Squares a number, returning `None` if the result is not representable. pub trait CheckedSquare { type Output; fn checked_square(self) -> Option; } /// Subtracts two numbers, returning `None` if the result is not representable. pub trait CheckedSub { type Output; fn checked_sub(self, other: RHS) -> Option; } /// Subtracts a number by the product of two other numbers, returning `None` if the result is not /// representable. pub trait CheckedSubMul { type Output; fn checked_sub_mul(self, y: Y, z: Z) -> Option; } /// Determines whether two numbers are coprime. pub trait CoprimeWith { fn coprime_with(self, other: RHS) -> bool; } /// Divides two numbers, assuming the first exactly divides the second. /// /// If it doesn't, the `div_exact` function may panic or return a meaningless result. pub trait DivExact { type Output; fn div_exact(self, other: RHS) -> Self::Output; } /// Divides a number by another number in place, assuming the first exactly divides the second. /// /// If it doesn't, this function may panic or assign a meaningless number to the first number. pub trait DivExactAssign { fn div_exact_assign(&mut self, other: RHS); } /// Divides two numbers, returning the quotient and remainder. The quotient is rounded towards /// negative infinity, and the remainder has the same sign as the divisor (second input). /// /// The quotient and remainder satisfy $x = qy + r$ and $0 \leq |r| < |y|$. pub trait DivMod { type DivOutput; type ModOutput; fn div_mod(self, other: RHS) -> (Self::DivOutput, Self::ModOutput); } /// Divides a number by another number in place, returning the remainder. The quotient is rounded /// towards negative infinity, and the remainder has the same sign as the divisor (second input). /// /// The quotient and remainder satisfy $x = qy + r$ and $0 \leq |r| < |y|$. pub trait DivAssignMod { type ModOutput; fn div_assign_mod(&mut self, other: RHS) -> Self::ModOutput; } /// Divides two numbers, returning the quotient and remainder. The quotient is rounded towards zero, /// and the remainder has the same sign as the dividend (first input). /// /// The quotient and remainder satisfy $x = qy + r$ and $0 \leq |r| < |y|$. pub trait DivRem { type DivOutput; type RemOutput; fn div_rem(self, other: RHS) -> (Self::DivOutput, Self::RemOutput); } /// Divides a number by another number in place, returning the remainder. The quotient is rounded /// towards zero, and the remainder has the same sign as the dividend (first input). /// /// The quotient and remainder satisfy $x = qy + r$ and $0 \leq |r| < |y|$. pub trait DivAssignRem { type RemOutput; fn div_assign_rem(&mut self, other: RHS) -> Self::RemOutput; } /// Divides a number by another number, returning the ceiling of the quotient and the remainder of /// the negative of the first number divided by the second. /// /// The quotient and remainder satisfy $x = qy - r$ and $0 \leq r < y$. pub trait CeilingDivNegMod { type DivOutput; type ModOutput; fn ceiling_div_neg_mod(self, other: RHS) -> (Self::DivOutput, Self::ModOutput); } /// Divides a number by another number in place, taking the ceiling of the quotient and returning /// the remainder of the negative of the first number divided by the second. /// /// The quotient and remainder satisfy $x = qy - r$ and $0 \leq r < y$. pub trait CeilingDivAssignNegMod { type ModOutput; fn ceiling_div_assign_neg_mod(&mut self, other: RHS) -> Self::ModOutput; } /// Divides a number by another number, returning the quotient and remainder. The quotient is /// rounded towards positive infinity and the remainder has the opposite sign as the divisor (second /// input). /// /// The quotient and remainder satisfy $x = qy + r$ and $0 \leq |r| < |y|$. pub trait CeilingDivMod { type DivOutput; type ModOutput; fn ceiling_div_mod(self, other: RHS) -> (Self::DivOutput, Self::ModOutput); } /// Divides a number by another number in place, taking the quotient and returning the remainder. /// The quotient is rounded towards positive infinity and the remainder has the opposite sign of the /// divisor (second input). /// /// The quotient and remainder satisfy $x = qy + r$ and $0 \leq |r| < |y|$. pub trait CeilingDivAssignMod { type ModOutput; fn ceiling_div_assign_mod(&mut self, other: RHS) -> Self::ModOutput; } /// Divides a number by another number and rounds according to a specified rounding mode. An /// [`Ordering`] is also returned, indicating whether the returned value is less than, equal to, or /// greater than the exact value. pub trait DivRound { type Output; fn div_round(self, other: RHS, rm: RoundingMode) -> (Self::Output, Ordering); } /// Divides a number by another number in place and rounds according to a specified rounding mode. /// An [`Ordering`] is returned, indicating whether the assigned value is less than, equal to, or /// greater than the exact value. pub trait DivRoundAssign { fn div_round_assign(&mut self, other: RHS, rm: RoundingMode) -> Ordering; } /// Determines whether a number is divisible by $2^k$. pub trait DivisibleByPowerOf2 { fn divisible_by_power_of_2(self, pow: u64) -> bool; } /// Determines whether a number is divisible by another number. pub trait DivisibleBy { fn divisible_by(self, other: RHS) -> bool; } /// Determines whether a number is equivalent to another number modulo $2^k$. pub trait EqModPowerOf2 { fn eq_mod_power_of_2(self, other: RHS, pow: u64) -> bool; } /// Determines whether a number is equivalent to another number modulo $m$. pub trait EqMod { fn eq_mod(self, other: RHS, m: M) -> bool; } /// Computes the GCD (greatest common divisor) of two numbers $a$ and $b$, and also the coefficients /// $x$ and $y$ in Bézout's identity $ax+by=\gcd(a,b)$. /// /// The are infinitely many $x$, $y$ that satisfy the identity, so the full specification is more /// detailed: /// /// - $f(0, 0) = (0, 0, 0)$. /// - $f(a, ak) = (a, 1, 0)$ if $a > 0$ and $k \neq 1$. /// - $f(a, ak) = (-a, -1, 0)$ if $a < 0$ and $k \neq 1$. /// - $f(bk, b) = (b, 0, 1)$ if $b > 0$. /// - $f(bk, b) = (-b, 0, -1)$ if $b < 0$. /// - $f(a, b) = (g, x, y)$ if $a \neq 0$ and $b \neq 0$ and $\gcd(a, b) \neq \min(|a|, |b|)$, where /// $g = \gcd(a, b) \geq 0$, $ax + by = g$, $x \leq \lfloor b/g \rfloor$, and $y \leq \lfloor a/g /// \rfloor$. pub trait ExtendedGcd { type Gcd; type Cofactor; fn extended_gcd(self, other: RHS) -> (Self::Gcd, Self::Cofactor, Self::Cofactor); } /// Computes the factorial of a `u64`. pub trait Factorial { fn factorial(n: u64) -> Self; } /// Computes the factorial of a `u64`, returning `None` if the result is too large to be /// represented. pub trait CheckedFactorial: Sized { fn checked_factorial(n: u64) -> Option; } /// Computes the double factorial of a `u64`. The double factorial of a non-negative integer is the /// product of all the positive integers that are less than or equal to it and have the same parity /// as it. pub trait DoubleFactorial { fn double_factorial(n: u64) -> Self; } /// Computes the double factorial of a `u64`, returning `None` if the result is too large to be /// represented. The double factorial of a non-negative integer is the product of all the positive /// integers that are less than or equal to it and have the same parity as it. pub trait CheckedDoubleFactorial: Sized { fn checked_double_factorial(n: u64) -> Option; } /// Computes the $m$-multifactorial of a `u64`. The $m$-multifactorial of a non-negative integer $n$ /// is the product of all integers $k$ such that $0 Self; } /// Computes the $m$-multifactorial of a `u64`, returning `None` if the result is too large to be /// represented. The $m$-multifactorial of a non-negative integer $n$ is the product of all integers /// $k$ such that $0 Option; } /// Computes the subfactorial of a `u64`. The subfactorial of a non-negative integer $n$ counts the /// number of derangements of $n$ elements, which are the permutations in which no element is fixed. pub trait Subfactorial { fn subfactorial(n: u64) -> Self; } /// Computes the subfactorial of a `u64`, returning `None` if the result is too large to be /// represented. The subfactorial of a non-negative integer $n$ counts the number of derangements of /// $n$ elements, which are the permutations in which no element is fixed. pub trait CheckedSubfactorial: Sized { fn checked_subfactorial(n: u64) -> Option; } /// Takes the floor of a number. pub trait Floor { type Output; fn floor(self) -> Self::Output; } /// Replaces a number with its floor. pub trait FloorAssign { fn floor_assign(&mut self); } /// Calculates the GCD (greatest common divisor) of two numbers. pub trait Gcd { type Output; fn gcd(self, other: RHS) -> Self::Output; } /// Replaces a number with the GCD (greatest common divisor) of it and another number. pub trait GcdAssign { fn gcd_assign(&mut self, other: RHS); } /// Determines whether a number is an integer power of 2. pub trait IsPowerOf2 { fn is_power_of_2(&self) -> bool; } /// Calculates the LCM (least common multiple) of two numbers. pub trait Lcm { type Output; fn lcm(self, other: RHS) -> Self::Output; } /// Replaces a number with the LCM (least common multiple) of it and another number. pub trait LcmAssign { fn lcm_assign(&mut self, other: RHS); } /// Takes the natural logarithm of a number. pub trait Ln { type Output; fn ln(self) -> Self::Output; } /// Calculates the LCM (least common multiple) of two numbers, returning `None` if the result is not /// representable. pub trait CheckedLcm { type Output; fn checked_lcm(self, other: RHS) -> Option; } /// Calculates the Legendre symbol of two numbers. Typically the implementations will be identical /// to those of [`JacobiSymbol`]. pub trait LegendreSymbol { fn legendre_symbol(self, other: RHS) -> i8; } /// Calculates the Jacobi symbol of two numbers. pub trait JacobiSymbol { fn jacobi_symbol(self, other: RHS) -> i8; } /// Calculates the Kronecker symbol of two numbers. pub trait KroneckerSymbol { fn kronecker_symbol(self, other: RHS) -> i8; } /// Calculates the base-$b$ logarithm of a number, or returns `None` if the number is not a perfect /// power of $b$. pub trait CheckedLogBase { type Output; fn checked_log_base(self, base: B) -> Option; } /// Calculates the floor of the base-$b$ logarithm of a number. pub trait FloorLogBase { type Output; fn floor_log_base(self, base: B) -> Self::Output; } /// Calculates the ceiling of the base-$b$ logarithm of a number. pub trait CeilingLogBase { type Output; fn ceiling_log_base(self, base: B) -> Self::Output; } /// Calculates the base-2 logarithm of a number, or returns `None` if the number is not a perfect /// power of 2. pub trait CheckedLogBase2 { type Output; fn checked_log_base_2(self) -> Option; } /// Calculates the floor of the base-2 logarithm of a number. pub trait FloorLogBase2 { type Output; fn floor_log_base_2(self) -> Self::Output; } /// Calculates the ceiling of the base-2 logarithm of a number. pub trait CeilingLogBase2 { type Output; fn ceiling_log_base_2(self) -> Self::Output; } /// Calculates the base-$2^k$ logarithm of a number, or returns `None` if the number is not a /// perfect power of $2^k$. pub trait CheckedLogBasePowerOf2 { type Output; fn checked_log_base_power_of_2(self, pow: POW) -> Option; } /// Calculates the floor of the base-$2^k$ logarithm of a number. pub trait FloorLogBasePowerOf2 { type Output; fn floor_log_base_power_of_2(self, pow: POW) -> Self::Output; } /// Calculates the ceiling of the base-$2^k$ logarithm of a number. pub trait CeilingLogBasePowerOf2 { type Output; fn ceiling_log_base_power_of_2(self, pow: POW) -> Self::Output; } /// Adds two numbers modulo a third number $m$. The inputs must be already reduced modulo $m$. pub trait ModAdd { type Output; fn mod_add(self, other: RHS, m: M) -> Self::Output; } /// Adds two numbers modulo a third number $m$, in place. The inputs must be already reduced modulo /// $m$. pub trait ModAddAssign { fn mod_add_assign(&mut self, other: RHS, m: M); } /// Finds the multiplicative inverse of a number modulo another number $m$. The input must be /// already reduced modulo $m$. pub trait ModInverse { type Output; fn mod_inverse(self, m: M) -> Option; } /// Checks whether a number is reduced modulo another number $m$. pub trait ModIsReduced { fn mod_is_reduced(&self, m: &M) -> bool; } /// Multiplies two numbers modulo a third number $m$. The inputs must be already reduced modulo $m$. pub trait ModMul { type Output; fn mod_mul(self, other: RHS, m: M) -> Self::Output; } /// Multiplies two numbers modulo a third number $m$, in place. The inputs must be already reduced /// modulo $m$. pub trait ModMulAssign { fn mod_mul_assign(&mut self, other: RHS, m: M); } /// Multiplies two numbers modulo a third number $m$. The inputs must be already reduced modulo $m$. /// /// If multiple modular multiplications with the same modulus are necessary, it can be quicker to /// precompute some piece of data and reuse it in the multiplication calls. This trait provides a /// function for precomputing the data and a function for using it during multiplication. pub trait ModMulPrecomputed { type Output; type Data; /// Precomputes some data to use for modular multiplication. fn precompute_mod_mul_data(m: &M) -> Self::Data; fn mod_mul_precomputed(self, other: RHS, m: M, data: &Self::Data) -> Self::Output; } /// Multiplies two numbers modulo a third number $m$, in place.The inputs must be already reduced /// modulo $m$. /// /// If multiple modular multiplications with the same modulus are necessary, it can be quicker to /// precompute some piece of data and reuse it in the multiplication calls. This trait provides a /// function for using precomputed data during multiplication. For precomputing the data, use the /// [`precompute_mod_mul_data`](ModMulPrecomputed::precompute_mod_mul_data) function in /// [`ModMulPrecomputed`]. pub trait ModMulPrecomputedAssign: ModMulPrecomputed { fn mod_mul_precomputed_assign(&mut self, other: RHS, m: M, data: &Self::Data); } /// Negates a number modulo another number $m$. The input must be already reduced modulo $m$. pub trait ModNeg { type Output; fn mod_neg(self, m: M) -> Self::Output; } /// Negates a number modulo another number $m$, in place. The input must be already reduced modulo /// $m$. pub trait ModNegAssign { fn mod_neg_assign(&mut self, m: M); } /// Divides a number by another number, returning just the remainder. The remainder has the same /// sign as the divisor (second number). /// /// If the quotient were computed, the quotient and remainder would satisfy $x = qy + r$ and $0 \leq /// |r| < |y|$. pub trait Mod { type Output; fn mod_op(self, other: RHS) -> Self::Output; } /// Divides a number by another number, replacing the first number by the remainder. The remainder /// has the same sign as the divisor (second number). /// /// If the quotient were computed, the quotient and remainder would satisfy $x = qy + r$ and $0 \leq /// |r| < |y|$. pub trait ModAssign { fn mod_assign(&mut self, other: RHS); } /// Divides the negative of a number by another number, returning the remainder. /// /// If the quotient were computed, the quotient and remainder would satisfy $x = qy - r$ and $0 \leq /// r < y$. pub trait NegMod { type Output; fn neg_mod(self, other: RHS) -> Self::Output; } /// Divides the negative of a number by another number, replacing the first number by the remainder. /// /// If the quotient were computed, the quotient and remainder would satisfy $x = qy - r$ and $0 \leq /// r < y$. pub trait NegModAssign { fn neg_mod_assign(&mut self, other: RHS); } /// Divides a number by another number, returning just the remainder. The remainder has the opposite /// sign as the divisor (second number). /// /// If the quotient were computed, the quotient and remainder would satisfy $x = qy + r$ and $0 \leq /// |r| < |y|$. pub trait CeilingMod { type Output; fn ceiling_mod(self, other: RHS) -> Self::Output; } /// Divides a number by another number, replacing the first number by the remainder. The remainder /// has the same sign as the divisor (second number). /// /// If the quotient were computed, the quotient and remainder would satisfy $x = qy + r$ and $0 \leq /// |r| < |y|$. pub trait CeilingModAssign { fn ceiling_mod_assign(&mut self, other: RHS); } /// Raises a number to a power modulo another number $m$. The base must be already reduced modulo /// $m$. pub trait ModPow { type Output; fn mod_pow(self, exp: RHS, m: M) -> Self::Output; } /// Raises a number to a power modulo another number $m$, in place. The base must be already reduced /// modulo $m$. pub trait ModPowAssign { fn mod_pow_assign(&mut self, exp: RHS, m: M); } /// Raises a number to a power modulo another number $m$. The base must be already reduced modulo /// $m$. /// /// If multiple modular exponentiations with the same modulus are necessary, it can be quicker to /// precompute some piece of data and reuse it in the exponentiation calls. This trait provides a /// function for precomputing the data and a function for using it during exponentiation. pub trait ModPowPrecomputed where Self: Sized, { type Output; type Data; /// Precomputes some data to use for modular exponentiation. fn precompute_mod_pow_data(m: &M) -> Self::Data; fn mod_pow_precomputed(self, exp: RHS, m: M, data: &Self::Data) -> Self::Output; } /// Raises a number to a power modulo another number $m$, in place. The base must be already reduced /// modulo $m$. /// /// If multiple modular exponentiations with the same modulus are necessary, it can be quicker to /// precompute some piece of data and reuse it in the exponentiation calls. This trait provides a /// function for using precomputed data during exponentiation. For precomputing the data, use the /// [`precompute_mod_pow_data`](ModPowPrecomputed::precompute_mod_pow_data) function in /// [`ModPowPrecomputed`]. pub trait ModPowPrecomputedAssign: ModPowPrecomputed { fn mod_pow_precomputed_assign(&mut self, exp: RHS, m: M, data: &Self::Data); } /// Adds two numbers modulo $2^k$. The inputs must be already reduced modulo $2^k$. pub trait ModPowerOf2Add { type Output; fn mod_power_of_2_add(self, other: RHS, pow: u64) -> Self::Output; } /// Adds two numbers modulo $2^k$, in place. The inputs must be already reduced modulo $2^k$. pub trait ModPowerOf2AddAssign { fn mod_power_of_2_add_assign(&mut self, other: RHS, pow: u64); } /// Finds the multiplicative inverse of a number modulo $2^k$. The input must be already reduced /// modulo $2^k$. pub trait ModPowerOf2Inverse { type Output; fn mod_power_of_2_inverse(self, pow: u64) -> Option; } /// Checks whether a number is reduced modulo $2^k$. pub trait ModPowerOf2IsReduced { fn mod_power_of_2_is_reduced(&self, pow: u64) -> bool; } /// Multiplies two numbers modulo $2^k$. The inputs must be already reduced modulo $2^k$. pub trait ModPowerOf2Mul { type Output; fn mod_power_of_2_mul(self, other: RHS, pow: u64) -> Self::Output; } /// Multiplies two numbers modulo $2^k$, in place. The inputs must be already reduced modulo $2^k$. pub trait ModPowerOf2MulAssign { fn mod_power_of_2_mul_assign(&mut self, other: RHS, pow: u64); } /// Negates a number modulo $2^k$. The input must be already reduced modulo $2^k$. pub trait ModPowerOf2Neg { type Output; fn mod_power_of_2_neg(self, pow: u64) -> Self::Output; } /// Negates a number modulo $2^k$ in place. The input must be already reduced modulo $2^k$. pub trait ModPowerOf2NegAssign { fn mod_power_of_2_neg_assign(&mut self, pow: u64); } /// Raises a number to a power modulo $2^k$. The base must be already reduced modulo $2^k$. pub trait ModPowerOf2Pow { type Output; fn mod_power_of_2_pow(self, exp: RHS, pow: u64) -> Self::Output; } /// Raises a number to a power modulo $2^k$, in place. The base must be already reduced modulo /// $2^k$. pub trait ModPowerOf2PowAssign { fn mod_power_of_2_pow_assign(&mut self, exp: RHS, pow: u64); } /// Left-shifts a number (multiplies it by a power of 2) modulo $2^k$. The number must be already /// reduced modulo $2^k$. pub trait ModPowerOf2Shl { type Output; fn mod_power_of_2_shl(self, other: RHS, pow: u64) -> Self::Output; } /// Left-shifts a number (multiplies it by a power of 2) modulo $2^k$, in place. The number must be /// already reduced modulo $2^k$. pub trait ModPowerOf2ShlAssign { fn mod_power_of_2_shl_assign(&mut self, other: RHS, pow: u64); } /// Right-shifts a number (divides it by a power of 2) modulo $2^k$. The number must be already /// reduced modulo $2^k$. pub trait ModPowerOf2Shr { type Output; fn mod_power_of_2_shr(self, other: RHS, pow: u64) -> Self::Output; } /// Right-shifts a number (divides it by a power of 2) modulo $2^k$, in place. The number must be /// already reduced modulo $2^k$. pub trait ModPowerOf2ShrAssign { fn mod_power_of_2_shr_assign(&mut self, other: RHS, pow: u64); } /// Squares a number modulo $2^k$. The input must be already reduced modulo $2^k$. pub trait ModPowerOf2Square { type Output; fn mod_power_of_2_square(self, pow: u64) -> Self::Output; } /// Squares a number modulo $2^k$ in place. The input must be already reduced modulo $2^k$. pub trait ModPowerOf2SquareAssign { fn mod_power_of_2_square_assign(&mut self, pow: u64); } /// Subtracts two numbers modulo $2^k$. The inputs must be already reduced modulo $2^k$. pub trait ModPowerOf2Sub { type Output; fn mod_power_of_2_sub(self, other: RHS, pow: u64) -> Self::Output; } /// Subtracts two numbers modulo $2^k$, in place. The inputs must be already reduced modulo $2^k$. pub trait ModPowerOf2SubAssign { fn mod_power_of_2_sub_assign(&mut self, other: RHS, pow: u64); } /// Divides a number by $2^k$, returning just the remainder. The remainder is non-negative. /// /// If the quotient were computed, the quotient and remainder would satisfy $x = q2^k + r$ and $0 /// \leq r < 2^k$. pub trait ModPowerOf2 { type Output; fn mod_power_of_2(self, other: u64) -> Self::Output; } /// Divides a number by $2^k$, replacing the number by the remainder. The remainder is non-negative. /// /// If the quotient were computed, the quotient and remainder would satisfy $x = q2^k + r$ and $0 /// \leq r < 2^k$. pub trait ModPowerOf2Assign { fn mod_power_of_2_assign(&mut self, other: u64); } /// Divides a number by $2^k$, returning just the remainder. The remainder has the same sign as the /// number. /// /// If the quotient were computed, the quotient and remainder would satisfy $x = q2^k + r$ and $0 /// \leq |r| < 2^k$. pub trait RemPowerOf2 { type Output; fn rem_power_of_2(self, other: u64) -> Self::Output; } /// Divides a number by $2^k$, replacing the number by the remainder. The remainder has the same /// sign as the number. /// /// If the quotient were computed, the quotient and remainder would satisfy $x = q2^k + r$ and $0 /// \leq |r| < 2^k$. pub trait RemPowerOf2Assign { fn rem_power_of_2_assign(&mut self, other: u64); } /// Divides the negative of a number by $2^k$, returning the remainder. /// /// If the quotient were computed, the quotient and remainder would satisfy $x = q2^k - r$ and $0 /// \leq r < 2^k$. pub trait NegModPowerOf2 { type Output; fn neg_mod_power_of_2(self, other: u64) -> Self::Output; } /// Divides the negative of a number by $2^k$, replacing the number by the remainder. /// /// If the quotient were computed, the quotient and remainder would satisfy $x = q2^k - r$ and $0 /// \leq r < 2^k$. pub trait NegModPowerOf2Assign { fn neg_mod_power_of_2_assign(&mut self, other: u64); } /// Divides a number by $2^k$, returning just the remainder. The remainder is non-positive. /// /// If the quotient were computed, the quotient and remainder would satisfy $x = q2^k + r$ and $0 /// \leq -r < 2^k$. pub trait CeilingModPowerOf2 { type Output; fn ceiling_mod_power_of_2(self, other: u64) -> Self::Output; } /// Divides a number by $2^k$, replacing the number by the remainder. The remainder is non-positive. /// /// If the quotient were computed, the quotient and remainder would satisfy $x = q2^k + r$ and $0 /// \leq -r < 2^k$. pub trait CeilingModPowerOf2Assign { fn ceiling_mod_power_of_2_assign(&mut self, other: u64); } /// Left-shifts a number (multiplies it by a power of 2) modulo another number $m$. The number must /// be already reduced modulo $m$. pub trait ModShl { type Output; fn mod_shl(self, other: RHS, m: M) -> Self::Output; } /// Left-shifts a number (multiplies it by a power of 2) modulo another number $m$, in place. The /// number must be already reduced modulo $m$. pub trait ModShlAssign { fn mod_shl_assign(&mut self, other: RHS, m: M); } /// Left-shifts a number (divides it by a power of 2) modulo another number $m$. The number must be /// already reduced modulo $m$. pub trait ModShr { type Output; fn mod_shr(self, other: RHS, m: M) -> Self::Output; } /// Left-shifts a number (divides it by a power of 2) modulo another number $m$, in place. The /// number must be already reduced modulo $m$. pub trait ModShrAssign { fn mod_shr_assign(&mut self, other: RHS, m: M); } /// Squares a number modulo another number $m$. The input must be already reduced modulo $m$. pub trait ModSquare { type Output; fn mod_square(self, m: M) -> Self::Output; } /// Squares a number modulo another number $m$, in place. The input must be already reduced modulo /// $m$. pub trait ModSquareAssign { fn mod_square_assign(&mut self, m: M); } /// Squares a number modulo another number $m$. The input must be already reduced modulo $m$. /// /// If multiple modular squarings with the same modulus are necessary, it can be quicker to /// precompute some piece of data using /// [`precompute_mod_pow_data`](ModPowPrecomputed::precompute_mod_pow_data) function in /// [`ModMulPrecomputed`] and reuse it in the squaring calls. pub trait ModSquarePrecomputed: ModPowPrecomputed where Self: Sized, { fn mod_square_precomputed(self, m: M, data: &Self::Data) -> Self::Output; } /// Squares a number modulo another number $m$, in place. The input must be already reduced modulo /// $m$. /// /// If multiple modular squarings with the same modulus are necessary, it can be quicker to /// precompute some piece of data using /// [`precompute_mod_pow_data`](ModPowPrecomputed::precompute_mod_pow_data) function in /// [`ModMulPrecomputed`] and reuse it in the squaring calls. pub trait ModSquarePrecomputedAssign: ModPowPrecomputed { fn mod_square_precomputed_assign(&mut self, m: M, data: &Self::Data); } /// Adds two numbers modulo a third number $m$. The inputs must be already reduced modulo $m$. pub trait ModSub { type Output; fn mod_sub(self, other: RHS, m: M) -> Self::Output; } /// Adds two numbers modulo a third number $m$, in place. The inputs must be already reduced modulo /// $m$. pub trait ModSubAssign { fn mod_sub_assign(&mut self, other: RHS, m: M); } /// Replaces a number with its negative. Assumes the result is representable. pub trait NegAssign { fn neg_assign(&mut self); } /// Returns the smallest power of 2 greater than or equal to a number. Assumes the result is /// representable. pub trait NextPowerOf2 { type Output; fn next_power_of_2(self) -> Self::Output; } /// Replaces a number with the smallest power of 2 greater than or equal it. Assumes the result is /// representable. pub trait NextPowerOf2Assign { fn next_power_of_2_assign(&mut self); } /// Takes the absolute value of a number. /// /// Returns a tuple of the result along with a boolean indicating whether an arithmetic overflow /// occured. If an overflow occurred, then the wrapped number is returned. pub trait OverflowingAbs { type Output; fn overflowing_abs(self) -> (Self::Output, bool); } /// Replaces a number with its absolute value. /// /// Returns a boolean indicating whether an arithmetic overflow occurred. If an overflow occurred, /// then the wrapped number is assigned. pub trait OverflowingAbsAssign { fn overflowing_abs_assign(&mut self) -> bool; } /// Adds two numbers. /// /// Returns a tuple of the sum along with a boolean indicating whether an arithmetic overflow /// occurred. If an overflow occurred, then the wrapped number is returned. pub trait OverflowingAdd { type Output; fn overflowing_add(self, other: RHS) -> (Self::Output, bool); } /// Adds a number to another number in place. /// /// Returns a boolean indicating whether an arithmetic overflow occurred. If an overflow occurred, /// then the wrapped number is assigned. pub trait OverflowingAddAssign { fn overflowing_add_assign(&mut self, other: RHS) -> bool; } /// Adds a number and the product of two other numbers. /// /// Returns a tuple of the result along with a boolean indicating whether an arithmetic overflow /// occurred. If an overflow occurred, then the wrapped number is returned. pub trait OverflowingAddMul { type Output; fn overflowing_add_mul(self, y: Y, z: Z) -> (Self::Output, bool); } /// Adds a number and the product of two other numbers, in place. /// /// Returns a tuple of the result along with a boolean indicating whether an arithmetic overflow /// occurred. If an overflow occurred, then the wrapped number is returned. pub trait OverflowingAddMulAssign { fn overflowing_add_mul_assign(&mut self, y: Y, z: Z) -> bool; } /// Divides two numbers. /// /// Returns a tuple of the sum along with a boolean indicating whether an arithmetic overflow /// occurred. If an overflow occurred, then the wrapped number is returned. pub trait OverflowingDiv { type Output; fn overflowing_div(self, other: RHS) -> (Self::Output, bool); } /// Divides a number by another number in place. /// /// Returns a boolean indicating whether an arithmetic overflow occurred. If an overflow occurred, /// then the wrapped number is assigned. pub trait OverflowingDivAssign { fn overflowing_div_assign(&mut self, other: RHS) -> bool; } /// Multiplies two numbers. /// /// Returns a tuple of the sum along with a boolean indicating whether an arithmetic overflow /// occurred. If an overflow occurred, then the wrapped number is returned. pub trait OverflowingMul { type Output; fn overflowing_mul(self, other: RHS) -> (Self::Output, bool); } /// Multiplies a number by another number in place. /// /// Returns a boolean indicating whether an arithmetic overflow occurred. If an overflow occurred, /// then the wrapped number is assigned. pub trait OverflowingMulAssign { fn overflowing_mul_assign(&mut self, other: RHS) -> bool; } /// Negates a number. /// /// Returns a tuple of the sum along with a boolean indicating whether an arithmetic overflow /// occurred. If an overflow occurred, then the wrapped number is returned. pub trait OverflowingNeg { type Output; fn overflowing_neg(self) -> (Self::Output, bool); } /// Negates a number in place. /// /// Returns a boolean indicating whether an arithmetic overflow occurred. If an overflow occurred, /// then the wrapped number is assigned. pub trait OverflowingNegAssign { fn overflowing_neg_assign(&mut self) -> bool; } /// Raises a number to a power. /// /// Returns a tuple of the sum along with a boolean indicating whether an arithmetic overflow /// occurred. If an overflow occurred, then the wrapped number is returned. pub trait OverflowingPow { type Output; fn overflowing_pow(self, exp: RHS) -> (Self::Output, bool); } /// Raises a number to a power in place. /// /// Returns a boolean indicating whether an arithmetic overflow occurred. If an overflow occurred, /// then the wrapped number is assigned. pub trait OverflowingPowAssign { fn overflowing_pow_assign(&mut self, exp: RHS) -> bool; } /// Squares a number. /// /// Returns a tuple of the sum along with a boolean indicating whether an arithmetic overflow /// occurred. If an overflow occurred, then the wrapped number is returned. pub trait OverflowingSquare { type Output; fn overflowing_square(self) -> (Self::Output, bool); } /// Squares a number in place. /// /// Returns a boolean indicating whether an arithmetic overflow occurred. If an overflow occurred, /// then the wrapped number is assigned. pub trait OverflowingSquareAssign { fn overflowing_square_assign(&mut self) -> bool; } /// Subtracts two numbers. /// /// Returns a tuple of the sum along with a boolean indicating whether an arithmetic overflow /// occurred. If an overflow occurred, then the wrapped number is returned. pub trait OverflowingSub { type Output; fn overflowing_sub(self, other: RHS) -> (Self::Output, bool); } /// Subtracts a number by another number in place. /// /// Returns a boolean indicating whether an arithmetic overflow occurred. If an overflow occurred, /// then the wrapped number is assigned. pub trait OverflowingSubAssign { fn overflowing_sub_assign(&mut self, other: RHS) -> bool; } /// Subtracts a number by the product of two other numbers. /// /// Returns a tuple of the result along with a boolean indicating whether an arithmetic overflow /// occurred. If an overflow occurred, then the wrapped number is returned. pub trait OverflowingSubMul { type Output; fn overflowing_sub_mul(self, y: Y, z: Z) -> (Self::Output, bool); } /// Subtracts a number by the product of two other numbers, in place. /// /// Returns a tuple of the result along with a boolean indicating whether an arithmetic overflow /// occurred. If an overflow occurred, then the wrapped number is returned. pub trait OverflowingSubMulAssign { fn overflowing_sub_mul_assign(&mut self, y: Y, z: Z) -> bool; } /// Determines whether a number is even or odd. pub trait Parity { /// Determines whether a number is even. fn even(self) -> bool; /// Determines whether a number is odd. fn odd(self) -> bool; } /// Raises a number to a power. Assumes the result is representable. pub trait Pow { type Output; fn pow(self, exp: RHS) -> Self::Output; } /// Raises a number to a power in place. Assumes the result is representable. pub trait PowAssign { fn pow_assign(&mut self, exp: RHS); } /// Raises 2 to a power. pub trait PowerOf2 { fn power_of_2(pow: POW) -> Self; } pub trait Primorial { fn primorial(n: u64) -> Self; fn product_of_first_n_primes(n: u64) -> Self; } pub trait CheckedPrimorial: Sized { fn checked_primorial(n: u64) -> Option; fn checked_product_of_first_n_primes(n: u64) -> Option; } /// Finds the reciprocal (multiplicative inverse) of a number. pub trait Reciprocal { type Output; fn reciprocal(self) -> Self::Output; } /// Replaces a number with its reciprocal (multiplicative inverse). pub trait ReciprocalAssign { fn reciprocal_assign(&mut self); } /// Finds the floor of the $n$th root of a number. pub trait FloorRoot { type Output; fn floor_root(self, pow: POW) -> Self::Output; } /// Replaces a number with the floor of its $n$th root. pub trait FloorRootAssign { fn floor_root_assign(&mut self, pow: POW); } /// Finds the ceiling of the $n$th root of a number. pub trait CeilingRoot { type Output; fn ceiling_root(self, pow: POW) -> Self::Output; } /// Replaces a number with the ceiling of its $n$th root. pub trait CeilingRootAssign { fn ceiling_root_assign(&mut self, pow: POW); } /// Finds the $n$th root of a number, returning `None` if it is not a perfect $n$th power. pub trait CheckedRoot { type Output; fn checked_root(self, pow: POW) -> Option; } /// Finds the floor of the $n$th root of a number, returning both the root and the remainder. pub trait RootRem { type RootOutput; type RemOutput; fn root_rem(self, exp: POW) -> (Self::RootOutput, Self::RemOutput); } /// Replaces a number with the floor of its $n$th root, returning the remainder. pub trait RootAssignRem { type RemOutput; fn root_assign_rem(&mut self, exp: POW) -> Self::RemOutput; } /// Rotates a number left, inserting the leftmost bits into the right end. pub trait RotateLeft { type Output; fn rotate_left(self, n: u64) -> Self::Output; } /// Rotates a number left, inserting the leftmost bits into the right end, in place. pub trait RotateLeftAssign { fn rotate_left_assign(&mut self, n: u64); } /// Rotates a number right, inserting the leftmost bits into the left end. pub trait RotateRight { type Output; fn rotate_right(self, n: u64) -> Self::Output; } /// Rotates a number right, inserting the leftmost bits into the left end, in place. pub trait RotateRightAssign { fn rotate_right_assign(&mut self, n: u64); } /// Rounds a number to a multiple of another number, according to a specified rounding mode. An /// [`Ordering`] is also returned, indicating whether the returned value is less than, equal to, or /// greater than the original value. pub trait RoundToMultiple { type Output; fn round_to_multiple(self, other: RHS, rm: RoundingMode) -> (Self::Output, Ordering); } /// Rounds a number to a multiple of another number in place, according to a specified rounding /// mode. [`Ordering`] is returned, indicating whether the returned value is less than, equal to, or /// greater than the original value. pub trait RoundToMultipleAssign { fn round_to_multiple_assign(&mut self, other: RHS, rm: RoundingMode) -> Ordering; } /// Rounds a number to a multiple of $2^k$, according to a specified rounding mode. An [`Ordering`] /// is also returned, indicating whether the returned value is less than, equal to, or greater than /// the original value. pub trait RoundToMultipleOfPowerOf2 { type Output; fn round_to_multiple_of_power_of_2( self, pow: RHS, rm: RoundingMode, ) -> (Self::Output, Ordering); } /// Rounds a number to a multiple of $2^k$ in place, according to a specified rounding mode. An /// [`Ordering`] is returned, indicating whether the returned value is less than, equal to, or /// greater than the original value. pub trait RoundToMultipleOfPowerOf2Assign { fn round_to_multiple_of_power_of_2_assign(&mut self, pow: RHS, rm: RoundingMode) -> Ordering; } /// Takes the absolute value of a number, saturating at the numeric bounds instead of overflowing. pub trait SaturatingAbs { type Output; fn saturating_abs(self) -> Self::Output; } /// Replaces a number with its absolute value, saturating at the numeric bounds instead of /// overflowing. pub trait SaturatingAbsAssign { fn saturating_abs_assign(&mut self); } /// Adds two numbers, saturating at the numeric bounds instead of overflowing. pub trait SaturatingAdd { type Output; fn saturating_add(self, other: RHS) -> Self::Output; } /// Add a number to another number in place, saturating at the numeric bounds instead of /// overflowing. pub trait SaturatingAddAssign { fn saturating_add_assign(&mut self, other: RHS); } /// Adds a number and the product of two other numbers, saturating at the numeric bounds instead of /// overflowing. pub trait SaturatingAddMul { type Output; fn saturating_add_mul(self, y: Y, z: Z) -> Self::Output; } /// Adds a number and the product of two other numbers in place, saturating at the numeric bounds /// instead of overflowing. pub trait SaturatingAddMulAssign { fn saturating_add_mul_assign(&mut self, y: Y, z: Z); } /// Multiplies two numbers, saturating at the numeric bounds instead of overflowing. pub trait SaturatingMul { type Output; fn saturating_mul(self, other: RHS) -> Self::Output; } /// Multiplies a number by another number in place, saturating at the numeric bounds instead of /// overflowing. pub trait SaturatingMulAssign { fn saturating_mul_assign(&mut self, other: RHS); } /// Negates a number, saturating at the numeric bounds instead of overflowing. pub trait SaturatingNeg { type Output; fn saturating_neg(self) -> Self::Output; } /// Negates a number in place, saturating at the numeric bounds instead of overflowing. pub trait SaturatingNegAssign { fn saturating_neg_assign(&mut self); } /// Raises a number to a power, saturating at the numeric bounds instead of overflowing. pub trait SaturatingPow { type Output; fn saturating_pow(self, exp: RHS) -> Self::Output; } /// Raises a number to a power in place, saturating at the numeric bounds instead of overflowing. pub trait SaturatingPowAssign { fn saturating_pow_assign(&mut self, exp: RHS); } /// Squares a number, saturating at the numeric bounds instead of overflowing. pub trait SaturatingSquare { type Output; fn saturating_square(self) -> Self::Output; } /// Squares a number in place, saturating at the numeric bounds instead of overflowing. pub trait SaturatingSquareAssign { fn saturating_square_assign(&mut self); } /// Subtracts two numbers, saturating at the numeric bounds instead of overflowing. pub trait SaturatingSub { type Output; fn saturating_sub(self, other: RHS) -> Self::Output; } /// Subtracts a number by another number in place, saturating at the numeric bounds instead of /// overflowing. pub trait SaturatingSubAssign { fn saturating_sub_assign(&mut self, other: RHS); } /// Subtracts a number by the product of two other numbers, saturating at the numeric bounds instead /// of overflowing. pub trait SaturatingSubMul { type Output; fn saturating_sub_mul(self, y: Y, z: Z) -> Self::Output; } /// Subtracts a number by the product of two other numbers in place, saturating at the numeric /// bounds instead of overflowing. pub trait SaturatingSubMulAssign { fn saturating_sub_mul_assign(&mut self, y: Y, z: Z); } /// Left-shifts a number (multiplies it by a power of 2), rounding the result according to a /// specified rounding mode. An [`Ordering`] is also returned, indicating whether the returned value /// is less than, equal to, or greater than the exact value. /// /// Rounding might only be necessary if `other` is negative. pub trait ShlRound { type Output; fn shl_round(self, other: RHS, rm: RoundingMode) -> (Self::Output, Ordering); } /// Left-shifts a number (multiplies it by a power of 2) in place, rounding the result according to /// a specified rounding mode. An [`Ordering`] is also returned, indicating whether the assigned /// value is less than, equal to, or greater than the exact value. /// /// Rounding might only be necessary if `other` is negative. pub trait ShlRoundAssign { fn shl_round_assign(&mut self, other: RHS, rm: RoundingMode) -> Ordering; } /// Right-shifts a number (divides it by a power of 2), rounding the result according to a specified /// rounding mode. An [`Ordering`] is also returned, indicating whether the returned value is less /// than, equal to, or greater than the exact value. /// /// Rounding might only be necessary if `other` is positive. pub trait ShrRound { type Output; fn shr_round(self, other: RHS, rm: RoundingMode) -> (Self::Output, Ordering); } /// Right-shifts a number (divides it by a power of 2) in place, rounding the result according to a /// specified rounding mode. An [`Ordering`] is also returned, indicating whether the assigned value /// is less than, equal to, or greater than the exact value. /// /// Rounding might only be necessary if `other` is positive. pub trait ShrRoundAssign { fn shr_round_assign(&mut self, other: RHS, rm: RoundingMode) -> Ordering; } /// Returns `Greater`, `Equal`, or `Less`, depending on whether a number is positive, zero, or /// negative, respectively. pub trait Sign { fn sign(&self) -> Ordering; } /// Takes the square root of a number. pub trait Sqrt { type Output; fn sqrt(self) -> Self::Output; } /// Replaces a number with its square root. pub trait SqrtAssign { fn sqrt_assign(&mut self); } /// Finds the floor of the square root of a number. pub trait FloorSqrt { type Output; fn floor_sqrt(self) -> Self::Output; } /// Replaces a number with the floor of its square root. pub trait FloorSqrtAssign { fn floor_sqrt_assign(&mut self); } /// Finds the ceiling of the square root of a number. pub trait CeilingSqrt { type Output; fn ceiling_sqrt(self) -> Self::Output; } /// Replaces a number with the ceiling of its square root. pub trait CeilingSqrtAssign { fn ceiling_sqrt_assign(&mut self); } /// Finds the square root of a number, returning `None` if it is not a perfect square. pub trait CheckedSqrt { type Output; fn checked_sqrt(self) -> Option; } /// Finds the floor of the square root of a number, returning both the root and the remainder. pub trait SqrtRem { type SqrtOutput; type RemOutput; fn sqrt_rem(self) -> (Self::SqrtOutput, Self::RemOutput); } /// Replaces a number with the floor of its square root, returning the remainder. pub trait SqrtAssignRem { type RemOutput; fn sqrt_assign_rem(&mut self) -> Self::RemOutput; } /// Squares a number. pub trait Square { type Output; fn square(self) -> Self::Output; } /// Replaces a number with its square. pub trait SquareAssign { fn square_assign(&mut self); } /// Subtracts a number by the product of two other numbers. pub trait SubMul { type Output; fn sub_mul(self, y: Y, z: Z) -> Self::Output; } /// Subtracts a number by the product of two other numbers, in place. pub trait SubMulAssign { fn sub_mul_assign(&mut self, y: Y, z: Z); } /// Takes the absolute value of a number, wrapping around at the boundary of the type. pub trait WrappingAbs { type Output; fn wrapping_abs(self) -> Self::Output; } /// Replaces a number with its absolute value, wrapping around at the boundary of the type. pub trait WrappingAbsAssign { fn wrapping_abs_assign(&mut self); } /// Adds two numbers, wrapping around at the boundary of the type. pub trait WrappingAdd { type Output; fn wrapping_add(self, other: RHS) -> Self::Output; } /// Adds a number to another number in place, wrapping around at the boundary of the type. pub trait WrappingAddAssign { fn wrapping_add_assign(&mut self, other: RHS); } /// Adds a number and the product of two other numbers, wrapping around at the boundary of the type. pub trait WrappingAddMul { type Output; fn wrapping_add_mul(self, y: Y, z: Z) -> Self::Output; } /// Adds a number and the product of two other numbers, in place, wrapping around at the boundary of /// the type. pub trait WrappingAddMulAssign { fn wrapping_add_mul_assign(&mut self, y: Y, z: Z); } /// Divides a number by another number, wrapping around at the boundary of the type. pub trait WrappingDiv { type Output; fn wrapping_div(self, other: RHS) -> Self::Output; } /// Divides a number by another number in place, wrapping around at the boundary of the type. pub trait WrappingDivAssign { fn wrapping_div_assign(&mut self, other: RHS); } /// Multiplies two numbers, wrapping around at the boundary of the type. pub trait WrappingMul { type Output; fn wrapping_mul(self, other: RHS) -> Self::Output; } /// Multiplies a number by another number in place, wrapping around at the boundary of the type. pub trait WrappingMulAssign { fn wrapping_mul_assign(&mut self, other: RHS); } /// Negates a number, wrapping around at the boundary of the type. pub trait WrappingNeg { type Output; fn wrapping_neg(self) -> Self::Output; } /// Negates a number in place, wrapping around at the boundary of the type. pub trait WrappingNegAssign { fn wrapping_neg_assign(&mut self); } /// Raises a number to a power, wrapping around at the boundary of the type. pub trait WrappingPow { type Output; fn wrapping_pow(self, exp: RHS) -> Self::Output; } /// Raises a number to a power in place, wrapping around at the boundary of the type. pub trait WrappingPowAssign { fn wrapping_pow_assign(&mut self, exp: RHS); } /// Squares a number, wrapping around at the boundary of the type. pub trait WrappingSquare { type Output; fn wrapping_square(self) -> Self::Output; } /// Squares a number in place, wrapping around at the boundary of the type. pub trait WrappingSquareAssign { fn wrapping_square_assign(&mut self); } /// Subtracts two numbers, wrapping around at the boundary of the type. pub trait WrappingSub { type Output; fn wrapping_sub(self, other: RHS) -> Self::Output; } /// Subtracts a number by another number in place, wrapping around at the boundary of the type. pub trait WrappingSubAssign { fn wrapping_sub_assign(&mut self, other: RHS); } /// Subtracts a number by the product of two other numbers, wrapping around at the boundary of the /// type. pub trait WrappingSubMul { type Output; fn wrapping_sub_mul(self, y: Y, z: Z) -> Self::Output; } /// Subtracts a number by the product of two other numbers, in place, wrapping around at the /// boundary of the type. pub trait WrappingSubMulAssign { fn wrapping_sub_mul_assign(&mut self, y: Y, z: Z); } /// Multiplies two numbers, returning the product as a pair of `Self` values. /// /// The more significant number always comes first. pub trait XMulYToZZ: Sized { fn x_mul_y_to_zz(x: Self, y: Self) -> (Self, Self); } /// Adds two numbers, each composed of two `Self` values, returning the sum as a pair of `Self` /// values. /// /// The more significant number always comes first. Addition is wrapping, and overflow is not /// indicated. pub trait XXAddYYToZZ: Sized { fn xx_add_yy_to_zz(x_1: Self, x_0: Self, y_1: Self, y_0: Self) -> (Self, Self); } /// Computes the quotient and remainder of two numbers. The first is composed of two `Self` values, /// and the second of a single one. /// /// `x_1` must be less than `y`. pub trait XXDivModYToQR: Sized { fn xx_div_mod_y_to_qr(x_1: Self, x_0: Self, y: Self) -> (Self, Self); } /// Subtracts two numbers, each composed of two `Self` values, returing the difference as a pair of /// `Self` values. /// /// The more significant number always comes first. Subtraction is wrapping, and overflow is not /// indicated. pub trait XXSubYYToZZ: Sized { fn xx_sub_yy_to_zz(x_1: Self, x_0: Self, y_1: Self, y_0: Self) -> (Self, Self); } /// Adds two numbers, each composed of three `Self` values, returning the sum as a triple of `Self` /// values. /// /// The more significant number always comes first. Addition is wrapping, and overflow is not /// indicated. pub trait XXXAddYYYToZZZ: Sized { fn xxx_add_yyy_to_zzz( x_2: Self, x_1: Self, x_0: Self, y_2: Self, y_1: Self, y_0: Self, ) -> (Self, Self, Self); } /// Subtracts two numbers, each composed of three `Self` values, returing the difference as a triple /// of `Self` values. /// /// The more significant number always comes first. Subtraction is wrapping, and overflow is not /// indicated. pub trait XXXSubYYYToZZZ: Sized { fn xxx_sub_yyy_to_zzz( x_2: Self, x_1: Self, x_0: Self, y_2: Self, y_1: Self, y_0: Self, ) -> (Self, Self, Self); } /// Adds two numbers, each composed of four `Self` values, returning the sum as a quadruple of /// `Self` values. /// /// The more significant number always comes first. Addition is wrapping, and overflow is not /// indicated. pub trait XXXXAddYYYYToZZZZ: Sized { #[allow(clippy::too_many_arguments)] fn xxxx_add_yyyy_to_zzzz( x_3: Self, x_2: Self, x_1: Self, x_0: Self, y_3: Self, y_2: Self, y_1: Self, y_0: Self, ) -> (Self, Self, Self, Self); } malachite-base-0.4.16/src/num/arithmetic/wrapping_abs.rs000064400000000000000000000032461046102023000213210ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{WrappingAbs, WrappingAbsAssign}; macro_rules! impl_wrapping_abs { ($t:ident) => { impl WrappingAbs for $t { type Output = $t; /// This is a wrapper over the `wrapping_abs` functions in the standard library, for /// example [this one](i32::wrapping_abs). #[inline] fn wrapping_abs(self) -> $t { $t::wrapping_abs(self) } } impl WrappingAbsAssign for $t { /// Replaces a number with its absolute value, wrapping around at the boundary of the /// type. /// /// $$ /// x \gets \\begin{cases} /// |x| & \text{if} \\quad x > -2^{W-1}, \\\\ /// -2^{W-1} & \text{if} \\quad x = -2^{W-1}, /// \\end{cases} /// $$ /// where $W$ is `Self::WIDTH`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::wrapping_abs#wrapping_abs_assign). #[inline] fn wrapping_abs_assign(&mut self) { *self = self.wrapping_abs(); } } }; } apply_to_signeds!(impl_wrapping_abs); malachite-base-0.4.16/src/num/arithmetic/wrapping_add.rs000064400000000000000000000030331046102023000212760ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{WrappingAdd, WrappingAddAssign}; macro_rules! impl_wrapping_add { ($t:ident) => { impl WrappingAdd<$t> for $t { type Output = $t; /// This is a wrapper over the `wrapping_add` functions in the standard library, for /// example [this one](u32::wrapping_add). #[inline] fn wrapping_add(self, other: $t) -> $t { $t::wrapping_add(self, other) } } impl WrappingAddAssign<$t> for $t { /// Adds a number to another number in place, wrapping around at the boundary of the /// type. /// /// $x \gets z$, where $z \equiv x + y \mod 2^W$ and $W$ is `Self::WIDTH`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::wrapping_add#wrapping_add_assign). #[inline] fn wrapping_add_assign(&mut self, other: $t) { *self = self.wrapping_add(other); } } }; } apply_to_primitive_ints!(impl_wrapping_add); malachite-base-0.4.16/src/num/arithmetic/wrapping_add_mul.rs000064400000000000000000000042331046102023000221560ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{WrappingAddMul, WrappingAddMulAssign}; use crate::num::basic::integers::PrimitiveInt; fn wrapping_add_mul(x: T, y: T, z: T) -> T { x.wrapping_add(y.wrapping_mul(z)) } fn wrapping_add_mul_assign(x: &mut T, y: T, z: T) { x.wrapping_add_assign(y.wrapping_mul(z)); } macro_rules! impl_wrapping_add_mul { ($t:ident) => { impl WrappingAddMul<$t> for $t { type Output = $t; /// Adds a number and the product of two other numbers, wrapping around at the boundary /// of the type. /// /// $f(x, y, z) = w$, where $w \equiv x + yz \mod 2^W$ and $W$ is `Self::WIDTH`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::wrapping_add_mul#wrapping_add_mul). #[inline] fn wrapping_add_mul(self, y: $t, z: $t) -> $t { wrapping_add_mul(self, y, z) } } impl WrappingAddMulAssign<$t> for $t { /// Adds a number and the product of two other numbers in place, wrapping around at the /// boundary of the type. /// /// $x \gets w$, where $w \equiv x + yz \mod 2^W$ and $W$ is `Self::WIDTH`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::wrapping_add_mul#wrapping_add_mul_assign). #[inline] fn wrapping_add_mul_assign(&mut self, y: $t, z: $t) { wrapping_add_mul_assign(self, y, z); } } }; } apply_to_primitive_ints!(impl_wrapping_add_mul); malachite-base-0.4.16/src/num/arithmetic/wrapping_div.rs000064400000000000000000000032511046102023000213320ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{WrappingDiv, WrappingDivAssign}; macro_rules! impl_wrapping_div { ($t:ident) => { impl WrappingDiv<$t> for $t { type Output = $t; /// This is a wrapper over the `wrapping_div` functions in the standard library, for /// example [this one](u32::wrapping_div). #[inline] fn wrapping_div(self, other: $t) -> $t { $t::wrapping_div(self, other) } } impl WrappingDivAssign<$t> for $t { /// Divides a number by another number in place, wrapping around at the boundary of the /// type. /// /// Wrapping only occurs when `Self` is signed, `self` is `Self::MIN`, and `other` is /// -1. The "actual" result, `-Self::MIN`, can't be represented and is wrapped back to /// `Self::MIN`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::wrapping_div#wrapping_div_assign). #[inline] fn wrapping_div_assign(&mut self, other: $t) { *self = self.wrapping_div(other); } } }; } apply_to_primitive_ints!(impl_wrapping_div); malachite-base-0.4.16/src/num/arithmetic/wrapping_mul.rs000064400000000000000000000030301046102023000213400ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{WrappingMul, WrappingMulAssign}; macro_rules! impl_wrapping_mul { ($t:ident) => { impl WrappingMul<$t> for $t { type Output = $t; /// This is a wrapper over the `wrapping_mul` functions in the standard library, for /// example [this one](u32::wrapping_mul). #[inline] fn wrapping_mul(self, other: $t) -> $t { $t::wrapping_mul(self, other) } } impl WrappingMulAssign<$t> for $t { /// Adds a number to another number in place, wrapping around at the boundary of the /// type. /// /// $x \gets z$, where $z \equiv xy \mod 2^W$ and $W$ is `Self::WIDTH`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::wrapping_mul#wrapping_mul_assign). #[inline] fn wrapping_mul_assign(&mut self, other: $t) { *self = self.wrapping_mul(other); } } }; } apply_to_primitive_ints!(impl_wrapping_mul); malachite-base-0.4.16/src/num/arithmetic/wrapping_neg.rs000064400000000000000000000027171046102023000213270ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{WrappingNeg, WrappingNegAssign}; macro_rules! impl_wrapping_neg { ($t:ident) => { impl WrappingNeg for $t { type Output = $t; /// This is a wrapper over the `wrapping_neg` functions in the standard library, for /// example [this one](u32::wrapping_neg). #[inline] fn wrapping_neg(self) -> $t { $t::wrapping_neg(self) } } impl WrappingNegAssign for $t { /// Negates a number in place, wrapping around at the boundary of the type. /// /// $x \gets y$, where $y \equiv -x \mod 2^W$ and $W$ is `Self::WIDTH`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::wrapping_neg#wrapping_neg_assign). #[inline] fn wrapping_neg_assign(&mut self) { *self = self.wrapping_neg(); } } }; } apply_to_primitive_ints!(impl_wrapping_neg); malachite-base-0.4.16/src/num/arithmetic/wrapping_pow.rs000064400000000000000000000060731046102023000213620ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{Parity, UnsignedAbs, WrappingPow, WrappingPowAssign}; use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::WrappingFrom; use crate::num::logic::traits::BitIterable; fn wrapping_pow_unsigned(x: T, exp: u64) -> T { if exp == 0 { T::ONE } else if x < T::TWO { x } else { let mut power = x; for bit in exp.bits().rev().skip(1) { power.wrapping_square_assign(); if bit { power.wrapping_mul_assign(x); } } power } } fn wrapping_pow_signed< U: PrimitiveUnsigned, S: PrimitiveSigned + UnsignedAbs + WrappingFrom, >( x: S, exp: u64, ) -> S { let p_abs = x.unsigned_abs().wrapping_pow(exp); if x >= S::ZERO || exp.even() { S::wrapping_from(p_abs) } else { S::wrapping_from(p_abs).wrapping_neg() } } macro_rules! impl_wrapping_pow_unsigned { ($t:ident) => { impl WrappingPow for $t { type Output = $t; /// This is a wrapper over the `wrapping_pow` functions in the standard library, for /// example [this one](u32::wrapping_pow). #[inline] fn wrapping_pow(self, exp: u64) -> $t { wrapping_pow_unsigned(self, exp) } } }; } apply_to_unsigneds!(impl_wrapping_pow_unsigned); macro_rules! impl_wrapping_pow_signed { ($t:ident) => { impl WrappingPow for $t { type Output = $t; /// This is a wrapper over the `wrapping_pow` functions in the standard library, for /// example [this one](i32::wrapping_pow). #[inline] fn wrapping_pow(self, exp: u64) -> $t { wrapping_pow_signed(self, exp) } } }; } apply_to_signeds!(impl_wrapping_pow_signed); macro_rules! impl_wrapping_pow_primitive_int { ($t:ident) => { impl WrappingPowAssign for $t { /// Raises a number to a power, in place, wrapping around at the boundary of the type. /// /// $x \gets y$, where $y \equiv x^n \mod 2^W$ and $W$ is `Self::WIDTH`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::wrapping_pow#wrapping_pow_assign). #[inline] fn wrapping_pow_assign(&mut self, exp: u64) { *self = WrappingPow::wrapping_pow(*self, exp); } } }; } apply_to_primitive_ints!(impl_wrapping_pow_primitive_int); malachite-base-0.4.16/src/num/arithmetic/wrapping_square.rs000064400000000000000000000033751046102023000220570ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{WrappingMulAssign, WrappingSquare, WrappingSquareAssign}; macro_rules! impl_wrapping_square { ($t:ident) => { impl WrappingSquare for $t { type Output = $t; /// Squares a number, wrapping around at the boundary of the type. /// /// $f(x) = y$, where $y \equiv x^2 \mod 2^W$ and $W$ is `Self::WIDTH`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::wrapping_square#wrapping_square). #[inline] fn wrapping_square(self) -> $t { self.wrapping_mul(self) } } impl WrappingSquareAssign for $t { /// Squares a number in place, wrapping around at the boundary of the type. /// /// $x \gets y$, where $y \equiv x^2 \mod 2^W$ and $W$ is `Self::WIDTH`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::wrapping_square#wrapping_square_assign). #[inline] fn wrapping_square_assign(&mut self) { self.wrapping_mul_assign(*self); } } }; } apply_to_primitive_ints!(impl_wrapping_square); malachite-base-0.4.16/src/num/arithmetic/wrapping_sub.rs000064400000000000000000000030401046102023000213350ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{WrappingSub, WrappingSubAssign}; macro_rules! impl_wrapping_sub { ($t:ident) => { impl WrappingSub<$t> for $t { type Output = $t; /// This is a wrapper over the `wrapping_sub` functions in the standard library, for /// example [this one](u32::wrapping_sub). #[inline] fn wrapping_sub(self, other: $t) -> $t { $t::wrapping_sub(self, other) } } impl WrappingSubAssign<$t> for $t { /// Subtracts a number by another number in place, wrapping around at the boundary of /// the type. /// /// $x \gets z$, where $z \equiv x - y \mod 2^W$ and $W$ is `Self::WIDTH`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::wrapping_sub#wrapping_sub_assign). #[inline] fn wrapping_sub_assign(&mut self, other: $t) { *self = self.wrapping_sub(other); } } }; } apply_to_primitive_ints!(impl_wrapping_sub); malachite-base-0.4.16/src/num/arithmetic/wrapping_sub_mul.rs000064400000000000000000000042421046102023000222170ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{WrappingSubMul, WrappingSubMulAssign}; use crate::num::basic::integers::PrimitiveInt; fn wrapping_sub_mul(x: T, y: T, z: T) -> T { x.wrapping_sub(y.wrapping_mul(z)) } fn wrapping_sub_mul_assign(x: &mut T, y: T, z: T) { x.wrapping_sub_assign(y.wrapping_mul(z)); } macro_rules! impl_wrapping_sub_mul { ($t:ident) => { impl WrappingSubMul<$t> for $t { type Output = $t; /// Subtracts a number by the product of two other numbers, wrapping around at the /// boundary of the type. /// /// $f(x, y, z) = w$, where $w \equiv x - yz \mod 2^W$ and $W$ is `Self::WIDTH`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::wrapping_sub_mul#wrapping_sub_mul). #[inline] fn wrapping_sub_mul(self, y: $t, z: $t) -> $t { wrapping_sub_mul(self, y, z) } } impl WrappingSubMulAssign<$t> for $t { /// Subtracts a number by the product of two other numbers in place, wrapping around at /// the boundary of the type. /// /// $x \gets w$, where $w \equiv x - yz \mod 2^W$ and $W$ is `Self::WIDTH`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::wrapping_sub_mul#wrapping_sub_mul_assign). #[inline] fn wrapping_sub_mul_assign(&mut self, y: $t, z: $t) { wrapping_sub_mul_assign(self, y, z) } } }; } apply_to_primitive_ints!(impl_wrapping_sub_mul); malachite-base-0.4.16/src/num/arithmetic/x_mul_y_to_zz.rs000064400000000000000000000112451046102023000215440ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // Uses code adopted from the GNU MP Library. // // Copyright © 1991-1994, 1996, 1997, 1999-2005, 2007-2009, 2011-2020 Free Software // Foundation, Inc. // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::XMulYToZZ; use crate::num::basic::integers::PrimitiveInt; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::half::{wide_join_halves, wide_split_in_half, wide_upper_half}; use crate::num::conversion::traits::{HasHalf, SplitInHalf, WrappingFrom}; fn implicit_x_mul_y_to_zz + HasHalf + PrimitiveUnsigned + SplitInHalf>( x: T, y: T, ) -> (T, T) { (DT::from(x) * DT::from(y)).split_in_half() } pub_test! {explicit_x_mul_y_to_zz(x: T, y: T) -> (T, T) { let (x_1, x_0) = wide_split_in_half(x); let (y_1, y_0) = wide_split_in_half(y); let x_0_y_0 = x_0 * y_0; let mut x_0_y_1 = x_0 * y_1; let x_1_y_0 = x_1 * y_0; let mut x_1_y_1 = x_1 * y_1; let (x_0_y_0_1, x_0_y_0_0) = wide_split_in_half(x_0_y_0); x_0_y_1.wrapping_add_assign(x_0_y_0_1); if x_0_y_1.overflowing_add_assign(x_1_y_0) { x_1_y_1.wrapping_add_assign(T::power_of_2(T::WIDTH >> 1)); } let z_1 = x_1_y_1.wrapping_add(wide_upper_half(x_0_y_1)); let z_0 = wide_join_halves(x_0_y_1, x_0_y_0_0); (z_1, z_0) }} macro_rules! implicit_x_mul_y_to_zz { ($t:ident, $dt:ident) => { impl XMulYToZZ for $t { /// Multiplies two numbers, returning the product as a pair of `Self` values. /// /// The more significant value always comes first. /// /// $$ /// f(x, y) = (z_1, z_0), /// $$ /// where $W$ is `Self::WIDTH`, /// /// $x, y, z_1, z_0 < 2^W$, and /// $$ /// xy = 2^Wz_1 + z_0. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::x_mul_y_to_zz#x_mul_y_to_zz). /// /// This is equivalent to `umul_ppmm` from `longlong.h`, GMP 6.2.1, where `(w1, w0)` is /// returned. #[inline] fn x_mul_y_to_zz(x: $t, y: $t) -> ($t, $t) { implicit_x_mul_y_to_zz::<$t, $dt>(x, y) } } }; } implicit_x_mul_y_to_zz!(u8, u16); implicit_x_mul_y_to_zz!(u16, u32); implicit_x_mul_y_to_zz!(u32, u64); implicit_x_mul_y_to_zz!(u64, u128); impl XMulYToZZ for usize { /// Multiplies two numbers, returning the product as a pair of [`usize`] values. /// /// The more significant value always comes first. /// /// $$ /// f(x, y) = (z_1, z_0), /// $$ /// where $W$ is `Self::WIDTH`, /// /// $x, y, z_1, z_0 < 2^W$, and /// $$ /// xy = 2^Wz_1 + z_0. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::x_mul_y_to_zz#x_mul_y_to_zz). /// /// This is equivalent to `umul_ppmm` from `longlong.h`, GMP 6.2.1, where `(w1, w0)` is /// returned. fn x_mul_y_to_zz(x: usize, y: usize) -> (usize, usize) { if usize::WIDTH == u32::WIDTH { let (z_1, z_0) = u32::x_mul_y_to_zz(u32::wrapping_from(x), u32::wrapping_from(y)); (usize::wrapping_from(z_1), usize::wrapping_from(z_0)) } else { let (z_1, z_0) = u64::x_mul_y_to_zz(u64::wrapping_from(x), u64::wrapping_from(y)); (usize::wrapping_from(z_1), usize::wrapping_from(z_0)) } } } impl XMulYToZZ for u128 { /// Multiplies two numbers, returning the product as a pair of [`u128`] values. /// /// The more significant value always comes first. /// /// $$ /// f(x, y) = (z_1, z_0), /// $$ /// where $W$ is `Self::WIDTH`, /// /// $x, y, z_1, z_0 < 2^W$, and /// $$ /// xy = 2^Wz_1 + z_0. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::x_mul_y_to_zz#x_mul_y_to_zz). /// /// This is equivalent to `umul_ppmm` from `longlong.h`, GMP 6.2.1, where `(w1, w0)` is /// returned. #[inline] fn x_mul_y_to_zz(x: u128, y: u128) -> (u128, u128) { explicit_x_mul_y_to_zz(x, y) } } malachite-base-0.4.16/src/num/arithmetic/xx_add_yy_to_zz.rs000064400000000000000000000123511046102023000220570ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // Uses code adopted from the GNU MP Library. // // Copyright © 1991-1994, 1996, 1997, 1999-2005, 2007-2009, 2011-2020 Free Software // Foundation, Inc. // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::XXAddYYToZZ; use crate::num::basic::integers::PrimitiveInt; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::{JoinHalves, SplitInHalf, WrappingFrom}; fn implicit_xx_add_yy_to_zz( x_1: DT::Half, x_0: DT::Half, y_1: DT::Half, y_0: DT::Half, ) -> (DT::Half, DT::Half) { DT::join_halves(x_1, x_0) .wrapping_add(DT::join_halves(y_1, y_0)) .split_in_half() } pub_test! { explicit_xx_add_yy_to_zz(x_1: T, x_0: T, y_1: T, y_0: T) -> (T, T) { let (z_0, carry) = x_0.overflowing_add(y_0); let mut z_1 = x_1.wrapping_add(y_1); if carry { z_1.wrapping_add_assign(T::ONE); } (z_1, z_0) }} macro_rules! implicit_xx_add_yy_to_zz { ($t:ident, $dt:ident) => { impl XXAddYYToZZ for $t { /// Adds two numbers, each composed of two `Self` values, returning the sum as a pair of /// `Self` values. /// /// The more significant value always comes first. Addition is wrapping, and overflow is /// not indicated. /// /// $$ /// f(x_1, x_0, y_1, y_0) = (z_1, z_0), /// $$ /// where $W$ is `Self::WIDTH`, /// /// $x_1, x_0, y_1, y_0, z_1, z_0 < 2^W$, and /// $$ /// (2^Wx_1 + x_0) + (2^Wy_1 + y_0) \equiv 2^Wz_1 + z_0 \mod 2^{2W}. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::xx_add_yy_to_zz#xx_add_yy_to_zz). /// /// This is equivalent to `add_ssaaaa` from `longlong.h`, GMP 6.2.1, where `(sh, sl)` is /// returned. #[inline] fn xx_add_yy_to_zz(x_1: $t, x_0: $t, y_1: $t, y_0: $t) -> ($t, $t) { implicit_xx_add_yy_to_zz::<$dt>(x_1, x_0, y_1, y_0) } } }; } implicit_xx_add_yy_to_zz!(u8, u16); implicit_xx_add_yy_to_zz!(u16, u32); implicit_xx_add_yy_to_zz!(u32, u64); implicit_xx_add_yy_to_zz!(u64, u128); impl XXAddYYToZZ for usize { /// Adds two numbers, each composed of two [`usize`] values, returning the sum as a pair of /// `usize` values. /// /// The more significant value always comes first. Addition is wrapping, and overflow is not /// indicated. /// /// $$ /// f(x_1, x_0, y_1, y_0) = (z_1, z_0), /// $$ /// where $W$ is `Self::WIDTH`, /// /// $x_1, x_0, y_1, y_0, z_1, z_0 < 2^W$, and /// $$ /// (2^Wx_1 + x_0) + (2^Wy_1 + y_0) \equiv 2^Wz_1 + z_0 \mod 2^{2W}. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::xx_add_yy_to_zz#xx_add_yy_to_zz). /// /// This is equivalent to `add_ssaaaa` from `longlong.h`, GMP 6.2.1, where `(sh, sl)` is /// returned. fn xx_add_yy_to_zz(x_1: usize, x_0: usize, y_1: usize, y_0: usize) -> (usize, usize) { if usize::WIDTH == u32::WIDTH { let (z_1, z_0) = u32::xx_add_yy_to_zz( u32::wrapping_from(x_1), u32::wrapping_from(x_0), u32::wrapping_from(y_1), u32::wrapping_from(y_0), ); (usize::wrapping_from(z_1), usize::wrapping_from(z_0)) } else { let (z_1, z_0) = u64::xx_add_yy_to_zz( u64::wrapping_from(x_1), u64::wrapping_from(x_0), u64::wrapping_from(y_1), u64::wrapping_from(y_0), ); (usize::wrapping_from(z_1), usize::wrapping_from(z_0)) } } } impl XXAddYYToZZ for u128 { /// Adds two numbers, each composed of two [`u128`] values, returning the sum as a pair of /// [`u128`] values. /// /// The more significant value always comes first. Addition is wrapping, and overflow is not /// indicated. /// /// $$ /// f(x_1, x_0, y_1, y_0) = (z_1, z_0), /// $$ /// where $W$ is `Self::WIDTH`, /// /// $x_1, x_0, y_1, y_0, z_1, z_0 < 2^W$, and /// $$ /// (2^Wx_1 + x_0) + (2^Wy_1 + y_0) \equiv 2^Wz_1 + z_0 \mod 2^{2W}. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::xx_add_yy_to_zz#xx_add_yy_to_zz). /// /// This is equivalent to `add_ssaaaa` from `longlong.h`, GMP 6.2.1, where `(sh, sl)` is /// returned. #[inline] fn xx_add_yy_to_zz(x_1: u128, x_0: u128, y_1: u128, y_0: u128) -> (u128, u128) { explicit_xx_add_yy_to_zz(x_1, x_0, y_1, y_0) } } malachite-base-0.4.16/src/num/arithmetic/xx_div_mod_y_to_qr.rs000064400000000000000000000151711046102023000225410ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // Uses code adopted from the FLINT Library. // // Copyright © 1991, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2005 // Free Software Foundation, Inc. // // Copyright © 2009, 2015, 2016 William Hart // // Copyright © 2011 Fredrik Johansson // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::XXDivModYToQR; use crate::num::basic::integers::PrimitiveInt; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::half::{wide_join_halves, wide_split_in_half}; use crate::num::conversion::traits::WrappingFrom; use crate::num::conversion::traits::{HasHalf, JoinHalves, SplitInHalf}; use crate::num::logic::traits::LeadingZeros; fn implicit_xx_div_mod_y_to_qr< T: PrimitiveUnsigned, DT: From + HasHalf + JoinHalves + PrimitiveUnsigned + SplitInHalf, >( x_1: T, x_0: T, y: T, ) -> (T, T) { assert!(x_1 < y); let (q, r) = DT::join_halves(x_1, x_0).div_mod(DT::from(y)); (q.lower_half(), r.lower_half()) } // This is equivalent to `udiv_qrnnd_int` from `longlong.h`, FLINT 2.7.1, where `(q, r)` is // returned. fn explicit_xx_div_mod_y_to_qr_normalized(x_1: T, x_0: T, y: T) -> (T, T) { let (d_1, d_0) = wide_split_in_half(y); let (x_0_1, x_0_0) = wide_split_in_half(x_0); let mut q_1 = x_1 / d_1; let mut r_1 = x_1.wrapping_sub(q_1.wrapping_mul(d_1)); let product = q_1.wrapping_mul(d_0); r_1 = wide_join_halves(r_1, x_0_1); if r_1 < product { q_1.wrapping_sub_assign(T::ONE); if !r_1.overflowing_add_assign(y) && r_1 < product { q_1.wrapping_sub_assign(T::ONE); r_1.wrapping_add_assign(y); } } r_1.wrapping_sub_assign(product); let mut q_0 = r_1 / d_1; let mut r_0 = r_1.wrapping_sub(q_0.wrapping_mul(d_1)); let product = q_0.wrapping_mul(d_0); r_0 = wide_join_halves(r_0, x_0_0); if r_0 < product { q_0.wrapping_sub_assign(T::ONE); if !r_0.overflowing_add_assign(y) && r_0 < product { q_0.wrapping_sub_assign(T::ONE); r_0.wrapping_add_assign(y); } } r_0.wrapping_sub_assign(product); (wide_join_halves(q_1, q_0), r_0) } // This is udiv_qrnnd from longlong.h, FLINT 2.7.1, where (q, r) is returned. pub_test! {explicit_xx_div_mod_y_to_qr(x_1: T, x_0: T, y: T) -> (T, T) { assert!(x_1 < y); let shift = LeadingZeros::leading_zeros(y); if shift == 0 { explicit_xx_div_mod_y_to_qr_normalized(x_1, x_0, y) } else { let (q, r) = explicit_xx_div_mod_y_to_qr_normalized( x_1 << shift | (x_0 >> (T::WIDTH - shift)), x_0 << shift, y << shift, ); (q, r >> shift) } }} macro_rules! implicit_xx_div_mod_to_qr { ($t:ident, $dt:ident) => { impl XXDivModYToQR for $t { /// Computes the quotient and remainder of two numbers. The first is composed of two /// `Self` values, and the second of a single one. /// /// `x_1` must be less than `y`. /// /// $$ /// f(x_1, x_0, y) = (q, r), /// $$ /// where $W$ is `Self::WIDTH`, /// /// $x_1, x_0, y, q, r < 2^W$, /// /// $x_1, r < y$, and /// $$ /// qy + r = 2^Wx_1 + x_0. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::xx_div_mod_y_to_qr#xx_div_mod_y_to_qr). /// /// This is equivalent to `udiv_qrnnd` from `longlong.h`, FLINT 2.7.1, where `(q, r)` is /// returned. #[inline] fn xx_div_mod_y_to_qr(x_1: $t, x_0: $t, y: $t) -> ($t, $t) { implicit_xx_div_mod_y_to_qr::<$t, $dt>(x_1, x_0, y) } } }; } implicit_xx_div_mod_to_qr!(u8, u16); implicit_xx_div_mod_to_qr!(u16, u32); implicit_xx_div_mod_to_qr!(u32, u64); implicit_xx_div_mod_to_qr!(u64, u128); impl XXDivModYToQR for usize { /// Computes the quotient and remainder of two numbers. The first is composed of two [`usize`] /// values, and the second of a single one. /// /// `x_1` must be less than `y`. /// /// $$ /// f(x_1, x_0, y) = (q, r), /// $$ /// where $W$ is `Self::WIDTH`, /// /// $x_1, x_0, y, q, r < 2^W$, /// /// $x_1, r < y$, and /// $$ /// qy + r = 2^Wx_1 + x_0. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::xx_div_mod_y_to_qr#xx_div_mod_y_to_qr). /// /// This is `udiv_qrnnd` from `longlong.h`, FLINT 2.7.1, where `(q, r)` is returned. fn xx_div_mod_y_to_qr(x_1: usize, x_0: usize, y: usize) -> (usize, usize) { if usize::WIDTH == u32::WIDTH { let (q, r) = u32::xx_div_mod_y_to_qr( u32::wrapping_from(x_1), u32::wrapping_from(x_0), u32::wrapping_from(y), ); (usize::wrapping_from(q), usize::wrapping_from(r)) } else { let (q, r) = u64::xx_div_mod_y_to_qr( u64::wrapping_from(x_1), u64::wrapping_from(x_0), u64::wrapping_from(y), ); (usize::wrapping_from(q), usize::wrapping_from(r)) } } } impl XXDivModYToQR for u128 { /// Computes the quotient and remainder of two numbers. The first is composed of two [`u128`] /// values, and the second of a single one. /// /// `x_1` must be less than `y`. /// /// $$ /// f(x_1, x_0, y) = (q, r), /// $$ /// where $W$ is `Self::WIDTH`, /// /// $x_1, x_0, y, q, r < 2^W$, /// /// $x_1, r < y$, and /// $$ /// qy + r = 2^Wx_1 + x_0. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::xx_div_mod_y_to_qr#xx_div_mod_y_to_qr). /// /// This is equivalent to `udiv_qrnnd` from `longlong.h`, FLINT 2.7.1, where `(q, r)` is /// returned. #[inline] fn xx_div_mod_y_to_qr(x_1: u128, x_0: u128, y: u128) -> (u128, u128) { explicit_xx_div_mod_y_to_qr(x_1, x_0, y) } } malachite-base-0.4.16/src/num/arithmetic/xx_sub_yy_to_zz.rs000064400000000000000000000124321046102023000221200ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // Uses code adopted from the GNU MP Library. // // Copyright © 1991-1994, 1996, 1997, 1999-2005, 2007-2009, 2011-2020 Free Software // Foundation, Inc. // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::XXSubYYToZZ; use crate::num::basic::integers::PrimitiveInt; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::{JoinHalves, SplitInHalf, WrappingFrom}; fn implicit_xx_sub_yy_to_zz( x_1: DT::Half, x_0: DT::Half, y_1: DT::Half, y_0: DT::Half, ) -> (DT::Half, DT::Half) { DT::join_halves(x_1, x_0) .wrapping_sub(DT::join_halves(y_1, y_0)) .split_in_half() } pub_test! { explicit_xx_sub_yy_to_zz(x_1: T, x_0: T, y_1: T, y_0: T) -> (T, T) { let (z_0, borrow) = x_0.overflowing_sub(y_0); let mut z_1 = x_1.wrapping_sub(y_1); if borrow { z_1.wrapping_sub_assign(T::ONE); } (z_1, z_0) }} macro_rules! implicit_xx_sub_yy_to_zz { ($t:ident, $dt:ident) => { impl XXSubYYToZZ for $t { /// Subtracts two numbers, each composed of two `Self` values, returning the difference /// as a pair of `Self` values. /// /// The more significant value always comes first. Subtraction is wrapping, and overflow /// is not indicated. /// /// $$ /// f(x_1, x_0, y_1, y_0) = (z_1, z_0), /// $$ /// where $W$ is `Self::WIDTH`, /// /// $x_1, x_0, y_1, y_0, z_1, z_0 < 2^W$, and /// $$ /// (2^Wx_1 + x_0) - (2^Wy_1 + y_0) \equiv 2^Wz_1 + z_0 \mod 2^{2W}. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::xx_sub_yy_to_zz#xx_sub_yy_to_zz). /// /// This is equivalent to `sub_ddmmss` from `longlong.h`, GMP 6.2.1, where `(sh, sl)` is /// returned. #[inline] fn xx_sub_yy_to_zz(x_1: $t, x_0: $t, y_1: $t, y_0: $t) -> ($t, $t) { implicit_xx_sub_yy_to_zz::<$dt>(x_1, x_0, y_1, y_0) } } }; } implicit_xx_sub_yy_to_zz!(u8, u16); implicit_xx_sub_yy_to_zz!(u16, u32); implicit_xx_sub_yy_to_zz!(u32, u64); implicit_xx_sub_yy_to_zz!(u64, u128); impl XXSubYYToZZ for usize { /// Subtracts two numbers, each composed of two [`usize`] values, returning the difference as a /// pair of [`usize`] values. /// /// The more significant value always comes first. Subtraction is wrapping, and overflow is not /// indicated. /// /// $$ /// f(x_1, x_0, y_1, y_0) = (z_1, z_0), /// $$ /// where $W$ is `Self::WIDTH`, /// /// $x_1, x_0, y_1, y_0, z_1, z_0 < 2^W$, and /// $$ /// (2^Wx_1 + x_0) - (2^Wy_1 + y_0) \equiv 2^Wz_1 + z_0 \mod 2^{2W}. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::xx_sub_yy_to_zz#xx_sub_yy_to_zz). /// /// This is equivalent to `sub_ddmmss` from `longlong.h`, GMP 6.2.1, where `(sh, sl)` is /// returned. fn xx_sub_yy_to_zz(x_1: usize, x_0: usize, y_1: usize, y_0: usize) -> (usize, usize) { if usize::WIDTH == u32::WIDTH { let (z_1, z_0) = u32::xx_sub_yy_to_zz( u32::wrapping_from(x_1), u32::wrapping_from(x_0), u32::wrapping_from(y_1), u32::wrapping_from(y_0), ); (usize::wrapping_from(z_1), usize::wrapping_from(z_0)) } else { let (z_1, z_0) = u64::xx_sub_yy_to_zz( u64::wrapping_from(x_1), u64::wrapping_from(x_0), u64::wrapping_from(y_1), u64::wrapping_from(y_0), ); (usize::wrapping_from(z_1), usize::wrapping_from(z_0)) } } } impl XXSubYYToZZ for u128 { /// Subtracts two numbers, each composed of two [`u128`] values, returning the difference as a /// pair of [`u128`] values. /// /// The more significant value always comes first. Subtraction is wrapping, and overflow is not /// indicated. /// /// $$ /// f(x_1, x_0, y_1, y_0) = (z_1, z_0), /// $$ /// where $W$ is `Self::WIDTH`, /// /// $x_1, x_0, y_1, y_0, z_1, z_0 < 2^W$, and /// $$ /// (2^Wx_1 + x_0) - (2^Wy_1 + y_0) \equiv 2^Wz_1 + z_0 \mod 2^{2W}. /// $$ /// /// # Examples /// See [here](super::xx_sub_yy_to_zz#xx_sub_yy_to_zz). /// /// # Worst-case complexity /// Constant time and additional memory. /// /// This is equivalent to `sub_ddmmss` from `longlong.h`, GMP 6.2.1, where `(sh, sl)` is /// returned. #[inline] fn xx_sub_yy_to_zz(x_1: u128, x_0: u128, y_1: u128, y_0: u128) -> (u128, u128) { explicit_xx_sub_yy_to_zz(x_1, x_0, y_1, y_0) } } malachite-base-0.4.16/src/num/arithmetic/xxx_add_yyy_to_zzz.rs000064400000000000000000000120301046102023000226240ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // Uses code adopted from the FLINT Library. // // Copyright © 1991, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2005 // Free Software Foundation, Inc. // // Copyright © 2009, 2015, 2016 William Hart // // Copyright © 2011 Fredrik Johansson // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::XXXAddYYYToZZZ; use crate::num::basic::integers::PrimitiveInt; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::WrappingFrom; pub_test! {xxx_add_yyy_to_zzz( x_2: T, x_1: T, x_0: T, y_2: T, y_1: T, y_0: T, ) -> (T, T, T) { let (z_0, carry_1) = x_0.overflowing_add(y_0); let (mut z_1, mut carry_2) = x_1.overflowing_add(y_1); if carry_1 { carry_2 |= z_1.overflowing_add_assign(T::ONE); } let mut z_2 = x_2.wrapping_add(y_2); if carry_2 { z_2.wrapping_add_assign(T::ONE); } (z_2, z_1, z_0) }} macro_rules! impl_xxx_add_yyy_to_zzz { ($t:ident) => { impl XXXAddYYYToZZZ for $t { /// Adds two numbers, each composed of three `Self` values, returning the sum as a /// triple of `Self` values. /// /// The more significant value always comes first. Addition is wrapping, and overflow is /// not indicated. /// /// $$ /// f(x_2, x_1, x_0, y_2, y_1, y_0) = (z_2, z_1, z_0), /// $$ /// where $W$ is `Self::WIDTH`, /// /// $x_2, x_1, x_0, y_2, y_1, y_0, z_2, z_1, z_0 < 2^W$, and /// $$ /// (2^{2W}x_2 + 2^Wx_1 + x_0) + (2^{2W}y_2 + 2^Wy_1 + y_0) /// \equiv 2^{2W}z_2 + 2^Wz_1 + z_0 \mod 2^{3W}. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::xxx_add_yyy_to_zzz#xxx_add_yyy_to_zzz). /// /// This is equivalent to `add_sssaaaaaa` from `longlong.h`, FLINT 2.7.1, where `(sh, /// sm, sl)` is returned. #[inline] fn xxx_add_yyy_to_zzz( x_2: $t, x_1: $t, x_0: $t, y_2: $t, y_1: $t, y_0: $t, ) -> ($t, $t, $t) { xxx_add_yyy_to_zzz::<$t>(x_2, x_1, x_0, y_2, y_1, y_0) } } }; } impl_xxx_add_yyy_to_zzz!(u8); impl_xxx_add_yyy_to_zzz!(u16); impl_xxx_add_yyy_to_zzz!(u32); impl_xxx_add_yyy_to_zzz!(u64); impl_xxx_add_yyy_to_zzz!(u128); impl XXXAddYYYToZZZ for usize { /// Adds two numbers, each composed of three [`usize`] values, returning the sum as a triple of /// [`usize`] values. /// /// The more significant value always comes first. Addition is wrapping, and overflow is not /// indicated. /// /// $$ /// f(x_2, x_1, x_0, y_2, y_1, y_0) = (z_2, z_1, z_0), /// $$ /// where $W$ is `Self::WIDTH`, /// /// $x_2, x_1, x_0, y_2, y_1, y_0, z_2, z_1, z_0 < 2^W$, and /// $$ /// (2^{2W}x_2 + 2^Wx_1 + x_0) + (2^{2W}y_2 + 2^Wy_1 + y_0) /// \equiv 2^{2W}z_2 + 2^Wz_1 + z_0 \mod 2^{3W}. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::xxx_add_yyy_to_zzz#xxx_add_yyy_to_zzz). /// /// This is equivalent to `add_sssaaaaaa` from `longlong.h`, FLINT 2.7.1, where `(sh, sm, sl)` /// is returned. fn xxx_add_yyy_to_zzz( x_2: usize, x_1: usize, x_0: usize, y_2: usize, y_1: usize, y_0: usize, ) -> (usize, usize, usize) { if usize::WIDTH == u32::WIDTH { let (z_2, z_1, z_0) = u32::xxx_add_yyy_to_zzz( u32::wrapping_from(x_2), u32::wrapping_from(x_1), u32::wrapping_from(x_0), u32::wrapping_from(y_2), u32::wrapping_from(y_1), u32::wrapping_from(y_0), ); ( usize::wrapping_from(z_2), usize::wrapping_from(z_1), usize::wrapping_from(z_0), ) } else { let (z_2, z_1, z_0) = u64::xxx_add_yyy_to_zzz( u64::wrapping_from(x_2), u64::wrapping_from(x_1), u64::wrapping_from(x_0), u64::wrapping_from(y_2), u64::wrapping_from(y_1), u64::wrapping_from(y_0), ); ( usize::wrapping_from(z_2), usize::wrapping_from(z_1), usize::wrapping_from(z_0), ) } } } malachite-base-0.4.16/src/num/arithmetic/xxx_sub_yyy_to_zzz.rs000064400000000000000000000120731046102023000226740ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // Uses code adopted from the FLINT Library. // // Copyright © 1991, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2005 // Free Software Foundation, Inc. // // Copyright © 2009, 2015, 2016 William Hart // // Copyright © 2011 Fredrik Johansson // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::XXXSubYYYToZZZ; use crate::num::basic::integers::PrimitiveInt; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::WrappingFrom; pub_test! {xxx_sub_yyy_to_zzz( x_2: T, x_1: T, x_0: T, y_2: T, y_1: T, y_0: T, ) -> (T, T, T) { let (z_0, borrow_1) = x_0.overflowing_sub(y_0); let (mut z_1, mut borrow_2) = x_1.overflowing_sub(y_1); if borrow_1 { borrow_2 |= z_1.overflowing_sub_assign(T::ONE); } let mut z_2 = x_2.wrapping_sub(y_2); if borrow_2 { z_2.wrapping_sub_assign(T::ONE); } (z_2, z_1, z_0) }} macro_rules! impl_xxx_sub_yyy_to_zzz { ($t:ident) => { impl XXXSubYYYToZZZ for $t { /// Subtracts two numbers, each composed of three `Self` values, returning the /// difference as a triple of `Self` values. /// /// The more significant value always comes first. Subtraction is wrapping, and overflow /// is not indicated. /// /// $$ /// f(x_2, x_1, x_0, y_2, y_1, y_0) = (z_2, z_1, z_0), /// $$ /// where $W$ is `Self::WIDTH`, /// /// $x_2, x_1, x_0, y_2, y_1, y_0, z_2, z_1, z_0 < 2^W$, and /// $$ /// (2^{2W}x_2 + 2^Wx_1 + x_0) - (2^{2W}y_2 + 2^Wy_1 + y_0) /// \equiv 2^{2W}z_2 + 2^Wz_1 + z_0 \mod 2^{3W}. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::xxx_sub_yyy_to_zzz#xxx_sub_yyy_to_zzz). /// /// This is equivalent to `sub_dddmmmsss` from `longlong.h`, FLINT 2.7.1, where `(dh, /// dm, dl)` is returned. #[inline] fn xxx_sub_yyy_to_zzz( x_2: $t, x_1: $t, x_0: $t, y_2: $t, y_1: $t, y_0: $t, ) -> ($t, $t, $t) { xxx_sub_yyy_to_zzz::<$t>(x_2, x_1, x_0, y_2, y_1, y_0) } } }; } impl_xxx_sub_yyy_to_zzz!(u8); impl_xxx_sub_yyy_to_zzz!(u16); impl_xxx_sub_yyy_to_zzz!(u32); impl_xxx_sub_yyy_to_zzz!(u64); impl_xxx_sub_yyy_to_zzz!(u128); impl XXXSubYYYToZZZ for usize { /// Subtracts two numbers, each composed of three [`usize`] values, returning the difference as /// a triple of [`usize`] values. /// /// The more significant value always comes first. Subtraction is wrapping, and overflow is not /// indicated. /// /// $$ /// f(x_2, x_1, x_0, y_2, y_1, y_0) = (z_2, z_1, z_0), /// $$ /// where $W$ is `Self::WIDTH`, /// /// $x_2, x_1, x_0, y_2, y_1, y_0, z_2, z_1, z_0 < 2^W$, and /// $$ /// (2^{2W}x_2 + 2^Wx_1 + x_0) - (2^{2W}y_2 + 2^Wy_1 + y_0) /// \equiv 2^{2W}z_2 + 2^Wz_1 + z_0 \mod 2^{3W}. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::xxx_sub_yyy_to_zzz#xxx_sub_yyy_to_zzz). /// /// This is equivalent to `sub_dddmmmsss` from `longlong.h`, FLINT 2.7.1, where `(dh, dm, dl)` /// is returned. fn xxx_sub_yyy_to_zzz( x_2: usize, x_1: usize, x_0: usize, y_2: usize, y_1: usize, y_0: usize, ) -> (usize, usize, usize) { if usize::WIDTH == u32::WIDTH { let (z_2, z_1, z_0) = u32::xxx_sub_yyy_to_zzz( u32::wrapping_from(x_2), u32::wrapping_from(x_1), u32::wrapping_from(x_0), u32::wrapping_from(y_2), u32::wrapping_from(y_1), u32::wrapping_from(y_0), ); ( usize::wrapping_from(z_2), usize::wrapping_from(z_1), usize::wrapping_from(z_0), ) } else { let (z_2, z_1, z_0) = u64::xxx_sub_yyy_to_zzz( u64::wrapping_from(x_2), u64::wrapping_from(x_1), u64::wrapping_from(x_0), u64::wrapping_from(y_2), u64::wrapping_from(y_1), u64::wrapping_from(y_0), ); ( usize::wrapping_from(z_2), usize::wrapping_from(z_1), usize::wrapping_from(z_0), ) } } } malachite-base-0.4.16/src/num/arithmetic/xxxx_add_yyyy_to_zzzz.rs000064400000000000000000000134371046102023000234130ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // Uses code adopted from the FLINT Library. // // Copyright © 1991, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2005 // Free Software Foundation, Inc. // // Copyright © 2009, 2015, 2016 William Hart // // Copyright © 2011 Fredrik Johansson // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::XXXXAddYYYYToZZZZ; use crate::num::basic::integers::PrimitiveInt; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::WrappingFrom; #[allow(clippy::too_many_arguments)] fn xxxx_add_yyyy_to_zzzz( x_3: T, x_2: T, x_1: T, x_0: T, y_3: T, y_2: T, y_1: T, y_0: T, ) -> (T, T, T, T) { let (z_0, carry_1) = x_0.overflowing_add(y_0); let (mut z_1, mut carry_2) = x_1.overflowing_add(y_1); if carry_1 { carry_2 |= z_1.overflowing_add_assign(T::ONE); } let (mut z_2, mut carry_3) = x_2.overflowing_add(y_2); if carry_2 { carry_3 |= z_2.overflowing_add_assign(T::ONE); } let mut z_3 = x_3.wrapping_add(y_3); if carry_3 { z_3.wrapping_add_assign(T::ONE); } (z_3, z_2, z_1, z_0) } macro_rules! impl_xxxx_add_yyyy_to_zzzz { ($t:ident) => { impl XXXXAddYYYYToZZZZ for $t { /// Adds two numbers, each composed of four `Self` values, returning the sum as a /// quadruple of `Self` values. /// /// The more significant value always comes first. Addition is wrapping, and overflow is /// not indicated. /// /// $$ /// f(x_3, x_2, x_1, x_0, y_2, y_2, y_1, y_0) = (z_3, z_2, z_1, z_0), /// $$ /// where $W$ is `Self::WIDTH`, /// /// $x_3, x_2, x_1, x_0, y_3, y_2, y_1, y_0, z_3, z_2, z_1, z_0 < 2^W$, and /// $$ /// (2^{3W}x_3 + 2^{2W}x_2 + 2^Wx_1 + x_0) + (2^{3W}y_3 + 2^{2W}y_2 + 2^Wy_1 + y_0) /// \equiv 2^{3W}z_3 + 2^{2W}z_2 + 2^Wz_1 + z_0 \mod 2^{4W}. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::xxxx_add_yyyy_to_zzzz#xxxx_add_yyyy_to_zzzz). /// /// This is equivalent to `add_ssssaaaaaaaa` from `longlong.h`, FLINT 2.7.1, where `(s3, /// s2, s1, s0)` is returned. #[inline] fn xxxx_add_yyyy_to_zzzz( x_3: $t, x_2: $t, x_1: $t, x_0: $t, y_3: $t, y_2: $t, y_1: $t, y_0: $t, ) -> ($t, $t, $t, $t) { xxxx_add_yyyy_to_zzzz::<$t>(x_3, x_2, x_1, x_0, y_3, y_2, y_1, y_0) } } }; } impl_xxxx_add_yyyy_to_zzzz!(u8); impl_xxxx_add_yyyy_to_zzzz!(u16); impl_xxxx_add_yyyy_to_zzzz!(u32); impl_xxxx_add_yyyy_to_zzzz!(u64); impl_xxxx_add_yyyy_to_zzzz!(u128); impl XXXXAddYYYYToZZZZ for usize { /// Adds two numbers, each composed of four [`usize`] values, returning the sum as a quadruple /// of [`usize`] values. /// /// The more significant value always comes first. Addition is wrapping, and overflow is not /// indicated. /// /// $$ /// f(x_3, x_2, x_1, x_0, y_2, y_2, y_1, y_0) = (z_3, z_2, z_1, z_0), /// $$ /// where $W$ is `Self::WIDTH`, /// /// $x_3, x_2, x_1, x_0, y_3, y_2, y_1, y_0, z_3, z_2, z_1, z_0 < 2^W$, and /// $$ /// (2^{3W}x_3 + 2^{2W}x_2 + 2^Wx_1 + x_0) + (2^{3W}y_3 + 2^{2W}y_2 + 2^Wy_1 + y_0) /// \equiv 2^{3W}z_3 + 2^{2W}z_2 + 2^Wz_1 + z_0 \mod 2^{4W}. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::xxxx_add_yyyy_to_zzzz#xxxx_add_yyyy_to_zzzz). /// /// This is equivalent to `add_ssssaaaaaaaa` from `longlong.h`, FLINT 2.7.1, where `(s3, s2, s1, /// s0)` is returned. fn xxxx_add_yyyy_to_zzzz( x_3: usize, x_2: usize, x_1: usize, x_0: usize, y_3: usize, y_2: usize, y_1: usize, y_0: usize, ) -> (usize, usize, usize, usize) { if usize::WIDTH == u32::WIDTH { let (z_3, z_2, z_1, z_0) = u32::xxxx_add_yyyy_to_zzzz( u32::wrapping_from(x_3), u32::wrapping_from(x_2), u32::wrapping_from(x_1), u32::wrapping_from(x_0), u32::wrapping_from(y_3), u32::wrapping_from(y_2), u32::wrapping_from(y_1), u32::wrapping_from(y_0), ); ( usize::wrapping_from(z_3), usize::wrapping_from(z_2), usize::wrapping_from(z_1), usize::wrapping_from(z_0), ) } else { let (z_3, z_2, z_1, z_0) = u64::xxxx_add_yyyy_to_zzzz( u64::wrapping_from(x_3), u64::wrapping_from(x_2), u64::wrapping_from(x_1), u64::wrapping_from(x_0), u64::wrapping_from(y_3), u64::wrapping_from(y_2), u64::wrapping_from(y_1), u64::wrapping_from(y_0), ); ( usize::wrapping_from(z_3), usize::wrapping_from(z_2), usize::wrapping_from(z_1), usize::wrapping_from(z_0), ) } } } malachite-base-0.4.16/src/num/basic/floats.rs000064400000000000000000000624231046102023000170670ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::comparison::traits::{Max, Min}; use crate::named::Named; use crate::num::arithmetic::traits::{ Abs, AbsAssign, AddMul, AddMulAssign, Ceiling, CeilingAssign, CeilingLogBase2, CeilingLogBasePowerOf2, CheckedLogBase2, CheckedLogBasePowerOf2, Floor, FloorAssign, FloorLogBase2, FloorLogBasePowerOf2, IsPowerOf2, Ln, NegAssign, NextPowerOf2, NextPowerOf2Assign, Pow, PowAssign, PowerOf2, Reciprocal, ReciprocalAssign, Sign, Sqrt, SqrtAssign, Square, SquareAssign, SubMul, SubMulAssign, }; use crate::num::basic::traits::{ Infinity, NaN, NegativeInfinity, NegativeOne, NegativeZero, One, OneHalf, PrimeConstant, ThueMorseConstant, Two, Zero, }; use crate::num::comparison::traits::PartialOrdAbs; use crate::num::conversion::traits::{ ConvertibleFrom, ExactInto, IntegerMantissaAndExponent, IsInteger, RawMantissaAndExponent, RoundingFrom, RoundingInto, SciMantissaAndExponent, WrappingFrom, }; use crate::num::float::FmtRyuString; use crate::num::logic::traits::{BitAccess, LowMask, SignificantBits, TrailingZeros}; use core::cmp::Ordering::*; use core::fmt::{Debug, Display, LowerExp, UpperExp}; use core::iter::{Product, Sum}; use core::num::FpCategory; use core::ops::{ Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, RemAssign, Sub, SubAssign, }; use core::panic::RefUnwindSafe; use core::str::FromStr; /// This trait defines functions on primitive float types: [`f32`] and [`f64`]. /// /// Many of the functions here concern exponents and mantissas. We define three ways to express a /// float, each with its own exponent and mantissa. In the following, let $x$ be an arbitrary /// positive, finite, non-zero, non-NaN float. Let $M$ and $E$ be the mantissa width and exponent /// width of the floating point type; for [`f32`]s, this is 23 and 8, and for [`f64`]s it's 52 and /// 11. /// /// In the following we assume that $x$ is positive, but you can easily extend these definitions to /// negative floats by first taking their absolute value. /// /// # raw form /// The raw exponent and raw mantissa are the actual bit patterns used to represent the components /// of $x$. The raw exponent $e_r$ is an integer in $[0, 2^E-2]$ and the raw mantissa $m_r$ is an /// integer in $[0, 2^M-1]$. Since we are dealing with a nonzero $x$, we forbid $e_r$ and $m_r$ from /// both being zero. We have /// $$ /// x = \\begin{cases} /// 2^{2-2^{E-1}-M}m_r & \text{if} \quad e_r = 0, \\\\ /// 2^{e_r-2^{E-1}+1}(2^{-M}m_r+1) & \textrm{otherwise}, /// \\end{cases} /// $$ /// $$ /// e_r = \\begin{cases} /// 0 & \text{if} \quad x < 2^{2-2^{E-1}}, \\\\ /// \lfloor \log_2 x \rfloor + 2^{E-1} - 1 & \textrm{otherwise}, /// \\end{cases} /// $$ /// $$ /// m_r = \\begin{cases} /// 2^{M+2^{E-1}-2}x & \text{if} \quad x < 2^{2-2^{E-1}}, \\\\ /// 2^M \left ( \frac{x}{2^{\lfloor \log_2 x \rfloor}}-1\right ) & \textrm{otherwise}. /// \\end{cases} /// $$ /// /// # scientific form /// We can write $x = 2^{e_s}m_s$, where $e_s$ is an integer and $m_s$ is a rational number with $1 /// \leq m_s < 2$. If $x$ is a valid float, the scientific mantissa $m_s$ is always exactly /// representable as a float of the same type. We have /// $$ /// x = 2^{e_s}m_s, /// $$ /// $$ /// e_s = \lfloor \log_2 x \rfloor, /// $$ /// $$ /// m_s = \frac{x}{2^{\lfloor \log_2 x \rfloor}}. /// $$ /// /// # integer form /// We can also write $x = 2^{e_i}m_i$, where $e_i$ is an integer and $m_i$ is an odd integer. We /// have /// $$ /// x = 2^{e_i}m_i, /// $$ /// $e_i$ is the unique integer such that $x/2^{e_i}$is an odd integer, and /// $$ /// m_i = \frac{x}{2^{e_i}}. /// $$ pub trait PrimitiveFloat: 'static + Abs + AbsAssign + Add + AddAssign + AddMul + AddMulAssign + Ceiling + CeilingAssign + CeilingLogBase2 + CeilingLogBasePowerOf2 + CheckedLogBase2 + CheckedLogBasePowerOf2 + ConvertibleFrom + ConvertibleFrom + ConvertibleFrom + ConvertibleFrom + ConvertibleFrom + ConvertibleFrom + ConvertibleFrom + ConvertibleFrom + ConvertibleFrom + ConvertibleFrom + ConvertibleFrom + ConvertibleFrom + Copy + Debug + Default + Display + Div + DivAssign + Floor + FloorAssign + FloorLogBase2 + FloorLogBasePowerOf2 + FmtRyuString + From + FromStr + Infinity + IntegerMantissaAndExponent + Into + IsInteger + IsPowerOf2 + Ln + LowerExp + Min + Max + Mul + MulAssign + Named + NaN + NegativeInfinity + NegativeZero + Neg + NegAssign + NegativeOne + NextPowerOf2 + NextPowerOf2Assign + One + PartialEq + PartialOrd + PartialOrdAbs + Pow + Pow + PowAssign + PowAssign + PowerOf2 + PrimeConstant + Product + RawMantissaAndExponent + Reciprocal + ReciprocalAssign + RefUnwindSafe + Rem + RemAssign + RoundingFrom + RoundingFrom + RoundingFrom + RoundingFrom + RoundingFrom + RoundingFrom + RoundingFrom + RoundingFrom + RoundingFrom + RoundingFrom + RoundingFrom + RoundingFrom + RoundingInto + RoundingInto + RoundingInto + RoundingInto + RoundingInto + RoundingInto + RoundingInto + RoundingInto + RoundingInto + RoundingInto + RoundingInto + RoundingInto + SciMantissaAndExponent + Sign + Sized + Sqrt + SqrtAssign + Square + SquareAssign + Sub + SubAssign + SubMul + SubMulAssign + Sum + ThueMorseConstant + Two + UpperExp + Zero { /// The number of bits taken up by the type. /// /// This is $M+E+1$. The three terms in the sum correspond to the width of the mantissa, the /// width of the exponent, and the sign bit. /// - For [`f32`]s, this is 32. /// - For [`f64`]s, this is 64. const WIDTH: u64; /// The number of bits taken up by the exponent. /// - For [`f32`]s, this is 8. /// - For [`f64`]s, this is 11. const EXPONENT_WIDTH: u64 = Self::WIDTH - Self::MANTISSA_WIDTH - 1; /// The number of bits taken up by the mantissa. /// - For [`f32`]s, this is 23. /// - For [`f64`]s, this is 52. const MANTISSA_WIDTH: u64; /// The smallest possible exponent of a float in the normal range. Any floats with smaller /// exponents are subnormal and thus have reduced precision. This is $2-2^{E-1}$. /// - For [`f32`]s, this is -126. /// - For [`f64`]s, this is -1022. const MIN_NORMAL_EXPONENT: i64 = -(1 << (Self::EXPONENT_WIDTH - 1)) + 2; /// The smallest possible exponent of a float. This is $2-2^{E-1}-M$. /// - For [`f32`]s, this is -149. /// - For [`f64`]s, this is -1074. const MIN_EXPONENT: i64 = Self::MIN_NORMAL_EXPONENT - (Self::MANTISSA_WIDTH as i64); /// The largest possible exponent of a float. This is $2^{E-1}-1$. /// - For [`f32`]s, this is 127. /// - For [`f64`]s, this is 1023. const MAX_EXPONENT: i64 = (1 << (Self::EXPONENT_WIDTH - 1)) - 1; /// The smallest positive float. This is $2^{2-2^{E-1}-M}$. /// - For [`f32`]s, this is $2^{-149}$, or `1.0e-45`. /// - For [`f64`]s, this is $2^{-1074}$, or `5.0e-324`. const MIN_POSITIVE_SUBNORMAL: Self; /// The largest float in the subnormal range. This is $2^{2-2^{E-1}-M}(2^M-1)$. /// - For [`f32`]s, this is $2^{-149}(2^{23}-1)$, or `1.1754942e-38`. /// - For [`f64`]s, this is $2^{-1074}(2^{52}-1)$, or `2.225073858507201e-308`. const MAX_SUBNORMAL: Self; /// The smallest positive normal float. This is $2^{2-2^{E-1}}$. /// - For [`f32`]s, this is $2^{-126}$, or `1.1754944e-38`. /// - For [`f64`]s, this is $2^{-1022}$, or `2.2250738585072014e-308`. const MIN_POSITIVE_NORMAL: Self; /// The largest finite float. This is $2^{2^{E-1}-1}(2-2^{-M})$. /// - For [`f32`]s, this is $2^{127}(2-2^{-23})$, or `3.4028235e38`. /// - For [`f64`]s, this is $2^{1023}(2-2^{-52})$, or `1.7976931348623157e308`. const MAX_FINITE: Self; /// The smallest positive integer that cannot be represented as a float. This is $2^{M+1}+1$. /// - For [`f32`]s, this is $2^{24}+1$, or 16777217. /// - For [`f64`]s, this is $2^{53}+1$, or 9007199254740993. const SMALLEST_UNREPRESENTABLE_UINT: u64; /// If you list all floats in increasing order, excluding NaN and giving negative and positive /// zero separate adjacent spots, this will be index of the last element, positive infinity. It /// is $2^{M+1}(2^E-1)+1$. /// - For [`f32`]s, this is $2^{32}-2^{24}+1$, or 4278190081. /// - For [`f64`]s, this is $2^{64}-2^{53}+1$, or 18437736874454810625. const LARGEST_ORDERED_REPRESENTATION: u64; fn is_nan(self) -> bool; fn is_infinite(self) -> bool; fn is_finite(self) -> bool; fn is_normal(self) -> bool; fn is_sign_positive(self) -> bool; fn is_sign_negative(self) -> bool; fn classify(self) -> FpCategory; fn to_bits(self) -> u64; fn from_bits(v: u64) -> Self; /// Tests whether `self` is negative zero. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::num::basic::floats::PrimitiveFloat; /// /// assert!((-0.0).is_negative_zero()); /// assert!(!0.0.is_negative_zero()); /// assert!(!1.0.is_negative_zero()); /// assert!(!f32::NAN.is_negative_zero()); /// assert!(!f32::INFINITY.is_negative_zero()); /// ``` #[inline] fn is_negative_zero(self) -> bool { self.sign() == Less && self == Self::ZERO } /// If `self` is negative zero, returns positive zero; otherwise, returns `self`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::num::basic::floats::PrimitiveFloat; /// use malachite_base::num::float::NiceFloat; /// /// assert_eq!(NiceFloat((-0.0).abs_negative_zero()), NiceFloat(0.0)); /// assert_eq!(NiceFloat(0.0.abs_negative_zero()), NiceFloat(0.0)); /// assert_eq!(NiceFloat(1.0.abs_negative_zero()), NiceFloat(1.0)); /// assert_eq!(NiceFloat((-1.0).abs_negative_zero()), NiceFloat(-1.0)); /// assert_eq!(NiceFloat(f32::NAN.abs_negative_zero()), NiceFloat(f32::NAN)); /// ``` #[inline] fn abs_negative_zero(self) -> Self { if self == Self::ZERO { Self::ZERO } else { self } } /// If `self` is negative zero, replaces it with positive zero; otherwise, leaves `self` /// unchanged. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::num::basic::floats::PrimitiveFloat; /// use malachite_base::num::float::NiceFloat; /// /// let mut f = -0.0; /// f.abs_negative_zero_assign(); /// assert_eq!(NiceFloat(f), NiceFloat(0.0)); /// /// let mut f = 0.0; /// f.abs_negative_zero_assign(); /// assert_eq!(NiceFloat(f), NiceFloat(0.0)); /// /// let mut f = 1.0; /// f.abs_negative_zero_assign(); /// assert_eq!(NiceFloat(f), NiceFloat(1.0)); /// /// let mut f = -1.0; /// f.abs_negative_zero_assign(); /// assert_eq!(NiceFloat(f), NiceFloat(-1.0)); /// /// let mut f = f32::NAN; /// f.abs_negative_zero_assign(); /// assert_eq!(NiceFloat(f), NiceFloat(f32::NAN)); /// ``` #[inline] fn abs_negative_zero_assign(&mut self) { if *self == Self::ZERO { *self = Self::ZERO; } } /// Returns the smallest float larger than `self`. /// /// Passing `-0.0` returns `0.0`; passing `NaN` or positive infinity panics. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` is `NaN` or positive infinity. /// /// # Examples /// ``` /// use malachite_base::num::basic::floats::PrimitiveFloat; /// use malachite_base::num::float::NiceFloat; /// /// assert_eq!(NiceFloat((-0.0f32).next_higher()), NiceFloat(0.0)); /// assert_eq!(NiceFloat(0.0f32.next_higher()), NiceFloat(1.0e-45)); /// assert_eq!(NiceFloat(1.0f32.next_higher()), NiceFloat(1.0000001)); /// assert_eq!(NiceFloat((-1.0f32).next_higher()), NiceFloat(-0.99999994)); /// ``` fn next_higher(self) -> Self { assert!(!self.is_nan()); if self.sign() == Greater { assert_ne!(self, Self::INFINITY); Self::from_bits(self.to_bits() + 1) } else if self == Self::ZERO { // negative zero -> positive zero Self::ZERO } else { Self::from_bits(self.to_bits() - 1) } } /// Returns the largest float smaller than `self`. /// /// Passing `0.0` returns `-0.0`; passing `NaN` or negative infinity panics. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` is `NaN` or negative infinity. /// /// # Examples /// ``` /// use malachite_base::num::basic::floats::PrimitiveFloat; /// use malachite_base::num::float::NiceFloat; /// /// assert_eq!(NiceFloat(0.0f32.next_lower()), NiceFloat(-0.0)); /// assert_eq!(NiceFloat((-0.0f32).next_lower()), NiceFloat(-1.0e-45)); /// assert_eq!(NiceFloat(1.0f32.next_lower()), NiceFloat(0.99999994)); /// assert_eq!(NiceFloat((-1.0f32).next_lower()), NiceFloat(-1.0000001)); /// ``` fn next_lower(self) -> Self { assert!(!self.is_nan()); if self.sign() == Less { assert_ne!(self, Self::NEGATIVE_INFINITY); Self::from_bits(self.to_bits() + 1) } else if self == Self::ZERO { // positive zero -> negative zero Self::NEGATIVE_ZERO } else { Self::from_bits(self.to_bits() - 1) } } /// Maps `self` to an integer. The map preserves ordering, and adjacent floats are mapped to /// adjacent integers. /// /// Negative infinity is mapped to 0, and positive infinity is mapped to the largest value, /// [`LARGEST_ORDERED_REPRESENTATION`](PrimitiveFloat::LARGEST_ORDERED_REPRESENTATION). Negative /// and positive zero are mapped to distinct adjacent values. Passing in `NaN` panics. /// /// The inverse operation is /// [`from_ordered_representation`](PrimitiveFloat::from_ordered_representation). /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` is `NaN`. /// /// # Examples /// ``` /// use malachite_base::num::basic::floats::PrimitiveFloat; /// use malachite_base::num::basic::traits::NegativeInfinity; /// /// assert_eq!(f32::NEGATIVE_INFINITY.to_ordered_representation(), 0); /// assert_eq!((-0.0f32).to_ordered_representation(), 2139095040); /// assert_eq!(0.0f32.to_ordered_representation(), 2139095041); /// assert_eq!(1.0f32.to_ordered_representation(), 3204448257); /// assert_eq!(f32::INFINITY.to_ordered_representation(), 4278190081); /// ``` fn to_ordered_representation(self) -> u64 { assert!(!self.is_nan()); let bits = self.to_bits(); if self.sign() == Greater { (u64::low_mask(Self::EXPONENT_WIDTH) << Self::MANTISSA_WIDTH) + bits + 1 } else { (u64::low_mask(Self::EXPONENT_WIDTH + 1) << Self::MANTISSA_WIDTH) - bits } } /// Maps a non-negative integer, less than or equal to /// [`LARGEST_ORDERED_REPRESENTATION`](PrimitiveFloat::LARGEST_ORDERED_REPRESENTATION), to a /// float. The map preserves ordering, and adjacent integers are mapped to adjacent floats. /// /// Zero is mapped to negative infinity, and /// [`LARGEST_ORDERED_REPRESENTATION`](PrimitiveFloat::LARGEST_ORDERED_REPRESENTATION) is mapped /// to positive infinity. Negative and positive zero are produced by two distinct adjacent /// integers. `NaN` is never produced. /// /// The inverse operation is /// [`to_ordered_representation`](PrimitiveFloat::to_ordered_representation). /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` is greater than /// [`LARGEST_ORDERED_REPRESENTATION`](PrimitiveFloat::LARGEST_ORDERED_REPRESENTATION). /// /// # Examples /// ``` /// use malachite_base::num::basic::floats::PrimitiveFloat; /// use malachite_base::num::basic::traits::NegativeInfinity; /// /// assert_eq!(f32::from_ordered_representation(0), f32::NEGATIVE_INFINITY); /// assert_eq!(f32::from_ordered_representation(2139095040), -0.0f32); /// assert_eq!(f32::from_ordered_representation(2139095041), 0.0f32); /// assert_eq!(f32::from_ordered_representation(3204448257), 1.0f32); /// assert_eq!(f32::from_ordered_representation(4278190081), f32::INFINITY); /// ``` fn from_ordered_representation(n: u64) -> Self { let zero_exp = u64::low_mask(Self::EXPONENT_WIDTH) << Self::MANTISSA_WIDTH; let f = if n <= zero_exp { Self::from_bits((u64::low_mask(Self::EXPONENT_WIDTH + 1) << Self::MANTISSA_WIDTH) - n) } else { let f = Self::from_bits(n - zero_exp - 1); assert_eq!(f.sign(), Greater); f }; assert!(!f.is_nan()); f } /// Returns the precision of a nonzero finite floating-point number. /// /// The precision is the number of significant bits of the integer mantissa. For example, the /// floats with precision 1 are the powers of 2, those with precision 2 are 3 times a power of /// 2, those with precision 3 are 5 or 7 times a power of 2, and so on. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` is zero, infinite, or `NaN`. /// /// # Examples /// ``` /// use malachite_base::num::basic::floats::PrimitiveFloat; /// /// assert_eq!(1.0.precision(), 1); /// assert_eq!(2.0.precision(), 1); /// assert_eq!(3.0.precision(), 2); /// assert_eq!(1.5.precision(), 2); /// assert_eq!(1.234f32.precision(), 23); /// ``` fn precision(self) -> u64 { assert!(self.is_finite()); assert!(self != Self::ZERO); let (mut mantissa, exponent) = self.raw_mantissa_and_exponent(); if exponent == 0 { mantissa.significant_bits() - TrailingZeros::trailing_zeros(mantissa) } else { mantissa.set_bit(Self::MANTISSA_WIDTH); Self::MANTISSA_WIDTH + 1 - TrailingZeros::trailing_zeros(mantissa) } } /// Given a scientific exponent, returns the largest possible precision for a float with that /// exponent. /// /// See the documentation of the [`precision`](PrimitiveFloat::precision) function for a /// definition of precision. /// /// For exponents greater than or equal to /// [`MIN_NORMAL_EXPONENT`](PrimitiveFloat::MIN_NORMAL_EXPONENT), the maximum precision is one /// more than the mantissa width. For smaller exponents (corresponding to the subnormal range), /// the precision is lower. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `exponent` is less than [`MIN_EXPONENT`](PrimitiveFloat::MIN_EXPONENT) or greater /// than [`MAX_EXPONENT`](PrimitiveFloat::MAX_EXPONENT). /// /// # Examples /// ``` /// use malachite_base::num::basic::floats::PrimitiveFloat; /// /// assert_eq!(f32::max_precision_for_sci_exponent(0), 24); /// assert_eq!(f32::max_precision_for_sci_exponent(127), 24); /// assert_eq!(f32::max_precision_for_sci_exponent(-149), 1); /// assert_eq!(f32::max_precision_for_sci_exponent(-148), 2); /// assert_eq!(f32::max_precision_for_sci_exponent(-147), 3); /// ``` fn max_precision_for_sci_exponent(exponent: i64) -> u64 { assert!(exponent >= Self::MIN_EXPONENT); assert!(exponent <= Self::MAX_EXPONENT); if exponent >= Self::MIN_NORMAL_EXPONENT { Self::MANTISSA_WIDTH + 1 } else { u64::wrapping_from(exponent - Self::MIN_EXPONENT) + 1 } } } /// Defines basic trait implementations for floating-point types. macro_rules! impl_basic_traits_primitive_float { ( $t: ident, $width: expr, $min_positive_subnormal: expr, $max_subnormal: expr, $min_positive_normal: expr, $thue_morse_constant: expr, $prime_constant: expr ) => { impl PrimitiveFloat for $t { const WIDTH: u64 = $width; const MANTISSA_WIDTH: u64 = ($t::MANTISSA_DIGITS as u64) - 1; const MAX_FINITE: Self = $t::MAX; const MIN_POSITIVE_SUBNORMAL: Self = $min_positive_subnormal; const MAX_SUBNORMAL: Self = $max_subnormal; const MIN_POSITIVE_NORMAL: Self = $min_positive_normal; const SMALLEST_UNREPRESENTABLE_UINT: u64 = (1 << (Self::MANTISSA_WIDTH + 1)) + 1; // We can't shift by $width when $width is 64, so we shift by $width - 1 and then by 1 const LARGEST_ORDERED_REPRESENTATION: u64 = (1u64 << ($width - 1) << 1) .wrapping_sub(((1 << Self::MANTISSA_WIDTH) - 1) << 1) - 1; #[inline] fn is_nan(self) -> bool { $t::is_nan(self) } #[inline] fn is_infinite(self) -> bool { $t::is_infinite(self) } #[inline] fn is_finite(self) -> bool { $t::is_finite(self) } #[inline] fn is_normal(self) -> bool { $t::is_normal(self) } #[inline] fn is_sign_positive(self) -> bool { $t::is_sign_positive(self) } #[inline] fn is_sign_negative(self) -> bool { $t::is_sign_negative(self) } #[inline] fn classify(self) -> FpCategory { $t::classify(self) } #[inline] fn to_bits(self) -> u64 { u64::wrapping_from($t::to_bits(self)) } #[inline] fn from_bits(v: u64) -> $t { $t::from_bits(v.exact_into()) } } impl_named!($t); /// The constant 0. impl Zero for $t { const ZERO: $t = 0.0; } /// The constant 1. impl One for $t { const ONE: $t = 1.0; } /// The constant 2. impl Two for $t { const TWO: $t = 2.0; } /// The constant 1/2. impl OneHalf for $t { const ONE_HALF: $t = 0.5; } /// The constant -1.0 for primitive floating-point types. impl NegativeOne for $t { const NEGATIVE_ONE: $t = -1.0; } /// The constant -0.0 for primitive floating-point types. impl NegativeZero for $t { const NEGATIVE_ZERO: $t = -0.0; } /// The constant Infinity for primitive floating-point types. impl Infinity for $t { const INFINITY: $t = $t::INFINITY; } /// The constant -Infinity for primitive floating-point types. impl NegativeInfinity for $t { const NEGATIVE_INFINITY: $t = $t::NEG_INFINITY; } /// The constant NaN for primitive floating-point types. impl NaN for $t { const NAN: $t = $t::NAN; } /// The lowest value representable by this type, negative infinity. impl Min for $t { const MIN: $t = $t::NEGATIVE_INFINITY; } /// The highest value representable by this type, positive infinity. impl Max for $t { const MAX: $t = $t::INFINITY; } /// The Thue-Morse constant. impl ThueMorseConstant for $t { const THUE_MORSE_CONSTANT: $t = $thue_morse_constant; } /// The prime constant. impl PrimeConstant for $t { const PRIME_CONSTANT: $t = $prime_constant; } }; } impl_basic_traits_primitive_float!( f32, 32, 1.0e-45, 1.1754942e-38, 1.1754944e-38, 0.41245404, 0.4146825 ); impl_basic_traits_primitive_float!( f64, 64, 5.0e-324, 2.225073858507201e-308, 2.2250738585072014e-308, 0.4124540336401076, 0.41468250985111166 ); malachite-base-0.4.16/src/num/basic/integers.rs000064400000000000000000001013271046102023000174140ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::comparison::traits::{Max, Min}; use crate::named::Named; use crate::num::arithmetic::traits::{ AbsDiff, AddMul, AddMulAssign, ArithmeticCheckedShl, ArithmeticCheckedShr, BinomialCoefficient, CeilingRoot, CeilingRootAssign, CeilingSqrt, CeilingSqrtAssign, CheckedAdd, CheckedAddMul, CheckedBinomialCoefficient, CheckedDiv, CheckedMul, CheckedNeg, CheckedPow, CheckedRoot, CheckedSqrt, CheckedSquare, CheckedSub, CheckedSubMul, DivAssignMod, DivAssignRem, DivExact, DivExactAssign, DivMod, DivRem, DivRound, DivRoundAssign, DivisibleBy, DivisibleByPowerOf2, EqMod, EqModPowerOf2, ExtendedGcd, FloorRoot, FloorRootAssign, FloorSqrt, FloorSqrtAssign, JacobiSymbol, KroneckerSymbol, LegendreSymbol, Mod, ModAssign, ModPowerOf2, ModPowerOf2Assign, OverflowingAdd, OverflowingAddAssign, OverflowingAddMul, OverflowingAddMulAssign, OverflowingDiv, OverflowingDivAssign, OverflowingMul, OverflowingMulAssign, OverflowingNeg, OverflowingNegAssign, OverflowingPow, OverflowingPowAssign, OverflowingSquare, OverflowingSquareAssign, OverflowingSub, OverflowingSubAssign, OverflowingSubMul, OverflowingSubMulAssign, Parity, Pow, PowAssign, PowerOf2, RemPowerOf2, RemPowerOf2Assign, RotateLeft, RotateLeftAssign, RotateRight, RotateRightAssign, RoundToMultiple, RoundToMultipleAssign, RoundToMultipleOfPowerOf2, RoundToMultipleOfPowerOf2Assign, SaturatingAdd, SaturatingAddAssign, SaturatingAddMul, SaturatingAddMulAssign, SaturatingMul, SaturatingMulAssign, SaturatingPow, SaturatingPowAssign, SaturatingSquare, SaturatingSquareAssign, SaturatingSub, SaturatingSubAssign, SaturatingSubMul, SaturatingSubMulAssign, ShlRound, ShlRoundAssign, ShrRound, ShrRoundAssign, Sign, Square, SquareAssign, SubMul, SubMulAssign, WrappingAdd, WrappingAddAssign, WrappingAddMul, WrappingAddMulAssign, WrappingDiv, WrappingDivAssign, WrappingMul, WrappingMulAssign, WrappingNeg, WrappingNegAssign, WrappingPow, WrappingPowAssign, WrappingSquare, WrappingSquareAssign, WrappingSub, WrappingSubAssign, WrappingSubMul, WrappingSubMulAssign, }; use crate::num::basic::traits::{One, Two, Zero}; use crate::num::comparison::traits::{EqAbs, OrdAbs, PartialOrdAbs}; use crate::num::conversion::traits::{ ConvertibleFrom, ExactFrom, ExactInto, FromSciString, FromStringBase, IsInteger, OverflowingFrom, OverflowingInto, RoundingFrom, RoundingInto, SaturatingFrom, SaturatingInto, ToSci, ToStringBase, WrappingFrom, WrappingInto, }; use crate::num::float::NiceFloat; use crate::num::logic::traits::{ BitAccess, BitBlockAccess, BitConvertible, BitIterable, BitScan, CountOnes, CountZeros, LeadingZeros, LowMask, NotAssign, SignificantBits, TrailingZeros, }; #[cfg(feature = "random")] use crate::num::random::HasRandomPrimitiveInts; use core::fmt::{Binary, Debug, Display, LowerHex, Octal, UpperHex}; use core::hash::Hash; use core::iter::{Product, Sum}; use core::ops::{ Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign, Mul, MulAssign, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign, }; use core::panic::{RefUnwindSafe, UnwindSafe}; use core::str::FromStr; // When the `random` feature is enabled, the HasRandomPrimitiveInts bound is included. #[cfg(feature = "random")] /// Defines functions on primitive integer types: uxx, ixx, usize, and isize. /// /// The different types are distinguished by whether they are signed or unsigned, and by their /// widths. The width $W$ is the number of bits in the type. For example, the width of [`u32`] or /// [`i32`] is 32. Each type has $2^W$ distinct values. /// /// Let $n$ be a value of type `Self`. If `Self` is unsigned, $0 \leq n < 2^W$. If `Self` is signed, /// $2^{W-1} \leq n < 2^{W-1}$. pub trait PrimitiveInt: 'static + AbsDiff + Add + AddAssign + AddMul + AddMulAssign + ArithmeticCheckedShl + ArithmeticCheckedShl + ArithmeticCheckedShl + ArithmeticCheckedShl + ArithmeticCheckedShl + ArithmeticCheckedShl + ArithmeticCheckedShl + ArithmeticCheckedShl + ArithmeticCheckedShl + ArithmeticCheckedShl + ArithmeticCheckedShl + ArithmeticCheckedShl + ArithmeticCheckedShr + ArithmeticCheckedShr + ArithmeticCheckedShr + ArithmeticCheckedShr + ArithmeticCheckedShr + ArithmeticCheckedShr + Binary + BinomialCoefficient + BitAccess + BitAnd + BitAndAssign + BitBlockAccess + BitConvertible + BitIterable + BitOr + BitOrAssign + BitScan + BitXor + BitXorAssign + CeilingRoot + CeilingRootAssign + CeilingSqrt + CeilingSqrtAssign + CheckedAdd + CheckedAddMul + CheckedBinomialCoefficient + CheckedDiv + CheckedMul + CheckedNeg + CheckedPow + CheckedRoot + CheckedSqrt + CheckedSquare + CheckedSub + CheckedSubMul + Clone + ConvertibleFrom + ConvertibleFrom + ConvertibleFrom + ConvertibleFrom + ConvertibleFrom + ConvertibleFrom + ConvertibleFrom + ConvertibleFrom + ConvertibleFrom + ConvertibleFrom + ConvertibleFrom + ConvertibleFrom + ConvertibleFrom + ConvertibleFrom + Copy + CountOnes + CountZeros + Debug + Default + Display + Div + DivAssign + DivAssignMod + DivAssignRem + DivExact + DivExactAssign + DivMod + DivRem + DivRound + DivRoundAssign + DivisibleBy + DivisibleByPowerOf2 + Eq + EqAbs + EqMod + EqModPowerOf2 + ExactFrom + ExactFrom + ExactFrom + ExactFrom + ExactFrom + ExactFrom + ExactFrom + ExactFrom + ExactFrom + ExactFrom + ExactFrom + ExactFrom + ExactInto + ExactInto + ExactInto + ExactInto + ExactInto + ExactInto + ExactInto + ExactInto + ExactInto + ExactInto + ExactInto + ExactInto + ExtendedGcd + FloorRoot + FloorRootAssign + FloorSqrt + FloorSqrtAssign + From + FromSciString + FromStr + FromStringBase + HasRandomPrimitiveInts + Hash + IsInteger + JacobiSymbol + KroneckerSymbol + LeadingZeros + LegendreSymbol + LowMask + LowerHex + Max + Min + Mod + ModAssign + ModPowerOf2 + ModPowerOf2Assign + Mul + MulAssign + Named + Not + NotAssign + Octal + One + Ord + OrdAbs + OverflowingAdd + OverflowingAddAssign + OverflowingAddMul + OverflowingAddMulAssign + OverflowingDiv + OverflowingDivAssign + OverflowingFrom + OverflowingFrom + OverflowingFrom + OverflowingFrom + OverflowingFrom + OverflowingFrom + OverflowingFrom + OverflowingFrom + OverflowingFrom + OverflowingFrom + OverflowingFrom + OverflowingFrom + OverflowingInto + OverflowingInto + OverflowingInto + OverflowingInto + OverflowingInto + OverflowingInto + OverflowingInto + OverflowingInto + OverflowingInto + OverflowingInto + OverflowingInto + OverflowingInto + OverflowingMul + OverflowingMulAssign + OverflowingNeg + OverflowingNegAssign + OverflowingPow + OverflowingPowAssign + OverflowingSquare + OverflowingSquareAssign + OverflowingSub + OverflowingSubAssign + OverflowingSubMul + OverflowingSubMulAssign + Parity + PartialEq + PartialOrd + PartialOrdAbs + Pow + PowAssign + PowerOf2 + Product + RefUnwindSafe + Rem + RemAssign + RemPowerOf2 + RemPowerOf2Assign + RotateLeft + RotateLeftAssign + RotateRight + RotateRightAssign + RoundToMultiple + RoundToMultipleAssign + RoundToMultipleOfPowerOf2 + RoundToMultipleOfPowerOf2Assign + RoundingFrom + RoundingFrom + RoundingInto + RoundingInto + SaturatingAdd + SaturatingAddAssign + SaturatingAddMul + SaturatingAddMulAssign + SaturatingFrom + SaturatingFrom + SaturatingFrom + SaturatingFrom + SaturatingFrom + SaturatingFrom + SaturatingFrom + SaturatingFrom + SaturatingFrom + SaturatingFrom + SaturatingFrom + SaturatingFrom + SaturatingInto + SaturatingInto + SaturatingInto + SaturatingInto + SaturatingInto + SaturatingInto + SaturatingInto + SaturatingInto + SaturatingInto + SaturatingInto + SaturatingInto + SaturatingInto + SaturatingMul + SaturatingMulAssign + SaturatingPow + SaturatingPowAssign + SaturatingSquare + SaturatingSquareAssign + SaturatingSub + SaturatingSubAssign + SaturatingSubMul + SaturatingSubMulAssign + Shl + Shl + Shl + Shl + Shl + Shl + Shl + Shl + Shl + Shl + ShlAssign + ShlAssign + ShlAssign + ShlAssign + ShlAssign + ShlAssign + ShlAssign + ShlAssign + ShlAssign + ShlAssign + ShlAssign + ShlAssign + ShlRound + ShlRound + ShlRound + ShlRound + ShlRound + ShlRound + ShlRoundAssign + ShlRoundAssign + ShlRoundAssign + ShlRoundAssign + ShlRoundAssign + ShlRoundAssign + Shr + Shr + Shr + Shr + Shr + Shr + Shr + Shr + Shr + Shr + Shr + Shr + ShrAssign + ShrAssign + ShrAssign + ShrAssign + ShrAssign + ShrAssign + ShrAssign + ShrAssign + ShrAssign + ShrAssign + ShrAssign + ShrAssign + ShrRound + ShrRound + ShrRound + ShrRound + ShrRound + ShrRound + ShrRound + ShrRound + ShrRound + ShrRound + ShrRound + ShrRound + ShrRoundAssign + ShrRoundAssign + ShrRoundAssign + ShrRoundAssign + ShrRoundAssign + ShrRoundAssign + ShrRoundAssign + ShrRoundAssign + ShrRoundAssign + ShrRoundAssign + ShrRoundAssign + ShrRoundAssign + Sign + SignificantBits + Sized + Square + SquareAssign + Sub + SubAssign + SubMul + SubMulAssign + Sum + ToSci + ToStringBase + TrailingZeros + TryFrom> + TryFrom + TryFrom + TryFrom + TryFrom + TryFrom + TryFrom + TryFrom + TryFrom + TryFrom + TryFrom + TryFrom + TryFrom + TryInto> + TryInto + TryInto + TryInto + TryInto + TryInto + TryInto + TryInto + TryInto + TryInto + TryInto + TryInto + TryInto + Two + UnwindSafe + UpperHex + WrappingAdd + WrappingAddAssign + WrappingAddMul + WrappingAddMulAssign + WrappingDiv + WrappingDivAssign + WrappingFrom + WrappingFrom + WrappingFrom + WrappingFrom + WrappingFrom + WrappingFrom + WrappingFrom + WrappingFrom + WrappingFrom + WrappingFrom + WrappingFrom + WrappingFrom + WrappingInto + WrappingInto + WrappingInto + WrappingInto + WrappingInto + WrappingInto + WrappingInto + WrappingInto + WrappingInto + WrappingInto + WrappingInto + WrappingInto + WrappingMul + WrappingMulAssign + WrappingNeg + WrappingNegAssign + WrappingPow + WrappingPowAssign + WrappingSquare + WrappingSquareAssign + WrappingSub + WrappingSubAssign + WrappingSubMul + WrappingSubMulAssign + Zero { /// The number of bits of `Self`. const WIDTH: u64; /// The base-2 logarithm of the number of bits of `Self`. /// /// Whenever you need to use `n / WIDTH`, you can use `n >> LOG_WIDTH` instead. /// /// This is $\log_2 W$. /// /// Note that this value is correct for all of the built-in primitive integer types, but it will /// not be correct for custom types whose $W$ is not a power of 2. For such implementations, /// `LOG_WIDTH` should not be used. const LOG_WIDTH: u64 = Self::WIDTH.trailing_zeros() as u64; /// A mask that consists of `LOG_WIDTH` bits. /// /// Whenever you need to use `n % WIDTH`, you can use `n & WIDTH_MASK` instead. /// /// This is $W - 1$. /// /// Note that this value is correct for all of the built-in primitive integer types, but it will /// not be correct for custom types whose $W$ is not a power of 2. For such implementations, /// `WIDTH_MASK` should not be used. const WIDTH_MASK: u64 = Self::WIDTH - 1; /// Gets the most-significant bit of `Self`. For signed integers, this is the sign bit. /// /// If `Self` is unsigned, $f(n) = (n \geq 2^{W-1})$. If `Self` is unsigned, $f(n) = (n < 0)$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::num::basic::integers::PrimitiveInt; /// /// assert_eq!(123u32.get_highest_bit(), false); /// assert_eq!(4000000000u32.get_highest_bit(), true); /// assert_eq!(2000000000i32.get_highest_bit(), false); /// assert_eq!((-2000000000i32).get_highest_bit(), true); /// ``` #[inline] fn get_highest_bit(&self) -> bool { self.get_bit(Self::WIDTH - 1) } } #[cfg(not(feature = "random"))] /// Defines functions on primitive integer types: uxx, ixx, usize, and isize. /// /// The different types are distinguished by whether they are signed or unsigned, and by their /// widths. The width $W$ is the number of bits in the type. For example, the width of [`u32`] or /// [`i32`] is 32. Each type has $2^W$ distinct values. /// /// Let $n$ be a value of type `Self`. If `Self` is unsigned, $0 \leq n < 2^W$. If `Self` is signed, /// $2^{W-1} \leq n < 2^{W-1}$. pub trait PrimitiveInt: 'static + AbsDiff + Add + AddAssign + AddMul + AddMulAssign + ArithmeticCheckedShl + ArithmeticCheckedShl + ArithmeticCheckedShl + ArithmeticCheckedShl + ArithmeticCheckedShl + ArithmeticCheckedShl + ArithmeticCheckedShl + ArithmeticCheckedShl + ArithmeticCheckedShl + ArithmeticCheckedShl + ArithmeticCheckedShl + ArithmeticCheckedShl + ArithmeticCheckedShr + ArithmeticCheckedShr + ArithmeticCheckedShr + ArithmeticCheckedShr + ArithmeticCheckedShr + ArithmeticCheckedShr + Binary + BinomialCoefficient + BitAccess + BitAnd + BitAndAssign + BitBlockAccess + BitConvertible + BitIterable + BitOr + BitOrAssign + BitScan + BitXor + BitXorAssign + CeilingRoot + CeilingRootAssign + CeilingSqrt + CeilingSqrtAssign + CheckedAdd + CheckedAddMul + CheckedBinomialCoefficient + CheckedDiv + CheckedMul + CheckedNeg + CheckedPow + CheckedRoot + CheckedSqrt + CheckedSquare + CheckedSub + CheckedSubMul + Clone + ConvertibleFrom + ConvertibleFrom + ConvertibleFrom + ConvertibleFrom + ConvertibleFrom + ConvertibleFrom + ConvertibleFrom + ConvertibleFrom + ConvertibleFrom + ConvertibleFrom + ConvertibleFrom + ConvertibleFrom + ConvertibleFrom + ConvertibleFrom + Copy + CountOnes + CountZeros + Debug + Default + Display + Div + DivAssign + DivAssignMod + DivAssignRem + DivExact + DivExactAssign + DivMod + DivRem + DivRound + DivRoundAssign + DivisibleBy + DivisibleByPowerOf2 + Eq + EqAbs + EqMod + EqModPowerOf2 + ExactFrom + ExactFrom + ExactFrom + ExactFrom + ExactFrom + ExactFrom + ExactFrom + ExactFrom + ExactFrom + ExactFrom + ExactFrom + ExactFrom + ExactInto + ExactInto + ExactInto + ExactInto + ExactInto + ExactInto + ExactInto + ExactInto + ExactInto + ExactInto + ExactInto + ExactInto + ExtendedGcd + FloorRoot + FloorRootAssign + FloorSqrt + FloorSqrtAssign + From + FromSciString + FromStr + FromStringBase + Hash + IsInteger + JacobiSymbol + KroneckerSymbol + LeadingZeros + LegendreSymbol + LowMask + LowerHex + Max + Min + Mod + ModAssign + ModPowerOf2 + ModPowerOf2Assign + Mul + MulAssign + Named + Not + NotAssign + Octal + One + Ord + OrdAbs + OverflowingAdd + OverflowingAddAssign + OverflowingAddMul + OverflowingAddMulAssign + OverflowingDiv + OverflowingDivAssign + OverflowingFrom + OverflowingFrom + OverflowingFrom + OverflowingFrom + OverflowingFrom + OverflowingFrom + OverflowingFrom + OverflowingFrom + OverflowingFrom + OverflowingFrom + OverflowingFrom + OverflowingFrom + OverflowingInto + OverflowingInto + OverflowingInto + OverflowingInto + OverflowingInto + OverflowingInto + OverflowingInto + OverflowingInto + OverflowingInto + OverflowingInto + OverflowingInto + OverflowingInto + OverflowingMul + OverflowingMulAssign + OverflowingNeg + OverflowingNegAssign + OverflowingPow + OverflowingPowAssign + OverflowingSquare + OverflowingSquareAssign + OverflowingSub + OverflowingSubAssign + OverflowingSubMul + OverflowingSubMulAssign + Parity + PartialEq + PartialOrd + PartialOrdAbs + Pow + PowAssign + PowerOf2 + Product + RefUnwindSafe + Rem + RemAssign + RemPowerOf2 + RemPowerOf2Assign + RotateLeft + RotateLeftAssign + RotateRight + RotateRightAssign + RoundToMultiple + RoundToMultipleAssign + RoundToMultipleOfPowerOf2 + RoundToMultipleOfPowerOf2Assign + RoundingFrom + RoundingFrom + RoundingInto + RoundingInto + SaturatingAdd + SaturatingAddAssign + SaturatingAddMul + SaturatingAddMulAssign + SaturatingFrom + SaturatingFrom + SaturatingFrom + SaturatingFrom + SaturatingFrom + SaturatingFrom + SaturatingFrom + SaturatingFrom + SaturatingFrom + SaturatingFrom + SaturatingFrom + SaturatingFrom + SaturatingInto + SaturatingInto + SaturatingInto + SaturatingInto + SaturatingInto + SaturatingInto + SaturatingInto + SaturatingInto + SaturatingInto + SaturatingInto + SaturatingInto + SaturatingInto + SaturatingMul + SaturatingMulAssign + SaturatingPow + SaturatingPowAssign + SaturatingSquare + SaturatingSquareAssign + SaturatingSub + SaturatingSubAssign + SaturatingSubMul + SaturatingSubMulAssign + Shl + Shl + Shl + Shl + Shl + Shl + Shl + Shl + Shl + Shl + ShlAssign + ShlAssign + ShlAssign + ShlAssign + ShlAssign + ShlAssign + ShlAssign + ShlAssign + ShlAssign + ShlAssign + ShlAssign + ShlAssign + ShlRound + ShlRound + ShlRound + ShlRound + ShlRound + ShlRound + ShlRoundAssign + ShlRoundAssign + ShlRoundAssign + ShlRoundAssign + ShlRoundAssign + ShlRoundAssign + Shr + Shr + Shr + Shr + Shr + Shr + Shr + Shr + Shr + Shr + Shr + Shr + ShrAssign + ShrAssign + ShrAssign + ShrAssign + ShrAssign + ShrAssign + ShrAssign + ShrAssign + ShrAssign + ShrAssign + ShrAssign + ShrAssign + ShrRound + ShrRound + ShrRound + ShrRound + ShrRound + ShrRound + ShrRound + ShrRound + ShrRound + ShrRound + ShrRound + ShrRound + ShrRoundAssign + ShrRoundAssign + ShrRoundAssign + ShrRoundAssign + ShrRoundAssign + ShrRoundAssign + ShrRoundAssign + ShrRoundAssign + ShrRoundAssign + ShrRoundAssign + ShrRoundAssign + ShrRoundAssign + Sign + SignificantBits + Sized + Square + SquareAssign + Sub + SubAssign + SubMul + SubMulAssign + Sum + ToSci + ToStringBase + TrailingZeros + TryFrom> + TryFrom + TryFrom + TryFrom + TryFrom + TryFrom + TryFrom + TryFrom + TryFrom + TryFrom + TryFrom + TryFrom + TryFrom + TryInto> + TryInto + TryInto + TryInto + TryInto + TryInto + TryInto + TryInto + TryInto + TryInto + TryInto + TryInto + TryInto + Two + UnwindSafe + UpperHex + WrappingAdd + WrappingAddAssign + WrappingAddMul + WrappingAddMulAssign + WrappingDiv + WrappingDivAssign + WrappingFrom + WrappingFrom + WrappingFrom + WrappingFrom + WrappingFrom + WrappingFrom + WrappingFrom + WrappingFrom + WrappingFrom + WrappingFrom + WrappingFrom + WrappingFrom + WrappingInto + WrappingInto + WrappingInto + WrappingInto + WrappingInto + WrappingInto + WrappingInto + WrappingInto + WrappingInto + WrappingInto + WrappingInto + WrappingInto + WrappingMul + WrappingMulAssign + WrappingNeg + WrappingNegAssign + WrappingPow + WrappingPowAssign + WrappingSquare + WrappingSquareAssign + WrappingSub + WrappingSubAssign + WrappingSubMul + WrappingSubMulAssign + Zero { /// The number of bits of `Self`. const WIDTH: u64; /// The base-2 logarithm of the number of bits of `Self`. /// /// Whenever you need to use `n / WIDTH`, you can use `n >> LOG_WIDTH` instead. /// /// This is $\log_2 W$. /// /// Note that this value is correct for all of the built-in primitive integer types, but it will /// not be correct for custom types whose $W$ is not a power of 2. For such implementations, /// `LOG_WIDTH` should not be used. const LOG_WIDTH: u64 = Self::WIDTH.trailing_zeros() as u64; /// A mask that consists of `LOG_WIDTH` bits. /// /// Whenever you need to use `n % WIDTH`, you can use `n & WIDTH_MASK` instead. /// /// This is $W - 1$. /// /// Note that this value is correct for all of the built-in primitive integer types, but it will /// not be correct for custom types whose $W$ is not a power of 2. For such implementations, /// `WIDTH_MASK` should not be used. const WIDTH_MASK: u64 = Self::WIDTH - 1; /// Gets the most-significant bit of `Self`. For signed integers, this is the sign bit. /// /// If `Self` is unsigned, $f(n) = (n \geq 2^{W-1})$. If `Self` is unsigned, $f(n) = (n < 0)$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::num::basic::integers::PrimitiveInt; /// /// assert_eq!(123u32.get_highest_bit(), false); /// assert_eq!(4000000000u32.get_highest_bit(), true); /// assert_eq!(2000000000i32.get_highest_bit(), false); /// assert_eq!((-2000000000i32).get_highest_bit(), true); /// ``` #[inline] fn get_highest_bit(&self) -> bool { self.get_bit(Self::WIDTH - 1) } } /// Defines basic trait implementations that are the same for unsigned and signed types. macro_rules! impl_basic_traits_primitive_int { ($t:ident, $width:expr) => { /// # Examples /// /// See [here](self). impl PrimitiveInt for $t { const WIDTH: u64 = $width; } impl_named!($t); /// The constant 0. /// /// # Examples /// See [here](self). impl Zero for $t { const ZERO: $t = 0; } /// The constant 1. /// /// # Examples /// See [here](self). impl One for $t { const ONE: $t = 1; } /// The constant 2. /// /// # Examples /// See [here](self). impl Two for $t { const TWO: $t = 2; } /// The lowest value representable by this type. /// /// If `Self` is unsigned, `MIN` is 0. If `Self` is signed, `MIN` is $-2^{W-1}$. /// /// # Examples /// See [here](self). impl Min for $t { const MIN: $t = $t::MIN; } /// The highest value representable by this type. /// /// If `Self` is unsigned, `MAX` is $2^W-1$. If `Self` is signed, `MAX` is $2^{W-1}-1$. /// /// # Examples /// See [here](self). impl Max for $t { const MAX: $t = $t::MAX; } }; } impl_basic_traits_primitive_int!(u8, 8); impl_basic_traits_primitive_int!(u16, 16); impl_basic_traits_primitive_int!(u32, 32); impl_basic_traits_primitive_int!(u64, 64); impl_basic_traits_primitive_int!(u128, 128); impl_basic_traits_primitive_int!(usize, 0usize.trailing_zeros() as u64); impl_basic_traits_primitive_int!(i8, 8); impl_basic_traits_primitive_int!(i16, 16); impl_basic_traits_primitive_int!(i32, 32); impl_basic_traits_primitive_int!(i64, 64); impl_basic_traits_primitive_int!(i128, 128); impl_basic_traits_primitive_int!(isize, 0usize.trailing_zeros() as u64); malachite-base-0.4.16/src/num/basic/mod.rs000064400000000000000000000024761046102023000163600ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . /// The [`PrimitiveFloat`](floats::PrimitiveFloat) trait. pub mod floats; /// The [`PrimitiveInt`](integers::PrimitiveInt) trait. /// /// ``` /// use malachite_base::num::basic::integers::PrimitiveInt; /// use malachite_base::num::basic::traits::{One, Two, Zero}; /// /// assert_eq!(u32::WIDTH, 32); /// assert_eq!(u32::LOG_WIDTH, 5); /// assert_eq!(u32::WIDTH_MASK, 0x1f); /// /// assert_eq!(u32::ZERO, 0); /// assert_eq!(u32::ONE, 1); /// assert_eq!(i16::TWO, 2); /// /// assert_eq!(u32::MAX, 0xffffffff); /// assert_eq!(u32::MIN, 0); /// assert_eq!(i32::MAX, 0x7fffffff); /// assert_eq!(i32::MIN, -0x80000000); /// ``` pub mod integers; /// The [`PrimitiveSigned`](signeds::PrimitiveSigned) trait. /// /// ``` /// use malachite_base::num::basic::traits::NegativeOne; /// /// assert_eq!(i16::NEGATIVE_ONE, -1); /// ``` pub mod signeds; /// Traits for constants. pub mod traits; /// The [`PrimitiveUnsigned`](unsigneds::PrimitiveUnsigned) trait. pub mod unsigneds; malachite-base-0.4.16/src/num/basic/signeds.rs000064400000000000000000000063721046102023000172340ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{ Abs, AbsAssign, CeilingDivAssignMod, CeilingDivMod, CeilingMod, CeilingModAssign, CeilingModPowerOf2, CeilingModPowerOf2Assign, CheckedAbs, ExtendedGcd, NegAssign, OverflowingAbs, OverflowingAbsAssign, SaturatingAbs, SaturatingAbsAssign, SaturatingNeg, SaturatingNegAssign, UnsignedAbs, WrappingAbs, WrappingAbsAssign, }; use crate::num::basic::integers::PrimitiveInt; use crate::num::basic::traits::NegativeOne; use crate::num::logic::traits::CheckedHammingDistance; #[cfg(feature = "random")] use crate::num::random::{HasRandomSignedRange, RandomSignedChunkable}; use core::ops::Neg; // When the `random` feature is enabled, the HasRandomSignedRange and RandomSignedChunkable bounds // are included. #[cfg(feature = "random")] /// Defines functions on primitive signed integer types: ixx and isize. pub trait PrimitiveSigned: Abs + AbsAssign + CeilingDivAssignMod + CeilingDivMod + CeilingMod + CeilingModAssign + CeilingModPowerOf2 + CeilingModPowerOf2Assign + CheckedAbs + CheckedHammingDistance + ExtendedGcd + From + HasRandomSignedRange + Neg + NegAssign + NegativeOne + OverflowingAbs + OverflowingAbsAssign + PrimitiveInt + RandomSignedChunkable + SaturatingAbs + SaturatingAbsAssign + SaturatingNeg + SaturatingNegAssign + UnsignedAbs + WrappingAbs + WrappingAbsAssign { } #[cfg(not(feature = "random"))] /// Defines functions on primitive signed integer types: ixx and isize. pub trait PrimitiveSigned: Abs + AbsAssign + CeilingDivAssignMod + CeilingDivMod + CeilingMod + CeilingModAssign + CeilingModPowerOf2 + CeilingModPowerOf2Assign + CheckedAbs + CheckedHammingDistance + ExtendedGcd + From + Neg + NegAssign + NegativeOne + OverflowingAbs + OverflowingAbsAssign + PrimitiveInt + SaturatingAbs + SaturatingAbsAssign + SaturatingNeg + SaturatingNegAssign + UnsignedAbs + WrappingAbs + WrappingAbsAssign { } /// Defines basic trait implementations for signed types. macro_rules! impl_basic_traits { ($s: ident) => { impl PrimitiveSigned for $s {} /// The constant -1. /// /// # Examples /// See [here](self). impl NegativeOne for $s { const NEGATIVE_ONE: $s = -1; } }; } apply_to_signeds!(impl_basic_traits); malachite-base-0.4.16/src/num/basic/traits.rs000064400000000000000000000061551046102023000171050ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // Implementations of traits for NonZero* types by b4D8. // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use core::num::*; /// Provides the constant 0. #[allow(clippy::declare_interior_mutable_const)] pub trait Zero { const ZERO: Self; } /// Provides the constant 1. #[allow(clippy::declare_interior_mutable_const)] pub trait One { const ONE: Self; } /// Provides the constant 2. #[allow(clippy::declare_interior_mutable_const)] pub trait Two { const TWO: Self; } /// Provides the constant -1. #[allow(clippy::declare_interior_mutable_const)] pub trait NegativeOne { const NEGATIVE_ONE: Self; } /// Provides the constant 1/2. #[allow(clippy::declare_interior_mutable_const)] pub trait OneHalf { const ONE_HALF: Self; } /// Provides the constant -0. #[allow(clippy::declare_interior_mutable_const)] pub trait NegativeZero { const NEGATIVE_ZERO: Self; } /// Provides the constant (positive) Infinity. #[allow(clippy::declare_interior_mutable_const)] pub trait Infinity { const INFINITY: Self; } /// Provides the constant -Infinity. #[allow(clippy::declare_interior_mutable_const)] pub trait NegativeInfinity { const NEGATIVE_INFINITY: Self; } /// Provides the constant NaN. #[allow(clippy::declare_interior_mutable_const)] pub trait NaN { const NAN: Self; } /// Provides the Thue-Morse constant, whose bits are the Thue-Morse sequence. pub trait ThueMorseConstant { const THUE_MORSE_CONSTANT: Self; } /// Provides the prime constant, whose $n$th bit (starting from $n=1$) is true if and only if $n$ is /// prime. pub trait PrimeConstant { const PRIME_CONSTANT: Self; } // Implementation for `NonZero*` types: // - `One` and `Two` for both signed and unsigned variants // - `NegativeOne` for the signed variant macro_rules! impl_non_zero { ($($t:ident),+) => { $( impl One for $t { const ONE: Self = match Self::new(1) { Some(v) => v, None => unreachable!() // 1 is a valid nonzero value }; } impl Two for $t { const TWO: Self = match Self::new(2) { Some(v) => v, None => unreachable!() // 2 is a valid nonzero value }; } )+ }; ($($u:ident && $i:ident),+) => { $( impl_non_zero!($u, $i); impl NegativeOne for $i { const NEGATIVE_ONE: Self = match Self::new(-1) { Some(v) => v, None => unreachable!() // -1 is a valid non zero value }; } )+ } } impl_non_zero!( NonZeroUsize && NonZeroIsize, NonZeroU128 && NonZeroI128, NonZeroU64 && NonZeroI64, NonZeroU32 && NonZeroI32, NonZeroU16 && NonZeroI16, NonZeroU8 && NonZeroI8 ); malachite-base-0.4.16/src/num/basic/unsigneds.rs000064400000000000000000000173451046102023000176010ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{ AbsDiff, AbsDiffAssign, CeilingDivAssignNegMod, CeilingDivNegMod, CeilingLogBase, CeilingLogBase2, CeilingLogBasePowerOf2, CheckedDoubleFactorial, CheckedFactorial, CheckedLcm, CheckedLogBase, CheckedLogBase2, CheckedLogBasePowerOf2, CheckedMultifactorial, CheckedNextPowerOf2, CheckedPrimorial, CheckedSubfactorial, CoprimeWith, DoubleFactorial, ExtendedGcd, Factorial, FloorLogBase, FloorLogBase2, FloorLogBasePowerOf2, Gcd, GcdAssign, IsPowerOf2, Lcm, LcmAssign, ModAdd, ModAddAssign, ModInverse, ModIsReduced, ModMul, ModMulAssign, ModMulPrecomputed, ModMulPrecomputedAssign, ModNeg, ModNegAssign, ModPow, ModPowAssign, ModPowPrecomputed, ModPowPrecomputedAssign, ModPowerOf2, ModPowerOf2Add, ModPowerOf2AddAssign, ModPowerOf2Inverse, ModPowerOf2IsReduced, ModPowerOf2Mul, ModPowerOf2MulAssign, ModPowerOf2Neg, ModPowerOf2NegAssign, ModPowerOf2Pow, ModPowerOf2PowAssign, ModPowerOf2Shl, ModPowerOf2ShlAssign, ModPowerOf2Shr, ModPowerOf2ShrAssign, ModPowerOf2Square, ModPowerOf2SquareAssign, ModPowerOf2Sub, ModPowerOf2SubAssign, ModSquare, ModSquareAssign, ModSquarePrecomputed, ModSquarePrecomputedAssign, ModSub, ModSubAssign, Multifactorial, NegMod, NegModAssign, NegModPowerOf2, NegModPowerOf2Assign, NextPowerOf2, NextPowerOf2Assign, Primorial, RootAssignRem, RootRem, SqrtAssignRem, SqrtRem, Subfactorial, XMulYToZZ, XXAddYYToZZ, XXDivModYToQR, XXSubYYToZZ, XXXAddYYYToZZZ, XXXSubYYYToZZZ, XXXXAddYYYYToZZZZ, }; use crate::num::basic::integers::PrimitiveInt; use crate::num::conversion::traits::{ Digits, FromOtherTypeSlice, IntegerMantissaAndExponent, PowerOf2DigitIterable, PowerOf2Digits, SciMantissaAndExponent, VecFromOtherType, VecFromOtherTypeSlice, }; use crate::num::factorization::primes::{PrimesIterator, PrimesLessThanIterator}; use crate::num::factorization::traits::Primes; use crate::num::logic::traits::{BitBlockAccess, HammingDistance}; /// Defines functions on primitive unsigned integer types: uxx and usize. pub trait PrimitiveUnsigned: AbsDiff + AbsDiffAssign + BitBlockAccess + CeilingLogBase + CeilingLogBase2 + CeilingLogBasePowerOf2 + CeilingDivAssignNegMod + CeilingDivNegMod + CheckedDoubleFactorial + CheckedFactorial + CheckedMultifactorial + CheckedPrimorial + CheckedSubfactorial + CheckedLcm + CheckedLogBase + CheckedLogBase2 + CheckedLogBasePowerOf2 + CheckedNextPowerOf2 + CoprimeWith + DoubleFactorial + Digits + Digits + Digits + Digits + Digits + Digits + ExtendedGcd + Factorial + FloorLogBase + FloorLogBase2 + FloorLogBasePowerOf2 + From + FromOtherTypeSlice + FromOtherTypeSlice + FromOtherTypeSlice + FromOtherTypeSlice + FromOtherTypeSlice + FromOtherTypeSlice + Gcd + GcdAssign + HammingDistance + IntegerMantissaAndExponent + IsPowerOf2 + Lcm + LcmAssign + ModIsReduced + ModAdd + ModAddAssign + ModInverse + ModMul + ModMulAssign + ModMulPrecomputed + ModMulPrecomputedAssign + ModNeg + ModNegAssign + ModPow + ModPowAssign + ModPowerOf2 + ModPowerOf2Add + ModPowerOf2AddAssign + ModPowerOf2Inverse + ModPowerOf2IsReduced + ModPowerOf2Mul + ModPowerOf2MulAssign + ModPowerOf2Neg + ModPowerOf2NegAssign + ModPowerOf2Pow + ModPowerOf2PowAssign + ModPowerOf2Shl + ModPowerOf2Shl + ModPowerOf2Shl + ModPowerOf2Shl + ModPowerOf2Shl + ModPowerOf2Shl + ModPowerOf2Shl + ModPowerOf2Shl + ModPowerOf2Shl + ModPowerOf2Shl + ModPowerOf2ShlAssign + ModPowerOf2ShlAssign + ModPowerOf2ShlAssign + ModPowerOf2ShlAssign + ModPowerOf2ShlAssign + ModPowerOf2ShlAssign + ModPowerOf2ShlAssign + ModPowerOf2ShlAssign + ModPowerOf2ShlAssign + ModPowerOf2ShlAssign + ModPowerOf2ShlAssign + ModPowerOf2ShlAssign + ModPowerOf2Shr + ModPowerOf2Shr + ModPowerOf2Shr + ModPowerOf2Shr + ModPowerOf2Shr + ModPowerOf2ShrAssign + ModPowerOf2ShrAssign + ModPowerOf2ShrAssign + ModPowerOf2ShrAssign + ModPowerOf2ShrAssign + ModPowerOf2ShrAssign + ModPowerOf2Square + ModPowerOf2SquareAssign + ModPowerOf2Sub + ModPowerOf2SubAssign + ModPowPrecomputed + ModPowPrecomputedAssign + ModSquare + ModSquareAssign + ModSquarePrecomputed + ModSquarePrecomputedAssign + ModSub + ModSubAssign + Multifactorial + NegMod + NegModAssign + NegModPowerOf2 + NegModPowerOf2Assign + NextPowerOf2 + NextPowerOf2Assign + PowerOf2Digits + PowerOf2Digits + PowerOf2Digits + PowerOf2Digits + PowerOf2Digits + PowerOf2Digits + PowerOf2DigitIterable + PowerOf2DigitIterable + PowerOf2DigitIterable + PowerOf2DigitIterable + PowerOf2DigitIterable + PowerOf2DigitIterable + Primes, LI = PrimesLessThanIterator> + PrimitiveInt + Primorial + RootRem + RootAssignRem + SciMantissaAndExponent + SciMantissaAndExponent + SqrtRem + SqrtAssignRem + Subfactorial + VecFromOtherType + VecFromOtherType + VecFromOtherType + VecFromOtherType + VecFromOtherType + VecFromOtherType + VecFromOtherTypeSlice + VecFromOtherTypeSlice + VecFromOtherTypeSlice + VecFromOtherTypeSlice + VecFromOtherTypeSlice + VecFromOtherTypeSlice + XXAddYYToZZ + XXDivModYToQR + XXSubYYToZZ + XMulYToZZ + XXXAddYYYToZZZ + XXXSubYYYToZZZ + XXXXAddYYYYToZZZZ { } macro_rules! impl_basic_traits { ($u:ident) => { impl PrimitiveUnsigned for $u {} }; } apply_to_unsigneds!(impl_basic_traits); malachite-base-0.4.16/src/num/comparison/cmp_abs.rs000064400000000000000000000067631046102023000203010ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::UnsignedAbs; use crate::num::basic::floats::PrimitiveFloat; use crate::num::comparison::traits::{OrdAbs, PartialOrdAbs}; use core::cmp::Ordering; macro_rules! impl_partial_ord_abs { ($t:ident) => { impl PartialOrdAbs<$t> for $t { /// Compares the absolute values of two numbers, taking both by reference. /// /// The [`PartialOrdAbs`] interface allows for pairs of incomparable elements, but for /// primitive integers these never occur. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::cmp_abs#partial_cmp_abs). #[inline] fn partial_cmp_abs(&self, other: &$t) -> Option { Some(self.cmp_abs(other)) } } }; } apply_to_primitive_ints!(impl_partial_ord_abs); macro_rules! impl_ord_abs_unsigned { ($t:ident) => { impl OrdAbs for $t { /// Compares the absolute values of two numbers, taking both by reference. /// /// For unsigned values, this is the same as ordinary comparison. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::cmp_abs#cmp_abs). #[inline] fn cmp_abs(&self, other: &Self) -> Ordering { self.cmp(other) } } }; } apply_to_unsigneds!(impl_ord_abs_unsigned); fn cmp_abs_signed>(x: &S, y: &S) -> Ordering { x.unsigned_abs().cmp(&y.unsigned_abs()) } macro_rules! impl_ord_abs_signed { ($t:ident) => { impl OrdAbs for $t { /// Compares the absolute values of two numbers, taking both by reference. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::cmp_abs#cmp_abs). #[inline] fn cmp_abs(&self, other: &Self) -> Ordering { cmp_abs_signed(self, other) } } }; } apply_to_signeds!(impl_ord_abs_signed); fn partial_cmp_abs_primitive_float(x: &T, y: &T) -> Option { x.abs().partial_cmp(&y.abs()) } macro_rules! impl_ord_abs_primitive_float { ($t:ident) => { impl PartialOrdAbs for $t { /// Compares the absolute values of two numbers, taking both by reference. /// /// For unsigned values, this is the same as ordinary comparison. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::cmp_abs#cmp_abs). #[inline] fn partial_cmp_abs(&self, other: &Self) -> Option { partial_cmp_abs_primitive_float(self, other) } } }; } apply_to_primitive_floats!(impl_ord_abs_primitive_float); malachite-base-0.4.16/src/num/comparison/eq_abs.rs000064400000000000000000000034561046102023000201230ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::UnsignedAbs; use crate::num::comparison::traits::EqAbs; macro_rules! impl_eq_abs_unsigned { ($t:ident) => { impl EqAbs<$t> for $t { /// Compares the absolute values of two numbers for equality, taking both by reference. /// /// For unsigned values, this is the same as ordinary equality. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::eq_abs#eq_abs). #[inline] fn eq_abs(&self, other: &Self) -> bool { self == other } } }; } apply_to_unsigneds!(impl_eq_abs_unsigned); fn eq_abs_signed>(x: &S, y: &S) -> bool { x.unsigned_abs() == y.unsigned_abs() } macro_rules! impl_eq_abs_signed { ($t:ident) => { impl EqAbs<$t> for $t { /// Compares the absolute values of two numbers for equality, taking both by reference. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::eq_abs#eq_abs). #[inline] fn eq_abs(&self, other: &Self) -> bool { eq_abs_signed(self, other) } } }; } apply_to_signeds!(impl_eq_abs_signed); malachite-base-0.4.16/src/num/comparison/mod.rs000064400000000000000000000030131046102023000174350ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . /// [`PartialOrdAbs`](`traits::PartialOrdAbs`) and [`OrdAbs`](`traits::OrdAbs`), traits for /// comparing the absolute values of numbers by order. /// /// # partial_cmp_abs /// ``` /// use malachite_base::num::comparison::traits::PartialOrdAbs; /// use std::cmp::Ordering::*; /// /// assert_eq!(123i32.partial_cmp_abs(&-456), Some(Less)); /// assert_eq!(123i32.partial_cmp_abs(&-123), Some(Equal)); /// ``` /// /// # cmp_abs /// ``` /// use malachite_base::num::comparison::traits::OrdAbs; /// use std::cmp::Ordering::*; /// /// assert_eq!(123u32.cmp_abs(&456), Less); /// assert_eq!(123u32.cmp_abs(&123), Equal); /// assert_eq!(123i32.cmp_abs(&-456), Less); /// assert_eq!(123i32.cmp_abs(&-123), Equal); /// ``` pub mod cmp_abs; /// [`EqAbs`](`traits::EqAbs`), a trait for comparing the absolute values of numbers by equality. /// /// # eq_abs /// ``` /// use malachite_base::num::comparison::traits::EqAbs; /// /// assert_eq!(123u32.eq_abs(&456), false); /// assert_eq!(123u32.eq_abs(&123), true); /// assert_eq!(123i32.eq_abs(&-456), false); /// assert_eq!(123i32.eq_abs(&-123), true); /// ``` pub mod eq_abs; /// Various traits for comparing numbers. pub mod traits; malachite-base-0.4.16/src/num/comparison/traits.rs000064400000000000000000000060451046102023000201740ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use core::cmp::Ordering::{self, *}; /// Determines equality between the absolute values of two numbers. pub trait EqAbs { /// Compares the absolute values of two numbers for equality, taking both by reference. fn eq_abs(&self, other: &Rhs) -> bool; /// Compares the absolute values of two numbers for inequality, taking both by reference. /// /// # Worst-case complexity /// Same as the time and additional memory complexity of [`eq_abs`](Self::eq_abs). #[inline] fn ne_abs(&self, other: &Rhs) -> bool { !self.eq_abs(other) } } /// Determines equality between the absolute values of two numbers, where some pairs of numbers may /// not be comparable. pub trait PartialOrdAbs { /// Compares the absolute values of two numbers, taking both by reference. /// /// If the two values are not comparable, `None` is returned. fn partial_cmp_abs(&self, other: &Rhs) -> Option; /// Determines whether the absolute value of one number is less than the absolute value of /// another. /// /// # Worst-case complexity /// Same as the time and additional memory complexity of /// [`partial_cmp_abs`](Self::partial_cmp_abs). #[inline] fn lt_abs(&self, other: &Rhs) -> bool { matches!(self.partial_cmp_abs(other), Some(Less)) } /// Determines whether the absolute value of one number is less than or equal to the absolute /// value of another. /// /// # Worst-case complexity /// Same as the time and additional memory complexity of /// [`partial_cmp_abs`](Self::partial_cmp_abs). #[inline] fn le_abs(&self, other: &Rhs) -> bool { matches!(self.partial_cmp_abs(other), Some(Less | Equal)) } /// Determines whether the absolute value of one number is greater than the absolute value of /// another. /// /// # Worst-case complexity /// Same as the time and additional memory complexity of /// [`partial_cmp_abs`](Self::partial_cmp_abs). #[inline] fn gt_abs(&self, other: &Rhs) -> bool { matches!(self.partial_cmp_abs(other), Some(Greater)) } /// Determines whether the absolute value of one number is greater than or equal to the absolute /// value of another. /// /// # Worst-case complexity /// Same as the time and additional memory complexity of /// [`partial_cmp_abs`](Self::partial_cmp_abs). #[inline] fn ge_abs(&self, other: &Rhs) -> bool { matches!(self.partial_cmp_abs(other), Some(Greater | Equal)) } } /// Compares the absolute values of two numbers. pub trait OrdAbs: Eq + PartialOrdAbs { fn cmp_abs(&self, other: &Self) -> Ordering; } malachite-base-0.4.16/src/num/conversion/digits/general_digits.rs000064400000000000000000000216121046102023000231410ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::{ ConvertibleFrom, Digits, ExactFrom, PowerOf2Digits, WrappingFrom, }; use alloc::vec::Vec; use itertools::Itertools; pub_test! {unsigned_to_digits_asc_naive< T: ExactFrom + PrimitiveUnsigned, U: PrimitiveUnsigned + WrappingFrom, >( x: &T, base: U, ) -> Vec { assert!(base > U::ONE); let mut digits = Vec::new(); let mut remainder = *x; let base = T::exact_from(base); while remainder != T::ZERO { digits.push(U::wrapping_from(remainder.div_assign_mod(base))); } digits }} fn to_digits_asc< T: ConvertibleFrom + ExactFrom + PrimitiveUnsigned + PowerOf2Digits, U: PrimitiveUnsigned + WrappingFrom, >( x: &T, base: &U, ) -> Vec { assert!(T::convertible_from(*base)); if *x == T::ZERO { Vec::new() } else if let Some(log_base) = base.checked_log_base_2() { x.to_power_of_2_digits_asc(log_base) } else { unsigned_to_digits_asc_naive(x, *base) } } fn to_digits_desc< T: ConvertibleFrom + ExactFrom + PrimitiveUnsigned + PowerOf2Digits, U: PrimitiveUnsigned + WrappingFrom, >( x: &T, base: &U, ) -> Vec { assert!(T::convertible_from(*base)); if *x == T::ZERO { Vec::new() } else if let Some(log_base) = base.checked_log_base_2() { x.to_power_of_2_digits_desc(log_base) } else { let mut digits = unsigned_to_digits_asc_naive(x, *base); digits.reverse(); digits } } fn from_digits_asc< T: Digits + PowerOf2Digits, U: PrimitiveUnsigned, I: Iterator, >( base: &U, digits: I, ) -> Option { if let Some(log_base) = base.checked_log_base_2() { T::from_power_of_2_digits_asc(log_base, digits) } else { let mut digits = digits.collect_vec(); digits.reverse(); T::from_digits_desc(base, digits.into_iter()) } } fn from_digits_desc< T: Digits + TryFrom + PrimitiveUnsigned + PowerOf2Digits, U: PrimitiveUnsigned, I: Iterator, >( base: &U, digits: I, ) -> Option { assert!(*base > U::ONE); if let Some(log_base) = base.checked_log_base_2() { T::from_power_of_2_digits_desc(log_base, digits) } else { let base = T::try_from(*base).ok()?; let mut x = T::ZERO; for digit in digits { let digit = T::try_from(digit).ok()?; if digit >= base { return None; } x = x.checked_mul(base)?.checked_add(digit)?; } Some(x) } } macro_rules! impl_digits { ($t:ident) => { macro_rules! impl_digits_inner { ($u:ident) => { impl Digits<$u> for $t { /// Returns a [`Vec`] containing the digits of a number in ascending order /// (least- to most-significant). /// /// The base must be convertible to `Self`. If `self` is 0, the [`Vec`] is /// empty; otherwise, it ends with a nonzero digit. /// /// $f(x, b) = (d_i)_ {i=0}^{k-1}$, where $0 \leq d_i < b$ for all $i$, $k=0$ or /// $d_{k-1} \neq 0$, and /// /// $$ /// \sum_{i=0}^{k-1}b^i d_i = x. /// $$ /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is /// `self.significant_bits()`. /// /// # Panics /// Panics if `base` is less than 2 or greater than `Self::MAX`. /// /// # Examples /// See [here](super::general_digits#to_digits_asc). #[inline] fn to_digits_asc(&self, base: &$u) -> Vec<$u> { to_digits_asc(self, base) } /// Returns a [`Vec`] containing the digits of a number in descending order /// (most- to least-significant). /// /// The base must be convertible to `Self`. If `self` is 0, the [`Vec`] is /// empty; otherwise, it begins with a nonzero digit. /// /// $f(x, b) = (d_i)_ {i=0}^{k-1}$, where $0 \leq d_i < b$ for all $i$, $k=0$ or /// $d_{k-1} \neq 0$, and /// /// $$ /// \sum_{i=0}^{k-1}b^i d_{k-i-1} = x. /// $$ /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is /// `self.significant_bits()`. /// /// # Panics /// Panics if `base` is less than 2 or greater than `$t::MAX`. /// /// # Examples /// See [here](super::general_digits#to_digits_desc). #[inline] fn to_digits_desc(&self, base: &$u) -> Vec<$u> { to_digits_desc(self, base) } /// Converts an iterator of digits into a value. /// /// The input digits are in ascending order (least- to most-significant). The /// base must be no larger than `Self::MAX`. The function returns `None` if the /// input represents a number that can't fit in `Self`, if `base` is greater /// than `Self::MAX`, or if any of the digits are greater than or equal to the /// base. /// /// $$ /// f((d_i)_ {i=0}^{k-1}, b) = \sum_{i=0}^{k-1}b^id_i. /// $$ /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `digits.count()`. /// /// # Panics /// Panics if `base` is less than 2. /// /// # Examples /// See [here](super::general_digits#from_digits_asc). #[inline] fn from_digits_asc>(base: &$u, digits: I) -> Option<$t> { from_digits_asc(base, digits) } /// Converts an iterator of digits into a value. /// /// The input digits are in descending order (most- to least-significant). The /// base must be no larger than `Self::MAX`. The function returns `None` if the /// input represents a number that can't fit in `Self`, if `base` is greater /// than `Self::MAX`, or if any of the digits are greater than or equal to the /// base. /// /// $$ /// f((d_i)_ {i=0}^{k-1}, b) = \sum_{i=0}^{k-1}b^{k-i-1}d_i. /// $$ /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `digits.count()`. /// /// # Panics /// Panics if `base` is less than 2. /// /// # Examples /// See [here](super::general_digits#from_digits_desc). #[inline] fn from_digits_desc>( base: &$u, digits: I, ) -> Option<$t> { from_digits_desc(base, digits) } } }; } apply_to_unsigneds!(impl_digits_inner); }; } apply_to_unsigneds!(impl_digits); malachite-base-0.4.16/src/num/conversion/digits/mod.rs000064400000000000000000000133571046102023000207470ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . /// [`Digits`](super::traits::Digits), a trait for extracting digits from numbers and constructing /// numbers from digits. /// /// # to_digits_asc /// ``` /// use malachite_base::num::conversion::traits::Digits; /// /// assert_eq!(0u8.to_digits_asc(&6u64), &[]); /// assert_eq!(2u16.to_digits_asc(&6u32), &[2]); /// assert_eq!( /// 123456u32.to_digits_asc(&3u16), /// &[0, 1, 1, 0, 0, 1, 1, 2, 0, 0, 2] /// ); /// ``` /// /// # to_digits_desc /// ``` /// use malachite_base::num::conversion::traits::Digits; /// /// assert_eq!(0u8.to_digits_asc(&6u64), &[]); /// assert_eq!(2u16.to_digits_asc(&6u32), &[2]); /// assert_eq!( /// 123456u32.to_digits_desc(&3u16), /// &[2, 0, 0, 2, 1, 1, 0, 0, 1, 1, 0] /// ); /// ``` /// /// # from_digits_asc /// ``` /// use malachite_base::num::conversion::traits::Digits; /// /// assert_eq!( /// u8::from_digits_asc(&64, [0u64, 0, 0].iter().cloned()), /// Some(0) /// ); /// assert_eq!( /// u32::from_digits_asc(&3, [0u64, 1, 1, 0, 0, 1, 1, 2, 0, 0, 2].iter().cloned()), /// Some(123456) /// ); /// assert_eq!( /// u32::from_digits_asc(&8, [3u16, 7, 1].iter().cloned()), /// Some(123) /// ); /// /// assert!(u64::from_digits_asc(&64, [1u8; 1000].iter().cloned()).is_none()); /// assert!(u64::from_digits_asc(&2, [2u8].iter().cloned()).is_none()); /// assert!(u8::from_digits_asc(&1000, [1u16, 2, 3].iter().cloned()).is_none()); /// ``` /// /// # from_digits_desc /// ``` /// use malachite_base::num::conversion::traits::Digits; /// /// assert_eq!( /// u8::from_digits_desc(&64, [0u64, 0, 0].iter().cloned()), /// Some(0) /// ); /// assert_eq!( /// u32::from_digits_desc(&3, [2u64, 0, 0, 2, 1, 1, 0, 0, 1, 1, 0].iter().cloned()), /// Some(123456) /// ); /// assert_eq!( /// u32::from_digits_desc(&8, [1u16, 7, 3].iter().cloned()), /// Some(123) /// ); /// /// assert!(u64::from_digits_desc(&64, [1u8; 1000].iter().cloned()).is_none()); /// assert!(u64::from_digits_desc(&2, [2u8].iter().cloned()).is_none()); /// assert!(u8::from_digits_desc(&1000, [1u16, 2, 3].iter().cloned()).is_none()); /// ``` pub mod general_digits; /// [`PowerOf2DigitIterable`](super::traits::PowerOf2DigitIterable), a trait for producing /// [`PrimitivePowerOf2DigitIterator`](power_of_2_digit_iterable::PrimitivePowerOf2DigitIterator), a /// double-ended iterator for iterating over a number's base-$2^k$ digits. /// /// # power_of_2_digits /// ``` /// use itertools::Itertools; /// use malachite_base::num::conversion::traits::PowerOf2DigitIterable; /// /// let mut digits = PowerOf2DigitIterable::::power_of_2_digits(0u8, 2); /// assert!(digits.next().is_none()); /// /// // 107 = 1101011b /// let digits = PowerOf2DigitIterable::::power_of_2_digits(107u32, 2); /// assert_eq!(digits.collect_vec(), &[3, 2, 2, 1]); /// /// let mut digits = PowerOf2DigitIterable::::power_of_2_digits(0u8, 2); /// assert!(digits.next_back().is_none()); /// /// // 107 = 1101011b /// let digits = PowerOf2DigitIterable::::power_of_2_digits(107u32, 2); /// assert_eq!(digits.rev().collect_vec(), &[1, 2, 2, 3]); /// ``` pub mod power_of_2_digit_iterable; /// [`PowerOf2Digits`](super::traits::PowerOf2Digits), a trait for extracting base-$2^k$ $digits /// from numbers and constructing numbers from digits. /// /// # to_power_of_2_digits_asc /// ``` /// use malachite_base::num::conversion::traits::PowerOf2Digits; /// /// assert_eq!( /// PowerOf2Digits::::to_power_of_2_digits_asc(&0u8, 6), /// &[] /// ); /// assert_eq!( /// PowerOf2Digits::::to_power_of_2_digits_asc(&2u16, 6), /// &[2] /// ); /// // 123_10 = 173_8 /// assert_eq!( /// PowerOf2Digits::::to_power_of_2_digits_asc(&123u32, 3), /// &[3, 7, 1] /// ); /// ``` /// /// # to_power_of_2_digits_desc /// ``` /// use malachite_base::num::conversion::traits::PowerOf2Digits; /// /// assert_eq!( /// PowerOf2Digits::::to_power_of_2_digits_desc(&0u8, 6), /// &[] /// ); /// assert_eq!( /// PowerOf2Digits::::to_power_of_2_digits_desc(&2u16, 6), /// &[2] /// ); /// // 123_10 = 173_8 /// assert_eq!( /// PowerOf2Digits::::to_power_of_2_digits_desc(&123u32, 3), /// &[1, 7, 3] /// ); /// ``` /// /// # from_power_of_2_digits_asc /// ``` /// use malachite_base::num::conversion::traits::PowerOf2Digits; /// /// assert_eq!( /// u8::from_power_of_2_digits_asc(6, [0u64, 0, 0].iter().cloned()), /// Some(0) /// ); /// assert_eq!( /// u16::from_power_of_2_digits_asc(6, [2u64, 0].iter().cloned()), /// Some(2) /// ); /// assert_eq!( /// u32::from_power_of_2_digits_asc(3, [3u16, 7, 1].iter().cloned()), /// Some(123) /// ); /// /// assert!(u8::from_power_of_2_digits_asc(4, [1u64; 100].iter().cloned()).is_none()); /// assert!(u8::from_power_of_2_digits_asc(1, [2u64].iter().cloned()).is_none()); /// ``` /// /// # from_power_of_2_digits_desc /// ``` /// use malachite_base::num::conversion::traits::PowerOf2Digits; /// /// assert_eq!( /// u8::from_power_of_2_digits_desc(6, [0u64, 0, 0].iter().cloned()), /// Some(0) /// ); /// assert_eq!( /// u16::from_power_of_2_digits_desc(6, [0u64, 2].iter().cloned()), /// Some(2) /// ); /// assert_eq!( /// u32::from_power_of_2_digits_desc(3, [1u16, 7, 3].iter().cloned()), /// Some(123) /// ); /// /// assert!(u8::from_power_of_2_digits_desc(4, [1u64; 100].iter().cloned()).is_none()); /// assert!(u8::from_power_of_2_digits_desc(1, [2u64].iter().cloned()).is_none()); /// ``` pub mod power_of_2_digits; malachite-base-0.4.16/src/num/conversion/digits/power_of_2_digit_iterable.rs000064400000000000000000000152061046102023000252530ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{DivRound, SaturatingSubAssign}; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::{ ExactFrom, PowerOf2DigitIterable, PowerOf2DigitIterator, WrappingFrom, }; use crate::num::logic::traits::BitBlockAccess; use crate::rounding_modes::RoundingMode::*; use core::marker::PhantomData; /// A double-ended iterator over the base-$2^k$ digits of an unsigned primitive integer. /// /// This `struct` is created by the [`PowerOf2DigitIterable::power_of_2_digits`] function. See its /// documentation for more. #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] pub struct PrimitivePowerOf2DigitIterator { pub(crate) value: T, pub(crate) log_base: u64, pub(crate) remaining: usize, // If `n` is nonzero, this index initially points to the least-significant bit of the least- // significant digit, and is left-shifted by `next`. pub(crate) i: u64, // If `n` is nonzero, this mask initially points to the least-significant bit of the most- // significant nonzero digit, and is right-shifted by `next_back`. pub(crate) j: u64, phantom: PhantomData<*const U>, } impl::Bits>> Iterator for PrimitivePowerOf2DigitIterator { type Item = U; fn next(&mut self) -> Option { if self.remaining != 0 { let digit = U::wrapping_from(self.value.get_bits(self.i, self.i + self.log_base)); self.i += self.log_base; self.remaining -= 1; Some(digit) } else { None } } fn size_hint(&self) -> (usize, Option) { (self.remaining, Some(self.remaining)) } } impl::Bits>> DoubleEndedIterator for PrimitivePowerOf2DigitIterator { fn next_back(&mut self) -> Option { if self.remaining != 0 { let digit = U::wrapping_from(self.value.get_bits(self.j, self.j + self.log_base)); self.j.saturating_sub_assign(self.log_base); self.remaining -= 1; Some(digit) } else { None } } } impl::Bits>> ExactSizeIterator for PrimitivePowerOf2DigitIterator { } impl::Bits>> PowerOf2DigitIterator for PrimitivePowerOf2DigitIterator { /// Retrieves base-$2^k$ digits by index. /// /// Indexing at or above the significant digit count returns zero. /// /// This function doesn't affect, and isn't affected by, the iterator's position. /// /// $f(x, k, i) = d_i$, where $0 \leq d_i < 2^k$ for all $i$ and /// $$ /// \sum_{i=0}^\infty2^{ki}d_i = x. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::num::conversion::traits::{ /// PowerOf2DigitIterable, PowerOf2DigitIterator, /// }; /// /// let digits = PowerOf2DigitIterable::::power_of_2_digits(0u8, 2); /// assert_eq!(digits.get(0), 0); /// /// // 107 = 1101011b /// let digits = PowerOf2DigitIterable::::power_of_2_digits(107u32, 2); /// assert_eq!(digits.get(0), 3); /// assert_eq!(digits.get(1), 2); /// assert_eq!(digits.get(2), 2); /// assert_eq!(digits.get(100), 0); /// ``` fn get(&self, index: u64) -> U { let i = index * self.log_base; U::wrapping_from(self.value.get_bits(i, i + self.log_base)) } } fn power_of_2_digits( x: T, log_base: u64, ) -> PrimitivePowerOf2DigitIterator { assert_ne!(log_base, 0); assert!( log_base <= U::WIDTH, "type {:?} is too small for a digit of width {}", U::NAME, log_base ); let significant_digits = x.significant_bits().div_round(log_base, Ceiling).0; PrimitivePowerOf2DigitIterator { value: x, log_base, remaining: usize::exact_from(significant_digits), i: 0, j: significant_digits.saturating_sub(1) * log_base, phantom: PhantomData, } } macro_rules! impl_power_of_2_digit_iterable { ($t:ident) => { macro_rules! impl_power_of_2_digit_iterable_inner { ($u:ident) => { impl PowerOf2DigitIterable<$u> for $t { type PowerOf2DigitIterator = PrimitivePowerOf2DigitIterator<$t, $u>; /// Returns a double-ended iterator over the base-$2^k$ digits of a primitive /// unsigned integer. /// /// The forward order is ascending, so that less-significant digits appear /// first. There are no trailing zeros going forward, or leading zeros going /// backward. /// /// If it's necessary to get a [`Vec`] of all the digits, consider using /// [`to_power_of_2_digits_asc`](super::super::traits::PowerOf2Digits::to_power_of_2_digits_asc) /// or /// [`to_power_of_2_digits_desc`](super::super::traits::PowerOf2Digits::to_power_of_2_digits_desc) /// instead. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `log_base` is larger than the width of output type width. /// /// # Examples /// See [here](super::power_of_2_digit_iterable#power_of_2_digits). #[inline] fn power_of_2_digits( self, log_base: u64, ) -> PrimitivePowerOf2DigitIterator<$t, $u> { power_of_2_digits(self, log_base) } } }; } apply_to_unsigneds!(impl_power_of_2_digit_iterable_inner); }; } apply_to_unsigneds!(impl_power_of_2_digit_iterable); malachite-base-0.4.16/src/num/conversion/digits/power_of_2_digits.rs000064400000000000000000000223651046102023000235730ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::{PowerOf2Digits, WrappingFrom}; use alloc::vec::Vec; fn to_power_of_2_digits_asc>( x: &T, log_base: u64, ) -> Vec { assert_ne!(log_base, 0); assert!( log_base <= U::WIDTH, "type {:?} is too small for a digit of width {}", U::NAME, log_base ); let mut digits = Vec::new(); if *x == T::ZERO { } else if x.significant_bits() <= log_base { digits.push(U::wrapping_from(*x)); } else { let mut x = *x; let mask = U::low_mask(log_base); while x != T::ZERO { digits.push(U::wrapping_from(x) & mask); x >>= log_base; } } digits } fn to_power_of_2_digits_desc>( x: &T, log_base: u64, ) -> Vec { let mut digits = to_power_of_2_digits_asc(x, log_base); digits.reverse(); digits } fn from_power_of_2_digits_asc< T: TryFrom + PrimitiveUnsigned + WrappingFrom, U: PrimitiveUnsigned, I: Iterator, >( log_base: u64, digits: I, ) -> Option { assert_ne!(log_base, 0); assert!( log_base <= U::WIDTH, "type {:?} is too small for a digit of width {}", U::NAME, log_base ); let mut n = T::ZERO; let mut shift = 0; for digit in digits { if digit.significant_bits() > log_base { return None; } n |= T::try_from(digit) .ok() .and_then(|d| d.arithmetic_checked_shl(shift))?; shift += log_base; } Some(n) } fn from_power_of_2_digits_desc< T: PrimitiveUnsigned + WrappingFrom, U: PrimitiveUnsigned, I: Iterator, >( log_base: u64, digits: I, ) -> Option { assert_ne!(log_base, 0); assert!( log_base <= U::WIDTH, "type {:?} is too small for a digit of width {}", U::NAME, log_base ); let mut n = T::ZERO; for digit in digits { if digit.significant_bits() > log_base { return None; } let shifted = n.arithmetic_checked_shl(log_base)?; n = shifted | T::wrapping_from(digit); } Some(n) } macro_rules! impl_power_of_2_digits { ($t:ident) => { macro_rules! impl_power_of_2_digits_inner { ($u:ident) => { impl PowerOf2Digits<$u> for $t { /// Returns a [`Vec`] containing the base-$2^k$ digits of a number in ascending /// order (least- to most-significant). /// /// The base-2 logarithm of the base is specified. `log_base` must be no larger /// than the width of the digit type. If `self` is 0, the [`Vec`] is empty; /// otherwise, it ends with a nonzero digit. /// /// $f(x, k) = (d_i)_ {i=0}^{n-1}$, where $0 \leq d_i < 2^k$ for all $i$, $n=0$ /// or $d_{n-1} \neq 0$, and /// /// $$ /// \sum_{i=0}^{n-1}2^{ki}d_i = x. /// $$ /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is /// `self.significant_bits()`. /// /// # Panics /// Panics if `log_base` is greater than the width of the output type, or if /// `log_base` is zero. /// /// # Examples /// See [here](super::power_of_2_digits#to_power_of_2_digits_asc). #[inline] fn to_power_of_2_digits_asc(&self, log_base: u64) -> Vec<$u> { to_power_of_2_digits_asc(self, log_base) } /// Returns a [`Vec`] containing the base-$2^k$ digits of a number in descending /// order (most- to least-significant). /// /// The base-2 logarithm of the base is specified. `log_base` must be no larger /// than the width of the digit type. If `self` is 0, the [`Vec`] is empty; /// otherwise, it begins with a nonzero digit. /// /// $f(x, k) = (d_i)_ {i=0}^{n-1}$, where $0 \leq d_i < 2^k$ for all $i$, $n=0$ /// or $d_0 \neq 0$, and /// /// $$ /// \sum_{i=0}^{n-1}2^{k (n-i-1)}d_i = x. /// $$ /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is /// `self.significant_bits()`. /// /// # Panics /// Panics if `log_base` is greater than the width of the output type, or if /// `log_base` is zero. /// /// # Examples /// See [here](super::power_of_2_digits#to_power_of_2_digits_desc). #[inline] fn to_power_of_2_digits_desc(&self, log_base: u64) -> Vec<$u> { to_power_of_2_digits_desc(self, log_base) } /// Converts an iterator of base-$2^k$ digits into a value. /// /// The base-2 logarithm of the base is specified. The input digits are in /// ascending order (least- to most-significant). `log_base` must be no larger /// than the width of the digit type. The function returns `None` if the input /// represents a number that can't fit in the output type. /// /// $$ /// f((d_i)_ {i=0}^{n-1}, k) = \sum_{i=0}^{n-1}2^{ki}d_i. /// $$ /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `digits.count()`. /// /// # Panics /// Panics if `log_base` is greater than the width of the digit type, or if /// `log_base` is zero. /// /// # Examples /// See [here](super::power_of_2_digits#from_power_of_2_digits_asc). #[inline] fn from_power_of_2_digits_asc>( log_base: u64, digits: I, ) -> Option<$t> { from_power_of_2_digits_asc(log_base, digits) } /// Converts an iterator of base-$2^k$ digits into a value. /// /// The base-2 logarithm of the base is specified. The input digits are in /// descending order (most- to least-significant). `log_base` must be no larger /// than the width of the digit type. The function returns `None` if the input /// represents a number that can't fit in the output type. /// /// $$ /// f((d_i)_ {i=0}^{n-1}, k) = \sum_{i=0}^{n-1}2^{k (n-i-1)}d_i. /// $$ /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `digits.count()`. /// /// # Panics /// Panics if `log_base` is greater than the width of the digit type, or if /// `log_base` is zero. /// /// # Examples /// See [here](super::power_of_2_digits#from_power_of_2_digits_desc). fn from_power_of_2_digits_desc>( log_base: u64, digits: I, ) -> Option<$t> { from_power_of_2_digits_desc(log_base, digits) } } }; } apply_to_unsigneds!(impl_power_of_2_digits_inner); }; } apply_to_unsigneds!(impl_power_of_2_digits); malachite-base-0.4.16/src/num/conversion/from.rs000064400000000000000000001231541046102023000176450ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{ShrRoundAssign, UnsignedAbs}; use crate::num::basic::floats::PrimitiveFloat; use crate::num::basic::integers::PrimitiveInt; use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::mantissa_and_exponent::sci_mantissa_and_exponent_round; use crate::num::conversion::traits::{ ConvertibleFrom, OverflowingFrom, RoundingFrom, SaturatingFrom, SciMantissaAndExponent, WrappingFrom, }; use crate::num::float::NiceFloat; use crate::rounding_modes::RoundingMode::{self, *}; use core::cmp::Ordering::{self, *}; use core::ops::Neg; // This macro defines conversions from a type to itself. macro_rules! identity_conversion { ($t:ty) => { impl WrappingFrom<$t> for $t { /// Converts a value to its own type. This conversion is always valid and always leaves /// the value unchanged. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::from#wrapping_from). #[inline] fn wrapping_from(value: $t) -> $t { value } } impl SaturatingFrom<$t> for $t { /// Converts a value to its own type. This conversion is always valid and always leaves /// the value unchanged. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::from#saturating_from). #[inline] fn saturating_from(value: $t) -> $t { value } } impl OverflowingFrom<$t> for $t { /// Converts a value to its own type. Since this conversion is always valid and always /// leaves the value unchanged, the second component of the result is always false (no /// overflow). /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::from#overflowing_from). #[inline] fn overflowing_from(value: $t) -> ($t, bool) { (value, false) } } impl ConvertibleFrom<$t> for $t { /// Checks whether a value is convertible to its own type. The result is always `true`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::from#convertible_from). #[inline] fn convertible_from(_: $t) -> bool { true } } }; } // This macro defines conversions from type $a to type $b, where every value of type $a is // representable by a value of type $b. macro_rules! lossless_conversion { ($a:ty, $b:ident) => { impl WrappingFrom<$a> for $b { /// Converts a value to another type. This conversion is always valid and always leaves /// the value unchanged. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::from#wrapping_from). #[inline] fn wrapping_from(value: $a) -> $b { $b::from(value) } } impl SaturatingFrom<$a> for $b { /// Converts a value to another type. This conversion is always valid and always leaves /// the value unchanged. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::from#saturating_from). #[inline] fn saturating_from(value: $a) -> $b { $b::from(value) } } impl OverflowingFrom<$a> for $b { /// Converts a value to the value's type. Since this conversion is always valid and /// always leaves the value unchanged, the second component of the result is always /// false (no overflow). /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::from#overflowing_from). #[inline] fn overflowing_from(value: $a) -> ($b, bool) { ($b::from(value), false) } } impl ConvertibleFrom<$a> for $b { /// Checks whether a value is convertible to a different type. The result is always /// `true`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::from#convertible_from). #[inline] fn convertible_from(_: $a) -> bool { true } } }; } fn saturating_from_lossy + PrimitiveInt, B: PrimitiveInt + WrappingFrom>( value: A, ) -> B { if let Ok(b_max) = A::try_from(B::MAX) { if value >= b_max { return B::MAX; } } if let Ok(b_min) = A::try_from(B::MIN) { if value <= b_min { return B::MIN; } } B::wrapping_from(value) } fn overflowing_from_lossy, B: PrimitiveInt + WrappingFrom>( value: A, ) -> (B, bool) { let result = B::wrapping_from(value); ( result, (result >= B::ZERO) != (value >= A::ZERO) || A::wrapping_from(result) != value, ) } fn convertible_from_lossy, B: PrimitiveInt + WrappingFrom>( value: A, ) -> bool { let result = B::wrapping_from(value); (result >= B::ZERO) == (value >= A::ZERO) && A::wrapping_from(result) == value } // This macro defines conversions from type $a to type $b, where not every value of type $a is // representable by a value of type $b. macro_rules! lossy_conversion { ($a:ident, $b:ident) => { #[allow(clippy::cast_lossless)] impl WrappingFrom<$a> for $b { /// Converts a value to another type. If the value cannot be represented in the new /// type, it is wrapped. /// /// Let $W$ be the width of the target type. /// /// If the target type is unsigned, then $f_W(n) = m$, where $m < 2^W$ and $n + 2^W k = /// m$ for some $k \in \Z$. /// /// If the target type is signed, then $f_W(n) = m$, where $-2^{W-1} \leq m < 2^{W-1}$ /// and $n + 2^W k = m$ for some $k \in \Z$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::from#wrapping_from). #[inline] fn wrapping_from(value: $a) -> $b { value as $b } } impl SaturatingFrom<$a> for $b { /// Converts a value to another type. If the value cannot be represented in the new /// type, the maximum or minimum value of the new type, whichever is closer, is /// returned. /// /// Let $W$ be the width of the target type. /// /// If the target type is unsigned, then /// $$ /// f_W(n) = \\begin{cases} /// 0 & n < 0 \\\\ /// 2^W-1 & \text{if} \\quad n \geq 2^W, \\\\ /// n & \\text{otherwise}. /// \\end{cases} /// $$ /// /// If the target type is signed, then /// $$ /// f_W(n) = \\begin{cases} /// -2^{W-1} & \text{if} \\quad n < -2^{W-1}, \\\\ /// 2^{W-1}-1 & \text{if} \\quad n \geq 2^{W-1}, \\\\ /// n & \\text{otherwise}. /// \\end{cases} /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::from#saturating_from). #[inline] fn saturating_from(value: $a) -> $b { saturating_from_lossy(value) } } impl OverflowingFrom<$a> for $b { /// Converts a value to another type. If the value cannot be represented in the new /// type, it is wrapped. The second component of the result indicates whether overflow /// occurred. /// /// Let $W$ be the width of the target type. /// /// If the target type is unsigned, then $f_W(n) = (m, k \neq 0)$, where $m < 2^W$ and /// $n + 2^W k = m$ for some $k \in \Z$. /// /// If the target type is signed, then $f_W(n) = (m, k \neq 0)$, where $-2^{W-1} \leq m /// < 2^{W-1}$ and $n + 2^W k = m$ for some $k \in \Z$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::from#overflowing_from). #[inline] fn overflowing_from(value: $a) -> ($b, bool) { overflowing_from_lossy(value) } } impl ConvertibleFrom<$a> for $b { /// Determines whether a value is convertible to a different type. /// /// Let $W$ be the width of the target type. /// /// If the target type is unsigned then, /// $$ /// f_W(n) = (0 \leq n < 2^W). /// $$ /// /// If the target type is signed then, /// $$ /// f_W(n) = (-2^{W-1} \leq n < 2^{W-1}-1). /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::from#convertible_from). #[inline] fn convertible_from(value: $a) -> bool { convertible_from_lossy::<$a, $b>(value) } } }; } // This macro defines conversions from type $a to type $b, where the set of values representable by // type $a is a proper subset of the set of values representable by type $b. macro_rules! proper_subset_conversion { ($a:ident, $b:ident) => { lossless_conversion!($a, $b); lossy_conversion!($b, $a); }; } // This macro defines conversions from type $a to type $b, where the set of values representable by // type $a is neither a subset nor a superset of the set of values representable by type $b. macro_rules! no_containment_conversion { ($a:ident, $b:ident) => { lossy_conversion!($a, $b); lossy_conversion!($b, $a); }; } apply_to_primitive_ints!(identity_conversion); proper_subset_conversion!(u8, u16); proper_subset_conversion!(u8, u32); proper_subset_conversion!(u8, u64); proper_subset_conversion!(u8, u128); proper_subset_conversion!(u8, usize); proper_subset_conversion!(u8, i16); proper_subset_conversion!(u8, i32); proper_subset_conversion!(u8, i64); proper_subset_conversion!(u8, i128); proper_subset_conversion!(u8, isize); proper_subset_conversion!(u16, u32); proper_subset_conversion!(u16, u64); proper_subset_conversion!(u16, u128); proper_subset_conversion!(u16, usize); proper_subset_conversion!(u16, i32); proper_subset_conversion!(u16, i64); proper_subset_conversion!(u16, i128); proper_subset_conversion!(u32, u64); proper_subset_conversion!(u32, u128); proper_subset_conversion!(u32, i64); proper_subset_conversion!(u32, i128); proper_subset_conversion!(u64, u128); proper_subset_conversion!(u64, i128); proper_subset_conversion!(i8, i16); proper_subset_conversion!(i8, i32); proper_subset_conversion!(i8, i64); proper_subset_conversion!(i8, i128); proper_subset_conversion!(i8, isize); proper_subset_conversion!(i16, i32); proper_subset_conversion!(i16, i64); proper_subset_conversion!(i16, i128); proper_subset_conversion!(i16, isize); proper_subset_conversion!(i32, i64); proper_subset_conversion!(i32, i128); proper_subset_conversion!(i64, i128); no_containment_conversion!(u8, i8); no_containment_conversion!(u16, i8); no_containment_conversion!(u16, i16); no_containment_conversion!(u16, isize); no_containment_conversion!(u32, usize); no_containment_conversion!(u32, i8); no_containment_conversion!(u32, i16); no_containment_conversion!(u32, i32); no_containment_conversion!(u32, isize); no_containment_conversion!(u64, usize); no_containment_conversion!(u64, i8); no_containment_conversion!(u64, i16); no_containment_conversion!(u64, i32); no_containment_conversion!(u64, i64); no_containment_conversion!(u64, isize); no_containment_conversion!(u128, usize); no_containment_conversion!(u128, i8); no_containment_conversion!(u128, i16); no_containment_conversion!(u128, i32); no_containment_conversion!(u128, i64); no_containment_conversion!(u128, i128); no_containment_conversion!(u128, isize); no_containment_conversion!(usize, i8); no_containment_conversion!(usize, i16); no_containment_conversion!(usize, i32); no_containment_conversion!(usize, i64); no_containment_conversion!(usize, i128); no_containment_conversion!(usize, isize); no_containment_conversion!(i32, isize); no_containment_conversion!(i64, isize); no_containment_conversion!(i128, isize); fn primitive_float_rounding_from_unsigned( value: U, rm: RoundingMode, ) -> (T, Ordering) { if value == U::ZERO { return (T::ZERO, Equal); } let (mantissa, exponent, o) = sci_mantissa_and_exponent_round(value, rm).unwrap(); if let Some(f) = T::from_sci_mantissa_and_exponent(mantissa, i64::wrapping_from(exponent)) { (f, o) } else { match rm { Exact => { panic!("Value cannot be represented exactly as an {}", T::NAME) } Floor | Down | Nearest => (T::MAX_FINITE, Less), _ => (T::INFINITY, Greater), } } } fn unsigned_rounding_from_primitive_float( value: U, rm: RoundingMode, ) -> (T, Ordering) { assert!(!value.is_nan()); if value.is_infinite() { return if value.is_sign_positive() { match rm { Exact => { panic!("Value cannot be represented exactly as a {}", T::NAME) } Down | Floor | Nearest => (T::MAX, Less), _ => panic!("Cannot round away from positive infinity"), } } else { match rm { Exact => { panic!("Value cannot be represented exactly as a {}", T::NAME) } Down | Ceiling | Nearest => (T::ZERO, Greater), _ => panic!("Cannot round away from negative infinity"), } }; } if value == U::ZERO { return (T::ZERO, Equal); } if value.is_sign_negative() { return match rm { Exact => { panic!("Value cannot be represented exactly as a {}", T::NAME) } Ceiling | Down | Nearest => (T::ZERO, Greater), _ => panic!("Value is less than 0 and rounding mode is {rm}"), }; } let (mut mantissa, exponent) = value.integer_mantissa_and_exponent(); let (result, o) = if exponent <= 0 { let o = mantissa.shr_round_assign(-exponent, rm); (T::try_from(mantissa).ok(), o) } else { ( T::try_from(mantissa) .ok() .and_then(|n| n.arithmetic_checked_shl(exponent)), Equal, ) }; if let Some(n) = result { (n, o) } else { match rm { Exact => { panic!("Value cannot be represented exactly as a {}", T::NAME) } Floor | Down | Nearest => (T::MAX, Less), _ => panic!( "Value is greater than {}::MAX and rounding mode is {}", T::NAME, rm ), } } } #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct PrimitiveFloatFromUnsignedError; fn primitive_float_try_from_unsigned( value: U, ) -> Result { if value == U::ZERO { return Ok(T::ZERO); } let (mantissa, exponent, _) = sci_mantissa_and_exponent_round(value, Exact).ok_or(PrimitiveFloatFromUnsignedError)?; T::from_sci_mantissa_and_exponent(mantissa, i64::wrapping_from(exponent)) .ok_or(PrimitiveFloatFromUnsignedError) } #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum UnsignedFromFloatError { FloatInfiniteOrNan, FloatNegative, FloatNonIntegerOrOutOfRange, } fn unsigned_try_from_primitive_float( value: U, ) -> Result { if !value.is_finite() { Err(UnsignedFromFloatError::FloatInfiniteOrNan) } else if value == U::ZERO { Ok(T::ZERO) } else if value < U::ZERO { Err(UnsignedFromFloatError::FloatNegative) } else { let (mantissa, exponent) = value.integer_mantissa_and_exponent(); if exponent < 0 { Err(UnsignedFromFloatError::FloatNonIntegerOrOutOfRange) } else { T::try_from(mantissa) .or(Err(UnsignedFromFloatError::FloatNonIntegerOrOutOfRange)) .and_then(|n| { n.arithmetic_checked_shl(exponent) .ok_or(UnsignedFromFloatError::FloatNonIntegerOrOutOfRange) }) } } } fn primitive_float_convertible_from_unsigned< T: PrimitiveFloat, U: PrimitiveUnsigned + SciMantissaAndExponent, >( value: U, ) -> bool { if value == U::ZERO { return true; } let precision = (value >> value.trailing_zeros()).significant_bits(); precision <= T::MANTISSA_WIDTH + 1 && i64::wrapping_from(SciMantissaAndExponent::::sci_exponent(value)) <= T::MAX_EXPONENT } #[inline] fn unsigned_convertible_from_primitive_float( value: U, ) -> bool { value >= U::ZERO && value.is_integer() && (value == U::ZERO || value.sci_exponent() < i64::wrapping_from(T::WIDTH)) } macro_rules! impl_from_float_unsigned { ($u:ident) => { macro_rules! impl_from_float_unsigned_inner { ($f:ident) => { impl RoundingFrom<$u> for $f { /// Converts a value of an unsigned type to a value of a floating point type /// according to a specified [`RoundingMode`]. An [`Ordering`] is also returned, /// indicating whether the returned value is less than, equal to, or greater /// than the original value. /// /// - If the rounding mode is `Floor` or `Down`, the largest float less than or /// equal to the value is returned. /// - If the rounding mode is `Ceiling` or `Up`, the smallest float greater than /// or equal to the value is returned. /// - If the rounding mode is `Nearest`, then the nearest float is returned. If /// the value is exactly between two floats, the float with the zero /// least-significant bit in its representation is selected. If the value is /// larger than the maximum finite float (which can only happen when /// converting a `u128` to an `f32`), the maximum finite float is returned. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `rm` is `Exact` but `value` is not exactly equal to any value of /// the primitive float type. /// /// # Examples /// See [here](super::from#rounding_from). #[inline] fn rounding_from(value: $u, rm: RoundingMode) -> ($f, Ordering) { primitive_float_rounding_from_unsigned(value, rm) } } impl RoundingFrom<$f> for $u { /// Converts a value of a floating point type to a value of an unsigned type /// according to a specified [`RoundingMode`]. An [`Ordering`] is also returned, /// indicating whether the returned value is less than, equal to, or greater /// than the original value. /// /// - If the rounding mode is `Floor`, the largest number less than or equal to /// the value is returned. If the float is greater than the maximum /// representable unsigned value, the maximum unsigned value is returned. If /// the float is negative, the function panics. /// - If the rounding mode is `Ceiling`, the smallest number greater than or /// equal to the value is returned. If the float is negative, zero is /// returned. If the float is greater than the maximum representable unsigned /// value, the function panics. /// - If the rounding mode is `Down`, then the rounding proceeds as with `Floor` /// if the float is non-negative and as with `Ceiling` if the value is /// negative. /// - If the rounding mode is `Up`, then the rounding proceeds as with `Ceiling` /// if the value is non-negative and as with `Floor` if the value is negative. /// - If the rounding mode is `Nearest`, then the nearest value is returned. If /// the value is exactly between two numbers, the even one is selected. If the /// float is greater than the maximum representable unsigned value, the /// maximum unsigned value is returned. If the float is negative, zero is /// returned. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// - If `value` is `NaN`. /// - If `rm` is `Exact` but `value` is not exactly equal to any value of the /// unsigned type. /// - If `value` is greater than the maximum value of the unsigned type and `rm` /// is `Ceiling` or `Up`. /// - If `value` is negative and `rm` is `Floor` or `Up`. /// /// # Examples /// See [here](super::from#rounding_from). #[inline] fn rounding_from(value: $f, rm: RoundingMode) -> ($u, Ordering) { unsigned_rounding_from_primitive_float(value, rm) } } impl TryFrom<$u> for NiceFloat<$f> { type Error = PrimitiveFloatFromUnsignedError; /// Converts a value of an unsigned type to a value of a floating point type, /// returning an error if an exact conversion is not possible. /// /// The conversion succeeds if the unsigned value is not too large to represent /// (which can only happen when converting a [`u128`] to an [`f32`]) and the /// precision of the unsigned value is not too high. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::from#try_from). #[inline] fn try_from(value: $u) -> Result, Self::Error> { primitive_float_try_from_unsigned(value).map(NiceFloat) } } impl TryFrom> for $u { type Error = UnsignedFromFloatError; /// Converts a value of a floating point type to a value of an unsigned type, /// returning an error if an exact conversion is not possible. /// /// The conversion succeeds if the floating point value is an integer, not /// negative (negative zero is ok), and not too large. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::from#try_from). #[inline] fn try_from(value: NiceFloat<$f>) -> Result<$u, Self::Error> { unsigned_try_from_primitive_float(value.0) } } impl ConvertibleFrom<$u> for $f { /// Checks whether a value of an unsigned type is convertible to a floating /// point type. /// /// An exact conversion is possible if the unsigned value is not too large to /// represent (which can only happen when converting a [`u128`] to an [`f32`]) /// and the precision of the unsigned value is not too high. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::from#convertible_from). #[inline] fn convertible_from(value: $u) -> bool { primitive_float_convertible_from_unsigned::<$f, $u>(value) } } impl ConvertibleFrom<$f> for $u { /// Checks whether a value of a floating point type is convertible to an /// unsigned type. /// /// An exact conversion is possible if the floating point value is an integer, /// not negative (negative zero is ok), and not too large. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::from#convertible_from). #[inline] fn convertible_from(value: $f) -> bool { unsigned_convertible_from_primitive_float::<$u, $f>(value) } } }; } apply_to_primitive_floats!(impl_from_float_unsigned_inner); }; } apply_to_unsigneds!(impl_from_float_unsigned); #[inline] fn primitive_float_rounding_from_signed< U: PrimitiveUnsigned, S: PrimitiveSigned + UnsignedAbs, F: PrimitiveFloat + RoundingFrom, >( value: S, rm: RoundingMode, ) -> (F, Ordering) { let abs = value.unsigned_abs(); if value >= S::ZERO { F::rounding_from(abs, rm) } else { let (x, o) = F::rounding_from(abs, -rm); (-x, o.reverse()) } } fn signed_rounding_from_primitive_float< U: PrimitiveUnsigned + RoundingFrom, S: TryFrom + PrimitiveSigned + UnsignedAbs, F: PrimitiveFloat, >( value: F, rm: RoundingMode, ) -> (S, Ordering) { if value.is_infinite() { return if value.is_sign_positive() { match rm { Exact => { panic!("Value cannot be represented exactly as a {}", S::NAME) } Down | Floor | Nearest => (S::MAX, Less), _ => panic!("Cannot round away from extreme value"), } } else { match rm { Exact => { panic!("Value cannot be represented exactly as a {}", S::NAME) } Down | Nearest | Ceiling => (S::MIN, Greater), _ => panic!("Cannot round away from extreme value"), } }; } if value == F::ZERO { return (S::ZERO, Equal); } if value.is_sign_positive() { let (abs, o) = U::rounding_from(value, rm); if let Ok(n) = S::try_from(abs) { (n, o) } else { match rm { Exact => { panic!("Value cannot be represented exactly as an {}", S::NAME) } Floor | Down | Nearest => (S::MAX, Less), _ => panic!( "Value is greater than {}::MAX and rounding mode is {}", S::NAME, rm ), } } } else { let (abs, o) = U::rounding_from(-value, -rm); let n = if abs == S::MIN.unsigned_abs() { Some(S::MIN) } else { S::try_from(abs).ok().map(Neg::neg) }; if let Some(n) = n { (n, o.reverse()) } else { match rm { Exact => { panic!("Value cannot be represented exactly as an {}", S::NAME) } Ceiling | Down | Nearest => (S::MIN, Greater), _ => panic!( "Value is smaller than {}::MIN and rounding mode is {}", S::NAME, rm ), } } } } #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct PrimitiveFloatFromSignedError; #[inline] fn primitive_float_try_from_signed< U: PrimitiveUnsigned, S: PrimitiveSigned + UnsignedAbs, F: PrimitiveFloat, >( value: S, ) -> Result where NiceFloat: TryFrom, { let abs = value.unsigned_abs(); if value >= S::ZERO { NiceFloat::::try_from(abs) .map(|f| f.0) .map_err(|_| PrimitiveFloatFromSignedError) } else { NiceFloat::::try_from(abs) .map(|f| -f.0) .map_err(|_| PrimitiveFloatFromSignedError) } } #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum SignedFromFloatError { FloatInfiniteOrNan, FloatNonIntegerOrOutOfRange, } fn signed_try_from_primitive_float< U: TryFrom> + PrimitiveUnsigned, S: TryFrom + PrimitiveSigned + UnsignedAbs, F: PrimitiveFloat, >( value: F, ) -> Result { if !value.is_finite() { return Err(SignedFromFloatError::FloatInfiniteOrNan); } if value >= F::ZERO { S::try_from( U::try_from(NiceFloat(value)) .or(Err(SignedFromFloatError::FloatNonIntegerOrOutOfRange))?, ) .or(Err(SignedFromFloatError::FloatNonIntegerOrOutOfRange)) } else { let abs = U::try_from(NiceFloat(-value)) .or(Err(SignedFromFloatError::FloatNonIntegerOrOutOfRange))?; if abs == S::MIN.unsigned_abs() { Ok(S::MIN) } else { S::try_from(abs) .map(Neg::neg) .or(Err(SignedFromFloatError::FloatNonIntegerOrOutOfRange)) } } } #[inline] fn primitive_float_convertible_from_signed< U: PrimitiveUnsigned, S: PrimitiveSigned + UnsignedAbs, F: ConvertibleFrom + PrimitiveFloat, >( value: S, ) -> bool { F::convertible_from(value.unsigned_abs()) } fn signed_convertible_from_primitive_float( value: F, ) -> bool { if !value.is_integer() { return false; } if value >= F::ZERO { value == F::ZERO || value.sci_exponent() < i64::wrapping_from(U::WIDTH) - 1 } else { let exponent = value.sci_exponent(); let limit = i64::wrapping_from(U::WIDTH) - 1; value == F::ZERO || exponent < limit || exponent == limit && value == -F::from_sci_mantissa_and_exponent(F::ONE, exponent).unwrap() } } macro_rules! impl_from_float_signed { ($u:ident, $i:ident) => { macro_rules! impl_from_float_signed_inner { ($f:ident) => { impl RoundingFrom<$i> for $f { /// Converts a value of a signed type to a value of a floating point type /// according to a specified [`RoundingMode`]. An [`Ordering`] is also returned, /// indicating whether the returned value is less than, equal to, or greater /// than the original value. /// /// - If the rounding mode is `Floor`, the largest float less than or equal to /// the value is returned. /// - If the rounding mode is `Ceiling`, the smallest float greater than or /// equal to the value is returned. /// - If the rounding mode is `Down`, then the rounding proceeds as with `Floor` /// if the value is non-negative and as with `Ceiling` if the value is /// negative. /// - If the rounding mode is `Up`, then the rounding proceeds as with `Ceiling` /// if the value is non-negative and as with `Floor` if the value is negative. /// - If the rounding mode is `Nearest`, then the nearest float is returned. If /// the value is exactly between two floats, the float with the zero /// least-significant bit in its representation is selected. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `rm` is `Exact` but `value` is not exactly equal to any value of /// the primitive float type. /// /// # Examples /// See [here](super::from#rounding_from). #[inline] fn rounding_from(value: $i, rm: RoundingMode) -> ($f, Ordering) { primitive_float_rounding_from_signed::<$u, $i, $f>(value, rm) } } impl RoundingFrom<$f> for $i { /// Converts a value of a floating point type to a value of a signed type /// according to a specified [`RoundingMode`]. An [`Ordering`] is also returned, /// indicating whether the returned value is less than, equal to, or greater /// than the original value. /// /// - If the rounding mode is `Floor`, the largest number less than or equal to /// the value is returned. If the float is greater than the maximum /// representable signed value, the maximum signed value is returned. If the /// float is smaller than the minimum representable signed value, the function /// panics. /// - If the rounding mode is `Ceiling`, the smallest number greater than or /// equal to the value is returned. If the float is smaller than the minimum /// representable signed value, the minimum signed value is returned. If the /// float is greater than the maximum representable signed value, the function /// panics. /// - If the rounding mode is `Down`, then the rounding proceeds as with `Floor` /// if the float is non-negative and as with `Ceiling` if the value is /// negative. /// - If the rounding mode is `Up`, then the rounding proceeds as with `Ceiling` /// if the value is non-negative and as with `Floor` if the value is negative. /// - If the rounding mode is `Nearest`, then the nearest value is returned. If /// the value is exactly between two numbers, the even one is selected. If the /// float is greater than the maximum representable signed value, the maximum /// signed value is returned. If the float is smaller than the minimum /// representable signed value, the minimum signed value is returned. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// - If `value` is `NaN`. /// - If `rm` is `Exact` but `value` is not exactly equal to any value of the /// unsigned type. /// - If `value` is greater than the maximum value of the signed type and `rm` /// is `Ceiling` or `Up`. /// - If `value` is smaller than the minimum value of the signed type and `rm` /// is `Floor` or `Up`. /// /// # Examples /// See [here](super::from#rounding_from). #[inline] fn rounding_from(value: $f, rm: RoundingMode) -> ($i, Ordering) { signed_rounding_from_primitive_float::<$u, $i, $f>(value, rm) } } impl TryFrom<$i> for NiceFloat<$f> { type Error = PrimitiveFloatFromSignedError; /// Converts a value of a signed type to a value of a floating point type, /// returning an error if an exact conversion is not possible. /// /// The conversion succeeds if the precision of the signed value is not too /// high. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::from#try_from). #[inline] fn try_from(value: $i) -> Result, Self::Error> { primitive_float_try_from_signed(value).map(NiceFloat) } } impl TryFrom> for $i { type Error = SignedFromFloatError; /// Converts a value of a floating point type to a value of a signed type, /// returning an error if an exact conversion is not possible. /// /// The conversion succeeds if the floating point value is an integer and not /// too large or too small. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::from#try_from). #[inline] fn try_from(value: NiceFloat<$f>) -> Result<$i, Self::Error> { signed_try_from_primitive_float::<$u, $i, $f>(value.0) } } impl ConvertibleFrom<$i> for $f { /// Checks whether a value of a signed type is convertible to a floating point /// type. /// /// An exact conversion is possible if the precision of the signed value is not /// too high. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::from#convertible_from). #[inline] fn convertible_from(value: $i) -> bool { primitive_float_convertible_from_signed::<$u, $i, $f>(value) } } impl ConvertibleFrom<$f> for $i { /// Checks whether a value of a floating point type is convertible to a signed /// type. /// /// An exact conversion is possible if the floating point value is an integer /// and not too large or too small. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::from#convertible_from). #[inline] fn convertible_from(value: $f) -> bool { signed_convertible_from_primitive_float::<$u, $f>(value) } } }; } apply_to_primitive_floats!(impl_from_float_signed_inner); }; } apply_to_unsigned_signed_pairs!(impl_from_float_signed); malachite-base-0.4.16/src/num/conversion/half.rs000064400000000000000000000066041046102023000176140ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::{HasHalf, JoinHalves, SplitInHalf, WrappingFrom}; #[inline] fn join_halves + PrimitiveUnsigned, H: PrimitiveUnsigned>(upper: H, lower: H) -> T { T::from(upper) << H::WIDTH | T::from(lower) } #[inline] fn upper_half>(x: &T) -> H { H::wrapping_from(*x >> H::WIDTH) } macro_rules! impl_half_traits { ($t:ident, $ht: ident) => { impl HasHalf for $t { /// The primitive integer type whose width is half of `Self`'s. type Half = $ht; } impl JoinHalves for $t { /// Joins two unsigned integers to form an unsigned integer with twice the width. /// /// Let $W$ be the width of `Self` (the output type). /// /// $f(x, y) = 2^{W/2} x + y$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::half#join_halves). #[inline] fn join_halves(upper: Self::Half, lower: Self::Half) -> Self { join_halves(upper, lower) } } impl SplitInHalf for $t { /// Extracts the lower, or least significant, half of an unsigned integer. /// /// Let $W$ be the width of `Self` (the input type). /// /// $f(n) = m$, where $m < 2^{W/2}$ and $n + 2^{W/2} k = m$ for some $k \in \Z$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::half#lower_half). #[inline] fn lower_half(&self) -> Self::Half { $ht::wrapping_from(*self) } /// Extracts the upper, or most-significant, half of an unsigned integer. /// /// Let $W$ be the width of `Self` (the input type). /// /// $f(n) = \lfloor \frac{n}{2^{W/2}} \rfloor$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::half#upper_half). #[inline] fn upper_half(&self) -> Self::Half { upper_half(self) } } }; } impl_half_traits!(u16, u8); impl_half_traits!(u32, u16); impl_half_traits!(u64, u32); impl_half_traits!(u128, u64); #[inline] fn wide_lower_half(x: T) -> T { x.mod_power_of_2(T::WIDTH >> 1) } #[inline] pub(crate) fn wide_upper_half(x: T) -> T { x >> (T::WIDTH >> 1) } #[inline] pub(crate) fn wide_split_in_half(x: T) -> (T, T) { (wide_upper_half(x), wide_lower_half(x)) } #[inline] pub(crate) fn wide_join_halves(hi: T, lo: T) -> T { (hi << (T::WIDTH >> 1)) | lo } malachite-base-0.4.16/src/num/conversion/is_integer.rs000064400000000000000000000045531046102023000210330ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::basic::floats::PrimitiveFloat; use crate::num::conversion::traits::{IsInteger, WrappingFrom}; use crate::num::logic::traits::TrailingZeros; fn is_integer_float(x: T) -> bool { if x.is_nan() || x.is_infinite() { false } else if x == T::ZERO { true } else { let (raw_mantissa, raw_exponent) = x.raw_mantissa_and_exponent(); raw_exponent != 0 && i64::wrapping_from( raw_exponent + if raw_mantissa == 0 { T::MANTISSA_WIDTH } else { TrailingZeros::trailing_zeros(raw_mantissa) }, ) > -T::MIN_EXPONENT } } macro_rules! impl_is_integer_primitive_int { ($t:ident) => { impl IsInteger for $t { /// Determines whether a value is an integer. /// /// For primitive integer types this always returns `true`. /// /// $f(x) = \textrm{true}$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::is_integer#is_integer). #[inline] fn is_integer(self) -> bool { true } } }; } apply_to_primitive_ints!(impl_is_integer_primitive_int); macro_rules! impl_is_integer_primitive_float { ($t:ident) => { impl IsInteger for $t { /// Determines whether a value is an integer. /// /// $f(x) = (x \in \Z)$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::is_integer#is_integer). #[inline] fn is_integer(self) -> bool { is_integer_float(self) } } }; } apply_to_primitive_floats!(impl_is_integer_primitive_float); malachite-base-0.4.16/src/num/conversion/mantissa_and_exponent.rs000064400000000000000000001101521046102023000232550ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{ ArithmeticCheckedShl, DivisibleByPowerOf2, ModPowerOf2, ShrRound, }; use crate::num::basic::floats::PrimitiveFloat; use crate::num::basic::integers::PrimitiveInt; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::{ ExactFrom, IntegerMantissaAndExponent, RawMantissaAndExponent, SciMantissaAndExponent, WrappingFrom, }; use crate::num::logic::traits::{BitAccess, LeadingZeros, LowMask, SignificantBits, TrailingZeros}; use crate::rounding_modes::RoundingMode::{self, *}; use core::cmp::Ordering::{self, *}; fn raw_mantissa_and_exponent(x: T) -> (u64, u64) { let bits = x.to_bits(); ( bits.mod_power_of_2(T::MANTISSA_WIDTH), (bits >> T::MANTISSA_WIDTH).mod_power_of_2(T::EXPONENT_WIDTH), ) } #[inline] fn raw_mantissa(x: T) -> u64 { x.to_bits().mod_power_of_2(T::MANTISSA_WIDTH) } #[inline] fn raw_exponent(x: T) -> u64 { (x.to_bits() >> T::MANTISSA_WIDTH).mod_power_of_2(T::EXPONENT_WIDTH) } fn from_raw_mantissa_and_exponent(raw_mantissa: u64, raw_exponent: u64) -> T { assert!(raw_mantissa.significant_bits() <= T::MANTISSA_WIDTH); assert!(raw_exponent.significant_bits() <= T::EXPONENT_WIDTH); let x = T::from_bits((raw_exponent << T::MANTISSA_WIDTH) | raw_mantissa); // Only output the canonical NaN if x.is_nan() { T::NAN } else { x } } fn integer_mantissa_and_exponent_primitive_float(x: T) -> (u64, i64) { assert!(x.is_finite()); assert!(x != T::ZERO); let (mut raw_mantissa, raw_exponent) = x.raw_mantissa_and_exponent(); if raw_exponent == 0 { let trailing_zeros = raw_mantissa.trailing_zeros(); ( raw_mantissa >> trailing_zeros, i64::wrapping_from(trailing_zeros) + T::MIN_EXPONENT, ) } else { raw_mantissa.set_bit(T::MANTISSA_WIDTH); let trailing_zeros = TrailingZeros::trailing_zeros(raw_mantissa); ( raw_mantissa >> trailing_zeros, i64::wrapping_from(raw_exponent + trailing_zeros) + T::MIN_EXPONENT - 1, ) } } fn integer_mantissa_primitive_float(x: T) -> u64 { assert!(x.is_finite()); assert!(x != T::ZERO); let (mut raw_mantissa, raw_exponent) = x.raw_mantissa_and_exponent(); if raw_exponent != 0 { raw_mantissa.set_bit(T::MANTISSA_WIDTH); } raw_mantissa >> raw_mantissa.trailing_zeros() } fn integer_exponent_primitive_float(x: T) -> i64 { assert!(x.is_finite()); assert!(x != T::ZERO); let (raw_mantissa, raw_exponent) = x.raw_mantissa_and_exponent(); if raw_exponent == 0 { i64::wrapping_from(raw_mantissa.trailing_zeros()) + T::MIN_EXPONENT } else { i64::wrapping_from( raw_exponent + if raw_mantissa == 0 { T::MANTISSA_WIDTH } else { TrailingZeros::trailing_zeros(raw_mantissa) }, ) + T::MIN_EXPONENT - 1 } } fn from_integer_mantissa_and_exponent_primitive_float( integer_mantissa: u64, integer_exponent: i64, ) -> Option { if integer_mantissa == 0 { return Some(T::ZERO); } let trailing_zeros = integer_mantissa.trailing_zeros(); let (integer_mantissa, adjusted_exponent) = ( integer_mantissa >> trailing_zeros, integer_exponent + i64::wrapping_from(trailing_zeros), ); let mantissa_bits = integer_mantissa.significant_bits(); let sci_exponent = adjusted_exponent.checked_add(i64::exact_from(mantissa_bits))? - 1; let mut raw_mantissa; let raw_exponent; if sci_exponent < T::MIN_EXPONENT || sci_exponent > T::MAX_EXPONENT { return None; } else if sci_exponent < T::MIN_NORMAL_EXPONENT { if adjusted_exponent < T::MIN_EXPONENT { return None; } raw_exponent = 0; raw_mantissa = integer_mantissa << (adjusted_exponent - T::MIN_EXPONENT); } else if mantissa_bits > T::MANTISSA_WIDTH + 1 { return None; } else { raw_exponent = u64::exact_from(sci_exponent + i64::low_mask(T::EXPONENT_WIDTH - 1)); raw_mantissa = integer_mantissa << (T::MANTISSA_WIDTH + 1 - mantissa_bits); raw_mantissa.clear_bit(T::MANTISSA_WIDTH); } Some(T::from_raw_mantissa_and_exponent( raw_mantissa, raw_exponent, )) } fn sci_mantissa_and_exponent_primitive_float(x: T) -> (T, i64) { assert!(x.is_finite()); assert!(x != T::ZERO); let (raw_mantissa, raw_exponent) = x.raw_mantissa_and_exponent(); // Note that Self::MAX_EXPONENT is also the raw exponent of 1.0. if raw_exponent == 0 { let leading_zeros = LeadingZeros::leading_zeros(raw_mantissa) - (u64::WIDTH - T::MANTISSA_WIDTH); let mut mantissa = raw_mantissa << (leading_zeros + 1); mantissa.clear_bit(T::MANTISSA_WIDTH); ( T::from_raw_mantissa_and_exponent(mantissa, u64::wrapping_from(T::MAX_EXPONENT)), i64::wrapping_from(T::MANTISSA_WIDTH - leading_zeros - 1) + T::MIN_EXPONENT, ) } else { ( T::from_raw_mantissa_and_exponent(raw_mantissa, u64::wrapping_from(T::MAX_EXPONENT)), i64::wrapping_from(raw_exponent) - T::MAX_EXPONENT, ) } } fn sci_mantissa_primitive_float(x: T) -> T { assert!(x.is_finite()); assert!(x != T::ZERO); let (mut mantissa, raw_exponent) = x.raw_mantissa_and_exponent(); // Note that Self::MAX_EXPONENT is also the raw exponent of 1.0. if raw_exponent == 0 { mantissa <<= LeadingZeros::leading_zeros(mantissa) - (u64::WIDTH - T::MANTISSA_WIDTH) + 1; mantissa.clear_bit(T::MANTISSA_WIDTH); } T::from_raw_mantissa_and_exponent(mantissa, u64::wrapping_from(T::MAX_EXPONENT)) } fn sci_exponent_primitive_float(x: T) -> i64 { assert!(x.is_finite()); assert!(x != T::ZERO); let (raw_mantissa, raw_exponent) = x.raw_mantissa_and_exponent(); // Note that Self::MAX_EXPONENT is also the raw exponent of 1.0. if raw_exponent == 0 { i64::wrapping_from(u64::WIDTH - LeadingZeros::leading_zeros(raw_mantissa) - 1) + T::MIN_EXPONENT } else { i64::wrapping_from(raw_exponent) - T::MAX_EXPONENT } } #[allow(clippy::wrong_self_convention)] fn from_sci_mantissa_and_exponent_primitive_float( sci_mantissa: T, sci_exponent: i64, ) -> Option { assert!(sci_mantissa.is_finite()); assert!(sci_mantissa > T::ZERO); if sci_exponent < T::MIN_EXPONENT || sci_exponent > T::MAX_EXPONENT { return None; } let (mut orig_mantissa, orig_exponent) = sci_mantissa.raw_mantissa_and_exponent(); // Note that Self::MAX_EXPONENT is also the raw exponent of 1.0. if orig_exponent != u64::wrapping_from(T::MAX_EXPONENT) { return None; } if sci_exponent < T::MIN_NORMAL_EXPONENT { let shift = T::MIN_NORMAL_EXPONENT - sci_exponent; if orig_mantissa.divisible_by_power_of_2(u64::wrapping_from(shift)) { orig_mantissa.set_bit(T::MANTISSA_WIDTH); Some(T::from_raw_mantissa_and_exponent(orig_mantissa >> shift, 0)) } else { None } } else { Some(T::from_raw_mantissa_and_exponent( orig_mantissa, u64::wrapping_from(sci_exponent + T::MAX_EXPONENT), )) } } /// Returns the scientific mantissa and exponent of an unsinged value. An [`Ordering`] is also /// returned, indicating whether the mantissa and exponent correspond to a value less than, equal /// to, or greater than the original value. /// /// When $x$ is positive, we can write $x = 2^{e_s}m_s$, where $e_s$ is an integer and $m_s$ is a /// rational number with $1 \leq m_s < 2$. We represent the rational mantissa as a float. The /// conversion might not be exact, so we round to the nearest float using the provided rounding /// mode. If the rounding mode is `Exact` but the conversion is not exact, `None` is returned. /// $$ /// f(x, r) \approx (\frac{x}{2^{\lfloor \log_2 x \rfloor}}, \lfloor \log_2 x \rfloor). /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::num::basic::floats::PrimitiveFloat; /// use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; /// use malachite_base::num::conversion::mantissa_and_exponent::*; /// use malachite_base::num::float::NiceFloat; /// use malachite_base::rounding_modes::RoundingMode::{self, *}; /// use std::cmp::Ordering::{self, *}; /// /// fn test( /// n: T, /// rm: RoundingMode, /// out: Option<(U, u64, Ordering)>, /// ) { /// assert_eq!( /// sci_mantissa_and_exponent_round(n, rm).map(|(m, e, o)| (NiceFloat(m), e, o)), /// out.map(|(m, e, o)| (NiceFloat(m), e, o)) /// ); /// } /// test::(3, Down, Some((1.5, 1, Equal))); /// test::(3, Ceiling, Some((1.5, 1, Equal))); /// test::(3, Up, Some((1.5, 1, Equal))); /// test::(3, Nearest, Some((1.5, 1, Equal))); /// test::(3, Exact, Some((1.5, 1, Equal))); /// /// test::(123, Floor, Some((1.921875, 6, Equal))); /// test::(123, Down, Some((1.921875, 6, Equal))); /// test::(123, Ceiling, Some((1.921875, 6, Equal))); /// test::(123, Up, Some((1.921875, 6, Equal))); /// test::(123, Nearest, Some((1.921875, 6, Equal))); /// test::(123, Exact, Some((1.921875, 6, Equal))); /// /// test::(1000000000, Nearest, Some((1.8626451, 29, Equal))); /// test::(999999999, Nearest, Some((1.8626451, 29, Greater))); /// ``` pub fn sci_mantissa_and_exponent_round( x: T, rm: RoundingMode, ) -> Option<(U, u64, Ordering)> { assert_ne!(x, T::ZERO); let significant_bits = x.significant_bits(); let mut exponent = significant_bits - 1; let (mut raw_mantissa, o) = if significant_bits > U::MANTISSA_WIDTH { let shift = significant_bits - U::MANTISSA_WIDTH - 1; if rm == Exact && TrailingZeros::trailing_zeros(x) < shift { return None; } let (s, o) = x.shr_round(shift, rm); (s.wrapping_into(), o) } else { let x: u64 = x.wrapping_into(); (x << (U::MANTISSA_WIDTH - significant_bits + 1), Equal) }; if raw_mantissa.significant_bits() == U::MANTISSA_WIDTH + 2 { // Rounding up to a power of 2 raw_mantissa >>= 1; exponent += 1; } raw_mantissa.clear_bit(U::MANTISSA_WIDTH); // Note that Self::MAX_EXPONENT is also the raw exponent of 1.0. Some(( U::from_raw_mantissa_and_exponent(raw_mantissa, u64::wrapping_from(U::MAX_EXPONENT)), exponent, o, )) } /// Constructs a primitive integer from its scientific mantissa and exponent. An [`Ordering`] is /// also returned, indicating whether the returned value is less than, equal to, or greater than the /// exact value implied by the input. /// /// When $x$ is positive, we can write $x = 2^{e_s}m_s$, where $e_s$ is an integer and $m_s$ is a /// rational number with $1 \leq m_s < 2$. Here, the rational mantissa is provided as a float. If /// the mantissa is outside the range $[1, 2)$, `None` is returned. /// /// Some combinations of mantissas and exponents do not specify an integer, in which case the /// resulting value is rounded to an integer using the specified rounding mode. If the rounding mode /// is `Exact` but the input does not exactly specify an integer, `None` is returned. /// /// $$ /// f(x, r) \approx 2^{e_s}m_s. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `sci_mantissa` is zero. /// /// # Examples /// ``` /// use malachite_base::num::basic::floats::PrimitiveFloat; /// use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; /// use malachite_base::num::conversion::mantissa_and_exponent::*; /// use malachite_base::rounding_modes::RoundingMode::{self, *}; /// use std::cmp::Ordering::{self, *}; /// /// fn test( /// mantissa: U, /// exponent: u64, /// rm: RoundingMode, /// out: Option<(T, Ordering)>, /// ) { /// assert_eq!( /// from_sci_mantissa_and_exponent_round::(mantissa, exponent, rm), /// out /// ); /// } /// test::(1.5, 1, Floor, Some((3, Equal))); /// test::(1.5, 1, Down, Some((3, Equal))); /// test::(1.5, 1, Ceiling, Some((3, Equal))); /// test::(1.5, 1, Up, Some((3, Equal))); /// test::(1.5, 1, Nearest, Some((3, Equal))); /// test::(1.5, 1, Exact, Some((3, Equal))); /// /// test::(1.51, 1, Floor, Some((3, Less))); /// test::(1.51, 1, Down, Some((3, Less))); /// test::(1.51, 1, Ceiling, Some((4, Greater))); /// test::(1.51, 1, Up, Some((4, Greater))); /// test::(1.51, 1, Nearest, Some((3, Less))); /// test::(1.51, 1, Exact, None); /// /// test::(2.0, 1, Floor, None); /// test::(10.0, 1, Floor, None); /// test::(0.5, 1, Floor, None); /// ``` pub fn from_sci_mantissa_and_exponent_round( sci_mantissa: U, sci_exponent: u64, rm: RoundingMode, ) -> Option<(T, Ordering)> { assert_ne!(sci_mantissa, U::ZERO); if sci_mantissa < U::ONE || sci_mantissa >= U::TWO { return None; } let mut raw_mantissa = sci_mantissa.raw_mantissa(); raw_mantissa.set_bit(U::MANTISSA_WIDTH); if sci_exponent >= U::MANTISSA_WIDTH { T::try_from(raw_mantissa) .ok()? .arithmetic_checked_shl(sci_exponent - U::MANTISSA_WIDTH) .map(|n| (n, Equal)) } else { let shift = U::MANTISSA_WIDTH - sci_exponent; if rm == Exact && TrailingZeros::trailing_zeros(raw_mantissa) < shift { return None; } let (s, o) = raw_mantissa.shr_round(shift, rm); T::try_from(s).ok().map(|s| (s, o)) } } macro_rules! impl_mantissa_and_exponent_unsigned { ($t:ident) => { impl IntegerMantissaAndExponent<$t, u64> for $t { /// Returns the integer mantissa and exponent. /// /// When $x$ is nonzero, we can write $x = 2^{e_i}m_i$, where $e_i$ is an integer and /// $m_i$ is an odd integer. /// $$ /// f(x) = (\frac{|x|}{2^{e_i}}, e_i), /// $$ /// where $e_i$ is the unique integer such that $x/2^{e_i}$ is an odd integer. /// /// The inverse operation is /// [`from_integer_mantissa_and_exponent`](Self::from_integer_mantissa_and_exponent). /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` is zero. /// /// # Examples /// See [here](super::mantissa_and_exponent#integer_mantissa_and_exponent). #[inline] fn integer_mantissa_and_exponent(self) -> ($t, u64) { assert_ne!(self, 0); let exponent = TrailingZeros::trailing_zeros(self); (self >> exponent, exponent) } /// Returns the integer mantissa. /// /// When $x$ is nonzero, we can write $x = 2^{e_i}m_i$, where $e_i$ is an integer and /// $m_i$ is an odd integer. /// $$ /// f(x) = \frac{|x|}{2^{e_i}}, /// $$ /// where $e_i$ is the unique integer such that $x/2^{e_i}$ is an odd integer. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` is zero. /// /// # Examples /// See [here](super::mantissa_and_exponent#integer_mantissa). #[inline] fn integer_mantissa(self) -> $t { assert_ne!(self, 0); self >> self.trailing_zeros() } /// Returns the integer exponent. /// /// When $x$ is nonzero, we can write $x = 2^{e_i}m_i$, where $e_i$ is an integer and /// $m_i$ is an odd integer. /// $$ /// f(x) = e_i, /// $$ /// where $e_i$ is the unique integer such that $x/2^{e_i}$ is an odd integer. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` is zero. /// /// # Examples /// See [here](super::mantissa_and_exponent#integer_exponent). #[inline] fn integer_exponent(self) -> u64 { assert_ne!(self, 0); TrailingZeros::trailing_zeros(self) } /// Constructs an unsigned primitive integer from its integer mantissa and exponent. /// /// When $x$ is nonzero, we can write $x = 2^{e_i}m_i$, where $e_i$ is an integer and /// $m_i$ is an odd integer. /// /// $$ /// f(x) = 2^{e_i}m_i, /// $$ /// or `None` if the result cannot be exactly represented as an integer of the desired /// type (this happens if the exponent is too large). /// /// The input does not have to be reduced; that is to say, the mantissa does not have to /// be odd. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::mantissa_and_exponent#from_integer_mantissa_and_exponent). #[inline] fn from_integer_mantissa_and_exponent( integer_mantissa: $t, integer_exponent: u64, ) -> Option<$t> { integer_mantissa.arithmetic_checked_shl(integer_exponent) } } }; } apply_to_unsigneds!(impl_mantissa_and_exponent_unsigned); macro_rules! impl_sci_mantissa_and_exponent_unsigned { ($u:ident) => { macro_rules! impl_sci_mantissa_and_exponent_unsigned_inner { ($f:ident) => { impl SciMantissaAndExponent<$f, u64> for $u { /// Returns the scientific mantissa and exponent. /// /// When $x$ is positive, we can write $x = 2^{e_s}m_s$, where $e_s$ is an /// integer and $m_s$ is a rational number with $1 \leq m_s < 2$. We represent /// the rational mantissa as a float. The conversion might not be exact, so we /// round to the nearest float using the `Nearest` rounding mode. To use other /// rounding modes, use [`sci_mantissa_and_exponent_round`]. /// /// If the result cannot be expressed as an integer of the specified type, /// `None` is returned. /// $$ /// f(x) \approx (\frac{x}{2^{\lfloor \log_2 x \rfloor}}, /// \lfloor \log_2 x \rfloor). /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` is zero. /// /// # Examples /// See [here](super::mantissa_and_exponent#sci_mantissa_and_exponent). #[inline] fn sci_mantissa_and_exponent(self) -> ($f, u64) { let (m, e, _) = sci_mantissa_and_exponent_round(self, Nearest).unwrap(); (m, e) } /// Constructs a primitive integer from its scientific mantissa and exponent. /// /// When $x$ is positive, we can write $x = 2^{e_s}m_s$, where $e_s$ is an /// integer and $m_s$ is a rational number with $1 \leq m_s < 2$. Here, the /// rational mantissa is provided as a float. If the mantissa is outside the /// range $[1, 2)$, `None` is returned. /// /// Some combinations of mantissas and exponents do not specify an integer, in /// which case the resulting value is rounded to an integer using the `Nearest` /// rounding mode. To specify other rounding modes, use /// [`from_sci_mantissa_and_exponent_round`]. /// /// $$ /// f(x) \approx 2^{e_s}m_s. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `sci_mantissa` is zero. /// /// # Examples /// See [here](super::mantissa_and_exponent#from_sci_mantissa_and_exponent). #[inline] fn from_sci_mantissa_and_exponent( sci_mantissa: $f, sci_exponent: u64, ) -> Option<$u> { from_sci_mantissa_and_exponent_round(sci_mantissa, sci_exponent, Nearest) .map(|p| p.0) } } }; } apply_to_primitive_floats!(impl_sci_mantissa_and_exponent_unsigned_inner); }; } apply_to_unsigneds!(impl_sci_mantissa_and_exponent_unsigned); macro_rules! impl_mantissa_and_exponent_primitive_float { ($t:ident) => { impl RawMantissaAndExponent for $t { /// Returns the raw mantissa and exponent. /// /// The raw exponent and raw mantissa are the actual bit patterns used to represent the /// components of `self`. When `self` is nonzero and finite, the raw exponent $e_r$ is /// an integer in $[0, 2^E-2]$ and the raw mantissa $m_r$ is an integer in $[0, 2^M-1]$. /// /// When `self` is nonzero and finite, $f(x) = (m_r, e_r)$, where /// $$ /// m_r = \\begin{cases} /// 2^{M+2^{E-1}-2}|x| & \text{if} \\quad |x| < 2^{2-2^{E-1},} \\\\ /// 2^M \left ( \frac{|x|}{2^{\lfloor \log_2 |x| \rfloor}}-1\right ) & /// \textrm{otherwise}, /// \\end{cases} /// $$ /// and /// $$ /// e_r = \\begin{cases} /// 0 & \text{if} \\quad |x| < 2^{2-2^{E-1}} \\\\ /// \lfloor \log_2 |x| \rfloor + 2^{E-1} - 1 & \textrm{otherwise}. /// \\end{cases} /// $$ /// and $M$ and $E$ are the mantissa width and exponent width, respectively. /// /// For zeros, infinities, or `NaN`, refer to [IEEE /// 754](https://standards.ieee.org/ieee/754/6210/) or look at the examples below. /// /// The inverse operation is [`Self::from_raw_mantissa_and_exponent`]. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::mantissa_and_exponent#raw_mantissa_and_exponent). #[inline] fn raw_mantissa_and_exponent(self) -> (u64, u64) { raw_mantissa_and_exponent(self) } /// Returns the raw mantissa. /// /// The raw mantissa is the actual bit pattern used to represent the mantissa of `self`. /// When `self` is nonzero and finite, it is an integer in $[0, 2^M-1]$. /// /// When `self` is nonzero and finite, /// $$ /// f(x) = \\begin{cases} /// 2^{M+2^{E-1}-2}|x| & \text{if} \\quad |x| < 2^{2-2^{E-1}}, \\\\ /// 2^M \left ( \frac{|x|}{2^{\lfloor \log_2 |x| \rfloor}}-1\right ) /// & \textrm{otherwise}, /// \\end{cases} /// $$ /// where $M$ and $E$ are the mantissa width and exponent width, respectively. /// /// For zeros, infinities, or `NaN`, refer to [IEEE /// 754](https://standards.ieee.org/ieee/754/6210/) or look at the examples below. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::mantissa_and_exponent#raw_mantissa). #[inline] fn raw_mantissa(self) -> u64 { raw_mantissa(self) } /// Returns the raw exponent. /// /// The raw exponent is the actual bit pattern used to represent the exponent of `self`. /// When `self` is nonzero and finite, it is an integer in $[0, 2^E-2]$. /// /// When `self` is nonzero and finite, /// $$ /// f(x) = \\begin{cases} /// 0 & \text{if} \\quad |x| < 2^{2-2^{E-1}}, \\\\ /// \lfloor \log_2 |x| \rfloor + 2^{E-1} - 1 & \textrm{otherwise}, /// \\end{cases} /// $$ /// where $M$ and $E$ are the mantissa width and exponent width, respectively. /// /// For zeros, infinities, or `NaN`, refer to [IEEE /// 754](https://standards.ieee.org/ieee/754/6210/) or look at the examples below. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::mantissa_and_exponent#raw_exponent). #[inline] fn raw_exponent(self) -> u64 { raw_exponent(self) } /// Constructs a float from its raw mantissa and exponent. /// /// The raw exponent and raw mantissa are the actual bit patterns used to represent the /// components of a float. When the float is nonzero and finite, the raw exponent $e_r$ /// is an integer in $[0, 2^E-2]$ and the raw mantissa $m_r$ is an integer in $[0, /// 2^M-1]$. /// /// When the exponent is not `2^E-1`, /// $$ /// f(m_r, e_r) = \\begin{cases} /// 2^{2-2^{E-1}-M}m_r & \text{if} \\quad e_r = 0, \\\\ /// 2^{e_r-2^{E-1}+1}(2^{-M}m_r+1) & \textrm{otherwise}, /// \\end{cases} /// $$ /// where $M$ and $E$ are the mantissa width and exponent width, respectively. /// /// For zeros, infinities, or `NaN`, refer to [IEEE /// 754](https://standards.ieee.org/ieee/754/6210/) or look at the examples below. /// /// This function only outputs a single, canonical, `NaN`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::mantissa_and_exponent#from_raw_mantissa_and_exponent). #[inline] fn from_raw_mantissa_and_exponent(raw_mantissa: u64, raw_exponent: u64) -> $t { from_raw_mantissa_and_exponent(raw_mantissa, raw_exponent) } } impl IntegerMantissaAndExponent for $t { /// Returns the integer mantissa and exponent. /// /// When $x$ is positive, nonzero, and finite, we can write $x = 2^{e_i}m_i$, where /// $e_i$ is an integer and $m_i$ is an odd integer. /// $$ /// f(x) = (\frac{|x|}{2^{e_i}}, e_i), /// $$ /// where $e_i$ is the unique integer such that $x/2^{e_i}$ is an odd integer. /// /// The inverse operation is [`Self::from_integer_mantissa_and_exponent`]. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` is zero, infinite, or `NaN`. /// /// # Examples /// See [here](super::mantissa_and_exponent#integer_mantissa_and_exponent). #[inline] fn integer_mantissa_and_exponent(self) -> (u64, i64) { integer_mantissa_and_exponent_primitive_float(self) } /// Returns the integer mantissa. /// /// When $x$ is positive, nonzero, and finite, we can write $x = 2^{e_i}m_i$, where /// $e_i$ is an integer and $m_i$ is an odd integer. /// $$ /// f(x) = \frac{|x|}{2^{e_i}}, /// $$ /// where $e_i$ is the unique integer such that $x/2^{e_i}$ is an odd integer. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` is zero, infinite, or `NaN`. /// /// # Examples /// See [here](super::mantissa_and_exponent#integer_mantissa). #[inline] fn integer_mantissa(self) -> u64 { integer_mantissa_primitive_float(self) } /// Returns the integer exponent. /// /// When $x$ is positive, nonzero, and finite, we can write $x = 2^{e_i}m_i$, where /// $e_i$ is an integer and $m_i$ is an odd integer. /// $$ /// f(x) = e_i, /// $$ /// where $e_i$ is the unique integer such that $x/2^{e_i}$ is an odd integer. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` is zero, infinite, or `NaN`. /// /// # Examples /// See [here](super::mantissa_and_exponent#integer_exponent). #[inline] fn integer_exponent(self) -> i64 { integer_exponent_primitive_float(self) } /// Constructs a float from its integer mantissa and exponent. /// /// When $x$ is positive, nonzero, and finite, we can write $x = 2^{e_i}m_i$, where /// $e_i$ is an integer and $m_i$ is an odd integer. /// /// $$ /// f(x) = 2^{e_i}m_i, /// $$ /// or `None` if the result cannot be exactly represented as a float of the desired type /// (this happens if the exponent is too large or too small, or if the mantissa's /// precision is too high for the exponent). /// /// The input does not have to be reduced; that is to say, the mantissa does not have to /// be odd. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::mantissa_and_exponent#from_integer_mantissa_and_exponent). #[inline] fn from_integer_mantissa_and_exponent( integer_mantissa: u64, integer_exponent: i64, ) -> Option<$t> { from_integer_mantissa_and_exponent_primitive_float( integer_mantissa, integer_exponent, ) } } impl SciMantissaAndExponent<$t, i64> for $t { /// Returns the scientific mantissa and exponent. /// /// When $x$ is positive, nonzero, and finite, we can write $x = 2^{e_s}m_s$, where /// $e_s$ is an integer and $m_s$ is a rational number with $1 \leq m_s < 2$. If $x$ is /// a valid float, the scientific mantissa $m_s$ is always exactly representable as a /// float of the same type. We have /// $$ /// f(x) = (\frac{x}{2^{\lfloor \log_2 x \rfloor}}, \lfloor \log_2 x \rfloor). /// $$ /// /// The inverse operation is `from_sci_mantissa_and_exponent`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` is zero, infinite, or `NaN`. /// /// # Examples /// See [here](super::mantissa_and_exponent#sci_mantissa_and_exponent). #[inline] fn sci_mantissa_and_exponent(self) -> ($t, i64) { sci_mantissa_and_exponent_primitive_float(self) } /// Returns the scientific mantissa. /// /// When $x$ is positive, nonzero, and finite, we can write $x = 2^{e_s}m_s$, where /// $e_s$ is an integer and $m_s$ is a rational number with $1 \leq m_s < 2$. If $x$ is /// a valid float, the scientific mantissa $m_s$ is always exactly representable as a /// float of the same type. We have /// $$ /// f(x) = \frac{x}{2^{\lfloor \log_2 x \rfloor}}. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` is zero, infinite, or `NaN`. /// /// # Examples /// See [here](super::mantissa_and_exponent#sci_mantissa). #[inline] fn sci_mantissa(self) -> $t { sci_mantissa_primitive_float(self) } /// Returns the scientific exponent. /// /// When $x$ is positive, nonzero, and finite, we can write $x = 2^{e_s}m_s$, where /// $e_s$ is an integer and $m_s$ is a rational number with $1 \leq m_s < 2$. We have /// $$ /// f(x) = \lfloor \log_2 x \rfloor. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `self` is zero, infinite, or `NaN`. /// /// # Examples /// See [here](super::mantissa_and_exponent#sci_exponent). #[inline] fn sci_exponent(self) -> i64 { sci_exponent_primitive_float(self) } /// Constructs a float from its scientific mantissa and exponent. /// /// When $x$ is positive, nonzero, and finite, we can write $x = 2^{e_s}m_s$, where /// $e_s$ is an integer and $m_s$ is a rational number with $1 \leq m_s < 2$. /// /// $$ /// f(x) = 2^{e_s}m_s, /// $$ /// or `None` if the result cannot be exactly represented as a float of the desired type /// (this happens if the exponent is too large or too small, if the mantissa is not in /// the range $[1, 2)$, or if the mantissa's precision is too high for the exponent). /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `mantissa` is zero, infinite, or `NaN`. /// /// # Examples /// See [here](super::mantissa_and_exponent#from_sci_mantissa_and_exponent). #[inline] fn from_sci_mantissa_and_exponent(sci_mantissa: $t, sci_exponent: i64) -> Option<$t> { from_sci_mantissa_and_exponent_primitive_float(sci_mantissa, sci_exponent) } } }; } apply_to_primitive_floats!(impl_mantissa_and_exponent_primitive_float); malachite-base-0.4.16/src/num/conversion/mod.rs000064400000000000000000000543371046102023000174670ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . /// Traits for working with the digits of numbers. pub mod digits; /// Traits for converting between different number types. The traits are /// [`WrappingFrom`](traits::WrappingFrom), [`SaturatingFrom`](traits::SaturatingFrom), /// [`OverflowingFrom`](traits::OverflowingFrom), [`ConvertibleFrom`](traits::ConvertibleFrom), and /// [`RoundingFrom`](traits::RoundingFrom). /// /// # try_from /// ``` /// use malachite_base::num::conversion::from::{ /// PrimitiveFloatFromSignedError, PrimitiveFloatFromUnsignedError, SignedFromFloatError, /// UnsignedFromFloatError, /// }; /// use malachite_base::num::float::NiceFloat; /// /// assert_eq!(NiceFloat::::try_from(100u8), Ok(NiceFloat(100.0))); /// assert_eq!( /// NiceFloat::::try_from(u32::MAX), /// Err(PrimitiveFloatFromUnsignedError) /// ); /// assert_eq!(NiceFloat::::try_from(100i8), Ok(NiceFloat(100.0))); /// assert_eq!( /// NiceFloat::::try_from(i32::MAX), /// Err(PrimitiveFloatFromSignedError) /// ); /// /// assert_eq!(u8::try_from(NiceFloat(100.0f32)), Ok(100)); /// assert_eq!( /// u8::try_from(NiceFloat(100.1f32)), /// Err(UnsignedFromFloatError::FloatNonIntegerOrOutOfRange) /// ); /// assert_eq!( /// u8::try_from(NiceFloat(300.0f32)), /// Err(UnsignedFromFloatError::FloatNonIntegerOrOutOfRange) /// ); /// assert_eq!( /// u8::try_from(NiceFloat(-100.0f32)), /// Err(UnsignedFromFloatError::FloatNegative) /// ); /// assert_eq!(i8::try_from(NiceFloat(-100.0f32)), Ok(-100)); /// assert_eq!( /// i8::try_from(NiceFloat(-200.0f32)), /// Err(SignedFromFloatError::FloatNonIntegerOrOutOfRange) /// ); /// ``` /// /// # wrapping_from /// ``` /// use malachite_base::num::conversion::traits::WrappingFrom; /// /// assert_eq!(u8::wrapping_from(123u8), 123); /// assert_eq!(i32::wrapping_from(-5i32), -5); /// /// assert_eq!(u16::wrapping_from(123u8), 123); /// assert_eq!(i64::wrapping_from(-5i32), -5); /// assert_eq!(u32::wrapping_from(5u64), 5); /// /// assert_eq!(u8::wrapping_from(1000u16), 232); /// assert_eq!(u32::wrapping_from(-5i32), 4294967291); /// assert_eq!(i32::wrapping_from(3000000000u32), -1294967296); /// assert_eq!(i8::wrapping_from(-1000i16), 24); /// ``` /// /// # saturating_from /// ``` /// use malachite_base::num::conversion::traits::SaturatingFrom; /// /// assert_eq!(u8::saturating_from(123u8), 123); /// assert_eq!(i32::saturating_from(-5i32), -5); /// /// assert_eq!(u16::saturating_from(123u8), 123); /// assert_eq!(i64::saturating_from(-5i32), -5); /// assert_eq!(u32::saturating_from(5u64), 5); /// /// assert_eq!(u8::saturating_from(1000u16), 255); /// assert_eq!(u32::saturating_from(-5i32), 0); /// assert_eq!(i32::saturating_from(3000000000u32), 2147483647); /// assert_eq!(i8::saturating_from(-1000i16), -128); /// ``` /// /// # overflowing_from /// ``` /// use malachite_base::num::conversion::traits::OverflowingFrom; /// /// assert_eq!(u8::overflowing_from(123u8), (123, false)); /// assert_eq!(i32::overflowing_from(-5i32), (-5, false)); /// /// assert_eq!(u16::overflowing_from(123u8), (123, false)); /// assert_eq!(i64::overflowing_from(-5i32), (-5, false)); /// assert_eq!(u32::overflowing_from(5u64), (5, false)); /// /// assert_eq!(u8::overflowing_from(1000u16), (232, true)); /// assert_eq!(u32::overflowing_from(-5i32), (4294967291, true)); /// assert_eq!(i32::overflowing_from(3000000000u32), (-1294967296, true)); /// assert_eq!(i8::overflowing_from(-1000i16), (24, true)); /// ``` /// /// # convertible_from /// ``` /// use malachite_base::num::conversion::traits::ConvertibleFrom; /// /// assert_eq!(u8::convertible_from(123u8), true); /// assert_eq!(i32::convertible_from(-5i32), true); /// /// assert_eq!(u16::convertible_from(123u8), true); /// assert_eq!(i64::convertible_from(-5i32), true); /// assert_eq!(u32::convertible_from(5u64), true); /// /// assert_eq!(u8::convertible_from(1000u16), false); /// assert_eq!(u32::convertible_from(-5i32), false); /// assert_eq!(i32::convertible_from(3000000000u32), false); /// assert_eq!(i8::convertible_from(-1000i16), false); /// /// assert_eq!(f32::convertible_from(100u8), true); /// assert_eq!(f32::convertible_from(u32::MAX), false); /// /// assert_eq!(u8::convertible_from(100.0f32), true); /// assert_eq!(u8::convertible_from(100.1f32), false); /// assert_eq!(u8::convertible_from(300.0f32), false); /// assert_eq!(u8::convertible_from(-100.0f32), false); /// ``` /// /// # rounding_from /// ``` /// use malachite_base::num::conversion::traits::RoundingFrom; /// use malachite_base::rounding_modes::RoundingMode::*; /// use std::cmp::Ordering::*; /// /// assert_eq!(f32::rounding_from(100, Floor), (100.0, Equal)); /// assert_eq!(f32::rounding_from(100, Down), (100.0, Equal)); /// assert_eq!(f32::rounding_from(100, Ceiling), (100.0, Equal)); /// assert_eq!(f32::rounding_from(100, Up), (100.0, Equal)); /// assert_eq!(f32::rounding_from(100, Nearest), (100.0, Equal)); /// assert_eq!(f32::rounding_from(100, Exact), (100.0, Equal)); /// /// assert_eq!(f32::rounding_from(i32::MAX, Floor), (2147483500.0, Less)); /// assert_eq!(f32::rounding_from(i32::MAX, Down), (2147483500.0, Less)); /// assert_eq!( /// f32::rounding_from(i32::MAX, Ceiling), /// (2147483600.0, Greater) /// ); /// assert_eq!(f32::rounding_from(i32::MAX, Up), (2147483600.0, Greater)); /// assert_eq!( /// f32::rounding_from(i32::MAX, Nearest), /// (2147483600.0, Greater) /// ); /// /// assert_eq!(u32::rounding_from(100.0f32, Floor), (100, Equal)); /// assert_eq!(u32::rounding_from(100.0f32, Down), (100, Equal)); /// assert_eq!(u32::rounding_from(100.0f32, Ceiling), (100, Equal)); /// assert_eq!(u32::rounding_from(100.0f32, Up), (100, Equal)); /// assert_eq!(u32::rounding_from(100.0f32, Nearest), (100, Equal)); /// assert_eq!(u32::rounding_from(100.0f32, Exact), (100, Equal)); /// /// assert_eq!(u32::rounding_from(100.5f32, Floor), (100, Less)); /// assert_eq!(u32::rounding_from(100.5f32, Down), (100, Less)); /// assert_eq!(u32::rounding_from(100.5f32, Ceiling), (101, Greater)); /// assert_eq!(u32::rounding_from(100.5f32, Up), (101, Greater)); /// assert_eq!(u32::rounding_from(100.5f32, Nearest), (100, Less)); /// ``` pub mod from; /// [`JoinHalves`](traits::JoinHalves) and [`SplitInHalf`](traits::SplitInHalf), traits for joining /// the bits of two numbers or for splitting a number in half. /// /// # join_halves /// ``` /// use malachite_base::num::conversion::traits::JoinHalves; /// /// assert_eq!(u16::join_halves(1, 2), 258); /// assert_eq!(u32::join_halves(0xabcd, 0x1234), 0xabcd1234); /// ``` /// /// # split_in_half /// ``` /// use malachite_base::num::conversion::traits::SplitInHalf; /// /// assert_eq!(258u16.split_in_half(), (1, 2)); /// assert_eq!(0xabcd1234u32.split_in_half(), (0xabcd, 0x1234)); /// ``` /// /// # lower_half /// ``` /// use malachite_base::num::conversion::traits::SplitInHalf; /// /// assert_eq!(258u16.lower_half(), 2); /// assert_eq!(0xabcd1234u32.lower_half(), 0x1234); /// ``` /// /// # upper_half /// ``` /// use malachite_base::num::conversion::traits::SplitInHalf; /// /// assert_eq!(258u16.upper_half(), 1); /// assert_eq!(0xabcd1234u32.upper_half(), 0xabcd); /// ``` pub mod half; /// [`IsInteger`](traits::IsInteger), a trait for determining whether a value is an integer. /// /// # is_integer /// ``` /// use malachite_base::num::basic::traits::NegativeInfinity; /// use malachite_base::num::conversion::traits::IsInteger; /// /// assert_eq!(0.is_integer(), true); /// assert_eq!(1.is_integer(), true); /// assert_eq!(100.is_integer(), true); /// assert_eq!((-1).is_integer(), true); /// assert_eq!((-100).is_integer(), true); /// /// assert_eq!(0.0.is_integer(), true); /// assert_eq!(1.0.is_integer(), true); /// assert_eq!(100.0.is_integer(), true); /// assert_eq!((-1.0).is_integer(), true); /// assert_eq!((-100.0).is_integer(), true); /// /// assert_eq!(0.1.is_integer(), false); /// assert_eq!(100.1.is_integer(), false); /// assert_eq!(f32::NAN.is_integer(), false); /// assert_eq!(f32::INFINITY.is_integer(), false); /// assert_eq!(f32::NEGATIVE_INFINITY.is_integer(), false); /// ``` pub mod is_integer; /// Traits for converting numbers to and from mantissa and exponent representations. /// /// See [`PrimitiveFloat`](super::basic::floats::PrimitiveFloat) for a description of the different /// types of mantissas and exponents. The traits are /// [`RawMantissaAndExponent`](traits::RawMantissaAndExponent), /// [`IntegerMantissaAndExponent`](traits::IntegerMantissaAndExponent), and /// [`SciMantissaAndExponent`](traits::SciMantissaAndExponent). /// /// # raw_mantissa_and_exponent /// ``` /// use malachite_base::num::basic::traits::NegativeInfinity; /// use malachite_base::num::conversion::traits::RawMantissaAndExponent; /// /// assert_eq!(0.0f32.raw_mantissa_and_exponent(), (0, 0)); /// assert_eq!((-0.0f32).raw_mantissa_and_exponent(), (0, 0)); /// assert_eq!(f32::NAN.raw_mantissa_and_exponent(), (0x400000, 255)); /// assert_eq!(f32::INFINITY.raw_mantissa_and_exponent(), (0, 255)); /// assert_eq!(f32::NEGATIVE_INFINITY.raw_mantissa_and_exponent(), (0, 255)); /// assert_eq!(1.0f32.raw_mantissa_and_exponent(), (0, 127)); /// assert_eq!( /// core::f32::consts::PI.raw_mantissa_and_exponent(), /// (4788187, 128) /// ); /// assert_eq!(0.1f32.raw_mantissa_and_exponent(), (5033165, 123)); /// ``` /// /// # raw_mantissa /// ``` /// use malachite_base::num::basic::traits::NegativeInfinity; /// use malachite_base::num::conversion::traits::RawMantissaAndExponent; /// /// assert_eq!(0.0f32.raw_mantissa(), 0); /// assert_eq!((-0.0f32).raw_mantissa(), 0); /// assert_eq!(f32::NAN.raw_mantissa(), 0x400000); /// assert_eq!(f32::INFINITY.raw_mantissa(), 0); /// assert_eq!(f32::NEGATIVE_INFINITY.raw_mantissa(), 0); /// assert_eq!(1.0f32.raw_mantissa(), 0); /// assert_eq!(core::f32::consts::PI.raw_mantissa(), 4788187); /// assert_eq!(0.1f32.raw_mantissa(), 5033165); /// ``` /// /// # raw_exponent /// /// ``` /// use malachite_base::num::basic::traits::NegativeInfinity; /// use malachite_base::num::conversion::traits::RawMantissaAndExponent; /// /// assert_eq!(0.0f32.raw_exponent(), 0); /// assert_eq!((-0.0f32).raw_exponent(), 0); /// assert_eq!(f32::NAN.raw_exponent(), 255); /// assert_eq!(f32::INFINITY.raw_exponent(), 255); /// assert_eq!(f32::NEGATIVE_INFINITY.raw_exponent(), 255); /// assert_eq!(1.0f32.raw_exponent(), 127); /// assert_eq!(core::f32::consts::PI.raw_exponent(), 128); /// assert_eq!(0.1f32.raw_exponent(), 123); /// ``` /// /// # from_raw_mantissa_and_exponent /// ``` /// use malachite_base::num::conversion::traits::RawMantissaAndExponent; /// use malachite_base::num::float::NiceFloat; /// /// assert_eq!( /// NiceFloat(f32::from_raw_mantissa_and_exponent(0, 0)), /// NiceFloat(0.0) /// ); /// assert_eq!( /// NiceFloat(f32::from_raw_mantissa_and_exponent(0x400000, 255)), /// NiceFloat(f32::NAN) /// ); /// assert_eq!( /// NiceFloat(f32::from_raw_mantissa_and_exponent(0, 255)), /// NiceFloat(f32::INFINITY) /// ); /// assert_eq!( /// NiceFloat(f32::from_raw_mantissa_and_exponent(0, 127)), /// NiceFloat(1.0) /// ); /// assert_eq!( /// NiceFloat(f32::from_raw_mantissa_and_exponent(4788187, 128)), /// NiceFloat(core::f32::consts::PI) /// ); /// assert_eq!( /// NiceFloat(f32::from_raw_mantissa_and_exponent(5033165, 123)), /// NiceFloat(0.1) /// ); /// assert_eq!( /// NiceFloat(f32::from_raw_mantissa_and_exponent(2097152, 130)), /// NiceFloat(10.0) /// ); /// ``` /// /// # integer_mantissa_and_exponent /// ``` /// use malachite_base::num::basic::floats::PrimitiveFloat; /// use malachite_base::num::conversion::traits::IntegerMantissaAndExponent; /// /// assert_eq!(1u8.integer_mantissa_and_exponent(), (1, 0)); /// assert_eq!(2u8.integer_mantissa_and_exponent(), (1, 1)); /// assert_eq!(3u8.integer_mantissa_and_exponent(), (3, 0)); /// assert_eq!(100u8.integer_mantissa_and_exponent(), (25, 2)); /// /// assert_eq!( /// core::f32::consts::PI.integer_mantissa_and_exponent(), /// (13176795, -22) /// ); /// assert_eq!(0.1f32.integer_mantissa_and_exponent(), (13421773, -27)); /// assert_eq!(10.0f32.integer_mantissa_and_exponent(), (5, 1)); /// assert_eq!( /// f32::MIN_POSITIVE_SUBNORMAL.integer_mantissa_and_exponent(), /// (1, -149) /// ); /// assert_eq!( /// f32::MAX_SUBNORMAL.integer_mantissa_and_exponent(), /// (0x7fffff, -149) /// ); /// assert_eq!( /// f32::MIN_POSITIVE_NORMAL.integer_mantissa_and_exponent(), /// (1, -126) /// ); /// assert_eq!( /// f32::MAX_FINITE.integer_mantissa_and_exponent(), /// (0xffffff, 104) /// ); /// ``` /// /// # integer_mantissa /// ``` /// use malachite_base::num::basic::floats::PrimitiveFloat; /// use malachite_base::num::conversion::traits::IntegerMantissaAndExponent; /// /// assert_eq!(1u8.integer_mantissa(), 1); /// assert_eq!(2u8.integer_mantissa(), 1); /// assert_eq!(3u8.integer_mantissa(), 3); /// assert_eq!(100u8.integer_mantissa(), 25); /// /// assert_eq!(1.0f32.integer_mantissa(), 1); /// assert_eq!(core::f32::consts::PI.integer_mantissa(), 13176795); /// assert_eq!(0.1f32.integer_mantissa(), 13421773); /// assert_eq!(10.0f32.integer_mantissa(), 5); /// assert_eq!(f32::MIN_POSITIVE_SUBNORMAL.integer_mantissa(), 1); /// assert_eq!(f32::MAX_SUBNORMAL.integer_mantissa(), 0x7fffff); /// assert_eq!(f32::MIN_POSITIVE_NORMAL.integer_mantissa(), 1); /// assert_eq!(f32::MAX_FINITE.integer_mantissa(), 0xffffff); /// ``` /// /// # integer_exponent /// ``` /// use malachite_base::num::basic::floats::PrimitiveFloat; /// use malachite_base::num::conversion::traits::IntegerMantissaAndExponent; /// /// assert_eq!(1u8.integer_exponent(), 0); /// assert_eq!(2u8.integer_exponent(), 1); /// assert_eq!(3u8.integer_exponent(), 0); /// assert_eq!(100u8.integer_exponent(), 2); /// /// assert_eq!(1.0f32.integer_exponent(), 0); /// assert_eq!(core::f32::consts::PI.integer_exponent(), -22); /// assert_eq!(0.1f32.integer_exponent(), -27); /// assert_eq!(10.0f32.integer_exponent(), 1); /// assert_eq!(f32::MIN_POSITIVE_SUBNORMAL.integer_exponent(), -149); /// assert_eq!(f32::MAX_SUBNORMAL.integer_exponent(), -149); /// assert_eq!(f32::MIN_POSITIVE_NORMAL.integer_exponent(), -126); /// assert_eq!(f32::MAX_FINITE.integer_exponent(), 104); /// ``` /// /// # from_integer_mantissa_and_exponent; /// ``` /// use malachite_base::num::conversion::traits::IntegerMantissaAndExponent; /// use malachite_base::num::float::NiceFloat; /// /// assert_eq!(u8::from_integer_mantissa_and_exponent(0, 1), Some(0)); /// assert_eq!(u8::from_integer_mantissa_and_exponent(1, 0), Some(1)); /// assert_eq!(u8::from_integer_mantissa_and_exponent(1, 1), Some(2)); /// assert_eq!(u8::from_integer_mantissa_and_exponent(3, 0), Some(3)); /// assert_eq!(u8::from_integer_mantissa_and_exponent(25, 2), Some(100)); /// /// assert_eq!( /// f32::from_integer_mantissa_and_exponent(0, 5).map(NiceFloat), /// Some(NiceFloat(0.0)) /// ); /// assert_eq!( /// f32::from_integer_mantissa_and_exponent(1, 0).map(NiceFloat), /// Some(NiceFloat(1.0)) /// ); /// assert_eq!( /// f32::from_integer_mantissa_and_exponent(4, -2).map(NiceFloat), /// Some(NiceFloat(1.0)) /// ); /// assert_eq!( /// f32::from_integer_mantissa_and_exponent(13176795, -22).map(NiceFloat), /// Some(NiceFloat(core::f32::consts::PI)) /// ); /// assert_eq!( /// f32::from_integer_mantissa_and_exponent(13421773, -27).map(NiceFloat), /// Some(NiceFloat(0.1)) /// ); /// assert_eq!( /// f32::from_integer_mantissa_and_exponent(5, 1).map(NiceFloat), /// Some(NiceFloat(10.0)) /// ); /// /// assert_eq!(f32::from_integer_mantissa_and_exponent(5, 10000), None); /// assert_eq!(f32::from_integer_mantissa_and_exponent(5, -10000), None); /// // In the next 3 examples, the precision is too high. /// assert_eq!(f32::from_integer_mantissa_and_exponent(u64::MAX, -32), None); /// assert_eq!(f32::from_integer_mantissa_and_exponent(3, -150), None); /// assert_eq!(f32::from_integer_mantissa_and_exponent(1, 128), None); /// ``` /// /// # sci_mantissa_and_exponent /// ``` /// use malachite_base::num::basic::floats::PrimitiveFloat; /// use malachite_base::num::conversion::traits::SciMantissaAndExponent; /// use malachite_base::num::float::NiceFloat; /// /// let test = |n: u32, mantissa: f32, exponent: u64| { /// let (m, e) = n.sci_mantissa_and_exponent(); /// assert_eq!(NiceFloat(m), NiceFloat(mantissa)); /// assert_eq!(e, exponent); /// }; /// test(3, 1.5, 1); /// test(123, 1.921875, 6); /// test(1000000000, 1.8626451, 29); /// /// let test = |x: f32, mantissa: f32, exponent: i64| { /// let (actual_mantissa, actual_exponent) = x.sci_mantissa_and_exponent(); /// assert_eq!(NiceFloat(actual_mantissa), NiceFloat(mantissa)); /// assert_eq!(actual_exponent, exponent); /// }; /// test(1.0, 1.0, 0); /// test(core::f32::consts::PI, 1.5707964, 1); /// test(0.1, 1.6, -4); /// test(10.0, 1.25, 3); /// test(f32::MIN_POSITIVE_SUBNORMAL, 1.0, -149); /// test(f32::MAX_SUBNORMAL, 1.9999998, -127); /// test(f32::MIN_POSITIVE_NORMAL, 1.0, -126); /// test(f32::MAX_FINITE, 1.9999999, 127); /// ``` /// /// # sci_mantissa /// ``` /// use malachite_base::num::basic::floats::PrimitiveFloat; /// use malachite_base::num::conversion::traits::SciMantissaAndExponent; /// use malachite_base::num::float::NiceFloat; /// /// assert_eq!(NiceFloat(1.0f32.sci_mantissa()), NiceFloat(1.0)); /// assert_eq!( /// NiceFloat(core::f32::consts::PI.sci_mantissa()), /// NiceFloat(1.5707964) /// ); /// assert_eq!(NiceFloat(0.1f32.sci_mantissa()), NiceFloat(1.6)); /// assert_eq!(NiceFloat(10.0f32.sci_mantissa()), NiceFloat(1.25)); /// assert_eq!( /// NiceFloat(f32::MIN_POSITIVE_SUBNORMAL.sci_mantissa()), /// NiceFloat(1.0) /// ); /// assert_eq!( /// NiceFloat(f32::MAX_SUBNORMAL.sci_mantissa()), /// NiceFloat(1.9999998) /// ); /// assert_eq!( /// NiceFloat(f32::MIN_POSITIVE_NORMAL.sci_mantissa()), /// NiceFloat(1.0) /// ); /// assert_eq!( /// NiceFloat(f32::MAX_FINITE.sci_mantissa()), /// NiceFloat(1.9999999) /// ); /// ``` /// /// # sci_exponent /// ``` /// use malachite_base::num::basic::floats::PrimitiveFloat; /// use malachite_base::num::conversion::traits::SciMantissaAndExponent; /// /// assert_eq!(1.0f32.sci_exponent(), 0); /// assert_eq!(core::f32::consts::PI.sci_exponent(), 1); /// assert_eq!(0.1f32.sci_exponent(), -4); /// assert_eq!(10.0f32.sci_exponent(), 3); /// assert_eq!(f32::MIN_POSITIVE_SUBNORMAL.sci_exponent(), -149); /// assert_eq!(f32::MAX_SUBNORMAL.sci_exponent(), -127); /// assert_eq!(f32::MIN_POSITIVE_NORMAL.sci_exponent(), -126); /// assert_eq!(f32::MAX_FINITE.sci_exponent(), 127); /// ``` /// /// # from_sci_mantissa_and_exponent; /// ``` /// use malachite_base::num::basic::floats::PrimitiveFloat; /// use malachite_base::num::conversion::traits::SciMantissaAndExponent; /// use malachite_base::num::float::NiceFloat; /// /// assert_eq!(u32::from_sci_mantissa_and_exponent(1.5, 1u64), Some(3u32)); /// assert_eq!(u32::from_sci_mantissa_and_exponent(1.51, 1u64), Some(3u32)); /// assert_eq!( /// u32::from_sci_mantissa_and_exponent(1.921875, 6u64), /// Some(123u32) /// ); /// assert_eq!(u32::from_sci_mantissa_and_exponent(1.5, 1u64), Some(3u32)); /// /// assert_eq!( /// f32::from_sci_mantissa_and_exponent(1.0, 0).map(NiceFloat), /// Some(NiceFloat(1.0)) /// ); /// assert_eq!( /// f32::from_sci_mantissa_and_exponent(1.5707964, 1).map(NiceFloat), /// Some(NiceFloat(core::f32::consts::PI)) /// ); /// assert_eq!( /// f32::from_sci_mantissa_and_exponent(1.6, -4).map(NiceFloat), /// Some(NiceFloat(0.1)) /// ); /// assert_eq!( /// f32::from_sci_mantissa_and_exponent(1.25, 3).map(NiceFloat), /// Some(NiceFloat(10.0)) /// ); /// assert_eq!( /// f32::from_sci_mantissa_and_exponent(1.0, -149).map(NiceFloat), /// Some(NiceFloat(f32::MIN_POSITIVE_SUBNORMAL)) /// ); /// assert_eq!( /// f32::from_sci_mantissa_and_exponent(1.9999998, -127).map(NiceFloat), /// Some(NiceFloat(f32::MAX_SUBNORMAL)) /// ); /// assert_eq!( /// f32::from_sci_mantissa_and_exponent(1.0, -126).map(NiceFloat), /// Some(NiceFloat(f32::MIN_POSITIVE_NORMAL)) /// ); /// assert_eq!( /// f32::from_sci_mantissa_and_exponent(1.9999999, 127).map(NiceFloat), /// Some(NiceFloat(f32::MAX_FINITE)) /// ); /// /// assert_eq!(f32::from_sci_mantissa_and_exponent(2.0, 1), None); /// assert_eq!(f32::from_sci_mantissa_and_exponent(1.1, -2000), None); /// assert_eq!(f32::from_sci_mantissa_and_exponent(1.1, 2000), None); /// assert_eq!(f32::from_sci_mantissa_and_exponent(1.999, -149), None); /// ``` pub mod mantissa_and_exponent; /// Traits for converting slices to numbers, slices to [`Vec`]s, or numbers to [`Vec`]s. The traits /// are [`FromOtherTypeSlice`](traits::FromOtherTypeSlice), /// [`VecFromOtherTypeSlice`](traits::VecFromOtherTypeSlice), and /// [`VecFromOtherType`](traits::VecFromOtherType). /// /// # from_other_type_slice /// ``` /// use malachite_base::num::conversion::traits::FromOtherTypeSlice; /// /// let xs: &[u32] = &[]; /// assert_eq!(u32::from_other_type_slice(xs), 0); /// assert_eq!(u32::from_other_type_slice(&[123u32, 456]), 123); /// /// assert_eq!(u8::from_other_type_slice(&[0xabcdu16, 0xef01]), 0xcd); /// /// assert_eq!(u16::from_other_type_slice(&[0xabu8, 0xcd, 0xef]), 0xcdab); /// assert_eq!(u64::from_other_type_slice(&[0xabu8, 0xcd, 0xef]), 0xefcdab); /// ``` /// /// # vec_from_other_type_slice /// ``` /// use malachite_base::num::conversion::traits::VecFromOtherTypeSlice; /// /// assert_eq!(u32::vec_from_other_type_slice(&[123u32, 456]), &[123, 456]); /// assert_eq!( /// u8::vec_from_other_type_slice(&[0xcdabu16, 0x01ef, 0x4523, 0x8967]), /// &[0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89] /// ); /// assert_eq!( /// u16::vec_from_other_type_slice(&[0xabu8, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67]), /// &[0xcdab, 0x01ef, 0x4523, 0x67] /// ); /// ``` /// /// # vec_from_other_type /// ``` /// use malachite_base::num::conversion::traits::VecFromOtherType; /// /// assert_eq!(u32::vec_from_other_type(123u32), &[123]); /// assert_eq!(u8::vec_from_other_type(0xcdabu16), &[0xab, 0xcd]); /// assert_eq!(u16::vec_from_other_type(0xabu8), &[0xab]); /// ``` pub mod slice; /// Traits for converting numbers to and from [`String`]s. pub mod string; /// Various traits for converting numbers. pub mod traits; malachite-base-0.4.16/src/num/conversion/slice.rs000064400000000000000000000525041046102023000200010ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::ShrRound; use crate::num::basic::integers::PrimitiveInt; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::{ FromOtherTypeSlice, SplitInHalf, VecFromOtherType, VecFromOtherTypeSlice, WrappingFrom, }; use crate::rounding_modes::RoundingMode::*; use alloc::vec; use alloc::vec::Vec; const fn from_other_type_slice_ident(xs: &[T]) -> T { if xs.is_empty() { T::ZERO } else { xs[0] } } macro_rules! impl_slice_traits_ident { ($a:ty) => { impl FromOtherTypeSlice<$a> for $a { /// Converts a slice of one type of value to a single value of the same type. /// /// $$ /// f((x_k)_{k=0}^{n-1}) = \\begin{cases} /// 0 & \text{if} \\quad n = 0, \\\\ /// x_0 & \\text{otherwise}, /// \\end{cases} /// $$ /// where $W$ is the width of the type. /// /// The slice is interpreted as the base-$2^W$ digits of the value, in ascending order, /// where $W$ is the width of the type. If there's more than one element in the input /// slice, the value wraps and all elements past the first are ignored. This means that /// if the slice is empty, the output value is 0; otherwise, it's the first element of /// the slice. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::slice#from_other_type_slice). #[inline] fn from_other_type_slice(xs: &[$a]) -> Self { from_other_type_slice_ident(xs) } } impl VecFromOtherTypeSlice<$a> for $a { /// Converts a slice of one type of value to a [`Vec`] of the same type. /// /// In this case, it just converts the slice to a [`Vec`] the usual way. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`. /// /// # Examples /// See [here](super::slice#vec_from_other_type_slice). #[inline] fn vec_from_other_type_slice(xs: &[$a]) -> Vec { xs.to_vec() } } impl VecFromOtherType<$a> for $a { /// Converts a value of one type to a [`Vec`] of the same type. /// /// In this case, it just creates a one-element [`Vec`]. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::slice#vec_from_other_type). #[inline] fn vec_from_other_type(x: $a) -> Vec { ::alloc::vec![x] } } }; } fn from_other_type_slice_large_to_small< A: PrimitiveUnsigned, B: PrimitiveUnsigned + WrappingFrom, >( xs: &[A], ) -> B { if xs.is_empty() { B::ZERO } else { B::wrapping_from(xs[0]) } } fn vec_from_other_type_slice_large_to_small< A: PrimitiveUnsigned, B: PrimitiveUnsigned + WrappingFrom, >( xs: &[A], ) -> Vec { let log_size_ratio = A::LOG_WIDTH - B::LOG_WIDTH; let mut out = ::alloc::vec![B::ZERO; xs.len() << log_size_ratio]; for (chunk, &u) in out.chunks_exact_mut(1 << log_size_ratio).zip(xs.iter()) { let mut u = u; for x in chunk { *x = B::wrapping_from(u); u >>= B::WIDTH; } } out } fn vec_from_other_type_large_to_small< A: PrimitiveUnsigned, B: PrimitiveUnsigned + WrappingFrom, >( mut x: A, ) -> Vec { let mut xs = ::alloc::vec![B::ZERO; 1 << (A::LOG_WIDTH - B::LOG_WIDTH)]; for out in &mut xs { *out = B::wrapping_from(x); x >>= B::WIDTH; } xs } macro_rules! impl_slice_traits_large_to_small { ($a:ident, $b:ident) => { impl FromOtherTypeSlice<$a> for $b { /// Converts a slice of one type of unsigned integer to a single value of a smaller /// unsigned type. /// /// $$ /// f((x_k)_{k=0}^{n-1}) = \\begin{cases} /// 0 & \text{if} \\quad n = 0, \\\\ /// y & \\text{otherwise}, /// \\end{cases} /// $$ /// where $0 \leq y < 2^W$, $x = y + k2^W$ for some integer $k$, and $W$ is the width of /// the output type. /// /// The slice is interpreted as the base-$2^W$ digits of the value, in ascending order, /// where $W$ is the width of the type. If the slice is empty, the output value is 0; /// otherwise, it consists of the least-significant bits of the first element of the /// slice. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::slice#from_other_type_slice). #[inline] fn from_other_type_slice(xs: &[$a]) -> Self { from_other_type_slice_large_to_small(xs) } } impl VecFromOtherTypeSlice<$a> for $b { /// Converts a slice of one type of unsigned integer to a [`Vec`] of a smaller unsigned /// type. /// /// Each value of the input slice will be broken up into several values in the output /// [`Vec`]. /// /// Let $V$ be the the width of the input type and $W$ the width of the output type. /// /// $f((x_k)_ {k=0}^{n-1}) = (y_k)_ {k=0}^{m-1}$, where /// /// $$ /// \sum_{j=0}^{n-1}2^{jV}x_j = \sum_{j=0}^{m-1}2^{jW}y_j, /// $$ /// /// $y_j < 2^W$ for all $j$, and $m = 2^{V-W}n$. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`. /// /// # Examples /// See [here](super::slice#vec_from_other_type_slice). #[inline] fn vec_from_other_type_slice(xs: &[$a]) -> Vec { vec_from_other_type_slice_large_to_small(xs) } } impl VecFromOtherType<$a> for $b { /// Converts a value of one type of unsigned integer to a [`Vec`] of a smaller unsigned /// type. /// /// The input value will be broken up into several values in the output [`Vec`]. /// /// $f(x) = (y_k)_{k=0}^{m-1}$, where $x = \sum_{j=0}^{m-1}2^{jW}y_j$ and $m = /// 2^{V-W}n$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::slice#vec_from_other_type). #[inline] fn vec_from_other_type(x: $a) -> Vec { vec_from_other_type_large_to_small(x) } } }; } fn from_other_type_slice_small_to_large< A: PrimitiveUnsigned, B: PrimitiveUnsigned + WrappingFrom, >( xs: &[A], ) -> B { let mut result = B::ZERO; let mut offset = 0; for &u in xs.iter().take(1 << (B::LOG_WIDTH - A::LOG_WIDTH)) { result |= B::wrapping_from(u) << offset; offset += A::WIDTH; } result } fn vec_from_other_type_slice_small_to_large< A: PrimitiveUnsigned, B: PrimitiveUnsigned + WrappingFrom, >( xs: &[A], ) -> Vec { let log_size_ratio = B::LOG_WIDTH - A::LOG_WIDTH; let mut out = ::alloc::vec![B::ZERO; xs.len().shr_round(log_size_ratio, Ceiling).0]; for (x, chunk) in out.iter_mut().zip(xs.chunks(1 << log_size_ratio)) { *x = from_other_type_slice_small_to_large(chunk); } out } fn vec_from_other_type_small_to_large>(x: A) -> Vec { ::alloc::vec![B::wrapping_from(x)] } macro_rules! impl_slice_traits_small_to_large { ($a:ident, $b:ident) => { impl FromOtherTypeSlice<$a> for $b { /// Converts a slice of one type of unsigned integer to a single value of a larger /// unsigned type. /// /// Let $V$ be the the width of the input type and $W$ the width of the output type. /// /// $f((x_k)_{k=0}^{n-1}) = y$, where $y < 2^W$ and /// /// $$ /// y = k2^W + \sum_{j=0}^{n-1}2^{jV}x_j /// $$ /// /// for some integer $k$. /// /// If the input slice contains more values than necessary to build an output value, the /// trailing values are ignored. If the input slice contains too few values to build an /// output value, the most-significant bits of the output value are set to 0. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::slice#from_other_type_slice). #[inline] fn from_other_type_slice(xs: &[$a]) -> Self { from_other_type_slice_small_to_large(xs) } } impl VecFromOtherTypeSlice<$a> for $b { /// Converts a slice of one type of unsigned integer to a [`Vec`] of a larger unsigned /// type. /// /// Adjacent chunks of values in the input slice will be joined into values of the /// output [`Vec`]. If the last few elements of the input slice don't make up a full /// chunk, the most-significant bits of the last output value are set to 0. /// /// Let $V$ be the the width of the input type and $W$ the width of the output type. /// /// $f((x_k)_ {k=0}^{n-1}) = (y_k)_ {k=0}^{m-1}$, where /// /// $$ /// \sum_{j=0}^{n-1}2^{jV}x_j = \sum_{j=0}^{m-1}2^{jW}y_j, /// $$ /// /// $y_j < 2^W$ for all $j$, and $m = \lceil n / 2^{W-V} \rceil$. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`. /// /// # Examples /// See [here](super::slice#vec_from_other_type_slice). #[inline] fn vec_from_other_type_slice(xs: &[$a]) -> Vec { vec_from_other_type_slice_small_to_large(xs) } } impl VecFromOtherType<$a> for $b { /// Converts a value of one type of unsigned integer to a [`Vec`] of a larger unsigned /// type. /// /// The output [`Vec`] only contains one value. The least-significant bits of the output /// value contain the input value, and the most-significant bits are set to 0. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::slice#vec_from_other_type). #[inline] fn vec_from_other_type(x: $a) -> Vec { vec_from_other_type_small_to_large(x) } } }; } apply_to_unsigneds!(impl_slice_traits_ident); impl_slice_traits_large_to_small!(u16, u8); impl_slice_traits_large_to_small!(u32, u8); impl_slice_traits_large_to_small!(u32, u16); impl_slice_traits_large_to_small!(u64, u8); impl_slice_traits_large_to_small!(u64, u16); impl_slice_traits_large_to_small!(u64, u32); impl_slice_traits_large_to_small!(u128, u8); impl_slice_traits_large_to_small!(u128, u16); impl_slice_traits_large_to_small!(u128, u32); impl_slice_traits_large_to_small!(u128, u64); impl_slice_traits_large_to_small!(u128, usize); impl_slice_traits_large_to_small!(usize, u8); impl_slice_traits_large_to_small!(usize, u16); impl_slice_traits_small_to_large!(u8, u16); impl_slice_traits_small_to_large!(u8, u32); impl_slice_traits_small_to_large!(u8, u64); impl_slice_traits_small_to_large!(u8, u128); impl_slice_traits_small_to_large!(u8, usize); impl_slice_traits_small_to_large!(u16, u32); impl_slice_traits_small_to_large!(u16, u64); impl_slice_traits_small_to_large!(u16, u128); impl_slice_traits_small_to_large!(u16, usize); impl_slice_traits_small_to_large!(u32, u64); impl_slice_traits_small_to_large!(u32, u128); impl_slice_traits_small_to_large!(u64, u128); impl_slice_traits_small_to_large!(usize, u128); impl FromOtherTypeSlice for usize { /// Converts a slice of `u32`s to a single `usize`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// See [here](super::slice#from_other_type_slice). fn from_other_type_slice(xs: &[u32]) -> Self { if usize::WIDTH == u32::WIDTH { if xs.is_empty() { 0 } else { usize::wrapping_from(xs[0]) } } else { assert_eq!(usize::WIDTH, u64::WIDTH); let mut result = 0; let mut offset = 0; for &u in xs.iter().take(2) { result |= usize::wrapping_from(u) << offset; offset += u32::WIDTH; } result } } } impl VecFromOtherTypeSlice for usize { /// Converts a slice of [`u32`]s to a [`Vec`] of [`usize`]s. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`. /// /// See [here](super::slice#vec_from_other_type_slice). fn vec_from_other_type_slice(xs: &[u32]) -> Vec { let mut out; if usize::WIDTH == u32::WIDTH { out = vec![0; xs.len()]; for (x, &u) in out.iter_mut().zip(xs.iter()) { *x = usize::wrapping_from(u); } } else { assert_eq!(usize::WIDTH, u64::WIDTH); out = vec![0; xs.len().shr_round(1, Ceiling).0]; for (x, chunk) in out.iter_mut().zip(xs.chunks(2)) { *x = usize::from_other_type_slice(chunk); } } out } } impl VecFromOtherType for usize { /// Converts a [`u32`] to a [`Vec`] of [`usize`]s. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// See [here](super::slice#vec_from_other_type). #[inline] fn vec_from_other_type(x: u32) -> Vec { vec![usize::wrapping_from(x)] } } impl FromOtherTypeSlice for usize { /// Converts a slice of [`u64`]s to a single [`usize`]. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// See [here](super::slice#from_other_type_slice). #[inline] fn from_other_type_slice(xs: &[u64]) -> Self { if xs.is_empty() { 0 } else { usize::wrapping_from(xs[0]) } } } impl VecFromOtherTypeSlice for usize { /// Converts a slice of [`u64`]s to a [`Vec`] of [`usize`]s. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`. /// /// See [here](super::slice#vec_from_other_type_slice). #[allow(arithmetic_overflow)] fn vec_from_other_type_slice(xs: &[u64]) -> Vec { let mut out; if usize::WIDTH == u32::WIDTH { out = ::alloc::vec![0; xs.len() << 1]; for (chunk, &u) in out.chunks_exact_mut(2).zip(xs.iter()) { let mut u = u; for x in chunk { *x = usize::wrapping_from(u); u >>= usize::WIDTH; } } } else { assert_eq!(usize::WIDTH, u64::WIDTH); out = ::alloc::vec![0; xs.len()]; for (x, &u) in out.iter_mut().zip(xs.iter()) { *x = usize::wrapping_from(u); } } out } } impl VecFromOtherType for usize { /// Converts a [`u64`] to a [`Vec`] of [`usize`]s. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// See [here](super::slice#vec_from_other_type). fn vec_from_other_type(x: u64) -> Vec { if usize::WIDTH == u32::WIDTH { let (upper, lower) = x.split_in_half(); ::alloc::vec![usize::wrapping_from(lower), usize::wrapping_from(upper)] } else { assert_eq!(usize::WIDTH, u64::WIDTH); ::alloc::vec![usize::wrapping_from(x)] } } } impl FromOtherTypeSlice for u32 { /// Converts a slice of [`usize`]s to a single [`u32`]. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// See [here](super::slice#from_other_type_slice). #[inline] fn from_other_type_slice(xs: &[usize]) -> Self { if xs.is_empty() { 0 } else { u32::wrapping_from(xs[0]) } } } impl VecFromOtherTypeSlice for u32 { /// Converts a slice of [`usize`]s to a [`Vec`] of [`u32`]s. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`. /// /// See [here](super::slice#vec_from_other_type_slice). #[allow(arithmetic_overflow)] fn vec_from_other_type_slice(xs: &[usize]) -> Vec { let mut out; if usize::WIDTH == u32::WIDTH { out = ::alloc::vec![0; xs.len()]; for (x, &u) in out.iter_mut().zip(xs.iter()) { *x = u32::wrapping_from(u); } } else { assert_eq!(usize::WIDTH, u64::WIDTH); out = ::alloc::vec![0; xs.len() << 1]; for (chunk, &u) in out.chunks_exact_mut(2).zip(xs.iter()) { let mut u = u; for x in chunk { *x = u32::wrapping_from(u); u >>= u32::WIDTH; } } } out } } impl VecFromOtherType for u32 { /// Converts a [`usize`] to a [`Vec`] of [`u32`]s. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// See [here](super::slice#vec_from_other_type). #[allow(arithmetic_overflow)] fn vec_from_other_type(x: usize) -> Vec { if usize::WIDTH == u32::WIDTH { ::alloc::vec![u32::wrapping_from(x)] } else { assert_eq!(usize::WIDTH, u64::WIDTH); let (upper, lower) = u64::wrapping_from(x).split_in_half(); ::alloc::vec![lower, upper] } } } impl FromOtherTypeSlice for u64 { /// Converts a slice of [`usize`]s to a single [`u64`]. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// See [here](super::slice#from_other_type_slice). fn from_other_type_slice(xs: &[usize]) -> Self { if usize::WIDTH == u32::WIDTH { let mut result = 0; let mut offset = 0; for &u in xs.iter().take(2) { result |= u64::wrapping_from(u) << offset; offset += usize::WIDTH; } result } else { assert_eq!(usize::WIDTH, u64::WIDTH); if xs.is_empty() { 0 } else { u64::wrapping_from(xs[0]) } } } } impl VecFromOtherTypeSlice for u64 { /// Converts a slice of [`usize`]s to a [`Vec`] of [`u64`]s. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`. /// /// See [here](super::slice#vec_from_other_type_slice). fn vec_from_other_type_slice(xs: &[usize]) -> Vec { let mut out; if usize::WIDTH == u32::WIDTH { out = ::alloc::vec![0; xs.len().shr_round(1, Ceiling).0]; for (x, chunk) in out.iter_mut().zip(xs.chunks(2)) { *x = u64::from_other_type_slice(chunk); } } else { assert_eq!(usize::WIDTH, u64::WIDTH); out = ::alloc::vec![0; xs.len()]; for (x, &u) in out.iter_mut().zip(xs.iter()) { *x = u64::wrapping_from(u); } } out } } impl VecFromOtherType for u64 { /// Converts a [`usize`] to a [`Vec`] of [`u64`]s. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// See [here](super::slice#vec_from_other_type). #[inline] fn vec_from_other_type(x: usize) -> Vec { ::alloc::vec![u64::wrapping_from(x)] } } malachite-base-0.4.16/src/num/conversion/string/from_sci_string.rs000064400000000000000000000235651046102023000234040ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::Parity; use crate::num::basic::integers::PrimitiveInt; use crate::num::conversion::string::from_string::digit_from_display_byte; use crate::num::conversion::string::options::FromSciStringOptions; use crate::num::conversion::traits::FromSciString; use crate::rounding_modes::RoundingMode::*; use alloc::vec::Vec; use core::cmp::Ordering::{self, *}; use core::str::FromStr; #[doc(hidden)] pub fn parse_exponent(s: &[u8]) -> Option { i64::from_str(core::str::from_utf8(s).ok()?).ok() } #[doc(hidden)] pub fn validate_helper(s: &[u8], base: u8) -> Option<()> { for &c in s { if digit_from_display_byte(c)? >= base { return None; } } Some(()) } #[doc(hidden)] pub fn is_zero_helper(s: &[u8], base: u8) -> Option { let mut all_zeros = true; for &c in s { let d = digit_from_display_byte(c)?; if d >= base { return None; } if d != 0 { all_zeros = false; } } Some(all_zeros) } #[doc(hidden)] pub fn cmp_half_helper(s: &[u8], base: u8) -> Option { if s.is_empty() { return Some(Less); } let h = base >> 1; let mut done = false; let mut result; if base.even() { // 1/2 is 0.h result = Equal; let mut first = true; for &c in s { let d = digit_from_display_byte(c)?; if d >= base { return None; } if done { continue; } if first { let half_c = d.cmp(&h); if half_c != Equal { result = half_c; done = true; } first = false; } else if d != 0 { result = Greater; done = true; } } } else { // 1/2 is 0.hhh... result = Less; for &c in s { let d = digit_from_display_byte(c)?; if done { continue; } let half_c = d.cmp(&h); if half_c != Equal { result = half_c; done = true; } } } Some(result) } fn parse_int(cs: &[u8], base: u8) -> Option { // if T is unsigned, from_string_base won't handle -0 let mut test_neg_zero = false; if T::MIN == T::ZERO { if let Some(&b'-') = cs.first() { test_neg_zero = true; } } if test_neg_zero { if cs.len() == 1 { return None; } for &c in &cs[1..] { if c != b'0' { return None; } } Some(T::ZERO) } else { T::from_string_base(base, core::str::from_utf8(cs).ok()?) } } fn up_1(x: T, neg: bool) -> Option { if neg { x.checked_sub(T::ONE) } else { x.checked_add(T::ONE) } } #[doc(hidden)] pub fn preprocess_sci_string(s: &str, options: FromSciStringOptions) -> Option<(Vec, i64)> { let mut s = s.as_bytes().to_vec(); let mut exponent = 0; if options.base < 15 { for (i, &c) in s.iter().enumerate().rev() { if c == b'e' || c == b'E' { if i == 0 || i == s.len() - 1 { return None; } exponent = parse_exponent(&s[i + 1..])?; s.truncate(i); break; } } } else { for (i, &c) in s.iter().enumerate().rev() { if c == b'+' || c == b'-' { if i == 0 { break; } if i == 1 || i == s.len() - 1 { return None; } let exp_indicator = s[i - 1]; if exp_indicator != b'e' && exp_indicator != b'E' { return None; } exponent = parse_exponent(&s[i..])?; s.truncate(i - 1); break; } } } let mut point_index = None; for (i, &c) in s.iter().enumerate() { if c == b'.' { point_index = Some(i); break; } } if let Some(point_index) = point_index { let len = s.len(); if point_index != len - 1 { let next_char = s[point_index + 1]; if next_char == b'+' || next_char == b'-' { return None; } exponent = exponent.checked_sub(i64::try_from(len - point_index - 1).ok()?)?; s.copy_within(point_index + 1..len, point_index); } s.pop(); } Some((s, exponent)) } fn from_sci_string_with_options_primitive_int( s: &str, options: FromSciStringOptions, ) -> Option { let (s, exponent) = preprocess_sci_string(s, options)?; if exponent >= 0 { let x = parse_int::(&s, options.base)?; x.checked_mul(T::wrapping_from(options.base).checked_pow(exponent.unsigned_abs())?) } else { let neg_exponent = usize::try_from(exponent.unsigned_abs()).ok()?; let len = s.len(); if len == 0 { return None; } let first = s[0]; let neg = first == b'-'; let sign = neg || first == b'+'; let rm = if neg { -options.rounding_mode } else { options.rounding_mode }; let sig_len = if sign { len - 1 } else { len }; if sig_len == 0 { return None; } if neg_exponent > sig_len { let s = if sign { &s[1..] } else { &s[..] }; return match rm { Down | Floor | Nearest => { validate_helper(s, options.base)?; Some(T::ZERO) } Up | Ceiling => { if is_zero_helper(s, options.base)? { Some(T::ZERO) } else { up_1(T::ZERO, neg) } } Exact => None, }; } let (before_e, after_e) = s.split_at(len - neg_exponent); let x = match before_e { &[] | &[b'-'] | &[b'+'] => T::ZERO, before_e => parse_int(before_e, options.base)?, }; if after_e.is_empty() { return Some(x); } match rm { Down | Floor => { validate_helper(after_e, options.base)?; Some(x) } Up | Ceiling => { if is_zero_helper(after_e, options.base)? { Some(x) } else { up_1(x, neg) } } Exact => { if is_zero_helper(after_e, options.base)? { Some(x) } else { None } } Nearest => match cmp_half_helper(after_e, options.base)? { Less => Some(x), Greater => up_1(x, neg), Equal => { if x.even() { Some(x) } else { up_1(x, neg) } } }, } } } macro_rules! impl_from_sci_string { ($t:ident) => { impl FromSciString for $t { /// Converts a [`String`], possibly in scientfic notation, to a primitive integer. /// /// Use [`FromSciStringOptions`] to specify the base (from 2 to 36, inclusive) and the /// rounding mode, in case rounding is necessary because the string represents a /// non-integer. /// /// If the base is greater than 10, the higher digits are represented by the letters /// `'a'` through `'z'` or `'A'` through `'Z'`; the case doesn't matter and doesn't need /// to be consistent. /// /// Exponents are allowed, and are indicated using the character `'e'` or `'E'`. If the /// base is 15 or greater, an ambiguity arises where it may not be clear whether `'e'` /// is a digit or an exponent indicator. To resolve this ambiguity, always use a `'+'` /// or `'-'` sign after the exponent indicator when the base is 15 or greater. /// /// The exponent itself is always parsed using base 10. /// /// Decimal (or other-base) points are allowed. These are most useful in conjunction /// with exponents, but they may be used on their own. If the string represents a /// non-integer, the rounding mode specified in `options` is used to round to an /// integer. /// /// If the string is unparseable or parses to an out-of-range integer, `None` is /// returned. `None` is also returned if the rounding mode in options is `Exact`, but /// rounding is necessary. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `s.len()`. /// /// # Examples /// See [here](super::from_sci_string). #[inline] fn from_sci_string_with_options(s: &str, options: FromSciStringOptions) -> Option<$t> { from_sci_string_with_options_primitive_int(s, options) } } }; } apply_to_primitive_ints!(impl_from_sci_string); malachite-base-0.4.16/src/num/conversion/string/from_string.rs000064400000000000000000000042751046102023000225430ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::conversion::traits::FromStringBase; /// Produces a digit from a byte corresponding to a numeric or alphabetic (lower- or uppercase) /// [`char`] that represents the digit. /// /// Bytes corresponding to `char`s from '0' to '9' become digits 0 to 9. Bytes corresponding to /// `char`s from 'a' to 'z' become digits 10 to 35. Bytes corresponding to `char`s from 'A' to 'Z' /// also become digits 10 to 35. Passing a byte that does not correspond to any of these `char`s /// yields `None`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::num::conversion::string::from_string::digit_from_display_byte; /// /// assert_eq!(digit_from_display_byte(b'0'), Some(0)); /// assert_eq!(digit_from_display_byte(b'9'), Some(9)); /// assert_eq!(digit_from_display_byte(b'a'), Some(10)); /// assert_eq!(digit_from_display_byte(b'z'), Some(35)); /// assert_eq!(digit_from_display_byte(b'A'), Some(10)); /// assert_eq!(digit_from_display_byte(b'Z'), Some(35)); /// assert_eq!(digit_from_display_byte(b' '), None); /// assert_eq!(digit_from_display_byte(b'!'), None); /// ``` pub const fn digit_from_display_byte(b: u8) -> Option { match b { b'0'..=b'9' => Some(b - b'0'), b'a'..=b'z' => Some(b - b'a' + 10), b'A'..=b'Z' => Some(b - b'A' + 10), _ => None, } } macro_rules! impl_from_string_base { ($t:ident) => { impl FromStringBase for $t { /// This is a wrapper over the `from_str_radix` functions in the standard library, for /// example [this one](u32::from_str_radix). #[inline] fn from_string_base(base: u8, s: &str) -> Option { $t::from_str_radix(s, u32::from(base)).ok() } } }; } apply_to_primitive_ints!(impl_from_string_base); malachite-base-0.4.16/src/num/conversion/string/mod.rs000064400000000000000000000161531046102023000207670ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . /// [`FromSciString`](super::traits::FromSciString), a trait for converting strings, possibly using /// scientific notation, to numbers. /// /// # from_sci_string /// ``` /// use malachite_base::num::conversion::traits::FromSciString; /// /// assert_eq!(u8::from_sci_string("123"), Some(123)); /// assert_eq!(u8::from_sci_string("123.5"), Some(124)); /// assert_eq!(u8::from_sci_string("256"), None); /// assert_eq!(u64::from_sci_string("1.23e10"), Some(12300000000)); /// ``` /// /// # from_sci_string_with_options /// ``` /// use malachite_base::num::conversion::string::options::FromSciStringOptions; /// use malachite_base::num::conversion::traits::FromSciString; /// use malachite_base::rounding_modes::RoundingMode::*; /// /// let mut options = FromSciStringOptions::default(); /// assert_eq!( /// u8::from_sci_string_with_options("123.5", options), /// Some(124) /// ); /// /// options.set_rounding_mode(Floor); /// assert_eq!( /// u8::from_sci_string_with_options("123.5", options), /// Some(123) /// ); /// /// options = FromSciStringOptions::default(); /// options.set_base(16); /// assert_eq!(u8::from_sci_string_with_options("ff", options), Some(255)); /// ``` pub mod from_sci_string; /// [`FromStringBase`](super::traits::FromStringBase), a trait for converting strings in a specified /// base to numbers. pub mod from_string; /// [`ToSciOptions`](options::ToSciOptions) and /// [`FromSciSringOptions`](options::FromSciStringOptions), `struct`s for specifying parameters when /// using the [`FromSciString`](super::traits::FromSciString) and [`ToSci`](super::traits::ToSci) /// traits. pub mod options; /// [`ToSci`](super::traits::ToSci), a trait for converting a number to string, possibly using /// scientific notation. /// /// # to_sci /// ``` /// use malachite_base::num::conversion::traits::ToSci; /// /// // If the value can fit in a `u32`, the result is the same as with `to_string` /// assert_eq!(123u8.to_sci().to_string(), "123"); /// /// assert_eq!(u128::MAX.to_sci().to_string(), "3.402823669209385e38"); /// assert_eq!(i128::MIN.to_sci().to_string(), "-1.701411834604692e38"); /// ``` /// /// # to_sci_with_options /// ``` /// use malachite_base::num::conversion::string::options::ToSciOptions; /// use malachite_base::num::conversion::traits::ToSci; /// use malachite_base::rounding_modes::RoundingMode::*; /// /// let mut options = ToSciOptions::default(); /// assert_eq!(123456u32.to_sci_with_options(options).to_string(), "123456"); /// /// options.set_precision(3); /// assert_eq!(123456u32.to_sci_with_options(options).to_string(), "1.23e5"); /// /// options.set_rounding_mode(Ceiling); /// assert_eq!(123456u32.to_sci_with_options(options).to_string(), "1.24e5"); /// /// options.set_e_uppercase(); /// assert_eq!(123456u32.to_sci_with_options(options).to_string(), "1.24E5"); /// /// options.set_force_exponent_plus_sign(true); /// assert_eq!( /// 123456u32.to_sci_with_options(options).to_string(), /// "1.24E+5" /// ); /// /// options = ToSciOptions::default(); /// options.set_base(36); /// assert_eq!(123456u32.to_sci_with_options(options).to_string(), "2n9c"); /// /// options.set_uppercase(); /// assert_eq!(123456u32.to_sci_with_options(options).to_string(), "2N9C"); /// /// options.set_base(2); /// options.set_precision(10); /// assert_eq!( /// 123456u32.to_sci_with_options(options).to_string(), /// "1.1110001e16" /// ); /// /// options.set_include_trailing_zeros(true); /// assert_eq!( /// 123456u32.to_sci_with_options(options).to_string(), /// "1.111000100e16" /// ); /// ``` /// /// # fmt_sci_valid /// ``` /// use malachite_base::num::conversion::string::options::ToSciOptions; /// use malachite_base::num::conversion::traits::ToSci; /// use malachite_base::rounding_modes::RoundingMode::*; /// /// let mut options = ToSciOptions::default(); /// assert!(123u8.fmt_sci_valid(options)); /// assert!(u128::MAX.fmt_sci_valid(options)); /// options.set_rounding_mode(Exact); /// assert!(!u128::MAX.fmt_sci_valid(options)); // u128::MAX has more than 16 significant digits /// options.set_precision(50); /// assert!(u128::MAX.fmt_sci_valid(options)); /// ``` pub mod to_sci; /// The [`BaseFmtWrapper`](to_string::BaseFmtWrapper) struct and /// [`ToStringBase`](super::traits::ToStringBase) trait, used for converting numbers to strings. /// /// # Display::fmt for BaseFmtWrapper /// ``` /// use malachite_base::num::conversion::string::to_string::BaseFmtWrapper; /// /// let x = BaseFmtWrapper::new(1000000000u32, 36); /// assert_eq!(format!("{}", x), "gjdgxs"); /// assert_eq!(format!("{:#}", x), "GJDGXS"); /// assert_eq!(format!("{:010}", x), "0000gjdgxs"); /// assert_eq!(format!("{:#010}", x), "0000GJDGXS"); /// /// let x = BaseFmtWrapper::new(-1000000000i32, 36); /// assert_eq!(format!("{}", x), "-gjdgxs"); /// assert_eq!(format!("{:#}", x), "-GJDGXS"); /// assert_eq!(format!("{:010}", x), "-000gjdgxs"); /// assert_eq!(format!("{:#010}", x), "-000GJDGXS"); /// ``` /// /// # Debug::fmt for BaseFmtWrapper /// ``` /// use malachite_base::num::conversion::string::to_string::BaseFmtWrapper; /// /// let x = BaseFmtWrapper::new(1000000000u32, 36); /// assert_eq!(format!("{:?}", x), "gjdgxs"); /// assert_eq!(format!("{:#?}", x), "GJDGXS"); /// assert_eq!(format!("{:010?}", x), "0000gjdgxs"); /// assert_eq!(format!("{:#010?}", x), "0000GJDGXS"); /// /// let x = BaseFmtWrapper::new(-1000000000i32, 36); /// assert_eq!(format!("{:?}", x), "-gjdgxs"); /// assert_eq!(format!("{:#?}", x), "-GJDGXS"); /// assert_eq!(format!("{:010?}", x), "-000gjdgxs"); /// assert_eq!(format!("{:#010?}", x), "-000GJDGXS"); /// ``` /// /// # to_string_base /// ``` /// use malachite_base::num::conversion::traits::ToStringBase; /// /// assert_eq!(1000u16.to_string_base(2), "1111101000"); /// assert_eq!(1000u16.to_string_base(10), "1000"); /// assert_eq!(1000u16.to_string_base(36), "rs"); /// /// assert_eq!(1000i16.to_string_base(2), "1111101000"); /// assert_eq!(1000i16.to_string_base(10), "1000"); /// assert_eq!(1000i16.to_string_base(36), "rs"); /// /// assert_eq!((-1000i16).to_string_base(2), "-1111101000"); /// assert_eq!((-1000i16).to_string_base(10), "-1000"); /// assert_eq!((-1000i16).to_string_base(36), "-rs"); /// ``` /// /// # to_string_base_upper /// ``` /// use malachite_base::num::conversion::traits::ToStringBase; /// /// assert_eq!(1000u16.to_string_base_upper(2), "1111101000"); /// assert_eq!(1000u16.to_string_base_upper(10), "1000"); /// assert_eq!(1000u16.to_string_base_upper(36), "RS"); /// /// assert_eq!(1000i16.to_string_base_upper(2), "1111101000"); /// assert_eq!(1000i16.to_string_base_upper(10), "1000"); /// assert_eq!(1000i16.to_string_base_upper(36), "RS"); /// /// assert_eq!((-1000i16).to_string_base_upper(2), "-1111101000"); /// assert_eq!((-1000i16).to_string_base_upper(10), "-1000"); /// assert_eq!((-1000i16).to_string_base_upper(36), "-RS"); /// ``` pub mod to_string; malachite-base-0.4.16/src/num/conversion/string/options/exhaustive.rs000064400000000000000000000105601046102023000240640ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::bools::exhaustive::exhaustive_bools; use crate::num::conversion::string::options::{FromSciStringOptions, SciSizeOptions, ToSciOptions}; use crate::num::exhaustive::{ exhaustive_negative_signeds, primitive_int_increasing_inclusive_range, }; use crate::num::logic::traits::NotAssign; use crate::rounding_modes::exhaustive::exhaustive_rounding_modes; use crate::rounding_modes::RoundingMode; use crate::tuples::exhaustive::{exhaustive_triples, lex_pairs, lex_quadruples_from_single}; use alloc::boxed::Box; /// Generates all [`SciSizeOptions`]s. /// /// This struct is created by [`exhaustive_sci_size_options`]; see its documentation for more. pub struct ExhaustiveSciSizeOptions { i: u64, even: bool, } impl Iterator for ExhaustiveSciSizeOptions { type Item = SciSizeOptions; fn next(&mut self) -> Option { let out = if self.even { if self.i == 0 { SciSizeOptions::Complete } else { SciSizeOptions::Precision(self.i) } } else { let i = self.i; self.i += 1; SciSizeOptions::Scale(i) }; self.even.not_assign(); Some(out) } } /// Generates all [`SciSizeOptions`]s. /// /// The output length is $2^{65}$. /// /// # Complexity per iteration /// Constant time and additional memory. pub const fn exhaustive_sci_size_options() -> ExhaustiveSciSizeOptions { ExhaustiveSciSizeOptions { i: 0, even: true } } /// Generates all [`ToSciOptions`]s. /// /// This struct is created by [`exhaustive_to_sci_options`]; see its documentation for more. pub struct ExhaustiveToSciOptions( Box< dyn Iterator< Item = ( (u8, SciSizeOptions, i64), (RoundingMode, (bool, bool, bool, bool)), ), >, >, ); impl Iterator for ExhaustiveToSciOptions { type Item = ToSciOptions; fn next(&mut self) -> Option { let ( (base, size_options, neg_exp_threshold), ( rounding_mode, (lowercase, e_lowercase, force_exponent_plus_sign, include_trailing_zeros), ), ) = self.0.next()?; Some(ToSciOptions { base, size_options, neg_exp_threshold, rounding_mode, lowercase, e_lowercase, force_exponent_plus_sign, include_trailing_zeros, }) } } /// Generates all [`ToSciOptions`]s. /// /// The output length is $2^{133}\times 3 \times 5 \times 7 \approx 1.4335 \times 10^{42}$. /// /// # Complexity per iteration /// Constant time and additional memory. pub fn exhaustive_to_sci_options() -> ExhaustiveToSciOptions { ExhaustiveToSciOptions(Box::new(lex_pairs( exhaustive_triples( primitive_int_increasing_inclusive_range(2, 36), exhaustive_sci_size_options(), exhaustive_negative_signeds(), ), lex_pairs( exhaustive_rounding_modes(), lex_quadruples_from_single(exhaustive_bools()), ), ))) } /// Generates all [`FromSciStringOptions`]s. /// /// This struct is created by [`exhaustive_from_sci_string_options`]; see its documentation for /// more. pub struct ExhaustiveFromSciStringOptions(Box>); impl Iterator for ExhaustiveFromSciStringOptions { type Item = FromSciStringOptions; fn next(&mut self) -> Option { let (base, rounding_mode) = self.0.next()?; Some(FromSciStringOptions { base, rounding_mode, }) } } /// Generates all [`FromSciStringOptions`]s. /// /// The output length is 210. /// /// # Complexity per iteration /// Constant time and additional memory. pub fn exhaustive_from_sci_string_options() -> ExhaustiveFromSciStringOptions { ExhaustiveFromSciStringOptions(Box::new(lex_pairs( primitive_int_increasing_inclusive_range(2, 36), exhaustive_rounding_modes(), ))) } malachite-base-0.4.16/src/num/conversion/string/options/mod.rs000064400000000000000000000251331046102023000224600ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::rounding_modes::RoundingMode::{self, *}; /// A `struct` determining how much "detail" should be used when creating a scientific-notation /// string. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum SciSizeOptions { /// Indicates that the number should be rendered in its full precision. Complete, /// Indicates how many significant figures should be shown. The precision cannot be zero. Precision(u64), /// Indicates how many digits after the decimal (or other-base) point should be shown. For /// example, if the base is 10 and the scale is 2, then up to two digits after the decimal point /// should be shown. Scale(u64), } impl Default for SciSizeOptions { fn default() -> SciSizeOptions { SciSizeOptions::Precision(16) // Similar to f64 string output } } #[cfg(feature = "test_build")] impl SciSizeOptions { pub const fn is_valid(&self) -> bool { if let SciSizeOptions::Precision(p) = *self { p != 0 } else { true } } } /// A `struct` determining how a number should be formatted as a "scientific" string. /// /// - The base must be between 2 and 36, inclusive. The characters representing the digits are `'0'` /// through `'9'` and either `'a'` through `'z'` or `'A'` through `'Z'`, depending on whether the /// `lowercase` field is set. The default base is 10. /// /// - The rounding mode determines how the output should be rounded, in case the `size_options` /// field is such that the number can't be fully represented. The default rounding mode is /// `Nearest`. /// /// - The size options determine the precision or scale that the number should be displayed with. /// The default is `Precision(16)`, which is about as much precision as an `f64` is usually /// displayed with. /// /// - The negative exponent threshold determines when small numbers switch to scientific notation. /// The default is $-6$, meaning that the numbers $1/10, 1/100, 1/1000, \ldots$. would be /// displayed as `0.1, 0.01, 0.001, 0.0001, 0.00001, 1e-6, 1e-7...`. The threshold must be /// negative. /// /// - The lowercase setting determines whether digits in bases greater than 10 are lowercase or /// uppercase. The default is `true`. /// /// - The exponent lowercase setting determines whether the exponent indicator is lowercase (`'e'`) /// or uppercase (`'E'`). The default is `true`. /// /// - The "force exponent plus sign" setting determines whether positive exponents should be /// rendered with an explicit plus sign. If the base is 15 or greater, then the explicit plus sign /// is used regardless, in order to distinguish the exponent indicator from the digit `'e'`. The /// default is `false`. /// /// - The "include trailing zeros" setting determines whether trailing zeros after the decimal (or /// other-base) point should be included. The default is `false`. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct ToSciOptions { pub(crate) base: u8, pub(crate) rounding_mode: RoundingMode, pub(crate) size_options: SciSizeOptions, neg_exp_threshold: i64, pub(crate) lowercase: bool, pub(crate) e_lowercase: bool, pub(crate) force_exponent_plus_sign: bool, pub(crate) include_trailing_zeros: bool, } impl Default for ToSciOptions { fn default() -> ToSciOptions { ToSciOptions { base: 10, rounding_mode: Nearest, size_options: SciSizeOptions::default(), neg_exp_threshold: -6, lowercase: true, e_lowercase: true, force_exponent_plus_sign: false, include_trailing_zeros: false, } } } impl ToSciOptions { /// Returns the base to be used in the conversion. It is always between 2 and 36, inclusive. #[inline] pub const fn get_base(&self) -> u8 { self.base } /// Returns the rounding mode to be used in the conversion. #[inline] pub const fn get_rounding_mode(&self) -> RoundingMode { self.rounding_mode } /// Returns the size options to be used in the conversion. #[inline] pub const fn get_size_options(&self) -> SciSizeOptions { self.size_options } /// Returns the exponent low threshold to be used in the conversion. It is always negative. #[inline] pub const fn get_neg_exp_threshold(&self) -> i64 { self.neg_exp_threshold } /// Returns whether the digits should be lowercase. #[inline] pub const fn get_lowercase(&self) -> bool { self.lowercase } /// Returns whether the exponent indicator should be lowercase (`'e'` rather than `'E'`). #[inline] pub const fn get_e_lowercase(&self) -> bool { self.e_lowercase } /// Returns whether positive exponents should always be preceded by an explicit plus sign. #[inline] pub const fn get_force_exponent_plus_sign(&self) -> bool { self.force_exponent_plus_sign } /// Returns whether trailing zeros should be included after the decimal (or other-base) point. #[inline] pub const fn get_include_trailing_zeros(&self) -> bool { self.include_trailing_zeros } /// Sets the base to be used in the conversion. /// /// # Panics /// Panics if `base` is less than 2 or greater than 36. #[inline] pub fn set_base(&mut self, base: u8) { assert!(base >= 2); assert!(base <= 36); self.base = base; } /// Sets the rounding mode to be used in the conversion. #[inline] pub fn set_rounding_mode(&mut self, rm: RoundingMode) { self.rounding_mode = rm; } /// Sets the size options to the "Complete" mode, indicating that the number should be converted /// using its full precision. #[inline] pub fn set_size_complete(&mut self) { self.size_options = SciSizeOptions::Complete; } /// Sets the size options to some precision, or number of significant digits. /// /// # Panics /// Panics if `precision` is zero. #[inline] pub fn set_precision(&mut self, precision: u64) { assert_ne!(precision, 0); self.size_options = SciSizeOptions::Precision(precision); } /// Sets the size options to some scale, or number of digits after the decimal (or other-base) /// point. #[inline] pub fn set_scale(&mut self, scale: u64) { self.size_options = SciSizeOptions::Scale(scale); } /// Sets the threshold at which nonzero numbers with a small absolute value start being /// represented using negative exponents. #[inline] pub fn set_neg_exp_threshold(&mut self, neg_exp_threshold: i64) { assert!(neg_exp_threshold < 0); self.neg_exp_threshold = neg_exp_threshold; } /// Specifies that digits in bases greater than ten should be output with lowercase letters. #[inline] pub fn set_lowercase(&mut self) { self.lowercase = true; } /// Specifies that digits in bases greater than ten should be output with uppercase letters. #[inline] pub fn set_uppercase(&mut self) { self.lowercase = false; } /// Specifies that the exponent-indicating character should be `'e'`. #[inline] pub fn set_e_lowercase(&mut self) { self.e_lowercase = true; } /// Specifies that the exponent-indicating character should be `'E'`. #[inline] pub fn set_e_uppercase(&mut self) { self.e_lowercase = false; } /// Sets whether a positive exponent should be preceded by an explicit plus sign. /// /// If the base is 15 or greater, an explicit plus sign will be used regardless, in order to /// differentiate the exponent-indicating character from the digit `'e'`. #[inline] pub fn set_force_exponent_plus_sign(&mut self, force_exponent_plus_sign: bool) { self.force_exponent_plus_sign = force_exponent_plus_sign; } /// Sets whether trailing zeros after the decimal (or other-base) point should be included. #[inline] pub fn set_include_trailing_zeros(&mut self, include_trailing_zeros: bool) { self.include_trailing_zeros = include_trailing_zeros; } #[cfg(feature = "test_build")] pub fn is_valid(&self) -> bool { (2..=36).contains(&self.base) && self.neg_exp_threshold < 0 && self.size_options.is_valid() } } /// A `struct` determining how a number should be parsed from a "scientific" string. /// /// - The base must be between 2 and 36, inclusive. The characters representing the digits may be /// `'0'` through `'9'` and either `'a'` through `'z'` or `'A'` through `'Z'`. The default base is /// 10. /// /// - The rounding mode determines how the output should be rounded, in case the output type can't /// represent all possible input strings. The default rounding mode is `Nearest`. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct FromSciStringOptions { pub(crate) base: u8, pub(crate) rounding_mode: RoundingMode, } impl Default for FromSciStringOptions { fn default() -> FromSciStringOptions { FromSciStringOptions { base: 10, rounding_mode: Nearest, } } } impl FromSciStringOptions { /// Returns the base to be used in the conversion. It is always between 2 and 36, inclusive. #[inline] pub const fn get_base(&self) -> u8 { self.base } /// Returns the rounding mode to be used in the conversion. #[inline] pub const fn get_rounding_mode(&self) -> RoundingMode { self.rounding_mode } /// Sets the base to be used in the conversion. /// /// # Panics /// Panics if `base` is less than 2 or greater than 36. #[inline] pub fn set_base(&mut self, base: u8) { assert!(base >= 2); assert!(base <= 36); self.base = base; } /// Sets the rounding mode to be used in the conversion. #[inline] pub fn set_rounding_mode(&mut self, rm: RoundingMode) { self.rounding_mode = rm; } #[cfg(feature = "test_build")] pub fn is_valid(&self) -> bool { (2..=36).contains(&self.base) } } /// Iterators that generate [`SciSizeOptions`], [`ToSciOptions`], and [`FromSciStringOptions`] /// without repetition. pub mod exhaustive; #[cfg(feature = "random")] /// Iterators that generate [`SciSizeOptions`], [`ToSciOptions`], and [`FromSciStringOptions`] /// randomly. pub mod random; malachite-base-0.4.16/src/num/conversion/string/options/random.rs000064400000000000000000000120031046102023000231510ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::bools::random::{random_bools, RandomBools}; use crate::num::conversion::string::options::{FromSciStringOptions, SciSizeOptions, ToSciOptions}; use crate::num::random::geometric::{ geometric_random_negative_signeds, geometric_random_unsigneds, GeometricRandomNaturalValues, GeometricRandomNegativeSigneds, }; use crate::num::random::{random_unsigned_inclusive_range, RandomUnsignedInclusiveRange}; use crate::random::Seed; use crate::rounding_modes::random::{random_rounding_modes, RandomRoundingModes}; /// Generates random [`SciSizeOptions`]s. /// /// This struct is created by [`random_sci_size_options`]; see its documentation for more. pub struct RandomSciSizeOptions { bs: RandomBools, xs: GeometricRandomNaturalValues, } impl Iterator for RandomSciSizeOptions { type Item = SciSizeOptions; fn next(&mut self) -> Option { let x = self.xs.next().unwrap(); Some(if self.bs.next().unwrap() { if x == 0 { SciSizeOptions::Complete } else { SciSizeOptions::Precision(x) } } else { SciSizeOptions::Scale(x) }) } } /// Generates random [`SciSizeOptions`]s. /// /// The scales and precisions are chosen from a geometric distribution whose mean is the ratio /// `m_size_numerator / m_size_denominator`. /// /// # Panics /// Panics if `m_size_numerator` or `m_size_denominator` are zero, or, if after being reduced to /// lowest terms, their sum is greater than or equal to $2^{64}$. /// /// The output length is infinite. pub fn random_sci_size_options( seed: Seed, m_size_numerator: u64, m_size_denominator: u64, ) -> RandomSciSizeOptions { RandomSciSizeOptions { bs: random_bools(seed.fork("bs")), xs: geometric_random_unsigneds(seed.fork("xs"), m_size_numerator, m_size_denominator), } } /// Generates random [`ToSciOptions`]s. /// /// This struct is created by [`random_to_sci_options`]; see its documentation for more. pub struct RandomToSciOptions { us: RandomUnsignedInclusiveRange, rms: RandomRoundingModes, sos: RandomSciSizeOptions, is: GeometricRandomNegativeSigneds, bs: RandomBools, } impl Iterator for RandomToSciOptions { type Item = ToSciOptions; fn next(&mut self) -> Option { Some(ToSciOptions { base: self.us.next().unwrap(), rounding_mode: self.rms.next().unwrap(), size_options: self.sos.next().unwrap(), neg_exp_threshold: self.is.next().unwrap(), lowercase: self.bs.next().unwrap(), e_lowercase: self.bs.next().unwrap(), force_exponent_plus_sign: self.bs.next().unwrap(), include_trailing_zeros: self.bs.next().unwrap(), }) } } /// Generates random [`ToSciOptions`]s. /// /// The scales, precisions, and the negative of the negative exponenet threshold are chosen from a /// geometric distribution whose mean is the ratio `m_size_numerator / m_size_denominator`. /// /// # Panics /// Panics if `m_size_numerator` or `m_size_denominator` are zero, or, if after being reduced to /// lowest terms, their sum is greater than or equal to $2^{64}$. /// /// The output length is infinite. pub fn random_to_sci_options( seed: Seed, m_size_numerator: u64, m_size_denominator: u64, ) -> RandomToSciOptions { RandomToSciOptions { us: random_unsigned_inclusive_range(seed.fork("us"), 2, 36), rms: random_rounding_modes(seed.fork("rms")), sos: random_sci_size_options(seed.fork("sos"), m_size_numerator, m_size_denominator), is: geometric_random_negative_signeds( seed.fork("is"), m_size_numerator, m_size_denominator, ), bs: random_bools(seed.fork("bs")), } } /// Generates random [`FromSciStringOptions`]s. /// /// This struct is created by [`random_from_sci_string_options`]; see its documentation for more. pub struct RandomFromSciStringOptions { us: RandomUnsignedInclusiveRange, rms: RandomRoundingModes, } impl Iterator for RandomFromSciStringOptions { type Item = FromSciStringOptions; fn next(&mut self) -> Option { Some(FromSciStringOptions { base: self.us.next().unwrap(), rounding_mode: self.rms.next().unwrap(), }) } } /// Generates random [`FromSciStringOptions`]s. /// /// The output length is infinite. pub fn random_from_sci_string_options(seed: Seed) -> RandomFromSciStringOptions { RandomFromSciStringOptions { us: random_unsigned_inclusive_range(seed.fork("us"), 2, 36), rms: random_rounding_modes(seed.fork("rms")), } } malachite-base-0.4.16/src/num/conversion/string/to_sci.rs000064400000000000000000000240041046102023000214620ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{CheckedLogBase2, NegAssign, Pow, UnsignedAbs}; use crate::num::basic::integers::PrimitiveInt; use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::string::options::{SciSizeOptions, ToSciOptions}; use crate::num::conversion::string::to_string::BaseFmtWrapper; use crate::num::conversion::string::to_string::{ digit_to_display_byte_lower, digit_to_display_byte_upper, }; use crate::num::conversion::traits::{ExactFrom, ToSci}; use crate::rounding_modes::RoundingMode::*; use crate::slices::slice_trailing_zeros; use alloc::string::String; use core::fmt::{Display, Formatter, Write}; /// A `struct` that can be used to format a number in scientific notation. pub struct SciWrapper<'a, T: ToSci> { pub(crate) x: &'a T, pub(crate) options: ToSciOptions, } impl<'a, T: ToSci> Display for SciWrapper<'a, T> { #[inline] fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { self.x.fmt_sci(f, self.options) } } #[doc(hidden)] pub fn write_exponent( f: &mut Formatter, options: ToSciOptions, exp: T, ) -> core::fmt::Result { f.write_char(if options.get_e_lowercase() { 'e' } else { 'E' })?; if exp > T::ZERO && (options.get_force_exponent_plus_sign() || options.get_base() >= 15) { f.write_char('+')?; } write!(f, "{exp}") } fn write_helper(x: T, f: &mut Formatter, options: ToSciOptions) -> core::fmt::Result where BaseFmtWrapper: Display, { let w = BaseFmtWrapper { x, base: options.base, }; if options.lowercase { Display::fmt(&w, f) } else { write!(f, "{w:#}") } } fn fmt_sci_valid_unsigned(x: T, options: ToSciOptions) -> bool { if x == T::ZERO || options.rounding_mode != Exact { return true; } match options.size_options { SciSizeOptions::Complete | SciSizeOptions::Scale(_) => true, SciSizeOptions::Precision(precision) => { let t_base = T::from(options.base); let log = x.floor_log_base(t_base); if log < precision { return true; } let neg_scale = log - precision + 1; if let Some(base_log) = options.base.checked_log_base_2() { x.divisible_by_power_of_2(base_log * neg_scale) } else { x.divisible_by(Pow::pow(t_base, neg_scale)) } } } } fn fmt_sci_unsigned( mut x: T, f: &mut Formatter, options: ToSciOptions, ) -> core::fmt::Result where BaseFmtWrapper: Display, { match options.size_options { SciSizeOptions::Complete | SciSizeOptions::Scale(0) => write_helper(x, f, options), SciSizeOptions::Scale(scale) => { write_helper(x, f, options)?; if options.include_trailing_zeros { f.write_char('.')?; for _ in 0..scale { f.write_char('0')?; } } Ok(()) } SciSizeOptions::Precision(precision) => { let t_base = T::from(options.base); let log = if x == T::ZERO { 0 } else { x.floor_log_base(t_base) }; if log < precision { // no exponent write_helper(x, f, options)?; if options.include_trailing_zeros { let extra_zeros = precision - log - 1; if extra_zeros != 0 { f.write_char('.')?; for _ in 0..extra_zeros { f.write_char('0')?; } } } Ok(()) } else { // exponent let mut e = log; let neg_scale = log - precision + 1; if let Some(base_log) = options.base.checked_log_base_2() { x.shr_round_assign(base_log * neg_scale, options.rounding_mode); } else { x.div_round_assign(Pow::pow(t_base, neg_scale), options.rounding_mode); } let mut chars = x.to_digits_desc(&options.base); let mut len = chars.len(); let p = usize::exact_from(precision); if len > p { // rounded up to a power of the base, need to reduce precision chars.pop(); len -= 1; e += 1; } assert_eq!(len, p); if !options.include_trailing_zeros { chars.truncate(len - slice_trailing_zeros(&chars)); } if options.lowercase { for digit in &mut chars { *digit = digit_to_display_byte_lower(*digit).unwrap(); } } else { for digit in &mut chars { *digit = digit_to_display_byte_upper(*digit).unwrap(); } } len = chars.len(); if len != 1 { chars.push(b'0'); chars.copy_within(1..len, 2); chars[1] = b'.'; } f.write_str(&String::from_utf8(chars).unwrap())?; write_exponent(f, options, e) } } } } #[inline] fn fmt_sci_valid_signed(x: T, options: ToSciOptions) -> bool where ::Output: PrimitiveUnsigned, { fmt_sci_valid_unsigned(x.unsigned_abs(), options) } fn fmt_sci_signed( x: T, f: &mut Formatter, mut options: ToSciOptions, ) -> core::fmt::Result where ::Output: PrimitiveUnsigned, { let abs = x.unsigned_abs(); if x >= T::ZERO { abs.fmt_sci(f, options) } else { options.rounding_mode.neg_assign(); f.write_char('-')?; abs.fmt_sci(f, options) } } macro_rules! impl_to_sci_unsigned { ($t:ident) => { impl ToSci for $t { /// Determines whether an unsigned number can be converted to a string using /// [`to_sci_with_options`](super::super::traits::ToSci::to_sci_with_options) and a /// particular set of options. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::to_sci#fmt_sci_valid). #[inline] fn fmt_sci_valid(&self, options: ToSciOptions) -> bool { fmt_sci_valid_unsigned(*self, options) } /// Converts an unsigned number to a string using a specified base, possibly formatting /// the number using scientific notation. /// /// See [`ToSciOptions`] for details on the available options. Note that setting /// `neg_exp_threshold` has no effect, since there is never a need to use negative /// exponents when representing an integer. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`. /// /// # Panics /// Panics if `options.rounding_mode` is `Exact`, but the size options are such that the /// input must be rounded. /// /// # Examples /// See [here](super::to_sci). #[inline] fn fmt_sci(&self, f: &mut Formatter, options: ToSciOptions) -> core::fmt::Result { fmt_sci_unsigned(*self, f, options) } } }; } apply_to_unsigneds!(impl_to_sci_unsigned); macro_rules! impl_to_sci_signed { ($t:ident) => { impl ToSci for $t { /// Determines whether a signed number can be converted to a string using /// [`to_sci_with_options`](super::super::traits::ToSci::to_sci_with_options) and a /// particular set of options. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::to_sci#fmt_sci_valid). #[inline] fn fmt_sci_valid(&self, options: ToSciOptions) -> bool { fmt_sci_valid_signed(*self, options) } /// Converts a signed number to a string using a specified base, possibly formatting the /// number using scientific notation. /// /// See [`ToSciOptions`] for details on the available options. Note that setting /// `neg_exp_threshold` has no effect, since there is never a need to use negative /// exponents when representing an integer. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`. /// /// # Panics /// Panics if `options.rounding_mode` is `Exact`, but the size options are such that the /// input must be rounded. /// /// # Examples /// See [here](super::to_sci). #[inline] fn fmt_sci(&self, f: &mut Formatter, options: ToSciOptions) -> core::fmt::Result { fmt_sci_signed(*self, f, options) } } }; } apply_to_signeds!(impl_to_sci_signed); malachite-base-0.4.16/src/num/conversion/string/to_string.rs000064400000000000000000000370731046102023000222240ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::UnsignedAbs; use crate::num::basic::traits::Zero; use crate::num::conversion::traits::{Digits, ToStringBase, WrappingFrom}; use crate::vecs::vec_pad_left; use alloc::string::String; use alloc::string::ToString; use core::fmt::{Debug, Display, Formatter, Result, Write}; /// A `struct` that allows for formatting a numeric type and rendering its digits in a specified /// base. #[derive(Clone, Eq, Hash, PartialEq)] pub struct BaseFmtWrapper { pub(crate) x: T, pub(crate) base: u8, } impl BaseFmtWrapper { /// Creates a new `BaseFmtWrapper`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `base` is less than 2 or greater than 36. /// /// # Examples /// ``` /// use malachite_base::num::conversion::string::to_string::BaseFmtWrapper; /// /// let x = BaseFmtWrapper::new(1000000000u32, 36); /// assert_eq!(format!("{}", x), "gjdgxs"); /// assert_eq!(format!("{:#}", x), "GJDGXS"); /// ``` pub fn new(x: T, base: u8) -> Self { assert!((2..=36).contains(&base), "base out of range"); BaseFmtWrapper { x, base } } /// Recovers the value from a `BaseFmtWrapper`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::num::conversion::string::to_string::BaseFmtWrapper; /// /// assert_eq!(BaseFmtWrapper::new(1000000000u32, 36).unwrap(), 1000000000); /// ``` #[allow(clippy::missing_const_for_fn)] pub fn unwrap(self) -> T { self.x } } /// Converts a digit to a byte corresponding to a numeric or lowercase alphabetic [`char`] that /// represents the digit. /// /// Digits from 0 to 9 become bytes corresponding to [`char`]s from '0' to '9'. Digits from 10 to 35 /// become bytes representing the lowercase [`char`]s 'a' to 'z'. Passing a digit greater than 35 /// gives a `None`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::num::conversion::string::to_string::digit_to_display_byte_lower; /// /// assert_eq!(digit_to_display_byte_lower(0), Some(b'0')); /// assert_eq!(digit_to_display_byte_lower(9), Some(b'9')); /// assert_eq!(digit_to_display_byte_lower(10), Some(b'a')); /// assert_eq!(digit_to_display_byte_lower(35), Some(b'z')); /// assert_eq!(digit_to_display_byte_lower(100), None); /// ``` pub const fn digit_to_display_byte_lower(b: u8) -> Option { match b { 0..=9 => Some(b + b'0'), 10..=35 => Some(b + b'a' - 10), _ => None, } } /// Converts a digit to a byte corresponding to a numeric or uppercase alphabetic [`char`] that /// represents the digit. /// /// Digits from 0 to 9 become bytes corresponding to [`char`]s from '0' to '9'. Digits from 10 to 35 /// become bytes representing the lowercase [`char`]s 'A' to 'Z'. Passing a digit greater than 35 /// gives a `None`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::num::conversion::string::to_string::digit_to_display_byte_upper; /// /// assert_eq!(digit_to_display_byte_upper(0), Some(b'0')); /// assert_eq!(digit_to_display_byte_upper(9), Some(b'9')); /// assert_eq!(digit_to_display_byte_upper(10), Some(b'A')); /// assert_eq!(digit_to_display_byte_upper(35), Some(b'Z')); /// assert_eq!(digit_to_display_byte_upper(100), None); /// ``` pub const fn digit_to_display_byte_upper(b: u8) -> Option { match b { 0..=9 => Some(b + b'0'), 10..=35 => Some(b + b'A' - 10), _ => None, } } fn fmt_unsigned + Eq + Zero>( w: &BaseFmtWrapper, f: &mut Formatter, ) -> Result { let mut digits = w.x.to_digits_desc(&u8::wrapping_from(w.base)); if f.alternate() { for digit in &mut digits { *digit = digit_to_display_byte_upper(*digit).unwrap(); } } else { for digit in &mut digits { *digit = digit_to_display_byte_lower(*digit).unwrap(); } } if w.x == T::ZERO { digits.push(b'0'); } f.pad_integral(true, "", core::str::from_utf8(&digits).unwrap()) } fn to_string_base_unsigned + Eq + Zero>(x: &T, base: u8) -> String { assert!((2..=36).contains(&base), "base out of range"); if *x == T::ZERO { "0".to_string() } else { let mut digits = x.to_digits_desc(&base); for digit in &mut digits { *digit = digit_to_display_byte_lower(*digit).unwrap(); } String::from_utf8(digits).unwrap() } } fn to_string_base_upper_unsigned + Eq + Zero>(x: &T, base: u8) -> String { assert!((2..=36).contains(&base), "base out of range"); if *x == T::ZERO { "0".to_string() } else { let mut digits = x.to_digits_desc(&base); for digit in &mut digits { *digit = digit_to_display_byte_upper(*digit).unwrap(); } String::from_utf8(digits).unwrap() } } macro_rules! impl_to_string_base_unsigned { ($t:ident) => { impl Display for BaseFmtWrapper<$t> { /// Writes a wrapped unsigned number to a string using a specified base. /// /// If the base is greater than 10, lowercase alphabetic letters are used by default. /// Using the `#` flag switches to uppercase letters. Padding with zeros works as usual. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`. /// /// # Panics /// Panics if `base` is less than 2 or greater than 36. /// /// # Examples /// See [here](super::to_string). #[inline] fn fmt(&self, f: &mut Formatter) -> Result { fmt_unsigned(self, f) } } impl Debug for BaseFmtWrapper<$t> { /// Writes a wrapped unsigned number to a string using a specified base. /// /// If the base is greater than 10, lowercase alphabetic letters are used by default. /// Using the `#` flag switches to uppercase letters. Padding with zeros works as usual. /// /// This is the same as the [`Display::fmt`] implementation. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`. /// /// # Panics /// Panics if `base` is less than 2 or greater than 36. /// /// # Examples /// See [here](super::to_string). #[inline] fn fmt(&self, f: &mut Formatter) -> Result { Display::fmt(self, f) } } impl ToStringBase for $t { /// Converts an unsigned number to a string using a specified base. /// /// Digits from 0 to 9 become `char`s from '0' to '9'. Digits from 10 to 35 become the /// lowercase [`char`]s 'a' to 'z'. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`. /// /// # Panics /// Panics if `base` is less than 2 or greater than 36. /// /// # Examples /// See [here](super::to_string#to_string_base). #[inline] fn to_string_base(&self, base: u8) -> String { to_string_base_unsigned(self, base) } /// Converts an unsigned number to a string using a specified base. /// /// Digits from 0 to 9 become `char`s from '0' to '9'. Digits from 10 to 35 become the /// uppercase [`char`]s 'A' to 'Z'. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`. /// /// # Panics /// Panics if `base` is less than 2 or greater than 36. /// /// # Examples /// See [here](super::to_string#to_string_base_upper). #[inline] fn to_string_base_upper(&self, base: u8) -> String { to_string_base_upper_unsigned(self, base) } } }; } apply_to_unsigneds!(impl_to_string_base_unsigned); fn fmt_signed( w: &BaseFmtWrapper, f: &mut Formatter, ) -> Result where BaseFmtWrapper<::Output>: Display, { if w.x < T::ZERO { f.write_char('-')?; if let Some(width) = f.width() { return if f.alternate() { write!( f, "{:#0width$}", &BaseFmtWrapper::new(w.x.unsigned_abs(), w.base), width = width.saturating_sub(1) ) } else { write!( f, "{:0width$}", &BaseFmtWrapper::new(w.x.unsigned_abs(), w.base), width = width.saturating_sub(1) ) }; } } Display::fmt(&BaseFmtWrapper::new(w.x.unsigned_abs(), w.base), f) } fn to_string_base_signed, S: Copy + Eq + Ord + UnsignedAbs + Zero>( x: &S, base: u8, ) -> String { assert!((2..=36).contains(&base), "base out of range"); if *x == S::ZERO { "0".to_string() } else { let mut digits = x.unsigned_abs().to_digits_desc(&u8::wrapping_from(base)); for digit in &mut digits { *digit = digit_to_display_byte_lower(*digit).unwrap(); } if *x < S::ZERO { vec_pad_left(&mut digits, 1, b'-'); } String::from_utf8(digits).unwrap() } } fn to_string_base_upper_signed< U: Digits, S: Copy + Eq + Ord + UnsignedAbs + Zero, >( x: &S, base: u8, ) -> String { assert!((2..=36).contains(&base), "base out of range"); if *x == S::ZERO { "0".to_string() } else { let mut digits = x.unsigned_abs().to_digits_desc(&base); for digit in &mut digits { *digit = digit_to_display_byte_upper(*digit).unwrap(); } if *x < S::ZERO { vec_pad_left(&mut digits, 1, b'-'); } String::from_utf8(digits).unwrap() } } macro_rules! impl_to_string_base_signed { ($u:ident, $s:ident) => { impl Display for BaseFmtWrapper<$s> { /// Writes a wrapped signed number to a string using a specified base. /// /// If the base is greater than 10, lowercase alphabetic letters are used by default. /// Using the `#` flag switches to uppercase letters. Padding with zeros works as usual. /// /// Unlike with the default implementations of [`Binary`](std::fmt::Binary), /// [`Octal`](std::fmt::Octal), [`LowerHex`](std::fmt::LowerHex), and /// [`UpperHex`](std::fmt::UpperHex), negative numbers are represented using a negative /// sign, not two's complement. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`. /// /// # Panics /// Panics if `base` is less than 2 or greater than 36. /// /// # Examples /// See [here](super::to_string). #[inline] fn fmt(&self, f: &mut Formatter) -> Result { fmt_signed(self, f) } } impl Debug for BaseFmtWrapper<$s> { /// Writes a wrapped signed number to a string using a specified base. /// /// If the base is greater than 10, lowercase alphabetic letters are used by default. /// Using the `#` flag switches to uppercase letters. Padding with zeros works as usual. /// /// Unlike with the default implementations of [`Binary`](std::fmt::Binary), /// [`Octal`](std::fmt::Octal), [`LowerHex`](std::fmt::LowerHex), and /// [`UpperHex`](std::fmt::UpperHex), negative numbers are represented using a negative /// sign, not two's complement. /// /// This is the same as the [`Display::fmt`] implementation. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`. /// /// # Panics /// Panics if `base` is less than 2 or greater than 36. /// /// # Examples /// See [here](super::to_string). #[inline] fn fmt(&self, f: &mut Formatter) -> Result { Display::fmt(self, f) } } impl ToStringBase for $s { /// Converts a signed number to a string using a specified base. /// /// Digits from 0 to 9 become `char`s from '0' to '9'. Digits from 10 to 35 become the /// lowercase [`char`]s 'a' to 'z'. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`. /// /// # Panics /// Panics if `base` is less than 2 or greater than 36. /// /// # Examples /// See [here](super::to_string#to_string_base). #[inline] fn to_string_base(&self, base: u8) -> String { to_string_base_signed::<$u, $s>(self, base) } /// Converts a signed number to a string using a specified base. /// /// Digits from 0 to 9 become `char`s from '0' to '9'. Digits from 10 to 35 become the /// uppercase [`char`]s 'A' to 'Z'. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`. /// /// # Panics /// Panics if `base` is less than 2 or greater than 36. /// /// # Examples /// See [here](super::to_string#to_string_base_upper). #[inline] fn to_string_base_upper(&self, base: u8) -> String { to_string_base_upper_signed::<$u, $s>(self, base) } } }; } apply_to_unsigned_signed_pairs!(impl_to_string_base_signed); malachite-base-0.4.16/src/num/conversion/traits.rs000064400000000000000000000351661046102023000202150ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::conversion::string::options::{FromSciStringOptions, ToSciOptions}; use crate::num::conversion::string::to_sci::SciWrapper; use crate::rounding_modes::RoundingMode; use alloc::string::String; use alloc::vec::Vec; use core::cmp::Ordering; use core::fmt::{Formatter, Result}; /// Expresses a value as a [`Vec`] of digits, or reads a value from an iterator of digits. /// /// The trait is parameterized by `T`, which is both the digit type and the base type. pub trait Digits: Sized { /// Returns a [`Vec`] containing the digits of a value in ascending order: least- to /// most-significant. fn to_digits_asc(&self, base: &T) -> Vec; /// Returns a [`Vec`] containing the digits of a value in descending order: most- to /// least-significant. fn to_digits_desc(&self, base: &T) -> Vec; /// Converts an iterator of digits into a value. /// /// The input digits are in ascending order: least- to most-significant. fn from_digits_asc>(base: &T, digits: I) -> Option; /// Converts an iterator of digits into a value. /// /// The input digits are in descending order: most- to least-significant. fn from_digits_desc>(base: &T, digits: I) -> Option; } /// An iterator over a value's base-$2^k$ digits. pub trait PowerOf2DigitIterator: Iterator + DoubleEndedIterator { fn get(&self, index: u64) -> T; } /// Creates an iterator over a value's base-$2^k$ digits. pub trait PowerOf2DigitIterable { type PowerOf2DigitIterator: PowerOf2DigitIterator; /// Returns a double-ended iterator over a value's digits in base $2^l$, where $k$ is /// `log_base`. /// /// The iterator ends after the value's most-significant digit. fn power_of_2_digits(self, log_base: u64) -> Self::PowerOf2DigitIterator; } /// Expresses a value as a [`Vec`] of base-$2^k$ digits, or reads a value from an iterator of /// base-$2^k$ digits. /// /// The trait is parameterized by the digit type. pub trait PowerOf2Digits: Sized { /// Returns a [`Vec`] containing the digits of a value in ascending order: least- to /// most-significant. /// /// The base is $2^k$, where $k$ is `log_base`. fn to_power_of_2_digits_asc(&self, log_base: u64) -> Vec; /// Returns a [`Vec`] containing the digits of a value in descending order: most- to /// least-significant. /// /// The base is $2^k$, where $k$ is `log_base`. fn to_power_of_2_digits_desc(&self, log_base: u64) -> Vec; /// Converts an iterator of digits into a value. /// /// The input digits are in ascending order: least- to most-significant. The base is $2^k$, /// where $k$ is `log_base`. fn from_power_of_2_digits_asc>(log_base: u64, digits: I) -> Option; /// Converts an iterator of digits into a value. /// /// The input digits are in descending order: most- to least-significant. The base is $2^k$, /// where $k$ is `log_base`. fn from_power_of_2_digits_desc>(log_base: u64, digits: I) -> Option; } /// Converts a string slice in a given base to a value. pub trait FromStringBase: Sized { fn from_string_base(base: u8, s: &str) -> Option; } /// Converts a number to a string using a specified base. pub trait ToStringBase { /// Converts a signed number to a lowercase string using a specified base. fn to_string_base(&self, base: u8) -> String; /// Converts a signed number to an uppercase string using a specified base. fn to_string_base_upper(&self, base: u8) -> String; } /// Converts a number to a string, possibly in scientific notation. pub trait ToSci: Sized { /// Formats a number, possibly in scientific notation. fn fmt_sci(&self, f: &mut Formatter, options: ToSciOptions) -> Result; /// Determines whether some formatting options can be applied to a number. fn fmt_sci_valid(&self, options: ToSciOptions) -> bool; /// Converts a number to a string, possibly in scientific notation. fn to_sci_with_options(&self, options: ToSciOptions) -> SciWrapper { SciWrapper { x: self, options } } /// Converts a number to a string, possibly in scientific notation, using the default /// [`ToSciOptions`]. #[inline] fn to_sci(&self) -> SciWrapper { SciWrapper { x: self, options: ToSciOptions::default(), } } } /// Converts a `&str`, possibly in scientific notation, to a number. pub trait FromSciString: Sized { /// Converts a `&str`, possibly in scientific notation, to a number. fn from_sci_string_with_options(s: &str, options: FromSciStringOptions) -> Option; /// Converts a `&str`, possibly in scientific notation, to a number, using the default /// [`FromSciStringOptions`]. #[inline] fn from_sci_string(s: &str) -> Option { Self::from_sci_string_with_options(s, FromSciStringOptions::default()) } } /// Converts a value from one type to another. If the conversion fails, the function panics. /// /// It is recommended that this trait is not implemented directly; it is automatically implemented /// when [`TryFrom`] is implemented. pub trait ExactFrom: Sized { fn exact_from(value: T) -> Self; } /// Converts a value from one type to another. If the conversion fails, the function panics. /// /// It is recommended that this trait is not implemented directly; it is automatically implemented /// when [`ExactFrom`] is implemented. pub trait ExactInto { fn exact_into(self) -> T; } impl> ExactFrom for U { #[inline] fn exact_from(value: T) -> U { U::try_from(value).ok().unwrap() } } impl> ExactInto for T { #[inline] fn exact_into(self) -> U { U::exact_from(self) } } /// Converts a value from one type to another. where if the conversion is not exact the result will /// wrap around. /// /// If `WrappingFrom` is implemented, it usually makes sense to implement [`OverflowingFrom`] as /// well. pub trait WrappingFrom: Sized { fn wrapping_from(value: T) -> Self; } /// Converts a value from one type to another, where if the conversion is not exact the result will /// wrap around. /// /// It is recommended that this trait is not implemented directly; it is automatically implemented /// when [`WrappingFrom`] is implemented. pub trait WrappingInto: Sized { fn wrapping_into(self) -> T; } impl> WrappingInto for T { #[inline] fn wrapping_into(self) -> U { U::wrapping_from(self) } } /// Converts a value from one type to another, where if the conversion is not exact the result is /// set to the maximum or minimum value of the result type, whichever is closer. pub trait SaturatingFrom: Sized { fn saturating_from(value: T) -> Self; } /// Converts a value from one type to another, where if the conversion is not exact the result is /// set to the maximum or minimum value of the result type, whichever is closer. /// /// It is recommended that this trait is not implemented directly; it is automatically implemented /// when [`SaturatingFrom`] is implemented. pub trait SaturatingInto: Sized { fn saturating_into(self) -> T; } impl> SaturatingInto for T { #[inline] fn saturating_into(self) -> U { U::saturating_from(self) } } /// Converts a value from one type to another, where if the conversion is not exact the result will /// wrap around. The result is returned along with a [`bool`] that indicates whether wrapping has /// occurred. /// /// If `OverflowingFrom` is implemented, it usually makes sense to implement [`WrappingFrom`] as /// well. pub trait OverflowingFrom: Sized { fn overflowing_from(value: T) -> (Self, bool); } /// Converts a value from one type to another, where if the conversion is not exact the result will /// wrap around. The result is returned along with a [`bool`] that indicates whether wrapping has /// occurred. /// /// It is recommended that this trait is not implemented directly; it is automatically implemented /// when [`OverflowingFrom`] is implemented. pub trait OverflowingInto: Sized { fn overflowing_into(self) -> (T, bool); } impl> OverflowingInto for T { #[inline] fn overflowing_into(self) -> (U, bool) { U::overflowing_from(self) } } /// Converts a value from one type to another, where the conversion is made according to a specified /// [`RoundingMode`]. An [`Ordering`] is also returned, indicating whether the returned value is /// less than, equal to, or greater than the original value. pub trait RoundingFrom: Sized { fn rounding_from(value: T, rm: RoundingMode) -> (Self, Ordering); } /// Converts a value from one type to another, where the conversion is made according to a specified /// [`RoundingMode`]. An [`Ordering`] is also returned, indicating whether the returned value is /// less than, equal to, or greater than the original value. /// /// It is recommended that this trait is not implemented directly; it is automatically implemented /// when [`RoundingFrom`] is implemented. pub trait RoundingInto: Sized { fn rounding_into(self, rm: RoundingMode) -> (T, Ordering); } impl> RoundingInto for T { #[inline] fn rounding_into(self, rm: RoundingMode) -> (U, Ordering) { U::rounding_from(self, rm) } } /// Tests whether a value of one type is convertible into a value of another. /// /// If `ConvertibleFrom` for `Self` is implemented, it usually makes sense to implement /// [`TryFrom`] for `T` as well. pub trait ConvertibleFrom { fn convertible_from(value: T) -> bool; } /// Associates with `Self` a type that's half `Self`'s size. pub trait HasHalf { /// The type that's half the size of `Self`. type Half; } /// Provides a function to join two pieces into a number. For example, two [`u32`]s may be joined to /// form a [`u64`]. pub trait JoinHalves: HasHalf { /// Joins two values into a single value; the upper, or most-significant, half comes first. fn join_halves(upper: Self::Half, lower: Self::Half) -> Self; } /// Provides functions to split a number into two pieces. For example, a [`u64`] may be split into /// two [`u32`]s. pub trait SplitInHalf: HasHalf { /// Extracts the lower, or least-significant, half of a number. fn lower_half(&self) -> Self::Half; /// Extracts the upper, or most-significant half of a number. fn upper_half(&self) -> Self::Half; /// Extracts both halves of a number; the upper, or most-significant, half comes first. /// /// # Worst-case complexity /// $T(n) = O(\max(T_U(n), T_L(n)))$ /// /// $M(n) = O(\max(M_U(n), M_L(n)))$ /// /// where $T$ is time, $M$ is additional memory, $T_U$ and $T_L$ are the time complexities of /// the [`upper_half`](Self::upper_half) and [`lower_half`](Self::lower_half) functions, /// respectively, and $M_U$ and $M_L$ are the memory complexities of the /// [`upper_half`](Self::upper_half) and [`lower_half`](Self::lower_half) functions, /// respectively. #[inline] fn split_in_half(&self) -> (Self::Half, Self::Half) { (self.upper_half(), self.lower_half()) } } /// Determines whether a number is an integer. pub trait IsInteger { #[allow(clippy::wrong_self_convention)] fn is_integer(self) -> bool; } /// Converts a number to or from a raw mantissa and exponent. /// /// See [here](crate::num::basic::floats::PrimitiveFloat) for a definition of raw mantissa and /// exponent. pub trait RawMantissaAndExponent: Sized { /// Extracts the raw mantissa and exponent from a number. fn raw_mantissa_and_exponent(self) -> (M, E); /// Extracts the raw mantissa from a number. fn raw_mantissa(self) -> M { self.raw_mantissa_and_exponent().0 } /// Extracts the raw exponent from a number. fn raw_exponent(self) -> E { self.raw_mantissa_and_exponent().1 } /// Constructs a number from its raw mantissa and exponent. fn from_raw_mantissa_and_exponent(raw_mantissa: M, raw_exponent: E) -> T; } /// Converts a number to or from an integer mantissa and exponent. /// /// See [here](crate::num::basic::floats::PrimitiveFloat) for a definition of integer mantissa and /// exponent. /// /// The mantissa is an odd integer, and the exponent is an integer, such that $x = 2^em$. pub trait IntegerMantissaAndExponent: Sized { /// Extracts the integer mantissa and exponent from a number. fn integer_mantissa_and_exponent(self) -> (M, E); /// Extracts the integer mantissa from a number. fn integer_mantissa(self) -> M { self.integer_mantissa_and_exponent().0 } /// Extracts the integer exponent from a number. fn integer_exponent(self) -> E { self.integer_mantissa_and_exponent().1 } /// Constructs a number from its integer mantissa and exponent. fn from_integer_mantissa_and_exponent(integer_mantissa: M, integer_exponent: E) -> Option; } /// Converts a number to or from a scientific mantissa and exponent. /// /// See [here](crate::num::basic::floats::PrimitiveFloat) for a definition of scientific mantissa /// and exponent. pub trait SciMantissaAndExponent: Sized { /// Extracts the scientific mantissa and exponent from a number. fn sci_mantissa_and_exponent(self) -> (M, E); /// Extracts the scientific mantissa from a number. fn sci_mantissa(self) -> M { self.sci_mantissa_and_exponent().0 } /// Extracts the scientific exponent from a number. fn sci_exponent(self) -> E { self.sci_mantissa_and_exponent().1 } /// Constructs a number from its scientific mantissa and exponent. fn from_sci_mantissa_and_exponent(sci_mantissa: M, sci_exponent: E) -> Option; } /// Converts a slice of one type of value to a single value of another type. pub trait FromOtherTypeSlice { fn from_other_type_slice(slice: &[T]) -> Self; } /// Converts a slice of one type of value to a [`Vec`] of another type. pub trait VecFromOtherTypeSlice: Sized { fn vec_from_other_type_slice(slice: &[T]) -> Vec; } /// Converts a slice of one type of value to a [`Vec`] of another type. pub trait VecFromOtherType: Sized { fn vec_from_other_type(value: T) -> Vec; } malachite-base-0.4.16/src/num/exhaustive/mod.rs000064400000000000000000002276451046102023000174730ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::iterators::{nonzero_values, NonzeroValues}; use crate::num::arithmetic::traits::{PowerOf2, RoundToMultipleOfPowerOf2}; use crate::num::basic::floats::PrimitiveFloat; use crate::num::basic::integers::PrimitiveInt; use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::{ExactFrom, WrappingFrom}; use crate::num::float::NiceFloat; use crate::num::iterators::{ruler_sequence, RulerSequence}; use crate::num::logic::traits::{BitAccess, NotAssign, SignificantBits}; use crate::rounding_modes::RoundingMode::*; use crate::tuples::exhaustive::{ exhaustive_dependent_pairs, lex_dependent_pairs, ExhaustiveDependentPairs, ExhaustiveDependentPairsYsGenerator, LexDependentPairs, }; use alloc::vec::IntoIter; use alloc::vec::Vec; use core::iter::{once, Chain, Once, Rev}; use core::marker::PhantomData; use itertools::{Interleave, Itertools}; /// Generates all primitive integers in an interval. /// /// This `struct` is created by [`primitive_int_increasing_range`] and /// [`primitive_int_increasing_inclusive_range`]; see their documentation for more. #[derive(Clone, Debug, Eq, Hash, PartialEq)] pub struct PrimitiveIntIncreasingRange { a: Option, b: Option, } impl Iterator for PrimitiveIntIncreasingRange { type Item = T; fn next(&mut self) -> Option { if self.a == self.b { None } else { let result = self.a; self.a = result.and_then(|x| x.checked_add(T::ONE)); result } } } impl DoubleEndedIterator for PrimitiveIntIncreasingRange { fn next_back(&mut self) -> Option { if self.a == self.b { None } else { self.b = Some(self.b.map_or(T::MAX, |b| b - T::ONE)); self.b } } } /// Generates all values of a signed integer type in an interval, in order of increasing absolute /// value. /// /// This `enum` is created by [`exhaustive_signed_range`] and [`exhaustive_signed_inclusive_range`]; /// see their documentation for more. #[derive(Clone, Debug)] pub enum ExhaustiveSignedRange { NonNegative(PrimitiveIntIncreasingRange), NonPositive(Rev>), BothSigns(ExhaustiveSigneds), } impl Iterator for ExhaustiveSignedRange { type Item = T; fn next(&mut self) -> Option { match self { ExhaustiveSignedRange::NonNegative(ref mut xs) => xs.next(), ExhaustiveSignedRange::NonPositive(ref mut xs) => xs.next(), ExhaustiveSignedRange::BothSigns(ref mut xs) => xs.next(), } } } #[doc(hidden)] pub type PrimitiveIntUpDown = Interleave, Rev>>; /// Generates all unsigned integers in ascending order. /// /// The output is $(k)_{k=0}^{2^W-1}$, where $W$ is the width of the type. /// /// The output length is $2^W$. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::exhaustive::exhaustive_unsigneds; /// /// assert_eq!( /// prefix_to_string(exhaustive_unsigneds::(), 10), /// "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ...]" /// ) /// ``` #[inline] pub fn exhaustive_unsigneds() -> PrimitiveIntIncreasingRange { primitive_int_increasing_inclusive_range(T::ZERO, T::MAX) } /// Generates all positive primitive integers in ascending order. /// /// Let $L=2^W-1$ if `T` is unsigned and $L=2^{W-1}-1$ if `T` is signed, where $W$ is the width of /// the type. /// /// The output is $(k)_{k=1}^{L}$. /// /// The output length is $L$. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::exhaustive::exhaustive_positive_primitive_ints; /// /// assert_eq!( /// prefix_to_string(exhaustive_positive_primitive_ints::(), 10), /// "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...]" /// ) /// ``` #[inline] pub fn exhaustive_positive_primitive_ints() -> PrimitiveIntIncreasingRange { primitive_int_increasing_inclusive_range(T::ONE, T::MAX) } pub type ExhaustiveSigneds = Chain, PrimitiveIntUpDown>; /// Generates all signed integers in order of increasing absolute value. /// /// When two numbers have the same absolute value, the positive one comes first. /// /// The output satisfies $(|x_i|, \operatorname{sgn}(-x_i)) <_\mathrm{lex} (|x_j|, /// \operatorname{sgn}(-x_j))$ whenever $i, j \\in [-2^{W-1}, 2^{W-1})$, where $W$ is the width of /// the type, and $i < j$. /// /// The output length is $2^W$. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::exhaustive::exhaustive_signeds; /// /// assert_eq!( /// prefix_to_string(exhaustive_signeds::(), 10), /// "[0, 1, -1, 2, -2, 3, -3, 4, -4, 5, ...]" /// ) /// ``` #[inline] pub fn exhaustive_signeds() -> ExhaustiveSigneds { once(T::ZERO).chain(exhaustive_nonzero_signeds()) } /// Generates all natural (non-negative) signed integers in ascending order. /// /// The output is $(k)_{k=0}^{2^{W-1}-1}$, where $W$ is the width of the type. /// /// The output length is $2^{W-1}$. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::exhaustive::exhaustive_natural_signeds; /// /// assert_eq!( /// prefix_to_string(exhaustive_natural_signeds::(), 10), /// "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ...]" /// ) /// ``` #[inline] pub fn exhaustive_natural_signeds() -> PrimitiveIntIncreasingRange { primitive_int_increasing_inclusive_range(T::ZERO, T::MAX) } /// Generates all negative signed integers in descending order. /// /// The output is $(-k)_{k=1}^{2^{W-1}}$, where $W$ is the width of the type. /// /// The output length is $2^{W-1}$. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::exhaustive::exhaustive_negative_signeds; /// /// assert_eq!( /// prefix_to_string(exhaustive_negative_signeds::(), 10), /// "[-1, -2, -3, -4, -5, -6, -7, -8, -9, -10, ...]" /// ) /// ``` #[inline] pub fn exhaustive_negative_signeds() -> Rev> { primitive_int_increasing_range(T::MIN, T::ZERO).rev() } /// Generates all nonzero signed integers in order of increasing absolute value. /// /// When two numbers have the same absolute value, the positive one comes first. /// /// The output satisfies $(|x_i|, \operatorname{sgn}(-x_i)) <_\mathrm{lex} (|x_j|, /// \operatorname{sgn}(-x_j))$ whenever $i, j \\in [-2^{W-1}, 2^{W-1}) \\setminus \\{0\\}$, where /// $W$ is the width of the type, and $i < j$. /// /// The output length is $2^W-1$. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::exhaustive::exhaustive_nonzero_signeds; /// /// assert_eq!( /// prefix_to_string(exhaustive_nonzero_signeds::(), 10), /// "[1, -1, 2, -2, 3, -3, 4, -4, 5, -5, ...]" /// ) /// ``` #[inline] pub fn exhaustive_nonzero_signeds() -> PrimitiveIntUpDown { exhaustive_positive_primitive_ints().interleave(exhaustive_negative_signeds()) } /// Generates all primitive integers in the half-open interval $[a, b)$, in ascending order. /// /// $a$ must be less than or equal to $b$. If $a$ and $b$ are equal, the range is empty. This /// function cannot create a range that includes `T::MAX`; for that, use /// [`primitive_int_increasing_inclusive_range`]. /// /// The output is $(k)_{k=a}^{b-1}$. /// /// The output length is $b - a$. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Panics /// Panics if $a > b$. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::exhaustive::primitive_int_increasing_range; /// /// assert_eq!( /// primitive_int_increasing_range::(-5, 5).collect_vec(), /// &[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4] /// ) /// ``` #[inline] pub fn primitive_int_increasing_range( a: T, b: T, ) -> PrimitiveIntIncreasingRange { assert!(a <= b, "a must be less than or equal to b. a: {a}, b: {b}"); PrimitiveIntIncreasingRange { a: Some(a), b: Some(b), } } /// Generates all primitive integers in the closed interval $[a, b]$, in ascending order. /// /// $a$ must be less than or equal to $b$. If $a$ and $b$ are equal, the range contains a single /// element. /// /// The output is $(k)_{k=a}^{b}$. /// /// The output length is $b - a + 1$. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Panics /// Panics if $a > b$. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::exhaustive::primitive_int_increasing_inclusive_range; /// /// assert_eq!( /// primitive_int_increasing_inclusive_range::(-5, 5).collect_vec(), /// &[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5] /// ) /// ``` #[inline] pub fn primitive_int_increasing_inclusive_range( a: T, b: T, ) -> PrimitiveIntIncreasingRange { assert!(a <= b, "a must be less than or equal to b. a: {a}, b: {b}"); PrimitiveIntIncreasingRange { a: Some(a), b: b.checked_add(T::ONE), } } /// Generates all signed integers in the half-open interval $[a, b)$, in order of increasing /// absolute value. /// /// When two numbers have the same absolute value, the positive one comes first. $a$ must be less /// than or equal to $b$. If $a$ and $b$ are equal, the range is empty. This function cannot create /// a range that includes `T::MAX`; for that, use [`exhaustive_signed_inclusive_range`]. /// /// The output satisfies $(|x_i|, \operatorname{sgn}(-x_i)) <_\mathrm{lex} (|x_j|, /// \operatorname{sgn}(-x_j))$ whenever $i, j \\in [0, b - a)$ and $i < j$. /// /// The output length is $b - a$. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Panics /// Panics if $a > b$. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::exhaustive::exhaustive_signed_range; /// /// assert_eq!( /// exhaustive_signed_range::(-5, 5).collect_vec(), /// &[0, 1, -1, 2, -2, 3, -3, 4, -4, -5] /// ) /// ``` pub fn exhaustive_signed_range(a: T, b: T) -> ExhaustiveSignedRange { assert!(a <= b, "a must be less than or equal to b. a: {a}, b: {b}"); if a >= T::ZERO { ExhaustiveSignedRange::NonNegative(primitive_int_increasing_range(a, b)) } else if b <= T::ZERO { ExhaustiveSignedRange::NonPositive(primitive_int_increasing_range(a, b).rev()) } else { ExhaustiveSignedRange::BothSigns( once(T::ZERO).chain( primitive_int_increasing_range(T::ONE, b) .interleave(primitive_int_increasing_range(a, T::ZERO).rev()), ), ) } } /// Generates all signed integers in the closed interval $[a, b]$, in order of increasing absolute /// value. /// /// When two numbers have the same absolute value, the positive one comes first. $a$ must be less /// than or equal to $b$. If $a$ and $b$ are equal, the range contains a single element. /// /// The output satisfies $(|x_i|, \operatorname{sgn}(-x_i)) <_\mathrm{lex} (|x_j|, /// \operatorname{sgn}(-x_j))$ whenever $i, j \\in [0, b - a]$ and $i < j$. /// /// The output length is $b - a + 1$. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Panics /// Panics if $a > b$. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::exhaustive::exhaustive_signed_inclusive_range; /// /// assert_eq!( /// exhaustive_signed_inclusive_range::(-5, 5).collect_vec(), /// &[0, 1, -1, 2, -2, 3, -3, 4, -4, 5, -5] /// ) /// ``` pub fn exhaustive_signed_inclusive_range( a: T, b: T, ) -> ExhaustiveSignedRange { assert!(a <= b, "a must be less than or equal to b. a: {a}, b: {b}"); if a >= T::ZERO { ExhaustiveSignedRange::NonNegative(primitive_int_increasing_inclusive_range(a, b)) } else if b <= T::ZERO { ExhaustiveSignedRange::NonPositive(primitive_int_increasing_inclusive_range(a, b).rev()) } else { ExhaustiveSignedRange::BothSigns( once(T::ZERO).chain( primitive_int_increasing_inclusive_range(T::ONE, b) .interleave(primitive_int_increasing_inclusive_range(a, T::NEGATIVE_ONE).rev()), ), ) } } /// Generates all primitive floats in an interval, in increasing order. /// /// This `struct` implements [`DoubleEndedIterator`], so you can reverse it to generate floats in /// decreasing order. /// /// Positive zero and negative zero are both generated. Negative zero is considered to be less than /// positive zero. /// /// This `struct` is created by [`primitive_float_increasing_range`] and /// [`primitive_float_increasing_inclusive_range`]; see their documentation for more. #[derive(Clone, Debug, Eq, Hash, PartialEq)] pub struct PrimitiveFloatIncreasingRange { phantom: PhantomData<*const T>, xs: PrimitiveIntIncreasingRange, } impl Iterator for PrimitiveFloatIncreasingRange { type Item = T; #[inline] fn next(&mut self) -> Option { self.xs.next().map(T::from_ordered_representation) } } impl DoubleEndedIterator for PrimitiveFloatIncreasingRange { #[inline] fn next_back(&mut self) -> Option { self.xs.next_back().map(T::from_ordered_representation) } } /// Generates all primitive floats in the half-open interval $[a, b)$, in ascending order. /// /// Positive and negative zero are treated as two distinct values, with negative zero being smaller /// than zero. /// /// `NiceFloat(a)` must be less than or equal to `NiceFloat(b)`. If `NiceFloat(a)` and /// `NiceFloat(b)` are equal, the range is empty. This function cannot create a range that includes /// `INFINITY`; for that, use [`primitive_float_increasing_inclusive_range`]. /// /// Let $\varphi$ be /// [`to_ordered_representation`](super::basic::floats::PrimitiveFloat::to_ordered_representation): /// /// The output is $(\varphi^{-1}(k))_{k=\varphi(a)}^{\varphi(b)-1}$. /// /// The output length is $\varphi(b) - \varphi(a)$. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Panics /// Panics if `NiceFloat(a) > NiceFloat(b)`. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::exhaustive::primitive_float_increasing_range; /// use malachite_base::num::float::NiceFloat; /// /// assert_eq!( /// prefix_to_string( /// primitive_float_increasing_range::(1.0, 2.0).map(NiceFloat), /// 20 /// ), /// "[1.0, 1.0000001, 1.0000002, 1.0000004, 1.0000005, 1.0000006, 1.0000007, 1.0000008, \ /// 1.000001, 1.0000011, 1.0000012, 1.0000013, 1.0000014, 1.0000015, 1.0000017, 1.0000018, \ /// 1.0000019, 1.000002, 1.0000021, 1.0000023, ...]" /// ); /// assert_eq!( /// prefix_to_string( /// primitive_float_increasing_range::(1.0, 2.0) /// .rev() /// .map(NiceFloat), /// 20, /// ), /// "[1.9999999, 1.9999998, 1.9999996, 1.9999995, 1.9999994, 1.9999993, 1.9999992, 1.999999, \ /// 1.9999989, 1.9999988, 1.9999987, 1.9999986, 1.9999985, 1.9999983, 1.9999982, 1.9999981, \ /// 1.999998, 1.9999979, 1.9999977, 1.9999976, ...]", /// ); /// ``` pub fn primitive_float_increasing_range( a: T, b: T, ) -> PrimitiveFloatIncreasingRange { assert!(!a.is_nan()); assert!(!b.is_nan()); assert!( NiceFloat(a) <= NiceFloat(b), "a must be less than or equal to b. a: {}, b: {}", NiceFloat(a), NiceFloat(b) ); PrimitiveFloatIncreasingRange { phantom: PhantomData, xs: primitive_int_increasing_range( a.to_ordered_representation(), b.to_ordered_representation(), ), } } /// Generates all primitive floats in the closed interval $[a, b]$, in ascending order. /// /// Positive and negative zero are treated as two distinct values, with negative zero being smaller /// than zero. /// /// `NiceFloat(a)` must be less than or equal to `NiceFloat(b)`. If `NiceFloat(a)` and /// `NiceFloat(b)` are equal, the range contains a single element. /// /// Let $\varphi$ be /// [`to_ordered_representation`](super::basic::floats::PrimitiveFloat::to_ordered_representation): /// /// The output is $(\varphi^{-1}(k))_{k=\varphi(a)}^\varphi(b)$. /// /// The output length is $\varphi(b) - \varphi(a) + 1$. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Panics /// Panics if `NiceFloat(a) > NiceFloat(b)`. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::exhaustive::primitive_float_increasing_inclusive_range; /// use malachite_base::num::float::NiceFloat; /// /// assert_eq!( /// prefix_to_string( /// primitive_float_increasing_inclusive_range::(1.0, 2.0).map(NiceFloat), /// 20 /// ), /// "[1.0, 1.0000001, 1.0000002, 1.0000004, 1.0000005, 1.0000006, 1.0000007, 1.0000008, \ /// 1.000001, 1.0000011, 1.0000012, 1.0000013, 1.0000014, 1.0000015, 1.0000017, 1.0000018, \ /// 1.0000019, 1.000002, 1.0000021, 1.0000023, ...]" /// ); /// assert_eq!( /// prefix_to_string( /// primitive_float_increasing_inclusive_range::(1.0, 2.0) /// .rev() /// .map(NiceFloat), /// 20 /// ), /// "[2.0, 1.9999999, 1.9999998, 1.9999996, 1.9999995, 1.9999994, 1.9999993, 1.9999992, \ /// 1.999999, 1.9999989, 1.9999988, 1.9999987, 1.9999986, 1.9999985, 1.9999983, 1.9999982, \ /// 1.9999981, 1.999998, 1.9999979, 1.9999977, ...]" /// ); /// ``` pub fn primitive_float_increasing_inclusive_range( a: T, b: T, ) -> PrimitiveFloatIncreasingRange { assert!(!a.is_nan()); assert!(!b.is_nan()); assert!( NiceFloat(a) <= NiceFloat(b), "a must be less than or equal to b. a: {}, b: {}", NiceFloat(a), NiceFloat(b) ); PrimitiveFloatIncreasingRange { phantom: PhantomData, xs: primitive_int_increasing_inclusive_range( a.to_ordered_representation(), b.to_ordered_representation(), ), } } /// Generates all finite positive primitive floats, in ascending order. /// /// Positive and negative zero are both excluded. /// /// [`MIN_POSITIVE_SUBNORMAL`](super::basic::floats::PrimitiveFloat::MIN_POSITIVE_SUBNORMAL) is /// generated first and [`MAX_FINITE`](super::basic::floats::PrimitiveFloat::MAX_FINITE) is /// generated last. The returned iterator is double-ended, so it may be reversed. /// /// Let $\varphi$ be /// [`to_ordered_representation`](super::basic::floats::PrimitiveFloat::to_ordered_representation): /// /// The output is $(\varphi^{-1}(k))_{k=2^M(2^E-1)+2}^{2^{M+1}(2^E-1)}$. /// /// The output length is $2^M(2^E-1)-1$. /// - For [`f32`], this is $2^{31}-2^{23}-1$, or 2139095039. /// - For [`f64`], this is $2^{63}-2^{52}-1$, or 9218868437227405311. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::exhaustive::positive_finite_primitive_floats_increasing; /// use malachite_base::num::float::NiceFloat; /// /// assert_eq!( /// prefix_to_string( /// positive_finite_primitive_floats_increasing::().map(NiceFloat), /// 20 /// ), /// "[1.0e-45, 3.0e-45, 4.0e-45, 6.0e-45, 7.0e-45, 8.0e-45, 1.0e-44, 1.1e-44, 1.3e-44, \ /// 1.4e-44, 1.5e-44, 1.7e-44, 1.8e-44, 2.0e-44, 2.1e-44, 2.2e-44, 2.4e-44, 2.5e-44, 2.7e-44, \ /// 2.8e-44, ...]" /// ); /// assert_eq!( /// prefix_to_string( /// positive_finite_primitive_floats_increasing::() /// .rev() /// .map(NiceFloat), /// 20 /// ), /// "[3.4028235e38, 3.4028233e38, 3.402823e38, 3.4028229e38, 3.4028227e38, 3.4028225e38, \ /// 3.4028222e38, 3.402822e38, 3.4028218e38, 3.4028216e38, 3.4028214e38, 3.4028212e38, \ /// 3.402821e38, 3.4028208e38, 3.4028206e38, 3.4028204e38, 3.4028202e38, 3.40282e38, \ /// 3.4028198e38, 3.4028196e38, ...]" /// ); /// ``` #[inline] pub fn positive_finite_primitive_floats_increasing( ) -> PrimitiveFloatIncreasingRange { primitive_float_increasing_inclusive_range(T::MIN_POSITIVE_SUBNORMAL, T::MAX_FINITE) } /// Generates all finite negative primitive floats, in ascending order. /// /// Positive and negative zero are both excluded. /// /// [`-MAX_FINITE`](super::basic::floats::PrimitiveFloat::MAX_FINITE) is generated first and /// [`-MIN_POSITIVE_SUBNORMAL`](super::basic::floats::PrimitiveFloat::MIN_POSITIVE_SUBNORMAL) is /// generated last. The returned iterator is double-ended, so it may be reversed. /// /// Let $\varphi$ be /// [`to_ordered_representation`](super::basic::floats::PrimitiveFloat::to_ordered_representation): /// /// The output is $(\varphi^{-1}(k))_{k=1}^{2^M(2^E-1)-1}$. /// /// The output length is $2^M(2^E-1)-1$. /// - For [`f32`], this is $2^{31}-2^{23}-1$, or 2139095039. /// - For [`f64`], this is $2^{63}-2^{52}-1$, or 9218868437227405311. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::exhaustive::negative_finite_primitive_floats_increasing; /// use malachite_base::num::float::NiceFloat; /// /// assert_eq!( /// prefix_to_string( /// negative_finite_primitive_floats_increasing::().map(NiceFloat), /// 20 /// ), /// "[-3.4028235e38, -3.4028233e38, -3.402823e38, -3.4028229e38, -3.4028227e38, \ /// -3.4028225e38, -3.4028222e38, -3.402822e38, -3.4028218e38, -3.4028216e38, -3.4028214e38, \ /// -3.4028212e38, -3.402821e38, -3.4028208e38, -3.4028206e38, -3.4028204e38, -3.4028202e38, \ /// -3.40282e38, -3.4028198e38, -3.4028196e38, ...]" /// ); /// assert_eq!( /// prefix_to_string( /// negative_finite_primitive_floats_increasing::() /// .rev() /// .map(NiceFloat), /// 20 /// ), /// "[-1.0e-45, -3.0e-45, -4.0e-45, -6.0e-45, -7.0e-45, -8.0e-45, -1.0e-44, -1.1e-44, \ /// -1.3e-44, -1.4e-44, -1.5e-44, -1.7e-44, -1.8e-44, -2.0e-44, -2.1e-44, -2.2e-44, -2.4e-44, \ /// -2.5e-44, -2.7e-44, -2.8e-44, ...]" /// ); /// ``` #[inline] pub fn negative_finite_primitive_floats_increasing( ) -> PrimitiveFloatIncreasingRange { primitive_float_increasing_inclusive_range(-T::MAX_FINITE, -T::MIN_POSITIVE_SUBNORMAL) } /// Generates all finite nonzero primitive floats, in ascending order. /// /// Positive and negative zero are both excluded. /// /// [-`MAX_FINITE`](super::basic::floats::PrimitiveFloat::MAX_FINITE) is generated first and /// [`MAX_FINITE`](super::basic::floats::PrimitiveFloat::MAX_FINITE) is generated last. The returned /// iterator is double-ended, so it may be reversed. /// /// Let $\varphi$ be /// [`to_ordered_representation`](super::basic::floats::PrimitiveFloat::to_ordered_representation): /// /// The output is /// $$ /// (\varphi^{-1}(k))_ {k=1}^{2^M(2^E-1)-1} ⧺ (\varphi^{-1}(k))_ {k=2^M(2^E-1)+2}^{2^{M+1}(2^E-1)} /// $$. /// /// The output length is $2^{M+1}(2^E-1)-2$. /// - For [`f32`], this is $2^{32}-2^{24}-2$, or 4278190078. /// - For [`f64`], this is $2^{64}-2^{53}-2$, or 18437736874454810622. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::exhaustive::nonzero_finite_primitive_floats_increasing; /// use malachite_base::num::float::NiceFloat; /// /// assert_eq!( /// prefix_to_string( /// nonzero_finite_primitive_floats_increasing::().map(NiceFloat), /// 20 /// ), /// "[-3.4028235e38, -3.4028233e38, -3.402823e38, -3.4028229e38, -3.4028227e38, \ /// -3.4028225e38, -3.4028222e38, -3.402822e38, -3.4028218e38, -3.4028216e38, -3.4028214e38, \ /// -3.4028212e38, -3.402821e38, -3.4028208e38, -3.4028206e38, -3.4028204e38, -3.4028202e38, \ /// -3.40282e38, -3.4028198e38, -3.4028196e38, ...]" /// ); /// assert_eq!( /// prefix_to_string( /// nonzero_finite_primitive_floats_increasing::() /// .rev() /// .map(NiceFloat), /// 20 /// ), /// "[3.4028235e38, 3.4028233e38, 3.402823e38, 3.4028229e38, 3.4028227e38, 3.4028225e38, \ /// 3.4028222e38, 3.402822e38, 3.4028218e38, 3.4028216e38, 3.4028214e38, 3.4028212e38, \ /// 3.402821e38, 3.4028208e38, 3.4028206e38, 3.4028204e38, 3.4028202e38, 3.40282e38, \ /// 3.4028198e38, 3.4028196e38, ...]" /// ); /// ``` #[inline] pub fn nonzero_finite_primitive_floats_increasing( ) -> NonzeroValues> { nonzero_values(finite_primitive_floats_increasing()) } /// Generates all finite primitive floats, in ascending order. /// /// Positive and negative zero are both included. Negative zero comes first. /// /// [`-MAX_FINITE`](super::basic::floats::PrimitiveFloat::MAX_FINITE) is generated first and /// [`MAX_FINITE`](super::basic::floats::PrimitiveFloat::MAX_FINITE) is generated last. The /// returned iterator is double-ended, so it may be reversed. /// /// Let $\varphi$ be /// [`to_ordered_representation`](super::basic::floats::PrimitiveFloat::to_ordered_representation): /// /// The output is $(\varphi^{-1}(k))_{k=1}^{2^{M+1}(2^E-1)}$. /// /// The output length is $2^{M+1}(2^E-1)$. /// - For [`f32`], this is $2^{32}-2^{24}$, or 4278190080. /// - For [`f64`], this is $2^{64}-2^{53}$, or 18437736874454810624. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::exhaustive::finite_primitive_floats_increasing; /// use malachite_base::num::float::NiceFloat; /// /// assert_eq!( /// prefix_to_string( /// finite_primitive_floats_increasing::().map(NiceFloat), /// 20 /// ), /// "[-3.4028235e38, -3.4028233e38, -3.402823e38, -3.4028229e38, -3.4028227e38, \ /// -3.4028225e38, -3.4028222e38, -3.402822e38, -3.4028218e38, -3.4028216e38, -3.4028214e38, \ /// -3.4028212e38, -3.402821e38, -3.4028208e38, -3.4028206e38, -3.4028204e38, -3.4028202e38, \ /// -3.40282e38, -3.4028198e38, -3.4028196e38, ...]", /// ); /// assert_eq!( /// prefix_to_string( /// finite_primitive_floats_increasing::() /// .rev() /// .map(NiceFloat), /// 20 /// ), /// "[3.4028235e38, 3.4028233e38, 3.402823e38, 3.4028229e38, 3.4028227e38, 3.4028225e38, \ /// 3.4028222e38, 3.402822e38, 3.4028218e38, 3.4028216e38, 3.4028214e38, 3.4028212e38, \ /// 3.402821e38, 3.4028208e38, 3.4028206e38, 3.4028204e38, 3.4028202e38, 3.40282e38, \ /// 3.4028198e38, 3.4028196e38, ...]" /// ); /// ``` #[inline] pub fn finite_primitive_floats_increasing() -> PrimitiveFloatIncreasingRange { primitive_float_increasing_inclusive_range(-T::MAX_FINITE, T::MAX_FINITE) } /// Generates all positive primitive floats, in ascending order. /// /// Positive and negative zero are both excluded. /// /// [`MIN_POSITIVE_SUBNORMAL`](super::basic::floats::PrimitiveFloat::MIN_POSITIVE_SUBNORMAL) is /// generated first and `INFINITY` is generated last. The returned iterator is /// double-ended, so it may be reversed. /// /// Let $\varphi$ be /// [`to_ordered_representation`](super::basic::floats::PrimitiveFloat::to_ordered_representation): /// /// The output is $(\varphi^{-1}(k))_{k=2^M(2^E-1)+2}^{2^{M+1}(2^E-1)+1}$. /// /// The output length is $2^M(2^E-1)$. /// - For [`f32`], this is $2^{31}-2^{23}$, or 2139095040. /// - For [`f64`], this is $2^{63}-2^{52}$, or 9218868437227405312. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::exhaustive::positive_primitive_floats_increasing; /// use malachite_base::num::float::NiceFloat; /// /// assert_eq!( /// prefix_to_string( /// positive_primitive_floats_increasing::().map(NiceFloat), /// 20 /// ), /// "[1.0e-45, 3.0e-45, 4.0e-45, 6.0e-45, 7.0e-45, 8.0e-45, 1.0e-44, 1.1e-44, 1.3e-44, \ /// 1.4e-44, 1.5e-44, 1.7e-44, 1.8e-44, 2.0e-44, 2.1e-44, 2.2e-44, 2.4e-44, 2.5e-44, 2.7e-44, \ /// 2.8e-44, ...]" /// ); /// assert_eq!( /// prefix_to_string( /// positive_primitive_floats_increasing::() /// .rev() /// .map(NiceFloat), /// 20 /// ), /// "[Infinity, 3.4028235e38, 3.4028233e38, 3.402823e38, 3.4028229e38, 3.4028227e38, \ /// 3.4028225e38, 3.4028222e38, 3.402822e38, 3.4028218e38, 3.4028216e38, 3.4028214e38, \ /// 3.4028212e38, 3.402821e38, 3.4028208e38, 3.4028206e38, 3.4028204e38, 3.4028202e38, \ /// 3.40282e38, 3.4028198e38, ...]" /// ); /// ``` #[inline] pub fn positive_primitive_floats_increasing() -> PrimitiveFloatIncreasingRange { primitive_float_increasing_inclusive_range(T::MIN_POSITIVE_SUBNORMAL, T::INFINITY) } /// Generates all negative primitive floats, in ascending order. /// /// Positive and negative zero are both excluded. /// /// `NEGATIVE_INFINITY` is generated first and /// [`-MIN_POSITIVE_SUBNORMAL`](super::basic::floats::PrimitiveFloat::MIN_POSITIVE_SUBNORMAL) is /// generated last. The returned iterator is double-ended, so it may be reversed. /// /// Let $\varphi$ be /// [`to_ordered_representation`](super::basic::floats::PrimitiveFloat::to_ordered_representation): /// /// The output is $(\varphi^{-1}(k))_{k=0}^{2^M(2^E-1)-1}$. /// /// The output length is $2^M(2^E-1)$. /// - For [`f32`], this is $2^{31}-2^{23}$, or 2139095040. /// - For [`f64`], this is $2^{63}-2^{52}$, or 9218868437227405312. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::exhaustive::negative_primitive_floats_increasing; /// use malachite_base::num::float::NiceFloat; /// /// assert_eq!( /// prefix_to_string( /// negative_primitive_floats_increasing::().map(NiceFloat), /// 20 /// ), /// "[-Infinity, -3.4028235e38, -3.4028233e38, -3.402823e38, -3.4028229e38, -3.4028227e38, \ /// -3.4028225e38, -3.4028222e38, -3.402822e38, -3.4028218e38, -3.4028216e38, -3.4028214e38, \ /// -3.4028212e38, -3.402821e38, -3.4028208e38, -3.4028206e38, -3.4028204e38, -3.4028202e38, \ /// -3.40282e38, -3.4028198e38, ...]" /// ); /// assert_eq!( /// prefix_to_string( /// negative_primitive_floats_increasing::() /// .rev() /// .map(NiceFloat), /// 20 /// ), /// "[-1.0e-45, -3.0e-45, -4.0e-45, -6.0e-45, -7.0e-45, -8.0e-45, -1.0e-44, -1.1e-44, \ /// -1.3e-44, -1.4e-44, -1.5e-44, -1.7e-44, -1.8e-44, -2.0e-44, -2.1e-44, -2.2e-44, -2.4e-44, \ /// -2.5e-44, -2.7e-44, -2.8e-44, ...]" /// ); /// ``` #[inline] pub fn negative_primitive_floats_increasing() -> PrimitiveFloatIncreasingRange { primitive_float_increasing_inclusive_range(T::NEGATIVE_INFINITY, -T::MIN_POSITIVE_SUBNORMAL) } /// Generates all nonzero primitive floats, in ascending order. /// /// Positive and negative zero are both excluded. /// /// `NEGATIVE_INFINITY` is generated first and `INFINITY` is generated last. The returned /// iterator is double-ended, so it may be reversed. /// /// Let $\varphi$ be /// [`to_ordered_representation`](super::basic::floats::PrimitiveFloat::to_ordered_representation): /// /// The output is /// $$ /// (\varphi^{-1}(k))_ {k=0}^{2^M(2^E-1)-1} ⧺ (\varphi^{-1}(k))_ /// {k=2^M(2^E-1)+2}^{2^{M+1}(2^E-1)+1} $$. /// /// The output length is $2^{M+1}(2^E-1)$. /// - For [`f32`], this is $2^{32}-2^{24}$, or 4278190080. /// - For [`f64`], this is $2^{64}-2^{53}$, or 18437736874454810624. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::exhaustive::nonzero_primitive_floats_increasing; /// use malachite_base::num::float::NiceFloat; /// /// assert_eq!( /// prefix_to_string( /// nonzero_primitive_floats_increasing::().map(NiceFloat), /// 20 /// ), /// "[-Infinity, -3.4028235e38, -3.4028233e38, -3.402823e38, -3.4028229e38, -3.4028227e38, \ /// -3.4028225e38, -3.4028222e38, -3.402822e38, -3.4028218e38, -3.4028216e38, -3.4028214e38, \ /// -3.4028212e38, -3.402821e38, -3.4028208e38, -3.4028206e38, -3.4028204e38, -3.4028202e38, \ /// -3.40282e38, -3.4028198e38, ...]" /// ); /// assert_eq!( /// prefix_to_string( /// nonzero_primitive_floats_increasing::() /// .rev() /// .map(NiceFloat), /// 20 /// ), /// "[Infinity, 3.4028235e38, 3.4028233e38, 3.402823e38, 3.4028229e38, 3.4028227e38, \ /// 3.4028225e38, 3.4028222e38, 3.402822e38, 3.4028218e38, 3.4028216e38, 3.4028214e38, \ /// 3.4028212e38, 3.402821e38, 3.4028208e38, 3.4028206e38, 3.4028204e38, 3.4028202e38, \ /// 3.40282e38, 3.4028198e38, ...]" /// ); /// ``` #[inline] pub fn nonzero_primitive_floats_increasing( ) -> NonzeroValues> { nonzero_values(primitive_floats_increasing()) } /// Generates all primitive floats, except `NaN`, in ascending order. /// /// Positive and negative zero are both included. Negative zero comes first. /// /// `NEGATIVE_INFINITY` is generated first and `INFINITY` is generated last. The returned iterator /// is double-ended, so it may be reversed. /// /// Let $\varphi$ be /// [`to_ordered_representation`](super::basic::floats::PrimitiveFloat::to_ordered_representation): /// /// The output is $(\varphi^{-1}(k))_{k=0}^{2^{M+1}(2^E-1)+1}$. /// /// The output length is $2^{M+1}(2^E-1)+2$. /// - For [`f32`], this is $2^{32}-2^{24}+2$, or 4278190082. /// - For [`f64`], this is $2^{64}-2^{53}+2$, or 18437736874454810626. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::exhaustive::primitive_floats_increasing; /// use malachite_base::num::float::NiceFloat; /// /// assert_eq!( /// prefix_to_string(primitive_floats_increasing::().map(NiceFloat), 20), /// "[-Infinity, -3.4028235e38, -3.4028233e38, -3.402823e38, -3.4028229e38, -3.4028227e38, \ /// -3.4028225e38, -3.4028222e38, -3.402822e38, -3.4028218e38, -3.4028216e38, -3.4028214e38, \ /// -3.4028212e38, -3.402821e38, -3.4028208e38, -3.4028206e38, -3.4028204e38, -3.4028202e38, \ /// -3.40282e38, -3.4028198e38, ...]" /// ); /// assert_eq!( /// prefix_to_string( /// primitive_floats_increasing::().rev().map(NiceFloat), /// 20 /// ), /// "[Infinity, 3.4028235e38, 3.4028233e38, 3.402823e38, 3.4028229e38, 3.4028227e38, \ /// 3.4028225e38, 3.4028222e38, 3.402822e38, 3.4028218e38, 3.4028216e38, 3.4028214e38, \ /// 3.4028212e38, 3.402821e38, 3.4028208e38, 3.4028206e38, 3.4028204e38, 3.4028202e38, \ /// 3.40282e38, 3.4028198e38, ...]" /// ); /// ``` pub fn primitive_floats_increasing() -> PrimitiveFloatIncreasingRange { primitive_float_increasing_inclusive_range(T::NEGATIVE_INFINITY, T::INFINITY) } /// Generates all finite positive primitive floats with a specified `sci_exponent` and precision. /// /// This `struct` is created by [`exhaustive_primitive_floats_with_sci_exponent_and_precision`]; see /// its documentation for more. #[derive(Clone, Debug, Default)] pub struct ConstantPrecisionPrimitiveFloats { phantom: PhantomData<*const T>, n: u64, increment: u64, i: u64, count: u64, } impl Iterator for ConstantPrecisionPrimitiveFloats { type Item = T; fn next(&mut self) -> Option { if self.i == self.count { None } else { let out = T::from_bits(self.n); self.i += 1; if self.i < self.count { self.n += self.increment; } Some(out) } } } /// Generates all finite positive primitive floats with a specified `sci_exponent` and precision. /// /// Positive and negative zero are both excluded. /// /// A finite positive primitive float may be uniquely expressed as $x = m_s2^e_s$, where $1 \leq m_s /// < 2$ and $e_s$ is an integer; then $e_s$ is the sci-exponent. An integer $e_s$ occurs as the /// sci-exponent of a float iff $2-2^{E-1}-M \leq e_s < 2^{E-1}$. /// /// In the above equation, $m$ is a dyadic rational. Let $p$ be the smallest integer such that /// $m2^{p-1}$ is an integer. Then $p$ is the float's precision. It is also the number of /// significant bits. /// /// For example, consider the float $100.0$. It may be written as $\frac{25}{16}2^6$, so /// $m=\frac{25}{16}$ and $e=6$. We can write $m$ in binary as $1.1001_2$. Thus, the sci-exponent is /// 6 and the precision is 5. /// /// If $p$ is 1, the output length is 1; otherwise, it is $2^{p-2}$. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Panics /// Panics if the sci-exponent is less than /// [`MIN_EXPONENT`](super::basic::floats::PrimitiveFloat::MIN_EXPONENT) or greater than /// [`MAX_EXPONENT`](super::basic::floats::PrimitiveFloat::MAX_EXPONENT), or if the precision is /// zero or too large for the given sci-exponent (this can be checked using /// [`max_precision_for_sci_exponent`](super::basic::floats::PrimitiveFloat::max_precision_for_sci_exponent)). /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::exhaustive::*; /// use malachite_base::num::float::NiceFloat; /// /// assert_eq!( /// exhaustive_primitive_floats_with_sci_exponent_and_precision::(0, 3) /// .map(NiceFloat) /// .collect_vec(), /// [1.25, 1.75].iter().copied().map(NiceFloat).collect_vec() /// ); /// assert_eq!( /// exhaustive_primitive_floats_with_sci_exponent_and_precision::(0, 5) /// .map(NiceFloat) /// .collect_vec(), /// [1.0625, 1.1875, 1.3125, 1.4375, 1.5625, 1.6875, 1.8125, 1.9375] /// .iter() /// .copied() /// .map(NiceFloat) /// .collect_vec() /// ); /// assert_eq!( /// exhaustive_primitive_floats_with_sci_exponent_and_precision::(6, 5) /// .map(NiceFloat) /// .collect_vec(), /// [68.0, 76.0, 84.0, 92.0, 100.0, 108.0, 116.0, 124.0] /// .iter() /// .copied() /// .map(NiceFloat) /// .collect_vec() /// ); /// ``` pub fn exhaustive_primitive_floats_with_sci_exponent_and_precision( sci_exponent: i64, precision: u64, ) -> ConstantPrecisionPrimitiveFloats { assert!(sci_exponent >= T::MIN_EXPONENT); assert!(sci_exponent <= T::MAX_EXPONENT); assert_ne!(precision, 0); let max_precision = T::max_precision_for_sci_exponent(sci_exponent); assert!(precision <= max_precision); let increment = u64::power_of_2(max_precision - precision + 1); let first_mantissa = if precision == 1 { 1 } else { u64::power_of_2(precision - 1) | 1 }; let first = T::from_integer_mantissa_and_exponent( first_mantissa, sci_exponent - i64::exact_from(precision) + 1, ) .unwrap() .to_bits(); let count = if precision == 1 { 1 } else { u64::power_of_2(precision - 2) }; ConstantPrecisionPrimitiveFloats { phantom: PhantomData, n: first, increment, i: 0, count, } } #[derive(Clone, Debug)] struct PrimitiveFloatsWithExponentGenerator { phantom: PhantomData<*const T>, sci_exponent: i64, } impl ExhaustiveDependentPairsYsGenerator> for PrimitiveFloatsWithExponentGenerator { #[inline] fn get_ys(&self, &precision: &u64) -> ConstantPrecisionPrimitiveFloats { exhaustive_primitive_floats_with_sci_exponent_and_precision(self.sci_exponent, precision) } } #[inline] fn exhaustive_primitive_floats_with_sci_exponent_helper( sci_exponent: i64, ) -> LexDependentPairs< u64, T, PrimitiveFloatsWithExponentGenerator, PrimitiveIntIncreasingRange, ConstantPrecisionPrimitiveFloats, > { lex_dependent_pairs( primitive_int_increasing_inclusive_range( 1, T::max_precision_for_sci_exponent(sci_exponent), ), PrimitiveFloatsWithExponentGenerator { phantom: PhantomData, sci_exponent, }, ) } /// Generates all positive finite primitive floats with a specified `sci_exponent`. /// /// This `struct` is created by [`exhaustive_primitive_floats_with_sci_exponent`]; see its /// documentation for more. #[derive(Clone, Debug)] pub struct ExhaustivePrimitiveFloatsWithExponent( LexDependentPairs< u64, T, PrimitiveFloatsWithExponentGenerator, PrimitiveIntIncreasingRange, ConstantPrecisionPrimitiveFloats, >, ); impl Iterator for ExhaustivePrimitiveFloatsWithExponent { type Item = T; #[inline] fn next(&mut self) -> Option { self.0.next().map(|p| p.1) } } /// Generates all positive finite primitive floats with a specified sci-exponent. /// /// Positive and negative zero are both excluded. /// /// A finite positive primitive float may be uniquely expressed as $x = m_s2^e_s$, where $1 \leq m_s /// < 2$ and $e_s$ is an integer; then $e$ is the sci-exponent. An integer $e_s$ occurs as the /// sci-exponent of a float iff $2-2^{E-1}-M \leq e_s < 2^{E-1}$. /// /// If $e_s \geq 2-2^{E-1}$ (the float is normal), the output length is $2^M$. /// - For [`f32`], this is $2^{23}$, or 8388608. /// - For [`f64`], this is $2^{52}$, or 4503599627370496. /// /// If $e_s < 2-2^{E-1}$ (the float is subnormal), the output length is $2^{e_s+2^{E-1}+M-2}$. /// - For [`f32`], this is $2^{e_s+149}$. /// - For [`f64`], this is $2^{e_s+1074}$. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Panics /// Panics if the sci-exponent is less than /// [`MIN_EXPONENT`](super::basic::floats::PrimitiveFloat::MIN_EXPONENT) or greater than /// [`MAX_EXPONENT`](super::basic::floats::PrimitiveFloat::MAX_EXPONENT). /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::exhaustive::exhaustive_primitive_floats_with_sci_exponent; /// use malachite_base::num::float::NiceFloat; /// /// assert_eq!( /// prefix_to_string( /// exhaustive_primitive_floats_with_sci_exponent::(0).map(NiceFloat), /// 20 /// ), /// "[1.0, 1.5, 1.25, 1.75, 1.125, 1.375, 1.625, 1.875, 1.0625, 1.1875, 1.3125, 1.4375, \ /// 1.5625, 1.6875, 1.8125, 1.9375, 1.03125, 1.09375, 1.15625, 1.21875, ...]", /// ); /// assert_eq!( /// prefix_to_string( /// exhaustive_primitive_floats_with_sci_exponent::(4).map(NiceFloat), /// 20 /// ), /// "[16.0, 24.0, 20.0, 28.0, 18.0, 22.0, 26.0, 30.0, 17.0, 19.0, 21.0, 23.0, 25.0, 27.0, \ /// 29.0, 31.0, 16.5, 17.5, 18.5, 19.5, ...]" /// ); /// assert_eq!( /// exhaustive_primitive_floats_with_sci_exponent::(-147) /// .map(NiceFloat) /// .collect_vec(), /// [6.0e-45, 8.0e-45, 7.0e-45, 1.0e-44] /// .iter() /// .copied() /// .map(NiceFloat) /// .collect_vec() /// ); /// ``` #[inline] pub fn exhaustive_primitive_floats_with_sci_exponent( sci_exponent: i64, ) -> ExhaustivePrimitiveFloatsWithExponent { ExhaustivePrimitiveFloatsWithExponent(exhaustive_primitive_floats_with_sci_exponent_helper( sci_exponent, )) } #[derive(Clone, Debug)] struct ExhaustivePositiveFinitePrimitiveFloatsGenerator { phantom: PhantomData<*const T>, } impl ExhaustiveDependentPairsYsGenerator> for ExhaustivePositiveFinitePrimitiveFloatsGenerator { #[inline] fn get_ys(&self, &sci_exponent: &i64) -> ExhaustivePrimitiveFloatsWithExponent { exhaustive_primitive_floats_with_sci_exponent(sci_exponent) } } #[inline] fn exhaustive_positive_finite_primitive_floats_helper( ) -> ExhaustiveDependentPairs< i64, T, RulerSequence, ExhaustivePositiveFinitePrimitiveFloatsGenerator, ExhaustiveSignedRange, ExhaustivePrimitiveFloatsWithExponent, > { exhaustive_dependent_pairs( ruler_sequence(), exhaustive_signed_inclusive_range(T::MIN_EXPONENT, T::MAX_EXPONENT), ExhaustivePositiveFinitePrimitiveFloatsGenerator { phantom: PhantomData, }, ) } /// Generates all positive finite primitive floats. /// /// This `struct` is created by [`exhaustive_positive_finite_primitive_floats`]; see its /// documentation for more. #[derive(Clone, Debug)] pub struct ExhaustivePositiveFinitePrimitiveFloats( ExhaustiveDependentPairs< i64, T, RulerSequence, ExhaustivePositiveFinitePrimitiveFloatsGenerator, ExhaustiveSignedRange, ExhaustivePrimitiveFloatsWithExponent, >, ); impl Iterator for ExhaustivePositiveFinitePrimitiveFloats { type Item = T; #[inline] fn next(&mut self) -> Option { self.0.next().map(|p| p.1) } } /// Generates all positive finite primitive floats. /// /// Positive and negative zero are both excluded. /// /// Roughly speaking, the simplest floats are generated first. If you want to generate the floats in /// ascending order instead, use [`positive_finite_primitive_floats_increasing`]. /// /// The output length is $2^M(2^E-1)-1$. /// - For [`f32`], this is $2^{31}-2^{23}-1$, or 2139095039. /// - For [`f64`], this is $2^{63}-2^{52}-1$, or 9218868437227405311. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::exhaustive::exhaustive_positive_finite_primitive_floats; /// use malachite_base::num::float::NiceFloat; /// /// assert_eq!( /// prefix_to_string( /// exhaustive_positive_finite_primitive_floats::().map(NiceFloat), /// 50 /// ), /// "[1.0, 2.0, 1.5, 0.5, 1.25, 3.0, 1.75, 4.0, 1.125, 2.5, 1.375, 0.75, 1.625, 3.5, 1.875, \ /// 0.25, 1.0625, 2.25, 1.1875, 0.625, 1.3125, 2.75, 1.4375, 6.0, 1.5625, 3.25, 1.6875, 0.875, \ /// 1.8125, 3.75, 1.9375, 8.0, 1.03125, 2.125, 1.09375, 0.5625, 1.15625, 2.375, 1.21875, 5.0, \ /// 1.28125, 2.625, 1.34375, 0.6875, 1.40625, 2.875, 1.46875, 0.375, 1.53125, 3.125, ...]" /// ); /// ``` #[inline] pub fn exhaustive_positive_finite_primitive_floats( ) -> ExhaustivePositiveFinitePrimitiveFloats { ExhaustivePositiveFinitePrimitiveFloats(exhaustive_positive_finite_primitive_floats_helper()) } /// Generates all negative finite primitive floats. /// /// This `struct` is created by [`exhaustive_negative_finite_primitive_floats`]; see its /// documentation for more. #[derive(Clone, Debug)] pub struct ExhaustiveNegativeFinitePrimitiveFloats( ExhaustivePositiveFinitePrimitiveFloats, ); impl Iterator for ExhaustiveNegativeFinitePrimitiveFloats { type Item = T; #[inline] fn next(&mut self) -> Option { self.0.next().map(|f| -f) } } /// Generates all negative finite primitive floats. /// /// Positive and negative zero are both excluded. /// /// Roughly speaking, the simplest floats are generated first. If you want to generate the floats in /// ascending order instead, use [`negative_finite_primitive_floats_increasing`]. /// /// The output length is $2^M(2^E-1)-1$. /// - For [`f32`], this is $2^{31}-2^{23}-1$, or 2139095039. /// - For [`f64`], this is $2^{63}-2^{52}-1$, or 9218868437227405311. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::exhaustive::exhaustive_negative_finite_primitive_floats; /// use malachite_base::num::float::NiceFloat; /// /// assert_eq!( /// prefix_to_string( /// exhaustive_negative_finite_primitive_floats::().map(NiceFloat), /// 50 /// ), /// "[-1.0, -2.0, -1.5, -0.5, -1.25, -3.0, -1.75, -4.0, -1.125, -2.5, -1.375, -0.75, -1.625, \ /// -3.5, -1.875, -0.25, -1.0625, -2.25, -1.1875, -0.625, -1.3125, -2.75, -1.4375, -6.0, \ /// -1.5625, -3.25, -1.6875, -0.875, -1.8125, -3.75, -1.9375, -8.0, -1.03125, -2.125, \ /// -1.09375, -0.5625, -1.15625, -2.375, -1.21875, -5.0, -1.28125, -2.625, -1.34375, -0.6875, \ /// -1.40625, -2.875, -1.46875, -0.375, -1.53125, -3.125, ...]" /// ); /// ``` #[inline] pub fn exhaustive_negative_finite_primitive_floats( ) -> ExhaustiveNegativeFinitePrimitiveFloats { ExhaustiveNegativeFinitePrimitiveFloats(exhaustive_positive_finite_primitive_floats()) } /// Generates all nonzero finite primitive floats. /// /// This `struct` is created by [`exhaustive_nonzero_finite_primitive_floats`]; see its /// documentation for more. #[derive(Clone, Debug)] pub struct ExhaustiveNonzeroFinitePrimitiveFloats { toggle: bool, xs: ExhaustivePositiveFinitePrimitiveFloats, x: T, } impl Iterator for ExhaustiveNonzeroFinitePrimitiveFloats { type Item = T; #[inline] fn next(&mut self) -> Option { self.toggle.not_assign(); Some(if self.toggle { self.x = self.xs.next().unwrap(); self.x } else { -self.x }) } } /// Generates all nonzero finite primitive floats. /// /// Positive and negative zero are both excluded. /// /// Roughly speaking, the simplest floats are generated first. If you want to generate the floats in /// ascending order instead, use [`nonzero_finite_primitive_floats_increasing`]. /// /// The output length is $2^{M+1}(2^E-1)-2$. /// - For [`f32`], this is $2^{32}-2^{24}-2$, or 4278190078. /// - For [`f64`], this is $2^{64}-2^{53}-2$, or 18437736874454810622. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::exhaustive::exhaustive_nonzero_finite_primitive_floats; /// use malachite_base::num::float::NiceFloat; /// /// assert_eq!( /// prefix_to_string( /// exhaustive_nonzero_finite_primitive_floats::().map(NiceFloat), /// 50 /// ), /// "[1.0, -1.0, 2.0, -2.0, 1.5, -1.5, 0.5, -0.5, 1.25, -1.25, 3.0, -3.0, 1.75, -1.75, 4.0, \ /// -4.0, 1.125, -1.125, 2.5, -2.5, 1.375, -1.375, 0.75, -0.75, 1.625, -1.625, 3.5, -3.5, \ /// 1.875, -1.875, 0.25, -0.25, 1.0625, -1.0625, 2.25, -2.25, 1.1875, -1.1875, 0.625, -0.625, \ /// 1.3125, -1.3125, 2.75, -2.75, 1.4375, -1.4375, 6.0, -6.0, 1.5625, -1.5625, ...]" /// ); /// ``` #[inline] pub fn exhaustive_nonzero_finite_primitive_floats( ) -> ExhaustiveNonzeroFinitePrimitiveFloats { ExhaustiveNonzeroFinitePrimitiveFloats { toggle: false, xs: exhaustive_positive_finite_primitive_floats(), x: T::ZERO, } } pub type ExhaustiveFinitePrimitiveFloats = Chain, ExhaustiveNonzeroFinitePrimitiveFloats>; /// Generates all finite primitive floats. /// /// Positive and negative zero are both included. /// /// Roughly speaking, the simplest floats are generated first. If you want to generate the floats in /// ascending order instead, use [`finite_primitive_floats_increasing`]. /// /// The output length is $2^{M+1}(2^E-1)$. /// - For [`f32`], this is $2^{32}-2^{24}$, or 4278190080. /// - For [`f64`], this is $2^{64}-2^{53}$, or 18437736874454810624. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::exhaustive::exhaustive_finite_primitive_floats; /// use malachite_base::num::float::NiceFloat; /// /// assert_eq!( /// prefix_to_string( /// exhaustive_finite_primitive_floats::().map(NiceFloat), /// 50 /// ), /// "[0.0, -0.0, 1.0, -1.0, 2.0, -2.0, 1.5, -1.5, 0.5, -0.5, 1.25, -1.25, 3.0, -3.0, 1.75, \ /// -1.75, 4.0, -4.0, 1.125, -1.125, 2.5, -2.5, 1.375, -1.375, 0.75, -0.75, 1.625, -1.625, \ /// 3.5, -3.5, 1.875, -1.875, 0.25, -0.25, 1.0625, -1.0625, 2.25, -2.25, 1.1875, -1.1875, \ /// 0.625, -0.625, 1.3125, -1.3125, 2.75, -2.75, 1.4375, -1.4375, 6.0, -6.0, ...]" /// ); /// ``` #[inline] pub fn exhaustive_finite_primitive_floats( ) -> Chain, ExhaustiveNonzeroFinitePrimitiveFloats> { ::alloc::vec![T::ZERO, T::NEGATIVE_ZERO] .into_iter() .chain(exhaustive_nonzero_finite_primitive_floats()) } /// Generates all positive primitive floats. /// /// Positive and negative zero are both excluded. /// /// Roughly speaking, the simplest floats are generated first. If you want to generate the floats in /// ascending order instead, use [`positive_primitive_floats_increasing`]. /// /// The output length is $2^M(2^E-1)$. /// - For [`f32`], this is $2^{31}-2^{23}$, or 2139095040. /// - For [`f64`], this is $2^{63}-2^{52}$, or 9218868437227405312. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::exhaustive::exhaustive_positive_primitive_floats; /// use malachite_base::num::float::NiceFloat; /// /// assert_eq!( /// prefix_to_string( /// exhaustive_positive_primitive_floats::().map(NiceFloat), /// 50 /// ), /// "[Infinity, 1.0, 2.0, 1.5, 0.5, 1.25, 3.0, 1.75, 4.0, 1.125, 2.5, 1.375, 0.75, 1.625, \ /// 3.5, 1.875, 0.25, 1.0625, 2.25, 1.1875, 0.625, 1.3125, 2.75, 1.4375, 6.0, 1.5625, 3.25, \ /// 1.6875, 0.875, 1.8125, 3.75, 1.9375, 8.0, 1.03125, 2.125, 1.09375, 0.5625, 1.15625, \ /// 2.375, 1.21875, 5.0, 1.28125, 2.625, 1.34375, 0.6875, 1.40625, 2.875, 1.46875, 0.375, \ /// 1.53125, ...]" /// ); /// ``` #[inline] pub fn exhaustive_positive_primitive_floats( ) -> Chain, ExhaustivePositiveFinitePrimitiveFloats> { once(T::INFINITY).chain(exhaustive_positive_finite_primitive_floats()) } /// Generates all negative primitive floats. /// /// Positive and negative zero are both excluded. /// /// Roughly speaking, the simplest floats are generated first. If you want to generate the floats in /// ascending order instead, use [`negative_primitive_floats_increasing`]. /// /// The output length is $2^M(2^E-1)$. /// - For [`f32`], this is $2^{31}-2^{23}$, or 2139095040. /// - For [`f64`], this is $2^{63}-2^{52}$, or 9218868437227405312. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::exhaustive::exhaustive_negative_primitive_floats; /// use malachite_base::num::float::NiceFloat; /// /// assert_eq!( /// prefix_to_string( /// exhaustive_negative_primitive_floats::().map(NiceFloat), /// 50 /// ), /// "[-Infinity, -1.0, -2.0, -1.5, -0.5, -1.25, -3.0, -1.75, -4.0, -1.125, -2.5, -1.375, \ /// -0.75, -1.625, -3.5, -1.875, -0.25, -1.0625, -2.25, -1.1875, -0.625, -1.3125, -2.75, \ /// -1.4375, -6.0, -1.5625, -3.25, -1.6875, -0.875, -1.8125, -3.75, -1.9375, -8.0, -1.03125, \ /// -2.125, -1.09375, -0.5625, -1.15625, -2.375, -1.21875, -5.0, -1.28125, -2.625, -1.34375, \ /// -0.6875, -1.40625, -2.875, -1.46875, -0.375, -1.53125, ...]" /// ); /// ``` #[inline] pub fn exhaustive_negative_primitive_floats( ) -> Chain, ExhaustiveNegativeFinitePrimitiveFloats> { once(T::NEGATIVE_INFINITY).chain(exhaustive_negative_finite_primitive_floats()) } /// Generates all nonzero primitive floats. /// /// Positive and negative zero are both excluded. NaN is excluded as well. /// /// Roughly speaking, the simplest floats are generated first. If you want to generate the floats in /// ascending order instead, use [`nonzero_primitive_floats_increasing`]. /// /// The output length is $2^{M+1}(2^E-1)$. /// - For [`f32`], this is $2^{32}-2^{24}$, or 4278190080. /// - For [`f64`], this is $2^{64}-2^{53}$, or 18437736874454810624. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::exhaustive::exhaustive_nonzero_primitive_floats; /// use malachite_base::num::float::NiceFloat; /// /// assert_eq!( /// prefix_to_string( /// exhaustive_nonzero_primitive_floats::().map(NiceFloat), /// 50 /// ), /// "[Infinity, -Infinity, 1.0, -1.0, 2.0, -2.0, 1.5, -1.5, 0.5, -0.5, 1.25, -1.25, 3.0, \ /// -3.0, 1.75, -1.75, 4.0, -4.0, 1.125, -1.125, 2.5, -2.5, 1.375, -1.375, 0.75, -0.75, \ /// 1.625, -1.625, 3.5, -3.5, 1.875, -1.875, 0.25, -0.25, 1.0625, -1.0625, 2.25, -2.25, \ /// 1.1875, -1.1875, 0.625, -0.625, 1.3125, -1.3125, 2.75, -2.75, 1.4375, -1.4375, 6.0, -6.0, \ /// ...]" /// ); /// ``` #[inline] pub fn exhaustive_nonzero_primitive_floats( ) -> Chain, ExhaustiveNonzeroFinitePrimitiveFloats> { ::alloc::vec![T::INFINITY, T::NEGATIVE_INFINITY] .into_iter() .chain(exhaustive_nonzero_finite_primitive_floats()) } /// Generates all primitive floats. /// /// Positive and negative zero are both included. /// /// Roughly speaking, the simplest floats are generated first. If you want to generate the floats /// (except `NaN`) in ascending order instead, use [`primitive_floats_increasing`]. /// /// The output length is $2^{M+1}(2^E-1)+2$. /// - For [`f32`], this is $2^{32}-2^{24}+2$, or 4278190082. /// - For [`f64`], this is $2^{64}-2^{53}+2$, or 18437736874454810626. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::exhaustive::exhaustive_primitive_floats; /// use malachite_base::num::float::NiceFloat; /// /// assert_eq!( /// prefix_to_string(exhaustive_primitive_floats::().map(NiceFloat), 50), /// "[NaN, Infinity, -Infinity, 0.0, -0.0, 1.0, -1.0, 2.0, -2.0, 1.5, -1.5, 0.5, -0.5, 1.25, \ /// -1.25, 3.0, -3.0, 1.75, -1.75, 4.0, -4.0, 1.125, -1.125, 2.5, -2.5, 1.375, -1.375, 0.75, \ /// -0.75, 1.625, -1.625, 3.5, -3.5, 1.875, -1.875, 0.25, -0.25, 1.0625, -1.0625, 2.25, \ /// -2.25, 1.1875, -1.1875, 0.625, -0.625, 1.3125, -1.3125, 2.75, -2.75, 1.4375, ...]" /// ); /// ``` #[inline] pub fn exhaustive_primitive_floats( ) -> Chain, ExhaustiveNonzeroFinitePrimitiveFloats> { ::alloc::vec![T::NAN, T::INFINITY, T::NEGATIVE_INFINITY, T::ZERO, T::NEGATIVE_ZERO] .into_iter() .chain(exhaustive_nonzero_finite_primitive_floats()) } pub_test! {exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range( a: T, b: T, sci_exponent: i64, precision: u64 ) -> ConstantPrecisionPrimitiveFloats { assert!(a.is_finite()); assert!(b.is_finite()); assert!(a > T::ZERO); assert!(b > T::ZERO); assert!(sci_exponent >= T::MIN_EXPONENT); assert!(sci_exponent <= T::MAX_EXPONENT); let (am, ae) = a.raw_mantissa_and_exponent(); let (bm, be) = b.raw_mantissa_and_exponent(); let ae_actual_sci_exponent = if ae == 0 { i64::wrapping_from(am.significant_bits()) + T::MIN_EXPONENT - 1 } else { i64::wrapping_from(ae) - T::MAX_EXPONENT }; let be_actual_sci_exponent = if be == 0 { i64::wrapping_from(bm.significant_bits()) + T::MIN_EXPONENT - 1 } else { i64::wrapping_from(be) - T::MAX_EXPONENT }; assert_eq!(ae_actual_sci_exponent, sci_exponent); assert_eq!(be_actual_sci_exponent, sci_exponent); assert!(am <= bm); assert_ne!(precision, 0); let max_precision = T::max_precision_for_sci_exponent(sci_exponent); assert!(precision <= max_precision); if precision == 1 && am == 0 { return ConstantPrecisionPrimitiveFloats { phantom: PhantomData, n: a.to_bits(), increment: 0, i: 0, count: 1, }; } let trailing_zeros = max_precision - precision; let increment = u64::power_of_2(trailing_zeros + 1); let mut start_mantissa = am.round_to_multiple_of_power_of_2(trailing_zeros, Up).0; if !start_mantissa.get_bit(trailing_zeros) { start_mantissa.set_bit(trailing_zeros); } if start_mantissa > bm { return ConstantPrecisionPrimitiveFloats::default(); } let mut end_mantissa = bm.round_to_multiple_of_power_of_2(trailing_zeros, Down).0; if !end_mantissa.get_bit(trailing_zeros) { let adjust = u64::power_of_2(trailing_zeros); if adjust > end_mantissa { return ConstantPrecisionPrimitiveFloats::default(); } end_mantissa -= adjust; } assert!(start_mantissa <= end_mantissa); let count = ((end_mantissa - start_mantissa) >> (trailing_zeros + 1)) + 1; let first = T::from_raw_mantissa_and_exponent(start_mantissa, ae).to_bits(); ConstantPrecisionPrimitiveFloats { phantom: PhantomData, n: first, increment, i: 0, count, } }} #[derive(Clone, Debug)] struct PrimitiveFloatsWithExponentInRangeGenerator { a: T, b: T, sci_exponent: i64, phantom: PhantomData<*const T>, } impl ExhaustiveDependentPairsYsGenerator> for PrimitiveFloatsWithExponentInRangeGenerator { #[inline] fn get_ys(&self, &precision: &u64) -> ConstantPrecisionPrimitiveFloats { exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range( self.a, self.b, self.sci_exponent, precision, ) } } #[inline] fn exhaustive_primitive_floats_with_sci_exponent_in_range_helper( a: T, b: T, sci_exponent: i64, ) -> LexDependentPairs< u64, T, PrimitiveFloatsWithExponentInRangeGenerator, PrimitiveIntIncreasingRange, ConstantPrecisionPrimitiveFloats, > { lex_dependent_pairs( primitive_int_increasing_inclusive_range( 1, T::max_precision_for_sci_exponent(sci_exponent), ), PrimitiveFloatsWithExponentInRangeGenerator { a, b, sci_exponent, phantom: PhantomData, }, ) } #[doc(hidden)] #[derive(Clone, Debug)] pub struct ExhaustivePrimitiveFloatsWithExponentInRange( LexDependentPairs< u64, T, PrimitiveFloatsWithExponentInRangeGenerator, PrimitiveIntIncreasingRange, ConstantPrecisionPrimitiveFloats, >, ); impl Iterator for ExhaustivePrimitiveFloatsWithExponentInRange { type Item = T; #[inline] fn next(&mut self) -> Option { self.0.next().map(|p| p.1) } } #[doc(hidden)] #[inline] pub fn exhaustive_primitive_floats_with_sci_exponent_in_range( a: T, b: T, sci_exponent: i64, ) -> ExhaustivePrimitiveFloatsWithExponentInRange { ExhaustivePrimitiveFloatsWithExponentInRange( exhaustive_primitive_floats_with_sci_exponent_in_range_helper(a, b, sci_exponent), ) } #[derive(Clone, Debug)] struct ExhaustivePositiveFinitePrimitiveFloatsInRangeGenerator { a: T, b: T, a_sci_exponent: i64, b_sci_exponent: i64, phantom: PhantomData<*const T>, } impl ExhaustiveDependentPairsYsGenerator> for ExhaustivePositiveFinitePrimitiveFloatsInRangeGenerator { #[inline] fn get_ys(&self, &sci_exponent: &i64) -> ExhaustivePrimitiveFloatsWithExponentInRange { let a = if sci_exponent == self.a_sci_exponent { self.a } else { T::from_integer_mantissa_and_exponent(1, sci_exponent).unwrap() }; let b = if sci_exponent == self.b_sci_exponent { self.b } else { T::from_integer_mantissa_and_exponent(1, sci_exponent + 1) .unwrap() .next_lower() }; exhaustive_primitive_floats_with_sci_exponent_in_range(a, b, sci_exponent) } } #[inline] fn exhaustive_positive_finite_primitive_floats_in_range_helper( a: T, b: T, ) -> ExhaustiveDependentPairs< i64, T, RulerSequence, ExhaustivePositiveFinitePrimitiveFloatsInRangeGenerator, ExhaustiveSignedRange, ExhaustivePrimitiveFloatsWithExponentInRange, > { assert!(a.is_finite()); assert!(b.is_finite()); assert!(a > T::ZERO); assert!(a <= b); let (am, ae) = a.raw_mantissa_and_exponent(); let (bm, be) = b.raw_mantissa_and_exponent(); let a_sci_exponent = if ae == 0 { i64::wrapping_from(am.significant_bits()) + T::MIN_EXPONENT - 1 } else { i64::wrapping_from(ae) - T::MAX_EXPONENT }; let b_sci_exponent = if be == 0 { i64::wrapping_from(bm.significant_bits()) + T::MIN_EXPONENT - 1 } else { i64::wrapping_from(be) - T::MAX_EXPONENT }; exhaustive_dependent_pairs( ruler_sequence(), exhaustive_signed_inclusive_range(a_sci_exponent, b_sci_exponent), ExhaustivePositiveFinitePrimitiveFloatsInRangeGenerator { a, b, a_sci_exponent, b_sci_exponent, phantom: PhantomData, }, ) } #[doc(hidden)] #[derive(Clone, Debug)] pub struct ExhaustivePositiveFinitePrimitiveFloatsInRange( ExhaustiveDependentPairs< i64, T, RulerSequence, ExhaustivePositiveFinitePrimitiveFloatsInRangeGenerator, ExhaustiveSignedRange, ExhaustivePrimitiveFloatsWithExponentInRange, >, ); impl Iterator for ExhaustivePositiveFinitePrimitiveFloatsInRange { type Item = T; #[inline] fn next(&mut self) -> Option { self.0.next().map(|p| p.1) } } #[doc(hidden)] #[inline] pub fn exhaustive_positive_finite_primitive_floats_in_range( a: T, b: T, ) -> ExhaustivePositiveFinitePrimitiveFloatsInRange { ExhaustivePositiveFinitePrimitiveFloatsInRange( exhaustive_positive_finite_primitive_floats_in_range_helper(a, b), ) } #[doc(hidden)] #[derive(Clone, Debug)] pub enum ExhaustiveNonzeroFinitePrimitiveFloatsInRange { AllPositive(ExhaustivePositiveFinitePrimitiveFloatsInRange), AllNegative(ExhaustivePositiveFinitePrimitiveFloatsInRange), PositiveAndNegative( bool, ExhaustivePositiveFinitePrimitiveFloatsInRange, ExhaustivePositiveFinitePrimitiveFloatsInRange, ), } impl Iterator for ExhaustiveNonzeroFinitePrimitiveFloatsInRange { type Item = T; fn next(&mut self) -> Option { match self { ExhaustiveNonzeroFinitePrimitiveFloatsInRange::AllPositive(ref mut xs) => xs.next(), ExhaustiveNonzeroFinitePrimitiveFloatsInRange::AllNegative(ref mut xs) => { xs.next().map(T::neg) } ExhaustiveNonzeroFinitePrimitiveFloatsInRange::PositiveAndNegative( ref mut toggle, ref mut pos_xs, ref mut neg_xs, ) => { toggle.not_assign(); if *toggle { pos_xs.next().or_else(|| neg_xs.next().map(T::neg)) } else { neg_xs.next().map(T::neg).or_else(|| pos_xs.next()) } } } } } #[doc(hidden)] #[inline] pub fn exhaustive_nonzero_finite_primitive_floats_in_range( a: T, b: T, ) -> ExhaustiveNonzeroFinitePrimitiveFloatsInRange { assert!(a.is_finite()); assert!(b.is_finite()); assert!(a != T::ZERO); assert!(b != T::ZERO); assert!(a <= b); if a > T::ZERO { ExhaustiveNonzeroFinitePrimitiveFloatsInRange::AllPositive( exhaustive_positive_finite_primitive_floats_in_range(a, b), ) } else if b < T::ZERO { ExhaustiveNonzeroFinitePrimitiveFloatsInRange::AllNegative( exhaustive_positive_finite_primitive_floats_in_range(-b, -a), ) } else { ExhaustiveNonzeroFinitePrimitiveFloatsInRange::PositiveAndNegative( false, exhaustive_positive_finite_primitive_floats_in_range(T::MIN_POSITIVE_SUBNORMAL, b), exhaustive_positive_finite_primitive_floats_in_range(T::MIN_POSITIVE_SUBNORMAL, -a), ) } } /// Generates all primitive floats in an interval. /// /// This `enum` is created by [`exhaustive_primitive_float_range`] and /// [`exhaustive_primitive_float_inclusive_range`]; see their documentation for more. #[allow(clippy::large_enum_variant)] #[derive(Clone, Debug)] pub enum ExhaustivePrimitiveFloatInclusiveRange { JustSpecials(IntoIter), NotJustSpecials(Chain, ExhaustiveNonzeroFinitePrimitiveFloatsInRange>), } impl Iterator for ExhaustivePrimitiveFloatInclusiveRange { type Item = T; fn next(&mut self) -> Option { match self { ExhaustivePrimitiveFloatInclusiveRange::JustSpecials(ref mut xs) => xs.next(), ExhaustivePrimitiveFloatInclusiveRange::NotJustSpecials(ref mut xs) => xs.next(), } } } /// Generates all primitive floats in the half-open interval $[a, b)$. /// /// Positive and negative zero are treated as two distinct values, with negative zero being smaller /// than zero. /// /// The floats are generated in a way such that simpler floats (with lower precision) are generated /// first. To generate floats in ascending order instead, use [`primitive_float_increasing_range`] /// instead. /// /// `NiceFloat(a)` must be less than or equal to `NiceFloat(b)`. If `NiceFloat(a)` and /// `NiceFloat(b)` are equal, the range is empty. /// /// Let $\varphi$ be /// [`to_ordered_representation`](super::basic::floats::PrimitiveFloat::to_ordered_representation): /// /// The output length is $\varphi(b) - \varphi(a)$. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Panics /// Panics if `NiceFloat(a) > NiceFloat(b)`. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::exhaustive::exhaustive_primitive_float_range; /// use malachite_base::num::float::NiceFloat; /// /// assert_eq!( /// prefix_to_string( /// exhaustive_primitive_float_range::(core::f32::consts::E, core::f32::consts::PI) /// .map(NiceFloat), /// 50 /// ), /// "[3.0, 2.75, 2.875, 3.125, 2.8125, 2.9375, 3.0625, 2.71875, 2.78125, 2.84375, 2.90625, \ /// 2.96875, 3.03125, 3.09375, 2.734375, 2.765625, 2.796875, 2.828125, 2.859375, 2.890625, \ /// 2.921875, 2.953125, 2.984375, 3.015625, 3.046875, 3.078125, 3.109375, 3.140625, \ /// 2.7265625, 2.7421875, 2.7578125, 2.7734375, 2.7890625, 2.8046875, 2.8203125, 2.8359375, \ /// 2.8515625, 2.8671875, 2.8828125, 2.8984375, 2.9140625, 2.9296875, 2.9453125, 2.9609375, \ /// 2.9765625, 2.9921875, 3.0078125, 3.0234375, 3.0390625, 3.0546875, ...]" /// ); /// ``` #[inline] pub fn exhaustive_primitive_float_range( a: T, b: T, ) -> ExhaustivePrimitiveFloatInclusiveRange { assert!(!a.is_nan()); assert!(!b.is_nan()); assert!(NiceFloat(a) <= NiceFloat(b)); if NiceFloat(a) == NiceFloat(b) { ExhaustivePrimitiveFloatInclusiveRange::JustSpecials(Vec::new().into_iter()) } else { exhaustive_primitive_float_inclusive_range(a, b.next_lower()) } } /// Generates all primitive floats in the closed interval $[a, b]$. /// /// Positive and negative zero are treated as two distinct values, with negative zero being smaller /// than zero. /// /// The floats are generated in a way such that simpler floats (with lower precision) are generated /// first. To generate floats in ascending order instead, use /// `primitive_float_increasing_inclusive_range` instead. /// /// `NiceFloat(a)` must be less than or equal to `NiceFloat(b)`. If `NiceFloat(a)` and /// `NiceFloat(b)` are equal, the range contains a single element. /// /// Let $\varphi$ be /// [`to_ordered_representation`](super::basic::floats::PrimitiveFloat::to_ordered_representation): /// /// The output length is $\varphi(b) - \varphi(a) + 1$. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Panics /// Panics if `NiceFloat(a) > NiceFloat(b)`. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::exhaustive::exhaustive_primitive_float_inclusive_range; /// use malachite_base::num::float::NiceFloat; /// /// assert_eq!( /// prefix_to_string( /// exhaustive_primitive_float_inclusive_range::( /// core::f32::consts::E, /// core::f32::consts::PI /// ) /// .map(NiceFloat), /// 50 /// ), /// "[3.0, 2.75, 2.875, 3.125, 2.8125, 2.9375, 3.0625, 2.71875, 2.78125, 2.84375, 2.90625, \ /// 2.96875, 3.03125, 3.09375, 2.734375, 2.765625, 2.796875, 2.828125, 2.859375, 2.890625, \ /// 2.921875, 2.953125, 2.984375, 3.015625, 3.046875, 3.078125, 3.109375, 3.140625, \ /// 2.7265625, 2.7421875, 2.7578125, 2.7734375, 2.7890625, 2.8046875, 2.8203125, 2.8359375, \ /// 2.8515625, 2.8671875, 2.8828125, 2.8984375, 2.9140625, 2.9296875, 2.9453125, 2.9609375, \ /// 2.9765625, 2.9921875, 3.0078125, 3.0234375, 3.0390625, 3.0546875, ...]" /// ); /// ``` #[inline] pub fn exhaustive_primitive_float_inclusive_range( mut a: T, mut b: T, ) -> ExhaustivePrimitiveFloatInclusiveRange { assert!(!a.is_nan()); assert!(!b.is_nan()); assert!(NiceFloat(a) <= NiceFloat(b)); let mut specials = Vec::new(); if b == T::INFINITY { specials.push(T::INFINITY); if a == T::INFINITY { return ExhaustivePrimitiveFloatInclusiveRange::JustSpecials(specials.into_iter()); } b = T::MAX_FINITE; } if a == T::NEGATIVE_INFINITY { specials.push(T::NEGATIVE_INFINITY); if b == T::NEGATIVE_INFINITY { return ExhaustivePrimitiveFloatInclusiveRange::JustSpecials(specials.into_iter()); } a = -T::MAX_FINITE; } if NiceFloat(a) <= NiceFloat(T::ZERO) && NiceFloat(b) >= NiceFloat(T::ZERO) { specials.push(T::ZERO); } if NiceFloat(a) <= NiceFloat(T::NEGATIVE_ZERO) && NiceFloat(b) >= NiceFloat(T::NEGATIVE_ZERO) { specials.push(T::NEGATIVE_ZERO); } if a == T::ZERO { if b == T::ZERO { return ExhaustivePrimitiveFloatInclusiveRange::JustSpecials(specials.into_iter()); } a = T::MIN_POSITIVE_SUBNORMAL; } if b == T::ZERO { b = -T::MIN_POSITIVE_SUBNORMAL; } ExhaustivePrimitiveFloatInclusiveRange::NotJustSpecials( specials .into_iter() .chain(exhaustive_nonzero_finite_primitive_floats_in_range(a, b)), ) } malachite-base-0.4.16/src/num/factorization/mod.rs000064400000000000000000000042041046102023000201420ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . /// An efficient prime sieve. pub mod prime_sieve; /// [`Primes`](traits::Primes), a trait for generating prime numbers. /// /// # primes_less_than /// ``` /// use itertools::Itertools; /// use malachite_base::num::factorization::traits::Primes; /// /// assert_eq!(u8::primes_less_than(&10).collect_vec(), &[2, 3, 5, 7]); /// assert_eq!(u16::primes_less_than(&11).collect_vec(), &[2, 3, 5, 7]); /// assert_eq!( /// u32::primes_less_than(&100).collect_vec(), /// &[ /// 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, /// 89, 97 /// ] /// ); /// ``` /// /// # primes_less_than_or_equal_to /// ``` /// use itertools::Itertools; /// use malachite_base::num::factorization::traits::Primes; /// /// assert_eq!( /// u8::primes_less_than_or_equal_to(&10).collect_vec(), /// &[2, 3, 5, 7] /// ); /// assert_eq!( /// u16::primes_less_than_or_equal_to(&11).collect_vec(), /// &[2, 3, 5, 7, 11] /// ); /// assert_eq!( /// u32::primes_less_than_or_equal_to(&100).collect_vec(), /// &[ /// 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, /// 89, 97 /// ] /// ); /// ``` /// /// # primes /// ``` /// use itertools::Itertools; /// use malachite_base::num::factorization::traits::Primes; /// /// assert_eq!( /// u8::primes().collect_vec(), /// &[ /// 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, /// 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, /// 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251 /// ] /// ); /// ``` pub mod primes; /// Various traits for generating primes, primality testing, and factorization. pub mod traits; malachite-base-0.4.16/src/num/factorization/prime_sieve.rs000064400000000000000000000425321046102023000217000ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // Uses code adopted from the GNU MP Library. // // `primesieve.c` contributed to the GNU project by Marco Bodrato. // // Copyright © 2010-2012, 2015, 2016 Free Software Foundation, Inc. // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::basic::integers::PrimitiveInt; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::ExactFrom; use crate::num::logic::traits::CountOnes; pub const SIEVE_SEED_U32: u32 = 0x69128480; // 70bits pre-sieved mask for primes 5, 7 pub const SIEVE_MASK1_U32: u32 = 0x12148960; pub const SIEVE_MASK2_U32: u32 = 0x44a120cc; pub const SIEVE_MASKT_U32: u32 = 0x1a; pub const SEED_LIMIT_U32: u64 = 120; pub const SIEVE_SEED_U64: u64 = 0x3294C9E069128480; // 110bits pre-sieved mask for primes 5, 11 pub const SIEVE_MASK1_U64: u64 = 0x81214a1204892058; pub const SIEVE_MASKT_U64: u64 = 0xc8130681244; // 182bits pre-sieved mask for primes 7, 13 pub const SIEVE_2MSK1_U64: u64 = 0x9402180c40230184; pub const SIEVE_2MSK2_U64: u64 = 0x0285021088402120; pub const SIEVE_2MSKT_U64: u64 = 0xa41210084421; pub const SEED_LIMIT_U64: u64 = 210; // # Worst-case complexity // $T(n) = O(n)$ // // $M(n) = O(1)$ // // where $T$ is time, $M$ is additional memory, and $n$ is `bit_array.len()`. // // This is equivalent to `fill_bitpattern` from `primesieve.c`, GMP 6.2.1. fn fill_bitpattern_u32(bit_array: &mut [u32], mut offset: u64) -> u64 { let mut len = bit_array.len(); let (mut mask, mut mask2, mut tail) = if offset == 0 { (SIEVE_MASK1_U32, SIEVE_MASK2_U32, SIEVE_MASKT_U32) } else { offset %= 70; if offset != 0 { if offset <= u32::WIDTH { let offset_comp = u32::WIDTH - offset; let mut mask = SIEVE_MASK2_U32 << offset_comp; let mut mask2 = SIEVE_MASKT_U32 << offset_comp; if offset != u32::WIDTH { mask |= SIEVE_MASK1_U32 >> offset; mask2 |= SIEVE_MASK2_U32 >> offset; } let tail = if offset <= 70 - 2 * u32::WIDTH { SIEVE_MASK1_U32 << (70 - 2 * u32::WIDTH - offset) | SIEVE_MASKT_U32 >> offset } else { mask2 |= SIEVE_MASK1_U32 << (70 - u32::WIDTH - offset); SIEVE_MASK1_U32 >> (offset + 2 * u32::WIDTH - 70) }; (mask, mask2, tail) } else if offset < 2 * u32::WIDTH { let mut mask = SIEVE_MASK2_U32 >> (offset - u32::WIDTH) | SIEVE_MASKT_U32 << (2 * u32::WIDTH - offset); if offset <= 70 - u32::WIDTH { let mut tail = SIEVE_MASK2_U32 << (70 - u32::WIDTH - offset); if offset != 70 - u32::WIDTH { tail |= SIEVE_MASK1_U32 >> (offset + 2 * u32::WIDTH - 70); } ( mask, SIEVE_MASKT_U32 >> (offset - u32::WIDTH) | SIEVE_MASK1_U32 << (70 - u32::WIDTH - offset), tail, ) } else { mask |= SIEVE_MASK1_U32 << (70 - offset); ( mask, SIEVE_MASK2_U32 << (70 - offset) | SIEVE_MASK1_U32 >> (u32::WIDTH - (70 - offset)), SIEVE_MASK2_U32 >> (u32::WIDTH - (70 - offset)), ) } } else { ( SIEVE_MASK1_U32 << (70 - offset) | SIEVE_MASKT_U32 >> (offset - 2 * u32::WIDTH), SIEVE_MASK2_U32 << (70 - offset) | SIEVE_MASK1_U32 >> (offset + u32::WIDTH - 70), SIEVE_MASKT_U32 << (70 - offset) | SIEVE_MASK2_U32 >> (offset + u32::WIDTH - 70), ) } } else { (SIEVE_MASK1_U32, SIEVE_MASK2_U32, SIEVE_MASKT_U32) } }; for xs in bit_array.chunks_mut(2) { xs[0] = mask; len -= 1; if len == 0 { break; } xs[1] = mask2; let temp = mask2 >> (3 * u32::WIDTH - 70); mask2 = mask2 << (70 - u32::WIDTH * 2) | mask >> (3 * u32::WIDTH - 70); mask = mask << (70 - u32::WIDTH * 2) | tail; tail = temp; len -= 1; if len == 0 { break; } } 2 } // # Worst-case complexity // $T(n) = O(n)$ // // $M(n) = O(1)$ // // where $T$ is time, $M$ is additional memory, and $n$ is `bit_array.len()`. // // This is equivalent to `fill_bitpattern` from `primesieve.c`, GMP 6.2.1. fn fill_bitpattern_u64(bit_array: &mut [u64], mut offset: u64) -> u64 { let mut len = bit_array.len(); let ((mut m11, mut m12), (mut m21, mut m22, mut m23)) = if offset == 0 { ( (SIEVE_MASK1_U64, SIEVE_MASKT_U64), (SIEVE_2MSK1_U64, SIEVE_2MSK2_U64, SIEVE_2MSKT_U64), ) } else { // correctly handle offset == 0... let mut m21 = offset % 110; let (m11, m12) = if m21 != 0 { if m21 < u64::WIDTH { let mut m11 = (SIEVE_MASK1_U64 >> m21) | (SIEVE_MASKT_U64 << (u64::WIDTH - m21)); if m21 <= 110 - u64::WIDTH { ( m11, SIEVE_MASK1_U64 << (110 - u64::WIDTH - m21) | SIEVE_MASKT_U64 >> m21, ) } else { m11 |= SIEVE_MASK1_U64 << (110 - m21); (m11, SIEVE_MASK1_U64 >> (m21 + u64::WIDTH - 110)) } } else { ( SIEVE_MASK1_U64 << (110 - m21) | SIEVE_MASKT_U64 >> (m21 - u64::WIDTH), SIEVE_MASKT_U64 << (110 - m21) | SIEVE_MASK1_U64 >> (m21 + u64::WIDTH - 110), ) } } else { (SIEVE_MASK1_U64, SIEVE_MASKT_U64) }; ((m11, m12), { offset %= 182; if offset != 0 { if offset <= u64::WIDTH { let mut m21 = SIEVE_2MSK2_U64 << (u64::WIDTH - offset); let mut m22 = SIEVE_2MSKT_U64 << (u64::WIDTH - offset); if offset != u64::WIDTH { m21 |= SIEVE_2MSK1_U64 >> offset; m22 |= SIEVE_2MSK2_U64 >> offset; } if offset <= 182 - 2 * u64::WIDTH { ( m21, m22, SIEVE_2MSK1_U64 << (182 - 2 * u64::WIDTH - offset) | SIEVE_2MSKT_U64 >> offset, ) } else { m22 |= SIEVE_2MSK1_U64 << (182 - u64::WIDTH - offset); (m21, m22, SIEVE_2MSK1_U64 >> (offset + 2 * u64::WIDTH - 182)) } } else if offset < 2 * u64::WIDTH { m21 = SIEVE_2MSK2_U64 >> (offset - u64::WIDTH) | SIEVE_2MSKT_U64 << (2 * u64::WIDTH - offset); if offset <= 182 - u64::WIDTH { let mut m23 = SIEVE_2MSK2_U64 << (182 - u64::WIDTH - offset); if offset != 182 - u64::WIDTH { m23 |= SIEVE_2MSK1_U64 >> (offset + 2 * u64::WIDTH - 182); } ( m21, SIEVE_2MSKT_U64 >> (offset - u64::WIDTH) | SIEVE_2MSK1_U64 << (182 - u64::WIDTH - offset), m23, ) } else { m21 |= SIEVE_2MSK1_U64 << (182 - offset); ( m21, SIEVE_2MSK2_U64 << (182 - offset) | SIEVE_2MSK1_U64 >> (u64::WIDTH + offset - 182), SIEVE_2MSK2_U64 >> (u64::WIDTH + offset - 182), ) } } else { ( SIEVE_2MSK1_U64 << (182 - offset) | SIEVE_2MSKT_U64 >> (offset - 2 * u64::WIDTH), SIEVE_2MSK2_U64 << (182 - offset) | SIEVE_2MSK1_U64 >> (offset + u64::WIDTH - 182), SIEVE_2MSKT_U64 << (182 - offset) | SIEVE_2MSK2_U64 >> (offset + u64::WIDTH - 182), ) } } else { (SIEVE_2MSK1_U64, SIEVE_2MSK2_U64, SIEVE_2MSKT_U64) } }) }; for xs in bit_array.chunks_mut(2) { xs[0] = m11 | m21; len -= 1; if len == 0 { break; } let temp = m11 >> (2 * u64::WIDTH - 110); m11 = (m11 << (110 - u64::WIDTH)) | m12; m12 = temp; xs[1] = m11 | m22; let temp = m11 >> (2 * u64::WIDTH - 110); m11 = (m11 << (110 - u64::WIDTH)) | m12; m12 = temp; let temp = m22 >> (3 * u64::WIDTH - 182); m22 = m22 << (182 - u64::WIDTH * 2) | m21 >> (3 * u64::WIDTH - 182); m21 = m21 << (182 - u64::WIDTH * 2) | m23; m23 = temp; len -= 1; if len == 0 { break; } } 4 } #[doc(hidden)] // This is equivalent to `n_to_bit` from `primesieve.c`, GMP 6.2.1. pub const fn n_to_bit(n: u64) -> u64 { ((n - 5) | 1) / 3 } #[doc(hidden)] // This is equivalent to `id_to_n` from `primesieve.c`, GMP 6.2.1. pub const fn id_to_n(id: u64) -> u64 { id * 3 + 1 + (id & 1) } // # Worst-case complexity // $T(n) = O(n\log\log n)$ // // $M(n) = O(1)$ // // where $T$ is time, $M$ is additional memory, and $n$ is `bit_array.len()`. // // This is equivalent to `first_block_primesieve` from `primesieve.c`, GMP 6.2.1. fn first_block_primesieve u64>( bit_array: &mut [T], n: u64, fill_bitpattern: F, sieve_seed: T, seed_limit: u64, ) { assert!(n > 4); let bits = n_to_bit(n); let limbs = usize::exact_from(bits >> T::LOG_WIDTH); let mut i = if limbs == 0 { 0 } else { fill_bitpattern(&mut bit_array[1..=limbs], 0) }; bit_array[0] = sieve_seed; if (bits + 1) & T::WIDTH_MASK != 0 { bit_array[limbs] |= T::MAX << ((bits + 1) & T::WIDTH_MASK); } if n > seed_limit { assert!(i < T::WIDTH); if n_to_bit(seed_limit + 1) < T::WIDTH { i = 0; } let mut mask = T::power_of_2(i); let mut index = 0; for i in i + 1.. { if bit_array[index] & mask == T::ZERO { let mut step = id_to_n(i); // lindex = n_to_bit(id_to_n(i) * id_to_n(i)); let mut lindex = i * (step + 1) - 1 + ((i & 1).wrapping_neg() & (i + 1)); // lindex = i * (step + 1 + (i & 1)) - 1 + (i & 1); if lindex > bits { break; } step <<= 1; let maskrot = step & T::WIDTH_MASK; let mut lmask = T::power_of_2(lindex & T::WIDTH_MASK); while lindex <= bits { bit_array[usize::exact_from(lindex >> T::LOG_WIDTH)] |= lmask; lmask.rotate_left_assign(maskrot); lindex += step; } // lindex = n_to_bit(id_to_n(i) * bit_to_n(i)); lindex = i * (i * 3 + 6) + (i & 1); lmask = T::power_of_2(lindex & T::WIDTH_MASK); while lindex <= bits { bit_array[usize::exact_from(lindex >> T::LOG_WIDTH)] |= lmask; lmask.rotate_left_assign(maskrot); lindex += step; } } mask <<= 1; if mask == T::ZERO { mask = T::ONE; index += 1; } } } } // # Worst-case complexity // $T(n) = O(n\log\log n)$ // // $M(n) = O(1)$ // // where $T$ is time, $M$ is additional memory, and $n$ is `bit_array.len()`. // // This is equivalent to `block_resieve` from `primesieve.c`, GMP 6.2.1. fn block_resieve u64>( bit_array: &mut [T], offset: u64, sieve: &[T], fill_bitpattern: &F, ) { let limbs = bit_array.len(); let off = offset; assert_ne!(limbs, 0); assert!(offset >= T::WIDTH); let bits = u64::exact_from(limbs << T::LOG_WIDTH) - 1; let i = fill_bitpattern(&mut bit_array[..limbs], offset - T::WIDTH); assert!(i < T::WIDTH); let mut mask = T::power_of_2(i); let mut index = 0; for i in i + 1.. { if sieve[index] & mask == T::ZERO { let mut step = id_to_n(i); // lindex = n_to_bit(id_to_n(i)*id_to_n(i)); let mut lindex = i * (step + 1) - 1 + ((i & 1).wrapping_neg() & (i + 1)); // lindex = i*(step+1+(i&1))-1+(i&1); if lindex > bits + off { break; } step <<= 1; let maskrot = step & T::WIDTH_MASK; if lindex < off { lindex += step * ((off - lindex - 1) / step + 1); } lindex -= off; let mut lmask = T::power_of_2(lindex & T::WIDTH_MASK); while lindex <= bits { bit_array[usize::exact_from(lindex >> T::LOG_WIDTH)] |= lmask; lmask.rotate_left_assign(maskrot); lindex += step; } // lindex = n_to_bit(id_to_n(i)*bit_to_n(i)); lindex = i * (i * 3 + 6) + (i & 1); if lindex < off { lindex += step * ((off - lindex - 1) / step + 1); } lindex -= off; lmask = T::power_of_2(lindex & T::WIDTH_MASK); while lindex <= bits { bit_array[usize::exact_from(lindex >> T::LOG_WIDTH)] |= lmask; lmask.rotate_left_assign(maskrot); lindex += step; } } mask <<= 1; if mask == T::ZERO { mask = T::ONE; index += 1; } } } #[doc(hidden)] #[inline] // This is equivalent to `primesieve_size` from `primesieve.c`, GMP 6.2.1. pub fn limbs_prime_sieve_size(n: u64) -> usize { assert!(n >= 5); usize::exact_from((n_to_bit(n) >> T::LOG_WIDTH) + 1) } const BLOCK_SIZE: usize = 2048; pub_test! {limbs_count_ones(xs: &[T]) -> u64 { xs.iter().map(|&x| CountOnes::count_ones(x)).sum() }} // Fills bit_array with the characteristic function of composite numbers up to the parameter n. I.e. // a bit set to "1" represent a composite, a "0" represent a prime. // // The primesieve_size(n) limbs pointed to by bit_array are overwritten. The returned value counts // prime integers in the interval [4, n]. Note that n > 4. // // Even numbers and multiples of 3 are excluded "a priori", only numbers equivalent to +/- 1 mod 6 // have their bit in the array. // // Once sieved, if the bit b is ZERO it represent a prime, the represented prime is bit_to_n(b), if // the LSbit is bit 0, or id_to_n(b), if you call "1" the first bit. // // # Worst-case complexity // $T(n) = O(n\log\log n)$ // // $M(n) = O(1)$ fn limbs_prime_sieve_generic u64>( bit_array: &mut [T], n: u64, fill_bitpattern: F, sieve_seed: T, seed_limit: u64, ) -> u64 { assert!(n > 4); let bits = n_to_bit(n); let size = usize::exact_from((bits >> T::LOG_WIDTH) + 1); if size > BLOCK_SIZE << 1 { let mut off = BLOCK_SIZE + (size % BLOCK_SIZE); first_block_primesieve( bit_array, id_to_n(u64::exact_from(off) << T::LOG_WIDTH), &fill_bitpattern, sieve_seed, seed_limit, ); let (sieve, bit_array) = bit_array.split_at_mut(off); for xs in bit_array.chunks_mut(BLOCK_SIZE) { block_resieve( xs, u64::exact_from(off) << T::LOG_WIDTH, sieve, &fill_bitpattern, ); off += BLOCK_SIZE; if off >= size { break; } } } else { first_block_primesieve(bit_array, n, &fill_bitpattern, sieve_seed, seed_limit); } if (bits + 1) & T::WIDTH_MASK != 0 { bit_array[size - 1] |= T::MAX << ((bits + 1) & T::WIDTH_MASK); } (u64::exact_from(size) << T::LOG_WIDTH) - limbs_count_ones(&bit_array[..size]) } #[doc(hidden)] // This is equivalent to `gmp_primesieve` from `primesieve.c`, GMP 6.2.1. #[inline] pub fn limbs_prime_sieve_u32(bit_array: &mut [u32], n: u64) -> u64 { limbs_prime_sieve_generic( bit_array, n, fill_bitpattern_u32, SIEVE_SEED_U32, SEED_LIMIT_U32, ) } #[doc(hidden)] // This is equivalent to `gmp_primesieve` from `primesieve.c`, GMP 6.2.1. #[inline] pub fn limbs_prime_sieve_u64(bit_array: &mut [u64], n: u64) -> u64 { limbs_prime_sieve_generic( bit_array, n, fill_bitpattern_u64, SIEVE_SEED_U64, SEED_LIMIT_U64, ) } malachite-base-0.4.16/src/num/factorization/primes.rs000064400000000000000000000303161046102023000206650ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::{ExactFrom, WrappingFrom}; use crate::num::factorization::prime_sieve::{ id_to_n, limbs_prime_sieve_size, limbs_prime_sieve_u64, }; use crate::num::factorization::traits::Primes; use crate::num::logic::traits::TrailingZeros; use alloc::vec::Vec; use core::marker::PhantomData; // This differs from the identically-named function in malachite-nz; this one returns None if there // are no more false bits. fn limbs_index_of_next_false_bit(xs: &[T], start: u64) -> Option { let starting_index = usize::exact_from(start >> T::LOG_WIDTH); if starting_index >= xs.len() { return None; } if let Some(result) = xs[starting_index].index_of_next_false_bit(start & T::WIDTH_MASK) { if result != T::WIDTH { return Some((u64::wrapping_from(starting_index) << T::LOG_WIDTH) + result); } } if starting_index == xs.len() - 1 { return None; } let false_index = starting_index + 1 + xs[starting_index + 1..] .iter() .take_while(|&&y| y == T::MAX) .count(); if false_index == xs.len() { None } else { Some( (u64::exact_from(false_index) << T::LOG_WIDTH) + TrailingZeros::trailing_zeros(!xs[false_index]), ) } } /// An iterator over that generates all primes less than a given value. /// /// This `struct` is created by [`Primes::primes_less_than`] and /// [`Primes::primes_less_than_or_equal_to`]; see their documentation for more. #[derive(Clone, Debug)] pub struct PrimesLessThanIterator { i: u8, j: u64, sieve: Vec, phantom: PhantomData<*const T>, } impl PrimesLessThanIterator { fn new(n: T) -> PrimesLessThanIterator { let n: u64 = n.saturating_into(); let mut sieve; if n < 5 { sieve = Vec::with_capacity(0); } else { sieve = alloc::vec![0; limbs_prime_sieve_size::(n)]; limbs_prime_sieve_u64(&mut sieve, n); } PrimesLessThanIterator { i: 0, j: n, sieve, phantom: PhantomData, } } } impl Iterator for PrimesLessThanIterator { type Item = T; fn next(&mut self) -> Option { match self.i { 0 => { if self.j < 2 { None } else { self.i = 1; Some(T::TWO) } } 1 => { if self.j == 2 { None } else { self.i = 2; self.j = 0; Some(T::from(3u8)) } } _ => { self.j = limbs_index_of_next_false_bit(&self.sieve, self.j)? + 1; Some(T::exact_from(id_to_n(self.j))) } } } } /// An iterator over that generates all primes. /// /// This `struct` is created by [`Primes::primes`]; see its documentation for more. #[derive(Clone, Debug)] pub struct PrimesIterator { limit: T, xs: PrimesLessThanIterator, } impl PrimesIterator { fn new() -> PrimesIterator { let limit = T::saturating_from(256u16); PrimesIterator { limit, xs: PrimesLessThanIterator::new(limit), } } } impl Iterator for PrimesIterator { type Item = T; fn next(&mut self) -> Option { loop { let p = self.xs.next(); if p.is_some() { return p; } else if self.limit == T::MAX { return None; } self.limit.saturating_mul_assign(T::TWO); let j = self.xs.j; self.xs = T::primes_less_than_or_equal_to(&self.limit); self.xs.i = 3; self.xs.j = j; } } } macro_rules! impl_primes { ($t:ident) => { impl Primes for $t { type I = PrimesIterator<$t>; type LI = PrimesLessThanIterator<$t>; /// Returns an iterator that generates all primes less than a given value. /// /// The iterator produced by `primes_less_than(n)` generates the same primes as the /// iterator produced by `primes().take_while(|&p| p < n)`, but the latter would be /// slower because it doesn't know in advance how large its prime sieve should be, and /// might have to create larger and larger prime sieves. /// /// # Worst-case complexity (amortized) /// $T(i) = O(\log \log i)$ /// /// $M(i) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $i$ is the iteration index. /// /// # Examples /// See [here](super::primes#primes_less_than). #[inline] fn primes_less_than(n: &$t) -> PrimesLessThanIterator<$t> { PrimesLessThanIterator::new(n.saturating_sub(1)) } /// Returns an iterator that generates all primes less than or equal to a given value. /// /// The iterator produced by `primes_less_than_or_equal_to(n)` generates the same primes /// as the iterator produced by `primes().take_while(|&p| p <= n)`, but the latter would /// be slower because it doesn't know in advance how large its prime sieve should be, /// and might have to create larger and larger prime sieves. /// /// # Worst-case complexity (amortized) /// $T(i) = O(\log \log i)$ /// /// $M(i) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $i$ is the iteration index. /// /// # Examples /// See [here](super::primes#primes_less_than_or_equal_to). #[inline] fn primes_less_than_or_equal_to(&n: &$t) -> PrimesLessThanIterator<$t> { PrimesLessThanIterator::new(n) } /// Returns all primes that fit into the specified type. /// /// The iterator produced by `primes(n)` generates the same primes as the iterator /// produced by `primes_less_than_or_equal_to(T::MAX)`. If you really need to generate /// _every_ prime, and `T` is `u32` or smaller, then you should use the latter, as it /// will allocate all the needed memory at once. If `T` is `u64` or larger, or if you /// probably don't need every prime, then `primes()` will be faster as it won't allocate /// too much memory right away. /// /// # Worst-case complexity (amortized) /// $T(i) = O(\log \log i)$ /// /// $M(i) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $i$ is the iteration index. /// /// # Examples /// See [here](super::primes#primes). #[inline] fn primes() -> PrimesIterator<$t> { PrimesIterator::new() } } }; } apply_to_unsigneds!(impl_primes); /// An iterator that generates `bool`s up to a certain limit, where the $n$th `bool` is `true` if /// and only if $n$ is prime. See [`prime_indicator_sequence_less_than`] for more information. #[derive(Clone, Debug)] pub struct PrimeIndicatorSequenceLessThan { primes: PrimesLessThanIterator, limit: u64, i: u64, next_prime: u64, } impl Iterator for PrimeIndicatorSequenceLessThan { type Item = bool; fn next(&mut self) -> Option { if self.i >= self.limit { None } else if self.i == self.next_prime { self.i += 1; self.next_prime = self.primes.next().unwrap_or(0); Some(true) } else { self.i += 1; Some(false) } } } /// Returns an iterator that generates an sequence of `bool`s, where the $n$th `bool` is `true` if /// and only if $n$ is prime. The first `bool` generated has index 1, and the last one has index /// $\max(0,\ell-1)$, where $\ell$ is `limit`. /// /// The output length is $max(0,\ell-1)$, where $\ell$ is `limit`. /// /// # Worst-case complexity (amortized) /// $T(i) = O(\log \log \log i)$ /// /// $M(i) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $i$ is the iteration index. /// /// # Examples /// ``` /// use malachite_base::num::factorization::primes::prime_indicator_sequence_less_than; /// /// let s: String = prime_indicator_sequence_less_than(101) /// .map(|b| if b { '1' } else { '0' }) /// .collect(); /// assert_eq!( /// s, /// "01101010001010001010001000001010000010001010001000001000001010000010001010000010001000001\ /// 00000001000" /// ) /// ``` pub fn prime_indicator_sequence_less_than(limit: u64) -> PrimeIndicatorSequenceLessThan { let mut primes = u64::primes_less_than(&limit); primes.next(); // skip 2 PrimeIndicatorSequenceLessThan { primes, limit, i: 1, next_prime: 2, } } /// Returns an iterator that generates an sequence of `bool`s, where the $n$th `bool` is `true` if /// and only if $n$ is prime. The first `bool` generated has index 1, and the last one has index /// `limit`. /// /// The output length is `limit`. /// /// # Worst-case complexity (amortized) /// $T(i) = O(\log \log \log i)$ /// /// $M(i) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $i$ is the iteration index. /// /// # Examples /// ``` /// use malachite_base::num::factorization::primes::prime_indicator_sequence_less_than_or_equal_to; /// /// let s: String = prime_indicator_sequence_less_than_or_equal_to(100) /// .map(|b| if b { '1' } else { '0' }) /// .collect(); /// assert_eq!( /// s, /// "01101010001010001010001000001010000010001010001000001000001010000010001010000010001000001\ /// 00000001000" /// ) /// ``` pub fn prime_indicator_sequence_less_than_or_equal_to( limit: u64, ) -> PrimeIndicatorSequenceLessThan { prime_indicator_sequence_less_than(limit.checked_add(1).unwrap()) } /// An iterator that generates `bool`s, where the $n$th `bool` is `true` if and only if $n$ is /// prime. See [`prime_indicator_sequence`] for more information. #[derive(Clone, Debug)] pub struct PrimeIndicatorSequence { primes: PrimesIterator, i: u64, next_prime: u64, } impl Iterator for PrimeIndicatorSequence { type Item = bool; fn next(&mut self) -> Option { Some(if self.i == self.next_prime { self.i += 1; self.next_prime = self.primes.next().unwrap(); true } else { self.i += 1; false }) } } /// Returns an iterator that generates an infinite sequence of `bool`s, where the $n$th `bool` is /// `true` if and only if $n$ is prime. The first `bool` generated has index 1. /// /// The output length is infinite. /// /// # Worst-case complexity (amortized) /// $T(i) = O(\log \log \log i)$ /// /// $M(i) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $i$ is the iteration index. /// /// # Examples /// ``` /// use malachite_base::num::factorization::primes::prime_indicator_sequence; /// /// let s: String = prime_indicator_sequence() /// .take(100) /// .map(|b| if b { '1' } else { '0' }) /// .collect(); /// assert_eq!( /// s, /// "01101010001010001010001000001010000010001010001000001000001010000010001010000010001000001\ /// 00000001000" /// ) /// ``` pub fn prime_indicator_sequence() -> PrimeIndicatorSequence { let mut primes = u64::primes(); primes.next(); // skip 2 PrimeIndicatorSequence { primes, i: 1, next_prime: 2, } } malachite-base-0.4.16/src/num/factorization/traits.rs000064400000000000000000000011351046102023000206710ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . pub trait Primes { type I: Iterator; type LI: Iterator; fn primes_less_than(n: &Self) -> Self::LI; fn primes_less_than_or_equal_to(n: &Self) -> Self::LI; fn primes() -> Self::I; } malachite-base-0.4.16/src/num/float/mod.rs000064400000000000000000000303061046102023000163750ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::basic::floats::PrimitiveFloat; use core::cmp::Ordering::{self, *}; use core::fmt::{self, Debug, Display, Formatter}; use core::hash::{Hash, Hasher}; use core::str::FromStr; /// `NiceFloat` is a wrapper around primitive float types that provides nicer [`Eq`], [`Ord`], /// [`Hash`], [`Display`], and [`FromStr`] instances. /// /// In most languages, floats behave weirdly due to the IEEE 754 standard. The `NiceFloat` type /// ignores the standard in favor of more intuitive behavior. /// * Using `NiceFloat`, `NaN`s are equal to themselves. There is a single, unique `NaN`; there's no /// concept of signalling `NaN`s. Positive and negative zero are two distinct values, not equal to /// each other. /// * The `NiceFloat` hash respects this equality. /// * `NiceFloat` has a total order. These are the classes of floats, in ascending order: /// - Negative infinity /// - Negative nonzero finite floats /// - Negative zero /// - NaN /// - Positive zero /// - Positive nonzero finite floats /// - Positive infinity /// * `NiceFloat` uses a different [`Display`] implementation than floats do by default in Rust. For /// example, Rust will format `f32::MIN_POSITIVE_SUBNORMAL` as something with many zeros, but /// `NiceFloat(f32::MIN_POSITIVE_SUBNORMAL)` just formats it as `"1.0e-45"`. The conversion /// function uses David Tolnay's [`ryu`](https://docs.rs/ryu/latest/ryu/) crate, with a few /// modifications: /// - All finite floats have a decimal point. For example, Ryu by itself would convert /// `f32::MIN_POSITIVE_SUBNORMAL` to `"1e-45"`. /// - Positive infinity, negative infinity, and NaN are converted to the strings `"Infinity"`, /// `"-Infinity"`, and "`NaN`", respectively. /// * [`FromStr`] accepts these strings. #[derive(Clone, Copy, Default)] pub struct NiceFloat(pub T); #[derive(Eq, Ord, PartialEq, PartialOrd)] enum FloatType { NegativeInfinity, NegativeFinite, NegativeZero, NaN, PositiveZero, PositiveFinite, PositiveInfinity, } impl NiceFloat { fn float_type(self) -> FloatType { let f = self.0; if f.is_nan() { FloatType::NaN } else if f.sign() == Greater { if f == T::ZERO { FloatType::PositiveZero } else if f.is_finite() { FloatType::PositiveFinite } else { FloatType::PositiveInfinity } } else if f == T::ZERO { FloatType::NegativeZero } else if f.is_finite() { FloatType::NegativeFinite } else { FloatType::NegativeInfinity } } } impl PartialEq> for NiceFloat { /// Compares two `NiceFloat`s for equality. /// /// This implementation ignores the IEEE 754 standard in favor of an equality operation that /// respects the expected properties of symmetry, reflexivity, and transitivity. Using /// `NiceFloat`, `NaN`s are equal to themselves. There is a single, unique `NaN`; there's no /// concept of signalling `NaN`s. Positive and negative zero are two distinct values, not equal /// to each other. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::num::float::NiceFloat; /// /// assert_eq!(NiceFloat(0.0), NiceFloat(0.0)); /// assert_eq!(NiceFloat(f32::NAN), NiceFloat(f32::NAN)); /// assert_ne!(NiceFloat(f32::NAN), NiceFloat(0.0)); /// assert_ne!(NiceFloat(0.0), NiceFloat(-0.0)); /// assert_eq!(NiceFloat(1.0), NiceFloat(1.0)); /// ``` #[inline] fn eq(&self, other: &NiceFloat) -> bool { let f = self.0; let g = other.0; f.to_bits() == g.to_bits() || f.is_nan() && g.is_nan() } } impl Eq for NiceFloat {} impl Hash for NiceFloat { /// Computes a hash of a `NiceFloat`. /// /// The hash is compatible with `NiceFloat` equality: all `NaN`s hash to the same value. /// /// # Worst-case complexity /// Constant time and additional memory. fn hash(&self, state: &mut H) { let f = self.0; if f.is_nan() { "NaN".hash(state); } else { f.to_bits().hash(state); } } } impl Ord for NiceFloat { /// Compares two `NiceFloat`s. /// /// This implementation ignores the IEEE 754 standard in favor of a comparison operation that /// respects the expected properties of antisymmetry, reflexivity, and transitivity. `NiceFloat` /// has a total order. These are the classes of floats, in ascending order: /// - Negative infinity /// - Negative nonzero finite floats /// - Negative zero /// - NaN /// - Positive zero /// - Positive nonzero finite floats /// - Positive infinity /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::num::float::NiceFloat; /// /// assert!(NiceFloat(0.0) > NiceFloat(-0.0)); /// assert!(NiceFloat(f32::NAN) < NiceFloat(0.0)); /// assert!(NiceFloat(f32::NAN) > NiceFloat(-0.0)); /// assert!(NiceFloat(f32::INFINITY) > NiceFloat(f32::NAN)); /// assert!(NiceFloat(f32::NAN) < NiceFloat(1.0)); /// ``` fn cmp(&self, other: &NiceFloat) -> Ordering { let self_type = self.float_type(); let other_type = other.float_type(); self_type.cmp(&other_type).then_with(|| { if self_type == FloatType::PositiveFinite || self_type == FloatType::NegativeFinite { self.0.partial_cmp(&other.0).unwrap() } else { Equal } }) } } impl PartialOrd> for NiceFloat { /// Compares a `NiceFloat` to another `NiceFloat`. /// /// See the documentation for the [`Ord`] implementation. #[inline] fn partial_cmp(&self, other: &NiceFloat) -> Option { Some(self.cmp(other)) } } #[doc(hidden)] pub trait FmtRyuString: Copy { fn fmt_ryu_string(self, f: &mut Formatter<'_>) -> fmt::Result; } macro_rules! impl_fmt_ryu_string { ($f: ident) => { impl FmtRyuString for $f { #[inline] fn fmt_ryu_string(self, f: &mut Formatter<'_>) -> fmt::Result { let mut buffer = ryu::Buffer::new(); let printed = buffer.format_finite(self); // Convert e.g. "1e100" to "1.0e100". `printed` is ASCII, so we can manipulate bytes // rather than chars. let mut e_index = None; let mut found_dot = false; for (i, &b) in printed.as_bytes().iter().enumerate() { match b { b'.' => { found_dot = true; break; // If there's a '.', we don't need to do anything } b'e' => { e_index = Some(i); break; // OK to break since there won't be a '.' after an 'e' } _ => {} } } if found_dot { f.write_str(printed) } else { if let Some(e_index) = e_index { let mut out_bytes = ::alloc::vec![0; printed.len() + 2]; let (in_bytes_lo, in_bytes_hi) = printed.as_bytes().split_at(e_index); let (out_bytes_lo, out_bytes_hi) = out_bytes.split_at_mut(e_index); out_bytes_lo.copy_from_slice(in_bytes_lo); out_bytes_hi[0] = b'.'; out_bytes_hi[1] = b'0'; out_bytes_hi[2..].copy_from_slice(in_bytes_hi); f.write_str(core::str::from_utf8(&out_bytes).unwrap()) } else { panic!("Unexpected Ryu string: {}", printed); } } } } }; } impl_fmt_ryu_string!(f32); impl_fmt_ryu_string!(f64); impl Display for NiceFloat { /// Formats a `NiceFloat` as a string. /// /// `NiceFloat` uses a different [`Display`] implementation than floats do by default in Rust. /// For example, Rust will convert `f32::MIN_POSITIVE_SUBNORMAL` to something with many zeros, /// but `NiceFloat(f32::MIN_POSITIVE_SUBNORMAL)` just converts to `"1.0e-45"`. The conversion /// function uses David Tolnay's [`ryu`](https://docs.rs/ryu/latest/ryu/) crate, with a few /// modifications: /// - All finite floats have a decimal point. For example, Ryu by itself would convert /// `f32::MIN_POSITIVE_SUBNORMAL` to `"1e-45"`. /// - Positive infinity, negative infinity, and NaN are converted to the strings `"Infinity"`, /// `"-Infinity"`, and "`NaN`", respectively. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::num::basic::floats::PrimitiveFloat; /// use malachite_base::num::basic::traits::NegativeInfinity; /// use malachite_base::num::float::NiceFloat; /// /// assert_eq!(NiceFloat(0.0).to_string(), "0.0"); /// assert_eq!(NiceFloat(-0.0).to_string(), "-0.0"); /// assert_eq!(NiceFloat(f32::INFINITY).to_string(), "Infinity"); /// assert_eq!(NiceFloat(f32::NEGATIVE_INFINITY).to_string(), "-Infinity"); /// assert_eq!(NiceFloat(f32::NAN).to_string(), "NaN"); /// /// assert_eq!(NiceFloat(1.0).to_string(), "1.0"); /// assert_eq!(NiceFloat(-1.0).to_string(), "-1.0"); /// assert_eq!( /// NiceFloat(f32::MIN_POSITIVE_SUBNORMAL).to_string(), /// "1.0e-45" /// ); /// assert_eq!( /// NiceFloat(std::f64::consts::E).to_string(), /// "2.718281828459045" /// ); /// assert_eq!( /// NiceFloat(std::f64::consts::PI).to_string(), /// "3.141592653589793" /// ); /// ``` fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { if self.0.is_nan() { f.write_str("NaN") } else if self.0.is_infinite() { if self.0.sign() == Greater { f.write_str("Infinity") } else { f.write_str("-Infinity") } } else { self.0.fmt_ryu_string(f) } } } impl Debug for NiceFloat { /// Formats a `NiceFloat` as a string. /// /// This is identical to the [`Display::fmt`] implementation. #[inline] fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { Display::fmt(self, f) } } impl FromStr for NiceFloat { type Err = ::Err; /// Converts a `&str` to a `NiceFloat`. /// /// If the `&str` does not represent a valid `NiceFloat`, an `Err` is returned. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ = `src.len()`. /// /// # Examples /// ``` /// use malachite_base::num::float::NiceFloat; /// use std::str::FromStr; /// /// assert_eq!(NiceFloat::from_str("NaN").unwrap(), NiceFloat(f32::NAN)); /// assert_eq!(NiceFloat::from_str("-0.00").unwrap(), NiceFloat(-0.0f64)); /// assert_eq!(NiceFloat::from_str(".123").unwrap(), NiceFloat(0.123f32)); /// ``` #[inline] fn from_str(src: &str) -> Result, ::Err> { match src { "NaN" => Ok(T::NAN), "Infinity" => Ok(T::INFINITY), "-Infinity" => Ok(T::NEGATIVE_INFINITY), "inf" | "-inf" => T::from_str("invalid"), src => T::from_str(src), } .map(NiceFloat) } } malachite-base-0.4.16/src/num/iterators/mod.rs000064400000000000000000000406131046102023000173060ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::iterators::bit_distributor::{BitDistributor, BitDistributorOutputType}; use crate::num::arithmetic::traits::{DivMod, DivisibleBy}; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::{ExactFrom, WrappingFrom}; use core::cmp::Ordering::*; use core::marker::PhantomData; #[doc(hidden)] #[derive(Clone, Debug)] pub struct SameWidthIteratorToBitChunks< I: Iterator, T: PrimitiveUnsigned, U: PrimitiveUnsigned, > { xs: I, width: u64, phantom: PhantomData<*const U>, } impl, T: PrimitiveUnsigned, U: PrimitiveUnsigned> SameWidthIteratorToBitChunks { fn next_with_wrapping U>(&mut self, wrap: F) -> Option> { self.xs.next().map(|x| { if x.significant_bits() <= self.width { Some(wrap(x)) } else { None } }) } } const fn same_width_iterator_to_bit_chunks< I: Iterator, T: PrimitiveUnsigned, U: PrimitiveUnsigned, >( xs: I, width: u64, ) -> SameWidthIteratorToBitChunks { SameWidthIteratorToBitChunks { xs, width, phantom: PhantomData, } } #[doc(hidden)] #[derive(Clone, Debug)] pub struct EvenFractionIteratorToBitChunks< I: Iterator, T: PrimitiveUnsigned, U: PrimitiveUnsigned, > { xs: I, x: T, multiple: u64, x_width: u64, y_width: u64, counter: u64, phantom: PhantomData<*const U>, } impl, T: PrimitiveUnsigned, U: PrimitiveUnsigned> EvenFractionIteratorToBitChunks { fn next_with_wrapping U>(&mut self, wrap: F) -> Option> { if self.counter == 0 { if let Some(x) = self.xs.next() { if x.significant_bits() > self.x_width { return Some(None); } self.x = x; self.counter = self.multiple; } else { return None; } } else { self.x >>= self.y_width; } let y = wrap(self.x.mod_power_of_2(self.y_width)); self.counter -= 1; Some(Some(y)) } } const fn even_fraction_iterator_to_bit_chunks< I: Iterator, T: PrimitiveUnsigned, U: PrimitiveUnsigned, >( xs: I, multiple: u64, out_chunk_size: u64, ) -> EvenFractionIteratorToBitChunks { EvenFractionIteratorToBitChunks { xs, x: T::ZERO, multiple, x_width: multiple * out_chunk_size, y_width: out_chunk_size, counter: 0, phantom: PhantomData, } } #[doc(hidden)] #[derive(Clone, Debug)] pub struct EvenMultipleIteratorToBitChunks< I: Iterator, T: PrimitiveUnsigned, U: PrimitiveUnsigned, > { xs: I, x_width: u64, y_width: u64, done: bool, phantom: PhantomData<*const U>, } impl, T: PrimitiveUnsigned, U: PrimitiveUnsigned> EvenMultipleIteratorToBitChunks { fn next_with_wrapping U>(&mut self, wrap: F) -> Option> { if self.done { return None; } let mut y = U::ZERO; let mut shift = 0; while shift < self.y_width { if let Some(x) = self.xs.next() { if x.significant_bits() > self.x_width { return Some(None); } y |= wrap(x) << shift; shift += self.x_width; } else { self.done = true; break; } } if shift == 0 { None } else { Some(Some(y)) } } } const fn even_multiple_iterator_to_bit_chunks< I: Iterator, T: PrimitiveUnsigned, U: PrimitiveUnsigned, >( xs: I, in_chunk_size: u64, out_chunk_size: u64, ) -> EvenMultipleIteratorToBitChunks { EvenMultipleIteratorToBitChunks { xs, x_width: in_chunk_size, y_width: out_chunk_size, done: false, phantom: PhantomData, } } #[doc(hidden)] #[derive(Clone, Debug)] pub struct IrregularIteratorToBitChunks< I: Iterator, T: PrimitiveUnsigned, U: PrimitiveUnsigned, > { xs: I, x: T, x_width: u64, y_width: u64, remaining_x_bits: u64, in_inner_loop: bool, phantom: PhantomData<*const U>, } impl, T: PrimitiveUnsigned, U: PrimitiveUnsigned> IrregularIteratorToBitChunks { fn next_with_wrapping U>(&mut self, wrap: F) -> Option> { let mut y = U::ZERO; let mut remaining_y_bits = self.y_width; loop { if !self.in_inner_loop { if let Some(x) = self.xs.next() { if x.significant_bits() > self.x_width { return Some(None); } self.x = x; } else { break; } self.remaining_x_bits = self.x_width; self.in_inner_loop = true; } while self.remaining_x_bits != 0 { let y_index = self.y_width - remaining_y_bits; if self.remaining_x_bits <= remaining_y_bits { y |= wrap(self.x) << y_index; remaining_y_bits -= self.remaining_x_bits; self.remaining_x_bits = 0; } else { y |= wrap(self.x).mod_power_of_2(remaining_y_bits) << y_index; self.x >>= remaining_y_bits; self.remaining_x_bits -= remaining_y_bits; remaining_y_bits = 0; } if remaining_y_bits == 0 { return Some(Some(y)); } } self.in_inner_loop = false; } if y == U::ZERO { None } else { Some(Some(y)) } } } const fn irregular_iterator_to_bit_chunks< I: Iterator, T: PrimitiveUnsigned, U: PrimitiveUnsigned, >( xs: I, in_chunk_size: u64, out_chunk_size: u64, ) -> IrregularIteratorToBitChunks { IrregularIteratorToBitChunks { xs, x: T::ZERO, x_width: in_chunk_size, y_width: out_chunk_size, remaining_x_bits: 0, in_inner_loop: false, phantom: PhantomData, } } /// Regroups an iterator of bit chunks into another iterator of bit chunks, possibly with a /// different chunk size. /// /// This `enum` is created by [`iterator_to_bit_chunks`]; see its documentation for more. #[derive(Clone, Debug)] pub enum IteratorToBitChunks, T: PrimitiveUnsigned, U: PrimitiveUnsigned> { SameWidth(SameWidthIteratorToBitChunks), EvenFraction(EvenFractionIteratorToBitChunks), EvenMultiple(EvenMultipleIteratorToBitChunks), Irregular(IrregularIteratorToBitChunks), } impl, T: PrimitiveUnsigned, U: PrimitiveUnsigned> IteratorToBitChunks { pub(crate) fn next_with_wrapping U>(&mut self, wrap: F) -> Option> { match *self { IteratorToBitChunks::SameWidth(ref mut xs) => xs.next_with_wrapping(wrap), IteratorToBitChunks::EvenFraction(ref mut xs) => xs.next_with_wrapping(wrap), IteratorToBitChunks::EvenMultiple(ref mut xs) => xs.next_with_wrapping(wrap), IteratorToBitChunks::Irregular(ref mut xs) => xs.next_with_wrapping(wrap), } } } impl, T: PrimitiveUnsigned, U: PrimitiveUnsigned + WrappingFrom> Iterator for IteratorToBitChunks { type Item = Option; #[inline] fn next(&mut self) -> Option> { self.next_with_wrapping(U::wrapping_from) } } /// Regroups an iterator of bit chunks into another iterator of bit chunks, possibly with a /// different chunk size. /// /// In other words, let $A$ be the input chunk size and $B$ the output chunk size. Let's consider /// the lowest $A$ bits of each unsigned value produced by the input iterator, and concatenate them /// (least-significant bits first) into a single bit sequence. Then we chop the sequence up into /// chunks of $B$ bits, and have the output iterator return each chunk. /// /// Let $(x\_i)\_{i=0}^{n-1}$ be the input iterator, where $n$ may be $\infty$. If $n$ is finite, we /// assume that $x\_{n-1} \neq 0$. Then we define the bit sequence $b\_{k=0}^\infty$ such that $b /// \in \\{0, 1\\}$, $b\_k=0$ for $k \geq An$, and /// $$ /// x_i = \sum_{k=0}^{A-1} b_{Ai+k}2^k. /// $$ /// Then, let $(y\_j)\_{j=0}^{m-1}$ be a sequence such that /// $$ /// y_j = \sum_{k=0}^{B-1} b_{Bi+k}2^k. /// $$ /// Then we have $f((x\_i)\_{i=0}^{n-1}) = (y\_j)\_{j=0}^{m-1}$. Note that the sequence $y$ is not /// uniquely specified, since it may contain arbitrarily many trailing zeros. However, if $x$ is /// finite, $y$ is guaranteed to also be finite. /// /// The output length is $An/B + O(1)$, where $n$ is `xs.count()`, $A$ is `in_chunk_size`, and $B$ /// is `out_chunk_size`. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::iterators::iterator_to_bit_chunks; /// /// assert_eq!( /// iterator_to_bit_chunks::<_, u16, u32>([123, 456].iter().cloned(), 10, 10) /// .map(Option::unwrap) /// .collect_vec(), /// &[123, 456] /// ); /// assert_eq!( /// iterator_to_bit_chunks::<_, u16, u16>([0b000111111, 0b110010010].iter().cloned(), 9, 3) /// .map(Option::unwrap) /// .collect_vec(), /// &[0b111, 0b111, 0b000, 0b010, 0b010, 0b110] /// ); /// assert_eq!( /// iterator_to_bit_chunks::<_, u16, u32>( /// [0b111, 0b111, 0b000, 0b010, 0b010, 0b110].iter().cloned(), /// 3, /// 9 /// ) /// .map(Option::unwrap) /// .collect_vec(), /// &[0b000111111, 0b110010010] /// ); /// assert_eq!( /// iterator_to_bit_chunks::<_, u32, u16>( /// [0b1010101, 0b1111101, 0b0100001, 0b110010].iter().cloned(), /// 7, /// 6 /// ) /// .map(Option::unwrap) /// .collect_vec(), /// &[0b010101, 0b111011, 0b000111, 0b010010, 0b110] /// ); /// ``` pub fn iterator_to_bit_chunks, T: PrimitiveUnsigned, U: PrimitiveUnsigned>( xs: I, in_chunk_size: u64, out_chunk_size: u64, ) -> IteratorToBitChunks { assert_ne!(in_chunk_size, 0); assert_ne!(out_chunk_size, 0); assert!(in_chunk_size <= T::WIDTH); assert!(out_chunk_size <= U::WIDTH); match in_chunk_size.cmp(&out_chunk_size) { Equal => { return IteratorToBitChunks::SameWidth(same_width_iterator_to_bit_chunks( xs, in_chunk_size, )) } Less => { if out_chunk_size.divisible_by(in_chunk_size) { return IteratorToBitChunks::EvenMultiple(even_multiple_iterator_to_bit_chunks( xs, in_chunk_size, out_chunk_size, )); } } Greater => { let (multiple, remainder) = in_chunk_size.div_mod(out_chunk_size); if remainder == 0 { return IteratorToBitChunks::EvenFraction(even_fraction_iterator_to_bit_chunks( xs, multiple, out_chunk_size, )); } } } IteratorToBitChunks::Irregular(irregular_iterator_to_bit_chunks( xs, in_chunk_size, out_chunk_size, )) } /// A `struct` that holds the state of the ruler sequence. /// /// This `struct` is created by [`ruler_sequence`]; see its documentation for more. #[derive(Clone, Debug, Eq, Hash, PartialEq)] pub struct RulerSequence> { i: u64, phantom: PhantomData<*const T>, } impl> Iterator for RulerSequence { type Item = T; fn next(&mut self) -> Option { self.i += 1; Some(T::exact_from(self.i.trailing_zeros())) } } /// Returns the ruler sequence. /// /// The ruler sequence () is the number of times that 2 divides the /// numbers $1, 2, 3, \ldots$. /// /// $(x_i)_{i=1}^\infty = t_i$, where for each $i$, $i = (2k_i+1)2^{t_i}$ for some $k_i\in /// \mathbb{Z}$. /// /// The $n$th term of this sequence is no greater than $\log_2(n + 1)$. Every number occurs /// infinitely many times, and any number's first occurrence is after all smaller numbers have /// occured. /// /// The output length is infinite. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::iterators::ruler_sequence; /// /// assert_eq!( /// prefix_to_string(ruler_sequence::(), 20), /// "[0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, ...]" /// ); /// ``` pub const fn ruler_sequence>() -> RulerSequence { RulerSequence { i: 0, phantom: PhantomData, } } /// A `struct` that holds the state of a bit distributor sequence. /// /// This `struct` is created by [`bit_distributor_sequence`]; see its documentation for more. #[derive(Clone, Debug)] pub struct BitDistributorSequence { bit_distributor: BitDistributor, } impl Iterator for BitDistributorSequence { type Item = usize; fn next(&mut self) -> Option { let i = self.bit_distributor.get_output(1); self.bit_distributor.increment_counter(); Some(i) } } /// Returns a sequence based on a [`BitDistributor`]. /// /// The sequence is obtained by taking the second output of a two-output [`BitDistributor`]. If both /// output types are normal with weight 1, the sequence is . /// /// The smaller the first output type is relative to the second (where tiny outputs are smaller than /// normal outputs), the slower the sequence will grow. /// /// - If the first output type is normal and the second is tiny, the sequence grows as $O(n)$. /// - If the first output type is tiny and the second is normal, the sequence grows as $O(\log n)$. /// - If both output types are normal with weights $p$ and $q$, the sequence grows as /// $O(n^\frac{p}{p+q})$. /// - The output types cannot both be tiny. /// /// Every number occurs infinitely many times, and any number's first occurrence is after all /// smaller numbers have occured. The sequence increases by no more than 1 at each step, but may /// decrease by an arbitrarily large amount. /// /// The output length is infinite. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Panics /// Panics if both output types are tiny. /// /// # Examples /// ``` /// use malachite_base::iterators::bit_distributor::BitDistributorOutputType; /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::iterators::bit_distributor_sequence; /// /// assert_eq!( /// prefix_to_string( /// bit_distributor_sequence( /// BitDistributorOutputType::normal(1), /// BitDistributorOutputType::normal(2) /// ), /// 50 /// ), /// "[0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 2, 3, 2, 3, 2, 3, 0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 2, 3, 2, \ /// 3, 2, 3, 0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 2, 3, 2, 3, 2, 3, 0, 1, ...]" /// ); /// assert_eq!( /// prefix_to_string( /// bit_distributor_sequence( /// BitDistributorOutputType::normal(2), /// BitDistributorOutputType::normal(1) /// ), /// 50 /// ), /// "[0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, 7, 8, 9, 10, 11, 8, 9, 10, 11, 12, 13, 14, \ /// 15, 12, 13, 14, 15, 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, 7, 8, 9, ...]" /// ); /// ``` pub fn bit_distributor_sequence( x_output_type: BitDistributorOutputType, y_output_type: BitDistributorOutputType, ) -> BitDistributorSequence { BitDistributorSequence { bit_distributor: BitDistributor::new(&[y_output_type, x_output_type]), } } malachite-base-0.4.16/src/num/logic/bit_access.rs000064400000000000000000000220241046102023000177030ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::logic::traits::BitAccess; fn get_bit_unsigned(x: &T, index: u64) -> bool { index < T::WIDTH && (*x >> index).odd() } fn set_bit_unsigned(x: &mut T, index: u64) { if index < T::WIDTH { *x |= T::power_of_2(index); } else { panic!( "Cannot set bit {} in non-negative value of width {}", index, T::WIDTH ); } } fn clear_bit_unsigned(x: &mut T, index: u64) { if index < T::WIDTH { *x &= !T::power_of_2(index); } } macro_rules! impl_bit_access_unsigned { ($t:ident) => { impl BitAccess for $t { /// Determines whether the $i$th bit of an unsigned primitive integer, or the /// coefficient of $2^i$ in its binary expansion, is 0 or 1. /// /// `false` means 0 and `true` means 1. Getting bits beyond the type's width is allowed; /// those bits are false. /// /// Let /// $$ /// n = \sum_{i=0}^\infty 2^{b_i}, /// $$ /// where for all $i$, $b_i\in \\{0, 1\\}$; so finitely many of the bits are 1, and the /// rest are 0. Then $f(n, j) = (b_j = 1)$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::bit_access#get_bit). #[inline] fn get_bit(&self, index: u64) -> bool { get_bit_unsigned(self, index) } /// Sets the $i$th bit of an unsigned primitive integer, or the coefficient of $2^i$ in /// its binary expansion, to 1. /// /// Setting bits beyond the type's width is disallowed. /// /// Let /// $$ /// n = \sum_{i=0}^{W-1} 2^{b_i}, /// $$ /// where for all $i$, $b_i\in \\{0, 1\\}$, and $W$ is the width of the type. Then /// $$ /// n \gets \\begin{cases} /// n + 2^j & \text{if} \\quad b_j = 0, \\\\ /// n & \text{otherwise}, /// \\end{cases} /// $$ /// where $j < W$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if $i \geq W$, where $i$ is `index` and $W$ is `$t::WIDTH`. /// /// # Examples /// See [here](super::bit_access#set_bit). #[inline] fn set_bit(&mut self, index: u64) { set_bit_unsigned(self, index) } /// Sets the $i$th bit of an unsigned primitive integer, or the coefficient of $2^i$ in /// its binary expansion, to 0. /// /// Clearing bits beyond the type's width is allowed; since those bits are already /// `false`, clearing them does nothing. /// /// Let /// $$ /// n = \sum_{i=0}^{W-1} 2^{b_i}, /// $$ /// where for all $i$, $b_i\in \\{0, 1\\}$, and $W$ is the width of the type. Then /// $$ /// n \gets \\begin{cases} /// n - 2^j & \text{if} \\quad b_j = 1, \\\\ /// n & \text{otherwise}. /// \\end{cases} /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::bit_access#clear_bit). #[inline] fn clear_bit(&mut self, index: u64) { clear_bit_unsigned(self, index) } } }; } apply_to_unsigneds!(impl_bit_access_unsigned); fn get_bit_signed(x: &T, index: u64) -> bool { if index < T::WIDTH { (*x >> index).odd() } else { *x < T::ZERO } } fn set_bit_signed(x: &mut T, index: u64) { if index < T::WIDTH { *x |= T::ONE << index; } else if *x >= T::ZERO { panic!( "Cannot set bit {} in non-negative value of width {}", index, T::WIDTH ); } } fn clear_bit_signed(x: &mut T, index: u64) { if index < T::WIDTH { *x &= !(T::ONE << index); } else if *x < T::ZERO { panic!( "Cannot clear bit {} in negative value of width {}", index, T::WIDTH ); } } macro_rules! impl_bit_access_signed { ($t:ident) => { impl BitAccess for $t { /// Determines whether the $i$th bit of a signed primitive integer is 0 or 1. /// /// `false` means 0 and `true` means 1. Getting bits beyond the type's width is allowed; /// those bits are `true` if the value is negative, and `false` otherwise. /// /// If $n \geq 0$, let /// $$ /// n = \sum_{i=0}^\infty 2^{b_i}, /// $$ /// where for all $i$, $b_i\in \\{0, 1\\}$; so finitely many of the bits are 1, and the /// rest are 0. Then $f(n, i) = (b_i = 1)$. /// /// If $n < 0$, let /// $$ /// 2^W + n = \sum_{i=0}^{W-1} 2^{b_i}, /// $$ /// where /// - $W$ is the type's width /// - for all $i$, $b_i\in \\{0, 1\\}$, and $b_i = 1$ for $i \geq W$. /// /// Then $f(n, j) = (b_j = 1)$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::bit_access#get_bit). #[inline] fn get_bit(&self, index: u64) -> bool { get_bit_signed(self, index) } /// Sets the $i$th bit of a signed primitive integer to 1. /// /// Setting bits beyond the type's width is disallowed if the number is non-negative. /// /// If $n \geq 0$ and $j \neq W - 1$, let /// $$ /// n = \sum_{i=0}^{W-1} 2^{b_i}; /// $$ /// but if $n < 0$ or $j = W - 1$, let /// $$ /// 2^W + n = \sum_{i=0}^{W-1} 2^{b_i}, /// $$ /// where for all $i$, $b_i\in \\{0, 1\\}$, and $W$ is the width of the type. Then /// $$ /// n \gets \\begin{cases} /// n + 2^j & \text{if} \\quad b_j = 0, \\\\ /// n & \text{otherwise}, /// \\end{cases} /// $$ /// where $n < 0$ or $j < W$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if $n \geq 0$ and $i \geq W$, where $n$ is `self`, $i$ is `index` and $W$ is /// the width of the type. /// /// # Examples /// See [here](super::bit_access#set_bit). #[inline] fn set_bit(&mut self, index: u64) { set_bit_signed(self, index) } /// Sets the $i$th bit of a signed primitive integer to 0. /// /// Clearing bits beyond the type's width is disallowed if the number is negative. /// /// If $n \geq 0$ or $j = W - 1$, let /// $$ /// n = \sum_{i=0}^{W-1} 2^{b_i}; /// $$ /// but if $n < 0$ or $j = W - 1$, let /// $$ /// 2^W + n = \sum_{i=0}^{W-1} 2^{b_i}, /// $$ /// where for all $i$, $b_i\in \\{0, 1\\}$ and $W$ is the width of the type. Then /// $$ /// n \gets \\begin{cases} /// n - 2^j & \text{if} \\quad b_j = 1, \\\\ /// n & \text{otherwise}, /// \\end{cases} /// $$ /// where $n \geq 0$ or $j < W$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if $n < 0$ and $i \geq W$, where $n$ is `self`, $i$ is `index` and $W$ is the /// width of the type. /// /// # Examples /// See [here](super::bit_access#clear_bit). #[inline] fn clear_bit(&mut self, index: u64) { clear_bit_signed(self, index) } } }; } apply_to_signeds!(impl_bit_access_signed); malachite-base-0.4.16/src/num/logic/bit_block_access.rs000064400000000000000000000261561046102023000210670ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{ModPowerOf2, UnsignedAbs}; use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::WrappingFrom; use crate::num::logic::traits::{BitBlockAccess, LeadingZeros}; use core::cmp::min; const ERROR_MESSAGE: &str = "Result exceeds width of output type"; fn get_bits_unsigned(x: &T, start: u64, end: u64) -> T { assert!(start <= end); if start >= T::WIDTH { T::ZERO } else { (*x >> start).mod_power_of_2(end - start) } } fn assign_bits_unsigned(x: &mut T, start: u64, end: u64, bits: &T) { assert!(start <= end); let width = T::WIDTH; let bits_width = end - start; let bits = bits.mod_power_of_2(bits_width); if bits != T::ZERO && LeadingZeros::leading_zeros(bits) < start { panic!("{}", ERROR_MESSAGE); } else if start < width { *x &= !(T::MAX.mod_power_of_2(min(bits_width, width - start)) << start); *x |= bits << start; } } macro_rules! impl_bit_block_access_unsigned { ($t:ident) => { impl BitBlockAccess for $t { type Bits = $t; /// Extracts a block of adjacent bits from a number. /// /// The first index is `start` and last index is `end - 1`. /// /// The block of bits has the same type as the input. If `end` is greater than the /// type's width, the high bits of the result are all 0. /// /// Let /// $$ /// n = \sum_{i=0}^\infty 2^{b_i}, /// $$ /// where for all $i$, $b_i\in \\{0, 1\\}$; so finitely many of the bits are 1, and the /// rest are 0. Then /// $$ /// f(n, p, q) = \sum_{i=p}^{q-1} 2^{b_{i-p}}. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `start < end`. /// /// # Examples /// See [here](super::bit_block_access#get_bits). #[inline] fn get_bits(&self, start: u64, end: u64) -> Self { get_bits_unsigned(self, start, end) } /// Replaces a block of adjacent bits in a number with other bits. /// /// The least-significant `end - start` bits of `bits` are assigned to bits `start` /// through `end - 1`, inclusive, of `self`. /// /// The block of bits has the same type as the input. If `bits` has fewer bits than `end /// - start`, the high bits are interpreted as 0. If `end` is greater than the type's /// width, the high bits of `bits` must be 0. /// /// Let /// $$ /// n = \sum_{i=0}^{W-1} 2^{b_i}, /// $$ /// where for all $i$, $b_i\in \\{0, 1\\}$ and $W$ is `$t::WIDTH`. Let /// $$ /// m = \sum_{i=0}^k 2^{d_i}, /// $$ /// where for all $i$, $d_i\in \\{0, 1\\}$. Also, let $p, q \in \mathbb{N}$, where $d_i /// = 0$ for all $i \geq W + p$. /// /// Then /// $$ /// n \gets \sum_{i=0}^{W-1} 2^{c_i}, /// $$ /// where /// $$ /// \\{c_0, c_1, c_2, \ldots, c_ {W-1}\\} = /// \\{b_0, b_1, b_2, \ldots, b_{p-1}, d_0, d_1, \ldots, d_{p-q-1}, b_q, \ldots, /// b_ {W-1}\\}. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Let `W` be the type's width. Panics if `start < end`, or if `end > W` and bits `W - /// start` through `end - start` of `bits` are nonzero. /// /// # Examples /// See [here](super::bit_block_access#assign_bits). #[inline] fn assign_bits(&mut self, start: u64, end: u64, bits: &Self::Bits) { assign_bits_unsigned(self, start, end, bits) } } }; } apply_to_unsigneds!(impl_bit_block_access_unsigned); fn get_bits_signed + PrimitiveSigned, U>( x: &T, start: u64, end: u64, ) -> U { assert!(start <= end); (if start >= T::WIDTH { -T::from(*x < T::ZERO) } else { *x >> start }) .mod_power_of_2(end - start) } fn assign_bits_signed< T: PrimitiveSigned + UnsignedAbs + WrappingFrom, U: PrimitiveUnsigned, >( x: &mut T, start: u64, end: u64, bits: &U, ) { assert!(start <= end); if *x >= T::ZERO { let mut abs_x = x.unsigned_abs(); abs_x.assign_bits(start, end, bits); assert!(!abs_x.get_highest_bit(), "{ERROR_MESSAGE}"); *x = T::wrapping_from(abs_x); } else { let width = T::WIDTH - 1; let bits_width = end - start; let bits = bits.mod_power_of_2(bits_width); let max = U::MAX; if bits_width > width + 1 { panic!("{}", ERROR_MESSAGE); } else if start >= width { assert!(bits == max.mod_power_of_2(bits_width), "{ERROR_MESSAGE}"); } else { let lower_width = width - start; if end > width && bits >> lower_width != max.mod_power_of_2(end - width) { panic!("{}", ERROR_MESSAGE); } else { *x &= T::wrapping_from(!(max.mod_power_of_2(min(bits_width, lower_width)) << start)); *x |= T::wrapping_from(bits << start); } } } } macro_rules! impl_bit_block_access_signed { ($u:ident, $s:ident) => { impl BitBlockAccess for $s { type Bits = $u; /// Extracts a block of adjacent bits from a number. /// /// The first index is `start` and last index is `end - 1`. /// /// The type of the block of bits is the unsigned version of the input type. If `end` is /// greater than the type's width, the high bits of the result are all 0, or all 1, /// depending on the input value's sign; and if the input is negative and `end - start` /// is greater than the type's width, the function panics. /// /// If $n \geq 0$, let /// $$ /// n = \sum_{i=0}^\infty 2^{b_i}, /// $$ /// where for all $i$, $b_i\in \\{0, 1\\}$; so finitely many of the bits are 1, and the /// rest are 0. Then /// $$ /// f(n, p, q) = \sum_{i=p}^{q-1} 2^{b_{i-p}}. /// $$ /// /// If $n < 0$, let /// $$ /// 2^W + n = \sum_{i=0}^{W-1} 2^{b_i}, /// $$ /// where /// - $W$ is the type's width /// - for all $i$, $b_i\in \\{0, 1\\}$, and $b_i = 1$ for $i \geq W$. /// /// Then /// $$ /// f(n, p, q) = \sum_{i=p}^{q-1} 2^{b_{i-p}}. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Let `W` be the type's width. Panics if `start < end` or (`self < 0` and `end - start /// > W`). /// /// # Examples /// See [here](super::bit_block_access#get_bits). #[inline] fn get_bits(&self, start: u64, end: u64) -> Self::Bits { get_bits_signed(self, start, end) } /// Replaces a block of adjacent bits in a number with other bits. /// /// The least-significant `end - start` bits of `bits` are assigned to bits `start` /// through `end - 1`, inclusive, of `self`. /// /// The type of the block of bits is the unsigned version of the input type. If `bits` /// has fewer bits than `end - start`, the high bits are interpreted as 0 or 1, /// depending on the sign of `self`. If `end` is greater than the type's width, the high /// bits of `bits` must be 0 or 1, depending on the sign of `self`. /// /// The sign of `self` remains unchanged, since only a finite number of bits are changed /// and the sign is determined by the implied infinite prefix of bits. /// /// If $n \geq 0$ and $j \neq W - 1$, let /// $$ /// n = \sum_{i=0}^{W-1} 2^{b_i}, /// $$ /// where for all $i$, $b_i\in \\{0, 1\\}$ and $W$ is `$t::WIDTH`. Let /// $$ /// m = \sum_{i=0}^k 2^{d_i}, /// $$ /// where for all $i$, $d_i\in \\{0, 1\\}$. Also, let $p, q \in \mathbb{N}$, where $d_i /// = 0$ for all $i \geq W + p - 1$. Then /// $$ /// n \gets \sum_{i=0}^{W-1} 2^{c_i}, /// $$ /// where /// $$ /// \\{c_0, c_1, c_2, \ldots, c_ {W-1}\\} = /// \\{b_0, b_1, b_2, \ldots, b_{p-1}, d_0, d_1, \ldots, d_{p-q-1}, b_q, \ldots, /// b_ {W-1}\\}. /// $$ /// /// If $n < 0$ or $j = W - 1$, let /// $$ /// 2^W + n = \sum_{i=0}^{W-1} 2^{b_i}, /// $$ /// where for all $i$, $b_i\in \\{0, 1\\}$ and $W$ is `$t::WIDTH`. Let /// $$ /// m = \sum_{i=0}^k 2^{d_i}, /// $$ /// where for all $i$, $d_i\in \\{0, 1\\}$. Also, let $p, q \in \mathbb{N}$, where $d_i /// = 1$ for all $i \geq W + p - 1$. Then /// $$ /// f(n, p, q, m) = \left ( \sum_{i=0}^{W-1} 2^{c_i} \right ) - 2^W, /// $$ /// where /// $$ /// \\{c_0, c_1, c_2, \ldots, c_ {W-1}\\} = /// \\{b_0, b_1, b_2, \ldots, b_{p-1}, d_0, d_1, \ldots, d_{p-q-1}, b_q, \ldots, /// b_ {W-1}\\}. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Let `W` be the type's width Panics if `start < end`, or if `end >= W` and bits `W - /// start` through `end - start` of `bits` are not equal to the original sign bit of /// `self`. /// /// # Examples /// See [here](super::bit_block_access#assign_bits). #[inline] fn assign_bits(&mut self, start: u64, end: u64, bits: &Self::Bits) { assign_bits_signed(self, start, end, bits) } } }; } apply_to_unsigned_signed_pairs!(impl_bit_block_access_signed); malachite-base-0.4.16/src/num/logic/bit_convertible.rs000064400000000000000000000323111046102023000207560ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::WrappingFrom; use crate::num::logic::traits::{BitConvertible, LeadingZeros}; use alloc::vec::Vec; fn to_bits_asc_unsigned(x: &T) -> Vec { let mut bits = Vec::new(); let mut x = *x; while x != T::ZERO { bits.push(x.odd()); x >>= 1; } bits } fn to_bits_desc_unsigned(x: &T) -> Vec { let mut bits = Vec::new(); if *x == T::ZERO { return bits; } bits.push(true); if *x == T::ONE { return bits; } let mut mask = T::power_of_2(T::WIDTH - LeadingZeros::leading_zeros(*x) - 2); while mask != T::ZERO { bits.push(*x & mask != T::ZERO); mask >>= 1; } bits } fn from_bits_asc_unsigned>(bits: I) -> T { let mut n = T::ZERO; let mut mask = T::ONE; for bit in bits { if mask == T::ZERO { assert!(!bit, "Bits cannot fit in integer of type {}", T::NAME); } else { if bit { n |= mask; } mask <<= 1; } } n } #[inline] fn from_bits_desc_unsigned>(bits: I) -> T { let mut n = T::ZERO; let high_mask = T::power_of_2(T::WIDTH - 1); for bit in bits { assert!( n & high_mask == T::ZERO, "Bits cannot fit in integer of type {}", T::NAME ); n <<= 1; if bit { n |= T::ONE; } } n } macro_rules! impl_bit_convertible_unsigned { ($t:ident) => { impl BitConvertible for $t { /// Returns a [`Vec`] containing the bits of a number in ascending order: least- to /// most-significant. /// /// If the number is 0, the [`Vec`] is empty; otherwise, it ends with `true`. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`. /// /// # Examples /// See [here](super::bit_convertible#to_bits_asc). #[inline] fn to_bits_asc(&self) -> Vec { to_bits_asc_unsigned(self) } /// Returns a [`Vec`] containing the bits of a number in descending order: most- to /// least-significant. /// /// If the number is 0, the [`Vec`] is empty; otherwise, it begins with `true`. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`. /// /// # Examples /// See [here](super::bit_convertible#to_bits_desc). #[inline] fn to_bits_desc(&self) -> Vec { to_bits_desc_unsigned(self) } /// Converts an iterator of bits into a number. The bits should be in ascending order /// (least- to most-significant). /// /// The function panics if the input represents a number that can't fit in the output /// type. /// /// $$ /// f((b_i)_ {i=0}^{k-1}) = \sum_{i=0}^{k-1}2^i \[b_i\], /// $$ /// where braces denote the Iverson bracket, which converts a bit to 0 or 1. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `bits.count()`. /// /// # Panics /// Panics if the bits represent a value that isn't representable by the output type. /// /// # Examples /// See [here](super::bit_convertible#from_bits_asc). #[inline] fn from_bits_asc>(bits: I) -> $t { from_bits_asc_unsigned(bits) } /// Converts an iterator of bits into a number. The bits should be in descending order /// (most- to least-significant). /// /// The function panics if the input represents a number that can't fit in the output /// type. /// /// $$ /// f((b_i)_ {i=0}^{k-1}) = \sum_{i=0}^{k-1}2^{k-i-1} \[b_i\], /// $$ /// where braces denote the Iverson bracket, which converts a bit to 0 or 1. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `bits.count()`. /// /// # Panics /// Panics if the bits represent a value that isn't representable by the output type. /// /// # Examples /// See [here](super::bit_convertible#from_bits_desc). #[inline] fn from_bits_desc>(bits: I) -> $t { from_bits_desc_unsigned(bits) } } }; } apply_to_unsigneds!(impl_bit_convertible_unsigned); fn to_bits_asc_signed(x: &T) -> Vec { let mut bits = Vec::new(); let mut x = *x; if x >= T::ZERO { while x != T::ZERO { bits.push(x.odd()); x >>= 1; } if !bits.is_empty() { bits.push(false); } } else { while x != T::NEGATIVE_ONE { bits.push(x.odd()); x >>= 1; } bits.push(true); } bits } fn to_bits_desc_signed(x: &T) -> Vec { let mut bits = Vec::new(); if *x >= T::ZERO { if *x == T::ZERO { return bits; } bits.push(false); bits.push(true); if *x == T::ONE { return bits; } let mut mask = T::power_of_2(T::WIDTH - LeadingZeros::leading_zeros(*x) - 2); while mask != T::ZERO { bits.push(*x & mask != T::ZERO); mask >>= 1; } } else { bits.push(true); if *x == T::NEGATIVE_ONE { return bits; } bits.push(false); if *x == T::NEGATIVE_ONE << 1 { return bits; } let mut mask = T::power_of_2(T::WIDTH - LeadingZeros::leading_zeros(!*x) - 2); while mask != T::ZERO { bits.push(*x & mask != T::ZERO); mask >>= 1; } } bits } fn from_bits_asc_signed< U: PrimitiveUnsigned, S: PrimitiveSigned + WrappingFrom, I: Iterator, >( bits: I, ) -> S { let mut n = U::ZERO; let mut mask = U::ONE; let mut last_bit = false; for bit in bits { if mask == U::ZERO { assert_eq!( bit, last_bit, "Bits cannot fit in integer of type {}", S::NAME ); } else { if bit { n |= mask; } mask <<= 1; last_bit = bit; } } if last_bit { S::wrapping_from(n | mask.wrapping_neg()) } else { S::wrapping_from(n) } } #[inline] fn from_bits_desc_signed< U: PrimitiveUnsigned, S: PrimitiveSigned + WrappingFrom, I: Iterator, >( bits: I, ) -> S { let mut n = U::ZERO; let high_mask = U::power_of_2(U::WIDTH - 2); let mut first = true; let mut sign_bit = false; for bit in bits { if first { sign_bit = bit; first = false; } else { assert!( n & high_mask == U::ZERO, "Bits cannot fit in integer of type {}", S::NAME ); n <<= 1; if bit != sign_bit { n |= U::ONE; } } } if sign_bit { S::wrapping_from(!n) } else { S::wrapping_from(n) } } macro_rules! impl_bit_convertible_signed { ($u:ident, $s:ident) => { impl BitConvertible for $s { /// Returns a [`Vec`] containing the bits of a number in ascending order: least- to /// most-significant. /// /// If the number is 0, the [`Vec`] is empty; otherwise, the last bit is the sign bit: /// `false` if the number is non-negative and `true` if it is negative. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`. /// /// # Examples /// See [here](super::bit_convertible#to_bits_asc). #[inline] fn to_bits_asc(&self) -> Vec { to_bits_asc_signed(self) } /// Returns a [`Vec`] containing the bits of a number in ascending order: most- to /// least-significant. /// /// If the number is 0, the [`Vec`] is empty; otherwise, the first bit is the sign bit: /// `false` if the number is non-negative and `true` if it is negative. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`. /// /// # Examples /// See [here](super::bit_convertible#to_bits_desc). #[inline] fn to_bits_desc(&self) -> Vec { to_bits_desc_signed(self) } /// Converts an iterator of bits into a value. The bits should be in ascending order /// (least- to most-significant). /// /// The bits are interpreted as in twos-complement, and the last bit is the sign bit; if /// it is `false`, the number is non-negative, and if it is `true`, the number is /// negative. /// /// The function panics if the input represents a number that can't fit in the output /// type. /// /// Let $k$ be `bits.count()`. If $k = 0$ or $b_{k-1}$ is `false`, then /// $$ /// f((b_i)_ {i=0}^{k-1}) = \sum_{i=0}^{k-1}2^i \[b_i\], /// $$ /// where braces denote the Iverson bracket, which converts a bit to 0 or 1. /// /// If $b_{k-1}$ is `true`, then /// $$ /// f((b_i)_ {i=0}^{k-1}) = \left ( \sum_{i=0}^{k-1}2^i \[b_i\] \right ) - 2^k. /// $$ /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `bits.count()`. /// /// # Panics /// Panics if the bits represent a value that doesn't fit in the output type. /// /// # Examples /// See [here](super::bit_convertible#from_bits_asc). #[inline] fn from_bits_asc>(bits: I) -> $s { from_bits_asc_signed::<$u, $s, _>(bits) } /// Converts an iterator of bits into a value. The bits should be in descending order /// (most- to least-significant). /// /// The bits are interpreted as in twos-complement, and the first bit is the sign bit; /// if it is `false`, the number is non-negative, and if it is `true`, the number is /// negative. /// /// The function panics if the input represents a number that can't fit in the output /// type. /// /// If `bits` is empty or $b_0$ is `false`, then /// $$ /// f((b_i)_ {i=0}^{k-1}) = \sum_{i=0}^{k-1}2^{k-i-1} \[b_i\], /// $$ /// where braces denote the Iverson bracket, which converts a bit to 0 or 1. /// /// If $b_0$ is `true`, then /// $$ /// f((b_i)_ {i=0}^{k-1}) = \left ( \sum_{i=0}^{k-1}2^{k-i-1} \[b_i\] \right ) - 2^k. /// $$ /// /// # Examples /// See [here](super::bit_convertible#from_bits_desc). #[inline] fn from_bits_desc>(bits: I) -> $s { from_bits_desc_signed::<$u, $s, _>(bits) } } }; } apply_to_unsigned_signed_pairs!(impl_bit_convertible_signed); malachite-base-0.4.16/src/num/logic/bit_iterable.rs000064400000000000000000000214741046102023000202410ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::{ExactFrom, WrappingFrom}; use crate::num::logic::traits::BitIterable; use core::cmp::min; use core::cmp::Ordering::*; use core::marker::PhantomData; use core::ops::Index; /// A double-ended iterator over the bits of an unsigned primitive integer. /// /// This `struct` is created by [`BitIterable::bits`]; see its documentation for more. #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] pub struct PrimitiveUnsignedBitIterator { pub(crate) value: T, pub(crate) remaining: usize, // If `n` is nonzero, this mask initially points to the least-significant bit, and is left- // shifted by next(). pub(crate) i_mask: T, // If `n` is nonzero, this mask initially points to the most-significant nonzero bit, and is // right-shifted by next_back(). pub(crate) j_mask: T, } impl Iterator for PrimitiveUnsignedBitIterator { type Item = bool; fn next(&mut self) -> Option { if self.remaining != 0 { let bit = self.value & self.i_mask != T::ZERO; self.i_mask <<= 1; self.remaining -= 1; Some(bit) } else { None } } fn size_hint(&self) -> (usize, Option) { (self.remaining, Some(self.remaining)) } } impl DoubleEndedIterator for PrimitiveUnsignedBitIterator { fn next_back(&mut self) -> Option { if self.remaining != 0 { let bit = self.value & self.j_mask != T::ZERO; self.j_mask >>= 1; self.remaining -= 1; Some(bit) } else { None } } } impl ExactSizeIterator for PrimitiveUnsignedBitIterator {} impl Index for PrimitiveUnsignedBitIterator { type Output = bool; /// A function to retrieve bits by index. /// /// The index is the power of 2 of which the bit is a coefficient. Indexing at or above the /// significant bit count returns false bits. /// /// This is equivalent to [`get_bit`](super::traits::BitAccess::get_bit). /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::num::logic::traits::BitIterable; /// /// assert_eq!(0u8.bits()[0], false); /// /// // 105 = 1101001b /// let bits = 105u32.bits(); /// assert_eq!(bits[0], true); /// assert_eq!(bits[1], false); /// assert_eq!(bits[2], false); /// assert_eq!(bits[3], true); /// assert_eq!(bits[4], false); /// assert_eq!(bits[5], true); /// assert_eq!(bits[6], true); /// assert_eq!(bits[7], false); /// assert_eq!(bits[100], false); /// ``` fn index(&self, index: u64) -> &bool { if self.value.get_bit(index) { &true } else { &false } } } fn bits_unsigned(x: T) -> PrimitiveUnsignedBitIterator { let significant_bits = x.significant_bits(); PrimitiveUnsignedBitIterator { value: x, remaining: usize::exact_from(significant_bits), i_mask: T::ONE, j_mask: T::power_of_2(significant_bits.saturating_sub(1)), } } macro_rules! impl_bit_iterable_unsigned { ($t:ident) => { impl BitIterable for $t { type BitIterator = PrimitiveUnsignedBitIterator<$t>; /// Returns a double-ended iterator over the bits of an unsigned primitive integer. /// /// The forward order is ascending, so that less significant bits appear first. There /// are no trailing false bits going forward, or leading falses going backward. /// /// If it's necessary to get a [`Vec`] of all the bits, consider using /// [`to_bits_asc`](super::traits::BitConvertible::to_bits_asc) or /// [`to_bits_desc`](super::traits::BitConvertible::to_bits_desc) instead. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::bit_iterable#bits). #[inline] fn bits(self) -> PrimitiveUnsignedBitIterator<$t> { bits_unsigned(self) } } }; } apply_to_unsigneds!(impl_bit_iterable_unsigned); /// A double-ended iterator over the bits of a signed primitive integer. /// /// This `struct` is created by [`BitIterable::bits`]; see its documentation for more. #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] pub struct PrimitiveSignedBitIterator { phantom: PhantomData<*const S>, xs: PrimitiveUnsignedBitIterator, } impl Iterator for PrimitiveSignedBitIterator { type Item = bool; #[inline] fn next(&mut self) -> Option { self.xs.next() } #[inline] fn size_hint(&self) -> (usize, Option) { self.xs.size_hint() } } impl DoubleEndedIterator for PrimitiveSignedBitIterator { #[inline] fn next_back(&mut self) -> Option { self.xs.next_back() } } impl ExactSizeIterator for PrimitiveSignedBitIterator { } impl Index for PrimitiveSignedBitIterator { type Output = bool; /// A function to retrieve bits by index. The index is the power of 2 of which the bit is a /// coefficient. /// /// Indexing at or above the significant bit count returns false or true bits, depending on the /// value's sign. /// /// This is equivalent to [`get_bit`](super::traits::BitAccess::get_bit). /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::num::logic::traits::BitIterable; /// /// assert_eq!(0i8.bits()[0], false); /// /// // -105 = 10010111 in two's complement /// let bits = (-105i32).bits(); /// assert_eq!(bits[0], true); /// assert_eq!(bits[1], true); /// assert_eq!(bits[2], true); /// assert_eq!(bits[3], false); /// assert_eq!(bits[4], true); /// assert_eq!(bits[5], false); /// assert_eq!(bits[6], false); /// assert_eq!(bits[7], true); /// assert_eq!(bits[100], true); /// ``` fn index(&self, index: u64) -> &bool { if self.xs[min(index, U::WIDTH - 1)] { &true } else { &false } } } fn bits_signed, S: PrimitiveSigned>( x: S, ) -> PrimitiveSignedBitIterator { let unsigned = U::wrapping_from(x); let significant_bits = match x.sign() { Equal => 0, Greater => unsigned.significant_bits() + 1, Less => (!unsigned).significant_bits() + 1, }; PrimitiveSignedBitIterator { phantom: PhantomData, xs: PrimitiveUnsignedBitIterator { value: unsigned, remaining: usize::exact_from(significant_bits), i_mask: U::ONE, j_mask: U::power_of_2(significant_bits.saturating_sub(1)), }, } } macro_rules! impl_bit_iterable_signed { ($u:ident, $s:ident) => { impl BitIterable for $s { type BitIterator = PrimitiveSignedBitIterator<$u, $s>; /// Returns a double-ended iterator over the bits of a signed primitive integer. /// /// The forward order is ascending, so that less significant bits appear first. There /// are no trailing sign bits going forward, or leading sign bits going backward. /// /// If it's necessary to get a [`Vec`] of all the bits, consider using /// [`to_bits_asc`](super::traits::BitConvertible::to_bits_asc) or /// [`to_bits_desc`](super::traits::BitConvertible::to_bits_desc) instead. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::bit_iterable#bits). #[inline] fn bits(self) -> PrimitiveSignedBitIterator<$u, $s> { bits_signed::<$u, $s>(self) } } }; } apply_to_unsigned_signed_pairs!(impl_bit_iterable_signed); malachite-base-0.4.16/src/num/logic/bit_scan.rs000064400000000000000000000130751046102023000173740ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::logic::traits::{BitScan, TrailingZeros}; fn index_of_next_false_bit_unsigned(x: T, start: u64) -> u64 { if start >= T::WIDTH { start } else { TrailingZeros::trailing_zeros(!(x | T::low_mask(start))) } } fn index_of_next_true_bit_unsigned(x: T, start: u64) -> Option { if start >= T::WIDTH { None } else { let index = TrailingZeros::trailing_zeros(x & !T::low_mask(start)); if index == T::WIDTH { None } else { Some(index) } } } macro_rules! impl_bit_scan_unsigned { ($t:ident) => { impl BitScan for $t { /// Given a number and a starting index, searches the number for the smallest index of a /// `false` bit that is greater than or equal to the starting index. /// /// Since the number is unsigned and therefore has an implicit prefix of infinitely-many /// zeros, this function always returns a value. /// /// Starting beyond the type's width is allowed; the result is the starting index. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::bit_scan#index_of_next_false_bit). #[inline] fn index_of_next_false_bit(self, start: u64) -> Option { Some(index_of_next_false_bit_unsigned(self, start)) } /// Given a number and a starting index, searches the number for the smallest index of a /// `true` bit that is greater than or equal to the starting index. /// /// If the starting index is greater than or equal to the type's width, the result is /// `None` since there are no `true` bits past that point. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::bit_scan#index_of_next_true_bit). #[inline] fn index_of_next_true_bit(self, start: u64) -> Option { index_of_next_true_bit_unsigned(self, start) } } }; } apply_to_unsigneds!(impl_bit_scan_unsigned); fn index_of_next_false_bit_signed(x: T, start: u64) -> Option { if start >= T::WIDTH - 1 { if x >= T::ZERO { Some(start) } else { None } } else { let index = TrailingZeros::trailing_zeros(!(x | T::low_mask(start))); if index == T::WIDTH { None } else { Some(index) } } } fn index_of_next_true_bit_signed(x: T, start: u64) -> Option { if start >= T::WIDTH - 1 { if x >= T::ZERO { None } else { Some(start) } } else { let index = TrailingZeros::trailing_zeros(x & !T::low_mask(start)); if index == T::WIDTH { None } else { Some(index) } } } macro_rules! impl_bit_scan_signed { ($t:ident) => { impl BitScan for $t { /// Given a number and a starting index, searches the number for the smallest index of a /// `false` bit that is greater than or equal to the starting index. /// /// If the starting index is greater than or equal to the type's width, then the result /// depends on whether the number is negative. If it is, then the result is `None` since /// there are no `false` bits past that point. If the number is non-negative, then the /// result is the starting index. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::bit_scan#index_of_next_false_bit). #[inline] fn index_of_next_false_bit(self, start: u64) -> Option { index_of_next_false_bit_signed(self, start) } /// Given a number and a starting index, searches the number for the smallest index of a /// `true` bit that is greater than or equal to the starting index. /// /// If the starting index is greater than or equal to the type's width, then the result /// depends on whether the number is non-negative. If it is, then the result is `None` /// since there are no `true` bits past that point. If the number is negative, then the /// result is the starting index. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::bit_scan#index_of_next_true_bit). #[inline] fn index_of_next_true_bit(self, start: u64) -> Option { index_of_next_true_bit_signed(self, start) } } }; } apply_to_signeds!(impl_bit_scan_signed); malachite-base-0.4.16/src/num/logic/count_ones.rs000064400000000000000000000015051046102023000177610ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::logic::traits::CountOnes; macro_rules! impl_count_ones { ($t:ident) => { impl CountOnes for $t { /// This is a wrapper over the `count_ones` functions in the standard library, for /// example [this one](u32::count_ones). #[inline] fn count_ones(self) -> u64 { u64::from($t::count_ones(self)) } } }; } apply_to_primitive_ints!(impl_count_ones); malachite-base-0.4.16/src/num/logic/count_zeros.rs000064400000000000000000000015151046102023000201600ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::logic::traits::CountZeros; macro_rules! impl_count_zeros { ($t:ident) => { impl CountZeros for $t { /// This is a wrapper over the `count_zeros` functions in the standard library, for /// example [this one](u32::count_zeros). #[inline] fn count_zeros(self) -> u64 { u64::from($t::count_zeros(self)) } } }; } apply_to_primitive_ints!(impl_count_zeros); malachite-base-0.4.16/src/num/logic/hamming_distance.rs000064400000000000000000000046471046102023000211110ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::logic::traits::{CheckedHammingDistance, CountOnes, HammingDistance}; fn hamming_distance_unsigned(x: T, y: T) -> u64 { CountOnes::count_ones(x ^ y) } macro_rules! impl_hamming_distance_unsigned { ($t:ident) => { impl HammingDistance<$t> for $t { /// Returns the Hamming distance between two numbers, or the number of bit flips needed /// to turn one into the other. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::hamming_distance#hamming_distance). #[inline] fn hamming_distance(self, other: $t) -> u64 { hamming_distance_unsigned(self, other) } } }; } apply_to_unsigneds!(impl_hamming_distance_unsigned); fn checked_hamming_distance_signed(x: T, y: T) -> Option { if (x >= T::ZERO) == (y >= T::ZERO) { Some(CountOnes::count_ones(x ^ y)) } else { None } } macro_rules! impl_checked_hamming_distance_signed { ($t:ident) => { impl CheckedHammingDistance<$t> for $t { /// Returns the Hamming distance between two numbers, or the number of bit flips needed /// to turn one into the other. /// /// If the two numbers have opposite signs, then the number of flips would be infinite, /// so the result is `None`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::hamming_distance#checked_hamming_distance). #[inline] fn checked_hamming_distance(self, other: $t) -> Option { checked_hamming_distance_signed(self, other) } } }; } apply_to_signeds!(impl_checked_hamming_distance_signed); malachite-base-0.4.16/src/num/logic/leading_zeros.rs000064400000000000000000000015351046102023000204350ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::logic::traits::LeadingZeros; macro_rules! impl_leading_zeros { ($t:ident) => { impl LeadingZeros for $t { /// This is a wrapper over the `leading_zeros` functions in the standard library, for /// example [this one](u32::leading_zeros). #[inline] fn leading_zeros(self) -> u64 { u64::from($t::leading_zeros(self)) } } }; } apply_to_primitive_ints!(impl_leading_zeros); malachite-base-0.4.16/src/num/logic/low_mask.rs000064400000000000000000000052501046102023000174220ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::logic::traits::LowMask; fn low_mask_unsigned(bits: u64) -> T { assert!(bits <= T::WIDTH); if bits == T::WIDTH { T::MAX } else { T::power_of_2(bits) - T::ONE } } macro_rules! impl_low_mask_unsigned { ($t:ident) => { impl LowMask for $t { /// Returns a number whose least significant $b$ bits are `true` and whose other bits /// are `false`. /// /// $f(b) = 2^b - 1$. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `bits` is greater than the width of of the type. /// /// # Examples /// See [here](super::low_mask#low_mask). #[inline] fn low_mask(bits: u64) -> $t { low_mask_unsigned(bits) } } }; } apply_to_unsigneds!(impl_low_mask_unsigned); fn low_mask_signed(bits: u64) -> T { assert!(bits <= T::WIDTH); if bits == T::WIDTH { T::NEGATIVE_ONE } else if bits == T::WIDTH - 1 { T::MAX } else { T::power_of_2(bits) - T::ONE } } macro_rules! impl_low_mask_signed { ($t:ident) => { impl LowMask for $t { /// Returns a number whose least significant $b$ bits are `true` and whose other bits /// are `false`. /// /// $$ /// f(b) = \\begin{cases} /// 2^b - 1 & \text{if} \\quad 0 \leq n < W, \\\\ /// -1 & \text{if} \\quad n = W, /// \\end{cases} /// $$ /// where $W$ is the width of the type. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `bits` is greater than the width of the type. /// /// # Examples /// See [here](super::low_mask#low_mask). #[inline] fn low_mask(bits: u64) -> $t { low_mask_signed(bits) } } }; } apply_to_signeds!(impl_low_mask_signed); malachite-base-0.4.16/src/num/logic/mod.rs000064400000000000000000000340671046102023000163750ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . /// [`BitAccess`](traits::BitAccess), a trait for getting and setting individual bits of a number. /// /// # get_bit /// ``` /// use malachite_base::num::logic::traits::BitAccess; /// /// assert_eq!(123u8.get_bit(2), false); /// assert_eq!(123u16.get_bit(3), true); /// assert_eq!(123u32.get_bit(100), false); /// assert_eq!(1000000000000u64.get_bit(12), true); /// assert_eq!(1000000000000u64.get_bit(100), false); /// /// assert_eq!(123i8.get_bit(2), false); /// assert_eq!(123i16.get_bit(3), true); /// assert_eq!(123i32.get_bit(100), false); /// assert_eq!((-123i8).get_bit(0), true); /// assert_eq!((-123i16).get_bit(1), false); /// assert_eq!((-123i32).get_bit(100), true); /// assert_eq!(1000000000000i64.get_bit(12), true); /// assert_eq!(1000000000000i64.get_bit(100), false); /// assert_eq!((-1000000000000i64).get_bit(12), true); /// assert_eq!((-1000000000000i64).get_bit(100), true); /// ``` /// /// # set_bit /// ``` /// use malachite_base::num::logic::traits::BitAccess; /// /// let mut x = 0u8; /// x.set_bit(2); /// x.set_bit(5); /// x.set_bit(6); /// assert_eq!(x, 100); /// /// let mut x = 0i8; /// x.set_bit(2); /// x.set_bit(5); /// x.set_bit(6); /// assert_eq!(x, 100); /// /// let mut x = -0x100i16; /// x.set_bit(2); /// x.set_bit(5); /// x.set_bit(6); /// assert_eq!(x, -156); /// ``` /// /// # clear_bit /// ``` /// use malachite_base::num::logic::traits::BitAccess; /// /// let mut x = 0x7fu8; /// x.clear_bit(0); /// x.clear_bit(1); /// x.clear_bit(3); /// x.clear_bit(4); /// assert_eq!(x, 100); /// /// let mut x = 0x7fi8; /// x.clear_bit(0); /// x.clear_bit(1); /// x.clear_bit(3); /// x.clear_bit(4); /// assert_eq!(x, 100); /// /// let mut x = -156i16; /// x.clear_bit(2); /// x.clear_bit(5); /// x.clear_bit(6); /// assert_eq!(x, -256); /// ``` /// /// # assign_bit /// ``` /// use malachite_base::num::logic::traits::BitAccess; /// /// let mut x = 0; /// x.assign_bit(2, true); /// x.assign_bit(5, true); /// x.assign_bit(6, true); /// assert_eq!(x, 100); /// x.assign_bit(2, false); /// x.assign_bit(5, false); /// x.assign_bit(6, false); /// assert_eq!(x, 0); /// /// x.assign_bit(2, true); /// x.assign_bit(5, true); /// x.assign_bit(6, true); /// assert_eq!(x, 100); /// x.assign_bit(2, false); /// x.assign_bit(5, false); /// x.assign_bit(6, false); /// assert_eq!(x, 0); /// /// let mut x = -0x100i16; /// x.assign_bit(2, true); /// x.assign_bit(5, true); /// x.assign_bit(6, true); /// assert_eq!(x, -156); /// x.assign_bit(2, false); /// x.assign_bit(5, false); /// x.assign_bit(6, false); /// assert_eq!(x, -256); /// ``` /// /// # flip_bit /// ``` /// use malachite_base::num::logic::traits::BitAccess; /// /// let mut x = 0u64; /// x.flip_bit(10); /// assert_eq!(x, 1024); /// x.flip_bit(10); /// assert_eq!(x, 0); /// /// let mut x = 0i32; /// x.flip_bit(10); /// assert_eq!(x, 1024); /// x.flip_bit(10); /// assert_eq!(x, 0); /// /// let mut x = -1i64; /// x.flip_bit(10); /// assert_eq!(x, -1025); /// x.flip_bit(10); /// assert_eq!(x, -1); /// ``` pub mod bit_access; /// [`BitBlockAccess`](traits::BitBlockAccess), a trait for getting and setting adjacent blocks of /// bits in a number. /// /// # get_bits /// ``` /// use malachite_base::num::logic::traits::BitBlockAccess; /// /// assert_eq!(0xabcdu16.get_bits(4, 8), 0xc); /// assert_eq!(0xabcdu16.get_bits(12, 100), 0xa); /// assert_eq!(0xabcdu16.get_bits(5, 9), 14); /// assert_eq!(0xabcdu16.get_bits(5, 5), 0); /// assert_eq!(0xabcdu16.get_bits(100, 200), 0); /// /// assert_eq!((-0x5433i16).get_bits(4, 8), 0xc); /// assert_eq!((-0x5433i16).get_bits(5, 9), 14); /// assert_eq!((-0x5433i16).get_bits(5, 5), 0); /// assert_eq!((-0x5433i16).get_bits(100, 104), 0xf); /// ``` /// /// # assign_bits /// ``` /// use malachite_base::num::logic::traits::BitBlockAccess; /// /// let mut x = 0xab5du16; /// x.assign_bits(4, 8, &0xc); /// assert_eq!(x, 0xabcd); /// /// let mut x = 0xabcdu16; /// x.assign_bits(100, 200, &0); /// assert_eq!(x, 0xabcd); /// /// let mut x = 0xabcdu16; /// x.assign_bits(0, 100, &0x1234); /// assert_eq!(x, 0x1234); /// /// let mut x = 0x2b5di16; /// x.assign_bits(4, 8, &0xc); /// assert_eq!(x, 0x2bcd); /// /// let mut x = -0x5413i16; /// x.assign_bits(4, 8, &0xc); /// assert_eq!(x, -0x5433); /// /// let mut x = -0x5433i16; /// x.assign_bits(100, 104, &0xf); /// assert_eq!(x, -0x5433); /// ``` pub mod bit_block_access; /// [`BitConvertible`](traits::BitConvertible), a trait for extracting all bits from a number or /// constructing a number from bits. /// /// # to_bits_asc /// ``` /// use malachite_base::num::logic::traits::BitConvertible; /// /// assert_eq!(0u8.to_bits_asc(), &[]); /// assert_eq!(2u16.to_bits_asc(), &[false, true]); /// assert_eq!( /// 123u32.to_bits_asc(), /// &[true, true, false, true, true, true, true] /// ); /// /// assert_eq!(0i8.to_bits_asc(), &[]); /// assert_eq!(2i16.to_bits_asc(), &[false, true, false]); /// assert_eq!( /// (-123i32).to_bits_asc(), /// &[true, false, true, false, false, false, false, true] /// ); /// ``` /// /// # to_bits_desc /// ``` /// use malachite_base::num::logic::traits::BitConvertible; /// /// assert_eq!(0u8.to_bits_desc(), &[]); /// assert_eq!(2u16.to_bits_desc(), &[true, false]); /// assert_eq!( /// 123u32.to_bits_desc(), /// &[true, true, true, true, false, true, true] /// ); /// /// assert_eq!(0i8.to_bits_desc(), &[]); /// assert_eq!(2i16.to_bits_desc(), &[false, true, false]); /// assert_eq!( /// (-123i32).to_bits_desc(), /// &[true, false, false, false, false, true, false, true] /// ); /// ``` /// /// # from_bits_asc /// ``` /// use malachite_base::num::logic::traits::BitConvertible; /// use std::iter::empty; /// /// assert_eq!(u8::from_bits_asc(empty()), 0); /// assert_eq!(u16::from_bits_asc([false, true, false].iter().cloned()), 2); /// assert_eq!( /// u32::from_bits_asc([true, true, false, true, true, true, true].iter().cloned()), /// 123 /// ); /// /// assert_eq!(i8::from_bits_asc(empty()), 0); /// assert_eq!(i16::from_bits_asc([false, true, false].iter().cloned()), 2); /// assert_eq!( /// i32::from_bits_asc( /// [true, false, true, false, false, false, false, true] /// .iter() /// .cloned() /// ), /// -123 /// ); /// ``` /// /// # from_bits_desc /// ``` /// use malachite_base::num::logic::traits::BitConvertible; /// use std::iter::empty; /// /// assert_eq!(u8::from_bits_desc(empty()), 0); /// assert_eq!(u16::from_bits_desc([false, true, false].iter().cloned()), 2); /// assert_eq!( /// u32::from_bits_desc([true, true, true, true, false, true, true].iter().cloned()), /// 123 /// ); /// /// assert_eq!(i8::from_bits_desc(empty()), 0); /// assert_eq!(i16::from_bits_desc([false, true, false].iter().cloned()), 2); /// assert_eq!( /// i32::from_bits_desc( /// [true, false, false, false, false, true, false, true] /// .iter() /// .cloned() /// ), /// -123 /// ); /// ``` pub mod bit_convertible; /// [`BitIterable`](traits::BitIterable), a trait for producing a double-ended iterator over a /// number's bits. /// /// # bits /// ``` /// use itertools::Itertools; /// use malachite_base::num::logic::traits::BitIterable; /// /// assert!(0u8.bits().next().is_none()); /// // 105 = 1101001b /// assert_eq!( /// 105u32.bits().collect_vec(), /// &[true, false, false, true, false, true, true] /// ); /// /// assert!(0u8.bits().next_back().is_none()); /// // 105 = 1101001b /// assert_eq!( /// 105u32.bits().rev().collect_vec(), /// &[true, true, false, true, false, false, true] /// ); /// /// assert_eq!(0i8.bits().next(), None); /// // 105 = 01101001b, with a leading false bit to indicate sign /// assert_eq!( /// 105i32.bits().collect_vec(), /// &[true, false, false, true, false, true, true, false] /// ); /// // -105 = 10010111 in two's complement, with a leading true bit to indicate sign /// assert_eq!( /// (-105i32).bits().collect_vec(), /// &[true, true, true, false, true, false, false, true] /// ); /// /// assert_eq!(0i8.bits().next_back(), None); /// // 105 = 01101001b, with a leading false bit to indicate sign /// assert_eq!( /// 105i32.bits().rev().collect_vec(), /// &[false, true, true, false, true, false, false, true] /// ); /// // -105 = 10010111 in two's complement, with a leading true bit to indicate sign /// assert_eq!( /// (-105i32).bits().rev().collect_vec(), /// &[true, false, false, true, false, true, true, true] /// ); /// ``` pub mod bit_iterable; /// [`BitScan`](traits::BitScan), a trait for finding the next `true` or `false` bit in a number /// after a provided index. /// /// # index_of_next_false_bit /// ``` /// use malachite_base::num::logic::traits::BitScan; /// /// assert_eq!(0xb00000000u64.index_of_next_false_bit(0), Some(0)); /// assert_eq!(0xb00000000u64.index_of_next_false_bit(20), Some(20)); /// assert_eq!(0xb00000000u64.index_of_next_false_bit(31), Some(31)); /// assert_eq!(0xb00000000u64.index_of_next_false_bit(32), Some(34)); /// assert_eq!(0xb00000000u64.index_of_next_false_bit(33), Some(34)); /// assert_eq!(0xb00000000u64.index_of_next_false_bit(34), Some(34)); /// assert_eq!(0xb00000000u64.index_of_next_false_bit(35), Some(36)); /// assert_eq!(0xb00000000u64.index_of_next_false_bit(100), Some(100)); /// /// assert_eq!((-0x500000000i64).index_of_next_false_bit(0), Some(0)); /// assert_eq!((-0x500000000i64).index_of_next_false_bit(20), Some(20)); /// assert_eq!((-0x500000000i64).index_of_next_false_bit(31), Some(31)); /// assert_eq!((-0x500000000i64).index_of_next_false_bit(32), Some(34)); /// assert_eq!((-0x500000000i64).index_of_next_false_bit(33), Some(34)); /// assert_eq!((-0x500000000i64).index_of_next_false_bit(34), Some(34)); /// assert_eq!((-0x500000000i64).index_of_next_false_bit(35), None); /// assert_eq!((-0x500000000i64).index_of_next_false_bit(100), None); /// ``` /// /// # index_of_next_true_bit /// ``` /// use malachite_base::num::logic::traits::BitScan; /// /// assert_eq!(0xb00000000u64.index_of_next_true_bit(0), Some(32)); /// assert_eq!(0xb00000000u64.index_of_next_true_bit(20), Some(32)); /// assert_eq!(0xb00000000u64.index_of_next_true_bit(31), Some(32)); /// assert_eq!(0xb00000000u64.index_of_next_true_bit(32), Some(32)); /// assert_eq!(0xb00000000u64.index_of_next_true_bit(33), Some(33)); /// assert_eq!(0xb00000000u64.index_of_next_true_bit(34), Some(35)); /// assert_eq!(0xb00000000u64.index_of_next_true_bit(35), Some(35)); /// assert_eq!(0xb00000000u64.index_of_next_true_bit(36), None); /// assert_eq!(0xb00000000u64.index_of_next_true_bit(100), None); /// /// assert_eq!((-0x500000000i64).index_of_next_true_bit(0), Some(32)); /// assert_eq!((-0x500000000i64).index_of_next_true_bit(20), Some(32)); /// assert_eq!((-0x500000000i64).index_of_next_true_bit(31), Some(32)); /// assert_eq!((-0x500000000i64).index_of_next_true_bit(32), Some(32)); /// assert_eq!((-0x500000000i64).index_of_next_true_bit(33), Some(33)); /// assert_eq!((-0x500000000i64).index_of_next_true_bit(34), Some(35)); /// assert_eq!((-0x500000000i64).index_of_next_true_bit(35), Some(35)); /// assert_eq!((-0x500000000i64).index_of_next_true_bit(36), Some(36)); /// assert_eq!((-0x500000000i64).index_of_next_true_bit(100), Some(100)); /// ``` pub mod bit_scan; /// [`CountOnes`](traits::CountOnes), a trait for counting the number of ones in the binary /// representation of a number. pub mod count_ones; /// [`CountZeros`](traits::CountZeros), a trait for counting the number of ones in the binary /// representation of a number. pub mod count_zeros; /// [`HammingDistance`](traits::HammingDistance) and /// [`CheckedHammingDistance`](traits::CheckedHammingDistance), traits for computing the Hamming /// distance between two numbers. /// /// # hamming_distance /// ``` /// use malachite_base::num::logic::traits::HammingDistance; /// /// assert_eq!(123u32.hamming_distance(456), 6); /// assert_eq!(0u8.hamming_distance(255), 8); /// ``` /// /// # checked_hamming_distance /// ``` /// use malachite_base::num::logic::traits::CheckedHammingDistance; /// /// assert_eq!(123i32.checked_hamming_distance(456), Some(6)); /// assert_eq!(0i8.checked_hamming_distance(127), Some(7)); /// assert_eq!(0i8.checked_hamming_distance(-1), None); /// ``` pub mod hamming_distance; /// [`LeadingZeros`](traits::LeadingZeros), a trait for determining the number of zeros that a /// number starts with, when written in binary using $W$ bits, $W$ being the type width. pub mod leading_zeros; /// [`LowMask`](traits::LowMask), a trait for generating a low bit mask (a number in which only the /// $k$ least-significant bits are 1). /// /// # low_mask /// ``` /// use malachite_base::num::logic::traits::LowMask; /// /// assert_eq!(u16::low_mask(0), 0); /// assert_eq!(u8::low_mask(3), 0x7); /// assert_eq!(u8::low_mask(8), 0xff); /// assert_eq!(u64::low_mask(40), 0xffffffffff); /// /// assert_eq!(i16::low_mask(0), 0); /// assert_eq!(i8::low_mask(3), 0x7); /// assert_eq!(i8::low_mask(8), -1); /// assert_eq!(i64::low_mask(40), 0xffffffffff); /// ``` pub mod low_mask; /// [`NotAssign`](traits::NotAssign), a trait for replacing a number with its bitwise negation. /// /// # not_assign /// ``` /// use malachite_base::num::logic::traits::NotAssign; /// /// let mut x = 123u16; /// x.not_assign(); /// assert_eq!(x, 65412); /// ``` pub mod not; /// [`SignificantBits`](traits::SignificantBits), a trait for determining how many significant bits /// a number has. /// /// # significant_bits /// ``` /// use malachite_base::num::logic::traits::SignificantBits; /// /// assert_eq!(0u8.significant_bits(), 0); /// assert_eq!(100u64.significant_bits(), 7); /// /// assert_eq!(0i8.significant_bits(), 0); /// assert_eq!((-100i64).significant_bits(), 7); /// ``` pub mod significant_bits; /// [`TrailingZeros`](traits::TrailingZeros), a trait for determining the number of zeros that a /// number ends with when written in binary. pub mod trailing_zeros; /// Various traits for performing logic or bitwise operations on numbers. pub mod traits; malachite-base-0.4.16/src/num/logic/not.rs000064400000000000000000000016311046102023000164050ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::logic::traits::NotAssign; macro_rules! impl_not { ($t:ident) => { impl NotAssign for $t { /// Replaces a number with its bitwise negation. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::not#not_assign). #[inline] fn not_assign(&mut self) { *self = !*self; } } }; } apply_to_primitive_ints!(impl_not); malachite-base-0.4.16/src/num/logic/significant_bits.rs000064400000000000000000000053201046102023000211230ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::UnsignedAbs; use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::logic::traits::{LeadingZeros, SignificantBits}; fn significant_bits_unsigned(x: T) -> u64 { T::WIDTH - LeadingZeros::leading_zeros(x) } macro_rules! impl_significant_bits_unsigned { ($t:ident) => { impl SignificantBits for $t { /// Returns the number of significant bits of an unsigned primitive integer. /// /// This is the integer's width minus the number of leading zeros. /// /// $$ /// f(n) = \\begin{cases} /// 0 & \text{if} \\quad n = 0, \\\\ /// \lfloor \log_2 n \rfloor + 1 & \text{if} \\quad n > 0. /// \\end{cases} /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::significant_bits#significant_bits). #[inline] fn significant_bits(self) -> u64 { significant_bits_unsigned(self) } } }; } apply_to_unsigneds!(impl_significant_bits_unsigned); fn significant_bits_signed>( x: S, ) -> u64 { x.unsigned_abs().significant_bits() } macro_rules! impl_significant_bits_signed { ($u:ident, $s:ident) => { /// Returns the number of significant bits of a signed primitive integer. /// /// This is the integer's width minus the number of leading zeros of its absolute value. /// /// $$ /// f(n) = \\begin{cases} /// 0 & \text{if} \\quad n = 0, \\\\ /// \lfloor \log_2 |n| \rfloor + 1 & \text{if} \\quad n \neq 0. /// \\end{cases} /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](super::significant_bits#significant_bits). impl SignificantBits for $s { #[inline] fn significant_bits(self) -> u64 { significant_bits_signed(self) } } }; } apply_to_unsigned_signed_pairs!(impl_significant_bits_signed); malachite-base-0.4.16/src/num/logic/trailing_zeros.rs000064400000000000000000000015451046102023000206440ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::logic::traits::TrailingZeros; macro_rules! impl_trailing_zeros { ($t:ident) => { impl TrailingZeros for $t { /// This is a wrapper over the `trailing_zeros` functions in the standard library, for /// example [this one](u32::trailing_zeros). #[inline] fn trailing_zeros(self) -> u64 { u64::from($t::trailing_zeros(self)) } } }; } apply_to_primitive_ints!(impl_trailing_zeros); malachite-base-0.4.16/src/num/logic/traits.rs000064400000000000000000000160551046102023000171210ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use alloc::vec::Vec; use core::ops::Index; /// Defines functions that access or modify individual bits in a number. pub trait BitAccess { /// Determines whether a number has a `true` or `false` bit at `index`. fn get_bit(&self, index: u64) -> bool; /// Sets the bit at `index` to `true`. fn set_bit(&mut self, index: u64); /// Sets the bit at `index` to `false`. fn clear_bit(&mut self, index: u64); /// Sets the bit at `index` to whichever value `bit` is. /// /// # Worst-case complexity /// $T(n) = O(\max(T_S(n), T_C(n)))$, /// /// $M(n) = O(\max(M_S(n), M_C(n)))$ /// /// where $T$ is time, $M$ is additional memory, $T_S$ and $M_S$ are the complexities of /// [`set_bit`](Self::set_bit), and $T_C$ and $M_C$ are the complexities of /// [`clear_bit`](Self::clear_bit). /// /// # Panics /// See panics for [`set_bit`](Self::set_bit) and [`clear_bit`](Self::clear_bit). #[inline] fn assign_bit(&mut self, index: u64, bit: bool) { if bit { self.set_bit(index); } else { self.clear_bit(index); } } /// Sets the bit at `index` to the opposite of its original value. /// /// # Worst-case complexity /// $T(n) = O(T_G(n) + \max(T_S(n), T_C(n)))$, /// /// $M(n) = O(M_G(n) + \max(M_S(n), M_C(n)))$ /// /// where $T$ is time, $M$ is additional memory, $T_G$ and $M_G$ are the complexities of /// [`get_bit`](Self::get_bit), $T_S$ and $M_S$ are the complexities of /// [`set_bit`](Self::set_bit), and $T_C$ and $M_C$ are the complexities of /// [`clear_bit`](Self::clear_bit). /// /// # Panics /// See panics for [`get_bit`](Self::get_bit), [`set_bit`](Self::set_bit) and /// [`clear_bit`](Self::clear_bit). #[inline] fn flip_bit(&mut self, index: u64) { if self.get_bit(index) { self.clear_bit(index); } else { self.set_bit(index); } } } /// Defines functions that access or modify blocks of adjacent bits in a number. pub trait BitBlockAccess: Sized { type Bits; /// Extracts a block of bits whose first index is `start` and last index is `end - 1`. fn get_bits(&self, start: u64, end: u64) -> Self::Bits; /// Extracts a block of bits whose first index is `start` and last index is `end - 1`, taking /// ownership of `self`. /// /// # Worst-case complexity /// For the default implementation, same as [`get_bits`](Self::get_bits). /// /// # Panics /// For the default implementation, ee panics for [`get_bits`](Self::get_bits). /// /// # Examples /// ``` /// use malachite_base::num::logic::traits::BitBlockAccess; /// /// assert_eq!((-0x5433i16).get_bits_owned(4, 8), 0xc); /// assert_eq!((-0x5433i16).get_bits_owned(5, 9), 14); /// assert_eq!((-0x5433i16).get_bits_owned(5, 5), 0); /// assert_eq!((-0x5433i16).get_bits_owned(100, 104), 0xf); /// ``` #[inline] fn get_bits_owned(self, start: u64, end: u64) -> Self::Bits { self.get_bits(start, end) } /// Assigns the least-significant `end - start` bits of `bits` to bits `start` through `end - 1` /// (inclusive) of `self`. fn assign_bits(&mut self, start: u64, end: u64, bits: &Self::Bits); } /// Defines functions that express a number as a [`Vec`] of bits or construct a number from an /// iterator of bits. pub trait BitConvertible { /// Returns a [`Vec`] containing the bits of a number in ascending order: least- to /// most-significant. fn to_bits_asc(&self) -> Vec; /// Returns a [`Vec`] containing the bits of a number in descending order: most- to /// least-significant. fn to_bits_desc(&self) -> Vec; /// Converts an iterator of bits into a number. The input bits are in ascending order: least- to /// most-significant. fn from_bits_asc>(bits: I) -> Self; /// Converts an iterator of bits into a value. The input bits are in descending order: most- to /// least-significant. fn from_bits_desc>(bits: I) -> Self; } /// Defines an iterator over a value's bits. pub trait BitIterable { type BitIterator: DoubleEndedIterator + Index; /// Returns a double-ended iterator over a number's bits. When iterating in the forward /// direction, the iterator ends after the producing the number's most-significant bit. fn bits(self) -> Self::BitIterator; } /// Defines functions that search for the next `true` or `false` bit in a number, starting at a /// specified index and searching in the more-significant direction. pub trait BitScan { /// Given a number and a starting index, searches the number for the smallest index of a `false` /// bit that is greater than or equal to the starting index. fn index_of_next_false_bit(self, start: u64) -> Option; /// Given a number and a starting index, searches the number for the smallest index of a `true` /// bit that is greater than or equal to the starting index. fn index_of_next_true_bit(self, start: u64) -> Option; } /// Returns the number of ones in the binary representation of a number. pub trait CountOnes { fn count_ones(self) -> u64; } /// Returns the number of zeros in the binary representation of a number. pub trait CountZeros { fn count_zeros(self) -> u64; } /// Returns the Hamming distance between two numbers, or the number of bit flips needed to turn one /// into the other. pub trait HammingDistance { fn hamming_distance(self, other: RHS) -> u64; } /// Returns the Hamming distance between two numbers, or the number of bit flips needed to turn one /// into the other. /// /// This trait allows for the possibility of the distance being undefined for some pairs of numbers, /// in which case [`checked_hamming_distance`](Self::checked_hamming_distance) should return `None`. pub trait CheckedHammingDistance { fn checked_hamming_distance(self, other: RHS) -> Option; } /// Returns the number of leading zeros in the binary representation of a number. pub trait LeadingZeros { fn leading_zeros(self) -> u64; } /// Returns a number whose least significant $b$ bits are `true` and whose other bits are `false`. pub trait LowMask { fn low_mask(bits: u64) -> Self; } /// Replaces a number with its bitwise negation. pub trait NotAssign { fn not_assign(&mut self); } // Returns the number of significant bits of a number. pub trait SignificantBits { /// The number of bits it takes to represent `self`. fn significant_bits(self) -> u64; } /// Returns the number of trailing zeros in the binary representation of a number. pub trait TrailingZeros { fn trailing_zeros(self) -> u64; } malachite-base-0.4.16/src/num/macros.rs000064400000000000000000000262741046102023000160060ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . #[doc(hidden)] #[macro_export] macro_rules! apply_to_unsigneds { ($m: tt) => { $m!(u8); $m!(u16); $m!(u32); $m!(u64); $m!(u128); $m!(usize); }; } #[doc(hidden)] #[macro_export] macro_rules! apply_to_signeds { ($m: tt) => { $m!(i8); $m!(i16); $m!(i32); $m!(i64); $m!(i128); $m!(isize); }; } #[doc(hidden)] #[macro_export] macro_rules! apply_to_primitive_ints { ($m: tt) => { apply_to_unsigneds!($m); apply_to_signeds!($m); }; } #[doc(hidden)] #[macro_export] macro_rules! apply_to_unsigned_signed_pairs { ($m: tt) => { $m!(u8, i8); $m!(u16, i16); $m!(u32, i32); $m!(u64, i64); $m!(u128, i128); $m!(usize, isize); }; } #[doc(hidden)] #[macro_export] macro_rules! apply_fn_to_unsigneds { ($f: ident) => { $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); }; } #[doc(hidden)] #[macro_export] macro_rules! apply_fn_to_signeds { ($f: ident) => { $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); }; } #[doc(hidden)] #[macro_export] macro_rules! apply_fn_to_primitive_ints { ($f: ident) => { apply_fn_to_unsigneds!($f); apply_fn_to_signeds!($f); }; } #[doc(hidden)] #[macro_export] macro_rules! apply_fn_to_unsigned_signed_pairs { ($f: ident) => { $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); }; } #[doc(hidden)] #[macro_export] macro_rules! apply_fn_to_unsigneds_and_unsigneds { ($f: ident) => { $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); }; } #[doc(hidden)] #[macro_export] macro_rules! apply_fn_to_unsigneds_and_signeds { ($f: ident) => { $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); }; } #[doc(hidden)] #[macro_export] macro_rules! apply_fn_to_unsigneds_and_primitive_ints { ($f: ident) => { apply_fn_to_unsigneds_and_unsigneds!($f); apply_fn_to_unsigneds_and_signeds!($f); }; } #[doc(hidden)] #[macro_export] macro_rules! apply_fn_to_unsigneds_and_unsigned_signed_pairs { ($f: ident) => { $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); }; } #[doc(hidden)] #[macro_export] macro_rules! apply_fn_to_unsigneds_and_primitive_floats { ($f: ident) => { $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); }; } #[doc(hidden)] #[macro_export] macro_rules! apply_fn_to_signeds_and_primitive_floats { ($f: ident) => { $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); }; } #[doc(hidden)] #[macro_export] macro_rules! apply_fn_to_primitive_ints_and_primitive_floats { ($f: ident) => { apply_fn_to_unsigneds_and_primitive_floats!($f); apply_fn_to_signeds_and_primitive_floats!($f); }; } #[doc(hidden)] #[macro_export] macro_rules! apply_fn_to_primitive_floats_and_unsigneds { ($f: ident) => { $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); }; } #[doc(hidden)] #[macro_export] macro_rules! apply_fn_to_primitive_floats_and_signeds { ($f: ident) => { $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); }; } #[doc(hidden)] #[macro_export] macro_rules! apply_fn_to_primitive_floats_and_unsigned_signed_pairs { ($f: ident) => { $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); }; } #[doc(hidden)] #[macro_export] macro_rules! apply_fn_to_signeds_and_unsigneds { ($f: ident) => { $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); }; } #[doc(hidden)] #[macro_export] macro_rules! apply_fn_to_signeds_and_signeds { ($f: ident) => { $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); $f::(); }; } #[doc(hidden)] #[macro_export] macro_rules! apply_fn_to_primitive_ints_and_unsigneds { ($f: ident) => { apply_fn_to_unsigneds_and_unsigneds!($f); apply_fn_to_signeds_and_unsigneds!($f); }; } #[doc(hidden)] #[macro_export] macro_rules! apply_fn_to_primitive_ints_and_signeds { ($f: ident) => { apply_fn_to_unsigneds_and_signeds!($f); apply_fn_to_signeds_and_signeds!($f); }; } #[doc(hidden)] #[macro_export] macro_rules! apply_fn_to_primitive_ints_and_primitive_ints { ($f: ident) => { apply_fn_to_primitive_ints_and_unsigneds!($f); apply_fn_to_primitive_ints_and_signeds!($f); }; } #[doc(hidden)] #[macro_export] macro_rules! apply_to_primitive_floats { ($m: tt) => { $m!(f32); $m!(f64); }; } #[doc(hidden)] #[macro_export] macro_rules! apply_to_primitive_float_unsigned_pairs { ($m: tt) => { $m!(f32, u32); $m!(f64, u64); }; } #[doc(hidden)] #[macro_export] macro_rules! apply_fn_to_primitive_floats { ($f: ident) => { $f::(); $f::(); }; } malachite-base-0.4.16/src/num/mod.rs000064400000000000000000000023501046102023000152660ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . #[doc(hidden)] #[macro_use] pub mod macros; /// Traits for arithmetic. pub mod arithmetic; /// Traits for primitive integers or floats and some of their basic functionality. pub mod basic; /// Traits for comparing the absolute values of numbers for equality or order. pub mod comparison; /// Traits for converting to and from numbers, converting to and from strings, and extracting /// digits. pub mod conversion; /// Iterators that generate numbers without repetition. pub mod exhaustive; /// Traits for generating primes, primality testing, and factorization (TODO!) pub mod factorization; /// [`NiceFloat`](float::NiceFloat), a wrapper around primitive floats. pub mod float; /// Iterators related to numbers. pub mod iterators; /// Traits for logic and bit manipulation. pub mod logic; #[cfg(feature = "random")] /// Iterators that generate numbers randomly. pub mod random; malachite-base-0.4.16/src/num/random/geometric.rs000064400000000000000000001502371046102023000177550ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::bools::random::{ get_weighted_random_bool, random_bools, weighted_random_bools, RandomBools, WeightedRandomBools, }; use crate::num::arithmetic::traits::Gcd; use crate::num::basic::integers::PrimitiveInt; use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::ExactInto; use crate::random::Seed; use std::fmt::Debug; use super::VariableRangeGenerator; #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub(crate) struct SimpleRational { pub(crate) n: u64, pub(crate) d: u64, } impl SimpleRational { pub(crate) fn new(n: u64, d: u64) -> SimpleRational { assert_ne!(d, 0); let gcd = n.gcd(d); SimpleRational { n: n / gcd, d: d / gcd, } } fn inverse(self) -> SimpleRational { assert_ne!(self.n, 0); SimpleRational { n: self.d, d: self.n, } } // unwrap not const yet #[allow(clippy::missing_const_for_fn)] fn sub_u64(self, x: u64) -> SimpleRational { SimpleRational { n: self.n.checked_sub(x.checked_mul(self.d).unwrap()).unwrap(), d: self.d, } } } pub(crate) fn mean_to_p_with_min( min: T, um_numerator: u64, um_denominator: u64, ) -> (u64, u64) { let um = SimpleRational::new(um_numerator, um_denominator); let p = um.sub_u64(ExactInto::::exact_into(min)).inverse(); (p.n, p.d) } /// Generates random unsigned integers from a truncated geometric distribution. #[derive(Clone, Debug)] pub struct GeometricRandomNaturalValues { xs: WeightedRandomBools, min: T, max: T, } impl Iterator for GeometricRandomNaturalValues { type Item = T; fn next(&mut self) -> Option { let mut failures = self.min; loop { if self.xs.next().unwrap() { return Some(failures); } // Wrapping to min is equivalent to restarting this function. if failures == self.max { failures = self.min; } else { failures += T::ONE; } } } } fn geometric_random_natural_values_inclusive_range( seed: Seed, min: T, max: T, um_numerator: u64, um_denominator: u64, ) -> GeometricRandomNaturalValues { assert!(min <= max); assert_ne!(um_denominator, 0); let (numerator, denominator) = mean_to_p_with_min(min, um_numerator, um_denominator); GeometricRandomNaturalValues { xs: weighted_random_bools(seed, numerator, numerator.checked_add(denominator).unwrap()), min, max, } } fn get_geometric_random_natural_value_from_inclusive_range( range_generator: &mut VariableRangeGenerator, min: T, max: T, um_numerator: u64, um_denominator: u64, ) -> T { assert!(min <= max); assert_ne!(um_denominator, 0); let (n, denominator) = mean_to_p_with_min(min, um_numerator, um_denominator); let d = n.checked_add(denominator).unwrap(); let mut failures = min; loop { if get_weighted_random_bool(range_generator, n, d) { return failures; } // Wrapping to min is equivalent to restarting this function. if failures == max { failures = min; } else { failures += T::ONE; } } } /// Generates random negative signed integers from a modified geometric distribution. #[derive(Clone, Debug)] pub struct GeometricRandomNegativeSigneds { xs: WeightedRandomBools, abs_min: T, abs_max: T, } impl Iterator for GeometricRandomNegativeSigneds { type Item = T; fn next(&mut self) -> Option { let mut result = self.abs_min; loop { if self.xs.next().unwrap() { return Some(result); } // Wrapping to min is equivalent to restarting this function. if result == self.abs_max { result = self.abs_min; } else { result -= T::ONE; } } } } fn geometric_random_negative_signeds_inclusive_range( seed: Seed, abs_min: T, abs_max: T, abs_um_numerator: u64, abs_um_denominator: u64, ) -> GeometricRandomNegativeSigneds { assert!(abs_min >= abs_max); assert_ne!(abs_um_denominator, 0); let (numerator, denominator) = mean_to_p_with_min( abs_min.checked_neg().unwrap(), abs_um_numerator, abs_um_denominator, ); GeometricRandomNegativeSigneds { xs: weighted_random_bools(seed, numerator, numerator.checked_add(denominator).unwrap()), abs_min, abs_max, } } fn get_geometric_random_negative_signed_from_inclusive_range( range_generator: &mut VariableRangeGenerator, abs_min: T, abs_max: T, abs_um_numerator: u64, abs_um_denominator: u64, ) -> T { assert!(abs_min >= abs_max); assert_ne!(abs_um_denominator, 0); let (n, denominator) = mean_to_p_with_min( abs_min.checked_neg().unwrap(), abs_um_numerator, abs_um_denominator, ); let d = n.checked_add(denominator).unwrap(); let mut result = abs_min; loop { if get_weighted_random_bool(range_generator, n, d) { return result; } // Wrapping to min is equivalent to restarting this function. if result == abs_max { result = abs_min; } else { result -= T::ONE; } } } /// Generates random nonzero signed integers from a modified geometric distribution. #[derive(Clone, Debug)] pub struct GeometricRandomNonzeroSigneds { bs: RandomBools, xs: WeightedRandomBools, min: T, max: T, } impl Iterator for GeometricRandomNonzeroSigneds { type Item = T; fn next(&mut self) -> Option { loop { if self.bs.next().unwrap() { let mut result = T::ONE; loop { if self.xs.next().unwrap() { return Some(result); } else if result == self.max { break; } result += T::ONE; } } else { let mut result = T::NEGATIVE_ONE; loop { if self.xs.next().unwrap() { return Some(result); } else if result == self.min { break; } result -= T::ONE; } } } } } fn geometric_random_nonzero_signeds_inclusive_range( seed: Seed, min: T, max: T, abs_um_numerator: u64, abs_um_denominator: u64, ) -> GeometricRandomNonzeroSigneds { assert!(min <= max); assert_ne!(abs_um_denominator, 0); let (numerator, denominator) = mean_to_p_with_min(T::ONE, abs_um_numerator, abs_um_denominator); GeometricRandomNonzeroSigneds { bs: random_bools(seed.fork("bs")), xs: weighted_random_bools( seed.fork("xs"), numerator, numerator.checked_add(denominator).unwrap(), ), min, max, } } /// Generates random signed integers from a modified geometric distribution. #[derive(Clone, Debug)] pub struct GeometricRandomSigneds { bs: RandomBools, xs: WeightedRandomBools, min: T, max: T, } impl Iterator for GeometricRandomSigneds { type Item = T; fn next(&mut self) -> Option { loop { let mut result = T::ZERO; if self.bs.next().unwrap() { loop { if self.xs.next().unwrap() { if result == T::ZERO && self.bs.next().unwrap() { break; } return Some(result); } else if result == self.max { break; } result += T::ONE; } } else { loop { if self.xs.next().unwrap() { if result == T::ZERO && self.bs.next().unwrap() { break; } return Some(result); } else if result == self.min { break; } result -= T::ONE; } } } } } fn geometric_random_signed_inclusive_range_helper( seed: Seed, min: T, max: T, abs_um_numerator: u64, abs_um_denominator: u64, ) -> GeometricRandomSigneds { assert!(min <= max); assert_ne!(abs_um_denominator, 0); let (numerator, denominator) = mean_to_p_with_min(T::ZERO, abs_um_numerator, abs_um_denominator); GeometricRandomSigneds { bs: random_bools(seed.fork("bs")), xs: weighted_random_bools( seed.fork("xs"), numerator, numerator.checked_add(denominator).unwrap(), ), min, max, } } fn get_geometric_random_signed_from_inclusive_range_helper( range_generator: &mut VariableRangeGenerator, min: T, max: T, abs_um_numerator: u64, abs_um_denominator: u64, ) -> T { assert!(min <= max); assert_ne!(abs_um_denominator, 0); let (n, denominator) = mean_to_p_with_min(T::ZERO, abs_um_numerator, abs_um_denominator); let d = n.checked_add(denominator).unwrap(); loop { let mut result = T::ZERO; if range_generator.next_bool() { loop { if get_weighted_random_bool(range_generator, n, d) { if result == T::ZERO && range_generator.next_bool() { break; } return result; } else if result == max { break; } result += T::ONE; } } else { loop { if get_weighted_random_bool(range_generator, n, d) { if result == T::ZERO && range_generator.next_bool() { break; } return result; } else if result == min { break; } result -= T::ONE; } } } } /// Generates random negative signed integers in a range from a modified geometric distribution. #[allow(clippy::large_enum_variant)] #[derive(Clone, Debug)] pub enum GeometricRandomSignedRange { NonNegative(GeometricRandomNaturalValues), NonPositive(GeometricRandomNegativeSigneds), BothSigns(GeometricRandomSigneds), } impl Iterator for GeometricRandomSignedRange { type Item = T; fn next(&mut self) -> Option { match self { GeometricRandomSignedRange::NonNegative(ref mut xs) => xs.next(), GeometricRandomSignedRange::NonPositive(ref mut xs) => xs.next(), GeometricRandomSignedRange::BothSigns(ref mut xs) => xs.next(), } } } /// Generates random unsigned integers from a truncated geometric distribution. /// /// With this distribution, the probability of a value being generated decreases as the value /// increases. The probabilities $P(0), P(1), P(2), \ldots$ decrease in a geometric sequence; that's /// where the "geometric" comes from. Unlike a true geometric distribution, this distribution is /// truncated, meaning that values above `T::MAX` are never generated. /// /// The probabilities can drop more quickly or more slowly depending on a parameter $m_u$, called /// the unadjusted mean. It is equal to `um_numerator / um_denominator`. The unadjusted mean is what /// the mean generated value would be if the distribution were not truncated. If $m_u$ is /// significantly lower than `T::MAX`, which is usually the case, then it is very close to the /// actual mean. The higher $m_u$ is, the more gently the probabilities drop; the lower it is, the /// more quickly they drop. $m_u$ must be greater than zero. It may be arbitrarily high, but note /// that the iteration time increases linearly with `um_numerator + um_denominator`. /// /// Here is a more precise characterization of this distribution. Let its support $S \subset \Z$ /// equal $[0, 2^W)$, where $W$ is the width of the type. Then we have /// $$ /// P(n) \neq 0 \leftrightarrow n \in S, /// $$ /// and whenever $n, n + 1 \in S$, /// $$ /// \frac{P(n)}{P(n+1)} = \frac{m_u + 1}{m_u}. /// $$ /// /// The output length is infinite. /// /// # Expected complexity per iteration /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ = `um_numerator + um_denominator`. /// /// # Panics /// Panics if `um_numerator` or `um_denominator` are zero, or, if after being reduced to lowest /// terms, their sum is greater than or equal to $2^{64}$. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::geometric::geometric_random_unsigneds; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string(geometric_random_unsigneds::(EXAMPLE_SEED, 1, 1), 10), /// "[1, 0, 0, 3, 4, 4, 1, 0, 0, 1, ...]" /// ) /// ``` /// /// # Further details /// Geometric distributions are more typically parametrized by a parameter $p$. The relationship /// between $p$ and $m_u$ is $m_u = \frac{1}{p} - 1$, or $p = \frac{1}{m_u + 1}$. /// /// The probability mass function of this distribution is /// $$ /// P(n) = \\begin{cases} /// \frac{(1-p)^np}{1-(1-p)^{2^W}} & \text{if} \\quad 0 \\leq n < 2^W, \\\\ /// 0 & \\text{otherwise}, /// \\end{cases} /// $$ /// where $W$ is the width of the type. /// /// It's also useful to note that /// $$ /// \lim_{W \to \infty} P(n) = (1-p)^np. /// $$ pub fn geometric_random_unsigneds( seed: Seed, um_numerator: u64, um_denominator: u64, ) -> GeometricRandomNaturalValues { assert_ne!(um_numerator, 0); geometric_random_natural_values_inclusive_range( seed, T::ZERO, T::MAX, um_numerator, um_denominator, ) } /// Generates random positive unsigned integers from a truncated geometric distribution. /// /// With this distribution, the probability of a value being generated decreases as the value /// increases. The probabilities $P(1), P(2), P(3), \ldots$ decrease in a geometric sequence; that's /// where the "geometric" comes from. Unlike a true geometric distribution, this distribution is /// truncated, meaning that values above `T::MAX` are never generated. /// /// The probabilities can drop more quickly or more slowly depending on a parameter $m_u$, called /// the unadjusted mean. It is equal to `um_numerator / um_denominator`. The unadjusted mean is what /// the mean generated value would be if the distribution were not truncated. If $m_u$ is /// significantly lower than `T::MAX`, which is usually the case, then it is very close to the /// actual mean. The higher $m_u$ is, the more gently the probabilities drop; the lower it is, the /// more quickly they drop. $m_u$ must be greater than one. It may be arbitrarily high, but note /// that the iteration time increases linearly with `um_numerator + um_denominator`. /// /// Here is a more precise characterization of this distribution. Let its support $S \subset \Z$ /// equal $[1, 2^W)$, where $W$ is the width of the type. Then we have /// $$ /// P(n) \neq 0 \leftrightarrow n \in S /// $$ /// and whenever $n, n + 1 \in S$, /// $$ /// \frac{P(n)}{P(n+1)} = \frac{m_u}{m_u - 1}. /// $$ /// /// The output length is infinite. /// /// # Expected complexity per iteration /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ = `um_numerator + um_denominator`. /// /// # Panics /// Panics if `um_denominator` is zero or if `um_numerator <= um_denominator`. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::geometric::geometric_random_positive_unsigneds; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string( /// geometric_random_positive_unsigneds::(EXAMPLE_SEED, 2, 1), /// 10 /// ), /// "[2, 1, 1, 4, 5, 5, 2, 1, 1, 2, ...]" /// ) /// ``` /// /// # Further details /// Geometric distributions are more typically parametrized by a parameter $p$. The relationship /// between $p$ and $m_u$ is $m_u = \frac{1}{p}$, or $p = \frac{1}{m_u}$. /// /// The probability mass function of this distribution is /// $$ /// P(n) = \\begin{cases} /// \frac{(1-p)^{n-1}p}{1-(1-p)^{2^W-1}} & \text{if} \\quad 0 < n < 2^W, \\\\ /// 0 & \\text{otherwise}, /// \\end{cases} /// $$ /// where $W$ is the width of the type. /// /// It's also useful to note that /// $$ /// \lim_{W \to \infty} P(n) = (1-p)^{n-1}p. /// $$ pub fn geometric_random_positive_unsigneds( seed: Seed, um_numerator: u64, um_denominator: u64, ) -> GeometricRandomNaturalValues { assert!(um_numerator > um_denominator); geometric_random_natural_values_inclusive_range( seed, T::ONE, T::MAX, um_numerator, um_denominator, ) } /// Generates random signed integers from a modified geometric distribution. /// /// This distribution can be derived from a truncated geometric distribution by mirroring it, /// producing a truncated double geometric distribution. Zero is included. /// /// With this distribution, the probability of a value being generated decreases as its absolute /// value increases. The probabilities $P(0), P(\pm 1), P(\pm 2), \ldots$ decrease in a geometric /// sequence; that's where the "geometric" comes from. Values below `T::MIN` or above `T::MAX` are /// never generated. /// /// The probabilities can drop more quickly or more slowly depending on a parameter $m_u$, called /// the unadjusted mean. It is equal to `abs_um_numerator / abs_um_denominator`. The unadjusted mean /// is what the mean generated value would be if the distribution were not truncated, and were /// restricted to non-negative values. If $m_u$ is significantly lower than `T::MAX`, which is /// usually the case, then it is very close to the actual mean of the distribution restricted to /// positive values. The higher $m_u$ is, the more gently the probabilities drop; the lower it is, /// the more quickly they drop. $m_u$ must be greater than zero. It may be arbitrarily high, but /// note that the iteration time increases linearly with `abs_um_numerator + abs_um_denominator`. /// /// Here is a more precise characterization of this distribution. Let its support $S \subset \Z$ /// equal $[-2^{W-1}, 2^{W-1})$, where $W$ is the width of the type. Then we have /// $$ /// P(n) \neq 0 \leftrightarrow n \in S /// $$ /// Whenever $n \geq 0$ and $n, n + 1 \in S$, /// $$ /// \frac{P(n)}{P(n+1)} = \frac{m_u}{m_u - 1}, /// $$ /// and whenever $n \leq 0$ and $n, n - 1 \in S$, /// $$ /// \frac{P(n)}{P(n-1)} = \frac{m_u}{m_u - 1}. /// $$ /// /// As a corollary, $P(n) = P(-n)$ whenever $n, -n \in S$. /// /// The output length is infinite. /// /// # Expected complexity per iteration /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ = `abs_um_numerator + abs_um_denominator`. /// /// # Panics /// Panics if `abs_um_numerator` or `abs_um_denominator` are zero, or, if after being reduced to /// lowest terms, their sum is greater than or equal to $2^{64}$. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::geometric::geometric_random_signeds; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string(geometric_random_signeds::(EXAMPLE_SEED, 1, 1), 10), /// "[-1, -1, -1, 1, -2, 1, 0, 0, 0, 0, ...]" /// ) /// ``` /// /// Geometric distributions are more typically parametrized by a parameter $p$. The relationship /// between $p$ and $m_u$ is $m_u = \frac{1}{p} - 1$, or $p = \frac{1}{m_u + 1}$. /// /// The probability mass function of this distribution is /// $$ /// P(n) = \\begin{cases} /// \frac{(1-p)^{|n|}p}{((1-p)^{2^{W-1}}-1)(p-2)} & /// \text{if} \\quad -2^{W-1} \leq n < 2^{W-1}, \\\\ /// 0 & \\text{otherwise}, /// \\end{cases} /// $$ /// where $W$ is the width of the type. /// /// It's also useful to note that /// $$ /// \lim_{W \to \infty} P(n) = \frac{(1-p)^{|n|}p}{2-p}. /// $$ pub fn geometric_random_signeds( seed: Seed, abs_um_numerator: u64, abs_um_denominator: u64, ) -> GeometricRandomSigneds { assert_ne!(abs_um_numerator, 0); geometric_random_signed_inclusive_range_helper( seed, T::MIN, T::MAX, abs_um_numerator, abs_um_denominator, ) } /// Generates random natural (non-negative) signed integers from a truncated geometric distribution. /// /// With this distribution, the probability of a value being generated decreases as the value /// increases. The probabilities $P(0), P(1), P(2), \ldots$ decrease in a geometric sequence; that's /// where the "geometric" comes from. Unlike a true geometric distribution, this distribution is /// truncated, meaning that values above `T::MAX` are never generated. /// /// The probabilities can drop more quickly or more slowly depending on a parameter $m_u$, called /// the unadjusted mean. It is equal to `um_numerator / um_denominator`. The unadjusted mean is what /// the mean generated value would be if the distribution were not truncated. If $m_u$ is /// significantly lower than `T::MAX`, which is usually the case, then it is very close to the /// actual mean. The higher $m_u$ is, the more gently the probabilities drop; the lower it is, the /// more quickly they drop. $m_u$ must be greater than zero. It may be arbitrarily high, but note /// that the iteration time increases linearly with `um_numerator + um_denominator`. /// /// Here is a more precise characterization of this distribution. Let its support $S \subset \Z$ /// equal $[0, 2^{W-1})$, where $W$ is the width of the type. Then we have /// $$ /// P(n) \neq 0 \leftrightarrow n \in S /// $$ /// and whenever $n, n + 1 \in S$, /// $$ /// \frac{P(n)}{P(n+1)} = \frac{m_u + 1}{m_u}. /// $$ /// /// The output length is infinite. /// /// # Expected complexity per iteration /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ = `um_numerator + um_denominator`. /// /// # Panics /// Panics if `um_numerator` or `um_denominator` are zero, or, if after being reduced to lowest /// terms, their sum is greater than or equal to $2^{64}$. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::geometric::geometric_random_natural_signeds; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string( /// geometric_random_natural_signeds::(EXAMPLE_SEED, 1, 1), /// 10 /// ), /// "[1, 0, 0, 3, 4, 4, 1, 0, 0, 1, ...]" /// ) /// ``` /// /// # Further details /// Geometric distributions are more typically parametrized by a parameter $p$. The relationship /// between $p$ and $m_u$ is $m_u = \frac{1}{p} - 1$, or $p = \frac{1}{m_u + 1}$. /// /// The probability mass function of this distribution is /// $$ /// P(n) = \\begin{cases} /// \frac{(1-p)^np}{1-(1-p)^{2^{W-1}}} & \text{if} \\quad 0 \\leq n < 2^{W-1}, \\\\ /// 0 & \\text{otherwise}, /// \\end{cases} /// $$ /// where $W$ is the width of the type. /// /// It's also useful to note that /// $$ /// \lim_{W \to \infty} P(n) = \\begin{cases} /// (1-p)^np & \text{if} \\quad n \geq 0, \\\\ /// 0 & \\text{otherwise}. /// \\end{cases} /// $$ pub fn geometric_random_natural_signeds( seed: Seed, um_numerator: u64, um_denominator: u64, ) -> GeometricRandomNaturalValues { assert_ne!(um_numerator, 0); geometric_random_natural_values_inclusive_range( seed, T::ZERO, T::MAX, um_numerator, um_denominator, ) } /// Generates random positive signed integers from a truncated geometric distribution. /// /// With this distribution, the probability of a value being generated decreases as the value /// increases. The probabilities $P(1), P(2), P(3), \ldots$ decrease in a geometric sequence; that's /// where the "geometric" comes from. Unlike a true geometric distribution, this distribution is /// truncated, meaning that values above `T::MAX` are never generated. /// /// The probabilities can drop more quickly or more slowly depending on a parameter $m_u$, called /// the unadjusted mean. It is equal to `um_numerator / um_denominator`. The unadjusted mean is what /// the mean generated value would be if the distribution were not truncated. If $m_u$ is /// significantly lower than `T::MAX`, which is usually the case, then it is very close to the /// actual mean. The higher $m_u$ is, the more gently the probabilities drop; the lower it is, the /// more quickly they drop. $m_u$ must be greater than one. It may be arbitrarily high, but note /// that the iteration time increases linearly with `um_numerator + um_denominator`. /// /// Here is a more precise characterization of this distribution. Let its support $S \subset \Z$ /// equal $[1, 2^{W-1})$, where $W$ is the width of the type. Then we have /// $$ /// P(n) \neq 0 \leftrightarrow n \in S /// $$ /// /// and whenever $n, n + 1 \in S$, /// $$ /// \frac{P(n)}{P(n+1)} = \frac{m_u}{m_u - 1}. /// $$ /// /// The output length is infinite. /// /// # Expected complexity per iteration /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ = `um_numerator + um_denominator`. /// /// # Panics /// Panics if `um_denominator` is zero or if `um_numerator <= um_denominator`. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::geometric::geometric_random_positive_signeds; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string( /// geometric_random_positive_signeds::(EXAMPLE_SEED, 2, 1), /// 10 /// ), /// "[2, 1, 1, 4, 5, 5, 2, 1, 1, 2, ...]" /// ) /// ``` /// /// # Further details /// Geometric distributions are more typically parametrized by a parameter $p$. The relationship /// between $p$ and $m_u$ is $m_u = \frac{1}{p}$, or $p = \frac{1}{m_u}$. /// /// The probability mass function of this distribution is /// $$ /// P(n) = \\begin{cases} /// \frac{(1-p)^{n-1}p}{1-(1-p)^{2^{W-1}-1}} & \text{if} \\quad 0 < n < 2^{W-1}, \\\\ /// 0 & \\text{otherwise}, /// \\end{cases} /// $$ /// where $W$ is the width of the type. /// /// It's also useful to note that /// $$ /// \lim_{W \to \infty} P(n) = \\begin{cases} /// (1-p)^{n-1}p & \text{if} \\quad n > 0, \\\\ /// 0 & \\text{otherwise}. /// \\end{cases} /// $$ pub fn geometric_random_positive_signeds( seed: Seed, um_numerator: u64, um_denominator: u64, ) -> GeometricRandomNaturalValues { geometric_random_natural_values_inclusive_range( seed, T::ONE, T::MAX, um_numerator, um_denominator, ) } /// Generates random negative signed integers from a modified geometric distribution. /// /// This distribution can be derived from a truncated geometric distribution by negating its domain. /// The distribution is truncated at `T::MIN`. /// /// With this distribution, the probability of a value being generated decreases as its absolute /// value increases. The probabilities $P(-1), P(-2), P(-3), \ldots$ decrease in a geometric /// sequence; that's where the "geometric" comes from. Values below `T::MIN` are never generated. /// /// The probabilities can drop more quickly or more slowly depending on a parameter $m_u$, called /// the unadjusted mean. It is equal to `abs_um_numerator / abs_um_denominator`. The unadjusted mean /// is what the mean of the absolute values of the generated values would be if the distribution /// were not truncated. If $m_u$ is significantly lower than `-T::MIN`, which is usually the case, /// then it is very close to the actual mean of the absolute values. The higher $m_u$ is, the more /// gently the probabilities drop; the lower it is, the more quickly they drop. $m_u$ must be /// greater than one. It may be arbitrarily high, but note that the iteration time increases /// linearly with `abs_um_numerator + abs_um_denominator`. /// /// Here is a more precise characterization of this distribution. Let its support $S \subset \Z$ /// equal $[-2^{W-1}, 0)$, where $W$ is the width of the type. Then we have /// $$ /// P(n) \neq 0 \leftrightarrow n \in S /// $$ /// /// and whenever $n, n - 1 \in S$, /// $$ /// \frac{P(n)}{P(n-1)} = \frac{m_u}{m_u - 1}. /// $$ /// /// The output length is infinite. /// /// # Expected complexity per iteration /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ = `abs_um_numerator + abs_um_denominator`. /// /// # Panics /// Panics if `abs_um_denominator` is zero or if `abs_um_numerator <= abs_um_denominator`. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::geometric::geometric_random_negative_signeds; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string( /// geometric_random_negative_signeds::(EXAMPLE_SEED, 2, 1), /// 10 /// ), /// "[-2, -1, -1, -4, -5, -5, -2, -1, -1, -2, ...]" /// ) /// ``` /// /// # Further details /// Geometric distributions are more typically parametrized by a parameter $p$. The relationship /// between $p$ and $m_u$ is $m_u = \frac{1}{p}$, or $p = \frac{1}{m_u}$. /// /// The probability mass function of this distribution is /// $$ /// P(n) = \\begin{cases} /// \frac{(1-p)^{-n-1}p}{1-(1-p)^{2^{W-1}}} & \text{if} \\quad -2^{W-1} \leq n < 0, \\\\ /// 0 & \\text{otherwise}, /// \\end{cases} /// $$ /// where $W$ is the width of the type. /// /// It's also useful to note that /// $$ /// \lim_{W \to \infty} P(n) = \\begin{cases} /// (1-p)^{-n-1}p & \text{if} \\quad n < 0, \\\\ /// 0 & \\text{otherwise}. /// \\end{cases} /// $$ pub fn geometric_random_negative_signeds( seed: Seed, abs_um_numerator: u64, abs_um_denominator: u64, ) -> GeometricRandomNegativeSigneds { assert!(abs_um_numerator > abs_um_denominator); geometric_random_negative_signeds_inclusive_range( seed, T::NEGATIVE_ONE, T::MIN, abs_um_numerator, abs_um_denominator, ) } /// Generates random nonzero signed integers from a modified geometric distribution. /// /// This distribution can be derived from a truncated geometric distribution by mirroring it, /// producing a truncated double geometric distribution. Zero is excluded. /// /// With this distribution, the probability of a value being generated decreases as its absolute /// value increases. The probabilities $P(\pm 1), P(\pm 2), P(\pm 3), \ldots$ decrease in a /// geometric sequence; that's where the "geometric" comes from. Values below `T::MIN` or above /// `T::MAX` are never generated. /// /// The probabilities can drop more quickly or more slowly depending on a parameter $m_u$, called /// the unadjusted mean. It is equal to `abs_um_numerator / abs_um_denominator`. The unadjusted mean /// is what the mean of the absolute values of the generated values would be if the distribution /// were not truncated. If $m_u$ is significantly lower than `T::MAX`, which is usually the case, /// then it is very close to the actual mean of the absolute values. The higher $m_u$ is, the more /// gently the probabilities drop; the lower it is, the more quickly they drop. $m_u$ must be /// greater than one. It may be arbitrarily high, but note that the iteration time increases /// linearly with `abs_um_numerator + abs_um_denominator`. /// /// Here is a more precise characterization of this distribution. Let its support $S \subset \Z$ /// equal $[-2^{W-1}, 2^{W-1}) \setminus \\{0\\}$, where $W$ is the width of the type. Then we have /// $$ /// P(n) \neq 0 \leftrightarrow n \in S /// $$ /// $$ /// P(1) = P(-1) /// $$ /// Whenever $n > 0$ and $n, n + 1 \in S$, /// $$ /// \frac{P(n)}{P(n+1)} = \frac{m_u}{m_u - 1}, /// $$ /// and whenever $n < 0$ and $n, n - 1 \in S$, /// $$ /// \frac{P(n)}{P(n-1)} = \frac{m_u}{m_u - 1}. /// $$ /// /// As a corollary, $P(n) = P(-n)$ whenever $n, -n \in S$. /// /// The output length is infinite. /// /// # Expected complexity per iteration /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ = `abs_um_numerator + abs_um_denominator`. /// /// # Panics /// Panics if `abs_um_denominator` is zero or if `abs_um_numerator <= abs_um_denominator`. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::geometric::geometric_random_nonzero_signeds; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string( /// geometric_random_nonzero_signeds::(EXAMPLE_SEED, 2, 1), /// 10 /// ), /// "[-2, -2, -2, 2, -3, 2, -1, -1, -1, 1, ...]" /// ) /// ``` /// /// # Further details /// Geometric distributions are more typically parametrized by a parameter $p$. The relationship /// between $p$ and $m_u$ is $m_u = \frac{1}{p}$, or $p = \frac{1}{m_u}$. /// /// The probability mass function of this distribution is /// $$ /// P(n) = \\begin{cases} /// \frac{(1-p)^{|n|}p}{(1-p)^{2^{W-1}}(p-2)-2p+2} & /// \text{if} \\quad -2^{W-1} \leq n < 0 \\ \mathrm{or} \\ 0 < n < -2^{W-1}, \\\\ /// 0 & \\text{otherwise}, /// \\end{cases} /// $$ /// where $W$ is the width of the type. /// /// It's also useful to note that /// $$ /// \lim_{W \to \infty} P(n) = \\begin{cases} /// \frac{(1-p)^{|n|}p}{2-2p} & \text{if} \\quad n \neq 0, \\\\ /// 0 & \\text{otherwise}. /// \\end{cases} /// $$ pub fn geometric_random_nonzero_signeds( seed: Seed, abs_um_numerator: u64, abs_um_denominator: u64, ) -> GeometricRandomNonzeroSigneds { assert!(abs_um_numerator > abs_um_denominator); geometric_random_nonzero_signeds_inclusive_range( seed, T::MIN, T::MAX, abs_um_numerator, abs_um_denominator, ) } /// Generates random unsigned integers from a truncated geometric distribution over the half-open /// interval $[a, b)$. /// /// With this distribution, the probability of a value being generated decreases as the value /// increases. The probabilities $P(a), P(a + 1), P(a + 2), \ldots$ decrease in a geometric /// sequence; that's where the "geometric" comes from. Unlike a true geometric distribution, this /// distribution is truncated, meaning that values above $b$ are never generated. /// /// The probabilities can drop more quickly or more slowly depending on a parameter $m_u$, called /// the unadjusted mean. It is equal to `um_numerator / um_denominator`. The unadjusted mean is what /// the mean generated value would be if the distribution were not truncated. If $m_u$ is /// significantly lower than $b$, then it is very close to the actual mean. The higher $m_u$ is, the /// more gently the probabilities drop; the lower it is, the more quickly they drop. $m_u$ must be /// greater than $a$. It may be arbitrarily high, but note that the iteration time increases /// linearly with `um_numerator + um_denominator`. /// /// Here is a more precise characterization of this distribution. Let its support $S \subset \Z$ /// equal $[a, b)$. Then we have /// $$ /// P(n) \neq 0 \leftrightarrow n \in S /// $$ /// /// and whenever $n, n + 1 \in S$, /// $$ /// \frac{P(n)}{P(n+1)} = \frac{m_u + 1}{m_u}. /// $$ /// /// The output length is infinite. /// /// # Expected complexity per iteration /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ = `um_numerator + um_denominator`. /// /// # Panics /// Panics if $a \geq b$, if `um_numerator` or `um_denominator` are zero, if their ratio is less /// than or equal to $a$, or if they are too large and manipulating them leads to arithmetic /// overflow. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::geometric::geometric_random_unsigned_range; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string( /// geometric_random_unsigned_range::(EXAMPLE_SEED, 1, 7, 3, 1), /// 10 /// ), /// "[2, 5, 2, 3, 4, 2, 5, 6, 1, 2, ...]" /// ) /// ``` /// /// # Further details /// Geometric distributions are more typically parametrized by a parameter $p$. The relationship /// between $p$ and $m_u$ is $m_u = \frac{1}{p} + a - 1$, or $p = \frac{1}{m_u - a + 1}$. /// /// The probability mass function of this distribution is /// $$ /// P(n) = \\begin{cases} /// \frac{(1-p)^np}{(1-p)^a-(1-p)^b} & \text{if} \\quad a \\leq n < b, \\\\ /// 0 & \\text{otherwise}. /// \\end{cases} /// $$ #[inline] pub fn geometric_random_unsigned_range( seed: Seed, a: T, b: T, um_numerator: u64, um_denominator: u64, ) -> GeometricRandomNaturalValues { assert!(a < b, "a must be less than b. a: {a}, b: {b}"); geometric_random_natural_values_inclusive_range( seed, a, b - T::ONE, um_numerator, um_denominator, ) } /// Generates random unsigned integers from a truncated geometric distribution over the closed /// interval $[a, b]$. /// /// With this distribution, the probability of a value being generated decreases as the value /// increases. The probabilities $P(a), P(a + 1), P(a + 2), \ldots$ decrease in a geometric /// sequence; that's where the "geometric" comes from. Unlike a true geometric distribution, this /// distribution is truncated, meaning that values above $b$ are never generated. /// /// The probabilities can drop more quickly or more slowly depending on a parameter $m_u$, called /// the unadjusted mean. It is equal to `um_numerator / um_denominator`. The unadjusted mean is what /// the mean generated value would be if the distribution were not truncated. If $m_u$ is /// significantly lower than $b$, then it is very close to the actual mean. The higher $m_u$ is, the /// more gently the probabilities drop; the lower it is, the more quickly they drop. $m_u$ must be /// greater than $a$. It may be arbitrarily high, but note that the iteration time increases /// linearly with `um_numerator + um_denominator`. /// /// Here is a more precise characterization of this distribution. Let its support $S \subset \Z$ /// equal $[a, b]$. Then we have /// $$ /// P(n) \neq 0 \leftrightarrow n \in S /// $$ /// /// and whenever $n, n + 1 \in S$, /// $$ /// \frac{P(n)}{P(n+1)} = \frac{m_u + 1}{m_u}. /// $$ /// /// The output length is infinite. /// /// # Expected complexity per iteration /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ = `um_numerator + um_denominator`. /// /// # Panics /// Panics if $a > b$, if `um_numerator` or `um_denominator` are zero, if their ratio is less than /// or equal to $a$, or if they are too large and manipulating them leads to arithmetic overflow. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::geometric::geometric_random_unsigned_inclusive_range; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string( /// geometric_random_unsigned_inclusive_range::(EXAMPLE_SEED, 1, 6, 3, 1), /// 10 /// ), /// "[2, 5, 2, 3, 4, 2, 5, 6, 1, 2, ...]" /// ) /// ``` /// /// # Further details /// Geometric distributions are more typically parametrized by a parameter $p$. The relationship /// between $p$ and $m_u$ is $m_u = \frac{1}{p} + a - 1$, or $p = \frac{1}{m_u - a + 1}$. /// /// The probability mass function of this distribution is /// $$ /// P(n) = \\begin{cases} /// \frac{(1-p)^np}{(1-p)^a-(1-p)^{b+1}} & \text{if} \\quad a \\leq n \\leq b, \\\\ /// 0 & \\text{otherwise}. /// \\end{cases} /// $$ #[inline] pub fn geometric_random_unsigned_inclusive_range( seed: Seed, a: T, b: T, um_numerator: u64, um_denominator: u64, ) -> GeometricRandomNaturalValues { assert!(a <= b, "a must be less than or equal to b. a: {a}, b: {b}"); geometric_random_natural_values_inclusive_range(seed, a, b, um_numerator, um_denominator) } /// Generates random signed integers from a modified geometric distribution over the half-open /// interval $[a, b)$. /// /// With this distribution, the probability of a value being generated decreases as its absolute /// value increases. The probabilities $P(n), P(n + \operatorname{sgn}(n)), P(n + /// 2\operatorname{sgn}(n)), \ldots$, where $n, n + \operatorname{sgn}(n), n + /// 2\operatorname{sgn}(n), \ldots \in [a, b) \\setminus \\{0\\}$, decrease in a geometric sequence; /// that's where the "geometric" comes from. /// /// The form of the distribution depends on the range. If $a \geq 0$, the distribution is highest at /// $a$ and is truncated at $b$. If $b \leq 1$, the distribution is reflected: it is highest at $b - /// 1$ and is truncated at $a$. Otherwise, the interval includes both positive and negative values. /// In that case the distribution is doubled: it is highest at zero and is truncated at $a$ and $b$. /// /// The probabilities can drop more quickly or more slowly depending on a parameter $m_u$, called /// the unadjusted mean. It is equal to `abs_um_numerator / abs_um_denominator`. The unadjusted mean /// is what the mean of the absolute values of the generated values would be if the distribution /// were not truncated. If $m_u$ is significantly lower than $b$, then it is very close to the /// actual mean of the absolute values. The higher $m_u$ is, the more gently the probabilities drop; /// the lower it is, the more quickly they drop. $m_u$ must be greater than $a$. It may be /// arbitrarily high, but note that the iteration time increases linearly with `abs_um_numerator + /// abs_um_denominator`. /// /// Here is a more precise characterization of this distribution. Let its support $S \subset \Z$ /// equal $[a, b)$. Let $c = \min_{n\in S}|n|$. Geometric distributions are typically parametrized /// by a parameter $p$. The relationship between $p$ and $m_u$ is $m_u = \frac{1}{p} + c - 1$, or $p /// = \frac{1}{m_u - c + 1}$. Then we have /// $$ /// P(n) \neq 0 \leftrightarrow n \in S /// $$ /// If $0, 1 \in S$, then /// $$ /// \frac{P(0)}{P(1)} = \frac{m_u + 1}{m_u}. /// $$ /// If $-1, 0 \in S$, then /// $$ /// \frac{P(0)}{P(-1)} = \frac{m_u + 1}{m_u}. /// $$ /// and whenever $n, n + \operatorname{sgn}(n) \in S \setminus \\{0\\}$, /// $$ /// \frac{P(n)}{P(n+\operatorname{sgn}(n))} = \frac{m_u + 1}{m_u}. /// $$ /// /// As a corollary, $P(n) = P(-n)$ whenever $n, -n \in S$. /// /// The output length is infinite. /// /// # Expected complexity per iteration /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ = `um_numerator + um_denominator`. /// /// # Panics /// Panics if $a \geq b$, if `um_numerator` or `um_denominator` are zero, if their ratio is less /// than or equal to $a$, or if they are too large and manipulating them leads to arithmetic /// overflow. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::geometric::geometric_random_signed_range; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string( /// geometric_random_signed_range::(EXAMPLE_SEED, -100, 100, 30, 1), /// 10 /// ), /// "[-32, -31, -88, 52, -40, 64, -36, -1, -7, 46, ...]" /// ) /// ``` /// /// # Further details /// The probability mass function of this distribution is /// $$ /// P(n) = \\begin{cases} /// \frac{(1-p)^np}{(1-p)^a-(1-p)^b} & \text{if} \\quad 0 \\leq a \\leq n < b, \\\\ /// \frac{(1-p)^{-n}p}{(1-p)^{1-b}-(1-p)^{1-a}} & \text{if} \\quad a \\leq n < b \\leq 1, \\\\ /// \frac{(1-p)^{|n|}p}{2-p-(1-p)^{1-a}-(1-p)^b} & /// \text{if} \\quad a < 0 < 1 < b \\ \mathrm{and} \\ a \\leq n < b, \\\\ /// 0 & \\text{otherwise}. /// \\end{cases} /// $$ #[inline] pub fn geometric_random_signed_range( seed: Seed, a: T, b: T, abs_um_numerator: u64, abs_um_denominator: u64, ) -> GeometricRandomSignedRange { assert!(a < b, "a must be less than b. a: {a}, b: {b}"); if a >= T::ZERO { GeometricRandomSignedRange::NonNegative(geometric_random_natural_values_inclusive_range( seed, a, b - T::ONE, abs_um_numerator, abs_um_denominator, )) } else if b <= T::ONE { GeometricRandomSignedRange::NonPositive(geometric_random_negative_signeds_inclusive_range( seed, b - T::ONE, a, abs_um_numerator, abs_um_denominator, )) } else { GeometricRandomSignedRange::BothSigns(geometric_random_signed_inclusive_range_helper( seed, a, b - T::ONE, abs_um_numerator, abs_um_denominator, )) } } /// Generates random signed integers from a modified geometric distribution over the closed interval /// $[a, b]$. /// /// With this distribution, the probability of a value being generated decreases as its absolute /// value increases. The probabilities $P(n), P(n + \operatorname{sgn}(n)), P(n + /// 2\operatorname{sgn}(n)), \ldots$, where $n, n + \operatorname{sgn}(n), n + /// 2\operatorname{sgn}(n), \ldots \in [a, b] \\setminus \\{0\\}$, decrease in a geometric sequence; /// that's where the "geometric" comes from. /// /// The form of the distribution depends on the range. If $a \geq 0$, the distribution is highest at /// $a$ and is truncated at $b$. If $b \leq 0$, the distribution is reflected: it is highest at $b$ /// and is truncated at $a$. Otherwise, the interval includes both positive and negative values. In /// that case the distribution is doubled: it is highest at zero and is truncated at $a$ and $b$. /// /// The probabilities can drop more quickly or more slowly depending on a parameter $m_u$, called /// the unadjusted mean. It is equal to `abs_um_numerator / abs_um_denominator`. The unadjusted mean /// is what the mean of the absolute values of the generated values would be if the distribution /// were not truncated. If $m_u$ is significantly lower than $b$, then it is very close to the /// actual mean of the absolute values. The higher $m_u$ is, the more gently the probabilities drop; /// the lower it is, the more quickly they drop. $m_u$ must be greater than $a$. It may be /// arbitrarily high, but note that the iteration time increases linearly with `abs_um_numerator + /// abs_um_denominator`. /// /// Here is a more precise characterization of this distribution. Let its support $S \subset \Z$ /// equal $[a, b]$. Let $c = \min_{n\in S}|n|$. Geometric distributions are typically parametrized /// by a parameter $p$. The relationship between $p$ and $m_u$ is $m_u = \frac{1}{p} + c - 1$, or $p /// = \frac{1}{m_u - c + 1}$. Then we have /// $$ /// P(n) \neq 0 \leftrightarrow n \in S /// $$ /// If $0, 1 \in S$, then /// $$ /// \frac{P(0)}{P(1)} = \frac{m_u + 1}{m_u}. /// $$ /// If $-1, 0 \in S$, then /// $$ /// \frac{P(0)}{P(-1)} = \frac{m_u + 1}{m_u}. /// $$ /// and whenever $n, n + \operatorname{sgn}(n) \in S \setminus \\{0\\}$, /// $$ /// \frac{P(n)}{P(n+\operatorname{sgn}(n))} = \frac{m_u + 1}{m_u}. /// $$ /// /// As a corollary, $P(n) = P(-n)$ whenever $n, -n \in S$. /// /// The output length is infinite. /// /// # Expected complexity per iteration /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ = `um_numerator + um_denominator`. /// /// # Panics /// Panics if $a > b$, if `um_numerator` or `um_denominator` are zero, if their ratio is less than /// or equal to $a$, or if they are too large and manipulating them leads to arithmetic overflow. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::geometric::geometric_random_signed_inclusive_range; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string( /// geometric_random_signed_inclusive_range::(EXAMPLE_SEED, -100, 99, 30, 1), /// 10 /// ), /// "[-32, -31, -88, 52, -40, 64, -36, -1, -7, 46, ...]" /// ) /// ``` /// /// # Further details /// The probability mass function of this distribution is /// $$ /// P(n) = \\begin{cases} /// \frac{(1-p)^np}{(1-p)^a-(1-p)^{b+1}} & \text{if} \\quad 0 \\leq a \\leq n \\leq b, \\\\ /// \frac{(1-p)^{-n}p}{(1-p)^{-b}-(1-p)^{1-a}} /// & \text{if} \\quad a \\leq n \\leq b \\leq 0, \\\\ /// \frac{(1-p)^{|n|}p}{2-p-(1-p)^{1-a}-(1-p)^{b+1}} /// & \text{if} \\quad a < 0 < b \\ \mathrm{and} \\ a \\leq n \\leq b, \\\\ /// 0 & \\text{otherwise}. /// \\end{cases} /// $$ #[inline] pub fn geometric_random_signed_inclusive_range( seed: Seed, a: T, b: T, abs_um_numerator: u64, abs_um_denominator: u64, ) -> GeometricRandomSignedRange { assert!(a <= b, "a must be less than or equal to b. a: {a}, b: {b}"); if a >= T::ZERO { GeometricRandomSignedRange::NonNegative(geometric_random_natural_values_inclusive_range( seed, a, b, abs_um_numerator, abs_um_denominator, )) } else if b <= T::ZERO { GeometricRandomSignedRange::NonPositive(geometric_random_negative_signeds_inclusive_range( seed, b, a, abs_um_numerator, abs_um_denominator, )) } else { GeometricRandomSignedRange::BothSigns(geometric_random_signed_inclusive_range_helper( seed, a, b, abs_um_numerator, abs_um_denominator, )) } } /// Generates a random signed integers from a modified geometric distribution over the closed /// interval $[a, b]$. /// /// See [`geometric_random_signed_inclusive_range`] for a detailed description of the distribution. /// /// The output length is infinite. /// /// # Expected complexity per iteration /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ = `um_numerator + um_denominator`. /// /// # Panics /// Panics if $a > b$, if `um_numerator` or `um_denominator` are zero, if their ratio is less than /// or equal to $a$, or if they are too large and manipulating them leads to arithmetic overflow. /// /// # Examples /// ``` /// use malachite_base::num::random::geometric::get_geometric_random_signed_from_inclusive_range; /// use malachite_base::num::random::VariableRangeGenerator; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// get_geometric_random_signed_from_inclusive_range::( /// &mut VariableRangeGenerator::new(EXAMPLE_SEED), /// -100, /// 99, /// 30, /// 1 /// ), /// 8 /// ) /// ``` pub fn get_geometric_random_signed_from_inclusive_range( range_generator: &mut VariableRangeGenerator, a: T, b: T, abs_um_numerator: u64, abs_um_denominator: u64, ) -> T { assert!(a <= b, "a must be less than or equal to b. a: {a}, b: {b}"); if a >= T::ZERO { get_geometric_random_natural_value_from_inclusive_range( range_generator, a, b, abs_um_numerator, abs_um_denominator, ) } else if b <= T::ZERO { get_geometric_random_negative_signed_from_inclusive_range( range_generator, b, a, abs_um_numerator, abs_um_denominator, ) } else { get_geometric_random_signed_from_inclusive_range_helper( range_generator, a, b, abs_um_numerator, abs_um_denominator, ) } } malachite-base-0.4.16/src/num/random/mod.rs000064400000000000000000002764621046102023000165670ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::bools::random::{random_bools, RandomBools}; use crate::iterators::{ nonzero_values, with_special_value, with_special_values, NonzeroValues, WithSpecialValue, WithSpecialValues, }; use crate::num::arithmetic::traits::{Parity, PowerOf2, ShrRound}; use crate::num::basic::floats::PrimitiveFloat; use crate::num::basic::integers::PrimitiveInt; use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::WrappingFrom; use crate::num::float::NiceFloat; use crate::num::iterators::{iterator_to_bit_chunks, IteratorToBitChunks}; use crate::num::logic::traits::{BitAccess, SignificantBits}; use crate::num::random::geometric::{ geometric_random_signed_inclusive_range, geometric_random_unsigned_inclusive_range, geometric_random_unsigneds, GeometricRandomNaturalValues, GeometricRandomSignedRange, }; use crate::random::{Seed, EXAMPLE_SEED}; use crate::rounding_modes::RoundingMode::*; use crate::vecs::{random_values_from_vec, RandomValuesFromVec}; use itertools::Itertools; use rand::Rng; use rand_chacha::ChaCha20Rng; use std::collections::HashMap; use std::convert::identity; use std::fmt::Debug; use std::marker::PhantomData; // Uniformly generates random primitive integers. #[doc(hidden)] #[derive(Clone, Debug, Eq, Hash, PartialEq)] pub struct ThriftyRandomState { x: u32, bits_left: u64, } #[doc(hidden)] pub trait HasRandomPrimitiveInts { type State: Clone + Debug; fn new_state() -> Self::State; fn get_random(rng: &mut ChaCha20Rng, state: &mut Self::State) -> Self; } macro_rules! impl_trivial_random_primitive_ints { ($t: ident) => { impl HasRandomPrimitiveInts for $t { type State = (); #[inline] fn new_state() -> () {} #[inline] fn get_random(rng: &mut ChaCha20Rng, _state: &mut ()) -> $t { rng.gen() } } }; } impl_trivial_random_primitive_ints!(u32); impl_trivial_random_primitive_ints!(u64); impl_trivial_random_primitive_ints!(u128); impl_trivial_random_primitive_ints!(usize); impl_trivial_random_primitive_ints!(i32); impl_trivial_random_primitive_ints!(i64); impl_trivial_random_primitive_ints!(i128); impl_trivial_random_primitive_ints!(isize); fn get_random(rng: &mut ChaCha20Rng, state: &mut ThriftyRandomState) -> T { if state.bits_left == 0 { state.x = rng.gen(); state.bits_left = u32::WIDTH - T::WIDTH; } else { state.x >>= T::WIDTH; state.bits_left -= T::WIDTH; } T::wrapping_from(state.x) } macro_rules! impl_thrifty_random_primitive_ints { ($t: ident) => { impl HasRandomPrimitiveInts for $t { type State = ThriftyRandomState; #[inline] fn new_state() -> ThriftyRandomState { ThriftyRandomState { x: 0, bits_left: 0 } } #[inline] fn get_random(rng: &mut ChaCha20Rng, state: &mut ThriftyRandomState) -> $t { get_random(rng, state) } } }; } impl_thrifty_random_primitive_ints!(u8); impl_thrifty_random_primitive_ints!(u16); impl_thrifty_random_primitive_ints!(i8); impl_thrifty_random_primitive_ints!(i16); /// Uniformly generates random primitive integers. /// /// This `struct` is created by [`random_primitive_ints`]; see its documentation for more. #[derive(Clone, Debug)] pub struct RandomPrimitiveInts { pub(crate) rng: ChaCha20Rng, pub(crate) state: T::State, } impl Iterator for RandomPrimitiveInts { type Item = T; #[inline] fn next(&mut self) -> Option { Some(T::get_random(&mut self.rng, &mut self.state)) } } /// Uniformly generates random unsigned integers less than a positive limit. /// /// This `enum` is created by [`random_unsigneds_less_than`]; see its documentation for more. #[allow(clippy::large_enum_variant)] #[derive(Clone, Debug)] pub enum RandomUnsignedsLessThan { One, AtLeastTwo(RandomUnsignedBitChunks, T), } impl Iterator for RandomUnsignedsLessThan { type Item = T; #[inline] fn next(&mut self) -> Option { match *self { RandomUnsignedsLessThan::One => Some(T::ZERO), RandomUnsignedsLessThan::AtLeastTwo(ref mut xs, limit) => loop { let x = xs.next(); if x.unwrap() < limit { return x; } }, } } } /// Uniformly generates random unsigned integers in the half-open interval $[a, b)$. /// /// This `struct` is created by [`random_unsigned_range`]; see its documentation for more. #[derive(Clone, Debug)] pub struct RandomUnsignedRange { pub(crate) xs: RandomUnsignedsLessThan, pub(crate) a: T, } impl Iterator for RandomUnsignedRange { type Item = T; #[inline] fn next(&mut self) -> Option { self.xs.next().map(|x| x + self.a) } } /// Uniformly generates random unsigned integers in the closed interval $[a, b]$. /// /// This `struct` is created by [`random_unsigned_inclusive_range`]; see its documentation for more. #[derive(Clone, Debug)] pub enum RandomUnsignedInclusiveRange { NotAll(RandomUnsignedsLessThan, T), All(RandomPrimitiveInts), } impl Iterator for RandomUnsignedInclusiveRange { type Item = T; #[inline] fn next(&mut self) -> Option { match self { RandomUnsignedInclusiveRange::NotAll(xs, a) => xs.next().map(|x| x + *a), RandomUnsignedInclusiveRange::All(xs) => xs.next(), } } } #[doc(hidden)] pub trait HasRandomSignedRange: Sized { type UnsignedValue: PrimitiveUnsigned; fn new_unsigned_range(seed: Seed, a: Self, b: Self) -> RandomUnsignedRange; fn new_unsigned_inclusive_range( seed: Seed, a: Self, b: Self, ) -> RandomUnsignedInclusiveRange; fn from_unsigned_value(x: Self::UnsignedValue) -> Self; } macro_rules! impl_has_random_signed_range { ($u: ident, $s: ident) => { impl HasRandomSignedRange for $s { type UnsignedValue = $u; fn new_unsigned_range(seed: Seed, mut a: $s, mut b: $s) -> RandomUnsignedRange<$u> { a.flip_bit($u::WIDTH - 1); b.flip_bit($u::WIDTH - 1); random_unsigned_range(seed, $u::wrapping_from(a), $u::wrapping_from(b)) } fn new_unsigned_inclusive_range( seed: Seed, mut a: $s, mut b: $s, ) -> RandomUnsignedInclusiveRange<$u> { a.flip_bit($u::WIDTH - 1); b.flip_bit($u::WIDTH - 1); random_unsigned_inclusive_range(seed, $u::wrapping_from(a), $u::wrapping_from(b)) } fn from_unsigned_value(mut u: $u) -> $s { u.flip_bit($u::WIDTH - 1); $s::wrapping_from(u) } } }; } apply_to_unsigned_signed_pairs!(impl_has_random_signed_range); /// Uniformly generates random signed integers in the half-open interval $[a, b)$. /// /// This `struct` is created by [`random_signed_range`]; see its documentation for more. #[derive(Clone, Debug)] pub struct RandomSignedRange { pub(crate) xs: RandomUnsignedRange, } impl Iterator for RandomSignedRange { type Item = T; fn next(&mut self) -> Option { self.xs.next().map(T::from_unsigned_value) } } /// Uniformly generates random signed integers in the closed interval $[a, b]$. /// /// This `struct` is created by [`random_signed_inclusive_range`]; see its documentation for more. #[derive(Clone, Debug)] pub struct RandomSignedInclusiveRange { pub(crate) xs: RandomUnsignedInclusiveRange, } impl Iterator for RandomSignedInclusiveRange { type Item = T; fn next(&mut self) -> Option { self.xs.next().map(T::from_unsigned_value) } } /// Uniformly generates unsigned integers with up to some number of bits. /// /// This `struct` is created by [`random_unsigned_bit_chunks`]; see its documentation for more. #[derive(Clone, Debug)] pub struct RandomUnsignedBitChunks { xs: IteratorToBitChunks, T, T>, } impl Iterator for RandomUnsignedBitChunks { type Item = T; fn next(&mut self) -> Option { self.xs.next_with_wrapping(identity).map(Option::unwrap) } } #[doc(hidden)] pub trait RandomSignedChunkable: Sized { type AbsoluteChunks: Clone + Debug; fn new_absolute_chunks(seed: Seed, chunk_size: u64) -> Self::AbsoluteChunks; fn next_chunk(xs: &mut Self::AbsoluteChunks) -> Option; } macro_rules! impl_random_signed_chunkable { ($u: ident, $s: ident) => { impl RandomSignedChunkable for $s { type AbsoluteChunks = RandomUnsignedBitChunks<$u>; fn new_absolute_chunks(seed: Seed, chunk_size: u64) -> RandomUnsignedBitChunks<$u> { random_unsigned_bit_chunks(seed, chunk_size) } fn next_chunk(xs: &mut Self::AbsoluteChunks) -> Option<$s> { xs.next().map(WrappingFrom::wrapping_from) } } }; } apply_to_unsigned_signed_pairs!(impl_random_signed_chunkable); /// Uniformly generates signed integers with up to some number of bits. /// /// This `struct` is created by [`random_signed_bit_chunks`]; see its documentation for more. #[derive(Clone, Debug)] pub struct RandomSignedBitChunks { pub(crate) xs: T::AbsoluteChunks, } impl Iterator for RandomSignedBitChunks { type Item = T; fn next(&mut self) -> Option { T::next_chunk(&mut self.xs) } } /// Modifies the output values of an iterator by setting their highest bit. #[derive(Clone, Debug)] pub struct RandomHighestBitSetValues where I::Item: PrimitiveInt, { pub(crate) xs: I, pub(crate) mask: I::Item, } impl Iterator for RandomHighestBitSetValues where I::Item: PrimitiveInt, { type Item = I::Item; #[inline] fn next(&mut self) -> Option { self.xs.next().map(|x| x | self.mask) } } /// Uniformly generates random primitive integers. /// /// $P(x) = 2^{-W}$, where $W$ is the width of the type. /// /// The output length is infinite. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::random_primitive_ints; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string(random_primitive_ints::(EXAMPLE_SEED), 10), /// "[113, 239, 69, 108, 228, 210, 168, 161, 87, 32, ...]" /// ) /// ``` #[inline] pub fn random_primitive_ints(seed: Seed) -> RandomPrimitiveInts { RandomPrimitiveInts { rng: seed.get_rng(), state: T::new_state(), } } /// Uniformly generates random positive unsigned integers. /// /// $$ /// P(x) = \\begin{cases} /// \\frac{1}{2^W-1} & \text{if} \\quad x > 0, \\\\ /// 0 & \\text{otherwise}, /// \\end{cases} /// $$ /// where $W$ is the width of the type. /// /// The output length is infinite. /// /// # Expected complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::random_positive_unsigneds; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string(random_positive_unsigneds::(EXAMPLE_SEED), 10), /// "[113, 239, 69, 108, 228, 210, 168, 161, 87, 32, ...]" /// ) /// ``` #[inline] pub fn random_positive_unsigneds( seed: Seed, ) -> NonzeroValues> { nonzero_values(random_primitive_ints(seed)) } /// Uniformly generates random positive signed integers. /// /// $$ /// P(x) = \\begin{cases} /// \\frac{1}{2^{W-1}-1} & \text{if} \\quad x > 0, \\\\ /// 0 & \\text{otherwise}, /// \\end{cases} /// $$ /// where $W$ is the width of the type. /// /// The output length is infinite. /// /// # Expected complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::random_positive_signeds; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string(random_positive_signeds::(EXAMPLE_SEED), 10), /// "[113, 94, 23, 98, 70, 92, 52, 84, 33, 47, ...]" /// ) /// ``` #[inline] pub fn random_positive_signeds( seed: Seed, ) -> NonzeroValues> { nonzero_values(random_natural_signeds(seed)) } /// Uniformly generates random negative signed integers. /// /// $$ /// P(x) = \\begin{cases} /// 2^{1-W} & \text{if} \\quad x < 0, \\\\ /// 0 & \\text{otherwise}, /// \\end{cases} /// $$ /// where $W$ is the width of the type. /// /// The output length is infinite. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::random_negative_signeds; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string(random_negative_signeds::(EXAMPLE_SEED), 10), /// "[-15, -34, -105, -30, -58, -36, -76, -44, -95, -81, ...]" /// ) /// ``` #[inline] pub fn random_negative_signeds( seed: Seed, ) -> RandomHighestBitSetValues> { RandomHighestBitSetValues { xs: random_signed_bit_chunks(seed, T::WIDTH - 1), mask: T::MIN, } } /// Uniformly generates random natural (non-negative) signed integers. /// /// $$ /// P(x) = \\begin{cases} /// 2^{1-W} & \text{if} \\quad x \geq 0, \\\\ /// 0 & \\text{otherwise}, /// \\end{cases} /// $$ /// where $W$ is the width of the type. /// /// The output length is infinite. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::random_natural_signeds; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string(random_natural_signeds::(EXAMPLE_SEED), 10), /// "[113, 94, 23, 98, 70, 92, 52, 84, 33, 47, ...]" /// ) /// ``` #[inline] pub fn random_natural_signeds(seed: Seed) -> RandomSignedBitChunks { random_signed_bit_chunks(seed, T::WIDTH - 1) } /// Uniformly generates random nonzero signed integers. /// /// $$ /// P(x) = \\begin{cases} /// \\frac{1}{2^W-1} & \text{if} \\quad x \\neq 0, \\\\ /// 0 & \\text{otherwise}, /// \\end{cases} /// $$ /// where $W$ is the width of the type. /// /// The output length is infinite. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::random_nonzero_signeds; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string(random_nonzero_signeds::(EXAMPLE_SEED), 10), /// "[113, -17, 69, 108, -28, -46, -88, -95, 87, 32, ...]" /// ) /// ``` #[inline] pub fn random_nonzero_signeds( seed: Seed, ) -> NonzeroValues> { nonzero_values(random_primitive_ints(seed)) } /// Uniformly generates random unsigned integers less than a positive limit. /// /// $$ /// P(x) = \\begin{cases} /// \frac{1}{\\ell} & \text{if} \\quad x < \\ell, \\\\ /// 0 & \\text{otherwise,} /// \\end{cases} /// $$ /// where $\ell$ is `limit`. /// /// The output length is infinite. /// /// # Expected complexity per iteration /// Constant time and additional memory. /// /// # Panics /// Panics if `limit` is 0. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::random_unsigneds_less_than; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string(random_unsigneds_less_than::(EXAMPLE_SEED, 10), 10), /// "[1, 7, 5, 4, 6, 4, 2, 8, 1, 7, ...]" /// ) /// ``` pub fn random_unsigneds_less_than( seed: Seed, limit: T, ) -> RandomUnsignedsLessThan { if limit == T::ZERO { panic!("limit cannot be 0."); } else if limit == T::ONE { RandomUnsignedsLessThan::One } else { RandomUnsignedsLessThan::AtLeastTwo( random_unsigned_bit_chunks(seed, limit.ceiling_log_base_2()), limit, ) } } /// Uniformly generates random unsigned integers in the half-open interval $[a, b)$. /// /// $a$ must be less than $b$. This function cannot create a range that includes `T::MAX`; for that, /// use [`random_unsigned_inclusive_range`]. /// /// $$ /// P(x) = \\begin{cases} /// \frac{1}{b-a} & \text{if} \\quad a \leq x < b, \\\\ /// 0 & \\text{otherwise.} /// \\end{cases} /// $$ /// /// The output length is infinite. /// /// # Expected complexity per iteration /// Constant time and additional memory. /// /// # Panics /// Panics if $a \geq b$. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::random_unsigned_range; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string(random_unsigned_range::(EXAMPLE_SEED, 10, 20), 10), /// "[11, 17, 15, 14, 16, 14, 12, 18, 11, 17, ...]" /// ) /// ``` pub fn random_unsigned_range( seed: Seed, a: T, b: T, ) -> RandomUnsignedRange { assert!(a < b, "a must be less than b. a: {a}, b: {b}"); RandomUnsignedRange { xs: random_unsigneds_less_than(seed, b - a), a, } } /// Uniformly generates random unsigned integers in the closed interval $[a, b]$. /// /// $a$ must be less than or equal to $b$. /// /// $$ /// P(x) = \\begin{cases} /// \frac{1}{b-a+1} & \text{if} \\quad a \leq x \leq b, \\\\ /// 0 & \\text{otherwise.} /// \\end{cases} /// $$ /// /// The output length is infinite. /// /// # Expected complexity per iteration /// Constant time and additional memory. /// /// # Panics /// Panics if $a > b$. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::random_unsigned_inclusive_range; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string( /// random_unsigned_inclusive_range::(EXAMPLE_SEED, 10, 19), /// 10 /// ), /// "[11, 17, 15, 14, 16, 14, 12, 18, 11, 17, ...]" /// ) /// ``` pub fn random_unsigned_inclusive_range( seed: Seed, a: T, b: T, ) -> RandomUnsignedInclusiveRange { assert!(a <= b, "a must be less than or equal to b. a: {a}, b: {b}"); if a == T::ZERO && b == T::MAX { RandomUnsignedInclusiveRange::All(random_primitive_ints(seed)) } else { RandomUnsignedInclusiveRange::NotAll(random_unsigneds_less_than(seed, b - a + T::ONE), a) } } /// Uniformly generates random signed integers in the half-open interval $[a, b)$. /// /// $a$ must be less than $b$. This function cannot create a range that includes `T::MAX`; for that, /// use [`random_signed_inclusive_range`]. /// /// $$ /// P(x) = \\begin{cases} /// \frac{1}{b-a} & \text{if} \\quad a \leq x < b, \\\\ /// 0 & \\text{otherwise.} /// \\end{cases} /// $$ /// /// The output length is infinite. /// /// # Expected complexity per iteration /// Constant time and additional memory. /// /// # Panics /// Panics if $a \geq b$. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::random_signed_range; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string(random_signed_range::(EXAMPLE_SEED, -100, 100), 10), /// "[13, -31, 8, 68, 61, -13, -68, 10, -17, 88, ...]" /// ) /// ``` #[inline] pub fn random_signed_range(seed: Seed, a: T, b: T) -> RandomSignedRange { assert!(a < b, "a must be less than b. a: {a}, b: {b}"); RandomSignedRange { xs: T::new_unsigned_range(seed, a, b), } } /// Uniformly generates random signed integers in the closed interval $[a, b]$. /// /// $a$ must be less than or equal to $b$. /// /// $$ /// P(x) = \\begin{cases} /// \frac{1}{b-a+1} & \text{if} \\quad a \leq x \leq b, \\\\ /// 0 & \\text{otherwise.} /// \\end{cases} /// $$ /// /// The output length is infinite. /// /// # Expected complexity per iteration /// Constant time and additional memory. /// /// # Panics /// Panics if $a > b$. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::random_signed_inclusive_range; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string( /// random_signed_inclusive_range::(EXAMPLE_SEED, -100, 99), /// 10 /// ), /// "[13, -31, 8, 68, 61, -13, -68, 10, -17, 88, ...]" /// ) /// ``` #[inline] pub fn random_signed_inclusive_range( seed: Seed, a: T, b: T, ) -> RandomSignedInclusiveRange { assert!(a <= b, "a must be less than or equal to b. a: {a}, b: {b}"); RandomSignedInclusiveRange { xs: T::new_unsigned_inclusive_range(seed, a, b), } } /// Uniformly generates unsigned integers containing some maximum number of bits. /// /// $$ /// P(x) = \\begin{cases} /// 2^{-c} & \text{if} \\quad 0 \\leq x < 2^c, \\\\ /// 0 & \\text{otherwise,} /// \\end{cases} /// $$ /// where $c$ is `chunk_size`. /// /// The output length is infinite. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Panics /// Panics if `chunk_size` is zero or greater than the width of the type. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::random_unsigned_bit_chunks; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string(random_unsigned_bit_chunks::(EXAMPLE_SEED, 3), 10), /// "[1, 6, 5, 7, 6, 3, 1, 2, 4, 5, ...]" /// ) /// ``` pub fn random_unsigned_bit_chunks( seed: Seed, chunk_size: u64, ) -> RandomUnsignedBitChunks { RandomUnsignedBitChunks { xs: iterator_to_bit_chunks(random_primitive_ints(seed), T::WIDTH, chunk_size), } } /// Uniformly generates signed integers containing some maximum number of bits. /// /// The generated values will all be non-negative unless `chunk_size` is equal to the width of the /// type. /// /// $$ /// P(x) = \\begin{cases} /// 2^{-c} & \text{if} \\quad c = W \\ \\text{or} /// \\ (c < W \\ \\text{and} \\ 0 \\leq x < 2^c), \\\\ /// 0 & \\text{otherwise,} /// \\end{cases} /// $$ /// where $c$ is `chunk_size` and $W$ is the width of the type. /// /// The output length is infinite. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Panics /// Panics if `chunk_size` is zero or greater than the width of the type. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::random_signed_bit_chunks; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string(random_signed_bit_chunks::(EXAMPLE_SEED, 3), 10), /// "[1, 6, 5, 7, 6, 3, 1, 2, 4, 5, ...]" /// ) /// ``` pub fn random_signed_bit_chunks( seed: Seed, chunk_size: u64, ) -> RandomSignedBitChunks { assert!(chunk_size <= T::WIDTH); RandomSignedBitChunks { xs: T::new_absolute_chunks(seed, chunk_size), } } /// Uniformly generates unsigned integers whose highest bit is set. /// /// $$ /// P(x) = \\begin{cases} /// 2^{1-W} & \text{if} \\quad 2^{W-1} \\leq x < 2^W ,\\\\ /// 0 & \\text{otherwise}, /// \\end{cases} /// $$ /// where $W$ is the width of the type. /// /// The output length is infinite. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::random_highest_bit_set_unsigneds; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string(random_highest_bit_set_unsigneds::(EXAMPLE_SEED), 10), /// "[241, 222, 151, 226, 198, 220, 180, 212, 161, 175, ...]" /// ) /// ``` #[inline] pub fn random_highest_bit_set_unsigneds( seed: Seed, ) -> RandomHighestBitSetValues> { RandomHighestBitSetValues { xs: random_unsigned_bit_chunks(seed, T::WIDTH - 1), mask: T::power_of_2(T::WIDTH - 1), } } /// Generates random primitive floats in the half-open interval $[a, b)$. /// /// This `struct` is created by [`random_primitive_float_range`]; see its documentation for more. #[derive(Clone, Debug)] pub struct RandomPrimitiveFloatRange { phantom: PhantomData<*const T>, xs: RandomUnsignedRange, } impl Iterator for RandomPrimitiveFloatRange { type Item = T; fn next(&mut self) -> Option { self.xs.next().map(T::from_ordered_representation) } } /// Generates random primitive floats in the closed interval $[a, b]$. /// /// This `struct` is created by [`random_primitive_float_inclusive_range`]; see its documentation /// for more. #[derive(Clone, Debug)] pub struct RandomPrimitiveFloatInclusiveRange { phantom: PhantomData<*const T>, xs: RandomUnsignedInclusiveRange, } impl Iterator for RandomPrimitiveFloatInclusiveRange { type Item = T; fn next(&mut self) -> Option { self.xs.next().map(T::from_ordered_representation) } } /// Generates random primitive floats in the half-open interval $[a, b)$. /// /// Every float within the range has an equal probability of being chosen. This does not mean that /// the distribution approximates a uniform distribution over the reals. For example, if the range /// is $[0, 2)$, a float in $[1/4, 1/2)$ is as likely to be chosen as a float in $[1, 2)$, since /// these subranges contain an equal number of floats. /// /// Positive and negative zero are treated as two distinct values, with negative zero being smaller /// than zero. /// /// `NaN` is never generated. /// /// $a$ must be less than $b$. This function cannot create a range that includes `T::INFINITY`; for /// that, use [`random_primitive_float_inclusive_range`]. /// /// The output length is infinite. /// /// # Expected complexity per iteration /// Constant time and additional memory. /// /// # Panics /// Panics if $a \geq b$. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::float::NiceFloat; /// use malachite_base::num::random::random_primitive_float_range; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string( /// random_primitive_float_range::(EXAMPLE_SEED, -0.1, 0.1).map(NiceFloat), /// 10 /// ), /// "[5.664681e-11, 1.2492925e-35, 2.3242339e-29, 4.699183e-7, -2.8244436e-36, -2.264039e-37, \ /// -0.0000017299129, 1.40616e-23, 2.7418007e-27, 1.5418819e-16, ...]" /// ); /// ``` #[inline] pub fn random_primitive_float_range( seed: Seed, a: T, b: T, ) -> RandomPrimitiveFloatRange { assert!(!a.is_nan()); assert!(!b.is_nan()); assert!( NiceFloat(a) < NiceFloat(b), "a must be less than b. a: {}, b: {}", NiceFloat(a), NiceFloat(b) ); RandomPrimitiveFloatRange { phantom: PhantomData, xs: random_unsigned_range( seed, a.to_ordered_representation(), b.to_ordered_representation(), ), } } /// Generates random primitive floats in the closed interval $[a, b]$. /// /// Every float within the range has an equal probability of being chosen. This does not mean that /// the distribution approximates a uniform distribution over the reals. For example, if the range /// is $[0, 2]$, a float in $[1/4, 1/2)$ is as likely to be chosen as a float in $[1, 2)$, since /// these subranges contain an equal number of floats. /// /// Positive and negative zero are treated as two distinct values, with negative zero being smaller /// than zero. /// /// $a$ must be less than or equal to $b$. /// /// `NaN` is never generated. /// /// The output length is infinite. /// /// # Expected complexity per iteration /// Constant time and additional memory. /// /// # Panics /// Panics if $a > b$. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::float::NiceFloat; /// use malachite_base::num::random::random_primitive_float_inclusive_range; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string( /// random_primitive_float_inclusive_range::(EXAMPLE_SEED, -0.1, 0.1).map(NiceFloat), /// 10 /// ), /// "[5.664681e-11, 1.2492925e-35, 2.3242339e-29, 4.699183e-7, -2.8244436e-36, -2.264039e-37, \ /// -0.0000017299129, 1.40616e-23, 2.7418007e-27, 1.5418819e-16, ...]" /// ); /// ``` #[inline] pub fn random_primitive_float_inclusive_range( seed: Seed, a: T, b: T, ) -> RandomPrimitiveFloatInclusiveRange { assert!(!a.is_nan()); assert!(!b.is_nan()); assert!( NiceFloat(a) <= NiceFloat(b), "a must be less than or equal to b. a: {}, b: {}", NiceFloat(a), NiceFloat(b) ); RandomPrimitiveFloatInclusiveRange { phantom: PhantomData, xs: random_unsigned_inclusive_range( seed, a.to_ordered_representation(), b.to_ordered_representation(), ), } } /// Generates random finite positive primitive floats. /// /// Every float within the range has an equal probability of being chosen. This does not mean that /// the distribution approximates a uniform distribution over the reals. For example, a float in /// $[1/4, 1/2)$ is as likely to be chosen as a float in $[1, 2)$, since these subranges contain an /// equal number of floats. /// /// Positive zero is generated; negative zero is not. `NaN` is not generated either. /// /// The output length is infinite. /// /// # Expected complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::float::NiceFloat; /// use malachite_base::num::random::random_positive_finite_primitive_floats; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string( /// random_positive_finite_primitive_floats::(EXAMPLE_SEED).map(NiceFloat), /// 10 /// ), /// "[9.5715654e26, 209.6476, 386935780.0, 7.965817e30, 0.00021030706, 0.0027270128, \ /// 3.4398167e-34, 2.3397111e14, 44567765000.0, 2.3479653e21, ...]" /// ); /// ``` #[inline] pub fn random_positive_finite_primitive_floats( seed: Seed, ) -> RandomPrimitiveFloatInclusiveRange { random_primitive_float_inclusive_range(seed, T::MIN_POSITIVE_SUBNORMAL, T::MAX_FINITE) } /// Generates random finite negative primitive floats. /// /// Every float within the range has an equal probability of being chosen. This does not mean that /// the distribution approximates a uniform distribution over the reals. For example, a float in /// $(-1/2, 1/4]$ is as likely to be chosen as a float in $(-2, -1]$, since these subranges contain /// an equal number of floats. /// /// Negative zero is generated; positive zero is not. `NaN` is not generated either. /// /// The output length is infinite. /// /// # Expected complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::float::NiceFloat; /// use malachite_base::num::random::random_negative_finite_primitive_floats; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string( /// random_negative_finite_primitive_floats::(EXAMPLE_SEED).map(NiceFloat), /// 10 /// ), /// "[-2.3484663e-27, -0.010641626, -5.8060583e-9, -2.8182442e-31, -10462.532, -821.12994, \ /// -6.303163e33, -9.50376e-15, -4.9561126e-11, -8.565163e-22, ...]" /// ); /// ``` #[inline] pub fn random_negative_finite_primitive_floats( seed: Seed, ) -> RandomPrimitiveFloatInclusiveRange { random_primitive_float_inclusive_range(seed, -T::MAX_FINITE, -T::MIN_POSITIVE_SUBNORMAL) } /// Generates random finite nonzero primitive floats. /// /// Every float within the range has an equal probability of being chosen. This does not mean that /// the distribution approximates a uniform distribution over the reals. For example, a float in /// $[1/4, 1/2)$ is as likely to be chosen as a float in $[1, 2)$, since these subranges contain an /// equal number of floats. /// /// Neither positive nor negative zero are generated. `NaN` is not generated either. /// /// The output length is infinite. /// /// # Expected complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::float::NiceFloat; /// use malachite_base::num::random::random_nonzero_finite_primitive_floats; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string( /// random_nonzero_finite_primitive_floats::(EXAMPLE_SEED).map(NiceFloat), /// 10 /// ), /// "[-2.3484663e-27, 2.287989e-18, -2.0729893e-12, 3.360012e28, -9.021723e-32, 3564911.2, \ /// -0.0000133769445, -1.8855448e18, 8.2494555e-29, 2.2178014e-38, ...]" /// ); /// ``` #[inline] pub fn random_nonzero_finite_primitive_floats( seed: Seed, ) -> NonzeroValues> { nonzero_values(random_finite_primitive_floats(seed)) } /// Generates random finite primitive floats. /// /// Every float within the range has an equal probability of being chosen. This does not mean that /// the distribution approximates a uniform distribution over the reals. For example, a float in /// $[1/4, 1/2)$ is as likely to be chosen as a float in $[1, 2)$, since these subranges contain an /// equal number of floats. /// /// Positive zero and negative zero are both generated. `NaN` is not. /// /// The output length is infinite. /// /// # Expected complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::float::NiceFloat; /// use malachite_base::num::random::random_finite_primitive_floats; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string( /// random_finite_primitive_floats::(EXAMPLE_SEED).map(NiceFloat), /// 10 /// ), /// "[-2.3484663e-27, 2.287989e-18, -2.0729893e-12, 3.360012e28, -9.021723e-32, 3564911.2, \ /// -0.0000133769445, -1.8855448e18, 8.2494555e-29, 2.2178014e-38, ...]" /// ); /// ``` #[inline] pub fn random_finite_primitive_floats( seed: Seed, ) -> RandomPrimitiveFloatInclusiveRange { random_primitive_float_inclusive_range(seed, -T::MAX_FINITE, T::MAX_FINITE) } /// Generates random positive primitive floats. /// /// Every float within the range has an equal probability of being chosen. This does not mean that /// the distribution approximates a uniform distribution over the reals. For example, a float in /// $[1/4, 1/2)$ is as likely to be chosen as a float in $[1, 2)$, since these subranges contain an /// equal number of floats. /// /// Positive zero is generated; negative zero is not. `NaN` is not generated either. /// /// The output length is infinite. /// /// # Expected complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::float::NiceFloat; /// use malachite_base::num::random::random_positive_primitive_floats; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string( /// random_positive_primitive_floats::(EXAMPLE_SEED).map(NiceFloat), /// 10 /// ), /// "[9.5715654e26, 209.6476, 386935780.0, 7.965817e30, 0.00021030706, 0.0027270128, \ /// 3.4398167e-34, 2.3397111e14, 44567765000.0, 2.3479653e21, ...]" /// ); /// ``` #[inline] pub fn random_positive_primitive_floats( seed: Seed, ) -> RandomPrimitiveFloatInclusiveRange { random_primitive_float_inclusive_range(seed, T::MIN_POSITIVE_SUBNORMAL, T::INFINITY) } /// Generates random negative primitive floats. /// /// Every float within the range has an equal probability of being chosen. This does not mean that /// the distribution approximates a uniform distribution over the reals. For example, a float in /// $(-1/2, -1/4]$ is as likely to be chosen as a float in $(-2, -1]$, since these subranges contain /// an equal number of floats. /// /// Negative zero is generated; positive zero is not. `NaN` is not generated either. /// /// The output length is infinite. /// /// # Expected complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::float::NiceFloat; /// use malachite_base::num::random::random_negative_primitive_floats; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string( /// random_negative_primitive_floats::(EXAMPLE_SEED).map(NiceFloat), /// 10 /// ), /// "[-2.3484665e-27, -0.010641627, -5.8060587e-9, -2.8182444e-31, -10462.533, -821.13, \ /// -6.3031636e33, -9.5037605e-15, -4.956113e-11, -8.565164e-22, ...]" /// ); /// ``` #[inline] pub fn random_negative_primitive_floats( seed: Seed, ) -> RandomPrimitiveFloatInclusiveRange { random_primitive_float_inclusive_range(seed, T::NEGATIVE_INFINITY, -T::MIN_POSITIVE_SUBNORMAL) } /// Generates random nonzero primitive floats. /// /// Every float within the range has an equal probability of being chosen. This does not mean that /// the distribution approximates a uniform distribution over the reals. For example, a float in /// $[1/4, 1/2)$ is as likely to be chosen as a float in $[1, 2)$, since these subranges contain an /// equal number of floats. /// /// Neither positive nor negative zero are generated. `NaN` is not generated either. /// /// The output length is infinite. /// /// # Expected complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::float::NiceFloat; /// use malachite_base::num::random::random_nonzero_primitive_floats; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string( /// random_nonzero_primitive_floats::(EXAMPLE_SEED).map(NiceFloat), /// 10 /// ), /// "[-2.3484665e-27, 2.2879888e-18, -2.0729896e-12, 3.3600117e28, -9.0217234e-32, 3564911.0, \ /// -0.000013376945, -1.885545e18, 8.249455e-29, 2.2178013e-38, ...]", /// ); /// ``` #[inline] pub fn random_nonzero_primitive_floats( seed: Seed, ) -> NonzeroValues> { nonzero_values(random_primitive_floats(seed)) } /// Generates random primitive floats. /// /// This `struct` is created by [`random_primitive_floats`]; see its documentation for more. #[derive(Clone, Debug)] pub struct RandomPrimitiveFloats { phantom: PhantomData<*const T>, pub(crate) xs: RandomUnsignedInclusiveRange, nan: u64, } impl Iterator for RandomPrimitiveFloats { type Item = T; fn next(&mut self) -> Option { self.xs.next().map(|x| { if x == self.nan { T::NAN } else { T::from_ordered_representation(x) } }) } } /// Generates random finite primitive floats. /// /// Every float has an equal probability of being chosen. This does not mean that the distribution /// approximates a uniform distribution over the reals. For example, a float in $[1/4, 1/2)$ is as /// likely to be chosen as a float in $[1, 2)$, since these subranges contain an equal number of /// floats. /// /// Positive zero, negative zero, and `NaN` are all generated. /// /// The output length is infinite. /// /// # Expected complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::float::NiceFloat; /// use malachite_base::num::random::random_primitive_floats; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string( /// random_primitive_floats::(EXAMPLE_SEED).map(NiceFloat), /// 10 /// ), /// "[-2.3484665e-27, 2.2879888e-18, -2.0729896e-12, 3.3600117e28, -9.0217234e-32, 3564911.0, \ /// -0.000013376945, -1.885545e18, 8.249455e-29, 2.2178013e-38, ...]" /// ); /// ``` #[inline] pub fn random_primitive_floats(seed: Seed) -> RandomPrimitiveFloats { let nan = T::INFINITY.to_ordered_representation() + 1; RandomPrimitiveFloats { phantom: PhantomData, xs: random_unsigned_inclusive_range(seed, 0, nan), nan, } } /// Generates positive finite primitive floats. /// /// This `struct` is created by [`special_random_positive_finite_primitive_floats`]; see its /// documentation for more. #[derive(Clone, Debug)] pub struct SpecialRandomPositiveFiniteFloats { seed: Seed, sci_exponents: GeometricRandomSignedRange, range_map: HashMap>, ranges: VariableRangeGenerator, mean_precision_n: u64, mean_precision_d: u64, phantom: PhantomData<*const T>, } impl Iterator for SpecialRandomPositiveFiniteFloats { type Item = T; fn next(&mut self) -> Option { let sci_exponent = self.sci_exponents.next().unwrap(); let mean_precision_n = self.mean_precision_n; let mean_precision_d = self.mean_precision_d; let seed = self.seed; let precisions = self.range_map.entry(sci_exponent).or_insert_with(move || { geometric_random_unsigned_inclusive_range( seed.fork(&sci_exponent.to_string()), 1, T::max_precision_for_sci_exponent(sci_exponent), mean_precision_n, mean_precision_d, ) }); let precision = precisions.next().unwrap(); let mantissa = if precision == 1 { 1 } else { // e.g. if precision is 4, generate odd values from 1001 through 1111, inclusive let x = self.ranges.next_in_range( u64::power_of_2(precision - 2), u64::power_of_2(precision - 1), ); (x << 1) | 1 }; T::from_integer_mantissa_and_exponent( mantissa, sci_exponent - i64::wrapping_from(precision) + 1, ) } } /// Generates positive finite primitive floats. /// /// Simpler floats (those with a lower absolute sci-exponent or precision) are more likely to be /// chosen. You can specify the mean absolute sci-exponent and precision by passing the numerators /// and denominators of their means. /// /// But note that the specified means are only approximate, since the distributions we are sampling /// are truncated geometric, and their exact means are somewhat annoying to deal with. The practical /// implications are that /// - The actual means are slightly lower than the specified means. /// - However, increasing the specified means increases the actual means, so this still works as a /// mechanism for controlling the sci-exponent and precision. /// - The specified sci-exponent mean must be greater than 0 and the precision mean greater than 2, /// but they may be as high as you like. /// /// Positive zero is generated; negative zero is not. `NaN` is not generated either. TODO: don't /// generate any zeros! /// /// The output length is infinite. /// /// # Expected complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::float::NiceFloat; /// use malachite_base::num::random::special_random_positive_finite_primitive_floats; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string( /// special_random_positive_finite_primitive_floats::(EXAMPLE_SEED, 10, 1, 10, 1) /// .map(NiceFloat), /// 20 /// ), /// "[0.80126953, 0.0000013709068, 0.015609741, 0.98552704, 65536.0, 0.008257866, \ /// 0.017333984, 2.25, 7.7089844, 0.00004425831, 0.40625, 24576.0, 37249.0, 1.1991882, \ /// 32.085938, 0.4375, 0.0012359619, 1536.0, 0.22912993, 0.0015716553, ...]" /// ); /// ``` pub fn special_random_positive_finite_primitive_floats( seed: Seed, mean_sci_exponent_numerator: u64, mean_sci_exponent_denominator: u64, mean_precision_numerator: u64, mean_precision_denominator: u64, ) -> SpecialRandomPositiveFiniteFloats { assert_ne!(mean_precision_denominator, 0); assert!(mean_precision_numerator > mean_precision_denominator); SpecialRandomPositiveFiniteFloats { seed: seed.fork("precisions"), sci_exponents: geometric_random_signed_inclusive_range( EXAMPLE_SEED.fork("exponents"), T::MIN_EXPONENT, T::MAX_EXPONENT, mean_sci_exponent_numerator, mean_sci_exponent_denominator, ), range_map: HashMap::new(), ranges: VariableRangeGenerator::new(seed.fork("ranges")), mean_precision_n: mean_precision_numerator, mean_precision_d: mean_precision_denominator, phantom: PhantomData, } } /// Generates negative finite primitive floats. /// /// This `struct` is created by [`special_random_negative_finite_primitive_floats`]; see its /// documentation for more. #[derive(Clone, Debug)] pub struct SpecialRandomNegativeFiniteFloats( SpecialRandomPositiveFiniteFloats, ); impl Iterator for SpecialRandomNegativeFiniteFloats { type Item = T; #[inline] fn next(&mut self) -> Option { self.0.next().map(|f| -f) } } /// Generates negative finite primitive floats. /// /// Simpler floats (those with a lower absolute sci-exponent or precision) are more likely to be /// chosen. You can specify the mean absolute sci-exponent and precision by passing the numerators /// and denominators of their means. /// /// But note that the specified means are only approximate, since the distributions we are sampling /// are truncated geometric, and their exact means are somewhat annoying to deal with. The practical /// implications are that /// - The actual means are slightly lower than the specified means. /// - However, increasing the specified means increases the actual means, so this still works as a /// mechanism for controlling the sci-exponent and precision. /// - The specified sci-exponent mean must be greater than 0 and the precision mean greater than 2, /// but they may be as high as you like. /// /// Negative zero is generated; positive zero is not. `NaN` is not generated either. /// /// The output length is infinite. /// /// # Expected complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::float::NiceFloat; /// use malachite_base::num::random::special_random_negative_finite_primitive_floats; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string( /// special_random_negative_finite_primitive_floats::(EXAMPLE_SEED, 10, 1, 10, 1) /// .map(NiceFloat), /// 20 /// ), /// "[-0.80126953, -0.0000013709068, -0.015609741, -0.98552704, -65536.0, -0.008257866, \ /// -0.017333984, -2.25, -7.7089844, -0.00004425831, -0.40625, -24576.0, -37249.0, \ /// -1.1991882, -32.085938, -0.4375, -0.0012359619, -1536.0, -0.22912993, -0.0015716553, ...]" /// ); /// ``` #[inline] pub fn special_random_negative_finite_primitive_floats( seed: Seed, mean_sci_exponent_numerator: u64, mean_sci_exponent_denominator: u64, mean_precision_numerator: u64, mean_precision_denominator: u64, ) -> SpecialRandomNegativeFiniteFloats { SpecialRandomNegativeFiniteFloats(special_random_positive_finite_primitive_floats( seed, mean_sci_exponent_numerator, mean_sci_exponent_denominator, mean_precision_numerator, mean_precision_denominator, )) } /// Generates nonzero finite primitive floats. /// /// This `struct` is created by [`special_random_nonzero_finite_primitive_floats`]; see its /// documentation for more. #[derive(Clone, Debug)] pub struct SpecialRandomNonzeroFiniteFloats { bs: RandomBools, xs: SpecialRandomPositiveFiniteFloats, } impl Iterator for SpecialRandomNonzeroFiniteFloats { type Item = T; #[inline] fn next(&mut self) -> Option { let x = self.xs.next().unwrap(); Some(if self.bs.next().unwrap() { x } else { -x }) } } /// Generates finite nonzero primitive floats. /// /// Simpler floats (those with a lower absolute sci-exponent or precision) are more likely to be /// chosen. You can specify the mean absolute sci-exponent and precision by passing the numerators /// and denominators of their means. /// /// But note that the specified means are only approximate, since the distributions we are sampling /// are truncated geometric, and their exact means are somewhat annoying to deal with. The practical /// implications are that /// - The actual means are slightly lower than the specified means. /// - However, increasing the specified means increases the actual means, so this still works as a /// mechanism for controlling the sci-exponent and precision. /// - The specified sci-exponent mean must be greater than 0 and the precision mean greater than 2, /// but they may be as high as you like. /// /// Neither positive not negative zero is generated. `NaN` is not generated either. /// /// The output length is infinite. /// /// # Expected complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::float::NiceFloat; /// use malachite_base::num::random::special_random_nonzero_finite_primitive_floats; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string( /// special_random_nonzero_finite_primitive_floats::(EXAMPLE_SEED, 10, 1, 10, 1) /// .map(NiceFloat), /// 20 /// ), /// "[-0.6328125, -9.536743e-7, -0.013671875, 0.6875, -70208.0, 0.01550293, -0.028625488, \ /// -3.3095703, -5.775879, 0.000034958124, 0.4375, 31678.0, -49152.0, -1.0, 49.885254, \ /// -0.40625, -0.0015869141, -1889.5625, -0.14140439, -0.001449585, ...]" /// ); /// ``` #[inline] pub fn special_random_nonzero_finite_primitive_floats( seed: Seed, mean_sci_exponent_numerator: u64, mean_sci_exponent_denominator: u64, mean_precision_numerator: u64, mean_precision_denominator: u64, ) -> SpecialRandomNonzeroFiniteFloats { SpecialRandomNonzeroFiniteFloats { bs: random_bools(seed.fork("bs")), xs: special_random_positive_finite_primitive_floats( seed.fork("xs"), mean_sci_exponent_numerator, mean_sci_exponent_denominator, mean_precision_numerator, mean_precision_denominator, ), } } /// Generates finite primitive floats. /// /// Simpler floats (those with a lower absolute sci-exponent or precision) are more likely to be /// chosen. You can specify the numerator and denominator of the probability that a zero will be /// generated. You can also specify the mean absolute sci-exponent and precision by passing the /// numerators and denominators of their means of the nonzero floats. /// /// But note that the specified means are only approximate, since the distributions we are sampling /// are truncated geometric, and their exact means are somewhat annoying to deal with. The practical /// implications are that /// - The actual means are slightly lower than the specified means. /// - However, increasing the specified means increases the actual means, so this still works as a /// mechanism for controlling the sci-exponent and precision. /// - The specified sci-exponent mean must be greater than 0 and the precision mean greater than 2, /// but they may be as high as you like. /// /// Positive and negative zero are both generated. `NaN` is not. /// /// The output length is infinite. /// /// # Expected complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::float::NiceFloat; /// use malachite_base::num::random::special_random_finite_primitive_floats; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string( /// special_random_finite_primitive_floats::(EXAMPLE_SEED, 10, 1, 10, 1, 1, 10) /// .map(NiceFloat), /// 20 /// ), /// "[0.65625, 0.0000014255784, 0.013183594, 0.0, -0.8125, -74240.0, -0.0078125, -0.03060913, \ /// 3.331552, 4.75, -0.000038146973, -0.3125, -27136.0, -0.0, -59392.0, -1.75, -41.1875, 0.0, \ /// 0.30940247, -0.0009765625, ...]" /// ); /// ``` #[inline] pub fn special_random_finite_primitive_floats( seed: Seed, mean_sci_exponent_numerator: u64, mean_sci_exponent_denominator: u64, mean_precision_numerator: u64, mean_precision_denominator: u64, mean_zero_p_numerator: u64, mean_zero_p_denominator: u64, ) -> WithSpecialValues> { with_special_values( seed, vec![T::ZERO, T::NEGATIVE_ZERO], mean_zero_p_numerator, mean_zero_p_denominator, &|seed_2| { special_random_nonzero_finite_primitive_floats( seed_2, mean_sci_exponent_numerator, mean_sci_exponent_denominator, mean_precision_numerator, mean_precision_denominator, ) }, ) } /// Generates positive primitive floats. /// /// Simpler floats (those with a lower absolute sci-exponent or precision) are more likely to be /// chosen. You can specify the numerator and denominator of the probability that positive infinity /// will be generated. You can also specify the mean absolute sci-exponent and precision by passing /// the numerators and denominators of their means of the finite floats. /// /// But note that the specified means are only approximate, since the distributions we are sampling /// are truncated geometric, and their exact means are somewhat annoying to deal with. The practical /// implications are that /// - The actual means are slightly lower than the specified means. /// - However, increasing the specified means increases the actual means, so this still works as a /// mechanism for controlling the sci-exponent and precision. /// - The specified sci-exponent mean must be greater than 0 and the precision mean greater than 2, /// but they may be as high as you like. /// /// Positive zero is generated; negative zero is not. `NaN` is not generated either. /// /// The output length is infinite. /// /// # Expected complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::float::NiceFloat; /// use malachite_base::num::random::special_random_positive_primitive_floats; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string( /// special_random_positive_primitive_floats::(EXAMPLE_SEED, 10, 1, 10, 1, 1, 10) /// .map(NiceFloat), /// 20 /// ), /// "[0.6328125, 9.536743e-7, 0.013671875, Infinity, 0.6875, 70208.0, 0.01550293, \ /// 0.028625488, 3.3095703, 5.775879, 0.000034958124, 0.4375, 31678.0, Infinity, 49152.0, \ /// 1.0, 49.885254, Infinity, 0.40625, 0.0015869141, ...]" /// ); /// ``` #[inline] pub fn special_random_positive_primitive_floats( seed: Seed, mean_sci_exponent_numerator: u64, mean_sci_exponent_denominator: u64, mean_precision_numerator: u64, mean_precision_denominator: u64, mean_special_p_numerator: u64, mean_special_p_denominator: u64, ) -> WithSpecialValue> { with_special_value( seed, T::INFINITY, mean_special_p_numerator, mean_special_p_denominator, &|seed_2| { special_random_positive_finite_primitive_floats( seed_2, mean_sci_exponent_numerator, mean_sci_exponent_denominator, mean_precision_numerator, mean_precision_denominator, ) }, ) } /// Generates negative primitive floats. /// /// Simpler floats (those with a lower absolute sci-exponent or precision) are more likely to be /// chosen. You can specify the numerator and denominator of the probability that negative infinity /// will be generated. You can also specify the mean absolute sci-exponent and precision by passing /// the numerators and denominators of their means of the finite floats. /// /// But note that the specified means are only approximate, since the distributions we are sampling /// are truncated geometric, and their exact means are somewhat annoying to deal with. The practical /// implications are that /// - The actual means are slightly lower than the specified means. /// - However, increasing the specified means increases the actual means, so this still works as a /// mechanism for controlling the sci-exponent and precision. /// - The specified sci-exponent mean must be greater than 0 and the precision mean greater than 2, /// but they may be as high as you like. /// /// Negative zero is generated; positive zero is not. `NaN` is not generated either. /// /// The output length is infinite. /// /// # Expected complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::float::NiceFloat; /// use malachite_base::num::random::special_random_negative_primitive_floats; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string( /// special_random_negative_primitive_floats::(EXAMPLE_SEED, 10, 1, 10, 1, 1, 10) /// .map(NiceFloat), /// 20 /// ), /// "[-0.6328125, -9.536743e-7, -0.013671875, -Infinity, -0.6875, -70208.0, -0.01550293, \ /// -0.028625488, -3.3095703, -5.775879, -0.000034958124, -0.4375, -31678.0, -Infinity, \ /// -49152.0, -1.0, -49.885254, -Infinity, -0.40625, -0.0015869141, ...]" /// ); /// ``` #[inline] pub fn special_random_negative_primitive_floats( seed: Seed, mean_sci_exponent_numerator: u64, mean_sci_exponent_denominator: u64, mean_precision_numerator: u64, mean_precision_denominator: u64, mean_special_p_numerator: u64, mean_special_p_denominator: u64, ) -> WithSpecialValue> { with_special_value( seed, T::NEGATIVE_INFINITY, mean_special_p_numerator, mean_special_p_denominator, &|seed_2| { special_random_negative_finite_primitive_floats( seed_2, mean_sci_exponent_numerator, mean_sci_exponent_denominator, mean_precision_numerator, mean_precision_denominator, ) }, ) } /// Generates nonzero primitive floats. /// /// Simpler floats (those with a lower absolute sci-exponent or precision) are more likely to be /// chosen. You can specify the numerator and denominator of the probability that an infinity will /// be generated. You can also specify the mean absolute sci-exponent and precision by passing the /// numerators and denominators of their means of the finite floats. /// /// But note that the specified means are only approximate, since the distributions we are sampling /// are truncated geometric, and their exact means are somewhat annoying to deal with. The practical /// implications are that /// - The actual means are slightly lower than the specified means. /// - However, increasing the specified means increases the actual means, so this still works as a /// mechanism for controlling the sci-exponent and precision. /// - The specified sci-exponent mean must be greater than 0 and the precision mean greater than 2, /// but they may be as high as you like. /// /// Neither negative not positive zero is generated. `NaN` is not generated either. /// /// The output length is infinite. /// /// # Expected complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::float::NiceFloat; /// use malachite_base::num::random::special_random_nonzero_primitive_floats; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string( /// special_random_nonzero_primitive_floats::(EXAMPLE_SEED, 10, 1, 10, 1, 1, 10) /// .map(NiceFloat), /// 20 /// ), /// "[0.65625, 0.0000014255784, 0.013183594, Infinity, -0.8125, -74240.0, -0.0078125, \ /// -0.03060913, 3.331552, 4.75, -0.000038146973, -0.3125, -27136.0, -Infinity, -59392.0, \ /// -1.75, -41.1875, Infinity, 0.30940247, -0.0009765625, ...]" /// ); /// ``` #[inline] pub fn special_random_nonzero_primitive_floats( seed: Seed, mean_sci_exponent_numerator: u64, mean_sci_exponent_denominator: u64, mean_precision_numerator: u64, mean_precision_denominator: u64, mean_special_p_numerator: u64, mean_special_p_denominator: u64, ) -> WithSpecialValues> { with_special_values( seed, vec![T::INFINITY, T::NEGATIVE_INFINITY], mean_special_p_numerator, mean_special_p_denominator, &|seed_2| { special_random_nonzero_finite_primitive_floats( seed_2, mean_sci_exponent_numerator, mean_sci_exponent_denominator, mean_precision_numerator, mean_precision_denominator, ) }, ) } /// Generates primitive floats. /// /// Simpler floats (those with a lower absolute sci-exponent or precision) are more likely to be /// chosen. You can specify the numerator and denominator of the probability that zero, infinity, or /// NaN will be generated. You can also specify the mean absolute sci-exponent and precision by /// passing the numerators and denominators of their means of the finite floats. /// /// But note that the specified means are only approximate, since the distributions we are sampling /// are truncated geometric, and their exact means are somewhat annoying to deal with. The practical /// implications are that /// - The actual means are slightly lower than the specified means. /// - However, increasing the specified means increases the actual means, so this still works as a /// mechanism for controlling the sci-exponent and precision. /// - The specified sci-exponent mean must be greater than 0 and the precision mean greater than 2, /// but they may be as high as you like. /// /// The output length is infinite. /// /// # Expected complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::float::NiceFloat; /// use malachite_base::num::random::special_random_primitive_floats; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string( /// special_random_primitive_floats::(EXAMPLE_SEED, 10, 1, 10, 1, 1, 10) /// .map(NiceFloat), /// 20 /// ), /// "[0.65625, 0.0000014255784, 0.013183594, Infinity, -0.8125, -74240.0, -0.0078125, \ /// -0.03060913, 3.331552, 4.75, -0.000038146973, -0.3125, -27136.0, Infinity, -59392.0, \ /// -1.75, -41.1875, Infinity, 0.30940247, -0.0009765625, ...]" /// ); /// ``` #[inline] pub fn special_random_primitive_floats( seed: Seed, mean_sci_exponent_numerator: u64, mean_sci_exponent_denominator: u64, mean_precision_numerator: u64, mean_precision_denominator: u64, mean_special_p_numerator: u64, mean_special_p_denominator: u64, ) -> WithSpecialValues> { with_special_values( seed, vec![T::ZERO, T::NEGATIVE_ZERO, T::INFINITY, T::NEGATIVE_INFINITY, T::NAN], mean_special_p_numerator, mean_special_p_denominator, &|seed_2| { special_random_nonzero_finite_primitive_floats( seed_2, mean_sci_exponent_numerator, mean_sci_exponent_denominator, mean_precision_numerator, mean_precision_denominator, ) }, ) } // normalized sci_exponent and raw mantissas in input, adjusted sci_exponent and mantissas in output fn mantissas_inclusive( mut sci_exponent: i64, mut am: u64, mut bm: u64, precision: u64, ) -> Option<(i64, u64, u64)> { assert_ne!(precision, 0); let p: u64 = if sci_exponent < T::MIN_NORMAL_EXPONENT { let ab = am.significant_bits(); let bb = bm.significant_bits(); assert_eq!(ab, bb); ab - precision } else { am.set_bit(T::MANTISSA_WIDTH); bm.set_bit(T::MANTISSA_WIDTH); T::MANTISSA_WIDTH + 1 - precision }; let mut lo = am.shr_round(p, Up).0; if lo.even() { lo += 1; } let mut hi = bm.shr_round(p, Down).0; if hi == 0 { return None; } else if hi.even() { hi -= 1; } if sci_exponent >= T::MIN_NORMAL_EXPONENT { sci_exponent -= i64::wrapping_from(T::MANTISSA_WIDTH); } sci_exponent += i64::wrapping_from(p); if lo > hi { None } else { Some((sci_exponent, lo >> 1, hi >> 1)) } } #[doc(hidden)] #[derive(Clone, Debug)] pub struct SpecialRandomPositiveFiniteFloatInclusiveRange { phantom: PhantomData<*const T>, am: u64, // raw mantissa bm: u64, ae: i64, // sci_exponent be: i64, sci_exponents: GeometricRandomSignedRange, precision_range_map: HashMap>, precision_indices: GeometricRandomNaturalValues, ranges: VariableRangeGenerator, } impl Iterator for SpecialRandomPositiveFiniteFloatInclusiveRange { type Item = T; fn next(&mut self) -> Option { let sci_exponent = self.sci_exponents.next().unwrap(); let ae = self.ae; let be = self.be; let am = self.am; let bm = self.bm; let precision_ranges = self .precision_range_map .entry(sci_exponent) .or_insert_with(|| { let am = if sci_exponent == ae { am } else { T::from_integer_mantissa_and_exponent(1, sci_exponent) .unwrap() .raw_mantissa() }; let bm = if sci_exponent == be { bm } else { T::from_integer_mantissa_and_exponent(1, sci_exponent + 1) .unwrap() .next_lower() .raw_mantissa() }; (1..=T::max_precision_for_sci_exponent(sci_exponent)) .filter_map(|p| mantissas_inclusive::(sci_exponent, am, bm, p)) .collect_vec() }); assert!(!precision_ranges.is_empty()); let i = self.precision_indices.next().unwrap() % precision_ranges.len(); let t = precision_ranges[i]; let mantissa = (self.ranges.next_in_inclusive_range(t.1, t.2) << 1) | 1; Some(T::from_integer_mantissa_and_exponent(mantissa, t.0).unwrap()) } } fn special_random_positive_finite_float_inclusive_range( seed: Seed, a: T, b: T, mean_sci_exponent_numerator: u64, mean_sci_exponent_denominator: u64, mean_precision_numerator: u64, mean_precision_denominator: u64, ) -> SpecialRandomPositiveFiniteFloatInclusiveRange { assert!(a.is_finite()); assert!(b.is_finite()); assert!(a > T::ZERO); assert!(a <= b); let (am, ae) = a.raw_mantissa_and_exponent(); let (bm, be) = b.raw_mantissa_and_exponent(); let ae = if ae == 0 { i64::wrapping_from(am.significant_bits()) + T::MIN_EXPONENT - 1 } else { i64::wrapping_from(ae) - T::MAX_EXPONENT }; let be = if be == 0 { i64::wrapping_from(bm.significant_bits()) + T::MIN_EXPONENT - 1 } else { i64::wrapping_from(be) - T::MAX_EXPONENT }; SpecialRandomPositiveFiniteFloatInclusiveRange { phantom: PhantomData, am, bm, ae, be, sci_exponents: geometric_random_signed_inclusive_range( seed.fork("exponents"), ae, be, mean_sci_exponent_numerator, mean_sci_exponent_denominator, ), precision_range_map: HashMap::new(), precision_indices: geometric_random_unsigneds( seed.fork("precisions"), mean_precision_numerator, mean_precision_denominator, ), ranges: VariableRangeGenerator::new(seed.fork("ranges")), } } #[allow(clippy::large_enum_variant)] #[doc(hidden)] #[derive(Clone, Debug)] pub enum SpecialRandomFiniteFloatInclusiveRange { AllPositive(SpecialRandomPositiveFiniteFloatInclusiveRange), AllNegative(SpecialRandomPositiveFiniteFloatInclusiveRange), PositiveAndNegative( RandomBools, SpecialRandomPositiveFiniteFloatInclusiveRange, SpecialRandomPositiveFiniteFloatInclusiveRange, ), } impl Iterator for SpecialRandomFiniteFloatInclusiveRange { type Item = T; fn next(&mut self) -> Option { match self { SpecialRandomFiniteFloatInclusiveRange::AllPositive(ref mut xs) => xs.next(), SpecialRandomFiniteFloatInclusiveRange::AllNegative(ref mut xs) => { xs.next().map(|x| -x) } SpecialRandomFiniteFloatInclusiveRange::PositiveAndNegative( ref mut bs, ref mut xs, ref mut ys, ) => { if bs.next().unwrap() { xs.next() } else { ys.next().map(|x| -x) } } } } } fn special_random_finite_float_inclusive_range( seed: Seed, a: T, b: T, mean_sci_exponent_numerator: u64, mean_sci_exponent_denominator: u64, mean_precision_numerator: u64, mean_precision_denominator: u64, ) -> SpecialRandomFiniteFloatInclusiveRange { assert!(a.is_finite()); assert!(b.is_finite()); assert_ne!(a, T::ZERO); assert_ne!(b, T::ZERO); assert!(a <= b); if a > T::ZERO { SpecialRandomFiniteFloatInclusiveRange::AllPositive( special_random_positive_finite_float_inclusive_range( seed, a, b, mean_sci_exponent_numerator, mean_sci_exponent_denominator, mean_precision_numerator, mean_precision_denominator, ), ) } else if b < T::ZERO { SpecialRandomFiniteFloatInclusiveRange::AllNegative( special_random_positive_finite_float_inclusive_range( seed, -b, -a, mean_sci_exponent_numerator, mean_sci_exponent_denominator, mean_precision_numerator, mean_precision_denominator, ), ) } else { SpecialRandomFiniteFloatInclusiveRange::PositiveAndNegative( random_bools(seed.fork("bs")), special_random_positive_finite_float_inclusive_range( seed, T::MIN_POSITIVE_SUBNORMAL, b, mean_sci_exponent_numerator, mean_sci_exponent_denominator, mean_precision_numerator, mean_precision_denominator, ), special_random_positive_finite_float_inclusive_range( seed, T::MIN_POSITIVE_SUBNORMAL, -a, mean_sci_exponent_numerator, mean_sci_exponent_denominator, mean_precision_numerator, mean_precision_denominator, ), ) } } /// Generates random primitive floats in a range. /// /// This `enum` is created by [`special_random_primitive_float_range`]; see its documentation for /// more. #[allow(clippy::large_enum_variant)] #[derive(Clone, Debug)] pub enum SpecialRandomFloatInclusiveRange { OnlySpecial(RandomValuesFromVec), NoSpecial(Box>), Special(Box>>), } impl Iterator for SpecialRandomFloatInclusiveRange { type Item = T; fn next(&mut self) -> Option { match self { SpecialRandomFloatInclusiveRange::OnlySpecial(ref mut xs) => xs.next(), SpecialRandomFloatInclusiveRange::NoSpecial(ref mut xs) => xs.next(), SpecialRandomFloatInclusiveRange::Special(ref mut xs) => xs.next(), } } } /// Generates random primitive floats in the half-open interval $[a, b)$. /// /// Simpler floats (those with a lower absolute sci-exponent or precision) are more likely to be /// chosen. You can specify the numerator and denominator of the probability that any special values /// (positive or negative zero or infinity) are generated, provided that they are in the range. You /// can also specify the mean absolute sci-exponent and precision by passing the numerators and /// denominators of their means of the finite floats. /// /// But note that the means are only approximate, since the distributions we are sampling are /// truncated geometric, and their exact means are somewhat annoying to deal with. The practical /// implications are that /// - The actual mean is lower than the specified means. /// - However, increasing the approximate mean increases the actual means, so this still works as a /// mechanism for controlling the sci-exponent and precision. /// - The specified sci-exponent mean must be greater the smallest absolute of any sci-exponent of a /// float in the range, and the precision mean greater than 2, but they may be as high as you /// like. /// /// But note that the specified means are only approximate, since the distributions we are sampling /// are truncated geometric, and their exact means are somewhat annoying to deal with. The practical /// implications are that /// - The actual means are slightly lower than the specified means. /// - However, increasing the specified means increases the actual means, so this still works as a /// mechanism for controlling the sci-exponent and precision. /// - The specified sci-exponent mean must be greater the smallest absolute value of any /// sci-exponent of a float in the range, and the precision mean greater than 2, but they may be /// as high as you like. /// /// `NaN` is never generated. /// /// The output length is infinite. /// /// # Expected complexity per iteration /// Constant time and additional memory. /// /// # Panics /// Panics if $a$ or $b$ are `NaN`, if $a$ is greater than or equal to $b$ in the `NiceFloat` /// ordering, if any of the denominators are zero, if the special probability is greater than 1, if /// the mean precision is less than 2, or if the mean sci-exponent is less than or equal to the /// minimum absolute value of any sci-exponent in the range. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::float::NiceFloat; /// use malachite_base::num::random::special_random_primitive_float_range; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string( /// special_random_primitive_float_range::( /// EXAMPLE_SEED, /// core::f32::consts::E, /// core::f32::consts::PI, /// 10, /// 1, /// 10, /// 1, /// 1, /// 100 /// ) /// .map(NiceFloat), /// 20 /// ), /// "[2.9238281, 2.953125, 3.0, 2.8671875, 2.8125, 3.125, 3.015625, 2.8462658, 3.140625, \ /// 2.875, 3.0, 2.75, 3.0, 2.71875, 2.75, 3.0214844, 2.970642, 3.0179443, 2.968872, 2.75, ...]" /// ); /// ``` pub fn special_random_primitive_float_range( seed: Seed, a: T, b: T, mean_sci_exponent_numerator: u64, mean_sci_exponent_denominator: u64, mean_precision_numerator: u64, mean_precision_denominator: u64, mean_special_p_numerator: u64, mean_special_p_denominator: u64, ) -> SpecialRandomFloatInclusiveRange { assert!(!a.is_nan()); assert!(!b.is_nan()); assert!(NiceFloat(a) < NiceFloat(b)); special_random_primitive_float_inclusive_range( seed, a, b.next_lower(), mean_sci_exponent_numerator, mean_sci_exponent_denominator, mean_precision_numerator, mean_precision_denominator, mean_special_p_numerator, mean_special_p_denominator, ) } /// Generates random primitive floats in the closed interval $[a, b]$. /// /// Simpler floats (those with a lower absolute sci-exponent or precision) are more likely to be /// chosen. You can specify the numerator and denominator of the probability that any special values /// (positive or negative zero or infinity) are generated, provided that they are in the range. You /// can also specify the mean absolute sci-exponent and precision by passing the numerators and /// denominators of their means of the finite floats. /// /// But note that the specified means are only approximate, since the distributions we are sampling /// are truncated geometric, and their exact means are somewhat annoying to deal with. The practical /// implications are that /// - The actual means are slightly lower than the specified means. /// - However, increasing the specified means increases the actual means, so this still works as a /// mechanism for controlling the sci-exponent and precision. /// - The specified sci-exponent mean must be greater the smallest absolute value of any /// sci-exponent of a float in the range, and the precision mean greater than 2, but they may be /// as high as you like. /// /// `NaN` is never generated. /// /// The output length is infinite. /// /// # Expected complexity per iteration /// Constant time and additional memory. /// /// # Panics /// Panics if $a$ or $b$ are `NaN`, if $a$ is greater than $b$ in the `NiceFloat` ordering, if any /// of the denominators are zero, if the special probability is greater than 1, if the mean /// precision is less than 2, or if the mean sci-exponent is less than or equal to the minimum /// absolute value of any sci-exponent in the range. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::float::NiceFloat; /// use malachite_base::num::random::special_random_primitive_float_inclusive_range; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string( /// special_random_primitive_float_inclusive_range::( /// EXAMPLE_SEED, /// core::f32::consts::E, /// core::f32::consts::PI, /// 10, /// 1, /// 10, /// 1, /// 1, /// 100 /// ) /// .map(NiceFloat), /// 20 /// ), /// "[2.9238281, 2.953125, 3.0, 2.8671875, 2.8125, 3.125, 3.015625, 2.8462658, 3.140625, \ /// 2.875, 3.0, 2.75, 3.0, 2.71875, 2.75, 3.0214844, 2.970642, 3.0179443, 2.968872, 2.75, ...]" /// ); /// ``` pub fn special_random_primitive_float_inclusive_range( seed: Seed, mut a: T, mut b: T, mean_sci_exponent_numerator: u64, mean_sci_exponent_denominator: u64, mean_precision_numerator: u64, mean_precision_denominator: u64, mean_special_p_numerator: u64, mean_special_p_denominator: u64, ) -> SpecialRandomFloatInclusiveRange { assert!(!a.is_nan()); assert!(!b.is_nan()); assert!(NiceFloat(a) <= NiceFloat(b)); assert_ne!(mean_special_p_denominator, 0); assert!(mean_special_p_numerator <= mean_special_p_denominator); assert_ne!(mean_precision_denominator, 0); assert!(mean_precision_numerator > mean_precision_denominator); let only_special = a == T::INFINITY || b == T::NEGATIVE_INFINITY || a == T::ZERO && b == T::ZERO; let mut special_values = Vec::new(); if a == T::NEGATIVE_INFINITY { special_values.push(a); a = -T::MAX_FINITE; } if b == T::INFINITY { special_values.push(b); b = T::MAX_FINITE; } if NiceFloat(a) <= NiceFloat(T::NEGATIVE_ZERO) && NiceFloat(b) >= NiceFloat(T::NEGATIVE_ZERO) { special_values.push(T::NEGATIVE_ZERO); } if NiceFloat(a) <= NiceFloat(T::ZERO) && NiceFloat(b) >= NiceFloat(T::ZERO) { special_values.push(T::ZERO); } if a == T::ZERO { a = T::MIN_POSITIVE_SUBNORMAL; } if b == T::ZERO { b = -T::MIN_POSITIVE_SUBNORMAL; } if only_special { SpecialRandomFloatInclusiveRange::OnlySpecial(random_values_from_vec(seed, special_values)) } else if special_values.is_empty() { SpecialRandomFloatInclusiveRange::NoSpecial(Box::new( special_random_finite_float_inclusive_range( seed, a, b, mean_sci_exponent_numerator, mean_sci_exponent_denominator, mean_precision_numerator, mean_precision_denominator, ), )) } else { SpecialRandomFloatInclusiveRange::Special(Box::new(with_special_values( seed, special_values, mean_special_p_numerator, mean_special_p_denominator, &|seed| { special_random_finite_float_inclusive_range( seed, a, b, mean_sci_exponent_numerator, mean_sci_exponent_denominator, mean_precision_numerator, mean_precision_denominator, ) }, ))) } } /// Generates unsigneds sampled from ranges. A single generator can sample from different ranges of /// different types. /// /// This `struct` is created by [`VariableRangeGenerator::new`]; see its documentation for more. #[derive(Clone, Debug)] pub struct VariableRangeGenerator { xs: RandomPrimitiveInts, x: u32, in_inner_loop: bool, remaining_x_bits: u64, } impl VariableRangeGenerator { /// Generates unsigneds sampled from ranges. A single generator can sample from different ranges /// of different types. /// /// If you only need to generate values from a single range, it is slightly more efficient to /// use [`random_unsigned_bit_chunks`], [`random_unsigneds_less_than`], /// [`random_unsigned_range`], or [`random_unsigned_inclusive_range`]. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::num::random::VariableRangeGenerator; /// use malachite_base::random::EXAMPLE_SEED; /// /// let mut generator = VariableRangeGenerator::new(EXAMPLE_SEED); /// assert_eq!(generator.next_bit_chunk::(10), 881); /// assert_eq!(generator.next_less_than::(100), 34); /// assert_eq!(generator.next_in_range::(10, 20), 16); /// assert_eq!(generator.next_in_inclusive_range::(10, 20), 14); /// ``` pub fn new(seed: Seed) -> VariableRangeGenerator { VariableRangeGenerator { xs: random_primitive_ints(seed), x: 0, in_inner_loop: false, remaining_x_bits: 0, } } /// Uniformly generates a `bool`. /// /// $$ /// $P(\text{false}) = P(\text{true}) = \frac{1}{2}$. /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::num::random::VariableRangeGenerator; /// use malachite_base::random::EXAMPLE_SEED; /// /// let mut xs = Vec::with_capacity(10); /// let mut generator = VariableRangeGenerator::new(EXAMPLE_SEED); /// for _ in 0..10 { /// xs.push(generator.next_bool()); /// } /// assert_eq!( /// xs, /// &[true, false, true, false, true, true, true, true, true, false] /// ); /// ``` pub fn next_bool(&mut self) -> bool { self.xs.next().unwrap().odd() } /// Uniformly generates an unsigned integer with up to some number of bits. /// /// $$ /// P(x) = \\begin{cases} /// 2^{-c} & \text{if} \\quad 0 \\leq x < 2^c, \\\\ /// 0 & \text{if} \\quad \\text{otherwise,} /// \\end{cases} /// $$ /// where $c$ is `chunk_size`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `chunk_size` is zero or greater than the width of the type. /// /// # Examples /// ``` /// use malachite_base::num::random::VariableRangeGenerator; /// use malachite_base::random::EXAMPLE_SEED; /// /// let mut xs = Vec::with_capacity(10); /// let mut generator = VariableRangeGenerator::new(EXAMPLE_SEED); /// for _ in 0..10 { /// xs.push(generator.next_bit_chunk::(3)); /// } /// assert_eq!(xs, &[1, 6, 5, 7, 6, 3, 1, 2, 4, 5]); /// ``` pub fn next_bit_chunk(&mut self, chunk_size: u64) -> T { assert_ne!(chunk_size, 0); assert!(chunk_size <= T::WIDTH); let mut y = T::ZERO; let mut remaining_y_bits = chunk_size; loop { if !self.in_inner_loop { self.x = self.xs.next().unwrap(); self.remaining_x_bits = u32::WIDTH; self.in_inner_loop = true; } while self.remaining_x_bits != 0 { let y_index = chunk_size - remaining_y_bits; if self.remaining_x_bits <= remaining_y_bits { y |= T::wrapping_from(self.x) << y_index; remaining_y_bits -= self.remaining_x_bits; self.remaining_x_bits = 0; } else { y |= T::wrapping_from(self.x).mod_power_of_2(remaining_y_bits) << y_index; self.x >>= remaining_y_bits; self.remaining_x_bits -= remaining_y_bits; remaining_y_bits = 0; } if remaining_y_bits == 0 { return y; } } self.in_inner_loop = false; } } /// Uniformly generates a random unsigned integer less than a positive limit. /// /// $$ /// P(x) = \\begin{cases} /// \frac{1}{\\ell} & \text{if} \\quad x < \\ell \\\\ /// 0 & \\text{otherwise} /// \\end{cases} /// $$ /// where $\ell$ is `limit`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `limit` is 0. /// /// # Examples /// ``` /// use malachite_base::num::random::VariableRangeGenerator; /// use malachite_base::random::EXAMPLE_SEED; /// /// let mut xs = Vec::with_capacity(10); /// let mut generator = VariableRangeGenerator::new(EXAMPLE_SEED); /// for _ in 0..10 { /// xs.push(generator.next_less_than(10u8)); /// } /// assert_eq!(xs, &[1, 7, 5, 4, 6, 4, 2, 8, 1, 7]); /// ``` pub fn next_less_than(&mut self, limit: T) -> T { assert_ne!(limit, T::ZERO); if limit == T::ONE { T::ZERO } else { let chunk_size = limit.ceiling_log_base_2(); loop { let x = self.next_bit_chunk(chunk_size); if x < limit { return x; } } } } /// Uniformly generates a random unsigned integer in the half-open interval $[a, b)$. /// /// $a$ must be less than $b$. This function cannot create a range that includes `T::MAX`; for /// that, use [`next_in_inclusive_range`](Self::next_in_inclusive_range). /// /// $$ /// P(x) = \\begin{cases} /// \frac{1}{b-a} & \text{if} \\quad a \leq x < b, \\\\ /// 0 & \\text{otherwise.} /// \\end{cases} /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if $a \geq b$. /// /// # Examples /// ``` /// use malachite_base::num::random::VariableRangeGenerator; /// use malachite_base::random::EXAMPLE_SEED; /// /// let mut xs = Vec::with_capacity(10); /// let mut generator = VariableRangeGenerator::new(EXAMPLE_SEED); /// for _ in 0..10 { /// xs.push(generator.next_in_range(10u8, 20)); /// } /// assert_eq!(xs, &[11, 17, 15, 14, 16, 14, 12, 18, 11, 17]); /// ``` pub fn next_in_range(&mut self, a: T, b: T) -> T { self.next_less_than(b - a) + a } /// Uniformly generates a random unsigned integer in the closed interval $[a, b]$. /// /// $a$ must be less than or equal to $b$. /// /// $$ /// P(x) = \\begin{cases} /// \frac{1}{b-a+1} & \text{if} \\quad a \leq x \leq b, \\\\ /// 0 & \\text{otherwise.} /// \\end{cases} /// $$ /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if $a > b$. /// /// # Examples /// ``` /// use malachite_base::num::random::VariableRangeGenerator; /// use malachite_base::random::EXAMPLE_SEED; /// /// let mut xs = Vec::with_capacity(10); /// let mut generator = VariableRangeGenerator::new(EXAMPLE_SEED); /// for _ in 0..10 { /// xs.push(generator.next_in_inclusive_range(10u8, 19)); /// } /// assert_eq!(xs, &[11, 17, 15, 14, 16, 14, 12, 18, 11, 17]); /// ``` pub fn next_in_inclusive_range(&mut self, a: T, b: T) -> T { if a == T::ZERO && b == T::MAX { self.next_bit_chunk(T::WIDTH) } else { self.next_less_than(b - a + T::ONE) + a } } } /// Iterators that generate primitive integers from geometric-like distributions. pub mod geometric; /// Iterators that generate primitive integers that tend to have long runs of binary 0s and 1s. /// /// Integers with long runs of 0s and 1s are good for testing; they're more likely to result in /// carries and borrows than uniformly random integers. This idea was inspired by GMP's /// `mpz_rrandomb` function, although striped integer generators are more general: they can also /// produce integers with runs that are shorter than average, so that they tend to contain /// alternating bits like $1010101$. /// /// Let the average length of a run of 0s and 1s be $m$. The functions in this module allow the user /// to specify a rational $m$ through the parameters `m_numerator` and `m_denominator`. Since any /// binary sequence has an average run length of at least 1, $m$ must be at least 1; but if it is /// exactly 1 then the sequence is strictly alternating and no longer random, so 1 is not allowed /// either. if $m$ is between 1 and 2, the sequence is less likely to have two equal adjacent bits /// than a uniformly random sequence. If $m$ is 2, the sequence is uniformly random. If $m$ is /// greater than 2 (the most useful case), the sequence tends to have long runs of 0s and 1s. /// /// # Details /// /// A random striped sequence with parameter $m \geq 1$ is an infinite sequence of bits, defined as /// follows. The first bit is 0 or 1 with equal probability. Every subsequent bit has a $1/m$ /// probability of being different than the preceding bit. Notice that every sequence has an equal /// probability as its negation. Also, if $m > 1$, any sequence has a nonzero probability of /// occurring. /// /// * $m=1$ is disallowed. If it were allowed, the sequence would be either /// $01010101010101010101\ldots$ or $10101010101010101010\ldots$. /// * If $12$, the sequence tends to have longer runs of 0s and 1s than a uniformly random /// sequence. A sample sequence with $m=32$ is $1111111111111111110000000011111111111111\ldots$. /// /// An alternative way to generate a striped sequence is to start with 0 or 1 with equal probability /// and then determine the length of each block of equal bits using a geometric distribution with /// mean $m$. In practice, this isn't any more efficient than the naive algorithm. /// /// We can generate a random striped unsigned integer of type `T` by taking the first $W$ bits of a /// striped sequence. Fixing the parameter $m$ defines a distribution over `T`s. A few things can be /// said about the probability $P_m(n)$ of an unsigned integer $n$ of width $W$ being generated: /// * $P_m(n) = P_m(\lnot n)$ /// * $P_m(0) = P_m(2^W-1) = \frac{1}{2} \left ( 1-\frac{1}{m} \right )^{W-1}$. If $m>2$, this is /// the maximum probability achieved; if $m<2$, the minimum. /// * $P_m(\lfloor 2^W/3 \rfloor) = P_m(\lfloor 2^{W+1}/3 \rfloor) = 1/(2m^{W-1})$. If $m>2$, this /// is the minimum probability achieved; if $m<2$, the maximum. /// * Because of these distributions' symmetry, their mean is $(2^W-1)/2$ and their skewness is 0. /// It's hard to say anything about their standard deviations or excess kurtoses, although these /// can be computed quickly for specific values of $m$ when $W$ is 8 or 16. /// /// We can similarly generate random striped signed integers of width $W$. The sign bit is chosen /// uniformly, and the remaining $W-1$ are taken from a striped sequence. /// /// To generate striped integers from a range, the integers are constructed one bit at a time. Some /// bits are forced; they must be 0 or 1 in order for the final integer to be within the specified /// range. If a bit is _not_ forced, it is different from the preceding bit with probability $1/m$. pub mod striped; malachite-base-0.4.16/src/num/random/striped.rs000064400000000000000000001677201046102023000174560ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::bools::random::{random_bools, weighted_random_bools, RandomBools, WeightedRandomBools}; use crate::iterators::{nonzero_values, NonzeroValues}; use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::{ExactFrom, WrappingFrom}; use crate::num::random::geometric::{ geometric_random_unsigned_inclusive_range, geometric_random_unsigneds, mean_to_p_with_min, GeometricRandomNaturalValues, }; use crate::num::random::{ random_unsigned_inclusive_range, random_unsigned_range, RandomUnsignedInclusiveRange, RandomUnsignedRange, }; use crate::random::Seed; use itertools::Itertools; use std::iter::{repeat, Repeat}; use std::marker::PhantomData; /// Generates bits from a striped random sequence. /// /// See [here](self) for more information. #[derive(Clone, Debug)] pub struct StripedBitSource { first_bit_of_block: bool, previous_bit: bool, bs: RandomBools, xs: WeightedRandomBools, } impl Iterator for StripedBitSource { type Item = bool; /// Gets a bit from this `StripedBitSource`. If this function is being called for the first /// time, the probabilities of a `true` or a `false` are equal. On subsequent calls, the /// probability of getting a bit different from the previous one is $1 / m$. /// /// To reset the bit source, so that the next call to `next` has equal probabilities of `true` /// or `false`, call [`end_block`](Self::end_block). /// /// # Expected complexity /// Constant time and additional memory. #[inline] fn next(&mut self) -> Option { self.previous_bit = if self.first_bit_of_block { self.first_bit_of_block = false; self.bs.next().unwrap() } else { self.previous_bit ^ self.xs.next().unwrap() }; Some(self.previous_bit) } } impl StripedBitSource { /// Creates a new `StripedBitSource`. /// /// The mean run length is $m$, where $m$ is `m_numerator / m_denominator`. /// /// # Expected complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `m_denominator` is zero or if `m_numerator <= m_denominator`. /// /// # Examples /// ``` /// use malachite_base::num::random::striped::StripedBitSource; /// use malachite_base::random::EXAMPLE_SEED; /// /// let bit_source = StripedBitSource::new(EXAMPLE_SEED, 4, 1); /// let mut string = String::with_capacity(40); /// for bit in bit_source.take(40) { /// if bit { /// string.push('1'); /// } else { /// string.push('0'); /// } /// } /// assert_eq!(string, "0000000101100110000000011110000000001111"); /// ``` pub fn new(seed: Seed, m_numerator: u64, m_denominator: u64) -> StripedBitSource { assert_ne!(m_denominator, 0); assert!(m_numerator > m_denominator); let (numerator, denominator) = mean_to_p_with_min(1u64, m_numerator, m_denominator); StripedBitSource { first_bit_of_block: true, previous_bit: false, bs: random_bools(seed.fork("bs")), xs: weighted_random_bools(seed.fork("xs"), numerator, numerator + denominator), } } /// Resets this `StripedBitSource`, so that the next time [`next`](Self::next) is called, the /// probabilities of `true` or `false` will be equal. /// /// # Expected complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::num::random::striped::StripedBitSource; /// use malachite_base::random::EXAMPLE_SEED; /// /// fn generate_string(bit_source: &mut StripedBitSource) -> String { /// let mut string = String::with_capacity(40); /// for bit in bit_source.take(40) { /// if bit { /// string.push('1'); /// } else { /// string.push('0'); /// } /// } /// string /// } /// /// let mut bit_source = StripedBitSource::new(EXAMPLE_SEED, 1000000, 1); /// let mut strings = Vec::with_capacity(5); /// for _ in 0..5 { /// strings.push(generate_string(&mut bit_source)); /// bit_source.end_block(); /// } /// assert_eq!( /// strings, /// &[ /// "0000000000000000000000000000000000000000", /// "0000000000000000000000000000000000000000", /// "0000000000000000000000000000000000000000", /// "1111111111111111111111111111111111111111", /// "0000000000000000000000000000000000000000" /// ] /// ); /// ``` pub fn end_block(&mut self) { self.first_bit_of_block = true; } /// Sets the previous bit of a `StripedBitSource`. This will affect the probability of the next /// bit. /// /// # Expected complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::num::random::striped::StripedBitSource; /// use malachite_base::random::EXAMPLE_SEED; /// /// fn generate_string(bit_source: &mut StripedBitSource) -> String { /// let mut string = String::with_capacity(40); /// for bit in bit_source.take(40) { /// if bit { /// string.push('1'); /// } else { /// string.push('0'); /// } /// } /// string /// } /// /// let mut bit_source = StripedBitSource::new(EXAMPLE_SEED, 1000000, 1); /// bit_source.next(); /// let mut strings = Vec::with_capacity(3); /// bit_source.set_previous_bit(true); /// strings.push(generate_string(&mut bit_source)); /// bit_source.set_previous_bit(false); /// strings.push(generate_string(&mut bit_source)); /// bit_source.set_previous_bit(true); /// strings.push(generate_string(&mut bit_source)); /// assert_eq!( /// strings, /// &[ /// "1111111111111111111111111111111111111111", /// "0000000000000000000000000000000000000000", /// "1111111111111111111111111111111111111111", /// ] /// ); /// ``` pub fn set_previous_bit(&mut self, bit: bool) { self.previous_bit = bit; } } /// Generates random unsigned integers from a random striped distribution. /// /// This `struct` is created by [`striped_random_unsigned_bit_chunks`]; see its documentation for /// more. #[derive(Clone, Debug)] pub struct StripedRandomUnsignedBitChunks { phantom: PhantomData<*const T>, bits: StripedBitSource, chunk_size: usize, } impl Iterator for StripedRandomUnsignedBitChunks { type Item = T; fn next(&mut self) -> Option { self.bits.end_block(); let mut x = T::ZERO; for bit in (&mut self.bits).take(self.chunk_size) { x <<= 1; if bit { x |= T::ONE; } } Some(x) } } /// Generates random signed integers from a random striped distribution. /// /// This `struct` is created by [`striped_random_signeds`]; see its documentation for more. #[derive(Clone, Debug)] pub struct StripedRandomSigneds { phantom: PhantomData<*const T>, bits: StripedBitSource, bs: RandomBools, } impl Iterator for StripedRandomSigneds { type Item = T; fn next(&mut self) -> Option { self.bits.end_block(); let mut x = T::ZERO; for bit in (&mut self.bits).take(usize::wrapping_from(T::WIDTH) - 1) { x <<= 1; if bit { x |= T::ONE; } } if self.bs.next().unwrap() { x.set_bit(T::WIDTH - 1); } Some(x) } } /// Generates random natural (non-negative) signed integers from a random striped distribution. /// /// This `struct` is created by [`striped_random_natural_signeds`]; see its documentation for more. #[derive(Clone, Debug)] pub struct StripedRandomNaturalSigneds { phantom: PhantomData<*const T>, bits: StripedBitSource, } impl Iterator for StripedRandomNaturalSigneds { type Item = T; fn next(&mut self) -> Option { self.bits.end_block(); let mut x = T::ZERO; for bit in (&mut self.bits).take(usize::wrapping_from(T::WIDTH) - 1) { x <<= 1; if bit { x |= T::ONE; } } Some(x) } } /// Generates random negative signed integers from a random striped distribution. /// /// This `struct` is created by [`striped_random_negative_signeds`]; see its documentation for more. #[derive(Clone, Debug)] pub struct StripedRandomNegativeSigneds { phantom: PhantomData<*const T>, bits: StripedBitSource, } impl Iterator for StripedRandomNegativeSigneds { type Item = T; fn next(&mut self) -> Option { self.bits.end_block(); let mut x = T::ZERO; for bit in (&mut self.bits).take(usize::wrapping_from(T::WIDTH) - 1) { x <<= 1; if bit { x |= T::ONE; } } x.set_bit(T::WIDTH - 1); Some(x) } } /// Generates random unsigned integers from a random striped distribution. /// /// See [here](self) for more information. /// /// The mean run length (before the bit sequences are truncated) is $m$ = `m_numerator / /// m_denominator`. /// /// The output length is infinite. /// /// # Expected complexity per iteration /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and `n` is the width of the type. /// /// # Panics /// Panics if `m_denominator` is zero or if m_numerator <= m_denominator. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::striped::striped_random_unsigneds; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::strings::ToBinaryString; /// /// assert_eq!( /// prefix_to_string( /// striped_random_unsigneds::(EXAMPLE_SEED, 4, 1).map(|x| x.to_binary_string()), /// 10 /// ), /// "[1, 1001100, 1111111, 11000011, 0, 10000000, 1111, 1110110, 0, 11111000, ...]" /// ) /// ``` #[inline] pub fn striped_random_unsigneds( seed: Seed, m_numerator: u64, m_denominator: u64, ) -> StripedRandomUnsignedBitChunks { striped_random_unsigned_bit_chunks(seed, T::WIDTH, m_numerator, m_denominator) } /// Generates random positive unsigned integers from a random striped distribution. /// /// See [here](self) for more information. /// /// The mean run length (before the bit sequences are truncated) is $m$ = `m_numerator / /// m_denominator`. /// /// The output length is infinite. /// /// # Expected complexity per iteration /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and `n` is the width of the type. /// /// # Panics /// Panics if `m_denominator` is zero or if m_numerator <= m_denominator. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::striped::striped_random_positive_unsigneds; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::strings::ToBinaryString; /// /// assert_eq!( /// prefix_to_string( /// striped_random_positive_unsigneds::(EXAMPLE_SEED, 4, 1) /// .map(|x| x.to_binary_string()), /// 10 /// ), /// "[1, 1001100, 1111111, 11000011, 10000000, 1111, 1110110, 11111000, 11111111, 11111101, \ /// ...]" /// ) /// ``` pub fn striped_random_positive_unsigneds( seed: Seed, m_numerator: u64, m_denominator: u64, ) -> NonzeroValues> { nonzero_values(striped_random_unsigneds(seed, m_numerator, m_denominator)) } /// Generates random signed integers from a random striped distribution. /// /// See [here](self) for more information. /// /// The mean run length (before the bit sequences are truncated) is $m$ = `m_numerator / /// m_denominator`. /// /// The output length is infinite. /// /// # Expected complexity per iteration /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and `n` is the width of the type. /// /// # Panics /// Panics if `m_denominator` is zero or if m_numerator <= m_denominator. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::striped::striped_random_signeds; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::strings::ToBinaryString; /// /// assert_eq!( /// prefix_to_string( /// striped_random_signeds::(EXAMPLE_SEED, 4, 1).map(|x| x.to_binary_string()), /// 10 /// ), /// "[1100001, 1000000, 1100000, 10000111, 1111, 10000001, 1111000, 100011, 111101, 11111100, \ /// ...]" /// ) /// ``` pub fn striped_random_signeds( seed: Seed, m_numerator: u64, m_denominator: u64, ) -> StripedRandomSigneds { StripedRandomSigneds { phantom: PhantomData, bits: StripedBitSource::new(seed.fork("bits"), m_numerator, m_denominator), bs: random_bools(seed.fork("bs")), } } /// Generates random natural (non-negative) signed integers from a random striped distribution. /// /// See [here](self) for more information. /// /// The mean run length (before the bit sequences are truncated) is $m$ = `m_numerator / /// m_denominator`. /// /// The output length is infinite. /// /// # Expected complexity per iteration /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and `n` is the width of the type. /// /// # Panics /// Panics if `m_denominator` is zero or if m_numerator <= m_denominator. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::striped::striped_random_natural_signeds; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::strings::ToBinaryString; /// /// assert_eq!( /// prefix_to_string( /// striped_random_natural_signeds::(EXAMPLE_SEED, 4, 1).map(|x| x.to_binary_string()), /// 10 /// ), /// "[0, 101100, 110000, 1111100, 1111, 1111110, 0, 111, 11101, 1100000, ...]" /// ) /// ``` pub fn striped_random_natural_signeds( seed: Seed, m_numerator: u64, m_denominator: u64, ) -> StripedRandomNaturalSigneds { StripedRandomNaturalSigneds { phantom: PhantomData, bits: StripedBitSource::new(seed, m_numerator, m_denominator), } } /// Generates random positive signed integers from a random striped distribution. /// /// See [here](self) for more information. /// /// The mean run length (before the bit sequences are truncated) is $m$ = `m_numerator / /// m_denominator`. /// /// The output length is infinite. /// /// # Expected complexity per iteration /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and `n` is the width of the type. /// /// # Panics /// Panics if `m_denominator` is zero or if m_numerator <= m_denominator. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::striped::striped_random_positive_signeds; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::strings::ToBinaryString; /// /// assert_eq!( /// prefix_to_string( /// striped_random_positive_signeds::(EXAMPLE_SEED, 4, 1).map(|x| x.to_binary_string()), /// 10 /// ), /// "[101100, 110000, 1111100, 1111, 1111110, 111, 11101, 1100000, 1111111, 1100000, ...]" /// ) /// ``` pub fn striped_random_positive_signeds( seed: Seed, m_numerator: u64, m_denominator: u64, ) -> NonzeroValues> { nonzero_values(striped_random_natural_signeds( seed, m_numerator, m_denominator, )) } /// Generates random negative signed integers from a random striped distribution. /// /// See [here](self) for more information. /// /// The mean run length (before the bit sequences are truncated) is $m$ = `m_numerator / /// m_denominator`. /// /// The output length is infinite. /// /// # Expected complexity per iteration /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and `n` is the width of the type. /// /// # Panics /// Panics if `m_denominator` is zero or if m_numerator <= m_denominator. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::striped::striped_random_negative_signeds; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::strings::ToBinaryString; /// /// assert_eq!( /// prefix_to_string( /// striped_random_negative_signeds::(EXAMPLE_SEED, 4, 1).map(|x| x.to_binary_string()), /// 10 /// ), /// "[10000000, 10101100, 10110000, 11111100, 10001111, 11111110, 10000000, 10000111, \ /// 10011101, 11100000, ...]" /// ) /// ``` pub fn striped_random_negative_signeds( seed: Seed, m_numerator: u64, m_denominator: u64, ) -> StripedRandomNegativeSigneds { StripedRandomNegativeSigneds { phantom: PhantomData, bits: StripedBitSource::new(seed, m_numerator, m_denominator), } } /// Generates random nonzero signed integers from a random striped distribution. /// /// See [here](self) for more information. /// /// The mean run length (before the bit sequences are truncated) is $m$ = `m_numerator / /// m_denominator`. /// /// The output length is infinite. /// /// # Expected complexity per iteration /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and `n` is the width of the type. /// /// # Panics /// Panics if `m_denominator` is zero or if m_numerator <= m_denominator. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::striped::striped_random_nonzero_signeds; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::strings::ToBinaryString; /// /// assert_eq!( /// prefix_to_string( /// striped_random_nonzero_signeds::(EXAMPLE_SEED, 4, 1).map(|x| x.to_binary_string()), /// 10 /// ), /// "[1100001, 1000000, 1100000, 10000111, 1111, 10000001, 1111000, 100011, 111101, 11111100, \ /// ...]" /// ) /// ``` pub fn striped_random_nonzero_signeds( seed: Seed, m_numerator: u64, m_denominator: u64, ) -> NonzeroValues> { nonzero_values(striped_random_signeds(seed, m_numerator, m_denominator)) } /// Generates random unsigned integers of up to `chunk_size` bits from a random striped /// distribution. /// /// See [here](self) for more information. /// /// The mean run length (before the bit sequences are truncated) is $m$ = `m_numerator / /// m_denominator`. /// /// The output length is infinite. /// /// # Expected complexity per iteration /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and `n` is `chunk_size`. /// /// # Panics /// Panics if `m_denominator` is zero, if m_numerator <= m_denominator, or if `chunk_size` is /// greater than the width of the type. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::striped::striped_random_unsigned_bit_chunks; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::strings::ToBinaryString; /// /// assert_eq!( /// prefix_to_string( /// striped_random_unsigned_bit_chunks::(EXAMPLE_SEED, 3, 4, 1) /// .map(|x| x.to_binary_string()), /// 10 /// ), /// "[0, 0, 0, 101, 11, 100, 11, 11, 0, 111, ...]" /// ) /// ``` pub fn striped_random_unsigned_bit_chunks( seed: Seed, chunk_size: u64, m_numerator: u64, m_denominator: u64, ) -> StripedRandomUnsignedBitChunks { assert!(chunk_size <= T::WIDTH); StripedRandomUnsignedBitChunks { phantom: PhantomData, bits: StripedBitSource::new(seed, m_numerator, m_denominator), chunk_size: usize::exact_from(chunk_size), } } /// Generates a striped `Vec`, with a given length, from a [`StripedBitSource`]. /// /// See [here](self) for more information. /// /// The output length is `len`. /// /// # Expected complexity /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and `n` is `len`. /// /// # Examples /// ``` /// use malachite_base::num::random::striped::{get_striped_bool_vec, StripedBitSource}; /// use malachite_base::random::EXAMPLE_SEED; /// /// let mut bit_source = StripedBitSource::new(EXAMPLE_SEED, 10, 1); /// let bits: String = get_striped_bool_vec(&mut bit_source, 50) /// .into_iter() /// .map(|b| if b { '1' } else { '0' }) /// .collect(); /// assert_eq!(bits, "00011111111111000000011111111111111000000000001111"); /// ``` pub fn get_striped_bool_vec(bit_source: &mut StripedBitSource, len: u64) -> Vec { bit_source.end_block(); bit_source.take(usize::exact_from(len)).collect() } /// Generates random striped `Vec`s. #[derive(Clone, Debug)] pub struct StripedRandomBoolVecs> { lengths: I, bit_source: StripedBitSource, } impl> Iterator for StripedRandomBoolVecs { type Item = Vec; fn next(&mut self) -> Option> { Some(get_striped_bool_vec( &mut self.bit_source, self.lengths.next().unwrap(), )) } } /// Generates random striped `Vec`s, with lengths from an iterator. /// /// See [here](self) for more information. /// /// The mean run length (before the bit sequences are truncated) is $m$ = `mean_stripe_numerator / /// mean_stripe_denominator`. /// /// # Panics /// Panics if `mean_stripe_denominator` is zero or if `mean_stripe_numerator <= /// mean_stripe_denominator`. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::striped::striped_random_bool_vecs_from_length_iterator; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::vecs::random_values_from_vec; /// /// assert_eq!( /// prefix_to_string( /// striped_random_bool_vecs_from_length_iterator( /// EXAMPLE_SEED, /// &|seed| random_values_from_vec(seed, vec![0, 2, 4]), /// 10, /// 1, /// ) /// .map(|bs| bs /// .into_iter() /// .map(|b| if b { '1' } else { '0' }) /// .collect::()), /// 20 /// ), /// "[00, 0000, 00, 0000, 0000, 11, , 00, , 1111, 0001, 11, 1100, 00, 0000, 0000, 1110, , \ /// 0000, , ...]" /// ); /// ``` #[inline] pub fn striped_random_bool_vecs_from_length_iterator>( seed: Seed, lengths_gen: &dyn Fn(Seed) -> I, mean_stripe_numerator: u64, mean_stripe_denominator: u64, ) -> StripedRandomBoolVecs { StripedRandomBoolVecs { lengths: lengths_gen(seed.fork("lengths")), bit_source: StripedBitSource::new( seed.fork("bit_source"), mean_stripe_numerator, mean_stripe_denominator, ), } } /// Generates random striped `Vec`s of a given length. /// /// See [here](self) for more information. /// /// The mean run length (before the bit sequences are truncated) is $m$ = `mean_stripe_numerator / /// mean_stripe_denominator`. /// /// If `len` is 0, the output consists of the empty list, repeated. /// /// # Expected complexity per iteration /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `len`. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::striped::striped_random_fixed_length_bool_vecs; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string( /// striped_random_fixed_length_bool_vecs(EXAMPLE_SEED, 5, 10, 1).map(|bs| bs /// .into_iter() /// .map(|b| if b { '1' } else { '0' }) /// .collect::()), /// 20 /// ), /// "[00000, 00000, 00000, 00000, 00011, 11000, 00000, 11111, 01111, 11111, 10000, 00011, \ /// 00000, 00000, 11000, 00000, 11111, 00000, 00000, 11111, ...]" /// ); /// ``` pub fn striped_random_fixed_length_bool_vecs( seed: Seed, len: u64, mean_stripe_numerator: u64, mean_stripe_denominator: u64, ) -> StripedRandomBoolVecs> { striped_random_bool_vecs_from_length_iterator( seed, &|_| repeat(len), mean_stripe_numerator, mean_stripe_denominator, ) } /// Generates random striped `Vec`s. /// /// See [here](self) for more information. /// /// The lengths of the [`Vec`]s are sampled from a geometric distribution with a specified mean $m$, /// equal to `mean_length_numerator / mean_length_denominator`. $m$ must be greater than 0. /// /// The mean run length (before the bit sequences are truncated) is $m$ = `mean_stripe_numerator / /// mean_stripe_denominator`. /// /// # Expected complexity per iteration /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `mean_length_numerator / /// mean_length_denominator`. /// /// # Panics /// Panics if `mean_stripe_denominator` is zero, if `mean_stripe_numerator <= /// mean_stripe_denominator`, if `mean_length_numerator` or `mean_length_denominator` are zero, or, /// if after being reduced to lowest terms, their sum is greater than or equal to $2^{64}$. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::striped::striped_random_bool_vecs; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string( /// striped_random_bool_vecs(EXAMPLE_SEED, 10, 1, 2, 1).map(|bs| bs /// .into_iter() /// .map(|b| if b { '1' } else { '0' }) /// .collect::()), /// 20 /// ), /// "[000000, 0, 00000000, 0, 00000001110000, , 11111, 0000, 1, , 011111, 11, , , 1, 000, , \ /// 0, , 0, ...]" /// ); /// ``` #[inline] pub fn striped_random_bool_vecs( seed: Seed, mean_stripe_numerator: u64, mean_stripe_denominator: u64, mean_length_numerator: u64, mean_length_denominator: u64, ) -> StripedRandomBoolVecs> { striped_random_bool_vecs_from_length_iterator( seed, &|seed_2| { geometric_random_unsigneds(seed_2, mean_length_numerator, mean_length_denominator) }, mean_stripe_numerator, mean_stripe_denominator, ) } /// Generates random striped `Vec`s, with a minimum length. /// /// See [here](self) for more information. /// /// The lengths of the [`Vec`]s are sampled from a geometric distribution with a specified mean $m$, /// equal to `mean_length_numerator / mean_length_denominator`. $m$ must be greater than /// `min_length`. /// /// The mean run length (before the bit sequences are truncated) is $m$ = `mean_stripe_numerator / /// mean_stripe_denominator`. /// /// # Expected complexity per iteration /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `mean_length_numerator / /// mean_length_denominator`. /// /// # Panics /// Panics if `mean_stripe_denominator` is zero, if `mean_stripe_numerator <= /// mean_stripe_denominator`, if `mean_length_numerator` or `mean_length_denominator` are zero, if /// their ratio is less than or equal to `min_length`, or if they are too large and manipulating /// them leads to arithmetic overflow. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::striped::striped_random_bool_vecs_min_length; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string( /// striped_random_bool_vecs_min_length(EXAMPLE_SEED, 3, 10, 1, 5, 1).map(|bs| bs /// .into_iter() /// .map(|b| if b { '1' } else { '0' }) /// .collect::()), /// 20 /// ), /// "[000000000, 0000, 00000000111, 0111, 00000000011111111, 100, 00000111, 1111111, 0001, \ /// 111, 111111111, 00000, 000, 000, 1111, 000000, 111, 0011, 000, 1111, ...]" /// ); /// ``` #[inline] pub fn striped_random_bool_vecs_min_length( seed: Seed, min_length: u64, mean_stripe_numerator: u64, mean_stripe_denominator: u64, mean_length_numerator: u64, mean_length_denominator: u64, ) -> StripedRandomBoolVecs> { striped_random_bool_vecs_from_length_iterator( seed, &|seed_2| { geometric_random_unsigned_inclusive_range( seed_2, min_length, u64::MAX, mean_length_numerator, mean_length_denominator, ) }, mean_stripe_numerator, mean_stripe_denominator, ) } /// Generates random striped `Vec`s, with lengths in $[a, b)$. /// /// See [here](self) for more information. /// /// The lengths of the [`Vec`]s are sampled from a uniform distribution on $[a, b)$. $a$ must be /// less than $b$. /// /// The mean run length (before the bit sequences are truncated) is $m$ = `mean_stripe_numerator / /// mean_stripe_denominator`. /// /// $$ /// P((x_0, x_1, \ldots, x_{n-1})) = \\begin{cases} /// \frac{1}{b-a}\prod_{i=0}^{n-1}P(x_i) & \text{if} \\quad a \leq n < b, \\\\ /// 0 & \\text{otherwise}. /// \\end{cases} /// $$ /// /// # Expected complexity per iteration /// $T(n) = O(b)$ /// /// $M(n) = O(b)$ /// /// where $T$ is time and $M$ is additional memory. /// /// # Panics /// Panics if `mean_stripe_denominator` is zero, if `mean_stripe_numerator <= /// mean_stripe_denominator`, or if $a \geq b$. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::striped::striped_random_bool_vecs_length_range; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string( /// striped_random_bool_vecs_length_range(EXAMPLE_SEED, 4, 10, 10, 1).map(|bs| bs /// .into_iter() /// .map(|b| if b { '1' } else { '0' }) /// .collect::()), /// 20 /// ), /// "[000000000, 000000000, 000111000, 000000000, 0111, 11111, 00111111, 1000000, 00000011, \ /// 111111111, 111111, 00000000, 00000000, 001111, 111111111, 000000000, 110000, 0001111, \ /// 0000000, 111101111, ...]" /// ); /// ``` #[inline] pub fn striped_random_bool_vecs_length_range( seed: Seed, a: u64, b: u64, mean_stripe_numerator: u64, mean_stripe_denominator: u64, ) -> StripedRandomBoolVecs> { striped_random_bool_vecs_from_length_iterator( seed, &|seed_2| random_unsigned_range(seed_2, a, b), mean_stripe_numerator, mean_stripe_denominator, ) } /// Generates random striped `Vec`s, with lengths in $[a, b]$. /// /// See [here](self) for more information. /// /// The lengths of the [`Vec`]s are sampled from a uniform distribution on $[a, b]$. $a$ must be /// less than $b$. /// /// The mean run length (before the bit sequences are truncated) is $m$ = `mean_stripe_numerator / /// mean_stripe_denominator`. /// /// $$ /// P((x_0, x_1, \ldots, x_{n-1})) = \\begin{cases} /// \frac{1}{b-a+1}\prod_{i=0}^{n-1}P(x_i) & \text{if} \\quad a \leq n \leq b, \\\\ /// 0 & \\text{otherwise}. /// \\end{cases} /// $$ /// /// # Expected complexity per iteration /// $T(n) = O(b)$ /// /// $M(n) = O(b)$ /// /// where $T$ is time and $M$ is additional memory. /// /// # Panics /// Panics if `mean_stripe_denominator` is zero, if `mean_stripe_numerator <= /// mean_stripe_denominator`, or if $a \geq b$. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::striped::striped_random_bool_vecs_length_inclusive_range; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// prefix_to_string( /// striped_random_bool_vecs_length_inclusive_range(EXAMPLE_SEED, 4, 9, 10, 1).map(|bs| bs /// .into_iter() /// .map(|b| if b { '1' } else { '0' }) /// .collect::()), /// 20 /// ), /// "[000000000, 000000000, 000111000, 000000000, 0111, 11111, 00111111, 1000000, 00000011, \ /// 111111111, 111111, 00000000, 00000000, 001111, 111111111, 000000000, 110000, 0001111, \ /// 0000000, 111101111, ...]" /// ); /// ``` #[inline] pub fn striped_random_bool_vecs_length_inclusive_range( seed: Seed, a: u64, b: u64, mean_stripe_numerator: u64, mean_stripe_denominator: u64, ) -> StripedRandomBoolVecs> { striped_random_bool_vecs_from_length_iterator( seed, &|seed_2| random_unsigned_inclusive_range(seed_2, a, b), mean_stripe_numerator, mean_stripe_denominator, ) } /// Generates a striped unsigned [`Vec`], with a given number of bits (not length!), from a /// [`StripedBitSource`]. /// /// See [here](self) for more information. /// /// The output length is `bit_len.div_round(T::WIDTH, Ceiling)`. /// /// # Expected complexity /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `bit_len`. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::random::striped::{get_striped_unsigned_vec, StripedBitSource}; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::strings::ToBinaryString; /// /// let mut bit_source = StripedBitSource::new(EXAMPLE_SEED, 10, 1); /// let xs = get_striped_unsigned_vec::(&mut bit_source, 100) /// .iter() /// .map(u8::to_binary_string) /// .collect_vec(); /// assert_eq!( /// xs, /// &[ /// "11111000", "111111", "11100000", "11111111", "111", "11000000", "11111111", "0", "0", /// "11111000", "11111111", "11111111", "11", /// ] /// ); /// ``` pub fn get_striped_unsigned_vec( bit_source: &mut StripedBitSource, bit_len: u64, ) -> Vec { bit_source.end_block(); bit_source .take(usize::exact_from(bit_len)) .chunks(usize::wrapping_from(T::WIDTH)) .into_iter() .map(T::from_bits_asc) .collect() } /// Generates random striped [`Vec`]s of unsigneds. #[derive(Clone, Debug)] pub struct StripedRandomUnsignedVecs> { phantom: PhantomData<*const T>, lengths: I, bit_source: StripedBitSource, } impl> Iterator for StripedRandomUnsignedVecs { type Item = Vec; fn next(&mut self) -> Option> { Some(get_striped_unsigned_vec( &mut self.bit_source, self.lengths.next().unwrap() << T::LOG_WIDTH, )) } } /// Generates random striped [`Vec`]s of unsigneds, with lengths from an iterator. /// /// See [here](self) for more information. /// /// The mean run length (before the bit sequences are truncated) is $m$ = `mean_stripe_numerator / /// mean_stripe_denominator`. /// /// # Panics /// Panics if `mean_stripe_denominator` is zero or if `mean_stripe_numerator <= /// mean_stripe_denominator`. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::striped::striped_random_unsigned_vecs_from_length_iterator; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::strings::ToBinaryString; /// use malachite_base::vecs::random_values_from_vec; /// /// assert_eq!( /// prefix_to_string( /// striped_random_unsigned_vecs_from_length_iterator::( /// EXAMPLE_SEED, /// &|seed| random_values_from_vec(seed, vec![0, 2, 4]), /// 10, /// 1, /// ) /// .map(|xs| prefix_to_string(xs.into_iter().map(|x: u8| x.to_binary_string()), 100)), /// 10, /// ), /// "[[0, 0], [1110000, 0, 11111100, 11], [11111110, 1111], [0, 0, 0, 11111000], \ /// [0, 0, 1111110, 0], [11011111, 11111111], [], [11110000, 11111111], [], \ /// [11111111, 11000011, 11111, 0], ...]" /// ); /// ``` #[inline] pub fn striped_random_unsigned_vecs_from_length_iterator< T: PrimitiveUnsigned, I: Iterator, >( seed: Seed, lengths_gen: &dyn Fn(Seed) -> I, mean_stripe_numerator: u64, mean_stripe_denominator: u64, ) -> StripedRandomUnsignedVecs { StripedRandomUnsignedVecs { phantom: PhantomData, lengths: lengths_gen(seed.fork("lengths")), bit_source: StripedBitSource::new( seed.fork("bit_source"), mean_stripe_numerator, mean_stripe_denominator, ), } } /// Generates random striped unsigned [`Vec`]s of a given length. /// /// See [here](self) for more information. /// /// The mean run length (before the bit sequences are truncated) is $m$ = `mean_stripe_numerator / /// mean_stripe_denominator`. /// /// If `len` is 0, the output consists of the empty list, repeated. /// /// # Expected complexity per iteration /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `len`. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::striped::striped_random_fixed_length_unsigned_vecs; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::strings::ToBinaryString; /// /// assert_eq!( /// prefix_to_string( /// striped_random_fixed_length_unsigned_vecs::(EXAMPLE_SEED, 3, 10, 1).map(|xs| { /// prefix_to_string(xs.into_iter().map(|x: u8| x.to_binary_string()), 100) /// }), /// 10, /// ), /// "[[0, 0, 111000], [0, 11111100, 11], [11111110, 1111, 0], [0, 0, 11111000], \ /// [0, 0, 1111110], [11111111, 11011111, 11111111], [11110000, 11111111, 11111111], \ /// [11000011, 11111, 0], [0, 10000000, 11111001], [11111111, 0, 0], ...]" /// ); /// ``` #[inline] pub fn striped_random_fixed_length_unsigned_vecs( seed: Seed, len: u64, mean_stripe_numerator: u64, mean_stripe_denominator: u64, ) -> StripedRandomUnsignedVecs> { striped_random_unsigned_vecs_from_length_iterator( seed, &|_| repeat(len), mean_stripe_numerator, mean_stripe_denominator, ) } /// Generates random striped [`Vec`]s of unsigneds. /// /// See [here](self) for more information. /// /// The lengths of the [`Vec`]s are sampled from a geometric distribution with a specified mean $m$, /// equal to `mean_length_numerator / mean_length_denominator`. $m$ must be greater than 0. /// /// The mean run length (before the bit sequences are truncated) is $m$ = `mean_stripe_numerator / /// mean_stripe_denominator`. /// /// $$ /// P((x_0, x_1, \ldots, x_{n-1})) = \frac{m^n}{(m+1)^{n+1}}\prod_{i=0}^{n-1}P(x_i). /// $$ /// /// # Expected complexity per iteration /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `mean_length_numerator / /// mean_length_denominator`. /// /// # Panics /// Panics if `mean_stripe_denominator` is zero, if `mean_stripe_numerator <= /// mean_stripe_denominator`, if `mean_length_numerator` or `mean_length_denominator` are zero, or, /// if after being reduced to lowest terms, their sum is greater than or equal to $2^{64}$. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::striped::striped_random_unsigned_vecs; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::strings::ToBinaryString; /// /// assert_eq!( /// prefix_to_string( /// striped_random_unsigned_vecs::(EXAMPLE_SEED, 10, 1, 2, 1) /// .map(|xs| prefix_to_string(xs.into_iter().map(|x: u8| x.to_binary_string()), 100)), /// 10, /// ), /// "[[0, 0, 111000, 0, 11111110, 10000001], [0], \ /// [11110000, 11111111, 11111111, 11111111, 11, 0, 10000000, 11111], [0], \ /// [10000, 0, 11111100, 11111111, 1111111, 11111000, 11, 0, 0, 10011000, 11111111, 111, 0, \ /// 0], [], [11111111, 11111111, 11111111, 11111111, 10111111], [0, 0, 0, 11110000], \ /// [11111111], [], ...]" /// ); /// ``` #[inline] pub fn striped_random_unsigned_vecs( seed: Seed, mean_stripe_numerator: u64, mean_stripe_denominator: u64, mean_length_numerator: u64, mean_length_denominator: u64, ) -> StripedRandomUnsignedVecs> { striped_random_unsigned_vecs_from_length_iterator( seed, &|seed_2| { geometric_random_unsigneds(seed_2, mean_length_numerator, mean_length_denominator) }, mean_stripe_numerator, mean_stripe_denominator, ) } /// Generates random striped [`Vec`]s of unsigneds, with a minimum length. /// /// See [here](self) for more information. /// /// The lengths of the [`Vec`]s are sampled from a geometric distribution with a specified mean $m$, /// equal to `mean_length_numerator / mean_length_denominator`. $m$ must be greater than /// `min_length`. /// /// The mean run length (before the bit sequences are truncated) is $m$ = `mean_stripe_numerator / /// mean_stripe_denominator`. /// /// $$ /// P((x_0, x_1, \ldots, x_{n-1})) = \\begin{cases} /// \frac{(m-a)^{n-a}}{(m+1-a)^{n+1-a}}\prod_{i=0}^{n-1}P(x_i) & n \geq a \\\\ /// 0 & \\text{otherwise}, /// \\end{cases} /// $$ /// where $a$ is `min_length`. /// /// # Expected complexity per iteration /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `mean_length_numerator / /// mean_length_denominator`. /// /// # Panics /// Panics if `mean_stripe_denominator` is zero, if `mean_stripe_numerator <= /// mean_stripe_denominator`, if `mean_length_numerator` or `mean_length_denominator` are zero, if /// their ratio is less than or equal to `min_length`, or if they are too large and manipulating /// them leads to arithmetic overflow. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::striped::striped_random_unsigned_vecs_min_length; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::strings::ToBinaryString; /// /// assert_eq!( /// prefix_to_string( /// striped_random_unsigned_vecs_min_length::(EXAMPLE_SEED, 2, 10, 1, 3, 1) /// .map(|xs| prefix_to_string(xs.into_iter().map(|x: u8| x.to_binary_string()), 100)), /// 10, /// ), /// "[[0, 0, 111000], [0, 11111100, 11, 11111111], \ /// [11110000, 11111111, 11111111, 11111111], [11111000, 11111111, 11111111, 11000000], \ /// [0, 10000, 0], [111, 0, 0, 1111], [11110000, 11111111], [11111111, 111111], \ /// [110, 10000000, 11111111], [11111111, 11111111], ...]" /// ); /// ``` #[inline] pub fn striped_random_unsigned_vecs_min_length( seed: Seed, min_length: u64, mean_stripe_numerator: u64, mean_stripe_denominator: u64, mean_length_numerator: u64, mean_length_denominator: u64, ) -> StripedRandomUnsignedVecs> { striped_random_unsigned_vecs_from_length_iterator( seed, &|seed_2| { geometric_random_unsigned_inclusive_range( seed_2, min_length, u64::MAX, mean_length_numerator, mean_length_denominator, ) }, mean_stripe_numerator, mean_stripe_denominator, ) } /// Generates random striped [`Vec`]s of unsigneds, with lengths in $[a, b)$. /// /// See [here](self) for more information. /// /// The lengths of the [`Vec`]s are sampled from a uniform distribution on $[a, b)$. $a$ must be /// less than $b$. /// /// The mean run length (before the bit sequences are truncated) is $m$ = `mean_stripe_numerator / /// mean_stripe_denominator`. /// /// $$ /// P((x_0, x_1, \ldots, x_{n-1})) = \\begin{cases} /// \frac{1}{b-a}\prod_{i=0}^{n-1}P(x_i) & \text{if} \\quad a \leq n < b, \\\\ /// 0 & \\text{otherwise}. /// \\end{cases} /// $$ /// /// # Expected complexity per iteration /// $T(n) = O(b)$ /// /// $M(n) = O(b)$ /// /// where $T$ is time and $M$ is additional memory. /// /// # Panics /// Panics if `mean_stripe_denominator` is zero, if `mean_stripe_numerator <= /// mean_stripe_denominator`, or if $a \geq b$. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::striped::striped_random_unsigned_vecs_length_range; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::strings::ToBinaryString; /// /// assert_eq!( /// prefix_to_string( /// striped_random_unsigned_vecs_length_range::(EXAMPLE_SEED, 2, 4, 10, 1) /// .map(|xs| prefix_to_string(xs.into_iter().map(|x: u8| x.to_binary_string()), 100)), /// 10, /// ), /// "[[0, 0, 111000], [0, 11111100], [11111000, 1, 11110000], [0, 0, 0], \ /// [11110000, 11111111], [11111111, 11, 11111111], [1000000, 0, 11110000], \ /// [11111111, 11111111], [1111000, 11000000, 11111111], [11111111, 11111111, 1100], ...]" /// ); /// ``` #[inline] pub fn striped_random_unsigned_vecs_length_range( seed: Seed, a: u64, b: u64, mean_stripe_numerator: u64, mean_stripe_denominator: u64, ) -> StripedRandomUnsignedVecs> { striped_random_unsigned_vecs_from_length_iterator( seed, &|seed_2| random_unsigned_range(seed_2, a, b), mean_stripe_numerator, mean_stripe_denominator, ) } /// Generates random striped [`Vec`]s of unsigneds, with lengths in $[a, b]$. /// /// See [here](self) for more information. /// /// The lengths of the [`Vec`]s are sampled from a uniform distribution on $[a, b]$. $a$ must be /// less than $b$. /// /// The mean run length (before the bit sequences are truncated) is $m$ = `mean_stripe_numerator / /// mean_stripe_denominator`. /// /// $$ /// P((x_0, x_1, \ldots, x_{n-1})) = \\begin{cases} /// \frac{1}{b-a+1}\prod_{i=0}^{n-1}P(x_i) & \text{if} \\quad a \leq n \leq b, \\\\ /// 0 & \\text{otherwise}. /// \\end{cases} /// $$ /// /// # Expected complexity per iteration /// $T(n) = O(b)$ /// /// $M(n) = O(b)$ /// /// where $T$ is time and $M$ is additional memory. /// /// # Panics /// Panics if `mean_stripe_denominator` is zero, if `mean_stripe_numerator <= /// mean_stripe_denominator`, or if $a \geq b$. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::striped::striped_random_unsigned_vecs_length_inclusive_range; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::strings::ToBinaryString; /// /// assert_eq!( /// prefix_to_string( /// striped_random_unsigned_vecs_length_inclusive_range::(EXAMPLE_SEED, 2, 3, 10, 1) /// .map(|xs| prefix_to_string(xs.into_iter().map(|x: u8| x.to_binary_string()), 100)), /// 10, /// ), /// "[[0, 0, 111000], [0, 11111100], [11111000, 1, 11110000], [0, 0, 0], \ /// [11110000, 11111111], [11111111, 11, 11111111], [1000000, 0, 11110000], \ /// [11111111, 11111111], [1111000, 11000000, 11111111], [11111111, 11111111, 1100], ...]" /// ); /// ``` #[inline] pub fn striped_random_unsigned_vecs_length_inclusive_range( seed: Seed, a: u64, b: u64, mean_stripe_numerator: u64, mean_stripe_denominator: u64, ) -> StripedRandomUnsignedVecs> { striped_random_unsigned_vecs_from_length_iterator( seed, &|seed_2| random_unsigned_inclusive_range(seed_2, a, b), mean_stripe_numerator, mean_stripe_denominator, ) } #[inline] fn ranges_intersect(lo_0: T, hi_0: T, lo: T, hi: T) -> bool { lo <= hi_0 && lo_0 <= hi } /// Generates random striped unsigneds from a range. #[derive(Clone, Debug)] pub struct StripedRandomUnsignedInclusiveRange { a: T, b: T, lo_template: T, hi_template: T, next_bit: u64, bit_source: StripedBitSource, } impl Iterator for StripedRandomUnsignedInclusiveRange { type Item = T; fn next(&mut self) -> Option { if self.next_bit == 0 { return Some(self.lo_template); } let mut lo_template = self.lo_template; let mut hi_template = self.hi_template; let mut first = true; let mut previous_forced = true; let mut previous_bit = lo_template.get_bit(self.next_bit); for next_bit in (0..self.next_bit).rev() { let false_possible; let true_possible; if first { false_possible = true; true_possible = true; lo_template.assign_bit(next_bit, true); hi_template.assign_bit(next_bit, true); first = false; } else { lo_template.assign_bit(next_bit, false); hi_template.assign_bit(next_bit, false); false_possible = ranges_intersect(lo_template, hi_template, self.a, self.b); lo_template.assign_bit(next_bit, true); hi_template.assign_bit(next_bit, true); true_possible = ranges_intersect(lo_template, hi_template, self.a, self.b); } assert!(false_possible || true_possible); let bit = if !false_possible { previous_forced = true; true } else if !true_possible { previous_forced = true; false } else { if previous_forced { self.bit_source.end_block(); self.bit_source.set_previous_bit(previous_bit); previous_forced = false; } self.bit_source.next().unwrap() }; if !bit { lo_template.assign_bit(next_bit, false); hi_template.assign_bit(next_bit, false); } previous_bit = bit; } Some(lo_template) } } /// Generates random striped unsigneds in the range $[a, b)$. /// /// See [here](self) for more information. /// /// The unsigneds are generated using a striped bit sequence with mean run length $m$ = /// `mean_stripe_numerator / mean_stripe_denominator`. /// /// Because the unsigneds are constrained to be within a certain range, the actual mean run length /// will usually not be $m$. Nonetheless, setting a higher $m$ will result in a higher mean run /// length. /// /// # Expected complexity per iteration /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `b.significant_bits()`. /// /// # Panics /// Panics if `mean_stripe_denominator` is zero, if `mean_stripe_numerator <= /// mean_stripe_denominator`, or if $a \geq b$. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::striped::striped_random_unsigned_range; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::strings::ToBinaryString; /// /// assert_eq!( /// prefix_to_string( /// striped_random_unsigned_range::(EXAMPLE_SEED, 1, 7, 4, 1) /// .map(|x| x.to_binary_string()), /// 10 /// ), /// "[1, 1, 1, 110, 1, 110, 10, 11, 11, 100, ...]" /// ); /// ``` #[inline] pub fn striped_random_unsigned_range( seed: Seed, a: T, b: T, mean_stripe_numerator: u64, mean_stripe_denominator: u64, ) -> StripedRandomUnsignedInclusiveRange { assert!(a < b); striped_random_unsigned_inclusive_range( seed, a, b - T::ONE, mean_stripe_numerator, mean_stripe_denominator, ) } /// Generates random striped unsigneds in the range $[a, b]$. /// /// See [here](self) for more information. /// /// The unsigneds are generated using a striped bit sequence with mean run length $m$ = /// `mean_stripe_numerator / mean_stripe_denominator`. /// /// Because the unsigneds are constrained to be within a certain range, the actual mean run length /// will usually not be $m$. Nonetheless, setting a higher $m$ will result in a higher mean run /// length. /// /// # Expected complexity per iteration /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `b.significant_bits()`. /// /// # Panics /// Panics if `mean_stripe_denominator` is zero, if `mean_stripe_numerator <= /// mean_stripe_denominator`, or if $a > b$. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::striped::striped_random_unsigned_inclusive_range; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::strings::ToBinaryString; /// /// assert_eq!( /// prefix_to_string( /// striped_random_unsigned_inclusive_range::(EXAMPLE_SEED, 1, 6, 4, 1) /// .map(|x| x.to_binary_string()), /// 10 /// ), /// "[1, 1, 1, 110, 1, 110, 10, 11, 11, 100, ...]" /// ); /// ``` pub fn striped_random_unsigned_inclusive_range( seed: Seed, a: T, b: T, mean_stripe_numerator: u64, mean_stripe_denominator: u64, ) -> StripedRandomUnsignedInclusiveRange { assert!(a <= b); let diff_bits = T::WIDTH - (a ^ b).leading_zeros(); let mask = T::low_mask(diff_bits); let lo_template = a & !mask; let hi_template = lo_template | mask; StripedRandomUnsignedInclusiveRange { a, b, lo_template, hi_template, next_bit: diff_bits, bit_source: StripedBitSource::new(seed, mean_stripe_numerator, mean_stripe_denominator), } } /// Generates random striped signeds from a range. #[allow(clippy::large_enum_variant)] #[derive(Clone, Debug)] pub enum StripedRandomSignedInclusiveRange< U: PrimitiveUnsigned, S: PrimitiveSigned + WrappingFrom, > { NonNegative(PhantomData, StripedRandomUnsignedInclusiveRange), Negative(PhantomData, StripedRandomUnsignedInclusiveRange), Both( PhantomData, Box, StripedRandomUnsignedInclusiveRange, StripedRandomUnsignedInclusiveRange, ), } impl> Iterator for StripedRandomSignedInclusiveRange { type Item = S; fn next(&mut self) -> Option { match self { StripedRandomSignedInclusiveRange::NonNegative(_, xs) => { xs.next().map(S::wrapping_from) } StripedRandomSignedInclusiveRange::Negative(_, xs) => { xs.next().map(|x| S::wrapping_from(x).wrapping_neg()) } StripedRandomSignedInclusiveRange::Both(_, bs, xs_nn, xs_n) => { if bs.next().unwrap() { xs_nn.next().map(S::wrapping_from) } else { xs_n.next().map(|x| S::wrapping_from(x).wrapping_neg()) } } } } } /// Generates random striped signeds in the range $[a, b]$. /// /// See [here](self) for more information. /// /// The unsigneds are generated using a striped bit sequence with mean run length $m$ = /// `mean_stripe_numerator / mean_stripe_denominator`. /// /// Because the signeds are constrained to be within a certain range, the actual mean run length /// will usually not be $m$. Nonetheless, setting a higher $m$ will result in a higher mean run /// length. /// /// # Expected complexity per iteration /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `max(a.significant_bits(), /// b.significant_bits())`. /// /// # Panics /// Panics if `mean_stripe_denominator` is zero, if `mean_stripe_numerator <= /// mean_stripe_denominator`, or if $a \geq b$. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::striped::striped_random_signed_inclusive_range; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::strings::ToBinaryString; /// /// assert_eq!( /// prefix_to_string( /// striped_random_signed_inclusive_range::(EXAMPLE_SEED, -5, 10, 4, 1) /// .map(|x| x.to_binary_string()), /// 10 /// ), /// "[11111011, 11111100, 1000, 111, 11111111, 1000, 11, 1000, 0, 1000, ...]" /// ); /// ``` #[inline] pub fn striped_random_signed_range< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >( seed: Seed, a: S, b: S, mean_stripe_numerator: u64, mean_stripe_denominator: u64, ) -> StripedRandomSignedInclusiveRange { assert!(a < b); striped_random_signed_inclusive_range( seed, a, b - S::ONE, mean_stripe_numerator, mean_stripe_denominator, ) } /// Generates random striped signeds in the range $[a, b)$. /// /// See [here](self) for more information. /// /// The unsigneds are generated using a striped bit sequence with mean run length $m$ = /// `mean_stripe_numerator / mean_stripe_denominator`. /// /// Because the signeds are constrained to be within a certain range, the actual mean run length /// will usually not be $m$. Nonetheless, setting a higher $m$ will result in a higher mean run /// length. /// /// # Expected complexity per iteration /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `max(a.significant_bits(), /// b.significant_bits())`. /// /// # Panics /// Panics if `mean_stripe_denominator` is zero, if `mean_stripe_numerator <= /// mean_stripe_denominator`, or if $a > b$. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::striped::striped_random_signed_range; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::strings::ToBinaryString; /// /// assert_eq!( /// prefix_to_string( /// striped_random_signed_range::(EXAMPLE_SEED, -5, 11, 4, 1) /// .map(|x| x.to_binary_string()), /// 10 /// ), /// "[11111011, 11111100, 1000, 111, 11111111, 1000, 11, 1000, 0, 1000, ...]" /// ); /// ``` pub fn striped_random_signed_inclusive_range< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >( seed: Seed, a: S, b: S, mean_stripe_numerator: u64, mean_stripe_denominator: u64, ) -> StripedRandomSignedInclusiveRange { assert!(a <= b); if a >= S::ZERO { StripedRandomSignedInclusiveRange::NonNegative( PhantomData, striped_random_unsigned_inclusive_range( seed, U::wrapping_from(a), U::wrapping_from(b), mean_stripe_numerator, mean_stripe_denominator, ), ) } else if b < S::ZERO { StripedRandomSignedInclusiveRange::Negative( PhantomData, striped_random_unsigned_inclusive_range( seed, U::wrapping_from(b.wrapping_neg()), U::wrapping_from(a.wrapping_neg()), mean_stripe_numerator, mean_stripe_denominator, ), ) } else { StripedRandomSignedInclusiveRange::Both( PhantomData, Box::new(random_bools(seed.fork("sign"))), striped_random_unsigned_inclusive_range( seed.fork("non-negative"), U::ZERO, U::wrapping_from(b), mean_stripe_numerator, mean_stripe_denominator, ), striped_random_unsigned_inclusive_range( seed.fork("negative"), U::ONE, U::wrapping_from(a.wrapping_neg()), mean_stripe_numerator, mean_stripe_denominator, ), ) } } malachite-base-0.4.16/src/options/exhaustive.rs000064400000000000000000000040241046102023000175700ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use core::iter::{once, Chain, Once}; /// Generates all [`Option`]s except `None`, with values from a given iterator. /// /// This `struct` is created by [`exhaustive_somes`]; see its documentation for more. #[derive(Clone, Debug)] pub struct ExhaustiveSomes { xs: I, } impl Iterator for ExhaustiveSomes { type Item = Option; fn next(&mut self) -> Option> { self.xs.next().map(Some) } } /// Generates all [`Option`]s except `None`, with values from a given iterator. /// /// The elements of the given iterator are wrapped in `Some` and generated in the original order. /// /// The output length is `xs.count()`. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::options::exhaustive::exhaustive_somes; /// /// assert_eq!( /// exhaustive_somes([1, 2, 3].iter().cloned()).collect_vec(), /// &[Some(1), Some(2), Some(3)] /// ); /// ``` #[inline] pub const fn exhaustive_somes(xs: I) -> ExhaustiveSomes { ExhaustiveSomes { xs } } /// Generates all [`Option`]s with values from a given iterator. /// /// `None` comes first, followed by the elements of the given iterator wrapped in `Some`. /// /// The output length is `xs.count()`. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::options::exhaustive::exhaustive_options; /// /// assert_eq!( /// exhaustive_options([1, 2, 3].iter().cloned()).collect_vec(), /// &[None, Some(1), Some(2), Some(3)] /// ); /// ``` #[inline] pub fn exhaustive_options(xs: I) -> Chain>, ExhaustiveSomes> { once(None).chain(exhaustive_somes(xs)) } malachite-base-0.4.16/src/options/mod.rs000064400000000000000000000050671046102023000161720ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use core::str::FromStr; /// Converts a string to an `Option`, where `T` implements [`FromStr`]. /// /// If the string does not represent a valid `Option`, `None` is returned. /// /// If `T` does not implement [`FromStr`], try using [`option_from_str_custom`] instead. /// /// # Examples /// ``` /// use malachite_base::options::option_from_str; /// /// assert_eq!(option_from_str::("Some(false)"), Some(Some(false))); /// assert_eq!(option_from_str::("Some(5)"), Some(Some(5))); /// assert_eq!(option_from_str::("None"), Some(None)); /// assert_eq!(option_from_str::("Some(hi)"), None); /// assert_eq!(option_from_str::("abc"), None); /// ``` #[inline] pub fn option_from_str(src: &str) -> Option> { option_from_str_custom(&(|t| t.parse().ok()), src) } /// Converts a string to an `Option`, given a function to parse a string into a `T`. /// /// If the string does not represent a valid `Option`, `None` is returned. /// /// If `f` just uses the [`FromStr`] implementation on `T`, you can use [`option_from_str`] instead. /// /// # Examples /// ``` /// use malachite_base::options::{option_from_str, option_from_str_custom}; /// use malachite_base::orderings::ordering_from_str; /// use std::cmp::Ordering::{self, *}; /// /// assert_eq!( /// option_from_str_custom::(&ordering_from_str, "Some(Less)"), /// Some(Some(Less)) /// ); /// assert_eq!( /// option_from_str_custom::>(&option_from_str, "Some(Some(false))"), /// Some(Some(Some(false))) /// ); /// assert_eq!( /// option_from_str_custom::(&ordering_from_str, "Some(hi)"), /// None /// ); /// assert_eq!( /// option_from_str_custom::(&ordering_from_str, "abc"), /// None /// ); /// ``` pub fn option_from_str_custom(f: &dyn Fn(&str) -> Option, src: &str) -> Option> { if src == "None" { Some(None) } else if src.starts_with("Some(") && src.ends_with(')') { f(&src[5..src.len() - 1]).map(Some) } else { None } } /// Iterators that generate [`Option`]s without repetition. pub mod exhaustive; #[cfg(feature = "random")] /// Iterators that generate [`Option`]s randomly. pub mod random; malachite-base-0.4.16/src/options/random.rs000064400000000000000000000103351046102023000166650ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::bools::random::{weighted_random_bools, WeightedRandomBools}; use crate::random::Seed; /// Generates random [`Option`]s except `None`, with values from a given random iterator. /// /// This `struct` is created by [`random_somes`]; see its documentation for more. #[derive(Clone, Debug)] pub struct RandomSomes { xs: I, } impl Iterator for RandomSomes { type Item = Option; #[inline] fn next(&mut self) -> Option> { Some(self.xs.next()) } } /// Generates random [`Option`]s except `None`, with values from a given random iterator. /// /// The values have the same distribution as the values generated by the given iterator: If $Q(x)$ /// is the probability of $x$ being generated by `xs`, then /// /// $P(\operatorname{Some}(x)) = Q(x)$. /// /// `xs` must be infinite. /// /// The output length is infinite. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::random_primitive_ints; /// use malachite_base::options::random::random_somes; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::strings::ToDebugString; /// /// assert_eq!( /// prefix_to_string( /// random_somes(random_primitive_ints::(EXAMPLE_SEED)).map(|x| x.to_debug_string()), /// 5 /// ), /// "[Some(113), Some(239), Some(69), Some(108), Some(228), ...]", /// ) /// ``` pub const fn random_somes(xs: I) -> RandomSomes { RandomSomes { xs } } /// Generates random [`Option`]s with values from a given random iterator. /// /// We don't use [`WithSpecialValue`](crate::iterators::WithSpecialValue) here because that requires /// `I::Item` to be cloneable. The "special value" in this case, `None`, can be produced on demand /// without any cloning. /// /// This `struct` is created by [`random_options`]; see its documentation for more. #[derive(Clone, Debug)] pub struct RandomOptions { bs: WeightedRandomBools, xs: I, } impl Iterator for RandomOptions { type Item = Option; #[inline] fn next(&mut self) -> Option> { Some(if self.bs.next().unwrap() { self.xs.next() } else { None }) } } /// Generates random [`Option`]s with values from a given random iterator. /// /// The probability of generating `None` is specified by $p$ = `none_p_numerator / /// none_p_denominator`. If a `Some` is generated, its values have the same distribution as the /// values generated by the given iterator. /// /// If $Q(x)$ is the probability of $x$ being generated by `xs`, then /// /// $P(\text{None}) = p$ /// /// $P(\operatorname{Some}(x)) = (1-p)Q(x)$ /// /// `xs` must be infinite. /// /// The output length is infinite. /// /// # Panics /// Panics if `none_p_denominator` is 0 or `none_p_numerator > none_p_denominator`. /// /// # Examples /// ``` /// use malachite_base::iterators::prefix_to_string; /// use malachite_base::num::random::random_primitive_ints; /// use malachite_base::options::random::random_options; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::strings::ToDebugString; /// /// assert_eq!( /// prefix_to_string( /// random_options(EXAMPLE_SEED, 1, 2, &random_primitive_ints::) /// .map(|x| x.to_debug_string()), /// 10 /// ), /// "[Some(85), Some(11), Some(136), None, Some(200), None, Some(235), Some(134), Some(203), \ /// None, ...]" /// ) /// ``` pub fn random_options( seed: Seed, none_p_numerator: u64, none_p_denominator: u64, xs_gen: &dyn Fn(Seed) -> I, ) -> RandomOptions { RandomOptions { bs: weighted_random_bools( seed.fork("bs"), none_p_denominator - none_p_numerator, none_p_denominator, ), xs: xs_gen(seed.fork("xs")), } } malachite-base-0.4.16/src/orderings/exhaustive.rs000064400000000000000000000032061046102023000200720ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::orderings::ORDERINGS; use core::cmp::Ordering::{self, *}; use core::iter::Copied; use core::slice::Iter; pub type ExhaustiveOrderings = Copied>; /// Generates all [`Ordering`]s, in increasing order. /// /// The output length is 3. /// /// # Worst-case complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::orderings::exhaustive::orderings_increasing; /// use std::cmp::Ordering::*; /// /// assert_eq!( /// orderings_increasing().collect_vec(), /// &[Less, Equal, Greater] /// ); /// ``` #[inline] pub fn orderings_increasing() -> ExhaustiveOrderings { [Less, Equal, Greater].iter().copied() } /// Generates all [`Ordering`]s, with `Equal` coming first. /// /// The output length is 3. /// /// # Worst-case complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::orderings::exhaustive::exhaustive_orderings; /// use std::cmp::Ordering::*; /// /// assert_eq!( /// exhaustive_orderings().collect_vec(), /// &[Equal, Less, Greater] /// ); /// ``` #[inline] pub fn exhaustive_orderings() -> Copied> { ORDERINGS.iter().copied() } malachite-base-0.4.16/src/orderings/mod.rs000064400000000000000000000026041046102023000164650ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use core::cmp::Ordering::{self, *}; pub(crate) const ORDERINGS: [Ordering; 3] = [Equal, Less, Greater]; /// Converts a string to an [`Ordering`]. /// /// If the string does not represent a valid [`Ordering`], `None` is returned. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::orderings::ordering_from_str; /// use std::cmp::Ordering::*; /// /// assert_eq!(ordering_from_str("Equal"), Some(Equal)); /// assert_eq!(ordering_from_str("Less"), Some(Less)); /// assert_eq!(ordering_from_str("Greater"), Some(Greater)); /// assert_eq!(ordering_from_str("abc"), None); /// ``` #[inline] pub fn ordering_from_str(src: &str) -> Option { match src { "Equal" => Some(Equal), "Less" => Some(Less), "Greater" => Some(Greater), _ => None, } } /// Iterators that generate [`Ordering`]s without repetition. pub mod exhaustive; #[cfg(feature = "random")] /// Iterators that generate [`Ordering`]s randomly. pub mod random; malachite-base-0.4.16/src/orderings/random.rs000064400000000000000000000025741046102023000171740ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::orderings::ORDERINGS; use crate::random::Seed; use crate::slices::{random_values_from_slice, RandomValuesFromSlice}; use std::cmp::Ordering; use std::iter::Copied; pub type RandomOrderings = Copied>; /// Generates a random [`Ordering`] that has an equal probability of being `Less`, `Greater`, or /// `Equal`. /// /// $P(<) = P(=) = P(>) = \frac{1}{3}$. /// /// The output length is infinite. /// /// # Expected complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::orderings::random::random_orderings; /// use malachite_base::random::EXAMPLE_SEED; /// use std::cmp::Ordering::*; /// /// assert_eq!( /// random_orderings(EXAMPLE_SEED).take(10).collect_vec(), /// &[Less, Equal, Less, Greater, Less, Less, Equal, Less, Equal, Greater] /// ) /// ``` #[inline] pub fn random_orderings(seed: Seed) -> RandomOrderings { random_values_from_slice(seed, &ORDERINGS).copied() } malachite-base-0.4.16/src/random/mod.rs000064400000000000000000000073731046102023000157610ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use rand::{RngCore, SeedableRng}; use rand_chacha::ChaCha20Rng; use sha3::{Digest, Sha3_256}; /// A random seed used for reproducible testing. pub const EXAMPLE_SEED: Seed = Seed::from_bytes([ 0xbf, 0x18, 0x11, 0xce, 0x15, 0xee, 0xfd, 0x20, 0x2f, 0xdf, 0x67, 0x6a, 0x6b, 0xba, 0xaf, 0x04, 0xff, 0x71, 0xe0, 0xf8, 0x0b, 0x2a, 0xcf, 0x27, 0x85, 0xb3, 0x32, 0xc6, 0x20, 0x80, 0x5e, 0x36, ]); /// A type representing a random seed. #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)] pub struct Seed { pub bytes: [u8; 32], } impl Seed { /// Creates a `Seed` from a slice of 32 bytes. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::random::Seed; /// /// Seed::from_bytes([10; 32]); /// ``` #[inline] pub const fn from_bytes(bytes: [u8; 32]) -> Seed { Seed { bytes } } /// Creates a PRNG from a slice of 32 bytes. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::random::EXAMPLE_SEED; /// /// EXAMPLE_SEED.get_rng(); /// ``` #[inline] pub fn get_rng(self) -> ChaCha20Rng { ChaCha20Rng::from_seed(self.bytes) } /// Uniformly generates a random `Seed`. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::random::Seed; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// EXAMPLE_SEED.next(), /// Seed::from_bytes([ /// 0x71, 0xef, 0x45, 0x6c, 0xe4, 0xd2, 0xa8, 0xa1, 0x57, 0x20, 0x6e, 0x53, 0xbc, 0x22, /// 0x59, 0xee, 0x5d, 0xc8, 0x95, 0x73, 0xbd, 0x95, 0xd9, 0xc9, 0x75, 0x92, 0x1f, 0x48, /// 0x97, 0xa9, 0xae, 0x21 /// ]) /// ); /// ``` #[inline] pub fn next(self) -> Seed { let mut bytes = [0; 32]; self.get_rng().fill_bytes(&mut bytes); Seed::from_bytes(bytes) } /// Generates a new `Seed` from this seed. Passing different `key`s will, with very high /// probability, generate different seeds. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::random::Seed; /// use malachite_base::random::EXAMPLE_SEED; /// /// assert_eq!( /// EXAMPLE_SEED.fork("first"), /// Seed::from_bytes([ /// 0x20, 0x18, 0x1, 0x3d, 0x96, 0x4d, 0x3e, 0x98, 0x10, 0x9d, 0x35, 0x75, 0x22, 0x89, /// 0xf7, 0xe9, 0xbe, 0x2f, 0x9c, 0x15, 0x95, 0x42, 0x1a, 0x79, 0x52, 0xf, 0x56, 0x9a, /// 0x7b, 0x8c, 0xd9, 0x34 /// ]) /// ); /// assert_eq!( /// EXAMPLE_SEED.fork("second"), /// Seed::from_bytes([ /// 0xe0, 0x36, 0x88, 0x58, 0x6d, 0x67, 0x33, 0xea, 0xf2, 0x1c, 0x88, 0xf9, 0xe3, 0xbd, /// 0x52, 0xc0, 0xe5, 0xad, 0x61, 0x81, 0x21, 0xd8, 0x2f, 0x8e, 0xcd, 0xf, 0x89, 0x9d, /// 0x32, 0xc5, 0x35, 0x83 /// ]) /// ); /// ``` pub fn fork(&self, key: &str) -> Seed { let mut seed = self.next(); let forked_seed = &mut seed.bytes; let hash = Sha3_256::digest(key.as_bytes()); for i in 0..32 { forked_seed[i] ^= hash[i]; } seed.next() } } malachite-base-0.4.16/src/rational_sequences/access.rs000064400000000000000000000104751046102023000210440ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::rational_sequences::{rational_sequence_reduce, RationalSequence}; use core::ops::Index; impl Index for RationalSequence { type Output = T; /// Gets a reference to an element of a [`RationalSequence`] at an index. /// /// If the index is greater than or equal to the length of the sequence, this function panics. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Panics /// Panics if `index` is greater than or equal to the length of this sequence. /// /// # Examples /// ``` /// use malachite_base::rational_sequences::RationalSequence; /// /// assert_eq!(RationalSequence::from_slices(&[1, 2], &[3, 4])[1], 2); /// assert_eq!(RationalSequence::from_slices(&[1, 2], &[3, 4])[10], 3); /// ``` #[inline] fn index(&self, i: usize) -> &T { self.get(i).unwrap() } } impl RationalSequence { /// Gets a reference to an element of a [`RationalSequence`] at an index. /// /// If the index is greater than or equal to the length of the sequence, `None` is returned. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::rational_sequences::RationalSequence; /// /// assert_eq!( /// RationalSequence::from_slices(&[1, 2], &[3, 4]).get(1), /// Some(&2) /// ); /// assert_eq!( /// RationalSequence::from_slices(&[1, 2], &[3, 4]).get(10), /// Some(&3) /// ); /// ``` pub fn get(&self, i: usize) -> Option<&T> { let non_repeating_len = self.non_repeating.len(); if i < non_repeating_len { Some(&self.non_repeating[i]) } else if self.repeating.is_empty() { None } else { Some(&self.repeating[(i - non_repeating_len) % self.repeating.len()]) } } } impl RationalSequence { /// Mutates an element of a [`RationalSequence`] at an index using a provided closure, and then /// returns whatever the closure returns. /// /// If the index is greater than or equal to the length of the sequence, this function panics. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `index`. /// /// # Panics /// Panics if `index` is greater than or equal to the length of this sequence. /// /// # Examples /// ``` /// use malachite_base::rational_sequences::RationalSequence; /// /// let mut xs = RationalSequence::from_slices(&[1, 2], &[3, 4]); /// assert_eq!( /// xs.mutate(1, |x| { /// *x = 100; /// 25 /// }), /// 25 /// ); /// assert_eq!(xs, RationalSequence::from_slices(&[1, 100], &[3, 4])); /// /// let mut xs = RationalSequence::from_slices(&[1, 2], &[3, 4]); /// assert_eq!( /// xs.mutate(6, |x| { /// *x = 100; /// 25 /// }), /// 25 /// ); /// assert_eq!( /// xs, /// RationalSequence::from_slices(&[1, 2, 3, 4, 3, 4, 100], &[4, 3]) /// ); /// ``` pub fn mutate U, U>(&mut self, i: usize, f: F) -> U { let non_repeating_len = self.non_repeating.len(); let result = if i < non_repeating_len { f(&mut self.non_repeating[i]) } else if self.repeating.is_empty() { panic!("index out of bounds"); } else { let repeating_len = self.repeating.len(); let extra = i - non_repeating_len + 1; self.non_repeating .extend(self.repeating.iter().cycle().take(extra).cloned()); self.repeating.rotate_left(extra % repeating_len); f(&mut self.non_repeating[i]) }; rational_sequence_reduce(&mut self.non_repeating, &mut self.repeating); result } } malachite-base-0.4.16/src/rational_sequences/cmp.rs000064400000000000000000000034021046102023000203520ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::rational_sequences::RationalSequence; use core::cmp::Ordering::{self, *}; impl PartialOrd for RationalSequence { /// Compares a [`RationalSequence`] to another [`RationalSequence`]. /// /// See [here](RationalSequence::cmp) for more information. #[inline] fn partial_cmp(&self, other: &RationalSequence) -> Option { Some(self.cmp(other)) } } impl Ord for RationalSequence { /// Compares a [`RationalSequence`] to another [`RationalSequence`]. /// /// The comparison is made lexicographically with respect to the element type's ordering. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `self.component_len()`. /// /// # Examples /// ``` /// use malachite_base::rational_sequences::RationalSequence; /// /// assert!( /// RationalSequence::from_slice(&[1, 2]) < RationalSequence::from_slices(&[1, 2], &[1]) /// ); /// assert!( /// RationalSequence::from_slice(&[1, 2, 3]) /// < RationalSequence::from_slices(&[1, 2], &[3, 4]) /// ); /// ``` fn cmp(&self, other: &RationalSequence) -> Ordering { if self == other { Equal } else { Iterator::cmp(self.iter(), other.iter()) } } } malachite-base-0.4.16/src/rational_sequences/conversion.rs000064400000000000000000000155311046102023000217660ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::rational_sequences::{rational_sequence_reduce, RationalSequence}; use alloc::vec; use alloc::vec::Vec; impl RationalSequence { /// Converts a [`Vec`] to a finite [`RationalSequence`]. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::rational_sequences::RationalSequence; /// /// assert_eq!(RationalSequence::::from_vec(vec![]).to_string(), "[]"); /// assert_eq!( /// RationalSequence::::from_vec(vec![1, 2]).to_string(), /// "[1, 2]" /// ); /// ``` pub fn from_vec(non_repeating: Vec) -> RationalSequence { RationalSequence { non_repeating, repeating: vec![], } } /// Converts two [`Vec`]s to a finite [`RationalSequence`]. The first [`Vec`] is the /// nonrepeating part and the second is the repeating part. /// /// # Worst-case complexity /// $T(n, m) = O(n + m^{1+\varepsilon})$ for all $\varepsilon > 0$ /// /// $M(n, m) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, $n$ is `non_repeating.len()`, and $m$ is /// `repeating.len()`. /// /// # Examples /// ``` /// use malachite_base::rational_sequences::RationalSequence; /// /// assert_eq!( /// RationalSequence::::from_vecs(vec![], vec![]).to_string(), /// "[]" /// ); /// assert_eq!( /// RationalSequence::::from_vecs(vec![], vec![1, 2]).to_string(), /// "[[1, 2]]" /// ); /// assert_eq!( /// RationalSequence::::from_vecs(vec![1, 2], vec![]).to_string(), /// "[1, 2]" /// ); /// assert_eq!( /// RationalSequence::::from_vecs(vec![1, 2], vec![3, 4]).to_string(), /// "[1, 2, [3, 4]]" /// ); /// assert_eq!( /// RationalSequence::::from_vecs(vec![1, 2, 3], vec![4, 3]).to_string(), /// "[1, 2, [3, 4]]" /// ); /// ``` pub fn from_vecs(mut non_repeating: Vec, mut repeating: Vec) -> RationalSequence { rational_sequence_reduce(&mut non_repeating, &mut repeating); RationalSequence { non_repeating, repeating, } } /// Converts a [`RationalSequence`] to a pair of [`Vec`]s containing the non-repeating and /// repeating parts, taking the [`RationalSequence`] by value. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::rational_sequences::RationalSequence; /// /// assert_eq!( /// RationalSequence::from_slices(&[1, 2], &[3, 4]).into_vecs(), /// (vec![1, 2], vec![3, 4]) /// ); /// ``` #[allow(clippy::missing_const_for_fn)] // can't be const because of destructors pub fn into_vecs(self) -> (Vec, Vec) { (self.non_repeating, self.repeating) } /// Returns references to the non-repeating and repeating parts of a [`RationalSequence`]. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::rational_sequences::RationalSequence; /// /// assert_eq!( /// RationalSequence::from_slices(&[1u8, 2], &[3, 4]).slices_ref(), /// (&[1u8, 2][..], &[3u8, 4][..]) /// ); /// ``` pub fn slices_ref(&self) -> (&[T], &[T]) { (&self.non_repeating, &self.repeating) } } impl RationalSequence { /// Converts a slice to a finite [`RationalSequence`]. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`. /// /// # Examples /// ``` /// use malachite_base::rational_sequences::RationalSequence; /// /// assert_eq!(RationalSequence::::from_slice(&[]).to_string(), "[]"); /// assert_eq!( /// RationalSequence::::from_slice(&[1, 2]).to_string(), /// "[1, 2]" /// ); /// ``` pub fn from_slice(non_repeating: &[T]) -> RationalSequence { RationalSequence { non_repeating: non_repeating.to_vec(), repeating: vec![], } } /// Converts two slices to a finite [`RationalSequence`]. The first slice is the nonrepeating /// part and the second is the repeating part. /// /// # Worst-case complexity /// $T(n, m) = O(n + m^{1+\varepsilon})$ for all $\varepsilon > 0$ /// /// $M(n, m) = O(n + m)$ /// /// where $T$ is time, $M$ is additional memory, $n$ is `non_repeating.len()`, and $m$ is /// `repeating.len()`. /// /// # Examples /// ``` /// use malachite_base::rational_sequences::RationalSequence; /// /// assert_eq!( /// RationalSequence::::from_slices(&[], &[]).to_string(), /// "[]" /// ); /// assert_eq!( /// RationalSequence::::from_slices(&[], &[1, 2]).to_string(), /// "[[1, 2]]" /// ); /// assert_eq!( /// RationalSequence::::from_slices(&[1, 2], &[]).to_string(), /// "[1, 2]" /// ); /// assert_eq!( /// RationalSequence::::from_slices(&[1, 2], &[3, 4]).to_string(), /// "[1, 2, [3, 4]]" /// ); /// assert_eq!( /// RationalSequence::::from_slices(&[1, 2, 3], &[4, 3]).to_string(), /// "[1, 2, [3, 4]]" /// ); /// ``` pub fn from_slices(non_repeating: &[T], repeating: &[T]) -> RationalSequence { let mut non_repeating = non_repeating.to_vec(); let mut repeating = repeating.to_vec(); rational_sequence_reduce(&mut non_repeating, &mut repeating); RationalSequence { non_repeating, repeating, } } /// Converts a [`RationalSequence`] to a pair of [`Vec`]s containing the non-repeating and /// repeating parts, taking the [`RationalSequence`] by reference. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `xs.component_len()`. /// /// # Examples /// ``` /// use malachite_base::rational_sequences::RationalSequence; /// /// assert_eq!( /// RationalSequence::from_slices(&[1, 2], &[3, 4]).to_vecs(), /// (vec![1, 2], vec![3, 4]) /// ); /// ``` pub fn to_vecs(&self) -> (Vec, Vec) { (self.non_repeating.clone(), self.repeating.clone()) } } malachite-base-0.4.16/src/rational_sequences/exhaustive.rs000064400000000000000000000055101046102023000217620ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::exhaustive::PrimitiveIntIncreasingRange; use crate::rational_sequences::{rational_sequence_is_reduced, RationalSequence}; use crate::tuples::exhaustive::{exhaustive_pairs_from_single, ExhaustivePairs1Input}; use crate::vecs::exhaustive::{exhaustive_vecs, ExhaustiveVecs}; /// Generates all [`RationalSequence`]s containing elements from an iterator. /// /// This `struct` is created by [`exhaustive_rational_sequences`]; see its documentation for more. #[derive(Clone, Debug)] pub struct ExhaustiveRationalSequences( ExhaustivePairs1Input, I>>, ) where I::Item: Clone; impl Iterator for ExhaustiveRationalSequences where I::Item: Clone + Eq, { type Item = RationalSequence; fn next(&mut self) -> Option> { loop { let (non_repeating, repeating) = self.0.next()?; if rational_sequence_is_reduced(&non_repeating, &repeating) { return Some(RationalSequence { non_repeating, repeating, }); } } } } /// Generates all [`RationalSequence`]s containing elements from a given iterator. /// /// The input iterator should contain no repetitions, but this is not enforced. /// /// The output length is 1 if the input iterator is empty, and infinite otherwise. /// /// # Worst-case complexity per iteration /// $T(i) = O(T^\prime(i) + (\log i)^{1+\varepsilon})$ for all $\varepsilon > 0$ /// /// $M(i) = O((\log i) M^\prime(i))$ /// /// where $T$ is time, $M$ is additional memory, and $T^\prime$ and $M^\prime$ are the time and /// memory functions of the input iterator. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::exhaustive::exhaustive_unsigneds; /// use malachite_base::rational_sequences::exhaustive::exhaustive_rational_sequences; /// use malachite_base::strings::ToDebugString; /// /// assert_eq!( /// exhaustive_rational_sequences(exhaustive_unsigneds::()) /// .take(10) /// .collect_vec() /// .to_debug_string(), /// "[[], [[0]], [0], [[1]], [0, [1]], [1], [1, [0]], [0, 0, 0], [0, 0, 0, [1]], [[2]]]" /// ) /// ``` pub fn exhaustive_rational_sequences(xs: I) -> ExhaustiveRationalSequences where I::Item: Clone + Eq, { ExhaustiveRationalSequences(exhaustive_pairs_from_single(exhaustive_vecs(xs))) } malachite-base-0.4.16/src/rational_sequences/mod.rs000064400000000000000000000200641046102023000203550ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::slices::min_repeating_len; use alloc::vec::Vec; use core::iter::{Chain, Cycle}; fn rational_sequence_reduce(non_repeating: &mut Vec, repeating: &mut Vec) { if repeating.is_empty() { return; } repeating.truncate(min_repeating_len(repeating)); if non_repeating.is_empty() { return; } let extra_non_repeating = non_repeating .iter() .rev() .zip(repeating.iter().rev().cycle()) .take_while(|(x, y)| x == y) .count(); if extra_non_repeating != 0 { non_repeating.truncate(non_repeating.len() - extra_non_repeating); let len = repeating.len(); repeating.rotate_right(extra_non_repeating % len); } } pub_test! {rational_sequence_is_reduced(non_repeating: &[T], repeating: &[T]) -> bool { if repeating.is_empty() { return true; } if min_repeating_len(repeating) != repeating.len() { return false; } if non_repeating.is_empty() { return true; } non_repeating .iter() .rev() .zip(repeating.iter().rev().cycle()) .take_while(|(x, y)| x == y) .count() == 0 }} /// A `RationalSequence` is a sequence that is either finite or eventually repeating, just like the /// digits of a rational number. /// /// In testing, the set of rational sequences may be used as a proxy for the set of all sequences, /// which is too large to work with. #[derive(Clone, Default, Eq, Hash, PartialEq)] pub struct RationalSequence { non_repeating: Vec, repeating: Vec, } impl RationalSequence { /// Returns whether this `RationalSequence` is empty. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::rational_sequences::RationalSequence; /// /// assert_eq!(RationalSequence::::from_slice(&[]).is_empty(), true); /// assert_eq!( /// RationalSequence::::from_slice(&[1, 2, 3]).is_empty(), /// false /// ); /// assert_eq!( /// RationalSequence::::from_slices(&[], &[3, 4]).is_empty(), /// false /// ); /// assert_eq!( /// RationalSequence::::from_slices(&[1, 2], &[3, 4]).is_empty(), /// false /// ); /// ``` pub fn is_empty(&self) -> bool { self.non_repeating.is_empty() && self.repeating.is_empty() } /// Returns whether this `RationalSequence` is finite (has no repeating part). /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::rational_sequences::RationalSequence; /// /// assert_eq!(RationalSequence::::from_slice(&[]).is_finite(), true); /// assert_eq!( /// RationalSequence::::from_slice(&[1, 2, 3]).is_finite(), /// true /// ); /// assert_eq!( /// RationalSequence::::from_slices(&[], &[3, 4]).is_finite(), /// false /// ); /// assert_eq!( /// RationalSequence::::from_slices(&[1, 2], &[3, 4]).is_finite(), /// false /// ); /// ``` pub fn is_finite(&self) -> bool { self.repeating.is_empty() } /// Returns the length of this `RationalSequence`. If the sequence is infinite, `None` is /// returned. /// /// For a measure of length that always exists, try [`component_len`](Self::component_len). /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::rational_sequences::RationalSequence; /// /// assert_eq!(RationalSequence::::from_slice(&[]).len(), Some(0)); /// assert_eq!( /// RationalSequence::::from_slice(&[1, 2, 3]).len(), /// Some(3) /// ); /// assert_eq!( /// RationalSequence::::from_slices(&[], &[3, 4]).len(), /// None /// ); /// assert_eq!( /// RationalSequence::::from_slices(&[1, 2], &[3, 4]).len(), /// None /// ); /// ``` pub fn len(&self) -> Option { if self.repeating.is_empty() { Some(self.non_repeating.len()) } else { None } } /// Returns the sum of the lengths of the non-repeating and repeating parts of this /// `RationalSequence`. /// /// This is often a more useful way of measuring the complexity of a sequence than /// [`len`](Self::len). /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::rational_sequences::RationalSequence; /// /// assert_eq!(RationalSequence::::from_slice(&[]).component_len(), 0); /// assert_eq!( /// RationalSequence::::from_slice(&[1, 2, 3]).component_len(), /// 3 /// ); /// assert_eq!( /// RationalSequence::::from_slices(&[], &[3, 4]).component_len(), /// 2 /// ); /// assert_eq!( /// RationalSequence::::from_slices(&[1, 2], &[3, 4]).component_len(), /// 4 /// ); /// ``` pub fn component_len(&self) -> usize { self.non_repeating.len() + self.repeating.len() } /// Returns an iterator of references to the elements of this sequence. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::rational_sequences::RationalSequence; /// /// let empty: &[u8] = &[]; /// assert_eq!( /// RationalSequence::::from_slice(empty) /// .iter() /// .cloned() /// .collect_vec(), /// empty /// ); /// assert_eq!( /// RationalSequence::::from_slice(&[1, 2, 3]) /// .iter() /// .cloned() /// .collect_vec(), /// &[1, 2, 3] /// ); /// assert_eq!( /// RationalSequence::::from_slices(&[], &[3, 4]) /// .iter() /// .cloned() /// .take(10) /// .collect_vec(), /// &[3, 4, 3, 4, 3, 4, 3, 4, 3, 4] /// ); /// assert_eq!( /// RationalSequence::::from_slices(&[1, 2], &[3, 4]) /// .iter() /// .cloned() /// .take(10) /// .collect_vec(), /// &[1, 2, 3, 4, 3, 4, 3, 4, 3, 4] /// ); /// ``` pub fn iter(&self) -> Chain, Cycle>> { self.non_repeating .iter() .chain(self.repeating.iter().cycle()) } } impl RationalSequence { // Returns true iff `self` is valid. // // To be valid, the non-repeating and repeating parts must be reduced. For example, `[1, 2]` and // `[3, 4]` is a reduced pair. On the other hand, `[1, 2]` and `[3, 4, 3, 4]` is a non-reduced // pair representing the same sequence, as is `[1, 2, 3]` and `[4, 3]`. All `RationalSequence`s // must be valid. #[cfg(feature = "test_build")] pub fn is_valid(&self) -> bool { rational_sequence_is_reduced(&self.non_repeating, &self.repeating) } } /// Functions for getting and setting elements in a [`RationalSequence`]. pub mod access; /// Functions for comparing [`RationalSequence`]s. pub mod cmp; /// Functions for converting a [`RationalSequence`]s to and from a [`Vec`] or a slice. pub mod conversion; /// Functions for generating all [`RationalSequence`]s over a set of elements. pub mod exhaustive; #[cfg(feature = "random")] /// Functions for generating random [`RationalSequence`]s from a set of elements. pub mod random; /// Functions for displaying a [`RationalSequence`]. pub mod to_string; malachite-base-0.4.16/src/rational_sequences/random.rs000064400000000000000000000060631046102023000210610ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::random::geometric::GeometricRandomNaturalValues; use crate::random::Seed; use crate::rational_sequences::RationalSequence; use crate::vecs::random::{random_vecs, RandomVecs}; /// Generates random [`RationalSequence`]s, given an iterator of random elements. /// /// This `struct` is created by [`random_rational_sequences`]; see its documentation for more. #[derive(Clone, Debug)] pub struct RandomRationalSequences( RandomVecs, I>, ) where I::Item: Eq; impl Iterator for RandomRationalSequences where I::Item: Eq, { type Item = RationalSequence; fn next(&mut self) -> Option> { Some(RationalSequence::from_vecs( self.0.next().unwrap(), self.0.next().unwrap(), )) } } /// Generates random [`RationalSequence`]s whose non-repeating and repeating components have a /// specified mean length, with elements from a given iterator. /// /// The input iterator must be infinite, but this is not enforced. /// /// The output length is infinite. /// /// # Panics /// Panics if `mean_length_numerator` or `mean_length_denominator` are zero, or, if after being /// reduced to lowest terms, their sum is greater than or equal to $2^{64}$. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::random::random_primitive_ints; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::rational_sequences::random::random_rational_sequences; /// use malachite_base::rational_sequences::RationalSequence; /// /// assert_eq!( /// random_rational_sequences(EXAMPLE_SEED, &random_primitive_ints::, 4, 1) /// .take(10) /// .map(|x| RationalSequence::to_string(&x)) /// .collect_vec(), /// &[ /// "[[85, 11, 136, 200, 235, 134, 203, 223, 38, 235, 217, 177, 162, 32]]", /// "[166, 234, 30, 218, [90, 106, 9, 216]]", /// "[204]", /// "[151, 213, 97, 253, 78, [91, 39]]", /// "[191, 175, 170, 232]", /// "[233, 2, 35, 22, 217, 198]", /// "[[114, 17, 32, 173, 114, 65, 121, 222, 173, 25, 144]]", /// "[148, 79, 115, 52, 73, 69, 137, 91]", /// "[153, 178, 112]", /// "[34, 95, 106, 167, 197, [130, 168, 122, 207, 172, 177, 86, 150, 221]]" /// ] /// ) /// ``` pub fn random_rational_sequences( seed: Seed, xs_gen: &dyn Fn(Seed) -> I, mean_length_numerator: u64, mean_length_denominator: u64, ) -> RandomRationalSequences where I::Item: Eq, { RandomRationalSequences(random_vecs( seed, xs_gen, mean_length_numerator, mean_length_denominator, )) } malachite-base-0.4.16/src/rational_sequences/to_string.rs000064400000000000000000000065721046102023000216160ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::rational_sequences::RationalSequence; use core::fmt::{Debug, Display, Formatter, Result, Write}; impl Display for RationalSequence { /// Converts a [`RationalSequence`] to a [`String`]. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `self.component_len()`. /// /// # Examples /// ``` /// use malachite_base::rational_sequences::RationalSequence; /// /// assert_eq!( /// RationalSequence::::from_vecs(vec![], vec![]).to_string(), /// "[]" /// ); /// assert_eq!( /// RationalSequence::::from_vecs(vec![], vec![1, 2]).to_string(), /// "[[1, 2]]" /// ); /// assert_eq!( /// RationalSequence::::from_vecs(vec![1, 2], vec![]).to_string(), /// "[1, 2]" /// ); /// assert_eq!( /// RationalSequence::::from_vecs(vec![1, 2], vec![3, 4]).to_string(), /// "[1, 2, [3, 4]]" /// ); /// ``` fn fmt(&self, f: &mut Formatter) -> Result { f.write_char('[')?; let mut first = true; for x in &self.non_repeating { if first { first = false; } else { f.write_str(", ")?; } Display::fmt(x, f)?; } if !self.repeating.is_empty() { if !self.non_repeating.is_empty() { f.write_str(", ")?; } f.write_char('[')?; let mut first = true; for x in &self.repeating { if first { first = false; } else { f.write_str(", ")?; } Display::fmt(x, f)?; } f.write_char(']')?; } f.write_char(']') } } impl Debug for RationalSequence { /// Converts a [`RationalSequence`] to a [`String`]. /// /// This is the same implementation as for [`Display`]. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `self.component_len()`. /// /// # Examples /// ``` /// use malachite_base::rational_sequences::RationalSequence; /// use malachite_base::strings::ToDebugString; /// /// assert_eq!( /// RationalSequence::::from_vecs(vec![], vec![]).to_debug_string(), /// "[]" /// ); /// assert_eq!( /// RationalSequence::::from_vecs(vec![], vec![1, 2]).to_debug_string(), /// "[[1, 2]]" /// ); /// assert_eq!( /// RationalSequence::::from_vecs(vec![1, 2], vec![]).to_debug_string(), /// "[1, 2]" /// ); /// assert_eq!( /// RationalSequence::::from_vecs(vec![1, 2], vec![3, 4]).to_string(), /// "[1, 2, [3, 4]]" /// ); /// ``` fn fmt(&self, f: &mut Formatter) -> Result { Display::fmt(self, f) } } malachite-base-0.4.16/src/rounding_modes/exhaustive.rs000064400000000000000000000021701046102023000211110ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::rounding_modes::{RoundingMode, ROUNDING_MODES}; use core::iter::Copied; use core::slice::Iter; pub type ExhaustiveRoundingModes = Copied>; /// Generates all [`RoundingMode`]s. /// /// The output length is 6. /// /// # Complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::rounding_modes::exhaustive::exhaustive_rounding_modes; /// use malachite_base::rounding_modes::RoundingMode::*; /// /// assert_eq!( /// exhaustive_rounding_modes().collect_vec(), /// &[Down, Up, Floor, Ceiling, Nearest, Exact,] /// ); /// ``` #[inline] pub fn exhaustive_rounding_modes() -> ExhaustiveRoundingModes { ROUNDING_MODES.iter().copied() } malachite-base-0.4.16/src/rounding_modes/from_str.rs000064400000000000000000000037221046102023000205630ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::rounding_modes::RoundingMode::{self, *}; use alloc::string::String; use alloc::string::ToString; use core::str::FromStr; impl FromStr for RoundingMode { type Err = String; /// Converts a string to a [`RoundingMode`]. /// /// If the string does not represent a valid [`RoundingMode`], an `Err` is returned with the /// unparseable string. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ = `src.len()`. /// /// The worst case occurs when the input string is invalid and must be copied into an `Err`. /// /// # Examples /// ``` /// use malachite_base::rounding_modes::RoundingMode::{self, *}; /// use std::str::FromStr; /// /// assert_eq!(RoundingMode::from_str("Down"), Ok(Down)); /// assert_eq!(RoundingMode::from_str("Up"), Ok(Up)); /// assert_eq!(RoundingMode::from_str("Floor"), Ok(Floor)); /// assert_eq!(RoundingMode::from_str("Ceiling"), Ok(Ceiling)); /// assert_eq!(RoundingMode::from_str("Nearest"), Ok(Nearest)); /// assert_eq!(RoundingMode::from_str("Exact"), Ok(Exact)); /// assert_eq!(RoundingMode::from_str("abc"), Err("abc".to_string())); /// ``` #[inline] fn from_str(src: &str) -> Result { match src { "Down" => Ok(Down), "Up" => Ok(Up), "Floor" => Ok(Floor), "Ceiling" => Ok(Ceiling), "Nearest" => Ok(Nearest), "Exact" => Ok(Exact), _ => Err(src.to_string()), } } } malachite-base-0.4.16/src/rounding_modes/mod.rs000064400000000000000000000100611046102023000175010ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::named::Named; use crate::rounding_modes::RoundingMode::*; /// An enum that specifies how a value should be rounded. /// /// A `RoundingMode` can often be specified when a function conceptually returns a value of one /// type, but must be rounded to another type. The most common case is a conceptually real-valued /// function whose result must be rounded to an integer, like /// [`div_round`](crate::num::arithmetic::traits::DivRound::div_round). /// /// # Examples /// Here are some examples of how floating-point values would be rounded to integer values using the /// different `RoundingMode`s. /// /// | x | `Floor` | `Ceiling` | `Down` | `Up` | `Nearest` | `Exact` | /// |------|---------|-----------|--------|------|-----------|------------| /// | 3.0 | 3 | 3 | 3 | 3 | 3 | 3 | /// | 3.2 | 3 | 4 | 3 | 4 | 3 | `panic!()` | /// | 3.8 | 3 | 4 | 3 | 4 | 4 | `panic!()` | /// | 3.5 | 3 | 4 | 3 | 4 | 4 | `panic!()` | /// | 4.5 | 4 | 5 | 4 | 5 | 4 | `panic!()` | /// | -3.2 | -4 | -3 | -3 | -4 | -3 | `panic!()` | /// | -3.8 | -4 | -3 | -3 | -4 | -4 | `panic!()` | /// | -3.5 | -4 | -3 | -3 | -4 | -4 | `panic!()` | /// | -4.5 | -5 | -4 | -4 | -5 | -4 | `panic!()` | /// /// Sometimes a `RoundingMode` is used in an unusual context, such as rounding an integer to a /// floating-point number, in which case further explanation of its behavior is provided at the /// usage site. /// /// A `RoundingMode` takes up 1 byte of space. #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] pub enum RoundingMode { /// Applies the function $x \mapsto \operatorname{sgn}(x) \lfloor |x| \rfloor$. In other words, /// the value is rounded towards $0$. Down, /// Applies the function $x \mapsto \operatorname{sgn}(x) \lceil |x| \rceil$. In other words, /// the value is rounded away from $0$. Up, /// Applies the floor function: $x \mapsto \lfloor x \rfloor$. In other words, the value is /// rounded towards $-\infty$. Floor, /// Applies the ceiling function: $x \mapsto \lceil x \rceil$. In other words, the value is /// rounded towards $\infty$. Ceiling, /// Applies the function /// $$ /// x \mapsto \\begin{cases} /// \lfloor x \rfloor & x - \lfloor x \rfloor < \frac{1}{2} \\\\ /// \lceil x \rceil & x - \lfloor x \rfloor > \frac{1}{2} \\\\ /// \lfloor x \rfloor & /// x - \lfloor x \rfloor = \frac{1}{2} \\ \text{and} /// \\ \lfloor x \rfloor \\ \text{is even} \\\\ /// \lceil x \rceil & /// x - \lfloor x \rfloor = \frac{1}{2} \\ \text{and} \\ \lfloor x \rfloor \\ \text{is odd.} /// \\end{cases} /// $$ /// In other words, it rounds to the nearest integer, and when there's a tie, it rounds to the /// nearest even integer. This is also called _bankers' rounding_ and is often used as a /// default. Nearest, /// Panics if the value is not already rounded. Exact, } impl_named!(RoundingMode); /// A list of all six rounding modes. pub const ROUNDING_MODES: [RoundingMode; 6] = [Down, Up, Floor, Ceiling, Nearest, Exact]; /// Iterators that generate [`RoundingMode`]s without repetition. pub mod exhaustive; /// Functions for converting a string to a [`RoundingMode`]. pub mod from_str; /// Functions for negating a [`RoundingMode`]. pub mod neg; #[cfg(feature = "random")] /// Iterators that generate [`RoundingMode`]s randomly. pub mod random; /// Functions for displaying a [`RoundingMode`]. pub mod to_string; malachite-base-0.4.16/src/rounding_modes/neg.rs000064400000000000000000000044131046102023000174770ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::NegAssign; use crate::rounding_modes::RoundingMode::{self, *}; use core::ops::Neg; /// Returns the negative of a [`RoundingMode`]. /// /// The negative is defined so that if a [`RoundingMode`] $m$ is used to round the result of an odd /// function $f$, then $f(x, -m) = -f(-x, m)$. `Floor` and `Ceiling` are swapped, and the other /// modes are unchanged. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::rounding_modes::RoundingMode::*; /// /// assert_eq!(-Down, Down); /// assert_eq!(-Up, Up); /// assert_eq!(-Floor, Ceiling); /// assert_eq!(-Ceiling, Floor); /// assert_eq!(-Nearest, Nearest); /// assert_eq!(-Exact, Exact); /// ``` impl Neg for RoundingMode { type Output = RoundingMode; #[inline] fn neg(self) -> RoundingMode { match self { Floor => Ceiling, Ceiling => Floor, rm => rm, } } } impl NegAssign for RoundingMode { /// Replaces a [`RoundingMode`] with its negative. /// /// The negative is defined so that if a [`RoundingMode`] $m$ is used to round the result of an /// odd function $f$, then $f(x, -m) = -f(-x, m)$. `Floor` and `Ceiling` are swapped, and the /// other modes are unchanged. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::num::arithmetic::traits::NegAssign; /// use malachite_base::rounding_modes::RoundingMode::*; /// /// let mut rm = Down; /// rm.neg_assign(); /// assert_eq!(rm, Down); /// /// let mut rm = Floor; /// rm.neg_assign(); /// assert_eq!(rm, Ceiling); /// ``` #[inline] fn neg_assign(&mut self) { if *self == Floor { *self = Ceiling; } else if *self == Ceiling { *self = Floor; } } } malachite-base-0.4.16/src/rounding_modes/random.rs000064400000000000000000000025711046102023000202110ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::random::Seed; use crate::rounding_modes::{RoundingMode, ROUNDING_MODES}; use crate::slices::{random_values_from_slice, RandomValuesFromSlice}; use std::iter::Copied; /// Uniformly generates random [`RoundingMode`]s. pub type RandomRoundingModes = Copied>; /// Uniformly generates random [`RoundingMode`]s. /// /// The output length is infinite. /// /// # Expected complexity /// /// Constant time and additional memory. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::rounding_modes::random::random_rounding_modes; /// use malachite_base::rounding_modes::RoundingMode::*; /// /// assert_eq!( /// random_rounding_modes(EXAMPLE_SEED).take(10).collect_vec(), /// &[Up, Exact, Ceiling, Up, Floor, Nearest, Exact, Up, Floor, Exact] /// ) /// ``` #[inline] pub fn random_rounding_modes(seed: Seed) -> RandomRoundingModes { random_values_from_slice(seed, &ROUNDING_MODES).copied() } malachite-base-0.4.16/src/rounding_modes/to_string.rs000064400000000000000000000021731046102023000207370ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::rounding_modes::RoundingMode; use core::fmt::{Debug, Display, Formatter, Result}; impl Display for RoundingMode { /// Converts a [`RoundingMode`] to a [`String`]. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// ``` /// use malachite_base::rounding_modes::RoundingMode::*; /// /// assert_eq!(Down.to_string(), "Down"); /// assert_eq!(Up.to_string(), "Up"); /// assert_eq!(Floor.to_string(), "Floor"); /// assert_eq!(Ceiling.to_string(), "Ceiling"); /// assert_eq!(Nearest.to_string(), "Nearest"); /// assert_eq!(Exact.to_string(), "Exact"); /// ``` #[inline] fn fmt(&self, f: &mut Formatter) -> Result { Debug::fmt(self, f) } } malachite-base-0.4.16/src/sets/exhaustive.rs000064400000000000000000001325471046102023000170670ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::vecs::exhaustive::{ ExhaustiveOrderedUniqueCollections, LexFixedLengthOrderedUniqueCollections, LexOrderedUniqueCollections, ShortlexOrderedUniqueCollections, }; #[cfg(not(feature = "test_build"))] use alloc::collections::BTreeSet; use core::hash::Hash; #[cfg(not(feature = "test_build"))] use hashbrown::HashSet; #[cfg(feature = "test_build")] use std::collections::{BTreeSet, HashSet}; /// Generates [`HashSet`]s of a given size with elements from a single iterator. /// /// The [`HashSet`]s are ordered lexicographically with respect to the order of the element /// iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// If $k$ is 0, the output length is 1. /// /// If $k$ is nonzero and the input iterator is infinite, the output length is also infinite. /// /// If $k$ is nonzero and the input iterator length is $n$, the output length is $\binom{n}{k}$. /// /// If $k$ is 0, the output consists of one empty [`HashSet`]. /// /// If `xs` is empty, the output is also empty, unless $k$ is 0. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::sets::exhaustive::lex_hash_sets_fixed_length; /// use maplit::hashset; /// /// let xss = lex_hash_sets_fixed_length(4, 1..=6).collect_vec(); /// assert_eq!( /// xss, /// &[ /// hashset! {1, 2, 3, 4}, /// hashset! {1, 2, 3, 5}, /// hashset! {1, 2, 3, 6}, /// hashset! {1, 2, 4, 5}, /// hashset! {1, 2, 4, 6}, /// hashset! {1, 2, 5, 6}, /// hashset! {1, 3, 4, 5}, /// hashset! {1, 3, 4, 6}, /// hashset! {1, 3, 5, 6}, /// hashset! {1, 4, 5, 6}, /// hashset! {2, 3, 4, 5}, /// hashset! {2, 3, 4, 6}, /// hashset! {2, 3, 5, 6}, /// hashset! {2, 4, 5, 6}, /// hashset! {3, 4, 5, 6} /// ] /// ); /// ``` #[inline] pub fn lex_hash_sets_fixed_length( k: u64, xs: I, ) -> LexFixedLengthOrderedUniqueCollections> where I::Item: Clone + Eq + Hash, { LexFixedLengthOrderedUniqueCollections::new(k, xs) } /// Generates [`HashSet`]s with elements from a single iterator. /// /// The [`HashSet`]s are generated in order of increasing length, and within each length they are /// ordered lexicographically with respect to the order of the element iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, [`HashSet`]s of length 2 and above will never /// be generated. /// /// If the input iterator is infinite, the output length is also infinite. /// /// If the input iterator length is $n$, the output length is $2^n$. /// /// If `xs` is empty, the output consists of a single empty [`HashSet`]. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::sets::exhaustive::shortlex_hash_sets; /// use maplit::hashset; /// /// let xss = shortlex_hash_sets(1..=4).collect_vec(); /// assert_eq!( /// xss, /// &[ /// hashset! {}, /// hashset! {1}, /// hashset! {2}, /// hashset! {3}, /// hashset! {4}, /// hashset! {1, 2}, /// hashset! {1, 3}, /// hashset! {1, 4}, /// hashset! {2, 3}, /// hashset! {2, 4}, /// hashset! {3, 4}, /// hashset! {1, 2, 3}, /// hashset! {1, 2, 4}, /// hashset! {1, 3, 4}, /// hashset! {2, 3, 4}, /// hashset! {1, 2, 3, 4} /// ] /// ); /// ``` #[inline] pub fn shortlex_hash_sets( xs: I, ) -> ShortlexOrderedUniqueCollections> where I::Item: Clone + Eq + Hash, { shortlex_hash_sets_length_inclusive_range(0, u64::MAX, xs) } /// Generates [`HashSet`]s with a mininum length, with elements from a single iterator. /// /// The [`HashSet`]s are generated in order of increasing length, and within each length they are /// ordered lexicographically with respect to the order of the element iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, [`HashSet`]s of length `\max(2, \ell + 1)` and /// above will never be generated. /// /// If the input iterator is infinite, the output length is also infinite. /// /// If the input iterator length is $n$ and the `min_length` is $\ell$, the output length is /// $$ /// \sum_{i=\ell}^n \binom{n}{i}. /// $$ /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::sets::exhaustive::shortlex_hash_sets_min_length; /// use maplit::hashset; /// /// let xss = shortlex_hash_sets_min_length(2, 1..=4).collect_vec(); /// assert_eq!( /// xss, /// &[ /// hashset! {1, 2}, /// hashset! {1, 3}, /// hashset! {1, 4}, /// hashset! {2, 3}, /// hashset! {2, 4}, /// hashset! {3, 4}, /// hashset! {1, 2, 3}, /// hashset! {1, 2, 4}, /// hashset! {1, 3, 4}, /// hashset! {2, 3, 4}, /// hashset! {1, 2, 3, 4} /// ] /// ); /// ``` #[inline] pub fn shortlex_hash_sets_min_length( min_length: u64, xs: I, ) -> ShortlexOrderedUniqueCollections> where I::Item: Clone + Eq + Hash, { shortlex_hash_sets_length_inclusive_range(min_length, u64::MAX, xs) } /// Generates [`HashSet`]s, with lengths in a range $[a, b)$, with elements from a single iterator. /// /// The [`HashSet`]s are generated in order of increasing length, and within each length they are /// ordered lexicographically with respect to the order of the element iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, [`HashSet`]s of length `\max(2, a + 1)` and /// above will never be generated. /// /// If $a \leq b$, the output is empty. /// /// If $a = 0$ and $b = 1$, the output consists of a single empty [`HashSet`]. /// /// If the input iterator is infinite and $0 < a < b$, the output length is also infinite. /// /// If the input iterator length is $n$, the output length is /// $$ /// \sum_{i=a}^b - 1 \binom{n}{i}. /// $$ /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::sets::exhaustive::shortlex_hash_sets_length_range; /// use maplit::hashset; /// /// let xss = shortlex_hash_sets_length_range(2, 4, 1..=4).collect_vec(); /// assert_eq!( /// xss, /// &[ /// hashset! {1, 2}, /// hashset! {1, 3}, /// hashset! {1, 4}, /// hashset! {2, 3}, /// hashset! {2, 4}, /// hashset! {3, 4}, /// hashset! {1, 2, 3}, /// hashset! {1, 2, 4}, /// hashset! {1, 3, 4}, /// hashset! {2, 3, 4}, /// ] /// ); /// ``` #[inline] pub fn shortlex_hash_sets_length_range( mut a: u64, mut b: u64, xs: I, ) -> ShortlexOrderedUniqueCollections> where I::Item: Clone + Eq + Hash, { if b == 0 { // Transform an empty (x, 0) range into (2, 1), which is also empty but doesn't cause // overflow a = 2; b = 1; } shortlex_hash_sets_length_inclusive_range(a, b - 1, xs) } /// Generates [`HashSet`]s, with lengths in a range $[a, b]$, with elements from a single iterator. /// /// The [`HashSet`]s are generated in order of increasing length, and within each length they are /// ordered lexicographically with respect to the order of the element iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, [`HashSet`]s of length `\max(2, a + 1)` and /// above will never be generated. /// /// If $a < b$, the output is empty. /// /// If $a = b = 0$, the output consists of a single empty [`HashSet`]. /// /// If the input iterator is infinite and $0 < a \leq b$, the output length is also infinite. /// /// If the input iterator length is $n$, the output length is /// $$ /// \sum_{i=a}^b \binom{n}{i}. /// $$ /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::sets::exhaustive::shortlex_hash_sets_length_inclusive_range; /// use maplit::hashset; /// /// let xss = shortlex_hash_sets_length_inclusive_range(2, 3, 1..=4).collect_vec(); /// assert_eq!( /// xss, /// &[ /// hashset! {1, 2}, /// hashset! {1, 3}, /// hashset! {1, 4}, /// hashset! {2, 3}, /// hashset! {2, 4}, /// hashset! {3, 4}, /// hashset! {1, 2, 3}, /// hashset! {1, 2, 4}, /// hashset! {1, 3, 4}, /// hashset! {2, 3, 4}, /// ] /// ); /// ``` #[inline] pub fn shortlex_hash_sets_length_inclusive_range( a: u64, b: u64, xs: I, ) -> ShortlexOrderedUniqueCollections> where I::Item: Clone + Eq + Hash, { ShortlexOrderedUniqueCollections::new(a, b, xs) } /// Generates [`HashSet`]s with elements from a single iterator. /// /// The [`HashSet`]s are ordered lexicographically with respect to the order of the element /// iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, only prefixes of the iterator will be /// generated. /// /// If the input iterator is infinite, the output length is also infinite. /// /// If the input iterator length is $n$, the output length is $2^n$. /// /// If `xs` is empty, the output consists of a single empty [`HashSet`]. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::sets::exhaustive::lex_hash_sets; /// use maplit::hashset; /// /// let xss = lex_hash_sets(1..=4).collect_vec(); /// assert_eq!( /// xss, /// &[ /// hashset! {}, /// hashset! {1}, /// hashset! {1, 2}, /// hashset! {1, 2, 3}, /// hashset! {1, 2, 3, 4}, /// hashset! {1, 2, 4}, /// hashset! {1, 3}, /// hashset! {1, 3, 4}, /// hashset! {1, 4}, /// hashset! {2}, /// hashset! {2, 3}, /// hashset! {2, 3, 4}, /// hashset! {2, 4}, /// hashset! {3}, /// hashset! {3, 4}, /// hashset! {4} /// ] /// ); /// ``` #[inline] pub fn lex_hash_sets(xs: I) -> LexOrderedUniqueCollections> where I::Item: Clone + Eq + Hash, { lex_hash_sets_length_inclusive_range(0, u64::MAX, xs) } /// Generates [`HashSet`]s with a mininum length, with elements from a single iterator. /// /// The [`HashSet`]s are ordered lexicographically with respect to the order of the element /// iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, only prefixes of the iterator will be /// generated. /// /// If the input iterator is infinite, the output length is also infinite. /// /// If the input iterator length is $n$ and the `min_length` is $\ell$, the output length is /// $$ /// \sum_{i=\ell}^n \binom{n}{i}. /// $$ /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::sets::exhaustive::lex_hash_sets_min_length; /// use maplit::hashset; /// /// let xss = lex_hash_sets_min_length(2, 1..=4).collect_vec(); /// assert_eq!( /// xss, /// &[ /// hashset! {1, 2}, /// hashset! {1, 2, 3}, /// hashset! {1, 2, 3, 4}, /// hashset! {1, 2, 4}, /// hashset! {1, 3}, /// hashset! {1, 3, 4}, /// hashset! {1, 4}, /// hashset! {2, 3}, /// hashset! {2, 3, 4}, /// hashset! {2, 4}, /// hashset! {3, 4}, /// ] /// ); /// ``` #[inline] pub fn lex_hash_sets_min_length( min_length: u64, xs: I, ) -> LexOrderedUniqueCollections> where I::Item: Clone + Eq + Hash, { lex_hash_sets_length_inclusive_range(min_length, u64::MAX, xs) } /// Generates [`HashSet`]s, with lengths in a range $[a, b)$, with elements from a single iterator. /// /// The [`HashSet`]s are ordered lexicographically with respect to the order of the element /// iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, only prefixes of the iterator will be /// generated. /// /// If $a \leq b$, the output is empty. /// /// If $a = 0$ and $b = 1$, the output consists of a single empty [`HashSet`]. /// /// If the input iterator is infinite and $0 < a < b$, the output length is also infinite. /// /// If the input iterator length is $n$, the output length is /// $$ /// \sum_{i=a}^b - 1 \binom{n}{i}. /// $$ /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::sets::exhaustive::lex_hash_sets_length_range; /// use maplit::hashset; /// /// let xss = lex_hash_sets_length_range(2, 4, 1..=4).collect_vec(); /// assert_eq!( /// xss, /// &[ /// hashset! {1, 2}, /// hashset! {1, 2, 3}, /// hashset! {1, 2, 4}, /// hashset! {1, 3}, /// hashset! {1, 3, 4}, /// hashset! {1, 4}, /// hashset! {2, 3}, /// hashset! {2, 3, 4}, /// hashset! {2, 4}, /// hashset! {3, 4}, /// ] /// ); /// ``` #[inline] pub fn lex_hash_sets_length_range( mut a: u64, mut b: u64, xs: I, ) -> LexOrderedUniqueCollections> where I::Item: Clone + Eq + Hash, { if b == 0 { // Transform an empty (x, 0) range into (2, 1), which is also empty but doesn't cause // overflow a = 2; b = 1; } lex_hash_sets_length_inclusive_range(a, b - 1, xs) } /// Generates [`HashSet`]s, with lengths in a range $[a, b]$, with elements from a single iterator. /// /// The [`HashSet`]s are ordered lexicographically with respect to the order of the element /// iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, only prefixes of the iterator will be /// generated. /// /// If $a < b$, the output is empty. /// /// If $a = b = 0$, the output consists of a single empty [`HashSet`]. /// /// If the input iterator is infinite and $0 < a \leq b$, the output length is also infinite. /// /// If the input iterator length is $n$, the output length is /// $$ /// \sum_{i=a}^b \binom{n}{i}. /// $$ /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::sets::exhaustive::lex_hash_sets_length_inclusive_range; /// use maplit::hashset; /// /// let xss = lex_hash_sets_length_inclusive_range(2, 3, 1..=4).collect_vec(); /// assert_eq!( /// xss, /// &[ /// hashset! {1, 2}, /// hashset! {1, 2, 3}, /// hashset! {1, 2, 4}, /// hashset! {1, 3}, /// hashset! {1, 3, 4}, /// hashset! {1, 4}, /// hashset! {2, 3}, /// hashset! {2, 3, 4}, /// hashset! {2, 4}, /// hashset! {3, 4}, /// ] /// ); /// ``` #[inline] pub fn lex_hash_sets_length_inclusive_range( a: u64, b: u64, xs: I, ) -> LexOrderedUniqueCollections> where I::Item: Clone + Eq + Hash, { LexOrderedUniqueCollections::new(a, b, xs) } /// Generates [`HashSet`]s of a given size with elements from a single iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// If $k$ is 0, the output length is 1. /// /// If $k$ is nonzero and the input iterator is infinite, the output length is also infinite. /// /// If $k$ is nonzero and the input iterator length is $n$, the output length is $\binom{n}{k}$. /// /// If $k$ is 0, the output consists of one empty [`HashSet`]. /// /// If `xs` is empty, the output is also empty, unless $k$ is 0. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::sets::exhaustive::exhaustive_hash_sets_fixed_length; /// use maplit::hashset; /// /// let xss = exhaustive_hash_sets_fixed_length(4, 1..=6).collect_vec(); /// assert_eq!( /// xss, /// &[ /// hashset! {1, 2, 3, 4}, /// hashset! {1, 2, 3, 5}, /// hashset! {1, 2, 4, 5}, /// hashset! {1, 3, 4, 5}, /// hashset! {2, 3, 4, 5}, /// hashset! {1, 2, 3, 6}, /// hashset! {1, 2, 4, 6}, /// hashset! {1, 3, 4, 6}, /// hashset! {2, 3, 4, 6}, /// hashset! {1, 2, 5, 6}, /// hashset! {1, 3, 5, 6}, /// hashset! {2, 3, 5, 6}, /// hashset! {1, 4, 5, 6}, /// hashset! {2, 4, 5, 6}, /// hashset! {3, 4, 5, 6} /// ] /// ); /// ``` #[inline] pub fn exhaustive_hash_sets_fixed_length( k: u64, xs: I, ) -> ExhaustiveOrderedUniqueCollections> where I::Item: Clone + Eq + Hash, { exhaustive_hash_sets_length_inclusive_range(k, k, xs) } /// Generates [`HashSet`]s with elements from a single iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, only prefixes of the iterator will be /// generated. /// /// If the input iterator is infinite, the output length is also infinite. /// /// If the input iterator length is $n$, the output length is $2^n$. /// /// If `xs` is empty, the output consists of a single empty [`HashSet`]. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::sets::exhaustive::exhaustive_hash_sets; /// use maplit::hashset; /// /// let xss = exhaustive_hash_sets(1..=4).collect_vec(); /// assert_eq!( /// xss, /// &[ /// hashset! {}, /// hashset! {1}, /// hashset! {2}, /// hashset! {1, 2}, /// hashset! {3}, /// hashset! {1, 3}, /// hashset! {2, 3}, /// hashset! {1, 2, 3}, /// hashset! {4}, /// hashset! {1, 4}, /// hashset! {2, 4}, /// hashset! {1, 2, 4}, /// hashset! {3, 4}, /// hashset! {1, 3, 4}, /// hashset! {2, 3, 4}, /// hashset! {1, 2, 3, 4} /// ] /// ); /// ``` #[inline] pub fn exhaustive_hash_sets( xs: I, ) -> ExhaustiveOrderedUniqueCollections> where I::Item: Clone + Eq + Hash, { exhaustive_hash_sets_length_inclusive_range(0, u64::MAX, xs) } /// Generates [`HashSet`]s with a mininum length, with elements from a single iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, only prefixes of the iterator will be /// generated. /// /// If the input iterator is infinite, the output length is also infinite. /// /// If the input iterator length is $n$ and the `min_length` is $\ell$, the output length is /// $$ /// \sum_{i=\ell}^n \binom{n}{i}. /// $$ /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::sets::exhaustive::exhaustive_hash_sets_min_length; /// use maplit::hashset; /// /// let xss = exhaustive_hash_sets_min_length(2, 1..=4).collect_vec(); /// assert_eq!( /// xss, /// &[ /// hashset! {1, 2}, /// hashset! {1, 3}, /// hashset! {2, 3}, /// hashset! {1, 2, 3}, /// hashset! {1, 4}, /// hashset! {2, 4}, /// hashset! {1, 2, 4}, /// hashset! {3, 4}, /// hashset! {1, 3, 4}, /// hashset! {2, 3, 4}, /// hashset! {1, 2, 3, 4} /// ] /// ); /// ``` #[inline] pub fn exhaustive_hash_sets_min_length( min_length: u64, xs: I, ) -> ExhaustiveOrderedUniqueCollections> where I::Item: Clone + Eq + Hash, { exhaustive_hash_sets_length_inclusive_range(min_length, u64::MAX, xs) } /// Generates [`HashSet`]s, with lengths in a range $[a, b)$, with elements from a single iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, only prefixes of the iterator will be /// generated. /// /// If $a \leq b$, the output is empty. /// /// If $a = 0$ and $b = 1$, the output consists of a single empty [`HashSet`]. /// /// If the input iterator is infinite and $0 < a < b$, the output length is also infinite. /// /// If the input iterator length is $n$, the output length is /// $$ /// \sum_{i=a}^b - 1 \binom{n}{i}. /// $$ /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::sets::exhaustive::exhaustive_hash_sets_length_range; /// use maplit::hashset; /// /// let xss = exhaustive_hash_sets_length_range(2, 4, 1..=4).collect_vec(); /// assert_eq!( /// xss, /// &[ /// hashset! {1, 2}, /// hashset! {1, 3}, /// hashset! {2, 3}, /// hashset! {1, 2, 3}, /// hashset! {1, 4}, /// hashset! {2, 4}, /// hashset! {1, 2, 4}, /// hashset! {3, 4}, /// hashset! {1, 3, 4}, /// hashset! {2, 3, 4} /// ] /// ); /// ``` #[inline] pub fn exhaustive_hash_sets_length_range( a: u64, b: u64, xs: I, ) -> ExhaustiveOrderedUniqueCollections> where I::Item: Clone + Eq + Hash, { if a >= b { ExhaustiveOrderedUniqueCollections::None } else { exhaustive_hash_sets_length_inclusive_range(a, b - 1, xs) } } /// Generates [`HashSet`]s, with lengths in a range $[a, b]$, with elements from a single iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, only prefixes of the iterator will be /// generated. /// /// If $a < b$, the output is empty. /// /// If $a = b = 0$, the output consists of a single empty [`HashSet`]. /// /// If the input iterator is infinite and $0 < a \leq b$, the output length is also infinite. /// /// If the input iterator length is $n$, the output length is /// $$ /// \sum_{i=a}^b \binom{n}{i}. /// $$ /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::sets::exhaustive::exhaustive_hash_sets_length_inclusive_range; /// use maplit::hashset; /// /// let xss = exhaustive_hash_sets_length_inclusive_range(2, 3, 1..=4).collect_vec(); /// assert_eq!( /// xss, /// &[ /// hashset! {1, 2}, /// hashset! {1, 3}, /// hashset! {2, 3}, /// hashset! {1, 2, 3}, /// hashset! {1, 4}, /// hashset! {2, 4}, /// hashset! {1, 2, 4}, /// hashset! {3, 4}, /// hashset! {1, 3, 4}, /// hashset! {2, 3, 4} /// ] /// ); /// ``` #[inline] pub fn exhaustive_hash_sets_length_inclusive_range( a: u64, b: u64, xs: I, ) -> ExhaustiveOrderedUniqueCollections> where I::Item: Clone + Eq + Hash, { ExhaustiveOrderedUniqueCollections::new(a, b, xs) } /// Generates [`BTreeSet`]s of a given size with elements from a single iterator. /// /// The [`BTreeSet`]s are ordered lexicographically with respect to the order of the element /// iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// If $k$ is 0, the output length is 1. /// /// If $k$ is nonzero and the input iterator is infinite, the output length is also infinite. /// /// If $k$ is nonzero and the input iterator length is $n$, the output length is $\binom{n}{k}$. /// /// If $k$ is 0, the output consists of one empty [`BTreeSet`]. /// /// If `xs` is empty, the output is also empty, unless $k$ is 0. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::sets::exhaustive::lex_b_tree_sets_fixed_length; /// use maplit::btreeset; /// /// let xss = lex_b_tree_sets_fixed_length(4, 1..=6).collect_vec(); /// assert_eq!( /// xss, /// &[ /// btreeset! {1, 2, 3, 4}, /// btreeset! {1, 2, 3, 5}, /// btreeset! {1, 2, 3, 6}, /// btreeset! {1, 2, 4, 5}, /// btreeset! {1, 2, 4, 6}, /// btreeset! {1, 2, 5, 6}, /// btreeset! {1, 3, 4, 5}, /// btreeset! {1, 3, 4, 6}, /// btreeset! {1, 3, 5, 6}, /// btreeset! {1, 4, 5, 6}, /// btreeset! {2, 3, 4, 5}, /// btreeset! {2, 3, 4, 6}, /// btreeset! {2, 3, 5, 6}, /// btreeset! {2, 4, 5, 6}, /// btreeset! {3, 4, 5, 6} /// ] /// ); /// ``` #[inline] pub fn lex_b_tree_sets_fixed_length( k: u64, xs: I, ) -> LexFixedLengthOrderedUniqueCollections> where I::Item: Clone + Ord, { LexFixedLengthOrderedUniqueCollections::new(k, xs) } /// Generates [`BTreeSet`]s with elements from a single iterator. /// /// The [`BTreeSet`]s are generated in order of increasing length, and within each length they are /// ordered lexicographically with respect to the order of the element iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, [`BTreeSet`]s of length 2 and above will never /// be generated. /// /// If the input iterator is infinite, the output length is also infinite. /// /// If the input iterator length is $n$, the output length is $2^n$. /// /// If `xs` is empty, the output consists of a single empty [`HashSet`]. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::sets::exhaustive::shortlex_b_tree_sets; /// use maplit::btreeset; /// /// let xss = shortlex_b_tree_sets(1..=4).collect_vec(); /// assert_eq!( /// xss, /// &[ /// btreeset! {}, /// btreeset! {1}, /// btreeset! {2}, /// btreeset! {3}, /// btreeset! {4}, /// btreeset! {1, 2}, /// btreeset! {1, 3}, /// btreeset! {1, 4}, /// btreeset! {2, 3}, /// btreeset! {2, 4}, /// btreeset! {3, 4}, /// btreeset! {1, 2, 3}, /// btreeset! {1, 2, 4}, /// btreeset! {1, 3, 4}, /// btreeset! {2, 3, 4}, /// btreeset! {1, 2, 3, 4} /// ] /// ); /// ``` #[inline] pub fn shortlex_b_tree_sets( xs: I, ) -> ShortlexOrderedUniqueCollections> where I::Item: Clone + Ord, { shortlex_b_tree_sets_length_inclusive_range(0, u64::MAX, xs) } /// Generates [`BTreeSet`]s with a mininum length, with elements from a single iterator. /// /// The [`BTreeSet`]s are generated in order of increasing length, and within each length they are /// ordered lexicographically with respect to the order of the element iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, [`BTreeSet`]s of length `\max(2, \ell + 1)` /// and above will never be generated. /// /// If the input iterator is infinite, the output length is also infinite. /// /// If the input iterator length is $n$ and the `min_length` is $\ell$, the output length is /// $$ /// \sum_{i=\ell}^n \binom{n}{i}. /// $$ /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::sets::exhaustive::shortlex_b_tree_sets_min_length; /// use maplit::btreeset; /// /// let xss = shortlex_b_tree_sets_min_length(2, 1..=4).collect_vec(); /// assert_eq!( /// xss, /// &[ /// btreeset! {1, 2}, /// btreeset! {1, 3}, /// btreeset! {1, 4}, /// btreeset! {2, 3}, /// btreeset! {2, 4}, /// btreeset! {3, 4}, /// btreeset! {1, 2, 3}, /// btreeset! {1, 2, 4}, /// btreeset! {1, 3, 4}, /// btreeset! {2, 3, 4}, /// btreeset! {1, 2, 3, 4} /// ] /// ); /// ``` #[inline] pub fn shortlex_b_tree_sets_min_length( min_length: u64, xs: I, ) -> ShortlexOrderedUniqueCollections> where I::Item: Clone + Ord, { shortlex_b_tree_sets_length_inclusive_range(min_length, u64::MAX, xs) } /// Generates [`BTreeSet`]s, with lengths in a range $[a, b)$, with elements from a single iterator. /// /// The [`BTreeSet`]s are generated in order of increasing length, and within each length they are /// ordered lexicographically with respect to the order of the element iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, [`BTreeSet`]s of length `\max(2, a + 1)` and /// above will never be generated. /// /// If $a \leq b$, the output is empty. /// /// If $a = 0$ and $b = 1$, the output consists of a single empty [`BTreeSet`]. /// /// If the input iterator is infinite and $0 < a < b$, the output length is also infinite. /// /// If the input iterator length is $n$, the output length is /// $$ /// \sum_{i=a}^b - 1 \binom{n}{i}. /// $$ /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::sets::exhaustive::shortlex_b_tree_sets_length_range; /// use maplit::btreeset; /// /// let xss = shortlex_b_tree_sets_length_range(2, 4, 1..=4).collect_vec(); /// assert_eq!( /// xss, /// &[ /// btreeset! {1, 2}, /// btreeset! {1, 3}, /// btreeset! {1, 4}, /// btreeset! {2, 3}, /// btreeset! {2, 4}, /// btreeset! {3, 4}, /// btreeset! {1, 2, 3}, /// btreeset! {1, 2, 4}, /// btreeset! {1, 3, 4}, /// btreeset! {2, 3, 4}, /// ] /// ); /// ``` #[inline] pub fn shortlex_b_tree_sets_length_range( mut a: u64, mut b: u64, xs: I, ) -> ShortlexOrderedUniqueCollections> where I::Item: Clone + Ord, { if b == 0 { // Transform an empty (x, 0) range into (2, 1), which is also empty but doesn't cause // overflow a = 2; b = 1; } shortlex_b_tree_sets_length_inclusive_range(a, b - 1, xs) } /// Generates [`BTreeSet`]s, with lengths in a range $[a, b]$, with elements from a single iterator. /// /// The [`BTreeSet`]s are generated in order of increasing length, and within each length they are /// ordered lexicographically with respect to the order of the element iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, [`BTreeSet`]s of length `\max(2, a + 1)` and /// above will never be generated. /// /// If $a < b$, the output is empty. /// /// If $a = b = 0$, the output consists of a single empty [`BTreeSet`]. /// /// If the input iterator is infinite and $0 < a \leq b$, the output length is also infinite. /// /// If the input iterator length is $n$, the output length is /// $$ /// \sum_{i=a}^b \binom{n}{i}. /// $$ /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::sets::exhaustive::shortlex_b_tree_sets_length_inclusive_range; /// use maplit::btreeset; /// /// let xss = shortlex_b_tree_sets_length_inclusive_range(2, 3, 1..=4).collect_vec(); /// assert_eq!( /// xss, /// &[ /// btreeset! {1, 2}, /// btreeset! {1, 3}, /// btreeset! {1, 4}, /// btreeset! {2, 3}, /// btreeset! {2, 4}, /// btreeset! {3, 4}, /// btreeset! {1, 2, 3}, /// btreeset! {1, 2, 4}, /// btreeset! {1, 3, 4}, /// btreeset! {2, 3, 4}, /// ] /// ); /// ``` #[inline] pub fn shortlex_b_tree_sets_length_inclusive_range( a: u64, b: u64, xs: I, ) -> ShortlexOrderedUniqueCollections> where I::Item: Clone + Ord, { ShortlexOrderedUniqueCollections::new(a, b, xs) } /// Generates [`BTreeSet`]s with elements from a single iterator. /// /// The [`BTreeSet`]s are ordered lexicographically with respect to the order of the element /// iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, only prefixes of the iterator will be /// generated. /// /// If the input iterator is infinite, the output length is also infinite. /// /// If the input iterator length is $n$, the output length is $2^n$. /// /// If `xs` is empty, the output consists of a single empty [`BTreeSet`]. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::sets::exhaustive::lex_b_tree_sets; /// use maplit::btreeset; /// /// let xss = lex_b_tree_sets(1..=4).collect_vec(); /// assert_eq!( /// xss, /// &[ /// btreeset! {}, /// btreeset! {1}, /// btreeset! {1, 2}, /// btreeset! {1, 2, 3}, /// btreeset! {1, 2, 3, 4}, /// btreeset! {1, 2, 4}, /// btreeset! {1, 3}, /// btreeset! {1, 3, 4}, /// btreeset! {1, 4}, /// btreeset! {2}, /// btreeset! {2, 3}, /// btreeset! {2, 3, 4}, /// btreeset! {2, 4}, /// btreeset! {3}, /// btreeset! {3, 4}, /// btreeset! {4} /// ] /// ); /// ``` #[inline] pub fn lex_b_tree_sets( xs: I, ) -> LexOrderedUniqueCollections> where I::Item: Clone + Ord, { lex_b_tree_sets_length_inclusive_range(0, u64::MAX, xs) } /// Generates [`BTreeSet`]s with a mininum length, with elements from a single iterator. /// /// The [`BTreeSet`]s are ordered lexicographically with respect to the order of the element /// iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, only prefixes of the iterator will be /// generated. /// /// If the input iterator is infinite, the output length is also infinite. /// /// If the input iterator length is $n$ and the `min_length` is $\ell$, the output length is /// $$ /// \sum_{i=\ell}^n \binom{n}{i}. /// $$ /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::sets::exhaustive::lex_b_tree_sets_min_length; /// use maplit::btreeset; /// /// let xss = lex_b_tree_sets_min_length(2, 1..=4).collect_vec(); /// assert_eq!( /// xss, /// &[ /// btreeset! {1, 2}, /// btreeset! {1, 2, 3}, /// btreeset! {1, 2, 3, 4}, /// btreeset! {1, 2, 4}, /// btreeset! {1, 3}, /// btreeset! {1, 3, 4}, /// btreeset! {1, 4}, /// btreeset! {2, 3}, /// btreeset! {2, 3, 4}, /// btreeset! {2, 4}, /// btreeset! {3, 4}, /// ] /// ); /// ``` #[inline] pub fn lex_b_tree_sets_min_length( min_length: u64, xs: I, ) -> LexOrderedUniqueCollections> where I::Item: Clone + Ord, { lex_b_tree_sets_length_inclusive_range(min_length, u64::MAX, xs) } /// Generates [`BTreeSet`]s, with lengths in a range $[a, b)$, with elements from a single iterator. /// /// The [`BTreeSet`]s are ordered lexicographically with respect to the order of the element /// iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, only prefixes of the iterator will be /// generated. /// /// If $a \leq b$, the output is empty. /// /// If $a = 0$ and $b = 1$, the output consists of a single empty [`BTreeSet`]. /// /// If the input iterator is infinite and $0 < a < b$, the output length is also infinite. /// /// If the input iterator length is $n$, the output length is /// $$ /// \sum_{i=a}^b - 1 \binom{n}{i}. /// $$ /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::sets::exhaustive::lex_b_tree_sets_length_range; /// use maplit::btreeset; /// /// let xss = lex_b_tree_sets_length_range(2, 4, 1..=4).collect_vec(); /// assert_eq!( /// xss, /// &[ /// btreeset! {1, 2}, /// btreeset! {1, 2, 3}, /// btreeset! {1, 2, 4}, /// btreeset! {1, 3}, /// btreeset! {1, 3, 4}, /// btreeset! {1, 4}, /// btreeset! {2, 3}, /// btreeset! {2, 3, 4}, /// btreeset! {2, 4}, /// btreeset! {3, 4}, /// ] /// ); /// ``` #[inline] pub fn lex_b_tree_sets_length_range( mut a: u64, mut b: u64, xs: I, ) -> LexOrderedUniqueCollections> where I::Item: Clone + Ord, { if b == 0 { // Transform an empty (x, 0) range into (2, 1), which is also empty but doesn't cause // overflow a = 2; b = 1; } lex_b_tree_sets_length_inclusive_range(a, b - 1, xs) } /// Generates [`BTreeSet`]s, with lengths in a range $[a, b]$, with elements from a single iterator. /// /// The [`BTreeSet`]s are ordered lexicographically with respect to the order of the element /// iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, only prefixes of the iterator will be /// generated. /// /// If $a < b$, the output is empty. /// /// If $a = b = 0$, the output consists of a single empty [`BTreeSet`]. /// /// If the input iterator is infinite and $0 < a \leq b$, the output length is also infinite. /// /// If the input iterator length is $n$, the output length is /// $$ /// \sum_{i=a}^b \binom{n}{i}. /// $$ /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::sets::exhaustive::lex_b_tree_sets_length_inclusive_range; /// use maplit::btreeset; /// /// let xss = lex_b_tree_sets_length_inclusive_range(2, 3, 1..=4).collect_vec(); /// assert_eq!( /// xss, /// &[ /// btreeset! {1, 2}, /// btreeset! {1, 2, 3}, /// btreeset! {1, 2, 4}, /// btreeset! {1, 3}, /// btreeset! {1, 3, 4}, /// btreeset! {1, 4}, /// btreeset! {2, 3}, /// btreeset! {2, 3, 4}, /// btreeset! {2, 4}, /// btreeset! {3, 4}, /// ] /// ); /// ``` #[inline] pub fn lex_b_tree_sets_length_inclusive_range( a: u64, b: u64, xs: I, ) -> LexOrderedUniqueCollections> where I::Item: Clone + Ord, { LexOrderedUniqueCollections::new(a, b, xs) } /// Generates [`BTreeSet`]s of a given size with elements from a single iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// If $k$ is 0, the output length is 1. /// /// If $k$ is nonzero and the input iterator is infinite, the output length is also infinite. /// /// If $k$ is nonzero and the input iterator length is $n$, the output length is $\binom{n}{k}$. /// /// If $k$ is 0, the output consists of one empty [`BTreeSet`]. /// /// If `xs` is empty, the output is also empty, unless $k$ is 0. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::sets::exhaustive::exhaustive_b_tree_sets_fixed_length; /// use maplit::btreeset; /// /// let xss = exhaustive_b_tree_sets_fixed_length(4, 1..=6).collect_vec(); /// assert_eq!( /// xss, /// &[ /// btreeset! {1, 2, 3, 4}, /// btreeset! {1, 2, 3, 5}, /// btreeset! {1, 2, 4, 5}, /// btreeset! {1, 3, 4, 5}, /// btreeset! {2, 3, 4, 5}, /// btreeset! {1, 2, 3, 6}, /// btreeset! {1, 2, 4, 6}, /// btreeset! {1, 3, 4, 6}, /// btreeset! {2, 3, 4, 6}, /// btreeset! {1, 2, 5, 6}, /// btreeset! {1, 3, 5, 6}, /// btreeset! {2, 3, 5, 6}, /// btreeset! {1, 4, 5, 6}, /// btreeset! {2, 4, 5, 6}, /// btreeset! {3, 4, 5, 6} /// ] /// ); /// ``` #[inline] pub fn exhaustive_b_tree_sets_fixed_length( k: u64, xs: I, ) -> ExhaustiveOrderedUniqueCollections> where I::Item: Clone + Ord, { exhaustive_b_tree_sets_length_inclusive_range(k, k, xs) } /// Generates [`BTreeSet`]s with elements from a single iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, only prefixes of the iterator will be /// generated. /// /// If the input iterator is infinite, the output length is also infinite. /// /// If the input iterator length is $n$, the output length is $2^n$. /// /// If `xs` is empty, the output consists of a single empty [`BTreeSet`]. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::sets::exhaustive::exhaustive_b_tree_sets; /// use maplit::btreeset; /// /// let xss = exhaustive_b_tree_sets(1..=4).collect_vec(); /// assert_eq!( /// xss, /// &[ /// btreeset! {}, /// btreeset! {1}, /// btreeset! {2}, /// btreeset! {1, 2}, /// btreeset! {3}, /// btreeset! {1, 3}, /// btreeset! {2, 3}, /// btreeset! {1, 2, 3}, /// btreeset! {4}, /// btreeset! {1, 4}, /// btreeset! {2, 4}, /// btreeset! {1, 2, 4}, /// btreeset! {3, 4}, /// btreeset! {1, 3, 4}, /// btreeset! {2, 3, 4}, /// btreeset! {1, 2, 3, 4} /// ] /// ); /// ``` #[inline] pub fn exhaustive_b_tree_sets( xs: I, ) -> ExhaustiveOrderedUniqueCollections> where I::Item: Clone + Ord, { exhaustive_b_tree_sets_length_inclusive_range(0, u64::MAX, xs) } /// Generates [`BTreeSet`]s with a mininum length, with elements from a single iterator. /// /// The [`BTreeSet`]s are ordered lexicographically with respect to the order of the element /// iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, only prefixes of the iterator will be /// generated. /// /// If the input iterator is infinite, the output length is also infinite. /// /// If the input iterator length is $n$ and the `min_length` is $\ell$, the output length is /// $$ /// \sum_{i=\ell}^n \binom{n}{i}. /// $$ /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::sets::exhaustive::exhaustive_b_tree_sets_min_length; /// use maplit::btreeset; /// /// let xss = exhaustive_b_tree_sets_min_length(2, 1..=4).collect_vec(); /// assert_eq!( /// xss, /// &[ /// btreeset! {1, 2}, /// btreeset! {1, 3}, /// btreeset! {2, 3}, /// btreeset! {1, 2, 3}, /// btreeset! {1, 4}, /// btreeset! {2, 4}, /// btreeset! {1, 2, 4}, /// btreeset! {3, 4}, /// btreeset! {1, 3, 4}, /// btreeset! {2, 3, 4}, /// btreeset! {1, 2, 3, 4} /// ] /// ); /// ``` #[inline] pub fn exhaustive_b_tree_sets_min_length( min_length: u64, xs: I, ) -> ExhaustiveOrderedUniqueCollections> where I::Item: Clone + Ord, { exhaustive_b_tree_sets_length_inclusive_range(min_length, u64::MAX, xs) } /// Generates [`BTreeSet`]s, with lengths in a range $[a, b)$, with elements from a single iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, only prefixes of the iterator will be /// generated. /// /// If $a \leq b$, the output is empty. /// /// If $a = 0$ and $b = 1$, the output consists of a single empty [`BTreeSet`]. /// /// If the input iterator is infinite and $0 < a < b$, the output length is also infinite. /// /// If the input iterator length is $n$, the output length is /// $$ /// \sum_{i=a}^b - 1 \binom{n}{i}. /// $$ /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::sets::exhaustive::exhaustive_b_tree_sets_length_range; /// use maplit::btreeset; /// /// let xss = exhaustive_b_tree_sets_length_range(2, 4, 1..=4).collect_vec(); /// assert_eq!( /// xss, /// &[ /// btreeset! {1, 2}, /// btreeset! {1, 3}, /// btreeset! {2, 3}, /// btreeset! {1, 2, 3}, /// btreeset! {1, 4}, /// btreeset! {2, 4}, /// btreeset! {1, 2, 4}, /// btreeset! {3, 4}, /// btreeset! {1, 3, 4}, /// btreeset! {2, 3, 4} /// ] /// ); /// ``` #[inline] pub fn exhaustive_b_tree_sets_length_range( a: u64, b: u64, xs: I, ) -> ExhaustiveOrderedUniqueCollections> where I::Item: Clone + Ord, { if a >= b { ExhaustiveOrderedUniqueCollections::None } else { exhaustive_b_tree_sets_length_inclusive_range(a, b - 1, xs) } } /// Generates [`BTreeSet`]s, with lengths in a range $[a, b]$, with elements from a single iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, only prefixes of the iterator will be /// generated. /// /// If $a < b$, the output is empty. /// /// If $a = b = 0$, the output consists of a single empty [`BTreeSet`]. /// /// If the input iterator is infinite and $0 < a \leq b$, the output length is also infinite. /// /// If the input iterator length is $n$, the output length is /// $$ /// \sum_{i=a}^b \binom{n}{i}. /// $$ /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::sets::exhaustive::exhaustive_b_tree_sets_length_inclusive_range; /// use maplit::btreeset; /// /// let xss = exhaustive_b_tree_sets_length_inclusive_range(2, 3, 1..=4).collect_vec(); /// assert_eq!( /// xss, /// &[ /// btreeset! {1, 2}, /// btreeset! {1, 3}, /// btreeset! {2, 3}, /// btreeset! {1, 2, 3}, /// btreeset! {1, 4}, /// btreeset! {2, 4}, /// btreeset! {1, 2, 4}, /// btreeset! {3, 4}, /// btreeset! {1, 3, 4}, /// btreeset! {2, 3, 4} /// ] /// ); /// ``` #[inline] pub fn exhaustive_b_tree_sets_length_inclusive_range( a: u64, b: u64, xs: I, ) -> ExhaustiveOrderedUniqueCollections> where I::Item: Clone + Ord, { ExhaustiveOrderedUniqueCollections::new(a, b, xs) } malachite-base-0.4.16/src/sets/mod.rs000064400000000000000000000010271046102023000154450ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . /// Iterators that generate sets without repetition. pub mod exhaustive; #[cfg(feature = "random")] /// Iterators that generate sets randomly. pub mod random; malachite-base-0.4.16/src/sets/random.rs000064400000000000000000000744321046102023000161600ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::conversion::traits::ExactFrom; use crate::num::random::geometric::{ geometric_random_unsigned_inclusive_range, geometric_random_unsigneds, GeometricRandomNaturalValues, }; use crate::num::random::{ random_unsigned_inclusive_range, random_unsigned_range, RandomUnsignedInclusiveRange, RandomUnsignedRange, }; use crate::random::Seed; #[cfg(not(feature = "test_build"))] use alloc::collections::BTreeSet; use core::hash::Hash; #[cfg(not(feature = "test_build"))] use hashbrown::HashSet; #[cfg(feature = "test_build")] use std::collections::{BTreeSet, HashSet}; /// Generates random [`HashSet`]s of a fixed length, where the [`Vec`]s have no repeated elements, /// and the elements are in ascending order. /// /// This `struct` is created by [`random_hash_sets_fixed_length`]; see its documentation for more. #[derive(Clone, Debug)] pub struct RandomHashSetsFixedLength where I::Item: Eq + Hash, { len: usize, xs: I, } impl Iterator for RandomHashSetsFixedLength where I::Item: Eq + Hash, { type Item = HashSet; #[inline] fn next(&mut self) -> Option> { let mut set = HashSet::new(); while set.len() < self.len { set.insert(self.xs.next().unwrap()); } Some(set) } } /// Randomly generates [`HashSet`]s of a given length. /// /// The input iterator must generate at least `len` distinct elements; otherwise, this iterator will /// hang. /// /// $$ /// P((x\_i)\_{i=0}^{n-1}) = n!\prod\_{i=0}^{n-1}P(x\_i). /// $$ /// /// If `len` is 0, the output consists of the empty set, repeated. /// /// `xs` must be infinite. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::random::random_unsigned_inclusive_range; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::sets::random::random_hash_sets_fixed_length; /// use maplit::hashset; /// /// let xss = random_hash_sets_fixed_length( /// 2, /// random_unsigned_inclusive_range::(EXAMPLE_SEED, 1, 100), /// ) /// .take(10) /// .collect_vec(); /// assert_eq!( /// xss, /// &[ /// hashset! {24, 95}, /// hashset! {71, 99}, /// hashset! {53, 93}, /// hashset! {34, 85}, /// hashset! {2, 48}, /// hashset! {11, 55}, /// hashset! {18, 48}, /// hashset! {90, 93}, /// hashset! {67, 93}, /// hashset! {93, 95} /// ] /// ); /// ``` #[inline] pub fn random_hash_sets_fixed_length(len: u64, xs: I) -> RandomHashSetsFixedLength where I::Item: Eq + Hash, { RandomHashSetsFixedLength { len: usize::exact_from(len), xs, } } /// Generates random [`HashSet`]s with lengths from an iterator. #[derive(Clone, Debug)] pub struct RandomHashSets, J: Iterator> { lengths: I, xs: J, } impl, J: Iterator> Iterator for RandomHashSets { type Item = HashSet; fn next(&mut self) -> Option> { let len = usize::exact_from(self.lengths.next().unwrap()); let mut set = HashSet::new(); while set.len() < len { set.insert(self.xs.next().unwrap()); } Some(set) } } /// Generates random [`HashSet`]s using elements from an iterator and with lengths from another /// iterator. /// /// The input iterator must generate at least many distinct elements as any number generated by the /// lengths iterator; otherwise, this iterator will hang. /// /// $$ /// P((x\_i)\_{i=0}^{n-1}) = n!P(n)\prod\_{i=0}^{n-1}P(x\_i). /// $$ /// /// `lengths` and `xs` must be infinite. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::random::random_primitive_ints; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::sets::random::random_hash_sets_from_length_iterator; /// use malachite_base::vecs::random_values_from_vec; /// use maplit::hashset; /// /// let xs = random_hash_sets_from_length_iterator( /// EXAMPLE_SEED, /// &|seed| random_values_from_vec(seed, vec![0, 2, 4]), /// &random_primitive_ints::, /// ); /// let values = xs.take(20).collect_vec(); /// assert_eq!( /// values, /// &[ /// hashset! {11, 85}, /// hashset! {134, 136, 200, 235}, /// hashset! {203, 223}, /// hashset! {38, 177, 217, 235}, /// hashset! {32, 162, 166, 234}, /// hashset! {30, 218}, /// hashset! {}, /// hashset! {90, 106}, /// hashset! {}, /// hashset! {9, 151, 204, 216}, /// hashset! {78, 97, 213, 253}, /// hashset! {39, 91}, /// hashset! {170, 175, 191, 232}, /// hashset! {2, 233}, /// hashset! {22, 35, 198, 217}, /// hashset! {17, 32, 114, 173}, /// hashset! {65, 114, 121, 222}, /// hashset! {}, /// hashset! {25, 144, 148, 173}, /// hashset! {} /// ] /// ); /// ``` #[inline] pub fn random_hash_sets_from_length_iterator< T: Eq + Hash, I: Iterator, J: Iterator, >( seed: Seed, lengths_gen: &dyn Fn(Seed) -> I, xs_gen: &dyn Fn(Seed) -> J, ) -> RandomHashSets { RandomHashSets { lengths: lengths_gen(seed.fork("lengths")), xs: xs_gen(seed.fork("xs")), } } /// Generates random [`HashSet`]s using elements from an iterator. /// /// The lengths of the [`HashSet`]s are sampled from a geometric distribution with a specified mean /// $m$, equal to `mean_length_numerator / mean_length_denominator`. $m$ must be greater than 0. /// /// Strictly speaking, the input iterator must generate infinitely many distinct elements. In /// practice it only needs to generate $k$ distinct elements, where $k$ is the largest length /// actually sampled from the geometric distribution. For example, if `mean_length_numerator / /// mean_length_denominator` is significantly lower than 256, then it's ok to use /// `random_unsigneds::`. /// /// $$ /// P((x\_i)\_{i=0}^{n-1}) = n!P_g(n)\prod\_{i=0}^{n-1}P(x\_i), /// $$ /// where $P_g(n)$ is the probability function described in [`geometric_random_unsigneds`]. /// /// `xs_gen` must be infinite. /// /// # Panics /// Panics if `mean_length_numerator` or `mean_length_denominator` are zero, or, if after being /// reduced to lowest terms, their sum is greater than or equal to $2^{64}$. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::random::random_primitive_ints; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::sets::random::random_hash_sets; /// use maplit::hashset; /// /// let xs = random_hash_sets(EXAMPLE_SEED, &random_primitive_ints::, 4, 1); /// let values = xs.take(20).collect_vec(); /// assert_eq!( /// values, /// &[ /// hashset! {}, /// hashset! {11, 32, 38, 85, 134, 136, 162, 166, 177, 200, 203, 217, 223, 235}, /// hashset! {30, 90, 218, 234}, /// hashset! {9, 106, 204, 216}, /// hashset! {151}, /// hashset! {}, /// hashset! {78, 91, 97, 213, 253}, /// hashset! {39, 191}, /// hashset! {170, 175, 232, 233}, /// hashset! {}, /// hashset! {2, 22, 35, 114, 198, 217}, /// hashset! {}, /// hashset! {}, /// hashset! {17, 25, 32, 65, 79, 114, 121, 144, 148, 173, 222}, /// hashset! {52, 69, 73, 91, 115, 137, 153, 178}, /// hashset! {}, /// hashset! {34, 95, 112}, /// hashset! {}, /// hashset! {106, 130, 167, 168, 197}, /// hashset! {86, 101, 122, 150, 172, 177, 207, 218, 221} /// ] /// ); /// ``` #[inline] pub fn random_hash_sets( seed: Seed, xs_gen: &dyn Fn(Seed) -> I, mean_length_numerator: u64, mean_length_denominator: u64, ) -> RandomHashSets, I> where I::Item: Eq + Hash, { random_hash_sets_from_length_iterator( seed, &|seed_2| { geometric_random_unsigneds(seed_2, mean_length_numerator, mean_length_denominator) }, xs_gen, ) } /// Generates random [`HashSet`]s with a minimum length, using elements from an iterator. /// /// Strictly speaking, the input iterator must generate infinitely many distinct elements. In /// practice it only needs to generate $k$ distinct elements, where $k$ is the largest length /// actually sampled from the geometric distribution. For example, if `mean_length_numerator / /// mean_length_denominator` is significantly lower than 256, then it's ok to use /// `random_unsigneds::`. /// /// $$ /// P((x\_i)\_{i=0}^{n-1}) = n!P_g(n)\prod\_{i=0}^{n-1}P(x\_i), /// $$ /// where $P_g(n)$ is the probability function described in /// [`geometric_random_unsigned_inclusive_range`] with $a$ equal to `min_length` and `b` to /// `u64::MAX`. /// /// `xs_gen` must be infinite. /// /// # Panics /// Panics if `mean_length_numerator` or `mean_length_denominator` are zero, if their ratio is less /// than or equal to `min_length`, or if they are too large and manipulating them leads to /// arithmetic overflow. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::random::random_primitive_ints; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::sets::random::random_hash_sets_min_length; /// use maplit::hashset; /// /// let xs = random_hash_sets_min_length(EXAMPLE_SEED, 2, &random_primitive_ints::, 6, 1); /// let values = xs.take(20).collect_vec(); /// assert_eq!( /// values, /// &[ /// hashset! {11, 85}, /// hashset! { /// 30, 32, 38, 90, 134, 136, 162, 166, 177, 200, 203, 217, 218, 223, 234, 235 /// }, /// hashset! {9, 106, 151, 204, 213, 216}, /// hashset! {39, 78, 91, 97, 191, 253}, /// hashset! {170, 175, 232}, /// hashset! {2, 233}, /// hashset! {17, 22, 32, 35, 114, 198, 217}, /// hashset! {65, 114, 121, 173}, /// hashset! {25, 79, 144, 148, 173, 222}, /// hashset! {52, 115}, /// hashset! {34, 69, 73, 91, 112, 137, 153, 178}, /// hashset! {95, 106}, /// hashset! {167, 197}, /// hashset! {74, 86, 101, 115, 122, 130, 150, 168, 172, 177, 207, 218, 221}, /// hashset! {9, 48, 52, 109, 123, 133, 159, 201, 247, 250}, /// hashset! {196, 235}, /// hashset! {40, 68, 97, 104, 190}, /// hashset! {7, 216}, /// hashset! {11, 24, 43, 112, 157, 216, 217}, /// hashset! {29, 51, 55, 65, 84, 89, 103, 135, 191, 206, 211} /// ] /// ); /// ``` #[inline] pub fn random_hash_sets_min_length( seed: Seed, min_length: u64, xs_gen: &dyn Fn(Seed) -> I, mean_length_numerator: u64, mean_length_denominator: u64, ) -> RandomHashSets, I> where I::Item: Eq + Hash, { random_hash_sets_from_length_iterator( seed, &|seed_2| { geometric_random_unsigned_inclusive_range( seed_2, min_length, u64::MAX, mean_length_numerator, mean_length_denominator, ) }, xs_gen, ) } /// Generates random [`HashSet`]s with lengths in $[a, b)$, using elements from an iterator. /// /// The lengths of the [`HashSet`]s are sampled from a uniform distribution on $[a, b)$. $a$ must be /// less than $b$. /// /// The input iterator must generate at least $b$ distinct elements. /// /// $$ /// P((x\_i)\_{i=0}^{n-1}, a, b) = \frac{n!}{b - a}\prod\_{i=0}^{n-1}P(x\_i). /// $$ /// /// `xs_gen` must be infinite. /// /// # Panics /// Panics if $a \geq b$. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::random::random_primitive_ints; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::sets::random::random_hash_sets_length_range; /// use maplit::hashset; /// /// let xs = random_hash_sets_length_range(EXAMPLE_SEED, 2, 5, &random_primitive_ints::); /// let values = xs.take(20).collect_vec(); /// assert_eq!( /// values, /// &[ /// hashset! {11, 85, 136}, /// hashset! {134, 200, 203, 235}, /// hashset! {38, 223, 235}, /// hashset! {32, 162, 177, 217}, /// hashset! {30, 166, 218, 234}, /// hashset! {9, 90, 106}, /// hashset! {204, 216}, /// hashset! {97, 151, 213}, /// hashset! {78, 253}, /// hashset! {39, 91, 175, 191}, /// hashset! {2, 170, 232, 233}, /// hashset! {22, 35, 217}, /// hashset! {17, 32, 114, 198}, /// hashset! {65, 114, 173}, /// hashset! {25, 121, 173, 222}, /// hashset! {79, 115, 144, 148}, /// hashset! {52, 69, 73, 137}, /// hashset! {91, 153}, /// hashset! {34, 95, 112, 178}, /// hashset! {106, 167} /// ] /// ); /// ``` #[inline] pub fn random_hash_sets_length_range( seed: Seed, a: u64, b: u64, xs_gen: &dyn Fn(Seed) -> I, ) -> RandomHashSets, I> where I::Item: Eq + Hash, { random_hash_sets_from_length_iterator( seed, &|seed_2| random_unsigned_range(seed_2, a, b), xs_gen, ) } /// Generates random [`HashSet`]s with lengths in $[a, b]$, using elements from an iterator. /// /// The lengths of the [`HashSet`]s are sampled from a uniform distribution on $[a, b)$. $a$ must be /// less than or equal to $b$. /// /// The input iterator must generate at least $b$ distinct elements. /// /// $$ /// P((x\_i)\_{i=0}^{n-1}, a, b) = \frac{n!}{b - a + 1}\prod\_{i=0}^{n-1}P(x\_i). /// $$ /// /// `xs_gen` must be infinite. /// /// # Panics /// Panics if $a \geq b$. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::random::random_primitive_ints; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::sets::random::random_hash_sets_length_inclusive_range; /// use maplit::hashset; /// /// let xs = /// random_hash_sets_length_inclusive_range(EXAMPLE_SEED, 2, 4, &random_primitive_ints::); /// let values = xs.take(20).collect_vec(); /// assert_eq!( /// values, /// &[ /// hashset! {11, 85, 136}, /// hashset! {134, 200, 203, 235}, /// hashset! {38, 223, 235}, /// hashset! {32, 162, 177, 217}, /// hashset! {30, 166, 218, 234}, /// hashset! {9, 90, 106}, /// hashset! {204, 216}, /// hashset! {97, 151, 213}, /// hashset! {78, 253}, /// hashset! {39, 91, 175, 191}, /// hashset! {2, 170, 232, 233}, /// hashset! {22, 35, 217}, /// hashset! {17, 32, 114, 198}, /// hashset! {65, 114, 173}, /// hashset! {25, 121, 173, 222}, /// hashset! {79, 115, 144, 148}, /// hashset! {52, 69, 73, 137}, /// hashset! {91, 153}, /// hashset! {34, 95, 112, 178}, /// hashset! {106, 167} /// ] /// ); /// ``` #[inline] pub fn random_hash_sets_length_inclusive_range( seed: Seed, a: u64, b: u64, xs_gen: &dyn Fn(Seed) -> I, ) -> RandomHashSets, I> where I::Item: Eq + Hash, { random_hash_sets_from_length_iterator( seed, &|seed_2| random_unsigned_inclusive_range(seed_2, a, b), xs_gen, ) } /// Generates random [`BTreeSet`]s of a fixed length, where the [`Vec`]s have no repeated elements, /// and the elements are in ascending order. /// /// This `struct` is created by [`random_b_tree_sets_fixed_length`]; see its documentation for more. #[derive(Clone, Debug)] pub struct RandomBTreeSetsFixedLength where I::Item: Ord, { len: usize, xs: I, } impl Iterator for RandomBTreeSetsFixedLength where I::Item: Ord, { type Item = BTreeSet; #[inline] fn next(&mut self) -> Option> { let mut set = BTreeSet::new(); while set.len() < self.len { set.insert(self.xs.next().unwrap()); } Some(set) } } /// Randomly generates [`BTreeSet`]s of a given length. /// /// The input iterator must generate at least `len` distinct elements; otherwise, this iterator will /// hang. /// /// $$ /// P((x\_i)\_{i=0}^{n-1}) = n!\prod\_{i=0}^{n-1}P(x\_i). /// $$ /// /// If `len` is 0, the output consists of the empty set, repeated. /// /// `xs` must be infinite. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::random::random_unsigned_inclusive_range; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::sets::random::random_b_tree_sets_fixed_length; /// use maplit::btreeset; /// /// let xss = random_b_tree_sets_fixed_length( /// 2, /// random_unsigned_inclusive_range::(EXAMPLE_SEED, 1, 100), /// ) /// .take(10) /// .collect_vec(); /// assert_eq!( /// xss, /// &[ /// btreeset! {24, 95}, /// btreeset! {71, 99}, /// btreeset! {53, 93}, /// btreeset! {34, 85}, /// btreeset! {2, 48}, /// btreeset! {11, 55}, /// btreeset! {18, 48}, /// btreeset! {90, 93}, /// btreeset! {67, 93}, /// btreeset! {93, 95} /// ] /// ); /// ``` #[inline] pub fn random_b_tree_sets_fixed_length( len: u64, xs: I, ) -> RandomBTreeSetsFixedLength where I::Item: Ord, { RandomBTreeSetsFixedLength { len: usize::exact_from(len), xs, } } /// Generates random [`BTreeSet`]s with lengths from an iterator. #[derive(Clone, Debug)] pub struct RandomBTreeSets, J: Iterator> { lengths: I, xs: J, } impl, J: Iterator> Iterator for RandomBTreeSets { type Item = BTreeSet; fn next(&mut self) -> Option> { let len = usize::exact_from(self.lengths.next().unwrap()); let mut set = BTreeSet::new(); while set.len() < len { set.insert(self.xs.next().unwrap()); } Some(set) } } /// Generates random [`BTreeSet`]s using elements from an iterator and with lengths from another /// iterator. /// /// The input iterator must generate at least many distinct elements as any number generated by the /// lengths iterator; otherwise, this iterator will hang. /// /// $$ /// P((x\_i)\_{i=0}^{n-1}) = n!P(n)\prod\_{i=0}^{n-1}P(x\_i). /// $$ /// /// `lengths` and `xs` must be infinite. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::random::random_primitive_ints; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::sets::random::random_b_tree_sets_from_length_iterator; /// use malachite_base::vecs::random_values_from_vec; /// use maplit::btreeset; /// /// let xs = random_b_tree_sets_from_length_iterator( /// EXAMPLE_SEED, /// &|seed| random_values_from_vec(seed, vec![0, 2, 4]), /// &random_primitive_ints::, /// ); /// let values = xs.take(20).collect_vec(); /// assert_eq!( /// values, /// &[ /// btreeset! {11, 85}, /// btreeset! {134, 136, 200, 235}, /// btreeset! {203, 223}, /// btreeset! {38, 177, 217, 235}, /// btreeset! {32, 162, 166, 234}, /// btreeset! {30, 218}, /// btreeset! {}, /// btreeset! {90, 106}, /// btreeset! {}, /// btreeset! {9, 151, 204, 216}, /// btreeset! {78, 97, 213, 253}, /// btreeset! {39, 91}, /// btreeset! {170, 175, 191, 232}, /// btreeset! {2, 233}, /// btreeset! {22, 35, 198, 217}, /// btreeset! {17, 32, 114, 173}, /// btreeset! {65, 114, 121, 222}, /// btreeset! {}, /// btreeset! {25, 144, 148, 173}, /// btreeset! {} /// ] /// ); /// ``` #[inline] pub fn random_b_tree_sets_from_length_iterator< T: Ord, I: Iterator, J: Iterator, >( seed: Seed, lengths_gen: &dyn Fn(Seed) -> I, xs_gen: &dyn Fn(Seed) -> J, ) -> RandomBTreeSets { RandomBTreeSets { lengths: lengths_gen(seed.fork("lengths")), xs: xs_gen(seed.fork("xs")), } } /// Generates random [`BTreeSet`]s using elements from an iterator. /// /// The lengths of the [`BTreeSet`]s are sampled from a geometric distribution with a specified mean /// $m$, equal to `mean_length_numerator / mean_length_denominator`. $m$ must be greater than 0. /// /// Strictly speaking, the input iterator must generate infinitely many distinct elements. In /// practice it only needs to generate $k$ distinct elements, where $k$ is the largest length /// actually sampled from the geometric distribution. For example, if `mean_length_numerator / /// mean_length_denominator` is significantly lower than 256, then it's ok to use /// `random_unsigneds::`. /// /// $$ /// P((x\_i)\_{i=0}^{n-1}) = n!P_g(n)\prod\_{i=0}^{n-1}P(x\_i), /// $$ /// where $P_g(n)$ is the probability function described in [`geometric_random_unsigneds`]. /// /// `xs_gen` must be infinite. /// /// # Panics /// Panics if `mean_length_numerator` or `mean_length_denominator` are zero, or, if after being /// reduced to lowest terms, their sum is greater than or equal to $2^{64}$. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::random::random_primitive_ints; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::sets::random::random_b_tree_sets; /// use maplit::btreeset; /// /// let xs = random_b_tree_sets(EXAMPLE_SEED, &random_primitive_ints::, 4, 1); /// let values = xs.take(20).collect_vec(); /// assert_eq!( /// values, /// &[ /// btreeset! {}, /// btreeset! {11, 32, 38, 85, 134, 136, 162, 166, 177, 200, 203, 217, 223, 235}, /// btreeset! {30, 90, 218, 234}, /// btreeset! {9, 106, 204, 216}, /// btreeset! {151}, /// btreeset! {}, /// btreeset! {78, 91, 97, 213, 253}, /// btreeset! {39, 191}, /// btreeset! {170, 175, 232, 233}, /// btreeset! {}, /// btreeset! {2, 22, 35, 114, 198, 217}, /// btreeset! {}, /// btreeset! {}, /// btreeset! {17, 25, 32, 65, 79, 114, 121, 144, 148, 173, 222}, /// btreeset! {52, 69, 73, 91, 115, 137, 153, 178}, /// btreeset! {}, /// btreeset! {34, 95, 112}, /// btreeset! {}, /// btreeset! {106, 130, 167, 168, 197}, /// btreeset! {86, 101, 122, 150, 172, 177, 207, 218, 221} /// ] /// ); /// ``` #[inline] pub fn random_b_tree_sets( seed: Seed, xs_gen: &dyn Fn(Seed) -> I, mean_length_numerator: u64, mean_length_denominator: u64, ) -> RandomBTreeSets, I> where I::Item: Ord, { random_b_tree_sets_from_length_iterator( seed, &|seed_2| { geometric_random_unsigneds(seed_2, mean_length_numerator, mean_length_denominator) }, xs_gen, ) } /// Generates random [`BTreeSet`]s with a minimum length, using elements from an iterator. /// /// Strictly speaking, the input iterator must generate infinitely many distinct elements. In /// practice it only needs to generate $k$ distinct elements, where $k$ is the largest length /// actually sampled from the geometric distribution. For example, if `mean_length_numerator / /// mean_length_denominator` is significantly lower than 256, then it's ok to use /// `random_unsigneds::`. /// /// $$ /// P((x\_i)\_{i=0}^{n-1}) = n!P_g(n)\prod\_{i=0}^{n-1}P(x\_i), /// $$ /// where $P_g(n)$ is the probability function described in /// [`geometric_random_unsigned_inclusive_range`], with $a$ equal to `min_length` and `b` to /// `u64::MAX`. /// /// `xs_gen` must be infinite. /// /// # Panics /// Panics if `mean_length_numerator` or `mean_length_denominator` are zero, if their ratio is less /// than or equal to `min_length`, or if they are too large and manipulating them leads to /// arithmetic overflow. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::random::random_primitive_ints; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::sets::random::random_b_tree_sets_min_length; /// use maplit::btreeset; /// /// let xs = random_b_tree_sets_min_length(EXAMPLE_SEED, 2, &random_primitive_ints::, 6, 1); /// let values = xs.take(20).collect_vec(); /// assert_eq!( /// values, /// &[ /// btreeset! {11, 85}, /// btreeset! { /// 30, 32, 38, 90, 134, 136, 162, 166, 177, 200, 203, 217, 218, 223, 234, 235 /// }, /// btreeset! {9, 106, 151, 204, 213, 216}, /// btreeset! {39, 78, 91, 97, 191, 253}, /// btreeset! {170, 175, 232}, /// btreeset! {2, 233}, /// btreeset! {17, 22, 32, 35, 114, 198, 217}, /// btreeset! {65, 114, 121, 173}, /// btreeset! {25, 79, 144, 148, 173, 222}, /// btreeset! {52, 115}, /// btreeset! {34, 69, 73, 91, 112, 137, 153, 178}, /// btreeset! {95, 106}, /// btreeset! {167, 197}, /// btreeset! {74, 86, 101, 115, 122, 130, 150, 168, 172, 177, 207, 218, 221}, /// btreeset! {9, 48, 52, 109, 123, 133, 159, 201, 247, 250}, /// btreeset! {196, 235}, /// btreeset! {40, 68, 97, 104, 190}, /// btreeset! {7, 216}, /// btreeset! {11, 24, 43, 112, 157, 216, 217}, /// btreeset! {29, 51, 55, 65, 84, 89, 103, 135, 191, 206, 211} /// ] /// ); /// ``` #[inline] pub fn random_b_tree_sets_min_length( seed: Seed, min_length: u64, xs_gen: &dyn Fn(Seed) -> I, mean_length_numerator: u64, mean_length_denominator: u64, ) -> RandomBTreeSets, I> where I::Item: Ord, { random_b_tree_sets_from_length_iterator( seed, &|seed_2| { geometric_random_unsigned_inclusive_range( seed_2, min_length, u64::MAX, mean_length_numerator, mean_length_denominator, ) }, xs_gen, ) } /// Generates random [`BTreeSet`]s with lengths in $[a, b]$, using elements from an iterator. /// /// The lengths of the [`BTreeSet`]s are sampled from a uniform distribution on $[a, b)$. $a$ must /// be less than or equal to $b$. /// /// The input iterator must generate at least $b$ distinct elements. /// /// $$ /// P((x\_i)\_{i=0}^{n-1}, a, b) = \frac{n!}{b - a + 1}\prod\_{i=0}^{n-1}P(x\_i). /// $$ /// /// `xs_gen` must be infinite. /// /// # Panics /// Panics if $a \geq b$. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::random::random_primitive_ints; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::sets::random::random_b_tree_sets_length_range; /// use maplit::btreeset; /// /// let xs = random_b_tree_sets_length_range(EXAMPLE_SEED, 2, 5, &random_primitive_ints::); /// let values = xs.take(20).collect_vec(); /// assert_eq!( /// values, /// &[ /// btreeset! {11, 85, 136}, /// btreeset! {134, 200, 203, 235}, /// btreeset! {38, 223, 235}, /// btreeset! {32, 162, 177, 217}, /// btreeset! {30, 166, 218, 234}, /// btreeset! {9, 90, 106}, /// btreeset! {204, 216}, /// btreeset! {97, 151, 213}, /// btreeset! {78, 253}, /// btreeset! {39, 91, 175, 191}, /// btreeset! {2, 170, 232, 233}, /// btreeset! {22, 35, 217}, /// btreeset! {17, 32, 114, 198}, /// btreeset! {65, 114, 173}, /// btreeset! {25, 121, 173, 222}, /// btreeset! {79, 115, 144, 148}, /// btreeset! {52, 69, 73, 137}, /// btreeset! {91, 153}, /// btreeset! {34, 95, 112, 178}, /// btreeset! {106, 167} /// ] /// ); /// ``` #[inline] pub fn random_b_tree_sets_length_range( seed: Seed, a: u64, b: u64, xs_gen: &dyn Fn(Seed) -> I, ) -> RandomBTreeSets, I> where I::Item: Ord, { random_b_tree_sets_from_length_iterator( seed, &|seed_2| random_unsigned_range(seed_2, a, b), xs_gen, ) } /// Generates random [`BTreeSet`]s with lengths in $[a, b]$, using elements from an iterator. /// /// The lengths of the [`BTreeSet`]s are sampled from a uniform distribution on $[a, b)$. $a$ must /// be less than or equal to $b$. /// /// The input iterator must generate at least $b$ distinct elements. /// /// $$ /// P((x\_i)\_{i=0}^{n-1}, a, b) = \frac{n!}{b - a + 1}\prod\_{i=0}^{n-1}P(x\_i). /// $$ /// /// `xs_gen` must be infinite. /// /// # Panics /// Panics if $a \geq b$. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::random::random_primitive_ints; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::sets::random::random_b_tree_sets_length_inclusive_range; /// use maplit::btreeset; /// /// let xs = /// random_b_tree_sets_length_inclusive_range(EXAMPLE_SEED, 2, 4, &random_primitive_ints::); /// let values = xs.take(20).collect_vec(); /// assert_eq!( /// values, /// &[ /// btreeset! {11, 85, 136}, /// btreeset! {134, 200, 203, 235}, /// btreeset! {38, 223, 235}, /// btreeset! {32, 162, 177, 217}, /// btreeset! {30, 166, 218, 234}, /// btreeset! {9, 90, 106}, /// btreeset! {204, 216}, /// btreeset! {97, 151, 213}, /// btreeset! {78, 253}, /// btreeset! {39, 91, 175, 191}, /// btreeset! {2, 170, 232, 233}, /// btreeset! {22, 35, 217}, /// btreeset! {17, 32, 114, 198}, /// btreeset! {65, 114, 173}, /// btreeset! {25, 121, 173, 222}, /// btreeset! {79, 115, 144, 148}, /// btreeset! {52, 69, 73, 137}, /// btreeset! {91, 153}, /// btreeset! {34, 95, 112, 178}, /// btreeset! {106, 167} /// ] /// ); /// ``` #[inline] pub fn random_b_tree_sets_length_inclusive_range( seed: Seed, a: u64, b: u64, xs_gen: &dyn Fn(Seed) -> I, ) -> RandomBTreeSets, I> where I::Item: Ord, { random_b_tree_sets_from_length_iterator( seed, &|seed_2| random_unsigned_inclusive_range(seed_2, a, b), xs_gen, ) } malachite-base-0.4.16/src/slices/mod.rs000064400000000000000000000356341046102023000157640ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // Uses code adopted from the GNU MP Library. // // Copyright © 1991, 1993-1997, 1999-2016, 2009, 2020 Free Software Foundation, Inc. // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::DivisibleBy; use crate::num::basic::traits::Zero; #[cfg(feature = "random")] use crate::num::conversion::traits::ExactFrom; #[cfg(feature = "random")] use crate::num::random::{random_unsigneds_less_than, RandomUnsignedsLessThan}; #[cfg(feature = "random")] use crate::random::Seed; use alloc::vec::Vec; #[cfg(feature = "random")] use rand::prelude::SliceRandom; #[cfg(feature = "random")] use rand_chacha::ChaCha20Rng; /// Sets all values in a slice to 0. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`. /// /// # Examples /// ``` /// use malachite_base::slices::slice_set_zero; /// /// let mut xs = [1, 2, 3, 4, 5]; /// slice_set_zero::(&mut xs[1..4]); /// assert_eq!(xs, [1, 0, 0, 0, 5]); /// ``` /// /// This is equivalent to `mpn_zero` from `mpn/generic/zero.c`, GMP 6.2.1. Note that this is needed /// less often in Malachite than in GMP, since Malachite generally initializes new memory with /// zeros. pub fn slice_set_zero(xs: &mut [T]) { for x in &mut *xs { *x = T::ZERO; } } /// Tests whether all values in a slice are equal to 0. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`. /// /// # Examples /// ``` /// use malachite_base::slices::slice_test_zero; /// /// assert!(slice_test_zero::(&[0, 0, 0])); /// assert!(!slice_test_zero::(&[0, 1, 0])); /// ``` /// /// This is equivalent to `mpn_zero_p` from `gmp-h.in`, GMP 6.2.1. pub fn slice_test_zero(xs: &[T]) -> bool { let zero = T::ZERO; xs.iter().all(|x| x == &zero) } /// Counts the number of zeros that a slice starts with. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`. /// /// # Examples /// ``` /// use malachite_base::slices::slice_leading_zeros; /// /// assert_eq!(slice_leading_zeros::(&[1, 2, 3]), 0); /// assert_eq!(slice_leading_zeros::(&[0, 0, 0, 1, 2, 3]), 3); /// ``` pub fn slice_leading_zeros(xs: &[T]) -> usize { let zero = T::ZERO; xs.iter().take_while(|&x| x == &zero).count() } /// Counts the number of zeros that a slice ends with. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`. /// /// # Examples /// ``` /// use malachite_base::slices::slice_trailing_zeros; /// /// assert_eq!(slice_trailing_zeros::(&[1, 2, 3]), 0); /// assert_eq!(slice_trailing_zeros::(&[1, 2, 3, 0, 0, 0]), 3); /// ``` pub fn slice_trailing_zeros(xs: &[T]) -> usize { let zero = T::ZERO; xs.iter().rev().take_while(|&x| x == &zero).count() } /// Given a slice and an starting index, copies the subslice starting from that index to the /// beginning of the slice. /// /// In other words, this function copies the contents of `&xs[starting_index..]` to `&xs[..xs.len() /// - starting_index]`. /// /// In other other words, if $k$ is `starting_index`, the sequence $[x_0, x_1, \ldots, x_{n-1}]$ /// becomes $[x_k, x_{k+1}, \ldots, x_{n-1}, x_{n-k}, x_{n-k+1}, \ldots, x_{n-1}]$. /// /// If `starting_index` is zero or `xs.len()`, nothing happens. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`. /// /// # Panics /// Panics if `starting_index` is greater than the length of `xs`. /// /// # Examples /// ``` /// use malachite_base::slices::slice_move_left; /// /// let xs = &mut [1, 2, 3, 4, 5, 6]; /// slice_move_left::(xs, 2); /// assert_eq!(xs, &[3, 4, 5, 6, 5, 6]); /// ``` #[inline] pub fn slice_move_left(xs: &mut [T], starting_index: usize) { xs.copy_within(starting_index..xs.len(), 0); } /// Splits an immutable slice into adjacent immutable chunks. /// /// An input slice $\mathbf{x}$, a chunk length $n$, and $k + 1$ output slice names $\\mathbf{x}_0, /// \\mathbf{x}_1, \\ldots, \\mathbf{x}_k$ are given. The last output slice name, $\mathbf{x}_k$, is /// specified via a separate argument called `xs_last`. /// /// The first $k$ output slice names are assigned adjacent length-$n$ chunks from $\mathbf{x}$. If /// $|\mathbf{x}| < kn$, the generated code panics. /// /// The last slice, $\mathbf{x}_k$, which is assigned to `xs_last`, has length $|\mathbf{x}| - kn$. /// This length may be greater than $n$. /// /// # Worst-case complexity /// $T(k) = O(k)$ /// /// $M(k) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $k$ is the number of output slice names `xs_i`. /// /// # Examples /// ``` /// use malachite_base::split_into_chunks; /// /// let xs = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; /// split_into_chunks!(xs, 3, [xs_1, xs_2, xs_3], xs_4); /// assert_eq!(xs_1, &[0, 1, 2]); /// assert_eq!(xs_2, &[3, 4, 5]); /// assert_eq!(xs_3, &[6, 7, 8]); /// assert_eq!(xs_4, &[9, 10, 11, 12]); /// ``` #[macro_export] macro_rules! split_into_chunks { ($xs: expr, $n: expr, [$($xs_i: ident),*], $xs_last: ident) => { let remainder = &$xs[..]; let n = $n; $( let ($xs_i, remainder) = remainder.split_at(n); )* let $xs_last = remainder; } } /// Splits a mutable slice into adjacent mutable chunks. /// /// An input slice $\mathbf{x}$, a chunk length $n$, and $k + 1$ output slice names $\\mathbf{x}_0, /// \\mathbf{x}_1, \\ldots, \\mathbf{x}_k$ are given. The last output slice name, $\mathbf{x}_k$, is /// specified via a separate argument called `xs_last`. /// /// The first $k$ output slice names are assigned adjacent length-$n$ chunks from $\mathbf{x}$. If /// $|\mathbf{x}| < kn$, the generated code panics. /// /// The last slice, $\mathbf{x}_k$, which is assigned to `xs_last`, has length $|\mathbf{x}| - kn$. /// This length may be greater than $n$. /// /// # Worst-case complexity /// $T(k) = O(k)$ /// /// $M(k) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, and $k$ is the number of output slice names `xs_i`. /// /// # Examples /// ``` /// use malachite_base::slices::slice_set_zero; /// use malachite_base::split_into_chunks_mut; /// /// let xs = &mut [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; /// split_into_chunks_mut!(xs, 3, [xs_1, xs_2, xs_3], xs_4); /// assert_eq!(xs_1, &[0, 1, 2]); /// assert_eq!(xs_2, &[3, 4, 5]); /// assert_eq!(xs_3, &[6, 7, 8]); /// assert_eq!(xs_4, &[9, 10, 11, 12]); /// /// slice_set_zero(xs_2); /// assert_eq!(xs, &[0, 1, 2, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12]); /// ``` #[macro_export] macro_rules! split_into_chunks_mut { ($xs: expr, $n: expr, [$($xs_i: ident),*], $xs_last: ident) => { let remainder = &mut $xs[..]; let n = $n; $( let ($xs_i, remainder) = remainder.split_at_mut(n); )* let $xs_last = remainder; } } #[cfg(feature = "random")] /// Uniformly generates a random reference to a value from a nonempty slice. /// /// This `struct` is created by [`random_values_from_slice`]; see its documentation for more. #[derive(Clone, Debug)] pub struct RandomValuesFromSlice<'a, T> { xs: &'a [T], indices: RandomUnsignedsLessThan, } #[cfg(feature = "random")] impl<'a, T> Iterator for RandomValuesFromSlice<'a, T> { type Item = &'a T; #[inline] fn next(&mut self) -> Option<&'a T> { Some(&self.xs[usize::exact_from(self.indices.next().unwrap())]) } } #[cfg(feature = "random")] /// Uniformly generates a random reference to a value from a nonempty slice. /// /// The iterator cannot outlive the slice. It may be more convenient for the iterator to own the /// data, in which case you may use [`random_values_from_vec`](crate::vecs::random_values_from_vec) /// instead. /// /// The output length is infinite. /// /// $P(x) = 1/n$, where $n$ is `xs.len()`. /// /// # Expected complexity per iteration /// Constant time and additional memory. /// /// # Panics /// Panics if `xs` is empty. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::slices::random_values_from_slice; /// /// let xs = &[2, 3, 5, 7, 11]; /// assert_eq!( /// random_values_from_slice(EXAMPLE_SEED, xs) /// .cloned() /// .take(10) /// .collect_vec(), /// &[3, 7, 3, 5, 11, 3, 5, 11, 2, 2] /// ); /// ``` #[inline] pub fn random_values_from_slice(seed: Seed, xs: &[T]) -> RandomValuesFromSlice { assert!(!xs.is_empty(), "empty slice"); RandomValuesFromSlice { xs, indices: random_unsigneds_less_than(seed, u64::exact_from(xs.len())), } } pub(crate) fn advance_indices(indices: &mut [usize]) -> bool { let n = indices.len(); if n == 0 { return true; } // Find the index of the value right before the longest descending suffix. let mut pivot_index = n; let mut i = 0; let mut reached_end = true; while pivot_index > 0 { pivot_index -= 1; let next_i = indices[pivot_index]; if next_i < i { reached_end = false; break; } i = next_i; } if reached_end { return true; } let pivot = indices[pivot_index]; let mut swap_index = n - 1; while indices[swap_index] < pivot { swap_index -= 1; } indices.swap(pivot_index, swap_index); indices[pivot_index + 1..].reverse(); false } /// Generates every permutation of a slice. /// /// This `struct` is created by [`exhaustive_slice_permutations`]; see its documentation for more. #[derive(Clone, Debug, Eq, Hash, PartialEq)] pub struct ExhaustiveSlicePermutations<'a, T> { xs: &'a [T], indices: Vec, done: bool, } impl<'a, T> Iterator for ExhaustiveSlicePermutations<'a, T> { type Item = Vec<&'a T>; fn next(&mut self) -> Option> { if self.done { None } else { let out = Some(self.indices.iter().map(|&i| &self.xs[i]).collect()); self.done = advance_indices(&mut self.indices); out } } } /// Generates every permutation of a slice. /// /// The permutations are [`Vec`]s of references into the slice. It may be more convenient for the /// iterator to own the data, in which case you may use /// [`exhaustive_vec_permutations`](crate::vecs::exhaustive_vec_permutations) instead. /// /// The permutations are generated in lexicographic order with respect to the ordering in the slice. /// /// The output length is $n!$, where $n$ is `xs.len()`. /// /// # Expected complexity per iteration /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::slices::exhaustive_slice_permutations; /// /// let css: Vec = exhaustive_slice_permutations(&['a', 'b', 'c', 'd']) /// .map(|ds| ds.into_iter().copied().collect()) /// .collect(); /// assert_eq!( /// css.iter().map(String::as_str).collect_vec().as_slice(), /// [ /// "abcd", "abdc", "acbd", "acdb", "adbc", "adcb", "bacd", "badc", "bcad", "bcda", "bdac", /// "bdca", "cabd", "cadb", "cbad", "cbda", "cdab", "cdba", "dabc", "dacb", "dbac", "dbca", /// "dcab", "dcba" /// ] /// ); /// ``` pub fn exhaustive_slice_permutations(xs: &[T]) -> ExhaustiveSlicePermutations { ExhaustiveSlicePermutations { xs, indices: (0..xs.len()).collect(), done: false, } } #[cfg(feature = "random")] /// Uniformly generates a random permutation of references to a slice. /// /// This `struct` is created by [`random_slice_permutations`]; see its documentation for more. #[derive(Clone, Debug)] pub struct RandomSlicePermutations<'a, T> { xs: &'a [T], indices: Vec, rng: ChaCha20Rng, } #[cfg(feature = "random")] impl<'a, T> Iterator for RandomSlicePermutations<'a, T> { type Item = Vec<&'a T>; fn next(&mut self) -> Option> { self.indices.shuffle(&mut self.rng); Some(self.indices.iter().map(|&i| &self.xs[i]).collect()) } } #[cfg(feature = "random")] /// Uniformly generates a random permutation of references to a slice. /// /// The iterator cannot outlive the slice. It may be more convenient for the iterator to own the /// data, in which case you may use /// [`random_vec_permutations`](crate::vecs::random_vec_permutations) instead. /// /// The output length is infinite. /// /// $P(p) = 1/n!$, where $n$ is `xs.len()`. /// /// # Expected complexity per iteration /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::slices::random_slice_permutations; /// /// let css: Vec = random_slice_permutations(EXAMPLE_SEED, &['a', 'b', 'c', 'd']) /// .take(20) /// .map(|ds| ds.into_iter().copied().collect()) /// .collect(); /// assert_eq!( /// css.iter().map(String::as_str).collect_vec().as_slice(), /// [ /// "cadb", "cbad", "cadb", "badc", "acdb", "cbad", "dabc", "dbca", "cdba", "cdab", "bacd", /// "cabd", "adbc", "cdab", "dcab", "abcd", "abcd", "dacb", "bcad", "adcb" /// ] /// ); /// ``` pub fn random_slice_permutations(seed: Seed, xs: &[T]) -> RandomSlicePermutations { RandomSlicePermutations { xs, indices: (0..xs.len()).collect(), rng: seed.get_rng(), } } /// Given a slice with nonzero length $\ell$, returns the smallest $n$ such that the slice consists /// of $n/\ell$ copies of a length-$\ell$ subslice. /// /// Typically $\ell = n$. /// /// # Worst-case complexity /// $T(n) = O(n^{1+\varepsilon})$ for all $\varepsilon > 0$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`. /// /// # Panics /// Panics if `xs` is empty. /// /// # Examples /// ``` /// use malachite_base::slices::min_repeating_len; /// /// assert_eq!(min_repeating_len(&[1, 2, 1, 2, 1, 2]), 2); /// assert_eq!(min_repeating_len(&[1, 2, 1, 2, 1, 3]), 6); /// assert_eq!(min_repeating_len(&[5, 5, 5]), 1); /// ``` pub fn min_repeating_len(xs: &[T]) -> usize { let len = xs.len(); assert_ne!(len, 0); for start_i in 1..=len >> 1 { if !len.divisible_by(start_i) { continue; } let (xs_lo, xs_hi) = xs.split_at(start_i); if Iterator::eq(xs_lo.iter().cycle().take(len - start_i), xs_hi.iter()) { return start_i; } } len } malachite-base-0.4.16/src/strings/exhaustive.rs000064400000000000000000000234271046102023000175760ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::chars::exhaustive::{exhaustive_chars, ExhaustiveChars}; use crate::num::exhaustive::PrimitiveIntIncreasingRange; use crate::strings::{strings_from_char_vecs, StringsFromCharVecs}; use crate::vecs::exhaustive::{ exhaustive_vecs, exhaustive_vecs_fixed_length_from_single, lex_vecs_fixed_length_from_single, shortlex_vecs, ExhaustiveFixedLengthVecs1Input, ExhaustiveVecs, LexFixedLengthVecsFromSingle, ShortlexVecs, }; /// Generates all [`String`]s of a given length with [`char`]s from a single iterator, in /// lexicographic order. /// /// The order is lexicographic with respect to the order of the element iterator. /// /// `cs` must be finite. /// /// The output length is $\ell^n$, where $\ell$ is `cs.count()` and $n$ is `len`. /// /// If `len` is 0, the output consists of one empty [`String`]. /// /// If `cs` is empty, the output is also empty, unless `len` is 0. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::strings::exhaustive::lex_fixed_length_strings_using_chars; /// /// let ss = lex_fixed_length_strings_using_chars(2, ['c', 'a', 't'].iter().cloned()).collect_vec(); /// assert_eq!( /// ss.iter().map(|cs| cs.as_str()).collect_vec().as_slice(), /// &["cc", "ca", "ct", "ac", "aa", "at", "tc", "ta", "tt"] /// ); /// ``` #[inline] pub fn lex_fixed_length_strings_using_chars>( len: u64, cs: I, ) -> StringsFromCharVecs> { strings_from_char_vecs(lex_vecs_fixed_length_from_single(len, cs)) } /// Generates all [`String`]s of a given length in lexicographic order. /// /// The order is lexicographic with respect to the order of [`exhaustive_chars`], which is not the /// default lexicographic order for [`char`]s. (For example, the first characters are not control /// characters, but lowercase Latin letters.) If you want the default [`char`] order, use /// `lex_fixed_length_strings_using_chars(len, chars_increasing())`. /// /// The output length is $1112064^n$, where $n$ is `len`. /// /// If `len` is 0, the output consists of one empty [`String`]. /// /// # Complexity per iteration /// $T(i, n) = O(n)$ /// /// $M(i, n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `len`. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::strings::exhaustive::lex_fixed_length_strings; /// /// let ss = lex_fixed_length_strings(2).take(20).collect_vec(); /// assert_eq!( /// ss.iter().map(|cs| cs.as_str()).collect_vec().as_slice(), /// &[ /// "aa", "ab", "ac", "ad", "ae", "af", "ag", "ah", "ai", "aj", "ak", "al", "am", "an", /// "ao", "ap", "aq", "ar", "as", "at" /// ] /// ); /// ``` #[inline] pub fn lex_fixed_length_strings( len: u64, ) -> StringsFromCharVecs> { lex_fixed_length_strings_using_chars(len, exhaustive_chars()) } /// Generates all `String`s of a given length with [`char`]s from a single iterator. /// /// If `cs` is finite, the output length is $\ell^n$, where $\ell$ is `cs.count()` and $n$ is `len`. /// If `cs` is infinite, the output is also infinite. /// /// If `len` is 0, the output consists of one empty [`String`]. /// /// If `cs` is empty, the output is also empty, unless `len` is 0. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::strings::exhaustive::exhaustive_fixed_length_strings_using_chars; /// /// let ss = exhaustive_fixed_length_strings_using_chars(2, ['c', 'a', 't'].iter().cloned()) /// .collect_vec(); /// assert_eq!( /// ss.iter().map(|cs| cs.as_str()).collect_vec().as_slice(), /// &["cc", "ca", "ac", "aa", "ct", "at", "tc", "ta", "tt"] /// ); /// ``` #[inline] pub fn exhaustive_fixed_length_strings_using_chars>( len: u64, cs: I, ) -> StringsFromCharVecs> { strings_from_char_vecs(exhaustive_vecs_fixed_length_from_single(len, cs)) } /// Generates all [`String`]s of a given length. /// /// The output length is $1112064^n$, where $n$ is `len`. /// /// If `len` is 0, the output consists of one empty [`String`]. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::strings::exhaustive::exhaustive_fixed_length_strings; /// /// let ss = exhaustive_fixed_length_strings(2).take(20).collect_vec(); /// assert_eq!( /// ss.iter().map(|cs| cs.as_str()).collect_vec().as_slice(), /// &[ /// "aa", "ab", "ba", "bb", "ac", "ad", "bc", "bd", "ca", "cb", "da", "db", "cc", "cd", /// "dc", "dd", "ae", "af", "be", "bf" /// ] /// ); /// ``` #[inline] pub fn exhaustive_fixed_length_strings( len: u64, ) -> StringsFromCharVecs> { exhaustive_fixed_length_strings_using_chars(len, exhaustive_chars()) } /// Generates [`String`]s with [`char`]s from a specified iterator, in shortlex order. /// /// Shortlex order means that the [`String`]s are output from shortest to longest, and [`String`]s /// of the same length are output in lexicographic order with respect to the ordering of the /// [`char`]s specified by the input iterator. /// /// `cs` must be finite; if it's infinite, only [`String`]s of length 0 and 1 are ever produced. /// /// If `cs` is empty, the output length is 1; otherwise, the output is infinite. /// /// The lengths of the output [`String`]s grow logarithmically. /// /// # Complexity per iteration /// $T(i) = O(\log i)$ /// /// $M(i) = O(\log i)$ /// /// where $T$ is time and $M$ is additional memory. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::strings::exhaustive::shortlex_strings_using_chars; /// /// let ss = shortlex_strings_using_chars('x'..='z') /// .take(20) /// .collect_vec(); /// assert_eq!( /// ss.iter().map(String::as_str).collect_vec().as_slice(), /// &[ /// "", "x", "y", "z", "xx", "xy", "xz", "yx", "yy", "yz", "zx", "zy", "zz", "xxx", "xxy", /// "xxz", "xyx", "xyy", "xyz", "xzx" /// ] /// ); /// ``` #[inline] pub fn shortlex_strings_using_chars>( cs: I, ) -> StringsFromCharVecs, I>> { strings_from_char_vecs(shortlex_vecs(cs)) } /// Generates [`String`]s in shortlex order. /// /// Shortlex order means that the [`String`]s are output from shortest to longest, and [`String`]s /// of the same length are output in lexicographic order with respect to the order of /// [`exhaustive_chars`], which is not the default lexicographic order for [`char`]s. (For example, /// the first characters are not control characters, but lowercase Latin letters.) If you want the /// default [`char`] order, use `shortlex_strings_using_chars(chars_increasing())`. /// /// The output is infinite. /// /// The lengths of the output [`String`]s grow logarithmically. /// /// # Complexity per iteration /// $T(i) = O(\log i)$ /// /// $M(i) = O(\log i)$ /// /// where $T$ is time and $M$ is additional memory. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::strings::exhaustive::shortlex_strings; /// /// let ss = shortlex_strings().take(20).collect_vec(); /// assert_eq!( /// ss.iter().map(String::as_str).collect_vec().as_slice(), /// &[ /// "", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", /// "q", "r", "s" /// ] /// ); /// ``` #[inline] pub fn shortlex_strings( ) -> StringsFromCharVecs, ExhaustiveChars>> { shortlex_strings_using_chars(exhaustive_chars()) } /// Generates all [`String`]s with [`char`]s from a specified iterator. /// /// If `cs` is empty, the output length is 1; otherwise, the output is infinite. /// /// The lengths of the output [`String`]s grow logarithmically. /// /// # Complexity per iteration /// $T(i) = O(\log i)$ /// /// $M(i) = O(\log i)$ /// /// where $T$ is time and $M$ is additional memory. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::strings::exhaustive::exhaustive_strings_using_chars; /// /// let ss = exhaustive_strings_using_chars('x'..='z') /// .take(20) /// .collect_vec(); /// assert_eq!( /// ss.iter().map(String::as_str).collect_vec().as_slice(), /// &[ /// "", "x", "y", "xxx", "z", "xx", "xy", "xxxxx", "yx", "xxy", "yy", "xxxx", "xz", "xyx", /// "yz", "xxxxxx", "zx", "xyy", "zy", "xxxy" /// ] /// ); /// ``` #[inline] pub fn exhaustive_strings_using_chars>( cs: I, ) -> StringsFromCharVecs, I>> { strings_from_char_vecs(exhaustive_vecs(cs)) } /// Generates all [`String`]s. /// /// The lengths of the output [`String`]s grow logarithmically. /// /// # Complexity per iteration /// $T(i) = O(\log i)$ /// /// $M(i) = O(\log i)$ /// /// where $T$ is time and $M$ is additional memory. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::strings::exhaustive::exhaustive_strings; /// /// let ss = exhaustive_strings().take(20).collect_vec(); /// assert_eq!( /// ss.iter().map(String::as_str).collect_vec().as_slice(), /// &[ /// "", "a", "b", "aaa", "c", "aa", "d", "aaaa", "e", "ab", "f", "aab", "g", "ba", "h", /// "aaaaa", "i", "bb", "j", "aba" /// ] /// ); /// ``` #[inline] pub fn exhaustive_strings( ) -> StringsFromCharVecs, ExhaustiveChars>> { exhaustive_strings_using_chars(exhaustive_chars()) } malachite-base-0.4.16/src/strings/mod.rs000064400000000000000000000164121046102023000161640ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::named::Named; use alloc::string::String; use alloc::vec::Vec; use core::fmt::{Binary, Debug, LowerHex, Octal, UpperHex}; use hashbrown::HashSet; use itertools::Itertools; /// Sorts the characters of a string slice and returns them in a new [`String`]. /// /// # Worst-case complexity /// $T(n) = O(n \log n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `s.len()`. /// /// # Examples /// ``` /// use malachite_base::strings::string_sort; /// /// assert_eq!(string_sort("Hello, world!"), " !,Hdellloorw"); /// assert_eq!(string_sort("Mississippi"), "Miiiippssss"); /// ``` pub fn string_sort(s: &str) -> String { let mut chars = s.chars().collect_vec(); chars.sort_unstable(); chars.iter().collect() } /// Takes a string slice's unique characters and returns them in a new [`String`]. /// /// The unique characters are output in order of appearance. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `s.len()`. /// /// # Examples /// ``` /// use malachite_base::strings::string_unique; /// /// assert_eq!(string_unique("Hello, world!"), "Helo, wrd!"); /// assert_eq!(string_unique("Mississippi"), "Misp"); /// ``` pub fn string_unique(s: &str) -> String { let mut chars = HashSet::new(); let mut nub = String::new(); for c in s.chars() { if chars.insert(c) { nub.push(c); } } nub } /// Returns whether all of the first string slice's characters are present in the second string /// slice. /// /// Does not take multiplicities into account. /// /// # Worst-case complexity /// $T(n) = O(n)$ /// /// $M(n) = O(n + m)$ /// /// where $T$ is time, $M$ is additional memory, $n$ is `s.len()`, and $m$ is `t.len()`. /// /// # Examples /// ``` /// use malachite_base::strings::string_is_subset; /// /// assert_eq!(string_is_subset("oH, well", "Hello, world!"), true); /// assert_eq!(string_is_subset("MMM", "Mississippi"), true); /// assert_eq!(string_is_subset("Hello, World!", "Hello, world!"), false); /// assert_eq!(string_is_subset("j", "Mississippi"), false); /// ``` pub fn string_is_subset(s: &str, t: &str) -> bool { let t_chars: HashSet = t.chars().collect(); s.chars().all(|c| t_chars.contains(&c)) } impl_named!(String); /// A trait that provides an ergonomic way to create the string specified by a [`Debug`] /// implementation. pub trait ToDebugString: Debug { fn to_debug_string(&self) -> String; } impl ToDebugString for T { /// Returns the [`String`] produced by `T`s [`Debug`] implementation. /// /// # Examples /// ``` /// use malachite_base::strings::ToDebugString; /// /// assert_eq!([1, 2, 3].to_debug_string(), "[1, 2, 3]"); /// assert_eq!( /// [vec![2, 3], vec![], vec![4]].to_debug_string(), /// "[[2, 3], [], [4]]" /// ); /// assert_eq!(Some(5).to_debug_string(), "Some(5)"); /// ``` #[inline] fn to_debug_string(&self) -> String { ::alloc::format!("{self:?}") } } /// A trait that provides an ergonomic way to create the string specified by a [`Binary`] /// implementation. pub trait ToBinaryString: Binary { fn to_binary_string(&self) -> String; } impl ToBinaryString for T { /// Returns the [`String`] produced by `T`s [`Binary`] implementation. /// /// # Examples /// ``` /// use malachite_base::strings::ToBinaryString; /// /// assert_eq!(5u64.to_binary_string(), "101"); /// assert_eq!((-100i16).to_binary_string(), "1111111110011100"); /// ``` #[inline] fn to_binary_string(&self) -> String { ::alloc::format!("{self:b}") } } /// A trait that provides an ergonomic way to create the string specified by an [`Octal`] /// implementation. pub trait ToOctalString: Octal { fn to_octal_string(&self) -> String; } impl ToOctalString for T { /// Returns the [`String`] produced by `T`s [`Octal`] implementation. /// /// # Examples /// ``` /// use malachite_base::strings::ToOctalString; /// /// assert_eq!(50u64.to_octal_string(), "62"); /// assert_eq!((-100i16).to_octal_string(), "177634"); /// ``` #[inline] fn to_octal_string(&self) -> String { ::alloc::format!("{self:o}") } } /// A trait that provides an ergonomic way to create the string specified by a [`LowerHex`] /// implementation. pub trait ToLowerHexString: LowerHex { fn to_lower_hex_string(&self) -> String; } impl ToLowerHexString for T { /// Returns the [`String`] produced by `T`s [`LowerHex`] implementation. /// /// # Examples /// ``` /// use malachite_base::strings::ToLowerHexString; /// /// assert_eq!(50u64.to_lower_hex_string(), "32"); /// assert_eq!((-100i16).to_lower_hex_string(), "ff9c"); /// ``` #[inline] fn to_lower_hex_string(&self) -> String { ::alloc::format!("{self:x}") } } /// A trait that provides an ergonomic way to create the string specified by an [`UpperHex`] /// implementation. pub trait ToUpperHexString: UpperHex { fn to_upper_hex_string(&self) -> String; } impl ToUpperHexString for T { /// Returns the [`String`] produced by `T`s [`UpperHex`] implementation. /// /// # Examples /// ``` /// use malachite_base::strings::ToUpperHexString; /// /// assert_eq!(50u64.to_upper_hex_string(), "32"); /// assert_eq!((-100i16).to_upper_hex_string(), "FF9C"); /// ``` #[inline] fn to_upper_hex_string(&self) -> String { ::alloc::format!("{self:X}") } } /// Generates [`String`]s, given an iterator that generates `Vec`s. /// /// This `struct` is created by [`strings_from_char_vecs`]; see its documentation for more. #[derive(Clone, Debug)] pub struct StringsFromCharVecs>> { css: I, } impl>> Iterator for StringsFromCharVecs { type Item = String; #[inline] fn next(&mut self) -> Option { self.css.next().map(|cs| cs.into_iter().collect()) } } /// Generates [`String`]s, given an iterator that generates `Vec`s. /// /// The elements appear in the same order as they do in the given iterator, but as [`String`]s. /// /// The output length is `css.count()`. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::strings::strings_from_char_vecs; /// /// let ss = /// &strings_from_char_vecs([vec!['a', 'b'], vec!['c', 'd']].iter().cloned()).collect_vec(); /// assert_eq!( /// ss.iter().map(|cs| cs.as_str()).collect_vec().as_slice(), /// &["ab", "cd"] /// ); /// ``` #[inline] pub const fn strings_from_char_vecs>>( css: I, ) -> StringsFromCharVecs { StringsFromCharVecs { css } } /// Iterators that generate [`String`]s without repetition. pub mod exhaustive; #[cfg(feature = "random")] /// Iterators that generate [`String`]s randomly. pub mod random; malachite-base-0.4.16/src/strings/random.rs000064400000000000000000000151751046102023000166720ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::chars::random::{random_chars, RandomCharRange}; use crate::num::random::geometric::GeometricRandomNaturalValues; use crate::random::Seed; use crate::strings::StringsFromCharVecs; use crate::vecs::random::{ random_vecs, random_vecs_fixed_length_from_single, RandomFixedLengthVecsFromSingle, RandomVecs, }; /// Randomly generates [`String`]s of a given length using [`char`]s from a single iterator. /// /// The probability of a particular length-$n$ [`String`] being generated is the product of the /// probabilities of each of its `char`s. /// /// If `len` is 0, the output consists of the empty [`String`], repeated. /// /// `cs` must be infinite. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::chars::random::random_char_inclusive_range; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::strings::random::random_fixed_length_strings_using_chars; /// /// let ss = random_fixed_length_strings_using_chars( /// 2, /// random_char_inclusive_range(EXAMPLE_SEED, 'a', 'c'), /// ) /// .take(10) /// .collect_vec(); /// assert_eq!( /// ss.iter().map(|cs| cs.as_str()).collect_vec().as_slice(), /// &["ba", "bc", "bb", "ab", "ac", "ba", "bc", "ca", "ba", "cc"] /// ); /// ``` #[inline] pub const fn random_fixed_length_strings_using_chars>( len: u64, cs: I, ) -> StringsFromCharVecs> { StringsFromCharVecs { css: random_vecs_fixed_length_from_single(len, cs), } } /// Randomly generates [`String`]s of a given length. /// /// The probability of a particular length-$n$ [`String`] being generated is $1112064^{-\ell}$, /// where $\ell$ is `len`. /// /// If `len` is 0, the output consists of the empty [`String`], repeated. /// /// # Expected complexity per iteration /// $T(n) = O(n)$ /// /// $M(n) = O(n)$ /// /// where $T$ is time, $M$ is additional memory, and $n$ is `len`. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::strings::random::random_fixed_length_strings; /// /// let ss = random_fixed_length_strings(EXAMPLE_SEED, 2) /// .take(10) /// .collect_vec(); /// assert_eq!( /// ss.iter().map(|cs| cs.as_str()).collect_vec().as_slice(), /// &[ /// "\u{5f771}\u{87234}", /// "\u{bcd36}\u{9e195}", /// "\u{5da07}\u{36553}", /// "\u{45028}\u{1cdfd}", /// "\u{d8530}\u{c7f2e}", /// "\u{ba4bc}\u{ff677}", /// "\u{a12e2}\u{d775c}", /// "\u{f827b}\u{bdf7a}", /// "簅\u{15aca}", /// "\u{4e5e2}\u{bb286}" /// ] /// ); /// ``` #[inline] pub fn random_fixed_length_strings( seed: Seed, len: u64, ) -> StringsFromCharVecs> { random_fixed_length_strings_using_chars(len, random_chars(seed)) } /// Generates random [`String`]s using [`char`]s from an iterator. /// /// The lengths of the [`String`]s are sampled from a geometric distribution with a specified mean /// $m$, equal to `mean_length_numerator / mean_length_denominator`. $m$ must be greater than 0. /// /// $$ /// P((c_0, c_1, \ldots, c_{n-1})) = \frac{m^n}{(m+1)^{n+1}}\prod_{i=0}^{n-1}P(c_i). /// $$ /// /// The iterators produced by `cs_gen` must be infinite. /// /// # Panics /// Panics if `mean_length_numerator` or `mean_length_denominator` are zero, or, if after being /// reduced to lowest terms, their sum is greater than or equal to $2^{64}$. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::chars::random::random_char_inclusive_range; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::strings::random::random_strings_using_chars; /// /// let ss = random_strings_using_chars( /// EXAMPLE_SEED, /// &|seed| random_char_inclusive_range(seed, 'x', 'z'), /// 4, /// 1, /// ) /// .take(10) /// .collect_vec(); /// assert_eq!( /// ss.iter().map(|cs| cs.as_str()).collect_vec().as_slice(), /// &["", "yyyyzxxxzxzxzx", "zzzy", "xzzx", "y", "", "zyzxz", "zy", "zyyx", ""] /// ); /// ``` #[inline] pub fn random_strings_using_chars>( seed: Seed, cs_gen: &dyn Fn(Seed) -> I, mean_length_numerator: u64, mean_length_denominator: u64, ) -> StringsFromCharVecs, I>> { StringsFromCharVecs { css: random_vecs(seed, cs_gen, mean_length_numerator, mean_length_denominator), } } /// Generates random [`String`]s. /// /// The lengths of the [`String`]s are sampled from a geometric distribution with a specified mean /// $m$, equal to `mean_length_numerator / mean_length_denominator`. $m$ must be greater than 0. /// /// $$ /// P((c_0, c_1, \ldots, c_{n-1})) = \frac{m^n}{1112064^n(m+1)^{n+1}} /// $$ /// /// # Expected complexity per iteration /// $T(n) = O(m)$ /// /// $M(n) = O(m)$ /// /// where $T$ is time, $M$ is additional memory, and $m$ is `mean_length_numerator / /// mean_length_denominator`. /// /// # Panics /// Panics if `mean_length_numerator` or `mean_length_denominator` are zero, or, if after being /// reduced to lowest terms, their sum is greater than or equal to $2^{64}$. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::strings::random::random_strings; /// /// let ss = random_strings(EXAMPLE_SEED, 4, 1).take(10).collect_vec(); /// assert_eq!( /// ss.iter().map(|cs| cs.as_str()).collect_vec().as_slice(), /// &[ /// "", /// "\u{81355}\u{a331d}\u{b707b}\u{1354b}\u{b16ac}𣙘\u{67377}\u{4aaa4}\u{a6d6e}\u{45616}\ /// \u{7725f}\u{41e2d}\u{d6b59}\u{de165}", /// "\u{c2d29}\u{695af}\u{98fd7}\u{10ca51}", /// "\u{bec46}\u{c0bec}\u{cb677}\u{71318}", /// "\u{755e1}", /// "", /// "𫮜\u{a2f84}柂\u{f5560}\u{6737b}", /// "\u{8442e}\u{a6883}", /// "\u{49cf2}\u{32d2b}\u{1e6e5}\u{1084bd}", /// "" /// ] /// ); /// ``` #[inline] pub fn random_strings( seed: Seed, mean_length_numerator: u64, mean_length_denominator: u64, ) -> StringsFromCharVecs, RandomCharRange>> { random_strings_using_chars( seed, &random_chars, mean_length_numerator, mean_length_denominator, ) } malachite-base-0.4.16/src/test_util/bench/bucketers.rs000064400000000000000000000727051046102023000210050ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::chars::crement::char_to_contiguous_range; use crate::max; use crate::num::arithmetic::traits::UnsignedAbs; use crate::num::basic::floats::PrimitiveFloat; use crate::num::basic::integers::PrimitiveInt; use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::{ExactFrom, WrappingFrom}; use crate::num::logic::traits::SignificantBits; use crate::rational_sequences::RationalSequence; use std::cmp::{max, min}; pub struct Bucketer<'a, T> { pub bucketing_function: &'a dyn Fn(&T) -> usize, pub bucketing_label: String, } pub fn char_bucketer<'a>() -> Bucketer<'a, char> { Bucketer { bucketing_function: &|&c| usize::exact_from(char_to_contiguous_range(c)), bucketing_label: "char_to_contiguous_range(c)".to_string(), } } pub fn float_size(f: T) -> usize { if f == T::ZERO || !f.is_finite() || f.is_nan() { 0 } else { let (m, e) = f.integer_mantissa_and_exponent(); usize::exact_from(m.significant_bits()) + usize::wrapping_from(e.abs()) } } pub fn primitive_float_bucketer<'a, T: PrimitiveFloat>(var_name: &str) -> Bucketer<'a, T> { Bucketer { bucketing_function: &|&f| float_size(f), bucketing_label: format!("precision({var_name}) + |exponent({var_name})|"), } } pub fn pair_1_primitive_float_bucketer<'a, T: PrimitiveFloat, U>( var_name: &str, ) -> Bucketer<'a, (T, U)> { Bucketer { bucketing_function: &|&(f, _)| float_size(f), bucketing_label: format!("precision({var_name}) + |exponent({var_name})|"), } } pub fn pair_max_primitive_float_bucketer<'a, T: PrimitiveFloat>( x_name: &str, y_name: &str, ) -> Bucketer<'a, (T, T)> { Bucketer { bucketing_function: &|&(f, g)| max(float_size(f), float_size(g)), bucketing_label: format!( "max(precision({x_name}) + |exponent({x_name})|, \ precision({y_name}) + |exponent({y_name})|)" ), } } pub fn triple_1_primitive_float_bucketer<'a, T: PrimitiveFloat, U, V>( var_name: &str, ) -> Bucketer<'a, (T, U, V)> { Bucketer { bucketing_function: &|&(f, _, _)| float_size(f), bucketing_label: format!("precision({var_name}) + |exponent({var_name})|"), } } pub fn triple_max_primitive_float_bucketer<'a, T: PrimitiveFloat>( x_name: &str, y_name: &str, z_name: &str, ) -> Bucketer<'a, (T, T, T)> { Bucketer { bucketing_function: &|&(f, g, h)| max!(float_size(f), float_size(g), float_size(h)), bucketing_label: format!( "max(precision({x_name}) + |exponent({x_name})|, \ precision({y_name}) + |exponent({y_name})|, \ precision({z_name}) + |exponent({z_name})|)", ), } } pub fn pair_primitive_float_bit_u64_max_bucketer<'a, T: PrimitiveFloat>( x_name: &'a str, y_name: &'a str, ) -> Bucketer<'a, (T, u64)> { Bucketer { bucketing_function: &|(x, y)| { usize::exact_from(max(u64::wrapping_from(float_size(*x)), *y)) }, bucketing_label: format!("max({x_name}.significant_bits(), {y_name})"), } } pub fn triple_1_2_primitive_float_bit_u64_max_bucketer<'a, T: PrimitiveFloat, U>( x_name: &'a str, y_name: &'a str, ) -> Bucketer<'a, (T, u64, U)> { Bucketer { bucketing_function: &|(x, y, _)| { usize::exact_from(max(u64::wrapping_from(float_size(*x)), *y)) }, bucketing_label: format!("max({x_name}.significant_bits(), {y_name})"), } } pub fn usize_convertible_direct_bucketer(var_name: &str) -> Bucketer where usize: ExactFrom, { Bucketer { bucketing_function: &|&x| usize::exact_from(x), bucketing_label: var_name.to_string(), } } pub fn primitive_int_direct_bucketer<'a, T: PrimitiveInt>() -> Bucketer<'a, T> where usize: ExactFrom, { usize_convertible_direct_bucketer("n") } pub fn unsigned_direct_bucketer<'a, T: PrimitiveUnsigned>() -> Bucketer<'a, T> where usize: ExactFrom, { usize_convertible_direct_bucketer("u") } pub fn signed_direct_bucketer<'a, T: PrimitiveSigned>() -> Bucketer<'a, T> where usize: ExactFrom, { usize_convertible_direct_bucketer("i") } pub fn usize_convertible_pair_max_bucketer<'a, T: Copy + Ord>( x_name: &'a str, y_name: &'a str, ) -> Bucketer<'a, (T, T)> where usize: ExactFrom, { Bucketer { bucketing_function: &|&(x, y)| usize::exact_from(max(x, y)), bucketing_label: format!("max({x_name}, {y_name})"), } } pub fn abs_usize_convertible_pair_max_bucketer<'a, T: Copy + UnsignedAbs>( x_name: &'a str, y_name: &'a str, ) -> Bucketer<'a, (T, T)> where usize: ExactFrom<::Output>, ::Output: Ord, { Bucketer { bucketing_function: &|&(x, y)| usize::exact_from(max(x.unsigned_abs(), y.unsigned_abs())), bucketing_label: format!("max({x_name}, {y_name})"), } } pub fn abs_pair_usize_convertible_max_bucketer<'a, T: Copy + UnsignedAbs, U: Copy>( x_name: &'a str, y_name: &'a str, ) -> Bucketer<'a, (T, U)> where usize: ExactFrom<::Output> + ExactFrom, ::Output: Ord, { Bucketer { bucketing_function: &|&(x, y)| { max(usize::exact_from(x.unsigned_abs()), usize::exact_from(y)) }, bucketing_label: format!("max({x_name}, {y_name})"), } } pub fn usize_convertible_pair_ratio_bucketer<'a, T: Copy>( x_name: &'a str, y_name: &'a str, ) -> Bucketer<'a, (T, T)> where usize: ExactFrom, { Bucketer { bucketing_function: &|&(x, y)| usize::exact_from(x) / usize::exact_from(y), bucketing_label: format!("{x_name} / {y_name}"), } } pub fn signed_abs_bucketer(var_name: &str) -> Bucketer where usize: ExactFrom<::Output>, { Bucketer { bucketing_function: &|&x| usize::exact_from(x.unsigned_abs()), bucketing_label: var_name.to_string(), } } pub fn bit_bucketer(var_name: &str) -> Bucketer { Bucketer { bucketing_function: &|&x| usize::exact_from(x.significant_bits()), bucketing_label: format!("{var_name}.significant_bits()"), } } pub fn primitive_int_bit_bucketer<'a, T: PrimitiveInt>() -> Bucketer<'a, T> { bit_bucketer("n") } pub fn unsigned_bit_bucketer<'a, T: PrimitiveUnsigned>() -> Bucketer<'a, T> { bit_bucketer("u") } pub fn signed_bit_bucketer<'a, T: PrimitiveSigned>() -> Bucketer<'a, T> { bit_bucketer("i") } pub fn ignore_highest_bit_unsigned_bit_bucketer<'a, T: PrimitiveUnsigned>( var_name: &str, ) -> Bucketer<'a, T> { Bucketer { bucketing_function: &|&x| { let mut x = x; x.clear_bit(T::WIDTH - 1); usize::exact_from(x.significant_bits()) }, bucketing_label: format!( "({} - (1 << {})).significant_bits()", var_name, T::WIDTH - 1 ), } } pub fn string_len_bucketer<'a>() -> Bucketer<'a, String> { Bucketer { bucketing_function: &String::len, bucketing_label: "s.len()".to_string(), } } pub fn pair_string_max_len_bucketer<'a>( s_name: &str, t_name: &str, ) -> Bucketer<'a, (String, String)> { Bucketer { bucketing_function: &|(s, t)| max(s.len(), t.len()), bucketing_label: format!("max(s.len({s_name}), t.len({t_name}))"), } } pub fn pair_1_string_len_bucketer(s_name: &str) -> Bucketer<(String, T)> { Bucketer { bucketing_function: &|(ref s, _)| s.len(), bucketing_label: format!("{s_name}.len()"), } } pub fn pair_2_string_len_bucketer(s_name: &str) -> Bucketer<(T, String)> { Bucketer { bucketing_function: &|(_, ref s)| s.len(), bucketing_label: format!("{s_name}.len()"), } } pub fn vec_len_bucketer<'a, T>() -> Bucketer<'a, Vec> { Bucketer { bucketing_function: &Vec::len, bucketing_label: "xs.len()".to_string(), } } pub fn pair_vec_max_len_bucketer<'a, T, U>( xs_name: &str, ys_name: &str, ) -> Bucketer<'a, (Vec, Vec)> { Bucketer { bucketing_function: &|(xs, ys)| max(xs.len(), ys.len()), bucketing_label: format!("max({xs_name}.len(), {ys_name}.len())"), } } pub fn pair_vec_min_len_bucketer<'a, T, U>( xs_name: &str, ys_name: &str, ) -> Bucketer<'a, (Vec, Vec)> { Bucketer { bucketing_function: &|(xs, ys)| min(xs.len(), ys.len()), bucketing_label: format!("min({xs_name}.len(), {ys_name}.len())"), } } pub fn pair_max_bit_bucketer<'a, T: Copy + SignificantBits, U: Copy + SignificantBits>( x_name: &str, y_name: &str, ) -> Bucketer<'a, (T, U)> { Bucketer { bucketing_function: &|&(x, y)| { usize::exact_from(max(x.significant_bits(), y.significant_bits())) }, bucketing_label: format!("max({x_name}.significant_bits(), {y_name}.significant_bits())"), } } pub fn triple_max_bit_bucketer< 'a, T: Copy + SignificantBits, U: Copy + SignificantBits, V: Copy + SignificantBits, >( x_name: &str, y_name: &str, z_name: &str, ) -> Bucketer<'a, (T, U, V)> { Bucketer { bucketing_function: &|&(x, y, z)| { usize::exact_from(max!( x.significant_bits(), y.significant_bits(), z.significant_bits() )) }, bucketing_label: format!( "max({x_name}.significant_bits(), {y_name}.significant_bits(), \ {z_name}.significant_bits())", ), } } pub fn quadruple_max_bit_bucketer< 'a, T: Copy + SignificantBits, U: Copy + SignificantBits, V: Copy + SignificantBits, W: Copy + SignificantBits, >( x_name: &str, y_name: &str, z_name: &str, w_name: &str, ) -> Bucketer<'a, (T, U, V, W)> { Bucketer { bucketing_function: &|&(x, y, z, w)| { usize::exact_from(max!( x.significant_bits(), y.significant_bits(), z.significant_bits(), w.significant_bits() )) }, bucketing_label: format!( "max({x_name}.significant_bits(), {y_name}.significant_bits(), \ {z_name}.significant_bits(), {w_name}.significant_bits())", ), } } pub fn sextuple_max_bit_bucketer< 'a, T: Copy + SignificantBits, U: Copy + SignificantBits, V: Copy + SignificantBits, W: Copy + SignificantBits, X: Copy + SignificantBits, Y: Copy + SignificantBits, >( x_name: &str, y_name: &str, z_name: &str, w_name: &str, v_name: &str, u_name: &str, ) -> Bucketer<'a, (T, U, V, W, X, Y)> { Bucketer { bucketing_function: &|&(x, y, z, w, v, u)| { usize::exact_from(max!( x.significant_bits(), y.significant_bits(), z.significant_bits(), w.significant_bits(), v.significant_bits(), u.significant_bits() )) }, bucketing_label: format!( "max({x_name}.significant_bits(), {y_name}.significant_bits(), \ {z_name}.significant_bits(), {w_name}.significant_bits(), \ {v_name}.significant_bits(), {u_name}.significant_bits())", ), } } #[allow(clippy::type_complexity)] pub fn octuple_max_bit_bucketer< 'a, T: Copy + SignificantBits, U: Copy + SignificantBits, V: Copy + SignificantBits, W: Copy + SignificantBits, X: Copy + SignificantBits, Y: Copy + SignificantBits, Z: Copy + SignificantBits, A: Copy + SignificantBits, >( x_name: &str, y_name: &str, z_name: &str, w_name: &str, v_name: &str, u_name: &str, t_name: &str, s_name: &str, ) -> Bucketer<'a, (T, U, V, W, X, Y, Z, A)> { Bucketer { bucketing_function: &|&(x, y, z, w, v, u, t, s)| { usize::exact_from(max!( x.significant_bits(), y.significant_bits(), z.significant_bits(), w.significant_bits(), v.significant_bits(), u.significant_bits(), t.significant_bits(), s.significant_bits() )) }, bucketing_label: format!( "max({x_name}.significant_bits(), {y_name}.significant_bits(), \ {z_name}.significant_bits(), {w_name}.significant_bits(), \ {v_name}.significant_bits(), {u_name}.significant_bits(), \ {t_name}.significant_bits(), {s_name}.significant_bits())", ), } } pub fn triple_1_2_max_bit_bucketer<'a, T: Copy + SignificantBits, U: Copy + SignificantBits, V>( x_name: &str, y_name: &str, ) -> Bucketer<'a, (T, U, V)> { Bucketer { bucketing_function: &|&(x, y, ref _z)| { usize::exact_from(max(x.significant_bits(), y.significant_bits())) }, bucketing_label: format!("max({x_name}.significant_bits(), {y_name}.significant_bits())"), } } pub fn triple_2_3_product_bit_bucketer< 'a, T, U: Copy + SignificantBits, V: Copy + SignificantBits, >( x_name: &str, y_name: &str, ) -> Bucketer<'a, (T, U, V)> { Bucketer { bucketing_function: &|&(_, y, z)| { usize::exact_from( y.significant_bits() .checked_mul(z.significant_bits()) .unwrap(), ) }, bucketing_label: format!("{x_name}.significant_bits() * {y_name}.significant_bits()"), } } pub fn pair_1_bucketer(x_name: &str) -> Bucketer<(T, U)> where usize: ExactFrom, { Bucketer { bucketing_function: &|&(x, _)| usize::exact_from(x), bucketing_label: x_name.to_string(), } } pub fn pair_2_bucketer(y_name: &str) -> Bucketer<(T, U)> where usize: ExactFrom, { Bucketer { bucketing_function: &|&(_, y)| usize::exact_from(y), bucketing_label: y_name.to_string(), } } pub fn pair_2_pair_2_bucketer(y_name: &str) -> Bucketer<(T, (U, V))> where usize: ExactFrom, { Bucketer { bucketing_function: &|&(_, (_, y))| usize::exact_from(y), bucketing_label: y_name.to_string(), } } pub fn pair_2_unsigned_abs_bucketer(y_name: &str) -> Bucketer<(T, U)> where usize: ExactFrom<::Output>, { Bucketer { bucketing_function: &|&(_, y)| usize::exact_from(y.unsigned_abs()), bucketing_label: y_name.to_string(), } } pub fn triple_2_bucketer(y_name: &str) -> Bucketer<(T, U, V)> where usize: ExactFrom, { Bucketer { bucketing_function: &|&(_, y, _)| usize::exact_from(y), bucketing_label: y_name.to_string(), } } pub fn triple_3_bucketer(z_name: &str) -> Bucketer<(T, U, V)> where usize: ExactFrom, { Bucketer { bucketing_function: &|&(_, _, z)| usize::exact_from(z), bucketing_label: z_name.to_string(), } } pub fn triple_2_unsigned_abs_bucketer( y_name: &str, ) -> Bucketer<(T, U, V)> where usize: ExactFrom<::Output>, { Bucketer { bucketing_function: &|&(_, y, _)| usize::exact_from(y.unsigned_abs()), bucketing_label: y_name.to_string(), } } pub fn pair_2_triple_2_bucketer(y_name: &str) -> Bucketer<(T, (U, V, W))> where usize: ExactFrom, { Bucketer { bucketing_function: &|&(_, (_, y, _))| usize::exact_from(y), bucketing_label: y_name.to_string(), } } pub fn triple_3_pair_2_bucketer(y_name: &str) -> Bucketer<(T, U, (V, W))> where usize: ExactFrom, { Bucketer { bucketing_function: &|&(_, _, (_, y))| usize::exact_from(y), bucketing_label: y_name.to_string(), } } pub fn pair_1_bit_bucketer(x_name: &str) -> Bucketer<(T, U)> { Bucketer { bucketing_function: &|&(x, _)| usize::exact_from(x.significant_bits()), bucketing_label: format!("{x_name}.significant_bits()"), } } pub fn pair_2_bit_bucketer(x_name: &str) -> Bucketer<(T, U)> { Bucketer { bucketing_function: &|&(_, x)| usize::exact_from(x.significant_bits()), bucketing_label: format!("{x_name}.significant_bits()"), } } pub fn triple_1_bit_bucketer(x_name: &str) -> Bucketer<(T, U, V)> { Bucketer { bucketing_function: &|&(x, _, _)| usize::exact_from(x.significant_bits()), bucketing_label: format!("{x_name}.significant_bits()"), } } pub fn triple_3_bit_bucketer(z_name: &str) -> Bucketer<(T, U, V)> { Bucketer { bucketing_function: &|&(_, _, z)| usize::exact_from(z.significant_bits()), bucketing_label: format!("{z_name}.significant_bits()"), } } pub fn quadruple_1_2_bit_bucketer( combined_name: &str, ) -> Bucketer<(T, T, U, V)> { Bucketer { bucketing_function: &|&(x_1, x_0, _, _)| { usize::exact_from(if x_1 == T::ZERO { x_0.significant_bits() } else { x_1.significant_bits() + T::WIDTH }) }, bucketing_label: format!("{combined_name}.significant_bits()"), } } pub fn quadruple_3_bucketer(z_name: &str) -> Bucketer<(T, U, V, W)> where usize: ExactFrom, { Bucketer { bucketing_function: &|&(_, _, z, _)| usize::exact_from(z), bucketing_label: z_name.to_string(), } } pub fn pair_primitive_int_bit_u64_max_bucketer<'a, T: PrimitiveInt>( x_name: &'a str, y_name: &'a str, ) -> Bucketer<'a, (T, u64)> { Bucketer { bucketing_function: &|(x, y)| usize::exact_from(max(x.significant_bits(), *y)), bucketing_label: format!("max({x_name}.significant_bits(), {y_name})"), } } pub fn triple_1_2_primitive_int_bit_u64_max_bucketer<'a, T: PrimitiveInt, U>( x_name: &'a str, y_name: &'a str, ) -> Bucketer<'a, (T, u64, U)> { Bucketer { bucketing_function: &|(x, y, _)| usize::exact_from(max(x.significant_bits(), *y)), bucketing_label: format!("max({x_name}.significant_bits(), {y_name})"), } } pub fn pair_primitive_int_bit_i64_max_bucketer<'a, T: PrimitiveInt>( x_name: &'a str, y_name: &'a str, ) -> Bucketer<'a, (T, i64)> { Bucketer { bucketing_function: &|(x, y)| { usize::exact_from(max(x.significant_bits(), y.unsigned_abs())) }, bucketing_label: format!("max({x_name}.significant_bits(), {y_name}.unsigned_abs())"), } } pub fn triple_primitive_int_bit_i64_u64_max_bucketer<'a, T: PrimitiveInt>( x_name: &'a str, y_name: &'a str, z_name: &'a str, ) -> Bucketer<'a, (T, i64, u64)> { Bucketer { bucketing_function: &|(x, y, z)| { usize::exact_from(max!(x.significant_bits(), y.unsigned_abs(), *z)) }, bucketing_label: format!( "max({x_name}.significant_bits(), {y_name}.unsigned_abs(), {z_name})" ), } } pub fn quadruple_1_2_3_primitive_int_bit_i64_u64_max_bucketer<'a, T: PrimitiveInt, U>( x_name: &'a str, y_name: &'a str, z_name: &'a str, ) -> Bucketer<'a, (T, i64, u64, U)> { Bucketer { bucketing_function: &|(x, y, z, _)| { usize::exact_from(max!(x.significant_bits(), y.unsigned_abs(), *z)) }, bucketing_label: format!( "max({x_name}.significant_bits(), {y_name}.unsigned_abs(), {z_name})" ), } } pub fn pair_1_vec_len_bucketer(xs_name: &str) -> Bucketer<(Vec, U)> { Bucketer { bucketing_function: &|(ref xs, _)| xs.len(), bucketing_label: format!("{xs_name}.len()"), } } pub fn pair_1_vec_len_sub_1_bucketer(xs_name: &str) -> Bucketer<(Vec, U)> { Bucketer { bucketing_function: &|(ref xs, _)| xs.len() - 1, bucketing_label: format!("{xs_name}.len() - 1"), } } pub fn pair_2_vec_len_bucketer(ys_name: &str) -> Bucketer<(T, Vec)> { Bucketer { bucketing_function: &|(_, ref ys)| ys.len(), bucketing_label: format!("{ys_name}.len()"), } } pub fn triple_1_vec_len_bucketer(xs_name: &str) -> Bucketer<(Vec, U, V)> { Bucketer { bucketing_function: &|(ref xs, _, _)| xs.len(), bucketing_label: format!("{xs_name}.len()"), } } pub fn triple_3_vec_len_bucketer(xs_name: &str) -> Bucketer<(T, U, Vec)> { Bucketer { bucketing_function: &|(_, _, ref xs)| xs.len(), bucketing_label: format!("{xs_name}.len()"), } } pub fn triple_2_vec_len_bucketer(xs_name: &str) -> Bucketer<(T, Vec, V)> { Bucketer { bucketing_function: &|(_, ref xs, _)| xs.len(), bucketing_label: format!("{xs_name}.len()"), } } pub fn triple_vec_max_len_bucketer<'a, T, U, V>( xs_name: &str, ys_name: &str, zs_name: &str, ) -> Bucketer<'a, (Vec, Vec, Vec)> { Bucketer { bucketing_function: &|(xs, ys, zs)| max!(xs.len(), ys.len(), zs.len()), bucketing_label: format!("max({xs_name}.len(), {ys_name}.len(), {zs_name}.len())"), } } pub fn triple_1_2_vec_max_len_bucketer<'a, T, U, V>( xs_name: &str, ys_name: &str, ) -> Bucketer<'a, (Vec, Vec, V)> { Bucketer { bucketing_function: &|(xs, ys, _)| max(xs.len(), ys.len()), bucketing_label: format!("max({xs_name}.len(), {ys_name}.len())"), } } pub fn triple_2_3_vec_max_len_bucketer<'a, T, U, V>( ys_name: &str, zs_name: &str, ) -> Bucketer<'a, (T, Vec, Vec)> { Bucketer { bucketing_function: &|(_, xs, ys)| max(xs.len(), ys.len()), bucketing_label: format!("max({ys_name}.len(), {zs_name}.len())"), } } pub fn triple_1_2_vec_min_len_bucketer<'a, T, U, V>( ys_name: &str, zs_name: &str, ) -> Bucketer<'a, (Vec, Vec, V)> { Bucketer { bucketing_function: &|(xs, ys, _)| min(xs.len(), ys.len()), bucketing_label: format!("min({ys_name}.len(), {zs_name}.len())"), } } pub fn triple_2_3_vec_min_len_bucketer<'a, T, U, V>( ys_name: &str, zs_name: &str, ) -> Bucketer<'a, (T, Vec, Vec)> { Bucketer { bucketing_function: &|(_, xs, ys)| min(xs.len(), ys.len()), bucketing_label: format!("min({ys_name}.len(), {zs_name}.len())"), } } pub fn quadruple_2_vec_len_bucketer(xs_name: &str) -> Bucketer<(T, Vec, V, W)> { Bucketer { bucketing_function: &|(_, ref xs, _, _)| xs.len(), bucketing_label: format!("{xs_name}.len()"), } } pub fn quadruple_3_vec_len_bucketer(xs_name: &str) -> Bucketer<(T, U, Vec, W)> { Bucketer { bucketing_function: &|(_, _, ref xs, _)| xs.len(), bucketing_label: format!("{xs_name}.len()"), } } pub fn quadruple_4_vec_len_bucketer(xs_name: &str) -> Bucketer<(T, U, V, Vec)> { Bucketer { bucketing_function: &|(_, _, _, ref xs)| xs.len(), bucketing_label: format!("{xs_name}.len()"), } } pub fn quadruple_1_3_vec_max_len_bucketer<'a, T, U, V, W>( xs_name: &str, ys_name: &str, ) -> Bucketer<'a, (T, Vec, V, Vec)> { Bucketer { bucketing_function: &|(_, xs, _, ys)| max(xs.len(), ys.len()), bucketing_label: format!("max({xs_name}.len(), {ys_name}.len())"), } } pub fn quintuple_1_vec_len_bucketer( xs_name: &str, ) -> Bucketer<(Vec, U, V, W, X)> { Bucketer { bucketing_function: &|(ref xs, _, _, _, _)| xs.len(), bucketing_label: format!("{xs_name}.len()"), } } pub fn pair_sum_vec_len_bucketer<'a, T, U>( xs_name: &str, ys_name: &str, ) -> Bucketer<'a, (Vec, Vec)> { Bucketer { bucketing_function: &|(xs, ys)| xs.len() + ys.len(), bucketing_label: format!("{xs_name}.len() + {ys_name}.len()"), } } pub fn triple_2_3_sum_vec_len_bucketer<'a, T, U, V>( xs_name: &str, ys_name: &str, ) -> Bucketer<'a, (T, Vec, Vec)> { Bucketer { bucketing_function: &|(_, xs, ys)| xs.len() + ys.len(), bucketing_label: format!("{xs_name}.len() + {ys_name}.len()"), } } pub fn triple_2_3_diff_vec_len_bucketer<'a, T, U, V>( xs_name: &str, ys_name: &str, ) -> Bucketer<'a, (T, Vec, Vec)> { Bucketer { bucketing_function: &|(_, xs, ys)| xs.len() - ys.len(), bucketing_label: format!("{xs_name}.len() - {ys_name}.len()"), } } pub fn quadruple_2_3_diff_vec_len_bucketer<'a, T, U, V, W>( xs_name: &str, ys_name: &str, ) -> Bucketer<'a, (T, Vec, Vec, W)> { Bucketer { bucketing_function: &|(_, xs, ys, _)| xs.len() - ys.len(), bucketing_label: format!("{xs_name}.len() - {ys_name}.len()"), } } pub fn get_bits_bucketer() -> Bucketer<'static, (T, u64, u64)> { Bucketer { bucketing_function: &|&(_, start, end)| usize::exact_from(end - start), bucketing_label: "end - start".to_string(), } } pub fn assign_bits_bucketer() -> Bucketer<'static, (T, u64, u64, U)> { Bucketer { bucketing_function: &|&(_, start, end, _)| usize::exact_from(end - start), bucketing_label: "end - start".to_string(), } } pub fn pair_1_vec_len_times_pair_2_bits_bucketer<'a, T, U: PrimitiveUnsigned>( xs_name: &'a str, y_name: &'a str, ) -> Bucketer<'a, (Vec, U)> { Bucketer { bucketing_function: &|(ref xs, ref y)| { xs.len() .checked_mul(usize::exact_from(y.significant_bits())) .unwrap() }, bucketing_label: format!("{xs_name}.len() * {y_name}.significant_bits()"), } } pub fn pair_product_vec_len_bucketer<'a, T, U>( xs_name: &str, ys_name: &str, ) -> Bucketer<'a, (Vec, Vec)> { Bucketer { bucketing_function: &|(xs, ys)| xs.len().checked_mul(ys.len()).unwrap(), bucketing_label: format!("{xs_name}.len() * {ys_name}.len()"), } } pub fn triple_1_2_product_vec_len_bucketer<'a, T, U, V>( xs_name: &str, ys_name: &str, ) -> Bucketer<'a, (Vec, Vec, V)> { Bucketer { bucketing_function: &|(xs, ys, _)| xs.len().checked_mul(ys.len()).unwrap(), bucketing_label: format!("{xs_name}.len() * {ys_name}.len()"), } } pub fn triple_2_bits_times_triple_3_bucketer<'a, T, U, V: Copy>( x_name: &'a str, y_name: &'a str, ) -> Bucketer<'a, (T, U, V)> where usize: ExactFrom, for<'b> &'b U: SignificantBits, { Bucketer { bucketing_function: &|(_, ref x, y)| { let x_bits: usize = ExactFrom::::exact_from(x.significant_bits()); x_bits.checked_mul(ExactFrom::::exact_from(*y)).unwrap() }, bucketing_label: format!("{x_name}.significant_bits() * {y_name}"), } } pub fn pair_1_vec_len_times_pair_2_bucketer<'a, T, U: Copy>( xs_name: &'a str, y_name: &'a str, ) -> Bucketer<'a, (Vec, U)> where usize: ExactFrom, { Bucketer { bucketing_function: &|(ref xs, y)| xs.len().checked_mul(usize::exact_from(*y)).unwrap(), bucketing_label: format!("{xs_name}.len() * {y_name}"), } } pub fn pair_1_bits_times_pair_2_bucketer<'a, T, U: Copy>( x_name: &'a str, y_name: &'a str, ) -> Bucketer<'a, (T, U)> where usize: ExactFrom, for<'b> &'b T: SignificantBits, { Bucketer { bucketing_function: &|(ref x, y)| { let x_bits: usize = ExactFrom::::exact_from(x.significant_bits()); x_bits.checked_mul(ExactFrom::::exact_from(*y)).unwrap() }, bucketing_label: format!("{x_name}.significant_bits() * {y_name}"), } } pub fn triple_3_pair_1_bits_times_pair_2_bucketer<'a, T, U, V, W: Copy>( x_name: &'a str, y_name: &'a str, ) -> Bucketer<'a, (T, U, (V, W))> where usize: ExactFrom, for<'b> &'b V: SignificantBits, { Bucketer { bucketing_function: &|(_, _, (ref x, y))| { let x_bits: usize = ExactFrom::::exact_from(x.significant_bits()); x_bits.checked_mul(ExactFrom::::exact_from(*y)).unwrap() }, bucketing_label: format!("{x_name}.significant_bits() * {y_name}"), } } pub fn rational_sequence_len_bucketer<'a, T: Eq>( xs_name: &str, ) -> Bucketer<'a, RationalSequence> { Bucketer { bucketing_function: &RationalSequence::component_len, bucketing_label: format!("{xs_name}.component_len()"), } } pub fn pair_rational_sequence_max_len_bucketer<'a, T: Eq, U: Eq>( xs_name: &str, ys_name: &str, ) -> Bucketer<'a, (RationalSequence, RationalSequence)> { Bucketer { bucketing_function: &|(xs, ys)| max(xs.component_len(), ys.component_len()), bucketing_label: format!("max({xs_name}.component_len(), {ys_name}.component_len())"), } } pub fn pair_1_rational_sequence_len_bucketer<'a, T: Eq, U>( xs_name: &str, ) -> Bucketer<'a, (RationalSequence, U)> { Bucketer { bucketing_function: &|(xs, _)| xs.component_len(), bucketing_label: format!("{xs_name}.component_len()"), } } pub fn quadruple_1_rational_sequence_len_bucketer<'a, T: Eq, U, V, W>( xs_name: &str, ) -> Bucketer<'a, (RationalSequence, U, V, W)> { Bucketer { bucketing_function: &|(xs, _, _, _)| xs.component_len(), bucketing_label: format!("{xs_name}.component_len()"), } } malachite-base-0.4.16/src/test_util/bench/mod.rs000064400000000000000000000176711046102023000175760ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::Parity; use crate::num::conversion::traits::ExactFrom; use crate::test_util::bench::bucketers::Bucketer; use gnuplot::{AxesCommon, Caption, Color, Figure}; use itertools::Itertools; use std::collections::{BTreeMap, HashMap}; use std::iter::Iterator; use std::time::Instant; fn escape_label_string(s: &str) -> String { let mut escaped = String::new(); for c in s.chars() { if c == '_' { escaped.push_str("\\_"); } else if c == '&' { escaped.push_str("\\&"); } else { escaped.push(c); } } escaped } struct BenchmarkSeriesOptions<'a, T: 'a> { pub name: &'a str, pub function: &'a mut dyn FnMut(T), pub color: &'a str, } struct BenchmarkOptions<'a, I: Iterator> where I::Item: 'a, { pub generator: I, pub title: &'a str, pub limit: usize, pub bucketing_function: &'a dyn Fn(&I::Item) -> usize, pub x_axis_label: &'a str, pub y_axis_label: &'a str, pub file_name: String, pub series_options: Vec>, } fn quick_median(xs: &mut [u64]) -> u64 { assert!(!xs.is_empty()); xs.sort_unstable(); let half_index = xs.len() >> 1; if xs.len().odd() { xs[half_index] } else { (xs[half_index - 1] + xs[half_index]) >> 1 } } fn quick_mean(xs: &[u64]) -> u64 { assert!(!xs.is_empty()); let sum: u64 = xs.iter().sum(); sum / u64::exact_from(xs.len()) } fn run_benchmark_internal(mut options: BenchmarkOptions) where I::Item: Clone, { let reps = 5; let min_bucket_size = 2; let mut durations_maps = Vec::new(); for _ in 0..options.series_options.len() { durations_maps.push(HashMap::new()); } for x in options.generator.take(options.limit) { let size = (options.bucketing_function)(&x); for (i, series) in options.series_options.iter_mut().enumerate() { let mut durations_vec = Vec::new(); for _ in 0..reps { let x = x.clone(); let now = Instant::now(); (series.function)(x); durations_vec.push(u64::exact_from(now.elapsed().as_nanos())); } let median_duration = quick_median(&mut durations_vec); durations_maps[i] .entry(size) .or_insert_with(Vec::new) .push(median_duration); } } let mut median_durations_maps = Vec::new(); for durations_map in durations_maps { let mut median_durations_map: BTreeMap = BTreeMap::new(); for (&size, durations) in &durations_map { if durations.len() >= min_bucket_size { median_durations_map.insert(size, quick_mean(durations)); } } median_durations_maps.push(median_durations_map); } let mut fg = Figure::new(); { let axes = fg.axes2d(); axes.set_title(&escape_label_string(options.title), &[]); axes.set_x_label(&escape_label_string(options.x_axis_label), &[]); axes.set_y_label(&escape_label_string(options.y_axis_label), &[]); for (median_durations_map, options) in median_durations_maps .iter() .zip(options.series_options.iter()) { let sizes = median_durations_map .iter() .map(|entry| *entry.0) .collect_vec(); let durations = median_durations_map .iter() .map(|entry| *entry.1) .collect_vec(); axes.lines( &sizes, &durations, &[Caption(&escape_label_string(options.name)), Color(options.color)], ); } } fg.echo_to_file(&options.file_name); } #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] pub enum BenchmarkType { Single, LibraryComparison, EvaluationStrategy, Algorithms, } #[allow(clippy::print_stdout, clippy::type_complexity)] pub fn run_benchmark<'a, I: Iterator>( title: &'a str, benchmark_type: BenchmarkType, generator: I, generation_mode_name: &'a str, limit: usize, file_name: &'a str, bucketer: &Bucketer<'a, I::Item>, series: &mut [(&'a str, &'a mut dyn FnMut(I::Item))], ) where I::Item: Clone, { assert_eq!( benchmark_type == BenchmarkType::Single, series.len() == 1, "Bad benchmark: {title}. \ Benchmarks should have type Single iff they have only one series.", ); if limit == 0 { return; } let title = match benchmark_type { BenchmarkType::Single => title.to_string(), BenchmarkType::LibraryComparison => format!("{title} library comparison"), BenchmarkType::EvaluationStrategy => format!("{title} evaluation strategy"), BenchmarkType::Algorithms => format!("{title} algorithms"), }; println!("benchmarking {generation_mode_name} {title}"); let colors = ["green", "blue", "red", "black", "orange", "yellow", "gray", "purple"]; assert!(series.len() <= colors.len(), "not enough available colors"); let mut series_options = Vec::new(); for (&mut (label, ref mut function), color) in series.iter_mut().zip(colors.iter()) { series_options.push(BenchmarkSeriesOptions { name: label, function, color, }); } let options = BenchmarkOptions { generator, title: &title, limit, bucketing_function: bucketer.bucketing_function, x_axis_label: &bucketer.bucketing_label, y_axis_label: "time (ns)", file_name: file_name.to_string(), series_options, }; run_benchmark_internal(options); } #[allow(clippy::print_stdout, clippy::type_complexity)] pub fn run_benchmark_old<'a, I: Iterator>( title: &'a str, benchmark_type: BenchmarkType, generator: I, generation_mode_name: &'a str, limit: usize, file_name: &'a str, bucketing_function: &'a dyn Fn(&I::Item) -> usize, bucketing_label: &'a str, series: &mut [(&'a str, &'a mut dyn FnMut(I::Item))], ) where I::Item: Clone, { assert_eq!( benchmark_type == BenchmarkType::Single, series.len() == 1, "Bad benchmark: {title}. \ Benchmarks should have type Single iff they have only one series.", ); if limit == 0 { return; } let title = match benchmark_type { BenchmarkType::Single => title.to_string(), BenchmarkType::LibraryComparison => format!("{title} library comparison"), BenchmarkType::EvaluationStrategy => format!("{title} evaluation strategy"), BenchmarkType::Algorithms => format!("{title} algorithms"), }; println!("benchmarking {generation_mode_name} {title}"); let colors = ["green", "blue", "red", "black", "orange", "yellow", "gray", "purple"]; assert!(series.len() <= colors.len(), "not enough available colors"); let mut series_options = Vec::new(); for (&mut (label, ref mut function), color) in series.iter_mut().zip(colors.iter()) { series_options.push(BenchmarkSeriesOptions { name: label, function, color, }); } let options = BenchmarkOptions { generator, title: &title, limit, bucketing_function, x_axis_label: bucketing_label, y_axis_label: "time (ns)", file_name: format!("benchmarks/{file_name}"), series_options, }; run_benchmark_internal(options); } #[macro_export] macro_rules! no_out { ($e:expr) => {{ $e; }}; } pub mod bucketers; malachite-base-0.4.16/src/test_util/common/mod.rs000064400000000000000000000061301046102023000177730ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use std::cmp::Ordering; use std::fmt::Debug; use std::str::FromStr; #[macro_export] macro_rules! assert_panic { ($e: expr) => { let result = catch_unwind(|| $e); assert!(result.is_err()); }; } fn read_strings(strings: &[&str]) -> Vec where T::Err: Debug, { strings.iter().map(|s| s.parse().unwrap()).collect() } fn test_helper_helper< T: Debug + FromStr, U: Debug + Eq, F: FnMut(usize, usize) -> U, G: FnMut(&T, &T) -> U, >( strings: &[&str], mut compare_indices: F, mut compare_elements: G, ) where T::Err: Debug, { let xs = read_strings::(strings); let ys = read_strings::(strings); for (i, x) in xs.iter().enumerate() { for (j, y) in ys.iter().enumerate() { assert_eq!(compare_indices(i, j), compare_elements(x, y)); } } } pub fn test_eq_helper(strings: &[&str]) where T::Err: Debug, { test_helper_helper(strings, |i, j| i == j, |x: &T, y: &T| x == y); } pub fn test_cmp_helper(strings: &[&str]) where T::Err: Debug, { test_helper_helper::(strings, |i, j| i.cmp(&j), Ord::cmp); } pub fn test_custom_cmp_helper Ordering>( strings: &[&str], compare: F, ) where T::Err: Debug, { test_helper_helper(strings, |i, j| i.cmp(&j), compare); } #[macro_export] macro_rules! triple_significant_bits_fn { ($t:ident, $bucketing_function:ident) => { fn $bucketing_function(t: &($t, $t, $t)) -> usize { usize::exact_from(max!( t.0.significant_bits(), t.1.significant_bits(), t.2.significant_bits() )) } }; } pub const TRIPLE_SIGNIFICANT_BITS_LABEL: &str = "max(a.significant_bits(), b.significant_bits(), c.significant_bits())"; pub fn rle_decode(ps: &[(T, usize)]) -> Vec { let mut out = Vec::new(); for (x, count) in ps { for _ in 0..*count { out.push(x.clone()); } } out } pub fn test_double_ended_iterator_size_hint( mut xs: I, original_expected_size: usize, ) { let original_xs = xs.clone(); let mut expected_size = original_expected_size; for _ in 0..10 { assert_eq!(xs.size_hint(), (expected_size, Some(expected_size))); if xs.next().is_none() { break; }; expected_size -= 1; } let mut xs = original_xs; let mut expected_size = original_expected_size; for _ in 0..10 { assert_eq!(xs.size_hint(), (expected_size, Some(expected_size))); if xs.next_back().is_none() { break; }; expected_size -= 1; } } malachite-base-0.4.16/src/test_util/extra_variadic/mod.rs000064400000000000000000000253511046102023000214760ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::iterators::bit_distributor::{BitDistributor, BitDistributorOutputType}; use crate::iterators::iterator_cache::IteratorCache; use crate::num::arithmetic::traits::CheckedPow; use crate::num::conversion::traits::{ExactFrom, WrappingFrom}; use crate::num::logic::traits::SignificantBits; use crate::num::random::{random_unsigned_range, RandomUnsignedRange}; use crate::random::Seed; use crate::tuples::exhaustive::clone_helper; use crate::tuples::random::next_helper; use crate::unions::UnionFromStrError; use crate::{ custom_tuples, exhaustive_tuples_1_input, exhaustive_unions, lex_custom_tuples, lex_tuples, random_custom_tuples, random_tuples, random_unions, union_struct, }; use std::cmp::max; use std::fmt::{self, Display, Formatter}; use std::marker::PhantomData; use std::str::FromStr; fn unwrap_triple((a, b, c): (Option, Option, Option)) -> (X, Y, Z) { (a.unwrap(), b.unwrap(), c.unwrap()) } #[allow(clippy::missing_const_for_fn)] fn unwrap_quadruple( (a, b, c, d): (Option, Option, Option, Option), ) -> (X, Y, Z, W) { (a.unwrap(), b.unwrap(), c.unwrap(), d.unwrap()) } lex_tuples!( (pub(crate)), 3, LexTriples, LexTriplesFromSingle, lex_triples, lex_triples_from_single, (T, T, T), [0, X, I, xs, x], [1, Y, J, ys, y], [2, Z, K, zs, z] ); lex_custom_tuples!( (pub(crate)), LexTriplesXYY, (X, Y, Y), (None, None, None), unwrap_triple, lex_triples_xyy, [X, I, xs, [0, x_0]], [Y, J, ys, [1, y_1], [2, y_2]] ); exhaustive_tuples_1_input!( (pub(crate)), ExhaustiveTriples1Input, exhaustive_triples_1_input, exhaustive_triples_from_single, (I::Item, I::Item, I::Item), [0, output_type_x], [1, output_type_y], [2, output_type_z] ); exhaustive_tuples_1_input!( (pub(crate)), ExhaustiveQuadruples1Input, exhaustive_quadruples_1_input, exhaustive_quadruples_from_single, (I::Item, I::Item, I::Item, I::Item), [0, output_type_x], [1, output_type_y], [2, output_type_z], [3, output_type_w] ); exhaustive_tuples_1_input!( (pub(crate)), ExhaustiveSextuples1Input, exhaustive_sextuples_1_input, exhaustive_sextuples_from_single, (I::Item, I::Item, I::Item, I::Item, I::Item, I::Item), [0, output_type_x], [1, output_type_y], [2, output_type_z], [3, output_type_w], [4, output_type_v], [5, output_type_u] ); exhaustive_tuples_1_input!( (pub(crate)), ExhaustiveOctuples1Input, exhaustive_octuples_1_input, exhaustive_octuples_from_single, ( I::Item, I::Item, I::Item, I::Item, I::Item, I::Item, I::Item, I::Item ), [0, output_type_x], [1, output_type_y], [2, output_type_z], [3, output_type_w], [4, output_type_v], [5, output_type_u], [6, output_type_t], [7, output_type_s] ); exhaustive_tuples_1_input!( (pub(crate)), ExhaustiveDuodecuples1Input, exhaustive_duodecuples_1_input, exhaustive_duodecuples_from_single, ( I::Item, I::Item, I::Item, I::Item, I::Item, I::Item, I::Item, I::Item, I::Item, I::Item, I::Item, I::Item ), [0, output_type_x], [1, output_type_y], [2, output_type_z], [3, output_type_w], [4, output_type_v], [5, output_type_u], [6, output_type_t], [7, output_type_s], [8, output_type_r], [9, output_type_q], [10, output_type_p], [11, output_type_o] ); custom_tuples!( (pub(crate)), ExhaustiveTriplesXXY, (X, X, Y), (None, None, None), unwrap_triple, exhaustive_triples_xxy, exhaustive_triples_xxy_custom_output, [X, I, xs, xs_done, [0, output_type_xs_0], [1, output_type_xs_1]], [Y, J, ys, ys_done, [2, output_type_ys_2]] ); custom_tuples!( (pub(crate)), ExhaustiveTriplesXYX, (X, Y, X), (None, None, None), unwrap_triple, exhaustive_triples_xyx, exhaustive_triples_xyx_custom_output, [X, I, xs, xs_done, [0, output_type_xs_0], [2, output_type_ys_1]], [Y, J, ys, ys_done, [1, output_type_xs_2]] ); custom_tuples!( (pub(crate)), ExhaustiveQuadruplesXXXY, (X, X, X, Y), (None, None, None, None), unwrap_quadruple, exhaustive_quadruples_xxxy, exhaustive_quadruples_xxxy_custom_output, [X, I, xs, xs_done, [0, output_type_xs_0], [1, output_type_xs_1], [2, output_type_xs_2]], [Y, J, ys, ys_done, [3, output_type_ys_3]] ); custom_tuples!( (pub(crate)), ExhaustiveQuadruplesXXYX, (X, X, Y, X), (None, None, None, None), unwrap_quadruple, exhaustive_quadruples_xxyx, exhaustive_quadruples_xxyx_custom_output, [X, I, xs, xs_done, [0, output_type_xs_0], [1, output_type_xs_1], [3, output_type_xs_3]], [Y, J, ys, ys_done, [2, output_type_ys_2]] ); custom_tuples!( (pub(crate)), ExhaustiveQuadruplesXYYX, (X, Y, Y, X), (None, None, None, None), unwrap_quadruple, exhaustive_quadruples_xyyx, exhaustive_quadruples_xyyx_custom_output, [X, I, xs, xs_done, [0, output_type_xs_0], [3, output_type_xs_3]], [Y, J, ys, ys_done, [1, output_type_ys_1], [2, output_type_ys_2]] ); custom_tuples!( (pub(crate)), ExhaustiveQuadruplesXYYZ, (X, Y, Y, Z), (None, None, None, None), unwrap_quadruple, exhaustive_quadruples_xyyz, exhaustive_quadruples_xyyz_custom_output, [X, I, xs, xs_done, [0, output_type_xs_0]], [Y, J, ys, ys_done, [1, output_type_ys_1], [2, output_type_ys_2]], [Z, K, zs, zs_done, [3, output_type_zs_3]] ); custom_tuples!( (pub(crate)), ExhaustiveQuadruplesXYZZ, (X, Y, Z, Z), (None, None, None, None), unwrap_quadruple, exhaustive_quadruples_xyzz, exhaustive_quadruples_xyzz_custom_output, [X, I, xs, xs_done, [0, output_type_xs_0]], [Y, J, ys, ys_done, [1, output_type_ys_1]], [Z, K, zs, zs_done, [2, output_type_zs_2], [3, output_type_zs_3]] ); random_tuples!( (pub(crate)), RandomTriples, RandomTriplesFromSingle, random_triples, random_triples_from_single, (I::Item, I::Item, I::Item), [0, X, I, xs, xs_gen], [1, Y, J, ys, ys_gen], [2, Z, K, zs, zs_gen] ); random_tuples!( (pub(crate)), RandomQuadruples, RandomQuadruplesFromSingle, random_quadruples, random_quadruples_from_single, (I::Item, I::Item, I::Item, I::Item), [0, X, I, xs, xs_gen], [1, Y, J, ys, ys_gen], [2, Z, K, zs, zs_gen], [3, W, L, ws, ws_gen] ); random_tuples!( (pub(crate)), RandomSextuples, RandomSextuplesFromSingle, random_sextuples, random_sextuples_from_single, (I::Item, I::Item, I::Item, I::Item, I::Item, I::Item), [0, X, I, xs, xs_gen], [1, Y, J, ys, ys_gen], [2, Z, K, zs, zs_gen], [3, W, L, ws, ws_gen], [4, V, M, vs, vs_gen], [5, U, N, us, us_gen] ); random_tuples!( (pub(crate)), RandomOctuples, RandomOctuplesFromSingle, random_octuples, random_octuples_from_single, ( I::Item, I::Item, I::Item, I::Item, I::Item, I::Item, I::Item, I::Item ), [0, X, I, xs, xs_gen], [1, Y, J, ys, ys_gen], [2, Z, K, zs, zs_gen], [3, W, L, ws, ws_gen], [4, V, M, vs, vs_gen], [5, U, N, us, us_gen], [6, T, O, ts, ts_gen], [7, S, P, ss, ss_gen] ); random_tuples!( (pub(crate)), RandomDuodecuples, RandomDuodecuplesFromSingle, random_duodecuples, random_duodecuples_from_single, ( I::Item, I::Item, I::Item, I::Item, I::Item, I::Item, I::Item, I::Item, I::Item, I::Item, I::Item, I::Item ), [0, X, I, xs, xs_gen], [1, Y, J, ys, ys_gen], [2, Z, K, zs, zs_gen], [3, W, L, ws, ws_gen], [4, V, M, vs, vs_gen], [5, U, N, us, us_gen], [6, T, OI, ts, ts_gen], [7, S, PI, ss, ss_gen], [8, R, QI, rs, rs_gen], [9, Q, RI, qs, qs_gen], [10, P, SI, ps, ps_gen], [11, O, TI, os, os_gen] ); random_custom_tuples!( (pub(crate)), RandomTriplesXXY, (X, X, Y), random_triples_xxy, [X, I, xs, xs_gen, [x_0, x_0], [x_1, x_1]], [Y, J, ys, ys_gen, [y_2, y_2]] ); random_custom_tuples!( (pub(crate)), RandomTriplesXYX, (X, Y, X), random_triples_xyx, [X, I, xs, xs_gen, [x_0, x_0], [x_2, y_1]], [Y, J, ys, ys_gen, [y_1, x_2]] ); random_custom_tuples!( (pub(crate)), RandomTriplesXYY, (X, Y, Y), random_triples_xyy, [X, I, xs, xs_gen, [x_0, x_0]], [Y, J, ys, ys_gen, [y_1, y_1], [y_2, y_2]] ); random_custom_tuples!( (pub(crate)), RandomQuadruplesXXXY, (X, X, X, Y), random_quadruples_xxxy, [X, I, xs, xs_gen, [x_0, x_0], [x_1, x_1], [x_2, x_2]], [Y, J, ys, ys_gen, [y_3, y_3]] ); random_custom_tuples!( (pub(crate)), RandomQuadruplesXXYX, (X, X, Y, X), random_quadruples_xxyx, [X, I, xs, xs_gen, [x_0, x_0], [x_1, x_1], [x_3, y_2]], [Y, J, ys, ys_gen, [y_2, x_3]] ); random_custom_tuples!( (pub(crate)), RandomQuadruplesXYYX, (X, Y, Y, X), random_quadruples_xyyx, [X, I, xs, xs_gen, [x_0, x_0], [x_3, y_1]], [Y, J, ys, ys_gen, [y_1, y_2], [y_2, x_3]] ); random_custom_tuples!( (pub(crate)), RandomQuadruplesXYXY, (X, Y, X, Y), random_quadruples_xyxy, [X, I, xs, xs_gen, [x_0, x_0], [x_2, y_1]], [Y, J, ys, ys_gen, [y_1, x_2], [y_3, y_3]] ); random_custom_tuples!( (pub(crate)), RandomQuadruplesXYYZ, (X, Y, Y, Z), random_quadruples_xyyz, [X, I, xs, xs_gen, [x_0, x_0]], [Y, J, ys, ys_gen, [y_1, y_1], [y_2, y_2]], [Z, K, zs, zs_gen, [z_3, z_3]] ); random_custom_tuples!( (pub(crate)), RandomQuadruplesXYZZ, (X, Y, Z, Z), random_quadruples_xyzz, [X, I, xs, xs_gen, [x_0, x_0]], [Y, J, ys, ys_gen, [y_1, y_1]], [Z, K, zs, zs_gen, [z_2, z_2], [z_3, z_3]] ); exhaustive_unions!( (pub(crate)), Union3, LexUnion3s, ExhaustiveUnion3s, lex_union3s, exhaustive_union3s, 3, [0, X, I, A, xs, xs_done], [1, Y, J, B, ys, ys_done], [2, Z, K, C, zs, zs_done] ); union_struct!( (pub(crate)), Union3, Union3, [A, A, 'A', a], [B, B, 'B', b], [C, C, 'C', c] ); random_unions!( (pub(crate)), Union3, RandomUnion3s, random_union3s, 3, [0, X, I, A, xs, xs_gen], [1, Y, J, B, ys, ys_gen], [2, Z, K, C, zs, zs_gen] ); malachite-base-0.4.16/src/test_util/generators/common.rs000064400000000000000000000151711046102023000213720ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use std::collections::HashMap; use std::marker::PhantomData; pub const TINY_LIMIT: usize = 1000; pub const SMALL_LIMIT: usize = 1000; pub const LARGE_LIMIT: usize = 10000; #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)] pub enum GenMode { Exhaustive, Random, SpecialRandom, } impl GenMode { pub const fn name(self) -> &'static str { match self { GenMode::Exhaustive => "exhaustive", GenMode::Random => "random", GenMode::SpecialRandom => "special_random", } } } pub type It = Box>; #[derive(Clone, Debug)] pub struct GenConfig(HashMap); impl GenConfig { pub fn new() -> GenConfig { GenConfig(HashMap::new()) } pub fn insert(&mut self, key: &str, value: u64) { self.0.insert(key.to_string(), value); } pub fn get_or(&self, key: &'static str, default: u64) -> u64 { *self.0.get(key).unwrap_or(&default) } } impl Default for GenConfig { fn default() -> GenConfig { GenConfig::new() } } pub struct Generator { phantom: PhantomData<*const T>, exhaustive: &'static dyn Fn() -> It, random: &'static dyn Fn(&GenConfig) -> It, special_random: Option<&'static dyn Fn(&GenConfig) -> It>, } impl Generator { pub fn new( exhaustive: &'static dyn Fn() -> It, random: &'static dyn Fn(&GenConfig) -> It, special_random: &'static dyn Fn(&GenConfig) -> It, ) -> Generator { Generator { phantom: PhantomData, exhaustive, random, special_random: Some(special_random), } } pub fn new_no_special( exhaustive: &'static dyn Fn() -> It, random: &'static dyn Fn(&GenConfig) -> It, ) -> Generator { Generator { phantom: PhantomData, exhaustive, random, special_random: None, } } fn test_properties_with_config_with_limit_and_optional_exhaustive_limit( &self, config: &GenConfig, mut test: F, limit: usize, exhaustive_limit: bool, ) { if exhaustive_limit { for x in (self.exhaustive)().take(limit) { test(x); } } else { for x in (self.exhaustive)() { test(x); } } for x in (self.random)(config).take(limit) { test(x); } if let Some(special_random) = self.special_random { for x in special_random(config).take(limit) { test(x); } } } pub fn test_properties_with_limit(&self, limit: usize, test: F) { self.test_properties_with_config_with_limit_and_optional_exhaustive_limit( &GenConfig::new(), test, limit, true, ); } fn test_properties_with_config_optional_exhaustive_limit( &self, config: &GenConfig, test: F, exhaustive_limit: bool, ) { self.test_properties_with_config_with_limit_and_optional_exhaustive_limit( config, test, LARGE_LIMIT, exhaustive_limit, ); } pub fn test_properties_with_config(&self, config: &GenConfig, test: F) { self.test_properties_with_config_optional_exhaustive_limit(config, test, true); } #[inline] pub fn test_properties(&self, test: F) { self.test_properties_with_config(&GenConfig::new(), test); } #[inline] pub fn test_properties_with_limit_and_no_exhaustive_limit(&self, test: F) { self.test_properties_with_config_optional_exhaustive_limit(&GenConfig::new(), test, false); } #[inline] pub fn test_properties_no_exhaustive_limit(&self, test: F) { self.test_properties_with_config_optional_exhaustive_limit(&GenConfig::new(), test, false); } pub fn get(&self, gm: GenMode, config: &GenConfig) -> It { match gm { GenMode::Exhaustive => (self.exhaustive)(), GenMode::Random => (self.random)(config), GenMode::SpecialRandom => { (self .special_random .expect("special_random mode unsupported"))(config) } } } } pub fn permute_1_3_2( it: Box>, ) -> Box> { Box::new(it.map(|(a, b, c)| (a, c, b))) } pub fn permute_2_1( it: Box>, ) -> Box> { Box::new(it.map(|(a, b)| (b, a))) } pub fn permute_3_1_4_2( it: Box>, ) -> Box> { Box::new(it.map(|(a, b, c, d)| (c, a, d, b))) } pub fn reshape_1_2_to_3( it: Box>, ) -> Box> { Box::new(it.map(|(a, (b, c))| (a, b, c))) } pub fn reshape_1_3_to_4( it: Box>, ) -> Box> { Box::new(it.map(|(a, (b, c, d))| (a, b, c, d))) } pub fn reshape_2_1_to_3( it: Box>, ) -> Box> { Box::new(it.map(|((a, b), c)| (a, b, c))) } pub fn reshape_2_1_1_to_4( it: Box>, ) -> Box> { Box::new(it.map(|((a, b), c, d)| (a, b, c, d))) } #[allow(clippy::type_complexity)] pub fn reshape_2_2_to_4( it: Box>, ) -> Box> { Box::new(it.map(|((a, b), (c, d))| (a, b, c, d))) } pub fn reshape_3_1_to_4( it: Box>, ) -> Box> { Box::new(it.map(|((a, b, c), d)| (a, b, c, d))) } malachite-base-0.4.16/src/test_util/generators/exhaustive.rs000064400000000000000000005770751046102023000223070ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::bools::exhaustive::{exhaustive_bools, ExhaustiveBools}; use crate::chars::constants::NUMBER_OF_CHARS; use crate::chars::exhaustive::{exhaustive_ascii_chars, exhaustive_chars}; use crate::comparison::traits::Min; use crate::iterators::bit_distributor::BitDistributorOutputType; use crate::iterators::iter_windows; use crate::max; use crate::num::arithmetic::traits::CoprimeWith; use crate::num::arithmetic::traits::{ ArithmeticCheckedShl, CheckedNeg, DivRound, Parity, PowerOf2, ShrRound, UnsignedAbs, }; use crate::num::basic::floats::PrimitiveFloat; use crate::num::basic::integers::PrimitiveInt; use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::string::options::exhaustive::{ exhaustive_from_sci_string_options, exhaustive_sci_size_options, exhaustive_to_sci_options, }; use crate::num::conversion::string::options::{FromSciStringOptions, SciSizeOptions, ToSciOptions}; use crate::num::conversion::traits::{ ConvertibleFrom, Digits, ExactFrom, HasHalf, JoinHalves, RoundingFrom, SaturatingFrom, SplitInHalf, WrappingFrom, }; use crate::num::exhaustive::{ exhaustive_finite_primitive_floats, exhaustive_natural_signeds, exhaustive_negative_signeds, exhaustive_nonzero_finite_primitive_floats, exhaustive_nonzero_signeds, exhaustive_positive_finite_primitive_floats, exhaustive_positive_primitive_ints, exhaustive_primitive_float_range, exhaustive_primitive_floats, exhaustive_signed_inclusive_range, exhaustive_signed_range, exhaustive_signeds, exhaustive_unsigneds, primitive_int_increasing_inclusive_range, primitive_int_increasing_range, ExhaustiveSigneds, PrimitiveIntIncreasingRange, }; use crate::num::float::NiceFloat; use crate::num::iterators::{bit_distributor_sequence, ruler_sequence}; use crate::num::logic::traits::{BitBlockAccess, LeadingZeros}; use crate::rational_sequences::exhaustive::exhaustive_rational_sequences; use crate::rational_sequences::RationalSequence; use crate::rounding_modes::exhaustive::exhaustive_rounding_modes; use crate::rounding_modes::RoundingMode::{self, *}; use crate::slices::slice_test_zero; use crate::strings::exhaustive::{exhaustive_strings, exhaustive_strings_using_chars}; use crate::strings::{strings_from_char_vecs, StringsFromCharVecs}; use crate::test_util::extra_variadic::{ exhaustive_duodecuples_from_single, exhaustive_octuples_from_single, exhaustive_quadruples_from_single, exhaustive_quadruples_xxxy, exhaustive_quadruples_xxxy_custom_output, exhaustive_quadruples_xxyx, exhaustive_quadruples_xyyx, exhaustive_quadruples_xyyz, exhaustive_quadruples_xyyz_custom_output, exhaustive_quadruples_xyzz, exhaustive_sextuples_from_single, exhaustive_triples_from_single, exhaustive_triples_xxy, exhaustive_triples_xxy_custom_output, exhaustive_triples_xyx, exhaustive_triples_xyx_custom_output, lex_triples_from_single, lex_triples_xyy, lex_union3s, ExhaustiveTriples1Input, ExhaustiveTriplesXXY, Union3, }; use crate::test_util::generators::common::{ permute_1_3_2, permute_2_1, permute_3_1_4_2, reshape_1_2_to_3, reshape_2_1_1_to_4, reshape_2_1_to_3, reshape_2_2_to_4, reshape_3_1_to_4, It, }; use crate::test_util::generators::{ digits_valid, exhaustive_pairs_big_small, exhaustive_pairs_big_tiny, large_exponent, signed_assign_bits_valid, smallest_invalid_value, unsigned_assign_bits_valid, }; use crate::test_util::num::arithmetic::mod_mul::limbs_invert_limb_naive; use crate::test_util::num::conversion::string::from_sci_string::DECIMAL_SCI_STRING_CHARS; use crate::test_util::num::float::PRIMITIVE_FLOAT_CHARS; use crate::test_util::rounding_modes::ROUNDING_MODE_CHARS; use crate::tuples::exhaustive::{ exhaustive_dependent_pairs, exhaustive_ordered_unique_pairs, exhaustive_pairs, exhaustive_pairs_from_single, exhaustive_quadruples, exhaustive_triples, exhaustive_triples_custom_output, exhaustive_triples_xyy, exhaustive_triples_xyy_custom_output, lex_pairs, lex_pairs_from_single, ExhaustiveDependentPairsYsGenerator, ExhaustivePairs, ExhaustivePairs1Input, ExhaustiveQuadruples, ExhaustiveTriples, ExhaustiveTriplesXYY, }; use crate::vecs::exhaustive::{ exhaustive_vecs, exhaustive_vecs_fixed_length_from_single, exhaustive_vecs_length_inclusive_range, exhaustive_vecs_min_length, lex_vecs_fixed_length_from_single, shortlex_vecs, shortlex_vecs_length_inclusive_range, shortlex_vecs_min_length, ExhaustiveFixedLengthVecs1Input, ExhaustiveVecs, LexFixedLengthVecsFromSingle, ShortlexVecs, }; use itertools::{repeat_n, Itertools}; use std::cmp::{max, min}; use std::iter::once; use std::marker::PhantomData; use std::vec::IntoIter; // general fn add_mul_inputs_valid(x: T, y: T, z: T) -> bool { x.checked_add_mul(y, z).is_some() } fn sub_mul_inputs_valid(x: T, y: T, z: T) -> bool { x.checked_sub_mul(y, z).is_some() } // -- bool -- pub fn exhaustive_bool_gen() -> It { Box::new(exhaustive_bools()) } // -- char -- pub fn exhaustive_char_gen() -> It { Box::new(exhaustive_chars()) } #[allow(unstable_name_collisions)] pub fn exhaustive_char_gen_var_1() -> It { Box::new(char::MIN..char::MAX) } #[allow(unstable_name_collisions)] pub fn exhaustive_char_gen_var_2() -> It { Box::new('\u{1}'..=char::MAX) } // -- (char, char) -- pub fn exhaustive_char_pair_gen() -> It<(char, char)> { Box::new(exhaustive_pairs_from_single(exhaustive_chars())) } // -- FromSciStringOptions -- pub fn exhaustive_from_sci_string_options_gen() -> It { Box::new(exhaustive_from_sci_string_options()) } // -- (FromSciStringOptions, PrimitiveUnsigned) -- pub fn exhaustive_from_sci_string_options_unsigned_pair_gen_var_1( ) -> It<(FromSciStringOptions, T)> { Box::new(exhaustive_pairs( exhaustive_from_sci_string_options(), primitive_int_increasing_inclusive_range(T::TWO, T::from(36u8)), )) } // -- (FromSciStringOptions, RoundingMode) -- pub fn exhaustive_from_sci_string_options_rounding_mode_pair_gen( ) -> It<(FromSciStringOptions, RoundingMode)> { Box::new(exhaustive_pairs( exhaustive_from_sci_string_options(), exhaustive_rounding_modes(), )) } // -- PrimitiveFloat -- pub fn exhaustive_primitive_float_gen() -> It { Box::new(exhaustive_primitive_floats()) } pub fn exhaustive_primitive_float_gen_var_1() -> It { Box::new(exhaustive_primitive_float_range( T::NEGATIVE_ONE / T::TWO, T::INFINITY, )) } struct ExhaustivePositiveNaturalFloats { phantom: PhantomData<*const T>, done: bool, exponent: i64, limit: u64, mantissa: u64, } impl Iterator for ExhaustivePositiveNaturalFloats { type Item = T; fn next(&mut self) -> Option { if self.done { None } else { let f = T::from_integer_mantissa_and_exponent(self.mantissa, self.exponent).unwrap(); if f == T::MAX_FINITE { self.done = true; } else { self.mantissa += 1; if self.mantissa == self.limit { self.mantissa >>= 1; self.exponent += 1; self.limit = u64::power_of_2(T::MANTISSA_WIDTH + 1); } } Some(f) } } } fn exhaustive_positive_natural_floats() -> ExhaustivePositiveNaturalFloats { ExhaustivePositiveNaturalFloats { phantom: PhantomData, done: false, exponent: 0, limit: u64::power_of_2(T::MANTISSA_WIDTH + 1), mantissa: 1, } } pub fn exhaustive_primitive_float_gen_var_2() -> It { Box::new(once(T::ZERO).chain(exhaustive_positive_natural_floats())) } pub fn exhaustive_primitive_float_gen_var_3() -> It { Box::new(exhaustive_positive_finite_primitive_floats::().filter(|f| !f.is_integer())) } pub fn exhaustive_primitive_float_gen_var_4() -> It { let limit = T::from_integer_mantissa_and_exponent(1, i64::wrapping_from(T::MANTISSA_WIDTH)).unwrap(); Box::new( exhaustive_positive_natural_floats::() .take_while(move |&f| f <= limit) .map(|f| f - T::ONE / T::TWO), ) } pub fn exhaustive_primitive_float_gen_var_5() -> It { Box::new( lex_pairs( exhaustive_primitive_float_gen_var_2::(), exhaustive_bools(), ) .map(|(f, b)| if b { f } else { -f }), ) } pub fn exhaustive_primitive_float_gen_var_6() -> It { Box::new( lex_pairs( exhaustive_primitive_float_gen_var_3::(), exhaustive_bools(), ) .map(|(f, b)| if b { f } else { -f }), ) } pub fn exhaustive_primitive_float_gen_var_7() -> It { Box::new( lex_pairs( exhaustive_primitive_float_gen_var_4::(), exhaustive_bools(), ) .map(|(f, b)| if b { f } else { -f }), ) } pub fn exhaustive_primitive_float_gen_var_8() -> It { Box::new(exhaustive_finite_primitive_floats()) } pub fn exhaustive_primitive_float_gen_var_9() -> It { Box::new(exhaustive_primitive_floats::().filter(|&f| !f.is_nan() && f != T::INFINITY)) } pub fn exhaustive_primitive_float_gen_var_10() -> It { Box::new( exhaustive_primitive_floats::().filter(|&f| !f.is_nan() && f != T::NEGATIVE_INFINITY), ) } pub fn exhaustive_primitive_float_gen_var_11() -> It { Box::new(exhaustive_primitive_floats::().filter(|&f| !f.is_nan())) } pub fn exhaustive_primitive_float_gen_var_12() -> It { Box::new(exhaustive_nonzero_finite_primitive_floats()) } pub fn exhaustive_primitive_float_gen_var_13() -> It where NiceFloat: TryFrom, { Box::new( exhaustive_unsigneds::().filter_map(|x| NiceFloat::::try_from(x).ok().map(|x| x.0)), ) } pub fn exhaustive_primitive_float_gen_var_14() -> It where NiceFloat: TryFrom, { Box::new( exhaustive_signeds::().filter_map(|x| NiceFloat::::try_from(x).ok().map(|x| x.0)), ) } pub fn exhaustive_primitive_float_gen_var_15< T: PrimitiveFloat, U: ConvertibleFrom + PrimitiveInt, >() -> It { Box::new(exhaustive_primitive_floats::().filter(|&f| !U::convertible_from(f))) } pub fn exhaustive_primitive_float_gen_var_16< T: PrimitiveFloat + RoundingFrom, U: PrimitiveUnsigned, >() -> It { let limit = min( NiceFloat(T::rounding_from(U::MAX, Down).0), NiceFloat( T::from_integer_mantissa_and_exponent(1, i64::wrapping_from(T::MANTISSA_WIDTH)) .unwrap(), ), ) .0; Box::new( exhaustive_positive_natural_floats::() .take_while(move |&f| f <= limit) .map(|f| f - T::ONE / T::TWO), ) } pub fn exhaustive_primitive_float_gen_var_17< T: PrimitiveFloat + RoundingFrom, U: PrimitiveSigned, >() -> It { let min_limit = min( NiceFloat(-T::rounding_from(U::MIN, Down).0), NiceFloat( T::from_integer_mantissa_and_exponent(1, i64::wrapping_from(T::MANTISSA_WIDTH)) .unwrap(), ), ) .0; let max_limit = min( NiceFloat(T::rounding_from(U::MAX, Down).0), NiceFloat( T::from_integer_mantissa_and_exponent(1, i64::wrapping_from(T::MANTISSA_WIDTH)) .unwrap(), ), ) .0; Box::new( exhaustive_positive_natural_floats::() .take_while(move |&f| f <= max_limit) .map(|f| f - T::ONE / T::TWO) .interleave( exhaustive_positive_natural_floats::() .take_while(move |&f| f <= min_limit) .map(|f| T::ONE / T::TWO - f), ), ) } pub fn exhaustive_primitive_float_gen_var_18() -> It { Box::new(exhaustive_positive_finite_primitive_floats::()) } pub fn exhaustive_primitive_float_gen_var_19() -> It { Box::new(exhaustive_primitive_float_range( T::ZERO, T::power_of_2(T::MAX_EXPONENT), )) } // -- (PrimitiveFloat, PrimitiveFloat) -- pub fn exhaustive_primitive_float_pair_gen() -> It<(T, T)> { Box::new(exhaustive_pairs_from_single(exhaustive_primitive_floats())) } pub fn exhaustive_primitive_float_pair_gen_var_1() -> It<(T, T)> { Box::new(exhaustive_pairs_from_single( exhaustive_primitive_floats::().filter(|&f| !f.is_nan()), )) } // -- (PrimitiveFloat, PrimitiveFloat, PrimitiveFloat) -- pub fn exhaustive_primitive_float_triple_gen() -> It<(T, T, T)> { Box::new(exhaustive_triples_from_single(exhaustive_primitive_floats())) } // -- (PrimitiveFloat, PrimitiveInt) -- pub fn exhaustive_primitive_float_primitive_int_pair_gen_var_1< T: PrimitiveFloat, U: PrimitiveInt, >() -> It<(T, U)> { Box::new(exhaustive_pairs_big_tiny( exhaustive_positive_finite_primitive_floats(), exhaustive_positive_primitive_ints(), )) } // -- (PrimitiveFloat, PrimitiveSigned) -- pub fn exhaustive_primitive_float_signed_pair_gen( ) -> It<(T, U)> { Box::new(exhaustive_pairs_big_tiny( exhaustive_primitive_floats(), exhaustive_signeds(), )) } pub fn exhaustive_primitive_float_signed_pair_gen_var_1( ) -> It<(T, U)> { Box::new(exhaustive_pairs_big_tiny( exhaustive_positive_finite_primitive_floats(), exhaustive_signeds(), )) } pub fn exhaustive_primitive_float_signed_pair_gen_var_2() -> It<(T, i64)> { Box::new( exhaustive_pairs_big_tiny( exhaustive_primitive_float_range(T::ONE, T::TWO), exhaustive_signed_inclusive_range(T::MIN_EXPONENT, T::MAX_EXPONENT), ) .filter(|&(m, e)| m.precision() <= T::max_precision_for_sci_exponent(e)), ) } pub fn exhaustive_primitive_float_signed_pair_gen_var_3() -> It<(T, i64)> { Box::new(exhaustive_pairs_big_tiny( exhaustive_primitive_float_range(T::ONE, T::TWO), exhaustive_signeds(), )) } pub fn exhaustive_primitive_float_signed_pair_gen_var_4( ) -> It<(T, U)> { Box::new(exhaustive_pairs_big_tiny( exhaustive_primitive_floats(), exhaustive_signeds(), )) } // -- (PrimitiveFloat, PrimitiveSigned, PrimitiveUnsigned) -- pub fn exhaustive_primitive_float_signed_unsigned_triple_gen_var_1< T: PrimitiveFloat, U: PrimitiveSigned, V: PrimitiveUnsigned, >() -> It<(T, U, V)> { reshape_1_2_to_3(Box::new(exhaustive_pairs_big_small( exhaustive_primitive_floats(), exhaustive_pairs(exhaustive_signeds(), exhaustive_positive_primitive_ints()), ))) } // -- (PrimitiveFloat, PrimitiveUnsigned) -- pub fn exhaustive_primitive_float_unsigned_pair_gen_var_1< T: PrimitiveFloat, U: PrimitiveUnsigned, >() -> It<(T, U)> { Box::new(exhaustive_pairs_big_tiny( exhaustive_positive_finite_primitive_floats(), exhaustive_unsigneds(), )) } pub fn exhaustive_primitive_float_unsigned_pair_gen_var_2() -> It<(T, u64)> { Box::new(exhaustive_pairs_big_tiny( exhaustive_primitive_float_range(T::ONE, T::TWO), exhaustive_unsigneds(), )) } pub fn exhaustive_primitive_float_unsigned_pair_gen_var_3< T: PrimitiveFloat, U: PrimitiveUnsigned, >() -> It<(T, U)> { Box::new(exhaustive_pairs_big_tiny( exhaustive_primitive_floats(), exhaustive_positive_primitive_ints(), )) } // -- (PrimitiveFloat, PrimitiveUnsigned, RoundingMode) -- pub fn exhaustive_primitive_float_unsigned_rounding_mode_triple_gen_var_1< T: PrimitiveFloat, U: PrimitiveUnsigned, >() -> It<(T, U, RoundingMode)> { reshape_2_1_to_3(Box::new(lex_pairs( exhaustive_pairs_big_tiny( exhaustive_positive_finite_primitive_floats(), exhaustive_unsigneds(), ), exhaustive_rounding_modes(), ))) } pub fn exhaustive_primitive_float_unsigned_rounding_mode_triple_gen_var_2( ) -> It<(T, u64, RoundingMode)> { reshape_2_1_to_3(Box::new(lex_pairs( exhaustive_pairs_big_tiny( exhaustive_primitive_float_range(T::ONE, T::TWO), exhaustive_unsigneds(), ), exhaustive_rounding_modes(), ))) } // var 3 is in malachite-float. // -- (PrimitiveFloat, RoundingMode) -- pub(crate) fn float_rounding_mode_filter_var_1(p: &(T, RoundingMode)) -> bool { let &(f, rm) = p; match rm { Floor | Up => f >= T::ZERO, Ceiling | Down => f > T::NEGATIVE_ONE, Nearest => f >= T::NEGATIVE_ONE / T::TWO, Exact => f >= T::ZERO && f.is_integer(), } } pub fn exhaustive_primitive_float_rounding_mode_pair_gen_var_1( ) -> It<(T, RoundingMode)> { Box::new( lex_pairs( exhaustive_finite_primitive_floats(), exhaustive_rounding_modes(), ) .filter(float_rounding_mode_filter_var_1), ) } pub fn exhaustive_primitive_float_rounding_mode_pair_gen_var_2( ) -> It<(T, RoundingMode)> { Box::new( lex_pairs( exhaustive_finite_primitive_floats::(), exhaustive_rounding_modes(), ) .filter(|&(f, rm)| rm != Exact || f.is_integer()), ) } pub fn exhaustive_primitive_float_rounding_mode_pair_gen_var_3< T: PrimitiveFloat + RoundingFrom, U: ConvertibleFrom + PrimitiveInt, >() -> It<(T, RoundingMode)> { let f_min = T::rounding_from(U::MIN, Down).0; let f_max = T::rounding_from(U::MAX, Down).0; Box::new( lex_pairs( exhaustive_primitive_floats::().filter(|f| !f.is_nan()), exhaustive_rounding_modes(), ) .filter(move |&(f, rm)| match rm { Up => f >= f_min && f <= f_max, Ceiling => f <= f_max, Floor => f >= f_min, Down | Nearest => true, Exact => U::convertible_from(f), }), ) } // -- PrimitiveInt -- pub fn exhaustive_primitive_int_gen_var_1() -> It { Box::new(exhaustive_positive_primitive_ints()) } pub fn exhaustive_primitive_int_gen_var_2() -> It { Box::new(primitive_int_increasing_inclusive_range(T::TWO, T::MAX)) } pub fn exhaustive_primitive_int_gen_var_3() -> It { Box::new(primitive_int_increasing_range(T::ZERO, T::exact_from(36))) } pub fn exhaustive_primitive_int_gen_var_4() -> It { Box::new(primitive_int_increasing_inclusive_range( T::TWO, T::exact_from(36), )) } pub fn exhaustive_primitive_int_gen_var_5() -> It { Box::new(primitive_int_increasing_inclusive_range( T::power_of_2(T::WIDTH - 2), T::MAX, )) } pub fn exhaustive_primitive_int_gen_var_6() -> It { Box::new(primitive_int_increasing_inclusive_range( T::wrapping_from(5u8), T::MAX, )) } // -- (PrimitiveInt, PrimitiveInt) -- pub fn exhaustive_primitive_int_pair_gen_var_1 + PrimitiveInt>( ) -> It<(T, U)> { Box::new(lex_pairs( exhaustive_positive_primitive_ints(), primitive_int_increasing_inclusive_range(U::TWO, U::exact_from(36u8)), )) } pub fn exhaustive_primitive_int_pair_gen_var_2() -> It<(T, U)> { Box::new(exhaustive_pairs_big_tiny( exhaustive_positive_primitive_ints(), exhaustive_positive_primitive_ints(), )) } pub fn exhaustive_primitive_int_pair_gen_var_3() -> T1 { Box::new(exhaustive_pairs_big_small( exhaustive_positive_primitive_ints(), primitive_int_increasing_inclusive_range(U::TWO, U::MAX), )) } pub fn exhaustive_primitive_int_pair_gen_var_4() -> It<(T, T)> { Box::new(exhaustive_ordered_unique_pairs( exhaustive_positive_primitive_ints(), )) } // -- (PrimitiveInt, PrimitiveUnsigned) -- pub fn exhaustive_primitive_int_unsigned_pair_gen_var_1( ) -> It<(T, U)> { Box::new(exhaustive_pairs_big_tiny( exhaustive_positive_primitive_ints(), exhaustive_unsigneds(), )) } pub fn exhaustive_primitive_int_unsigned_pair_gen_var_2( ) -> It<(T, U)> { Box::new(exhaustive_pairs( primitive_int_increasing_inclusive_range(T::power_of_2(T::WIDTH - 2), T::MAX), exhaustive_unsigneds(), )) } // -- (PrimitiveInt, PrimitiveUnsigned, PrimitiveUnsigned) -- pub fn exhaustive_primitive_int_unsigned_unsigned_triple_gen_var_1< T: PrimitiveInt, U: PrimitiveUnsigned, >() -> It<(T, U, U)> { Box::new( exhaustive_triples_xyy_custom_output( exhaustive_positive_primitive_ints(), exhaustive_unsigneds(), BitDistributorOutputType::normal(1), BitDistributorOutputType::tiny(), BitDistributorOutputType::tiny(), ) .filter_map(|(x, y, z): (T, U, U)| y.checked_add(z).map(|new_z| (x, y, new_z))), ) } // -- (PrimitiveInt, RoundingMode) -- pub fn exhaustive_primitive_int_rounding_mode_pair_gen_var_1( ) -> It<(T, RoundingMode)> { Box::new(lex_pairs( exhaustive_positive_primitive_ints(), exhaustive_rounding_modes(), )) } pub fn exhaustive_primitive_int_rounding_mode_pair_gen_var_2( ) -> It<(T, RoundingMode)> { Box::new(lex_pairs( exhaustive_positive_primitive_ints(), exhaustive_rounding_modes().filter(|&rm| rm != Exact), )) } // -- PrimitiveSigned -- pub fn exhaustive_signed_gen() -> It { Box::new(exhaustive_signeds()) } pub fn exhaustive_signed_gen_var_1() -> It { Box::new(exhaustive_signed_inclusive_range(T::MIN + T::ONE, T::MAX)) } pub fn exhaustive_signed_gen_var_2() -> It { Box::new(exhaustive_natural_signeds()) } pub fn exhaustive_signed_gen_var_3() -> It { Box::new(exhaustive_signeds().filter(|&x| x != T::ZERO && x != T::NEGATIVE_ONE)) } pub fn exhaustive_signed_gen_var_4() -> It { Box::new(exhaustive_negative_signeds()) } pub fn exhaustive_signed_gen_var_5() -> It { Box::new(exhaustive_nonzero_signeds()) } pub fn exhaustive_signed_gen_var_6 + PrimitiveFloat>( ) -> It { Box::new(exhaustive_signeds().filter(|&x| U::convertible_from(x))) } pub fn exhaustive_signed_gen_var_7 + PrimitiveFloat>( ) -> It { Box::new( primitive_int_increasing_inclusive_range( T::saturating_from(U::SMALLEST_UNREPRESENTABLE_UINT), T::MAX, ) .interleave( primitive_int_increasing_inclusive_range( T::MIN, T::saturating_from(U::SMALLEST_UNREPRESENTABLE_UINT).saturating_neg(), ) .rev(), ) .filter(|&x| !U::convertible_from(x)), ) } pub fn exhaustive_signed_gen_var_8 + PrimitiveFloat>( ) -> It { Box::new( iter_windows( 2, primitive_int_increasing_inclusive_range( T::exact_from(U::SMALLEST_UNREPRESENTABLE_UINT), T::MAX, ) .filter(|&x| U::convertible_from(x)), ) .filter_map(|xs| { let mut xs = xs.into_iter(); let a = xs.next().unwrap(); let diff = xs.next().unwrap() - a; if diff.even() { // This happens almost always Some(a + (diff >> 1)) } else { None } }) .interleave( iter_windows( 2, primitive_int_increasing_inclusive_range( T::MIN, T::exact_from(U::SMALLEST_UNREPRESENTABLE_UINT) .checked_neg() .unwrap(), ) .rev() .filter(|&x| U::convertible_from(x)), ) .filter_map(|xs| { let mut xs = xs.into_iter(); let a = xs.next().unwrap(); let diff = a - xs.next().unwrap(); if diff.even() { // This happens almost always Some(a - (diff >> 1)) } else { None } }), ), ) } pub fn exhaustive_signed_gen_var_9< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >() -> It { let limit = S::wrapping_from(U::wrapping_from(S::MAX).floor_sqrt()); Box::new(exhaustive_signed_inclusive_range(-limit, limit)) } pub fn exhaustive_signed_gen_var_10() -> It { Box::new(exhaustive_signed_inclusive_range( T::MIN_EXPONENT, T::MAX_EXPONENT, )) } pub fn exhaustive_signed_gen_var_11() -> It { Box::new(exhaustive_signeds().filter(|&x| x != T::ZERO && x != T::MIN)) } pub fn exhaustive_signed_gen_var_12() -> It { Box::new( primitive_int_increasing_inclusive_range(T::ZERO, T::low_mask(T::WIDTH - 2)) .map(|u| (u << 1) | T::ONE), ) } // -- (PrimitiveSigned, PrimitiveSigned) -- pub fn exhaustive_signed_pair_gen() -> It<(T, T)> { Box::new(exhaustive_pairs_from_single(exhaustive_signeds())) } pub fn exhaustive_signed_pair_gen_var_1() -> It<(T, T)> { Box::new( exhaustive_pairs_from_single(exhaustive_natural_signeds()) .interleave(exhaustive_pairs_from_single(exhaustive_negative_signeds())), ) } pub fn exhaustive_signed_pair_gen_var_3() -> It<(T, U)> { Box::new(exhaustive_pairs_big_tiny( exhaustive_signeds(), exhaustive_signeds(), )) } struct TakeWhileExtra bool> { xs: I, p: P, false_seen: bool, } impl bool> Iterator for TakeWhileExtra { type Item = I::Item; fn next(&mut self) -> Option { loop { if let Some(x) = self.xs.next() { if (self.p)(&x) { return Some(x); } else if self.false_seen { return None; } self.false_seen = true; } else { return None; } } } } #[inline] const fn take_while_extra bool>( xs: I, p: P, ) -> TakeWhileExtra { TakeWhileExtra { xs, p, false_seen: false, } } struct SignedDivisiblePairsGenerator { phantom: PhantomData<*const T>, } impl ExhaustiveDependentPairsYsGenerator> for SignedDivisiblePairsGenerator { #[inline] fn get_ys(&self, y: &T) -> It { // A simple take_while doesn't work. For example, if T is i8 and y is 64, trying to // checked-multiply y by the exhaustive signeds gives [Some(0), Some(64), Some(-64), None, // Some(-128), None, None, ...], where the first None corresponds to 128, which is not // representable as an i8. Doing a take_while would lose the Some(-128). Instead, we use // take_while_extra, which is like a take_while, but it waits until it sees a second None to // stop iterating. let y = *y; Box::new( take_while_extra( exhaustive_signeds().map(move |k| y.checked_mul(k)), Option::is_some, ) .map(Option::unwrap), ) } } pub fn exhaustive_signed_pair_gen_var_4() -> It<(T, T)> { permute_2_1(Box::new(exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(1), ), exhaustive_nonzero_signeds(), SignedDivisiblePairsGenerator { phantom: PhantomData, }, ))) } pub fn exhaustive_signed_pair_gen_var_5() -> It<(T, T)> { Box::new( exhaustive_pairs(exhaustive_signeds(), exhaustive_nonzero_signeds()) .filter(|&(x, y)| x != T::MIN || y != T::NEGATIVE_ONE), ) } pub fn exhaustive_signed_pair_gen_var_6() -> It<(T, T)> { Box::new( exhaustive_pairs(exhaustive_signeds::(), exhaustive_nonzero_signeds::()) .filter(|&(x, y)| !x.divisible_by(y)), ) } pub fn exhaustive_signed_pair_gen_var_7() -> It<(T, T)> { Box::new(exhaustive_pairs( exhaustive_signeds(), exhaustive_nonzero_signeds(), )) } pub fn exhaustive_signed_pair_gen_var_8() -> It<(T, T)> { Box::new(exhaustive_pairs_from_single(exhaustive_natural_signeds())) } pub fn exhaustive_signed_pair_gen_var_9() -> It<(T, T)> { Box::new(exhaustive_pairs( exhaustive_signeds(), primitive_int_increasing_inclusive_range(T::ZERO, T::low_mask(T::WIDTH - 2)) .map(|u| (u << 1) | T::ONE), )) } pub fn exhaustive_signed_pair_gen_var_10() -> It<(T, T)> where ::Output: PrimitiveUnsigned, { Box::new( exhaustive_pairs_from_single( primitive_int_increasing_inclusive_range(T::ZERO, T::low_mask(T::WIDTH - 2)) .map(|u| (u << 1) | T::ONE), ) .filter(|&(a, b): &(T, T)| a.unsigned_abs().coprime_with(b.unsigned_abs())), ) } pub fn exhaustive_signed_pair_gen_var_11< U: PrimitiveUnsigned, S: PrimitiveSigned + UnsignedAbs, >() -> It<(S, S)> { Box::new( exhaustive_pairs_from_single(exhaustive_signeds()) .filter(|&(x, y): &(S, S)| x.unsigned_abs().coprime_with(y.unsigned_abs())), ) } pub fn exhaustive_signed_pair_gen_var_12() -> It<(T, U)> { Box::new(exhaustive_pairs(exhaustive_signeds(), exhaustive_signeds())) } pub fn exhaustive_signed_pair_gen_var_13() -> It<(T, T)> { Box::new( exhaustive_pairs_from_single(exhaustive_signeds()) .filter(|&(n, k)| T::checked_binomial_coefficient(n, k).is_some()), ) } // -- (PrimitiveSigned, PrimitiveSigned, PrimitiveSigned) -- pub fn exhaustive_signed_triple_gen() -> It<(T, T, T)> { Box::new(exhaustive_triples_from_single(exhaustive_signeds())) } pub fn exhaustive_signed_triple_gen_var_1() -> It<(T, T, T)> { Box::new( exhaustive_triples_from_single(exhaustive_signeds()) .filter(|&(x, y, z)| add_mul_inputs_valid(x, y, z)), ) } pub fn exhaustive_signed_triple_gen_var_2() -> It<(T, T, T)> { Box::new( exhaustive_triples_from_single(exhaustive_signeds()) .filter(|&(x, y, z)| sub_mul_inputs_valid(x, y, z)), ) } pub fn exhaustive_signed_triple_gen_var_3() -> It<(T, T, T)> { Box::new( exhaustive_triples_from_single(exhaustive_natural_signeds()) .interleave(exhaustive_triples_from_single(exhaustive_negative_signeds())), ) } struct SignedModEqTriplesInnerGenerator { phantom_u: PhantomData<*const U>, phantom_s: PhantomData<*const S>, } impl> ExhaustiveDependentPairsYsGenerator<(U, U), (S, S), It<(S, S)>> for SignedModEqTriplesInnerGenerator { #[inline] fn get_ys(&self, p: &(U, U)) -> It<(S, S)> { let &(m, k) = p; if k == U::ZERO { Box::new(exhaustive_signeds().map(|x| (x, x))) } else { let d = m.checked_mul(k).unwrap(); let d_s = S::wrapping_from(d); Box::new( exhaustive_signed_inclusive_range(S::MIN, S::MAX.wrapping_sub(d_s)) .map(move |n| (n, n.wrapping_add(d_s))) .interleave( exhaustive_signed_inclusive_range(S::MIN, S::MAX.wrapping_sub(d_s)) .map(move |n| (n.wrapping_add(d_s), n)), ), ) } } } struct SignedModEqTriplesGenerator { phantom_u: PhantomData<*const U>, phantom_s: PhantomData<*const S>, } impl + WrappingFrom> ExhaustiveDependentPairsYsGenerator> for SignedModEqTriplesGenerator { #[inline] fn get_ys(&self, m: &S) -> It<(S, S)> { let m = *m; let m_abs = m.unsigned_abs(); if m == S::ZERO { Box::new(exhaustive_signeds().map(|x| (x, x))) } else { Box::new( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(1), ), primitive_int_increasing_inclusive_range(U::ZERO, U::MAX / m_abs) .map(move |k| (m_abs, k)), SignedModEqTriplesInnerGenerator { phantom_u: PhantomData, phantom_s: PhantomData, }, ) .map(|p| p.1), ) } } } pub fn exhaustive_signed_triple_gen_var_4< U: PrimitiveUnsigned, S: PrimitiveSigned + UnsignedAbs + WrappingFrom, >() -> It<(S, S, S)> { reshape_2_1_to_3(permute_2_1(Box::new(exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(1), ), exhaustive_signeds(), SignedModEqTriplesGenerator { phantom_u: PhantomData, phantom_s: PhantomData, }, )))) } pub fn exhaustive_signed_triple_gen_var_5() -> It<(T, T, T)> { Box::new( exhaustive_triples_from_single(exhaustive_signeds::()) .filter(|&(x, y, m)| !x.eq_mod(y, m)), ) } pub fn exhaustive_signed_triple_gen_var_6() -> It<(T, T, T)> { Box::new(exhaustive_triples_xxy( exhaustive_signeds(), primitive_int_increasing_inclusive_range(T::ZERO, T::low_mask(T::WIDTH - 2)) .map(|u| (u << 1) | T::ONE), )) } pub fn exhaustive_signed_triple_gen_var_7() -> It<(T, T, T)> { Box::new(exhaustive_triples_xyy( exhaustive_signeds(), primitive_int_increasing_inclusive_range(T::ZERO, T::low_mask(T::WIDTH - 2)) .map(|u| (u << 1) | T::ONE), )) } // -- (PrimitiveSigned, PrimitiveSigned, PrimitiveSigned, PrimitiveSigned) -- pub fn exhaustive_signed_quadruple_gen() -> It<(T, T, T, T)> { Box::new(exhaustive_quadruples_from_single(exhaustive_signeds())) } // -- (PrimitiveSigned, PrimitiveSigned, PrimitiveSigned, PrimitiveUnsigned) -- pub fn exhaustive_signed_signed_signed_unsigned_quadruple_gen_var_1< T: PrimitiveSigned, U: PrimitiveUnsigned, >() -> It<(T, T, T, U)> { Box::new(exhaustive_quadruples_xxxy_custom_output( exhaustive_signeds(), exhaustive_unsigneds(), BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(1), BitDistributorOutputType::tiny(), )) } // -- (PrimitiveSigned, PrimitiveSigned, PrimitiveUnsigned) -- struct SignedModPow2EqTriplesInnerGenerator { phantom_u: PhantomData<*const U>, phantom_s: PhantomData<*const S>, } impl> ExhaustiveDependentPairsYsGenerator<(u64, U), (S, S), It<(S, S)>> for SignedModPow2EqTriplesInnerGenerator { #[inline] fn get_ys(&self, p: &(u64, U)) -> It<(S, S)> { let &(pow, k) = p; if k == U::ZERO { Box::new(exhaustive_signeds().map(|x| (x, x))) } else { let d = k << pow; let d_s = S::wrapping_from(d); Box::new( exhaustive_signed_inclusive_range(S::MIN, S::MAX.wrapping_sub(d_s)) .map(move |n| (n, n.wrapping_add(d_s))) .interleave( exhaustive_signed_inclusive_range(S::MIN, S::MAX.wrapping_sub(d_s)) .map(move |n| (n.wrapping_add(d_s), n)), ), ) } } } struct SignedModPow2EqTriplesGenerator { phantom_u: PhantomData<*const U>, phantom_s: PhantomData<*const S>, } impl> ExhaustiveDependentPairsYsGenerator> for SignedModPow2EqTriplesGenerator { #[inline] fn get_ys(&self, pow: &u64) -> It<(S, S)> { let pow = *pow; if pow >= S::WIDTH { Box::new(exhaustive_signeds().map(|x| (x, x))) } else { Box::new( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(1), ), primitive_int_increasing_inclusive_range(U::ZERO, U::MAX >> pow) .map(move |k| (pow, k)), SignedModPow2EqTriplesInnerGenerator { phantom_u: PhantomData, phantom_s: PhantomData, }, ) .map(|p| p.1), ) } } } pub fn exhaustive_signed_signed_unsigned_triple_gen_var_1< U: PrimitiveUnsigned, S: PrimitiveSigned + WrappingFrom, >() -> It<(S, S, u64)> { reshape_2_1_to_3(permute_2_1(Box::new(exhaustive_dependent_pairs( ruler_sequence(), exhaustive_unsigneds(), SignedModPow2EqTriplesGenerator:: { phantom_u: PhantomData, phantom_s: PhantomData, }, )))) } pub fn exhaustive_signed_signed_unsigned_triple_gen_var_2() -> It<(T, T, u64)> { Box::new( exhaustive_triples_xxy_custom_output( exhaustive_signeds::(), exhaustive_unsigneds(), BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(1), BitDistributorOutputType::tiny(), ) .filter(|&(x, y, pow)| !x.eq_mod_power_of_2(y, pow)), ) } pub fn exhaustive_signed_signed_unsigned_triple_gen_var_3< T: PrimitiveSigned, U: PrimitiveSigned, V: PrimitiveUnsigned, >() -> It<(T, U, V)> { reshape_1_2_to_3(Box::new(exhaustive_pairs_big_small( exhaustive_signeds(), exhaustive_pairs(exhaustive_signeds(), exhaustive_positive_primitive_ints()), ))) } // -- (PrimitiveSigned, PrimitiveSigned, RoundingMode) -- pub fn exhaustive_signed_signed_rounding_mode_triple_gen_var_1( ) -> It<(T, T, RoundingMode)> { reshape_2_1_to_3(Box::new( lex_pairs( exhaustive_pairs(exhaustive_signeds::(), exhaustive_nonzero_signeds::()), exhaustive_rounding_modes(), ) .filter(|&((x, y), rm)| { (x != T::MIN || y != T::NEGATIVE_ONE) && (rm != Exact || x.divisible_by(y)) }), )) } fn round_to_multiple_unsigned_helper(x: T, y: T, rm: RoundingMode) -> bool { if x == y { true } else if y == T::ZERO { rm == Down || rm == Floor || rm == Nearest } else { x.div_round(y, rm).0.checked_mul(y).is_some() } } fn round_to_multiple_signed_helper< U: PrimitiveUnsigned, S: TryFrom + ConvertibleFrom + PrimitiveSigned + UnsignedAbs, >( x: S, y: S, rm: RoundingMode, ) -> bool { let x_abs = x.unsigned_abs(); let y_abs = y.unsigned_abs(); if x >= S::ZERO { round_to_multiple_unsigned_helper(x_abs, y_abs, rm) && S::convertible_from(x_abs.round_to_multiple(y_abs, rm).0) } else if !round_to_multiple_unsigned_helper(x_abs, y_abs, -rm) { false } else { let abs_result = x_abs.round_to_multiple(y_abs, -rm).0; abs_result == S::MIN.unsigned_abs() || S::try_from(abs_result) .ok() .and_then(CheckedNeg::checked_neg) .is_some() } } pub(crate) fn round_to_multiple_signed_filter_map< U: PrimitiveUnsigned, S: TryFrom + ConvertibleFrom + PrimitiveSigned + UnsignedAbs, >( x: S, y: S, rm: RoundingMode, ) -> Option<(S, S, RoundingMode)> { if rm == Exact { x.checked_mul(y).map(|product| (product, y, rm)) } else if round_to_multiple_signed_helper(x, y, rm) { Some((x, y, rm)) } else { None } } pub fn exhaustive_signed_signed_rounding_mode_triple_gen_var_2< U: PrimitiveUnsigned, S: TryFrom + ConvertibleFrom + PrimitiveSigned + UnsignedAbs, >() -> It<(S, S, RoundingMode)> { Box::new( lex_pairs( exhaustive_pairs(exhaustive_signeds(), exhaustive_nonzero_signeds()), exhaustive_rounding_modes(), ) .filter_map(|((x, y), rm)| round_to_multiple_signed_filter_map::(x, y, rm)), ) } pub fn exhaustive_signed_signed_rounding_mode_triple_gen_var_3< T: PrimitiveSigned, U: PrimitiveSigned, >() -> It<(T, U, RoundingMode)> { reshape_2_1_to_3(Box::new( lex_pairs( exhaustive_pairs_big_small(exhaustive_signeds::(), exhaustive_signeds::()), exhaustive_rounding_modes(), ) .filter(|&((x, pow), rm)| { rm != Exact || pow <= U::ZERO || x.divisible_by_power_of_2(pow.exact_into()) }), )) } pub fn exhaustive_signed_signed_rounding_mode_triple_gen_var_4< T: PrimitiveSigned, U: PrimitiveSigned, >() -> It<(T, U, RoundingMode)> { reshape_2_1_to_3(Box::new( lex_pairs( exhaustive_pairs_big_small(exhaustive_signeds::(), exhaustive_signeds::()), exhaustive_rounding_modes(), ) .filter(|&((x, pow), rm)| { let pow: i64 = pow.exact_into(); rm != Exact || pow >= 0 || x.divisible_by_power_of_2(pow.unsigned_abs()) }), )) } // -- (PrimitiveSigned, PrimitiveUnsigned) -- pub fn exhaustive_signed_unsigned_pair_gen() -> It<(T, U)> { Box::new(exhaustive_pairs( exhaustive_signeds(), exhaustive_unsigneds(), )) } pub fn exhaustive_signed_unsigned_pair_gen_var_2( ) -> It<(T, U)> { Box::new(exhaustive_pairs_big_tiny( exhaustive_signeds(), exhaustive_unsigneds(), )) } pub fn exhaustive_signed_unsigned_pair_gen_var_3() -> It<(T, u64)> { Box::new( lex_pairs( exhaustive_natural_signeds(), primitive_int_increasing_range(0, T::WIDTH), ) .interleave(exhaustive_pairs( exhaustive_negative_signeds(), exhaustive_unsigneds(), )), ) } pub fn exhaustive_signed_unsigned_pair_gen_var_4() -> It<(T, u64)> { Box::new(lex_pairs( exhaustive_signeds(), primitive_int_increasing_range(0, T::WIDTH), )) } pub fn exhaustive_signed_unsigned_pair_gen_var_5() -> It<(T, u64)> { Box::new( lex_pairs( exhaustive_negative_signeds(), primitive_int_increasing_range(0, T::WIDTH), ) .interleave(exhaustive_pairs( exhaustive_natural_signeds(), exhaustive_unsigneds(), )), ) } pub fn exhaustive_signed_unsigned_pair_gen_var_6< T: PrimitiveSigned, U: ExactFrom + PrimitiveUnsigned, >() -> It<(T, U)> { Box::new(lex_pairs( exhaustive_signeds(), primitive_int_increasing_inclusive_range(U::TWO, U::exact_from(36u8)), )) } pub fn exhaustive_signed_unsigned_pair_gen_var_7( ) -> It<(T, U)> { Box::new(exhaustive_pairs_big_tiny( exhaustive_natural_signeds(), exhaustive_unsigneds(), )) } pub fn exhaustive_signed_unsigned_pair_gen_var_8< T: PrimitiveSigned, U: ExactFrom + PrimitiveUnsigned, >() -> It<(T, U)> { Box::new(lex_pairs( exhaustive_natural_signeds(), primitive_int_increasing_inclusive_range(U::TWO, U::exact_from(36u8)), )) } pub fn exhaustive_signed_unsigned_pair_gen_var_9( ) -> It<(T, U)> { Box::new( exhaustive_pairs_big_tiny(exhaustive_signeds::(), exhaustive_unsigneds::()) .filter(|&(x, y)| !x.divisible_by_power_of_2(y.exact_into())), ) } struct SignedDivisibleByP2PairsGenerator { phantom: PhantomData<*const T>, } impl ExhaustiveDependentPairsYsGenerator> for SignedDivisibleByP2PairsGenerator { #[inline] fn get_ys(&self, pow: &u64) -> It { let pow = *pow; if pow >= T::WIDTH { Box::new(once(T::ZERO)) } else if pow == 0 { Box::new(exhaustive_signeds()) } else { Box::new( exhaustive_signed_inclusive_range( -T::low_mask(T::WIDTH - pow), T::low_mask(T::WIDTH - pow), ) .map(move |k| k << pow), ) } } } pub fn exhaustive_signed_unsigned_pair_gen_var_10() -> It<(T, u64)> { permute_2_1(Box::new(exhaustive_dependent_pairs( ruler_sequence(), exhaustive_unsigneds(), SignedDivisibleByP2PairsGenerator { phantom: PhantomData, }, ))) } pub fn exhaustive_signed_unsigned_pair_gen_var_11() -> It<(T, u64)> { Box::new( exhaustive_pairs_big_tiny(exhaustive_natural_signeds(), exhaustive_unsigneds()).interleave( exhaustive_pairs_big_tiny( exhaustive_signeds(), primitive_int_increasing_inclusive_range(0, T::WIDTH), ), ), ) } pub fn exhaustive_signed_unsigned_pair_gen_var_12() -> It<(T, u64)> { Box::new( exhaustive_pairs_big_tiny( exhaustive_signed_range(T::MIN + T::ONE, T::ONE), exhaustive_unsigneds(), ) .interleave(exhaustive_pairs_big_tiny( exhaustive_signeds(), primitive_int_increasing_range(0, T::WIDTH), )), ) } pub fn exhaustive_signed_unsigned_pair_gen_var_13( ) -> It<(T, u64)> { Box::new(lex_pairs( exhaustive_signeds(), primitive_int_increasing_inclusive_range(0, U::WIDTH), )) } pub fn exhaustive_signed_unsigned_pair_gen_var_14( ) -> It<(T, U)> { Box::new(exhaustive_pairs( exhaustive_signed_inclusive_range( if T::WIDTH <= u64::WIDTH { T::MIN } else { -T::exact_from(u64::MAX) }, T::saturating_from(u64::MAX), ), exhaustive_positive_primitive_ints(), )) } pub fn exhaustive_signed_unsigned_pair_gen_var_15() -> It<(T, u64)> { Box::new( exhaustive_pairs(exhaustive_signeds::(), exhaustive_unsigneds()) .filter(|&(x, y)| x.checked_pow(y).is_some()), ) } pub fn exhaustive_signed_unsigned_pair_gen_var_16( ) -> It<(T, U)> { Box::new(exhaustive_pairs_big_tiny( exhaustive_signed_range(T::MIN + T::ONE, T::ZERO), exhaustive_unsigneds(), )) } pub fn exhaustive_signed_unsigned_pair_gen_var_17( ) -> It<(T, U)> { Box::new( exhaustive_pairs_big_tiny( exhaustive_natural_signeds(), exhaustive_positive_primitive_ints(), ) .interleave(exhaustive_pairs_big_tiny( exhaustive_negative_signeds(), exhaustive_unsigneds::() .filter_map(|i| i.arithmetic_checked_shl(1).map(|j| j | U::ONE)), )), ) } pub fn exhaustive_signed_unsigned_pair_gen_var_18( ) -> It<(T, U)> { Box::new(exhaustive_pairs( exhaustive_signeds(), exhaustive_positive_primitive_ints(), )) } pub fn exhaustive_signed_unsigned_pair_gen_var_19( ) -> It<(T, U)> { Box::new(exhaustive_pairs_big_tiny( exhaustive_signeds(), exhaustive_positive_primitive_ints(), )) } // -- (PrimitiveSigned, PrimitiveUnsigned, bool) -- pub fn exhaustive_signed_unsigned_bool_triple_gen_var_1() -> It<(T, u64, bool)> { Box::new( exhaustive_pairs_big_tiny(exhaustive_signeds(), exhaustive_unsigneds()) .map(|(x, y)| (x, y, x < T::ZERO)) .interleave( lex_pairs( exhaustive_signeds(), primitive_int_increasing_range(0, T::WIDTH), ) .map(|(x, y)| (x, y, x >= T::ZERO)), ), ) } // -- (PrimitiveSigned, PrimitiveUnsigned, PrimitiveUnsigned) -- pub fn exhaustive_signed_unsigned_unsigned_triple_gen_var_1< T: PrimitiveSigned, U: PrimitiveUnsigned, V: PrimitiveUnsigned, >() -> It<(T, U, V)> { Box::new(exhaustive_triples_custom_output( exhaustive_signeds(), exhaustive_unsigneds(), exhaustive_unsigneds(), BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(1), BitDistributorOutputType::tiny(), )) } pub fn exhaustive_signed_unsigned_unsigned_triple_gen_var_2< T: PrimitiveSigned, U: PrimitiveUnsigned, >() -> It<(T, U, U)> { Box::new( exhaustive_triples_xyy_custom_output( exhaustive_positive_primitive_ints(), exhaustive_unsigneds(), BitDistributorOutputType::normal(1), BitDistributorOutputType::tiny(), BitDistributorOutputType::tiny(), ) .interleave(exhaustive_triples_custom_output( exhaustive_signed_inclusive_range(T::MIN, T::ZERO), exhaustive_unsigneds(), primitive_int_increasing_inclusive_range(U::ZERO, U::exact_from(T::WIDTH)), BitDistributorOutputType::normal(1), BitDistributorOutputType::tiny(), BitDistributorOutputType::tiny(), )) .filter_map(|(x, y, z)| y.checked_add(z).map(|new_z| (x, y, new_z))), ) } pub fn exhaustive_signed_unsigned_unsigned_triple_gen_var_3< T: PrimitiveSigned, U: ExactFrom + PrimitiveUnsigned, V: PrimitiveUnsigned, >() -> It<(T, U, V)> { permute_1_3_2(reshape_2_1_to_3(Box::new(lex_pairs( exhaustive_pairs_big_tiny(exhaustive_signeds(), exhaustive_unsigneds()), primitive_int_increasing_inclusive_range(U::TWO, U::exact_from(36u8)), )))) } pub fn exhaustive_signed_unsigned_unsigned_triple_gen_var_4< T: PrimitiveSigned, U: PrimitiveUnsigned, >() -> It<(T, T, U)> { Box::new(exhaustive_triples_xxy_custom_output( exhaustive_signeds(), exhaustive_unsigneds(), BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(1), BitDistributorOutputType::tiny(), )) } // -- (PrimitiveSigned, PrimitiveUnsigned, PrimitiveUnsigned, PrimitiveUnsigned) -- pub fn exhaustive_signed_unsigned_unsigned_unsigned_quadruple_gen_var_1< T: PrimitiveSigned + UnsignedAbs, U: BitBlockAccess + PrimitiveUnsigned, >() -> It<(T, u64, u64, U)> { Box::new( exhaustive_quadruples_xyyz_custom_output( exhaustive_signeds(), exhaustive_unsigneds(), exhaustive_unsigneds(), BitDistributorOutputType::normal(1), BitDistributorOutputType::tiny(), BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ) .filter_map(|(x, y, z, w): (T, u64, u64, U)| { y.checked_add(z).and_then(|new_z| { if signed_assign_bits_valid(x, y, new_z, w) { Some((x, y, new_z, w)) } else { None } }) }), ) } // -- (PrimitiveSigned, PrimitiveUnsigned, RoundingMode) -- pub fn exhaustive_signed_unsigned_rounding_mode_triple_gen_var_1( ) -> It<(T, u64, RoundingMode)> { Box::new( lex_pairs( exhaustive_pairs_big_small(exhaustive_signeds::(), exhaustive_unsigneds::()), exhaustive_rounding_modes(), ) .filter_map(|((x, pow), rm)| round_to_multiple_of_power_of_2_filter_map(x, pow, rm)), ) } pub fn exhaustive_signed_unsigned_rounding_mode_triple_gen_var_2< T: PrimitiveSigned, U: PrimitiveUnsigned, >() -> It<(T, U, RoundingMode)> { reshape_2_1_to_3(Box::new( lex_pairs( exhaustive_pairs_big_small(exhaustive_signeds::(), exhaustive_unsigneds::()), exhaustive_rounding_modes(), ) .filter(|&((x, y), rm)| rm != Exact || x.divisible_by_power_of_2(y.exact_into())), )) } // var 3 is in malachite-float. // -- (PrimitiveSigned, RoundingMode) -- pub fn exhaustive_signed_rounding_mode_pair_gen() -> It<(T, RoundingMode)> { Box::new(lex_pairs(exhaustive_signeds(), exhaustive_rounding_modes())) } pub fn exhaustive_signed_rounding_mode_pair_gen_var_1() -> It<(T, RoundingMode)> { Box::new(lex_pairs( exhaustive_nonzero_signeds(), exhaustive_rounding_modes(), )) } pub fn exhaustive_signed_rounding_mode_pair_gen_var_2() -> It<(T, RoundingMode)> { Box::new(lex_pairs( exhaustive_signed_inclusive_range(T::MIN + T::ONE, T::MAX), exhaustive_rounding_modes(), )) } pub fn exhaustive_signed_rounding_mode_pair_gen_var_3() -> It<(T, RoundingMode)> { Box::new(lex_pairs( exhaustive_nonzero_signeds().filter(|&x| x != T::MIN), exhaustive_rounding_modes(), )) } pub fn exhaustive_signed_rounding_mode_pair_gen_var_4< T: PrimitiveSigned, U: ConvertibleFrom + PrimitiveFloat, >() -> It<(T, RoundingMode)> { Box::new( lex_pairs(exhaustive_signeds(), exhaustive_rounding_modes()) .filter(|&(i, rm)| rm != Exact || U::convertible_from(i)), ) } // -- (PrimitiveSigned, ToSciOptions) -- pub fn exhaustive_signed_to_sci_options_pair_gen() -> It<(T, ToSciOptions)> { Box::new(exhaustive_pairs( exhaustive_signeds(), exhaustive_to_sci_options(), )) } type TSO = ToSciOptions; pub fn exhaustive_signed_to_sci_options_pair_gen_var_1() -> It<(T, TSO)> { Box::new( exhaustive_pairs(exhaustive_signeds::(), exhaustive_to_sci_options()) .filter(|(x, options)| x.fmt_sci_valid(*options)), ) } // -- (PrimitiveSigned, Vec) -- struct SignedBoolVecPairGeneratorVar1; impl ExhaustiveDependentPairsYsGenerator, LexFixedLengthVecsFromSingle> for SignedBoolVecPairGeneratorVar1 { #[inline] fn get_ys(&self, &x: &T) -> LexFixedLengthVecsFromSingle { lex_vecs_fixed_length_from_single( u64::exact_from(x.to_bits_asc().len()), exhaustive_bools(), ) } } pub fn exhaustive_signed_bool_vec_pair_gen_var_1() -> It<(T, Vec)> { Box::new(exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(1), ), exhaustive_signeds(), SignedBoolVecPairGeneratorVar1, )) } // -- PrimitiveUnsigned -- pub fn exhaustive_unsigned_gen() -> It { Box::new(exhaustive_unsigneds()) } pub fn exhaustive_unsigned_gen_var_1() -> It { Box::new(primitive_int_increasing_range(0, NUMBER_OF_CHARS)) } pub fn exhaustive_unsigned_gen_var_2() -> It { Box::new(primitive_int_increasing_inclusive_range(1, T::WIDTH)) } pub fn exhaustive_unsigned_gen_var_4< T: PrimitiveUnsigned, U: PrimitiveUnsigned + SaturatingFrom, >() -> It { Box::new(primitive_int_increasing_inclusive_range( U::TWO, U::saturating_from(T::MAX), )) } pub fn exhaustive_unsigned_gen_var_5() -> It { Box::new(primitive_int_increasing_inclusive_range(0, T::WIDTH)) } pub fn exhaustive_unsigned_gen_var_6() -> It { Box::new( lex_union3s( primitive_int_increasing_inclusive_range(b'0', b'9'), primitive_int_increasing_inclusive_range(b'a', b'z'), primitive_int_increasing_inclusive_range(b'A', b'Z'), ) .map(Union3::unwrap), ) } pub fn exhaustive_unsigned_gen_var_7() -> It { Box::new(primitive_int_increasing_inclusive_range( T::power_of_2(T::WIDTH - 1), T::MAX, )) } pub fn exhaustive_unsigned_gen_var_8() -> It { Box::new(primitive_int_increasing_inclusive_range( 0, T::LARGEST_ORDERED_REPRESENTATION, )) } pub fn exhaustive_unsigned_gen_var_9() -> It { Box::new(primitive_int_increasing_inclusive_range( T::ZERO, T::power_of_2(T::WIDTH - 1), )) } pub fn exhaustive_unsigned_gen_var_10() -> It { Box::new(primitive_int_increasing_range(0, T::WIDTH)) } pub fn exhaustive_unsigned_gen_var_11() -> It { Box::new(primitive_int_increasing_inclusive_range(0, T::WIDTH - 2)) } pub fn exhaustive_unsigned_gen_var_12< T: PrimitiveUnsigned, U: ConvertibleFrom + PrimitiveFloat, >() -> It { Box::new(exhaustive_unsigneds().filter(|&x| U::convertible_from(x))) } pub fn exhaustive_unsigned_gen_var_13< T: PrimitiveUnsigned, U: ConvertibleFrom + PrimitiveFloat, >() -> It { Box::new( primitive_int_increasing_inclusive_range( T::saturating_from(U::SMALLEST_UNREPRESENTABLE_UINT), T::MAX, ) .filter(|&x| !U::convertible_from(x)), ) } pub fn exhaustive_unsigned_gen_var_14< T: PrimitiveUnsigned, U: ConvertibleFrom + PrimitiveFloat, >() -> It { Box::new( iter_windows( 2, primitive_int_increasing_inclusive_range( T::exact_from(U::SMALLEST_UNREPRESENTABLE_UINT), T::MAX, ) .filter(|&x| U::convertible_from(x)), ) .filter_map(|xs| { let mut xs = xs.into_iter(); let a = xs.next().unwrap(); let diff = xs.next().unwrap() - a; if diff.even() { // This happens almost always Some(a + (diff >> 1)) } else { None } }), ) } pub fn exhaustive_unsigned_gen_var_15() -> It { Box::new(primitive_int_increasing_inclusive_range( T::ZERO, T::MAX.floor_sqrt(), )) } pub fn exhaustive_unsigned_gen_var_22() -> It { Box::new( primitive_int_increasing_inclusive_range(T::ZERO, T::low_mask(T::WIDTH - 1)) .map(|u| (u << 1) | T::ONE), ) } pub fn exhaustive_unsigned_gen_var_23() -> It { let limit = smallest_invalid_value(T::checked_factorial); Box::new(primitive_int_increasing_range(0, limit)) } pub fn exhaustive_unsigned_gen_var_24() -> It { let limit = smallest_invalid_value(T::checked_double_factorial); Box::new(primitive_int_increasing_range(0, limit)) } pub fn exhaustive_unsigned_gen_var_25() -> It { let limit = smallest_invalid_value(T::checked_subfactorial); Box::new(primitive_int_increasing_range(0, limit)) } pub fn exhaustive_unsigned_gen_var_26() -> It { let limit = smallest_invalid_value(T::checked_primorial); Box::new(primitive_int_increasing_range(0, limit)) } pub fn exhaustive_unsigned_gen_var_27() -> It { let limit = smallest_invalid_value(T::checked_product_of_first_n_primes); Box::new(primitive_int_increasing_range(0, limit)) } // -- (PrimitiveUnsigned, PrimitiveInt) -- pub fn exhaustive_unsigned_primitive_int_gen_var_1( ) -> It<(T, U)> { Box::new(exhaustive_pairs( exhaustive_unsigneds(), exhaustive_positive_primitive_ints(), )) } pub fn exhaustive_unsigned_primitive_int_pair_gen_var_2< T: PrimitiveUnsigned, U: ExactFrom + PrimitiveInt, >() -> It<(T, U)> { Box::new(lex_pairs( exhaustive_unsigneds(), primitive_int_increasing_inclusive_range(U::TWO, U::exact_from(36u8)), )) } pub fn exhaustive_unsigned_primitive_int_gen_var_3( ) -> It<(T, U)> { Box::new(exhaustive_pairs_big_tiny( exhaustive_unsigneds(), exhaustive_positive_primitive_ints(), )) } // -- (PrimitiveUnsigned, PrimitiveInt, PrimitiveUnsigned) -- pub fn exhaustive_unsigned_primitive_int_unsigned_triple_gen_var_3< T: PrimitiveUnsigned, U: PrimitiveInt, V: PrimitiveUnsigned, >() -> It<(T, u64, V)> { Box::new(exhaustive_triples( exhaustive_unsigneds(), primitive_int_increasing_inclusive_range(1, U::WIDTH), exhaustive_unsigneds(), )) } // -- (PrimitiveUnsigned, PrimitiveSigned) -- pub fn exhaustive_unsigned_signed_pair_gen() -> It<(T, U)> { Box::new(exhaustive_pairs( exhaustive_unsigneds(), exhaustive_signeds(), )) } pub fn exhaustive_unsigned_signed_pair_gen_var_1( ) -> It<(T, U)> { Box::new(exhaustive_pairs_big_tiny( exhaustive_unsigneds(), exhaustive_signeds(), )) } struct IntegerMantissaAndExponentGenerator { phantom: PhantomData<*const T>, } impl ExhaustiveDependentPairsYsGenerator<(u64, i64), (u64, i64), It<(u64, i64)>> for IntegerMantissaAndExponentGenerator { #[inline] fn get_ys(&self, p: &(u64, i64)) -> It<(u64, i64)> { let &(mantissa, exponent) = p; Box::new(exhaustive_natural_signeds().filter_map(move |i| { Some(( mantissa.arithmetic_checked_shl(i)?, exponent.checked_sub(i)?, )) })) } } pub fn exhaustive_unsigned_signed_pair_gen_var_2() -> It<(u64, i64)> { Box::new( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::normal(1), BitDistributorOutputType::tiny(), ), exhaustive_positive_finite_primitive_floats().map(T::integer_mantissa_and_exponent), IntegerMantissaAndExponentGenerator:: { phantom: PhantomData, }, ) .map(|p| p.1), ) } // -- (PrimitiveUnsigned, PrimitiveSigned, PrimitiveUnsigned) -- struct ModPowerOfTwoPairWithExtraSignedGenerator { phantom_t: PhantomData<*const T>, phantom_u: PhantomData<*const U>, } type LongType = ExhaustivePairs, U, ExhaustiveSigneds>; impl ExhaustiveDependentPairsYsGenerator< u64, (T, U), ExhaustivePairs, U, ExhaustiveSigneds>, > for ModPowerOfTwoPairWithExtraSignedGenerator { #[inline] fn get_ys(&self, &pow: &u64) -> LongType { exhaustive_pairs( primitive_int_increasing_inclusive_range(T::ZERO, T::low_mask(pow)), exhaustive_signeds(), ) } } pub fn exhaustive_unsigned_signed_unsigned_triple_gen_var_1< T: PrimitiveUnsigned, U: PrimitiveSigned, >() -> It<(T, U, u64)> { reshape_2_1_to_3(permute_2_1(Box::new(exhaustive_dependent_pairs( ruler_sequence(), primitive_int_increasing_inclusive_range(0, T::WIDTH), ModPowerOfTwoPairWithExtraSignedGenerator:: { phantom_t: PhantomData, phantom_u: PhantomData, }, )))) } pub fn exhaustive_unsigned_signed_unsigned_triple_gen_var_2< T: PrimitiveUnsigned, U: PrimitiveSigned, >() -> It<(T, U, T)> { Box::new( exhaustive_triples_xyx( exhaustive_unsigneds(), exhaustive_signed_inclusive_range( if U::WIDTH <= u64::WIDTH { U::MIN } else { -U::exact_from(u64::MAX) }, U::saturating_from(u64::MAX), ), ) .filter_map(|(x, y, z): (T, U, T)| Some((x, y, x.checked_add(z)?.checked_add(T::ONE)?))), ) } pub fn exhaustive_unsigned_signed_unsigned_triple_gen_var_3< T: PrimitiveUnsigned, U: PrimitiveSigned, >() -> It<(T, U, T)> { Box::new( exhaustive_triples_xyx(exhaustive_unsigneds(), exhaustive_signeds()).filter_map( |(x, y, z): (T, U, T)| Some((x, y, x.checked_add(z)?.checked_add(T::ONE)?)), ), ) } pub fn exhaustive_unsigned_signed_unsigned_triple_gen_var_4< T: PrimitiveUnsigned, U: PrimitiveSigned, V: PrimitiveUnsigned, >() -> It<(T, U, V)> { reshape_1_2_to_3(Box::new(exhaustive_pairs_big_small( exhaustive_unsigneds(), exhaustive_pairs(exhaustive_signeds(), exhaustive_positive_primitive_ints()), ))) } // -- (PrimitiveUnsigned, PrimitiveSigned, RoundingMode) -- pub fn exhaustive_unsigned_signed_rounding_mode_triple_gen_var_1< T: PrimitiveUnsigned, U: PrimitiveSigned, >() -> It<(T, U, RoundingMode)> { reshape_2_1_to_3(Box::new( lex_pairs( exhaustive_pairs_big_small(exhaustive_unsigneds::(), exhaustive_signeds::()), exhaustive_rounding_modes(), ) .filter(|&((x, pow), rm)| { rm != Exact || pow <= U::ZERO || x.divisible_by_power_of_2(pow.exact_into()) }), )) } pub fn exhaustive_unsigned_signed_rounding_mode_triple_gen_var_2< T: PrimitiveUnsigned, U: PrimitiveSigned, >() -> It<(T, U, RoundingMode)> { reshape_2_1_to_3(Box::new( lex_pairs( exhaustive_pairs_big_small(exhaustive_unsigneds::(), exhaustive_signeds::()), exhaustive_rounding_modes(), ) .filter(|&((x, pow), rm)| { let pow: i64 = pow.exact_into(); rm != Exact || pow >= 0 || x.divisible_by_power_of_2(pow.unsigned_abs()) }), )) } // -- (PrimitiveUnsigned, PrimitiveUnsigned) -- pub fn exhaustive_unsigned_pair_gen() -> It<(T, U)> { Box::new(exhaustive_pairs( exhaustive_unsigneds(), exhaustive_unsigneds(), )) } pub fn exhaustive_unsigned_pair_gen_var_1() -> It<(u32, u32)> { Box::new(exhaustive_pairs_from_single( primitive_int_increasing_range(0, NUMBER_OF_CHARS), )) } type T1 = It<(T, U)>; pub fn exhaustive_unsigned_pair_gen_var_2() -> T1 { Box::new(exhaustive_pairs_big_tiny( exhaustive_unsigneds(), exhaustive_unsigneds(), )) } pub fn exhaustive_unsigned_pair_gen_var_3() -> It<(T, u64)> { Box::new(lex_pairs( exhaustive_unsigneds(), primitive_int_increasing_range(0, T::WIDTH), )) } pub fn exhaustive_unsigned_pair_gen_var_4() -> It<(T, u64)> { Box::new(lex_pairs( exhaustive_unsigneds(), primitive_int_increasing_inclusive_range(1, U::WIDTH), )) } pub fn exhaustive_unsigned_pair_gen_var_5< T: PrimitiveUnsigned, U: PrimitiveUnsigned + SaturatingFrom, >() -> It<(T, U)> { Box::new(exhaustive_pairs_big_small( exhaustive_unsigneds(), primitive_int_increasing_inclusive_range(U::TWO, U::saturating_from(T::MAX)), )) } // TODO make better pub fn exhaustive_unsigned_pair_gen_var_6() -> It<(T, T)> { Box::new(exhaustive_pairs_from_single(exhaustive_unsigneds()).filter(|(x, y)| x <= y)) } pub fn exhaustive_unsigned_pair_gen_var_7< T: PrimitiveInt + SaturatingFrom, U: PrimitiveUnsigned, V: PrimitiveUnsigned, >() -> It<(T, V)> { Box::new(exhaustive_pairs_big_tiny( primitive_int_increasing_inclusive_range(T::TWO, T::saturating_from(U::MAX)), exhaustive_unsigneds(), )) } struct UnsignedDivisiblePairsGenerator { phantom: PhantomData<*const T>, } impl ExhaustiveDependentPairsYsGenerator> for UnsignedDivisiblePairsGenerator { #[inline] fn get_ys(&self, y: &T) -> It { let y = *y; Box::new( exhaustive_unsigneds() .map(move |k| y.checked_mul(k)) .take_while(Option::is_some) .map(Option::unwrap), ) } } pub fn exhaustive_unsigned_pair_gen_var_8() -> It<(T, T)> { permute_2_1(Box::new(exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(1), ), exhaustive_positive_primitive_ints(), UnsignedDivisiblePairsGenerator { phantom: PhantomData, }, ))) } pub fn exhaustive_unsigned_pair_gen_var_9() -> T1 { Box::new(exhaustive_pairs( exhaustive_unsigneds(), exhaustive_positive_primitive_ints(), )) } pub fn exhaustive_unsigned_pair_gen_var_10() -> It<(T, T)> { Box::new( exhaustive_pairs( exhaustive_unsigneds::(), exhaustive_positive_primitive_ints::(), ) .filter(|&(x, y)| !x.divisible_by(y)), ) } pub fn exhaustive_unsigned_pair_gen_var_11() -> T1 { Box::new( exhaustive_pairs_big_tiny(exhaustive_unsigneds::(), exhaustive_unsigneds::()) .filter(|&(x, y)| !x.divisible_by_power_of_2(y.exact_into())), ) } struct UnsignedDivisibleByP2PairsGenerator { phantom: PhantomData<*const T>, } impl ExhaustiveDependentPairsYsGenerator> for UnsignedDivisibleByP2PairsGenerator { #[inline] fn get_ys(&self, pow: &u64) -> It { let pow = *pow; if pow >= T::WIDTH { Box::new(once(T::ZERO)) } else { Box::new( primitive_int_increasing_inclusive_range(T::ZERO, T::low_mask(T::WIDTH - pow)) .map(move |k| k << pow), ) } } } pub fn exhaustive_unsigned_pair_gen_var_12() -> It<(T, u64)> { permute_2_1(Box::new(exhaustive_dependent_pairs( ruler_sequence(), exhaustive_unsigneds(), UnsignedDivisibleByP2PairsGenerator { phantom: PhantomData, }, ))) } pub fn exhaustive_unsigned_pair_gen_var_13() -> It<(T, T)> { Box::new(exhaustive_ordered_unique_pairs(exhaustive_unsigneds())) } struct ModPowerOfTwoSingleGenerator { phantom: PhantomData<*const T>, } impl ExhaustiveDependentPairsYsGenerator> for ModPowerOfTwoSingleGenerator { #[inline] fn get_ys(&self, &pow: &u64) -> PrimitiveIntIncreasingRange { primitive_int_increasing_inclusive_range(T::ZERO, T::low_mask(pow)) } } struct ModPowerOfTwoSingleGenerator2 { phantom: PhantomData<*const T>, } impl ExhaustiveDependentPairsYsGenerator> for ModPowerOfTwoSingleGenerator2 { #[inline] fn get_ys(&self, &pow: &u64) -> PrimitiveIntIncreasingRange { primitive_int_increasing_inclusive_range(T::ONE, T::low_mask(pow)) } } pub fn exhaustive_unsigned_pair_gen_var_14() -> It<(T, u64)> { permute_2_1(Box::new(exhaustive_dependent_pairs( ruler_sequence(), primitive_int_increasing_inclusive_range(0, T::WIDTH), ModPowerOfTwoSingleGenerator { phantom: PhantomData, }, ))) } pub fn exhaustive_unsigned_pair_gen_var_15() -> It<(T, u64)> { Box::new( exhaustive_unsigneds() .map(|x| (T::ZERO, x)) .interleave(exhaustive_pairs_big_tiny( exhaustive_positive_primitive_ints(), primitive_int_increasing_range(0, T::WIDTH), )), ) } pub fn exhaustive_unsigned_pair_gen_var_16() -> It<(u64, u64)> { Box::new(exhaustive_pairs_from_single( primitive_int_increasing_inclusive_range(0, T::LARGEST_ORDERED_REPRESENTATION), )) } pub fn exhaustive_unsigned_pair_gen_var_17() -> It<(T, u64)> { Box::new(lex_pairs( exhaustive_unsigneds(), primitive_int_increasing_inclusive_range(0, U::WIDTH), )) } pub fn exhaustive_unsigned_pair_gen_var_18( ) -> It<(T, U)> { Box::new(exhaustive_pairs( primitive_int_increasing_inclusive_range(T::ZERO, T::saturating_from(u64::MAX)), exhaustive_positive_primitive_ints(), )) } pub fn exhaustive_unsigned_pair_gen_var_19() -> It<(u64, u64)> { Box::new(exhaustive_pairs( primitive_int_increasing_range(0, u64::power_of_2(T::MANTISSA_WIDTH)), primitive_int_increasing_range(0, u64::power_of_2(T::EXPONENT_WIDTH)), )) } pub fn exhaustive_unsigned_pair_gen_var_20() -> It<(T, T)> { Box::new(exhaustive_pairs_from_single(exhaustive_unsigneds())) } pub fn exhaustive_unsigned_pair_gen_var_21() -> It<(T, u64)> { Box::new( exhaustive_pairs(exhaustive_unsigneds::(), exhaustive_unsigneds()) .filter(|&(x, y)| x.checked_pow(y).is_some()), ) } pub fn exhaustive_unsigned_pair_gen_var_22() -> It<(T, u64)> { Box::new(exhaustive_unsigned_pair_gen_var_14().map(|(x, p)| (x, T::WIDTH - p))) } pub fn exhaustive_unsigned_pair_gen_var_23() -> It<(T, T)> { Box::new( exhaustive_pairs_from_single(exhaustive_unsigneds::()) .filter(|&(x, y)| x.checked_lcm(y).is_some()), ) } pub fn exhaustive_unsigned_pair_gen_var_24() -> It<(T, T)> { Box::new(exhaustive_pairs( primitive_int_increasing_inclusive_range(T::power_of_2(T::WIDTH - 1), T::MAX), exhaustive_unsigneds(), )) } pub fn exhaustive_unsigned_pair_gen_var_25() -> It<(T, T)> { Box::new( exhaustive_pairs(exhaustive_positive_primitive_ints(), exhaustive_unsigneds()) .filter(|&(x, y)| x != T::ONE || y != T::ZERO), ) } pub fn exhaustive_unsigned_pair_gen_var_26() -> It<(T, u64)> { permute_2_1(Box::new(exhaustive_dependent_pairs( ruler_sequence(), primitive_int_increasing_inclusive_range(1, T::WIDTH), ModPowerOfTwoSingleGenerator2 { phantom: PhantomData, }, ))) } pub fn exhaustive_unsigned_pair_gen_var_27() -> It<(T, T)> { Box::new(exhaustive_pairs( exhaustive_unsigneds(), primitive_int_increasing_inclusive_range(T::ZERO, T::low_mask(T::WIDTH - 1)) .map(|u| (u << 1) | T::ONE), )) } pub fn exhaustive_unsigned_pair_gen_var_28() -> It<(T, T)> { Box::new( exhaustive_pairs_from_single( primitive_int_increasing_inclusive_range(T::ZERO, T::low_mask(T::WIDTH - 1)) .map(|u| (u << 1) | T::ONE), ) .filter(|&(a, b): &(T, T)| a.coprime_with(b)), ) } pub fn exhaustive_unsigned_pair_gen_var_29() -> It<(T, T)> { Box::new( exhaustive_pairs_from_single(exhaustive_unsigneds()) .filter(|&(x, y): &(T, T)| x.coprime_with(y)), ) } struct MultifactorialNGenerator { phantom: PhantomData<*const T>, } impl ExhaustiveDependentPairsYsGenerator> for MultifactorialNGenerator { #[inline] fn get_ys(&self, &m: &u64) -> PrimitiveIntIncreasingRange { let limit = smallest_invalid_value(|n| T::checked_multifactorial(n, m)); primitive_int_increasing_range(0, limit) } } pub fn exhaustive_unsigned_pair_gen_var_30() -> It<(u64, u64)> { permute_2_1(Box::new(exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(1), ), exhaustive_positive_primitive_ints(), MultifactorialNGenerator { phantom: PhantomData::<*const T>, }, ))) } pub fn exhaustive_unsigned_pair_gen_var_31() -> It<(T, T)> { Box::new( exhaustive_pairs_from_single(exhaustive_unsigneds()) .filter(|&(n, k)| T::checked_binomial_coefficient(n, k).is_some()), ) } // var 32 is in malachite-nz. // -- (PrimitiveUnsigned, PrimitiveUnsigned, bool) -- pub fn exhaustive_unsigned_unsigned_bool_triple_gen_var_1( ) -> It<(T, u64, bool)> { Box::new( exhaustive_pairs_big_tiny(exhaustive_unsigneds(), exhaustive_unsigneds()) .map(|(x, y)| (x, y, false)) .interleave( lex_pairs( exhaustive_unsigneds(), primitive_int_increasing_range(0, T::WIDTH), ) .map(|(x, y)| (x, y, true)), ), ) } pub fn exhaustive_unsigned_unsigned_bool_triple_gen_var_2< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >() -> It<(T, U, bool)> { reshape_2_1_to_3(Box::new(lex_pairs( exhaustive_pairs(exhaustive_unsigneds(), exhaustive_positive_primitive_ints()), exhaustive_bools(), ))) } // -- (PrimitiveUnsigned, PrimitiveUnsigned, PrimitiveUnsigned) -- pub fn exhaustive_unsigned_triple_gen_var_1() -> It<(T, T, T)> { Box::new( exhaustive_triples_from_single(exhaustive_unsigneds()) .filter(|&(x, y, z)| add_mul_inputs_valid(x, y, z)), ) } pub fn exhaustive_unsigned_triple_gen_var_2() -> It<(T, T, T)> { Box::new( exhaustive_triples_from_single(exhaustive_unsigneds()) .filter(|&(x, y, z)| sub_mul_inputs_valid(x, y, z)), ) } pub fn exhaustive_unsigned_triple_gen_var_3( ) -> It<(T, T, U)> { Box::new(exhaustive_triples_xxy_custom_output( exhaustive_unsigneds(), exhaustive_unsigneds(), BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(1), BitDistributorOutputType::tiny(), )) } pub fn exhaustive_unsigned_triple_gen_var_4( ) -> It<(T, U, U)> { Box::new( exhaustive_triples_xyy_custom_output( exhaustive_unsigneds(), exhaustive_unsigneds(), BitDistributorOutputType::normal(1), BitDistributorOutputType::tiny(), BitDistributorOutputType::tiny(), ) .filter_map(|(x, y, z): (T, U, U)| y.checked_add(z).map(|new_z| (x, y, new_z))), ) } pub fn exhaustive_unsigned_triple_gen_var_5< T: PrimitiveUnsigned, U: ExactFrom + PrimitiveUnsigned, V: PrimitiveUnsigned, >() -> It<(T, U, V)> { permute_1_3_2(reshape_2_1_to_3(Box::new(lex_pairs( exhaustive_pairs_big_tiny(exhaustive_unsigneds(), exhaustive_unsigneds()), primitive_int_increasing_inclusive_range(U::TWO, U::exact_from(36u8)), )))) } struct UnsignedModEqTriplesInnerGenerator { phantom: PhantomData<*const T>, } impl ExhaustiveDependentPairsYsGenerator<(T, T), (T, T), It<(T, T)>> for UnsignedModEqTriplesInnerGenerator { #[inline] fn get_ys(&self, p: &(T, T)) -> It<(T, T)> { let &(m, k) = p; if k == T::ZERO { Box::new(exhaustive_unsigneds().map(|x| (x, x))) } else { let d = m.checked_mul(k).unwrap(); Box::new( primitive_int_increasing_inclusive_range(T::ZERO, T::MAX - d) .map(move |n| (n, n + d)) .interleave( primitive_int_increasing_inclusive_range(T::ZERO, T::MAX - d) .map(move |n| (n + d, n)), ), ) } } } struct UnsignedModEqTriplesGenerator { phantom: PhantomData<*const T>, } impl ExhaustiveDependentPairsYsGenerator> for UnsignedModEqTriplesGenerator { #[inline] fn get_ys(&self, m: &T) -> It<(T, T)> { let m = *m; if m == T::ZERO { Box::new(exhaustive_unsigneds().map(|x| (x, x))) } else { Box::new( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(1), ), primitive_int_increasing_inclusive_range(T::ZERO, T::MAX / m) .map(move |k| (m, k)), UnsignedModEqTriplesInnerGenerator { phantom: PhantomData, }, ) .map(|p| p.1), ) } } } pub fn exhaustive_unsigned_triple_gen_var_6() -> It<(T, T, T)> { reshape_2_1_to_3(permute_2_1(Box::new(exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(1), ), exhaustive_unsigneds(), UnsignedModEqTriplesGenerator { phantom: PhantomData, }, )))) } pub fn exhaustive_unsigned_triple_gen_var_7() -> It<(T, T, T)> { Box::new( exhaustive_triples_from_single(exhaustive_unsigneds::()) .filter(|&(x, y, m)| !x.eq_mod(y, m)), ) } struct UnsignedModPow2EqTriplesInnerGenerator { phantom: PhantomData<*const T>, } impl ExhaustiveDependentPairsYsGenerator<(u64, T), (T, T), It<(T, T)>> for UnsignedModPow2EqTriplesInnerGenerator { #[inline] fn get_ys(&self, p: &(u64, T)) -> It<(T, T)> { let &(pow, k) = p; if k == T::ZERO { Box::new(exhaustive_unsigneds().map(|x| (x, x))) } else { let d = k << pow; Box::new( primitive_int_increasing_inclusive_range(T::ZERO, T::MAX - d) .map(move |n| (n, n + d)) .interleave( primitive_int_increasing_inclusive_range(T::ZERO, T::MAX - d) .map(move |n| (n + d, n)), ), ) } } } struct UnsignedModPow2EqTriplesGenerator { phantom: PhantomData<*const T>, } impl ExhaustiveDependentPairsYsGenerator> for UnsignedModPow2EqTriplesGenerator { #[inline] fn get_ys(&self, pow: &u64) -> It<(T, T)> { let pow = *pow; if pow >= T::WIDTH { Box::new(exhaustive_unsigneds().map(|x| (x, x))) } else { Box::new( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(1), ), primitive_int_increasing_inclusive_range(T::ZERO, T::MAX >> pow) .map(move |k| (pow, k)), UnsignedModPow2EqTriplesInnerGenerator { phantom: PhantomData, }, ) .map(|p| p.1), ) } } } pub fn exhaustive_unsigned_triple_gen_var_8() -> It<(T, T, u64)> { reshape_2_1_to_3(permute_2_1(Box::new(exhaustive_dependent_pairs( ruler_sequence(), exhaustive_unsigneds(), UnsignedModPow2EqTriplesGenerator { phantom: PhantomData, }, )))) } pub fn exhaustive_unsigned_triple_gen_var_9() -> It<(T, T, u64)> { Box::new( exhaustive_triples_xxy_custom_output( exhaustive_unsigneds::(), exhaustive_unsigneds(), BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(1), BitDistributorOutputType::tiny(), ) .filter(|&(x, y, pow)| !x.eq_mod_power_of_2(y, pow)), ) } struct ModPowerOfTwoPairGenerator { phantom: PhantomData<*const T>, } impl ExhaustiveDependentPairsYsGenerator< u64, (T, T), ExhaustivePairs1Input>, > for ModPowerOfTwoPairGenerator { #[inline] fn get_ys(&self, &pow: &u64) -> ExhaustivePairs1Input> { exhaustive_pairs_from_single(primitive_int_increasing_inclusive_range( T::ZERO, T::low_mask(pow), )) } } pub fn exhaustive_unsigned_triple_gen_var_10() -> It<(T, T, u64)> { reshape_2_1_to_3(permute_2_1(Box::new(exhaustive_dependent_pairs( ruler_sequence(), primitive_int_increasing_inclusive_range(0, T::WIDTH), ModPowerOfTwoPairGenerator { phantom: PhantomData, }, )))) } pub fn exhaustive_unsigned_triple_gen_var_11() -> It<(T, T, T)> { Box::new( exhaustive_triples_from_single(exhaustive_unsigneds::()) .filter_map(|(x, y, z)| Some((x, y, max(x, y).checked_add(z)?.checked_add(T::ONE)?))), ) } pub fn exhaustive_unsigned_triple_gen_var_12( ) -> It<(T, U, U)> { Box::new(exhaustive_triples_xyy_custom_output( exhaustive_unsigneds(), exhaustive_unsigneds(), BitDistributorOutputType::normal(1), BitDistributorOutputType::tiny(), BitDistributorOutputType::tiny(), )) } pub fn exhaustive_unsigned_triple_gen_var_13( ) -> It<(T, U, T)> { Box::new( exhaustive_triples_xyx_custom_output( exhaustive_unsigneds(), exhaustive_unsigneds(), BitDistributorOutputType::normal(1), BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ) .filter_map(|(x, y, z): (T, U, T)| Some((x, y, x.checked_add(z)?.checked_add(T::ONE)?))), ) } pub fn exhaustive_unsigned_triple_gen_var_14( ) -> It<(T, U, T)> { Box::new( exhaustive_triples_xyx(exhaustive_unsigneds(), exhaustive_unsigneds()).filter_map( |(x, y, z): (T, U, T)| Some((x, y, x.checked_add(z)?.checked_add(T::ONE)?)), ), ) } struct ModPowerOfTwoPairWithExtraUnsignedGenerator { phantom_t: PhantomData<*const T>, phantom_u: PhantomData<*const U>, } impl ExhaustiveDependentPairsYsGenerator< u64, (T, U), ExhaustivePairs, U, PrimitiveIntIncreasingRange>, > for ModPowerOfTwoPairWithExtraUnsignedGenerator { #[inline] fn get_ys( &self, &pow: &u64, ) -> ExhaustivePairs, U, PrimitiveIntIncreasingRange> { exhaustive_pairs( primitive_int_increasing_inclusive_range(T::ZERO, T::low_mask(pow)), exhaustive_unsigneds(), ) } } pub fn exhaustive_unsigned_triple_gen_var_15( ) -> It<(T, U, u64)> { reshape_2_1_to_3(permute_2_1(Box::new(exhaustive_dependent_pairs( ruler_sequence(), primitive_int_increasing_inclusive_range(0, T::WIDTH), ModPowerOfTwoPairWithExtraUnsignedGenerator:: { phantom_t: PhantomData, phantom_u: PhantomData, }, )))) } pub fn exhaustive_unsigned_triple_gen_var_16( ) -> It<(T, U, T)> { Box::new( exhaustive_triples_xyx( exhaustive_unsigneds(), primitive_int_increasing_inclusive_range(U::ZERO, U::saturating_from(u64::MAX)), ) .filter_map(|(x, y, z): (T, U, T)| Some((x, y, x.checked_add(z)?.checked_add(T::ONE)?))), ) } pub fn exhaustive_unsigned_triple_gen_var_17() -> It<(T, T, T)> { Box::new(exhaustive_triples_from_single(exhaustive_unsigneds())) } pub fn exhaustive_unsigned_triple_gen_var_18() -> It<(T, T, T)> { Box::new(exhaustive_triples_xyx( exhaustive_unsigneds(), primitive_int_increasing_inclusive_range(T::ZERO, T::low_mask(T::WIDTH - 1)) .map(|u| (u << 1) | T::ONE), )) } pub fn exhaustive_unsigned_triple_gen_var_19() -> It<(T, T, T)> { Box::new(exhaustive_triples_xxy( exhaustive_unsigneds(), primitive_int_increasing_inclusive_range(T::ZERO, T::low_mask(T::WIDTH - 1)) .map(|u| (u << 1) | T::ONE), )) } pub fn exhaustive_unsigned_triple_gen_var_20() -> It<(T, T, T)> { Box::new(exhaustive_triples_xyy( exhaustive_unsigneds(), primitive_int_increasing_inclusive_range(T::ZERO, T::low_mask(T::WIDTH - 1)) .map(|u| (u << 1) | T::ONE), )) } // -- (PrimitiveUnsigned, PrimitiveUnsigned, PrimitiveUnsigned, PrimitiveUnsigned) -- pub fn exhaustive_unsigned_quadruple_gen_var_1( ) -> It<(T, u64, u64, U)> { Box::new( exhaustive_quadruples_xyyz_custom_output( exhaustive_unsigneds(), exhaustive_unsigneds(), exhaustive_unsigneds(), BitDistributorOutputType::normal(1), BitDistributorOutputType::tiny(), BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ) .filter_map(|(x, y, z, w): (T, u64, u64, U)| { y.checked_add(z).and_then(|new_z| { if unsigned_assign_bits_valid(y, new_z, w) { Some((x, y, new_z, w)) } else { None } }) }), ) } pub fn exhaustive_unsigned_quadruple_gen_var_2( ) -> It<(T, T, T, U)> { Box::new(exhaustive_quadruples_xxxy_custom_output( exhaustive_unsigneds(), exhaustive_unsigneds(), BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(1), BitDistributorOutputType::tiny(), )) } struct ModPowerOfTwoTripleGenerator { phantom: PhantomData<*const T>, } impl ExhaustiveDependentPairsYsGenerator< u64, (T, T, T), ExhaustiveTriples1Input>, > for ModPowerOfTwoTripleGenerator { #[inline] fn get_ys(&self, &pow: &u64) -> ExhaustiveTriples1Input> { exhaustive_triples_from_single(primitive_int_increasing_inclusive_range( T::ZERO, T::low_mask(pow), )) } } pub fn exhaustive_unsigned_quadruple_gen_var_3() -> It<(T, T, T, u64)> { reshape_3_1_to_4(permute_2_1(Box::new(exhaustive_dependent_pairs( ruler_sequence(), primitive_int_increasing_inclusive_range(0, T::WIDTH), ModPowerOfTwoTripleGenerator { phantom: PhantomData, }, )))) } pub fn exhaustive_unsigned_quadruple_gen_var_4() -> It<(T, T, T, T)> { Box::new( exhaustive_quadruples_from_single(exhaustive_unsigneds::()).filter_map( |(x, y, z, w)| Some((x, y, z, max!(x, y, z).checked_add(w)?.checked_add(T::ONE)?)), ), ) } pub fn exhaustive_unsigned_quadruple_gen_var_5< T: TryFrom
+ PrimitiveUnsigned, DT: From + HasHalf + JoinHalves + PrimitiveUnsigned + SplitInHalf, >() -> It<(T, T, T, T)> { Box::new( exhaustive_triples_xxy(exhaustive_unsigneds(), exhaustive_positive_primitive_ints()).map( |(x_1, x_0, d)| { let inv = limbs_invert_limb_naive::(d << LeadingZeros::leading_zeros(d)); (x_1, x_0, d, inv) }, ), ) } pub fn exhaustive_unsigned_quadruple_gen_var_6( ) -> It<(T, T, U, T)> { Box::new( exhaustive_quadruples_xxyx(exhaustive_unsigneds::(), exhaustive_unsigneds::()) .filter_map(|(x, y, z, w)| { Some((x, y, z, max(x, y).checked_add(w)?.checked_add(T::ONE)?)) }), ) } pub fn exhaustive_unsigned_quadruple_gen_var_7( ) -> It<(T, U, U, T)> { Box::new( exhaustive_quadruples_xyyx(exhaustive_unsigneds::(), exhaustive_unsigneds::()) .filter_map(|(x, y, z, w)| Some((x, y, z, x.checked_add(w)?.checked_add(T::ONE)?))), ) } struct ModPowerOfTwoTripleWithExtraUnsignedGenerator { phantom_t: PhantomData<*const T>, phantom_u: PhantomData<*const U>, } impl ExhaustiveDependentPairsYsGenerator< u64, (T, T, U), ExhaustiveTriplesXXY, U, PrimitiveIntIncreasingRange>, > for ModPowerOfTwoTripleWithExtraUnsignedGenerator { #[inline] fn get_ys( &self, &pow: &u64, ) -> ExhaustiveTriplesXXY, U, PrimitiveIntIncreasingRange> { exhaustive_triples_xxy( primitive_int_increasing_inclusive_range(T::ZERO, T::low_mask(pow)), exhaustive_unsigneds(), ) } } pub fn exhaustive_unsigned_quadruple_gen_var_8( ) -> It<(T, T, U, u64)> { reshape_3_1_to_4(permute_2_1(Box::new(exhaustive_dependent_pairs( ruler_sequence(), primitive_int_increasing_inclusive_range(0, T::WIDTH), ModPowerOfTwoTripleWithExtraUnsignedGenerator:: { phantom_t: PhantomData, phantom_u: PhantomData, }, )))) } struct ModPowerOfTwoQuadrupleWithTwoExtraUnsignedsGenerator< T: PrimitiveUnsigned, U: PrimitiveUnsigned, > { phantom_t: PhantomData<*const T>, phantom_u: PhantomData<*const U>, } impl ExhaustiveDependentPairsYsGenerator< u64, (T, U, U), ExhaustiveTriplesXYY, U, PrimitiveIntIncreasingRange>, > for ModPowerOfTwoQuadrupleWithTwoExtraUnsignedsGenerator { #[inline] fn get_ys( &self, &pow: &u64, ) -> ExhaustiveTriplesXYY, U, PrimitiveIntIncreasingRange> { exhaustive_triples_xyy( primitive_int_increasing_inclusive_range(T::ZERO, T::low_mask(pow)), exhaustive_unsigneds(), ) } } pub fn exhaustive_unsigned_quadruple_gen_var_9( ) -> It<(T, U, U, u64)> { reshape_3_1_to_4(permute_2_1(Box::new(exhaustive_dependent_pairs( ruler_sequence(), primitive_int_increasing_inclusive_range(0, T::WIDTH), ModPowerOfTwoQuadrupleWithTwoExtraUnsignedsGenerator:: { phantom_t: PhantomData, phantom_u: PhantomData, }, )))) } pub fn exhaustive_unsigned_quadruple_gen_var_10() -> It<(T, T, T, T)> { Box::new(exhaustive_quadruples_from_single(exhaustive_unsigneds())) } pub fn exhaustive_unsigned_quadruple_gen_var_11() -> It<(T, T, T, T)> { Box::new( exhaustive_quadruples_from_single(exhaustive_unsigneds()).filter(|&(n1, n0, d1, d0)| { // conditions: D >= 2^W, N >= D, and N / D < 2^W d1 != T::ZERO && (n1 > d1 || n1 == d1 && n0 >= d0) }), ) } pub fn exhaustive_unsigned_quadruple_gen_var_12() -> It<(T, T, T, T)> { Box::new(exhaustive_quadruples_xxxy( exhaustive_unsigneds(), primitive_int_increasing_inclusive_range(T::ZERO, T::low_mask(T::WIDTH - 1)) .map(|u| (u << 1) | T::ONE), )) } // -- (PrimitiveUnsigned * 6) -- pub fn exhaustive_unsigned_sextuple_gen_var_1() -> It<(T, T, T, T, T, T)> { Box::new(exhaustive_sextuples_from_single(exhaustive_unsigneds())) } // var 2 is in malachite-nz. // -- (PrimitiveUnsigned * 8) -- #[allow(clippy::type_complexity)] pub fn exhaustive_unsigned_octuple_gen_var_1() -> It<(T, T, T, T, T, T, T, T)> { Box::new(exhaustive_octuples_from_single(exhaustive_unsigneds())) } // -- (PrimitiveUnsigned * 9) -- #[allow(clippy::type_complexity)] pub fn exhaustive_unsigned_nonuple_gen_var_1( ) -> It<(T, T, T, T, T, T, T, T, T)> { Box::new( exhaustive_triples_from_single(exhaustive_triples_from_single(exhaustive_unsigneds())) .map(|((a, b, c), (d, e, f), (g, h, i))| (a, b, c, d, e, f, g, h, i)), ) } // -- (PrimitiveUnsigned * 12) -- #[allow(clippy::type_complexity)] pub fn exhaustive_unsigned_duodecuple_gen_var_1( ) -> It<(T, T, T, T, T, T, T, T, T, T, T, T)> { Box::new(exhaustive_duodecuples_from_single(exhaustive_unsigneds())) } // -- (PrimitiveUnsigned, PrimitiveUnsigned, RoundingMode) -- pub fn exhaustive_unsigned_unsigned_rounding_mode_triple_gen_var_1( ) -> It<(T, T, RoundingMode)> { reshape_2_1_to_3(Box::new( lex_pairs( exhaustive_pairs( exhaustive_unsigneds::(), exhaustive_positive_primitive_ints::(), ), exhaustive_rounding_modes(), ) .filter(|&((x, y), rm)| rm != Exact || x.divisible_by(y)), )) } pub(crate) fn round_to_multiple_unsigned_filter_map( x: T, y: T, rm: RoundingMode, ) -> Option<(T, T, RoundingMode)> { if x == y { Some((x, y, rm)) } else if y == T::ZERO { if rm == Floor || rm == Down || rm == Nearest { Some((x, y, rm)) } else { None } } else if rm != Exact { x.div_round(y, rm).0.checked_mul(y).map(|_| (x, y, rm)) } else { x.checked_mul(y).map(|product| (product, y, rm)) } } pub(crate) fn round_to_multiple_of_power_of_2_filter_map( n: T, u: u64, rm: RoundingMode, ) -> Option<(T, u64, RoundingMode)> { if n == T::ZERO || rm != Exact { n.shr_round(u, rm) .0 .arithmetic_checked_shl(u) .map(|_| (n, u, rm)) } else { n.arithmetic_checked_shl(u).map(|shifted| (shifted, u, rm)) } } pub fn exhaustive_unsigned_unsigned_rounding_mode_triple_gen_var_3( ) -> It<(T, T, RoundingMode)> { Box::new( lex_pairs( exhaustive_pairs( exhaustive_unsigneds::(), exhaustive_positive_primitive_ints::(), ), exhaustive_rounding_modes(), ) .filter_map(|((x, y), rm)| round_to_multiple_unsigned_filter_map(x, y, rm)), ) } pub fn exhaustive_unsigned_unsigned_rounding_mode_triple_gen_var_4( ) -> It<(T, u64, RoundingMode)> { Box::new( lex_pairs( exhaustive_pairs_big_small(exhaustive_unsigneds::(), exhaustive_unsigneds::()), exhaustive_rounding_modes(), ) .filter_map(|((x, pow), rm)| round_to_multiple_of_power_of_2_filter_map(x, pow, rm)), ) } pub fn exhaustive_unsigned_unsigned_rounding_mode_triple_gen_var_5< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >() -> It<(T, U, RoundingMode)> { reshape_2_1_to_3(Box::new( lex_pairs( exhaustive_pairs_big_small(exhaustive_unsigneds::(), exhaustive_unsigneds::()), exhaustive_rounding_modes(), ) .filter(|&((x, y), rm)| rm != Exact || x.divisible_by_power_of_2(y.exact_into())), )) } // var 6 is in malachite-float. // -- (PrimitiveUnsigned, PrimitiveUnsigned, Vec) -- struct UnsignedUnsignedBoolVecTripleGeneratorVar1; impl ExhaustiveDependentPairsYsGenerator< (T, u64), Vec, LexFixedLengthVecsFromSingle, > for UnsignedUnsignedBoolVecTripleGeneratorVar1 { #[inline] fn get_ys(&self, &(x, log_base): &(T, u64)) -> LexFixedLengthVecsFromSingle { lex_vecs_fixed_length_from_single( x.significant_bits().div_round(log_base, Ceiling).0, exhaustive_bools(), ) } } pub fn exhaustive_unsigned_unsigned_bool_vec_triple_gen_var_1< T: PrimitiveUnsigned, U: PrimitiveInt, >() -> It<(T, u64, Vec)> { reshape_2_1_to_3(Box::new(exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(1), ), lex_pairs( exhaustive_unsigneds(), primitive_int_increasing_inclusive_range(1, U::WIDTH), ), UnsignedUnsignedBoolVecTripleGeneratorVar1, ))) } // -- (PrimitiveUnsigned, RoundingMode) -- pub fn exhaustive_unsigned_rounding_mode_pair_gen() -> It<(T, RoundingMode)> { Box::new(lex_pairs( exhaustive_unsigneds(), exhaustive_rounding_modes(), )) } pub fn exhaustive_unsigned_rounding_mode_pair_gen_var_1< T: PrimitiveUnsigned, U: ConvertibleFrom + PrimitiveFloat, >() -> It<(T, RoundingMode)> { Box::new( lex_pairs(exhaustive_unsigneds(), exhaustive_rounding_modes()) .filter(move |&(u, rm)| rm != Exact || U::convertible_from(u)), ) } // -- (PrimitiveUnsigned, String) -- pub fn valid_digit_chars(base: u8) -> Vec { let mut chars = Vec::new(); if base <= 10 { chars.extend('0'..char::from(base + b'0')); } else { chars.extend('0'..='9'); chars.extend('a'..char::from(base - 10 + b'a')); chars.extend('A'..char::from(base - 10 + b'A')); } chars } struct DigitStringGenerator; impl ExhaustiveDependentPairsYsGenerator< u8, String, StringsFromCharVecs, IntoIter>>, > for DigitStringGenerator { #[inline] fn get_ys( &self, &base: &u8, ) -> StringsFromCharVecs, IntoIter>> { assert!((2..=36).contains(&base)); strings_from_char_vecs(exhaustive_vecs_min_length( 1, valid_digit_chars(base).into_iter(), )) } } pub fn exhaustive_unsigned_string_pair_gen_var_1() -> It<(u8, String)> { Box::new(exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(1), ), primitive_int_increasing_inclusive_range(2, 36), DigitStringGenerator, )) } pub fn exhaustive_unsigned_string_pair_gen_var_2() -> It<(u8, String)> { Box::new(exhaustive_pairs( primitive_int_increasing_inclusive_range(2, 36), exhaustive_strings(), )) } struct TargetedIntegerFromStringBaseInputs { neg: bool, u: u8, s: String, uss: It<(u8, String)>, } impl Iterator for TargetedIntegerFromStringBaseInputs { type Item = (u8, String); fn next(&mut self) -> Option<(u8, String)> { Some(if self.neg { self.neg = false; let next = self.uss.next().unwrap(); self.u = next.0; self.s = next.1; (self.u, self.s.clone()) } else { self.neg = true; let mut s = '-'.to_string(); s.push_str(&self.s); (self.u, s) }) } } pub fn exhaustive_unsigned_string_pair_gen_var_3() -> It<(u8, String)> { Box::new(TargetedIntegerFromStringBaseInputs { neg: true, u: 0, s: String::new(), uss: exhaustive_unsigned_string_pair_gen_var_1(), }) } // -- (PrimitiveUnsigned, ToSciOptions) -- pub fn exhaustive_unsigned_to_sci_options_pair_gen() -> It<(T, ToSciOptions)> { Box::new(exhaustive_pairs( exhaustive_unsigneds(), exhaustive_to_sci_options(), )) } pub fn exhaustive_unsigned_to_sci_options_pair_gen_var_1( ) -> It<(T, ToSciOptions)> { Box::new( exhaustive_pairs(exhaustive_unsigneds::(), exhaustive_to_sci_options()) .filter(|(x, options)| x.fmt_sci_valid(*options)), ) } // -- (PrimitiveUnsigned, Vec) -- struct UnsignedBoolVecPairGeneratorVar1; impl ExhaustiveDependentPairsYsGenerator, LexFixedLengthVecsFromSingle> for UnsignedBoolVecPairGeneratorVar1 { #[inline] fn get_ys(&self, &x: &T) -> LexFixedLengthVecsFromSingle { lex_vecs_fixed_length_from_single(x.significant_bits(), exhaustive_bools()) } } pub fn exhaustive_unsigned_bool_vec_pair_gen_var_1() -> It<(T, Vec)> { Box::new(exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(1), ), exhaustive_unsigneds(), UnsignedBoolVecPairGeneratorVar1, )) } // -- RationalSequence -- pub fn exhaustive_unsigned_rational_sequence_gen() -> It> { Box::new(exhaustive_rational_sequences(exhaustive_unsigneds())) } // -- (RationalSequence, PrimitiveUnsigned) -- pub fn exhaustive_unsigned_rational_sequence_unsigned_pair_gen_var_1< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >() -> It<(RationalSequence, U)> { Box::new(exhaustive_pairs_big_tiny( exhaustive_rational_sequences(exhaustive_unsigneds()), exhaustive_unsigneds(), )) } pub fn exhaustive_unsigned_rational_sequence_unsigned_pair_gen_var_2( ) -> It<(RationalSequence, usize)> { Box::new( exhaustive_pairs_big_tiny( exhaustive_rational_sequences(exhaustive_unsigneds()), exhaustive_unsigneds(), ) .filter(|&(ref xs, i)| { if let Some(len) = xs.len() { i < len } else { true } }), ) } // -- (RationalSequence, RationalSequence) -- pub fn exhaustive_unsigned_rational_sequence_pair_gen( ) -> It<(RationalSequence, RationalSequence)> { Box::new(exhaustive_pairs_from_single(exhaustive_rational_sequences( exhaustive_unsigneds(), ))) } // -- RationalSequence * 3 -- pub fn exhaustive_unsigned_rational_sequence_triple_gen() -> It<( RationalSequence, RationalSequence, RationalSequence, )> { Box::new(exhaustive_triples_from_single( exhaustive_rational_sequences(exhaustive_unsigneds()), )) } // -- RoundingMode -- pub fn exhaustive_rounding_mode_gen() -> It { Box::new(exhaustive_rounding_modes()) } // -- (RoundingMode, RoundingMode) -- pub fn exhaustive_rounding_mode_pair_gen() -> It<(RoundingMode, RoundingMode)> { Box::new(lex_pairs_from_single(exhaustive_rounding_modes())) } // -- (RoundingMode, RoundingMode, RoundingMode) -- pub fn exhaustive_rounding_mode_triple_gen() -> It<(RoundingMode, RoundingMode, RoundingMode)> { Box::new(lex_triples_from_single(exhaustive_rounding_modes())) } // -- SciSizeOptions -- pub fn exhaustive_sci_size_options_gen() -> It { Box::new(exhaustive_sci_size_options()) } // -- String -- pub fn exhaustive_string_gen() -> It { Box::new(exhaustive_strings()) } pub fn exhaustive_string_gen_var_1() -> It { Box::new(exhaustive_strings_using_chars(exhaustive_ascii_chars())) } pub fn exhaustive_string_gen_var_2() -> It { Box::new(exhaustive_strings_using_chars(ROUNDING_MODE_CHARS.chars())) } pub fn exhaustive_string_gen_var_3() -> It { Box::new(strings_from_char_vecs(exhaustive_vecs_min_length( 1, '0'..='9', ))) } struct TargetedIntegerFromStrStringsVar1 { neg: bool, s: String, ss: It, } impl Iterator for TargetedIntegerFromStrStringsVar1 { type Item = String; fn next(&mut self) -> Option { Some(if self.neg { self.neg = false; self.s = self.ss.next().unwrap(); self.s.clone() } else { self.neg = true; format!("-{}", self.s) }) } } pub fn exhaustive_string_gen_var_4() -> It { Box::new(TargetedIntegerFromStrStringsVar1 { neg: true, s: String::new(), ss: exhaustive_string_gen_var_3(), }) } pub fn exhaustive_string_gen_var_5() -> It { Box::new(strings_from_char_vecs(exhaustive_vecs_min_length( 1, '0'..='1', ))) } pub fn exhaustive_string_gen_var_6() -> It { Box::new(strings_from_char_vecs(exhaustive_vecs_min_length( 1, '0'..='7', ))) } pub fn exhaustive_string_gen_var_7() -> It { Box::new(strings_from_char_vecs(exhaustive_vecs_min_length( 1, lex_union3s('0'..='9', 'a'..='f', 'A'..='F').map(Union3::unwrap), ))) } pub fn exhaustive_string_gen_var_8() -> It { Box::new( strings_from_char_vecs(exhaustive_vecs_min_length( 1, lex_union3s('0'..='9', 'a'..='f', 'A'..='F').map(Union3::unwrap), )) .map(|s| format!("\"0x{s}\"")), ) } struct TargetedIntegerFromStrStringsVar2 { neg: bool, s: String, ss: It, } impl Iterator for TargetedIntegerFromStrStringsVar2 { type Item = String; fn next(&mut self) -> Option { Some(if self.neg { self.neg = false; self.s = self.ss.next().unwrap(); format!("\"0x{}\"", self.s) } else { self.neg = true; format!("\"-0x{}\"", self.s) }) } } pub fn exhaustive_string_gen_var_9() -> It { Box::new(TargetedIntegerFromStrStringsVar2 { neg: true, s: String::new(), ss: exhaustive_string_gen_var_7(), }) } pub fn exhaustive_string_gen_var_10() -> It { Box::new(exhaustive_strings_using_chars( PRIMITIVE_FLOAT_CHARS.chars(), )) } // vars 11 through 12 are in malachite-q. pub fn exhaustive_string_gen_var_13() -> It { Box::new(exhaustive_strings_using_chars( DECIMAL_SCI_STRING_CHARS.chars(), )) } pub fn exhaustive_string_gen_var_14() -> It { Box::new(exhaustive_strings().filter(|s| !large_exponent(s))) } pub fn exhaustive_string_gen_var_15() -> It { Box::new( exhaustive_strings_using_chars(DECIMAL_SCI_STRING_CHARS.chars()) .filter(|s| !large_exponent(s)), ) } // -- (String, FromSciStringOptions) -- pub fn exhaustive_string_from_sci_string_options_pair_gen() -> It<(String, FromSciStringOptions)> { Box::new(exhaustive_pairs( exhaustive_strings(), exhaustive_from_sci_string_options(), )) } struct SciDigitStringGenerator; impl ExhaustiveDependentPairsYsGenerator< FromSciStringOptions, String, StringsFromCharVecs, IntoIter>>, > for SciDigitStringGenerator { #[inline] fn get_ys( &self, &options: &FromSciStringOptions, ) -> StringsFromCharVecs, IntoIter>> { let base = options.get_base(); let mut cs = vec!['+', '-', '.']; if base < 15 { cs.push('e'); cs.push('E'); } cs.extend(valid_digit_chars(base)); assert!((2..=36).contains(&base)); strings_from_char_vecs(exhaustive_vecs_min_length(1, cs.into_iter())) } } struct SciDigitStringGenerator2; impl ExhaustiveDependentPairsYsGenerator< u8, String, StringsFromCharVecs, IntoIter>>, > for SciDigitStringGenerator2 { #[inline] fn get_ys( &self, &base: &u8, ) -> StringsFromCharVecs, IntoIter>> { let mut cs = vec!['+', '-', '.']; if base < 15 { cs.push('e'); cs.push('E'); } cs.extend(valid_digit_chars(base)); assert!((2..=36).contains(&base)); strings_from_char_vecs(exhaustive_vecs_min_length(1, cs.into_iter())) } } pub fn exhaustive_string_from_sci_string_options_pair_gen_var_1( ) -> It<(String, FromSciStringOptions)> { permute_2_1(Box::new(exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(1), ), exhaustive_from_sci_string_options(), SciDigitStringGenerator, ))) } pub fn exhaustive_string_from_sci_string_options_pair_gen_var_2( ) -> It<(String, FromSciStringOptions)> { Box::new(exhaustive_pairs( exhaustive_strings().filter(|s| !large_exponent(s)), exhaustive_from_sci_string_options(), )) } pub fn exhaustive_string_from_sci_string_options_pair_gen_var_3( ) -> It<(String, FromSciStringOptions)> { permute_2_1(Box::new( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(1), ), exhaustive_from_sci_string_options(), SciDigitStringGenerator, ) .filter(|(_, s)| !large_exponent(s)), )) } // -- (String, PrimitiveUnsigned) -- pub fn exhaustive_string_unsigned_pair_gen_var_1() -> It<(String, u8)> { Box::new(exhaustive_pairs( exhaustive_strings().filter(|s| !large_exponent(s)), primitive_int_increasing_inclusive_range(2, 36), )) } pub fn exhaustive_string_unsigned_pair_gen_var_2() -> It<(String, u8)> { permute_2_1(Box::new( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(1), ), primitive_int_increasing_inclusive_range(2, 36), SciDigitStringGenerator2, ) .filter(|(_, s)| !large_exponent(s)), )) } // -- (String, String) -- pub fn exhaustive_string_pair_gen() -> It<(String, String)> { Box::new(exhaustive_pairs_from_single(exhaustive_strings())) } pub fn exhaustive_string_pair_gen_var_1() -> It<(String, String)> { Box::new(exhaustive_pairs_from_single( exhaustive_strings_using_chars(exhaustive_ascii_chars()), )) } // -- ToSciOptions -- pub fn exhaustive_to_sci_options_gen() -> It { Box::new(exhaustive_to_sci_options()) } // -- (ToSciOptions, bool) -- pub fn exhaustive_to_sci_options_bool_pair_gen() -> It<(ToSciOptions, bool)> { Box::new(lex_pairs(exhaustive_to_sci_options(), exhaustive_bools())) } // -- (ToSciOptions, PrimitiveInt) -- pub fn exhaustive_to_sci_options_primitive_int_pair_gen_var_1( ) -> It<(ToSciOptions, T)> { Box::new(exhaustive_pairs_big_tiny( exhaustive_to_sci_options(), exhaustive_positive_primitive_ints(), )) } // -- (ToSciOptions, PrimitiveSigned) -- pub fn exhaustive_to_sci_options_signed_pair_gen_var_1() -> It<(TSO, T)> { Box::new(exhaustive_pairs_big_tiny( exhaustive_to_sci_options(), exhaustive_negative_signeds(), )) } // -- (ToSciOptions, PrimitiveUnsigned) -- pub fn exhaustive_to_sci_options_unsigned_pair_gen_var_1( ) -> It<(ToSciOptions, T)> { Box::new(exhaustive_pairs( exhaustive_to_sci_options(), primitive_int_increasing_inclusive_range(T::TWO, T::from(36u8)), )) } pub fn exhaustive_to_sci_options_unsigned_pair_gen_var_2( ) -> It<(ToSciOptions, T)> { Box::new(exhaustive_pairs_big_tiny( exhaustive_to_sci_options(), exhaustive_unsigneds(), )) } // -- (ToSciOptions, RoundingMode) -- pub fn exhaustive_to_sci_options_rounding_mode_pair_gen() -> It<(ToSciOptions, RoundingMode)> { Box::new(exhaustive_pairs( exhaustive_to_sci_options(), exhaustive_rounding_modes(), )) } // -- Vec -- pub fn exhaustive_bool_vec_gen() -> It> { Box::new(shortlex_vecs(exhaustive_bools())) } pub fn exhaustive_bool_vec_gen_var_1() -> It> { Box::new( shortlex_vecs_length_inclusive_range(0, T::WIDTH, exhaustive_bools()).interleave( exhaustive_pairs_big_tiny( lex_vecs_fixed_length_from_single(T::WIDTH, exhaustive_bools()), exhaustive_positive_primitive_ints(), ) .map(|(bs, n)| bs.into_iter().chain(repeat_n(false, n)).collect()), ), ) } pub fn exhaustive_bool_vec_gen_var_2() -> It> { Box::new( shortlex_vecs_length_inclusive_range(0, T::WIDTH - 1, exhaustive_bools()).interleave( exhaustive_pairs_big_tiny( lex_vecs_fixed_length_from_single(T::WIDTH - 1, exhaustive_bools()), exhaustive_nonzero_signeds::(), ) .map(|(bs, n)| { bs.into_iter() .chain(repeat_n(n < 0, n.unsigned_abs())) .collect() }), ), ) } pub fn exhaustive_bool_vec_gen_var_3() -> It> { Box::new( shortlex_vecs_length_inclusive_range(0, T::WIDTH, exhaustive_bools()).interleave( exhaustive_pairs_big_tiny( lex_vecs_fixed_length_from_single(T::WIDTH, exhaustive_bools()), exhaustive_positive_primitive_ints(), ) .map(|(bs, n)| repeat_n(false, n).chain(bs).collect()), ), ) } pub fn exhaustive_bool_vec_gen_var_4() -> It> { Box::new( shortlex_vecs_length_inclusive_range(0, T::WIDTH - 1, exhaustive_bools()).interleave( exhaustive_pairs_big_tiny( lex_vecs_fixed_length_from_single(T::WIDTH - 1, exhaustive_bools()), exhaustive_nonzero_signeds::(), ) .map(|(bs, n)| repeat_n(n < 0, n.unsigned_abs()).chain(bs).collect()), ), ) } pub fn exhaustive_bool_vec_gen_var_5() -> It> { Box::new(shortlex_vecs_min_length(1, exhaustive_bools()).filter(|bs| bs.iter().any(|&b| b))) } // -- Vec -- pub fn exhaustive_unsigned_vec_gen() -> It> { Box::new(exhaustive_vecs(exhaustive_unsigneds())) } pub fn exhaustive_unsigned_vec_gen_var_1() -> It> { Box::new( exhaustive_vecs_min_length(1, exhaustive_unsigneds()) .filter(|xs| *xs.last().unwrap() != T::ZERO), ) } pub fn exhaustive_unsigned_vec_gen_var_2() -> It> { Box::new( exhaustive_vecs_min_length(1, exhaustive_unsigneds()).filter(|xs| !slice_test_zero(xs)), ) } pub fn exhaustive_unsigned_vec_gen_var_3() -> It> { Box::new(exhaustive_vecs(exhaustive_unsigneds()).filter(|xs| xs.last() != Some(&T::ZERO))) } pub fn exhaustive_unsigned_vec_gen_var_4() -> It> { Box::new(exhaustive_vecs_min_length(1, exhaustive_unsigneds())) } // var 5 is in malachite-nz. pub fn exhaustive_unsigned_vec_gen_var_6() -> It> { Box::new(exhaustive_vecs_min_length(2, exhaustive_unsigneds())) } // --(Vec, PrimitiveInt) -- pub fn exhaustive_unsigned_vec_primitive_int_pair_gen_var_1< T: PrimitiveUnsigned, U: PrimitiveInt, >() -> It<(Vec, U)> { Box::new(exhaustive_pairs_big_small( exhaustive_vecs_min_length(1, exhaustive_unsigneds()) .filter(|xs| *xs.last().unwrap() != T::ZERO), exhaustive_positive_primitive_ints(), )) } pub fn exhaustive_unsigned_vec_primitive_int_pair_gen_var_2< T: PrimitiveUnsigned, U: PrimitiveInt, >() -> It<(Vec, U)> { Box::new(exhaustive_pairs_big_small( exhaustive_vecs_min_length(1, exhaustive_unsigneds()) .filter(|xs| *xs.last().unwrap() != T::ZERO), primitive_int_increasing_inclusive_range(U::exact_from(3), U::MAX), )) } pub fn exhaustive_unsigned_vec_primitive_int_pair_gen_var_3< T: PrimitiveUnsigned, U: PrimitiveInt, >() -> It<(Vec, U)> { Box::new(exhaustive_pairs( exhaustive_vecs_min_length(1, exhaustive_unsigneds()).filter(|xs| !slice_test_zero(xs)), exhaustive_positive_primitive_ints(), )) } pub fn exhaustive_unsigned_vec_primitive_int_pair_gen_var_4< T: PrimitiveUnsigned, U: PrimitiveInt, >() -> It<(Vec, U)> { Box::new(exhaustive_pairs( exhaustive_vecs_min_length(2, exhaustive_unsigneds()), exhaustive_positive_primitive_ints(), )) } pub fn exhaustive_unsigned_vec_primitive_int_pair_gen_var_5< T: PrimitiveUnsigned, U: PrimitiveInt, >() -> It<(Vec, U)> { Box::new(exhaustive_pairs( exhaustive_vecs_min_length(2, exhaustive_unsigneds()).filter(|xs| !slice_test_zero(xs)), exhaustive_positive_primitive_ints(), )) } pub fn exhaustive_unsigned_vec_primitive_int_pair_gen_var_6< T: PrimitiveUnsigned, U: PrimitiveInt, >() -> It<(Vec, U)> { Box::new(exhaustive_pairs( exhaustive_vecs_min_length(2, exhaustive_unsigneds()), primitive_int_increasing_inclusive_range(U::power_of_2(U::WIDTH - 1), U::MAX), )) } pub fn exhaustive_unsigned_vec_primitive_int_pair_gen_var_7< T: PrimitiveUnsigned, U: PrimitiveInt, >() -> It<(Vec, U)> { Box::new(exhaustive_pairs( exhaustive_vecs_min_length(2, exhaustive_unsigneds()), primitive_int_increasing_range(U::ONE, U::power_of_2(U::WIDTH - 1)), )) } pub fn exhaustive_unsigned_vec_primitive_int_pair_gen_var_8< T: PrimitiveUnsigned, U: PrimitiveInt, >() -> It<(Vec, U)> { Box::new(exhaustive_pairs( exhaustive_vecs_min_length(1, exhaustive_unsigneds()), primitive_int_increasing_inclusive_range(U::power_of_2(U::WIDTH - 1), U::MAX), )) } pub fn exhaustive_unsigned_vec_primitive_int_pair_gen_var_9< T: PrimitiveUnsigned, U: PrimitiveInt, >() -> It<(Vec, U)> { Box::new(exhaustive_pairs( exhaustive_vecs_min_length(1, exhaustive_unsigneds()), primitive_int_increasing_range(U::ONE, U::power_of_2(U::WIDTH - 1)), )) } pub fn exhaustive_unsigned_vec_primitive_int_pair_gen_var_10< T: PrimitiveUnsigned, U: PrimitiveInt, >() -> It<(Vec, U)> { Box::new(exhaustive_pairs( exhaustive_vecs_min_length(1, exhaustive_unsigneds()), primitive_int_increasing_range(U::ONE, U::power_of_2(U::WIDTH - 2)), )) } pub fn exhaustive_unsigned_vec_primitive_int_pair_gen_var_11< T: PrimitiveUnsigned, U: PrimitiveInt, >() -> It<(Vec, U)> { Box::new(exhaustive_pairs_big_small( exhaustive_vecs_min_length(1, exhaustive_unsigneds()) .filter(|xs| *xs.last().unwrap() != T::ZERO), primitive_int_increasing_inclusive_range(U::TWO, U::MAX), )) } // --(Vec, PrimitiveUnsigned) -- pub fn exhaustive_unsigned_vec_unsigned_pair_gen( ) -> It<(Vec, U)> { Box::new(exhaustive_pairs( exhaustive_vecs(exhaustive_unsigneds()), exhaustive_unsigneds(), )) } struct UnsignedVecUnsignedPairGeneratorVar1; impl ExhaustiveDependentPairsYsGenerator< (usize, usize), Vec, ExhaustiveFixedLengthVecs1Input>, > for UnsignedVecUnsignedPairGeneratorVar1 { #[inline] fn get_ys( &self, &p: &(usize, usize), ) -> ExhaustiveFixedLengthVecs1Input> { exhaustive_vecs_fixed_length_from_single(u64::exact_from(p.1), exhaustive_unsigneds()) } } // TODO generate (usize, usize) pairs better pub fn exhaustive_unsigned_vec_unsigned_pair_gen_var_1() -> T1, usize> { Box::new( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(1), ), exhaustive_pairs_from_single(exhaustive_unsigneds()).filter(|(x, y)| x <= y), UnsignedVecUnsignedPairGeneratorVar1, ) .map(|((x, _), zs)| (zs, x)), ) } struct UnsignedVecUnsignedPairGeneratorVar2 { phantom_t: PhantomData<*const T>, phantom_u: PhantomData<*const U>, } impl ExhaustiveDependentPairsYsGenerator, It>> for UnsignedVecUnsignedPairGeneratorVar2 { #[inline] fn get_ys(&self, &log_base: &u64) -> It> { Box::new( exhaustive_vecs_length_inclusive_range( 0, T::WIDTH.div_round(log_base, Ceiling).0, primitive_int_increasing_inclusive_range( U::ZERO, U::low_mask(min(T::WIDTH, log_base)), ), ) .filter(move |xs| digits_valid::(log_base, xs)), ) } } pub fn exhaustive_unsigned_vec_unsigned_pair_gen_var_2< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >() -> It<(Vec, u64)> { permute_2_1(Box::new(exhaustive_dependent_pairs( ruler_sequence(), primitive_int_increasing_inclusive_range(1, U::WIDTH), UnsignedVecUnsignedPairGeneratorVar2:: { phantom_t: PhantomData, phantom_u: PhantomData, }, ))) } pub fn exhaustive_unsigned_vec_unsigned_pair_gen_var_3< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >() -> It<(Vec, u64)> { Box::new( exhaustive_unsigned_vec_unsigned_pair_gen_var_2::() .map(|(xs, y)| (xs.into_iter().rev().collect(), y)), ) } // var 4 is in malachite-nz struct ValidDigitsGenerator { phantom_t: PhantomData<*const T>, phantom_u: PhantomData<*const U>, } impl, U: PrimitiveUnsigned> ExhaustiveDependentPairsYsGenerator, It>> for ValidDigitsGenerator { #[inline] fn get_ys(&self, base: &U) -> It> { Box::new(exhaustive_vecs(primitive_int_increasing_range( T::ZERO, T::wrapping_from(*base), ))) } } pub fn exhaustive_unsigned_vec_unsigned_pair_gen_var_5< T: PrimitiveUnsigned + WrappingFrom, U: PrimitiveUnsigned + SaturatingFrom, >() -> It<(Vec, U)> { permute_2_1(Box::new(exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(1), ), primitive_int_increasing_inclusive_range(U::TWO, U::saturating_from(T::MAX)), ValidDigitsGenerator { phantom_t: PhantomData, phantom_u: PhantomData, }, ))) } pub fn exhaustive_unsigned_vec_unsigned_pair_gen_var_6() -> It<(Vec, u64)> { Box::new(exhaustive_pairs( exhaustive_vecs(exhaustive_unsigneds()), primitive_int_increasing_inclusive_range(1, T::WIDTH), )) } struct DigitsDesc { max_digits: Vec, ds: ShortlexVecs, PrimitiveIntIncreasingRange>, } impl Iterator for DigitsDesc { type Item = Vec; fn next(&mut self) -> Option> { loop { let digits = self.ds.next()?; if digits.len() < self.max_digits.len() || digits <= self.max_digits { return Some(digits); } } } } struct DigitsDescGenerator + PrimitiveUnsigned> { phantom_t: PhantomData<*const T>, phantom_u: PhantomData<*const U>, } impl + PrimitiveUnsigned> ExhaustiveDependentPairsYsGenerator, DigitsDesc> for DigitsDescGenerator { #[inline] fn get_ys(&self, base: &T) -> DigitsDesc { let max_digits = U::MAX.to_digits_desc(base); DigitsDesc { ds: shortlex_vecs_length_inclusive_range( 0, u64::exact_from(max_digits.len()), primitive_int_increasing_range(T::ZERO, *base), ), max_digits, } } } pub fn exhaustive_unsigned_vec_unsigned_pair_gen_var_7< T: PrimitiveUnsigned + SaturatingFrom, U: Digits + PrimitiveUnsigned, >() -> It<(Vec, T)> { permute_2_1(Box::new(exhaustive_dependent_pairs( ruler_sequence(), primitive_int_increasing_inclusive_range(T::TWO, T::saturating_from(U::MAX)), DigitsDescGenerator:: { phantom_t: PhantomData, phantom_u: PhantomData, }, ))) } pub fn exhaustive_unsigned_vec_unsigned_pair_gen_var_8< T: PrimitiveUnsigned + SaturatingFrom, U: Digits + PrimitiveUnsigned, >() -> It<(Vec, T)> { Box::new( exhaustive_unsigned_vec_unsigned_pair_gen_var_7::().map(|(mut xs, base)| { xs.reverse(); (xs, base) }), ) } pub fn exhaustive_unsigned_vec_unsigned_pair_gen_var_9() -> It<(Vec, T)> { Box::new(exhaustive_pairs( exhaustive_vecs(exhaustive_unsigneds()), primitive_int_increasing_inclusive_range(T::TWO, T::MAX), )) } struct PowerOfTwoDigitsGenerator; impl ExhaustiveDependentPairsYsGenerator< u64, Vec, ExhaustiveVecs, PrimitiveIntIncreasingRange>, > for PowerOfTwoDigitsGenerator { #[inline] fn get_ys( &self, &log_base: &u64, ) -> ExhaustiveVecs, PrimitiveIntIncreasingRange> { exhaustive_vecs(primitive_int_increasing_inclusive_range( T::ZERO, T::low_mask(log_base), )) } } pub fn exhaustive_unsigned_vec_unsigned_pair_gen_var_10() -> It<(Vec, u64)> { permute_2_1(Box::new(exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(1), ), primitive_int_increasing_inclusive_range(1, T::WIDTH), PowerOfTwoDigitsGenerator, ))) } pub fn exhaustive_unsigned_vec_unsigned_pair_gen_var_11() -> It<(Vec, u64)> { Box::new(exhaustive_pairs( exhaustive_vecs(exhaustive_unsigneds()), primitive_int_increasing_inclusive_range(1, T::WIDTH), )) } pub fn exhaustive_unsigned_vec_unsigned_pair_gen_var_12< T: PrimitiveUnsigned, U: PrimitiveUnsigned + SaturatingFrom, >() -> It<(Vec, U)> { Box::new(exhaustive_pairs( exhaustive_vecs(exhaustive_unsigneds()), primitive_int_increasing_inclusive_range(U::TWO, U::saturating_from(T::MAX)), )) } pub fn exhaustive_unsigned_vec_unsigned_pair_gen_var_13< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >() -> It<(Vec, U)> { Box::new(exhaustive_pairs( exhaustive_vecs_min_length(1, exhaustive_unsigneds()), exhaustive_unsigneds(), )) } pub fn exhaustive_unsigned_vec_unsigned_pair_gen_var_14< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >() -> It<(Vec, U)> { Box::new(exhaustive_pairs_big_tiny( exhaustive_vecs(exhaustive_unsigneds()), exhaustive_unsigneds(), )) } pub fn exhaustive_unsigned_vec_unsigned_pair_gen_var_15< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >() -> It<(Vec, U)> { Box::new( exhaustive_pairs_big_tiny( exhaustive_vecs(exhaustive_unsigneds()), exhaustive_unsigneds(), ) .filter(|(xs, y)| *y < U::exact_from(xs.len() << T::LOG_WIDTH)), ) } pub fn exhaustive_unsigned_vec_unsigned_pair_gen_var_16< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >() -> It<(Vec, U)> { Box::new(exhaustive_pairs( exhaustive_vecs_min_length(1, exhaustive_unsigneds()).filter(|xs| !slice_test_zero(xs)), exhaustive_unsigneds(), )) } pub fn exhaustive_unsigned_vec_unsigned_pair_gen_var_17< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >() -> It<(Vec, U)> { Box::new(exhaustive_pairs_big_tiny( exhaustive_vecs_min_length(1, exhaustive_unsigneds()).filter(|xs| !slice_test_zero(xs)), exhaustive_unsigneds(), )) } // vars 18 through 20 are in malachite-nz. pub fn exhaustive_unsigned_vec_unsigned_pair_gen_var_21( ) -> It<(Vec, u64)> { Box::new(exhaustive_pairs( exhaustive_vecs(exhaustive_unsigneds()), primitive_int_increasing_range(1, U::WIDTH), )) } pub fn exhaustive_unsigned_vec_unsigned_pair_gen_var_22( ) -> It<(Vec, u64)> { Box::new(exhaustive_pairs( exhaustive_vecs_min_length(1, exhaustive_unsigneds()), primitive_int_increasing_range(1, U::WIDTH), )) } // -- (Vec, PrimitiveUnsigned, PrimitiveUnsigned) -- pub fn exhaustive_unsigned_vec_unsigned_unsigned_triple_gen( ) -> It<(Vec, T, T)> { Box::new(exhaustive_triples_xyy( exhaustive_vecs(exhaustive_unsigneds()), exhaustive_unsigneds(), )) } pub fn exhaustive_unsigned_vec_unsigned_unsigned_triple_gen_var_1< T: PrimitiveUnsigned, U: PrimitiveUnsigned, V: PrimitiveUnsigned, >() -> It<(Vec, U, V)> { Box::new(exhaustive_triples_custom_output( exhaustive_vecs(exhaustive_unsigneds()), exhaustive_unsigneds(), exhaustive_unsigneds(), BitDistributorOutputType::normal(1), BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), )) } struct UnsignedVecUnsignedUnsignedTripleGeneratorVar2; impl ExhaustiveDependentPairsYsGenerator< (usize, usize), Vec, ExhaustiveVecs, PrimitiveIntIncreasingRange>, > for UnsignedVecUnsignedUnsignedTripleGeneratorVar2 { #[inline] fn get_ys( &self, &(i, j): &(usize, usize), ) -> ExhaustiveVecs, PrimitiveIntIncreasingRange> { exhaustive_vecs_min_length(u64::exact_from(i * j), exhaustive_unsigneds()) } } pub fn exhaustive_unsigned_vec_unsigned_unsigned_triple_gen_var_2( ) -> It<(Vec, usize, usize)> { reshape_1_2_to_3(permute_2_1(Box::new(exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), exhaustive_pairs_from_single(exhaustive_unsigneds()), UnsignedVecUnsignedUnsignedTripleGeneratorVar2, )))) } pub fn exhaustive_unsigned_vec_unsigned_unsigned_triple_gen_var_3< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >() -> It<(Vec, U, U)> { Box::new( exhaustive_triples_xyy_custom_output( exhaustive_vecs(exhaustive_unsigneds()), exhaustive_unsigneds(), BitDistributorOutputType::normal(1), BitDistributorOutputType::tiny(), BitDistributorOutputType::tiny(), ) .filter_map(|(xs, y, z): (Vec, U, U)| y.checked_add(z).map(|new_z| (xs, y, new_z))), ) } pub fn exhaustive_unsigned_vec_unsigned_unsigned_triple_gen_var_4< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >() -> It<(Vec, U, U)> { Box::new( exhaustive_triples_xyy_custom_output( exhaustive_vecs_min_length(1, exhaustive_unsigneds()).filter(|xs| !slice_test_zero(xs)), exhaustive_unsigneds(), BitDistributorOutputType::normal(1), BitDistributorOutputType::tiny(), BitDistributorOutputType::tiny(), ) .filter_map(|(xs, y, z): (Vec, U, U)| y.checked_add(z).map(|new_z| (xs, y, new_z))), ) } pub fn exhaustive_unsigned_vec_unsigned_unsigned_triple_gen_var_5( ) -> It<(Vec, T, T)> { Box::new(exhaustive_triples_xyy( exhaustive_vecs_min_length(2, exhaustive_unsigneds()) .filter(|xs| *xs.last().unwrap() != T::ZERO), exhaustive_positive_primitive_ints(), )) } // var 6 is in malachite-nz. pub fn exhaustive_unsigned_vec_unsigned_unsigned_triple_gen_var_7( ) -> It<(Vec, T, T)> { Box::new(exhaustive_triples( exhaustive_vecs_min_length(2, exhaustive_unsigneds()) .filter(|xs| *xs.last().unwrap() != T::ZERO), exhaustive_unsigneds(), exhaustive_positive_primitive_ints(), )) } pub fn exhaustive_unsigned_vec_unsigned_unsigned_triple_gen_var_8< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >() -> It<(Vec, T, U)> { Box::new(exhaustive_triples_custom_output( exhaustive_vecs_min_length(2, exhaustive_unsigneds()) .filter(|xs| *xs.last().unwrap() != T::ZERO), exhaustive_unsigneds(), exhaustive_unsigneds(), BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(1), BitDistributorOutputType::tiny(), )) } // var 9 is in malachite-nz. pub fn exhaustive_unsigned_vec_unsigned_unsigned_triple_gen_var_10( ) -> It<(Vec, T, T)> { Box::new(exhaustive_triples( exhaustive_vecs_min_length(1, exhaustive_unsigneds()), primitive_int_increasing_inclusive_range(T::ZERO, T::low_mask(T::WIDTH - 1)) .map(|u| (u << 1) | T::ONE), exhaustive_unsigneds(), )) } // vars 11 through 12 are in malachite-nz. pub fn exhaustive_unsigned_vec_unsigned_unsigned_triple_gen_var_13< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >() -> It<(Vec, T, U)> { Box::new(exhaustive_triples_custom_output( exhaustive_vecs_min_length(1, exhaustive_unsigneds()) .filter(|xs| *xs.last().unwrap() != T::ZERO), exhaustive_unsigneds(), exhaustive_unsigneds(), BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(1), BitDistributorOutputType::tiny(), )) } // var 14 is in malachite-nz. // -- (Vec, PrimitiveUnsigned, RoundingMode) -- pub fn exhaustive_unsigned_vec_unsigned_rounding_mode_triple_gen_var_1< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >() -> It<(Vec, U, RoundingMode)> { Box::new(exhaustive_triples( exhaustive_vecs_min_length(2, exhaustive_unsigneds()) .filter(|xs| *xs.last().unwrap() != T::ZERO), exhaustive_unsigneds(), exhaustive_rounding_modes(), )) } pub fn exhaustive_unsigned_vec_unsigned_rounding_mode_triple_gen_var_2< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >() -> It<(Vec, U, RoundingMode)> { Box::new(exhaustive_triples_custom_output( exhaustive_vecs_min_length(1, exhaustive_unsigneds()).filter(|xs| !slice_test_zero(xs)), exhaustive_unsigneds(), exhaustive_rounding_modes(), BitDistributorOutputType::normal(1), BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), )) } // -- (Vec, Vec) -- pub fn exhaustive_unsigned_vec_pair_gen() -> It<(Vec, Vec)> { Box::new(exhaustive_pairs_from_single(exhaustive_vecs( exhaustive_unsigneds(), ))) } pub struct UnsignedVecPairLenGenerator1; impl ExhaustiveDependentPairsYsGenerator< (u64, u64), (Vec, Vec), ExhaustivePairs< Vec, ExhaustiveFixedLengthVecs1Input>, Vec, ExhaustiveFixedLengthVecs1Input>, >, > for UnsignedVecPairLenGenerator1 { #[allow(clippy::type_complexity)] #[inline] fn get_ys( &self, &(i, j): &(u64, u64), ) -> ExhaustivePairs< Vec, ExhaustiveFixedLengthVecs1Input>, Vec, ExhaustiveFixedLengthVecs1Input>, > { exhaustive_pairs( exhaustive_vecs_fixed_length_from_single(i, exhaustive_unsigneds()), exhaustive_vecs_fixed_length_from_single(j, exhaustive_unsigneds()), ) } } pub fn exhaustive_unsigned_vec_pair_gen_var_1() -> It<(Vec, Vec)> { Box::new( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), // TODO exhaustive_pairs_from_single(exhaustive_unsigneds()).filter(|(x, y)| x >= y), UnsignedVecPairLenGenerator1, ) .map(|p| p.1), ) } pub fn exhaustive_unsigned_vec_pair_gen_var_2() -> It<(Vec, Vec)> { Box::new( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), // TODO exhaustive_pairs_from_single(exhaustive_positive_primitive_ints()) .filter(|(x, y)| x >= y), UnsignedVecPairLenGenerator1, ) .map(|p| p.1), ) } pub fn exhaustive_unsigned_vec_pair_gen_var_3() -> It<(Vec, Vec)> { Box::new(exhaustive_pairs_from_single(exhaustive_vecs_min_length( 1, exhaustive_unsigneds(), ))) } pub fn exhaustive_unsigned_vec_pair_gen_var_4() -> It<(Vec, Vec)> { Box::new( exhaustive_pairs_from_single(exhaustive_vecs_min_length(1, exhaustive_unsigneds())).filter( |(ref xs, ref es)| { !xs.is_empty() && (es.len() > 1 || es.len() == 1 && es[0] > T::ONE) && *es.last().unwrap() != T::ZERO }, ), ) } struct UnsignedVecSqrtRemGenerator; impl ExhaustiveDependentPairsYsGenerator<(u64, u64), (Vec, Vec), It<(Vec, Vec)>> for UnsignedVecSqrtRemGenerator { #[allow(clippy::type_complexity)] #[inline] fn get_ys(&self, &(out_len, len): &(u64, u64)) -> It<(Vec, Vec)> { Box::new( exhaustive_triples( exhaustive_vecs_fixed_length_from_single(out_len, exhaustive_unsigneds()), exhaustive_vecs_fixed_length_from_single(len - 1, exhaustive_unsigneds()), primitive_int_increasing_inclusive_range(T::power_of_2(T::WIDTH - 2), T::MAX), ) .map(move |(out, mut ns, n_hi)| { ns.insert((usize::exact_from(out_len) << 1) - 1, n_hi); (out, ns) }), ) } } pub fn exhaustive_unsigned_vec_pair_gen_var_5() -> It<(Vec, Vec)> { Box::new( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), exhaustive_pairs_from_single(exhaustive_unsigneds::()).filter_map(|(x, y)| { let n = x.checked_add(2)?; let len: u64 = n.arithmetic_checked_shl(1)?; let len = len.checked_add(y)?; Some((n, len)) }), UnsignedVecSqrtRemGenerator, ) .map(|p| p.1), ) } struct UnsignedVecSqrtGenerator; impl ExhaustiveDependentPairsYsGenerator<(u64, u64), (Vec, Vec), It<(Vec, Vec)>> for UnsignedVecSqrtGenerator { #[allow(clippy::type_complexity)] #[inline] fn get_ys(&self, &(out_len, len): &(u64, u64)) -> It<(Vec, Vec)> { Box::new( exhaustive_triples( exhaustive_vecs_fixed_length_from_single(out_len, exhaustive_unsigneds()), exhaustive_vecs_fixed_length_from_single(len - 1, exhaustive_unsigneds()), exhaustive_positive_primitive_ints(), ) .map(move |(out, mut ns, n_hi)| { ns.push(n_hi); (out, ns) }), ) } } pub fn exhaustive_unsigned_vec_pair_gen_var_6() -> It<(Vec, Vec)> { Box::new( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), exhaustive_pairs_from_single(exhaustive_unsigneds::()).filter_map(|(x, y)| { let in_len = x.checked_add(1)?; let mut out_len: u64 = in_len.shr_round(1, Ceiling).0; out_len = out_len.checked_add(y)?; Some((out_len, in_len)) }), UnsignedVecSqrtGenerator, ) .map(|p| p.1), ) } struct UnsignedVecPairSameLenGenerator; impl ExhaustiveDependentPairsYsGenerator< u64, (Vec, Vec), ExhaustivePairs1Input>>, > for UnsignedVecPairSameLenGenerator { #[allow(clippy::type_complexity)] #[inline] fn get_ys( &self, &len: &u64, ) -> ExhaustivePairs1Input>> { exhaustive_pairs_from_single(exhaustive_vecs_fixed_length_from_single( len, exhaustive_unsigneds(), )) } } pub fn exhaustive_unsigned_vec_pair_gen_var_7() -> It<(Vec, Vec)> { Box::new( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), exhaustive_unsigneds(), UnsignedVecPairSameLenGenerator, ) .map(|p| p.1), ) } pub fn exhaustive_unsigned_vec_pair_gen_var_8() -> It<(Vec, Vec)> { Box::new(exhaustive_pairs_from_single( exhaustive_vecs(exhaustive_unsigneds()).filter(|xs| xs.last() != Some(&T::ZERO)), )) } pub fn exhaustive_unsigned_vec_pair_gen_var_9() -> It<(Vec, Vec)> { Box::new(exhaustive_pairs_from_single( exhaustive_vecs_min_length(1, exhaustive_unsigneds()).filter(|xs| !slice_test_zero(xs)), )) } pub struct UnsignedVecPairLenGenerator2; impl ExhaustiveDependentPairsYsGenerator< (u64, u64), (Vec, Vec), ExhaustivePairs, It>, Vec, It>>, > for UnsignedVecPairLenGenerator2 { #[allow(clippy::type_complexity)] #[inline] fn get_ys( &self, &(i, j): &(u64, u64), ) -> ExhaustivePairs, It>, Vec, It>> { exhaustive_pairs( Box::new( exhaustive_vecs_fixed_length_from_single(i, exhaustive_unsigneds()) .filter(|xs| !slice_test_zero(xs)), ), Box::new( exhaustive_vecs_fixed_length_from_single(j, exhaustive_unsigneds()) .filter(|xs| !slice_test_zero(xs)), ), ) } } pub fn exhaustive_unsigned_vec_pair_gen_var_10() -> It<(Vec, Vec)> { Box::new( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), // TODO exhaustive_pairs_from_single(exhaustive_positive_primitive_ints()) .filter(|(x, y)| x >= y), UnsignedVecPairLenGenerator2, ) .map(|p| p.1), ) } // var 11 is in malachite-nz. pub fn exhaustive_unsigned_vec_pair_gen_var_12() -> It<(Vec, Vec)> { Box::new( exhaustive_dependent_pairs( ruler_sequence(), // TODO exhaustive_pairs_from_single(primitive_int_increasing_inclusive_range(2, u64::MAX)) .filter(|(x, y)| x >= y), UnsignedVecPairLenGenerator1, ) .filter_map(|(_, (ns, ds))| { if *ds.last().unwrap() == T::ZERO { None } else { Some((ns, ds)) } }), ) } pub fn exhaustive_unsigned_vec_pair_gen_var_13() -> It<(Vec, Vec)> { Box::new( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), // TODO exhaustive_pairs_from_single(exhaustive_positive_primitive_ints()) .filter(|(x, y)| x >= y), UnsignedVecPairLenGenerator1, ) .filter_map( |(_, (xs, ys)): (_, (Vec, Vec))| if ys[0].odd() { Some((xs, ys)) } else { None }, ), ) } // vars 14 through 15 are in malachite-nz pub fn exhaustive_unsigned_vec_pair_gen_var_16() -> It<(Vec, Vec)> { Box::new( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), // TODO exhaustive_pairs_from_single(exhaustive_positive_primitive_ints()) .filter(|(x, y)| x >= y), UnsignedVecPairLenGenerator1, ) .filter_map(|(_, (mut xs, mut ys))| { let last_x = xs.last_mut().unwrap(); let last_y = ys.last_mut().unwrap(); if *last_x == T::MAX || *last_y == T::MAX { None } else { *last_x += T::ONE; *last_y += T::ONE; Some((xs, ys)) } }), ) } pub fn exhaustive_unsigned_vec_pair_gen_var_17() -> It<(Vec, Vec)> { Box::new( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), // TODO exhaustive_pairs_from_single(primitive_int_increasing_inclusive_range(2, u64::MAX)) .filter(|(x, y)| x >= y), UnsignedVecPairLenGenerator1, ) .filter_map(|(_, (mut xs, mut ys))| { let last_x = xs.last_mut().unwrap(); let last_y = ys.last_mut().unwrap(); if *last_x == T::MAX || *last_y == T::MAX { None } else { *last_x += T::ONE; *last_y += T::ONE; Some((xs, ys)) } }), ) } // var 18 is in malachite-nz. pub fn exhaustive_unsigned_vec_pair_gen_var_19() -> It<(Vec, Vec)> { Box::new( exhaustive_triples( exhaustive_vecs_min_length(2, exhaustive_unsigneds()), primitive_int_increasing_inclusive_range(T::power_of_2(T::WIDTH - 1), T::MAX), exhaustive_unsigneds(), ) .map(|(n, d_1, d_0)| (n, vec![d_0, d_1])), ) } pub fn exhaustive_unsigned_vec_pair_gen_var_20() -> It<(Vec, Vec)> { Box::new(exhaustive_pairs_from_single( exhaustive_vecs_min_length(1, exhaustive_unsigneds::()).filter_map(|mut xs| { let last = xs.last_mut().unwrap(); *last = last.checked_add(T::ONE)?; Some(xs) }), )) } pub fn exhaustive_unsigned_vec_pair_gen_var_21() -> It<(Vec, Vec)> { Box::new( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), // TODO exhaustive_pairs_from_single(primitive_int_increasing_inclusive_range(2, u64::MAX)) .filter(|(x, y)| x >= y), UnsignedVecPairLenGenerator1, ) .map(|p| p.1), ) } // vars 22 through 31 are in malachite-nz. pub fn exhaustive_unsigned_vec_pair_gen_var_32() -> It<(Vec, Vec)> { Box::new( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), // TODO exhaustive_pairs_from_single(exhaustive_unsigneds()).filter(|(x, y)| x >= y), UnsignedVecPairLenGenerator1, ) .map(|p| p.1), ) } pub fn exhaustive_unsigned_vec_pair_gen_var_33() -> It<(Vec, Vec)> { Box::new( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), exhaustive_positive_primitive_ints(), UnsignedVecPairSameLenGenerator, ) .filter_map(|(_, (xs, ys)): (_, (Vec, Vec))| { if (*xs.last().unwrap() != T::ZERO || *ys.last().unwrap() != T::ZERO) && ys[0].odd() { Some((xs, ys)) } else { None } }), ) } // var 34 is in malachite-nz. // --(Vec, Vec, bool) -- pub fn exhaustive_unsigned_vec_unsigned_vec_bool_triple_gen_var_1( ) -> It<(Vec, Vec, bool)> { reshape_2_1_to_3(Box::new(lex_pairs( exhaustive_unsigned_vec_pair_gen_var_7(), exhaustive_bools(), ))) } // --(Vec, Vec, PrimitiveUnsigned) -- pub fn exhaustive_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_1( ) -> It<(Vec, Vec, T)> { reshape_2_1_to_3(Box::new(exhaustive_pairs( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), // TODO exhaustive_pairs_from_single(exhaustive_unsigneds()).filter(|(x, y)| x >= y), UnsignedVecPairLenGenerator1, ) .map(|p| p.1), exhaustive_unsigneds(), ))) } // var 2 and 3 are in malachite-nz pub fn exhaustive_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_4( ) -> It<(Vec, Vec, T)> { reshape_2_1_to_3(Box::new(exhaustive_pairs( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), // TODO exhaustive_pairs_from_single(exhaustive_positive_primitive_ints()) .filter(|(x, y)| x >= y), UnsignedVecPairLenGenerator1, ) .map(|p| p.1), exhaustive_unsigneds(), ))) } struct UnsignedVecPairLenGenerator3; impl ExhaustiveDependentPairsYsGenerator< (u64, u64), (Vec, Vec), ExhaustivePairs< Vec, ExhaustiveFixedLengthVecs1Input>, Vec, It>, >, > for UnsignedVecPairLenGenerator3 { #[allow(clippy::type_complexity)] #[inline] fn get_ys( &self, &(i, j): &(u64, u64), ) -> ExhaustivePairs< Vec, ExhaustiveFixedLengthVecs1Input>, Vec, It>, > { exhaustive_pairs( exhaustive_vecs_fixed_length_from_single(i, exhaustive_unsigneds()), Box::new( exhaustive_vecs_fixed_length_from_single(j, exhaustive_unsigneds()) .filter(|xs| !slice_test_zero(xs)), ), ) } } pub fn exhaustive_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_5( ) -> It<(Vec, Vec, T)> { reshape_2_1_to_3(Box::new(exhaustive_pairs( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), // TODO exhaustive_pairs_from_single(exhaustive_positive_primitive_ints()) .filter(|(x, y)| x >= y), UnsignedVecPairLenGenerator3, ) .map(|p| p.1), exhaustive_unsigneds(), ))) } pub fn exhaustive_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_6< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >() -> It<(Vec, Vec, U)> { Box::new(exhaustive_triples_xxy( exhaustive_vecs_min_length(2, exhaustive_unsigneds()) .filter(|xs| *xs.last().unwrap() != T::ZERO), exhaustive_positive_primitive_ints(), )) } // vars 7 through 8 are in malachite-nz. pub fn exhaustive_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_9< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >() -> It<(Vec, Vec, U)> { Box::new(exhaustive_triples_xxy_custom_output( exhaustive_vecs_min_length(1, exhaustive_unsigneds()) .filter(|xs| *xs.last().unwrap() != T::ZERO), exhaustive_unsigneds(), BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(1), BitDistributorOutputType::tiny(), )) } pub fn exhaustive_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_10< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >() -> It<(Vec, Vec, U)> { Box::new(exhaustive_triples_xxy( exhaustive_vecs_min_length(1, exhaustive_unsigneds()) .filter(|xs| *xs.last().unwrap() != T::ZERO), exhaustive_positive_primitive_ints(), )) } struct UnsignedVecPairLenAndIndexGenerator; impl ExhaustiveDependentPairsYsGenerator< (u64, u64, u64), (Vec, Vec, usize), It<(Vec, Vec, usize)>, > for UnsignedVecPairLenAndIndexGenerator { #[inline] fn get_ys(&self, &(x, y, i): &(u64, u64, u64)) -> It<(Vec, Vec, usize)> { Box::new( exhaustive_pairs( exhaustive_vecs_fixed_length_from_single(x, exhaustive_unsigneds()), exhaustive_vecs_fixed_length_from_single(y, exhaustive_unsigneds()), ) .map(move |(x, y)| (x, y, usize::exact_from(i))), ) } } pub fn exhaustive_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_11( ) -> It<(Vec, Vec, usize)> { Box::new( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), // TODO exhaustive_triples_from_single(exhaustive_unsigneds::()).filter_map( |(x, y, i)| { let y = y.checked_add(i)?; let x = x.checked_add(y)?; Some((x, y, i)) }, ), UnsignedVecPairLenAndIndexGenerator, ) .map(|p| p.1), ) } pub fn exhaustive_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_12( ) -> It<(Vec, Vec, T)> { reshape_2_1_to_3(Box::new(exhaustive_pairs( exhaustive_unsigned_vec_pair_gen_var_7(), exhaustive_unsigneds(), ))) } pub fn exhaustive_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_13( ) -> It<(Vec, Vec, T)> { reshape_2_1_to_3(Box::new(exhaustive_pairs( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), // TODO exhaustive_pairs_from_single(primitive_int_increasing_inclusive_range(2, u64::MAX)) .filter(|(x, y)| x >= y), UnsignedVecPairLenGenerator1, ) .map(|p| p.1), exhaustive_positive_primitive_ints(), ))) } pub fn exhaustive_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_22< T: PrimitiveUnsigned, U: PrimitiveInt, >() -> It<(Vec, Vec, u64)> { reshape_2_1_to_3(Box::new(exhaustive_pairs( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), // TODO exhaustive_pairs_from_single(exhaustive_unsigneds()).filter(|(x, y)| x >= y), UnsignedVecPairLenGenerator1, ) .map(|p| p.1), primitive_int_increasing_range(1, U::WIDTH), ))) } pub fn exhaustive_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_23< T: PrimitiveUnsigned, U: PrimitiveInt, >() -> It<(Vec, Vec, u64)> { reshape_2_1_to_3(Box::new(exhaustive_pairs( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), // TODO exhaustive_pairs_from_single(exhaustive_positive_primitive_ints()) .filter(|(x, y)| x >= y), UnsignedVecPairLenGenerator1, ) .map(|p| p.1), primitive_int_increasing_range(1, U::WIDTH), ))) } pub fn exhaustive_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_24( ) -> It<(Vec, Vec, usize)> { Box::new( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), // TODO exhaustive_pairs_from_single(exhaustive_unsigneds::()).filter_map(|(x, i)| { let x = x.checked_add(i)?; Some((x, x, i)) }), UnsignedVecPairLenAndIndexGenerator, ) .map(|p| p.1), ) } // --(Vec, Vec, Vec) -- pub struct UnsignedVecTripleXYYLenGenerator; impl ExhaustiveDependentPairsYsGenerator< (u64, u64), (Vec, Vec, Vec), ExhaustiveTriplesXYY< Vec, ExhaustiveFixedLengthVecs1Input>, Vec, ExhaustiveFixedLengthVecs1Input>, >, > for UnsignedVecTripleXYYLenGenerator { #[allow(clippy::type_complexity)] #[inline] fn get_ys( &self, &(i, j): &(u64, u64), ) -> ExhaustiveTriplesXYY< Vec, ExhaustiveFixedLengthVecs1Input>, Vec, ExhaustiveFixedLengthVecs1Input>, > { exhaustive_triples_xyy( exhaustive_vecs_fixed_length_from_single(i, exhaustive_unsigneds()), exhaustive_vecs_fixed_length_from_single(j, exhaustive_unsigneds()), ) } } pub fn exhaustive_unsigned_vec_triple_gen_var_1( ) -> It<(Vec, Vec, Vec)> { Box::new( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), exhaustive_pairs_from_single(exhaustive_unsigneds::()).filter_map(|(x, y)| { let y = y.checked_add(1)?; let x = x.checked_add(y.arithmetic_checked_shl(1)?)?; Some((x, y)) }), UnsignedVecTripleXYYLenGenerator, ) .map(|p| p.1), ) } pub struct UnsignedVecTripleLenGenerator1; impl ExhaustiveDependentPairsYsGenerator< (u64, u64, u64), (Vec, Vec, Vec), ExhaustiveTriples< Vec, ExhaustiveFixedLengthVecs1Input>, Vec, ExhaustiveFixedLengthVecs1Input>, Vec, ExhaustiveFixedLengthVecs1Input>, >, > for UnsignedVecTripleLenGenerator1 { #[allow(clippy::type_complexity)] #[inline] fn get_ys( &self, &(i, j, k): &(u64, u64, u64), ) -> ExhaustiveTriples< Vec, ExhaustiveFixedLengthVecs1Input>, Vec, ExhaustiveFixedLengthVecs1Input>, Vec, ExhaustiveFixedLengthVecs1Input>, > { exhaustive_triples( exhaustive_vecs_fixed_length_from_single(i, exhaustive_unsigneds()), exhaustive_vecs_fixed_length_from_single(j, exhaustive_unsigneds()), exhaustive_vecs_fixed_length_from_single(k, exhaustive_unsigneds()), ) } } pub struct UnsignedVecQuadrupleLenGenerator1; impl ExhaustiveDependentPairsYsGenerator< (u64, u64, u64, u64), (Vec, Vec, Vec, Vec), ExhaustiveQuadruples< Vec, ExhaustiveFixedLengthVecs1Input>, Vec, ExhaustiveFixedLengthVecs1Input>, Vec, ExhaustiveFixedLengthVecs1Input>, Vec, ExhaustiveFixedLengthVecs1Input>, >, > for UnsignedVecQuadrupleLenGenerator1 { #[allow(clippy::type_complexity)] #[inline] fn get_ys( &self, &(i, j, k, l): &(u64, u64, u64, u64), ) -> ExhaustiveQuadruples< Vec, ExhaustiveFixedLengthVecs1Input>, Vec, ExhaustiveFixedLengthVecs1Input>, Vec, ExhaustiveFixedLengthVecs1Input>, Vec, ExhaustiveFixedLengthVecs1Input>, > { exhaustive_quadruples( exhaustive_vecs_fixed_length_from_single(i, exhaustive_unsigneds()), exhaustive_vecs_fixed_length_from_single(j, exhaustive_unsigneds()), exhaustive_vecs_fixed_length_from_single(k, exhaustive_unsigneds()), exhaustive_vecs_fixed_length_from_single(l, exhaustive_unsigneds()), ) } } pub fn exhaustive_unsigned_vec_triple_gen_var_2( ) -> It<(Vec, Vec, Vec)> { Box::new( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), exhaustive_triples_from_single(exhaustive_unsigneds::()).filter_map( |(o, x, y)| { let y = y.checked_add(1)?; let x = x.checked_add(y)?; let o = x.checked_add(y)?.checked_add(o)?; Some((o, x, y)) }, ), UnsignedVecTripleLenGenerator1, ) .map(|p| p.1), ) } pub fn exhaustive_unsigned_vec_triple_gen_var_3( ) -> It<(Vec, Vec, Vec)> { Box::new( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), exhaustive_triples_from_single(exhaustive_unsigneds::()).filter_map( |(o, x, y)| { let y = y.checked_add(1)?; let x = x.checked_add(1)?; let o = x.checked_add(y)?.checked_add(o)?; Some((o, x, y)) }, ), UnsignedVecTripleLenGenerator1, ) .map(|p| p.1), ) } // vars 4 through 23 are in malachite-nz pub fn exhaustive_unsigned_vec_triple_gen_var_24( ) -> It<(Vec, Vec, Vec)> { Box::new( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), exhaustive_pairs_from_single(exhaustive_unsigneds::()).filter_map(|(x, y)| { let y = y.checked_add(1)?; let x = x.checked_add(y)?; Some((x, y)) }), UnsignedVecTripleXYYLenGenerator, ) .map(|p| p.1), ) } pub fn exhaustive_unsigned_vec_triple_gen_var_25( ) -> It<(Vec, Vec, Vec)> { Box::new( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), exhaustive_pairs_from_single(exhaustive_unsigneds::()).filter_map(|(x, y)| { let y = y.checked_add(2)?; let x = x.checked_add(y.arithmetic_checked_shl(1)?)?; Some((x, y)) }), UnsignedVecTripleXYYLenGenerator, ) .map(|p| p.1), ) } pub fn exhaustive_unsigned_vec_triple_gen_var_26( ) -> It<(Vec, Vec, Vec)> { Box::new( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), exhaustive_pairs_from_single(exhaustive_unsigneds::()).filter_map(|(x, y)| { let y = y.checked_add(2)?; let x = x.checked_add(y)?; Some((x, y)) }), UnsignedVecTripleXYYLenGenerator, ) .map(|p| p.1), ) } struct UnsignedVecTripleXXXLenGenerator; impl ExhaustiveDependentPairsYsGenerator< u64, (Vec, Vec, Vec), ExhaustiveTriples1Input>>, > for UnsignedVecTripleXXXLenGenerator { #[inline] fn get_ys( &self, &i: &u64, ) -> ExhaustiveTriples1Input>> { exhaustive_triples_from_single(exhaustive_vecs_fixed_length_from_single( i, exhaustive_unsigneds(), )) } } pub fn exhaustive_unsigned_vec_triple_gen_var_27( ) -> It<(Vec, Vec, Vec)> { Box::new( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), primitive_int_increasing_inclusive_range::(2, u64::MAX), UnsignedVecTripleXXXLenGenerator, ) .map(|p| p.1), ) } struct UnsignedVecSqrtRemGenerator3; impl ExhaustiveDependentPairsYsGenerator< (u64, u64, u64), (Vec, Vec, Vec), It<(Vec, Vec, Vec)>, > for UnsignedVecSqrtRemGenerator3 { #[allow(clippy::type_complexity)] #[inline] fn get_ys(&self, &(out_len, rem_len, len): &(u64, u64, u64)) -> It<(Vec, Vec, Vec)> { Box::new( exhaustive_quadruples( exhaustive_vecs_fixed_length_from_single(out_len, exhaustive_unsigneds()), exhaustive_vecs_fixed_length_from_single(rem_len, exhaustive_unsigneds()), exhaustive_vecs_fixed_length_from_single(len - 1, exhaustive_unsigneds()), exhaustive_positive_primitive_ints(), ) .map(move |(out, rs, mut ns, n_hi)| { ns.push(n_hi); (out, rs, ns) }), ) } } pub fn exhaustive_unsigned_vec_triple_gen_var_28( ) -> It<(Vec, Vec, Vec)> { Box::new( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), exhaustive_triples_from_single(exhaustive_unsigneds::()).filter_map( |(x, y, z)| { let in_len = x.checked_add(1)?; let mut out_len: u64 = in_len.shr_round(1, Ceiling).0; out_len = out_len.checked_add(y)?; let rem_len = in_len.checked_add(z)?; Some((out_len, rem_len, in_len)) }, ), UnsignedVecSqrtRemGenerator3, ) .map(|p| p.1), ) } pub fn exhaustive_unsigned_vec_triple_gen_var_29( ) -> It<(Vec, Vec, Vec)> { Box::new( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), exhaustive_unsigneds(), UnsignedVecTripleXXXLenGenerator, ) .map(|p| p.1), ) } pub fn exhaustive_unsigned_vec_triple_gen_var_30( ) -> It<(Vec, Vec, Vec)> { Box::new(exhaustive_triples_from_single( exhaustive_vecs(exhaustive_unsigneds()).filter(|xs| xs.last() != Some(&T::ZERO)), )) } pub fn exhaustive_unsigned_vec_triple_gen_var_31( ) -> It<(Vec, Vec, Vec)> { Box::new( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), exhaustive_pairs_from_single(exhaustive_unsigneds::()).filter_map(|(x, y)| { let x = x.checked_add(y)?; Some((x, y)) }), UnsignedVecTripleXYYLenGenerator, ) .map(|p| p.1), ) } pub fn exhaustive_unsigned_vec_triple_gen_var_32( ) -> It<(Vec, Vec, Vec)> { Box::new( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), exhaustive_triples_from_single(exhaustive_unsigneds::()).filter_map( |(o, x, y)| { let o = max(x, y).checked_add(o)?; Some((o, x, y)) }, ), UnsignedVecTripleLenGenerator1, ) .map(|p| p.1), ) } struct UnsignedVecTripleLenGenerator2; impl ExhaustiveDependentPairsYsGenerator< (u64, u64, u64), (Vec, Vec, Vec), ExhaustiveTriples< Vec, ExhaustiveFixedLengthVecs1Input>, Vec, It>, Vec, It>, >, > for UnsignedVecTripleLenGenerator2 { #[allow(clippy::type_complexity)] #[inline] fn get_ys( &self, &(i, j, k): &(u64, u64, u64), ) -> ExhaustiveTriples< Vec, ExhaustiveFixedLengthVecs1Input>, Vec, It>, Vec, It>, > { exhaustive_triples( exhaustive_vecs_fixed_length_from_single(i, exhaustive_unsigneds()), Box::new( exhaustive_vecs_fixed_length_from_single(j, exhaustive_unsigneds()) .filter(|xs| !slice_test_zero(xs)), ), Box::new( exhaustive_vecs_fixed_length_from_single(k, exhaustive_unsigneds()) .filter(|xs| !slice_test_zero(xs)), ), ) } } pub fn exhaustive_unsigned_vec_triple_gen_var_33( ) -> It<(Vec, Vec, Vec)> { Box::new( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), exhaustive_triples_from_single(exhaustive_unsigneds::()).filter_map( |(o, x, y)| { let x = x.checked_add(1)?; let y = y.checked_add(1)?; let o = o.checked_add(x)?; Some((o, x, y)) }, ), UnsignedVecTripleLenGenerator2, ) .map(|p| p.1), ) } pub fn exhaustive_unsigned_vec_triple_gen_var_34( ) -> It<(Vec, Vec, Vec)> { Box::new( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), exhaustive_triples_from_single(exhaustive_unsigneds::()).filter_map( |(o, x, y)| { let x = x.checked_add(1)?; let y = y.checked_add(1)?; let o = o.checked_add(max(x, y))?; Some((o, x, y)) }, ), UnsignedVecTripleLenGenerator2, ) .map(|p| p.1), ) } pub fn exhaustive_unsigned_vec_triple_gen_var_35( ) -> It<(Vec, Vec, Vec)> { Box::new( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), exhaustive_triples_from_single(exhaustive_unsigneds::()).filter_map( |(o, x, y)| { let x = x.checked_add(1)?; let y = y.checked_add(1)?; let o = o.checked_add(min(x, y))?; Some((o, x, y)) }, ), UnsignedVecTripleLenGenerator2, ) .map(|p| p.1), ) } pub fn exhaustive_unsigned_vec_triple_gen_var_36( ) -> It<(Vec, Vec, Vec)> { Box::new(exhaustive_triples_from_single( exhaustive_vecs_min_length(2, exhaustive_unsigneds()) .filter(|xs| *xs.last().unwrap() != T::ZERO), )) } // vars 37 through 38 are in malachite-nz. pub fn exhaustive_unsigned_vec_triple_gen_var_39( ) -> It<(Vec, Vec, Vec)> { Box::new(exhaustive_triples_from_single( exhaustive_vecs_min_length(1, exhaustive_unsigneds()) .filter(|xs| *xs.last().unwrap() != T::ZERO), )) } pub fn exhaustive_unsigned_vec_triple_gen_var_40( ) -> It<(Vec, Vec, Vec)> { Box::new( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), exhaustive_triples_from_single(exhaustive_unsigneds::()).filter_map( |(o, x, y)| { let x = x.checked_add(y)?; let o = o.checked_add(x)?; Some((o, x, y)) }, ), UnsignedVecTripleLenGenerator1, ) .map(|p| p.1), ) } pub fn exhaustive_unsigned_vec_triple_gen_var_41( ) -> It<(Vec, Vec, Vec)> { Box::new(exhaustive_triples_xxy( exhaustive_vecs_min_length(1, exhaustive_unsigneds()) .filter(|xs| *xs.last().unwrap() != T::ZERO), exhaustive_vecs_min_length(2, exhaustive_unsigneds()) .filter(|xs| *xs.last().unwrap() != T::ZERO), )) } // vars 42 through 49 are in malachite-nz. pub fn exhaustive_unsigned_vec_triple_gen_var_50( ) -> It<(Vec, Vec, Vec)> { Box::new( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), exhaustive_triples_from_single(exhaustive_unsigneds::()).filter_map( |(x, y, z)| { let y = y.checked_add(1)?; let x = x.checked_add(y)?; let z = z.checked_add(y.arithmetic_checked_shl(1)?)?; Some((x, y, z)) }, ), UnsignedVecTripleLenGenerator1, ) .filter_map(|(_, (x, mut y, z)): (_, (Vec, Vec, Vec))| { let last_y = y.last_mut().unwrap(); if last_y.get_highest_bit() { return None; } last_y.set_bit(T::WIDTH - 1); Some((x, y, z)) }), ) } pub fn exhaustive_unsigned_vec_triple_gen_var_51( ) -> It<(Vec, Vec, Vec)> { Box::new( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), exhaustive_triples_from_single(exhaustive_unsigneds::()).filter_map( |(x, y, z)| { let y = y.checked_add(5)?; let x = x.checked_add(y)?; let z = z.checked_add(y.arithmetic_checked_shl(1)?)?; Some((x, y, z)) }, ), UnsignedVecTripleLenGenerator1, ) .filter_map(|(_, (x, mut y, z)): (_, (Vec, Vec, Vec))| { let last_y = y.last_mut().unwrap(); if last_y.get_highest_bit() { return None; } last_y.set_bit(T::WIDTH - 1); Some((x, y, z)) }), ) } pub fn exhaustive_unsigned_vec_triple_gen_var_52( ) -> It<(Vec, Vec, Vec)> { Box::new( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), exhaustive_triples_from_single(exhaustive_unsigneds::()).filter_map( |(x, y, z)| { let q = x.checked_add(3)?; let n = y.checked_add(9)?; let d = z.checked_add(6)?; if n < d { return None; } let q_alt = n - d + 1; if (q_alt << 1) > n || q_alt > d { return None; } let n_alt = q_alt << 1; let d_alt = q_alt; if q >= q_alt && d_alt >= 6 && n_alt >= d_alt + 3 && d_alt >= q_alt { Some((q, n, d)) } else { None } }, ), UnsignedVecTripleLenGenerator1, ) .filter_map(|(_, (x, y, mut z)): (_, (Vec, Vec, Vec))| { let last_z = z.last_mut().unwrap(); if last_z.get_highest_bit() { return None; } last_z.set_bit(T::WIDTH - 1); Some((x, y, z)) }), ) } pub fn exhaustive_unsigned_vec_triple_gen_var_53( ) -> It<(Vec, Vec, Vec)> { Box::new( exhaustive_pairs( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), exhaustive_pairs( exhaustive_unsigneds(), primitive_int_increasing_inclusive_range(2, u64::MAX), ) .filter(|&(x, y)| x >= y - 2), UnsignedVecPairLenGenerator1, ), exhaustive_unsigned_pair_gen_var_24(), ) .map(|((_, (q, n)), (d_1, d_0))| (q, n, vec![d_0, d_1])), ) } // vars 54 through 56 are in malachite-nz. pub fn exhaustive_unsigned_vec_triple_gen_var_57( ) -> It<(Vec, Vec, Vec)> { Box::new( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), exhaustive_triples_from_single(exhaustive_unsigneds::()).filter_map( |(r_len, n_len, d_len)| { let d_len = d_len.checked_add(2)?; let r_len = r_len.checked_add(d_len)?; let n_len = n_len.checked_add(d_len)?; Some((r_len, n_len, d_len)) }, ), UnsignedVecTripleLenGenerator1, ) .filter_map(|(_, (r, n, mut d)): (_, (Vec, Vec, Vec))| { let last_d = d.last_mut().unwrap(); *last_d = last_d.checked_add(T::ONE)?; Some((r, n, d)) }), ) } // var 58 is in malachite-nz. pub fn exhaustive_unsigned_vec_triple_gen_var_59( ) -> It<(Vec, Vec, Vec)> { Box::new( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), exhaustive_triples_from_single(exhaustive_unsigneds::()).filter_map( |(xs_len, ys_len, zs_len)| { let ys_len = ys_len.checked_add(2)?; let zs_len = zs_len.checked_add(2)?; let xs_len = xs_len.checked_add(ys_len + zs_len - 1)?; Some((xs_len, ys_len, zs_len)) }, ), UnsignedVecTripleLenGenerator1, ) .filter_map( |(_, (mut xs, mut ys, mut zs)): (_, (Vec, Vec, Vec))| { let last_x = xs.last_mut().unwrap(); *last_x = last_x.checked_add(T::ONE)?; let last_y = ys.last_mut().unwrap(); *last_y = last_y.checked_add(T::ONE)?; let last_z = zs.last_mut().unwrap(); *last_z = last_z.checked_add(T::ONE)?; Some((xs, ys, zs)) }, ), ) } // var 60 is in malachite-nz. // -- large types -- pub fn exhaustive_large_type_gen_var_1() -> It<(Vec, Vec, T, T)> { reshape_2_2_to_4(Box::new(exhaustive_pairs( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), // TODO exhaustive_pairs_from_single(exhaustive_unsigneds()).filter(|(x, y)| x >= y), UnsignedVecPairLenGenerator1, ) .map(|p| p.1), exhaustive_pairs_from_single(exhaustive_unsigneds()), ))) } struct UnsignedVecSqrtRemGenerator2; impl ExhaustiveDependentPairsYsGenerator< (u64, u64), (Vec, Vec, u64, bool), It<(Vec, Vec, u64, bool)>, > for UnsignedVecSqrtRemGenerator2 { #[allow(clippy::type_complexity)] #[inline] fn get_ys(&self, &(n, len): &(u64, u64)) -> It<(Vec, Vec, u64, bool)> { Box::new( exhaustive_pairs( exhaustive_vecs_fixed_length_from_single(n, exhaustive_unsigneds()), exhaustive_vecs_fixed_length_from_single(len, exhaustive_unsigneds::()) .filter(|xs| *xs.last().unwrap() != T::ZERO), ) .map(move |(out, ns)| { let shift = ns.last().unwrap().leading_zeros() >> 1; (out, ns, shift, len.odd()) }), ) } } pub fn exhaustive_large_type_gen_var_2() -> It<(Vec, Vec, u64, bool)> { Box::new( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), Box::new(exhaustive_unsigneds::().filter_map(|x| { let len = x.checked_add(9)?; let n = len.shr_round(1, Ceiling).0; Some((n, len)) })), UnsignedVecSqrtRemGenerator2, ) .map(|p| p.1), ) } pub fn exhaustive_large_type_gen_var_3( ) -> It<(Vec, U, U, Vec)> { Box::new( exhaustive_quadruples_xyyx::, _, U, _>( exhaustive_vecs(exhaustive_unsigneds()), exhaustive_unsigneds(), ) .filter_map(|(x, y, z, w)| Some((x, y, y.checked_add(U::ONE)?.checked_add(z)?, w))), ) } pub fn exhaustive_large_type_gen_var_4( ) -> It<(Vec, U, U, Vec)> { Box::new( exhaustive_quadruples_xyyz( exhaustive_vecs_min_length(1, exhaustive_unsigneds::()) .filter(|xs| !slice_test_zero(xs)), exhaustive_unsigneds::(), exhaustive_vecs(exhaustive_unsigneds::()), ) .filter_map(|(x, y, z, w)| Some((x, y, y.checked_add(U::ONE)?.checked_add(z)?, w))), ) } // vars 5 through 8 are in malachite-nz #[allow(clippy::type_complexity)] pub fn exhaustive_large_type_gen_var_9() -> It<(Vec, Vec, Vec, bool)> { reshape_3_1_to_4(Box::new(lex_pairs( exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), exhaustive_pairs_from_single(exhaustive_unsigneds::()).filter_map(|(x, y)| { let x = x.checked_add(y)?; Some((x, y)) }), UnsignedVecTripleXYYLenGenerator, ) .map(|p| p.1), exhaustive_bools(), ))) } // vars 10 through 21 are in malachite-nz. pub fn exhaustive_large_type_gen_var_22( ) -> It<(RationalSequence, usize, T, T)> { Box::new( exhaustive_quadruples_xyzz( exhaustive_rational_sequences(exhaustive_unsigneds()), exhaustive_unsigneds(), exhaustive_unsigneds(), ) .filter(|&(ref xs, index, _, _)| { if let Some(len) = xs.len() { index < len } else { true } }), ) } // vars 23 through 26 are in malachite-nz. pub fn exhaustive_large_type_gen_var_27() -> It<(bool, Vec, bool, Vec)> { permute_3_1_4_2(reshape_2_1_1_to_4(Box::new(lex_triples_xyy( exhaustive_pairs_from_single( exhaustive_vecs(exhaustive_unsigneds()).filter(|xs| xs.last() != Some(&T::ZERO)), ), exhaustive_bools(), )))) } malachite-base-0.4.16/src/test_util/generators/mod.rs000064400000000000000000005177761046102023000207030ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::iterators::bit_distributor::BitDistributorOutputType; use crate::num::arithmetic::traits::UnsignedAbs; use crate::num::basic::floats::PrimitiveFloat; use crate::num::basic::integers::PrimitiveInt; use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::string::options::{FromSciStringOptions, SciSizeOptions, ToSciOptions}; use crate::num::conversion::traits::{ ConvertibleFrom, Digits, ExactFrom, HasHalf, JoinHalves, RoundingFrom, SaturatingFrom, SplitInHalf, WrappingFrom, WrappingInto, }; use crate::num::float::NiceFloat; use crate::num::logic::traits::{BitBlockAccess, LeadingZeros}; use crate::rational_sequences::RationalSequence; use crate::rounding_modes::RoundingMode; use crate::slices::slice_trailing_zeros; use crate::test_util::generators::common::Generator; use crate::test_util::generators::exhaustive::*; use crate::test_util::generators::random::*; use crate::test_util::generators::special_random::*; use crate::tuples::exhaustive::{exhaustive_pairs_custom_output, ExhaustivePairs}; // general #[inline] pub fn exhaustive_pairs_big_tiny< X: Clone, I: Iterator, Y: Clone, J: Iterator, >( xs: I, ys: J, ) -> ExhaustivePairs { exhaustive_pairs_custom_output( xs, ys, BitDistributorOutputType::normal(1), BitDistributorOutputType::tiny(), ) } #[inline] pub fn exhaustive_pairs_big_small< X: Clone, I: Iterator, Y: Clone, J: Iterator, >( xs: I, ys: J, ) -> ExhaustivePairs { exhaustive_pairs_custom_output( xs, ys, BitDistributorOutputType::normal(2), BitDistributorOutputType::normal(1), ) } fn digits_valid(log_base: u64, digits: &[U]) -> bool { let digits = &digits[..digits.len() - slice_trailing_zeros(digits)]; if digits.is_empty() { return true; } let significant_bits = ((u64::wrapping_from(digits.len()) - 1) * log_base) + digits.last().unwrap().significant_bits(); significant_bits <= T::WIDTH } fn unsigned_assign_bits_valid(start: u64, end: u64, bits: T) -> bool { let bits_width = end - start; let bits = bits.mod_power_of_2(bits_width); bits == T::ZERO || LeadingZeros::leading_zeros(bits) >= start } fn signed_assign_bits_valid< T: PrimitiveSigned + UnsignedAbs, U: BitBlockAccess + PrimitiveUnsigned, >( x: T, start: u64, end: u64, bits: U, ) -> bool { if x >= T::ZERO { unsigned_assign_bits_valid(start, end, bits) && { let mut abs_self = x.unsigned_abs(); abs_self.assign_bits(start, end, &bits); !abs_self.get_highest_bit() } } else { start <= end && { let width = T::WIDTH; let bits_width = end - start; let bits = bits.mod_power_of_2(bits_width); bits_width <= width && if start >= width - 1 { bits == U::low_mask(bits_width) } else { end < width || bits >> (width - 1 - start) == U::low_mask(end - width + 1) } } } } // -- bool -- pub fn bool_gen() -> Generator { Generator::new_no_special(&exhaustive_bool_gen, &random_bool_gen) } // -- char -- pub fn char_gen() -> Generator { Generator::new( &exhaustive_char_gen, &random_char_gen, &special_random_char_gen, ) } // All `char`s except for `char::MAX`. pub fn char_gen_var_1() -> Generator { Generator::new( &exhaustive_char_gen_var_1, &random_char_gen_var_1, &special_random_char_gen_var_1, ) } // All `char`s except for `char::MIN`. pub fn char_gen_var_2() -> Generator { Generator::new( &exhaustive_char_gen_var_2, &random_char_gen_var_2, &special_random_char_gen_var_2, ) } // -- (char, char) -- pub fn char_pair_gen() -> Generator<(char, char)> { Generator::new( &exhaustive_char_pair_gen, &random_char_pair_gen, &special_random_char_pair_gen, ) } // -- FromSciStringOptions -- pub fn from_sci_string_options_gen() -> Generator { Generator::new_no_special( &exhaustive_from_sci_string_options_gen, &random_from_sci_string_options_gen, ) } // -- (FromSciStringOptions, PrimitiveUnsigned) -- // All `(FromSciStringOptions, T)` where `T` is unsigned and the `T` is between 2 and 36, inclusive. pub fn from_sci_string_options_unsigned_pair_gen_var_1( ) -> Generator<(FromSciStringOptions, T)> { Generator::new( &exhaustive_from_sci_string_options_unsigned_pair_gen_var_1, &random_from_sci_string_options_unsigned_pair_gen_var_1, &special_random_from_sci_string_options_unsigned_pair_gen_var_1, ) } // -- (FromSciStringOptions, RoundingMode) -- pub fn from_sci_string_options_rounding_mode_pair_gen( ) -> Generator<(FromSciStringOptions, RoundingMode)> { Generator::new_no_special( &exhaustive_from_sci_string_options_rounding_mode_pair_gen, &random_from_sci_string_options_rounding_mode_pair_gen, ) } // -- PrimitiveFloat -- pub fn primitive_float_gen() -> Generator { Generator::new( &exhaustive_primitive_float_gen, &random_primitive_float_gen, &special_random_primitive_float_gen, ) } // All primitive floats that are finite, not NaN, and greater than or equal to -0.5. pub fn primitive_float_gen_var_1() -> Generator { Generator::new( &exhaustive_primitive_float_gen_var_1, &random_primitive_float_gen_var_1, &special_random_primitive_float_gen_var_1, ) } // All primitive floats that are non-negative and equal to an integer. pub fn primitive_float_gen_var_2() -> Generator { Generator::new( &exhaustive_primitive_float_gen_var_2, &random_primitive_float_gen_var_2, &special_random_primitive_float_gen_var_2, ) } // All primitive floats that are non-negative and not equal to any integer. pub fn primitive_float_gen_var_3() -> Generator { Generator::new( &exhaustive_primitive_float_gen_var_3, &random_primitive_float_gen_var_3, &special_random_primitive_float_gen_var_3, ) } // All primitive floats that are non-negative and halfway between two adjacent integers. pub fn primitive_float_gen_var_4() -> Generator { Generator::new( &exhaustive_primitive_float_gen_var_4, &random_primitive_float_gen_var_4, &special_random_primitive_float_gen_var_4, ) } // All primitive floats that are equal to an integer. pub fn primitive_float_gen_var_5() -> Generator { Generator::new( &exhaustive_primitive_float_gen_var_5, &random_primitive_float_gen_var_5, &special_random_primitive_float_gen_var_5, ) } // All primitive floats that are not equal to any integer. pub fn primitive_float_gen_var_6() -> Generator { Generator::new( &exhaustive_primitive_float_gen_var_6, &random_primitive_float_gen_var_6, &special_random_primitive_float_gen_var_6, ) } // All primitive floats that are halfway between two adjacent integers. pub fn primitive_float_gen_var_7() -> Generator { Generator::new( &exhaustive_primitive_float_gen_var_7, &random_primitive_float_gen_var_7, &special_random_primitive_float_gen_var_7, ) } // All finite primitive floats. pub fn primitive_float_gen_var_8() -> Generator { Generator::new( &exhaustive_primitive_float_gen_var_8, &random_primitive_float_gen_var_8, &special_random_primitive_float_gen_var_8, ) } // All primitive floats that are not NaN or positive infinity. pub fn primitive_float_gen_var_9() -> Generator { Generator::new( &exhaustive_primitive_float_gen_var_9, &random_primitive_float_gen_var_9, &special_random_primitive_float_gen_var_9, ) } // All primitive floats that are not NaN or negative infinity. pub fn primitive_float_gen_var_10() -> Generator { Generator::new( &exhaustive_primitive_float_gen_var_10, &random_primitive_float_gen_var_10, &special_random_primitive_float_gen_var_10, ) } // All primitive floats that are not NaN. pub fn primitive_float_gen_var_11() -> Generator { Generator::new( &exhaustive_primitive_float_gen_var_11, &random_primitive_float_gen_var_11, &special_random_primitive_float_gen_var_11, ) } // All nonzero finite primitive floats. pub fn primitive_float_gen_var_12() -> Generator { Generator::new( &exhaustive_primitive_float_gen_var_12, &random_primitive_float_gen_var_12, &special_random_primitive_float_gen_var_12, ) } // All primitive floats `T` that are equal to an unsigned value of type `U`. pub fn primitive_float_gen_var_13, U: PrimitiveUnsigned>( ) -> Generator where NiceFloat: TryFrom, { Generator::new( &exhaustive_primitive_float_gen_var_13::, &random_primitive_float_gen_var_13::, &special_random_primitive_float_gen_var_13::, ) } // All primitive floats `T` that are equal to a signed value of type `U`. pub fn primitive_float_gen_var_14, U: PrimitiveSigned>( ) -> Generator where NiceFloat: TryFrom, { Generator::new( &exhaustive_primitive_float_gen_var_14::, &random_primitive_float_gen_var_13::, &special_random_primitive_float_gen_var_14::, ) } // All primitive floats of type `T` that are not equal to any primitive integer of type `U`. pub fn primitive_float_gen_var_15 + PrimitiveInt>( ) -> Generator { Generator::new( &exhaustive_primitive_float_gen_var_15::, &random_primitive_float_gen_var_14::, &special_random_primitive_float_gen_var_15::, ) } // All primitive floats of type `T` that are halfway between two adjacent values of the primitive // unsigned type `U`. pub fn primitive_float_gen_var_16, U: PrimitiveUnsigned>( ) -> Generator { Generator::new( &exhaustive_primitive_float_gen_var_16::, &random_primitive_float_gen_var_15::, &special_random_primitive_float_gen_var_16::, ) } // All primitive floats of type `T` that are halfway between two adjacent values of the primitive // signed type `U`. pub fn primitive_float_gen_var_17, U: PrimitiveSigned>( ) -> Generator { Generator::new( &exhaustive_primitive_float_gen_var_17::, &random_primitive_float_gen_var_16::, &special_random_primitive_float_gen_var_17::, ) } // All positive finite primitive floats of type `T`. pub fn primitive_float_gen_var_18() -> Generator { Generator::new( &exhaustive_primitive_float_gen_var_18, &random_primitive_float_gen_var_17, &special_random_primitive_float_gen_var_18, ) } // All non-negative finite primitive floats of type `T` that are less than or equal to the largest // representable power of 2. Negative zero is excluded. pub fn primitive_float_gen_var_19() -> Generator { Generator::new( &exhaustive_primitive_float_gen_var_19, &random_primitive_float_gen_var_18, &special_random_primitive_float_gen_var_19, ) } // -- (PrimitiveFloat, PrimitiveFloat) -- pub fn primitive_float_pair_gen() -> Generator<(T, T)> { Generator::new( &exhaustive_primitive_float_pair_gen, &random_primitive_float_pair_gen, &special_random_primitive_float_pair_gen, ) } // All pairs of primitive floats that are not NaN. pub fn primitive_float_pair_gen_var_1() -> Generator<(T, T)> { Generator::new( &exhaustive_primitive_float_pair_gen_var_1, &random_primitive_float_pair_gen_var_1, &special_random_primitive_float_pair_gen_var_1, ) } // -- (PrimitiveFloat, PrimitiveFloat, PrimitiveFloat) -- pub fn primitive_float_triple_gen() -> Generator<(T, T, T)> { Generator::new( &exhaustive_primitive_float_triple_gen, &random_primitive_float_triple_gen, &special_random_primitive_float_triple_gen, ) } // -- (PrimitiveFloat, PrimitiveSigned) -- pub fn primitive_float_signed_pair_gen() -> Generator<(T, U)> { Generator::new( &exhaustive_primitive_float_signed_pair_gen, &random_primitive_float_signed_pair_gen, &special_random_primitive_float_signed_pair_gen, ) } // All `(T, U)` where `T` is a primitive float type, `U` is signed, the `T` is finite and positive, // and the `U` is small. pub fn primitive_float_signed_pair_gen_var_1( ) -> Generator<(T, U)> { Generator::new( &exhaustive_primitive_float_signed_pair_gen_var_1, &random_primitive_float_signed_pair_gen_var_1, &special_random_primitive_float_signed_pair_gen_var_1, ) } // All `(T, i64)` that are valid inputs to `T::from_sci_mantissa_and_exponent`. pub fn primitive_float_signed_pair_gen_var_2() -> Generator<(T, i64)> { Generator::new( &exhaustive_primitive_float_signed_pair_gen_var_2, &random_primitive_float_signed_pair_gen_var_2, &special_random_primitive_float_signed_pair_gen_var_2, ) } // All `(T, i64)` where `T` is a primitive float type, the `T` is greater than or equal to 1.0 and // less than 2.0, and the `i64` is small. pub fn primitive_float_signed_pair_gen_var_3() -> Generator<(T, i64)> { Generator::new( &exhaustive_primitive_float_signed_pair_gen_var_3, &random_primitive_float_signed_pair_gen_var_3, &special_random_primitive_float_signed_pair_gen_var_3, ) } // All `(T, U)` where `T` is a primitive float type, `U` is signed, and the `U` is small. pub fn primitive_float_signed_pair_gen_var_4( ) -> Generator<(T, U)> { Generator::new( &exhaustive_primitive_float_signed_pair_gen_var_4, &random_primitive_float_signed_pair_gen_var_4, &special_random_primitive_float_signed_pair_gen_var_4, ) } // -- (PrimitiveFloat, PrimitiveSigned, PrimitiveUnsigned) -- // All `(T, U, V)` where `T` is a primitive float type, `U` is signed, `V` is unsigned, the `U` is // small, and the `V` is small and positive. pub fn primitive_float_signed_unsigned_triple_gen_var_1< T: PrimitiveFloat, U: PrimitiveSigned, V: PrimitiveUnsigned, >() -> Generator<(T, U, V)> { Generator::new( &exhaustive_primitive_float_signed_unsigned_triple_gen_var_1, &random_primitive_float_signed_unsigned_triple_gen_var_1, &special_random_primitive_float_signed_unsigned_triple_gen_var_1, ) } // -- (PrimitiveFloat, PrimitiveUnsigned) -- // All `(T, U)` where `T` is a primitive float type, `U` is unsigned, the `T` is finite and // positive, and the `U` is small. pub fn primitive_float_unsigned_pair_gen_var_1( ) -> Generator<(T, U)> { Generator::new( &exhaustive_primitive_float_unsigned_pair_gen_var_1, &random_primitive_float_unsigned_pair_gen_var_1, &special_random_primitive_float_unsigned_pair_gen_var_1, ) } // All `(T, u64)` where `T` is a primitive float type, the `T` is greater than or equal to 1.0 and // less than 2.0, and the `u64` is small. pub fn primitive_float_unsigned_pair_gen_var_2() -> Generator<(T, u64)> { Generator::new( &exhaustive_primitive_float_unsigned_pair_gen_var_2, &random_primitive_float_unsigned_pair_gen_var_2, &special_random_primitive_float_unsigned_pair_gen_var_2, ) } // All `(T, U)` where `T` is a primitive float type, `U` is unsigned, the `T` is finite and // positive, and the `U` is small and positive. pub fn primitive_float_unsigned_pair_gen_var_3( ) -> Generator<(T, U)> { Generator::new( &exhaustive_primitive_float_primitive_int_pair_gen_var_1, &random_primitive_float_unsigned_pair_gen_var_3, &special_random_primitive_float_unsigned_pair_gen_var_3, ) } // All `(T, U)` where `T` is a primitive float type, `U` is unsigned, and the `U` is small and // positive. pub fn primitive_float_unsigned_pair_gen_var_4( ) -> Generator<(T, U)> { Generator::new( &exhaustive_primitive_float_unsigned_pair_gen_var_3, &random_primitive_float_unsigned_pair_gen_var_4, &special_random_primitive_float_unsigned_pair_gen_var_4, ) } // -- (PrimitiveFloat, PrimitiveUnsigned, RoundingMode) -- // All `(T, U, RoundingMode)` where `T` is a primitive float type, `U` is unsigned, the `T` is // finite and positive, and the `U` is small. pub fn primitive_float_unsigned_rounding_mode_triple_gen_var_1< T: PrimitiveFloat, U: PrimitiveUnsigned, >() -> Generator<(T, U, RoundingMode)> { Generator::new( &exhaustive_primitive_float_unsigned_rounding_mode_triple_gen_var_1, &random_primitive_float_unsigned_rounding_mode_triple_gen_var_1, &special_random_primitive_float_unsigned_rounding_mode_triple_gen_var_1, ) } // All `(T, u64, RoundingMode)` where `T` is a primitive float type, the `T` is greater than or // equal to 1.0 and less than 2.0, and the `u64` is small. pub fn primitive_float_unsigned_rounding_mode_triple_gen_var_2( ) -> Generator<(T, u64, RoundingMode)> { Generator::new( &exhaustive_primitive_float_unsigned_rounding_mode_triple_gen_var_2, &random_primitive_float_unsigned_rounding_mode_triple_gen_var_2, &special_random_primitive_float_unsigned_rounding_mode_triple_gen_var_2, ) } // var 3 is in malachite-float. // -- (PrimitiveFloat, RoundingMode) -- // All `(T, RoundingMode)` where `T` is a primitive float and the values are valid inputs to // `Natural::rounding_from`. pub fn primitive_float_rounding_mode_pair_gen_var_1( ) -> Generator<(T, RoundingMode)> { Generator::new( &exhaustive_primitive_float_rounding_mode_pair_gen_var_1, &random_primitive_float_rounding_mode_pair_gen_var_1, &special_random_primitive_float_rounding_mode_pair_gen_var_1, ) } // All `(T, RoundingMode)` where `T` is a primitive float and the values are valid inputs to // `Integer::rounding_from`. pub fn primitive_float_rounding_mode_pair_gen_var_2( ) -> Generator<(T, RoundingMode)> { Generator::new( &exhaustive_primitive_float_rounding_mode_pair_gen_var_2, &random_primitive_float_rounding_mode_pair_gen_var_2, &special_random_primitive_float_rounding_mode_pair_gen_var_2, ) } // All `(T, RoundingMode)` where `T` is a primitive float, `U` is unsigned, and the pair is a valid // input to `U::rounding_from`. pub fn primitive_float_rounding_mode_pair_gen_var_3< T: PrimitiveFloat + RoundingFrom, U: ConvertibleFrom + PrimitiveInt, >() -> Generator<(T, RoundingMode)> { Generator::new( &exhaustive_primitive_float_rounding_mode_pair_gen_var_3::, &random_primitive_float_rounding_mode_pair_gen_var_3::, &special_random_primitive_float_rounding_mode_pair_gen_var_3::, ) } // -- PrimitiveSigned -- pub fn signed_gen() -> Generator { Generator::new( &exhaustive_signed_gen, &random_primitive_int_gen, &special_random_signed_gen, ) } // All signed `T`s which are not `T::MIN`. pub fn signed_gen_var_1() -> Generator { Generator::new( &exhaustive_signed_gen_var_1, &random_signed_gen_var_1, &special_random_signed_gen_var_1, ) } // All signed natural (non-negative) `T`s. pub fn signed_gen_var_2() -> Generator { Generator::new( &exhaustive_signed_gen_var_2, &random_signed_gen_var_2, &special_random_signed_gen_var_2, ) } // All signed `T`s that are neither 0 nor -1. pub fn signed_gen_var_3() -> Generator { Generator::new( &exhaustive_signed_gen_var_3, &random_signed_gen_var_3, &special_random_signed_gen_var_3, ) } // All negative signed `T`s. pub fn signed_gen_var_4() -> Generator { Generator::new( &exhaustive_signed_gen_var_4, &random_signed_gen_var_4, &special_random_signed_gen_var_4, ) } // All small signed `T`s. pub fn signed_gen_var_5() -> Generator { Generator::new_no_special(&exhaustive_signed_gen::, &random_signed_gen_var_5::) } // All nonzero signed `T`s. pub fn signed_gen_var_6() -> Generator { Generator::new( &exhaustive_signed_gen_var_5, &random_signed_gen_var_6, &special_random_signed_gen_var_5, ) } // All signeds `T` that are equal to a primitive float value of type `U`. pub fn signed_gen_var_7< T: PrimitiveSigned + RoundingFrom, U: ConvertibleFrom + PrimitiveFloat + RoundingFrom, >() -> Generator { Generator::new( &exhaustive_signed_gen_var_6::, &random_primitive_int_gen_var_1::, &special_random_primitive_int_gen_var_1::, ) } type G = Generator; // All signeds `S` that are not exactly equal to any value of a floating-point type `V`. // // Acceptable `(S, V)` pairs are those where `S::WIDTH` > `V::MANTISSA_WIDTH`. pub fn signed_gen_var_8< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, V: ConvertibleFrom + PrimitiveFloat, >() -> G { Generator::new( &exhaustive_signed_gen_var_7::, &random_signed_gen_var_7::, &special_random_signed_gen_var_6::, ) } // All signeds `S` that are exactly between two values of a floating-point type `V`. // // Acceptable `(S, V)` pairs are those where `S::WIDTH` > `V::MANTISSA_WIDTH`. pub fn signed_gen_var_9< U: PrimitiveUnsigned + WrappingFrom, S: TryFrom> + PrimitiveSigned + WrappingFrom, V: ConvertibleFrom + PrimitiveFloat + RoundingFrom, >() -> Generator { Generator::new( &exhaustive_signed_gen_var_8::, &random_signed_gen_var_8::, &special_random_signed_gen_var_7::, ) } // All signed `T`s whose square is also representable as a `T`. pub fn signed_gen_var_10< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >() -> Generator { Generator::new( &exhaustive_signed_gen_var_9::, &random_signed_gen_var_9::, &special_random_signed_gen_var_8::, ) } // All valid scientific exponents for the float type `T`. pub fn signed_gen_var_11() -> Generator { Generator::new( &exhaustive_signed_gen_var_10::, &random_signed_gen_var_10::, &special_random_signed_gen_var_9::, ) } // All signed `T`s that are neither 0 nor -1. pub fn signed_gen_var_12() -> Generator { Generator::new( &exhaustive_signed_gen_var_11, &random_signed_gen_var_11, &special_random_signed_gen_var_10, ) } // All odd positive signeds. pub fn signed_gen_var_13< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >() -> Generator { Generator::new( &exhaustive_signed_gen_var_12, &random_signed_gen_var_12, &special_random_signed_gen_var_11::, ) } // -- (PrimitiveSigned, PrimitiveSigned) -- pub fn signed_pair_gen() -> Generator<(T, T)> { Generator::new( &exhaustive_signed_pair_gen, &random_primitive_int_pair_gen_var_1, &special_random_signed_pair_gen, ) } // All pairs of signeds where either both values are non-negative or both are negative. pub fn signed_pair_gen_var_1() -> Generator<(T, T)> { Generator::new( &exhaustive_signed_pair_gen_var_1, &random_signed_pair_gen_var_1, &special_random_signed_pair_gen_var_1, ) } // All pairs of signeds where the second value is small. pub fn signed_pair_gen_var_2() -> Generator<(T, U)> { Generator::new( &exhaustive_signed_pair_gen_var_3, &random_primitive_int_signed_pair_gen_var_1, &special_random_signed_pair_gen_var_2, ) } // All pairs of signed `T` where the first is divisible by the second. pub fn signed_pair_gen_var_3() -> Generator<(T, T)> { Generator::new( &exhaustive_signed_pair_gen_var_4, &random_signed_pair_gen_var_2, &special_random_signed_pair_gen_var_3, ) } // All pairs of signed `T` where the second `T` is nonzero and the pair is not `(T::MIN, -1)`. pub fn signed_pair_gen_var_4() -> Generator<(T, T)> { Generator::new( &exhaustive_signed_pair_gen_var_5, &random_signed_pair_gen_var_3, &special_random_signed_pair_gen_var_4, ) } // All pairs of signed `T` where the second `T` is nonzero and the first is not divisible by the // second. pub fn signed_pair_gen_var_5() -> Generator<(T, T)> { Generator::new( &exhaustive_signed_pair_gen_var_6, &random_signed_pair_gen_var_4, &special_random_signed_pair_gen_var_5, ) } // All pairs of signed `T` where the second `T` is nonzero. pub fn signed_pair_gen_var_6() -> Generator<(T, T)> { Generator::new( &exhaustive_signed_pair_gen_var_7, &random_signed_pair_gen_var_5, &special_random_signed_pair_gen_var_6, ) } // All pairs of natural (non-negative) signeds. pub fn signed_pair_gen_var_7() -> Generator<(T, T)> { Generator::new( &exhaustive_signed_pair_gen_var_8, &random_signed_pair_gen_var_6, &special_random_signed_pair_gen_var_7, ) } // All pairs of signeds where the second element is positive and odd. pub fn signed_pair_gen_var_8< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >() -> Generator<(S, S)> { Generator::new( &exhaustive_signed_pair_gen_var_9, &random_signed_pair_gen_var_7, &special_random_signed_pair_gen_var_8::, ) } // All coprime pairs of signeds where both elements are odd and positive. pub fn signed_pair_gen_var_9< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + UnsignedAbs + WrappingFrom, >() -> Generator<(S, S)> { Generator::new( &exhaustive_signed_pair_gen_var_10, &random_signed_pair_gen_var_8, &special_random_signed_pair_gen_var_9::, ) } // All coprime pairs of signeds. pub fn signed_pair_gen_var_10< U: PrimitiveUnsigned, S: PrimitiveSigned + UnsignedAbs, >() -> Generator<(S, S)> { Generator::new( &exhaustive_signed_pair_gen_var_11, &random_signed_pair_gen_var_9, &special_random_signed_pair_gen_var_10, ) } // All `(T, U)` where `T` and `U` are signed and both the `T` and the `U` are small. pub fn signed_pair_gen_var_11() -> Generator<(T, U)> { Generator::new_no_special( &exhaustive_signed_pair_gen_var_12, &random_signed_pair_gen_var_10, ) } // All `(T, T)` where the `T`s are small, signed, and valid inputs to `T::binomial_coefficient`. pub fn signed_pair_gen_var_12() -> Generator<(T, T)> { Generator::new_no_special( &exhaustive_signed_pair_gen_var_13, &random_signed_pair_gen_var_11, ) } // -- (PrimitiveSigned, PrimitiveSigned, PrimitiveSigned) -- pub fn signed_triple_gen() -> Generator<(T, T, T)> { Generator::new( &exhaustive_signed_triple_gen, &random_primitive_int_triple_gen_var_4, &special_random_signed_triple_gen, ) } // All `(x, y, z): (T, T, T)` where `T` is signed and x + y * z does not overflow. pub fn signed_triple_gen_var_1() -> Generator<(T, T, T)> { Generator::new( &exhaustive_signed_triple_gen_var_1, &random_signed_triple_gen_var_1, &special_random_signed_triple_gen_var_1, ) } // All `(x, y, z): (T, T, T)` where `T` is signed and x - y * z does not overflow. pub fn signed_triple_gen_var_2() -> Generator<(T, T, T)> { Generator::new( &exhaustive_signed_triple_gen_var_2, &random_signed_triple_gen_var_2, &special_random_signed_triple_gen_var_2, ) } // All triple of signeds where either all values are non-negative or all are negative. pub fn signed_triple_gen_var_3() -> Generator<(T, T, T)> { Generator::new( &exhaustive_signed_triple_gen_var_3, &random_signed_triple_gen_var_3, &special_random_signed_triple_gen_var_3, ) } // All triples of signeds (x, y, m) where x is equal to y mod m. pub fn signed_triple_gen_var_4< U: PrimitiveUnsigned + WrappingInto + WrappingFrom, S: PrimitiveSigned + UnsignedAbs + WrappingFrom, >() -> Generator<(S, S, S)> { Generator::new( &exhaustive_signed_triple_gen_var_4, &random_signed_triple_gen_var_4::, &special_random_signed_triple_gen_var_4::, ) } // All triples of signeds (x, y, m) where x is not equal to y mod m. pub fn signed_triple_gen_var_5() -> Generator<(T, T, T)> { Generator::new( &exhaustive_signed_triple_gen_var_5, &random_primitive_int_triple_gen_var_1, &special_random_signed_triple_gen_var_5, ) } // All triples of signeds where the third element is positive and odd. pub fn signed_triple_gen_var_6< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >() -> Generator<(S, S, S)> { Generator::new( &exhaustive_signed_triple_gen_var_6, &random_signed_triple_gen_var_5, &special_random_signed_triple_gen_var_6::, ) } // All triples of signeds where the second and third elements are positive and odd. pub fn signed_triple_gen_var_7< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >() -> Generator<(S, S, S)> { Generator::new( &exhaustive_signed_triple_gen_var_7, &random_signed_triple_gen_var_6, &special_random_signed_triple_gen_var_7::, ) } // -- (PrimitiveSigned, PrimitiveSigned, PrimitiveSigned, PrimitiveSigned) -- pub fn signed_quadruple_gen() -> Generator<(T, T, T, T)> { Generator::new( &exhaustive_signed_quadruple_gen, &random_primitive_int_quadruple_gen_var_4, &special_random_signed_quadruple_gen, ) } // -- (PrimitiveSigned, PrimitiveSigned, PrimitiveSigned, PrimitiveUnsigned) -- // All `(T, T, T, U)` where `T` is signed, `U` is unsigned, and the `U` is small. pub fn signed_signed_signed_unsigned_quadruple_gen_var_1< T: PrimitiveSigned, U: PrimitiveUnsigned, >() -> Generator<(T, T, T, U)> { Generator::new( &exhaustive_signed_signed_signed_unsigned_quadruple_gen_var_1, &random_primitive_int_primitive_int_primitive_int_unsigned_quadruple_gen_var_1, &special_random_signed_signed_signed_unsigned_quadruple_gen_var_2, ) } // -- (PrimitiveSigned, PrimitiveSigned, PrimitiveUnsigned) -- // All triples `(T, T, u64)` (x, y, k) where `T` is signed and x is equal to y mod $2^k$. pub fn signed_signed_unsigned_triple_gen_var_1< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >() -> Generator<(S, S, u64)> { Generator::new( &exhaustive_signed_signed_unsigned_triple_gen_var_1::, &random_signed_signed_unsigned_triple_gen_var_1::, &special_random_signed_signed_unsigned_triple_gen_var_1::, ) } // All `(T, T, U)` where `T` is signed, `U` is unsigned, and the `U` is small. pub fn signed_signed_unsigned_triple_gen_var_2( ) -> Generator<(T, T, U)> { Generator::new( &exhaustive_signed_unsigned_unsigned_triple_gen_var_4, &random_primitive_int_primitive_int_unsigned_triple_gen_var_2, &special_random_signed_signed_unsigned_triple_gen_var_2, ) } // All triples `(T, T, u64)` (x, y, k) where `T` is unsigned and x is not equal to y mod $2^k$. pub fn signed_signed_unsigned_triple_gen_var_3() -> Generator<(T, T, u64)> { Generator::new( &exhaustive_signed_signed_unsigned_triple_gen_var_2, &random_primitive_int_primitive_int_unsigned_triple_gen_var_3, &special_random_signed_signed_unsigned_triple_gen_var_3, ) } // All `(T, U, V)` where `T` is signed, `U` is signed and small, and `V` is unsigned, small, and // positive. pub fn signed_signed_unsigned_triple_gen_var_4< T: PrimitiveSigned, U: PrimitiveSigned, V: PrimitiveUnsigned, >() -> Generator<(T, U, V)> { Generator::new( &exhaustive_signed_signed_unsigned_triple_gen_var_3, &random_signed_signed_unsigned_triple_gen_var_2, &special_random_signed_signed_unsigned_triple_gen_var_4, ) } // -- (PrimitiveSigned, PrimitiveSigned, RoundingMode) -- // All `(T, T, RoundingMode)` where `T` is signed and the triple is a valid input to `T::div_round`. pub fn signed_signed_rounding_mode_triple_gen_var_1( ) -> Generator<(T, T, RoundingMode)> { Generator::new( &exhaustive_signed_signed_rounding_mode_triple_gen_var_1, &random_signed_signed_rounding_mode_triple_gen_var_1, &special_random_signed_signed_rounding_mode_triple_gen_var_1, ) } // All `(T, T, RoundingMode)` where `T` is signed and the triple is a valid input to // `T::round_to_multiple`. pub fn signed_signed_rounding_mode_triple_gen_var_2< U: PrimitiveUnsigned, S: TryFrom + ConvertibleFrom + PrimitiveSigned + UnsignedAbs, >() -> Generator<(S, S, RoundingMode)> { Generator::new( &exhaustive_signed_signed_rounding_mode_triple_gen_var_2, &random_signed_signed_rounding_mode_triple_gen_var_2, &special_random_signed_signed_rounding_mode_triple_gen_var_2, ) } // All `(T, U, RoundingMode)` where `T` and `U` are signed and the triple is a valid input to // `T::shr_round`. pub fn signed_signed_rounding_mode_triple_gen_var_3( ) -> Generator<(T, U, RoundingMode)> { Generator::new( &exhaustive_signed_signed_rounding_mode_triple_gen_var_3, &random_primitive_int_signed_rounding_mode_triple_gen_var_1, &special_random_signed_signed_rounding_mode_triple_gen_var_3, ) } // All `(T, U, RoundingMode)` where `T` and `U` are signed and the triple is a valid input to // `T::shl_round`. pub fn signed_signed_rounding_mode_triple_gen_var_4( ) -> Generator<(T, U, RoundingMode)> { Generator::new( &exhaustive_signed_signed_rounding_mode_triple_gen_var_4, &random_primitive_int_signed_rounding_mode_triple_gen_var_2, &special_random_signed_signed_rounding_mode_triple_gen_var_4, ) } // -- (PrimitiveSigned, PrimitiveUnsigned) -- pub fn signed_unsigned_pair_gen() -> Generator<(T, U)> { Generator::new( &exhaustive_signed_unsigned_pair_gen, &random_primitive_int_pair_gen, &special_random_signed_unsigned_pair_gen, ) } // All `(T, U)`s where `T` is signed, `U` is unsigned, and the `U` is small. pub fn signed_unsigned_pair_gen_var_1( ) -> Generator<(T, U)> { Generator::new( &exhaustive_signed_unsigned_pair_gen_var_2, &random_primitive_int_unsigned_pair_gen_var_1, &special_random_signed_unsigned_pair_gen_var_1, ) } // All `(T, u64)`s where `T` is signed and the `u64` is smaller than `T::WIDTH`. pub fn signed_unsigned_pair_gen_var_2() -> Generator<(T, u64)> { Generator::new( &exhaustive_signed_unsigned_pair_gen_var_4, &random_primitive_int_unsigned_pair_gen_var_2, &special_random_signed_unsigned_pair_gen_var_2, ) } // All `(T, u64)`s where `T` is signed and the either the `T` is negative or the `u64` is less than // `T::WIDTH`. pub fn signed_unsigned_pair_gen_var_3() -> Generator<(T, u64)> { Generator::new( &exhaustive_signed_unsigned_pair_gen_var_3, &random_signed_unsigned_pair_gen_var_1, &special_random_signed_unsigned_pair_gen_var_3, ) } // All `(T, u64)`s where `T` is signed and the either the `T` is non-negative or the `u64` is less // than `T::WIDTH`. pub fn signed_unsigned_pair_gen_var_4() -> Generator<(T, u64)> { Generator::new( &exhaustive_signed_unsigned_pair_gen_var_5, &random_signed_unsigned_pair_gen_var_2, &special_random_signed_unsigned_pair_gen_var_4, ) } // All `(T, U)`s where `T` is signed, `U` is unsigned, and the `U` is greater than 1 and no greater // than 36. pub fn signed_unsigned_pair_gen_var_5 + PrimitiveUnsigned>( ) -> Generator<(T, U)> { Generator::new( &exhaustive_signed_unsigned_pair_gen_var_6, &random_primitive_int_unsigned_pair_gen_var_5, &special_random_signed_unsigned_pair_gen_var_5, ) } // All `(T, U)`s where `T` is signed, `U` is unsigned, the `T` is non-negative, and the `U` is // small. pub fn signed_unsigned_pair_gen_var_6( ) -> Generator<(T, U)> { Generator::new( &exhaustive_signed_unsigned_pair_gen_var_7, &random_signed_unsigned_pair_gen_var_3, &special_random_signed_unsigned_pair_gen_var_6, ) } // All `(T, U)`s where `T` is signed, `U` is unsigned, the `T` is non-negative, and the `U` is // greater than 1 and no greater than 36. pub fn signed_unsigned_pair_gen_var_7 + PrimitiveUnsigned>( ) -> Generator<(T, U)> { Generator::new( &exhaustive_signed_unsigned_pair_gen_var_8, &random_signed_unsigned_pair_gen_var_4, &special_random_signed_unsigned_pair_gen_var_7, ) } // All `(T, U)`s where `T` is signed, `U` is unsigned, the `U` is small, and the `T` is not // divisible by 2 to the power of the `U`. pub fn signed_unsigned_pair_gen_var_8( ) -> Generator<(T, U)> { Generator::new( &exhaustive_signed_unsigned_pair_gen_var_9, &random_primitive_int_unsigned_pair_gen_var_6, &special_random_signed_unsigned_pair_gen_var_8, ) } // All `(T, U)`s where `T` is signed, `U` is unsigned, the `U` is small, and the `T` is divisible by // 2 to the power of the `U`. pub fn signed_unsigned_pair_gen_var_9( ) -> Generator<(T, u64)> { Generator::new( &exhaustive_signed_unsigned_pair_gen_var_10, &random_primitive_int_unsigned_pair_gen_var_7, &special_random_signed_unsigned_pair_gen_var_9, ) } // All `(T, u64)`s where `T` is signed and the either the `T` is non-negative or the `u64` is less // than or equal to `T::WIDTH`. pub fn signed_unsigned_pair_gen_var_10() -> Generator<(T, u64)> { Generator::new( &exhaustive_signed_unsigned_pair_gen_var_11, &random_signed_unsigned_pair_gen_var_5, &special_random_signed_unsigned_pair_gen_var_10, ) } // All `(S, u64)`s where `S` is signed and the either the `S` is non-positive and not `S::MIN`, or // the `u64` is less than `S::WIDTH`. pub fn signed_unsigned_pair_gen_var_11< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >() -> Generator<(S, u64)> { Generator::new( &exhaustive_signed_unsigned_pair_gen_var_12, &random_signed_unsigned_pair_gen_var_6, &special_random_signed_unsigned_pair_gen_var_11::, ) } // All `(T, u64)`s where `T` is signed and the `u64` is between 0 and `U::WIDTH`, inclusive. pub fn signed_unsigned_pair_gen_var_12( ) -> Generator<(T, u64)> { Generator::new( &exhaustive_signed_unsigned_pair_gen_var_13::, &random_primitive_int_unsigned_pair_gen_var_8::, &special_random_unsigned_pair_gen_var_17::, ) } // All `(S, V)`s where `S` is signed, `V` is unsigned, `S` is between `-u64::MAX` and `u64::MAX`, // inclusive, and the `V` is positive. pub fn signed_unsigned_pair_gen_var_13< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, V: PrimitiveUnsigned, >() -> Generator<(S, V)> { Generator::new( &exhaustive_signed_unsigned_pair_gen_var_14, &random_signed_unsigned_pair_gen_var_7, &special_random_signed_unsigned_pair_gen_var_12::, ) } // All `(T, U)`s where `T` is signed, `U` is unsigned, and both `T` and `U` are small. pub fn signed_unsigned_pair_gen_var_14( ) -> Generator<(T, U)> { Generator::new_no_special( &exhaustive_signed_unsigned_pair_gen, &random_signed_unsigned_pair_gen_var_8, ) } // All `(T, u64)`s where `T` is signed, both the `T` and the `u64` are small, and the `T` raised to // the power of the `u64` does not overflow. pub fn signed_unsigned_pair_gen_var_15() -> Generator<(T, u64)> { Generator::new_no_special( &exhaustive_signed_unsigned_pair_gen_var_15, &random_signed_unsigned_pair_gen_var_9, ) } // All `(T, U)`s where `T` is signed, `U` is unsigned, the `T` is positive, and the `U` is small. pub fn signed_unsigned_pair_gen_var_16( ) -> Generator<(T, U)> { Generator::new( &exhaustive_primitive_int_unsigned_pair_gen_var_1, &random_signed_unsigned_pair_gen_var_10, &special_random_signed_unsigned_pair_gen_var_13, ) } // All `(S, V)`s where `S` is signed, `V` is unsigned, the `S` is negative and not `S::MIN`, and the // `V` is small. pub fn signed_unsigned_pair_gen_var_17< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, V: PrimitiveUnsigned, >() -> Generator<(S, V)> { Generator::new( &exhaustive_signed_unsigned_pair_gen_var_16, &random_signed_unsigned_pair_gen_var_11, &special_random_signed_unsigned_pair_gen_var_15::, ) } // All `(T, U)`s where `T` is signed, the `U` is unsigned, positive, and small, and either the `T` // is non-negative or the `U` is odd. pub fn signed_unsigned_pair_gen_var_18( ) -> Generator<(T, U)> { Generator::new( &exhaustive_signed_unsigned_pair_gen_var_17, &random_signed_unsigned_pair_gen_var_12, &special_random_signed_unsigned_pair_gen_var_14, ) } // All `(T, U)`s where `T` is signed, `U` is unsigned, and both `T` and `U` are small, and the `U` // is positive. pub fn signed_unsigned_pair_gen_var_19( ) -> Generator<(T, U)> { Generator::new_no_special( &exhaustive_signed_unsigned_pair_gen_var_18, &random_signed_unsigned_pair_gen_var_13, ) } // All `(T, U)`s where `T` is signed, `U` is unsigned, and the `U` is small and positive. pub fn signed_unsigned_pair_gen_var_20( ) -> Generator<(T, U)> { Generator::new( &exhaustive_signed_unsigned_pair_gen_var_19, &random_primitive_int_unsigned_pair_gen_var_10, &special_random_signed_unsigned_pair_gen_var_16, ) } // -- (PrimitiveSigned, PrimitiveUnsigned, bool) -- // All (`T`, `u64`, and `bool`) where `T` is signed and either the `u64` is smaller than `T::WIDTH` // or the `bool` is equal to whether the `T` is negative. pub fn signed_unsigned_bool_triple_gen_var_1() -> Generator<(T, u64, bool)> { Generator::new( &exhaustive_signed_unsigned_bool_triple_gen_var_1, &random_primitive_int_unsigned_bool_triple_gen_var_2, &random_signed_unsigned_bool_triple_gen_var_1, ) } // -- (PrimitiveSigned, PrimitiveUnsigned, PrimitiveUnsigned) -- // All `(T, U, V)` where `T` is signed, `U` and `V` are unsigned, and the `V` is small. pub fn signed_unsigned_unsigned_triple_gen_var_1< T: PrimitiveSigned, U: PrimitiveUnsigned, V: PrimitiveUnsigned, >() -> Generator<(T, U, V)> { Generator::new( &exhaustive_signed_unsigned_unsigned_triple_gen_var_1, &random_primitive_int_primitive_int_unsigned_triple_gen_var_2, &special_random_signed_unsigned_unsigned_triple_gen_var_1, ) } // All `(S, V, V)` where `S` is signed, `V` is unsigned, both `V`s are small, the first `V` is less // than or equal to the second, and if the `S` is negative, the difference between the two `V`s is // no greater than the width of `S`. pub fn signed_unsigned_unsigned_triple_gen_var_2< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, V: PrimitiveUnsigned, >() -> Generator<(S, V, V)> { Generator::new( &exhaustive_signed_unsigned_unsigned_triple_gen_var_2, &random_signed_unsigned_unsigned_triple_gen_var_1, &special_random_signed_unsigned_unsigned_triple_gen_var_2::, ) } // All `(T, U, V)`s where `T` is signed, `U` and `V` are unsigned, the `U` is greater than 1 and no // greater than 36, and the `V` is small. pub fn signed_unsigned_unsigned_triple_gen_var_3< T: PrimitiveSigned, U: ExactFrom + PrimitiveUnsigned, V: PrimitiveUnsigned, >() -> Generator<(T, U, V)> { Generator::new( &exhaustive_signed_unsigned_unsigned_triple_gen_var_3, &random_primitive_int_unsigned_unsigned_triple_gen_var_3, &special_random_signed_unsigned_unsigned_triple_gen_var_3, ) } // -- (PrimitiveSigned, PrimitiveUnsigned, PrimitiveUnsigned, PrimitiveUnsigned) -- // All `(T, u64, u64, U)` where `T` is signed, `U` is unsigned, both `u64`s are small, and the four // values are valid arguments to `assign_bits`. pub fn signed_unsigned_unsigned_unsigned_quadruple_gen_var_1< T: PrimitiveSigned + UnsignedAbs, U: BitBlockAccess + PrimitiveUnsigned, >() -> Generator<(T, u64, u64, U)> { Generator::new( &exhaustive_signed_unsigned_unsigned_unsigned_quadruple_gen_var_1, &random_signed_unsigned_unsigned_unsigned_quadruple_gen_var_1, &special_random_signed_unsigned_unsigned_unsigned_quadruple_gen_var_1, ) } // -- (PrimitiveSigned, PrimitiveUnsigned, RoundingMode) -- // All `(T, u64, RoundingMode)` where `T` is signed and the triple is a valid input to // `T::round_to_multiple_of_power_of_2`. pub fn signed_unsigned_rounding_mode_triple_gen_var_1( ) -> Generator<(T, u64, RoundingMode)> { Generator::new( &exhaustive_signed_unsigned_rounding_mode_triple_gen_var_1, &random_primitive_int_unsigned_rounding_mode_triple_gen_var_1, &special_random_signed_unsigned_rounding_mode_triple_gen_var_1, ) } // All `(T, U, RoundingMode)` where `T` is signed, `U` is unsigned, and the triple is a valid input // to `T::shr_round`. pub fn signed_unsigned_rounding_mode_triple_gen_var_2( ) -> Generator<(T, U, RoundingMode)> { Generator::new( &exhaustive_signed_unsigned_rounding_mode_triple_gen_var_2, &random_primitive_int_unsigned_rounding_mode_triple_gen_var_2, &special_random_signed_unsigned_rounding_mode_triple_gen_var_2, ) } // var 3 is in malachite-float. // -- (PrimitiveSigned, RoundingMode) -- pub fn signed_rounding_mode_pair_gen() -> Generator<(T, RoundingMode)> { Generator::new( &exhaustive_signed_rounding_mode_pair_gen, &random_primitive_int_rounding_mode_pair_gen, &special_random_signed_rounding_mode_pair_gen, ) } // All `(T, RoundingMode)`s where `T` is signed and the `T` is nonzero. pub fn signed_rounding_mode_pair_gen_var_1() -> Generator<(T, RoundingMode)> { Generator::new( &exhaustive_signed_rounding_mode_pair_gen_var_1, &random_signed_rounding_mode_pair_gen_var_1, &special_random_signed_rounding_mode_pair_gen_var_1, ) } // All `(T, RoundingMode)`s where `T` is signed and the `T` is not `T::MIN`. pub fn signed_rounding_mode_pair_gen_var_2() -> Generator<(T, RoundingMode)> { Generator::new( &exhaustive_signed_rounding_mode_pair_gen_var_2, &random_signed_rounding_mode_pair_gen_var_2, &special_random_signed_rounding_mode_pair_gen_var_2, ) } // All `(T, RoundingMode)`s where `T` is signed and the `T` is nonzero and not `T::MIN`. pub fn signed_rounding_mode_pair_gen_var_3() -> Generator<(T, RoundingMode)> { Generator::new( &exhaustive_signed_rounding_mode_pair_gen_var_3, &random_signed_rounding_mode_pair_gen_var_3, &special_random_signed_rounding_mode_pair_gen_var_3, ) } // All `(T, RoundingMode)` where `T` is signed, `U` is a primitive float type, and the pair is a // valid input to `U::rounding_from`. pub fn signed_rounding_mode_pair_gen_var_4< T: PrimitiveSigned, U: ConvertibleFrom + PrimitiveFloat, >() -> Generator<(T, RoundingMode)> { Generator::new( &exhaustive_signed_rounding_mode_pair_gen_var_4::, &random_primitive_int_rounding_mode_pair_gen_var_1::, &special_random_signed_rounding_mode_pair_gen_var_4::, ) } // -- (PrimitiveSigned, ToSciOptions) -- pub fn signed_to_sci_options_pair_gen() -> Generator<(T, ToSciOptions)> { Generator::new( &exhaustive_signed_to_sci_options_pair_gen, &random_primitive_int_to_sci_options_pair_gen, &special_random_signed_to_sci_options_pair_gen, ) } // All `(T, ToSciOptions)` pairs where `T` is signed and the `T` can be formatted using the options. pub fn signed_to_sci_options_pair_gen_var_1() -> Generator<(T, ToSciOptions)> { Generator::new( &exhaustive_signed_to_sci_options_pair_gen_var_1, &random_primitive_int_to_sci_options_pair_gen_var_1, &special_random_signed_to_sci_options_pair_gen_var_1, ) } // -- (PrimitiveSigned, Vec) -- // All `(T, Vec)` where `T` is signed and the `Vec` has as many elements as // `u64::exact_from(n.to_bits_asc().len())` (which is not necessarily the same as the number of // significant bits). pub fn signed_bool_vec_pair_gen_var_1() -> Generator<(T, Vec)> { Generator::new( &exhaustive_signed_bool_vec_pair_gen_var_1, &random_signed_bool_vec_pair_gen_var_1, &special_random_signed_bool_vec_pair_gen_var_1, ) } // -- PrimitiveUnsigned -- pub fn unsigned_gen() -> Generator { Generator::new( &exhaustive_unsigned_gen, &random_primitive_int_gen, &special_random_unsigned_gen, ) } // All unsigned positive `T`s. pub fn unsigned_gen_var_1() -> Generator { Generator::new( &exhaustive_primitive_int_gen_var_1, &random_unsigned_gen_var_1, &special_random_unsigned_gen_var_1, ) } // All `u32`s smaller than `NUMBER_OF_CHARS`. pub fn unsigned_gen_var_2() -> Generator { Generator::new( &exhaustive_unsigned_gen_var_1, &random_unsigned_gen_var_2, &special_random_unsigned_gen_var_2, ) } // All `u64`s between 1 and `T::WIDTH`, inclusive, where `T` is a primitive integer. pub fn unsigned_gen_var_3() -> Generator { Generator::new( &exhaustive_unsigned_gen_var_2::, &random_unsigned_gen_var_3::, &special_random_unsigned_gen_var_3::, ) } // All `U`s greater than 1 and no greater than `T::MAX`. pub fn unsigned_gen_var_4>( ) -> Generator { Generator::new( &exhaustive_unsigned_gen_var_4::, &random_unsigned_gen_var_4::, &special_random_unsigned_gen_var_4::, ) } // All small unsigned `T`s. pub fn unsigned_gen_var_5() -> Generator { Generator::new_no_special( &exhaustive_unsigned_gen::, &random_unsigned_gen_var_5::, ) } // All unsigned `T`s greater than or equal to 2. pub fn unsigned_gen_var_6() -> Generator { Generator::new( &exhaustive_primitive_int_gen_var_2::, &random_unsigned_gen_var_6::, &special_random_unsigned_gen_var_5::, ) } // All unsigned `T`s less than 36. pub fn unsigned_gen_var_7() -> Generator { Generator::new( &exhaustive_primitive_int_gen_var_3, &random_unsigned_gen_var_7, &special_random_unsigned_gen_var_6, ) } // All unsigned `T`s greater than or equal to 2 and less than or equal to 36. pub fn unsigned_gen_var_8() -> Generator { Generator::new( &exhaustive_primitive_int_gen_var_4, &random_unsigned_gen_var_8, &special_random_unsigned_gen_var_7, ) } // All `u64`s between 0 and `T::WIDTH`, inclusive, where `T` is a primitive integer. pub fn unsigned_gen_var_9() -> Generator { Generator::new( &exhaustive_unsigned_gen_var_5::, &random_unsigned_gen_var_9::, &special_random_unsigned_gen_var_8::, ) } // All `u8`s that correspond to an ASCII alphanumeric character: '0' through '9', 'a' through 'z', // and 'A' through 'Z'. pub fn unsigned_gen_var_10() -> Generator { Generator::new( &exhaustive_unsigned_gen_var_6, &random_unsigned_gen_var_10, &special_random_unsigned_gen_var_9, ) } // All small positive unsigned `T`s. pub fn unsigned_gen_var_11() -> Generator { Generator::new_no_special( &exhaustive_primitive_int_gen_var_1::, &random_unsigned_gen_var_11::, ) } // All unsigned `T`s whose highest bit is set. pub fn unsigned_gen_var_12() -> Generator { Generator::new( &exhaustive_unsigned_gen_var_7, &random_unsigned_gen_var_12, &special_random_unsigned_gen_var_10, ) } // All unsigneds that are valid inputs into `T::from_ordered_representation` for a float type `T`. pub fn unsigned_gen_var_13() -> Generator { Generator::new( &exhaustive_unsigned_gen_var_8::, &random_unsigned_gen_var_13::, &special_random_unsigned_gen_var_11::, ) } // All unsigned `T`s that are less than or equal to the largest representable power of 2. pub fn unsigned_gen_var_14() -> Generator { Generator::new( &exhaustive_unsigned_gen_var_9, &random_unsigned_gen_var_14, &special_random_unsigned_gen_var_12, ) } // All `u64`s between 0 and `T::WIDTH - 1`, inclusive, where `T` is a primitive integer. pub fn unsigned_gen_var_15() -> Generator { Generator::new( &exhaustive_unsigned_gen_var_10::, &random_unsigned_gen_var_15::, &special_random_unsigned_gen_var_13::, ) } // All `u64`s between 0 and `T::WIDTH - 2`, inclusive, where `T` is a primitive integer. pub fn unsigned_gen_var_16() -> Generator { Generator::new( &exhaustive_unsigned_gen_var_11::, &random_unsigned_gen_var_16::, &special_random_unsigned_gen_var_14::, ) } // All unsigned `T`s whose two highest bits are not both zero. pub fn unsigned_gen_var_17() -> Generator { Generator::new( &exhaustive_primitive_int_gen_var_5, &random_unsigned_gen_var_17, &special_random_unsigned_gen_var_15, ) } // All unsigneds `T` that are equal to a primitive float value of type `U`. pub fn unsigned_gen_var_18< T: PrimitiveUnsigned + RoundingFrom, U: ConvertibleFrom + PrimitiveFloat + RoundingFrom, >() -> Generator { Generator::new( &exhaustive_unsigned_gen_var_12::, &random_primitive_int_gen_var_1::, &special_random_primitive_int_gen_var_1::, ) } // All unsigneds `T` that are not exactly equal to any value of a floating-point type `U`. // // Acceptable `(T, U)` pairs are those where `T::WIDTH` > `U::MANTISSA_WIDTH`. pub fn unsigned_gen_var_19 + PrimitiveFloat>( ) -> Generator { Generator::new( &exhaustive_unsigned_gen_var_13::, &random_unsigned_gen_var_18::, &special_random_unsigned_gen_var_16::, ) } // All unsigneds `T` that are exactly between two values of a floating-point type `U`. // // Acceptable `(T, U)` pairs are those where `T::WIDTH` > `U::MANTISSA_WIDTH`. pub fn unsigned_gen_var_20< T: TryFrom> + PrimitiveUnsigned, U: ConvertibleFrom + PrimitiveFloat + RoundingFrom, >() -> Generator { Generator::new( &exhaustive_unsigned_gen_var_14::, &random_unsigned_gen_var_19::, &special_random_unsigned_gen_var_17::, ) } // All unsigned `T`s whose square is also representable as a `T`. pub fn unsigned_gen_var_21() -> Generator { Generator::new( &exhaustive_unsigned_gen_var_15, &random_unsigned_gen_var_20, &special_random_unsigned_gen_var_18, ) } // All odd unsigned `T`s. pub fn unsigned_gen_var_22() -> Generator { Generator::new( &exhaustive_unsigned_gen_var_22, &random_unsigned_gen_var_21, &special_random_unsigned_gen_var_19, ) } pub(crate) fn smallest_invalid_value Option>(f: F) -> u64 { for n in 0.. { if f(n).is_none() { return n; } } 0 } // All `u64`s whose factorial is representable as a `T`. pub fn unsigned_gen_var_23() -> Generator { Generator::new( &exhaustive_unsigned_gen_var_23::, &random_unsigned_gen_var_22::, &special_random_unsigned_gen_var_20::, ) } // All `u64`s whose double factorial is representable as a `T`. pub fn unsigned_gen_var_24() -> Generator { Generator::new( &exhaustive_unsigned_gen_var_24::, &random_unsigned_gen_var_23::, &special_random_unsigned_gen_var_21::, ) } // All `u64`s whose subfactorial is representable as a `T`. pub fn unsigned_gen_var_25() -> Generator { Generator::new( &exhaustive_unsigned_gen_var_25::, &random_unsigned_gen_var_24::, &special_random_unsigned_gen_var_22::, ) } // All small unsigned `T`s greater than 4. pub fn unsigned_gen_var_26() -> Generator { Generator::new_no_special( &exhaustive_primitive_int_gen_var_6, &random_unsigned_gen_var_25, ) } // All `u64`s whose primorial is representable as a `T`. pub fn unsigned_gen_var_27() -> Generator { Generator::new( &exhaustive_unsigned_gen_var_26::, &random_unsigned_gen_var_26::, &special_random_unsigned_gen_var_23::, ) } // All `u64`s `n` such that the product of the first `n` primes is representable as a `T`. pub fn unsigned_gen_var_28() -> Generator { Generator::new( &exhaustive_unsigned_gen_var_27::, &random_unsigned_gen_var_27::, &special_random_unsigned_gen_var_24::, ) } // -- (PrimitiveUnsigned, PrimitiveSigned) -- pub fn unsigned_signed_pair_gen() -> Generator<(T, U)> { Generator::new( &exhaustive_unsigned_signed_pair_gen, &random_primitive_int_pair_gen, &special_random_unsigned_signed_pair_gen, ) } // All `(T, U)`s where `T` is unsigned, `U` is signed, and the `U` is small. pub fn unsigned_signed_pair_gen_var_1( ) -> Generator<(T, U)> { Generator::new( &exhaustive_unsigned_signed_pair_gen_var_1, &random_primitive_int_signed_pair_gen_var_1, &special_random_unsigned_signed_pair_gen_var_1, ) } // Given a float type `T`, returns all `(T::UnsignedOfEqualWidth, i64)` that are valid inputs to // `T::from_integer_mantissa_and_exponent`. pub fn unsigned_signed_pair_gen_var_2() -> Generator<(u64, i64)> { Generator::new( &exhaustive_unsigned_signed_pair_gen_var_2::, &random_unsigned_signed_pair_gen_var_1::, &special_random_unsigned_signed_pair_gen_var_2::, ) } // -- (PrimitiveUnsigned, PrimitiveSigned, PrimitiveUnsigned) -- // All `(T, U, u64)` where `T` is unsigned, `U` is signed, the `U` is small, the u64 is no greater // than `T::WIDTH`, and the `T`s is less than 2 to the power of the `u64`. pub fn unsigned_signed_unsigned_triple_gen_var_1( ) -> Generator<(T, U, u64)> { Generator::new( &exhaustive_unsigned_signed_unsigned_triple_gen_var_1, &random_unsigned_signed_unsigned_triple_gen_var_1, &special_random_unsigned_signed_unsigned_triple_gen_var_1, ) } // All `(T, S, T)` where `T` is unsigned, `S` is signed, the `S` is between `-u64::MAX` and // `u64::MAX`, inclusive, and the first element is less than the third. pub fn unsigned_signed_unsigned_triple_gen_var_2< T: PrimitiveUnsigned, U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >() -> Generator<(T, S, T)> { Generator::new( &exhaustive_unsigned_signed_unsigned_triple_gen_var_2, &random_primitive_int_signed_primitive_int_triple_gen_var_1, &special_random_unsigned_signed_unsigned_triple_gen_var_2::, ) } // All `(T, U, T)` where `T` is unsigned, `U` is signed, and the first element is less than the // third. pub fn unsigned_signed_unsigned_triple_gen_var_3( ) -> Generator<(T, U, T)> { Generator::new( &exhaustive_unsigned_signed_unsigned_triple_gen_var_3, &random_primitive_int_triple_gen_var_3, &special_random_unsigned_signed_unsigned_triple_gen_var_3, ) } // All `(T, U, V)` where `T` is unsigned, `U` is signed and small, and `V` is unsigned, small, and // positive. pub fn unsigned_signed_unsigned_triple_gen_var_4< T: PrimitiveUnsigned, U: PrimitiveSigned, V: PrimitiveUnsigned, >() -> Generator<(T, U, V)> { Generator::new( &exhaustive_unsigned_signed_unsigned_triple_gen_var_4, &random_unsigned_signed_unsigned_triple_gen_var_2, &special_random_unsigned_signed_unsigned_triple_gen_var_4, ) } // -- (PrimitiveUnsigned, PrimitiveSigned, RoundingMode) -- // All `(T, U, RoundingMode)` where `T` is unsigned, `U` is signed, and the triple is a valid input // to `T::shr_round`. pub fn unsigned_signed_rounding_mode_triple_gen_var_1( ) -> Generator<(T, U, RoundingMode)> { Generator::new( &exhaustive_unsigned_signed_rounding_mode_triple_gen_var_1, &random_primitive_int_signed_rounding_mode_triple_gen_var_1, &special_random_unsigned_signed_rounding_mode_triple_gen_var_1, ) } // All `(T, U, RoundingMode)` where `T` is unsigned, `U` is signed, and the triple is a valid input // to `T::shl_round`. pub fn unsigned_signed_rounding_mode_triple_gen_var_2( ) -> Generator<(T, U, RoundingMode)> { Generator::new( &exhaustive_unsigned_signed_rounding_mode_triple_gen_var_2, &random_primitive_int_signed_rounding_mode_triple_gen_var_2, &special_random_unsigned_signed_rounding_mode_triple_gen_var_2, ) } // -- (PrimitiveUnsigned, PrimitiveUnsigned) -- pub fn unsigned_pair_gen() -> Generator<(T, U)> { Generator::new( &exhaustive_unsigned_pair_gen, &random_primitive_int_pair_gen, &special_random_unsigned_pair_gen, ) } // All `(u32, u32)`s where each `u32` is smaller than `NUMBER_OF_CHARS`. pub fn unsigned_pair_gen_var_1() -> Generator<(u32, u32)> { Generator::new( &exhaustive_unsigned_pair_gen_var_1, &random_unsigned_pair_gen_var_1, &special_random_unsigned_pair_gen_var_26, ) } // All `(T, U)`s where `T` and `U` are unsigned and the `U` is small. pub fn unsigned_pair_gen_var_2() -> Generator<(T, U)> { Generator::new( &exhaustive_unsigned_pair_gen_var_2, &random_primitive_int_unsigned_pair_gen_var_1, &special_random_unsigned_pair_gen_var_1, ) } // All `(T, u64)`s where `T` is unsigned and the `u64` is smaller than `T::WIDTH`. pub fn unsigned_pair_gen_var_3() -> Generator<(T, u64)> { Generator::new( &exhaustive_unsigned_pair_gen_var_3, &random_primitive_int_unsigned_pair_gen_var_2, &special_random_unsigned_pair_gen_var_2, ) } // All `(T, u64)`s where `T` is unsigned and the `u64` is between 1 and `U::WIDTH`, inclusive. pub fn unsigned_pair_gen_var_4() -> Generator<(T, u64)> { Generator::new( &exhaustive_unsigned_pair_gen_var_4::, &random_primitive_int_unsigned_pair_gen_var_3::, &special_random_unsigned_pair_gen_var_3::, ) } // All `(T, u64)`s where `T` is unsigned, the `T` is small, and the `u64` is between 1 and // `U::WIDTH`, inclusive. pub fn unsigned_pair_gen_var_5() -> Generator<(T, u64)> { Generator::new( &exhaustive_unsigned_pair_gen_var_4::, &random_unsigned_pair_gen_var_2::, &special_random_unsigned_pair_gen_var_27::, ) } // All `(T, U)`s where `T` and `U` are unsigned and the `U` is greater than 1 and no greater than // `T::MAX`. pub fn unsigned_pair_gen_var_6>( ) -> Generator<(T, U)> { Generator::new( &exhaustive_unsigned_pair_gen_var_5::, &random_primitive_int_unsigned_pair_gen_var_4::, &special_random_unsigned_pair_gen_var_4::, ) } // All `(T, T)` where `T` is unsigned and the first element is less than or equal to the second. pub fn unsigned_pair_gen_var_7() -> Generator<(T, T)> { Generator::new( &exhaustive_unsigned_pair_gen_var_6, &random_primitive_int_pair_gen_var_2, &special_random_unsigned_pair_gen_var_5, ) } // All `(T, U)`s where `T` and `U` are unsigned and the `U` is greater than 1 and no greater than // 36. pub fn unsigned_pair_gen_var_8 + PrimitiveUnsigned>( ) -> Generator<(T, U)> { Generator::new( &exhaustive_unsigned_primitive_int_pair_gen_var_2, &random_primitive_int_unsigned_pair_gen_var_5, &special_random_unsigned_pair_gen_var_6, ) } // All `(T, U)`s where `T` and `U` are unsigned, the `T` is small, and the `U` is greater than 1 and // no greater than 36. pub fn unsigned_pair_gen_var_9 + PrimitiveUnsigned>( ) -> Generator<(T, U)> { Generator::new( &exhaustive_unsigned_primitive_int_pair_gen_var_2, &random_unsigned_pair_gen_var_3, &special_random_unsigned_pair_gen_var_28, ) } // All `(T, V)`s where `T` is unsigned, the `T` is between 2 and `max(T::MAX, U::MAX)`, inclusive, // and the `V` is small. pub fn unsigned_pair_gen_var_10< T: PrimitiveUnsigned + SaturatingFrom, U: PrimitiveUnsigned, V: PrimitiveUnsigned, >() -> Generator<(T, V)> { Generator::new( &exhaustive_unsigned_pair_gen_var_7::, &random_unsigned_pair_gen_var_4::, &special_random_unsigned_pair_gen_var_29::, ) } // All pairs of unsigned `T` where the first is divisible by the second, and the second is positive. pub fn unsigned_pair_gen_var_11() -> Generator<(T, T)> { Generator::new( &exhaustive_unsigned_pair_gen_var_8, &random_unsigned_pair_gen_var_5, &special_random_unsigned_pair_gen_var_7, ) } // All pairs of unsigned `T` and `U` where the `U` is positive. pub fn unsigned_pair_gen_var_12() -> Generator<(T, U)> { Generator::new( &exhaustive_unsigned_pair_gen_var_9, &random_unsigned_pair_gen_var_6, &special_random_unsigned_pair_gen_var_8, ) } // All pairs of unsigned `T` where the second `T` is positive and the first is not divisible by the // second. pub fn unsigned_pair_gen_var_13() -> Generator<(T, T)> { Generator::new( &exhaustive_unsigned_pair_gen_var_10, &random_unsigned_pair_gen_var_7, &special_random_unsigned_pair_gen_var_9, ) } // All `(T, U)`s where `T` and `U` are unsigned, the `U` is small, and the `T` is not divisible by 2 // to the power of the `U`. pub fn unsigned_pair_gen_var_14() -> Generator<(T, U)> { Generator::new( &exhaustive_unsigned_pair_gen_var_11, &random_primitive_int_unsigned_pair_gen_var_6, &special_random_unsigned_pair_gen_var_10, ) } // All `(T, U)`s where `T` and `U` are unsigned, the `U` is small, and the `T` is divisible by 2 to // the power of the `U`. pub fn unsigned_pair_gen_var_15() -> Generator<(T, u64)> { Generator::new( &exhaustive_unsigned_pair_gen_var_12, &random_primitive_int_unsigned_pair_gen_var_7, &special_random_unsigned_pair_gen_var_11, ) } // All `(T, T)` where `T` is unsigned and the first element is smaller than the second. pub fn unsigned_pair_gen_var_16() -> Generator<(T, T)> { Generator::new( &exhaustive_unsigned_pair_gen_var_13, &random_primitive_int_pair_gen_var_3, &special_random_unsigned_pair_gen_var_12, ) } // All `(T, u64)` where `T` is unsigned, the u64 is no greater than `T::WIDTH`, and the `T` is less // than 2 to the power of the `u64`. pub fn unsigned_pair_gen_var_17() -> Generator<(T, u64)> { Generator::new( &exhaustive_unsigned_pair_gen_var_14, &random_unsigned_pair_gen_var_8, &special_random_unsigned_pair_gen_var_13, ) } // All `(T, U)` where `T` and `U` are unsigned, the `T` and the `U` are small, and the `U` is // positive. pub fn unsigned_pair_gen_var_18() -> Generator<(T, U)> { Generator::new_no_special( &exhaustive_unsigned_primitive_int_gen_var_1, &random_unsigned_pair_gen_var_9, ) } // All `(T, U)`s where `T` and `U` are unsigned, the `T` is positive and small, and the `U` is // greater than 1 and no greater than 36. pub fn unsigned_pair_gen_var_19 + PrimitiveUnsigned>( ) -> Generator<(T, U)> { Generator::new( &exhaustive_primitive_int_pair_gen_var_1, &random_unsigned_pair_gen_var_10, &special_random_unsigned_pair_gen_var_30, ) } // All `(T, u64)`s where `T` is unsigned, and either the `T` is 0 or the `u64` is less than // `T::WIDTH`. pub fn unsigned_pair_gen_var_20() -> Generator<(T, u64)> { Generator::new( &exhaustive_unsigned_pair_gen_var_15, &random_unsigned_pair_gen_var_11, &special_random_unsigned_pair_gen_var_31, ) } // All `(T, U)`s where `T` and `U` are unsigned and positive and the `U` is small. pub fn unsigned_pair_gen_var_21() -> Generator<(T, U)> { Generator::new( &exhaustive_primitive_int_pair_gen_var_2, &random_unsigned_pair_gen_var_12, &special_random_unsigned_pair_gen_var_14, ) } // All pairs of unsigneds that each are valid inputs into `T::from_ordered_representation` for a // float type `T`. pub fn unsigned_pair_gen_var_22() -> Generator<(u64, u64)> { Generator::new( &exhaustive_unsigned_pair_gen_var_16::, &random_unsigned_pair_gen_var_13::, &special_random_unsigned_pair_gen_var_32::, ) } // All `(T, u64)`s where `T` is unsigned and the `u64` is between 0 and `U::WIDTH`, inclusive. pub fn unsigned_pair_gen_var_23() -> Generator<(T, u64)> { Generator::new( &exhaustive_unsigned_pair_gen_var_17::, &random_primitive_int_unsigned_pair_gen_var_8::, &special_random_unsigned_pair_gen_var_15::, ) } // All pairs of unsigneds where the first element is positive and the second is greater than 1. pub fn unsigned_pair_gen_var_24() -> Generator<(T, U)> { Generator::new( &exhaustive_primitive_int_pair_gen_var_3, &random_unsigned_pair_gen_var_14, &special_random_unsigned_pair_gen_var_16, ) } // All pairs of unsigned `T` and `U` where the `U` is no greater than `u64::MAX` and `T` is // positive. pub fn unsigned_pair_gen_var_25() -> Generator<(T, U)> { Generator::new( &exhaustive_unsigned_pair_gen_var_18, &random_unsigned_pair_gen_var_15, &special_random_unsigned_pair_gen_var_18, ) } // Given a float type `T`, all `(u64, u64)` that are valid raw mantissas and exponents of a value of // type `T`. pub fn unsigned_pair_gen_var_26() -> Generator<(u64, u64)> { Generator::new( &exhaustive_unsigned_pair_gen_var_19::, &random_unsigned_pair_gen_var_16::, &special_random_unsigned_pair_gen_var_19::, ) } // All pairs of unsigneds of the same type. pub fn unsigned_pair_gen_var_27() -> Generator<(T, T)> { Generator::new( &exhaustive_unsigned_pair_gen_var_20, &random_primitive_int_pair_gen_var_1, &special_random_unsigned_pair_gen_var_35, ) } // All `(T, U)` where `T` and `U` are unsigned and both the `T` and the `U` are small. pub fn unsigned_pair_gen_var_28() -> Generator<(T, U)> { Generator::new_no_special( &exhaustive_unsigned_pair_gen, &random_unsigned_pair_gen_var_17, ) } // All `(T, u64)` where `T` is unsigned, both the `T` and the `u64` are small, and the `T` raised // the power of the `u64` does not overflow. pub fn unsigned_pair_gen_var_29() -> Generator<(T, u64)> { Generator::new_no_special( &exhaustive_unsigned_pair_gen_var_21, &random_unsigned_pair_gen_var_18, ) } // All `(T, u64)` where `T` is unsigned and the `u64` is no greater than the number of leading zeros // of the `T`. pub fn unsigned_pair_gen_var_30() -> Generator<(T, u64)> { Generator::new( &exhaustive_unsigned_pair_gen_var_22, &random_unsigned_pair_gen_var_19, &special_random_unsigned_pair_gen_var_20, ) } // All pairs of unsigned `T` where the two highest bits of the first `T` are not both zero. pub fn unsigned_pair_gen_var_31() -> Generator<(T, T)> { Generator::new( &exhaustive_primitive_int_unsigned_pair_gen_var_2::, &random_unsigned_primitive_int_pair_gen_var_1::, &special_random_unsigned_pair_gen_var_33::, ) } // All `(T, U)`s where `T` and `U` are unsigned and the `U` is small and positive. pub fn unsigned_pair_gen_var_32() -> Generator<(T, U)> { Generator::new( &exhaustive_unsigned_primitive_int_gen_var_3, &random_primitive_int_unsigned_pair_gen_var_9, &special_random_unsigned_pair_gen_var_21, ) } // All `(T, T)`s where `T` is unsigned. When the generation mode is random or special random, the // pairs are selected from a distribution such that their product is likely to be representable. pub fn unsigned_pair_gen_var_33() -> Generator<(T, T)> { Generator::new( &exhaustive_unsigned_pair_gen_var_20, &random_unsigned_pair_gen_var_21, &special_random_unsigned_pair_gen_var_22, ) } // All `(T, T)`s where the LCM of the two numbers is representable. pub fn unsigned_pair_gen_var_34() -> Generator<(T, T)> { Generator::new( &exhaustive_unsigned_pair_gen_var_23, &random_unsigned_pair_gen_var_22, &special_random_unsigned_pair_gen_var_23, ) } // All pairs of unsigneds where the highest bit of the first element is set. pub fn unsigned_pair_gen_var_35() -> Generator<(T, T)> { Generator::new( &exhaustive_unsigned_pair_gen_var_24, &random_unsigned_pair_gen_var_23, &special_random_unsigned_pair_gen_var_24, ) } // All pairs of unsigneds that are valid inputs to `limbs_precompute_mod_mul_two_limbs`. pub fn unsigned_pair_gen_var_36() -> Generator<(T, T)> { Generator::new( &exhaustive_unsigned_pair_gen_var_25, &random_unsigned_pair_gen_var_24, &special_random_unsigned_pair_gen_var_25, ) } // All `(T, U)`s where `T` and `U` are unsigned, the `T` is positive, and the `U` is small. pub fn unsigned_pair_gen_var_37() -> Generator<(T, U)> { Generator::new( &exhaustive_primitive_int_unsigned_pair_gen_var_1, &random_unsigned_pair_gen_var_25, &special_random_unsigned_pair_gen_var_34, ) } // All `(T, T)` where `T` is unsigned, both elements are nonzero, and the first element is smaller // than the second. pub fn unsigned_pair_gen_var_38() -> Generator<(T, T)> { Generator::new( &exhaustive_primitive_int_pair_gen_var_4, &random_unsigned_pair_gen_var_26, &special_random_unsigned_pair_gen_var_36, ) } // All `(T, u64)` where `T` is unsigned, the u64 is no greater than `T::WIDTH`, the `T` is positive, // and the `T` is less than 2 to the power of the `u64`. pub fn unsigned_pair_gen_var_39() -> Generator<(T, u64)> { Generator::new( &exhaustive_unsigned_pair_gen_var_26, &random_unsigned_pair_gen_var_27, &special_random_unsigned_pair_gen_var_37, ) } // All pairs of unsigneds where the second element is odd. pub fn unsigned_pair_gen_var_40() -> Generator<(T, T)> { Generator::new( &exhaustive_unsigned_pair_gen_var_27, &random_unsigned_pair_gen_var_28, &special_random_unsigned_pair_gen_var_38, ) } // All coprime pairs of unsigneds where both elements are odd. pub fn unsigned_pair_gen_var_41() -> Generator<(T, T)> { Generator::new( &exhaustive_unsigned_pair_gen_var_28, &random_unsigned_pair_gen_var_29, &special_random_unsigned_pair_gen_var_39, ) } // All coprime pairs of unsigneds of the same type. pub fn unsigned_pair_gen_var_42() -> Generator<(T, T)> { Generator::new( &exhaustive_unsigned_pair_gen_var_29, &random_unsigned_pair_gen_var_30, &special_random_unsigned_pair_gen_var_40, ) } // All pairs `u64`s that are valid inputs to `T::multifactorial`. pub fn unsigned_pair_gen_var_43() -> Generator<(u64, u64)> { Generator::new_no_special( &exhaustive_unsigned_pair_gen_var_30::, &random_unsigned_pair_gen_var_31::, ) } // All `(T, T)` where the `T`s are small, unsigned, and valid inputs to `T::binomial_coefficient`. pub fn unsigned_pair_gen_var_44() -> Generator<(T, T)> { Generator::new_no_special( &exhaustive_unsigned_pair_gen_var_31, &random_unsigned_pair_gen_var_32, ) } // var 45 is in malachite-nz // -- (PrimitiveUnsigned, PrimitiveUnsigned, bool) -- // All `(T, u64, `bool) where `T` is unsigned and either the `bool` is false or the `u64` is smaller // than `T::WIDTH`. pub fn unsigned_unsigned_bool_triple_gen_var_1() -> Generator<(T, u64, bool)> { Generator::new( &exhaustive_unsigned_unsigned_bool_triple_gen_var_1, &random_primitive_int_unsigned_bool_triple_gen_var_1, &special_random_unsigned_unsigned_bool_triple_gen_var_1, ) } // All `(T, U, bool)` where `T` and `U` are unsigned and the `U` is positive. pub fn unsigned_unsigned_bool_triple_gen_var_2( ) -> Generator<(T, U, bool)> { Generator::new( &exhaustive_unsigned_unsigned_bool_triple_gen_var_2, &random_primitive_int_unsigned_bool_triple_gen_var_3, &special_random_unsigned_unsigned_bool_triple_gen_var_2, ) } // -- (PrimitiveUnsigned, PrimitiveUnsigned, PrimitiveUnsigned) -- // All `(x, y, z): (T, T, T)` where `T` is unsigned and x + y * z does not overflow. pub fn unsigned_triple_gen_var_1() -> Generator<(T, T, T)> { Generator::new( &exhaustive_unsigned_triple_gen_var_1, &random_unsigned_triple_gen_var_1, &special_random_unsigned_triple_gen_var_1, ) } // All `(x, y, z): (T, T, T)` where `T` is unsigned and x - y * z does not overflow. pub fn unsigned_triple_gen_var_2() -> Generator<(T, T, T)> { Generator::new( &exhaustive_unsigned_triple_gen_var_2, &random_unsigned_triple_gen_var_2, &special_random_unsigned_triple_gen_var_2, ) } // All `(T, u64, V)` where `T` is unsigned, the `u64` is between 1 and `U::WIDTH`, inclusive, and // `V` is unsigned and the `V` is small. pub fn unsigned_triple_gen_var_3( ) -> Generator<(T, u64, V)> { Generator::new( &exhaustive_unsigned_primitive_int_unsigned_triple_gen_var_3::, &random_primitive_int_unsigned_unsigned_triple_gen_var_1::, &special_random_unsigned_triple_gen_var_3::, ) } // All `(T, T, U)` where `T` and `U` are unsigned and the `U` is small. pub fn unsigned_triple_gen_var_4( ) -> Generator<(T, T, U)> { Generator::new( &exhaustive_unsigned_triple_gen_var_3, &random_primitive_int_primitive_int_unsigned_triple_gen_var_1, &special_random_unsigned_triple_gen_var_4, ) } // All `(T, U, U)` where `T` and `U` are unsigned, both `U`s are small, and the first `U` is less // than or equal to the second. pub fn unsigned_triple_gen_var_5( ) -> Generator<(T, U, U)> { Generator::new( &exhaustive_unsigned_triple_gen_var_4, &random_primitive_int_unsigned_unsigned_triple_gen_var_2, &special_random_unsigned_triple_gen_var_5, ) } // All `(T, U, V)`s where `T`, `U`, and `V` are unsigned, the `U` is greater than 1 and no greater // than 36, and the `V` is small. pub fn unsigned_triple_gen_var_6< T: PrimitiveUnsigned, U: ExactFrom + PrimitiveUnsigned, V: PrimitiveUnsigned, >() -> Generator<(T, U, V)> { Generator::new( &exhaustive_unsigned_triple_gen_var_5, &random_primitive_int_unsigned_unsigned_triple_gen_var_3, &special_random_unsigned_triple_gen_var_6, ) } // All triples of unsigneds (x, y, m) where x is equal to y mod m. pub fn unsigned_triple_gen_var_7() -> Generator<(T, T, T)> { Generator::new( &exhaustive_unsigned_triple_gen_var_6, &random_unsigned_triple_gen_var_3, &special_random_unsigned_triple_gen_var_7, ) } // All triples of unsigneds (x, y, m) where x is not equal to y mod m. pub fn unsigned_triple_gen_var_8() -> Generator<(T, T, T)> { Generator::new( &exhaustive_unsigned_triple_gen_var_7, &random_primitive_int_triple_gen_var_1, &special_random_unsigned_triple_gen_var_8, ) } // All triples `(T, T, u64)` (x, y, k) where `T` is unsigned and x is equal to y mod $2^k$. pub fn unsigned_triple_gen_var_9() -> Generator<(T, T, u64)> { Generator::new( &exhaustive_unsigned_triple_gen_var_8, &random_unsigned_triple_gen_var_4, &special_random_unsigned_triple_gen_var_9, ) } // All triples `(T, T, u64)` (x, y, k) where `T` is unsigned and x is not equal to y mod $2^k$. pub fn unsigned_triple_gen_var_10() -> Generator<(T, T, u64)> { Generator::new( &exhaustive_unsigned_triple_gen_var_9, &random_primitive_int_primitive_int_unsigned_triple_gen_var_3, &special_random_unsigned_triple_gen_var_10, ) } // All `(T, T, u64)` where `T` is unsigned, the u64 is no greater than `T::WIDTH`, and both `T`s are // less than 2 to the power of the `u64`. pub fn unsigned_triple_gen_var_11() -> Generator<(T, T, u64)> { Generator::new( &exhaustive_unsigned_triple_gen_var_10, &random_unsigned_triple_gen_var_5, &special_random_unsigned_triple_gen_var_11, ) } // All `(T, T, T)` where `T` is unsigned and the first and second elements are less than the third. pub fn unsigned_triple_gen_var_12() -> Generator<(T, T, T)> { Generator::new( &exhaustive_unsigned_triple_gen_var_11, &random_primitive_int_triple_gen_var_2, &special_random_unsigned_triple_gen_var_12, ) } // All `(T, U, U)` where `T` and `U` are unsigned and the `U`s are small. pub fn unsigned_triple_gen_var_13( ) -> Generator<(T, U, U)> { Generator::new( &exhaustive_unsigned_triple_gen_var_12, &random_primitive_int_unsigned_unsigned_triple_gen_var_4, &special_random_unsigned_triple_gen_var_13, ) } // All `(T, U, T)` where `T` and `U` are unsigned, the `U` is small, and the first element is less // than the third. pub fn unsigned_triple_gen_var_14( ) -> Generator<(T, U, T)> { Generator::new( &exhaustive_unsigned_triple_gen_var_13, &random_primitive_int_unsigned_primitive_int_triple_gen_var_1, &special_random_unsigned_triple_gen_var_14, ) } // All `(T, U, T)` where `T` and `U` are unsigned and the first element is less than the third. pub fn unsigned_triple_gen_var_15( ) -> Generator<(T, U, T)> { Generator::new( &exhaustive_unsigned_triple_gen_var_14, &random_primitive_int_triple_gen_var_3, &special_random_unsigned_triple_gen_var_15, ) } // All `(T, U, u64)` where `T` and `U` are unsigned, the u64 is no greater than `T::WIDTH`, and the // `T`s is less than 2 to the power of the `u64`. pub fn unsigned_triple_gen_var_16( ) -> Generator<(T, U, u64)> { Generator::new( &exhaustive_unsigned_triple_gen_var_15, &random_unsigned_primitive_int_unsigned_triple_gen_var_1, &special_random_unsigned_triple_gen_var_16, ) } // All `(T, U, u64)` where `T` and `U` are unsigned, the `U` is small, the u64 is no greater than // `T::WIDTH`, and the `T`s is less than 2 to the power of the `u64`. pub fn unsigned_triple_gen_var_17( ) -> Generator<(T, U, u64)> { Generator::new( &exhaustive_unsigned_triple_gen_var_15, &random_unsigned_triple_gen_var_6, &special_random_unsigned_triple_gen_var_17, ) } // All `(T, U, T)` where `T` and `U` are unsigned, the `U` is no larger than `u64::MAX`, and the // first element is less than the third. pub fn unsigned_triple_gen_var_18( ) -> Generator<(T, U, T)> { Generator::new( &exhaustive_unsigned_triple_gen_var_16, &random_primitive_int_unsigned_primitive_int_triple_gen_var_2, &special_random_unsigned_triple_gen_var_18, ) } // All triples of unsigneds of the same type. pub fn unsigned_triple_gen_var_19() -> Generator<(T, T, T)> { Generator::new( &exhaustive_unsigned_triple_gen_var_17, &random_primitive_int_triple_gen_var_4, &special_random_unsigned_triple_gen_var_19, ) } // All `(T, U, U)` where `T` and `U` are unsigned, both `U`s are small, the `T` is positive, and the // first `U` is less than or equal to the second. pub fn unsigned_triple_gen_var_20( ) -> Generator<(T, U, U)> { Generator::new( &exhaustive_primitive_int_unsigned_unsigned_triple_gen_var_1, &random_unsigned_triple_gen_var_7, &special_random_unsigned_triple_gen_var_20, ) } // All triples of unsigneds where the second element is odd. pub fn unsigned_triple_gen_var_21() -> Generator<(T, T, T)> { Generator::new( &exhaustive_unsigned_triple_gen_var_18, &random_unsigned_triple_gen_var_8, &special_random_unsigned_triple_gen_var_21, ) } // All triples of unsigneds where the third element is odd. pub fn unsigned_triple_gen_var_22() -> Generator<(T, T, T)> { Generator::new( &exhaustive_unsigned_triple_gen_var_19, &random_unsigned_triple_gen_var_9, &special_random_unsigned_triple_gen_var_22, ) } // All triples of unsigneds where the second and third elements are odd. pub fn unsigned_triple_gen_var_23() -> Generator<(T, T, T)> { Generator::new( &exhaustive_unsigned_triple_gen_var_20, &random_unsigned_triple_gen_var_10, &special_random_unsigned_triple_gen_var_23, ) } // -- (PrimitiveUnsigned, PrimitiveUnsigned, PrimitiveUnsigned, PrimitiveUnsigned) -- // All `(T, u64, u64, U)` where `T` and `U` are unsigned, both `u64`s are small, and the four values // are valid arguments to `assign_bits`. pub fn unsigned_quadruple_gen_var_1( ) -> Generator<(T, u64, u64, U)> { Generator::new( &exhaustive_unsigned_quadruple_gen_var_1, &random_primitive_int_unsigned_unsigned_unsigned_quadruple_gen_var_1, &special_random_unsigned_quadruple_gen_var_1, ) } // All `(T, T, T, U)` where `T` and `U` are unsigned and the `U` is small. pub fn unsigned_quadruple_gen_var_2( ) -> Generator<(T, T, T, U)> { Generator::new( &exhaustive_unsigned_quadruple_gen_var_2, &random_primitive_int_primitive_int_primitive_int_unsigned_quadruple_gen_var_1, &special_random_unsigned_quadruple_gen_var_2, ) } // All `(T, T, T, u64)` where `T` is unsigned, the u64 is no greater than `T::WIDTH`, and all three // `T`s are less than 2 to the power of the `u64`. pub fn unsigned_quadruple_gen_var_3() -> Generator<(T, T, T, u64)> { Generator::new( &exhaustive_unsigned_quadruple_gen_var_3, &random_unsigned_quadruple_gen_var_1, &special_random_unsigned_quadruple_gen_var_3, ) } // All `(T, T, T, T)` where `T` is unsigned and the first three elements are each less than the // fourth. pub fn unsigned_quadruple_gen_var_4() -> Generator<(T, T, T, T)> { Generator::new( &exhaustive_unsigned_quadruple_gen_var_4, &random_primitive_int_quadruple_gen_var_1, &special_random_unsigned_quadruple_gen_var_4, ) } // All `(T, T, T, T)` that are valid inputs to `limbs_mod_preinverted`. pub fn unsigned_quadruple_gen_var_5< T: TryFrom
+ PrimitiveUnsigned, DT: From + HasHalf + JoinHalves + PrimitiveUnsigned + SplitInHalf, >() -> Generator<(T, T, T, T)> { Generator::new( &exhaustive_unsigned_quadruple_gen_var_5::, &random_unsigned_quadruple_gen_var_2::, &special_random_unsigned_quadruple_gen_var_5::, ) } // All `(T, T, U, T)` where `T` and `U` are unsigned and the first two elements are each less than // the fourth. pub fn unsigned_quadruple_gen_var_6( ) -> Generator<(T, T, U, T)> { Generator::new( &exhaustive_unsigned_quadruple_gen_var_6, &random_primitive_int_quadruple_gen_var_2, &special_random_unsigned_quadruple_gen_var_6, ) } // All `(T, U, U, T)` where `T` and `U` are unsigned and the first element is less than the fourth. pub fn unsigned_quadruple_gen_var_7( ) -> Generator<(T, U, U, T)> { Generator::new( &exhaustive_unsigned_quadruple_gen_var_7, &random_primitive_int_quadruple_gen_var_3, &special_random_unsigned_quadruple_gen_var_7, ) } // All `(T, T, U, u64)` where `T` and `U` are unsigned, the u64 is no greater than `T::WIDTH`, and // both `T`s are less than 2 to the power of the `u64`. pub fn unsigned_quadruple_gen_var_8( ) -> Generator<(T, T, U, u64)> { Generator::new( &exhaustive_unsigned_quadruple_gen_var_8, &random_unsigned_unsigned_primitive_int_unsigned_quadruple_gen_var_1, &special_random_unsigned_quadruple_gen_var_8, ) } // All `(T, U, U, u64)` where `T` and `U` are unsigned, the u64 is no greater than `T::WIDTH`, and // the `T`s is less than 2 to the power of the `u64`. pub fn unsigned_quadruple_gen_var_9( ) -> Generator<(T, U, U, u64)> { Generator::new( &exhaustive_unsigned_quadruple_gen_var_9, &random_unsigned_primitive_int_primitive_int_unsigned_quadruple_gen_var_1, &special_random_unsigned_quadruple_gen_var_9, ) } // All quadruples of unsigneds of the same type. pub fn unsigned_quadruple_gen_var_10() -> Generator<(T, T, T, T)> { Generator::new( &exhaustive_unsigned_quadruple_gen_var_10, &random_primitive_int_quadruple_gen_var_4, &special_random_unsigned_quadruple_gen_var_10, ) } // All quadruples of unsigneds which, if grouped into two double-width unsigneds N and D (high // halves first) satisfy D >= 2^W, N >= D, and N / D < 2^W. pub fn unsigned_quadruple_gen_var_11() -> Generator<(T, T, T, T)> { Generator::new( &exhaustive_unsigned_quadruple_gen_var_11, &random_primitive_int_quadruple_gen_var_5, &special_random_unsigned_quadruple_gen_var_11, ) } // All quadruples of unsigneds where the fourth element is odd. pub fn unsigned_quadruple_gen_var_12() -> Generator<(T, T, T, T)> { Generator::new( &exhaustive_unsigned_quadruple_gen_var_12, &random_unsigned_quadruple_gen_var_3, &special_random_unsigned_quadruple_gen_var_12, ) } // -- (PrimitiveUnsigned * 6) -- // All sextuples of unsigneds of the same type. pub fn unsigned_sextuple_gen_var_1() -> Generator<(T, T, T, T, T, T)> { Generator::new( &exhaustive_unsigned_sextuple_gen_var_1, &random_primitive_int_sextuple_gen_var_1, &special_random_unsigned_sextuple_gen_var_1, ) } // var 2 is in malachite-nz. // -- (PrimitiveUnsigned * 8) -- // All octuples of unsigneds of the same type. #[allow(clippy::type_complexity)] pub fn unsigned_octuple_gen_var_1() -> Generator<(T, T, T, T, T, T, T, T)> { Generator::new( &exhaustive_unsigned_octuple_gen_var_1, &random_primitive_int_octuple_gen_var_1, &special_random_unsigned_octuple_gen_var_1, ) } // -- (PrimitiveUnsigned * 9) -- // All nonuples of unsigneds of the same type. #[allow(clippy::type_complexity)] pub fn unsigned_nonuple_gen_var_1() -> Generator<(T, T, T, T, T, T, T, T, T)> { Generator::new( &exhaustive_unsigned_nonuple_gen_var_1, &random_primitive_int_nonuple_gen_var_1, &special_random_unsigned_nonuple_gen_var_1, ) } // -- (PrimitiveUnsigned * 12) -- // All duodecuples of unsigneds of the same type. #[allow(clippy::type_complexity)] pub fn unsigned_duodecuple_gen_var_1( ) -> Generator<(T, T, T, T, T, T, T, T, T, T, T, T)> { Generator::new( &exhaustive_unsigned_duodecuple_gen_var_1, &random_primitive_int_duodecuple_gen_var_1, &special_random_unsigned_duodecuple_gen_var_1, ) } // -- (PrimitiveUnsigned, PrimitiveUnsigned, RoundingMode) -- // All `(T, T, RoundingMode)` that are valid inputs to `T::div_round`. pub fn unsigned_unsigned_rounding_mode_triple_gen_var_1( ) -> Generator<(T, T, RoundingMode)> { Generator::new( &exhaustive_unsigned_unsigned_rounding_mode_triple_gen_var_1, &random_unsigned_unsigned_rounding_mode_triple_gen_var_1, &special_random_unsigned_unsigned_rounding_mode_triple_gen_var_1, ) } // All `(T, T, RoundingMode)` where `T` is unsigned and the triple is a valid input to // `T::round_to_multiple`. pub fn unsigned_unsigned_rounding_mode_triple_gen_var_2( ) -> Generator<(T, T, RoundingMode)> { Generator::new( &exhaustive_unsigned_unsigned_rounding_mode_triple_gen_var_3, &random_unsigned_unsigned_rounding_mode_triple_gen_var_2, &special_random_unsigned_unsigned_rounding_mode_triple_gen_var_2, ) } // All `(T, u64, RoundingMode)` where `T` is unsigned and the triple is a valid input to // `T::round_to_multiple_of_power_of_2`. pub fn unsigned_unsigned_rounding_mode_triple_gen_var_3( ) -> Generator<(T, u64, RoundingMode)> { Generator::new( &exhaustive_unsigned_unsigned_rounding_mode_triple_gen_var_4, &random_primitive_int_unsigned_rounding_mode_triple_gen_var_1, &special_random_unsigned_unsigned_rounding_mode_triple_gen_var_3, ) } // All `(T, U, RoundingMode)` where `T` is unsigned, `U` is unsigned, and the triple is a valid // input to `T::shr_round`. pub fn unsigned_unsigned_rounding_mode_triple_gen_var_4< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >() -> Generator<(T, U, RoundingMode)> { Generator::new( &exhaustive_unsigned_unsigned_rounding_mode_triple_gen_var_5, &random_primitive_int_unsigned_rounding_mode_triple_gen_var_2, &special_random_unsigned_unsigned_rounding_mode_triple_gen_var_4, ) } // var 5 is in malachite-float. // -- (PrimitiveUnsigned, PrimitiveUnsigned, Vec) -- // All `(T, u64, Vec)` where `T` is unsigned, the `u64` is between 1 and `U::WIDTH`, // inclusive, and the `Vec` has as many elements as the `T` has digits in base $2^\ell$, where // $\ell$ is the `u64`. pub fn unsigned_unsigned_bool_vec_triple_gen_var_1( ) -> Generator<(T, u64, Vec)> { Generator::new( &exhaustive_unsigned_unsigned_bool_vec_triple_gen_var_1::, &random_primitive_int_unsigned_bool_vec_triple_gen_var_1::, &special_random_unsigned_unsigned_bool_vec_triple_gen_var_1::, ) } // -- (PrimitiveUnsigned, RoundingMode) -- pub fn unsigned_rounding_mode_pair_gen() -> Generator<(T, RoundingMode)> { Generator::new( &exhaustive_unsigned_rounding_mode_pair_gen, &random_primitive_int_rounding_mode_pair_gen, &special_random_unsigned_rounding_mode_pair_gen, ) } // All `(T, RoundingMode)`s where `T` is unsigned and the `T` is positive. pub fn unsigned_rounding_mode_pair_gen_var_1() -> Generator<(T, RoundingMode)> { Generator::new( &exhaustive_primitive_int_rounding_mode_pair_gen_var_1, &random_unsigned_rounding_mode_pair_gen_var_1, &special_random_unsigned_rounding_mode_pair_gen_var_1, ) } // All `(T, RoundingMode)` where `T` is unsigned, `U` is a primitive float type, and the pair is a // valid input to `U::rounding_from`. pub fn unsigned_rounding_mode_pair_gen_var_2< T: PrimitiveUnsigned, U: ConvertibleFrom + PrimitiveFloat, >() -> Generator<(T, RoundingMode)> { Generator::new( &exhaustive_unsigned_rounding_mode_pair_gen_var_1::, &random_primitive_int_rounding_mode_pair_gen_var_1::, &special_random_unsigned_rounding_mode_pair_gen_var_2::, ) } // All `(T, RoundingMode)`s where `T` is small, unsigned, and positive. pub fn unsigned_rounding_mode_pair_gen_var_3() -> Generator<(T, RoundingMode)> { Generator::new_no_special( &exhaustive_primitive_int_rounding_mode_pair_gen_var_1, &random_unsigned_rounding_mode_pair_gen_var_2, ) } // All `(T, RoundingMode)`s where `T` is small, unsigned, and positive, and the rounding mode is not // `Exact`. pub fn unsigned_rounding_mode_pair_gen_var_4() -> Generator<(T, RoundingMode)> { Generator::new_no_special( &exhaustive_primitive_int_rounding_mode_pair_gen_var_2, &random_unsigned_rounding_mode_pair_gen_var_3, ) } // -- (PrimitiveUnsigned, String) -- // All `(u8, String)` that, when passed to `Natural::from_string_base`, return a `Some`. pub fn unsigned_string_pair_gen_var_1() -> Generator<(u8, String)> { Generator::new_no_special( &exhaustive_unsigned_string_pair_gen_var_1, &random_unsigned_string_pair_gen_var_1, ) } // All `(u8, String)` that are valid inputs to `Natural::from_string_base` or // `Integer::from_string_base`, regardless of whether it returns `Some` or `None`. pub fn unsigned_string_pair_gen_var_2() -> Generator<(u8, String)> { Generator::new( &exhaustive_unsigned_string_pair_gen_var_2, &random_unsigned_string_pair_gen_var_2, &special_random_unsigned_string_pair_gen_var_1, ) } // All `(u8, String)` that, when passed to `Integer::from_string_base`, return a `Some`. pub fn unsigned_string_pair_gen_var_3() -> Generator<(u8, String)> { Generator::new_no_special( &exhaustive_unsigned_string_pair_gen_var_3, &random_unsigned_string_pair_gen_var_3, ) } // -- (PrimitiveUnsigned, ToSciOptions) -- pub fn unsigned_to_sci_options_pair_gen() -> Generator<(T, ToSciOptions)> { Generator::new( &exhaustive_unsigned_to_sci_options_pair_gen, &random_primitive_int_to_sci_options_pair_gen, &special_random_unsigned_to_sci_options_pair_gen, ) } type TSO = ToSciOptions; // All `(T, ToSciOptions)` pairs where `T` is unsigned and the `T` can be formatted using the // options. pub fn unsigned_to_sci_options_pair_gen_var_1() -> Generator<(T, TSO)> { Generator::new( &exhaustive_unsigned_to_sci_options_pair_gen_var_1, &random_primitive_int_to_sci_options_pair_gen_var_1, &special_random_unsigned_to_sci_options_pair_gen_var_1, ) } // -- (PrimitiveUnsigned, Vec) -- // All `(T, Vec)` where `T` is unsigned and the `Vec` has as many elements as the `T` has // significant bits. pub fn unsigned_bool_vec_pair_gen_var_1() -> Generator<(T, Vec)> { Generator::new( &exhaustive_unsigned_bool_vec_pair_gen_var_1, &random_unsigned_bool_vec_pair_gen_var_1, &special_random_unsigned_bool_vec_pair_gen_var_1, ) } // -- RationalSequence -- pub fn unsigned_rational_sequence_gen() -> Generator> { Generator::new( &exhaustive_unsigned_rational_sequence_gen, &random_primitive_int_rational_sequence_gen, &special_random_unsigned_rational_sequence_gen, ) } // -- (RationalSequence, PrimitiveUnsigned) -- // All `(RationalSequence, U)` pairs where `T` and `U` are unsigned and the `U` is small. pub fn unsigned_rational_sequence_unsigned_pair_gen_var_1< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >() -> Generator<(RationalSequence, U)> { Generator::new( &exhaustive_unsigned_rational_sequence_unsigned_pair_gen_var_1, &random_primitive_int_rational_sequence_unsigned_pair_gen_var_1, &special_random_unsigned_rational_sequence_unsigned_pair_gen_var_1, ) } // All `(RationalSequence, usize)` pairs where `T` is unsigned and the `usize` is less than the // length of the `RationalSequence`. pub fn unsigned_rational_sequence_unsigned_pair_gen_var_2( ) -> Generator<(RationalSequence, usize)> { Generator::new( &exhaustive_unsigned_rational_sequence_unsigned_pair_gen_var_2, &random_primitive_int_rational_sequence_unsigned_pair_gen_var_2, &special_random_unsigned_rational_sequence_unsigned_pair_gen_var_2, ) } // -- (RationalSequence, RationalSequence) -- pub fn unsigned_rational_sequence_pair_gen( ) -> Generator<(RationalSequence, RationalSequence)> { Generator::new( &exhaustive_unsigned_rational_sequence_pair_gen, &random_primitive_int_rational_sequence_pair_gen, &special_random_unsigned_rational_sequence_pair_gen, ) } // -- RationalSequence * 3 -- pub fn unsigned_rational_sequence_triple_gen() -> Generator<( RationalSequence, RationalSequence, RationalSequence, )> { Generator::new( &exhaustive_unsigned_rational_sequence_triple_gen, &random_primitive_int_rational_sequence_triple_gen, &special_random_unsigned_rational_sequence_triple_gen, ) } // -- RoundingMode -- pub fn rounding_mode_gen() -> Generator { Generator::new_no_special(&exhaustive_rounding_mode_gen, &random_rounding_mode_gen) } // -- (RoundingMode, RoundingMode) -- pub fn rounding_mode_pair_gen() -> Generator<(RoundingMode, RoundingMode)> { Generator::new_no_special( &exhaustive_rounding_mode_pair_gen, &random_rounding_mode_pair_gen, ) } // -- (RoundingMode, RoundingMode, RoundingMode) -- pub fn rounding_mode_triple_gen() -> Generator<(RoundingMode, RoundingMode, RoundingMode)> { Generator::new_no_special( &exhaustive_rounding_mode_triple_gen, &random_rounding_mode_triple_gen, ) } // -- SciSizeOptions -- pub fn sci_size_options_gen() -> Generator { Generator::new_no_special( &exhaustive_sci_size_options_gen, &random_sci_size_options_gen, ) } // -- String -- pub fn string_gen() -> Generator { Generator::new( &exhaustive_string_gen, &random_string_gen, &special_random_string_gen, ) } // All ASCII `String`s. pub fn string_gen_var_1() -> Generator { Generator::new( &exhaustive_string_gen_var_1, &random_string_gen_var_1, &special_random_string_gen_var_1, ) } // All `String`s containing only characters that appear in the `String` representations of // `RoundingMode`s. pub fn string_gen_var_2() -> Generator { Generator::new_no_special(&exhaustive_string_gen_var_2, &random_string_gen_var_2) } // All nonempty `String`s containing only the characters '0' through '9'. pub fn string_gen_var_3() -> Generator { Generator::new_no_special(&exhaustive_string_gen_var_3, &random_string_gen_var_3) } // All nonempty `String`s containing only the characters '0' through '9', except for a possible '-' // in the first position. pub fn string_gen_var_4() -> Generator { Generator::new_no_special(&exhaustive_string_gen_var_4, &random_string_gen_var_4) } // All nonempty `String`s containing only the characters '0' and '1'. pub fn string_gen_var_5() -> Generator { Generator::new_no_special(&exhaustive_string_gen_var_5, &random_string_gen_var_5) } // All nonempty `String`s containing only the characters '0' through '7'. pub fn string_gen_var_6() -> Generator { Generator::new_no_special(&exhaustive_string_gen_var_6, &random_string_gen_var_6) } // All nonempty `String`s containing only the characters '0' through '9', 'a' through 'f', or 'A' // through 'F'. pub fn string_gen_var_7() -> Generator { Generator::new_no_special(&exhaustive_string_gen_var_7, &random_string_gen_var_7) } // All `String`s of the form `"\"0xD\""`, where D is a nonempty substring containing only the // characters '0' through '9', 'a' through 'f', or 'A' through 'F'. pub fn string_gen_var_8() -> Generator { Generator::new_no_special(&exhaustive_string_gen_var_8, &random_string_gen_var_8) } // All `String`s of the form `"\"0xD\""` or `"\"-0xD\""`, where D is a nonempty substring containing // only the characters '0' through '9', 'a' through 'f', or 'A' through 'F'. pub fn string_gen_var_9() -> Generator { Generator::new_no_special(&exhaustive_string_gen_var_9, &random_string_gen_var_9) } // All `String`s containing only characters that appear in the `String` representations of // `NiceFloat`s. pub fn string_gen_var_10() -> Generator { Generator::new_no_special(&exhaustive_string_gen_var_10, &random_string_gen_var_10) } // vars 11 through 12 are in malachite-q. // All `String`s containing only the characters `+-.0123456789Ee`. pub fn string_gen_var_13() -> Generator { Generator::new_no_special(&exhaustive_string_gen_var_13, &random_string_gen_var_13) } fn large_exponent(s: &str) -> bool { let mut i = 0; let mut expect_e = false; for c in s.chars().rev() { if expect_e { return c == 'e' || c == 'E'; } else if c.is_ascii_digit() { i += 1; } else if i <= 3 { return false; } else if c == 'e' || c == 'E' { return true; } else if c == '+' || c == '-' { expect_e = true; } } false } // All `Strings` that do not end in an 'e' or 'E' followed by an optional plus or minus sign and // more than three digits. pub fn string_gen_var_14() -> Generator { Generator::new( &exhaustive_string_gen_var_14, &random_string_gen_var_14, &special_random_string_gen_var_4, ) } // All `String`s containing only the characters `+-.0123456789Ee`, and that do not end in an 'e' or // 'E' followed by an optional plus or minus sign and more than three digits. pub fn string_gen_var_15() -> Generator { Generator::new_no_special(&exhaustive_string_gen_var_15, &random_string_gen_var_15) } // -- (String, FromSciStringOptions) -- pub fn string_from_sci_string_options_pair_gen() -> Generator<(String, FromSciStringOptions)> { Generator::new( &exhaustive_string_from_sci_string_options_pair_gen, &random_string_from_sci_string_options_pair_gen, &special_random_string_from_sci_string_options_pair_gen, ) } // All `(String, FromSciStringOptions)`, where the `String` only contains characters that occur in // valid inputs to `T::from_sci_string_options`, using the specified options. pub fn string_from_sci_string_options_pair_gen_var_1() -> Generator<(String, FromSciStringOptions)> { Generator::new_no_special( &exhaustive_string_from_sci_string_options_pair_gen_var_1, &random_string_from_sci_string_options_pair_gen_var_1, ) } // All `(String, FromSciStringOptions)`, where the string does not end in an 'e' or 'E' followed by // an optional plus or minus sign and more than three digits. pub fn string_from_sci_string_options_pair_gen_var_2() -> Generator<(String, FromSciStringOptions)> { Generator::new( &exhaustive_string_from_sci_string_options_pair_gen_var_2, &random_string_from_sci_string_options_pair_gen_var_2, &special_random_string_from_sci_string_options_pair_gen_var_1, ) } // All `(String, FromSciStringOptions)`, where the `String` only contains characters that occur in // valid inputs to `T::from_sci_string_options`, using the specified options, and the string does // not end in an 'e' or 'E' followed by an optional plus or minus sign and more than three digits. pub fn string_from_sci_string_options_pair_gen_var_3() -> Generator<(String, FromSciStringOptions)> { Generator::new_no_special( &exhaustive_string_from_sci_string_options_pair_gen_var_3, &random_string_from_sci_string_options_pair_gen_var_3, ) } // -- (String, PrimitiveUnsigned) -- // All `(String, u8)`s where the `u8` is between 2 and 36, inclusive, and the string does not end in // an 'e' or 'E' followed by an optional plus or minus sign and more than three digits. pub fn string_unsigned_pair_gen_var_1() -> Generator<(String, u8)> { Generator::new( &exhaustive_string_unsigned_pair_gen_var_1, &random_string_unsigned_pair_gen_var_1, &special_random_string_unsigned_pair_gen_var_1, ) } // All `(String, u8)`s where the `u8` is between 2 and 36, inclusive, the `String` only contains // characters that occur in valid inputs to `T::from_sci_string_options` with the specified base, // and the string does not end in an 'e' or 'E' followed by an optional plus or minus sign and more // than three digits. pub fn string_unsigned_pair_gen_var_2() -> Generator<(String, u8)> { Generator::new_no_special( &exhaustive_string_unsigned_pair_gen_var_2, &random_string_unsigned_pair_gen_var_2, ) } // -- (String, String) -- pub fn string_pair_gen() -> Generator<(String, String)> { Generator::new( &exhaustive_string_pair_gen, &random_string_pair_gen, &special_random_string_pair_gen, ) } // All pairs of ASCII `String`s. pub fn string_pair_gen_var_1() -> Generator<(String, String)> { Generator::new( &exhaustive_string_pair_gen_var_1, &random_string_pair_gen_var_1, &special_random_string_pair_gen_var_1, ) } // -- ToSciOptions -- pub fn to_sci_options_gen() -> Generator { Generator::new_no_special(&exhaustive_to_sci_options_gen, &random_to_sci_options_gen) } // -- (ToSciOptions, bool) -- pub fn to_sci_options_bool_pair_gen() -> Generator<(ToSciOptions, bool)> { Generator::new_no_special( &exhaustive_to_sci_options_bool_pair_gen, &random_to_sci_options_bool_pair_gen, ) } // -- (ToSciOptions, PrimitiveSigned) -- // All `(ToSciOptions, T)` where `T` is signed and the `T` is small and negative. pub fn to_sci_options_signed_pair_gen_var_1() -> Generator<(ToSciOptions, T)> { Generator::new_no_special( &exhaustive_to_sci_options_signed_pair_gen_var_1, &random_to_sci_options_signed_pair_gen_var_1, ) } // -- (ToSciOptions, PrimitiveUnsigned) -- // All `(ToSciOptions, T)` where `T` is unsigned and the `T` is between 2 and 36, inclusive. pub fn to_sci_options_unsigned_pair_gen_var_1() -> Generator<(TSO, T)> { Generator::new( &exhaustive_to_sci_options_unsigned_pair_gen_var_1, &random_to_sci_options_unsigned_pair_gen_var_1, &special_random_to_sci_options_unsigned_pair_gen_var_1, ) } // All `(ToSciOptions, T)` where `T` is unsigned and the `T` is small. pub fn to_sci_options_unsigned_pair_gen_var_2() -> Generator<(TSO, T)> { Generator::new_no_special( &exhaustive_to_sci_options_unsigned_pair_gen_var_2, &random_to_sci_options_unsigned_pair_gen_var_2, ) } // All `(ToSciOptions, T)` where `T` is unsigned and the `T` is small and positive. pub fn to_sci_options_unsigned_pair_gen_var_3() -> Generator<(TSO, T)> { Generator::new_no_special( &exhaustive_to_sci_options_primitive_int_pair_gen_var_1, &random_to_sci_options_unsigned_pair_gen_var_3, ) } // -- (ToSciOptions, RoundingMode) -- pub fn to_sci_options_rounding_mode_pair_gen() -> Generator<(ToSciOptions, RoundingMode)> { Generator::new_no_special( &exhaustive_to_sci_options_rounding_mode_pair_gen, &random_to_sci_options_rounding_mode_pair_gen, ) } // -- Vec -- pub fn bool_vec_gen() -> Generator> { Generator::new( &exhaustive_bool_vec_gen, &random_bool_vec_gen, &special_random_bool_vec_gen, ) } // All `Vec`s that could be the bits, in ascending order, of an unsigned value of type `T`. // The `Vec`s may be arbitrarily long. pub fn bool_vec_gen_var_1() -> Generator> { Generator::new( &exhaustive_bool_vec_gen_var_1::, &random_bool_vec_gen_var_1::, &special_random_bool_vec_gen_var_1::, ) } // All `Vec`s that could be the bits, in ascending order, of a signed value of type `T`. The // `Vec`s may be arbitrarily long. pub fn bool_vec_gen_var_2() -> Generator> { Generator::new( &exhaustive_bool_vec_gen_var_2::, &random_bool_vec_gen_var_2::, &special_random_bool_vec_gen_var_2::, ) } // All `Vec`s that could be the bits, in descending order, of an unsigned value of type `T`. // The `Vec`s may be arbitrarily long. pub fn bool_vec_gen_var_3() -> Generator> { Generator::new( &exhaustive_bool_vec_gen_var_3::, &random_bool_vec_gen_var_3::, &special_random_bool_vec_gen_var_3::, ) } // All `Vec`s that could be the bits, in descending order, of a signed value of type `T`. The // `Vec`s may be arbitrarily long. pub fn bool_vec_gen_var_4() -> Generator> { Generator::new( &exhaustive_bool_vec_gen_var_4::, &random_bool_vec_gen_var_4::, &special_random_bool_vec_gen_var_4::, ) } // All `Vec`s that contain at least one `true`. pub fn bool_vec_gen_var_5() -> Generator> { Generator::new( &exhaustive_bool_vec_gen_var_5, &random_bool_vec_gen_var_5, &special_random_bool_vec_gen_var_5, ) } // -- Vec -- pub fn unsigned_vec_gen() -> Generator> { Generator::new( &exhaustive_unsigned_vec_gen, &random_primitive_int_vec_gen, &special_random_unsigned_vec_gen, ) } // All nonempty `Vec`s of unsigneds whose last element is not zero. pub fn unsigned_vec_gen_var_1() -> Generator> { Generator::new( &exhaustive_unsigned_vec_gen_var_1, &random_primitive_int_vec_gen_var_1, &special_random_unsigned_vec_gen_var_1, ) } // All `Vec`s of unsigneds that contain at least one nonzero value. pub fn unsigned_vec_gen_var_2() -> Generator> { Generator::new( &exhaustive_unsigned_vec_gen_var_2, &random_primitive_int_vec_gen_var_2, &special_random_unsigned_vec_gen_var_2, ) } // All nonempty `Vec`s of unsigneds that do not end in a nonzero value. pub fn unsigned_vec_gen_var_3() -> Generator> { Generator::new( &exhaustive_unsigned_vec_gen_var_3, &random_primitive_int_vec_gen_var_3, &special_random_unsigned_vec_gen_var_3, ) } // All nonempty `Vec`s of unsigneds. pub fn unsigned_vec_gen_var_4() -> Generator> { Generator::new( &exhaustive_unsigned_vec_gen_var_4, &random_primitive_int_vec_gen_var_4, &special_random_unsigned_vec_gen_var_4, ) } // var 5 is in malachite-nz. // All `Vec`s of unsigneds with lengths at least 2. pub fn unsigned_vec_gen_var_6() -> Generator> { Generator::new( &exhaustive_unsigned_vec_gen_var_6, &random_primitive_int_vec_gen_var_5, &special_random_unsigned_vec_gen_var_6, ) } // -- (Vec, PrimitiveUnsigned) -- pub fn unsigned_vec_unsigned_pair_gen( ) -> Generator<(Vec, U)> { Generator::new( &exhaustive_unsigned_vec_unsigned_pair_gen, &random_primitive_int_vec_primitive_int_pair_gen, &special_random_unsigned_vec_unsigned_pair_gen, ) } // All `(Vec, usize)` where `T` is unsigned and the `usize` is less than or equal to the length // of the `Vec`. pub fn unsigned_vec_unsigned_pair_gen_var_1() -> Generator<(Vec, usize)> { Generator::new( &exhaustive_unsigned_vec_unsigned_pair_gen_var_1, &random_primitive_int_vec_unsigned_pair_gen_var_1, &special_random_unsigned_vec_unsigned_pair_gen_var_3, ) } // All `(Vec, u64)` such that the flipped `(u64, Vec)` is a `Some`-returning input to // `from_power_of_2_digits_asc`, where the `Vec` is no longer than the number of digits of // `T::MAX` in the base 2 to the power of the `u64`. pub fn unsigned_vec_unsigned_pair_gen_var_2( ) -> Generator<(Vec, u64)> { Generator::new( &exhaustive_unsigned_vec_unsigned_pair_gen_var_2::, &random_unsigned_vec_unsigned_pair_gen_var_1::, &special_random_unsigned_vec_unsigned_pair_gen_var_1::, ) } // All `(Vec, u64)` such that the flipped `(u64, Vec)` is a `Some`-returning input to // `from_power_of_2_digits_desc`, where the `Vec` is no longer than the number of digits of // `T::MAX` in the base 2 to the power of the `u64`. pub fn unsigned_vec_unsigned_pair_gen_var_3( ) -> Generator<(Vec, u64)> { Generator::new( &exhaustive_unsigned_vec_unsigned_pair_gen_var_3::, &random_unsigned_vec_unsigned_pair_gen_var_2::, &special_random_unsigned_vec_unsigned_pair_gen_var_2::, ) } // var 4 is in malachite-nz // All `(Vec, U)` that are valid, `Some`-returning inputs to _from_digits_desc_basecase in // malachite-nz. pub fn unsigned_vec_unsigned_pair_gen_var_5< T: ExactFrom + PrimitiveUnsigned + WrappingFrom, U: PrimitiveUnsigned + SaturatingFrom + WrappingFrom, >() -> Generator<(Vec, U)> { Generator::new_no_special( &exhaustive_unsigned_vec_unsigned_pair_gen_var_5::, &random_unsigned_vec_unsigned_pair_gen_var_3::, ) } // All `(Vec, u64)` such that the flipped `(u64, Vec)` is a `Some`-returning input to // `from_power_of_2_digits_asc` or `from_power_of_2_digits_desc`, regardless of whether // the returned value is `Some` or `None`. pub fn unsigned_vec_unsigned_pair_gen_var_6() -> Generator<(Vec, u64)> { Generator::new( &exhaustive_unsigned_vec_unsigned_pair_gen_var_6::, &random_primitive_int_vec_unsigned_pair_gen_var_2::, &special_random_unsigned_vec_unsigned_pair_gen_var_5::, ) } // All `(T, Vec)` that are a valid input to `U::from_digits_desc`, where the `Vec` is no longer // than the number of digits of `U::MAX` in the base of the `T`. pub fn unsigned_vec_unsigned_pair_gen_var_7< T: PrimitiveUnsigned + SaturatingFrom, U: Digits + PrimitiveUnsigned, >() -> Generator<(Vec, T)> { Generator::new_no_special( &exhaustive_unsigned_vec_unsigned_pair_gen_var_7::, &random_unsigned_vec_unsigned_pair_gen_var_4::, ) } // All `(Vec, T)` that are is a valid input to `U::from_digits_asc`, where the `Vec` is no longer // than the number of digits of `U::MAX` in the base of the `T`. pub fn unsigned_vec_unsigned_pair_gen_var_8< T: PrimitiveUnsigned + SaturatingFrom, U: Digits + PrimitiveUnsigned, >() -> Generator<(Vec, T)> { Generator::new_no_special( &exhaustive_unsigned_vec_unsigned_pair_gen_var_8::, &random_unsigned_vec_unsigned_pair_gen_var_5::, ) } // All `(Vec, T)` such that the flipped `(u64, Vec)` is a `Some`-returning input to // `from_digits_asc` or `from_digits_desc`, regardless of whether the returned value is // `Some` or `None`. pub fn unsigned_vec_unsigned_pair_gen_var_9() -> Generator<(Vec, T)> { Generator::new( &exhaustive_unsigned_vec_unsigned_pair_gen_var_9::, &random_unsigned_vec_unsigned_pair_gen_var_6::, &special_random_unsigned_vec_unsigned_pair_gen_var_6::, ) } // All `(Vec, u64)`, where the `u64` is between 1 and `T::WIDTH`, inclusive, and each `T` in the // `Vec` is less than 2 to the power of the `u64`. pub fn unsigned_vec_unsigned_pair_gen_var_10() -> Generator<(Vec, u64)> { Generator::new( &exhaustive_unsigned_vec_unsigned_pair_gen_var_10, &random_unsigned_vec_unsigned_pair_gen_var_7, &special_random_unsigned_vec_unsigned_pair_gen_var_7, ) } // All `(Vec, u64)`, where the `u64` is between 1 and `T::WIDTH`, inclusive. pub fn unsigned_vec_unsigned_pair_gen_var_11() -> Generator<(Vec, u64)> { Generator::new( &exhaustive_unsigned_vec_unsigned_pair_gen_var_11, &random_primitive_int_vec_unsigned_pair_gen_var_3, &special_random_unsigned_vec_unsigned_pair_gen_var_8, ) } // All `(Vec, U)` that are valid, inputs to from_digits_desc_basecase in malachite-nz, regardless // of whether they return `Some` or `None`. pub fn unsigned_vec_unsigned_pair_gen_var_12< T: PrimitiveUnsigned, U: PrimitiveUnsigned + SaturatingFrom, >() -> Generator<(Vec, U)> { Generator::new( &exhaustive_unsigned_vec_unsigned_pair_gen_var_12::, &random_primitive_int_vec_unsigned_pair_gen_var_4::, &special_random_unsigned_vec_unsigned_pair_gen_var_9::, ) } // All `(Vec, U)` where the last element of the `Vec` is nonzero. pub fn unsigned_vec_unsigned_pair_gen_var_13( ) -> Generator<(Vec, U)> { Generator::new( &exhaustive_unsigned_vec_primitive_int_pair_gen_var_1::, &random_primitive_int_vec_unsigned_pair_gen_var_5::, &special_random_unsigned_vec_unsigned_pair_gen_var_10::, ) } // All `(Vec, U)` where the last element of the `Vec` is nonzero and `U` is small and greater // than 2. pub fn unsigned_vec_unsigned_pair_gen_var_14( ) -> Generator<(Vec, U)> { Generator::new( &exhaustive_unsigned_vec_primitive_int_pair_gen_var_2::, &random_primitive_int_vec_unsigned_pair_gen_var_6::, &special_random_unsigned_vec_unsigned_pair_gen_var_11::, ) } // All `(Vec, U)` where `T` and `U` are unsigned and the `Vec` is nonempty. pub fn unsigned_vec_unsigned_pair_gen_var_15( ) -> Generator<(Vec, U)> { Generator::new( &exhaustive_unsigned_vec_unsigned_pair_gen_var_13, &random_primitive_int_vec_primitive_int_pair_gen_var_1, &special_random_unsigned_vec_unsigned_pair_gen_var_11, ) } // All `(Vec, U)` where `T` and `U` are unsigned and the `U` is small. pub fn unsigned_vec_unsigned_pair_gen_var_16( ) -> Generator<(Vec, U)> { Generator::new( &exhaustive_unsigned_vec_unsigned_pair_gen_var_14, &random_primitive_int_vec_unsigned_pair_gen_var_7, &special_random_unsigned_vec_unsigned_pair_gen_var_13, ) } // All `(Vec, U)` where `T` and `U` are unsigned and the U is less than `T::WIDTH` times the // length of the `Vec`. pub fn unsigned_vec_unsigned_pair_gen_var_17( ) -> Generator<(Vec, U)> { Generator::new( &exhaustive_unsigned_vec_unsigned_pair_gen_var_15, &random_primitive_int_vec_unsigned_pair_gen_var_8, &special_random_unsigned_vec_unsigned_pair_gen_var_14, ) } // All `(Vec, U)` where `T` and `U` are unsigned and the `Vec` contains at least one nonzero // value. pub fn unsigned_vec_unsigned_pair_gen_var_18( ) -> Generator<(Vec, U)> { Generator::new( &exhaustive_unsigned_vec_unsigned_pair_gen_var_16, &random_primitive_int_vec_primitive_int_pair_gen_var_2, &special_random_unsigned_vec_unsigned_pair_gen_var_15, ) } // All `(Vec, U)` where `T` and `U` are unsigned, the `Vec` contains at least one nonzero value, // and the `U` is positive. pub fn unsigned_vec_unsigned_pair_gen_var_19( ) -> Generator<(Vec, U)> { Generator::new( &exhaustive_unsigned_vec_primitive_int_pair_gen_var_3, &random_primitive_int_vec_unsigned_pair_gen_var_9, &special_random_unsigned_vec_unsigned_pair_gen_var_16, ) } // All `(Vec, U)` where `T` and `U` are unsigned, the `Vec` contains at least one nonzero value, // and the `U` is small. pub fn unsigned_vec_unsigned_pair_gen_var_20( ) -> Generator<(Vec, U)> { Generator::new( &exhaustive_unsigned_vec_unsigned_pair_gen_var_17, &random_primitive_int_vec_unsigned_pair_gen_var_10, &special_random_unsigned_vec_unsigned_pair_gen_var_17, ) } // var 21 is in malachite-nz. // All `(Vec, U)` where `T` and `U` are unsigned, the `Vec` has at least 2 elements, and the `U` // is positive. pub fn unsigned_vec_unsigned_pair_gen_var_22( ) -> Generator<(Vec, U)> { Generator::new( &exhaustive_unsigned_vec_primitive_int_pair_gen_var_4, &random_primitive_int_vec_unsigned_pair_gen_var_11, &special_random_unsigned_vec_unsigned_pair_gen_var_19, ) } // All `(Vec, U)` where `T` and `U` are unsigned, the `Vec` has at least 2 elements and at least // one nonzero element, and the `U` is positive. pub fn unsigned_vec_unsigned_pair_gen_var_23( ) -> Generator<(Vec, U)> { Generator::new( &exhaustive_unsigned_vec_primitive_int_pair_gen_var_5, &random_primitive_int_vec_unsigned_pair_gen_var_12, &special_random_unsigned_vec_unsigned_pair_gen_var_20, ) } // All `(Vec, U)` where `T` and `U` are unsigned, the `Vec` has at least 2 elements, and the // highest bit of the `U` is set. pub fn unsigned_vec_unsigned_pair_gen_var_24( ) -> Generator<(Vec, U)> { Generator::new( &exhaustive_unsigned_vec_primitive_int_pair_gen_var_6, &random_primitive_int_vec_unsigned_pair_gen_var_13, &special_random_unsigned_vec_unsigned_pair_gen_var_21, ) } // All `(Vec, U)` where `T` and `U` are unsigned, the `Vec` has at least 2 elements, the `U` is // positive, and the highest bit of the `U` is not set. pub fn unsigned_vec_unsigned_pair_gen_var_25( ) -> Generator<(Vec, U)> { Generator::new( &exhaustive_unsigned_vec_primitive_int_pair_gen_var_7, &random_primitive_int_vec_unsigned_pair_gen_var_14, &special_random_unsigned_vec_unsigned_pair_gen_var_22, ) } // All `(Vec, U)` where `T` and `U` are unsigned, the `Vec` is nonempty, and the highest bit of // the `U` is set. pub fn unsigned_vec_unsigned_pair_gen_var_26( ) -> Generator<(Vec, U)> { Generator::new( &exhaustive_unsigned_vec_primitive_int_pair_gen_var_8, &random_primitive_int_vec_unsigned_pair_gen_var_15, &special_random_unsigned_vec_unsigned_pair_gen_var_23, ) } // All `(Vec, U)` where `T` and `U` are unsigned, the `Vec` is nonempty, the `U` is positive, and // the highest bit of the `U` is not set. pub fn unsigned_vec_unsigned_pair_gen_var_27( ) -> Generator<(Vec, U)> { Generator::new( &exhaustive_unsigned_vec_primitive_int_pair_gen_var_9, &random_primitive_int_vec_unsigned_pair_gen_var_16, &special_random_unsigned_vec_unsigned_pair_gen_var_24, ) } // All `(Vec, U)` where `T` and `U` are unsigned, the `Vec` is nonempty, the `U` is positive, and // the two highest bits of the `U` are not set. pub fn unsigned_vec_unsigned_pair_gen_var_28( ) -> Generator<(Vec, U)> { Generator::new( &exhaustive_unsigned_vec_primitive_int_pair_gen_var_10, &random_primitive_int_vec_unsigned_pair_gen_var_17, &special_random_unsigned_vec_unsigned_pair_gen_var_25, ) } // vars 29 through 30 are in malachite-nz. // All `(Vec, U)` where the last element of the `Vec` is nonzero and `U` is small and greater // than 1. pub fn unsigned_vec_unsigned_pair_gen_var_31( ) -> Generator<(Vec, U)> { Generator::new( &exhaustive_unsigned_vec_primitive_int_pair_gen_var_11::, &random_primitive_int_vec_unsigned_pair_gen_var_18::, &special_random_unsigned_vec_unsigned_pair_gen_var_28::, ) } // All `(Vec, u64)`, where `T` is unsigned, `U` is a primitive integer type, and the `u64` is // between 1 and `U::WIDTH` - 1, inclusive. pub fn unsigned_vec_unsigned_pair_gen_var_32( ) -> Generator<(Vec, u64)> { Generator::new( &exhaustive_unsigned_vec_unsigned_pair_gen_var_21::, &random_primitive_int_vec_unsigned_pair_gen_var_19::, &special_random_unsigned_vec_unsigned_pair_gen_var_29::, ) } // All `(Vec, u64)`, where `T` is unsigned, `U` is a primitive integer type, the `Vec` is // nonempty, and the `u64` is between 1 and `U::WIDTH` - 1, inclusive. pub fn unsigned_vec_unsigned_pair_gen_var_33( ) -> Generator<(Vec, u64)> { Generator::new( &exhaustive_unsigned_vec_unsigned_pair_gen_var_22::, &random_primitive_int_vec_unsigned_pair_gen_var_20::, &special_random_unsigned_vec_unsigned_pair_gen_var_30::, ) } // -- (Vec, PrimitiveUnsigned, PrimitiveUnsigned) -- type T1 = Generator<(Vec, T, T)>; pub fn unsigned_vec_unsigned_unsigned_triple_gen() -> T1 { Generator::new( &exhaustive_unsigned_vec_unsigned_unsigned_triple_gen, &random_primitive_int_vec_primitive_int_primitive_int_triple_gen, &special_random_unsigned_vec_unsigned_unsigned_triple_gen, ) } // All `(Vec, U, V)` where `T`, `U`, and `V` are unsigned and the `U` is small. pub fn unsigned_vec_unsigned_unsigned_triple_gen_var_1< T: PrimitiveUnsigned, U: PrimitiveUnsigned, V: PrimitiveUnsigned, >() -> Generator<(Vec, U, V)> { Generator::new( &exhaustive_unsigned_vec_unsigned_unsigned_triple_gen_var_1, &random_primitive_int_vec_unsigned_primitive_int_triple_gen_var_1, &special_random_unsigned_vec_unsigned_unsigned_triple_gen_var_1, ) } // All `(Vec, usize, usize)` where `T` is unsigned and the length of the `Vec` is at least the // product of the `usize`s. pub fn unsigned_vec_unsigned_unsigned_triple_gen_var_2( ) -> Generator<(Vec, usize, usize)> { Generator::new( &exhaustive_unsigned_vec_unsigned_unsigned_triple_gen_var_2, &random_primitive_int_vec_unsigned_unsigned_triple_gen_var_1, &special_random_unsigned_vec_unsigned_unsigned_triple_gen_var_2, ) } // All `(Vec, U, U)` where `T` and `U` are unsigned, both `U`s are small, and the first `U` is // less than or equal to the second. pub fn unsigned_vec_unsigned_unsigned_triple_gen_var_3< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >() -> Generator<(Vec, U, U)> { Generator::new( &exhaustive_unsigned_vec_unsigned_unsigned_triple_gen_var_3, &random_primitive_int_vec_unsigned_unsigned_triple_gen_var_2, &special_random_unsigned_vec_unsigned_unsigned_triple_gen_var_3, ) } // All `(Vec, U, U)` where `T` and `U` are unsigned, both `U`s are small, the `Vec` contains at // least one nonzero value, and the first `U` is less than or equal to the second. pub fn unsigned_vec_unsigned_unsigned_triple_gen_var_4< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >() -> Generator<(Vec, U, U)> { Generator::new( &exhaustive_unsigned_vec_unsigned_unsigned_triple_gen_var_4, &random_primitive_int_vec_unsigned_unsigned_triple_gen_var_3, &special_random_unsigned_vec_unsigned_unsigned_triple_gen_var_4, ) } // All `(Vec, T, T)` where `T` is unsigned, both `T`s are positive, the `Vec` contains at least // two elements, and its last element is nonzero. pub fn unsigned_vec_unsigned_unsigned_triple_gen_var_5() -> T1 { Generator::new( &exhaustive_unsigned_vec_unsigned_unsigned_triple_gen_var_5, &random_primitive_int_vec_unsigned_unsigned_triple_gen_var_4, &special_random_unsigned_vec_unsigned_unsigned_triple_gen_var_5, ) } // var 6 is in malachite-nz. // All `(Vec, T, T)` where `T` is unsigned, the second `T` is positive, the `Vec` contains at // least two elements, and its last element is nonzero. pub fn unsigned_vec_unsigned_unsigned_triple_gen_var_7() -> T1 { Generator::new( &exhaustive_unsigned_vec_unsigned_unsigned_triple_gen_var_7, &random_primitive_int_vec_unsigned_unsigned_triple_gen_var_5, &special_random_unsigned_vec_unsigned_unsigned_triple_gen_var_7, ) } // All `(Vec, T, U)` where `T` and `U` are unsigned, the `U` is small, the `Vec` contains at // least two elements, and its last element is nonzero. pub fn unsigned_vec_unsigned_unsigned_triple_gen_var_8< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >() -> Generator<(Vec, T, U)> { Generator::new( &exhaustive_unsigned_vec_unsigned_unsigned_triple_gen_var_8, &random_primitive_int_vec_unsigned_unsigned_triple_gen_var_6, &special_random_unsigned_vec_unsigned_unsigned_triple_gen_var_8, ) } // var 9 is in malachite-nz. // All `(Vec, T, T)`s where `T` is unsigned, the `Vec` is nonempty, and the first `T` is odd. pub fn unsigned_vec_unsigned_unsigned_triple_gen_var_10( ) -> Generator<(Vec, T, T)> { Generator::new( &exhaustive_unsigned_vec_unsigned_unsigned_triple_gen_var_10, &random_unsigned_vec_unsigned_unsigned_triple_gen_var_3, &special_random_unsigned_vec_unsigned_unsigned_triple_gen_var_10, ) } // vars 11 through 12 are in malachite-nz. // All `(Vec, T, U)` where `T` and `U` are unsigned, the `U` is small, and the `Vec` ends with a // nonzero element. pub fn unsigned_vec_unsigned_unsigned_triple_gen_var_13< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >() -> Generator<(Vec, T, U)> { Generator::new( &exhaustive_unsigned_vec_unsigned_unsigned_triple_gen_var_13, &random_primitive_int_vec_unsigned_unsigned_triple_gen_var_7, &special_random_unsigned_vec_unsigned_unsigned_triple_gen_var_13, ) } // var 14 is in malachite-nz. // -- (Vec, PrimitiveUnsigned, RoundingMode) -- // All `(Vec, T, RoundingMode)` where `T` is unsigned, the `Vec` has at least two elements, and // the `Vec`s last element is nonzero. pub fn unsigned_vec_unsigned_rounding_mode_triple_gen_var_1( ) -> Generator<(Vec, T, RoundingMode)> { Generator::new( &exhaustive_unsigned_vec_unsigned_rounding_mode_triple_gen_var_1, &random_primitive_int_vec_primitive_int_rounding_mode_triple_gen_var_1, &special_random_unsigned_vec_unsigned_rounding_mode_triple_gen_var_1, ) } // All `(Vec, U, RoundingMode)` where `T` and `U` are unsigned, the `U` is small, and the `Vec` // does not only contain zeros. pub fn unsigned_vec_unsigned_rounding_mode_triple_gen_var_2< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >() -> Generator<(Vec, U, RoundingMode)> { Generator::new( &exhaustive_unsigned_vec_unsigned_rounding_mode_triple_gen_var_2, &random_primitive_int_vec_primitive_int_rounding_mode_triple_gen_var_2, &special_random_unsigned_vec_unsigned_rounding_mode_triple_gen_var_2, ) } // -- (Vec, Vec) -- pub fn unsigned_vec_pair_gen() -> Generator<(Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_pair_gen, &random_primitive_int_vec_pair_gen, &special_random_unsigned_vec_pair_gen, ) } // All `(Vec, Vec)` where `T` is unsigned, both `Vec`s are nonempty, and the first `Vec` is at // least as long as the second. pub fn unsigned_vec_pair_gen_var_1() -> Generator<(Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_pair_gen_var_2, &random_primitive_int_vec_pair_gen_var_2, &special_random_unsigned_vec_pair_gen_var_2, ) } // All `(Vec, Vec)` where `T` is unsigned and both `Vec`s are nonempty. pub fn unsigned_vec_pair_gen_var_2() -> Generator<(Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_pair_gen_var_3, &random_primitive_int_vec_pair_gen_var_3, &special_random_unsigned_vec_pair_gen_var_3, ) } // All `(Vec, Vec)` that are valid inputs to `limbs_pow_low` in malachite-nz. pub fn unsigned_vec_pair_gen_var_3() -> Generator<(Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_pair_gen_var_4, &random_primitive_int_vec_pair_gen_var_4, &special_random_unsigned_vec_pair_gen_var_4, ) } // All `(Vec, Vec)` that are valid `(out, xs)` inputs to `limbs_sqrt_rem_helper`. pub fn unsigned_vec_pair_gen_var_4() -> Generator<(Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_pair_gen_var_5::, &random_unsigned_vec_pair_gen_var_1::, &special_random_unsigned_vec_pair_gen_var_5::, ) } // All `(Vec, Vec)` that are valid `(out, xs)` inputs to `limbs_sqrt_to_out`. pub fn unsigned_vec_pair_gen_var_5() -> Generator<(Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_pair_gen_var_6::, &random_unsigned_vec_pair_gen_var_2::, &special_random_unsigned_vec_pair_gen_var_6::, ) } // All `(Vec, Vec)` where `T` is unsigned and both `Vec`s have the same length. pub fn unsigned_vec_pair_gen_var_6() -> Generator<(Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_pair_gen_var_7, &random_primitive_int_vec_pair_gen_var_5, &special_random_unsigned_vec_pair_gen_var_7, ) } // All `(Vec, Vec)` where `T` is unsigned and neither `Vec` ends with zero. pub fn unsigned_vec_pair_gen_var_7() -> Generator<(Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_pair_gen_var_8, &random_primitive_int_vec_pair_gen_var_6, &special_random_unsigned_vec_pair_gen_var_8, ) } // All `(Vec, Vec)` where `T` is unsigned and each `Vec` contains at least one nonzero value. pub fn unsigned_vec_pair_gen_var_8() -> Generator<(Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_pair_gen_var_9, &random_primitive_int_vec_pair_gen_var_7, &special_random_unsigned_vec_pair_gen_var_9, ) } // All `(Vec, Vec)` where `T` is unsigned, each `Vec` contains at least one nonzero value, and // the first `Vec` is at least as long as the second. pub fn unsigned_vec_pair_gen_var_9() -> Generator<(Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_pair_gen_var_10, &random_primitive_int_vec_pair_gen_var_8, &special_random_unsigned_vec_pair_gen_var_10, ) } // var 10 is in malachite-nz. // All `(Vec, Vec)` where `T` is unsigned, both `Vec`s have at least 2 elements, the first // `Vec` is at least as long as the second, and the last element of the second `Vec` is nonzero. pub fn unsigned_vec_pair_gen_var_11() -> Generator<(Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_pair_gen_var_12, &random_primitive_int_vec_pair_gen_var_10, &special_random_unsigned_vec_pair_gen_var_12, ) } // All `(Vec, Vec)` where `T` is unsigned, both `Vec`s are nonempty, the first `Vec` is at // least as long as the second, and the first element of the second `Vec` is odd. pub fn unsigned_vec_pair_gen_var_12() -> Generator<(Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_pair_gen_var_13, &random_primitive_int_vec_pair_gen_var_11, &special_random_unsigned_vec_pair_gen_var_13, ) } // vars 13 through 14 are in malachite-nz. // All `(Vec, Vec)` where `T` is unsigned, both `Vec`s are nonempty, the last elements of both // `Vec`s are nonzero, and the first `Vec` is at least as long as the second. pub fn unsigned_vec_pair_gen_var_15() -> Generator<(Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_pair_gen_var_16, &random_primitive_int_vec_pair_gen_var_12, &special_random_unsigned_vec_pair_gen_var_16, ) } // All `(Vec, Vec)` that are valid inputs to `limbs_div_mod` and `limbs_divisible_by`. pub fn unsigned_vec_pair_gen_var_16() -> Generator<(Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_pair_gen_var_17, &random_primitive_int_vec_pair_gen_var_13, &special_random_unsigned_vec_pair_gen_var_17, ) } // var 17 is in malachite-nz. // All `(Vec, Vec)` that are valid inputs to `limbs_mod_by_two_limb_normalized`. pub fn unsigned_vec_pair_gen_var_18() -> Generator<(Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_pair_gen_var_19, &random_unsigned_vec_pair_gen_var_5, &special_random_unsigned_vec_pair_gen_var_19, ) } // All `(Vec, Vec)` where `T` is unsigned and both `Vec`s end with a nonzero number. pub fn unsigned_vec_pair_gen_var_19() -> Generator<(Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_pair_gen_var_20, &random_primitive_int_vec_pair_gen_var_14, &special_random_unsigned_vec_pair_gen_var_20, ) } // All `(Vec, Vec)` where `T` is unsigned, both `Vec`s have at least 2 elements, and the first // `Vec` is at least as long as the second. pub fn unsigned_vec_pair_gen_var_20() -> Generator<(Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_pair_gen_var_21, &random_primitive_int_vec_pair_gen_var_15, &special_random_unsigned_vec_pair_gen_var_21, ) } // vars 21 through 30 are malachite-nz. // All `(Vec, Vec)` where `T` is unsigned and the first `Vec` is at least as long as the // second. pub fn unsigned_vec_pair_gen_var_31() -> Generator<(Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_pair_gen_var_32, &random_primitive_int_vec_pair_gen_var_26, &special_random_unsigned_vec_pair_gen_var_32, ) } // All `(Vec, Vec)` where `T` is unsigned, both `Vec`s have the same length, at least one ends // with a nonzero value, and the first element of the second `Vec` is odd. pub fn unsigned_vec_pair_gen_var_32() -> Generator<(Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_pair_gen_var_33, &random_primitive_int_vec_pair_gen_var_27, &special_random_unsigned_vec_pair_gen_var_33, ) } // var 33 is in malachite-nz. // -- (Vec, Vec, bool) -- // All `(Vec, Vec, bool)` where `T` is unsigned and both `Vec`s have the same length. pub fn unsigned_vec_unsigned_vec_bool_triple_gen_var_1( ) -> Generator<(Vec, Vec, bool)> { Generator::new( &exhaustive_unsigned_vec_unsigned_vec_bool_triple_gen_var_1, &random_primitive_int_vec_primitive_int_vec_bool_triple_gen_var_1, &special_random_unsigned_vec_unsigned_vec_bool_triple_gen_var_1, ) } // -- (Vec, Vec, PrimitiveUnsigned) -- // All `(Vec, Vec, T)` where `T` is unsigned and the first `Vec` is at least as long as the // second. pub fn unsigned_vec_unsigned_vec_unsigned_triple_gen_var_1( ) -> Generator<(Vec, Vec, T)> { Generator::new( &exhaustive_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_1, &random_primitive_int_vec_primitive_int_vec_primitive_int_triple_gen_var_1, &special_random_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_1, ) } // vars 2 and 3 are in malachite-nz // All `(Vec, Vec, T)` where `T` is unsigned, the first `Vec` is at least as long as the // second, and the second is nonempty. pub fn unsigned_vec_unsigned_vec_unsigned_triple_gen_var_4( ) -> Generator<(Vec, Vec, T)> { Generator::new( &exhaustive_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_4, &random_primitive_int_vec_primitive_int_vec_primitive_int_triple_gen_var_2, &special_random_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_4, ) } // All `(Vec, Vec, T)` where `T` is unsigned, the first `Vec` is at least as long as the // second, and the second contains at least one nonzero value. pub fn unsigned_vec_unsigned_vec_unsigned_triple_gen_var_5( ) -> Generator<(Vec, Vec, T)> { Generator::new( &exhaustive_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_5, &random_primitive_int_vec_primitive_int_vec_primitive_int_triple_gen_var_3, &special_random_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_5, ) } // All `(Vec, Vec, U)` where `T` and `U` are unsigned, the `U` is positive, both `Vec`s // contain at least two elements, and their last elements are nonzero. pub fn unsigned_vec_unsigned_vec_unsigned_triple_gen_var_6< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >() -> Generator<(Vec, Vec, U)> { Generator::new( &exhaustive_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_6, &random_primitive_int_vec_primitive_int_vec_primitive_int_triple_gen_var_4, &special_random_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_6, ) } // vars 7 through 8 are in malachite-nz. // All `(Vec, Vec, U)` where `T` and `U` are unsigned, the `U` is small, and the last elements // of both `Vec`s are nonzero. pub fn unsigned_vec_unsigned_vec_unsigned_triple_gen_var_9< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >() -> Generator<(Vec, Vec, U)> { Generator::new( &exhaustive_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_9, &random_primitive_int_vec_primitive_int_vec_primitive_int_triple_gen_var_5, &special_random_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_9, ) } // All `(Vec, Vec, U)` where `T` and `U` are unsigned, the `U` is positive, and the last // elements of both `Vec`s are nonzero. pub fn unsigned_vec_unsigned_vec_unsigned_triple_gen_var_10< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >() -> Generator<(Vec, Vec, U)> { Generator::new( &exhaustive_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_10, &random_primitive_int_vec_primitive_int_vec_primitive_int_triple_gen_var_6, &special_random_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_10, ) } // All `(Vec, Vec, usize)` where `T` is unsigned, the first `Vec` is at least as long as the // second, and the `usize` is no greater than the length of the second `Vec`. pub fn unsigned_vec_unsigned_vec_unsigned_triple_gen_var_11( ) -> Generator<(Vec, Vec, usize)> { Generator::new( &exhaustive_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_11, &random_primitive_int_vec_primitive_int_vec_unsigned_triple_gen_var_1, &special_random_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_11, ) } // All `(Vec, Vec, T)` where `T` is unsigned and the two `Vec`s have the same length. pub fn unsigned_vec_unsigned_vec_unsigned_triple_gen_var_12( ) -> Generator<(Vec, Vec, T)> { Generator::new( &exhaustive_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_12, &random_primitive_int_vec_primitive_int_vec_primitive_int_triple_gen_var_7, &special_random_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_12, ) } // All `(Vec, Vec, T)` where `T` is unsigned and positive, the first `Vec` is at least as long // as the second, and the second has at least two elements. pub fn unsigned_vec_unsigned_vec_unsigned_triple_gen_var_13( ) -> Generator<(Vec, Vec, T)> { Generator::new( &exhaustive_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_13, &random_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_1, &special_random_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_13, ) } // vars 14 through 21 are in malachite-nz. // All `(Vec, Vec, u64)` where `T` is unsigned, `U` is a primitive integer type, the first // `Vec` is at least as long as the second, and the `u64` is between 1 and `U::WIDTH - 1`, // inclusive. pub fn unsigned_vec_unsigned_vec_unsigned_triple_gen_var_22< T: PrimitiveUnsigned, U: PrimitiveInt, >() -> Generator<(Vec, Vec, u64)> { Generator::new( &exhaustive_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_22::, &random_primitive_int_vec_primitive_int_vec_primitive_int_triple_gen_var_8::, &special_random_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_22::, ) } // All `(Vec, Vec, u64)` where `T` is unsigned, `U` is a primitive integer type, the first // `Vec` is at least as long as the second, neither `Vec` is empty, and the `u64` is between 1 and // `U::WIDTH - 1`, inclusive. pub fn unsigned_vec_unsigned_vec_unsigned_triple_gen_var_23< T: PrimitiveUnsigned, U: PrimitiveInt, >() -> Generator<(Vec, Vec, u64)> { Generator::new( &exhaustive_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_23::, &random_primitive_int_vec_primitive_int_vec_primitive_int_triple_gen_var_9::, &special_random_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_23::, ) } // All `(Vec, Vec, usize)` where `T` is unsigned, the `Vec`s have the same length, and the // `usize` is no greater than the length of either `Vec`. pub fn unsigned_vec_unsigned_vec_unsigned_triple_gen_var_24( ) -> Generator<(Vec, Vec, usize)> { Generator::new( &exhaustive_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_24, &random_primitive_int_vec_primitive_int_vec_unsigned_triple_gen_var_2, &special_random_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_24, ) } // -- (Vec, Vec, Vec) -- // All `(Vec, Vec, Vec)` where `T` is unsigned, no `Vec` is empty, the second and third // `Vec`s have equal length, and the first is at least twice as long as the second. pub fn unsigned_vec_triple_gen_var_1() -> Generator<(Vec, Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_triple_gen_var_1, &random_primitive_int_vec_triple_gen_var_1, &special_random_unsigned_vec_triple_gen_var_1, ) } // All `(Vec, Vec, Vec)` where `T` is unsigned, no `Vec` is empty, the second is at least // as long as the third, and the length of the first is at least the sum of the lengths of the // second and the third. pub fn unsigned_vec_triple_gen_var_2() -> Generator<(Vec, Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_triple_gen_var_2, &random_primitive_int_vec_triple_gen_var_2, &special_random_unsigned_vec_triple_gen_var_2, ) } // All `(Vec, Vec, Vec)` where `T` is unsigned, no `Vec` is empty, and the length of the // first is at least the sum of the lengths of the second and the third. pub fn unsigned_vec_triple_gen_var_3() -> Generator<(Vec, Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_triple_gen_var_3, &random_primitive_int_vec_triple_gen_var_3, &special_random_unsigned_vec_triple_gen_var_3, ) } // vars 4 through 23 are in malachite-nz // All `(Vec, Vec, Vec)` where `T` is unsigned, no `Vec` is empty, the second and third // `Vec`s have equal length, and the first is at least as long as the second. pub fn unsigned_vec_triple_gen_var_24() -> Generator<(Vec, Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_triple_gen_var_24, &random_primitive_int_vec_triple_gen_var_24, &special_random_unsigned_vec_triple_gen_var_24, ) } // All `(Vec, Vec, Vec)` where `T` is unsigned, all `Vec`s have length at least 2, the // second and third `Vec`s have equal length, and the first is at least twice as long as the second. pub fn unsigned_vec_triple_gen_var_25() -> Generator<(Vec, Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_triple_gen_var_25, &random_primitive_int_vec_triple_gen_var_25, &special_random_unsigned_vec_triple_gen_var_25, ) } // All `(Vec, Vec, Vec)` where `T` is unsigned, all `Vec`s have length at least 2, the // second and third `Vec`s have equal length, and the first is at least as long as the second. pub fn unsigned_vec_triple_gen_var_26() -> Generator<(Vec, Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_triple_gen_var_26, &random_primitive_int_vec_triple_gen_var_26, &special_random_unsigned_vec_triple_gen_var_26, ) } // All `(Vec, Vec, Vec)` where `T` is unsigned and all three `Vec`s have the same length, // which is at least 2. pub fn unsigned_vec_triple_gen_var_27() -> Generator<(Vec, Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_triple_gen_var_27, &random_primitive_int_vec_triple_gen_var_27, &special_random_unsigned_vec_triple_gen_var_27, ) } // All `(Vec, Vec, Vec)` that are valid `(out, rs, xs)` inputs to `limbs_sqrt_rem_to_out`. pub fn unsigned_vec_triple_gen_var_28() -> Generator<(Vec, Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_triple_gen_var_28::, &random_unsigned_vec_triple_gen_var_9::, &special_random_unsigned_vec_triple_gen_var_28::, ) } // All `(Vec, Vec, Vec)` where `T` is unsigned and all three `Vec`s have the same length. pub fn unsigned_vec_triple_gen_var_29() -> Generator<(Vec, Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_triple_gen_var_29, &random_primitive_int_vec_triple_gen_var_28, &special_random_unsigned_vec_triple_gen_var_29, ) } // All `(Vec, Vec, Vec)` where `T` is unsigned and no `Vec` ends with zero. pub fn unsigned_vec_triple_gen_var_30() -> Generator<(Vec, Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_triple_gen_var_30, &random_primitive_int_vec_triple_gen_var_29, &special_random_unsigned_vec_triple_gen_var_30, ) } // All `(Vec, Vec, Vec)` where `T` is unsigned, the second and third `Vec`s have equal // length, and the first is at least as long as the second. pub fn unsigned_vec_triple_gen_var_31() -> Generator<(Vec, Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_triple_gen_var_31, &random_primitive_int_vec_triple_gen_var_30, &special_random_unsigned_vec_triple_gen_var_31, ) } // All `(Vec, Vec, Vec)` where `T` is unsigned and the first `Vec` is at least as long as // the second and at least as long as the third. pub fn unsigned_vec_triple_gen_var_32() -> Generator<(Vec, Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_triple_gen_var_32, &random_primitive_int_vec_triple_gen_var_31, &special_random_unsigned_vec_triple_gen_var_32, ) } // All `(Vec, Vec, Vec)` where `T` is unsigned, the second and third `Vec`s each contain at // least one nonzero element, and the first `Vec` is at least as long as the second. pub fn unsigned_vec_triple_gen_var_33() -> Generator<(Vec, Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_triple_gen_var_33, &random_primitive_int_vec_triple_gen_var_32, &special_random_unsigned_vec_triple_gen_var_33, ) } // All `(Vec, Vec, Vec)` where `T` is unsigned, the second and third `Vec`s each contain at // least one nonzero element, and the first `Vec` is at least as long as the second AND at least as // long as the third. pub fn unsigned_vec_triple_gen_var_34() -> Generator<(Vec, Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_triple_gen_var_34, &random_primitive_int_vec_triple_gen_var_33, &special_random_unsigned_vec_triple_gen_var_34, ) } // All `(Vec, Vec, Vec)` where `T` is unsigned, the second and third `Vec`s each contain at // least one nonzero element, and the first `Vec` is at least as long as the second OR at least as // long as the third. pub fn unsigned_vec_triple_gen_var_35() -> Generator<(Vec, Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_triple_gen_var_35, &random_primitive_int_vec_triple_gen_var_34, &special_random_unsigned_vec_triple_gen_var_35, ) } // All `(Vec, Vec, Vec)` where `T` is unsigned, each `Vec` contains at least two elements, // and the last element of each `Vec` is nonzero. pub fn unsigned_vec_triple_gen_var_36() -> Generator<(Vec, Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_triple_gen_var_36, &random_primitive_int_vec_triple_gen_var_35, &special_random_unsigned_vec_triple_gen_var_36, ) } // vars 37 through 38 are in malachite-nz // All `(Vec, Vec, Vec)` where `T` is unsigned and each `Vec` ends with a nonzero element. pub fn unsigned_vec_triple_gen_var_39() -> Generator<(Vec, Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_triple_gen_var_39, &random_primitive_int_vec_triple_gen_var_38, &special_random_unsigned_vec_triple_gen_var_39, ) } // All `(Vec, Vec, Vec)` where `T` is unsigned and the first `Vec` is at least as long as // the second and the second is at least as long as the third. pub fn unsigned_vec_triple_gen_var_40() -> Generator<(Vec, Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_triple_gen_var_40, &random_primitive_int_vec_triple_gen_var_39, &special_random_unsigned_vec_triple_gen_var_40, ) } // All `(Vec, Vec, Vec)` where `T` is unsigned, every `Vec` ends with a nonzero element, // and the last `Vec` has length at least 2. pub fn unsigned_vec_triple_gen_var_41() -> Generator<(Vec, Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_triple_gen_var_41, &random_primitive_int_vec_triple_gen_var_40, &special_random_unsigned_vec_triple_gen_var_41, ) } // vars 42 through 49 are in malachite-nz. // All `(Vec, Vec, Vec)` where the first `Vec` is at least as long as the second, the third // is at least as long as twice the length of the second, and the second is nonempty and its most // significant bit is set. pub fn unsigned_vec_triple_gen_var_50() -> Generator<(Vec, Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_triple_gen_var_50, &random_primitive_int_vec_triple_gen_var_41, &special_random_unsigned_vec_triple_gen_var_50, ) } // All `(Vec, Vec, Vec)` where the first `Vec` is at least as long as the second, the third // is at least as long as twice the length of the second, and the second has length at least 5 and // its most significant bit is set. pub fn unsigned_vec_triple_gen_var_51() -> Generator<(Vec, Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_triple_gen_var_51, &random_primitive_int_vec_triple_gen_var_42, &special_random_unsigned_vec_triple_gen_var_51, ) } // All `(Vec, Vec, Vec)` that meet certain preconditions that enable comparing the // performance of divide-and-conquer division and Barrett division. pub fn unsigned_vec_triple_gen_var_52() -> Generator<(Vec, Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_triple_gen_var_52, &random_primitive_int_vec_triple_gen_var_43, &special_random_unsigned_vec_triple_gen_var_52, ) } // All `(Vec, Vec, Vec)` that are valid inputs to `limbs_div_mod_by_two_limb_normalized`. pub fn unsigned_vec_triple_gen_var_53() -> Generator<(Vec, Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_triple_gen_var_53, &random_unsigned_vec_triple_gen_var_10, &special_random_unsigned_vec_triple_gen_var_53, ) } // vars 54 through 56 are in malachite-base. // All `(Vec, Vec, Vec)` where `T` is unsigned, the first `Vec` is at least as long as the // second and at least as long as the third, all `Vec`s have at least 2 elements, and the last // element of the third is nonzero. pub fn unsigned_vec_triple_gen_var_57() -> Generator<(Vec, Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_triple_gen_var_57, &random_primitive_int_vec_triple_gen_var_44, &special_random_unsigned_vec_triple_gen_var_57, ) } // var 58 is in malachite-nz. // All `(Vec, Vec, Vec)` `(xs, ys, zs)` where `T` is unsigned, `ys` and `zs` have at least // two elements, `xs` has at least `ys.len() + zs.len() - 1` elements, and each slice ends with a // nonzero value. pub fn unsigned_vec_triple_gen_var_59() -> Generator<(Vec, Vec, Vec)> { Generator::new( &exhaustive_unsigned_vec_triple_gen_var_59, &random_primitive_int_vec_triple_gen_var_46, &special_random_unsigned_vec_triple_gen_var_59, ) } // var 60 is in malachite-nz. // -- large types -- // TODO description pub fn large_type_gen_var_1() -> Generator<(Vec, Vec, T, T)> { Generator::new( &exhaustive_large_type_gen_var_1, &random_large_type_gen_var_1, &special_random_large_type_gen_var_1, ) } // All `(Vec, Vec, u64, bool)` that are valid inputs to `limbs_sqrt_helper`. pub fn large_type_gen_var_2() -> Generator<(Vec, Vec, u64, bool)> { Generator::new( &exhaustive_large_type_gen_var_2, &random_large_type_gen_var_2, &special_random_large_type_gen_var_2, ) } // All `(Vec, U, U, Vec)` where `T` and `U` are unsigned and the first `U` is less than the // second. pub fn large_type_gen_var_3( ) -> Generator<(Vec, U, U, Vec)> { Generator::new( &exhaustive_large_type_gen_var_3, &random_large_type_gen_var_3, &special_random_large_type_gen_var_3, ) } // All `(Vec, U, U, Vec)` where `T` and `U` are unsigned, the first `U` is less than the // second, and the first `Vec` contains at least one nonzero value. pub fn large_type_gen_var_4( ) -> Generator<(Vec, U, U, Vec)> { Generator::new( &exhaustive_large_type_gen_var_4, &random_large_type_gen_var_4, &special_random_large_type_gen_var_4, ) } // vars 5 through 8 are in malachite-nz // All `(Vec, Vec, Vec, bool)` where `T` is unsigned, the second and third `Vec`s have // equal length, and the first is at least as long as the second. #[allow(clippy::type_complexity)] pub fn large_type_gen_var_9() -> Generator<(Vec, Vec, Vec, bool)> { Generator::new( &exhaustive_large_type_gen_var_9, &random_large_type_gen_var_9, &special_random_large_type_gen_var_9, ) } // vars 10 through 21 are in malachite-nz. type T2 = Generator<(RationalSequence, usize, T, T)>; // All `(RationalSequence, usize, T, T)` quadruples where `T` is unsigned and the `usize` is less // than the length of the `RationalSequence`. pub fn large_type_gen_var_22() -> T2 { Generator::new( &exhaustive_large_type_gen_var_22, &random_large_type_gen_var_22, &special_random_large_type_gen_var_22, ) } // vars 23 through 26 are in malachite-nz. // All (bool, Vec, bool, Vec) where `T` is unsigned and neither `Vec` ends with a zero. pub fn large_type_gen_var_27() -> Generator<(bool, Vec, bool, Vec)> { Generator::new( &exhaustive_large_type_gen_var_27, &random_large_type_gen_var_27, &special_random_large_type_gen_var_25, ) } // var 23 is in malachite-nz. pub mod common; pub mod exhaustive; pub mod random; pub mod special_random; malachite-base-0.4.16/src/test_util/generators/random.rs000064400000000000000000007526621046102023000213770ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::bools::random::{random_bools, RandomBools}; use crate::chars::constants::NUMBER_OF_CHARS; use crate::chars::random::{ random_ascii_chars, random_char_inclusive_range, random_char_range, random_chars, }; use crate::comparison::traits::Min; use crate::iterators::with_special_value; use crate::num::arithmetic::traits::CoprimeWith; use crate::num::arithmetic::traits::{ ArithmeticCheckedShl, DivRound, Parity, PowerOf2, ShrRound, UnsignedAbs, }; use crate::num::basic::floats::PrimitiveFloat; use crate::num::basic::integers::PrimitiveInt; use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::string::options::random::{ random_from_sci_string_options, random_sci_size_options, random_to_sci_options, RandomFromSciStringOptions, }; use crate::num::conversion::string::options::{FromSciStringOptions, SciSizeOptions, ToSciOptions}; use crate::num::conversion::traits::{ ConvertibleFrom, Digits, ExactFrom, HasHalf, JoinHalves, RoundingFrom, SaturatingFrom, SplitInHalf, WrappingFrom, WrappingInto, }; use crate::num::float::NiceFloat; use crate::num::logic::traits::{BitBlockAccess, LeadingZeros}; use crate::num::random::geometric::{ geometric_random_natural_signeds, geometric_random_negative_signeds, geometric_random_nonzero_signeds, geometric_random_positive_unsigneds, geometric_random_signed_inclusive_range, geometric_random_signed_range, geometric_random_signeds, geometric_random_unsigned_inclusive_range, geometric_random_unsigned_range, geometric_random_unsigneds, GeometricRandomNaturalValues, GeometricRandomSignedRange, GeometricRandomSigneds, }; use crate::num::random::{ random_highest_bit_set_unsigneds, random_natural_signeds, random_negative_signeds, random_nonzero_signeds, random_positive_signeds, random_positive_unsigneds, random_primitive_ints, random_signed_inclusive_range, random_signed_range, random_unsigned_bit_chunks, random_unsigned_inclusive_range, random_unsigned_range, random_unsigneds_less_than, special_random_finite_primitive_floats, special_random_nonzero_finite_primitive_floats, special_random_positive_finite_primitive_floats, special_random_primitive_float_inclusive_range, special_random_primitive_float_range, special_random_primitive_floats, RandomPrimitiveInts, RandomUnsignedBitChunks, RandomUnsignedInclusiveRange, RandomUnsignedRange, SpecialRandomNonzeroFiniteFloats, VariableRangeGenerator, }; use crate::random::{Seed, EXAMPLE_SEED}; use crate::rational_sequences::random::random_rational_sequences; use crate::rational_sequences::RationalSequence; use crate::rounding_modes::random::{random_rounding_modes, RandomRoundingModes}; use crate::rounding_modes::RoundingMode::{self, *}; use crate::slices::slice_test_zero; use crate::strings::random::{random_strings, random_strings_using_chars}; use crate::strings::strings_from_char_vecs; use crate::test_util::extra_variadic::{ random_duodecuples_from_single, random_octuples_from_single, random_quadruples_from_single, random_quadruples_xxxy, random_quadruples_xxyx, random_quadruples_xyxy, random_quadruples_xyyx, random_quadruples_xyyz, random_quadruples_xyzz, random_sextuples_from_single, random_triples, random_triples_from_single, random_triples_xxy, random_triples_xyx, random_triples_xyy, random_union3s, Union3, }; use crate::test_util::generators::common::{ reshape_1_2_to_3, reshape_2_1_to_3, reshape_2_2_to_4, reshape_3_1_to_4, GenConfig, It, }; use crate::test_util::generators::exhaustive::{ float_rounding_mode_filter_var_1, valid_digit_chars, }; use crate::test_util::generators::{ digits_valid, large_exponent, round_to_multiple_of_power_of_2_filter_map, round_to_multiple_signed_filter_map, round_to_multiple_unsigned_filter_map, signed_assign_bits_valid, smallest_invalid_value, unsigned_assign_bits_valid, }; use crate::test_util::num::arithmetic::mod_mul::limbs_invert_limb_naive; use crate::test_util::num::conversion::string::from_sci_string::DECIMAL_SCI_STRING_CHARS; use crate::test_util::num::float::PRIMITIVE_FLOAT_CHARS; use crate::test_util::rounding_modes::ROUNDING_MODE_CHARS; use crate::tuples::random::{random_ordered_unique_pairs, random_pairs, random_pairs_from_single}; use crate::unions::random::random_union2s; use crate::unions::Union2; use crate::vecs::random::{ random_vecs, random_vecs_fixed_length_from_single, random_vecs_length_inclusive_range, random_vecs_min_length, }; use crate::vecs::random_values_from_vec; use itertools::repeat_n; use itertools::Itertools; use std::cmp::{max, min, Ordering::*}; use std::collections::HashMap; use std::marker::PhantomData; use std::mem::swap; // -- bool -- pub fn random_bool_gen(_config: &GenConfig) -> It { Box::new(random_bools(EXAMPLE_SEED)) } // -- char -- pub fn random_char_gen(_config: &GenConfig) -> It { Box::new(random_chars(EXAMPLE_SEED)) } #[allow(unstable_name_collisions)] pub fn random_char_gen_var_1(_config: &GenConfig) -> It { Box::new(random_char_range(EXAMPLE_SEED, char::MIN, char::MAX)) } #[allow(unstable_name_collisions)] pub fn random_char_gen_var_2(_config: &GenConfig) -> It { Box::new(random_char_inclusive_range( EXAMPLE_SEED, '\u{1}', char::MAX, )) } // -- (char, char) -- pub fn random_char_pair_gen(_config: &GenConfig) -> It<(char, char)> { Box::new(random_pairs_from_single(random_chars(EXAMPLE_SEED))) } // -- FromSciStringOptions -- pub fn random_from_sci_string_options_gen(_config: &GenConfig) -> It { Box::new(random_from_sci_string_options(EXAMPLE_SEED)) } // -- (FromSciStringOptions, PrimitiveUnsigned) -- pub fn random_from_sci_string_options_unsigned_pair_gen_var_1( _config: &GenConfig, ) -> It<(FromSciStringOptions, T)> { Box::new(random_pairs( EXAMPLE_SEED, &random_from_sci_string_options, &|seed| random_unsigned_inclusive_range(seed, T::TWO, T::from(36u8)), )) } // -- (FromSciStringOptions, RoundingMode) -- pub fn random_from_sci_string_options_rounding_mode_pair_gen( _config: &GenConfig, ) -> It<(FromSciStringOptions, RoundingMode)> { Box::new(random_pairs( EXAMPLE_SEED, &random_from_sci_string_options, &random_rounding_modes, )) } // -- PrimitiveFloat -- pub fn random_primitive_float_gen(config: &GenConfig) -> It { Box::new(special_random_primitive_floats( EXAMPLE_SEED, config.get_or("exponent_mean_n", 8), config.get_or("exponent_mean_d", 1), config.get_or("precision_mean_n", 8), config.get_or("precision_mean_d", 1), config.get_or("special_p_mean_n", 1), config.get_or("special_p_mean_d", 64), )) } pub fn random_primitive_float_gen_var_1(config: &GenConfig) -> It { Box::new(special_random_primitive_float_range( EXAMPLE_SEED, T::NEGATIVE_ONE / T::TWO, T::INFINITY, config.get_or("exponent_mean_n", 8), config.get_or("exponent_mean_d", 1), config.get_or("precision_mean_n", 8), config.get_or("precision_mean_d", 1), config.get_or("special_p_mean_n", 1), config.get_or("special_p_mean_d", 64), )) } struct RandomPositiveNaturalFloats { exponents: GeometricRandomSignedRange, ranges: VariableRangeGenerator, phantom: PhantomData, } impl Iterator for RandomPositiveNaturalFloats { type Item = T; fn next(&mut self) -> Option { let exponent = self.exponents.next().unwrap(); let a = if exponent == 0 { 1 } else { u64::power_of_2(T::MANTISSA_WIDTH) }; let mantissa = self .ranges .next_in_range(a, u64::power_of_2(T::MANTISSA_WIDTH + 1)); Some(T::from_integer_mantissa_and_exponent(mantissa, exponent).unwrap()) } } fn random_positive_natural_floats( seed: Seed, mean_exponent_numerator: u64, mean_exponent_denominator: u64, ) -> RandomPositiveNaturalFloats { RandomPositiveNaturalFloats { exponents: geometric_random_signed_range( seed.fork("exponents"), 0, i64::power_of_2(T::EXPONENT_WIDTH - 1) - i64::wrapping_from(T::MANTISSA_WIDTH) - 1, mean_exponent_numerator, mean_exponent_denominator, ), ranges: VariableRangeGenerator::new(seed.fork("mantissas")), phantom: PhantomData, } } pub fn random_primitive_float_gen_var_2(config: &GenConfig) -> It { Box::new(with_special_value(EXAMPLE_SEED, T::ZERO, 1, 100, &|seed| { random_positive_natural_floats( seed, config.get_or("exponent_mean_n", 8), config.get_or("exponent_mean_d", 1), ) })) } pub fn random_primitive_float_gen_var_3(config: &GenConfig) -> It { Box::new( special_random_positive_finite_primitive_floats::( EXAMPLE_SEED, config.get_or("exponent_mean_n", 8), config.get_or("exponent_mean_d", 1), config.get_or("precision_mean_n", 8), config.get_or("precision_mean_d", 1), ) .filter(|f| !f.is_integer()), ) } pub fn random_primitive_float_gen_var_4(config: &GenConfig) -> It { Box::new( special_random_primitive_float_inclusive_range::( EXAMPLE_SEED, T::ONE, T::from_integer_mantissa_and_exponent(1, i64::wrapping_from(T::MANTISSA_WIDTH)) .unwrap(), config.get_or("exponent_mean_n", 8), config.get_or("exponent_mean_d", 1), config.get_or("precision_mean_n", 8), config.get_or("precision_mean_d", 1), 1, 100, ) .map(|f| f.floor() - T::ONE / T::TWO), ) } pub fn random_primitive_float_gen_var_5(config: &GenConfig) -> It { Box::new( random_pairs( EXAMPLE_SEED, &|seed| { with_special_value(seed, T::ZERO, 1, 100, &|seed_2| { random_positive_natural_floats( seed_2, config.get_or("exponent_mean_n", 8), config.get_or("exponent_mean_d", 1), ) }) }, &random_bools, ) .map(|(f, b)| if b { f } else { -f }), ) } pub fn random_primitive_float_gen_var_6(config: &GenConfig) -> It { Box::new( random_pairs( EXAMPLE_SEED, &|seed| { special_random_positive_finite_primitive_floats::( seed, config.get_or("exponent_mean_n", 8), config.get_or("exponent_mean_d", 1), config.get_or("precision_mean_n", 8), config.get_or("precision_mean_d", 1), ) .filter(|f| !f.is_integer()) }, &random_bools, ) .map(|(f, b)| if b { f } else { -f }), ) } pub fn random_primitive_float_gen_var_7(config: &GenConfig) -> It { Box::new( random_pairs( EXAMPLE_SEED, &|seed| { special_random_primitive_float_inclusive_range::( seed, T::ONE, T::from_integer_mantissa_and_exponent(1, i64::wrapping_from(T::MANTISSA_WIDTH)) .unwrap(), config.get_or("exponent_mean_n", 8), config.get_or("exponent_mean_d", 1), config.get_or("precision_mean_n", 8), config.get_or("precision_mean_d", 1), 1, 100, ) .map(|f| f.floor() - T::ONE / T::TWO) }, &random_bools, ) .map(|(f, b)| if b { f } else { -f }), ) } pub fn random_primitive_float_gen_var_8(config: &GenConfig) -> It { Box::new(special_random_finite_primitive_floats( EXAMPLE_SEED, config.get_or("exponent_mean_n", 8), config.get_or("exponent_mean_d", 1), config.get_or("precision_mean_n", 8), config.get_or("precision_mean_d", 1), config.get_or("special_p_mean_n", 1), config.get_or("special_p_mean_d", 64), )) } pub fn random_primitive_float_gen_var_9(config: &GenConfig) -> It { Box::new( special_random_primitive_floats::( EXAMPLE_SEED, config.get_or("exponent_mean_n", 8), config.get_or("exponent_mean_d", 1), config.get_or("precision_mean_n", 8), config.get_or("precision_mean_d", 1), config.get_or("special_p_mean_n", 1), config.get_or("special_p_mean_d", 64), ) .filter(|&f| !f.is_nan() && f != T::INFINITY), ) } pub fn random_primitive_float_gen_var_10(config: &GenConfig) -> It { Box::new( special_random_primitive_floats::( EXAMPLE_SEED, config.get_or("exponent_mean_n", 8), config.get_or("exponent_mean_d", 1), config.get_or("precision_mean_n", 8), config.get_or("precision_mean_d", 1), config.get_or("special_p_mean_n", 1), config.get_or("special_p_mean_d", 64), ) .filter(|&f| !f.is_nan() && f != T::NEGATIVE_INFINITY), ) } pub fn random_primitive_float_gen_var_11(config: &GenConfig) -> It { Box::new( special_random_primitive_floats::( EXAMPLE_SEED, config.get_or("exponent_mean_n", 8), config.get_or("exponent_mean_d", 1), config.get_or("precision_mean_n", 8), config.get_or("precision_mean_d", 1), config.get_or("special_p_mean_n", 1), config.get_or("special_p_mean_d", 64), ) .filter(|&f| !f.is_nan()), ) } pub fn random_primitive_float_gen_var_12(config: &GenConfig) -> It { Box::new(special_random_nonzero_finite_primitive_floats( EXAMPLE_SEED, config.get_or("exponent_mean_n", 8), config.get_or("exponent_mean_d", 1), config.get_or("precision_mean_n", 8), config.get_or("precision_mean_d", 1), )) } pub fn random_primitive_float_gen_var_13, U: PrimitiveInt>( _config: &GenConfig, ) -> It { Box::new(random_primitive_ints::(EXAMPLE_SEED).map(|n| T::rounding_from(n, Down).0)) } pub fn random_primitive_float_gen_var_14< T: PrimitiveFloat, U: ConvertibleFrom + PrimitiveInt, >( config: &GenConfig, ) -> It { Box::new( special_random_primitive_floats::( EXAMPLE_SEED, config.get_or("exponent_mean_n", 8), config.get_or("exponent_mean_d", 1), config.get_or("precision_mean_n", 8), config.get_or("precision_mean_d", 1), config.get_or("special_p_mean_n", 1), config.get_or("special_p_mean_d", 64), ) .filter(|&f| !U::convertible_from(f)), ) } pub fn random_primitive_float_gen_var_15< T: PrimitiveFloat + RoundingFrom, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It { let limit = min( NiceFloat(T::rounding_from(U::MAX, Down).0), NiceFloat( T::from_integer_mantissa_and_exponent(1, i64::wrapping_from(T::MANTISSA_WIDTH)) .unwrap(), ), ) .0; Box::new( special_random_primitive_float_inclusive_range::( EXAMPLE_SEED, T::ONE, limit, config.get_or("exponent_mean_n", 8), config.get_or("exponent_mean_d", 1), config.get_or("precision_mean_n", 8), config.get_or("precision_mean_d", 1), 1, 100, ) .map(|f| f.floor() - T::ONE / T::TWO), ) } pub fn random_primitive_float_gen_var_16< T: PrimitiveFloat + RoundingFrom, U: PrimitiveSigned, >( config: &GenConfig, ) -> It { let min_limit = min( NiceFloat(-T::rounding_from(U::MIN, Down).0), NiceFloat( T::from_integer_mantissa_and_exponent(1, i64::wrapping_from(T::MANTISSA_WIDTH)) .unwrap(), ), ) .0; let max_limit = min( NiceFloat(T::rounding_from(U::MAX, Down).0), NiceFloat( T::from_integer_mantissa_and_exponent(1, i64::wrapping_from(T::MANTISSA_WIDTH)) .unwrap(), ), ) .0; Box::new( random_union2s( EXAMPLE_SEED, &|seed| { special_random_primitive_float_inclusive_range::( seed, T::ONE, max_limit, config.get_or("exponent_mean_n", 8), config.get_or("exponent_mean_d", 1), config.get_or("precision_mean_n", 8), config.get_or("precision_mean_d", 1), 1, 100, ) .map(|f| f.floor() - T::ONE / T::TWO) }, &|seed| { special_random_primitive_float_inclusive_range::( seed, T::ONE, min_limit, config.get_or("exponent_mean_n", 8), config.get_or("exponent_mean_d", 1), config.get_or("precision_mean_n", 8), config.get_or("precision_mean_d", 1), 1, 100, ) .map(|f| T::ONE / T::TWO - f.floor()) }, ) .map(Union2::unwrap), ) } pub fn random_primitive_float_gen_var_17(config: &GenConfig) -> It { Box::new(special_random_positive_finite_primitive_floats::( EXAMPLE_SEED, config.get_or("exponent_mean_n", 8), config.get_or("exponent_mean_d", 1), config.get_or("precision_mean_n", 8), config.get_or("precision_mean_d", 1), )) } pub fn random_primitive_float_gen_var_18(config: &GenConfig) -> It { Box::new(special_random_primitive_float_inclusive_range::( EXAMPLE_SEED, T::ZERO, T::power_of_2(T::MAX_EXPONENT), config.get_or("exponent_mean_n", 8), config.get_or("exponent_mean_d", 1), config.get_or("precision_mean_n", 8), config.get_or("precision_mean_d", 1), 1, 100, )) } // -- (PrimitiveFloat, PrimitiveFloat) -- pub fn random_primitive_float_pair_gen(config: &GenConfig) -> It<(T, T)> { Box::new(random_pairs_from_single(special_random_primitive_floats( EXAMPLE_SEED, config.get_or("exponent_mean_n", 8), config.get_or("exponent_mean_d", 1), config.get_or("precision_mean_n", 8), config.get_or("precision_mean_d", 1), config.get_or("special_p_mean_n", 1), config.get_or("special_p_mean_d", 64), ))) } pub fn random_primitive_float_pair_gen_var_1(config: &GenConfig) -> It<(T, T)> { Box::new(random_pairs_from_single( special_random_primitive_floats::( EXAMPLE_SEED, config.get_or("exponent_mean_n", 8), config.get_or("exponent_mean_d", 1), config.get_or("precision_mean_n", 8), config.get_or("precision_mean_d", 1), config.get_or("special_p_mean_n", 1), config.get_or("special_p_mean_d", 64), ) .filter(|&f| !f.is_nan()), )) } // -- (PrimitiveFloat, PrimitiveFloat, PrimitiveFloat) -- pub fn random_primitive_float_triple_gen(config: &GenConfig) -> It<(T, T, T)> { Box::new(random_triples_from_single(special_random_primitive_floats( EXAMPLE_SEED, config.get_or("exponent_mean_n", 8), config.get_or("exponent_mean_d", 1), config.get_or("precision_mean_n", 8), config.get_or("precision_mean_d", 1), config.get_or("special_p_mean_n", 1), config.get_or("special_p_mean_d", 64), ))) } // -- (PrimitiveFloat, PrimitiveSigned) -- pub fn random_primitive_float_signed_pair_gen( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { special_random_primitive_floats( seed, config.get_or("exponent_mean_n", 8), config.get_or("exponent_mean_d", 1), config.get_or("precision_mean_n", 8), config.get_or("precision_mean_d", 1), config.get_or("special_p_mean_n", 1), config.get_or("special_p_mean_d", 64), ) }, &|seed| { geometric_random_signeds( seed, config.get_or("mean_small_signed_n", 32), config.get_or("mean_small_signed_d", 1), ) }, )) } pub fn random_primitive_float_signed_pair_gen_var_1( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { special_random_positive_finite_primitive_floats( seed, config.get_or("exponent_mean_n", 8), config.get_or("exponent_mean_d", 1), config.get_or("precision_mean_n", 8), config.get_or("precision_mean_d", 1), ) }, &|seed| { geometric_random_signeds( seed, config.get_or("mean_small_signed_n", 32), config.get_or("mean_small_signed_d", 1), ) }, )) } pub fn random_primitive_float_signed_pair_gen_var_2( config: &GenConfig, ) -> It<(T, i64)> { Box::new( random_pairs( EXAMPLE_SEED, &|seed| { special_random_primitive_float_range( seed, T::ONE, T::TWO, config.get_or("exponent_mean_n", 8), config.get_or("exponent_mean_d", 1), config.get_or("precision_mean_n", 8), config.get_or("precision_mean_d", 1), config.get_or("special_p_mean_n", 1), config.get_or("special_p_mean_d", 64), ) }, &|seed| { geometric_random_signed_inclusive_range( seed, T::MIN_EXPONENT, T::MAX_EXPONENT, config.get_or("mean_small_signed_n", 32), config.get_or("mean_small_signed_d", 1), ) }, ) .filter(|&(m, e)| m.precision() <= T::max_precision_for_sci_exponent(e)), ) } pub fn random_primitive_float_signed_pair_gen_var_3( config: &GenConfig, ) -> It<(T, i64)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { special_random_primitive_float_range( seed, T::ONE, T::TWO, config.get_or("exponent_mean_n", 8), config.get_or("exponent_mean_d", 1), config.get_or("precision_mean_n", 8), config.get_or("precision_mean_d", 1), config.get_or("special_p_mean_n", 1), config.get_or("special_p_mean_d", 64), ) }, &|seed| { geometric_random_signeds( seed, config.get_or("mean_small_signed_n", 32), config.get_or("mean_small_signed_d", 1), ) }, )) } pub fn random_primitive_float_signed_pair_gen_var_4( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { special_random_primitive_floats( seed, config.get_or("exponent_mean_n", 8), config.get_or("exponent_mean_d", 1), config.get_or("precision_mean_n", 8), config.get_or("precision_mean_d", 1), config.get_or("special_p_mean_n", 1), config.get_or("special_p_mean_d", 64), ) }, &|seed| { geometric_random_signeds( seed, config.get_or("mean_small_signed_n", 32), config.get_or("mean_small_signed_d", 1), ) }, )) } // -- (PrimitiveFloat, PrimitiveSigned, PrimitiveUnsigned) -- pub fn random_primitive_float_signed_unsigned_triple_gen_var_1< T: PrimitiveFloat, U: PrimitiveSigned, V: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(T, U, V)> { Box::new(random_triples( EXAMPLE_SEED, &|seed| { special_random_primitive_floats( seed, config.get_or("exponent_mean_n", 8), config.get_or("exponent_mean_d", 1), config.get_or("precision_mean_n", 8), config.get_or("precision_mean_d", 1), config.get_or("special_p_mean_n", 1), config.get_or("special_p_mean_d", 64), ) }, &|seed| { geometric_random_signeds( seed, config.get_or("mean_small_signed_n", 32), config.get_or("mean_small_signed_d", 1), ) }, &|seed| { geometric_random_positive_unsigneds( seed, config.get_or("mean_small_unsigned_n", 32), config.get_or("mean_small_unsigned_d", 1), ) }, )) } // -- (PrimitiveFloat, PrimitiveUnsigned) -- pub fn random_primitive_float_unsigned_pair_gen_var_1( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { special_random_positive_finite_primitive_floats( seed, config.get_or("exponent_mean_n", 8), config.get_or("exponent_mean_d", 1), config.get_or("precision_mean_n", 8), config.get_or("precision_mean_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_unsigned_n", 32), config.get_or("mean_small_unsigned_d", 1), ) }, )) } pub fn random_primitive_float_unsigned_pair_gen_var_2( config: &GenConfig, ) -> It<(T, u64)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { special_random_primitive_float_range( seed, T::ONE, T::TWO, config.get_or("exponent_mean_n", 8), config.get_or("exponent_mean_d", 1), config.get_or("precision_mean_n", 8), config.get_or("precision_mean_d", 1), config.get_or("special_p_mean_n", 1), config.get_or("special_p_mean_d", 64), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_unsigned_n", 32), config.get_or("mean_small_unsigned_d", 1), ) }, )) } pub fn random_primitive_float_unsigned_pair_gen_var_3( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { special_random_positive_finite_primitive_floats( seed, config.get_or("exponent_mean_n", 8), config.get_or("exponent_mean_d", 1), config.get_or("precision_mean_n", 8), config.get_or("precision_mean_d", 1), ) }, &|seed| { geometric_random_positive_unsigneds( seed, config.get_or("mean_small_unsigned_n", 32), config.get_or("mean_small_unsigned_d", 1), ) }, )) } pub fn random_primitive_float_unsigned_pair_gen_var_4( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { special_random_primitive_floats( seed, config.get_or("exponent_mean_n", 8), config.get_or("exponent_mean_d", 1), config.get_or("precision_mean_n", 8), config.get_or("precision_mean_d", 1), config.get_or("special_p_mean_n", 1), config.get_or("special_p_mean_d", 64), ) }, &|seed| { geometric_random_positive_unsigneds( seed, config.get_or("mean_small_unsigned_n", 32), config.get_or("mean_small_unsigned_d", 1), ) }, )) } // -- (PrimitiveFloat, PrimitiveUnsigned, RoundingMode) -- pub fn random_primitive_float_unsigned_rounding_mode_triple_gen_var_1< T: PrimitiveFloat, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(T, U, RoundingMode)> { Box::new(random_triples( EXAMPLE_SEED, &|seed| { special_random_positive_finite_primitive_floats( seed, config.get_or("exponent_mean_n", 8), config.get_or("exponent_mean_d", 1), config.get_or("precision_mean_n", 8), config.get_or("precision_mean_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_signed_n", 32), config.get_or("mean_small_signed_d", 1), ) }, &random_rounding_modes, )) } pub fn random_primitive_float_unsigned_rounding_mode_triple_gen_var_2( config: &GenConfig, ) -> It<(T, u64, RoundingMode)> { Box::new(random_triples( EXAMPLE_SEED, &|seed| { special_random_primitive_float_range( seed, T::ONE, T::TWO, config.get_or("exponent_mean_n", 8), config.get_or("exponent_mean_d", 1), config.get_or("precision_mean_n", 8), config.get_or("precision_mean_d", 1), config.get_or("special_p_mean_n", 1), config.get_or("special_p_mean_d", 64), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_signed_n", 32), config.get_or("mean_small_signed_d", 1), ) }, &random_rounding_modes, )) } // var 3 is in malachite-float. // -- (PrimitiveFloat, RoundingMode) -- pub fn random_primitive_float_rounding_mode_pair_gen_var_1( config: &GenConfig, ) -> It<(T, RoundingMode)> { Box::new( random_pairs( EXAMPLE_SEED, &|seed| { special_random_finite_primitive_floats( seed, config.get_or("exponent_mean_n", 8), config.get_or("exponent_mean_d", 1), config.get_or("precision_mean_n", 8), config.get_or("precision_mean_d", 1), config.get_or("special_p_mean_n", 1), config.get_or("special_p_mean_d", 64), ) }, &random_rounding_modes, ) .filter(float_rounding_mode_filter_var_1), ) } pub fn random_primitive_float_rounding_mode_pair_gen_var_2( config: &GenConfig, ) -> It<(T, RoundingMode)> { Box::new( random_pairs( EXAMPLE_SEED, &|seed| { special_random_finite_primitive_floats::( seed, config.get_or("exponent_mean_n", 8), config.get_or("exponent_mean_d", 1), config.get_or("precision_mean_n", 8), config.get_or("precision_mean_d", 1), config.get_or("special_p_mean_n", 1), config.get_or("special_p_mean_d", 64), ) }, &random_rounding_modes, ) .filter(|&(f, rm)| rm != Exact || f.is_integer()), ) } pub fn random_primitive_float_rounding_mode_pair_gen_var_3< T: PrimitiveFloat + RoundingFrom, U: ConvertibleFrom + PrimitiveInt, >( config: &GenConfig, ) -> It<(T, RoundingMode)> { let f_min = T::rounding_from(U::MIN, Down).0; let f_max = T::rounding_from(U::MAX, Down).0; Box::new( random_pairs( EXAMPLE_SEED, &|seed| { special_random_primitive_floats::( seed, config.get_or("exponent_mean_n", 8), config.get_or("exponent_mean_d", 1), config.get_or("precision_mean_n", 8), config.get_or("precision_mean_d", 1), config.get_or("special_p_mean_n", 1), config.get_or("special_p_mean_d", 64), ) .filter(|f| !f.is_nan()) }, &random_rounding_modes, ) .filter(move |&(f, rm)| match rm { Up => f >= f_min && f <= f_max, Ceiling => f <= f_max, Floor => f >= f_min, Down | Nearest => true, Exact => U::convertible_from(f), }), ) } // -- PrimitiveInt -- pub fn random_primitive_int_gen(_config: &GenConfig) -> It { Box::new(random_primitive_ints(EXAMPLE_SEED)) } pub fn random_primitive_int_gen_var_1< T: PrimitiveInt + RoundingFrom, U: PrimitiveFloat + RoundingFrom, >( config: &GenConfig, ) -> It { Box::new( special_random_primitive_float_range( EXAMPLE_SEED, U::rounding_from(T::MIN, Down).0, U::rounding_from(T::MAX, Down).0, config.get_or("exponent_mean_n", 8), config.get_or("exponent_mean_d", 1), config.get_or("precision_mean_n", 8), config.get_or("precision_mean_d", 1), config.get_or("special_p_mean_n", 1), config.get_or("special_p_mean_d", 64), ) .map(|f| T::rounding_from(f, Down).0), ) } // -- (PrimitiveInt, PrimitiveInt) -- pub fn random_primitive_int_pair_gen( _config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &random_primitive_ints, &random_primitive_ints, )) } pub fn random_primitive_int_pair_gen_var_1(_config: &GenConfig) -> It<(T, T)> { Box::new(random_pairs_from_single(random_primitive_ints( EXAMPLE_SEED, ))) } // TODO make better pub fn random_primitive_int_pair_gen_var_2(_config: &GenConfig) -> It<(T, T)> { Box::new( random_pairs_from_single(random_primitive_ints(EXAMPLE_SEED)).map(|(x, y)| { if x <= y { (x, y) } else { (y, x) } }), ) } pub fn random_primitive_int_pair_gen_var_3(_config: &GenConfig) -> It<(T, T)> { Box::new(random_ordered_unique_pairs(random_primitive_ints::( EXAMPLE_SEED, ))) } // -- (PrimitiveInt, PrimitiveInt, PrimitiveInt) -- pub fn random_primitive_int_triple_gen_var_1( _config: &GenConfig, ) -> It<(T, T, T)> { Box::new( random_triples_from_single(random_primitive_ints::(EXAMPLE_SEED)) .filter(|&(x, y, m)| !x.eq_mod(y, m)), ) } // Returns (highest, second-highest) pub fn get_two_highest(xs: &[T]) -> (&T, &T) { assert!(xs.len() > 1); let (mut hi, mut next_hi) = (&xs[0], &xs[1]); if hi < next_hi { swap(&mut hi, &mut next_hi); } for x in &xs[2..] { if x > next_hi { if x > hi { hi = x; next_hi = hi; } else { next_hi = x; } } } (hi, next_hi) } pub fn random_primitive_int_triple_gen_var_2( _config: &GenConfig, ) -> It<(T, T, T)> { Box::new( random_triples_from_single(random_primitive_ints::(EXAMPLE_SEED)).filter_map( |(x, y, z)| { let ranking = [(x, 0), (y, 1), (z, 2)]; let (hi, next_hi) = get_two_highest(&ranking); if hi.0 == next_hi.0 { None } else { Some(match hi.1 { 0 => (y, z, x), 1 => (x, z, y), _ => (x, y, z), }) } }, ), ) } pub fn random_primitive_int_triple_gen_var_3( _config: &GenConfig, ) -> It<(T, U, T)> { Box::new( random_triples_xyx(EXAMPLE_SEED, &random_primitive_ints, &random_primitive_ints) .filter_map(|(x, y, z): (T, U, T)| match x.cmp(&z) { Equal => None, Less => Some((x, y, z)), Greater => Some((z, y, x)), }), ) } pub fn random_primitive_int_triple_gen_var_4( _config: &GenConfig, ) -> It<(T, T, T)> { Box::new(random_triples_from_single(random_primitive_ints( EXAMPLE_SEED, ))) } // -- (PrimitiveInt, PrimitiveInt, PrimitiveInt, PrimitiveInt) -- pub fn random_primitive_int_quadruple_gen_var_1( _config: &GenConfig, ) -> It<(T, T, T, T)> { Box::new( random_quadruples_from_single(random_primitive_ints::(EXAMPLE_SEED)).filter_map( |(x, y, z, w)| { let ranking = [(x, 0), (y, 1), (z, 2), (w, 3)]; let (hi, next_hi) = get_two_highest(&ranking); if hi.0 == next_hi.0 { None } else { Some(match hi.1 { 0 => (y, z, w, x), 1 => (x, z, w, y), 2 => (x, y, w, z), _ => (x, y, z, w), }) } }, ), ) } pub fn random_primitive_int_quadruple_gen_var_2( _config: &GenConfig, ) -> It<(T, T, U, T)> { Box::new( random_quadruples_xxyx( EXAMPLE_SEED, &random_primitive_ints::, &random_primitive_ints::, ) .filter_map(|(x, y, z, w)| { let ranking = [(x, 0), (y, 1), (w, 2)]; let (hi, next_hi) = get_two_highest(&ranking); if hi.0 == next_hi.0 { None } else { Some(match hi.1 { 0 => (y, w, z, x), 1 => (x, w, z, y), _ => (x, y, z, w), }) } }), ) } pub fn random_primitive_int_quadruple_gen_var_3( _config: &GenConfig, ) -> It<(T, U, U, T)> { Box::new( random_quadruples_xyyx( EXAMPLE_SEED, &random_primitive_ints::, &random_primitive_ints::, ) .filter_map(|(x, y, z, w)| match x.cmp(&w) { Equal => None, Less => Some((x, y, z, w)), Greater => Some((w, y, z, x)), }), ) } pub fn random_primitive_int_quadruple_gen_var_4( _config: &GenConfig, ) -> It<(T, T, T, T)> { Box::new(random_quadruples_from_single(random_primitive_ints( EXAMPLE_SEED, ))) } pub fn random_primitive_int_quadruple_gen_var_5( _config: &GenConfig, ) -> It<(T, T, T, T)> { Box::new( random_quadruples_from_single(random_primitive_ints(EXAMPLE_SEED)).filter( |&(n1, n0, d1, d0)| { // conditions: D >= 2^W, N >= D, and N / D < 2^W d1 != T::ZERO && (n1 > d1 || n1 == d1 && n0 >= d0) }, ), ) } // -- (PrimitiveInt * 6) -- pub fn random_primitive_int_sextuple_gen_var_1( _config: &GenConfig, ) -> It<(T, T, T, T, T, T)> { Box::new(random_sextuples_from_single(random_primitive_ints( EXAMPLE_SEED, ))) } // -- (PrimitiveInt * 8) -- #[allow(clippy::type_complexity)] pub fn random_primitive_int_octuple_gen_var_1( _config: &GenConfig, ) -> It<(T, T, T, T, T, T, T, T)> { Box::new(random_octuples_from_single(random_primitive_ints( EXAMPLE_SEED, ))) } // -- (PrimitiveInt * 9) -- #[allow(clippy::type_complexity)] pub fn random_primitive_int_nonuple_gen_var_1( _config: &GenConfig, ) -> It<(T, T, T, T, T, T, T, T, T)> { Box::new( random_triples_from_single(random_triples_from_single(random_primitive_ints( EXAMPLE_SEED, ))) .map(|((a, b, c), (d, e, f), (g, h, i))| (a, b, c, d, e, f, g, h, i)), ) } // -- (PrimitiveInt * 12) -- #[allow(clippy::type_complexity)] pub fn random_primitive_int_duodecuple_gen_var_1( _config: &GenConfig, ) -> It<(T, T, T, T, T, T, T, T, T, T, T, T)> { Box::new(random_duodecuples_from_single(random_primitive_ints( EXAMPLE_SEED, ))) } // -- (PrimitiveInt, PrimitiveInt, PrimitiveUnsigned) -- pub fn random_primitive_int_primitive_int_unsigned_triple_gen_var_1< T: PrimitiveInt, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(T, T, U)> { Box::new(random_triples_xxy( EXAMPLE_SEED, &random_primitive_ints, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, )) } pub fn random_primitive_int_primitive_int_unsigned_triple_gen_var_2< T: PrimitiveInt, U: PrimitiveInt, V: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(T, U, V)> { Box::new(random_triples( EXAMPLE_SEED, &random_primitive_ints, &random_primitive_ints, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, )) } pub fn random_primitive_int_primitive_int_unsigned_triple_gen_var_3( config: &GenConfig, ) -> It<(T, T, u64)> { Box::new( random_triples_xxy(EXAMPLE_SEED, &random_primitive_ints::, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }) .filter(|&(x, y, pow)| !x.eq_mod_power_of_2(y, pow)), ) } // -- (PrimitiveInt, PrimitiveInt, PrimitiveInt, PrimitiveUnsigned) -- pub fn random_primitive_int_primitive_int_primitive_int_unsigned_quadruple_gen_var_1< T: PrimitiveInt, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(T, T, T, U)> { Box::new(random_quadruples_xxxy( EXAMPLE_SEED, &random_primitive_ints, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, )) } // -- (PrimitiveInt, PrimitiveSigned) -- pub fn random_primitive_int_signed_pair_gen_var_1( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &random_primitive_ints, &|seed| { geometric_random_signeds( seed, config.get_or("mean_small_signed_n", 32), config.get_or("mean_small_signed_d", 1), ) }, )) } // -- (PrimitiveInt, PrimitiveSigned, PrimitiveInt) -- pub fn random_primitive_int_signed_primitive_int_triple_gen_var_1< T: PrimitiveInt, U: PrimitiveSigned, >( _config: &GenConfig, ) -> It<(T, U, T)> { Box::new( random_triples_xyx(EXAMPLE_SEED, &random_primitive_ints, &|seed| { random_signed_inclusive_range( seed, if U::WIDTH <= u64::WIDTH { U::MIN } else { -U::exact_from(u64::MAX) }, U::saturating_from(u64::MAX), ) }) .filter_map(|(x, y, z): (T, U, T)| match x.cmp(&z) { Equal => None, Less => Some((x, y, z)), Greater => Some((z, y, x)), }), ) } // -- (PrimitiveInt, PrimitiveSigned, RoundingMode) -- pub fn random_primitive_int_signed_rounding_mode_triple_gen_var_1< T: PrimitiveInt, U: PrimitiveSigned, >( config: &GenConfig, ) -> It<(T, U, RoundingMode)> { Box::new( random_triples( EXAMPLE_SEED, &random_primitive_ints::, &|seed| { geometric_random_signeds::( seed, config.get_or("mean_shift_n", 4), config.get_or("mean_shift_d", 1), ) }, &random_rounding_modes, ) .filter(|&(x, pow, rm)| { rm != Exact || pow <= U::ZERO || x.divisible_by_power_of_2(pow.exact_into()) }), ) } pub fn random_primitive_int_signed_rounding_mode_triple_gen_var_2< T: PrimitiveInt, U: PrimitiveSigned, >( config: &GenConfig, ) -> It<(T, U, RoundingMode)> { Box::new( random_triples( EXAMPLE_SEED, &random_primitive_ints::, &|seed| { geometric_random_signeds::( seed, config.get_or("mean_shift_n", 4), config.get_or("mean_shift_d", 1), ) }, &random_rounding_modes, ) .filter(|&(x, pow, rm)| { let pow: i64 = pow.exact_into(); rm != Exact || pow >= 0 || x.divisible_by_power_of_2(pow.unsigned_abs()) }), ) } // -- (PrimitiveInt, PrimitiveUnsigned) -- pub fn random_primitive_int_unsigned_pair_gen_var_1( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &random_primitive_ints, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, )) } pub fn random_primitive_int_unsigned_pair_gen_var_2( _config: &GenConfig, ) -> It<(T, u64)> { Box::new(random_pairs( EXAMPLE_SEED, &random_primitive_ints, &|seed| random_unsigneds_less_than(seed, T::WIDTH), )) } pub fn random_primitive_int_unsigned_pair_gen_var_3( _config: &GenConfig, ) -> It<(T, u64)> { Box::new(random_pairs( EXAMPLE_SEED, &random_primitive_ints, &|seed| random_unsigned_inclusive_range(seed, 1, U::WIDTH), )) } pub fn random_primitive_int_unsigned_pair_gen_var_4< T: PrimitiveInt, U: PrimitiveUnsigned + SaturatingFrom, >( _config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &random_primitive_ints, &|seed| random_unsigned_inclusive_range(seed, U::TWO, U::saturating_from(T::MAX)), )) } pub fn random_primitive_int_unsigned_pair_gen_var_5< T: PrimitiveInt, U: ExactFrom + PrimitiveUnsigned, >( _config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &random_primitive_ints, &|seed| random_unsigned_inclusive_range(seed, U::TWO, U::exact_from(36u8)), )) } pub fn random_primitive_int_unsigned_pair_gen_var_6( config: &GenConfig, ) -> It<(T, U)> { Box::new( random_pairs(EXAMPLE_SEED, &random_primitive_ints::, &|seed| { geometric_random_unsigneds::( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }) .filter(|&(x, y)| !x.divisible_by_power_of_2(y.exact_into())), ) } pub fn random_primitive_int_unsigned_pair_gen_var_7( config: &GenConfig, ) -> It<(T, U)> { Box::new( random_pairs(EXAMPLE_SEED, &random_primitive_ints::, &|seed| { geometric_random_unsigneds::( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }) .map(|(mut x, y)| { x.round_to_multiple_of_power_of_2_assign(y.exact_into(), Down); (x, y) }), ) } pub fn random_primitive_int_unsigned_pair_gen_var_8( _config: &GenConfig, ) -> It<(T, u64)> { Box::new(random_pairs( EXAMPLE_SEED, &random_primitive_ints, &|seed| random_unsigneds_less_than(seed, U::WIDTH + 1), )) } pub fn random_primitive_int_unsigned_pair_gen_var_9( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &random_primitive_ints, &|seed| { geometric_random_positive_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, )) } pub fn random_primitive_int_unsigned_pair_gen_var_10( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &random_primitive_ints, &|seed| { geometric_random_positive_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, )) } // -- (PrimitiveInt, PrimitiveUnsigned, bool) -- pub fn random_primitive_int_unsigned_bool_triple_gen_var_1( config: &GenConfig, ) -> It<(T, u64, bool)> { reshape_1_2_to_3(Box::new(random_pairs( EXAMPLE_SEED, &random_primitive_ints, &|seed| { random_union2s( seed, &|seed_2| { geometric_random_unsigneds( seed_2, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) .map(|x| (x, false)) }, &|seed_2| random_unsigneds_less_than(seed_2, T::WIDTH).map(|x| (x, true)), ) .map(Union2::unwrap) }, ))) } pub fn random_primitive_int_unsigned_bool_triple_gen_var_2( config: &GenConfig, ) -> It<(T, u64, bool)> { Box::new( random_union2s( EXAMPLE_SEED, &|seed| { random_pairs(seed, &random_primitive_ints, &|seed_2| { geometric_random_unsigneds( seed_2, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }) .map(|(x, y)| (x, y, x < T::ZERO)) }, &|seed| { random_pairs(seed, &random_primitive_ints, &|seed_2| { random_unsigneds_less_than(seed_2, T::WIDTH) }) .map(|(x, y)| (x, y, x >= T::ZERO)) }, ) .map(Union2::unwrap), ) } pub fn random_primitive_int_unsigned_bool_triple_gen_var_3< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >( _config: &GenConfig, ) -> It<(T, U, bool)> { Box::new(random_triples( EXAMPLE_SEED, &random_primitive_ints::, &random_positive_unsigneds::, &random_bools, )) } // -- (PrimitiveInt, PrimitiveUnsigned, PrimitiveInt) -- pub fn random_primitive_int_unsigned_primitive_int_triple_gen_var_1< T: PrimitiveInt, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(T, U, T)> { Box::new( random_triples_xyx(EXAMPLE_SEED, &random_primitive_ints, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }) .filter_map(|(x, y, z): (T, U, T)| match x.cmp(&z) { Equal => None, Less => Some((x, y, z)), Greater => Some((z, y, x)), }), ) } pub fn random_primitive_int_unsigned_primitive_int_triple_gen_var_2< T: PrimitiveInt, U: PrimitiveUnsigned, >( _config: &GenConfig, ) -> It<(T, U, T)> { Box::new( random_triples_xyx(EXAMPLE_SEED, &random_primitive_ints, &|seed| { random_unsigned_inclusive_range(seed, U::ZERO, U::saturating_from(u64::MAX)) }) .filter_map(|(x, y, z): (T, U, T)| match x.cmp(&z) { Equal => None, Less => Some((x, y, z)), Greater => Some((z, y, x)), }), ) } pub fn random_primitive_int_unsigned_primitive_int_triple_gen_var_3< T: PrimitiveInt, U: PrimitiveInt, >( _config: &GenConfig, ) -> It<(T, U, T)> { Box::new( random_triples_xyx(EXAMPLE_SEED, &random_primitive_ints, &random_primitive_ints) .filter_map(|(x, y, z): (T, U, T)| match x.cmp(&z) { Equal => None, Less => Some((x, y, z)), Greater => Some((z, y, x)), }), ) } // -- (PrimitiveInt, PrimitiveUnsigned, PrimitiveUnsigned) -- pub fn random_primitive_int_unsigned_unsigned_triple_gen_var_1< T: PrimitiveInt, U: PrimitiveInt, V: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(T, u64, V)> { Box::new(random_triples( EXAMPLE_SEED, &random_primitive_ints, &|seed| random_unsigned_inclusive_range(seed, 1, U::WIDTH), &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, )) } pub fn random_primitive_int_unsigned_unsigned_triple_gen_var_2< T: PrimitiveInt, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(T, U, U)> { Box::new( random_triples_xyy(EXAMPLE_SEED, &random_primitive_ints, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }) .map(|(x, y, z)| if y <= z { (x, y, z) } else { (x, z, y) }), ) } pub fn random_primitive_int_unsigned_unsigned_triple_gen_var_3< T: PrimitiveInt, U: ExactFrom + PrimitiveUnsigned, V: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(T, U, V)> { Box::new(random_triples( EXAMPLE_SEED, &random_primitive_ints, &|seed| random_unsigned_inclusive_range(seed, U::TWO, U::exact_from(36u8)), &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 4), config.get_or("mean_small_d", 1), ) }, )) } pub fn random_primitive_int_unsigned_unsigned_triple_gen_var_4< T: PrimitiveInt, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(T, U, U)> { Box::new(random_triples_xyy( EXAMPLE_SEED, &random_primitive_ints, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, )) } // --(PrimitiveInt, PrimitiveUnsigned, PrimitiveUnsigned, PrimitiveUnsigned) -- pub fn random_primitive_int_unsigned_unsigned_unsigned_quadruple_gen_var_1< T: PrimitiveInt, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(T, u64, u64, U)> { Box::new( random_quadruples_xyyz( EXAMPLE_SEED, &random_primitive_ints, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, &random_primitive_ints, ) .filter_map(|(x, y, z, w)| { let (y, z) = if y <= z { (y, z) } else { (z, y) }; if unsigned_assign_bits_valid(y, z, w) { Some((x, y, z, w)) } else { None } }), ) } // --(PrimitiveInt, PrimitiveUnsigned, RoundingMode) -- pub fn random_primitive_int_unsigned_rounding_mode_triple_gen_var_1( config: &GenConfig, ) -> It<(T, u64, RoundingMode)> { Box::new( random_triples( EXAMPLE_SEED, &random_primitive_ints, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_shift_n", 4), config.get_or("mean_shift_d", 1), ) }, &random_rounding_modes, ) .filter_map(|(x, pow, rm)| round_to_multiple_of_power_of_2_filter_map(x, pow, rm)), ) } pub fn random_primitive_int_unsigned_rounding_mode_triple_gen_var_2< T: PrimitiveInt, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(T, U, RoundingMode)> { Box::new( random_triples( EXAMPLE_SEED, &random_primitive_ints::, &|seed| { geometric_random_unsigneds::( seed, config.get_or("mean_shift_n", 4), config.get_or("mean_shift_d", 1), ) }, &random_rounding_modes, ) .filter(|&(x, y, rm)| rm != Exact || x.divisible_by_power_of_2(y.exact_into())), ) } // --(PrimitiveInt, PrimitiveUnsigned, Vec) -- struct PrimitiveIntUnsignedBoolVecTripleGeneratorVar1 { xs: RandomPrimitiveInts, log_bases: RandomUnsignedInclusiveRange, bs: RandomBools, } impl Iterator for PrimitiveIntUnsignedBoolVecTripleGeneratorVar1 { type Item = (T, u64, Vec); fn next(&mut self) -> Option<(T, u64, Vec)> { let x = self.xs.next().unwrap(); let log_base = self.log_bases.next().unwrap(); let bs = (&mut self.bs) .take(usize::exact_from( x.significant_bits().div_round(log_base, Ceiling).0, )) .collect(); Some((x, log_base, bs)) } } pub fn random_primitive_int_unsigned_bool_vec_triple_gen_var_1( _config: &GenConfig, ) -> It<(T, u64, Vec)> { Box::new(PrimitiveIntUnsignedBoolVecTripleGeneratorVar1 { xs: random_primitive_ints(EXAMPLE_SEED.fork("xs")), log_bases: random_unsigned_inclusive_range(EXAMPLE_SEED.fork("log_bases"), 1, U::WIDTH), bs: random_bools(EXAMPLE_SEED.fork("bs")), }) } // -- (PrimitiveInt, RoundingMode) -- pub fn random_primitive_int_rounding_mode_pair_gen( _config: &GenConfig, ) -> It<(T, RoundingMode)> { Box::new(random_pairs( EXAMPLE_SEED, &random_primitive_ints, &random_rounding_modes, )) } pub fn random_primitive_int_rounding_mode_pair_gen_var_1< T: PrimitiveInt, U: ConvertibleFrom + PrimitiveFloat, >( _config: &GenConfig, ) -> It<(T, RoundingMode)> { Box::new( random_pairs(EXAMPLE_SEED, &random_primitive_ints, &random_rounding_modes) .filter(move |&(n, rm)| rm != Exact || U::convertible_from(n)), ) } // -- (PrimitiveInt, ToSciOptions) -- pub fn random_primitive_int_to_sci_options_pair_gen( config: &GenConfig, ) -> It<(T, ToSciOptions)> { Box::new(random_pairs( EXAMPLE_SEED, &random_primitive_ints, &|seed| { random_to_sci_options( seed, config.get_or("mean_size_n", 32), config.get_or("mean_size_d", 1), ) }, )) } pub fn random_primitive_int_to_sci_options_pair_gen_var_1( config: &GenConfig, ) -> It<(T, ToSciOptions)> { Box::new( random_pairs(EXAMPLE_SEED, &random_primitive_ints::, &|seed| { random_to_sci_options( seed, config.get_or("mean_size_n", 32), config.get_or("mean_size_d", 1), ) }) .filter(|(x, options)| x.fmt_sci_valid(*options)), ) } // -- PrimitiveSigned -- pub fn random_signed_gen_var_1(_config: &GenConfig) -> It { Box::new(random_primitive_ints(EXAMPLE_SEED).filter(|&x| x != T::MIN)) } pub fn random_signed_gen_var_2(_config: &GenConfig) -> It { Box::new(random_natural_signeds(EXAMPLE_SEED)) } pub fn random_signed_gen_var_3(_config: &GenConfig) -> It { Box::new(random_primitive_ints(EXAMPLE_SEED).filter(|&x| x != T::ZERO && x != T::NEGATIVE_ONE)) } pub fn random_signed_gen_var_4(_config: &GenConfig) -> It { Box::new(random_negative_signeds(EXAMPLE_SEED)) } pub fn random_signed_gen_var_5(config: &GenConfig) -> It { Box::new(geometric_random_signeds( EXAMPLE_SEED, config.get_or("mean_small_signed_n", 32), config.get_or("mean_small_signed_d", 1), )) } pub fn random_signed_gen_var_6(_config: &GenConfig) -> It { Box::new(random_nonzero_signeds(EXAMPLE_SEED)) } pub fn random_signed_gen_var_7 + PrimitiveFloat>( _config: &GenConfig, ) -> It { Box::new( random_union2s( EXAMPLE_SEED, &|seed| { random_signed_inclusive_range( seed, T::saturating_from(U::SMALLEST_UNREPRESENTABLE_UINT), T::MAX, ) }, &|seed| { random_signed_inclusive_range( seed, T::MIN, T::saturating_from(U::SMALLEST_UNREPRESENTABLE_UINT).saturating_neg(), ) }, ) .map(Union2::unwrap) .filter(|&x| !U::convertible_from(x)), ) } pub fn random_signed_gen_var_8< T: TryFrom> + PrimitiveSigned, U: PrimitiveFloat + RoundingFrom, >( _config: &GenConfig, ) -> It { Box::new( random_union2s( EXAMPLE_SEED, &|seed| { random_signed_inclusive_range( seed, T::exact_from(U::SMALLEST_UNREPRESENTABLE_UINT), T::MAX, ) .filter_map(|a| { let f = U::rounding_from(a, Down).0; let a = T::try_from(NiceFloat(f)).ok()?; let b = T::try_from(NiceFloat(f.next_higher())).ok()?; let diff = b - a; if diff.even() { // This happens almost always Some(a + (diff >> 1)) } else { None } }) }, &|seed| { random_signed_inclusive_range( seed, T::MIN, T::exact_from(U::SMALLEST_UNREPRESENTABLE_UINT) .checked_neg() .unwrap(), ) .filter_map(|a| { let f = U::rounding_from(a, Down).0; let a = T::try_from(NiceFloat(f)).ok()?; let b = T::try_from(NiceFloat(f.next_lower())).ok()?; let diff = a - b; if diff.even() { // This happens almost always Some(a - (diff >> 1)) } else { None } }) }, ) .map(Union2::unwrap), ) } pub fn random_signed_gen_var_9< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >( _config: &GenConfig, ) -> It { let limit = S::wrapping_from(U::wrapping_from(S::MAX).floor_sqrt()); Box::new(random_signed_inclusive_range(EXAMPLE_SEED, -limit, limit)) } pub fn random_signed_gen_var_10(_config: &GenConfig) -> It { Box::new(random_signed_inclusive_range( EXAMPLE_SEED, T::MIN_EXPONENT, T::MAX_EXPONENT, )) } pub fn random_signed_gen_var_11(_config: &GenConfig) -> It { Box::new(random_primitive_ints(EXAMPLE_SEED).filter(|&x| x != T::ZERO && x != T::MIN)) } pub fn random_signed_gen_var_12(_config: &GenConfig) -> It { Box::new( random_signed_inclusive_range(EXAMPLE_SEED, T::ZERO, T::low_mask(T::WIDTH - 2)) .map(|u| (u << 1) | T::ONE), ) } // -- (PrimitiveSigned, PrimitiveSigned) -- pub fn random_signed_pair_gen_var_1(_config: &GenConfig) -> It<(T, T)> { Box::new( random_union2s( EXAMPLE_SEED, &|seed| random_pairs_from_single(random_natural_signeds(seed)), &|seed| random_pairs_from_single(random_negative_signeds(seed)), ) .map(Union2::unwrap), ) } pub fn random_signed_pair_gen_var_2(_config: &GenConfig) -> It<(T, T)> { Box::new( random_pairs( EXAMPLE_SEED, &random_primitive_ints::, &random_nonzero_signeds::, ) .filter_map(|(mut x, y)| { x.round_to_multiple_assign(y, Down); if x == T::MIN && y == T::NEGATIVE_ONE { None } else { Some((x, y)) } }), ) } pub fn random_signed_pair_gen_var_3(_config: &GenConfig) -> It<(T, T)> { Box::new( random_pairs( EXAMPLE_SEED, &random_primitive_ints::, &random_nonzero_signeds::, ) .filter(|&(x, y)| x != T::MIN || y != T::NEGATIVE_ONE), ) } pub fn random_signed_pair_gen_var_4(_config: &GenConfig) -> It<(T, T)> { Box::new( random_pairs( EXAMPLE_SEED, &random_primitive_ints::, &random_nonzero_signeds::, ) .filter(|&(x, y)| !x.divisible_by(y)), ) } pub fn random_signed_pair_gen_var_5(_config: &GenConfig) -> It<(T, T)> { Box::new(random_pairs( EXAMPLE_SEED, &random_primitive_ints::, &random_nonzero_signeds::, )) } pub fn random_signed_pair_gen_var_6(_config: &GenConfig) -> It<(T, T)> { Box::new(random_pairs_from_single(random_natural_signeds::( EXAMPLE_SEED, ))) } pub fn random_signed_pair_gen_var_7(_config: &GenConfig) -> It<(T, T)> { Box::new(random_pairs( EXAMPLE_SEED, &random_primitive_ints, &|seed| { random_signed_inclusive_range(seed, T::ZERO, T::low_mask(T::WIDTH - 2)) .map(|u| (u << 1) | T::ONE) }, )) } pub fn random_signed_pair_gen_var_8(_config: &GenConfig) -> It<(T, T)> where ::Output: PrimitiveUnsigned, { Box::new( random_pairs_from_single( random_signed_inclusive_range(EXAMPLE_SEED, T::ZERO, T::low_mask(T::WIDTH - 2)) .map(|u| (u << 1) | T::ONE), ) .filter(|&(a, b): &(T, T)| a.unsigned_abs().coprime_with(b.unsigned_abs())), ) } pub fn random_signed_pair_gen_var_9< U: PrimitiveUnsigned, S: PrimitiveSigned + UnsignedAbs, >( _config: &GenConfig, ) -> It<(S, S)> { Box::new( random_pairs_from_single(random_primitive_ints(EXAMPLE_SEED)) .filter(|&(x, y): &(S, S)| x.unsigned_abs().coprime_with(y.unsigned_abs())), ) } pub fn random_signed_pair_gen_var_10( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { geometric_random_signeds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, &|seed| { geometric_random_signeds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, )) } pub fn random_signed_pair_gen_var_11(config: &GenConfig) -> It<(T, T)> { Box::new( random_pairs_from_single(geometric_random_signeds( EXAMPLE_SEED, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), )) .filter(|&(n, k)| T::checked_binomial_coefficient(n, k).is_some()), ) } // -- (PrimitiveSigned, PrimitiveSigned, PrimitiveSigned) -- fn halve_bits(x: T) -> T { let half_width = (T::WIDTH >> 1) - 1; let half_mask = T::low_mask(half_width); if x >= T::ZERO { x & half_mask } else { x | (T::NEGATIVE_ONE << half_width) } } pub(crate) fn reduce_to_fit_add_mul_signed(x: T, y: T, z: T) -> (T, T, T) { if x.checked_add_mul(y, z).is_some() { (x, y, z) } else { (halve_bits(x), halve_bits(y), halve_bits(z)) } } pub fn random_signed_triple_gen_var_1(_config: &GenConfig) -> It<(T, T, T)> { Box::new( random_triples_from_single(random_primitive_ints(EXAMPLE_SEED)) .map(|(x, y, z)| reduce_to_fit_add_mul_signed(x, y, z)), ) } pub(crate) fn reduce_to_fit_sub_mul_signed(x: T, y: T, z: T) -> (T, T, T) { if x.checked_sub_mul(y, z).is_some() { (x, y, z) } else { (halve_bits(x), halve_bits(y), halve_bits(z)) } } pub fn random_signed_triple_gen_var_2(_config: &GenConfig) -> It<(T, T, T)> { Box::new( random_triples_from_single(random_primitive_ints(EXAMPLE_SEED)) .map(|(x, y, z)| reduce_to_fit_sub_mul_signed(x, y, z)), ) } pub fn random_signed_triple_gen_var_3(_config: &GenConfig) -> It<(T, T, T)> { Box::new( random_union2s( EXAMPLE_SEED, &|seed| random_triples_from_single(random_natural_signeds(seed)), &|seed| random_triples_from_single(random_negative_signeds(seed)), ) .map(Union2::unwrap), ) } pub fn random_signed_triple_gen_var_4< U: PrimitiveUnsigned + WrappingFrom + WrappingInto, S: PrimitiveSigned + UnsignedAbs, >( _config: &GenConfig, ) -> It<(S, S, S)> { Box::new( random_triples_from_single(random_primitive_ints::(EXAMPLE_SEED)).map(|(x, y, m)| { if m == S::ZERO { let min = min(x, y); (min, min, m) } else if x <= y { let adjusted_diff = U::wrapping_from(y.wrapping_sub(x)) .round_to_multiple(m.unsigned_abs(), Down) .0; ( x, (U::wrapping_from(x).wrapping_add(adjusted_diff)).wrapping_into(), m, ) } else { let adjusted_diff = U::wrapping_from(x.wrapping_sub(y)) .round_to_multiple(m.unsigned_abs(), Down) .0; ( (U::wrapping_from(y).wrapping_add(adjusted_diff)).wrapping_into(), y, m, ) } }), ) } pub fn random_signed_triple_gen_var_5(_config: &GenConfig) -> It<(T, T, T)> { Box::new(random_triples_xxy( EXAMPLE_SEED, &random_primitive_ints, &|seed| { random_signed_inclusive_range(seed, T::ZERO, T::low_mask(T::WIDTH - 2)) .map(|u| (u << 1) | T::ONE) }, )) } pub fn random_signed_triple_gen_var_6(_config: &GenConfig) -> It<(T, T, T)> { Box::new(random_triples_xyy( EXAMPLE_SEED, &random_primitive_ints, &|seed| { random_signed_inclusive_range(seed, T::ZERO, T::low_mask(T::WIDTH - 2)) .map(|u| (u << 1) | T::ONE) }, )) } // -- (PrimitiveSigned, PrimitiveSigned, PrimitiveUnsigned) -- pub fn random_signed_signed_unsigned_triple_gen_var_1< U: PrimitiveUnsigned + WrappingFrom + WrappingInto, S: PrimitiveSigned, >( config: &GenConfig, ) -> It<(S, S, u64)> { Box::new( random_triples_xxy(EXAMPLE_SEED, &random_primitive_ints::, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_pow_n", 32), config.get_or("mean_pow_d", 1), ) }) .map(|(x, y, pow)| { if pow >= S::WIDTH { (x, x, pow) } else if x <= y { let adjusted_diff = U::wrapping_from(y.wrapping_sub(x)) .round_to_multiple_of_power_of_2(pow, Down) .0; ( x, (U::wrapping_from(x).wrapping_add(adjusted_diff)).wrapping_into(), pow, ) } else { let adjusted_diff = U::wrapping_from(x.wrapping_sub(y)) .round_to_multiple_of_power_of_2(pow, Down) .0; ( (U::wrapping_from(y).wrapping_add(adjusted_diff)).wrapping_into(), y, pow, ) } }), ) } pub fn random_signed_signed_unsigned_triple_gen_var_2< T: PrimitiveSigned, U: PrimitiveSigned, V: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(T, U, V)> { Box::new(random_triples( EXAMPLE_SEED, &random_primitive_ints, &|seed| { geometric_random_signeds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, &|seed| { geometric_random_positive_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, )) } // -- (PrimitiveSigned, PrimitiveSigned, RoundingMode) -- struct SignedSignedRoundingModeTripleGenerator { xs: RandomPrimitiveInts, rms: RandomRoundingModes, } impl Iterator for SignedSignedRoundingModeTripleGenerator { type Item = (T, T, RoundingMode); fn next(&mut self) -> Option<(T, T, RoundingMode)> { let mut x; let mut y; loop { x = self.xs.next().unwrap(); loop { y = self.xs.next().unwrap(); if y != T::ZERO { break; } } if x != T::MIN || y != T::NEGATIVE_ONE { break; } } let rm = self.rms.next().unwrap(); if rm == Exact { x.round_to_multiple_assign(y, Down); } Some((x, y, rm)) } } pub fn random_signed_signed_rounding_mode_triple_gen_var_1( _config: &GenConfig, ) -> It<(T, T, RoundingMode)> { Box::new(SignedSignedRoundingModeTripleGenerator { xs: random_primitive_ints(EXAMPLE_SEED.fork("xs")), rms: random_rounding_modes(EXAMPLE_SEED.fork("rms")), }) } pub fn random_signed_signed_rounding_mode_triple_gen_var_2< U: PrimitiveUnsigned, S: TryFrom + ConvertibleFrom + PrimitiveSigned + UnsignedAbs, >( _config: &GenConfig, ) -> It<(S, S, RoundingMode)> { Box::new( random_triples( EXAMPLE_SEED, &random_primitive_ints, &random_nonzero_signeds, &random_rounding_modes, ) .filter_map(|(x, y, rm)| round_to_multiple_signed_filter_map(x, y, rm)), ) } // -- (PrimitiveSigned, PrimitiveUnsigned) -- pub fn random_signed_unsigned_pair_gen_var_1( config: &GenConfig, ) -> It<(T, u64)> { Box::new( random_union2s( EXAMPLE_SEED, &|seed| { random_pairs(seed, &random_natural_signeds, &|seed_2| { random_unsigned_range(seed_2, 0, T::WIDTH) }) }, &|seed| { random_pairs(seed, &random_negative_signeds, &|seed_2| { geometric_random_unsigneds( seed_2, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }) }, ) .map(Union2::unwrap), ) } pub fn random_signed_unsigned_pair_gen_var_2( config: &GenConfig, ) -> It<(T, u64)> { Box::new( random_union2s( EXAMPLE_SEED, &|seed| { random_pairs(seed, &random_negative_signeds, &|seed_2| { random_unsigned_range(seed_2, 0, T::WIDTH) }) }, &|seed| { random_pairs(seed, &random_natural_signeds, &|seed_2| { geometric_random_unsigneds( seed_2, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }) }, ) .map(Union2::unwrap), ) } pub fn random_signed_unsigned_pair_gen_var_3( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &random_natural_signeds, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, )) } pub fn random_signed_unsigned_pair_gen_var_4< T: PrimitiveSigned, U: ExactFrom + PrimitiveUnsigned, >( _config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &random_natural_signeds, &|seed| random_unsigned_inclusive_range(seed, U::TWO, U::exact_from(36u8)), )) } pub fn random_signed_unsigned_pair_gen_var_5( config: &GenConfig, ) -> It<(T, u64)> { Box::new( random_union2s( EXAMPLE_SEED, &|seed| { random_pairs(seed, &random_natural_signeds, &|seed_2| { geometric_random_unsigneds( seed_2, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }) }, &|seed| { random_pairs(seed, &random_primitive_ints, &|seed_2| { random_unsigned_inclusive_range(seed_2, 0, T::WIDTH) }) }, ) .map(Union2::unwrap), ) } pub fn random_signed_unsigned_pair_gen_var_6( config: &GenConfig, ) -> It<(T, u64)> { Box::new( random_union2s( EXAMPLE_SEED, &|seed| { random_pairs( seed, &|seed_2| random_signed_range(seed_2, T::MIN + T::ONE, T::ONE), &|seed_2| { geometric_random_unsigneds( seed_2, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, ) }, &|seed| { random_pairs(seed, &random_primitive_ints, &|seed_2| { random_unsigned_range(seed_2, 0, T::WIDTH) }) }, ) .map(Union2::unwrap), ) } pub fn random_signed_unsigned_pair_gen_var_7( _config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { random_signed_inclusive_range( seed, if T::WIDTH <= u64::WIDTH { T::MIN } else { -T::exact_from(u64::MAX) }, T::saturating_from(u64::MAX), ) }, &random_positive_unsigneds, )) } pub fn random_signed_unsigned_pair_gen_var_8( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { geometric_random_signeds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, )) } pub fn random_signed_unsigned_pair_gen_var_9( config: &GenConfig, ) -> It<(T, u64)> { Box::new( random_pairs( EXAMPLE_SEED, &|seed| { geometric_random_signeds::( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, ) .filter(|&(x, y)| x.checked_pow(y).is_some()), ) } pub fn random_signed_unsigned_pair_gen_var_10( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &random_positive_signeds, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, )) } pub fn random_signed_unsigned_pair_gen_var_11( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| random_signed_range(seed, T::MIN + T::ONE, T::ZERO), &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, )) } pub fn random_signed_unsigned_pair_gen_var_12( config: &GenConfig, ) -> It<(T, U)> { Box::new( random_union2s( EXAMPLE_SEED, &|seed| { random_pairs(seed, &random_natural_signeds, &|seed_2| { geometric_random_positive_unsigneds( seed_2, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }) }, &|seed| { random_pairs(seed, &random_negative_signeds, &|seed_2| { geometric_random_unsigneds::( seed_2, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) .filter_map(|i| i.arithmetic_checked_shl(1).map(|j| j | U::ONE)) }) }, ) .map(Union2::unwrap), ) } pub fn random_signed_unsigned_pair_gen_var_13( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { geometric_random_signeds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, &|seed| { geometric_random_positive_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, )) } // -- (PrimitiveSigned, PrimitiveUnsigned, PrimitiveUnsigned) -- pub fn random_signed_unsigned_unsigned_triple_gen_var_1< T: PrimitiveSigned, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(T, U, U)> { Box::new( random_union2s( EXAMPLE_SEED, &|seed| { random_triples_xyy(seed, &random_positive_signeds, &|seed_2| { geometric_random_unsigneds( seed_2, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }) .map(|(x, y, z)| if y <= z { (x, y, z) } else { (x, z, y) }) }, &|seed| { random_triples( seed, &|seed_2| random_signed_range(seed_2, T::MIN, T::ZERO), &|seed_2| { geometric_random_unsigneds( seed_2, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, &|seed_2| random_unsigned_range(seed_2, U::ZERO, U::exact_from(T::WIDTH)), ) .filter_map(|(x, y, z): (T, U, U)| y.checked_add(z).map(|new_z| (x, y, new_z))) }, ) .map(Union2::unwrap), ) } // -- (PrimitiveSigned, PrimitiveUnsigned, PrimitiveUnsigned, PrimitiveUnsigned) -- pub fn random_signed_unsigned_unsigned_unsigned_quadruple_gen_var_1< T: PrimitiveSigned + UnsignedAbs, U: BitBlockAccess + PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(T, u64, u64, U)> { Box::new( random_quadruples_xyyz( EXAMPLE_SEED, &random_primitive_ints, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, &random_primitive_ints, ) .filter_map(|(x, y, z, w)| { let (y, z) = if y <= z { (y, z) } else { (z, y) }; if signed_assign_bits_valid(x, y, z, w) { Some((x, y, z, w)) } else { None } }), ) } pub fn random_signed_rounding_mode_pair_gen_var_1( _config: &GenConfig, ) -> It<(T, RoundingMode)> { Box::new(random_pairs( EXAMPLE_SEED, &random_nonzero_signeds, &random_rounding_modes, )) } pub fn random_signed_rounding_mode_pair_gen_var_2( _config: &GenConfig, ) -> It<(T, RoundingMode)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| random_signed_inclusive_range(seed, T::MIN + T::ONE, T::MAX), &random_rounding_modes, )) } pub fn random_signed_rounding_mode_pair_gen_var_3( _config: &GenConfig, ) -> It<(T, RoundingMode)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| random_nonzero_signeds(seed).filter(|&x| x != T::MIN), &random_rounding_modes, )) } // --(PrimitiveSigned, Vec) -- struct SignedBoolVecPairGeneratorVar1 { xs: RandomPrimitiveInts, bs: RandomBools, } impl Iterator for SignedBoolVecPairGeneratorVar1 { type Item = (T, Vec); fn next(&mut self) -> Option<(T, Vec)> { let x = self.xs.next().unwrap(); let bs = (&mut self.bs) .take(usize::exact_from(u64::exact_from(x.to_bits_asc().len()))) .collect(); Some((x, bs)) } } pub fn random_signed_bool_vec_pair_gen_var_1( _config: &GenConfig, ) -> It<(T, Vec)> { Box::new(SignedBoolVecPairGeneratorVar1 { xs: random_primitive_ints(EXAMPLE_SEED.fork("xs")), bs: random_bools(EXAMPLE_SEED.fork("bs")), }) } // -- PrimitiveUnsigned -- pub fn random_unsigned_gen_var_1(_config: &GenConfig) -> It { Box::new(random_positive_unsigneds(EXAMPLE_SEED)) } pub fn random_unsigned_gen_var_2(_config: &GenConfig) -> It { Box::new(random_unsigneds_less_than(EXAMPLE_SEED, NUMBER_OF_CHARS)) } pub fn random_unsigned_gen_var_3(_config: &GenConfig) -> It { Box::new(random_unsigned_inclusive_range(EXAMPLE_SEED, 1, T::WIDTH)) } pub fn random_unsigned_gen_var_4>( _config: &GenConfig, ) -> It { Box::new(random_unsigned_inclusive_range( EXAMPLE_SEED, U::TWO, U::saturating_from(T::MAX), )) } pub fn random_unsigned_gen_var_5(config: &GenConfig) -> It { Box::new(geometric_random_unsigneds( EXAMPLE_SEED, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), )) } pub fn random_unsigned_gen_var_6(_config: &GenConfig) -> It { Box::new(random_unsigned_inclusive_range( EXAMPLE_SEED, T::TWO, T::MAX, )) } pub fn random_unsigned_gen_var_7(_config: &GenConfig) -> It { Box::new(random_unsigneds_less_than(EXAMPLE_SEED, T::exact_from(36))) } pub fn random_unsigned_gen_var_8(_config: &GenConfig) -> It { Box::new(random_unsigned_inclusive_range( EXAMPLE_SEED, T::TWO, T::exact_from(36), )) } pub fn random_unsigned_gen_var_9(_config: &GenConfig) -> It { Box::new(random_unsigneds_less_than(EXAMPLE_SEED, T::WIDTH + 1)) } pub fn random_unsigned_gen_var_10(_config: &GenConfig) -> It { Box::new( random_union3s( EXAMPLE_SEED, &|seed| random_unsigned_inclusive_range(seed, b'0', b'9'), &|seed| random_unsigned_inclusive_range(seed, b'a', b'z'), &|seed| random_unsigned_inclusive_range(seed, b'A', b'Z'), ) .map(Union3::unwrap), ) } pub fn random_unsigned_gen_var_11(config: &GenConfig) -> It { Box::new(geometric_random_positive_unsigneds( EXAMPLE_SEED, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), )) } pub fn random_unsigned_gen_var_12(_config: &GenConfig) -> It { Box::new(random_highest_bit_set_unsigneds(EXAMPLE_SEED)) } pub fn random_unsigned_gen_var_13(_config: &GenConfig) -> It { Box::new(random_unsigneds_less_than( EXAMPLE_SEED, T::LARGEST_ORDERED_REPRESENTATION, )) } pub fn random_unsigned_gen_var_14(_config: &GenConfig) -> It { Box::new(random_unsigneds_less_than( EXAMPLE_SEED, T::power_of_2(T::WIDTH - 1) + T::ONE, )) } pub fn random_unsigned_gen_var_15(_config: &GenConfig) -> It { Box::new(random_unsigneds_less_than(EXAMPLE_SEED, T::WIDTH)) } pub fn random_unsigned_gen_var_16(_config: &GenConfig) -> It { Box::new(random_unsigneds_less_than(EXAMPLE_SEED, T::WIDTH - 1)) } pub fn random_unsigned_gen_var_17(_config: &GenConfig) -> It { Box::new(random_unsigned_inclusive_range( EXAMPLE_SEED, T::power_of_2(T::WIDTH - 2), T::MAX, )) } pub fn random_unsigned_gen_var_18 + PrimitiveFloat>( _config: &GenConfig, ) -> It { Box::new( random_unsigned_inclusive_range( EXAMPLE_SEED, T::saturating_from(U::SMALLEST_UNREPRESENTABLE_UINT), T::MAX, ) .filter(|&x| !U::convertible_from(x)), ) } pub fn random_unsigned_gen_var_19< T: TryFrom> + PrimitiveUnsigned, U: PrimitiveFloat + RoundingFrom, >( _config: &GenConfig, ) -> It { Box::new( random_unsigned_inclusive_range( EXAMPLE_SEED, T::exact_from(U::SMALLEST_UNREPRESENTABLE_UINT), T::MAX, ) .filter_map(|a| { let f = U::rounding_from(a, Down).0; let a = T::try_from(NiceFloat(f)).ok()?; let b = T::try_from(NiceFloat(f.next_higher())).ok()?; let diff = b - a; if diff.even() { // This happens almost always Some(a + (diff >> 1)) } else { None } }), ) } pub fn random_unsigned_gen_var_20(_config: &GenConfig) -> It { Box::new(random_unsigned_inclusive_range( EXAMPLE_SEED, T::ZERO, T::MAX.floor_sqrt(), )) } pub fn random_unsigned_gen_var_21(_config: &GenConfig) -> It { Box::new( random_unsigned_inclusive_range(EXAMPLE_SEED, T::ZERO, T::low_mask(T::WIDTH - 1)) .map(|u| (u << 1) | T::ONE), ) } pub fn random_unsigned_gen_var_22(_config: &GenConfig) -> It { let limit = smallest_invalid_value(T::checked_factorial); Box::new(random_unsigned_range(EXAMPLE_SEED, 0, limit)) } pub fn random_unsigned_gen_var_23(_config: &GenConfig) -> It { let limit = smallest_invalid_value(T::checked_double_factorial); Box::new(random_unsigned_range(EXAMPLE_SEED, 0, limit)) } pub fn random_unsigned_gen_var_24(_config: &GenConfig) -> It { let limit = smallest_invalid_value(T::checked_subfactorial); Box::new(random_unsigned_range(EXAMPLE_SEED, 0, limit)) } pub fn random_unsigned_gen_var_25(config: &GenConfig) -> It { Box::new(geometric_random_unsigned_inclusive_range( EXAMPLE_SEED, T::wrapping_from(5u8), T::MAX, config.get_or("mean_n", 128), config.get_or("mean_d", 1), )) } pub fn random_unsigned_gen_var_26(_config: &GenConfig) -> It { let limit = smallest_invalid_value(T::checked_primorial); Box::new(random_unsigned_range(EXAMPLE_SEED, 0, limit)) } pub fn random_unsigned_gen_var_27(_config: &GenConfig) -> It { let limit = smallest_invalid_value(T::checked_product_of_first_n_primes); Box::new(random_unsigned_range(EXAMPLE_SEED, 0, limit)) } // -- (PrimitiveUnsigned, PrimitiveInt) -- pub fn random_unsigned_primitive_int_pair_gen_var_1( _config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| random_unsigned_inclusive_range(seed, T::power_of_2(T::WIDTH - 2), T::MAX), &random_primitive_ints, )) } // -- (PrimitiveUnsigned, PrimitiveInt, PrimitiveInt, PrimitiveUnsigned) -- struct ModPowerOfTwoQuadrupleWithTwoExtraPrimitiveIntsGenerator< T: PrimitiveUnsigned, U: PrimitiveInt, > { ms: GeometricRandomNaturalValues, us: RandomPrimitiveInts, xss: Vec>>, } impl Iterator for ModPowerOfTwoQuadrupleWithTwoExtraPrimitiveIntsGenerator { type Item = (T, U, U, u64); fn next(&mut self) -> Option<(T, U, U, u64)> { let pow = self.ms.next().unwrap(); let x = if pow == 0 { T::ZERO } else { let xs = &mut self.xss[usize::wrapping_from(pow)]; if xs.is_none() { *xs = Some(random_unsigned_bit_chunks( EXAMPLE_SEED.fork(&pow.to_string()), pow, )); } xs.as_mut().unwrap().next().unwrap() }; Some((x, self.us.next().unwrap(), self.us.next().unwrap(), pow)) } } pub fn random_unsigned_primitive_int_primitive_int_unsigned_quadruple_gen_var_1< T: PrimitiveUnsigned, U: PrimitiveInt, >( config: &GenConfig, ) -> It<(T, U, U, u64)> { Box::new(ModPowerOfTwoQuadrupleWithTwoExtraPrimitiveIntsGenerator { ms: geometric_random_unsigned_range( EXAMPLE_SEED.fork("ms"), 0, T::WIDTH, config.get_or("mean_pow_n", T::WIDTH >> 1), config.get_or("mean_pow_d", 1), ), us: random_primitive_ints(EXAMPLE_SEED.fork("us")), xss: vec![None; usize::wrapping_from(T::WIDTH) + 1], }) } // -- (PrimitiveUnsigned, PrimitiveInt, PrimitiveUnsigned) -- struct ModPowerOfTwoTripleWithExtraPrimitiveIntGenerator { ms: GeometricRandomNaturalValues, us: RandomPrimitiveInts, xss: Vec>>, } impl Iterator for ModPowerOfTwoTripleWithExtraPrimitiveIntGenerator { type Item = (T, U, u64); fn next(&mut self) -> Option<(T, U, u64)> { let pow = self.ms.next().unwrap(); let x = if pow == 0 { T::ZERO } else { let xs = &mut self.xss[usize::wrapping_from(pow)]; if xs.is_none() { *xs = Some(random_unsigned_bit_chunks( EXAMPLE_SEED.fork(&pow.to_string()), pow, )); } xs.as_mut().unwrap().next().unwrap() }; Some((x, self.us.next().unwrap(), pow)) } } pub fn random_unsigned_primitive_int_unsigned_triple_gen_var_1< T: PrimitiveUnsigned, U: PrimitiveInt, >( config: &GenConfig, ) -> It<(T, U, u64)> { Box::new(ModPowerOfTwoTripleWithExtraPrimitiveIntGenerator { ms: geometric_random_unsigned_range( EXAMPLE_SEED.fork("ms"), 0, T::WIDTH, config.get_or("mean_pow_n", T::WIDTH >> 1), config.get_or("mean_pow_d", 1), ), us: random_primitive_ints(EXAMPLE_SEED.fork("us")), xss: vec![None; usize::wrapping_from(T::WIDTH) + 1], }) } // -- (PrimitiveUnsigned, PrimitiveSigned) -- struct IntegerMantissaAndExponentGenerator { xs: SpecialRandomNonzeroFiniteFloats, shifts: GeometricRandomNaturalValues, } #[inline] pub(crate) fn shift_integer_mantissa_and_exponent( mantissa: u64, exponent: i64, shift: i64, ) -> Option<(u64, i64)> { Some(( mantissa.arithmetic_checked_shl(shift)?, exponent.checked_sub(shift)?, )) } impl Iterator for IntegerMantissaAndExponentGenerator { type Item = (u64, i64); fn next(&mut self) -> Option<(u64, i64)> { loop { let (mantissa, exponent) = self.xs.next().unwrap().integer_mantissa_and_exponent(); let shift = self.shifts.next().unwrap(); let out = shift_integer_mantissa_and_exponent(mantissa, exponent, shift); if out.is_some() { return out; } } } } pub fn random_unsigned_signed_pair_gen_var_1( config: &GenConfig, ) -> It<(u64, i64)> { Box::new(IntegerMantissaAndExponentGenerator:: { xs: special_random_nonzero_finite_primitive_floats( EXAMPLE_SEED.fork("xs"), config.get_or("exponent_mean_n", 8), config.get_or("exponent_mean_d", 1), config.get_or("precision_mean_n", 8), config.get_or("precision_mean_d", 1), ), shifts: geometric_random_natural_signeds( EXAMPLE_SEED.fork("shifts"), config.get_or("shift_mean_n", 4), config.get_or("shift_mean_d", 1), ), }) } // -- (PrimitiveUnsigned, PrimitiveSigned, PrimitiveUnsigned) -- struct ModPowerOfTwoTripleWithExtraSmallSignedGenerator { ms: GeometricRandomNaturalValues, us: GeometricRandomSigneds, xss: Vec>>, } impl Iterator for ModPowerOfTwoTripleWithExtraSmallSignedGenerator { type Item = (T, U, u64); fn next(&mut self) -> Option<(T, U, u64)> { let pow = self.ms.next().unwrap(); let x = if pow == 0 { T::ZERO } else { let xs = &mut self.xss[usize::wrapping_from(pow)]; if xs.is_none() { *xs = Some(random_unsigned_bit_chunks( EXAMPLE_SEED.fork(&pow.to_string()), pow, )); } xs.as_mut().unwrap().next().unwrap() }; Some((x, self.us.next().unwrap(), pow)) } } pub fn random_unsigned_signed_unsigned_triple_gen_var_1< T: PrimitiveUnsigned, U: PrimitiveSigned, >( config: &GenConfig, ) -> It<(T, U, u64)> { Box::new(ModPowerOfTwoTripleWithExtraSmallSignedGenerator { ms: geometric_random_unsigned_range( EXAMPLE_SEED.fork("ms"), 0, T::WIDTH, config.get_or("mean_pow_n", T::WIDTH >> 1), config.get_or("mean_pow_d", 1), ), us: geometric_random_signeds( EXAMPLE_SEED.fork("us"), config.get_or("mean_pow_n", T::WIDTH >> 1), config.get_or("mean_pow_d", 1), ), xss: vec![None; usize::wrapping_from(T::WIDTH) + 1], }) } pub fn random_unsigned_signed_unsigned_triple_gen_var_2< T: PrimitiveUnsigned, U: PrimitiveSigned, V: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(T, U, V)> { Box::new(random_triples( EXAMPLE_SEED, &random_primitive_ints, &|seed| { geometric_random_signeds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, &|seed| { geometric_random_positive_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, )) } // -- (PrimitiveUnsigned, PrimitiveUnsigned) -- pub fn random_unsigned_pair_gen_var_1(_config: &GenConfig) -> It<(u32, u32)> { Box::new(random_pairs_from_single(random_unsigneds_less_than( EXAMPLE_SEED, NUMBER_OF_CHARS, ))) } pub fn random_unsigned_pair_gen_var_2( config: &GenConfig, ) -> It<(T, u64)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, &|seed| random_unsigned_inclusive_range(seed, 1, U::WIDTH), )) } pub fn random_unsigned_pair_gen_var_3< T: PrimitiveUnsigned, U: ExactFrom + PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, &|seed| random_unsigned_inclusive_range(seed, U::TWO, U::exact_from(36u8)), )) } pub fn random_unsigned_pair_gen_var_4< T: PrimitiveUnsigned + SaturatingFrom, U: PrimitiveUnsigned, V: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(T, V)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| random_unsigned_inclusive_range(seed, T::TWO, T::saturating_from(U::MAX)), &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, )) } pub fn random_unsigned_pair_gen_var_5(_config: &GenConfig) -> It<(T, T)> { Box::new( random_pairs( EXAMPLE_SEED, &random_primitive_ints::, &random_positive_unsigneds::, ) .map(|(x, y)| (x.round_to_multiple(y, Down).0, y)), ) } pub fn random_unsigned_pair_gen_var_6( _config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &random_primitive_ints::, &random_positive_unsigneds::, )) } pub fn random_unsigned_pair_gen_var_7(_config: &GenConfig) -> It<(T, T)> { Box::new( random_pairs( EXAMPLE_SEED, &random_primitive_ints::, &random_positive_unsigneds::, ) .filter(|&(x, y)| !x.divisible_by(y)), ) } struct ModPowerOfTwoSingleGenerator { ms: GeometricRandomNaturalValues, xss: Vec>>, } impl Iterator for ModPowerOfTwoSingleGenerator { type Item = (T, u64); fn next(&mut self) -> Option<(T, u64)> { let pow = self.ms.next().unwrap(); let x = if pow == 0 { T::ZERO } else { let xs = &mut self.xss[usize::wrapping_from(pow)]; if xs.is_none() { *xs = Some(random_unsigned_bit_chunks( EXAMPLE_SEED.fork(&pow.to_string()), pow, )); } xs.as_mut().unwrap().next().unwrap() }; Some((x, pow)) } } struct ModPowerOfTwoSingleGenerator2 { ms: GeometricRandomNaturalValues, xss: Vec>>>, } impl Iterator for ModPowerOfTwoSingleGenerator2 { type Item = (T, u64); fn next(&mut self) -> Option<(T, u64)> { let pow = self.ms.next().unwrap(); assert_ne!(pow, 0); let xs = &mut self.xss[usize::wrapping_from(pow)]; if xs.is_none() { *xs = Some(Box::new( random_unsigned_bit_chunks(EXAMPLE_SEED.fork(&pow.to_string()), pow) .filter(|&x| x != T::ZERO), )); } let x = xs.as_mut().unwrap().next().unwrap(); Some((x, pow)) } } pub fn random_unsigned_pair_gen_var_8(config: &GenConfig) -> It<(T, u64)> { Box::new(ModPowerOfTwoSingleGenerator { ms: geometric_random_unsigned_range( EXAMPLE_SEED.fork("ms"), 0, T::WIDTH, config.get_or("mean_pow_n", T::WIDTH >> 1), config.get_or("mean_pow_d", 1), ), xss: vec![None; usize::wrapping_from(T::WIDTH) + 1], }) } pub fn random_unsigned_pair_gen_var_9( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, &|seed| { geometric_random_positive_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, )) } pub fn random_unsigned_pair_gen_var_10< T: PrimitiveUnsigned, U: ExactFrom + PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { geometric_random_positive_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, &|seed| random_unsigned_inclusive_range(seed, U::TWO, U::exact_from(36u8)), )) } pub fn random_unsigned_pair_gen_var_11(config: &GenConfig) -> It<(T, u64)> { Box::new( random_union2s( EXAMPLE_SEED, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) .map(|x| (T::ZERO, x)) }, &|seed| { random_pairs(seed, &random_positive_unsigneds, &|seed_2| { random_unsigneds_less_than(seed_2, T::WIDTH) }) }, ) .map(Union2::unwrap), ) } pub fn random_unsigned_pair_gen_var_12( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &random_positive_unsigneds, &|seed| { geometric_random_positive_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, )) } pub fn random_unsigned_pair_gen_var_13(_config: &GenConfig) -> It<(u64, u64)> { Box::new(random_pairs_from_single(random_unsigneds_less_than( EXAMPLE_SEED, T::LARGEST_ORDERED_REPRESENTATION, ))) } pub fn random_unsigned_pair_gen_var_14( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &random_positive_unsigneds, &|seed| { geometric_random_unsigned_range( seed, U::TWO, U::MAX, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, )) } pub fn random_unsigned_pair_gen_var_15( _config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| random_unsigned_inclusive_range(seed, T::ZERO, T::saturating_from(u64::MAX)), &random_positive_unsigneds::, )) } pub fn random_unsigned_pair_gen_var_16(_config: &GenConfig) -> It<(u64, u64)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| random_unsigned_bit_chunks(seed, T::MANTISSA_WIDTH), &|seed| random_unsigned_bit_chunks(seed, T::EXPONENT_WIDTH), )) } pub fn random_unsigned_pair_gen_var_17( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, )) } pub fn random_unsigned_pair_gen_var_18(config: &GenConfig) -> It<(T, u64)> { Box::new( random_pairs( EXAMPLE_SEED, &|seed| { geometric_random_unsigneds::( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, ) .filter(|&(x, y)| x.checked_pow(y).is_some()), ) } pub fn random_unsigned_pair_gen_var_19(config: &GenConfig) -> It<(T, u64)> { Box::new(random_unsigned_pair_gen_var_8(config).map(|(x, p)| (x, T::WIDTH - p))) } pub fn random_unsigned_pair_gen_var_20( _config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &random_primitive_ints, &|seed| random_unsigned_inclusive_range(seed, U::power_of_2(U::WIDTH - 2), U::MAX), )) } struct LikelyMultiplyablePairs { bits: GeometricRandomNaturalValues, ranges: VariableRangeGenerator, phantom: PhantomData<*const T>, } impl Iterator for LikelyMultiplyablePairs { type Item = (T, T); fn next(&mut self) -> Option<(T, T)> { let x_bits = self.bits.next().unwrap(); let x = if x_bits == 0 { T::ZERO } else { self.ranges.next_bit_chunk(x_bits) }; let y_bits = self.bits.next().unwrap(); let y = if y_bits == 0 { T::ZERO } else { self.ranges.next_bit_chunk(y_bits) }; Some((x, y)) } } pub fn random_unsigned_pair_gen_var_21(_config: &GenConfig) -> It<(T, T)> { Box::new(LikelyMultiplyablePairs { bits: geometric_random_unsigned_inclusive_range( EXAMPLE_SEED.fork("bits"), 0, T::WIDTH, T::WIDTH >> 1, 1, ), ranges: VariableRangeGenerator::new(EXAMPLE_SEED.fork("ranges")), phantom: PhantomData, }) } pub fn random_unsigned_pair_gen_var_22(config: &GenConfig) -> It<(T, T)> { Box::new( random_unsigned_pair_gen_var_21::(config).filter(|&(x, y)| x.checked_lcm(y).is_some()), ) } pub fn random_unsigned_pair_gen_var_23(_config: &GenConfig) -> It<(T, T)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| random_unsigned_inclusive_range(seed, T::power_of_2(T::WIDTH - 1), T::MAX), &random_primitive_ints, )) } pub fn random_unsigned_pair_gen_var_24(_config: &GenConfig) -> It<(T, T)> { Box::new( random_pairs( EXAMPLE_SEED, &random_positive_unsigneds, &random_primitive_ints, ) .filter(|&(x, y)| x != T::ONE || y != T::ZERO), ) } pub fn random_unsigned_pair_gen_var_25( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &random_positive_unsigneds, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, )) } pub fn random_unsigned_pair_gen_var_26(_config: &GenConfig) -> It<(T, T)> { Box::new(random_ordered_unique_pairs(random_positive_unsigneds::( EXAMPLE_SEED, ))) } pub fn random_unsigned_pair_gen_var_27(config: &GenConfig) -> It<(T, u64)> { Box::new(ModPowerOfTwoSingleGenerator2 { ms: geometric_random_unsigned_range( EXAMPLE_SEED.fork("ms"), 1, T::WIDTH, config.get_or("mean_pow_n", T::WIDTH >> 1), config.get_or("mean_pow_d", 1), ), xss: { let len = usize::wrapping_from(T::WIDTH) + 1; let mut xss = Vec::with_capacity(len); xss.resize_with(len, || None); xss }, }) } pub fn random_unsigned_pair_gen_var_28(_config: &GenConfig) -> It<(T, T)> { Box::new(random_pairs( EXAMPLE_SEED, &random_primitive_ints, &|seed| { random_unsigned_inclusive_range(seed, T::ZERO, T::low_mask(T::WIDTH - 1)) .map(|u| (u << 1) | T::ONE) }, )) } pub fn random_unsigned_pair_gen_var_29(_config: &GenConfig) -> It<(T, T)> { Box::new( random_pairs_from_single( random_unsigned_inclusive_range(EXAMPLE_SEED, T::ZERO, T::low_mask(T::WIDTH - 1)) .map(|u| (u << 1) | T::ONE), ) .filter(|&(a, b): &(T, T)| a.coprime_with(b)), ) } pub fn random_unsigned_pair_gen_var_30(_config: &GenConfig) -> It<(T, T)> { Box::new( random_pairs_from_single(random_primitive_ints(EXAMPLE_SEED)) .filter(|&(x, y): &(T, T)| x.coprime_with(y)), ) } struct MultifactorialNGenerator { ms: GeometricRandomNaturalValues, ranges: VariableRangeGenerator, ms_to_n_limit: HashMap, phantom: PhantomData<*const T>, } impl Iterator for MultifactorialNGenerator { type Item = (u64, u64); fn next(&mut self) -> Option<(u64, u64)> { let m = self.ms.next().unwrap(); let smallest_invalid_n = self .ms_to_n_limit .entry(m) .or_insert_with(|| smallest_invalid_value(|n| T::checked_multifactorial(n, m))); let n = self.ranges.next_less_than(*smallest_invalid_n); Some((n, m)) } } pub fn random_unsigned_pair_gen_var_31(config: &GenConfig) -> It<(u64, u64)> { Box::new(MultifactorialNGenerator { ms: geometric_random_positive_unsigneds( EXAMPLE_SEED.fork("digit_counts"), config.get_or("mean_m_n", 4), config.get_or("mean_m_d", 1), ), ranges: VariableRangeGenerator::new(EXAMPLE_SEED.fork("ranges")), ms_to_n_limit: HashMap::new(), phantom: PhantomData::<*const T>, }) } pub fn random_unsigned_pair_gen_var_32(config: &GenConfig) -> It<(T, T)> { Box::new( random_pairs_from_single(geometric_random_unsigneds( EXAMPLE_SEED, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), )) .filter(|&(n, k)| T::checked_binomial_coefficient(n, k).is_some()), ) } // var 33 is in malachite-nz // -- (PrimitiveUnsigned, PrimitiveUnsigned, PrimitiveInt, PrimitiveUnsigned) -- struct ModPowerOfTwoQuadrupleWithExtraPrimitiveIntGenerator { ms: GeometricRandomNaturalValues, us: RandomPrimitiveInts, xss: Vec>>, } impl Iterator for ModPowerOfTwoQuadrupleWithExtraPrimitiveIntGenerator { type Item = (T, T, U, u64); fn next(&mut self) -> Option<(T, T, U, u64)> { let pow = self.ms.next().unwrap(); let (x, y) = if pow == 0 { (T::ZERO, T::ZERO) } else { let xs = &mut self.xss[usize::wrapping_from(pow)]; if xs.is_none() { *xs = Some(random_unsigned_bit_chunks( EXAMPLE_SEED.fork(&pow.to_string()), pow, )); } let xs = xs.as_mut().unwrap(); (xs.next().unwrap(), xs.next().unwrap()) }; Some((x, y, self.us.next().unwrap(), pow)) } } pub fn random_unsigned_unsigned_primitive_int_unsigned_quadruple_gen_var_1< T: PrimitiveUnsigned, U: PrimitiveInt, >( config: &GenConfig, ) -> It<(T, T, U, u64)> { Box::new(ModPowerOfTwoQuadrupleWithExtraPrimitiveIntGenerator { ms: geometric_random_unsigned_range( EXAMPLE_SEED.fork("ms"), 0, T::WIDTH, config.get_or("mean_pow_n", T::WIDTH >> 1), config.get_or("mean_pow_d", 1), ), us: random_primitive_ints(EXAMPLE_SEED.fork("us")), xss: vec![None; usize::wrapping_from(T::WIDTH) + 1], }) } // -- (PrimitiveUnsigned, PrimitiveUnsigned, PrimitiveUnsigned) -- fn wrapping_shr(x: T, bits: u64) -> T { if bits >= x.significant_bits() { T::ZERO } else { x >> bits } } pub(crate) fn reduce_to_fit_add_mul_unsigned(x: T, y: T, z: T) -> (T, T, T) { let (p_hi, p_lo) = T::x_mul_y_to_zz(y, z); let r_hi = T::xx_add_yy_to_zz(T::ZERO, x, p_hi, p_lo).0; if r_hi == T::ZERO { (x, y, z) } else { let excess_x: u64 = r_hi.significant_bits(); let excess_yz = excess_x.shr_round(1, Ceiling).0; ( wrapping_shr(x, excess_x), wrapping_shr(y, excess_yz), wrapping_shr(z, excess_yz), ) } } pub fn random_unsigned_triple_gen_var_1( _config: &GenConfig, ) -> It<(T, T, T)> { Box::new( random_triples_from_single(random_primitive_ints(EXAMPLE_SEED)) .map(|(x, y, z)| reduce_to_fit_add_mul_unsigned(x, y, z)), ) } pub(crate) fn reduce_to_fit_sub_mul_unsigned(x: T, y: T, z: T) -> (T, T, T) { let x_bits = x.significant_bits(); let (p_hi, p_lo) = T::x_mul_y_to_zz(y, z); let product_bits = if p_hi == T::ZERO { p_lo.significant_bits() } else { p_hi.significant_bits() + T::WIDTH }; if x_bits > product_bits { (x, y, z) } else { let excess = (product_bits - x_bits + 1).shr_round(1, Ceiling).0; (x, wrapping_shr(y, excess), wrapping_shr(z, excess)) } } pub fn random_unsigned_triple_gen_var_2( _config: &GenConfig, ) -> It<(T, T, T)> { Box::new( random_triples_from_single(random_primitive_ints(EXAMPLE_SEED)) .map(|(x, y, z)| reduce_to_fit_sub_mul_unsigned(x, y, z)), ) } pub fn random_unsigned_triple_gen_var_3( _config: &GenConfig, ) -> It<(T, T, T)> { Box::new( random_triples_from_single(random_primitive_ints::(EXAMPLE_SEED)).map(|(x, y, m)| { if m == T::ZERO { let min = min(x, y); (min, min, m) } else if x <= y { let adjusted_diff = (y - x).round_to_multiple(m, Down).0; (x, x + adjusted_diff, m) } else { let adjusted_diff = (x - y).round_to_multiple(m, Down).0; (y + adjusted_diff, y, m) } }), ) } pub fn random_unsigned_triple_gen_var_4( config: &GenConfig, ) -> It<(T, T, u64)> { Box::new( random_triples_xxy(EXAMPLE_SEED, &random_primitive_ints::, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_pow_n", 32), config.get_or("mean_pow_d", 1), ) }) .map(|(x, y, pow)| { if pow >= T::WIDTH { (x, x, pow) } else if x <= y { let adjusted_diff = (y - x).round_to_multiple_of_power_of_2(pow, Down).0; (x, x + adjusted_diff, pow) } else { let adjusted_diff = (x - y).round_to_multiple_of_power_of_2(pow, Down).0; (y + adjusted_diff, y, pow) } }), ) } struct ModPowerOfTwoPairGenerator { ms: GeometricRandomNaturalValues, xss: Vec>>, } impl Iterator for ModPowerOfTwoPairGenerator { type Item = (T, T, u64); fn next(&mut self) -> Option<(T, T, u64)> { let pow = self.ms.next().unwrap(); let (x, y) = if pow == 0 { (T::ZERO, T::ZERO) } else { let xs = &mut self.xss[usize::wrapping_from(pow)]; if xs.is_none() { *xs = Some(random_unsigned_bit_chunks( EXAMPLE_SEED.fork(&pow.to_string()), pow, )); } let xs = xs.as_mut().unwrap(); (xs.next().unwrap(), xs.next().unwrap()) }; Some((x, y, pow)) } } pub fn random_unsigned_triple_gen_var_5( config: &GenConfig, ) -> It<(T, T, u64)> { Box::new(ModPowerOfTwoPairGenerator { ms: geometric_random_unsigned_range( EXAMPLE_SEED.fork("ms"), 0, T::WIDTH, config.get_or("mean_pow_n", T::WIDTH >> 1), config.get_or("mean_pow_d", 1), ), xss: vec![None; usize::wrapping_from(T::WIDTH) + 1], }) } struct ModPowerOfTwoTripleWithExtraSmallUnsignedGenerator< T: PrimitiveUnsigned, U: PrimitiveUnsigned, > { ms: GeometricRandomNaturalValues, us: GeometricRandomNaturalValues, xss: Vec>>, } impl Iterator for ModPowerOfTwoTripleWithExtraSmallUnsignedGenerator { type Item = (T, U, u64); fn next(&mut self) -> Option<(T, U, u64)> { let pow = self.ms.next().unwrap(); let x = if pow == 0 { T::ZERO } else { let xs = &mut self.xss[usize::wrapping_from(pow)]; if xs.is_none() { *xs = Some(random_unsigned_bit_chunks( EXAMPLE_SEED.fork(&pow.to_string()), pow, )); } xs.as_mut().unwrap().next().unwrap() }; Some((x, self.us.next().unwrap(), pow)) } } pub fn random_unsigned_triple_gen_var_6( config: &GenConfig, ) -> It<(T, U, u64)> { Box::new(ModPowerOfTwoTripleWithExtraSmallUnsignedGenerator { ms: geometric_random_unsigned_range( EXAMPLE_SEED.fork("ms"), 0, T::WIDTH, config.get_or("mean_pow_n", T::WIDTH >> 1), config.get_or("mean_pow_d", 1), ), us: geometric_random_unsigneds( EXAMPLE_SEED.fork("us"), config.get_or("mean_pow_n", T::WIDTH >> 1), config.get_or("mean_pow_d", 1), ), xss: vec![None; usize::wrapping_from(T::WIDTH) + 1], }) } pub fn random_unsigned_triple_gen_var_7( config: &GenConfig, ) -> It<(T, U, U)> { Box::new( random_triples_xyy(EXAMPLE_SEED, &random_positive_unsigneds, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }) .map(|(x, y, z)| if y <= z { (x, y, z) } else { (x, z, y) }), ) } pub fn random_unsigned_triple_gen_var_8( _config: &GenConfig, ) -> It<(T, T, T)> { Box::new(random_triples_xyx( EXAMPLE_SEED, &random_primitive_ints, &|seed| { random_unsigned_inclusive_range(seed, T::ZERO, T::low_mask(T::WIDTH - 1)) .map(|u| (u << 1) | T::ONE) }, )) } pub fn random_unsigned_triple_gen_var_9( _config: &GenConfig, ) -> It<(T, T, T)> { Box::new(random_triples_xxy( EXAMPLE_SEED, &random_primitive_ints, &|seed| { random_unsigned_inclusive_range(seed, T::ZERO, T::low_mask(T::WIDTH - 1)) .map(|u| (u << 1) | T::ONE) }, )) } pub fn random_unsigned_triple_gen_var_10( _config: &GenConfig, ) -> It<(T, T, T)> { Box::new(random_triples_xyy( EXAMPLE_SEED, &random_primitive_ints, &|seed| { random_unsigned_inclusive_range(seed, T::ZERO, T::low_mask(T::WIDTH - 1)) .map(|u| (u << 1) | T::ONE) }, )) } // -- (PrimitiveUnsigned, PrimitiveUnsigned, PrimitiveUnsigned, PrimitiveUnsigned) -- struct ModPowerOfTwoTripleGenerator { ms: GeometricRandomNaturalValues, xss: Vec>>, } impl Iterator for ModPowerOfTwoTripleGenerator { type Item = (T, T, T, u64); fn next(&mut self) -> Option<(T, T, T, u64)> { let pow = self.ms.next().unwrap(); let (x, y, z) = if pow == 0 { (T::ZERO, T::ZERO, T::ZERO) } else { let xs = &mut self.xss[usize::wrapping_from(pow)]; if xs.is_none() { *xs = Some(random_unsigned_bit_chunks( EXAMPLE_SEED.fork(&pow.to_string()), pow, )); } let xs = xs.as_mut().unwrap(); (xs.next().unwrap(), xs.next().unwrap(), xs.next().unwrap()) }; Some((x, y, z, pow)) } } pub fn random_unsigned_quadruple_gen_var_1( config: &GenConfig, ) -> It<(T, T, T, u64)> { Box::new(ModPowerOfTwoTripleGenerator { ms: geometric_random_unsigned_range( EXAMPLE_SEED.fork("ms"), 0, T::WIDTH, config.get_or("mean_pow_n", T::WIDTH >> 1), config.get_or("mean_pow_d", 1), ), xss: vec![None; usize::wrapping_from(T::WIDTH) + 1], }) } pub fn random_unsigned_quadruple_gen_var_2< T: TryFrom
+ PrimitiveUnsigned, DT: From + HasHalf + JoinHalves + PrimitiveUnsigned + SplitInHalf, >( _config: &GenConfig, ) -> It<(T, T, T, T)> { Box::new( random_triples_xxy( EXAMPLE_SEED, &random_primitive_ints, &random_positive_unsigneds, ) .map(|(x_1, x_0, d)| { let inv = limbs_invert_limb_naive::(d << LeadingZeros::leading_zeros(d)); (x_1, x_0, d, inv) }), ) } pub fn random_unsigned_quadruple_gen_var_3( _config: &GenConfig, ) -> It<(T, T, T, T)> { Box::new(random_quadruples_xxxy( EXAMPLE_SEED, &random_primitive_ints, &|seed| { random_unsigned_inclusive_range(seed, T::ZERO, T::low_mask(T::WIDTH - 1)) .map(|u| (u << 1) | T::ONE) }, )) } // -- (PrimitiveUnsigned, PrimitiveUnsigned, RoundingMode) -- struct UnsignedUnsignedRoundingModeTripleGenerator { xs: RandomPrimitiveInts, rms: RandomRoundingModes, } impl Iterator for UnsignedUnsignedRoundingModeTripleGenerator { type Item = (T, T, RoundingMode); fn next(&mut self) -> Option<(T, T, RoundingMode)> { let mut x = self.xs.next().unwrap(); let mut y; loop { y = self.xs.next().unwrap(); if y != T::ZERO { break; } } let rm = self.rms.next().unwrap(); if rm == Exact { x.round_to_multiple_assign(y, Down); } Some((x, y, rm)) } } pub fn random_unsigned_unsigned_rounding_mode_triple_gen_var_1( _config: &GenConfig, ) -> It<(T, T, RoundingMode)> { Box::new(UnsignedUnsignedRoundingModeTripleGenerator { xs: random_primitive_ints(EXAMPLE_SEED.fork("xs")), rms: random_rounding_modes(EXAMPLE_SEED.fork("rms")), }) } pub fn random_unsigned_unsigned_rounding_mode_triple_gen_var_2( _config: &GenConfig, ) -> It<(T, T, RoundingMode)> { Box::new( random_triples( EXAMPLE_SEED, &random_primitive_ints, &random_positive_unsigneds, &random_rounding_modes, ) .filter_map(|(x, y, rm)| round_to_multiple_unsigned_filter_map(x, y, rm)), ) } // var 3 is in malachite-float. // -- (PrimitiveUnsigned, RoundingMode) -- pub fn random_unsigned_rounding_mode_pair_gen_var_1( _config: &GenConfig, ) -> It<(T, RoundingMode)> { Box::new(random_pairs( EXAMPLE_SEED, &random_positive_unsigneds, &random_rounding_modes, )) } pub fn random_unsigned_rounding_mode_pair_gen_var_2( config: &GenConfig, ) -> It<(T, RoundingMode)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { geometric_random_positive_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, &random_rounding_modes, )) } pub fn random_unsigned_rounding_mode_pair_gen_var_3( config: &GenConfig, ) -> It<(T, RoundingMode)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { geometric_random_positive_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, &|seed| random_rounding_modes(seed).filter(|&rm| rm != Exact), )) } // -- (PrimitiveUnsigned, String) -- struct DigitStringGenerator { ranges: VariableRangeGenerator, digit_map: HashMap>, digit_counts: GeometricRandomNaturalValues, } impl Iterator for DigitStringGenerator { type Item = (u8, String); fn next(&mut self) -> Option<(u8, String)> { let base = self.ranges.next_in_inclusive_range(2, 36); let digits = self .digit_map .entry(base) .or_insert_with(|| valid_digit_chars(base)); let digit_count = self.digit_counts.next().unwrap(); let mut s = String::with_capacity(digit_count); for _ in 0..digit_count { let index = self.ranges.next_less_than(digits.len()); s.push(digits[index]); } Some((base, s)) } } pub fn random_unsigned_string_pair_gen_var_1(config: &GenConfig) -> It<(u8, String)> { Box::new(DigitStringGenerator { ranges: VariableRangeGenerator::new(EXAMPLE_SEED.fork("ranges")), digit_map: HashMap::new(), digit_counts: geometric_random_unsigned_range( EXAMPLE_SEED.fork("digit_counts"), 1, usize::MAX, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ), }) } pub fn random_unsigned_string_pair_gen_var_2(config: &GenConfig) -> It<(u8, String)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| random_unsigned_inclusive_range(seed, 2, 36), &|seed| { random_strings( seed, config.get_or("mean_length_n", 32), config.get_or("mean_length_d", 1), ) }, )) } struct TargetedIntegerFromStringBaseInputs { uss: It<(u8, String)>, negs: RandomBools, } impl Iterator for TargetedIntegerFromStringBaseInputs { type Item = (u8, String); fn next(&mut self) -> Option<(u8, String)> { if self.negs.next().unwrap() { let (u, s) = self.uss.next().unwrap(); let mut out = '-'.to_string(); out.push_str(&s); Some((u, out)) } else { self.uss.next() } } } pub fn random_unsigned_string_pair_gen_var_3(config: &GenConfig) -> It<(u8, String)> { Box::new(TargetedIntegerFromStringBaseInputs { uss: Box::new(DigitStringGenerator { ranges: VariableRangeGenerator::new(EXAMPLE_SEED.fork("ranges")), digit_map: HashMap::new(), digit_counts: geometric_random_unsigned_range( EXAMPLE_SEED.fork("digit_counts"), 1, usize::MAX, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ), }), negs: random_bools(EXAMPLE_SEED.fork("negs")), }) } // --(PrimitiveUnsigned, Vec) -- struct UnsignedBoolVecPairGeneratorVar1 { xs: RandomPrimitiveInts, bs: RandomBools, } impl Iterator for UnsignedBoolVecPairGeneratorVar1 { type Item = (T, Vec); fn next(&mut self) -> Option<(T, Vec)> { let x = self.xs.next().unwrap(); let bs = (&mut self.bs) .take(usize::exact_from(x.significant_bits())) .collect(); Some((x, bs)) } } pub fn random_unsigned_bool_vec_pair_gen_var_1( _config: &GenConfig, ) -> It<(T, Vec)> { Box::new(UnsignedBoolVecPairGeneratorVar1 { xs: random_primitive_ints(EXAMPLE_SEED.fork("xs")), bs: random_bools(EXAMPLE_SEED.fork("bs")), }) } // -- RationalSequence -- pub fn random_primitive_int_rational_sequence_gen( config: &GenConfig, ) -> It> { Box::new(random_rational_sequences( EXAMPLE_SEED, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) } // -- (RationalSequence, PrimitiveUnsigned) -- pub fn random_primitive_int_rational_sequence_unsigned_pair_gen_var_1< T: PrimitiveInt, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(RationalSequence, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { random_rational_sequences( seed, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_unsigned_n", 32), config.get_or("mean_small_unsigned_d", 1), ) }, )) } pub fn random_primitive_int_rational_sequence_unsigned_pair_gen_var_2( config: &GenConfig, ) -> It<(RationalSequence, usize)> { Box::new( random_pairs( EXAMPLE_SEED, &|seed| { random_rational_sequences( seed, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_unsigned_n", 32), config.get_or("mean_small_unsigned_d", 1), ) }, ) .filter(|&(ref xs, i)| { if let Some(len) = xs.len() { i < len } else { true } }), ) } // -- (RationalSequence, RationalSequence) -- pub fn random_primitive_int_rational_sequence_pair_gen( config: &GenConfig, ) -> It<(RationalSequence, RationalSequence)> { Box::new(random_pairs_from_single(random_rational_sequences( EXAMPLE_SEED, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ))) } // -- RationalSequence * 3 -- pub fn random_primitive_int_rational_sequence_triple_gen( config: &GenConfig, ) -> It<( RationalSequence, RationalSequence, RationalSequence, )> { Box::new(random_triples_from_single(random_rational_sequences( EXAMPLE_SEED, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ))) } // -- RoundingMode -- pub fn random_rounding_mode_gen(_config: &GenConfig) -> It { Box::new(random_rounding_modes(EXAMPLE_SEED)) } // -- (RoundingMode, RoundingMode) -- pub fn random_rounding_mode_pair_gen(_config: &GenConfig) -> It<(RoundingMode, RoundingMode)> { Box::new(random_pairs_from_single(random_rounding_modes( EXAMPLE_SEED, ))) } // -- (RoundingMode, RoundingMode, RoundingMode) -- pub fn random_rounding_mode_triple_gen( _config: &GenConfig, ) -> It<(RoundingMode, RoundingMode, RoundingMode)> { Box::new(random_triples_from_single(random_rounding_modes( EXAMPLE_SEED, ))) } // -- SciSizeOptions -- pub fn random_sci_size_options_gen(config: &GenConfig) -> It { Box::new(random_sci_size_options( EXAMPLE_SEED, config.get_or("mean_size_n", 32), config.get_or("mean_size_d", 1), )) } // -- String -- pub fn random_string_gen(config: &GenConfig) -> It { Box::new(random_strings( EXAMPLE_SEED, config.get_or("mean_length_n", 32), config.get_or("mean_length_d", 1), )) } pub fn random_string_gen_var_1(config: &GenConfig) -> It { Box::new(random_strings_using_chars( EXAMPLE_SEED, &random_ascii_chars, config.get_or("mean_length_n", 32), config.get_or("mean_length_d", 1), )) } pub fn random_string_gen_var_2(config: &GenConfig) -> It { Box::new(random_strings_using_chars( EXAMPLE_SEED, &|seed| random_values_from_vec(seed, ROUNDING_MODE_CHARS.chars().collect()), config.get_or("mean_length_n", 32), config.get_or("mean_length_d", 1), )) } pub fn random_string_gen_var_3(config: &GenConfig) -> It { Box::new(strings_from_char_vecs(random_vecs_min_length( EXAMPLE_SEED, 1, &|seed| random_values_from_vec(seed, ('0'..='9').collect()), config.get_or("mean_length_n", 32), config.get_or("mean_length_d", 1), ))) } struct TargetedIntegerFromStrStringsVar1 { ss: It, negs: RandomBools, } impl Iterator for TargetedIntegerFromStrStringsVar1 { type Item = String; fn next(&mut self) -> Option { if self.negs.next().unwrap() { Some(format!("-{}", self.ss.next().unwrap())) } else { self.ss.next() } } } pub fn random_string_gen_var_4(config: &GenConfig) -> It { Box::new(TargetedIntegerFromStrStringsVar1 { ss: Box::new(strings_from_char_vecs(random_vecs_min_length( EXAMPLE_SEED.fork("ss"), 1, &|seed| random_values_from_vec(seed, ('0'..='9').collect()), config.get_or("mean_length_n", 32), config.get_or("mean_length_d", 1), ))), negs: random_bools(EXAMPLE_SEED.fork("negs")), }) } pub fn random_string_gen_var_5(config: &GenConfig) -> It { Box::new(strings_from_char_vecs(random_vecs_min_length( EXAMPLE_SEED, 1, &|seed| random_values_from_vec(seed, ('0'..='1').collect()), config.get_or("mean_length_n", 32), config.get_or("mean_length_d", 1), ))) } pub fn random_string_gen_var_6(config: &GenConfig) -> It { Box::new(strings_from_char_vecs(random_vecs_min_length( EXAMPLE_SEED, 1, &|seed| random_values_from_vec(seed, ('0'..='7').collect()), config.get_or("mean_length_n", 32), config.get_or("mean_length_d", 1), ))) } pub fn random_string_gen_var_7(config: &GenConfig) -> It { Box::new(strings_from_char_vecs(random_vecs_min_length( EXAMPLE_SEED, 1, &|seed| { random_union3s( seed, &|seed_2| random_values_from_vec(seed_2, ('0'..='9').collect()), &|seed_2| random_values_from_vec(seed_2, ('a'..='f').collect()), &|seed_2| random_values_from_vec(seed_2, ('A'..='F').collect()), ) .map(Union3::unwrap) }, config.get_or("mean_length_n", 32), config.get_or("mean_length_d", 1), ))) } pub fn random_string_gen_var_8(config: &GenConfig) -> It { Box::new( strings_from_char_vecs(random_vecs_min_length( EXAMPLE_SEED, 1, &|seed| { random_union3s( seed, &|seed_2| random_values_from_vec(seed_2, ('0'..='9').collect()), &|seed_2| random_values_from_vec(seed_2, ('a'..='f').collect()), &|seed_2| random_values_from_vec(seed_2, ('A'..='F').collect()), ) .map(Union3::unwrap) }, config.get_or("mean_length_n", 32), config.get_or("mean_length_d", 1), )) .map(|s| format!("\"0x{s}\"")), ) } struct TargetedIntegerFromStrStringsVar2 { ss: It, negs: RandomBools, } impl Iterator for TargetedIntegerFromStrStringsVar2 { type Item = String; fn next(&mut self) -> Option { Some(if self.negs.next().unwrap() { format!("\"-0x{}\"", self.ss.next().unwrap()) } else { format!("\"0x{}\"", self.ss.next().unwrap()) }) } } pub fn random_string_gen_var_9(config: &GenConfig) -> It { Box::new(TargetedIntegerFromStrStringsVar2 { ss: Box::new(strings_from_char_vecs(random_vecs_min_length( EXAMPLE_SEED.fork("ss"), 1, &|seed| { random_union3s( seed, &|seed_2| random_values_from_vec(seed_2, ('0'..='9').collect()), &|seed_2| random_values_from_vec(seed_2, ('a'..='f').collect()), &|seed_2| random_values_from_vec(seed_2, ('A'..='F').collect()), ) .map(Union3::unwrap) }, config.get_or("mean_length_n", 32), config.get_or("mean_length_d", 1), ))), negs: random_bools(EXAMPLE_SEED.fork("negs")), }) } pub fn random_string_gen_var_10(config: &GenConfig) -> It { Box::new(random_strings_using_chars( EXAMPLE_SEED, &|seed| random_values_from_vec(seed, PRIMITIVE_FLOAT_CHARS.chars().collect()), config.get_or("mean_length_n", 32), config.get_or("mean_length_d", 1), )) } // vars 11 through 12 are in malachite-q. pub fn random_string_gen_var_13(config: &GenConfig) -> It { Box::new(random_strings_using_chars( EXAMPLE_SEED, &|seed| random_values_from_vec(seed, DECIMAL_SCI_STRING_CHARS.chars().collect()), config.get_or("mean_length_n", 32), config.get_or("mean_length_d", 1), )) } pub fn random_string_gen_var_14(config: &GenConfig) -> It { Box::new( random_strings( EXAMPLE_SEED, config.get_or("mean_length_n", 32), config.get_or("mean_length_d", 1), ) .filter(|s| !large_exponent(s)), ) } pub fn random_string_gen_var_15(config: &GenConfig) -> It { Box::new( random_strings_using_chars( EXAMPLE_SEED, &|seed| random_values_from_vec(seed, DECIMAL_SCI_STRING_CHARS.chars().collect()), config.get_or("mean_length_n", 32), config.get_or("mean_length_d", 1), ) .filter(|s| !large_exponent(s)), ) } // -- (String, FromSciStringOptions) -- pub fn random_string_from_sci_string_options_pair_gen( config: &GenConfig, ) -> It<(String, FromSciStringOptions)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { random_strings( seed, config.get_or("mean_length_n", 32), config.get_or("mean_length_d", 1), ) }, &random_from_sci_string_options, )) } struct SciDigitStringGenerator { options: RandomFromSciStringOptions, ranges: VariableRangeGenerator, digit_map: HashMap>, digit_counts: GeometricRandomNaturalValues, } impl Iterator for SciDigitStringGenerator { type Item = (String, FromSciStringOptions); fn next(&mut self) -> Option<(String, FromSciStringOptions)> { let options = self.options.next().unwrap(); let base = options.get_base(); let digits = self.digit_map.entry(base).or_insert_with(|| { let mut cs = vec!['+', '-', '.']; if base < 15 { cs.push('e'); cs.push('E'); } cs.extend(valid_digit_chars(base)); cs }); let digit_count = self.digit_counts.next().unwrap(); let mut s = String::with_capacity(digit_count); for _ in 0..digit_count { let index = self.ranges.next_less_than(digits.len()); s.push(digits[index]); } Some((s, options)) } } struct SciDigitStringGenerator2 { ranges: VariableRangeGenerator, digit_map: HashMap>, digit_counts: GeometricRandomNaturalValues, } impl Iterator for SciDigitStringGenerator2 { type Item = (String, u8); fn next(&mut self) -> Option<(String, u8)> { let base = self.ranges.next_in_inclusive_range(2, 36); let digits = self.digit_map.entry(base).or_insert_with(|| { let mut cs = vec!['+', '-', '.']; if base < 15 { cs.push('e'); cs.push('E'); } cs.extend(valid_digit_chars(base)); cs }); let digit_count = self.digit_counts.next().unwrap(); let mut s = String::with_capacity(digit_count); for _ in 0..digit_count { let index = self.ranges.next_less_than(digits.len()); s.push(digits[index]); } Some((s, base)) } } pub fn random_string_from_sci_string_options_pair_gen_var_1( config: &GenConfig, ) -> It<(String, FromSciStringOptions)> { Box::new(SciDigitStringGenerator { options: random_from_sci_string_options(EXAMPLE_SEED.fork("options")), ranges: VariableRangeGenerator::new(EXAMPLE_SEED.fork("ranges")), digit_map: HashMap::new(), digit_counts: geometric_random_unsigned_range( EXAMPLE_SEED.fork("digit_counts"), 1, usize::MAX, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ), }) } pub fn random_string_from_sci_string_options_pair_gen_var_2( config: &GenConfig, ) -> It<(String, FromSciStringOptions)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { random_strings( seed, config.get_or("mean_length_n", 32), config.get_or("mean_length_d", 1), ) .filter(|s| !large_exponent(s)) }, &random_from_sci_string_options, )) } pub fn random_string_from_sci_string_options_pair_gen_var_3( config: &GenConfig, ) -> It<(String, FromSciStringOptions)> { Box::new( SciDigitStringGenerator { options: random_from_sci_string_options(EXAMPLE_SEED.fork("options")), ranges: VariableRangeGenerator::new(EXAMPLE_SEED.fork("ranges")), digit_map: HashMap::new(), digit_counts: geometric_random_unsigned_range( EXAMPLE_SEED.fork("digit_counts"), 1, usize::MAX, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ), } .filter(|(s, _)| !large_exponent(s)), ) } // -- (String, PrimitiveUnsigned) -- pub fn random_string_unsigned_pair_gen_var_1(config: &GenConfig) -> It<(String, u8)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { random_strings( seed, config.get_or("mean_length_n", 32), config.get_or("mean_length_d", 1), ) .filter(|s| !large_exponent(s)) }, &|seed| random_unsigned_inclusive_range(seed, 2, 36), )) } pub fn random_string_unsigned_pair_gen_var_2(config: &GenConfig) -> It<(String, u8)> { Box::new( SciDigitStringGenerator2 { ranges: VariableRangeGenerator::new(EXAMPLE_SEED.fork("ranges")), digit_map: HashMap::new(), digit_counts: geometric_random_unsigned_range( EXAMPLE_SEED.fork("digit_counts"), 1, usize::MAX, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ), } .filter(|(s, _)| !large_exponent(s)), ) } // -- (String, String) -- pub fn random_string_pair_gen(config: &GenConfig) -> It<(String, String)> { Box::new(random_pairs_from_single(random_strings( EXAMPLE_SEED, config.get_or("mean_length_n", 32), config.get_or("mean_length_d", 1), ))) } pub fn random_string_pair_gen_var_1(config: &GenConfig) -> It<(String, String)> { Box::new(random_pairs_from_single(random_strings_using_chars( EXAMPLE_SEED, &random_ascii_chars, config.get_or("mean_length_n", 32), config.get_or("mean_length_d", 1), ))) } // -- ToSciOptions -- pub fn random_to_sci_options_gen(config: &GenConfig) -> It { Box::new(random_to_sci_options( EXAMPLE_SEED, config.get_or("mean_size_n", 32), config.get_or("mean_size_d", 1), )) } // -- (ToSciOptions, bool) -- pub fn random_to_sci_options_bool_pair_gen(config: &GenConfig) -> It<(ToSciOptions, bool)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { random_to_sci_options( seed, config.get_or("mean_size_n", 32), config.get_or("mean_size_d", 1), ) }, &random_bools, )) } // -- (ToSciOptions, PrimitiveSigned) -- pub fn random_to_sci_options_signed_pair_gen_var_1( config: &GenConfig, ) -> It<(ToSciOptions, T)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { random_to_sci_options( seed, config.get_or("mean_size_n", 32), config.get_or("mean_size_d", 1), ) }, &|seed| { geometric_random_negative_signeds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, )) } // -- (ToSciOptions, PrimitiveUnsigned) -- pub fn random_to_sci_options_unsigned_pair_gen_var_1( config: &GenConfig, ) -> It<(ToSciOptions, T)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { random_to_sci_options( seed, config.get_or("mean_size_n", 32), config.get_or("mean_size_d", 1), ) }, &|seed| random_unsigned_inclusive_range(seed, T::TWO, T::from(36u8)), )) } pub fn random_to_sci_options_unsigned_pair_gen_var_2( config: &GenConfig, ) -> It<(ToSciOptions, T)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { random_to_sci_options( seed, config.get_or("mean_size_n", 32), config.get_or("mean_size_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, )) } pub fn random_to_sci_options_unsigned_pair_gen_var_3( config: &GenConfig, ) -> It<(ToSciOptions, T)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { random_to_sci_options( seed, config.get_or("mean_size_n", 32), config.get_or("mean_size_d", 1), ) }, &|seed| { geometric_random_positive_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, )) } // -- (ToSciOptions, RoundingMode) -- pub fn random_to_sci_options_rounding_mode_pair_gen( config: &GenConfig, ) -> It<(ToSciOptions, RoundingMode)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { random_to_sci_options( seed, config.get_or("mean_size_n", 32), config.get_or("mean_size_d", 1), ) }, &random_rounding_modes, )) } // -- Vec -- pub fn random_bool_vec_gen(config: &GenConfig) -> It> { Box::new(random_vecs( EXAMPLE_SEED, &random_bools, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) } pub fn random_bool_vec_gen_var_1(config: &GenConfig) -> It> { Box::new( random_union2s( EXAMPLE_SEED, &|seed| random_vecs_length_inclusive_range(seed, 0, T::WIDTH, &random_bools), &|seed| { random_pairs( seed, &|seed_2| random_vecs_fixed_length_from_single(T::WIDTH, random_bools(seed_2)), &|seed_2| { geometric_random_positive_unsigneds( seed_2, config.get_or("mean_excess_length_n", 32), config.get_or("mean_excess_length_d", 1), ) }, ) .map(|(bs, n)| bs.into_iter().chain(repeat_n(false, n)).collect()) }, ) .map(Union2::unwrap), ) } pub fn random_bool_vec_gen_var_2(config: &GenConfig) -> It> { Box::new( random_union2s( EXAMPLE_SEED, &|seed| random_vecs_length_inclusive_range(seed, 0, T::WIDTH - 1, &random_bools), &|seed| { random_pairs( seed, &|seed_2| { random_vecs_fixed_length_from_single(T::WIDTH - 1, random_bools(seed_2)) }, &|seed_2| { geometric_random_nonzero_signeds::( seed_2, config.get_or("mean_excess_length_n", 32), config.get_or("mean_excess_length_d", 1), ) }, ) .map(|(bs, n)| { bs.into_iter() .chain(repeat_n(n < 0, n.unsigned_abs())) .collect() }) }, ) .map(Union2::unwrap), ) } pub fn random_bool_vec_gen_var_3(config: &GenConfig) -> It> { Box::new( random_union2s( EXAMPLE_SEED, &|seed| random_vecs_length_inclusive_range(seed, 0, T::WIDTH, &random_bools), &|seed| { random_pairs( seed, &|seed_2| random_vecs_fixed_length_from_single(T::WIDTH, random_bools(seed_2)), &|seed_2| { geometric_random_positive_unsigneds( seed_2, config.get_or("mean_excess_length_n", 32), config.get_or("mean_excess_length_d", 1), ) }, ) .map(|(bs, n)| repeat_n(false, n).chain(bs).collect()) }, ) .map(Union2::unwrap), ) } pub fn random_bool_vec_gen_var_4(config: &GenConfig) -> It> { Box::new( random_union2s( EXAMPLE_SEED, &|seed| random_vecs_length_inclusive_range(seed, 0, T::WIDTH - 1, &random_bools), &|seed| { random_pairs( seed, &|seed_2| { random_vecs_fixed_length_from_single(T::WIDTH - 1, random_bools(seed_2)) }, &|seed_2| { geometric_random_nonzero_signeds::( seed_2, config.get_or("mean_excess_length_n", 32), config.get_or("mean_excess_length_d", 1), ) }, ) .map(|(bs, n)| repeat_n(n < 0, n.unsigned_abs()).chain(bs).collect()) }, ) .map(Union2::unwrap), ) } pub fn random_bool_vec_gen_var_5(config: &GenConfig) -> It> { Box::new( random_vecs_min_length( EXAMPLE_SEED, 1, &random_bools, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|bs| bs.iter().any(|&b| b)), ) } // -- Vec -- pub fn random_primitive_int_vec_gen(config: &GenConfig) -> It> { Box::new(random_vecs( EXAMPLE_SEED, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) } pub fn random_primitive_int_vec_gen_var_1(config: &GenConfig) -> It> { Box::new( random_vecs_min_length( EXAMPLE_SEED, 1, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| *xs.last().unwrap() != T::ZERO), ) } pub fn random_primitive_int_vec_gen_var_2(config: &GenConfig) -> It> { Box::new( random_vecs_min_length( EXAMPLE_SEED, 1, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| !slice_test_zero(xs)), ) } pub fn random_primitive_int_vec_gen_var_3(config: &GenConfig) -> It> { Box::new( random_vecs( EXAMPLE_SEED, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| xs.last() != Some(&T::ZERO)), ) } pub fn random_primitive_int_vec_gen_var_4(config: &GenConfig) -> It> { Box::new(random_vecs_min_length( EXAMPLE_SEED, 1, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) } pub fn random_primitive_int_vec_gen_var_5(config: &GenConfig) -> It> { Box::new(random_vecs_min_length( EXAMPLE_SEED, 2, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) } // --(Vec, PrimitiveInt) -- pub fn random_primitive_int_vec_primitive_int_pair_gen( config: &GenConfig, ) -> It<(Vec, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { random_vecs( seed, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &random_primitive_ints, )) } pub fn random_primitive_int_vec_primitive_int_pair_gen_var_1( config: &GenConfig, ) -> It<(Vec, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { random_vecs_min_length( seed, 1, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &random_primitive_ints, )) } pub fn random_primitive_int_vec_primitive_int_pair_gen_var_2( config: &GenConfig, ) -> It<(Vec, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { random_vecs_min_length( seed, 1, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| !slice_test_zero(xs)) }, &random_primitive_ints, )) } // --(Vec, PrimitiveUnsigned) -- struct PrimitiveIntVecUnsignedPairGeneratorVar1 { xs: GeometricRandomNaturalValues, ys: RandomPrimitiveInts, } impl Iterator for PrimitiveIntVecUnsignedPairGeneratorVar1 { type Item = (Vec, usize); fn next(&mut self) -> Option<(Vec, usize)> { let x_1 = self.xs.next().unwrap(); let x_2 = self.xs.next().unwrap(); let (len, i) = if x_1 <= x_2 { (x_2, x_1) } else { (x_1, x_2) }; Some(((&mut self.ys).take(len).collect(), i)) } } pub fn random_primitive_int_vec_unsigned_pair_gen_var_1( config: &GenConfig, ) -> It<(Vec, usize)> { Box::new(PrimitiveIntVecUnsignedPairGeneratorVar1 { xs: geometric_random_unsigneds( EXAMPLE_SEED.fork("xs"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ), ys: random_primitive_ints(EXAMPLE_SEED.fork("ys")), }) } pub fn random_primitive_int_vec_unsigned_pair_gen_var_2( config: &GenConfig, ) -> It<(Vec, u64)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { random_vecs( seed, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| { geometric_random_unsigned_range( seed, 1, T::WIDTH, config.get_or("mean_log_base_n", 4), config.get_or("mean_log_base_d", 1), ) }, )) } pub fn random_primitive_int_vec_unsigned_pair_gen_var_3( config: &GenConfig, ) -> It<(Vec, u64)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { random_vecs( seed, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| { geometric_random_unsigned_inclusive_range( seed, 1, T::WIDTH, config.get_or("mean_log_base_n", 4), config.get_or("mean_log_base_d", 1), ) }, )) } pub fn random_primitive_int_vec_unsigned_pair_gen_var_4< T: PrimitiveInt, U: PrimitiveUnsigned + SaturatingFrom, >( config: &GenConfig, ) -> It<(Vec, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { random_vecs( seed, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| { random_unsigned_inclusive_range(seed.fork("base"), U::TWO, U::saturating_from(T::MAX)) }, )) } pub fn random_primitive_int_vec_unsigned_pair_gen_var_5( config: &GenConfig, ) -> It<(Vec, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { random_vecs_min_length( seed, 1, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| *xs.last().unwrap() != T::ZERO) }, &|seed| { geometric_random_positive_unsigneds( seed, config.get_or("mean_small_unsigned_n", 4), config.get_or("mean_small_unsigned_d", 1), ) }, )) } pub fn random_primitive_int_vec_unsigned_pair_gen_var_6( config: &GenConfig, ) -> It<(Vec, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { random_vecs_min_length( seed, 1, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| *xs.last().unwrap() != T::ZERO) }, &|seed| { geometric_random_unsigned_inclusive_range( seed, U::exact_from(3), U::MAX, config.get_or("mean_small_unsigned_n", 4), config.get_or("mean_small_unsigned_d", 1), ) }, )) } pub fn random_primitive_int_vec_unsigned_pair_gen_var_7( config: &GenConfig, ) -> It<(Vec, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { random_vecs( seed, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, )) } pub fn random_primitive_int_vec_unsigned_pair_gen_var_8( config: &GenConfig, ) -> It<(Vec, U)> { Box::new( random_pairs( EXAMPLE_SEED, &|seed| { random_vecs( seed, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, ) .filter(|(xs, y)| *y < U::exact_from(xs.len() << T::LOG_WIDTH)), ) } pub fn random_primitive_int_vec_unsigned_pair_gen_var_9( config: &GenConfig, ) -> It<(Vec, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { random_vecs_min_length( seed, 1, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| !slice_test_zero(xs)) }, &random_positive_unsigneds, )) } pub fn random_primitive_int_vec_unsigned_pair_gen_var_10( config: &GenConfig, ) -> It<(Vec, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { random_vecs_min_length( seed, 1, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| !slice_test_zero(xs)) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, )) } pub fn random_primitive_int_vec_unsigned_pair_gen_var_11( config: &GenConfig, ) -> It<(Vec, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { random_vecs_min_length( seed, 2, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &random_positive_unsigneds, )) } pub fn random_primitive_int_vec_unsigned_pair_gen_var_12( config: &GenConfig, ) -> It<(Vec, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { random_vecs_min_length( seed, 2, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| !slice_test_zero(xs)) }, &random_positive_unsigneds, )) } pub fn random_primitive_int_vec_unsigned_pair_gen_var_13( config: &GenConfig, ) -> It<(Vec, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { random_vecs_min_length( seed, 2, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| random_unsigned_inclusive_range(seed, U::power_of_2(U::WIDTH - 1), U::MAX), )) } pub fn random_primitive_int_vec_unsigned_pair_gen_var_14( config: &GenConfig, ) -> It<(Vec, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { random_vecs_min_length( seed, 2, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| random_unsigned_range(seed, U::ONE, U::power_of_2(U::WIDTH - 1)), )) } pub fn random_primitive_int_vec_unsigned_pair_gen_var_15( config: &GenConfig, ) -> It<(Vec, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { random_vecs_min_length( seed, 1, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| random_unsigned_inclusive_range(seed, U::power_of_2(U::WIDTH - 1), U::MAX), )) } pub fn random_primitive_int_vec_unsigned_pair_gen_var_16( config: &GenConfig, ) -> It<(Vec, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { random_vecs_min_length( seed, 1, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| random_unsigned_range(seed, U::ONE, U::power_of_2(U::WIDTH - 1)), )) } pub fn random_primitive_int_vec_unsigned_pair_gen_var_17( config: &GenConfig, ) -> It<(Vec, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { random_vecs_min_length( seed, 1, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| random_unsigned_range(seed, U::ONE, U::power_of_2(U::WIDTH - 2)), )) } pub fn random_primitive_int_vec_unsigned_pair_gen_var_18( config: &GenConfig, ) -> It<(Vec, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { random_vecs_min_length( seed, 1, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| *xs.last().unwrap() != T::ZERO) }, &|seed| { geometric_random_unsigned_inclusive_range( seed, U::TWO, U::MAX, config.get_or("mean_small_unsigned_n", 4), config.get_or("mean_small_unsigned_d", 1), ) }, )) } pub fn random_primitive_int_vec_unsigned_pair_gen_var_19( config: &GenConfig, ) -> It<(Vec, u64)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { random_vecs( seed, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| { geometric_random_unsigned_range( seed, 1, U::WIDTH, config.get_or("mean_log_base_n", 4), config.get_or("mean_log_base_d", 1), ) }, )) } pub fn random_primitive_int_vec_unsigned_pair_gen_var_20( config: &GenConfig, ) -> It<(Vec, u64)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { random_vecs_min_length( seed, 1, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| { geometric_random_unsigned_range( seed, 1, U::WIDTH, config.get_or("mean_log_base_n", 4), config.get_or("mean_log_base_d", 1), ) }, )) } // --(Vec, PrimitiveUnsigned, PrimitiveInt) -- pub fn random_primitive_int_vec_unsigned_primitive_int_triple_gen_var_1< T: PrimitiveInt, U: PrimitiveUnsigned, V: PrimitiveInt, >( config: &GenConfig, ) -> It<(Vec, U, V)> { Box::new(random_triples( EXAMPLE_SEED, &|seed| { random_vecs( seed, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 4), config.get_or("mean_small_d", 1), ) }, &random_primitive_ints, )) } // --(Vec, PrimitiveInt, PrimitiveInt) -- pub fn random_primitive_int_vec_primitive_int_primitive_int_triple_gen( config: &GenConfig, ) -> It<(Vec, T, T)> { Box::new(random_triples_xyy( EXAMPLE_SEED, &|seed| { random_vecs( seed, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &random_primitive_ints, )) } // --(Vec, PrimitiveInt, RoundingMode) -- pub fn random_primitive_int_vec_primitive_int_rounding_mode_triple_gen_var_1( config: &GenConfig, ) -> It<(Vec, T, RoundingMode)> { Box::new(random_triples( EXAMPLE_SEED, &|seed| { random_vecs_min_length( seed, 2, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| *xs.last().unwrap() != T::ZERO) }, &random_primitive_ints, &random_rounding_modes, )) } pub fn random_primitive_int_vec_primitive_int_rounding_mode_triple_gen_var_2< T: PrimitiveInt, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(Vec, U, RoundingMode)> { Box::new(random_triples( EXAMPLE_SEED, &|seed| { random_vecs_min_length( seed, 2, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| *xs.last().unwrap() != T::ZERO) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 4), config.get_or("mean_small_d", 1), ) }, &random_rounding_modes, )) } // --(Vec, PrimitiveUnsigned, PrimitiveUnsigned) -- struct PrimitiveIntVecUnsignedUnsignedTripleGeneratorVar1 { is: GeometricRandomNaturalValues, xs: RandomPrimitiveInts, } impl Iterator for PrimitiveIntVecUnsignedUnsignedTripleGeneratorVar1 { type Item = (Vec, usize, usize); fn next(&mut self) -> Option<(Vec, usize, usize)> { let i = self.is.next().unwrap(); let j = self.is.next().unwrap(); let excess = self.is.next().unwrap(); let xs = (&mut self.xs).take(i * j + excess).collect(); Some((xs, i, j)) } } pub fn random_primitive_int_vec_unsigned_unsigned_triple_gen_var_1( config: &GenConfig, ) -> It<(Vec, usize, usize)> { Box::new(PrimitiveIntVecUnsignedUnsignedTripleGeneratorVar1 { is: geometric_random_unsigneds( EXAMPLE_SEED.fork("is"), config.get_or("mean_small_n", 2), config.get_or("mean_small_d", 1), ), xs: random_primitive_ints(EXAMPLE_SEED.fork("xs")), }) } pub fn random_primitive_int_vec_unsigned_unsigned_triple_gen_var_2< T: PrimitiveInt, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(Vec, U, U)> { Box::new( random_triples_xyy( EXAMPLE_SEED, &|seed| { random_vecs( seed, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, ) .map(|(xs, y, z)| if y <= z { (xs, y, z) } else { (xs, z, y) }), ) } pub fn random_primitive_int_vec_unsigned_unsigned_triple_gen_var_3< T: PrimitiveInt, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(Vec, U, U)> { Box::new( random_triples_xyy( EXAMPLE_SEED, &|seed| { random_vecs_min_length( seed, 1, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| !slice_test_zero(xs)) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, ) .map(|(xs, y, z)| if y <= z { (xs, y, z) } else { (xs, z, y) }), ) } pub fn random_primitive_int_vec_unsigned_unsigned_triple_gen_var_4< T: PrimitiveInt, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(Vec, U, U)> { Box::new(random_triples_xyy( EXAMPLE_SEED, &|seed| { random_vecs_min_length( seed, 2, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| *xs.last().unwrap() != T::ZERO) }, &random_positive_unsigneds, )) } pub fn random_primitive_int_vec_unsigned_unsigned_triple_gen_var_5< T: PrimitiveInt, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(Vec, U, U)> { Box::new(random_triples( EXAMPLE_SEED, &|seed| { random_vecs_min_length( seed, 2, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| *xs.last().unwrap() != T::ZERO) }, &random_primitive_ints, &random_positive_unsigneds, )) } pub fn random_primitive_int_vec_unsigned_unsigned_triple_gen_var_6< T: PrimitiveInt, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(Vec, T, U)> { Box::new(random_triples( EXAMPLE_SEED, &|seed| { random_vecs_min_length( seed, 2, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| *xs.last().unwrap() != T::ZERO) }, &random_primitive_ints, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, )) } pub fn random_primitive_int_vec_unsigned_unsigned_triple_gen_var_7< T: PrimitiveInt, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(Vec, T, U)> { Box::new(random_triples( EXAMPLE_SEED, &|seed| { random_vecs_min_length( seed, 1, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| *xs.last().unwrap() != T::ZERO) }, &random_primitive_ints, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, )) } // -- (Vec, Vec) -- pub fn random_primitive_int_vec_pair_gen( config: &GenConfig, ) -> It<(Vec, Vec)> { Box::new(random_pairs_from_single(random_vecs( EXAMPLE_SEED, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ))) } pub struct PrimitiveIntVecPairLenGenerator1> { pub phantom: PhantomData<*const T>, pub lengths: I, pub xs: RandomPrimitiveInts, } impl> Iterator for PrimitiveIntVecPairLenGenerator1 { type Item = (Vec, Vec); fn next(&mut self) -> Option<(Vec, Vec)> { let (i, j) = self.lengths.next().unwrap(); Some(( (&mut self.xs).take(i).collect(), (&mut self.xs).take(j).collect(), )) } } fn random_primitive_int_vec_pair_gen_var_1_helper( config: &GenConfig, seed: Seed, ) -> It<(Vec, Vec)> { Box::new(PrimitiveIntVecPairLenGenerator1 { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_unsigneds( seed.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .map(|(x, y)| if x >= y { (x, y) } else { (y, x) }), xs: random_primitive_ints(seed.fork("xs")), }) } pub fn random_primitive_int_vec_pair_gen_var_1( config: &GenConfig, ) -> It<(Vec, Vec)> { random_primitive_int_vec_pair_gen_var_1_helper(config, EXAMPLE_SEED) } pub fn random_primitive_int_vec_pair_gen_var_2( config: &GenConfig, ) -> It<(Vec, Vec)> { Box::new(PrimitiveIntVecPairLenGenerator1 { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_positive_unsigneds( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .map(|(x, y)| if x >= y { (x, y) } else { (y, x) }), xs: random_primitive_ints(EXAMPLE_SEED.fork("xs")), }) } pub fn random_primitive_int_vec_pair_gen_var_3( config: &GenConfig, ) -> It<(Vec, Vec)> { Box::new(random_pairs_from_single(random_vecs_min_length( EXAMPLE_SEED, 1, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ))) } pub fn random_primitive_int_vec_pair_gen_var_4( config: &GenConfig, ) -> It<(Vec, Vec)> { Box::new( random_pairs_from_single(random_vecs_min_length( EXAMPLE_SEED, 1, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter(|(ref xs, ref es)| { !xs.is_empty() && (es.len() > 1 || es.len() == 1 && es[0] > T::ONE) && *es.last().unwrap() != T::ZERO }), ) } struct PrimitiveIntVecPairSameLenGenerator> { phantom: PhantomData<*const T>, lengths: I, xs: RandomPrimitiveInts, } impl> Iterator for PrimitiveIntVecPairSameLenGenerator { type Item = (Vec, Vec); fn next(&mut self) -> Option<(Vec, Vec)> { let len = self.lengths.next().unwrap(); Some(( (&mut self.xs).take(len).collect(), (&mut self.xs).take(len).collect(), )) } } pub fn random_primitive_int_vec_pair_gen_var_5( config: &GenConfig, ) -> It<(Vec, Vec)> { Box::new(PrimitiveIntVecPairSameLenGenerator { phantom: PhantomData, lengths: geometric_random_positive_unsigneds( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ), xs: random_primitive_ints(EXAMPLE_SEED.fork("xs")), }) } pub fn random_primitive_int_vec_pair_gen_var_6( config: &GenConfig, ) -> It<(Vec, Vec)> { Box::new(random_pairs_from_single( random_vecs( EXAMPLE_SEED, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| xs.last() != Some(&T::ZERO)), )) } pub fn random_primitive_int_vec_pair_gen_var_7( config: &GenConfig, ) -> It<(Vec, Vec)> { Box::new(random_pairs_from_single( random_vecs_min_length( EXAMPLE_SEED, 1, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| !slice_test_zero(xs)), )) } pub struct PrimitiveIntVecPairLenGenerator2> { pub phantom: PhantomData<*const T>, pub lengths: I, pub xs: RandomPrimitiveInts, } impl> Iterator for PrimitiveIntVecPairLenGenerator2 { type Item = (Vec, Vec); fn next(&mut self) -> Option<(Vec, Vec)> { let (i, j) = self.lengths.next().unwrap(); let mut xs; loop { xs = (&mut self.xs).take(i).collect_vec(); if !slice_test_zero(&xs) { break; } } let mut ys; loop { ys = (&mut self.xs).take(j).collect_vec(); if !slice_test_zero(&ys) { break; } } Some((xs, ys)) } } pub fn random_primitive_int_vec_pair_gen_var_8( config: &GenConfig, ) -> It<(Vec, Vec)> { Box::new(PrimitiveIntVecPairLenGenerator2 { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_positive_unsigneds( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .map(|(x, y)| if x >= y { (x, y) } else { (y, x) }), xs: random_primitive_ints(EXAMPLE_SEED.fork("xs")), }) } // var 9 is in malachite-nz. pub fn random_primitive_int_vec_pair_gen_var_10( config: &GenConfig, ) -> It<(Vec, Vec)> { Box::new( PrimitiveIntVecPairLenGenerator1 { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_unsigned_inclusive_range( EXAMPLE_SEED.fork("lengths"), 2, usize::MAX, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .map(|(x, y)| if x >= y { (x, y) } else { (y, x) }), xs: random_primitive_ints(EXAMPLE_SEED.fork("xs")), } .filter(|(_, ds)| *ds.last().unwrap() != T::ZERO), ) } pub fn random_primitive_int_vec_pair_gen_var_11( config: &GenConfig, ) -> It<(Vec, Vec)> { Box::new( PrimitiveIntVecPairLenGenerator1 { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_positive_unsigneds( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .map(|(x, y)| if x >= y { (x, y) } else { (y, x) }), xs: random_primitive_ints::(EXAMPLE_SEED.fork("xs")), } .map(|(xs, mut ys)| { ys[0] |= T::ONE; (xs, ys) }), ) } pub fn random_primitive_int_vec_pair_gen_var_12( config: &GenConfig, ) -> It<(Vec, Vec)> { Box::new( PrimitiveIntVecPairLenGenerator1 { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_positive_unsigneds( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .map(|(x, y)| if x >= y { (x, y) } else { (y, x) }), xs: random_primitive_ints(EXAMPLE_SEED.fork("xs")), } .filter(|(xs, ys)| *xs.last().unwrap() != T::ZERO && *ys.last().unwrap() != T::ZERO), ) } pub fn random_primitive_int_vec_pair_gen_var_13( config: &GenConfig, ) -> It<(Vec, Vec)> { Box::new( PrimitiveIntVecPairLenGenerator1 { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_unsigned_inclusive_range( EXAMPLE_SEED.fork("lengths"), 2, usize::MAX, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .map(|(x, y)| if x >= y { (x, y) } else { (y, x) }), xs: random_primitive_ints(EXAMPLE_SEED.fork("xs")), } .filter(|(xs, ys)| *xs.last().unwrap() != T::ZERO && *ys.last().unwrap() != T::ZERO), ) } pub fn random_primitive_int_vec_pair_gen_var_14( config: &GenConfig, ) -> It<(Vec, Vec)> { Box::new(random_pairs_from_single( random_vecs_min_length( EXAMPLE_SEED, 1, &random_primitive_ints::, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter_map(|mut xs| { let last = xs.last_mut().unwrap(); *last = last.checked_add(T::ONE)?; Some(xs) }), )) } pub fn random_primitive_int_vec_pair_gen_var_15( config: &GenConfig, ) -> It<(Vec, Vec)> { Box::new(PrimitiveIntVecPairLenGenerator1 { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_unsigned_inclusive_range( EXAMPLE_SEED.fork("lengths"), 2, usize::MAX, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .map(|(x, y)| if x >= y { (x, y) } else { (y, x) }), xs: random_primitive_ints(EXAMPLE_SEED.fork("xs")), }) } // vars 16 through 25 are in malachite-nz. pub fn random_primitive_int_vec_pair_gen_var_26( config: &GenConfig, ) -> It<(Vec, Vec)> { Box::new(PrimitiveIntVecPairLenGenerator1 { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_unsigneds( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .map(|(x, y)| if x >= y { (x, y) } else { (y, x) }), xs: random_primitive_ints(EXAMPLE_SEED.fork("xs")), }) } pub fn random_primitive_int_vec_pair_gen_var_27( config: &GenConfig, ) -> It<(Vec, Vec)> { Box::new( PrimitiveIntVecPairSameLenGenerator { phantom: PhantomData, lengths: geometric_random_positive_unsigneds( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ), xs: random_primitive_ints(EXAMPLE_SEED.fork("xs")), } .filter(|(ref xs, ref ys): &(Vec, Vec)| { (*xs.last().unwrap() != T::ZERO || *ys.last().unwrap() != T::ZERO) && ys[0].odd() }), ) } // var 28 is in malachite-nz. // -- (Vec, Vec, bool) -- pub fn random_primitive_int_vec_primitive_int_vec_bool_triple_gen_var_1( config: &GenConfig, ) -> It<(Vec, Vec, bool)> { reshape_2_1_to_3(Box::new(random_pairs( EXAMPLE_SEED, &|seed| PrimitiveIntVecPairSameLenGenerator { phantom: PhantomData, lengths: geometric_random_positive_unsigneds( seed.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ), xs: random_primitive_ints(seed.fork("xs")), }, &random_bools, ))) } // -- (Vec, Vec, PrimitiveInt) -- pub fn random_primitive_int_vec_primitive_int_vec_primitive_int_triple_gen_var_1< T: PrimitiveInt, >( config: &GenConfig, ) -> It<(Vec, Vec, T)> { reshape_2_1_to_3(Box::new(random_pairs( EXAMPLE_SEED, &|seed| random_primitive_int_vec_pair_gen_var_1_helper(config, seed), &random_primitive_ints, ))) } fn random_primitive_int_vec_pair_gen_var_2_helper( config: &GenConfig, seed: Seed, ) -> It<(Vec, Vec)> { Box::new(PrimitiveIntVecPairLenGenerator1 { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_positive_unsigneds( seed.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .map(|(x, y)| if x >= y { (x, y) } else { (y, x) }), xs: random_primitive_ints(seed.fork("xs")), }) } pub fn random_primitive_int_vec_primitive_int_vec_primitive_int_triple_gen_var_2< T: PrimitiveInt, >( config: &GenConfig, ) -> It<(Vec, Vec, T)> { reshape_2_1_to_3(Box::new(random_pairs( EXAMPLE_SEED, &|seed| random_primitive_int_vec_pair_gen_var_2_helper(config, seed), &random_primitive_ints, ))) } struct PrimitiveIntVecPairLenGenerator3> { phantom: PhantomData<*const T>, lengths: I, xs: RandomPrimitiveInts, } impl> Iterator for PrimitiveIntVecPairLenGenerator3 { type Item = (Vec, Vec); fn next(&mut self) -> Option<(Vec, Vec)> { let (i, j) = self.lengths.next().unwrap(); let xs = (&mut self.xs).take(i).collect(); let mut ys; loop { ys = (&mut self.xs).take(j).collect_vec(); if !slice_test_zero(&ys) { break; } } Some((xs, ys)) } } fn random_primitive_int_vec_pair_gen_var_3_helper( config: &GenConfig, seed: Seed, ) -> It<(Vec, Vec)> { Box::new(PrimitiveIntVecPairLenGenerator3 { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_positive_unsigneds( seed.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .map(|(x, y)| if x >= y { (x, y) } else { (y, x) }), xs: random_primitive_ints(seed.fork("xs")), }) } pub fn random_primitive_int_vec_primitive_int_vec_primitive_int_triple_gen_var_3< T: PrimitiveInt, >( config: &GenConfig, ) -> It<(Vec, Vec, T)> { reshape_2_1_to_3(Box::new(random_pairs( EXAMPLE_SEED, &|seed| random_primitive_int_vec_pair_gen_var_3_helper(config, seed), &random_primitive_ints, ))) } pub fn random_primitive_int_vec_primitive_int_vec_primitive_int_triple_gen_var_4< T: PrimitiveInt, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(Vec, Vec, U)> { Box::new(random_triples_xxy( EXAMPLE_SEED, &|seed| { random_vecs_min_length( seed, 2, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| *xs.last().unwrap() != T::ZERO) }, &random_positive_unsigneds, )) } pub fn random_primitive_int_vec_primitive_int_vec_primitive_int_triple_gen_var_5< T: PrimitiveInt, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(Vec, Vec, U)> { Box::new(random_triples_xxy( EXAMPLE_SEED, &|seed| { random_vecs_min_length( seed, 1, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| *xs.last().unwrap() != T::ZERO) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, )) } pub fn random_primitive_int_vec_primitive_int_vec_primitive_int_triple_gen_var_6< T: PrimitiveInt, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(Vec, Vec, U)> { Box::new(random_triples_xxy( EXAMPLE_SEED, &|seed| { random_vecs_min_length( seed, 1, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| *xs.last().unwrap() != T::ZERO) }, &random_positive_unsigneds, )) } pub fn random_primitive_int_vec_primitive_int_vec_primitive_int_triple_gen_var_7< T: PrimitiveInt, >( config: &GenConfig, ) -> It<(Vec, Vec, T)> { reshape_2_1_to_3(Box::new(random_pairs( EXAMPLE_SEED, &|seed| PrimitiveIntVecPairSameLenGenerator { phantom: PhantomData, lengths: geometric_random_positive_unsigneds( seed.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ), xs: random_primitive_ints(seed.fork("xs")), }, &random_primitive_ints, ))) } pub fn random_primitive_int_vec_primitive_int_vec_primitive_int_triple_gen_var_8< T: PrimitiveInt, U: PrimitiveInt, >( config: &GenConfig, ) -> It<(Vec, Vec, u64)> { reshape_2_1_to_3(Box::new(random_pairs( EXAMPLE_SEED, &|seed| random_primitive_int_vec_pair_gen_var_1_helper(config, seed), &|seed| random_unsigned_range(seed, 1, U::WIDTH), ))) } pub fn random_primitive_int_vec_primitive_int_vec_primitive_int_triple_gen_var_9< T: PrimitiveInt, U: PrimitiveInt, >( config: &GenConfig, ) -> It<(Vec, Vec, u64)> { reshape_2_1_to_3(Box::new(random_pairs( EXAMPLE_SEED, &|seed| PrimitiveIntVecPairLenGenerator1 { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_positive_unsigneds( seed.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .map(|(x, y)| if x >= y { (x, y) } else { (y, x) }), xs: random_primitive_ints(seed.fork("xs")), }, &|seed| random_unsigned_range(seed, 1, U::WIDTH), ))) } // -- (Vec, Vec, PrimitiveUnsigned) -- pub struct PrimitiveIntVecPairLenAndIndexGenerator< T: PrimitiveInt, I: Iterator, > { pub phantom: PhantomData<*const T>, pub lengths: I, pub xs: RandomPrimitiveInts, } impl> Iterator for PrimitiveIntVecPairLenAndIndexGenerator { type Item = (Vec, Vec, usize); fn next(&mut self) -> Option<(Vec, Vec, usize)> { let (i, j, k) = self.lengths.next().unwrap(); Some(( (&mut self.xs).take(i).collect(), (&mut self.xs).take(j).collect(), k, )) } } pub fn random_primitive_int_vec_primitive_int_vec_unsigned_triple_gen_var_1( config: &GenConfig, ) -> It<(Vec, Vec, usize)> { Box::new(PrimitiveIntVecPairLenAndIndexGenerator { phantom: PhantomData, lengths: random_triples_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(o, x, y)| { let x = x.checked_add(y)?; let o = o.checked_add(x)?; Some((o, x, y)) }), xs: random_primitive_ints(EXAMPLE_SEED.fork("xs")), }) } pub fn random_primitive_int_vec_primitive_int_vec_unsigned_triple_gen_var_2( config: &GenConfig, ) -> It<(Vec, Vec, usize)> { Box::new(PrimitiveIntVecPairLenAndIndexGenerator { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(x, i)| { let x = x.checked_add(i)?; Some((x, x, i)) }), xs: random_primitive_ints(EXAMPLE_SEED.fork("xs")), }) } // -- (Vec, Vec, Vec) -- pub struct PrimitiveIntVecTripleXYYLenGenerator> { pub phantom: PhantomData<*const T>, pub lengths: I, pub xs: RandomPrimitiveInts, } impl> Iterator for PrimitiveIntVecTripleXYYLenGenerator { type Item = (Vec, Vec, Vec); fn next(&mut self) -> Option<(Vec, Vec, Vec)> { let (i, j) = self.lengths.next().unwrap(); Some(( (&mut self.xs).take(i).collect(), (&mut self.xs).take(j).collect(), (&mut self.xs).take(j).collect(), )) } } pub fn random_primitive_int_vec_triple_gen_var_1( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new(PrimitiveIntVecTripleXYYLenGenerator { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(x, y)| { let y = y.checked_add(1)?; let x = x.checked_add(y.arithmetic_checked_shl(1)?)?; Some((x, y)) }), xs: random_primitive_ints(EXAMPLE_SEED.fork("xs")), }) } pub struct PrimitiveIntVecTripleLenGenerator1< T: PrimitiveInt, I: Iterator, > { pub phantom: PhantomData<*const T>, pub lengths: I, pub xs: RandomPrimitiveInts, } impl> Iterator for PrimitiveIntVecTripleLenGenerator1 { type Item = (Vec, Vec, Vec); fn next(&mut self) -> Option<(Vec, Vec, Vec)> { let (i, j, k) = self.lengths.next().unwrap(); Some(( (&mut self.xs).take(i).collect(), (&mut self.xs).take(j).collect(), (&mut self.xs).take(k).collect(), )) } } pub struct PrimitiveIntVecQuadrupleLenGenerator1< T: PrimitiveInt, I: Iterator, > { pub phantom: PhantomData<*const T>, pub lengths: I, pub xs: RandomPrimitiveInts, } impl> Iterator for PrimitiveIntVecQuadrupleLenGenerator1 { type Item = (Vec, Vec, Vec, Vec); fn next(&mut self) -> Option { let (i, j, k, l) = self.lengths.next().unwrap(); Some(( (&mut self.xs).take(i).collect(), (&mut self.xs).take(j).collect(), (&mut self.xs).take(k).collect(), (&mut self.xs).take(l).collect(), )) } } pub fn random_primitive_int_vec_triple_gen_var_2( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new(PrimitiveIntVecTripleLenGenerator1 { phantom: PhantomData, lengths: random_triples_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(o, x, y)| { let y = y.checked_add(1)?; let x = x.checked_add(y)?; let o = x.checked_add(y)?.checked_add(o)?; Some((o, x, y)) }), xs: random_primitive_ints(EXAMPLE_SEED.fork("xs")), }) } pub fn random_primitive_int_vec_triple_gen_var_3( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new(PrimitiveIntVecTripleLenGenerator1 { phantom: PhantomData, lengths: random_triples_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(o, x, y)| { let y = y.checked_add(1)?; let x = x.checked_add(1)?; let o = x.checked_add(y)?.checked_add(o)?; Some((o, x, y)) }), xs: random_primitive_ints(EXAMPLE_SEED.fork("xs")), }) } // vars 4 through 23 are in malachite-nz pub fn random_primitive_int_vec_triple_gen_var_24( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new(PrimitiveIntVecTripleXYYLenGenerator { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(x, y)| { let y = y.checked_add(1)?; let x = x.checked_add(y)?; Some((x, y)) }), xs: random_primitive_ints(EXAMPLE_SEED.fork("xs")), }) } pub fn random_primitive_int_vec_triple_gen_var_25( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new(PrimitiveIntVecTripleXYYLenGenerator { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(x, y)| { let y = y.checked_add(2)?; let x = x.checked_add(y.arithmetic_checked_shl(1)?)?; Some((x, y)) }), xs: random_primitive_ints(EXAMPLE_SEED.fork("xs")), }) } pub fn random_primitive_int_vec_triple_gen_var_26( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new(PrimitiveIntVecTripleXYYLenGenerator { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(x, y)| { let y = y.checked_add(2)?; let x = x.checked_add(y)?; Some((x, y)) }), xs: random_primitive_ints(EXAMPLE_SEED.fork("xs")), }) } struct PrimitiveIntVecTripleXXXLenGenerator> { pub phantom: PhantomData<*const T>, pub lengths: I, pub xs: RandomPrimitiveInts, } impl> Iterator for PrimitiveIntVecTripleXXXLenGenerator { type Item = (Vec, Vec, Vec); fn next(&mut self) -> Option<(Vec, Vec, Vec)> { let i = self.lengths.next().unwrap(); Some(( (&mut self.xs).take(i).collect(), (&mut self.xs).take(i).collect(), (&mut self.xs).take(i).collect(), )) } } pub fn random_primitive_int_vec_triple_gen_var_27( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new(PrimitiveIntVecTripleXXXLenGenerator { phantom: PhantomData, lengths: geometric_random_unsigned_range( EXAMPLE_SEED.fork("lengths"), 2, usize::MAX, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ), xs: random_primitive_ints(EXAMPLE_SEED.fork("xs")), }) } pub fn random_primitive_int_vec_triple_gen_var_28( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new(PrimitiveIntVecTripleXXXLenGenerator { phantom: PhantomData, lengths: geometric_random_unsigneds( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ), xs: random_primitive_ints(EXAMPLE_SEED.fork("xs")), }) } pub fn random_primitive_int_vec_triple_gen_var_29( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new(random_triples_from_single( random_vecs( EXAMPLE_SEED, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| xs.last() != Some(&T::ZERO)), )) } pub fn random_primitive_int_vec_triple_gen_var_30( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new(PrimitiveIntVecTripleXYYLenGenerator { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(x, y)| { let x = x.checked_add(y)?; Some((x, y)) }), xs: random_primitive_ints(EXAMPLE_SEED.fork("xs")), }) } pub fn random_primitive_int_vec_triple_gen_var_31( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new(PrimitiveIntVecTripleLenGenerator1 { phantom: PhantomData, lengths: random_triples_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(o, x, y)| { let o = max(x, y).checked_add(o)?; Some((o, x, y)) }), xs: random_primitive_ints(EXAMPLE_SEED.fork("xs")), }) } struct PrimitiveIntVecTripleLenGenerator2< T: PrimitiveInt, I: Iterator, > { pub phantom: PhantomData<*const T>, pub lengths: I, pub xs: RandomPrimitiveInts, } impl> Iterator for PrimitiveIntVecTripleLenGenerator2 { type Item = (Vec, Vec, Vec); fn next(&mut self) -> Option<(Vec, Vec, Vec)> { let (i, j, k) = self.lengths.next().unwrap(); let out = (&mut self.xs).take(i).collect(); let mut xs; loop { xs = (&mut self.xs).take(j).collect_vec(); if !slice_test_zero(&xs) { break; } } let mut ys; loop { ys = (&mut self.xs).take(k).collect_vec(); if !slice_test_zero(&ys) { break; } } Some((out, xs, ys)) } } pub fn random_primitive_int_vec_triple_gen_var_32( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new(PrimitiveIntVecTripleLenGenerator2 { phantom: PhantomData, lengths: random_triples_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(o, x, y)| { let x = x.checked_add(1)?; let y = y.checked_add(1)?; let o = o.checked_add(x)?; Some((o, x, y)) }), xs: random_primitive_ints(EXAMPLE_SEED.fork("xs")), }) } pub fn random_primitive_int_vec_triple_gen_var_33( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new(PrimitiveIntVecTripleLenGenerator2 { phantom: PhantomData, lengths: random_triples_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(o, x, y)| { let x = x.checked_add(1)?; let y = y.checked_add(1)?; let o = o.checked_add(max(x, y))?; Some((o, x, y)) }), xs: random_primitive_ints(EXAMPLE_SEED.fork("xs")), }) } pub fn random_primitive_int_vec_triple_gen_var_34( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new(PrimitiveIntVecTripleLenGenerator2 { phantom: PhantomData, lengths: random_triples_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(o, x, y)| { let x = x.checked_add(1)?; let y = y.checked_add(1)?; let o = o.checked_add(min(x, y))?; Some((o, x, y)) }), xs: random_primitive_ints(EXAMPLE_SEED.fork("xs")), }) } pub fn random_primitive_int_vec_triple_gen_var_35( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new(random_triples_from_single( random_vecs_min_length( EXAMPLE_SEED, 2, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| *xs.last().unwrap() != T::ZERO), )) } // vars 36 through 37 are in malachite-nz. pub fn random_primitive_int_vec_triple_gen_var_38( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new(random_triples_from_single( random_vecs_min_length( EXAMPLE_SEED, 1, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| *xs.last().unwrap() != T::ZERO), )) } pub fn random_primitive_int_vec_triple_gen_var_39( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new(PrimitiveIntVecTripleLenGenerator1 { phantom: PhantomData, lengths: random_triples_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(o, x, y)| { let x = x.checked_add(y)?; let o = o.checked_add(x)?; Some((o, x, y)) }), xs: random_primitive_ints(EXAMPLE_SEED.fork("xs")), }) } pub fn random_primitive_int_vec_triple_gen_var_40( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new(random_triples_xxy( EXAMPLE_SEED, &|seed| { random_vecs_min_length( seed, 1, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| *xs.last().unwrap() != T::ZERO) }, &|seed| { random_vecs_min_length( seed, 2, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| *xs.last().unwrap() != T::ZERO) }, )) } pub fn random_primitive_int_vec_triple_gen_var_41( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new( PrimitiveIntVecTripleLenGenerator1 { phantom: PhantomData, lengths: random_triples_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(x, y, z)| { let y = y.checked_add(1)?; let x = x.checked_add(y)?; let z = z.checked_add(y.arithmetic_checked_shl(1)?)?; Some((x, y, z)) }), xs: random_primitive_ints::(EXAMPLE_SEED.fork("xs")), } .map(|(x, mut y, z)| { y.last_mut().unwrap().set_bit(T::WIDTH - 1); (x, y, z) }), ) } pub fn random_primitive_int_vec_triple_gen_var_42( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new( PrimitiveIntVecTripleLenGenerator1 { phantom: PhantomData, lengths: random_triples_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(x, y, z)| { let y = y.checked_add(5)?; let x = x.checked_add(y)?; let z = z.checked_add(y.arithmetic_checked_shl(1)?)?; Some((x, y, z)) }), xs: random_primitive_ints::(EXAMPLE_SEED.fork("xs")), } .map(|(x, mut y, z)| { y.last_mut().unwrap().set_bit(T::WIDTH - 1); (x, y, z) }), ) } pub fn random_primitive_int_vec_triple_gen_var_43( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new( PrimitiveIntVecTripleLenGenerator1 { phantom: PhantomData, lengths: random_triples_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(x, y, z)| { let q = x.checked_add(3)?; let n = y.checked_add(9)?; let d = z.checked_add(6)?; if n < d { return None; } let q_alt = n - d + 1; if (q_alt << 1) > n || q_alt > d { return None; } let n_alt = q_alt << 1; let d_alt = q_alt; if q >= q_alt && d_alt >= 6 && n_alt >= d_alt + 3 && d_alt >= q_alt { Some((q, n, d)) } else { None } }), xs: random_primitive_ints::(EXAMPLE_SEED.fork("xs")), } .map(|(x, y, mut z)| { z.last_mut().unwrap().set_bit(T::WIDTH - 1); (x, y, z) }), ) } pub fn random_primitive_int_vec_triple_gen_var_44( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new( PrimitiveIntVecTripleLenGenerator1 { phantom: PhantomData, lengths: random_triples_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(r_len, n_len, d_len)| { let d_len = d_len.checked_add(2)?; let r_len = r_len.checked_add(d_len)?; let n_len = n_len.checked_add(d_len)?; Some((r_len, n_len, d_len)) }), xs: random_primitive_ints(EXAMPLE_SEED.fork("xs")), } .filter_map(|(r, n, mut d): (Vec, Vec, Vec)| { let last_d = d.last_mut().unwrap(); *last_d = last_d.checked_add(T::ONE)?; Some((r, n, d)) }), ) } // var 45 is in malachite-nz. pub fn random_primitive_int_vec_triple_gen_var_46( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new( PrimitiveIntVecTripleLenGenerator1 { phantom: PhantomData, lengths: random_triples_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(xs_len, ys_len, zs_len)| { let ys_len = ys_len.checked_add(2)?; let zs_len = zs_len.checked_add(2)?; let xs_len = xs_len.checked_add(ys_len + zs_len - 1)?; Some((xs_len, ys_len, zs_len)) }), xs: random_primitive_ints(EXAMPLE_SEED.fork("xs")), } .filter_map(|(mut xs, mut ys, mut zs): (Vec, Vec, Vec)| { let last_x = xs.last_mut().unwrap(); *last_x = last_x.checked_add(T::ONE)?; let last_y = ys.last_mut().unwrap(); *last_y = last_y.checked_add(T::ONE)?; let last_z = zs.last_mut().unwrap(); *last_z = last_z.checked_add(T::ONE)?; Some((xs, ys, zs)) }), ) } // var 47 is in malachite-nz. // -- (Vec, PrimitiveUnsigned) -- struct UnsignedVecUnsignedPairGeneratorVar1 { log_bases: GeometricRandomNaturalValues, ranges: VariableRangeGenerator, phantom_t: PhantomData<*const T>, phantom_u: PhantomData<*const U>, } impl Iterator for UnsignedVecUnsignedPairGeneratorVar1 { type Item = (Vec, u64); fn next(&mut self) -> Option<(Vec, u64)> { let log_base = self.log_bases.next().unwrap(); let max_count = usize::exact_from(T::WIDTH.div_round(log_base, Ceiling).0); loop { let digit_count = self.ranges.next_in_inclusive_range(0, max_count); let mut digits = Vec::with_capacity(digit_count); for _ in 0..digit_count { digits.push(self.ranges.next_bit_chunk(log_base)); } if digits_valid::(log_base, &digits) { return Some((digits, log_base)); } } } } pub fn random_unsigned_vec_unsigned_pair_gen_var_1( config: &GenConfig, ) -> It<(Vec, u64)> { Box::new(UnsignedVecUnsignedPairGeneratorVar1:: { log_bases: geometric_random_unsigned_range( EXAMPLE_SEED.fork("log_bases"), 1, U::WIDTH, config.get_or("mean_log_base_n", 4), config.get_or("mean_log_base_d", 1), ), ranges: VariableRangeGenerator::new(EXAMPLE_SEED.fork("ranges")), phantom_t: PhantomData, phantom_u: PhantomData, }) } pub fn random_unsigned_vec_unsigned_pair_gen_var_2( config: &GenConfig, ) -> It<(Vec, u64)> { Box::new( random_unsigned_vec_unsigned_pair_gen_var_1::(config) .map(|(xs, y)| (xs.into_iter().rev().collect(), y)), ) } struct BasecaseDigitsRandomGenerator< T: ExactFrom + PrimitiveUnsigned, U: PrimitiveUnsigned + SaturatingFrom, > { bases: RandomUnsignedInclusiveRange, digit_counts: GeometricRandomNaturalValues, digits: VariableRangeGenerator, phantom: PhantomData<*const T>, } impl + PrimitiveUnsigned, U: PrimitiveUnsigned + SaturatingFrom> Iterator for BasecaseDigitsRandomGenerator { type Item = (Vec, U); fn next(&mut self) -> Option<(Vec, U)> { let base = self.bases.next().unwrap(); let digit_count = self.digit_counts.next().unwrap(); let mut digits = Vec::with_capacity(digit_count); let t_base = T::exact_from(base); for _ in 0..digit_count { digits.push(self.digits.next_less_than(t_base)); } Some((digits, base)) } } pub fn random_unsigned_vec_unsigned_pair_gen_var_3< T: ExactFrom + PrimitiveUnsigned, U: PrimitiveUnsigned + SaturatingFrom, >( config: &GenConfig, ) -> It<(Vec, U)> { Box::new(BasecaseDigitsRandomGenerator { bases: random_unsigned_inclusive_range( EXAMPLE_SEED.fork("bases"), U::TWO, U::saturating_from(T::MAX), ), digit_counts: geometric_random_unsigneds( EXAMPLE_SEED.fork("digit_counts"), config.get_or("mean_digit_count_n", 4), config.get_or("mean_digit_count_d", 1), ), digits: VariableRangeGenerator::new(EXAMPLE_SEED.fork("ranges")), phantom: PhantomData, }) } struct DigitsDesc + PrimitiveUnsigned> { ranges: VariableRangeGenerator, phantom_t: PhantomData<*const T>, phantom_u: PhantomData<*const U>, } impl, U: Digits + PrimitiveUnsigned> Iterator for DigitsDesc { type Item = (Vec, T); fn next(&mut self) -> Option<(Vec, T)> { let base = self .ranges .next_in_inclusive_range(T::TWO, T::saturating_from(U::MAX)); let max_digits = U::MAX.to_digits_desc(&base); let max_digits_len = max_digits.len(); loop { let digit_count = self.ranges.next_in_inclusive_range(0, max_digits_len); let mut ds = Vec::with_capacity(digit_count); for _ in 0..digit_count { ds.push(self.ranges.next_less_than(base)); } if digit_count < max_digits_len || ds <= max_digits { return Some((ds, base)); } } } } pub fn random_unsigned_vec_unsigned_pair_gen_var_4< T: PrimitiveUnsigned + SaturatingFrom, U: Digits + PrimitiveUnsigned, >( _config: &GenConfig, ) -> It<(Vec, T)> { Box::new(DigitsDesc:: { ranges: VariableRangeGenerator::new(EXAMPLE_SEED.fork("ranges")), phantom_t: PhantomData, phantom_u: PhantomData, }) } pub fn random_unsigned_vec_unsigned_pair_gen_var_5< T: PrimitiveUnsigned + SaturatingFrom, U: Digits + PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(Vec, T)> { Box::new( random_unsigned_vec_unsigned_pair_gen_var_4::(config).map(|(mut xs, base)| { xs.reverse(); (xs, base) }), ) } pub fn random_unsigned_vec_unsigned_pair_gen_var_6( config: &GenConfig, ) -> It<(Vec, T)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { random_vecs( seed, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| random_unsigned_inclusive_range(seed, T::TWO, T::MAX), )) } struct PowerOfTwoDigitsGenerator { log_bases: GeometricRandomNaturalValues, digit_counts: GeometricRandomNaturalValues, ranges: VariableRangeGenerator, phantom: PhantomData<*const T>, } impl Iterator for PowerOfTwoDigitsGenerator { type Item = (Vec, u64); fn next(&mut self) -> Option<(Vec, u64)> { let log_base = self.log_bases.next().unwrap(); let digit_count = self.digit_counts.next().unwrap(); let mut digits = Vec::with_capacity(digit_count); for _ in 0..digit_count { digits.push(self.ranges.next_bit_chunk(log_base)); } Some((digits, log_base)) } } pub fn random_unsigned_vec_unsigned_pair_gen_var_7( config: &GenConfig, ) -> It<(Vec, u64)> { Box::new(PowerOfTwoDigitsGenerator:: { log_bases: geometric_random_unsigned_range( EXAMPLE_SEED.fork("log_bases"), 1, T::WIDTH, config.get_or("mean_log_base_n", 4), config.get_or("mean_log_base_d", 1), ), digit_counts: geometric_random_unsigneds( EXAMPLE_SEED.fork("digit_count"), config.get_or("mean_digit_count_n", 4), config.get_or("mean_digit_count_d", 1), ), ranges: VariableRangeGenerator::new(EXAMPLE_SEED.fork("ranges")), phantom: PhantomData, }) } // vars 8 through 11 are in malachite-nz. // -- (Vec, PrimitiveUnsigned, PrimitiveUnsigned) -- // vars 1 through 2 are in malachite-nz. pub fn random_unsigned_vec_unsigned_unsigned_triple_gen_var_3( config: &GenConfig, ) -> It<(Vec, T, T)> { Box::new(random_triples( EXAMPLE_SEED, &|seed| { random_vecs_min_length( seed, 1, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| { random_unsigned_inclusive_range(seed, T::ZERO, T::low_mask(T::WIDTH - 1)) .map(|u| (u << 1) | T::ONE) }, &random_primitive_ints, )) } // vars 4 through 6 are in malachite-nz. // -- (Vec, Vec) -- struct UnsignedVecSqrtRemGenerator> { pub phantom: PhantomData<*const T>, pub lengths: I, pub xs: RandomPrimitiveInts, hi_n_bits: RandomUnsignedRange, } impl> Iterator for UnsignedVecSqrtRemGenerator { type Item = (Vec, Vec); fn next(&mut self) -> Option<(Vec, Vec)> { let (out_len, len) = self.lengths.next().unwrap(); let out = (&mut self.xs).take(out_len).collect(); let mut ns: Vec = (&mut self.xs).take(len).collect(); let n_hi = &mut ns[(usize::exact_from(out_len) << 1) - 1]; n_hi.mod_power_of_2_assign(T::WIDTH - 2); *n_hi |= self.hi_n_bits.next().unwrap() << (T::WIDTH - 2); Some((out, ns)) } } pub fn random_unsigned_vec_pair_gen_var_1( config: &GenConfig, ) -> It<(Vec, Vec)> { Box::new(UnsignedVecSqrtRemGenerator { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(x, y)| { let out_len = x.checked_add(2)?; let len: usize = out_len.arithmetic_checked_shl(1)?; let len = len.checked_add(y)?; Some((out_len, len)) }), xs: random_primitive_ints(EXAMPLE_SEED.fork("xs")), hi_n_bits: random_unsigned_range(EXAMPLE_SEED.fork("hi_n_bits"), T::ONE, T::exact_from(4)), }) } struct UnsignedVecSqrtGenerator> { pub phantom: PhantomData<*const T>, pub lengths: I, pub xs: RandomPrimitiveInts, } impl> Iterator for UnsignedVecSqrtGenerator { type Item = (Vec, Vec); fn next(&mut self) -> Option<(Vec, Vec)> { let (out_len, len) = self.lengths.next().unwrap(); let out = (&mut self.xs).take(out_len).collect(); let mut ns: Vec = (&mut self.xs).take(len).collect(); let hi_n = ns.last_mut().unwrap(); if *hi_n == T::ZERO { *hi_n = T::ONE; } Some((out, ns)) } } pub fn random_unsigned_vec_pair_gen_var_2( config: &GenConfig, ) -> It<(Vec, Vec)> { Box::new(UnsignedVecSqrtGenerator { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(x, y)| { let in_len = x.checked_add(1)?; let mut out_len: usize = in_len.shr_round(1, Ceiling).0; out_len = out_len.checked_add(y)?; Some((out_len, in_len)) }), xs: random_primitive_ints(EXAMPLE_SEED.fork("xs")), }) } // vars 3 through 4 are in malachite-nz. pub fn random_unsigned_vec_pair_gen_var_5( config: &GenConfig, ) -> It<(Vec, Vec)> { Box::new( random_triples( EXAMPLE_SEED, &|seed| { random_vecs_min_length( seed, 2, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| random_unsigned_inclusive_range(seed, T::power_of_2(T::WIDTH - 1), T::MAX), &random_primitive_ints, ) .map(|(n, d_1, d_0)| (n, vec![d_0, d_1])), ) } // -- (Vec, Vec, PrimitiveUnsigned) -- pub fn random_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_1( config: &GenConfig, ) -> It<(Vec, Vec, T)> { reshape_2_1_to_3(Box::new(random_pairs( EXAMPLE_SEED, &|seed| PrimitiveIntVecPairLenGenerator1 { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_unsigned_inclusive_range( seed.fork("lengths"), 2, usize::MAX, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .map(|(x, y)| if x >= y { (x, y) } else { (y, x) }), xs: random_primitive_ints(seed.fork("xs")), }, &random_positive_unsigneds, ))) } // var 2 is in malachite-nz. // -- (Vec, Vec, Vec) -- // vars 1 through 8 are in malachite-nz. struct UnsignedVecSqrtRemGenerator3> { pub phantom: PhantomData<*const T>, pub lengths: I, pub xs: RandomPrimitiveInts, } impl> Iterator for UnsignedVecSqrtRemGenerator3 { type Item = (Vec, Vec, Vec); fn next(&mut self) -> Option<(Vec, Vec, Vec)> { let (out_len, rs_len, len) = self.lengths.next().unwrap(); let out = (&mut self.xs).take(out_len).collect(); let rs = (&mut self.xs).take(rs_len).collect(); let mut ns: Vec = (&mut self.xs).take(len).collect(); let hi_n = ns.last_mut().unwrap(); if *hi_n == T::ZERO { *hi_n = T::ONE; } Some((out, rs, ns)) } } pub fn random_unsigned_vec_triple_gen_var_9( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new(UnsignedVecSqrtRemGenerator3 { phantom: PhantomData, lengths: random_triples_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(x, y, z)| { let in_len = x.checked_add(1)?; let mut out_len: usize = in_len.shr_round(1, Ceiling).0; out_len = out_len.checked_add(y)?; let rem_len = in_len.checked_add(z)?; Some((out_len, rem_len, in_len)) }), xs: random_primitive_ints(EXAMPLE_SEED.fork("xs")), }) } pub fn random_unsigned_vec_triple_gen_var_10( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new( random_pairs( EXAMPLE_SEED, &|seed| PrimitiveIntVecPairLenGenerator1 { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_positive_unsigneds( seed.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter(|&(x, y)| x >= y - 2), xs: random_primitive_ints(seed.fork("xs")), }, &|seed| { random_pairs( seed, &|seed_2| { random_unsigned_inclusive_range(seed_2, T::power_of_2(T::WIDTH - 1), T::MAX) }, &random_primitive_ints, ) }, ) .map(|((q, n), (d_1, d_0))| (q, n, vec![d_0, d_1])), ) } // var 11 is in malachite-nz. // -- large types -- pub fn random_large_type_gen_var_1( config: &GenConfig, ) -> It<(Vec, Vec, T, T)> { reshape_2_2_to_4(Box::new(random_pairs( EXAMPLE_SEED, &|seed| random_primitive_int_vec_pair_gen_var_1_helper(config, seed), &|seed| random_pairs_from_single(random_primitive_ints(seed)), ))) } struct UnsignedVecSqrtRemGenerator2 { pub phantom: PhantomData<*const T>, pub lengths: GeometricRandomNaturalValues, pub xs: RandomPrimitiveInts, } impl Iterator for UnsignedVecSqrtRemGenerator2 { type Item = (Vec, Vec, u64, bool); fn next(&mut self) -> Option<(Vec, Vec, u64, bool)> { let len = self.lengths.next().unwrap(); let n = len.shr_round(1, Ceiling).0; let out = (&mut self.xs).take(n).collect(); let mut ns: Vec = (&mut self.xs).take(len).collect(); let last = ns.last_mut().unwrap(); if *last == T::ZERO { *last = T::ONE; } let shift = last.leading_zeros() >> 1; Some((out, ns, shift, len.odd())) } } pub fn random_large_type_gen_var_2( config: &GenConfig, ) -> It<(Vec, Vec, u64, bool)> { Box::new(UnsignedVecSqrtRemGenerator2 { phantom: PhantomData, lengths: geometric_random_unsigned_range::( EXAMPLE_SEED.fork("lengths"), 9, usize::MAX, config.get_or("mean_length_n", 12), config.get_or("mean_length_d", 1), ), xs: random_primitive_ints(EXAMPLE_SEED.fork("xs")), }) } pub fn random_large_type_gen_var_3( config: &GenConfig, ) -> It<(Vec, U, U, Vec)> { Box::new( random_quadruples_xyyx::<_, _, U, _>( EXAMPLE_SEED, &|seed| { random_vecs( seed, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, ) .filter_map(|(x, y, z, w)| match y.cmp(&z) { Less => Some((x, y, z, w)), Greater => Some((x, z, y, w)), Equal => None, }), ) } pub fn random_large_type_gen_var_4( config: &GenConfig, ) -> It<(Vec, U, U, Vec)> { Box::new( random_quadruples_xyyz( EXAMPLE_SEED, &|seed| { random_vecs( seed, &random_primitive_ints::, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| !slice_test_zero(xs)) }, &|seed| { geometric_random_unsigneds::( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, &|seed| { random_vecs( seed, &random_primitive_ints::, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, ) .filter_map(|(x, y, z, w)| match y.cmp(&z) { Less => Some((x, y, z, w)), Greater => Some((x, z, y, w)), Equal => None, }), ) } // vars 5 through 8 are in malachite-nz #[allow(clippy::type_complexity)] pub fn random_large_type_gen_var_9( config: &GenConfig, ) -> It<(Vec, Vec, Vec, bool)> { reshape_3_1_to_4(Box::new(random_pairs( EXAMPLE_SEED, &|seed| PrimitiveIntVecTripleXYYLenGenerator { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_unsigneds::( seed.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(x, y)| { let x = x.checked_add(y)?; Some((x, y)) }), xs: random_primitive_ints(seed.fork("xs")), }, &random_bools, ))) } // vars 10 through 21 are in malachite-nz. pub fn random_large_type_gen_var_22( config: &GenConfig, ) -> It<(RationalSequence, usize, T, T)> { Box::new( random_quadruples_xyzz( EXAMPLE_SEED, &|seed| { random_rational_sequences( seed, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_unsigned_n", 32), config.get_or("mean_small_unsigned_d", 1), ) }, &random_primitive_ints, ) .filter(|&(ref xs, index, _, _)| { if let Some(len) = xs.len() { index < len } else { true } }), ) } // vars 23 through 26 are in malachite-nz. pub fn random_large_type_gen_var_27( config: &GenConfig, ) -> It<(bool, Vec, bool, Vec)> { Box::new(random_quadruples_xyxy( EXAMPLE_SEED, &random_bools, &|seed| { random_vecs( seed, &random_primitive_ints, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| xs.last() != Some(&T::ZERO)) }, )) } malachite-base-0.4.16/src/test_util/generators/special_random.rs000064400000000000000000011260511046102023000230630ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::bools::random::random_bools; use crate::chars::constants::NUMBER_OF_CHARS; use crate::chars::random::{ graphic_weighted_random_ascii_chars, graphic_weighted_random_char_inclusive_range, graphic_weighted_random_char_range, graphic_weighted_random_chars, }; use crate::comparison::traits::Min; use crate::iterators::{with_special_value, NonzeroValues}; use crate::num::arithmetic::traits::{ ArithmeticCheckedShl, DivRound, Parity, PowerOf2, ShrRound, UnsignedAbs, }; use crate::num::basic::floats::PrimitiveFloat; use crate::num::basic::integers::PrimitiveInt; use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::string::options::random::{ random_from_sci_string_options, random_to_sci_options, }; use crate::num::conversion::string::options::{FromSciStringOptions, ToSciOptions}; use crate::num::conversion::traits::{ ConvertibleFrom, ExactFrom, HasHalf, JoinHalves, RoundingFrom, SaturatingFrom, SplitInHalf, WrappingFrom, WrappingInto, }; use crate::num::float::NiceFloat; use crate::num::logic::traits::{BitAccess, BitBlockAccess, LeadingZeros}; use crate::num::random::geometric::{ geometric_random_natural_signeds, geometric_random_nonzero_signeds, geometric_random_positive_unsigneds, geometric_random_signed_inclusive_range, geometric_random_signed_range, geometric_random_signeds, geometric_random_unsigned_inclusive_range, geometric_random_unsigned_range, geometric_random_unsigneds, GeometricRandomNaturalValues, GeometricRandomSignedRange, GeometricRandomSigneds, }; use crate::num::random::striped::{ get_striped_bool_vec, get_striped_unsigned_vec, striped_random_bool_vecs, striped_random_bool_vecs_length_inclusive_range, striped_random_bool_vecs_min_length, striped_random_fixed_length_bool_vecs, striped_random_natural_signeds, striped_random_negative_signeds, striped_random_nonzero_signeds, striped_random_positive_signeds, striped_random_positive_unsigneds, striped_random_signed_inclusive_range, striped_random_signed_range, striped_random_signeds, striped_random_unsigned_bit_chunks, striped_random_unsigned_inclusive_range, striped_random_unsigned_range, striped_random_unsigned_vecs, striped_random_unsigned_vecs_min_length, striped_random_unsigneds, StripedBitSource, StripedRandomSigneds, StripedRandomUnsignedBitChunks, StripedRandomUnsignedInclusiveRange, }; use crate::num::random::{ random_finite_primitive_floats, random_nonzero_finite_primitive_floats, random_positive_finite_primitive_floats, random_primitive_float_inclusive_range, random_primitive_float_range, random_primitive_floats, random_unsigneds_less_than, RandomPrimitiveFloatInclusiveRange, VariableRangeGenerator, }; use crate::random::{Seed, EXAMPLE_SEED}; use crate::rational_sequences::random::random_rational_sequences; use crate::rational_sequences::RationalSequence; use crate::rounding_modes::random::{random_rounding_modes, RandomRoundingModes}; use crate::rounding_modes::RoundingMode::{self, *}; use crate::slices::slice_test_zero; use crate::strings::random::random_strings_using_chars; use crate::test_util::extra_variadic::{ random_duodecuples_from_single, random_octuples_from_single, random_quadruples_from_single, random_quadruples_xxxy, random_quadruples_xxyx, random_quadruples_xyxy, random_quadruples_xyyx, random_quadruples_xyyz, random_quadruples_xyzz, random_sextuples_from_single, random_triples, random_triples_from_single, random_triples_xxy, random_triples_xyx, random_triples_xyy, random_union3s, Union3, }; use crate::test_util::generators::common::{ reshape_1_2_to_3, reshape_2_1_to_3, reshape_2_2_to_4, reshape_3_1_to_4, GenConfig, It, }; use crate::test_util::generators::{ digits_valid, float_rounding_mode_filter_var_1, get_two_highest, large_exponent, reduce_to_fit_add_mul_signed, reduce_to_fit_add_mul_unsigned, reduce_to_fit_sub_mul_signed, reduce_to_fit_sub_mul_unsigned, round_to_multiple_of_power_of_2_filter_map, round_to_multiple_signed_filter_map, round_to_multiple_unsigned_filter_map, shift_integer_mantissa_and_exponent, signed_assign_bits_valid, smallest_invalid_value, unsigned_assign_bits_valid, }; use crate::test_util::num::arithmetic::mod_mul::limbs_invert_limb_naive; use crate::tuples::random::{random_ordered_unique_pairs, random_pairs, random_pairs_from_single}; use crate::unions::random::random_union2s; use crate::unions::Union2; use itertools::repeat_n; use itertools::Itertools; use std::cmp::{max, min, Ordering::*}; use std::collections::HashMap; use std::marker::PhantomData; // -- char -- pub fn special_random_char_gen(config: &GenConfig) -> It { Box::new(graphic_weighted_random_chars( EXAMPLE_SEED, config.get_or("graphic_char_prob_n", 50), config.get_or("graphic_char_prob_d", 51), )) } #[allow(unstable_name_collisions)] pub fn special_random_char_gen_var_1(config: &GenConfig) -> It { Box::new(graphic_weighted_random_char_range( EXAMPLE_SEED, char::MIN, char::MAX, config.get_or("graphic_char_prob_n", 50), config.get_or("graphic_char_prob_d", 51), )) } #[allow(unstable_name_collisions)] pub fn special_random_char_gen_var_2(config: &GenConfig) -> It { Box::new(graphic_weighted_random_char_inclusive_range( EXAMPLE_SEED, '\u{1}', char::MAX, config.get_or("graphic_char_prob_n", 50), config.get_or("graphic_char_prob_d", 51), )) } // -- (char, char) -- pub fn special_random_char_pair_gen(config: &GenConfig) -> It<(char, char)> { Box::new(random_pairs_from_single(graphic_weighted_random_chars( EXAMPLE_SEED, config.get_or("graphic_char_prob_n", 50), config.get_or("graphic_char_prob_d", 51), ))) } // -- (FromSciStringOptions, PrimitiveUnsigned> -- pub fn special_random_from_sci_string_options_unsigned_pair_gen_var_1( config: &GenConfig, ) -> It<(FromSciStringOptions, T)> { Box::new(random_pairs( EXAMPLE_SEED, &random_from_sci_string_options, &|seed| { striped_random_unsigned_inclusive_range( seed, T::TWO, T::from(36u8), config.get_or("mean_stripe_n", T::WIDTH), config.get_or("mean_stripe_d", 1), ) }, )) } // -- PrimitiveFloat -- pub fn special_random_primitive_float_gen(_config: &GenConfig) -> It { Box::new(random_primitive_floats(EXAMPLE_SEED)) } pub fn special_random_primitive_float_gen_var_1(_config: &GenConfig) -> It { Box::new(random_primitive_float_range( EXAMPLE_SEED, T::NEGATIVE_ONE / T::TWO, T::INFINITY, )) } struct SpecialRandomPositiveNaturalFloats { exponents: GeometricRandomSignedRange, mantissas: StripedRandomUnsignedBitChunks, phantom: PhantomData, } impl Iterator for SpecialRandomPositiveNaturalFloats { type Item = T; fn next(&mut self) -> Option { let exponent = self.exponents.next().unwrap(); let mut mantissa = self.mantissas.next().unwrap(); if exponent != 0 { mantissa.set_bit(T::MANTISSA_WIDTH); } else if mantissa == 0 { mantissa = 1; } Some(T::from_integer_mantissa_and_exponent(mantissa, exponent).unwrap()) } } fn special_random_positive_natural_floats( seed: Seed, mean_exponent_numerator: u64, mean_exponent_denominator: u64, mean_stripe_numerator: u64, mean_stripe_denominator: u64, ) -> SpecialRandomPositiveNaturalFloats { SpecialRandomPositiveNaturalFloats { exponents: geometric_random_signed_range( seed.fork("exponents"), 0, i64::power_of_2(T::EXPONENT_WIDTH - 1) - i64::wrapping_from(T::MANTISSA_WIDTH) - 1, mean_exponent_numerator, mean_exponent_denominator, ), mantissas: striped_random_unsigned_bit_chunks( seed.fork("mantissas"), T::MANTISSA_WIDTH + 1, mean_stripe_numerator, mean_stripe_denominator, ), phantom: PhantomData, } } pub fn special_random_primitive_float_gen_var_2(config: &GenConfig) -> It { Box::new(with_special_value(EXAMPLE_SEED, T::ZERO, 1, 100, &|seed| { special_random_positive_natural_floats( seed, config.get_or("exponent_mean_n", 8), config.get_or("exponent_mean_d", 1), config.get_or("mean_stripe_n", 16), config.get_or("mean_stripe_d", 1), ) })) } pub fn special_random_primitive_float_gen_var_3(_config: &GenConfig) -> It { Box::new(random_positive_finite_primitive_floats::(EXAMPLE_SEED).filter(|f| !f.is_integer())) } pub fn special_random_primitive_float_gen_var_4(_config: &GenConfig) -> It { Box::new( random_primitive_float_inclusive_range::( EXAMPLE_SEED, T::ONE, T::from_integer_mantissa_and_exponent(1, i64::wrapping_from(T::MANTISSA_WIDTH)) .unwrap(), ) .map(|f| f.floor() - T::ONE / T::TWO), ) } pub fn special_random_primitive_float_gen_var_5(config: &GenConfig) -> It { Box::new( random_pairs( EXAMPLE_SEED, &|seed| { with_special_value(seed, T::ZERO, 1, 100, &|seed_2| { special_random_positive_natural_floats( seed_2, config.get_or("exponent_mean_n", 8), config.get_or("exponent_mean_d", 1), config.get_or("mean_stripe_n", 16), config.get_or("mean_stripe_d", 1), ) }) }, &random_bools, ) .map(|(f, b)| if b { f } else { -f }), ) } pub fn special_random_primitive_float_gen_var_6(_config: &GenConfig) -> It { Box::new( random_pairs( EXAMPLE_SEED, &|seed| random_positive_finite_primitive_floats::(seed).filter(|f| !f.is_integer()), &random_bools, ) .map(|(f, b)| if b { f } else { -f }), ) } pub fn special_random_primitive_float_gen_var_7(_config: &GenConfig) -> It { Box::new( random_pairs( EXAMPLE_SEED, &|seed| { random_primitive_float_inclusive_range::( seed, T::ONE, T::from_integer_mantissa_and_exponent(1, i64::wrapping_from(T::MANTISSA_WIDTH)) .unwrap(), ) .map(|f| f.floor() - T::ONE / T::TWO) }, &random_bools, ) .map(|(f, b)| if b { f } else { -f }), ) } pub fn special_random_primitive_float_gen_var_8(_config: &GenConfig) -> It { Box::new(random_finite_primitive_floats(EXAMPLE_SEED)) } pub fn special_random_primitive_float_gen_var_9(_config: &GenConfig) -> It { Box::new( random_primitive_floats::(EXAMPLE_SEED).filter(|&f| !f.is_nan() && f != T::INFINITY), ) } pub fn special_random_primitive_float_gen_var_10(_config: &GenConfig) -> It { Box::new( random_primitive_floats::(EXAMPLE_SEED) .filter(|&f| !f.is_nan() && f != T::NEGATIVE_INFINITY), ) } pub fn special_random_primitive_float_gen_var_11(_config: &GenConfig) -> It { Box::new(random_primitive_floats::(EXAMPLE_SEED).filter(|&f| !f.is_nan())) } pub fn special_random_primitive_float_gen_var_12(_config: &GenConfig) -> It { Box::new(random_nonzero_finite_primitive_floats(EXAMPLE_SEED)) } pub fn special_random_primitive_float_gen_var_13< T: PrimitiveFloat + RoundingFrom, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It { Box::new( striped_random_unsigneds::( EXAMPLE_SEED, config.get_or("mean_stripe_n", U::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) .map(|n| T::rounding_from(n, Down).0), ) } pub fn special_random_primitive_float_gen_var_14< T: PrimitiveFloat + RoundingFrom, U: PrimitiveSigned, >( config: &GenConfig, ) -> It { Box::new( striped_random_signeds::( EXAMPLE_SEED, config.get_or("mean_stripe_n", U::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) .map(|n| T::rounding_from(n, Down).0), ) } pub fn special_random_primitive_float_gen_var_15< T: PrimitiveFloat, U: ConvertibleFrom + PrimitiveInt, >( _config: &GenConfig, ) -> It { Box::new(random_primitive_floats::(EXAMPLE_SEED).filter(|&f| !U::convertible_from(f))) } pub fn special_random_primitive_float_gen_var_16< T: PrimitiveFloat + RoundingFrom, U: PrimitiveUnsigned, >( _config: &GenConfig, ) -> It { let limit = min( NiceFloat(T::rounding_from(U::MAX, Down).0), NiceFloat( T::from_integer_mantissa_and_exponent(1, i64::wrapping_from(T::MANTISSA_WIDTH)) .unwrap(), ), ) .0; Box::new( random_primitive_float_inclusive_range::(EXAMPLE_SEED, T::ONE, limit) .map(|f| f.floor() - T::ONE / T::TWO), ) } pub fn special_random_primitive_float_gen_var_17< T: PrimitiveFloat + RoundingFrom, U: PrimitiveSigned, >( _config: &GenConfig, ) -> It { let min_limit = min( NiceFloat(-T::rounding_from(U::MIN, Down).0), NiceFloat( T::from_integer_mantissa_and_exponent(1, i64::wrapping_from(T::MANTISSA_WIDTH)) .unwrap(), ), ) .0; let max_limit = min( NiceFloat(T::rounding_from(U::MAX, Down).0), NiceFloat( T::from_integer_mantissa_and_exponent(1, i64::wrapping_from(T::MANTISSA_WIDTH)) .unwrap(), ), ) .0; Box::new( random_union2s( EXAMPLE_SEED, &|seed| { random_primitive_float_inclusive_range::(seed, T::ONE, max_limit) .map(|f| f.floor() - T::ONE / T::TWO) }, &|seed| { random_primitive_float_inclusive_range::(seed, T::ONE, min_limit) .map(|f| T::ONE / T::TWO - f.floor()) }, ) .map(Union2::unwrap), ) } pub fn special_random_primitive_float_gen_var_18(_config: &GenConfig) -> It { Box::new(random_positive_finite_primitive_floats::(EXAMPLE_SEED)) } pub fn special_random_primitive_float_gen_var_19(_config: &GenConfig) -> It { Box::new(random_primitive_float_inclusive_range( EXAMPLE_SEED, T::ZERO, T::power_of_2(T::MAX_EXPONENT), )) } // -- (PrimitiveFloat, PrimitiveFloat) -- pub fn special_random_primitive_float_pair_gen( _config: &GenConfig, ) -> It<(T, T)> { Box::new(random_pairs_from_single(random_primitive_floats( EXAMPLE_SEED, ))) } pub fn special_random_primitive_float_pair_gen_var_1( _config: &GenConfig, ) -> It<(T, T)> { Box::new(random_pairs_from_single( random_primitive_floats::(EXAMPLE_SEED).filter(|&f| !f.is_nan()), )) } // -- (PrimitiveFloat, PrimitiveFloat, PrimitiveFloat) -- pub fn special_random_primitive_float_triple_gen( _config: &GenConfig, ) -> It<(T, T, T)> { Box::new(random_triples_from_single(random_primitive_floats( EXAMPLE_SEED, ))) } // -- (PrimitiveFloat, PrimitiveSigned) -- pub fn special_random_primitive_float_signed_pair_gen( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &random_primitive_floats, &|seed| { geometric_random_signeds( seed, config.get_or("small_signed_mean_n", 32), config.get_or("small_signed_mean_d", 1), ) }, )) } pub fn special_random_primitive_float_signed_pair_gen_var_1< T: PrimitiveFloat, U: PrimitiveSigned, >( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &random_positive_finite_primitive_floats, &|seed| { geometric_random_signeds( seed, config.get_or("small_signed_mean_n", 32), config.get_or("small_signed_mean_d", 1), ) }, )) } pub fn special_random_primitive_float_signed_pair_gen_var_2( config: &GenConfig, ) -> It<(T, i64)> { Box::new( random_pairs( EXAMPLE_SEED, &|seed| random_primitive_float_range(seed, T::ONE, T::TWO), &|seed| { geometric_random_signed_inclusive_range( seed, T::MIN_EXPONENT, T::MAX_EXPONENT, config.get_or("small_signed_mean_n", 32), config.get_or("small_signed_mean_d", 1), ) }, ) .filter(|&(m, e)| m.precision() <= T::max_precision_for_sci_exponent(e)), ) } pub fn special_random_primitive_float_signed_pair_gen_var_3( config: &GenConfig, ) -> It<(T, i64)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| random_primitive_float_range(seed, T::ONE, T::TWO), &|seed| { geometric_random_signeds( seed, config.get_or("small_signed_mean_n", 32), config.get_or("small_signed_mean_d", 1), ) }, )) } pub fn special_random_primitive_float_signed_pair_gen_var_4< T: PrimitiveFloat, U: PrimitiveSigned, >( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &random_primitive_floats, &|seed| { geometric_random_signeds( seed, config.get_or("small_signed_mean_n", 32), config.get_or("small_signed_mean_d", 1), ) }, )) } // -- (PrimitiveFloat, PrimitiveSigned, PrimitiveUnsigned) -- pub fn special_random_primitive_float_signed_unsigned_triple_gen_var_1< T: PrimitiveFloat, U: PrimitiveSigned, V: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(T, U, V)> { Box::new(random_triples( EXAMPLE_SEED, &random_primitive_floats, &|seed| { geometric_random_signeds( seed, config.get_or("small_signed_mean_n", 32), config.get_or("small_signed_mean_d", 1), ) }, &|seed| { geometric_random_positive_unsigneds( seed, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, )) } // -- (PrimitiveFloat, PrimitiveUnsigned) -- pub fn special_random_primitive_float_unsigned_pair_gen_var_1< T: PrimitiveFloat, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &random_positive_finite_primitive_floats, &|seed| { geometric_random_unsigneds( seed, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, )) } pub fn special_random_primitive_float_unsigned_pair_gen_var_2( config: &GenConfig, ) -> It<(T, u64)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| random_primitive_float_range(seed, T::ONE, T::TWO), &|seed| { geometric_random_unsigneds( seed, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, )) } pub fn special_random_primitive_float_unsigned_pair_gen_var_3< T: PrimitiveFloat, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &random_positive_finite_primitive_floats, &|seed| { geometric_random_positive_unsigneds( seed, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, )) } pub fn special_random_primitive_float_unsigned_pair_gen_var_4< T: PrimitiveFloat, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &random_primitive_floats, &|seed| { geometric_random_positive_unsigneds( seed, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, )) } // -- (PrimitiveFloat, PrimitiveUnsigned, RoundingMode) -- pub fn special_random_primitive_float_unsigned_rounding_mode_triple_gen_var_1< T: PrimitiveFloat, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(T, U, RoundingMode)> { Box::new(random_triples( EXAMPLE_SEED, &random_positive_finite_primitive_floats, &|seed| { geometric_random_unsigneds( seed, config.get_or("small_signed_mean_n", 32), config.get_or("small_signed_mean_d", 1), ) }, &random_rounding_modes, )) } pub fn special_random_primitive_float_unsigned_rounding_mode_triple_gen_var_2( config: &GenConfig, ) -> It<(T, u64, RoundingMode)> { Box::new(random_triples( EXAMPLE_SEED, &|seed| random_primitive_float_range(seed, T::ONE, T::TWO), &|seed| { geometric_random_unsigneds( seed, config.get_or("small_signed_mean_n", 32), config.get_or("small_signed_mean_d", 1), ) }, &random_rounding_modes, )) } // var 3 is in malachite-float. // -- (PrimitiveFloat, RoundingMode) -- pub fn special_random_primitive_float_rounding_mode_pair_gen_var_1( _config: &GenConfig, ) -> It<(T, RoundingMode)> { Box::new( random_pairs( EXAMPLE_SEED, &random_finite_primitive_floats, &random_rounding_modes, ) .filter(float_rounding_mode_filter_var_1), ) } pub fn special_random_primitive_float_rounding_mode_pair_gen_var_2( _config: &GenConfig, ) -> It<(T, RoundingMode)> { Box::new( random_pairs( EXAMPLE_SEED, &random_primitive_floats::, &random_rounding_modes, ) .filter(|&(f, rm)| rm != Exact || f.is_integer()), ) } pub fn special_random_primitive_float_rounding_mode_pair_gen_var_3< T: PrimitiveFloat + RoundingFrom, U: ConvertibleFrom + PrimitiveInt, >( _config: &GenConfig, ) -> It<(T, RoundingMode)> { let f_min = T::rounding_from(U::MIN, Down).0; let f_max = T::rounding_from(U::MAX, Down).0; Box::new( random_pairs( EXAMPLE_SEED, &|seed| random_primitive_floats::(seed).filter(|f| !f.is_nan()), &random_rounding_modes, ) .filter(move |&(f, rm)| match rm { Up => f >= f_min && f <= f_max, Ceiling => f <= f_max, Floor => f >= f_min, Down | Nearest => true, Exact => U::convertible_from(f), }), ) } // -- PrimitiveInt -- pub fn special_random_primitive_int_gen_var_1< T: PrimitiveInt + RoundingFrom, U: PrimitiveFloat + RoundingFrom, >( _config: &GenConfig, ) -> It { Box::new( random_primitive_float_range( EXAMPLE_SEED, U::rounding_from(T::MIN, Down).0, U::rounding_from(T::MAX, Down).0, ) .map(|f| T::rounding_from(f, Down).0), ) } // -- PrimitiveSigned -- pub fn special_random_signed_gen(config: &GenConfig) -> It { Box::new(striped_random_signeds( EXAMPLE_SEED, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), )) } pub fn special_random_signed_gen_var_1(config: &GenConfig) -> It { Box::new(special_random_signed_gen(config).filter(|&x| x != T::MIN)) } pub fn special_random_signed_gen_var_2(config: &GenConfig) -> It { Box::new(striped_random_natural_signeds( EXAMPLE_SEED, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), )) } pub fn special_random_signed_gen_var_3(config: &GenConfig) -> It { Box::new( striped_random_signeds( EXAMPLE_SEED, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) .filter(|&x| x != T::ZERO && x != T::NEGATIVE_ONE), ) } pub fn special_random_signed_gen_var_4(config: &GenConfig) -> It { Box::new(striped_random_negative_signeds( EXAMPLE_SEED, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), )) } pub fn special_random_signed_gen_var_5(config: &GenConfig) -> It { Box::new(striped_random_nonzero_signeds( EXAMPLE_SEED, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), )) } pub fn special_random_signed_gen_var_6< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, V: ConvertibleFrom + PrimitiveFloat, >( config: &GenConfig, ) -> It { Box::new( random_union2s( EXAMPLE_SEED, &|seed| { striped_random_signed_inclusive_range::( seed, S::saturating_from(V::SMALLEST_UNREPRESENTABLE_UINT), S::MAX, config.get_or("mean_stripe_n", S::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { striped_random_signed_inclusive_range::( seed, S::MIN, S::saturating_from(V::SMALLEST_UNREPRESENTABLE_UINT).saturating_neg(), config.get_or("mean_stripe_n", S::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, ) .map(Union2::unwrap) .filter(|&x| !V::convertible_from(x)), ) } pub fn special_random_signed_gen_var_7< U: PrimitiveUnsigned + WrappingFrom, S: TryFrom> + PrimitiveSigned + WrappingFrom, V: PrimitiveFloat + RoundingFrom, >( config: &GenConfig, ) -> It { Box::new( random_union2s( EXAMPLE_SEED, &|seed| { striped_random_signed_inclusive_range::( seed, S::exact_from(V::SMALLEST_UNREPRESENTABLE_UINT), S::MAX, config.get_or("mean_stripe_n", S::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) .filter_map(|a| { let f = V::rounding_from(a, Down).0; let a = S::try_from(NiceFloat(f)).ok()?; let b = S::try_from(NiceFloat(f.next_higher())).ok()?; let diff = b - a; if diff.even() { // This happens almost always Some(a + (diff >> 1)) } else { None } }) }, &|seed| { striped_random_signed_inclusive_range::( seed, S::MIN, S::exact_from(V::SMALLEST_UNREPRESENTABLE_UINT) .checked_neg() .unwrap(), config.get_or("mean_stripe_n", S::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) .filter_map(|a| { let f = V::rounding_from(a, Down).0; let a = S::try_from(NiceFloat(f)).ok()?; let b = S::try_from(NiceFloat(f.next_lower())).ok()?; let diff = a - b; if diff.even() { // This happens almost always Some(a - (diff >> 1)) } else { None } }) }, ) .map(Union2::unwrap), ) } pub fn special_random_signed_gen_var_8< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >( config: &GenConfig, ) -> It { let limit = S::wrapping_from(U::wrapping_from(S::MAX).floor_sqrt()); Box::new(striped_random_signed_inclusive_range::( EXAMPLE_SEED, -limit, limit, config.get_or("mean_stripe_n", S::WIDTH >> 1), config.get_or("mean_stripe_d", 1), )) } pub fn special_random_signed_gen_var_9(config: &GenConfig) -> It { Box::new(striped_random_signed_inclusive_range::( EXAMPLE_SEED, T::MIN_EXPONENT, T::MAX_EXPONENT, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), )) } pub fn special_random_signed_gen_var_10(config: &GenConfig) -> It { Box::new( striped_random_signeds( EXAMPLE_SEED, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) .filter(|&x| x != T::ZERO && x != T::MIN), ) } pub fn special_random_signed_gen_var_11< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >( config: &GenConfig, ) -> It { Box::new( striped_random_signed_inclusive_range::( EXAMPLE_SEED, S::ZERO, S::low_mask(S::WIDTH - 2), config.get_or("mean_stripe_n", S::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) .map(|u| (u << 1) | S::ONE), ) } // -- (PrimitiveSigned, PrimitiveSigned) -- pub fn special_random_signed_pair_gen(config: &GenConfig) -> It<(T, T)> { Box::new(random_pairs_from_single(striped_random_signeds( EXAMPLE_SEED, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ))) } pub fn special_random_signed_pair_gen_var_1(config: &GenConfig) -> It<(T, T)> { Box::new( random_union2s( EXAMPLE_SEED, &|seed| { random_pairs_from_single(striped_random_natural_signeds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), )) }, &|seed| { random_pairs_from_single(striped_random_negative_signeds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), )) }, ) .map(Union2::unwrap), ) } pub fn special_random_signed_pair_gen_var_2( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_signeds( seed, config.get_or("mean_large_signed_stripe_n", T::WIDTH >> 1), config.get_or("mean_large_signed_stripe_d", 1), ) }, &|seed| { geometric_random_signeds( seed, config.get_or("mean_small_signed_n", 32), config.get_or("mean_small_signed_d", 1), ) }, )) } pub fn special_random_signed_pair_gen_var_3(config: &GenConfig) -> It<(T, T)> { Box::new( random_pairs( EXAMPLE_SEED, &|seed| { striped_random_signeds::( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { striped_random_nonzero_signeds::( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, ) .filter_map(|(mut x, y)| { x.round_to_multiple_assign(y, Down); if x == T::MIN && y == T::NEGATIVE_ONE { None } else { Some((x, y)) } }), ) } pub fn special_random_signed_pair_gen_var_4(config: &GenConfig) -> It<(T, T)> { Box::new( random_pairs( EXAMPLE_SEED, &|seed| { striped_random_signeds::( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { striped_random_nonzero_signeds::( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, ) .filter(|&(x, y)| x != T::MIN || y != T::NEGATIVE_ONE), ) } pub fn special_random_signed_pair_gen_var_5(config: &GenConfig) -> It<(T, T)> { Box::new( random_pairs( EXAMPLE_SEED, &|seed| { striped_random_signeds::( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { striped_random_nonzero_signeds::( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, ) .filter(|&(x, y)| !x.divisible_by(y)), ) } pub fn special_random_signed_pair_gen_var_6(config: &GenConfig) -> It<(T, T)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_signeds::( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { striped_random_nonzero_signeds::( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, )) } pub fn special_random_signed_pair_gen_var_7(config: &GenConfig) -> It<(T, T)> { Box::new(random_pairs_from_single(striped_random_natural_signeds( EXAMPLE_SEED, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ))) } pub fn special_random_signed_pair_gen_var_8< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >( config: &GenConfig, ) -> It<(S, S)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_signeds( seed, config.get_or("mean_stripe_n", S::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { striped_random_signed_inclusive_range::( seed, S::ZERO, S::low_mask(S::WIDTH - 2), config.get_or("mean_stripe_n", S::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) .map(|u| (u << 1) | S::ONE) }, )) } pub fn special_random_signed_pair_gen_var_9< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + UnsignedAbs + WrappingFrom, >( config: &GenConfig, ) -> It<(S, S)> { Box::new( random_pairs_from_single( striped_random_signed_inclusive_range::( EXAMPLE_SEED, S::ZERO, S::low_mask(S::WIDTH - 2), config.get_or("mean_stripe_n", S::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) .map(|u| (u << 1) | S::ONE), ) .filter(|&(a, b): &(S, S)| a.unsigned_abs().coprime_with(b.unsigned_abs())), ) } pub fn special_random_signed_pair_gen_var_10< U: PrimitiveUnsigned, S: PrimitiveSigned + UnsignedAbs, >( config: &GenConfig, ) -> It<(S, S)> { Box::new( random_pairs_from_single(striped_random_signeds( EXAMPLE_SEED, config.get_or("mean_stripe_n", S::WIDTH >> 1), config.get_or("mean_stripe_d", 1), )) .filter(|&(x, y): &(S, S)| x.unsigned_abs().coprime_with(y.unsigned_abs())), ) } // -- (PrimitiveSigned, PrimitiveSigned, PrimitiveSigned) -- pub fn special_random_signed_triple_gen(config: &GenConfig) -> It<(T, T, T)> { Box::new(random_triples_from_single(striped_random_signeds( EXAMPLE_SEED, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ))) } pub fn special_random_signed_triple_gen_var_1( config: &GenConfig, ) -> It<(T, T, T)> { Box::new( random_triples_from_single(striped_random_signeds( EXAMPLE_SEED, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), )) .map(|(x, y, z)| reduce_to_fit_add_mul_signed(x, y, z)), ) } pub fn special_random_signed_triple_gen_var_2( config: &GenConfig, ) -> It<(T, T, T)> { Box::new( random_triples_from_single(striped_random_signeds( EXAMPLE_SEED, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), )) .map(|(x, y, z)| reduce_to_fit_sub_mul_signed(x, y, z)), ) } pub fn special_random_signed_triple_gen_var_3( config: &GenConfig, ) -> It<(T, T, T)> { Box::new( random_union2s( EXAMPLE_SEED, &|seed| { random_triples_from_single(striped_random_natural_signeds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), )) }, &|seed| { random_triples_from_single(striped_random_negative_signeds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), )) }, ) .map(Union2::unwrap), ) } pub fn special_random_signed_triple_gen_var_4< U: PrimitiveUnsigned + WrappingFrom + WrappingInto, S: PrimitiveSigned + UnsignedAbs, >( config: &GenConfig, ) -> It<(S, S, S)> { Box::new( random_triples_from_single(striped_random_signeds::( EXAMPLE_SEED, config.get_or("mean_stripe_n", S::WIDTH >> 1), config.get_or("mean_stripe_d", 1), )) .map(|(x, y, m)| { if m == S::ZERO { let min = min(x, y); (min, min, m) } else if x <= y { let adjusted_diff = U::wrapping_from(y.wrapping_sub(x)) .round_to_multiple(m.unsigned_abs(), Down) .0; ( x, (U::wrapping_from(x).wrapping_add(adjusted_diff)).wrapping_into(), m, ) } else { let adjusted_diff = U::wrapping_from(x.wrapping_sub(y)) .round_to_multiple(m.unsigned_abs(), Down) .0; ( (U::wrapping_from(y).wrapping_add(adjusted_diff)).wrapping_into(), y, m, ) } }), ) } pub fn special_random_signed_triple_gen_var_5( config: &GenConfig, ) -> It<(T, T, T)> { Box::new( random_triples_from_single(striped_random_signeds::( EXAMPLE_SEED, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), )) .filter(|&(x, y, m)| !x.eq_mod(y, m)), ) } pub fn special_random_signed_triple_gen_var_6< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >( config: &GenConfig, ) -> It<(S, S, S)> { Box::new(random_triples_xxy( EXAMPLE_SEED, &|seed| { striped_random_signeds( seed, config.get_or("mean_stripe_n", S::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { striped_random_signed_inclusive_range::( seed, S::ZERO, S::low_mask(S::WIDTH - 2), config.get_or("mean_stripe_n", S::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) .map(|u| (u << 1) | S::ONE) }, )) } pub fn special_random_signed_triple_gen_var_7< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >( config: &GenConfig, ) -> It<(S, S, S)> { Box::new(random_triples_xyy( EXAMPLE_SEED, &|seed| { striped_random_signeds( seed, config.get_or("mean_stripe_n", S::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { striped_random_signed_inclusive_range::( seed, S::ZERO, S::low_mask(S::WIDTH - 2), config.get_or("mean_stripe_n", S::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) .map(|u| (u << 1) | S::ONE) }, )) } // -- (PrimitiveSigned, PrimitiveSigned, PrimitiveSigned, PrimitiveSigned) -- pub fn special_random_signed_quadruple_gen( config: &GenConfig, ) -> It<(T, T, T, T)> { Box::new(random_quadruples_from_single(striped_random_signeds( EXAMPLE_SEED, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ))) } // -- (PrimitiveSigned, PrimitiveSigned, PrimitiveSigned, PrimitiveUnsigned) -- pub fn special_random_signed_signed_signed_unsigned_quadruple_gen_var_2< T: PrimitiveSigned, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(T, T, T, U)> { Box::new(random_quadruples_xxxy( EXAMPLE_SEED, &|seed| { striped_random_signeds( seed, config.get_or("mean_large_unsigned_stripe_n", T::WIDTH >> 1), config.get_or("mean_large_unsigned_stripe_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, )) } // -- (PrimitiveSigned, PrimitiveSigned, PrimitiveUnsigned) -- pub fn special_random_signed_signed_unsigned_triple_gen_var_1< U: PrimitiveUnsigned + WrappingFrom + WrappingInto, S: PrimitiveSigned, >( config: &GenConfig, ) -> It<(S, S, u64)> { Box::new( random_triples_xxy( EXAMPLE_SEED, &|seed| { striped_random_signeds::( seed, config.get_or("mean_stripe_n", S::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_pow_n", 32), config.get_or("mean_pow_d", 1), ) }, ) .map(|(x, y, pow)| { if pow >= S::WIDTH { (x, x, pow) } else if x <= y { let adjusted_diff = U::wrapping_from(y.wrapping_sub(x)) .round_to_multiple_of_power_of_2(pow, Down) .0; ( x, (U::wrapping_from(x).wrapping_add(adjusted_diff)).wrapping_into(), pow, ) } else { let adjusted_diff = U::wrapping_from(x.wrapping_sub(y)) .round_to_multiple_of_power_of_2(pow, Down) .0; ( (U::wrapping_from(y).wrapping_add(adjusted_diff)).wrapping_into(), y, pow, ) } }), ) } pub fn special_random_signed_signed_unsigned_triple_gen_var_2< T: PrimitiveSigned, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(T, T, U)> { Box::new(random_triples( EXAMPLE_SEED, &|seed| { striped_random_signeds( seed, config.get_or("mean_large_stripe_n", T::WIDTH >> 1), config.get_or("mean_large_stripe_d", 1), ) }, &|seed| { striped_random_signeds( seed, config.get_or("mean_large_stripe_n", T::WIDTH >> 1), config.get_or("mean_large_stripe_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, )) } pub fn special_random_signed_signed_unsigned_triple_gen_var_3( config: &GenConfig, ) -> It<(T, T, u64)> { Box::new( random_triples_xxy( EXAMPLE_SEED, &|seed| { striped_random_signeds::( seed, config.get_or("mean_large_unsigned_stripe_n", T::WIDTH >> 1), config.get_or("mean_large_unsigned_stripe_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, ) .filter(|&(x, y, pow)| !x.eq_mod_power_of_2(y, pow)), ) } pub fn special_random_signed_signed_unsigned_triple_gen_var_4< T: PrimitiveSigned, U: PrimitiveSigned, V: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(T, U, V)> { Box::new(random_triples( EXAMPLE_SEED, &|seed| { striped_random_signeds( seed, config.get_or("mean_large_unsigned_stripe_n", T::WIDTH >> 1), config.get_or("mean_large_unsigned_stripe_d", 1), ) }, &|seed| { geometric_random_signeds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, &|seed| { geometric_random_positive_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, )) } // -- (PrimitiveSigned, PrimitiveSigned, RoundingMode) -- struct SignedSignedRoundingModeTripleGenerator { xs: StripedRandomSigneds, rms: RandomRoundingModes, } impl Iterator for SignedSignedRoundingModeTripleGenerator { type Item = (T, T, RoundingMode); fn next(&mut self) -> Option<(T, T, RoundingMode)> { let mut x; let mut y; loop { x = self.xs.next().unwrap(); loop { y = self.xs.next().unwrap(); if y != T::ZERO { break; } } if x != T::MIN || y != T::NEGATIVE_ONE { break; } } let rm = self.rms.next().unwrap(); if rm == Exact { x.round_to_multiple_assign(y, Down); } Some((x, y, rm)) } } pub fn special_random_signed_signed_rounding_mode_triple_gen_var_1( config: &GenConfig, ) -> It<(T, T, RoundingMode)> { Box::new(SignedSignedRoundingModeTripleGenerator { xs: striped_random_signeds( EXAMPLE_SEED.fork("xs"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), rms: random_rounding_modes(EXAMPLE_SEED.fork("rms")), }) } pub fn special_random_signed_signed_rounding_mode_triple_gen_var_2< U: PrimitiveUnsigned, S: TryFrom + ConvertibleFrom + PrimitiveSigned + UnsignedAbs, >( config: &GenConfig, ) -> It<(S, S, RoundingMode)> { Box::new( random_triples( EXAMPLE_SEED, &|seed| { striped_random_signeds( seed, config.get_or("mean_stripe_n", S::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { striped_random_nonzero_signeds( seed, config.get_or("mean_stripe_n", S::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &random_rounding_modes, ) .filter_map(|(x, y, rm)| round_to_multiple_signed_filter_map(x, y, rm)), ) } pub fn special_random_signed_signed_rounding_mode_triple_gen_var_3< T: PrimitiveSigned, U: PrimitiveSigned, >( config: &GenConfig, ) -> It<(T, U, RoundingMode)> { Box::new( random_triples( EXAMPLE_SEED, &|seed| { striped_random_signeds::( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { geometric_random_signeds::( seed, config.get_or("mean_shift_n", 4), config.get_or("mean_shift_d", 1), ) }, &random_rounding_modes, ) .filter(|&(x, pow, rm)| { rm != Exact || pow <= U::ZERO || x.divisible_by_power_of_2(pow.exact_into()) }), ) } pub fn special_random_signed_signed_rounding_mode_triple_gen_var_4< T: PrimitiveSigned, U: PrimitiveSigned, >( config: &GenConfig, ) -> It<(T, U, RoundingMode)> { Box::new( random_triples( EXAMPLE_SEED, &|seed| { striped_random_signeds::( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { geometric_random_signeds::( seed, config.get_or("mean_shift_n", 4), config.get_or("mean_shift_d", 1), ) }, &random_rounding_modes, ) .filter(|&(x, pow, rm)| { let pow: i64 = pow.exact_into(); rm != Exact || pow >= 0 || x.divisible_by_power_of_2(pow.unsigned_abs()) }), ) } // -- (PrimitiveSigned, PrimitiveUnsigned) -- pub fn special_random_signed_unsigned_pair_gen( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_signeds( seed, config.get_or("mean_large_unsigned_stripe_n", T::WIDTH >> 1), config.get_or("mean_large_unsigned_stripe_d", 1), ) }, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_large_unsigned_stripe_n", U::WIDTH >> 1), config.get_or("mean_large_unsigned_stripe_d", 1), ) }, )) } pub fn special_random_signed_unsigned_pair_gen_var_1( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_signeds( seed, config.get_or("mean_large_unsigned_stripe_n", T::WIDTH >> 1), config.get_or("mean_large_unsigned_stripe_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, )) } pub fn special_random_signed_unsigned_pair_gen_var_2( config: &GenConfig, ) -> It<(T, u64)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_signeds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| random_unsigneds_less_than(seed, T::WIDTH), )) } pub fn special_random_signed_unsigned_pair_gen_var_3( config: &GenConfig, ) -> It<(T, u64)> { Box::new( random_union2s( EXAMPLE_SEED, &|seed| { random_pairs( seed, &|seed| { striped_random_natural_signeds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed_2| { striped_random_unsigned_range( seed_2, 0, T::WIDTH, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, ) }, &|seed| { random_pairs( seed, &|seed| { striped_random_negative_signeds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed_2| { geometric_random_unsigneds( seed_2, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, ) }, ) .map(Union2::unwrap), ) } pub fn special_random_signed_unsigned_pair_gen_var_4( config: &GenConfig, ) -> It<(T, u64)> { Box::new( random_union2s( EXAMPLE_SEED, &|seed| { random_pairs( seed, &|seed_2| { striped_random_negative_signeds( seed_2, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed_2| { striped_random_unsigned_range( seed_2, 0, T::WIDTH, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, ) }, &|seed| { random_pairs( seed, &|seed_2| { striped_random_natural_signeds( seed_2, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed_2| { geometric_random_unsigneds( seed_2, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, ) }, ) .map(Union2::unwrap), ) } pub fn special_random_signed_unsigned_pair_gen_var_5< T: PrimitiveSigned, U: ExactFrom + PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_signeds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { striped_random_unsigned_inclusive_range( seed, U::TWO, U::exact_from(36u8), config.get_or("mean_stripe_n", U::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, )) } pub fn special_random_signed_unsigned_pair_gen_var_6( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_natural_signeds( seed, config.get_or("mean_large_unsigned_stripe_n", T::WIDTH >> 1), config.get_or("mean_large_unsigned_stripe_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, )) } pub fn special_random_signed_unsigned_pair_gen_var_7< T: PrimitiveSigned, U: ExactFrom + PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_natural_signeds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { striped_random_unsigned_inclusive_range( seed, U::TWO, U::exact_from(36u8), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, )) } pub fn special_random_signed_unsigned_pair_gen_var_8( config: &GenConfig, ) -> It<(T, U)> { Box::new( random_pairs( EXAMPLE_SEED, &|seed| { striped_random_signeds::( seed, config.get_or("mean_large_signed_stripe_n", T::WIDTH >> 1), config.get_or("mean_large_signed_stripe_d", 1), ) }, &|seed| { geometric_random_unsigneds::( seed, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, ) .filter(|&(x, y)| !x.divisible_by_power_of_2(y.exact_into())), ) } pub fn special_random_signed_unsigned_pair_gen_var_9( config: &GenConfig, ) -> It<(T, U)> { Box::new( random_pairs( EXAMPLE_SEED, &|seed| { striped_random_signeds::( seed, config.get_or("mean_large_unsigned_stripe_n", T::WIDTH >> 1), config.get_or("mean_large_unsigned_stripe_d", 1), ) }, &|seed| { geometric_random_unsigneds::( seed, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, ) .map(|(mut x, y)| { x.round_to_multiple_of_power_of_2_assign(y.exact_into(), Down); (x, y) }), ) } pub fn special_random_signed_unsigned_pair_gen_var_10( config: &GenConfig, ) -> It<(T, u64)> { Box::new( random_union2s( EXAMPLE_SEED, &|seed| { random_pairs( seed, &|seed_2| { striped_random_natural_signeds::( seed_2, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed_2| { geometric_random_unsigneds( seed_2, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, ) }, &|seed| { random_pairs( seed, &|seed_2| { striped_random_signeds::( seed_2, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed_2| { striped_random_unsigned_inclusive_range( seed_2, 0, T::WIDTH, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, ) }, ) .map(Union2::unwrap), ) } pub fn special_random_signed_unsigned_pair_gen_var_11< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >( config: &GenConfig, ) -> It<(S, u64)> { Box::new( random_union2s( EXAMPLE_SEED, &|seed| { random_pairs( seed, &|seed_2| { striped_random_signed_range::( seed_2, S::MIN + S::ONE, S::ONE, config.get_or("mean_stripe_n", S::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed_2| { geometric_random_unsigneds( seed_2, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, ) }, &|seed| { random_pairs( seed, &|seed_2| { striped_random_signeds::( seed_2, config.get_or("mean_large_unsigned_stripe_n", S::WIDTH >> 1), config.get_or("mean_large_unsigned_stripe_d", 1), ) }, &|seed_2| { striped_random_unsigned_range( seed_2, 0, S::WIDTH, config.get_or("mean_stripe_n", S::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, ) }, ) .map(Union2::unwrap), ) } pub fn special_random_signed_unsigned_pair_gen_var_12< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, V: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(S, V)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_signed_inclusive_range::( seed, if S::WIDTH <= u64::WIDTH { S::MIN } else { -S::exact_from(u64::MAX) }, S::saturating_from(u64::MAX), config.get_or("mean_stripe_n", S::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { geometric_random_positive_unsigneds( seed, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, )) } pub fn special_random_signed_unsigned_pair_gen_var_13( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_positive_signeds( seed, config.get_or("mean_large_unsigned_stripe_n", T::WIDTH >> 1), config.get_or("mean_large_unsigned_stripe_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, )) } pub fn special_random_signed_unsigned_pair_gen_var_14( config: &GenConfig, ) -> It<(T, U)> { Box::new( random_union2s( EXAMPLE_SEED, &|seed| { random_pairs( seed, &|seed| { striped_random_natural_signeds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed_2| { geometric_random_positive_unsigneds( seed_2, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, ) }, &|seed| { random_pairs( seed, &|seed| { striped_random_negative_signeds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed_2| { geometric_random_unsigneds::( seed_2, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) .filter_map(|i| i.arithmetic_checked_shl(1).map(|j| j | U::ONE)) }, ) }, ) .map(Union2::unwrap), ) } pub fn special_random_signed_unsigned_pair_gen_var_15< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, V: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(S, V)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_signed_range::( seed, S::MIN + S::ONE, S::ZERO, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, )) } pub fn special_random_signed_unsigned_pair_gen_var_16( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_signeds( seed, config.get_or("mean_large_unsigned_stripe_n", T::WIDTH >> 1), config.get_or("mean_large_unsigned_stripe_d", 1), ) }, &|seed| { geometric_random_positive_unsigneds( seed, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, )) } // -- (PrimitiveSigned, PrimitiveUnsigned, bool) -- pub fn random_signed_unsigned_bool_triple_gen_var_1( config: &GenConfig, ) -> It<(T, u64, bool)> { Box::new( random_union2s( EXAMPLE_SEED, &|seed| { random_pairs( seed, &|seed_2| { striped_random_signeds( seed_2, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed_2| { geometric_random_unsigneds( seed_2, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, ) .map(|(x, y)| (x, y, x < T::ZERO)) }, &|seed| { random_pairs( seed, &|seed_2| { striped_random_signeds( seed_2, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed_2| random_unsigneds_less_than(seed_2, T::WIDTH), ) .map(|(x, y)| (x, y, x >= T::ZERO)) }, ) .map(Union2::unwrap), ) } // -- (PrimitiveSigned, PrimitiveUnsigned, PrimitiveUnsigned) -- pub fn special_random_signed_unsigned_unsigned_triple_gen_var_1< T: PrimitiveSigned, U: PrimitiveUnsigned, V: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(T, U, V)> { Box::new(random_triples( EXAMPLE_SEED, &|seed| { striped_random_signeds( seed, config.get_or("mean_large_stripe_n", T::WIDTH >> 1), config.get_or("mean_large_stripe_d", 1), ) }, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_large_stripe_n", T::WIDTH >> 1), config.get_or("mean_large_stripe_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, )) } pub fn special_random_signed_unsigned_unsigned_triple_gen_var_2< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, V: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(S, V, V)> { Box::new( random_union2s( EXAMPLE_SEED, &|seed| { random_triples_xyy( seed, &|seed_2| { striped_random_positive_signeds( seed_2, config.get_or("mean_large_stripe_n", S::WIDTH >> 1), config.get_or("mean_large_stripe_d", 1), ) }, &|seed_2| { geometric_random_unsigneds( seed_2, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, ) .map(|(x, y, z)| if y <= z { (x, y, z) } else { (x, z, y) }) }, &|seed| { random_triples( seed, &|seed_2| { striped_random_signed_range::( seed_2, S::MIN, S::ZERO, config.get_or("mean_stripe_n", S::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed_2| { geometric_random_unsigneds( seed_2, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, &|seed_2| { striped_random_unsigned_range( seed_2, V::ZERO, V::exact_from(S::WIDTH), config.get_or("mean_stripe_n", S::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, ) .filter_map(|(x, y, z): (S, V, V)| y.checked_add(z).map(|new_z| (x, y, new_z))) }, ) .map(Union2::unwrap), ) } pub fn special_random_signed_unsigned_unsigned_triple_gen_var_3< T: PrimitiveSigned, U: ExactFrom + PrimitiveUnsigned, V: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(T, U, V)> { Box::new(random_triples( EXAMPLE_SEED, &|seed| { striped_random_signeds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { striped_random_unsigned_inclusive_range( seed, U::TWO, U::exact_from(36u8), config.get_or("mean_stripe_n", U::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("small_unsigned_mean_n", 4), config.get_or("small_unsigned_mean_d", 1), ) }, )) } // -- (PrimitiveSigned, PrimitiveUnsigned, PrimitiveUnsigned, PrimitiveUnsigned) -- pub fn special_random_signed_unsigned_unsigned_unsigned_quadruple_gen_var_1< T: PrimitiveSigned + UnsignedAbs, U: BitBlockAccess + PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(T, u64, u64, U)> { Box::new( random_quadruples_xyyz( EXAMPLE_SEED, &|seed_2| { striped_random_signeds( seed_2, config.get_or("mean_large_stripe_n", T::WIDTH >> 1), config.get_or("mean_large_stripe_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, &|seed_2| { striped_random_unsigneds( seed_2, config.get_or("mean_large_stripe_n", T::WIDTH >> 1), config.get_or("mean_large_stripe_d", 1), ) }, ) .filter_map(|(x, y, z, w)| { let (y, z) = if y <= z { (y, z) } else { (z, y) }; if signed_assign_bits_valid(x, y, z, w) { Some((x, y, z, w)) } else { None } }), ) } // -- (PrimitiveSigned, PrimitiveUnsigned, RoundingMode) -- pub fn special_random_signed_unsigned_rounding_mode_triple_gen_var_1( config: &GenConfig, ) -> It<(T, u64, RoundingMode)> { Box::new( random_triples( EXAMPLE_SEED, &|seed| { striped_random_signeds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_shift_n", 4), config.get_or("mean_shift_d", 1), ) }, &random_rounding_modes, ) .filter_map(|(x, pow, rm)| round_to_multiple_of_power_of_2_filter_map(x, pow, rm)), ) } pub fn special_random_signed_unsigned_rounding_mode_triple_gen_var_2< T: PrimitiveSigned, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(T, U, RoundingMode)> { Box::new( random_triples( EXAMPLE_SEED, &|seed| { striped_random_signeds::( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { geometric_random_unsigneds::( seed, config.get_or("mean_shift_n", 4), config.get_or("mean_shift_d", 1), ) }, &random_rounding_modes, ) .filter(|&(x, y, rm)| rm != Exact || x.divisible_by_power_of_2(y.exact_into())), ) } // var 3 is in malachite-float. // -- (PrimitiveSigned, RoundingMode) -- pub fn special_random_signed_rounding_mode_pair_gen( config: &GenConfig, ) -> It<(T, RoundingMode)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_signeds::( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &random_rounding_modes, )) } pub fn special_random_signed_rounding_mode_pair_gen_var_1( config: &GenConfig, ) -> It<(T, RoundingMode)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_nonzero_signeds::( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &random_rounding_modes, )) } pub fn special_random_signed_rounding_mode_pair_gen_var_2( config: &GenConfig, ) -> It<(T, RoundingMode)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_signeds::( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) .filter(|&x| x != T::MIN) }, &random_rounding_modes, )) } pub fn special_random_signed_rounding_mode_pair_gen_var_3( config: &GenConfig, ) -> It<(T, RoundingMode)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_nonzero_signeds::( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) .filter(|&x| x != T::MIN) }, &random_rounding_modes, )) } pub fn special_random_signed_rounding_mode_pair_gen_var_4< T: PrimitiveSigned, U: ConvertibleFrom + PrimitiveFloat, >( config: &GenConfig, ) -> It<(T, RoundingMode)> { Box::new( random_pairs( EXAMPLE_SEED, &|seed| { striped_random_positive_signeds::( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &random_rounding_modes, ) .filter(move |&(n, rm)| rm != Exact || U::convertible_from(n)), ) } // -- (PrimitiveUnsigned, ToSciOptions) -- pub fn special_random_signed_to_sci_options_pair_gen( config: &GenConfig, ) -> It<(T, ToSciOptions)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_positive_signeds::( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { random_to_sci_options( seed, config.get_or("mean_size_n", 32), config.get_or("mean_size_d", 1), ) }, )) } pub fn special_random_signed_to_sci_options_pair_gen_var_1( config: &GenConfig, ) -> It<(T, ToSciOptions)> { Box::new( random_pairs( EXAMPLE_SEED, &|seed| { striped_random_positive_signeds::( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { random_to_sci_options( seed, config.get_or("mean_size_n", 32), config.get_or("mean_size_d", 1), ) }, ) .filter(|(x, options)| x.fmt_sci_valid(*options)), ) } // -- (PrimitiveSigned, Vec) -- struct SignedBoolVecPairGeneratorVar1 { xs: StripedRandomSigneds, striped_bit_source: StripedBitSource, } impl Iterator for SignedBoolVecPairGeneratorVar1 { type Item = (T, Vec); fn next(&mut self) -> Option<(T, Vec)> { let x = self.xs.next().unwrap(); let bs = get_striped_bool_vec( &mut self.striped_bit_source, u64::exact_from(x.to_bits_asc().len()), ); Some((x, bs)) } } pub fn special_random_signed_bool_vec_pair_gen_var_1( config: &GenConfig, ) -> It<(T, Vec)> { Box::new(SignedBoolVecPairGeneratorVar1 { xs: striped_random_signeds( EXAMPLE_SEED.fork("xs"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), striped_bit_source: StripedBitSource::new( EXAMPLE_SEED.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), }) } // -- PrimitiveUnsigned -- pub fn special_random_unsigned_gen(config: &GenConfig) -> It { Box::new(striped_random_unsigneds( EXAMPLE_SEED, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), )) } pub fn special_random_unsigned_gen_var_1(config: &GenConfig) -> It { Box::new(striped_random_positive_unsigneds( EXAMPLE_SEED, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), )) } pub fn special_random_unsigned_gen_var_2(config: &GenConfig) -> It { Box::new(striped_random_unsigned_range( EXAMPLE_SEED, 0, NUMBER_OF_CHARS, config.get_or("mean_stripe_n", 16), config.get_or("mean_stripe_d", 1), )) } pub fn special_random_unsigned_gen_var_3(config: &GenConfig) -> It { Box::new(striped_random_unsigned_inclusive_range( EXAMPLE_SEED, 1, T::WIDTH, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), )) } pub fn special_random_unsigned_gen_var_4< T: PrimitiveInt, U: PrimitiveUnsigned + SaturatingFrom, >( config: &GenConfig, ) -> It { Box::new(striped_random_unsigned_inclusive_range( EXAMPLE_SEED, U::TWO, U::saturating_from(T::MAX), config.get_or("mean_stripe_n", U::WIDTH >> 1), config.get_or("mean_stripe_d", 1), )) } pub fn special_random_unsigned_gen_var_5(config: &GenConfig) -> It { Box::new(striped_random_unsigned_inclusive_range( EXAMPLE_SEED, T::TWO, T::MAX, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), )) } pub fn special_random_unsigned_gen_var_6(config: &GenConfig) -> It { Box::new(striped_random_unsigned_range( EXAMPLE_SEED, T::ZERO, T::exact_from(36), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), )) } pub fn special_random_unsigned_gen_var_7(config: &GenConfig) -> It { Box::new(striped_random_unsigned_inclusive_range( EXAMPLE_SEED, T::TWO, T::exact_from(36), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), )) } pub fn special_random_unsigned_gen_var_8(config: &GenConfig) -> It { Box::new(striped_random_unsigned_range( EXAMPLE_SEED, 0, T::WIDTH + 1, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), )) } pub fn special_random_unsigned_gen_var_9(config: &GenConfig) -> It { Box::new( random_union3s( EXAMPLE_SEED, &|seed| { striped_random_unsigned_inclusive_range( seed, b'0', b'9', config.get_or("mean_stripe_n", 4), config.get_or("mean_stripe_d", 1), ) }, &|seed| { striped_random_unsigned_inclusive_range( seed, b'a', b'z', config.get_or("mean_stripe_n", 4), config.get_or("mean_stripe_d", 1), ) }, &|seed| { striped_random_unsigned_inclusive_range( seed, b'A', b'Z', config.get_or("mean_stripe_n", 4), config.get_or("mean_stripe_d", 1), ) }, ) .map(Union3::unwrap), ) } pub fn special_random_unsigned_gen_var_10(config: &GenConfig) -> It { Box::new(striped_random_unsigned_inclusive_range( EXAMPLE_SEED, T::power_of_2(T::WIDTH - 1), T::MAX, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), )) } pub fn special_random_unsigned_gen_var_11(config: &GenConfig) -> It { Box::new(striped_random_unsigned_range( EXAMPLE_SEED, 0, T::LARGEST_ORDERED_REPRESENTATION, config.get_or("mean_stripe_n", 32), config.get_or("mean_stripe_d", 1), )) } pub fn special_random_unsigned_gen_var_12(config: &GenConfig) -> It { Box::new(striped_random_unsigned_range( EXAMPLE_SEED, T::ZERO, T::power_of_2(T::WIDTH - 1) + T::ONE, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), )) } pub fn special_random_unsigned_gen_var_13(config: &GenConfig) -> It { Box::new(striped_random_unsigned_range( EXAMPLE_SEED, 0, T::WIDTH, config.get_or("mean_stripe_n", 32), config.get_or("mean_stripe_d", 1), )) } pub fn special_random_unsigned_gen_var_14(config: &GenConfig) -> It { Box::new(striped_random_unsigned_range( EXAMPLE_SEED, 0, T::WIDTH - 1, config.get_or("mean_stripe_n", 32), config.get_or("mean_stripe_d", 1), )) } pub fn special_random_unsigned_gen_var_15(config: &GenConfig) -> It { Box::new(striped_random_unsigned_inclusive_range( EXAMPLE_SEED, T::power_of_2(T::WIDTH - 2), T::MAX, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), )) } pub fn special_random_unsigned_gen_var_16< T: PrimitiveUnsigned, U: ConvertibleFrom + PrimitiveFloat, >( config: &GenConfig, ) -> It { Box::new( striped_random_unsigned_inclusive_range( EXAMPLE_SEED, T::saturating_from(U::SMALLEST_UNREPRESENTABLE_UINT), T::MAX, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) .filter(|&x| !U::convertible_from(x)), ) } pub fn special_random_unsigned_gen_var_17< T: TryFrom> + PrimitiveUnsigned, U: PrimitiveFloat + RoundingFrom, >( config: &GenConfig, ) -> It { Box::new( striped_random_unsigned_inclusive_range( EXAMPLE_SEED, T::exact_from(U::SMALLEST_UNREPRESENTABLE_UINT), T::MAX, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) .filter_map(|a| { let f = U::rounding_from(a, Down).0; let a = T::try_from(NiceFloat(f)).ok()?; let b = T::try_from(NiceFloat(f.next_higher())).ok()?; let diff = b - a; if diff.even() { // This happens almost always Some(a + (diff >> 1)) } else { None } }), ) } pub fn special_random_unsigned_gen_var_18(config: &GenConfig) -> It { Box::new(striped_random_unsigned_inclusive_range( EXAMPLE_SEED, T::ZERO, T::MAX.floor_sqrt(), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), )) } pub fn special_random_unsigned_gen_var_19(config: &GenConfig) -> It { Box::new( striped_random_unsigned_inclusive_range( EXAMPLE_SEED, T::ZERO, T::low_mask(T::WIDTH - 1), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) .map(|u| (u << 1) | T::ONE), ) } pub fn special_random_unsigned_gen_var_20(config: &GenConfig) -> It { let limit = smallest_invalid_value(T::checked_factorial); Box::new(striped_random_unsigned_range( EXAMPLE_SEED, 0, limit, config.get_or("mean_stripe_n", 4), config.get_or("mean_stripe_d", 1), )) } pub fn special_random_unsigned_gen_var_21(config: &GenConfig) -> It { let limit = smallest_invalid_value(T::checked_double_factorial); Box::new(striped_random_unsigned_range( EXAMPLE_SEED, 0, limit, config.get_or("mean_stripe_n", 4), config.get_or("mean_stripe_d", 1), )) } pub fn special_random_unsigned_gen_var_22(config: &GenConfig) -> It { let limit = smallest_invalid_value(T::checked_subfactorial); Box::new(striped_random_unsigned_range( EXAMPLE_SEED, 0, limit, config.get_or("mean_stripe_n", 4), config.get_or("mean_stripe_d", 1), )) } pub fn special_random_unsigned_gen_var_23(config: &GenConfig) -> It { let limit = smallest_invalid_value(T::checked_primorial); Box::new(striped_random_unsigned_range( EXAMPLE_SEED, 0, limit, config.get_or("mean_stripe_n", 4), config.get_or("mean_stripe_d", 1), )) } pub fn special_random_unsigned_gen_var_24(config: &GenConfig) -> It { let limit = smallest_invalid_value(T::checked_product_of_first_n_primes); Box::new(striped_random_unsigned_range( EXAMPLE_SEED, 0, limit, config.get_or("mean_stripe_n", 4), config.get_or("mean_stripe_d", 1), )) } // -- (PrimitiveUnsigned, PrimitiveSigned) -- pub fn special_random_unsigned_signed_pair_gen( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { striped_random_signeds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, )) } pub fn special_random_unsigned_signed_pair_gen_var_1( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_large_unsigned_stripe_n", T::WIDTH >> 1), config.get_or("mean_large_unsigned_stripe_d", 1), ) }, &|seed| { geometric_random_signeds( seed, config.get_or("mean_small_signed_n", 32), config.get_or("mean_small_signed_d", 1), ) }, )) } struct IntegerMantissaAndExponentGenerator { xs: NonzeroValues>, shifts: GeometricRandomNaturalValues, } impl Iterator for IntegerMantissaAndExponentGenerator { type Item = (u64, i64); fn next(&mut self) -> Option<(u64, i64)> { loop { let (mantissa, exponent) = self.xs.next().unwrap().integer_mantissa_and_exponent(); let shift = self.shifts.next().unwrap(); let out = shift_integer_mantissa_and_exponent(mantissa, exponent, shift); if out.is_some() { return out; } } } } pub fn special_random_unsigned_signed_pair_gen_var_2( config: &GenConfig, ) -> It<(u64, i64)> { Box::new(IntegerMantissaAndExponentGenerator:: { xs: random_nonzero_finite_primitive_floats(EXAMPLE_SEED.fork("xs")), shifts: geometric_random_natural_signeds( EXAMPLE_SEED.fork("shifts"), config.get_or("shift_mean_n", 4), config.get_or("shift_mean_d", 1), ), }) } // -- (PrimitiveUnsigned, PrimitiveSigned, PrimitiveUnsigned) -- struct ModPowerOfTwoTripleExtraSmallSignedGenerator { ms: GeometricRandomNaturalValues, xss: Vec>>, us: GeometricRandomSigneds, mean_stripe_n: u64, mean_stripe_d: u64, } impl Iterator for ModPowerOfTwoTripleExtraSmallSignedGenerator { type Item = (T, U, u64); fn next(&mut self) -> Option<(T, U, u64)> { let pow = self.ms.next().unwrap(); let x = if pow == 0 { T::ZERO } else { let xs = &mut self.xss[usize::wrapping_from(pow)]; if xs.is_none() { *xs = Some(striped_random_unsigned_bit_chunks( EXAMPLE_SEED.fork(&pow.to_string()), pow, self.mean_stripe_n, self.mean_stripe_d, )); } xs.as_mut().unwrap().next().unwrap() }; Some((x, self.us.next().unwrap(), pow)) } } pub fn special_random_unsigned_signed_unsigned_triple_gen_var_1< T: PrimitiveUnsigned, U: PrimitiveSigned, >( config: &GenConfig, ) -> It<(T, U, u64)> { Box::new(ModPowerOfTwoTripleExtraSmallSignedGenerator { ms: geometric_random_unsigned_range( EXAMPLE_SEED.fork("ms"), 0, T::WIDTH, config.get_or("mean_pow_n", T::WIDTH >> 1), config.get_or("mean_pow_d", 1), ), us: geometric_random_signeds( EXAMPLE_SEED.fork("ms"), config.get_or("mean_pow_n", T::WIDTH >> 1), config.get_or("mean_pow_d", 1), ), xss: vec![None; usize::wrapping_from(T::WIDTH) + 1], mean_stripe_n: config.get_or("mean_stripe_n", T::WIDTH >> 1), mean_stripe_d: config.get_or("mean_stripe_d", 1), }) } pub fn special_random_unsigned_signed_unsigned_triple_gen_var_2< T: PrimitiveUnsigned, U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >( config: &GenConfig, ) -> It<(T, S, T)> { Box::new( random_triples_xyx( EXAMPLE_SEED, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_large_unsigned_stripe_n", T::WIDTH >> 1), config.get_or("mean_large_unsigned_stripe_d", 1), ) }, &|seed| { striped_random_signed_inclusive_range::( seed, if S::WIDTH <= u64::WIDTH { S::MIN } else { -S::exact_from(u64::MAX) }, S::saturating_from(u64::MAX), config.get_or("mean_stripe_n", S::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, ) .filter_map(|(x, y, z): (T, S, T)| match x.cmp(&z) { Equal => None, Less => Some((x, y, z)), Greater => Some((z, y, x)), }), ) } pub fn special_random_unsigned_signed_unsigned_triple_gen_var_3< T: PrimitiveUnsigned, U: PrimitiveSigned, >( config: &GenConfig, ) -> It<(T, U, T)> { Box::new( random_triples_xyx( EXAMPLE_SEED, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_large_unsigned_stripe_n", T::WIDTH >> 1), config.get_or("mean_large_unsigned_stripe_d", 1), ) }, &|seed| { striped_random_signeds( seed, config.get_or("mean_large_unsigned_stripe_n", U::WIDTH >> 1), config.get_or("mean_large_unsigned_stripe_d", 1), ) }, ) .filter_map(|(x, y, z): (T, U, T)| match x.cmp(&z) { Equal => None, Less => Some((x, y, z)), Greater => Some((z, y, x)), }), ) } pub fn special_random_unsigned_signed_unsigned_triple_gen_var_4< T: PrimitiveUnsigned, U: PrimitiveSigned, V: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(T, U, V)> { Box::new(random_triples( EXAMPLE_SEED, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_large_unsigned_stripe_n", T::WIDTH >> 1), config.get_or("mean_large_unsigned_stripe_d", 1), ) }, &|seed| { geometric_random_signeds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, &|seed| { geometric_random_positive_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, )) } // -- (PrimitiveUnsigned, PrimitiveSigned, RoundingMode) -- pub fn special_random_unsigned_signed_rounding_mode_triple_gen_var_1< T: PrimitiveUnsigned, U: PrimitiveSigned, >( config: &GenConfig, ) -> It<(T, U, RoundingMode)> { Box::new( random_triples( EXAMPLE_SEED, &|seed| { striped_random_unsigneds::( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { geometric_random_signeds::( seed, config.get_or("mean_shift_n", 4), config.get_or("mean_shift_d", 1), ) }, &random_rounding_modes, ) .filter(|&(x, pow, rm)| { rm != Exact || pow <= U::ZERO || x.divisible_by_power_of_2(pow.exact_into()) }), ) } pub fn special_random_unsigned_signed_rounding_mode_triple_gen_var_2< T: PrimitiveUnsigned, U: PrimitiveSigned, >( config: &GenConfig, ) -> It<(T, U, RoundingMode)> { Box::new( random_triples( EXAMPLE_SEED, &|seed| { striped_random_unsigneds::( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { geometric_random_signeds::( seed, config.get_or("mean_shift_n", 4), config.get_or("mean_shift_d", 1), ) }, &random_rounding_modes, ) .filter(|&(x, pow, rm)| { let pow: i64 = pow.exact_into(); rm != Exact || pow >= 0 || x.divisible_by_power_of_2(pow.unsigned_abs()) }), ) } // -- (PrimitiveUnsigned, PrimitiveUnsigned) -- pub fn special_random_unsigned_pair_gen( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_stripe_n", U::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, )) } pub fn special_random_unsigned_pair_gen_var_1( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_large_unsigned_stripe_n", T::WIDTH >> 1), config.get_or("mean_large_unsigned_stripe_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, )) } pub fn special_random_unsigned_pair_gen_var_2( config: &GenConfig, ) -> It<(T, u64)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| random_unsigneds_less_than(seed, T::WIDTH), )) } pub fn special_random_unsigned_pair_gen_var_3( config: &GenConfig, ) -> It<(T, u64)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { striped_random_unsigned_inclusive_range( seed, 1, U::WIDTH, config.get_or("mean_stripe_n", U::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, )) } pub fn special_random_unsigned_pair_gen_var_4< T: PrimitiveUnsigned, U: PrimitiveUnsigned + SaturatingFrom, >( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { striped_random_unsigned_inclusive_range( seed, U::TWO, U::saturating_from(T::MAX), config.get_or("mean_stripe_n", U::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, )) } // TODO make better pub fn special_random_unsigned_pair_gen_var_5( config: &GenConfig, ) -> It<(T, T)> { Box::new( random_pairs_from_single(striped_random_unsigneds( EXAMPLE_SEED, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), )) .map(|(x, y)| if x <= y { (x, y) } else { (y, x) }), ) } pub fn special_random_unsigned_pair_gen_var_6< T: PrimitiveUnsigned, U: ExactFrom + PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { striped_random_unsigned_inclusive_range( seed, U::TWO, U::exact_from(36u8), config.get_or("mean_stripe_n", U::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, )) } pub fn special_random_unsigned_pair_gen_var_7( config: &GenConfig, ) -> It<(T, T)> { Box::new( random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigneds::( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { striped_random_positive_unsigneds::( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, ) .map(|(x, y)| (x.round_to_multiple(y, Down).0, y)), ) } pub fn special_random_unsigned_pair_gen_var_8( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigneds::( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { striped_random_positive_unsigneds::( seed, config.get_or("mean_stripe_n", U::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, )) } pub fn special_random_unsigned_pair_gen_var_9( config: &GenConfig, ) -> It<(T, T)> { Box::new( random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigneds::( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { striped_random_positive_unsigneds::( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, ) .filter(|&(x, y)| !x.divisible_by(y)), ) } pub fn special_random_unsigned_pair_gen_var_10( config: &GenConfig, ) -> It<(T, U)> { Box::new( random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigneds::( seed, config.get_or("mean_large_unsigned_stripe_n", T::WIDTH >> 1), config.get_or("mean_large_unsigned_stripe_d", 1), ) }, &|seed| { geometric_random_unsigneds::( seed, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, ) .filter(|&(x, y)| !x.divisible_by_power_of_2(y.exact_into())), ) } pub fn special_random_unsigned_pair_gen_var_11( config: &GenConfig, ) -> It<(T, U)> { Box::new( random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigneds::( seed, config.get_or("mean_large_unsigned_stripe_n", T::WIDTH >> 1), config.get_or("mean_large_unsigned_stripe_d", 1), ) }, &|seed| { geometric_random_unsigneds::( seed, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, ) .map(|(mut x, y)| { x.round_to_multiple_of_power_of_2_assign(y.exact_into(), Down); (x, y) }), ) } pub fn special_random_unsigned_pair_gen_var_12( config: &GenConfig, ) -> It<(T, T)> { Box::new(random_ordered_unique_pairs(striped_random_unsigneds::( EXAMPLE_SEED, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ))) } struct ModPowerOfTwoSingleGenerator { ms: GeometricRandomNaturalValues, xss: Vec>>, mean_stripe_n: u64, mean_stripe_d: u64, } impl Iterator for ModPowerOfTwoSingleGenerator { type Item = (T, u64); fn next(&mut self) -> Option<(T, u64)> { let pow = self.ms.next().unwrap(); let x = if pow == 0 { T::ZERO } else { let xs = &mut self.xss[usize::wrapping_from(pow)]; if xs.is_none() { *xs = Some(striped_random_unsigned_bit_chunks( EXAMPLE_SEED.fork(&pow.to_string()), pow, self.mean_stripe_n, self.mean_stripe_d, )); } xs.as_mut().unwrap().next().unwrap() }; Some((x, pow)) } } struct ModPowerOfTwoSingleGenerator2 { ms: GeometricRandomNaturalValues, xss: Vec>>>, mean_stripe_n: u64, mean_stripe_d: u64, } impl Iterator for ModPowerOfTwoSingleGenerator2 { type Item = (T, u64); fn next(&mut self) -> Option<(T, u64)> { let pow = self.ms.next().unwrap(); assert_ne!(pow, 0); let xs = &mut self.xss[usize::wrapping_from(pow)]; if xs.is_none() { *xs = Some(Box::new( striped_random_unsigned_bit_chunks( EXAMPLE_SEED.fork(&pow.to_string()), pow, self.mean_stripe_n, self.mean_stripe_d, ) .filter(|&x| x != T::ZERO), )); } let x = xs.as_mut().unwrap().next().unwrap(); Some((x, pow)) } } pub fn special_random_unsigned_pair_gen_var_13( config: &GenConfig, ) -> It<(T, u64)> { Box::new(ModPowerOfTwoSingleGenerator { ms: geometric_random_unsigned_range( EXAMPLE_SEED.fork("ms"), 0, T::WIDTH, config.get_or("mean_pow_n", T::WIDTH >> 1), config.get_or("mean_pow_d", 1), ), xss: vec![None; usize::wrapping_from(T::WIDTH) + 1], mean_stripe_n: config.get_or("mean_stripe_n", T::WIDTH >> 1), mean_stripe_d: config.get_or("mean_stripe_d", 1), }) } pub fn special_random_unsigned_pair_gen_var_14( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_positive_unsigneds( seed, config.get_or("mean_large_unsigned_stripe_n", T::WIDTH >> 1), config.get_or("mean_large_unsigned_stripe_d", 1), ) }, &|seed| { geometric_random_positive_unsigneds( seed, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, )) } pub fn special_random_unsigned_pair_gen_var_15( config: &GenConfig, ) -> It<(T, u64)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| random_unsigneds_less_than(seed, U::WIDTH + 1), )) } pub fn special_random_unsigned_pair_gen_var_16( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_positive_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { geometric_random_unsigned_range( seed, U::TWO, U::MAX, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, )) } pub fn special_random_unsigned_pair_gen_var_17( config: &GenConfig, ) -> It<(T, u64)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_signeds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| random_unsigneds_less_than(seed, U::WIDTH + 1), )) } pub fn special_random_unsigned_pair_gen_var_18( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigned_inclusive_range( seed, T::ZERO, T::saturating_from(u64::MAX), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { striped_random_positive_unsigneds::( seed, config.get_or("mean_stripe_n", U::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, )) } pub fn special_random_unsigned_pair_gen_var_19( config: &GenConfig, ) -> It<(u64, u64)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigned_bit_chunks( seed, T::MANTISSA_WIDTH, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { striped_random_unsigned_bit_chunks( seed, T::EXPONENT_WIDTH, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, )) } pub fn special_random_unsigned_pair_gen_var_20( config: &GenConfig, ) -> It<(T, u64)> { Box::new(special_random_unsigned_pair_gen_var_13(config).map(|(x, p)| (x, T::WIDTH - p))) } pub fn special_random_unsigned_pair_gen_var_21( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_large_unsigned_stripe_n", T::WIDTH >> 1), config.get_or("mean_large_unsigned_stripe_d", 1), ) }, &|seed| { geometric_random_positive_unsigneds( seed, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, )) } struct LikelyMultiplyablePairs { bits: GeometricRandomNaturalValues, striped_bit_source: StripedBitSource, phantom: PhantomData<*const T>, } impl Iterator for LikelyMultiplyablePairs { type Item = (T, T); fn next(&mut self) -> Option<(T, T)> { let x = T::from_bits_asc( get_striped_bool_vec(&mut self.striped_bit_source, self.bits.next().unwrap()) .into_iter(), ); let y = T::from_bits_asc( get_striped_bool_vec(&mut self.striped_bit_source, self.bits.next().unwrap()) .into_iter(), ); Some((x, y)) } } pub fn special_random_unsigned_pair_gen_var_22( config: &GenConfig, ) -> It<(T, T)> { Box::new(LikelyMultiplyablePairs { bits: geometric_random_unsigned_inclusive_range( EXAMPLE_SEED.fork("bits"), 0, T::WIDTH, T::WIDTH >> 1, 1, ), striped_bit_source: StripedBitSource::new( EXAMPLE_SEED.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), phantom: PhantomData, }) } pub fn special_random_unsigned_pair_gen_var_23( config: &GenConfig, ) -> It<(T, T)> { Box::new( special_random_unsigned_pair_gen_var_22::(config) .filter(|&(x, y)| x.checked_lcm(y).is_some()), ) } pub fn special_random_unsigned_pair_gen_var_24( config: &GenConfig, ) -> It<(T, T)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigned_inclusive_range( seed, T::power_of_2(T::WIDTH - 1), T::MAX, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_unsigned_stripe_n", T::WIDTH >> 1), config.get_or("mean_unsigned_stripe_d", 1), ) }, )) } pub fn special_random_unsigned_pair_gen_var_25( config: &GenConfig, ) -> It<(T, T)> { Box::new( random_pairs( EXAMPLE_SEED, &|seed| { striped_random_positive_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, ) .filter(|&(x, y)| x != T::ONE || y != T::ZERO), ) } pub fn special_random_unsigned_pair_gen_var_26(config: &GenConfig) -> It<(u32, u32)> { Box::new(random_pairs_from_single(striped_random_unsigned_range( EXAMPLE_SEED, 0, NUMBER_OF_CHARS, config.get_or("mean_stripe_n", 16), config.get_or("mean_stripe_d", 1), ))) } pub fn special_random_unsigned_pair_gen_var_27( config: &GenConfig, ) -> It<(T, u64)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, &|seed| { striped_random_unsigned_inclusive_range( seed, 1, U::WIDTH, config.get_or("mean_stripe_n", 4), config.get_or("mean_stripe_d", 1), ) }, )) } pub fn special_random_unsigned_pair_gen_var_28< T: PrimitiveUnsigned, U: ExactFrom + PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, &|seed| { striped_random_unsigned_inclusive_range( seed, U::TWO, U::exact_from(36u8), config.get_or("mean_stripe_n", 4), config.get_or("mean_stripe_d", 1), ) }, )) } pub fn special_random_unsigned_pair_gen_var_29< T: PrimitiveUnsigned + SaturatingFrom, U: PrimitiveUnsigned, V: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(T, V)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigned_inclusive_range( seed, T::TWO, T::saturating_from(U::MAX), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, )) } pub fn special_random_unsigned_pair_gen_var_30< T: PrimitiveUnsigned, U: ExactFrom + PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { geometric_random_positive_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, &|seed| { striped_random_unsigned_inclusive_range( seed, U::TWO, U::exact_from(36u8), config.get_or("mean_stripe_n", 4), config.get_or("mean_stripe_d", 1), ) }, )) } pub fn special_random_unsigned_pair_gen_var_31( config: &GenConfig, ) -> It<(T, u64)> { Box::new( random_union2s( EXAMPLE_SEED, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) .map(|x| (T::ZERO, x)) }, &|seed| { random_pairs( seed, &|seed_2| { striped_random_positive_unsigneds::( seed_2, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed_2| { striped_random_unsigned_range( seed_2, 0, T::WIDTH, config.get_or("mean_stripe_n", 4), config.get_or("mean_stripe_d", 1), ) }, ) }, ) .map(Union2::unwrap), ) } pub fn special_random_unsigned_pair_gen_var_32( config: &GenConfig, ) -> It<(u64, u64)> { Box::new(random_pairs_from_single(striped_random_unsigned_range( EXAMPLE_SEED, 0, T::LARGEST_ORDERED_REPRESENTATION, config.get_or("mean_stripe_n", 32), config.get_or("mean_stripe_d", 1), ))) } pub fn special_random_unsigned_pair_gen_var_33( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigned_inclusive_range( seed, T::power_of_2(T::WIDTH - 2), T::MAX, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_stripe_n", U::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, )) } pub fn special_random_unsigned_pair_gen_var_34( config: &GenConfig, ) -> It<(T, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_positive_unsigneds( seed, config.get_or("mean_large_unsigned_stripe_n", T::WIDTH >> 1), config.get_or("mean_large_unsigned_stripe_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, )) } pub fn special_random_unsigned_pair_gen_var_35( config: &GenConfig, ) -> It<(T, T)> { Box::new(random_pairs_from_single(striped_random_unsigneds( EXAMPLE_SEED, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ))) } pub fn special_random_unsigned_pair_gen_var_36( config: &GenConfig, ) -> It<(T, T)> { Box::new(random_ordered_unique_pairs( striped_random_positive_unsigneds::( EXAMPLE_SEED, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), )) } pub fn special_random_unsigned_pair_gen_var_37( config: &GenConfig, ) -> It<(T, u64)> { Box::new(ModPowerOfTwoSingleGenerator2 { ms: geometric_random_unsigned_range( EXAMPLE_SEED.fork("ms"), 1, T::WIDTH, config.get_or("mean_pow_n", T::WIDTH >> 1), config.get_or("mean_pow_d", 1), ), xss: { let len = usize::wrapping_from(T::WIDTH) + 1; let mut xss = Vec::with_capacity(len); xss.resize_with(len, || None); xss }, mean_stripe_n: config.get_or("mean_stripe_n", T::WIDTH >> 1), mean_stripe_d: config.get_or("mean_stripe_d", 1), }) } pub fn special_random_unsigned_pair_gen_var_38( config: &GenConfig, ) -> It<(T, T)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { striped_random_unsigned_inclusive_range( seed, T::ZERO, T::low_mask(T::WIDTH - 1), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) .map(|u| (u << 1) | T::ONE) }, )) } pub fn special_random_unsigned_pair_gen_var_39( config: &GenConfig, ) -> It<(T, T)> { Box::new( random_pairs_from_single( striped_random_unsigned_inclusive_range( EXAMPLE_SEED, T::ZERO, T::low_mask(T::WIDTH - 1), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) .map(|u| (u << 1) | T::ONE), ) .filter(|&(a, b): &(T, T)| a.coprime_with(b)), ) } pub fn special_random_unsigned_pair_gen_var_40( config: &GenConfig, ) -> It<(T, T)> { Box::new( random_pairs_from_single(striped_random_unsigneds( EXAMPLE_SEED, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), )) .filter(|&(x, y): &(T, T)| x.coprime_with(y)), ) } // -- (PrimitiveUnsigned, PrimitiveUnsigned, bool) -- pub fn special_random_unsigned_unsigned_bool_triple_gen_var_1( config: &GenConfig, ) -> It<(T, u64, bool)> { reshape_1_2_to_3(Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { random_union2s( seed, &|seed_2| { geometric_random_unsigneds( seed_2, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) .map(|x| (x, false)) }, &|seed_2| random_unsigneds_less_than(seed_2, T::WIDTH).map(|x| (x, true)), ) .map(Union2::unwrap) }, ))) } pub fn special_random_unsigned_unsigned_bool_triple_gen_var_2< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(T, U, bool)> { Box::new(random_triples( EXAMPLE_SEED, &|seed| { striped_random_unsigneds::( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { striped_random_positive_unsigneds::( seed, config.get_or("mean_stripe_n", U::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &random_bools, )) } // -- (PrimitiveUnsigned, PrimitiveUnsigned, PrimitiveUnsigned) -- pub fn special_random_unsigned_triple_gen_var_1( config: &GenConfig, ) -> It<(T, T, T)> { Box::new( random_triples_from_single(striped_random_unsigneds( EXAMPLE_SEED, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), )) .map(|(x, y, z)| reduce_to_fit_add_mul_unsigned(x, y, z)), ) } pub fn special_random_unsigned_triple_gen_var_2( config: &GenConfig, ) -> It<(T, T, T)> { Box::new( random_triples_from_single(striped_random_unsigneds( EXAMPLE_SEED, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), )) .map(|(x, y, z)| reduce_to_fit_sub_mul_unsigned(x, y, z)), ) } pub fn special_random_unsigned_triple_gen_var_3< T: PrimitiveUnsigned, U: PrimitiveInt, V: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(T, u64, V)> { Box::new(random_triples( EXAMPLE_SEED, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { striped_random_unsigned_inclusive_range( seed, 1, U::WIDTH, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, )) } pub fn special_random_unsigned_triple_gen_var_4( config: &GenConfig, ) -> It<(T, T, U)> { Box::new(random_triples_xxy( EXAMPLE_SEED, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_large_unsigned_stripe_n", T::WIDTH >> 1), config.get_or("mean_large_unsigned_stripe_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, )) } pub fn special_random_unsigned_triple_gen_var_5( config: &GenConfig, ) -> It<(T, U, U)> { Box::new( random_triples_xyy( EXAMPLE_SEED, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_large_unsigned_stripe_n", T::WIDTH >> 1), config.get_or("mean_large_unsigned_stripe_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, ) .map(|(x, y, z)| if y <= z { (x, y, z) } else { (x, z, y) }), ) } pub fn special_random_unsigned_triple_gen_var_6< T: PrimitiveUnsigned, U: ExactFrom + PrimitiveUnsigned, V: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(T, U, V)> { Box::new(random_triples( EXAMPLE_SEED, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { striped_random_unsigned_inclusive_range( seed, U::TWO, U::exact_from(36u8), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("small_unsigned_mean_n", 4), config.get_or("small_unsigned_mean_d", 1), ) }, )) } pub fn special_random_unsigned_triple_gen_var_7( config: &GenConfig, ) -> It<(T, T, T)> { Box::new( random_triples_from_single(striped_random_unsigneds::( EXAMPLE_SEED, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), )) .map(|(x, y, m)| { if m == T::ZERO { let min = min(x, y); (min, min, m) } else if x <= y { let adjusted_diff = (y - x).round_to_multiple(m, Down).0; (x, x + adjusted_diff, m) } else { let adjusted_diff = (x - y).round_to_multiple(m, Down).0; (y + adjusted_diff, y, m) } }), ) } pub fn special_random_unsigned_triple_gen_var_8( config: &GenConfig, ) -> It<(T, T, T)> { Box::new( random_triples_from_single(striped_random_unsigneds::( EXAMPLE_SEED, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), )) .filter(|&(x, y, m)| !x.eq_mod(y, m)), ) } pub fn special_random_unsigned_triple_gen_var_9( config: &GenConfig, ) -> It<(T, T, u64)> { Box::new( random_triples_xxy( EXAMPLE_SEED, &|seed| { striped_random_unsigneds::( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_pow_n", 32), config.get_or("mean_pow_d", 1), ) }, ) .map(|(x, y, pow)| { if pow >= T::WIDTH { (x, x, pow) } else if x <= y { let adjusted_diff = (y - x).round_to_multiple_of_power_of_2(pow, Down).0; (x, x + adjusted_diff, pow) } else { let adjusted_diff = (x - y).round_to_multiple_of_power_of_2(pow, Down).0; (y + adjusted_diff, y, pow) } }), ) } pub fn special_random_unsigned_triple_gen_var_10( config: &GenConfig, ) -> It<(T, T, u64)> { Box::new( random_triples_xxy( EXAMPLE_SEED, &|seed| { striped_random_unsigneds::( seed, config.get_or("mean_large_unsigned_stripe_n", T::WIDTH >> 1), config.get_or("mean_large_unsigned_stripe_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, ) .filter(|&(x, y, pow)| !x.eq_mod_power_of_2(y, pow)), ) } struct ModPowerOfTwoPairGenerator { ms: GeometricRandomNaturalValues, xss: Vec>>, mean_stripe_n: u64, mean_stripe_d: u64, } impl Iterator for ModPowerOfTwoPairGenerator { type Item = (T, T, u64); fn next(&mut self) -> Option<(T, T, u64)> { let pow = self.ms.next().unwrap(); let (x, y) = if pow == 0 { (T::ZERO, T::ZERO) } else { let xs = &mut self.xss[usize::wrapping_from(pow)]; if xs.is_none() { *xs = Some(striped_random_unsigned_bit_chunks( EXAMPLE_SEED.fork(&pow.to_string()), pow, self.mean_stripe_n, self.mean_stripe_d, )); } let xs = xs.as_mut().unwrap(); (xs.next().unwrap(), xs.next().unwrap()) }; Some((x, y, pow)) } } pub fn special_random_unsigned_triple_gen_var_11( config: &GenConfig, ) -> It<(T, T, u64)> { Box::new(ModPowerOfTwoPairGenerator { ms: geometric_random_unsigned_range( EXAMPLE_SEED.fork("ms"), 0, T::WIDTH, config.get_or("mean_pow_n", T::WIDTH >> 1), config.get_or("mean_pow_d", 1), ), xss: vec![None; usize::wrapping_from(T::WIDTH) + 1], mean_stripe_n: config.get_or("mean_stripe_n", T::WIDTH >> 1), mean_stripe_d: config.get_or("mean_stripe_d", 1), }) } pub fn special_random_unsigned_triple_gen_var_12( config: &GenConfig, ) -> It<(T, T, T)> { Box::new( random_triples_from_single(striped_random_unsigneds::( EXAMPLE_SEED, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), )) .filter_map(|(x, y, z)| { let ranking = [(x, 0), (y, 1), (z, 2)]; let (hi, next_hi) = get_two_highest(&ranking); if hi.0 == next_hi.0 { None } else { Some(match hi.1 { 0 => (y, z, x), 1 => (x, z, y), _ => (x, y, z), }) } }), ) } pub fn special_random_unsigned_triple_gen_var_13( config: &GenConfig, ) -> It<(T, U, U)> { Box::new(random_triples_xyy( EXAMPLE_SEED, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_large_unsigned_stripe_n", T::WIDTH >> 1), config.get_or("mean_large_unsigned_stripe_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, )) } pub fn special_random_unsigned_triple_gen_var_14( config: &GenConfig, ) -> It<(T, U, T)> { Box::new( random_triples_xyx( EXAMPLE_SEED, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_large_unsigned_stripe_n", T::WIDTH >> 1), config.get_or("mean_large_unsigned_stripe_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, ) .filter_map(|(x, y, z): (T, U, T)| match x.cmp(&z) { Equal => None, Less => Some((x, y, z)), Greater => Some((z, y, x)), }), ) } pub fn special_random_unsigned_triple_gen_var_15( config: &GenConfig, ) -> It<(T, U, T)> { Box::new( random_triples_xyx( EXAMPLE_SEED, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_large_unsigned_stripe_n", T::WIDTH >> 1), config.get_or("mean_large_unsigned_stripe_d", 1), ) }, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_large_unsigned_stripe_n", U::WIDTH >> 1), config.get_or("mean_large_unsigned_stripe_d", 1), ) }, ) .filter_map(|(x, y, z): (T, U, T)| match x.cmp(&z) { Equal => None, Less => Some((x, y, z)), Greater => Some((z, y, x)), }), ) } struct ModPowerOfTwoTripleExtraUnsignedGenerator { ms: GeometricRandomNaturalValues, xss: Vec>>, us: StripedRandomUnsignedBitChunks, mean_stripe_n: u64, mean_stripe_d: u64, } impl Iterator for ModPowerOfTwoTripleExtraUnsignedGenerator { type Item = (T, U, u64); fn next(&mut self) -> Option<(T, U, u64)> { let pow = self.ms.next().unwrap(); let x = if pow == 0 { T::ZERO } else { let xs = &mut self.xss[usize::wrapping_from(pow)]; if xs.is_none() { *xs = Some(striped_random_unsigned_bit_chunks( EXAMPLE_SEED.fork(&pow.to_string()), pow, self.mean_stripe_n, self.mean_stripe_d, )); } xs.as_mut().unwrap().next().unwrap() }; Some((x, self.us.next().unwrap(), pow)) } } pub fn special_random_unsigned_triple_gen_var_16( config: &GenConfig, ) -> It<(T, U, u64)> { Box::new(ModPowerOfTwoTripleExtraUnsignedGenerator { ms: geometric_random_unsigned_range( EXAMPLE_SEED.fork("ms"), 0, T::WIDTH, config.get_or("mean_pow_n", T::WIDTH >> 1), config.get_or("mean_pow_d", 1), ), us: striped_random_unsigneds::( EXAMPLE_SEED.fork("us"), config.get_or("mean_stripe_n", U::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), xss: vec![None; usize::wrapping_from(T::WIDTH) + 1], mean_stripe_n: config.get_or("mean_stripe_n", T::WIDTH >> 1), mean_stripe_d: config.get_or("mean_stripe_d", 1), }) } struct ModPowerOfTwoTripleExtraSmallUnsignedGenerator { ms: GeometricRandomNaturalValues, xss: Vec>>, us: GeometricRandomNaturalValues, mean_stripe_n: u64, mean_stripe_d: u64, } impl Iterator for ModPowerOfTwoTripleExtraSmallUnsignedGenerator { type Item = (T, U, u64); fn next(&mut self) -> Option<(T, U, u64)> { let pow = self.ms.next().unwrap(); let x = if pow == 0 { T::ZERO } else { let xs = &mut self.xss[usize::wrapping_from(pow)]; if xs.is_none() { *xs = Some(striped_random_unsigned_bit_chunks( EXAMPLE_SEED.fork(&pow.to_string()), pow, self.mean_stripe_n, self.mean_stripe_d, )); } xs.as_mut().unwrap().next().unwrap() }; Some((x, self.us.next().unwrap(), pow)) } } pub fn special_random_unsigned_triple_gen_var_17( config: &GenConfig, ) -> It<(T, U, u64)> { Box::new(ModPowerOfTwoTripleExtraSmallUnsignedGenerator { ms: geometric_random_unsigned_range( EXAMPLE_SEED.fork("ms"), 0, T::WIDTH, config.get_or("mean_pow_n", T::WIDTH >> 1), config.get_or("mean_pow_d", 1), ), us: geometric_random_unsigneds( EXAMPLE_SEED.fork("ms"), config.get_or("mean_pow_n", T::WIDTH >> 1), config.get_or("mean_pow_d", 1), ), xss: vec![None; usize::wrapping_from(T::WIDTH) + 1], mean_stripe_n: config.get_or("mean_stripe_n", T::WIDTH >> 1), mean_stripe_d: config.get_or("mean_stripe_d", 1), }) } pub fn special_random_unsigned_triple_gen_var_18( config: &GenConfig, ) -> It<(T, U, T)> { Box::new( random_triples_xyx( EXAMPLE_SEED, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_large_unsigned_stripe_n", T::WIDTH >> 1), config.get_or("mean_large_unsigned_stripe_d", 1), ) }, &|seed| { striped_random_unsigned_inclusive_range( seed, U::ZERO, U::saturating_from(u64::MAX), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, ) .filter_map(|(x, y, z): (T, U, T)| match x.cmp(&z) { Equal => None, Less => Some((x, y, z)), Greater => Some((z, y, x)), }), ) } pub fn special_random_unsigned_triple_gen_var_19( config: &GenConfig, ) -> It<(T, T, T)> { Box::new(random_triples_from_single(striped_random_unsigneds( EXAMPLE_SEED, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ))) } pub fn special_random_unsigned_triple_gen_var_20( config: &GenConfig, ) -> It<(T, U, U)> { Box::new( random_triples_xyy( EXAMPLE_SEED, &|seed| { striped_random_positive_unsigneds( seed, config.get_or("mean_large_unsigned_stripe_n", T::WIDTH >> 1), config.get_or("mean_large_unsigned_stripe_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, ) .map(|(x, y, z)| if y <= z { (x, y, z) } else { (x, z, y) }), ) } pub fn special_random_unsigned_triple_gen_var_21( config: &GenConfig, ) -> It<(T, T, T)> { Box::new(random_triples_xyx( EXAMPLE_SEED, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { striped_random_unsigned_inclusive_range( seed, T::ZERO, T::low_mask(T::WIDTH - 1), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) .map(|u| (u << 1) | T::ONE) }, )) } pub fn special_random_unsigned_triple_gen_var_22( config: &GenConfig, ) -> It<(T, T, T)> { Box::new(random_triples_xxy( EXAMPLE_SEED, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { striped_random_unsigned_inclusive_range( seed, T::ZERO, T::low_mask(T::WIDTH - 1), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) .map(|u| (u << 1) | T::ONE) }, )) } pub fn special_random_unsigned_triple_gen_var_23( config: &GenConfig, ) -> It<(T, T, T)> { Box::new(random_triples_xyy( EXAMPLE_SEED, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { striped_random_unsigned_inclusive_range( seed, T::ZERO, T::low_mask(T::WIDTH - 1), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) .map(|u| (u << 1) | T::ONE) }, )) } // -- (PrimitiveUnsigned, PrimitiveUnsigned, PrimitiveUnsigned, PrimitiveUnsigned) -- pub fn special_random_unsigned_quadruple_gen_var_1( config: &GenConfig, ) -> It<(T, u64, u64, U)> { Box::new( random_quadruples_xyyz( EXAMPLE_SEED, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_large_unsigned_stripe_n", T::WIDTH >> 1), config.get_or("mean_large_unsigned_stripe_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_large_unsigned_stripe_n", T::WIDTH >> 1), config.get_or("mean_large_unsigned_stripe_d", 1), ) }, ) .filter_map(|(x, y, z, w)| { let (y, z) = if y <= z { (y, z) } else { (z, y) }; if unsigned_assign_bits_valid(y, z, w) { Some((x, y, z, w)) } else { None } }), ) } pub fn special_random_unsigned_quadruple_gen_var_2( config: &GenConfig, ) -> It<(T, T, T, U)> { Box::new(random_quadruples_xxxy( EXAMPLE_SEED, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_large_unsigned_stripe_n", T::WIDTH >> 1), config.get_or("mean_large_unsigned_stripe_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, )) } struct ModPowerOfTwoTripleGenerator { ms: GeometricRandomNaturalValues, xss: Vec>>, mean_stripe_n: u64, mean_stripe_d: u64, } impl Iterator for ModPowerOfTwoTripleGenerator { type Item = (T, T, T, u64); fn next(&mut self) -> Option<(T, T, T, u64)> { let pow = self.ms.next().unwrap(); let (x, y, z) = if pow == 0 { (T::ZERO, T::ZERO, T::ZERO) } else { let xs = &mut self.xss[usize::wrapping_from(pow)]; if xs.is_none() { *xs = Some(striped_random_unsigned_bit_chunks( EXAMPLE_SEED.fork(&pow.to_string()), pow, self.mean_stripe_n, self.mean_stripe_d, )); } let xs = xs.as_mut().unwrap(); (xs.next().unwrap(), xs.next().unwrap(), xs.next().unwrap()) }; Some((x, y, z, pow)) } } pub fn special_random_unsigned_quadruple_gen_var_3( config: &GenConfig, ) -> It<(T, T, T, u64)> { Box::new(ModPowerOfTwoTripleGenerator { ms: geometric_random_unsigned_range( EXAMPLE_SEED.fork("ms"), 0, T::WIDTH, config.get_or("mean_pow_n", T::WIDTH >> 1), config.get_or("mean_pow_d", 1), ), xss: vec![None; usize::wrapping_from(T::WIDTH) + 1], mean_stripe_n: config.get_or("mean_stripe_n", T::WIDTH >> 1), mean_stripe_d: config.get_or("mean_stripe_d", 1), }) } pub fn special_random_unsigned_quadruple_gen_var_4( config: &GenConfig, ) -> It<(T, T, T, T)> { Box::new( random_quadruples_from_single(striped_random_unsigneds::( EXAMPLE_SEED, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), )) .filter_map(|(x, y, z, w)| { let ranking = [(x, 0), (y, 1), (z, 2), (w, 3)]; let (hi, next_hi) = get_two_highest(&ranking); if hi.0 == next_hi.0 { None } else { Some(match hi.1 { 0 => (y, z, w, x), 1 => (x, z, w, y), 2 => (x, y, w, z), _ => (x, y, z, w), }) } }), ) } pub fn special_random_unsigned_quadruple_gen_var_5< T: TryFrom
+ PrimitiveUnsigned, DT: From + HasHalf + JoinHalves + PrimitiveUnsigned + SplitInHalf, >( config: &GenConfig, ) -> It<(T, T, T, T)> { Box::new( random_triples_xxy( EXAMPLE_SEED, &|seed| { striped_random_unsigneds::( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { striped_random_positive_unsigneds::( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, ) .map(|(x_1, x_0, d)| { let inv = limbs_invert_limb_naive::(d << LeadingZeros::leading_zeros(d)); (x_1, x_0, d, inv) }), ) } pub fn special_random_unsigned_quadruple_gen_var_6( config: &GenConfig, ) -> It<(T, T, U, T)> { Box::new( random_quadruples_xxyx( EXAMPLE_SEED, &|seed| { striped_random_unsigneds::( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { striped_random_unsigneds::( seed, config.get_or("mean_stripe_n", U::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, ) .filter_map(|(x, y, z, w)| { let ranking = [(x, 0), (y, 1), (w, 2)]; let (hi, next_hi) = get_two_highest(&ranking); if hi.0 == next_hi.0 { None } else { Some(match hi.1 { 0 => (y, w, z, x), 1 => (x, w, z, y), _ => (x, y, z, w), }) } }), ) } pub fn special_random_unsigned_quadruple_gen_var_7( config: &GenConfig, ) -> It<(T, U, U, T)> { Box::new( random_quadruples_xyyx( EXAMPLE_SEED, &|seed| { striped_random_unsigneds::( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { striped_random_unsigneds::( seed, config.get_or("mean_stripe_n", U::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, ) .filter_map(|(x, y, z, w)| match x.cmp(&w) { Equal => None, Less => Some((x, y, z, w)), Greater => Some((w, y, z, x)), }), ) } struct ModPowerOfTwoQuadrupleWithExtraUnsignedGenerator { ms: GeometricRandomNaturalValues, xss: Vec>>, us: StripedRandomUnsignedBitChunks, mean_stripe_n: u64, mean_stripe_d: u64, } impl Iterator for ModPowerOfTwoQuadrupleWithExtraUnsignedGenerator { type Item = (T, T, U, u64); fn next(&mut self) -> Option<(T, T, U, u64)> { let pow = self.ms.next().unwrap(); let (x, y) = if pow == 0 { (T::ZERO, T::ZERO) } else { let xs = &mut self.xss[usize::wrapping_from(pow)]; if xs.is_none() { *xs = Some(striped_random_unsigned_bit_chunks( EXAMPLE_SEED.fork(&pow.to_string()), pow, self.mean_stripe_n, self.mean_stripe_d, )); } let xs = xs.as_mut().unwrap(); (xs.next().unwrap(), xs.next().unwrap()) }; Some((x, y, self.us.next().unwrap(), pow)) } } pub fn special_random_unsigned_quadruple_gen_var_8( config: &GenConfig, ) -> It<(T, T, U, u64)> { Box::new(ModPowerOfTwoQuadrupleWithExtraUnsignedGenerator { ms: geometric_random_unsigned_range( EXAMPLE_SEED.fork("ms"), 0, T::WIDTH, config.get_or("mean_pow_n", T::WIDTH >> 1), config.get_or("mean_pow_d", 1), ), us: striped_random_unsigneds::( EXAMPLE_SEED.fork("us"), config.get_or("mean_stripe_n", U::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), xss: vec![None; usize::wrapping_from(T::WIDTH) + 1], mean_stripe_n: config.get_or("mean_stripe_n", T::WIDTH >> 1), mean_stripe_d: config.get_or("mean_stripe_d", 1), }) } struct ModPowerOfTwoQuadrupleWithTwoExtraUnsignedGenerator< T: PrimitiveUnsigned, U: PrimitiveUnsigned, > { ms: GeometricRandomNaturalValues, xss: Vec>>, us: StripedRandomUnsignedBitChunks, mean_stripe_n: u64, mean_stripe_d: u64, } impl Iterator for ModPowerOfTwoQuadrupleWithTwoExtraUnsignedGenerator { type Item = (T, U, U, u64); fn next(&mut self) -> Option<(T, U, U, u64)> { let pow = self.ms.next().unwrap(); let x = if pow == 0 { T::ZERO } else { let xs = &mut self.xss[usize::wrapping_from(pow)]; if xs.is_none() { *xs = Some(striped_random_unsigned_bit_chunks( EXAMPLE_SEED.fork(&pow.to_string()), pow, self.mean_stripe_n, self.mean_stripe_d, )); } xs.as_mut().unwrap().next().unwrap() }; Some((x, self.us.next().unwrap(), self.us.next().unwrap(), pow)) } } pub fn special_random_unsigned_quadruple_gen_var_9( config: &GenConfig, ) -> It<(T, U, U, u64)> { Box::new(ModPowerOfTwoQuadrupleWithTwoExtraUnsignedGenerator { ms: geometric_random_unsigned_range( EXAMPLE_SEED.fork("ms"), 0, T::WIDTH, config.get_or("mean_pow_n", T::WIDTH >> 1), config.get_or("mean_pow_d", 1), ), us: striped_random_unsigneds::( EXAMPLE_SEED.fork("us"), config.get_or("mean_stripe_n", U::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), xss: vec![None; usize::wrapping_from(T::WIDTH) + 1], mean_stripe_n: config.get_or("mean_stripe_n", T::WIDTH >> 1), mean_stripe_d: config.get_or("mean_stripe_d", 1), }) } pub fn special_random_unsigned_quadruple_gen_var_10( config: &GenConfig, ) -> It<(T, T, T, T)> { Box::new(random_quadruples_from_single(striped_random_unsigneds( EXAMPLE_SEED, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ))) } pub fn special_random_unsigned_quadruple_gen_var_11( config: &GenConfig, ) -> It<(T, T, T, T)> { Box::new( random_quadruples_from_single(striped_random_unsigneds( EXAMPLE_SEED, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), )) .filter(|&(n1, n0, d1, d0)| { // conditions: D >= 2^W, N >= D, and N / D < 2^W d1 != T::ZERO && (n1 > d1 || n1 == d1 && n0 >= d0) }), ) } pub fn special_random_unsigned_quadruple_gen_var_12( config: &GenConfig, ) -> It<(T, T, T, T)> { Box::new(random_quadruples_xxxy( EXAMPLE_SEED, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { striped_random_unsigned_inclusive_range( seed, T::ZERO, T::low_mask(T::WIDTH - 1), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) .map(|u| (u << 1) | T::ONE) }, )) } // -- (PrimitiveUnsigned * 6) -- pub fn special_random_unsigned_sextuple_gen_var_1( config: &GenConfig, ) -> It<(T, T, T, T, T, T)> { Box::new(random_sextuples_from_single(striped_random_unsigneds( EXAMPLE_SEED, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ))) } // var 2 is in malachite-nz. // -- (PrimitiveUnsigned * 8) -- #[allow(clippy::type_complexity)] pub fn special_random_unsigned_octuple_gen_var_1( config: &GenConfig, ) -> It<(T, T, T, T, T, T, T, T)> { Box::new(random_octuples_from_single(striped_random_unsigneds( EXAMPLE_SEED, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ))) } // -- (PrimitiveUnsigned * 9) -- #[allow(clippy::type_complexity)] pub fn special_random_unsigned_nonuple_gen_var_1( config: &GenConfig, ) -> It<(T, T, T, T, T, T, T, T, T)> { Box::new( random_triples_from_single(random_triples_from_single(striped_random_unsigneds( EXAMPLE_SEED, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ))) .map(|((a, b, c), (d, e, f), (g, h, i))| (a, b, c, d, e, f, g, h, i)), ) } // -- (PrimitiveUnsigned * 12) -- #[allow(clippy::type_complexity)] pub fn special_random_unsigned_duodecuple_gen_var_1( config: &GenConfig, ) -> It<(T, T, T, T, T, T, T, T, T, T, T, T)> { Box::new(random_duodecuples_from_single(striped_random_unsigneds( EXAMPLE_SEED, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ))) } // -- (PrimitiveUnsigned, PrimitiveUnsigned, RoundingMode) -- struct UnsignedUnsignedRoundingModeTripleGenerator { xs: StripedRandomUnsignedBitChunks, rms: RandomRoundingModes, } impl Iterator for UnsignedUnsignedRoundingModeTripleGenerator { type Item = (T, T, RoundingMode); fn next(&mut self) -> Option<(T, T, RoundingMode)> { let mut x = self.xs.next().unwrap(); let mut y; loop { y = self.xs.next().unwrap(); if y != T::ZERO { break; } } let rm = self.rms.next().unwrap(); if rm == Exact { x.round_to_multiple_assign(y, Down); } Some((x, y, rm)) } } pub fn special_random_unsigned_unsigned_rounding_mode_triple_gen_var_1( config: &GenConfig, ) -> It<(T, T, RoundingMode)> { Box::new(UnsignedUnsignedRoundingModeTripleGenerator { xs: striped_random_unsigneds( EXAMPLE_SEED.fork("xs"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), rms: random_rounding_modes(EXAMPLE_SEED.fork("rms")), }) } pub fn special_random_unsigned_unsigned_rounding_mode_triple_gen_var_2( config: &GenConfig, ) -> It<(T, T, RoundingMode)> { Box::new( random_triples( EXAMPLE_SEED, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { striped_random_positive_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &random_rounding_modes, ) .filter_map(|(x, y, rm)| round_to_multiple_unsigned_filter_map(x, y, rm)), ) } pub fn special_random_unsigned_unsigned_rounding_mode_triple_gen_var_3( config: &GenConfig, ) -> It<(T, u64, RoundingMode)> { Box::new( random_triples( EXAMPLE_SEED, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &random_rounding_modes, ) .filter_map(|(x, pow, rm)| round_to_multiple_of_power_of_2_filter_map(x, pow, rm)), ) } pub fn special_random_unsigned_unsigned_rounding_mode_triple_gen_var_4< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(T, U, RoundingMode)> { Box::new( random_triples( EXAMPLE_SEED, &|seed| { striped_random_unsigneds::( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { geometric_random_unsigneds::( seed, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &random_rounding_modes, ) .filter(|&(x, y, rm)| rm != Exact || x.divisible_by_power_of_2(y.exact_into())), ) } // var 5 is in malachite-float. // -- (PrimitiveUnsigned, PrimitiveUnsigned, Vec) -- struct UnsignedUnsignedBoolVecTripleGeneratorVar1 { xs: StripedRandomUnsignedBitChunks, log_bases: StripedRandomUnsignedInclusiveRange, striped_bit_source: StripedBitSource, } impl Iterator for UnsignedUnsignedBoolVecTripleGeneratorVar1 { type Item = (T, u64, Vec); fn next(&mut self) -> Option<(T, u64, Vec)> { let x = self.xs.next().unwrap(); let log_base = self.log_bases.next().unwrap(); let bs = get_striped_bool_vec( &mut self.striped_bit_source, x.significant_bits().div_round(log_base, Ceiling).0, ); Some((x, log_base, bs)) } } pub fn special_random_unsigned_unsigned_bool_vec_triple_gen_var_1< T: PrimitiveUnsigned, U: PrimitiveInt, >( config: &GenConfig, ) -> It<(T, u64, Vec)> { Box::new(UnsignedUnsignedBoolVecTripleGeneratorVar1 { xs: striped_random_unsigneds( EXAMPLE_SEED.fork("xs"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), log_bases: striped_random_unsigned_inclusive_range( EXAMPLE_SEED.fork("log_bases"), 1, U::WIDTH, config.get_or("mean_stripe_n", U::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), striped_bit_source: StripedBitSource::new( EXAMPLE_SEED.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), }) } // -- (PrimitiveUnsigned, RoundingMode) -- pub fn special_random_unsigned_rounding_mode_pair_gen( config: &GenConfig, ) -> It<(T, RoundingMode)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigneds::( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &random_rounding_modes, )) } pub fn special_random_unsigned_rounding_mode_pair_gen_var_1( config: &GenConfig, ) -> It<(T, RoundingMode)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_positive_unsigneds::( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &random_rounding_modes, )) } pub fn special_random_unsigned_rounding_mode_pair_gen_var_2< T: PrimitiveUnsigned, U: ConvertibleFrom + PrimitiveFloat, >( config: &GenConfig, ) -> It<(T, RoundingMode)> { Box::new( random_pairs( EXAMPLE_SEED, &|seed| { striped_random_positive_unsigneds::( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &random_rounding_modes, ) .filter(move |&(n, rm)| rm != Exact || U::convertible_from(n)), ) } // -- (PrimitiveUnsigned, String) -- pub fn special_random_unsigned_string_pair_gen_var_1(config: &GenConfig) -> It<(u8, String)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigned_inclusive_range( seed, 2, 36, config.get_or("mean_stripe_n", 4), config.get_or("mean_stripe_d", 1), ) }, &|seed| { random_strings_using_chars( seed, &|seed_2| { graphic_weighted_random_chars( seed_2, config.get_or("graphic_char_prob_n", 50), config.get_or("graphic_char_prob_d", 51), ) }, config.get_or("mean_length_n", 32), config.get_or("mean_length_d", 1), ) }, )) } // -- (PrimitiveUnsigned, ToSciOptions) -- pub fn special_random_unsigned_to_sci_options_pair_gen( config: &GenConfig, ) -> It<(T, ToSciOptions)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_positive_unsigneds::( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { random_to_sci_options( seed, config.get_or("mean_size_n", 32), config.get_or("mean_size_d", 1), ) }, )) } pub fn special_random_unsigned_to_sci_options_pair_gen_var_1( config: &GenConfig, ) -> It<(T, ToSciOptions)> { Box::new( random_pairs( EXAMPLE_SEED, &|seed| { striped_random_positive_unsigneds::( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { random_to_sci_options( seed, config.get_or("mean_size_n", 32), config.get_or("mean_size_d", 1), ) }, ) .filter(|(x, options)| x.fmt_sci_valid(*options)), ) } // -- (PrimitiveUnsigned, Vec) -- struct UnsignedBoolVecPairGeneratorVar1 { xs: StripedRandomUnsignedBitChunks, striped_bit_source: StripedBitSource, } impl Iterator for UnsignedBoolVecPairGeneratorVar1 { type Item = (T, Vec); fn next(&mut self) -> Option<(T, Vec)> { let x = self.xs.next().unwrap(); let bs = get_striped_bool_vec(&mut self.striped_bit_source, x.significant_bits()); Some((x, bs)) } } pub fn special_random_unsigned_bool_vec_pair_gen_var_1( config: &GenConfig, ) -> It<(T, Vec)> { Box::new(UnsignedBoolVecPairGeneratorVar1 { xs: striped_random_unsigneds( EXAMPLE_SEED.fork("xs"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), striped_bit_source: StripedBitSource::new( EXAMPLE_SEED.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), }) } // -- RationalSequence -- pub fn special_random_unsigned_rational_sequence_gen( config: &GenConfig, ) -> It> { Box::new(random_rational_sequences( EXAMPLE_SEED, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) } // -- (RationalSequence, PrimitiveUnsigned) -- pub fn special_random_unsigned_rational_sequence_unsigned_pair_gen_var_1< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(RationalSequence, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { random_rational_sequences( seed, &|seed_2| { striped_random_unsigneds( seed_2, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_unsigned_n", 32), config.get_or("mean_small_unsigned_d", 1), ) }, )) } pub fn special_random_unsigned_rational_sequence_unsigned_pair_gen_var_2( config: &GenConfig, ) -> It<(RationalSequence, usize)> { Box::new( random_pairs( EXAMPLE_SEED, &|seed| { random_rational_sequences( seed, &|seed_2| { striped_random_unsigneds( seed_2, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_unsigned_n", 32), config.get_or("mean_small_unsigned_d", 1), ) }, ) .filter(|&(ref xs, i)| { if let Some(len) = xs.len() { i < len } else { true } }), ) } // -- (RationalSequence, RationalSequence) -- pub fn special_random_unsigned_rational_sequence_pair_gen( config: &GenConfig, ) -> It<(RationalSequence, RationalSequence)> { Box::new(random_pairs_from_single(random_rational_sequences( EXAMPLE_SEED, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ))) } // -- RationalSequence * 3 -- pub fn special_random_unsigned_rational_sequence_triple_gen( config: &GenConfig, ) -> It<( RationalSequence, RationalSequence, RationalSequence, )> { Box::new(random_triples_from_single(random_rational_sequences( EXAMPLE_SEED, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ))) } // -- String -- pub fn special_random_string_gen(config: &GenConfig) -> It { Box::new(random_strings_using_chars( EXAMPLE_SEED, &|seed| { graphic_weighted_random_chars( seed, config.get_or("graphic_char_prob_n", 50), config.get_or("graphic_char_prob_d", 51), ) }, config.get_or("mean_length_n", 32), config.get_or("mean_length_d", 1), )) } pub fn special_random_string_gen_var_1(config: &GenConfig) -> It { Box::new(random_strings_using_chars( EXAMPLE_SEED, &|seed| { graphic_weighted_random_ascii_chars( seed, config.get_or("graphic_char_prob_n", 50), config.get_or("graphic_char_prob_d", 51), ) }, config.get_or("mean_length_n", 32), config.get_or("mean_length_d", 1), )) } // vars 2 and 3 are in malachite-q. pub fn special_random_string_gen_var_4(config: &GenConfig) -> It { Box::new( random_strings_using_chars( EXAMPLE_SEED, &|seed| { graphic_weighted_random_chars( seed, config.get_or("graphic_char_prob_n", 50), config.get_or("graphic_char_prob_d", 51), ) }, config.get_or("mean_length_n", 32), config.get_or("mean_length_d", 1), ) .filter(|s| !large_exponent(s)), ) } // -- (String, FromSciStringOptions) -- pub fn special_random_string_from_sci_string_options_pair_gen( config: &GenConfig, ) -> It<(String, FromSciStringOptions)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { random_strings_using_chars( seed, &|seed_2| { graphic_weighted_random_chars( seed_2, config.get_or("graphic_char_prob_n", 50), config.get_or("graphic_char_prob_d", 51), ) }, config.get_or("mean_length_n", 32), config.get_or("mean_length_d", 1), ) }, &random_from_sci_string_options, )) } pub fn special_random_string_from_sci_string_options_pair_gen_var_1( config: &GenConfig, ) -> It<(String, FromSciStringOptions)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { random_strings_using_chars( seed, &|seed_2| { graphic_weighted_random_chars( seed_2, config.get_or("graphic_char_prob_n", 50), config.get_or("graphic_char_prob_d", 51), ) }, config.get_or("mean_length_n", 32), config.get_or("mean_length_d", 1), ) .filter(|s| !large_exponent(s)) }, &random_from_sci_string_options, )) } // -- (String, PrimitiveUnsigned) -- pub fn special_random_string_unsigned_pair_gen_var_1(config: &GenConfig) -> It<(String, u8)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { random_strings_using_chars( seed, &|seed_2| { graphic_weighted_random_chars( seed_2, config.get_or("graphic_char_prob_n", 50), config.get_or("graphic_char_prob_d", 51), ) }, config.get_or("mean_length_n", 32), config.get_or("mean_length_d", 1), ) .filter(|s| !large_exponent(s)) }, &|seed| { striped_random_unsigned_inclusive_range( seed, 2, 36, config.get_or("mean_stripe_n", 4), config.get_or("mean_stripe_d", 1), ) }, )) } // -- (String, String) -- pub fn special_random_string_pair_gen(config: &GenConfig) -> It<(String, String)> { Box::new(random_pairs_from_single(random_strings_using_chars( EXAMPLE_SEED, &|seed| { graphic_weighted_random_chars( seed, config.get_or("graphic_char_prob_n", 50), config.get_or("graphic_char_prob_d", 51), ) }, config.get_or("mean_length_n", 32), config.get_or("mean_length_d", 1), ))) } pub fn special_random_string_pair_gen_var_1(config: &GenConfig) -> It<(String, String)> { Box::new(random_pairs_from_single(random_strings_using_chars( EXAMPLE_SEED, &|seed| { graphic_weighted_random_ascii_chars( seed, config.get_or("graphic_char_prob_n", 50), config.get_or("graphic_char_prob_d", 51), ) }, config.get_or("mean_length_n", 32), config.get_or("mean_length_d", 1), ))) } // -- (ToSciOptions, PrimitiveUnsigned> -- pub fn special_random_to_sci_options_unsigned_pair_gen_var_1( config: &GenConfig, ) -> It<(ToSciOptions, T)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { random_to_sci_options( seed, config.get_or("mean_size_n", 32), config.get_or("mean_size_d", 1), ) }, &|seed| { striped_random_unsigned_inclusive_range( seed, T::TWO, T::from(36u8), config.get_or("mean_stripe_n", T::WIDTH), config.get_or("mean_stripe_d", 1), ) }, )) } // -- Vec -- pub fn special_random_bool_vec_gen(config: &GenConfig) -> It> { Box::new(striped_random_bool_vecs( EXAMPLE_SEED, config.get_or("mean_stripe_n", 8), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) } pub fn special_random_bool_vec_gen_var_1( config: &GenConfig, ) -> It> { Box::new( random_union2s( EXAMPLE_SEED, &|seed| { striped_random_bool_vecs_length_inclusive_range( seed, 0, T::WIDTH, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { random_pairs( seed, &|seed_2| { striped_random_fixed_length_bool_vecs( seed_2, T::WIDTH, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed_2| { geometric_random_positive_unsigneds( seed_2, config.get_or("mean_excess_length_n", 32), config.get_or("mean_excess_length_d", 1), ) }, ) .map(|(bs, n)| bs.into_iter().chain(repeat_n(false, n)).collect()) }, ) .map(Union2::unwrap), ) } pub fn special_random_bool_vec_gen_var_2(config: &GenConfig) -> It> { Box::new( random_union2s( EXAMPLE_SEED, &|seed| { striped_random_bool_vecs_length_inclusive_range( seed, 0, T::WIDTH, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { random_pairs( seed, &|seed_2| { striped_random_fixed_length_bool_vecs( seed_2, T::WIDTH - 1, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed_2| { geometric_random_nonzero_signeds::( seed_2, config.get_or("mean_excess_length_n", 32), config.get_or("mean_excess_length_d", 1), ) }, ) .map(|(bs, n)| { bs.into_iter() .chain(repeat_n(n < 0, n.unsigned_abs())) .collect() }) }, ) .map(Union2::unwrap), ) } pub fn special_random_bool_vec_gen_var_3( config: &GenConfig, ) -> It> { Box::new( random_union2s( EXAMPLE_SEED, &|seed| { striped_random_bool_vecs_length_inclusive_range( seed, 0, T::WIDTH, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { random_pairs( seed, &|seed_2| { striped_random_fixed_length_bool_vecs( seed_2, T::WIDTH, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed_2| { geometric_random_positive_unsigneds( seed_2, config.get_or("mean_excess_length_n", 32), config.get_or("mean_excess_length_d", 1), ) }, ) .map(|(bs, n)| repeat_n(false, n).chain(bs).collect()) }, ) .map(Union2::unwrap), ) } pub fn special_random_bool_vec_gen_var_4(config: &GenConfig) -> It> { Box::new( random_union2s( EXAMPLE_SEED, &|seed| { striped_random_bool_vecs_length_inclusive_range( seed, 0, T::WIDTH - 1, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { random_pairs( seed, &|seed_2| { striped_random_fixed_length_bool_vecs( seed_2, T::WIDTH - 1, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed_2| { geometric_random_nonzero_signeds::( seed_2, config.get_or("mean_excess_length_n", 32), config.get_or("mean_excess_length_d", 1), ) }, ) .map(|(bs, n)| repeat_n(n < 0, n.unsigned_abs()).chain(bs).collect()) }, ) .map(Union2::unwrap), ) } pub fn special_random_bool_vec_gen_var_5(config: &GenConfig) -> It> { Box::new( striped_random_bool_vecs_min_length( EXAMPLE_SEED, 1, config.get_or("mean_stripe_n", 8), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|bs| bs.iter().any(|&b| b)), ) } // -- Vec -- pub fn special_random_unsigned_vec_gen(config: &GenConfig) -> It> { Box::new(striped_random_unsigned_vecs( EXAMPLE_SEED, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) } pub fn special_random_unsigned_vec_gen_var_1( config: &GenConfig, ) -> It> { Box::new( striped_random_unsigned_vecs_min_length( EXAMPLE_SEED, 1, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| *xs.last().unwrap() != T::ZERO), ) } pub fn special_random_unsigned_vec_gen_var_2( config: &GenConfig, ) -> It> { Box::new( striped_random_unsigned_vecs_min_length( EXAMPLE_SEED, 1, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| !slice_test_zero(xs)), ) } pub fn special_random_unsigned_vec_gen_var_3( config: &GenConfig, ) -> It> { Box::new( striped_random_unsigned_vecs( EXAMPLE_SEED, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| xs.last() != Some(&T::ZERO)), ) } pub fn special_random_unsigned_vec_gen_var_4( config: &GenConfig, ) -> It> { Box::new(striped_random_unsigned_vecs_min_length( EXAMPLE_SEED, 1, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) } // var 5 is in malachite-nz. pub fn special_random_unsigned_vec_gen_var_6( config: &GenConfig, ) -> It> { Box::new(striped_random_unsigned_vecs_min_length( EXAMPLE_SEED, 2, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) } // --(Vec, PrimitiveUnsigned) -- pub fn special_random_unsigned_vec_unsigned_pair_gen( config: &GenConfig, ) -> It<(Vec, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigned_vecs( seed, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, )) } struct UnsignedVecUnsignedPairGeneratorVar1 { log_bases: GeometricRandomNaturalValues, ranges: VariableRangeGenerator, striped_bit_source: StripedBitSource, phantom_t: PhantomData<*const T>, phantom_u: PhantomData<*const U>, } impl Iterator for UnsignedVecUnsignedPairGeneratorVar1 { type Item = (Vec, u64); fn next(&mut self) -> Option<(Vec, u64)> { let log_base = self.log_bases.next().unwrap(); let max_count = usize::exact_from(T::WIDTH.div_round(log_base, Ceiling).0); loop { let digit_count = self.ranges.next_in_inclusive_range(0, max_count); let mut digits = Vec::with_capacity(digit_count); for _ in 0..digit_count { digits.push(U::from_bits_asc( get_striped_bool_vec(&mut self.striped_bit_source, log_base).into_iter(), )); } if digits_valid::(log_base, &digits) { return Some((digits, log_base)); } } } } pub fn special_random_unsigned_vec_unsigned_pair_gen_var_1< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(Vec, u64)> { Box::new(UnsignedVecUnsignedPairGeneratorVar1:: { log_bases: geometric_random_unsigned_range( EXAMPLE_SEED.fork("log_bases"), 1, U::WIDTH, config.get_or("mean_log_base_n", 4), config.get_or("mean_log_base_d", 1), ), striped_bit_source: StripedBitSource::new( EXAMPLE_SEED.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), ranges: VariableRangeGenerator::new(EXAMPLE_SEED.fork("ranges")), phantom_t: PhantomData, phantom_u: PhantomData, }) } pub fn special_random_unsigned_vec_unsigned_pair_gen_var_2< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(Vec, u64)> { Box::new( special_random_unsigned_vec_unsigned_pair_gen_var_1::(config) .map(|(xs, y)| (xs.into_iter().rev().collect(), y)), ) } struct UnsignedVecUnsignedPairGeneratorVar3 { phantom: PhantomData<*const T>, xs: GeometricRandomNaturalValues, striped_bit_source: StripedBitSource, } impl Iterator for UnsignedVecUnsignedPairGeneratorVar3 { type Item = (Vec, usize); fn next(&mut self) -> Option<(Vec, usize)> { let x_1 = self.xs.next().unwrap(); let x_2 = self.xs.next().unwrap(); let (len, i) = if x_1 <= x_2 { (x_2, x_1) } else { (x_1, x_2) }; Some(( get_striped_unsigned_vec( &mut self.striped_bit_source, u64::exact_from(len) << T::LOG_WIDTH, ), i, )) } } pub fn special_random_unsigned_vec_unsigned_pair_gen_var_3( config: &GenConfig, ) -> It<(Vec, usize)> { Box::new(UnsignedVecUnsignedPairGeneratorVar3 { phantom: PhantomData, xs: geometric_random_unsigneds( EXAMPLE_SEED.fork("xs"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ), striped_bit_source: StripedBitSource::new( EXAMPLE_SEED.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), ), }) } // var 4 is in malachite-nz pub fn special_random_unsigned_vec_unsigned_pair_gen_var_5( config: &GenConfig, ) -> It<(Vec, u64)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigned_vecs( seed, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| { geometric_random_unsigned_range( seed.fork("log_bases"), 1, T::WIDTH, config.get_or("mean_log_base_n", 4), config.get_or("mean_log_base_d", 1), ) }, )) } pub fn special_random_unsigned_vec_unsigned_pair_gen_var_6( config: &GenConfig, ) -> It<(Vec, T)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigned_vecs( seed, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| { striped_random_unsigned_inclusive_range( seed, T::TWO, T::MAX, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, )) } struct PowerOfTwoDigitsGenerator { log_bases: GeometricRandomNaturalValues, digit_counts: GeometricRandomNaturalValues, digit_map: HashMap>, mean_stripe_n: u64, mean_stripe_d: u64, phantom: PhantomData<*const T>, } impl Iterator for PowerOfTwoDigitsGenerator { type Item = (Vec, u64); fn next(&mut self) -> Option<(Vec, u64)> { let log_base = self.log_bases.next().unwrap(); let digit_count = self.digit_counts.next().unwrap(); let mean_stripe_n = self.mean_stripe_n; let mean_stripe_d = self.mean_stripe_d; let digits = self.digit_map.entry(log_base).or_insert_with(|| { striped_random_unsigned_bit_chunks( EXAMPLE_SEED.fork(&log_base.to_string()), log_base, mean_stripe_n, mean_stripe_d, ) }); let digits = digits.take(digit_count).collect_vec(); Some((digits, log_base)) } } pub fn special_random_unsigned_vec_unsigned_pair_gen_var_7( config: &GenConfig, ) -> It<(Vec, u64)> { Box::new(PowerOfTwoDigitsGenerator:: { log_bases: geometric_random_unsigned_range( EXAMPLE_SEED.fork("log_bases"), 1, T::WIDTH, config.get_or("mean_log_base_n", 4), config.get_or("mean_log_base_d", 1), ), digit_counts: geometric_random_unsigneds( EXAMPLE_SEED.fork("digit_count"), config.get_or("mean_digit_count_n", 4), config.get_or("mean_digit_count_d", 1), ), digit_map: HashMap::new(), mean_stripe_n: config.get_or("mean_stripe_n", T::WIDTH << 1), mean_stripe_d: config.get_or("mean_stripe_d", 1), phantom: PhantomData, }) } pub fn special_random_unsigned_vec_unsigned_pair_gen_var_8( config: &GenConfig, ) -> It<(Vec, u64)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigned_vecs( seed, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| { geometric_random_unsigned_inclusive_range( seed.fork("log_bases"), 1, T::WIDTH, config.get_or("mean_log_base_n", 4), config.get_or("mean_log_base_d", 1), ) }, )) } pub fn special_random_unsigned_vec_unsigned_pair_gen_var_9< T: PrimitiveUnsigned, U: PrimitiveUnsigned + SaturatingFrom, >( config: &GenConfig, ) -> It<(Vec, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigned_vecs( seed, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| { striped_random_unsigned_inclusive_range( seed.fork("base"), U::TWO, U::saturating_from(T::MAX), config.get_or("mean_stripe_n", U::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, )) } pub fn special_random_unsigned_vec_unsigned_pair_gen_var_10< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(Vec, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigned_vecs_min_length( seed, 1, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| *xs.last().unwrap() != T::ZERO) }, &|seed| { geometric_random_positive_unsigneds( seed, config.get_or("mean_small_unsigned_n", 4), config.get_or("mean_small_unsigned_d", 1), ) }, )) } pub fn special_random_unsigned_vec_unsigned_pair_gen_var_11< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(Vec, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigned_vecs_min_length( seed, 1, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| *xs.last().unwrap() != T::ZERO) }, &|seed| { geometric_random_unsigned_inclusive_range( seed, U::exact_from(3), U::MAX, config.get_or("mean_small_unsigned_n", 4), config.get_or("mean_small_unsigned_d", 1), ) }, )) } pub fn special_random_unsigned_vec_unsigned_pair_gen_var_12< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(Vec, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigned_vecs_min_length( seed, 1, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, )) } pub fn special_random_unsigned_vec_unsigned_pair_gen_var_13< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(Vec, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigned_vecs( seed, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_unsigned_n", 4), config.get_or("mean_small_unsigned_d", 1), ) }, )) } pub fn special_random_unsigned_vec_unsigned_pair_gen_var_14< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(Vec, U)> { Box::new( random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigned_vecs( seed, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_unsigned_n", 4), config.get_or("mean_small_unsigned_d", 1), ) }, ) .filter(|(xs, y)| *y < U::exact_from(xs.len() << T::LOG_WIDTH)), ) } pub fn special_random_unsigned_vec_unsigned_pair_gen_var_15< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(Vec, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigned_vecs_min_length( seed, 1, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| !slice_test_zero(xs)) }, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, )) } pub fn special_random_unsigned_vec_unsigned_pair_gen_var_16< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(Vec, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigned_vecs_min_length( seed, 1, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| !slice_test_zero(xs)) }, &|seed| { striped_random_positive_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, )) } pub fn special_random_unsigned_vec_unsigned_pair_gen_var_17< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(Vec, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigned_vecs_min_length( seed, 1, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| !slice_test_zero(xs)) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_unsigned_n", 4), config.get_or("mean_small_unsigned_d", 1), ) }, )) } // var 18 is in malachite-nz pub fn special_random_unsigned_vec_unsigned_pair_gen_var_19< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(Vec, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigned_vecs_min_length( seed, 2, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| { striped_random_positive_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, )) } pub fn special_random_unsigned_vec_unsigned_pair_gen_var_20< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(Vec, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigned_vecs_min_length( seed, 2, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| !slice_test_zero(xs)) }, &|seed| { striped_random_positive_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, )) } pub fn special_random_unsigned_vec_unsigned_pair_gen_var_21< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(Vec, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigned_vecs_min_length( seed, 2, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| { striped_random_unsigned_inclusive_range( seed, U::power_of_2(U::WIDTH - 1), U::MAX, config.get_or("mean_stripe_n", U::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, )) } pub fn special_random_unsigned_vec_unsigned_pair_gen_var_22< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(Vec, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigned_vecs_min_length( seed, 2, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| { striped_random_unsigned_range( seed, U::ONE, U::power_of_2(U::WIDTH - 1), config.get_or("mean_stripe_n", U::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, )) } pub fn special_random_unsigned_vec_unsigned_pair_gen_var_23< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(Vec, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigned_vecs_min_length( seed, 1, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| { striped_random_unsigned_inclusive_range( seed, U::power_of_2(U::WIDTH - 1), U::MAX, config.get_or("mean_stripe_n", U::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, )) } pub fn special_random_unsigned_vec_unsigned_pair_gen_var_24< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(Vec, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigned_vecs_min_length( seed, 1, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| { striped_random_unsigned_range( seed, U::ONE, U::power_of_2(U::WIDTH - 1), config.get_or("mean_stripe_n", U::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, )) } pub fn special_random_unsigned_vec_unsigned_pair_gen_var_25< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(Vec, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigned_vecs_min_length( seed, 1, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| { striped_random_unsigned_range( seed, U::ONE, U::power_of_2(U::WIDTH - 2), config.get_or("mean_stripe_n", U::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, )) } // vars 26 through 27 are in malachite-nz. pub fn special_random_unsigned_vec_unsigned_pair_gen_var_28< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(Vec, U)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigned_vecs_min_length( seed, 1, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| *xs.last().unwrap() != T::ZERO) }, &|seed| { geometric_random_unsigned_inclusive_range( seed, U::TWO, U::MAX, config.get_or("mean_small_unsigned_n", 4), config.get_or("mean_small_unsigned_d", 1), ) }, )) } pub fn special_random_unsigned_vec_unsigned_pair_gen_var_29< T: PrimitiveUnsigned, U: PrimitiveInt, >( config: &GenConfig, ) -> It<(Vec, u64)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigned_vecs( seed, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| { geometric_random_unsigned_range( seed.fork("log_bases"), 1, U::WIDTH, config.get_or("mean_log_base_n", 4), config.get_or("mean_log_base_d", 1), ) }, )) } pub fn special_random_unsigned_vec_unsigned_pair_gen_var_30< T: PrimitiveUnsigned, U: PrimitiveInt, >( config: &GenConfig, ) -> It<(Vec, u64)> { Box::new(random_pairs( EXAMPLE_SEED, &|seed| { striped_random_unsigned_vecs_min_length( seed, 1, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| { geometric_random_unsigned_range( seed.fork("log_bases"), 1, U::WIDTH, config.get_or("mean_log_base_n", 4), config.get_or("mean_log_base_d", 1), ) }, )) } // --(Vec, PrimitiveUnsigned, PrimitiveUnsigned) -- pub fn special_random_unsigned_vec_unsigned_unsigned_triple_gen_var_1< T: PrimitiveUnsigned, U: PrimitiveUnsigned, V: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(Vec, U, V)> { Box::new(random_triples( EXAMPLE_SEED, &|seed| { striped_random_unsigned_vecs( seed, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("small_unsigned_mean_n", 4), config.get_or("small_unsigned_mean_d", 1), ) }, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, )) } pub fn special_random_unsigned_vec_unsigned_unsigned_triple_gen( config: &GenConfig, ) -> It<(Vec, T, T)> { Box::new(random_triples_xyy( EXAMPLE_SEED, &|seed| { striped_random_unsigned_vecs( seed, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, )) } struct UnsignedVecUnsignedUnsignedTripleGeneratorVar1 { phantom: PhantomData<*const T>, is: GeometricRandomNaturalValues, striped_bit_source: StripedBitSource, } impl Iterator for UnsignedVecUnsignedUnsignedTripleGeneratorVar1 { type Item = (Vec, usize, usize); fn next(&mut self) -> Option<(Vec, usize, usize)> { let i = self.is.next().unwrap(); let j = self.is.next().unwrap(); let excess = self.is.next().unwrap(); let xs = get_striped_unsigned_vec( &mut self.striped_bit_source, u64::exact_from(i * j + excess) << T::LOG_WIDTH, ); Some((xs, i, j)) } } pub fn special_random_unsigned_vec_unsigned_unsigned_triple_gen_var_2( config: &GenConfig, ) -> It<(Vec, usize, usize)> { Box::new(UnsignedVecUnsignedUnsignedTripleGeneratorVar1 { phantom: PhantomData, is: geometric_random_unsigneds( EXAMPLE_SEED.fork("is"), config.get_or("small_unsigned_mean_n", 2), config.get_or("small_unsigned_mean_d", 1), ), striped_bit_source: StripedBitSource::new( EXAMPLE_SEED.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), }) } pub fn special_random_unsigned_vec_unsigned_unsigned_triple_gen_var_3< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(Vec, U, U)> { Box::new( random_triples_xyy( EXAMPLE_SEED, &|seed| { striped_random_unsigned_vecs( seed, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, ) .map(|(xs, y, z)| if y <= z { (xs, y, z) } else { (xs, z, y) }), ) } pub fn special_random_unsigned_vec_unsigned_unsigned_triple_gen_var_4< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(Vec, U, U)> { Box::new( random_triples_xyy( EXAMPLE_SEED, &|seed| { striped_random_unsigned_vecs_min_length( seed, 1, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| !slice_test_zero(xs)) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, ) .map(|(xs, y, z)| if y <= z { (xs, y, z) } else { (xs, z, y) }), ) } pub fn special_random_unsigned_vec_unsigned_unsigned_triple_gen_var_5( config: &GenConfig, ) -> It<(Vec, T, T)> { Box::new(random_triples_xyy( EXAMPLE_SEED, &|seed| { striped_random_unsigned_vecs_min_length( seed, 2, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| *xs.last().unwrap() != T::ZERO) }, &|seed| { striped_random_positive_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, )) } // var 6 is in malachite-nz. pub fn special_random_unsigned_vec_unsigned_unsigned_triple_gen_var_7( config: &GenConfig, ) -> It<(Vec, T, T)> { Box::new(random_triples( EXAMPLE_SEED, &|seed| { striped_random_unsigned_vecs_min_length( seed, 2, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| *xs.last().unwrap() != T::ZERO) }, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { striped_random_positive_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, )) } pub fn special_random_unsigned_vec_unsigned_unsigned_triple_gen_var_8< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(Vec, T, U)> { Box::new(random_triples( EXAMPLE_SEED, &|seed| { striped_random_unsigned_vecs_min_length( seed, 2, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| *xs.last().unwrap() != T::ZERO) }, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, )) } // var 9 is in malachite-nz. pub fn special_random_unsigned_vec_unsigned_unsigned_triple_gen_var_10( config: &GenConfig, ) -> It<(Vec, T, T)> { Box::new(random_triples( EXAMPLE_SEED, &|seed| { striped_random_unsigned_vecs_min_length( seed, 1, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| { striped_random_unsigned_inclusive_range( seed, T::ZERO, T::low_mask(T::WIDTH - 1), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) .map(|u| (u << 1) | T::ONE) }, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, )) } // vars 11 through 12 are in malachite-nz. pub fn special_random_unsigned_vec_unsigned_unsigned_triple_gen_var_13< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(Vec, T, U)> { Box::new(random_triples( EXAMPLE_SEED, &|seed| { striped_random_unsigned_vecs_min_length( seed, 1, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| *xs.last().unwrap() != T::ZERO) }, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("small_unsigned_mean_n", 32), config.get_or("small_unsigned_mean_d", 1), ) }, )) } // var 14 is in malachite-nz. // -- (Vec, PrimitiveUnsigned, RoundingMode) -- pub fn special_random_unsigned_vec_unsigned_rounding_mode_triple_gen_var_1( config: &GenConfig, ) -> It<(Vec, T, RoundingMode)> { Box::new(random_triples( EXAMPLE_SEED, &|seed| { striped_random_unsigned_vecs_min_length( seed, 2, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| *xs.last().unwrap() != T::ZERO) }, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &random_rounding_modes, )) } pub fn special_random_unsigned_vec_unsigned_rounding_mode_triple_gen_var_2< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(Vec, U, RoundingMode)> { Box::new(random_triples( EXAMPLE_SEED, &|seed| { striped_random_unsigned_vecs_min_length( seed, 1, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| !slice_test_zero(xs)) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 4), config.get_or("mean_small_d", 1), ) }, &random_rounding_modes, )) } // -- (Vec, Vec) -- pub fn special_random_unsigned_vec_pair_gen( config: &GenConfig, ) -> It<(Vec, Vec)> { Box::new(random_pairs_from_single(striped_random_unsigned_vecs( EXAMPLE_SEED, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ))) } pub struct UnsignedVecPairLenGenerator1> { pub phantom: PhantomData<*const T>, pub lengths: I, pub striped_bit_source: StripedBitSource, } impl> Iterator for UnsignedVecPairLenGenerator1 { type Item = (Vec, Vec); fn next(&mut self) -> Option<(Vec, Vec)> { let (i, j) = self.lengths.next().unwrap(); Some(( get_striped_unsigned_vec(&mut self.striped_bit_source, i << T::LOG_WIDTH), get_striped_unsigned_vec(&mut self.striped_bit_source, j << T::LOG_WIDTH), )) } } fn special_random_unsigned_vec_pair_gen_var_1_helper( config: &GenConfig, seed: Seed, ) -> It<(Vec, Vec)> { Box::new(UnsignedVecPairLenGenerator1 { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_unsigneds( seed.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .map(|(x, y)| if x >= y { (x, y) } else { (y, x) }), striped_bit_source: StripedBitSource::new( seed.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), }) } pub fn special_random_unsigned_vec_pair_gen_var_1( config: &GenConfig, ) -> It<(Vec, Vec)> { special_random_unsigned_vec_pair_gen_var_1_helper(config, EXAMPLE_SEED) } pub fn special_random_unsigned_vec_pair_gen_var_2( config: &GenConfig, ) -> It<(Vec, Vec)> { Box::new(UnsignedVecPairLenGenerator1 { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_positive_unsigneds( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .map(|(x, y)| if x >= y { (x, y) } else { (y, x) }), striped_bit_source: StripedBitSource::new( EXAMPLE_SEED.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), }) } pub fn special_random_unsigned_vec_pair_gen_var_3( config: &GenConfig, ) -> It<(Vec, Vec)> { Box::new(random_pairs_from_single( striped_random_unsigned_vecs_min_length( EXAMPLE_SEED, 1, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ), )) } pub fn special_random_unsigned_vec_pair_gen_var_4( config: &GenConfig, ) -> It<(Vec, Vec)> { Box::new( random_pairs_from_single(striped_random_unsigned_vecs_min_length( EXAMPLE_SEED, 1, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter(|(ref xs, ref es)| { !xs.is_empty() && (es.len() > 1 || es.len() == 1 && es[0] > T::ONE) && *es.last().unwrap() != T::ZERO }), ) } struct UnsignedVecSqrtRemGenerator> { phantom: PhantomData<*const T>, lengths: I, striped_bit_source: StripedBitSource, hi_n_bits: StripedRandomUnsignedInclusiveRange, } impl> Iterator for UnsignedVecSqrtRemGenerator { type Item = (Vec, Vec); fn next(&mut self) -> Option<(Vec, Vec)> { let (out_len, len) = self.lengths.next().unwrap(); let out = get_striped_unsigned_vec(&mut self.striped_bit_source, out_len << T::LOG_WIDTH); let mut ns: Vec = get_striped_unsigned_vec(&mut self.striped_bit_source, len << T::LOG_WIDTH); let n_hi = &mut ns[(usize::exact_from(out_len) << 1) - 1]; n_hi.mod_power_of_2_assign(T::WIDTH - 2); *n_hi |= self.hi_n_bits.next().unwrap() << (T::WIDTH - 2); Some((out, ns)) } } pub fn special_random_unsigned_vec_pair_gen_var_5( config: &GenConfig, ) -> It<(Vec, Vec)> { Box::new(UnsignedVecSqrtRemGenerator { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(x, y)| { let out_len = x.checked_add(2)?; let len: u64 = out_len.arithmetic_checked_shl(1)?; let len = len.checked_add(y)?; Some((out_len, len)) }), striped_bit_source: StripedBitSource::new( EXAMPLE_SEED.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), hi_n_bits: striped_random_unsigned_range( EXAMPLE_SEED.fork("hi_n_bits"), T::ONE, T::exact_from(4), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), }) } struct UnsignedVecSqrtGenerator> { phantom: PhantomData<*const T>, lengths: I, striped_bit_source: StripedBitSource, } impl> Iterator for UnsignedVecSqrtGenerator { type Item = (Vec, Vec); fn next(&mut self) -> Option<(Vec, Vec)> { let (out_len, len) = self.lengths.next().unwrap(); let out = get_striped_unsigned_vec(&mut self.striped_bit_source, out_len << T::LOG_WIDTH); let mut ns: Vec = get_striped_unsigned_vec(&mut self.striped_bit_source, len << T::LOG_WIDTH); let hi_n = ns.last_mut().unwrap(); if *hi_n == T::ZERO { *hi_n = T::ONE; } Some((out, ns)) } } pub fn special_random_unsigned_vec_pair_gen_var_6( config: &GenConfig, ) -> It<(Vec, Vec)> { Box::new(UnsignedVecSqrtGenerator { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(x, y)| { let in_len = x.checked_add(1)?; let mut out_len: u64 = in_len.shr_round(1, Ceiling).0; out_len = out_len.checked_add(y)?; Some((out_len, in_len)) }), striped_bit_source: StripedBitSource::new( EXAMPLE_SEED.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), }) } struct UnsignedVecPairSameLenGenerator> { phantom: PhantomData<*const T>, lengths: I, striped_bit_source: StripedBitSource, } impl> Iterator for UnsignedVecPairSameLenGenerator { type Item = (Vec, Vec); fn next(&mut self) -> Option<(Vec, Vec)> { let len = self.lengths.next().unwrap() << T::LOG_WIDTH; Some(( get_striped_unsigned_vec(&mut self.striped_bit_source, len), get_striped_unsigned_vec(&mut self.striped_bit_source, len), )) } } pub fn special_random_unsigned_vec_pair_gen_var_7( config: &GenConfig, ) -> It<(Vec, Vec)> { Box::new(UnsignedVecPairSameLenGenerator { phantom: PhantomData, lengths: geometric_random_positive_unsigneds( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ), striped_bit_source: StripedBitSource::new( EXAMPLE_SEED.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), }) } pub fn special_random_unsigned_vec_pair_gen_var_8( config: &GenConfig, ) -> It<(Vec, Vec)> { Box::new(random_pairs_from_single( striped_random_unsigned_vecs( EXAMPLE_SEED, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| xs.last() != Some(&T::ZERO)), )) } pub fn special_random_unsigned_vec_pair_gen_var_9( config: &GenConfig, ) -> It<(Vec, Vec)> { Box::new(random_pairs_from_single( striped_random_unsigned_vecs_min_length( EXAMPLE_SEED, 1, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| !slice_test_zero(xs)), )) } pub struct UnsignedVecPairLenGenerator2> { pub phantom: PhantomData<*const T>, pub lengths: I, pub striped_bit_source: StripedBitSource, } impl> Iterator for UnsignedVecPairLenGenerator2 { type Item = (Vec, Vec); fn next(&mut self) -> Option<(Vec, Vec)> { let (i, j) = self.lengths.next().unwrap(); let mut xs; loop { xs = get_striped_unsigned_vec(&mut self.striped_bit_source, i << T::LOG_WIDTH); if !slice_test_zero(&xs) { break; } } let mut ys; loop { ys = get_striped_unsigned_vec(&mut self.striped_bit_source, j << T::LOG_WIDTH); if !slice_test_zero(&ys) { break; } } Some((xs, ys)) } } pub fn special_random_unsigned_vec_pair_gen_var_10( config: &GenConfig, ) -> It<(Vec, Vec)> { Box::new(UnsignedVecPairLenGenerator2 { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_positive_unsigneds( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .map(|(x, y)| if x >= y { (x, y) } else { (y, x) }), striped_bit_source: StripedBitSource::new( EXAMPLE_SEED.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), }) } // var 11 is in malachite-nz. pub fn special_random_unsigned_vec_pair_gen_var_12( config: &GenConfig, ) -> It<(Vec, Vec)> { Box::new( UnsignedVecPairLenGenerator1 { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_unsigned_inclusive_range( EXAMPLE_SEED.fork("lengths"), 2, u64::MAX, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .map(|(x, y)| if x >= y { (x, y) } else { (y, x) }), striped_bit_source: StripedBitSource::new( EXAMPLE_SEED.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), } .filter(|(_, ds)| *ds.last().unwrap() != T::ZERO), ) } pub fn special_random_unsigned_vec_pair_gen_var_13( config: &GenConfig, ) -> It<(Vec, Vec)> { Box::new( UnsignedVecPairLenGenerator1 { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_positive_unsigneds( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .map(|(x, y)| if x >= y { (x, y) } else { (y, x) }), striped_bit_source: StripedBitSource::new( EXAMPLE_SEED.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), } .map(|(xs, mut ys)| { ys[0] |= T::ONE; (xs, ys) }), ) } // vars 14 through 15 are in malachite-nz. pub fn special_random_unsigned_vec_pair_gen_var_16( config: &GenConfig, ) -> It<(Vec, Vec)> { Box::new( UnsignedVecPairLenGenerator1 { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_positive_unsigneds( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .map(|(x, y)| if x >= y { (x, y) } else { (y, x) }), striped_bit_source: StripedBitSource::new( EXAMPLE_SEED.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), } .filter(|(xs, ys)| *xs.last().unwrap() != T::ZERO && *ys.last().unwrap() != T::ZERO), ) } pub fn special_random_unsigned_vec_pair_gen_var_17( config: &GenConfig, ) -> It<(Vec, Vec)> { Box::new( UnsignedVecPairLenGenerator1 { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_unsigned_inclusive_range( EXAMPLE_SEED.fork("lengths"), 2, u64::MAX, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .map(|(x, y)| if x >= y { (x, y) } else { (y, x) }), striped_bit_source: StripedBitSource::new( EXAMPLE_SEED.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), } .filter(|(xs, ys)| *xs.last().unwrap() != T::ZERO && *ys.last().unwrap() != T::ZERO), ) } // var 18 is in malachite-nz. pub fn special_random_unsigned_vec_pair_gen_var_19( config: &GenConfig, ) -> It<(Vec, Vec)> { Box::new( random_triples( EXAMPLE_SEED, &|seed| { striped_random_unsigned_vecs_min_length( seed, 2, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| { striped_random_unsigned_inclusive_range( seed, T::power_of_2(T::WIDTH - 1), T::MAX, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_unsigned_stripe_n", T::WIDTH >> 1), config.get_or("mean_unsigned_stripe_d", 1), ) }, ) .map(|(n, d_1, d_0)| (n, vec![d_0, d_1])), ) } pub fn special_random_unsigned_vec_pair_gen_var_20( config: &GenConfig, ) -> It<(Vec, Vec)> { Box::new(random_pairs_from_single( striped_random_unsigned_vecs_min_length::( EXAMPLE_SEED, 1, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter_map(|mut xs| { let last = xs.last_mut().unwrap(); *last = last.checked_add(T::ONE)?; Some(xs) }), )) } pub fn special_random_unsigned_vec_pair_gen_var_21( config: &GenConfig, ) -> It<(Vec, Vec)> { Box::new(UnsignedVecPairLenGenerator1 { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_unsigned_inclusive_range( EXAMPLE_SEED.fork("lengths"), 2, u64::MAX, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .map(|(x, y)| if x >= y { (x, y) } else { (y, x) }), striped_bit_source: StripedBitSource::new( EXAMPLE_SEED.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), }) } // vars 22 through 31 are in malachite-nz. pub fn special_random_unsigned_vec_pair_gen_var_32( config: &GenConfig, ) -> It<(Vec, Vec)> { Box::new(UnsignedVecPairLenGenerator1 { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_unsigneds( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .map(|(x, y)| if x >= y { (x, y) } else { (y, x) }), striped_bit_source: StripedBitSource::new( EXAMPLE_SEED.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), }) } pub fn special_random_unsigned_vec_pair_gen_var_33( config: &GenConfig, ) -> It<(Vec, Vec)> { Box::new( UnsignedVecPairSameLenGenerator { phantom: PhantomData, lengths: geometric_random_positive_unsigneds( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ), striped_bit_source: StripedBitSource::new( EXAMPLE_SEED.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), } .filter(|(ref xs, ref ys): &(Vec, Vec)| { (*xs.last().unwrap() != T::ZERO || *ys.last().unwrap() != T::ZERO) && ys[0].odd() }), ) } // var 34 is in malachite-nz. // -- (Vec, Vec, bool) -- pub fn special_random_unsigned_vec_unsigned_vec_bool_triple_gen_var_1( config: &GenConfig, ) -> It<(Vec, Vec, bool)> { reshape_2_1_to_3(Box::new(random_pairs( EXAMPLE_SEED, &|seed| UnsignedVecPairSameLenGenerator { phantom: PhantomData, lengths: geometric_random_positive_unsigneds( seed.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ), striped_bit_source: StripedBitSource::new( seed.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), }, &random_bools, ))) } // -- (Vec, Vec, PrimitiveUnsigned) -- pub fn special_random_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_1( config: &GenConfig, ) -> It<(Vec, Vec, T)> { reshape_2_1_to_3(Box::new(random_pairs( EXAMPLE_SEED, &|seed| special_random_unsigned_vec_pair_gen_var_1_helper(config, seed), &|seed| { striped_random_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, ))) } // var 2 and 3 are in malachite-nz fn special_random_unsigned_vec_pair_gen_var_2_helper( config: &GenConfig, seed: Seed, ) -> It<(Vec, Vec)> { Box::new(UnsignedVecPairLenGenerator1 { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_positive_unsigneds( seed.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .map(|(x, y)| if x >= y { (x, y) } else { (y, x) }), striped_bit_source: StripedBitSource::new( seed.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), }) } pub fn special_random_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_4( config: &GenConfig, ) -> It<(Vec, Vec, T)> { reshape_2_1_to_3(Box::new(random_pairs( EXAMPLE_SEED, &|seed| special_random_unsigned_vec_pair_gen_var_2_helper(config, seed), &|seed| { striped_random_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, ))) } struct UnsignedVecPairLenGenerator3> { phantom: PhantomData<*const T>, lengths: I, striped_bit_source: StripedBitSource, } impl> Iterator for UnsignedVecPairLenGenerator3 { type Item = (Vec, Vec); fn next(&mut self) -> Option<(Vec, Vec)> { let (i, j) = self.lengths.next().unwrap(); let xs = get_striped_unsigned_vec(&mut self.striped_bit_source, i << T::LOG_WIDTH); let mut ys; loop { ys = get_striped_unsigned_vec(&mut self.striped_bit_source, j << T::LOG_WIDTH); if !slice_test_zero(&ys) { break; } } Some((xs, ys)) } } fn special_random_unsigned_vec_pair_gen_var_3_helper( config: &GenConfig, seed: Seed, ) -> It<(Vec, Vec)> { Box::new(UnsignedVecPairLenGenerator3 { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_positive_unsigneds( seed.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .map(|(x, y)| if x >= y { (x, y) } else { (y, x) }), striped_bit_source: StripedBitSource::new( seed.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), }) } pub fn special_random_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_5( config: &GenConfig, ) -> It<(Vec, Vec, T)> { reshape_2_1_to_3(Box::new(random_pairs( EXAMPLE_SEED, &|seed| special_random_unsigned_vec_pair_gen_var_3_helper(config, seed), &|seed| { striped_random_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, ))) } pub fn special_random_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_6< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(Vec, Vec, U)> { Box::new(random_triples_xxy( EXAMPLE_SEED, &|seed| { striped_random_unsigned_vecs_min_length( seed, 2, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| *xs.last().unwrap() != T::ZERO) }, &|seed| { striped_random_positive_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, )) } // vars 7 through 8 are in malachite-nz. pub fn special_random_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_9< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(Vec, Vec, U)> { Box::new(random_triples_xxy( EXAMPLE_SEED, &|seed| { striped_random_unsigned_vecs_min_length( seed, 1, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| *xs.last().unwrap() != T::ZERO) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, )) } pub fn special_random_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_10< T: PrimitiveUnsigned, U: PrimitiveUnsigned, >( config: &GenConfig, ) -> It<(Vec, Vec, U)> { Box::new(random_triples_xxy( EXAMPLE_SEED, &|seed| { striped_random_unsigned_vecs_min_length( seed, 1, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| *xs.last().unwrap() != T::ZERO) }, &|seed| { striped_random_positive_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, )) } pub struct PrimitiveIntVecPairLenAndIndexGenerator< T: PrimitiveUnsigned, I: Iterator, > { pub phantom: PhantomData<*const T>, pub lengths: I, pub striped_bit_source: StripedBitSource, } impl> Iterator for PrimitiveIntVecPairLenAndIndexGenerator { type Item = (Vec, Vec, usize); fn next(&mut self) -> Option<(Vec, Vec, usize)> { let (i, j, k) = self.lengths.next().unwrap(); Some(( get_striped_unsigned_vec(&mut self.striped_bit_source, i << T::LOG_WIDTH), get_striped_unsigned_vec(&mut self.striped_bit_source, j << T::LOG_WIDTH), usize::exact_from(k), )) } } pub fn special_random_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_11( config: &GenConfig, ) -> It<(Vec, Vec, usize)> { Box::new(PrimitiveIntVecPairLenAndIndexGenerator { phantom: PhantomData, lengths: random_triples_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(o, x, y)| { let x = x.checked_add(y)?; let o = o.checked_add(x)?; Some((o, x, y)) }), striped_bit_source: StripedBitSource::new( EXAMPLE_SEED.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), }) } pub fn special_random_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_12( config: &GenConfig, ) -> It<(Vec, Vec, T)> { reshape_2_1_to_3(Box::new(random_pairs( EXAMPLE_SEED, &|seed| UnsignedVecPairSameLenGenerator { phantom: PhantomData, lengths: geometric_random_positive_unsigneds( seed.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ), striped_bit_source: StripedBitSource::new( seed.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), }, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, ))) } pub fn special_random_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_13( config: &GenConfig, ) -> It<(Vec, Vec, T)> { reshape_2_1_to_3(Box::new(random_pairs( EXAMPLE_SEED, &|seed| UnsignedVecPairLenGenerator1 { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_unsigned_inclusive_range( seed.fork("lengths"), 2, u64::MAX, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .map(|(x, y)| if x >= y { (x, y) } else { (y, x) }), striped_bit_source: StripedBitSource::new( seed.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), }, &|seed| { striped_random_positive_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, ))) } // vars 14 through 21 are in malachite-nz. pub fn special_random_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_22< T: PrimitiveUnsigned, U: PrimitiveInt, >( config: &GenConfig, ) -> It<(Vec, Vec, u64)> { reshape_2_1_to_3(Box::new(random_pairs( EXAMPLE_SEED, &|seed| special_random_unsigned_vec_pair_gen_var_1_helper(config, seed), &|seed| { striped_random_unsigned_range( seed, 1, U::WIDTH, config.get_or("mean_stripe_n", U::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, ))) } pub fn special_random_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_23< T: PrimitiveUnsigned, U: PrimitiveInt, >( config: &GenConfig, ) -> It<(Vec, Vec, u64)> { reshape_2_1_to_3(Box::new(random_pairs( EXAMPLE_SEED, &|seed| UnsignedVecPairLenGenerator1 { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_positive_unsigneds( seed.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .map(|(x, y)| if x >= y { (x, y) } else { (y, x) }), striped_bit_source: StripedBitSource::new( seed.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), }, &|seed| { striped_random_unsigned_range( seed, 1, U::WIDTH, config.get_or("mean_stripe_n", U::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, ))) } pub fn special_random_unsigned_vec_unsigned_vec_unsigned_triple_gen_var_24( config: &GenConfig, ) -> It<(Vec, Vec, usize)> { Box::new(PrimitiveIntVecPairLenAndIndexGenerator { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(x, i)| { let x = x.checked_add(i)?; Some((x, x, i)) }), striped_bit_source: StripedBitSource::new( EXAMPLE_SEED.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), }) } // -- (Vec, Vec, Vec) -- pub struct UnsignedVecTripleXYYLenGenerator> { pub phantom: PhantomData<*const T>, pub lengths: I, pub striped_bit_source: StripedBitSource, } impl> Iterator for UnsignedVecTripleXYYLenGenerator { type Item = (Vec, Vec, Vec); fn next(&mut self) -> Option<(Vec, Vec, Vec)> { let (i, j) = self.lengths.next().unwrap(); let shifted_j = j << T::LOG_WIDTH; Some(( get_striped_unsigned_vec(&mut self.striped_bit_source, i << T::LOG_WIDTH), get_striped_unsigned_vec(&mut self.striped_bit_source, shifted_j), get_striped_unsigned_vec(&mut self.striped_bit_source, shifted_j), )) } } pub fn special_random_unsigned_vec_triple_gen_var_1( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new(UnsignedVecTripleXYYLenGenerator { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(x, y)| { let y = y.checked_add(1)?; let x = x.checked_add(y.arithmetic_checked_shl(1)?)?; Some((x, y)) }), striped_bit_source: StripedBitSource::new( EXAMPLE_SEED.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), }) } pub struct UnsignedVecTripleLenGenerator1> { pub phantom: PhantomData<*const T>, pub lengths: I, pub striped_bit_source: StripedBitSource, } impl> Iterator for UnsignedVecTripleLenGenerator1 { type Item = (Vec, Vec, Vec); fn next(&mut self) -> Option<(Vec, Vec, Vec)> { let (i, j, k) = self.lengths.next().unwrap(); Some(( get_striped_unsigned_vec(&mut self.striped_bit_source, i << T::LOG_WIDTH), get_striped_unsigned_vec(&mut self.striped_bit_source, j << T::LOG_WIDTH), get_striped_unsigned_vec(&mut self.striped_bit_source, k << T::LOG_WIDTH), )) } } pub struct UnsignedVecQuadrupleLenGenerator1< T: PrimitiveUnsigned, I: Iterator, > { pub phantom: PhantomData<*const T>, pub lengths: I, pub striped_bit_source: StripedBitSource, } impl> Iterator for UnsignedVecQuadrupleLenGenerator1 { type Item = (Vec, Vec, Vec, Vec); fn next(&mut self) -> Option { let (i, j, k, l) = self.lengths.next().unwrap(); Some(( get_striped_unsigned_vec(&mut self.striped_bit_source, i << T::LOG_WIDTH), get_striped_unsigned_vec(&mut self.striped_bit_source, j << T::LOG_WIDTH), get_striped_unsigned_vec(&mut self.striped_bit_source, k << T::LOG_WIDTH), get_striped_unsigned_vec(&mut self.striped_bit_source, l << T::LOG_WIDTH), )) } } pub fn special_random_unsigned_vec_triple_gen_var_2( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new(UnsignedVecTripleLenGenerator1 { phantom: PhantomData, lengths: random_triples_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(o, x, y)| { let y = y.checked_add(1)?; let x = x.checked_add(y)?; let o = x.checked_add(y)?.checked_add(o)?; Some((o, x, y)) }), striped_bit_source: StripedBitSource::new( EXAMPLE_SEED.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), }) } pub fn special_random_unsigned_vec_triple_gen_var_3( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new(UnsignedVecTripleLenGenerator1 { phantom: PhantomData, lengths: random_triples_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(o, x, y)| { let y = y.checked_add(1)?; let x = x.checked_add(1)?; let o = x.checked_add(y)?.checked_add(o)?; Some((o, x, y)) }), striped_bit_source: StripedBitSource::new( EXAMPLE_SEED.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), }) } // vars 4 through 23 are in malachite-nz pub fn special_random_unsigned_vec_triple_gen_var_24( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new(UnsignedVecTripleXYYLenGenerator { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(x, y)| { let y = y.checked_add(1)?; let x = x.checked_add(y)?; Some((x, y)) }), striped_bit_source: StripedBitSource::new( EXAMPLE_SEED.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), }) } pub fn special_random_unsigned_vec_triple_gen_var_25( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new(UnsignedVecTripleXYYLenGenerator { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(x, y)| { let y = y.checked_add(2)?; let x = x.checked_add(y.arithmetic_checked_shl(1)?)?; Some((x, y)) }), striped_bit_source: StripedBitSource::new( EXAMPLE_SEED.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), }) } pub fn special_random_unsigned_vec_triple_gen_var_26( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new(UnsignedVecTripleXYYLenGenerator { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(x, y)| { let y = y.checked_add(2)?; let x = x.checked_add(y)?; Some((x, y)) }), striped_bit_source: StripedBitSource::new( EXAMPLE_SEED.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), }) } struct UnsignedVecTripleXXXLenGenerator> { pub phantom: PhantomData<*const T>, pub lengths: I, pub striped_bit_source: StripedBitSource, } impl> Iterator for UnsignedVecTripleXXXLenGenerator { type Item = (Vec, Vec, Vec); fn next(&mut self) -> Option<(Vec, Vec, Vec)> { let i = self.lengths.next().unwrap() << T::LOG_WIDTH; Some(( get_striped_unsigned_vec(&mut self.striped_bit_source, i), get_striped_unsigned_vec(&mut self.striped_bit_source, i), get_striped_unsigned_vec(&mut self.striped_bit_source, i), )) } } pub fn special_random_unsigned_vec_triple_gen_var_27( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new(UnsignedVecTripleXXXLenGenerator { phantom: PhantomData, lengths: geometric_random_unsigned_range( EXAMPLE_SEED.fork("lengths"), 2, u64::MAX, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ), striped_bit_source: StripedBitSource::new( EXAMPLE_SEED.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), }) } struct UnsignedVecSqrtRemGenerator3> { phantom: PhantomData<*const T>, lengths: I, striped_bit_source: StripedBitSource, } impl> Iterator for UnsignedVecSqrtRemGenerator3 { type Item = (Vec, Vec, Vec); fn next(&mut self) -> Option<(Vec, Vec, Vec)> { let (out_len, rs_len, len) = self.lengths.next().unwrap(); let out = get_striped_unsigned_vec(&mut self.striped_bit_source, out_len << T::LOG_WIDTH); let rs = get_striped_unsigned_vec(&mut self.striped_bit_source, rs_len << T::LOG_WIDTH); let mut ns: Vec = get_striped_unsigned_vec(&mut self.striped_bit_source, len << T::LOG_WIDTH); let hi_n = ns.last_mut().unwrap(); if *hi_n == T::ZERO { *hi_n = T::ONE; } Some((out, rs, ns)) } } pub fn special_random_unsigned_vec_triple_gen_var_28( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new(UnsignedVecSqrtRemGenerator3 { phantom: PhantomData, lengths: random_triples_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(x, y, z)| { let in_len = x.checked_add(1)?; let mut out_len: u64 = in_len.shr_round(1, Ceiling).0; out_len = out_len.checked_add(y)?; let rem_len = in_len.checked_add(z)?; Some((out_len, rem_len, in_len)) }), striped_bit_source: StripedBitSource::new( EXAMPLE_SEED.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), }) } pub fn special_random_unsigned_vec_triple_gen_var_29( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new(UnsignedVecTripleXXXLenGenerator { phantom: PhantomData, lengths: geometric_random_unsigneds( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ), striped_bit_source: StripedBitSource::new( EXAMPLE_SEED.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), }) } pub fn special_random_unsigned_vec_triple_gen_var_30( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new(random_triples_from_single( striped_random_unsigned_vecs( EXAMPLE_SEED, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| xs.last() != Some(&T::ZERO)), )) } pub fn special_random_unsigned_vec_triple_gen_var_31( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new(UnsignedVecTripleXYYLenGenerator { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(x, y)| { let x = x.checked_add(y)?; Some((x, y)) }), striped_bit_source: StripedBitSource::new( EXAMPLE_SEED.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), }) } pub fn special_random_unsigned_vec_triple_gen_var_32( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new(UnsignedVecTripleLenGenerator1 { phantom: PhantomData, lengths: random_triples_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(o, x, y)| { let o = max(x, y).checked_add(o)?; Some((o, x, y)) }), striped_bit_source: StripedBitSource::new( EXAMPLE_SEED.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), }) } struct UnsignedVecTripleLenGenerator2> { pub phantom: PhantomData<*const T>, pub lengths: I, pub striped_bit_source: StripedBitSource, } impl> Iterator for UnsignedVecTripleLenGenerator2 { type Item = (Vec, Vec, Vec); fn next(&mut self) -> Option<(Vec, Vec, Vec)> { let (i, j, k) = self.lengths.next().unwrap(); let out = get_striped_unsigned_vec(&mut self.striped_bit_source, i << T::LOG_WIDTH); let mut xs; loop { xs = get_striped_unsigned_vec(&mut self.striped_bit_source, j << T::LOG_WIDTH); if !slice_test_zero(&xs) { break; } } let mut ys; loop { ys = get_striped_unsigned_vec(&mut self.striped_bit_source, k << T::LOG_WIDTH); if !slice_test_zero(&ys) { break; } } Some((out, xs, ys)) } } pub fn special_random_unsigned_vec_triple_gen_var_33( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new(UnsignedVecTripleLenGenerator2 { phantom: PhantomData, lengths: random_triples_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(o, x, y)| { let x = x.checked_add(1)?; let y = y.checked_add(1)?; let o = o.checked_add(x)?; Some((o, x, y)) }), striped_bit_source: StripedBitSource::new( EXAMPLE_SEED.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), }) } pub fn special_random_unsigned_vec_triple_gen_var_34( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new(UnsignedVecTripleLenGenerator2 { phantom: PhantomData, lengths: random_triples_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(o, x, y)| { let x = x.checked_add(1)?; let y = y.checked_add(1)?; let o = o.checked_add(max(x, y))?; Some((o, x, y)) }), striped_bit_source: StripedBitSource::new( EXAMPLE_SEED.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), }) } pub fn special_random_unsigned_vec_triple_gen_var_35( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new(UnsignedVecTripleLenGenerator2 { phantom: PhantomData, lengths: random_triples_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(o, x, y)| { let x = x.checked_add(1)?; let y = y.checked_add(1)?; let o = o.checked_add(min(x, y))?; Some((o, x, y)) }), striped_bit_source: StripedBitSource::new( EXAMPLE_SEED.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), }) } pub fn special_random_unsigned_vec_triple_gen_var_36( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new(random_triples_from_single( striped_random_unsigned_vecs_min_length( EXAMPLE_SEED, 2, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| *xs.last().unwrap() != T::ZERO), )) } // vars 37 through 38 are in malachite-nz. pub fn special_random_unsigned_vec_triple_gen_var_39( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new(random_triples_from_single( striped_random_unsigned_vecs_min_length( EXAMPLE_SEED, 1, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| *xs.last().unwrap() != T::ZERO), )) } pub fn special_random_unsigned_vec_triple_gen_var_40( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new(UnsignedVecTripleLenGenerator1 { phantom: PhantomData, lengths: random_triples_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(o, x, y)| { let x = x.checked_add(y)?; let o = o.checked_add(x)?; Some((o, x, y)) }), striped_bit_source: StripedBitSource::new( EXAMPLE_SEED.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), }) } pub fn special_random_unsigned_vec_triple_gen_var_41( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new(random_triples_xxy( EXAMPLE_SEED, &|seed| { striped_random_unsigned_vecs_min_length( seed, 1, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| *xs.last().unwrap() != T::ZERO) }, &|seed| { striped_random_unsigned_vecs_min_length( seed, 2, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| *xs.last().unwrap() != T::ZERO) }, )) } // vars 42 through 49 are in malachite-nz. pub fn special_random_unsigned_vec_triple_gen_var_50( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new( UnsignedVecTripleLenGenerator1 { phantom: PhantomData, lengths: random_triples_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(x, y, z)| { let y = y.checked_add(1)?; let x = x.checked_add(y)?; let z = z.checked_add(y.arithmetic_checked_shl(1)?)?; Some((x, y, z)) }), striped_bit_source: StripedBitSource::new( EXAMPLE_SEED.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), } .map(|(x, mut y, z): (Vec, Vec, Vec)| { y.last_mut().unwrap().set_bit(T::WIDTH - 1); (x, y, z) }), ) } pub fn special_random_unsigned_vec_triple_gen_var_51( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new( UnsignedVecTripleLenGenerator1 { phantom: PhantomData, lengths: random_triples_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(x, y, z)| { let y = y.checked_add(5)?; let x = x.checked_add(y)?; let z = z.checked_add(y.arithmetic_checked_shl(1)?)?; Some((x, y, z)) }), striped_bit_source: StripedBitSource::new( EXAMPLE_SEED.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), } .map(|(x, mut y, z): (Vec, Vec, Vec)| { y.last_mut().unwrap().set_bit(T::WIDTH - 1); (x, y, z) }), ) } pub fn special_random_unsigned_vec_triple_gen_var_52( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new( UnsignedVecTripleLenGenerator1 { phantom: PhantomData, lengths: random_triples_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(x, y, z)| { let q = x.checked_add(3)?; let n = y.checked_add(9)?; let d = z.checked_add(6)?; if n < d { return None; } let q_alt = n - d + 1; if (q_alt << 1) > n || q_alt > d { return None; } let n_alt = q_alt << 1; let d_alt = q_alt; if q >= q_alt && d_alt >= 6 && n_alt >= d_alt + 3 && d_alt >= q_alt { Some((q, n, d)) } else { None } }), striped_bit_source: StripedBitSource::new( EXAMPLE_SEED.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), } .map(|(x, y, mut z): (Vec, Vec, Vec)| { z.last_mut().unwrap().set_bit(T::WIDTH - 1); (x, y, z) }), ) } pub fn special_random_unsigned_vec_triple_gen_var_53( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new( random_pairs( EXAMPLE_SEED, &|seed| UnsignedVecPairLenGenerator1 { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_unsigneds( seed.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter(|&(x, y)| x >= y - 2), striped_bit_source: StripedBitSource::new( seed.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), }, &|seed| { random_pairs( seed, &|seed_2| { striped_random_unsigned_inclusive_range( seed_2, T::power_of_2(T::WIDTH - 1), T::MAX, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, ) }, ) .map(|((q, n), (d_1, d_0))| (q, n, vec![d_0, d_1])), ) } // vars 54 through 56 are in malachite-nz. pub fn special_random_unsigned_vec_triple_gen_var_57( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new( UnsignedVecTripleLenGenerator1 { phantom: PhantomData, lengths: random_triples_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(r_len, n_len, d_len)| { let d_len = d_len.checked_add(2)?; let r_len = r_len.checked_add(d_len)?; let n_len = n_len.checked_add(d_len)?; Some((r_len, n_len, d_len)) }), striped_bit_source: StripedBitSource::new( EXAMPLE_SEED.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), } .filter_map(|(r, n, mut d): (Vec, Vec, Vec)| { let last_d = d.last_mut().unwrap(); *last_d = last_d.checked_add(T::ONE)?; Some((r, n, d)) }), ) } // var 58 is in malachite-nz. pub fn special_random_unsigned_vec_triple_gen_var_59( config: &GenConfig, ) -> It<(Vec, Vec, Vec)> { Box::new( UnsignedVecTripleLenGenerator1 { phantom: PhantomData, lengths: random_triples_from_single(geometric_random_unsigneds::( EXAMPLE_SEED.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(xs_len, ys_len, zs_len)| { let ys_len = ys_len.checked_add(2)?; let zs_len = zs_len.checked_add(2)?; let xs_len = xs_len.checked_add(ys_len + zs_len - 1)?; Some((xs_len, ys_len, zs_len)) }), striped_bit_source: StripedBitSource::new( EXAMPLE_SEED.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), } .filter_map(|(mut xs, mut ys, mut zs): (Vec, Vec, Vec)| { let last_x = xs.last_mut().unwrap(); *last_x = last_x.checked_add(T::ONE)?; let last_y = ys.last_mut().unwrap(); *last_y = last_y.checked_add(T::ONE)?; let last_z = zs.last_mut().unwrap(); *last_z = last_z.checked_add(T::ONE)?; Some((xs, ys, zs)) }), ) } // var 60 is in malachite-nz. // -- large types -- pub fn special_random_large_type_gen_var_1( config: &GenConfig, ) -> It<(Vec, Vec, T, T)> { reshape_2_2_to_4(Box::new(random_pairs( EXAMPLE_SEED, &|seed| special_random_unsigned_vec_pair_gen_var_1_helper(config, seed), &|seed| { random_pairs_from_single(striped_random_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), )) }, ))) } struct UnsignedVecSqrtRemGenerator2 { pub phantom: PhantomData<*const T>, pub lengths: GeometricRandomNaturalValues, striped_bit_source: StripedBitSource, } impl Iterator for UnsignedVecSqrtRemGenerator2 { type Item = (Vec, Vec, u64, bool); fn next(&mut self) -> Option<(Vec, Vec, u64, bool)> { let len = self.lengths.next().unwrap(); let n = len.shr_round(1, Ceiling).0; let out = get_striped_unsigned_vec(&mut self.striped_bit_source, n << T::LOG_WIDTH); let mut ns: Vec = get_striped_unsigned_vec(&mut self.striped_bit_source, len << T::LOG_WIDTH); let last = ns.last_mut().unwrap(); if *last == T::ZERO { *last = T::ONE; } let shift = last.leading_zeros() >> 1; Some((out, ns, shift, len.odd())) } } pub fn special_random_large_type_gen_var_2( config: &GenConfig, ) -> It<(Vec, Vec, u64, bool)> { Box::new(UnsignedVecSqrtRemGenerator2 { phantom: PhantomData, lengths: geometric_random_unsigned_range::( EXAMPLE_SEED.fork("lengths"), 9, u64::MAX, config.get_or("mean_length_n", 12), config.get_or("mean_length_d", 1), ), striped_bit_source: StripedBitSource::new( EXAMPLE_SEED.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), }) } pub fn special_random_large_type_gen_var_3( config: &GenConfig, ) -> It<(Vec, U, U, Vec)> { Box::new( random_quadruples_xyyx::<_, _, U, _>( EXAMPLE_SEED, &|seed| { striped_random_unsigned_vecs( seed, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, ) .filter_map(|(x, y, z, w)| match y.cmp(&z) { Less => Some((x, y, z, w)), Greater => Some((x, z, y, w)), Equal => None, }), ) } pub fn special_random_large_type_gen_var_4( config: &GenConfig, ) -> It<(Vec, U, U, Vec)> { Box::new( random_quadruples_xyyz( EXAMPLE_SEED, &|seed| { striped_random_unsigned_vecs::( seed, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| !slice_test_zero(xs)) }, &|seed| { geometric_random_unsigneds::( seed, config.get_or("mean_small_n", 32), config.get_or("mean_small_d", 1), ) }, &|seed| { striped_random_unsigned_vecs::( seed, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, ) .filter_map(|(x, y, z, w)| match y.cmp(&z) { Less => Some((x, y, z, w)), Greater => Some((x, z, y, w)), Equal => None, }), ) } // vars 5 through 8 are in malachite-nz #[allow(clippy::type_complexity)] pub fn special_random_large_type_gen_var_9( config: &GenConfig, ) -> It<(Vec, Vec, Vec, bool)> { reshape_3_1_to_4(Box::new(random_pairs( EXAMPLE_SEED, &|seed| UnsignedVecTripleXYYLenGenerator { phantom: PhantomData, lengths: random_pairs_from_single(geometric_random_unsigneds::( seed.fork("lengths"), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), )) .filter_map(|(x, y)| { let x = x.checked_add(y)?; Some((x, y)) }), striped_bit_source: StripedBitSource::new( seed.fork("striped_bit_source"), config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ), }, &random_bools, ))) } // vars 10 through 21 are in malachite-nz. pub fn special_random_large_type_gen_var_22( config: &GenConfig, ) -> It<(RationalSequence, usize, T, T)> { Box::new( random_quadruples_xyzz( EXAMPLE_SEED, &|seed| { random_rational_sequences( seed, &|seed_2| { striped_random_unsigneds( seed_2, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) }, &|seed| { geometric_random_unsigneds( seed, config.get_or("mean_small_unsigned_n", 32), config.get_or("mean_small_unsigned_d", 1), ) }, &|seed| { striped_random_unsigneds( seed, config.get_or("mean_stripe_n", T::WIDTH >> 1), config.get_or("mean_stripe_d", 1), ) }, ) .filter(|&(ref xs, index, _, _)| { if let Some(len) = xs.len() { index < len } else { true } }), ) } // vars 23 through 24 are in malachite-nz. pub fn special_random_large_type_gen_var_25( config: &GenConfig, ) -> It<(bool, Vec, bool, Vec)> { Box::new(random_quadruples_xyxy( EXAMPLE_SEED, &random_bools, &|seed| { striped_random_unsigned_vecs( seed, config.get_or("mean_stripe_n", T::WIDTH << 1), config.get_or("mean_stripe_d", 1), config.get_or("mean_length_n", 4), config.get_or("mean_length_d", 1), ) .filter(|xs| xs.last() != Some(&T::ZERO)) }, )) } malachite-base-0.4.16/src/test_util/hash/mod.rs000064400000000000000000000010671046102023000174320ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use std::collections::hash_map::DefaultHasher; use std::hash::{Hash, Hasher}; pub fn hash(n: &T) -> u64 { let mut s = DefaultHasher::new(); n.hash(&mut s); s.finish() } malachite-base-0.4.16/src/test_util/mod.rs000064400000000000000000000011011046102023000164740ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . pub mod bench; pub mod common; pub mod extra_variadic; pub mod generators; pub mod hash; pub mod num; pub mod rounding_modes; pub mod runner; pub mod sets; pub mod slices; pub mod stats; pub mod vecs; malachite-base-0.4.16/src/test_util/num/arithmetic/extended_gcd.rs000064400000000000000000000016771046102023000233040ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::WrappingFrom; pub fn extended_gcd_unsigned_euclidean< U: PrimitiveUnsigned, S: PrimitiveSigned + WrappingFrom, >( a: U, b: U, ) -> (U, S, S) { if a == U::ZERO && b == U::ZERO { (U::ZERO, S::ZERO, S::ZERO) } else if a == b || a == U::ZERO { (b, S::ZERO, S::ONE) } else { let (gcd, x, y) = extended_gcd_unsigned_euclidean(b % a, a); (gcd, y - S::wrapping_from(b / a) * x, x) } } malachite-base-0.4.16/src/test_util/num/arithmetic/factorial.rs000064400000000000000000000024461046102023000226260ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::logic::traits::NotAssign; pub fn checked_factorial_naive(n: u64) -> Option { let mut f = T::ONE; let mut n = T::try_from(n).ok()?; while n != T::ZERO { f = f.checked_mul(n)?; n -= T::ONE; } Some(f) } pub fn checked_double_factorial_naive(n: u64) -> Option { let mut f = T::ONE; let mut n = T::try_from(n).ok()?; while n != T::ZERO { f = f.checked_mul(n)?; n.saturating_sub_assign(T::TWO); } Some(f) } pub fn checked_subfactorial_naive(n: u64) -> Option { let mut f = T::ONE; let mut b = true; for i in 1..=n { f = f.checked_mul(T::try_from(i).ok()?)?; if b { f -= T::ONE; } else { f = f.checked_add(T::ONE)?; } b.not_assign(); } Some(f) } malachite-base-0.4.16/src/test_util/num/arithmetic/kronecker_symbol.rs000064400000000000000000000256431046102023000242360ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // Uses code adopted from the GNU MP Library. // // Copyright © 1996, 1998, 1999-2002, 2000-2004, 2008, 2010 Free Software Foundation, Inc. // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{NegAssign, Parity}; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::{HasHalf, JoinHalves}; use crate::num::logic::traits::NotAssign; use std::mem::swap; // This is equivalent to `n_jacobi_unsigned` from `ulong_extras/jacobi.c`, FLINT 2.7.1. pub fn jacobi_symbol_unsigned_fast_1(x: T, y: T) -> i8 { let mut a = x; let mut b = y; let mut s = 1; if a < b && b != T::ONE { if a == T::ZERO { return 0; } swap(&mut a, &mut b); let exp = b.trailing_zeros(); b >>= exp; if T::wrapping_from(exp) .wrapping_mul(a.wrapping_square() - T::ONE) .get_bit(3) != (a - T::ONE).wrapping_mul(b - T::ONE).get_bit(2) { s.neg_assign(); } } while b != T::ONE { if a >> 2 < b { let temp = a - b; a = b; b = if temp < b { temp } else if temp < b << 1 { temp - a } else { temp - (a << 1) } } else { a %= b; swap(&mut a, &mut b); } if b == T::ZERO { return 0; } let exp = b.trailing_zeros(); b >>= exp; if T::wrapping_from(exp) .wrapping_mul(a.wrapping_square() - T::ONE) .get_bit(3) != (a - T::ONE).wrapping_mul(b - T::ONE).get_bit(2) { s.neg_assign(); } } s } // This is equivalent to `mpn_jacobi_base` from `mpn/jacbase.c`, GMP 6.2.1, where // `JACOBI_BASE_METHOD == 1` and `result_bit_1` is false. pub fn jacobi_symbol_unsigned_fast_2_1(mut a: T, mut b: T) -> i8 { assert!(b.odd()); if b == T::ONE { return 1; } else if a == T::ZERO { return 0; } let mut s = 1; let a_twos = a.trailing_zeros(); if a_twos.odd() && ((b >> 1u32) ^ b).get_bit(1) { s.neg_assign(); } a >>= a_twos; if a == T::ONE { return s; } if a < b { if (a & b).get_bit(1) { s.neg_assign(); } swap(&mut a, &mut b); } loop { assert!(a.odd()); assert!(b.odd()); assert!(a >= b); a -= b; if a == T::ZERO { return 0; } let a_twos = a.trailing_zeros(); if a_twos.odd() && ((b >> 1u32) ^ b).get_bit(1) { s.neg_assign(); } a >>= a_twos; if a == T::ONE { return s; } if a < b { if (a & b).get_bit(1) { s.neg_assign(); } swap(&mut a, &mut b); } } } // This is equivalent to `mpn_jacobi_base` from `mpn/jacbase.c`, GMP 6.2.1, where // `JACOBI_BASE_METHOD == 2` and `result_bit_1` is false. pub fn jacobi_symbol_unsigned_fast_2_2(mut a: T, mut b: T) -> i8 { assert!(b.odd()); if b == T::ONE { return 1; } else if a == T::ZERO { return 0; } let mut s = 1; if a.even() { let two = (b >> 1u32) ^ b; loop { a >>= 1; if two.get_bit(1) { s.neg_assign(); } if a.odd() { break; } } } if a == T::ONE { return s; } if a < b { if (a & b).get_bit(1) { s.neg_assign(); } swap(&mut a, &mut b); } loop { assert!(a.odd()); assert!(b.odd()); assert!(a >= b); a -= b; if a == T::ZERO { return 0; } let two = (b >> 1u32) ^ b; loop { a >>= 1; if two.get_bit(1) { s.neg_assign(); } if a.odd() { break; } } if a == T::ONE { return s; } if a < b { if (a & b).get_bit(1) { s.neg_assign(); } swap(&mut a, &mut b); } } } // This is equivalent to `mpn_jacobi_base` from `mpn/jacbase.c`, GMP 6.2.1, where // `JACOBI_BASE_METHOD == 3` and `result_bit_1` is false. pub fn jacobi_symbol_unsigned_fast_2_3(mut a: T, mut b: T) -> i8 { assert!(b.odd()); if b == T::ONE { return 1; } else if a == T::ZERO { return 0; } let mut s = 1; let two = (b >> 1u32) ^ b; let shift = !a & T::ONE; let shift_8: u8 = shift.wrapping_into(); a >>= shift_8; let mask = shift << 1u32; if (two & mask).get_bit(1) { s.neg_assign(); } let two_bit = two.get_bit(1); while a.even() { a >>= 1; if two_bit { s.neg_assign(); } } if a == T::ONE { return s; } if a < b { if (a & b).get_bit(1) { s.neg_assign(); } swap(&mut a, &mut b); } loop { assert!(a.odd()); assert!(b.odd()); assert!(a >= b); a -= b; if a == T::ZERO { return 0; } let two = (b >> 1u32) ^ b; let mask = !a & T::TWO; a >>= 1; if a.even() { a >>= 1; } if (two ^ (two & mask)).get_bit(1) { s.neg_assign(); } while a.even() { a >>= 1; if two.get_bit(1) { s.neg_assign(); } } if a == T::ONE { return s; } if a < b { if (a & b).get_bit(1) { s.neg_assign(); } swap(&mut a, &mut b); } } } // This is equivalent to `mpn_jacobi_base` from `mpn/jacbase.c`, GMP 6.2.1, where // `JACOBI_BASE_METHOD == 4` and `result_bit_1` is false. pub fn jacobi_symbol_unsigned_fast_2_4(mut a: T, mut b: T) -> i8 { assert!(b.odd()); if b == T::ONE { return 1; } else if a == T::ZERO { return 0; } let mut s = 1; b >>= 1u32; let c = a.trailing_zeros(); if (T::wrapping_from(c) & (b ^ (b >> 1))).odd() { s.neg_assign(); } // We may have c == T::WIDTH - 1, so we can't use a >> (c + 1). a >>= c; a >>= 1; while b != T::ZERO { let t = a.wrapping_sub(b); if t == T::ZERO { return 0; } let bgta = if t.get_highest_bit() { T::MAX } else { T::ZERO }; // If b > a, invoke reciprocity if (bgta & a & b).odd() { s.neg_assign(); } // b <-- min (a, b) b.wrapping_add_assign(bgta & t); // a <-- |a - b| a = (t ^ bgta).wrapping_sub(bgta); // Number of trailing zeros is the same no matter if we look at t or a, but using t gives // more parallelism. let c = t.trailing_zeros() + 1; // (2/b) = -1 if b = 3 or 5 mod 8 if (T::wrapping_from(c) & (b ^ (b >> 1))).odd() { s.neg_assign(); } a >>= c; } s } pub fn jacobi_symbol_unsigned_double_simple< T: PrimitiveUnsigned, D: HasHalf + JoinHalves + PrimitiveUnsigned, >( x_1: T, x_0: T, y_1: T, y_0: T, ) -> i8 { D::join_halves(x_1, x_0).jacobi_symbol(D::join_halves(y_1, y_0)) } // Computes (a / b) where b is odd, and a and b are otherwise arbitrary two-limb numbers. // // This is equivalent to `mpn_jacobi_2` from `mpn/jacobi_2.c`, GMP 6.2.1, where `JACOBI_2_METHOD == // 1` and `bit` is 0. pub fn jacobi_symbol_unsigned_double_fast_1( mut x_1: T, mut x_0: T, mut y_1: T, mut y_0: T, ) -> i8 { assert!(y_0.odd()); y_0 = (y_1 << (T::WIDTH - 1)) | (y_0 >> 1); y_1 >>= 1; if y_1 == T::ZERO && y_0 == T::ZERO { return 1; } if x_1 == T::ZERO && x_0 == T::ZERO { return 0; } if x_0 == T::ZERO { x_0 = x_1; x_1 = T::ZERO; } let mut bit = false; let c = x_0.trailing_zeros() + 1; if c.even() && (y_0 ^ (y_0 >> 1)).odd() { bit.not_assign(); } if c == T::WIDTH { x_0 = x_1; x_1 = T::ZERO; } else { x_0 = (x_1 << (T::WIDTH - c)) | (x_0 >> c); x_1 >>= c; } while x_1 != T::ZERO || y_1 != T::ZERO { let (diff_1, diff_0) = T::xx_sub_yy_to_zz(x_1, x_0, y_1, y_0); if diff_0 == T::ZERO && diff_1 == T::ZERO { return 0; } let mask = if diff_1.get_highest_bit() { T::MAX } else { T::ZERO }; // If y > x, invoke reciprocity if (mask & x_0 & y_0).odd() { bit.not_assign(); } // y <- min(x, y) (y_1, y_0) = T::xx_add_yy_to_zz(y_1, y_0, diff_1 & mask, diff_0 & mask); if y_1 == T::ZERO && y_0 == T::ZERO { return if bit { -1 } else { 1 }; } // x <- |x - y| x_0 = (mask ^ diff_0).wrapping_sub(mask); x_1 = mask ^ diff_1; if x_0 == T::ZERO { // If y > x, x_0 == 0 implies that we have a carry to propagate. x_0 = x_1.wrapping_sub(mask); x_1 = T::ZERO; } let c = x_0.trailing_zeros() + 1; if c.odd() && (y_0 ^ (y_0 >> 1)).odd() { bit.not_assign(); } if c == T::WIDTH { x_0 = x_1; x_1 = T::ZERO; } else { x_0 = (x_1 << (T::WIDTH - c)) | (x_0 >> c); x_1 >>= c; } } assert_ne!(y_0, T::ZERO); while (x_0 | y_0).get_highest_bit() { // Need an extra comparison to get the mask. let t = x_0.wrapping_sub(y_0); let mask = if y_0 > x_0 { T::MAX } else { T::ZERO }; if t == T::ZERO { return 0; } // If y > x, invoke reciprocity if (mask & x_0 & y_0).odd() { bit.not_assign(); } // y <- min(x, y) y_0.wrapping_add_assign(mask & t); // x <- |x - y| x_0 = (t ^ mask).wrapping_sub(mask); // Number of trailing zeros is the same no matter if we look at t or x, but using t gives // more parallelism. let c = t.trailing_zeros() + 1; // (2 / y) = -1 if y = 3 or 5 mod 8 if c.odd() && (y_0 ^ (y_0 >> 1)).odd() { bit.not_assign(); } if c == T::WIDTH { return if bit { -1 } else { 1 }; } x_0 >>= c; } let j = ((x_0 << 1u32) | T::ONE).jacobi_symbol((y_0 << 1u32) | T::ONE); if bit { -j } else { j } } malachite-base-0.4.16/src/test_util/num/arithmetic/mod.rs000064400000000000000000000010451046102023000214330ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . pub mod extended_gcd; pub mod factorial; pub mod kronecker_symbol; pub mod mod_inverse; pub mod mod_mul; pub mod mod_pow; pub mod mod_power_of_2_inverse; pub mod primorial; malachite-base-0.4.16/src/test_util/num/arithmetic/mod_inverse.rs000064400000000000000000000021241046102023000231650ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::WrappingFrom; use crate::test_util::num::arithmetic::extended_gcd::extended_gcd_unsigned_euclidean; pub fn mod_inverse_euclidean< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >( x: U, m: U, ) -> Option { assert_ne!(x, U::ZERO); assert!(x < m); let (gcd, inverse, _) = extended_gcd_unsigned_euclidean::(x, m); if gcd == U::ONE { Some(if inverse >= S::ZERO { U::wrapping_from(inverse) } else { U::wrapping_from(inverse).wrapping_add(m) }) } else { None } } malachite-base-0.4.16/src/test_util/num/arithmetic/mod_mul.rs000064400000000000000000000012701046102023000223100ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::HasHalf; pub fn limbs_invert_limb_naive< T: TryFrom
+ PrimitiveUnsigned, DT: From + HasHalf + PrimitiveUnsigned, >( x: T, ) -> T { T::exact_from(DT::MAX / DT::from(x) - DT::power_of_2(T::WIDTH)) } malachite-base-0.4.16/src/test_util/num/arithmetic/mod_pow.rs000064400000000000000000000013151046102023000223200ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::basic::unsigneds::PrimitiveUnsigned; pub fn naive_mod_pow(x: T, exp: u64, m: T) -> T { if m == T::ONE { return T::ZERO; } let data = T::precompute_mod_mul_data(&m); let mut out = T::ONE; for _ in 0..exp { out.mod_mul_precomputed_assign(x, m, &data); } out } malachite-base-0.4.16/src/test_util/num/arithmetic/mod_power_of_2_inverse.rs000064400000000000000000000026651046102023000253200ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::WrappingFrom; use crate::test_util::num::arithmetic::extended_gcd::extended_gcd_unsigned_euclidean; pub fn mod_power_of_2_inverse_euclidean< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >( a: U, pow: u64, ) -> Option { assert_ne!(a, U::ZERO); assert!(pow <= U::WIDTH); assert!(a.significant_bits() <= pow); if a.even() { return None; } else if a == U::ONE { return Some(U::ONE); } Some(if pow == U::WIDTH { let (q, r) = U::xx_div_mod_y_to_qr(U::ONE, U::ZERO, a); let (_, x, y) = extended_gcd_unsigned_euclidean(r, a); U::wrapping_from(y - S::wrapping_from(q) * x) } else { let m = U::power_of_2(pow); let (_, x, _) = extended_gcd_unsigned_euclidean::(a, m); if x >= S::ZERO { U::wrapping_from(x) } else { U::wrapping_from(x).wrapping_add(m) } }) } malachite-base-0.4.16/src/test_util/num/arithmetic/primorial.rs000064400000000000000000000015741046102023000226610ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::basic::unsigneds::PrimitiveUnsigned; pub fn checked_primorial_naive(n: u64) -> Option { let n = T::try_from(n).ok()?; let mut f = T::ONE; for p in T::primes().take_while(|&p| p <= n) { f = f.checked_mul(p)?; } Some(f) } pub fn checked_product_of_first_n_primes_naive(n: u64) -> Option { let mut f = T::ONE; for p in T::primes().take(usize::try_from(n).ok()?) { f = f.checked_mul(p)?; } Some(f) } malachite-base-0.4.16/src/test_util/num/conversion/mod.rs000064400000000000000000000006101046102023000214640ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . pub mod string; malachite-base-0.4.16/src/test_util/num/conversion/string/from_sci_string.rs000064400000000000000000000006661046102023000254150ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . pub const DECIMAL_SCI_STRING_CHARS: &str = "+-.0123456789Ee"; malachite-base-0.4.16/src/test_util/num/conversion/string/mod.rs000064400000000000000000000006441046102023000230010ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . pub mod from_sci_string; pub mod to_string; malachite-base-0.4.16/src/test_util/num/conversion/string/to_string.rs000064400000000000000000000037371046102023000242400ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{DivAssignMod, UnsignedAbs}; use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::traits::Zero; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::string::to_string::digit_to_display_byte_lower; use crate::num::conversion::traits::WrappingFrom; pub fn to_string_base_unsigned_naive(mut x: T, base: u8) -> String where u8: WrappingFrom, { assert!((2..=36).contains(&base), "base out of range"); if x == T::ZERO { "0".to_string() } else { let base = T::from(base); let mut cs = Vec::new(); while x != T::ZERO { cs.push(char::from( digit_to_display_byte_lower(u8::wrapping_from(x.div_assign_mod(base))).unwrap(), )); } cs.into_iter().rev().collect() } } pub fn to_string_base_signed_naive(x: T, base: u8) -> String where u8: WrappingFrom<::Output>, ::Output: PrimitiveUnsigned, { assert!((2..=36).contains(&base), "base out of range"); if x == T::ZERO { "0".to_string() } else { let base = ::Output::from(base); let mut cs = Vec::new(); let mut abs_x = x.unsigned_abs(); while abs_x != ::Output::ZERO { cs.push(char::from( digit_to_display_byte_lower(u8::wrapping_from(abs_x.div_assign_mod(base))).unwrap(), )); } if x < T::ZERO { cs.push('-'); } cs.into_iter().rev().collect() } } malachite-base-0.4.16/src/test_util/num/exhaustive/mod.rs000064400000000000000000000027451046102023000214770ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::basic::floats::PrimitiveFloat; use crate::num::float::NiceFloat; use itertools::Itertools; pub fn exhaustive_primitive_floats_helper_helper_with_limit< T: PrimitiveFloat, I: Iterator, >( limit: usize, xs: I, out: &[T], ) { assert_eq!( xs.take(limit).map(NiceFloat).collect_vec(), out.iter().copied().map(NiceFloat).collect_vec() ); } pub fn exhaustive_primitive_floats_helper_helper>( xs: I, out: &[T], ) { exhaustive_primitive_floats_helper_helper_with_limit(50, xs, out); } pub fn exhaustive_primitive_floats_helper_helper_with_reverse< T: PrimitiveFloat, I: Clone + DoubleEndedIterator, >( xs: I, first_20: &[T], last_20: &[T], ) { assert_eq!( xs.clone().take(20).map(NiceFloat).collect_vec(), first_20.iter().copied().map(NiceFloat).collect_vec() ); let mut reversed = xs.rev().take(20).map(NiceFloat).collect_vec(); reversed.reverse(); assert_eq!( reversed, last_20.iter().copied().map(NiceFloat).collect_vec() ); } malachite-base-0.4.16/src/test_util/num/factorization/mod.rs000064400000000000000000000006351046102023000221620ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . pub mod prime_sieve; pub mod primes; malachite-base-0.4.16/src/test_util/num/factorization/prime_sieve.rs000064400000000000000000000102201046102023000237010ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{CheckedSquare, DivisibleBy, FloorSqrt, Parity}; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::{ExactFrom, WrappingFrom}; use crate::num::factorization::prime_sieve::{id_to_n, limbs_count_ones, n_to_bit}; use crate::num::logic::traits::{NotAssign, TrailingZeros}; use crate::slices::slice_leading_zeros; // Replace with good primality test once we have one fn is_prime_simple(n: u64) -> bool { match n { 0 | 1 => false, 2 => true, n if n.even() => false, n => { for f in 3..=n.floor_sqrt() { if n.divisible_by(f) { return false; } } true } } } pub fn limbs_prime_sieve_naive_1(bit_array: &mut [T], n: u64) -> u64 { assert!(n > 4); let mut f = 5; let mut b = false; 'outer: for x in &mut *bit_array { *x = T::MAX; for i in 0..T::WIDTH { if is_prime_simple(f) { x.clear_bit(i); } f += if b { 4 } else { 2 }; if f > n { break 'outer; } b.not_assign(); } } (u64::exact_from(bit_array.len()) << T::LOG_WIDTH) - limbs_count_ones(bit_array) } fn limbs_index_of_next_true_bit(xs: &[T], start: u64) -> Option { let starting_index = usize::exact_from(start >> T::LOG_WIDTH); if starting_index >= xs.len() { None } else if let Some(result) = xs[starting_index].index_of_next_true_bit(start & T::WIDTH_MASK) { Some((u64::wrapping_from(starting_index) << T::LOG_WIDTH) + result) } else if starting_index == xs.len() - 1 { None } else { let true_index = starting_index + 1 + slice_leading_zeros(&xs[starting_index + 1..]); if true_index == xs.len() { None } else { let result_offset = u64::wrapping_from(true_index) << T::LOG_WIDTH; Some( result_offset .checked_add(TrailingZeros::trailing_zeros(xs[true_index])) .unwrap(), ) } } } fn limbs_set_bit_helper(xs: &mut [T], index: u64, limb_index: usize) { xs[limb_index].set_bit(index & T::WIDTH_MASK); } fn limbs_slice_set_bit(xs: &mut [T], index: u64) { limbs_set_bit_helper(xs, index, usize::exact_from(index >> T::LOG_WIDTH)); } fn limbs_clear_bit(xs: &mut [T], index: u64) { let small_index = usize::exact_from(index >> T::LOG_WIDTH); if small_index < xs.len() { xs[small_index].clear_bit(index & T::WIDTH_MASK); } } pub fn limbs_prime_sieve_naive_2(bit_array: &mut [T], n: u64) -> u64 { assert!(n > 4); for x in &mut *bit_array { *x = T::MAX; } let mut p = 0; loop { let id = limbs_index_of_next_true_bit(bit_array, if p == 0 { 0 } else { n_to_bit(p) + 1 }); if let Some(id) = id { p = id_to_n(id + 1); } else { break; } let m = p.checked_square(); if m.is_none() { break; } let mut m = m.unwrap(); if m > n { break; } let two_p = p << 1; while m <= n { if m.odd() && !m.divisible_by(3) { limbs_clear_bit(bit_array, n_to_bit(m)); } m += two_p; } } for x in &mut *bit_array { x.not_assign(); } let bit_len = u64::exact_from(bit_array.len()) << T::LOG_WIDTH; for i in (0..bit_len).rev() { if id_to_n(i + 1) <= n { break; } limbs_slice_set_bit(bit_array, i); } bit_len - limbs_count_ones(bit_array) } malachite-base-0.4.16/src/test_util/num/factorization/primes.rs000064400000000000000000000026531046102023000227040ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::exhaustive::primitive_int_increasing_inclusive_range; pub struct PrimesNaive(T); impl Iterator for PrimesNaive { type Item = T; fn next(&mut self) -> Option { if self.0 == T::ONE { self.0 = T::TWO; return Some(self.0); } else if self.0 == T::TWO { self.0 = T::from(3u8); return Some(self.0); } 'outer: loop { self.0 = self.0.checked_add(T::TWO)?; let a = T::from(3u8); let b = self.0.floor_sqrt(); if a <= b { for f in primitive_int_increasing_inclusive_range(a, b) { if self.0.divisible_by(f) { continue 'outer; } } } return Some(self.0); } } } pub const fn primes_naive() -> PrimesNaive { // 1 will never actually be generated PrimesNaive(T::ONE) } malachite-base-0.4.16/src/test_util/num/float/mod.rs000064400000000000000000000006711046102023000204130ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . pub const PRIMITIVE_FLOAT_CHARS: &str = "-.0123456789INaefinty"; malachite-base-0.4.16/src/test_util/num/logic/bit_block_access.rs000064400000000000000000000015621046102023000230750ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::basic::traits::Zero; use crate::num::logic::traits::BitAccess; pub fn get_bits_naive(n: &T, start: u64, end: u64) -> U { let mut result = U::ZERO; for i in start..end { if n.get_bit(i) { result.set_bit(i - start); } } result } pub fn assign_bits_naive(n: &mut T, start: u64, end: u64, bits: &U) { for i in start..end { n.assign_bit(i, bits.get_bit(i - start)); } } malachite-base-0.4.16/src/test_util/num/logic/bit_convertible.rs000064400000000000000000000065551046102023000230050ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::ExactFrom; use crate::num::logic::traits::BitConvertible; use itertools::Itertools; pub fn to_bits_asc_alt(n: &T) -> Vec { let mut bits = n.to_bits_desc(); bits.reverse(); bits } pub fn to_bits_desc_alt(n: &T) -> Vec { let mut bits = n.to_bits_asc(); bits.reverse(); bits } pub fn from_bits_asc_alt>(bits: I) -> T { let mut bits = bits.collect_vec(); bits.reverse(); T::from_bits_desc(bits.into_iter()) } pub fn from_bits_desc_alt>(bits: I) -> T { let mut bits = bits.collect_vec(); bits.reverse(); T::from_bits_asc(bits.into_iter()) } pub fn to_bits_asc_unsigned_naive(n: T) -> Vec { let mut bits = Vec::new(); for i in 0..n.significant_bits() { bits.push(n.get_bit(i)); } bits } pub fn to_bits_desc_unsigned_naive(n: T) -> Vec { let mut bits = Vec::new(); for i in (0..n.significant_bits()).rev() { bits.push(n.get_bit(i)); } bits } pub fn from_bits_asc_unsigned_naive>(bits: I) -> T { let mut n = T::ZERO; for i in bits .enumerate() .filter_map(|(i, bit)| if bit { Some(u64::exact_from(i)) } else { None }) { n.set_bit(i); } n } pub fn to_bits_asc_signed_naive(n: T) -> Vec { let mut bits = Vec::new(); if n == T::ZERO { return bits; } for i in 0..n.significant_bits() { bits.push(n.get_bit(i)); } let last_bit = *bits.last().unwrap(); if last_bit != (n < T::ZERO) { bits.push(!last_bit); } bits } pub fn to_bits_desc_signed_naive(n: T) -> Vec { let mut bits = Vec::new(); if n == T::ZERO { return bits; } let significant_bits = n.significant_bits(); let last_bit = n.get_bit(significant_bits - 1); if last_bit != (n < T::ZERO) { bits.push(!last_bit); } for i in (0..significant_bits).rev() { bits.push(n.get_bit(i)); } bits } pub fn from_bits_asc_signed_naive>(bits: I) -> T { let bits = bits.collect_vec(); if bits.is_empty() { return T::ZERO; } let mut n; if *bits.last().unwrap() { n = T::NEGATIVE_ONE; for i in bits.iter() .enumerate() .filter_map(|(i, &bit)| if bit { None } else { Some(u64::exact_from(i)) }) { n.clear_bit(i); } } else { n = T::ZERO; for i in bits.iter() .enumerate() .filter_map(|(i, &bit)| if bit { Some(u64::exact_from(i)) } else { None }) { n.set_bit(i); } }; n } malachite-base-0.4.16/src/test_util/num/logic/mod.rs000064400000000000000000000006531046102023000204030ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . pub mod bit_block_access; pub mod bit_convertible; malachite-base-0.4.16/src/test_util/num/mod.rs000064400000000000000000000007711046102023000173070ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . pub mod arithmetic; pub mod conversion; pub mod exhaustive; pub mod factorization; pub mod float; pub mod logic; pub mod random; malachite-base-0.4.16/src/test_util/num/random/geometric.rs000064400000000000000000000040231046102023000217600ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::basic::floats::PrimitiveFloat; use crate::num::basic::integers::PrimitiveInt; use crate::num::logic::traits::BitAccess; use std::cmp::Ordering::*; pub fn unadjusted_mean_to_adjusted_mean(unadjusted_mean: f64, limit: f64) -> f64 { let m = limit; assert!(unadjusted_mean > 0.0); assert!(m > 0.0); let p = 1.0 / (unadjusted_mean + 1.0); let q = 1.0 - p; let pow = q.powf(m + 1.0); let adjusted = ((m * p + 1.0) * pow - q) / (p * (pow - 1.0)); adjusted.abs() } pub fn adjusted_mean_to_unadjusted_mean(adjusted_mean: f64, limit: f64) -> f64 { assert!(adjusted_mean > 0.0); assert!(adjusted_mean < limit / 2.0); let mut min = f64::MIN_POSITIVE_SUBNORMAL.to_ordered_representation(); let mut max = f64::MAX_FINITE.to_ordered_representation(); loop { if min == max { let f_max = unadjusted_mean_to_adjusted_mean(f64::from_ordered_representation(max), limit); assert!(!f_max.is_nan() && f_max <= limit && f_max >= adjusted_mean); return f64::from_ordered_representation(max); } let (sum, overflow) = min.overflowing_add(max); let mut mid = sum >> 1; if overflow { mid.set_bit(u64::WIDTH - 1); } let f_mid = unadjusted_mean_to_adjusted_mean(f64::from_ordered_representation(mid), limit); let compare = if f_mid.is_nan() { Greater } else { f_mid.partial_cmp(&adjusted_mean).unwrap() }; match compare { Greater => max = mid, Less => min = mid + 1, Equal => return f64::from_ordered_representation(mid), } } } malachite-base-0.4.16/src/test_util/num/random/mod.rs000064400000000000000000000056601046102023000205710ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::basic::floats::PrimitiveFloat; use crate::num::float::NiceFloat; use crate::test_util::stats::common_values_map::common_values_map; use crate::test_util::stats::median; use crate::test_util::stats::moments::{moment_stats, CheckedToF64, MomentStats}; use itertools::Itertools; pub fn random_primitive_floats_helper_helper< T: CheckedToF64 + PrimitiveFloat, I: Clone + Iterator, >( xs: I, expected_values: &[T], expected_common_values: &[(T, usize)], expected_median: (T, Option), expected_moment_stats: MomentStats, ) { let actual_values = xs.clone().take(20).map(NiceFloat).collect_vec(); let actual_common_values = common_values_map(1000000, 10, xs.clone().map(NiceFloat)); let actual_median = median(xs.clone().map(NiceFloat).take(1000000)); let actual_moment_stats = moment_stats(xs.take(1000000)); let (lo, hi) = expected_median; assert_eq!( ( actual_values, actual_common_values.as_slice(), actual_median, actual_moment_stats ), ( expected_values.iter().copied().map(NiceFloat).collect_vec(), expected_common_values .iter() .map(|&(x, freq)| (NiceFloat(x), freq)) .collect_vec() .as_slice(), (NiceFloat(lo), hi.map(NiceFloat)), expected_moment_stats ) ); } pub fn special_random_primitive_floats_helper_helper< T: CheckedToF64 + PrimitiveFloat, I: Clone + Iterator, >( xs: I, expected_values: &[T], expected_common_values: &[(T, usize)], expected_median: (T, Option), expected_moment_stats: MomentStats, ) { let actual_values = xs.clone().take(50).map(NiceFloat).collect_vec(); let actual_common_values = common_values_map(1000000, 20, xs.clone().map(NiceFloat)); let actual_median = median(xs.clone().map(NiceFloat).take(1000000)); let actual_moment_stats = moment_stats(xs.take(1000000)); let (lo, hi) = expected_median; assert_eq!( ( actual_values, actual_common_values.as_slice(), actual_median, actual_moment_stats ), ( expected_values.iter().copied().map(NiceFloat).collect_vec(), expected_common_values .iter() .map(|&(x, freq)| (NiceFloat(x), freq)) .collect_vec() .as_slice(), (NiceFloat(lo), hi.map(NiceFloat)), expected_moment_stats ) ); } pub mod geometric; malachite-base-0.4.16/src/test_util/rounding_modes/mod.rs000064400000000000000000000006661046102023000215270ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . pub const ROUNDING_MODE_CHARS: &str = "CDEFNUacegilnoprstwx"; malachite-base-0.4.16/src/test_util/runner/cmd.rs000064400000000000000000000077251046102023000200130ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::test_util::generators::common::{GenConfig, GenMode}; use clap::{App, Arg}; use itertools::Itertools; use std::str::FromStr; #[derive(Clone, Debug)] pub struct CommandLineArguments { pub codegen_key: Option, pub demo_key: Option, pub bench_key: Option, pub generation_mode: GenMode, pub config: GenConfig, pub limit: usize, pub out: String, } pub fn read_command_line_arguments(name: &str) -> CommandLineArguments { let matches = App::new(name) .version("0.1.0") .author("Mikhail Hogrefe ") .about("Runs demos and benchmarks for malachite-base functions.") .arg( Arg::with_name("generation_mode") .short("m") .long("generation_mode") .help("May be 'exhaustive', 'random', or 'special_random'.") .takes_value(true), ) .arg( Arg::with_name("config") .short("c") .long("config") .help("e.g. 'mean_run_length_n 4 mean_run_length_d 1'") .takes_value(true), ) .arg( Arg::with_name("limit") .short("l") .long("limit") .help("Specifies the maximum number of elements to generate") .takes_value(true), ) .arg( Arg::with_name("out") .short("o") .long("out") .help("Specifies the file name to write a benchmark to") .takes_value(true), ) .arg( Arg::with_name("demo") .short("d") .long("demo") .help("Specifies the demo name") .takes_value(true), ) .arg( Arg::with_name("bench") .short("b") .long("bench") .help("Specifies the benchmark name") .takes_value(true), ) .arg( Arg::with_name("codegen") .short("g") .long("codegen") .help("Specifies the code to generate") .takes_value(true), ) .get_matches(); let generation_mode = match matches.value_of("generation_mode").unwrap_or("exhaustive") { "exhaustive" => GenMode::Exhaustive, "random" => GenMode::Random, "special_random" => GenMode::SpecialRandom, _ => panic!("Invalid generation mode"), }; let config_string = matches.value_of("config").unwrap_or(""); let mut config = GenConfig::new(); if !config_string.is_empty() { for mut chunk in &config_string.split(' ').chunks(2) { let key = chunk.next().unwrap(); let value = u64::from_str(chunk.next().expect("Bad config")).expect("Invalid config value"); config.insert(key, value); } } let limit = usize::from_str(matches.value_of("limit").unwrap_or("10000")).expect("Invalid limit"); let out = matches.value_of("out").unwrap_or("temp.gp").to_string(); let demo_key = matches.value_of("demo").map(ToString::to_string); let bench_key = matches.value_of("bench").map(ToString::to_string); let codegen_key = matches.value_of("codegen").map(ToString::to_string); assert!( demo_key.is_some() || bench_key.is_some() || codegen_key.is_some(), "Must specify demo, bench, or codegen" ); CommandLineArguments { codegen_key, demo_key, bench_key, generation_mode, config, limit, out, } } malachite-base-0.4.16/src/test_util/runner/mod.rs000064400000000000000000000566621046102023000200330ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::test_util::generators::common::{GenConfig, GenMode}; use std::collections::HashMap; pub type DemoFn = &'static dyn Fn(GenMode, &GenConfig, usize); pub type BenchFn = &'static dyn Fn(GenMode, &GenConfig, usize, &str); pub struct Runner { demo_map: HashMap<&'static str, DemoFn>, bench_map: HashMap<&'static str, BenchFn>, } impl Runner { pub fn new() -> Runner { Runner { demo_map: HashMap::new(), bench_map: HashMap::new(), } } pub fn run_demo(&self, key: &str, gm: GenMode, config: &GenConfig, limit: usize) { self.demo_map.get(key).expect("Invalid demo key")(gm, config, limit); } pub fn run_bench( &self, key: &str, gm: GenMode, config: &GenConfig, limit: usize, file_name: &str, ) { self.bench_map.get(key).expect("Invalid bench key")(gm, config, limit, file_name); } pub fn register_demo(&mut self, key: &'static str, f: DemoFn) { assert!( self.demo_map.insert(key, f).is_none(), "Duplicate demo with key {key}", ); } pub fn register_bench(&mut self, key: &'static str, f: BenchFn) { assert!( self.bench_map.insert(key, f).is_none(), "Duplicate bench with key {key}", ); } } impl Default for Runner { fn default() -> Runner { Runner::new() } } #[macro_export] macro_rules! register_demo { ($runner: ident, $f: ident) => { $runner.register_demo(stringify!($f), &$f); }; } #[macro_export] macro_rules! register_generic_demos { ($runner: ident, $f: ident $(,$t:ty)*) => { $( $runner.register_demo(concat!(stringify!($f), "_", stringify!($t)), &$f::<$t>); )* }; } #[macro_export] macro_rules! register_generic_demos_2 { ($runner: ident, $f: ident $(,[$t:ty, $u:ty])*) => { $( $runner.register_demo( concat!(stringify!($f), "_", stringify!($t), "_", stringify!($u)), &$f::<$t, $u> ); )* }; } #[macro_export] macro_rules! register_generic_demos_3_only_1_3_in_key { ($runner: ident, $f: ident $(,[$t:ty, $u:ty, $v:ty])*) => { $( $runner.register_demo( concat!(stringify!($f), "_", stringify!($t), "_", stringify!($v)), &$f::<$t, $u, $v> ); )* }; } #[macro_export] macro_rules! register_generic_benches_3_only_1_3_in_key { ($runner: ident, $f: ident $(,[$t:ty, $u:ty, $v:ty])*) => { $( $runner.register_bench( concat!(stringify!($f), "_", stringify!($t), "_", stringify!($v)), &$f::<$t, $u, $v> ); )* }; } #[macro_export] macro_rules! register_generic_demos_2_only_first_in_key { ($runner: ident, $f: ident $(,[$t:ty, $u:ty])*) => { $( $runner.register_demo( concat!(stringify!($f), "_", stringify!($t)), &$f::<$t, $u> ); )* }; } #[macro_export] macro_rules! register_unsigned_demos { ($runner: ident, $f: ident) => { register_generic_demos!($runner, $f, u8, u16, u32, u64, u128, usize); }; } #[macro_export] macro_rules! register_signed_demos { ($runner: ident, $f: ident) => { register_generic_demos!($runner, $f, i8, i16, i32, i64, i128, isize); }; } #[macro_export] macro_rules! register_primitive_float_demos { ($runner: ident, $f: ident) => { register_generic_demos!($runner, $f, f32, f64); }; } #[macro_export] macro_rules! register_primitive_float_unsigned_demos { ($runner: ident, $f: ident) => { register_generic_demos_2!( $runner, $f, [f32, u8], [f32, u16], [f32, u32], [f32, u64], [f32, u128], [f32, usize], [f64, u8], [f64, u16], [f64, u32], [f64, u64], [f64, u128], [f64, usize] ); }; } #[macro_export] macro_rules! register_primitive_float_signed_demos { ($runner: ident, $f: ident) => { register_generic_demos_2!( $runner, $f, [f32, i8], [f32, i16], [f32, i32], [f32, i64], [f32, i128], [f32, isize], [f64, i8], [f64, i16], [f64, i32], [f64, i64], [f64, i128], [f64, isize] ); }; } #[macro_export] macro_rules! register_signed_unsigned_match_demos { ($runner: ident, $f: ident) => { register_generic_demos_2_only_first_in_key!( $runner, $f, [i8, u8], [i16, u16], [i32, u32], [i64, u64], [i128, u128], [isize, usize] ); }; } #[macro_export] macro_rules! register_unsigned_signed_match_demos { ($runner: ident, $f: ident) => { register_generic_demos_2_only_first_in_key!( $runner, $f, [u8, i8], [u16, i16], [u32, i32], [u64, i64], [u128, i128], [usize, isize] ); }; } #[macro_export] macro_rules! register_primitive_int_demos { ($runner: ident, $f: ident) => { register_unsigned_demos!($runner, $f); register_signed_demos!($runner, $f); }; } #[macro_export] macro_rules! register_unsigned_unsigned_demos { ($runner: ident, $f: ident) => { register_generic_demos_2!( $runner, $f, [u8, u8], [u8, u16], [u8, u32], [u8, u64], [u8, u128], [u8, usize], [u16, u8], [u16, u16], [u16, u32], [u16, u64], [u16, u128], [u16, usize], [u32, u8], [u32, u16], [u32, u32], [u32, u64], [u32, u128], [u32, usize], [u64, u8], [u64, u16], [u64, u32], [u64, u64], [u64, u128], [u64, usize], [u128, u8], [u128, u16], [u128, u32], [u128, u64], [u128, u128], [u128, usize], [usize, u8], [usize, u16], [usize, u32], [usize, u64], [usize, u128], [usize, usize] ); }; } #[macro_export] macro_rules! register_signed_unsigned_demos { ($runner: ident, $f: ident) => { register_generic_demos_2!( $runner, $f, [i8, u8], [i8, u16], [i8, u32], [i8, u64], [i8, u128], [i8, usize], [i16, u8], [i16, u16], [i16, u32], [i16, u64], [i16, u128], [i16, usize], [i32, u8], [i32, u16], [i32, u32], [i32, u64], [i32, u128], [i32, usize], [i64, u8], [i64, u16], [i64, u32], [i64, u64], [i64, u128], [i64, usize], [i128, u8], [i128, u16], [i128, u32], [i128, u64], [i128, u128], [i128, usize], [isize, u8], [isize, u16], [isize, u32], [isize, u64], [isize, u128], [isize, usize] ); }; } #[macro_export] macro_rules! register_primitive_int_unsigned_demos { ($runner: ident, $f: ident) => { register_unsigned_unsigned_demos!($runner, $f); register_signed_unsigned_demos!($runner, $f); }; } #[macro_export] macro_rules! register_unsigned_signed_demos { ($runner: ident, $f: ident) => { register_generic_demos_2!( $runner, $f, [u8, i8], [u8, i16], [u8, i32], [u8, i64], [u8, i128], [u8, isize], [u16, i8], [u16, i16], [u16, i32], [u16, i64], [u16, i128], [u16, isize], [u32, i8], [u32, i16], [u32, i32], [u32, i64], [u32, i128], [u32, isize], [u64, i8], [u64, i16], [u64, i32], [u64, i64], [u64, i128], [u64, isize], [u128, i8], [u128, i16], [u128, i32], [u128, i64], [u128, i128], [u128, isize], [usize, i8], [usize, i16], [usize, i32], [usize, i64], [usize, i128], [usize, isize] ); }; } #[macro_export] macro_rules! register_unsigned_unsigned_signed_match_demos { ($runner: ident, $f: ident) => { register_generic_demos_3_only_1_3_in_key!( $runner, $f, [u8, u8, i8], [u8, u16, i16], [u8, u32, i32], [u8, u64, i64], [u8, u128, i128], [u8, usize, isize], [u16, u8, i8], [u16, u16, i16], [u16, u32, i32], [u16, u64, i64], [u16, u128, i128], [u16, usize, isize], [u32, u8, i8], [u32, u16, i16], [u32, u32, i32], [u32, u64, i64], [u32, u128, i128], [u32, usize, isize], [u64, u8, i8], [u64, u16, i16], [u64, u32, i32], [u64, u64, i64], [u64, u128, i128], [u64, usize, isize], [u128, u8, i8], [u128, u16, i16], [u128, u32, i32], [u128, u64, i64], [u128, u128, i128], [u128, usize, isize], [usize, u8, i8], [usize, u16, i16], [usize, u32, i32], [usize, u64, i64], [usize, u128, i128], [usize, usize, isize] ); }; } #[macro_export] macro_rules! register_signed_signed_demos { ($runner: ident, $f: ident) => { register_generic_demos_2!( $runner, $f, [i8, i8], [i8, i16], [i8, i32], [i8, i64], [i8, i128], [i8, isize], [i16, i8], [i16, i16], [i16, i32], [i16, i64], [i16, i128], [i16, isize], [i32, i8], [i32, i16], [i32, i32], [i32, i64], [i32, i128], [i32, isize], [i64, i8], [i64, i16], [i64, i32], [i64, i64], [i64, i128], [i64, isize], [i128, i8], [i128, i16], [i128, i32], [i128, i64], [i128, i128], [i128, isize], [isize, i8], [isize, i16], [isize, i32], [isize, i64], [isize, i128], [isize, isize] ); }; } #[macro_export] macro_rules! register_primitive_int_signed_demos { ($runner: ident, $f: ident) => { register_unsigned_signed_demos!($runner, $f); register_signed_signed_demos!($runner, $f); }; } #[macro_export] macro_rules! register_unsigned_primitive_float_demos { ($runner: ident, $f: ident) => { register_generic_demos_2!( $runner, $f, [u8, f32], [u8, f64], [u16, f32], [u16, f64], [u32, f32], [u32, f64], [u64, f32], [u64, f64], [u128, f32], [u128, f64], [usize, f32], [usize, f64] ); }; } #[macro_export] macro_rules! register_signed_primitive_float_demos { ($runner: ident, $f: ident) => { register_generic_demos_2!( $runner, $f, [i8, f32], [i8, f64], [i16, f32], [i16, f64], [i32, f32], [i32, f64], [i64, f32], [i64, f64], [i128, f32], [i128, f64], [isize, f32], [isize, f64] ); }; } #[macro_export] macro_rules! register_primitive_int_primitive_float_demos { ($runner: ident, $f: ident) => { register_unsigned_primitive_float_demos!($runner, $f); register_signed_primitive_float_demos!($runner, $f); }; } #[macro_export] macro_rules! register_bench { ($runner: ident, $f: ident) => { $runner.register_bench(stringify!($f), &$f); }; } #[macro_export] macro_rules! register_generic_benches { ($runner: ident, $f: ident $(,$t:ty)*) => { $( $runner.register_bench(concat!(stringify!($f), "_", stringify!($t)), &$f::<$t>); )* }; } #[macro_export] macro_rules! register_generic_benches_2 { ($runner: ident, $f: ident $(,[$t:ty, $u:ty])*) => { $( $runner.register_bench( concat!(stringify!($f), "_", stringify!($t), "_", stringify!($u)), &$f::<$t, $u> ); )* }; } #[macro_export] macro_rules! register_generic_benches_2_only_first_in_key { ($runner: ident, $f: ident $(,[$t:ty, $u:ty])*) => { $( $runner.register_bench( concat!(stringify!($f), "_", stringify!($t)), &$f::<$t, $u> ); )* }; } #[macro_export] macro_rules! register_unsigned_benches { ($runner: ident, $f: ident) => { register_generic_benches!($runner, $f, u8, u16, u32, u64, u128, usize); }; } #[macro_export] macro_rules! register_signed_benches { ($runner: ident, $f: ident) => { register_generic_benches!($runner, $f, i8, i16, i32, i64, i128, isize); }; } #[macro_export] macro_rules! register_primitive_float_benches { ($runner: ident, $f: ident) => { register_generic_benches!($runner, $f, f32, f64); }; } #[macro_export] macro_rules! register_primitive_float_unsigned_benches { ($runner: ident, $f: ident) => { register_generic_benches_2!( $runner, $f, [f32, u8], [f32, u16], [f32, u32], [f32, u64], [f32, u128], [f32, usize], [f64, u8], [f64, u16], [f64, u32], [f64, u64], [f64, u128], [f64, usize] ); }; } #[macro_export] macro_rules! register_primitive_float_signed_benches { ($runner: ident, $f: ident) => { register_generic_benches_2!( $runner, $f, [f32, i8], [f32, i16], [f32, i32], [f32, i64], [f32, i128], [f32, isize], [f64, i8], [f64, i16], [f64, i32], [f64, i64], [f64, i128], [f64, isize] ); }; } #[macro_export] macro_rules! register_signed_unsigned_match_benches { ($runner: ident, $f: ident) => { register_generic_benches_2_only_first_in_key!( $runner, $f, [i8, u8], [i16, u16], [i32, u32], [i64, u64], [i128, u128], [isize, usize] ); }; } #[macro_export] macro_rules! register_unsigned_signed_match_benches { ($runner: ident, $f: ident) => { register_generic_benches_2_only_first_in_key!( $runner, $f, [u8, i8], [u16, i16], [u32, i32], [u64, i64], [u128, i128], [usize, isize] ); }; } #[macro_export] macro_rules! register_primitive_int_benches { ($runner: ident, $f: ident) => { register_unsigned_benches!($runner, $f); register_signed_benches!($runner, $f); }; } #[macro_export] macro_rules! register_unsigned_unsigned_benches { ($runner: ident, $f: ident) => { register_generic_benches_2!( $runner, $f, [u8, u8], [u8, u16], [u8, u32], [u8, u64], [u8, u128], [u8, usize], [u16, u8], [u16, u16], [u16, u32], [u16, u64], [u16, u128], [u16, usize], [u32, u8], [u32, u16], [u32, u32], [u32, u64], [u32, u128], [u32, usize], [u64, u8], [u64, u16], [u64, u32], [u64, u64], [u64, u128], [u64, usize], [u128, u8], [u128, u16], [u128, u32], [u128, u64], [u128, u128], [u128, usize], [usize, u8], [usize, u16], [usize, u32], [usize, u64], [usize, u128], [usize, usize] ); }; } #[macro_export] macro_rules! register_signed_unsigned_benches { ($runner: ident, $f: ident) => { register_generic_benches_2!( $runner, $f, [i8, u8], [i8, u16], [i8, u32], [i8, u64], [i8, u128], [i8, usize], [i16, u8], [i16, u16], [i16, u32], [i16, u64], [i16, u128], [i16, usize], [i32, u8], [i32, u16], [i32, u32], [i32, u64], [i32, u128], [i32, usize], [i64, u8], [i64, u16], [i64, u32], [i64, u64], [i64, u128], [i64, usize], [i128, u8], [i128, u16], [i128, u32], [i128, u64], [i128, u128], [i128, usize], [isize, u8], [isize, u16], [isize, u32], [isize, u64], [isize, u128], [isize, usize] ); }; } #[macro_export] macro_rules! register_primitive_int_unsigned_benches { ($runner: ident, $f: ident) => { register_unsigned_unsigned_benches!($runner, $f); register_signed_unsigned_benches!($runner, $f); }; } #[macro_export] macro_rules! register_unsigned_signed_benches { ($runner: ident, $f: ident) => { register_generic_benches_2!( $runner, $f, [u8, i8], [u8, i16], [u8, i32], [u8, i64], [u8, i128], [u8, isize], [u16, i8], [u16, i16], [u16, i32], [u16, i64], [u16, i128], [u16, isize], [u32, i8], [u32, i16], [u32, i32], [u32, i64], [u32, i128], [u32, isize], [u64, i8], [u64, i16], [u64, i32], [u64, i64], [u64, i128], [u64, isize], [u128, i8], [u128, i16], [u128, i32], [u128, i64], [u128, i128], [u128, isize], [usize, i8], [usize, i16], [usize, i32], [usize, i64], [usize, i128], [usize, isize] ); }; } #[macro_export] macro_rules! register_unsigned_unsigned_signed_match_benches { ($runner: ident, $f: ident) => { register_generic_benches_3_only_1_3_in_key!( $runner, $f, [u8, u8, i8], [u8, u16, i16], [u8, u32, i32], [u8, u64, i64], [u8, u128, i128], [u8, usize, isize], [u16, u8, i8], [u16, u16, i16], [u16, u32, i32], [u16, u64, i64], [u16, u128, i128], [u16, usize, isize], [u32, u8, i8], [u32, u16, i16], [u32, u32, i32], [u32, u64, i64], [u32, u128, i128], [u32, usize, isize], [u64, u8, i8], [u64, u16, i16], [u64, u32, i32], [u64, u64, i64], [u64, u128, i128], [u64, usize, isize], [u128, u8, i8], [u128, u16, i16], [u128, u32, i32], [u128, u64, i64], [u128, u128, i128], [u128, usize, isize], [usize, u8, i8], [usize, u16, i16], [usize, u32, i32], [usize, u64, i64], [usize, u128, i128], [usize, usize, isize] ); }; } #[macro_export] macro_rules! register_signed_signed_benches { ($runner: ident, $f: ident) => { register_generic_benches_2!( $runner, $f, [i8, i8], [i8, i16], [i8, i32], [i8, i64], [i8, i128], [i8, isize], [i16, i8], [i16, i16], [i16, i32], [i16, i64], [i16, i128], [i16, isize], [i32, i8], [i32, i16], [i32, i32], [i32, i64], [i32, i128], [i32, isize], [i64, i8], [i64, i16], [i64, i32], [i64, i64], [i64, i128], [i64, isize], [i128, i8], [i128, i16], [i128, i32], [i128, i64], [i128, i128], [i128, isize], [isize, i8], [isize, i16], [isize, i32], [isize, i64], [isize, i128], [isize, isize] ); }; } #[macro_export] macro_rules! register_primitive_int_signed_benches { ($runner: ident, $f: ident) => { register_unsigned_signed_benches!($runner, $f); register_signed_signed_benches!($runner, $f); }; } #[macro_export] macro_rules! register_unsigned_primitive_float_benches { ($runner: ident, $f: ident) => { register_generic_benches_2!( $runner, $f, [u8, f32], [u8, f64], [u16, f32], [u16, f64], [u32, f32], [u32, f64], [u64, f32], [u64, f64], [u128, f32], [u128, f64], [usize, f32], [usize, f64] ); }; } #[macro_export] macro_rules! register_signed_primitive_float_benches { ($runner: ident, $f: ident) => { register_generic_benches_2!( $runner, $f, [i8, f32], [i8, f64], [i16, f32], [i16, f64], [i32, f32], [i32, f64], [i64, f32], [i64, f64], [i128, f32], [i128, f64], [isize, f32], [isize, f64] ); }; } #[macro_export] macro_rules! register_primitive_int_primitive_float_benches { ($runner: ident, $f: ident) => { register_unsigned_primitive_float_benches!($runner, $f); register_signed_primitive_float_benches!($runner, $f); }; } pub mod cmd; malachite-base-0.4.16/src/test_util/sets/exhaustive/mod.rs000064400000000000000000000032771046102023000216570ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use std::collections::{BTreeSet, HashSet}; use std::fmt::Debug; use std::hash::Hash; pub fn exhaustive_b_tree_sets_helper_helper< T: Clone + Debug + Ord, I: Iterator>, >( xss: I, out: &[BTreeSet], ) { let xss = xss.take(20).collect_vec(); assert_eq!(xss.into_iter().collect_vec().as_slice(), out); } pub fn exhaustive_b_tree_sets_small_helper_helper< T: Clone + Debug + Ord, I: Clone + Iterator>, >( xss: I, out_len: usize, out: &[BTreeSet], ) { let xss_prefix = xss.clone().take(20).collect_vec(); assert_eq!(xss_prefix.into_iter().collect_vec().as_slice(), out); assert_eq!(xss.count(), out_len); } pub fn exhaustive_hash_sets_helper_helper< T: Clone + Debug + Eq + Hash, I: Iterator>, >( xss: I, out: &[HashSet], ) { let xss = xss.take(20).collect_vec(); assert_eq!(xss.into_iter().collect_vec().as_slice(), out); } pub fn exhaustive_hash_sets_small_helper_helper< T: Clone + Debug + Eq + Hash, I: Clone + Iterator>, >( xss: I, out_len: usize, out: &[HashSet], ) { let xss_prefix = xss.clone().take(20).collect_vec(); assert_eq!(xss_prefix.into_iter().collect_vec().as_slice(), out); assert_eq!(xss.count(), out_len); } malachite-base-0.4.16/src/test_util/sets/mod.rs000064400000000000000000000006141046102023000174620ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . pub mod exhaustive; malachite-base-0.4.16/src/test_util/slices/mod.rs000064400000000000000000000010621046102023000177640ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . pub fn slice_move_left_naive(xs: &mut [T], amount: usize) { let slice = xs[amount..].to_vec(); let limit = xs.len() - amount; xs[..limit].copy_from_slice(&slice); } malachite-base-0.4.16/src/test_util/stats/common_values_map.rs000064400000000000000000000057461046102023000226020ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::strings::ToDebugString; use std::cmp::Ordering; use std::collections::{BinaryHeap, HashMap}; use std::fmt::{Debug, Display}; use std::hash::Hash; macro_rules! impl_common_values_map { ($CommonOrdered: ident, $StringTrait: ident, $to_string: ident, $common_values_map: ident) => { #[derive(Eq, PartialEq)] struct $CommonOrdered { x: T, frequency: usize, } impl PartialOrd for $CommonOrdered { fn partial_cmp(&self, other: &$CommonOrdered) -> Option { Some(self.cmp(other)) } } impl Ord for $CommonOrdered { fn cmp(&self, other: &$CommonOrdered) -> Ordering { other.frequency.cmp(&self.frequency).then_with(|| { let x = self.x.$to_string(); let y = other.x.$to_string(); x.len().cmp(&y.len()).then_with(|| x.cmp(&y)) }) } } /// Takes the first `limit` values of an iterator `xs`. Groups them into (unique value, /// frequency) pairs. Takes the top `n` pairs, preferring ones with high frequency. To break /// ties, prefers values with low `$to_string` representations, where the strings are /// shortlex-ordered (ordered by length, then lexicographically). pub fn $common_values_map( limit: usize, n: usize, xs: I, ) -> Vec<(I::Item, usize)> where I::Item: $StringTrait + Eq + Hash, { assert_ne!(n, 0); let mut frequencies: HashMap = HashMap::new(); for x in xs.take(limit) { *frequencies.entry(x).or_insert(0) += 1; } let mut top_n = BinaryHeap::new(); let mut full = false; for (x, frequency) in frequencies { top_n.push($CommonOrdered { x, frequency }); if full { top_n.pop(); } else if top_n.len() == n { full = true; } } let mut common_values = Vec::new(); while let Some(pair) = top_n.pop() { common_values.push((pair.x, pair.frequency)); } common_values.reverse(); common_values } }; } impl_common_values_map!(CommonOrdered, Display, to_string, common_values_map); impl_common_values_map!( CommonOrderedDebug, Debug, to_debug_string, common_values_map_debug ); malachite-base-0.4.16/src/test_util/stats/median.rs000064400000000000000000000146621046102023000203300ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::basic::integers::PrimitiveInt; use crate::num::basic::signeds::PrimitiveSigned; use crate::test_util::stats::moments::CheckedToF64; pub const fn uniform_bool_median(min: bool, max: bool) -> (bool, Option) { if min == max { (min, None) } else { (false, Some(true)) } } pub fn uniform_primitive_int_median(min: T, max: T) -> (T, Option) { let mut mean = min.wrapping_add(max); mean >>= 1; if mean < min || mean > max { mean.flip_bit(T::WIDTH - 1); } if min.even() == max.even() { (mean, None) } else { (mean, Some(mean + T::ONE)) } } pub fn deleted_uniform_primitive_int_median( min: T, max: T, deleted: T, ) -> (T, Option) { let (mut lo, mut hi) = uniform_primitive_int_median(min, max - T::ONE); if lo >= deleted { lo += T::ONE; } if let Some(hi) = hi.as_mut() { if *hi >= deleted { *hi += T::ONE; } } (lo, hi) } fn binary_search_median f64, C: Fn(T) -> f64>( mut min: T, mut max: T, pmf: P, cdf: C, ) -> (T, Option) { let initial_median; loop { if min == max { initial_median = Some(min); break; } let mut mean = min.wrapping_add(max); mean >>= 1; if mean < min || mean > max { mean.flip_bit(T::WIDTH - 1); } if 1.0 - cdf(mean) > 0.5 { min = mean + T::ONE; } else if cdf(max) - pmf(max) > 0.5 { max = mean; } else { initial_median = Some(mean); break; } } let mut first_median = initial_median.unwrap(); let mut first_good = false; while 1.0 - cdf(first_median) <= 0.5 && cdf(first_median) - pmf(first_median) <= 0.5 { first_good = true; first_median.wrapping_sub_assign(T::ONE); } assert!(first_good, "could not find median"); first_median.wrapping_add_assign(T::ONE); let mut last_median = first_median.wrapping_add(T::ONE); while 1.0 - cdf(last_median) <= 0.5 && cdf(last_median) - pmf(last_median) <= 0.5 { last_median.wrapping_add_assign(T::ONE); } last_median.wrapping_sub_assign(T::ONE); if first_median == last_median { (first_median, None) } else { (first_median, Some(last_median)) } } fn truncated_geometric_pmf(m: f64, unadjusted_mean: f64, n: f64) -> f64 { if n >= 0.0 && m >= n { let p = 1.0 / (unadjusted_mean + 1.0); let q = 1.0 - p; (q.powf(n) * p) / (1.0 - q.powf(1.0 + m)) } else { 0.0 } } fn truncated_geometric_cdf(m: f64, unadjusted_mean: f64, n: f64) -> f64 { let p = 1.0 / (unadjusted_mean + 1.0); if n < 0.0 { 0.0 } else if n <= m { let q = 1.0 - p; (1.0 - q.powf(1.0 + n)) / (1.0 - q.powf(1.0 + m)) } else { 1.0 } } pub fn truncated_geometric_median( min: T, max: T, unadjusted_mean: f64, ) -> (T, Option) { assert!(min >= T::ZERO); assert!(min <= max); let min_64 = min.checked_to_f64(); let max_64 = max.checked_to_f64() - min_64; let unadjusted_mean = unadjusted_mean - min_64; binary_search_median( min, max, |n| truncated_geometric_pmf(max_64, unadjusted_mean, n.checked_to_f64() - min_64), |n| truncated_geometric_cdf(max_64, unadjusted_mean, n.checked_to_f64() - min_64), ) } fn double_nonzero_geometric_pmf(a: f64, b: f64, unadjusted_mean: f64, n: f64) -> f64 { if n == 0.0 || n > a || n < -b { 0.0 } else { let p = 1.0 / (unadjusted_mean + 1.0); let q = 1.0 - p; q.powf(-1.0 + n.abs()) * p / (2.0 - q.powf(a) - q.powf(b)) } } fn double_nonzero_geometric_cdf(a: f64, b: f64, unadjusted_mean: f64, n: f64) -> f64 { if n < -b { return 0.0; } else if n >= a { return 1.0; } let p = 1.0 / (unadjusted_mean + 1.0); let q = 1.0 - p; let d = 2.0 - q.powf(a) - q.powf(b); if n == -b { q.powf(-1.0 + b) * p / d } else if n < 0.0 { (1.0 - q.powf(1.0 + b + n)) * q.powf(-1.0 - n) / d } else { (2.0 - q.powf(b) - q.powf(n)) / d } } pub fn double_nonzero_geometric_median( min: T, max: T, unadjusted_mean: f64, ) -> (T, Option) { assert!(min < T::ZERO); assert!(max > T::ZERO); let min_64 = -min.checked_to_f64(); let max_64 = max.checked_to_f64(); binary_search_median( min, max, |n| double_nonzero_geometric_pmf(max_64, min_64, unadjusted_mean, n.checked_to_f64()), |n| double_nonzero_geometric_cdf(max_64, min_64, unadjusted_mean, n.checked_to_f64()), ) } fn double_geometric_pmf(a: f64, b: f64, unadjusted_mean: f64, n: f64) -> f64 { if n > a || n < -b { 0.0 } else { let p = 1.0 / (unadjusted_mean + 1.0); let q = 1.0 - p; let qpa = q.powf(a); q.powf(n.abs()) * p / (2.0 - qpa - q.powf(1.0 + b) - p + qpa * p) } } fn double_geometric_cdf(a: f64, b: f64, unadjusted_mean: f64, n: f64) -> f64 { if n < -b { return 0.0; } else if n >= a { return 1.0; } let p = 1.0 / (unadjusted_mean + 1.0); let q = 1.0 - p; let qpa = q.powf(a); let qpb = q.powf(b); let d = 2.0 - qpa - q.powf(1.0 + b) - p + qpa * p; if n == -b { qpb * p / d } else if n <= 0.0 { (1.0 - q.powf(1.0 + b + n)) * q.powf(-n) / d } else { (2.0 - qpb - q.powf(1.0 + n) - p + qpb * p) / d } } pub fn double_geometric_median( min: T, max: T, unadjusted_mean: f64, ) -> (T, Option) { assert!(min < T::ZERO); assert!(max > T::ZERO); let min_64 = -min.checked_to_f64(); let max_64 = max.checked_to_f64(); binary_search_median( min, max, |n| double_geometric_pmf(max_64, min_64, unadjusted_mean, n.checked_to_f64()), |n| double_geometric_cdf(max_64, min_64, unadjusted_mean, n.checked_to_f64()), ) } malachite-base-0.4.16/src/test_util/stats/mod.rs000064400000000000000000000021061046102023000176400ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::Parity; use itertools::Itertools; pub fn median(xs: I) -> (I::Item, Option) where I::Item: Eq + Ord, { let mut xs = xs.collect_vec(); assert!(!xs.is_empty()); xs.sort_unstable(); let n = xs.len(); let half_n = n >> 1; if n.even() { // swap-remove m_2 first because if n == 2 it's the last element of the list. let m_2 = xs.swap_remove(half_n); let m_1 = xs.swap_remove(half_n - 1); if m_1 == m_2 { (m_1, None) } else { (m_1, Some(m_2)) } } else { (xs.swap_remove(half_n), None) } } pub mod common_values_map; pub mod median; pub mod moments; malachite-base-0.4.16/src/test_util/stats/moments.rs000064400000000000000000000650361046102023000205560ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::arithmetic::traits::{SaturatingAbs, UnsignedAbs}; use crate::num::basic::integers::PrimitiveInt; use crate::num::basic::signeds::PrimitiveSigned; use crate::num::basic::traits::Zero; use crate::num::basic::unsigneds::PrimitiveUnsigned; use crate::num::conversion::traits::WrappingFrom; use crate::num::float::NiceFloat; use crate::test_util::stats::common_values_map::common_values_map; use crate::test_util::stats::median; use crate::test_util::stats::median::{ deleted_uniform_primitive_int_median, double_geometric_median, double_nonzero_geometric_median, truncated_geometric_median, uniform_bool_median, uniform_primitive_int_median, }; use itertools::Itertools; use std::fmt::{self, Debug, Formatter}; // Panics if the input exceeds the finite range of f64. pub trait CheckedToF64 { fn checked_to_f64(&self) -> f64; } macro_rules! impl_checked_to_f64_for_primitive_ints { ($t: ident) => { impl CheckedToF64 for $t { #[allow(clippy::cast_lossless)] #[inline] fn checked_to_f64(&self) -> f64 { // No primitive integer type, not even u128 and i128, exceeds the finite range of // f64. *self as f64 } } }; } apply_to_primitive_ints!(impl_checked_to_f64_for_primitive_ints); impl CheckedToF64 for bool { #[inline] fn checked_to_f64(&self) -> f64 { if *self { 1.0 } else { 0.0 } } } impl CheckedToF64 for f32 { #[inline] fn checked_to_f64(&self) -> f64 { f64::from(*self) } } impl CheckedToF64 for f64 { #[inline] fn checked_to_f64(&self) -> f64 { *self } } #[derive(Copy, Clone, Eq, PartialEq)] pub struct MomentStats { pub mean: NiceFloat, pub standard_deviation: NiceFloat, pub skewness: NiceFloat, pub excess_kurtosis: NiceFloat, } impl Debug for MomentStats { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_fmt(format_args!( "MomentStats {{ mean: NiceFloat({}), standard_deviation: NiceFloat({}), \ skewness: NiceFloat({}), excess_kurtosis: NiceFloat({}) }}", self.mean, self.standard_deviation, self.skewness, self.excess_kurtosis )) } } // From https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance #[allow(clippy::suspicious_operation_groupings)] pub fn moment_stats(xs: I) -> MomentStats where I::Item: CheckedToF64, { let mut n: usize = 1; let mut m = 0.0; let mut m_2 = 0.0; let mut m_3 = 0.0; let mut m_4 = 0.0; for x in xs { let d = x.checked_to_f64() - m; let nf = n.checked_to_f64(); let d_n = d / nf; let d_n_2 = d_n * d_n; let d_n_3 = d_n_2 * d_n; let m_4_1 = (nf - 1.0) * (nf * nf - 3.0 * nf + 3.0) * d_n_3 * d; let m_4_2 = m_2 * d_n_2 * 6.0; let m_4_3 = m_3 * d_n * 4.0; m_4 += m_4_1 + m_4_2 - m_4_3; let m_3_1 = (nf - 1.0) * (nf - 2.0) * d_n_2 * d; let m_3_2 = m_2 * d_n * 3.0; m_3 += m_3_1 - m_3_2; m_2 += (nf - 1.0) * d_n * d; m += d_n; n += 1; } n -= 1; let nf = n.checked_to_f64(); let mean = m; let standard_deviation = (m_2 / (nf - 1.0)).sqrt(); let sqrt_m_2 = m_2.sqrt(); let skewness = m_3 * nf.sqrt() / (sqrt_m_2 * sqrt_m_2 * sqrt_m_2); let excess_kurtosis = m_4 * nf / (m_2 * m_2) - 3.0; MomentStats { mean: NiceFloat(mean), standard_deviation: NiceFloat(standard_deviation), skewness: NiceFloat(skewness), excess_kurtosis: NiceFloat(excess_kurtosis), } } pub const NAN_MOMENT_STATS: MomentStats = MomentStats { mean: NiceFloat(f64::NAN), standard_deviation: NiceFloat(f64::NAN), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; pub fn mean(xs: I) -> NiceFloat where I::Item: CheckedToF64, { let mut n: usize = 1; let mut m = 0.0; for x in xs { let d_n = (x.checked_to_f64() - m) / n.checked_to_f64(); m += d_n; n += 1; } NiceFloat(m) } fn moment_stats_from_raw_moments( mean: f64, p_2_mean: f64, p_3_mean: f64, p_4_mean: f64, ) -> MomentStats { let mean_2 = mean * mean; let mean_3 = mean_2 * mean; let mean_4 = mean_2 * mean_2; let variance = p_2_mean - mean_2; let standard_deviation = variance.sqrt(); let mu_3 = p_3_mean - 3.0 * mean * p_2_mean + 2.0 * mean_3; let mu_4 = p_4_mean - 4.0 * mean * p_3_mean + 6.0 * mean_2 * p_2_mean - 3.0 * mean_4; MomentStats { mean: NiceFloat(mean), standard_deviation: NiceFloat(standard_deviation), skewness: NiceFloat(mu_3 / (variance * standard_deviation)), excess_kurtosis: NiceFloat(mu_4 / (variance * variance) - 3.0), } } #[inline] fn pop_uniform_mean(a: &T, b: &T) -> f64 { (a.checked_to_f64() + b.checked_to_f64()) / 2.0 } fn pop_uniform_standard_deviation(a: &T, b: &T) -> f64 { let a = a.checked_to_f64(); let b = b.checked_to_f64(); let n = b - a + 1.0; ((n * n - 1.0) / 12.0).sqrt() } fn pop_uniform_skewness(a: &T, b: &T) -> f64 { let a = a.checked_to_f64(); let b = b.checked_to_f64(); if a == b { f64::NAN } else { 0.0 } } fn pop_uniform_excess_kurtosis(a: &T, b: &T) -> f64 { let a = a.checked_to_f64(); let b = b.checked_to_f64(); if a == b { f64::NAN } else { let n = b - a + 1.0; let n_squared = n * n; 6.0 / 5.0 * (-1.0 - 2.0 / (-1.0 + n_squared)) } } pub fn pop_disc_uniform_dist_moment_stats(a: &T, b: &T) -> MomentStats { MomentStats { mean: NiceFloat(pop_uniform_mean(a, b)), standard_deviation: NiceFloat(pop_uniform_standard_deviation(a, b)), skewness: NiceFloat(pop_uniform_skewness(a, b)), excess_kurtosis: NiceFloat(pop_uniform_excess_kurtosis(a, b)), } } pub fn uniform_bool_assertions>( xs: I, a: bool, b: bool, expected_values: &[bool], expected_common_values: &[(bool, usize)], expected_pop_median: (bool, Option), expected_sample_median: (bool, Option), expected_pop_moment_stats: MomentStats, expected_sample_moment_stats: MomentStats, ) { let actual_values = xs.clone().take(20).collect_vec(); let actual_common_values = common_values_map(1000000, 10, xs.clone()); let actual_sample_median = median(xs.clone().take(1000000)); let actual_sample_moment_stats = moment_stats(xs.take(1000000)); assert_eq!( ( actual_values.as_slice(), actual_common_values.as_slice(), uniform_bool_median(a, b), actual_sample_median, pop_disc_uniform_dist_moment_stats(&a, &b), actual_sample_moment_stats ), ( expected_values, expected_common_values, expected_pop_median, expected_sample_median, expected_pop_moment_stats, expected_sample_moment_stats ) ); } pub fn uniform_primitive_int_assertions( xs: I, a: I::Item, b: I::Item, expected_values: &[I::Item], expected_common_values: &[(I::Item, usize)], expected_pop_median: (I::Item, Option), expected_sample_median: (I::Item, Option), expected_pop_moment_stats: MomentStats, expected_sample_moment_stats: MomentStats, ) where I::Item: CheckedToF64 + PrimitiveInt, { let actual_values = xs.clone().take(20).collect_vec(); let actual_common_values = common_values_map(1000000, 10, xs.clone()); let actual_sample_median = median(xs.clone().take(1000000)); let actual_sample_moment_stats = moment_stats(xs.take(1000000)); assert_eq!( ( actual_values.as_slice(), actual_common_values.as_slice(), uniform_primitive_int_median(a, b), actual_sample_median, pop_disc_uniform_dist_moment_stats(&a, &b), actual_sample_moment_stats ), ( expected_values, expected_common_values, expected_pop_median, expected_sample_median, expected_pop_moment_stats, expected_sample_moment_stats ) ); } fn pop_deleted_disc_uniform_dist_mean(a: &T, b: &T, c: &T) -> f64 { let a = a.checked_to_f64(); let b = b.checked_to_f64(); let c = c.checked_to_f64(); (a - a * a + b + b * b - 2.0 * c) / (2.0 * (b - a)) } fn pop_deleted_disc_uniform_dist_2_mean(a: &T, b: &T, c: &T) -> f64 { let a = a.checked_to_f64(); let b = b.checked_to_f64(); let c = c.checked_to_f64(); let a_2 = a * a; let a_3 = a_2 * a; (a - 3.0 * a_2 + 2.0 * a_3 - b * (1.0 + b) * (1.0 + 2.0 * b) + 6.0 * c * c) / (6.0 * (a - b)) } fn pop_deleted_disc_uniform_dist_3_mean(a: &T, b: &T, c: &T) -> f64 { let a = a.checked_to_f64(); let b = b.checked_to_f64(); let c = c.checked_to_f64(); let a_2 = a * a; let b_2 = b * b; let a_m_1 = a - 1.0; let b_p_1 = b + 1.0; (a_m_1 * a_m_1 * a_2 - b_2 * b_p_1 * b_p_1 + 4.0 * c * c * c) / (4.0 * (a - b)) } fn pop_deleted_disc_uniform_dist_4_mean(a: &T, b: &T, c: &T) -> f64 { let a = a.checked_to_f64(); let b = b.checked_to_f64(); let c = c.checked_to_f64(); let a_2 = a * a; let a_3 = a_2 * a; let a_4 = a_2 * a_2; let a_5 = a_3 * a_2; let b_2 = b * b; let b_3 = b_2 * b; let b_4 = b_2 * b_2; let b_5 = b_3 * b_2; let c_2 = c * c; (-a + 10.0 * a_3 - 15.0 * a_4 + 6.0 * a_5 + b - 10.0 * b_3 - 15.0 * b_4 - 6.0 * b_5 + 30.0 * c_2 * c_2) / (30.0 * (a - b)) } fn deleted_uniform_primitive_int_moment_stats( a: &T, b: &T, c: &T, ) -> MomentStats { assert!(a <= c); assert!(c <= b); moment_stats_from_raw_moments( pop_deleted_disc_uniform_dist_mean(a, b, c), pop_deleted_disc_uniform_dist_2_mean(a, b, c), pop_deleted_disc_uniform_dist_3_mean(a, b, c), pop_deleted_disc_uniform_dist_4_mean(a, b, c), ) } pub fn deleted_uniform_primitive_int_assertions( xs: I, a: I::Item, b: I::Item, c: I::Item, expected_values: &[I::Item], expected_common_values: &[(I::Item, usize)], expected_pop_median: (I::Item, Option), expected_sample_median: (I::Item, Option), expected_pop_moment_stats: MomentStats, expected_sample_moment_stats: MomentStats, ) where I::Item: CheckedToF64 + PrimitiveInt, { let actual_values = xs.clone().take(20).collect_vec(); let actual_common_values = common_values_map(1000000, 10, xs.clone()); let actual_sample_median = median(xs.clone().take(1000000)); let actual_sample_moment_stats = moment_stats(xs.take(1000000)); assert_eq!( ( actual_values.as_slice(), actual_common_values.as_slice(), deleted_uniform_primitive_int_median(a, b, c), actual_sample_median, deleted_uniform_primitive_int_moment_stats(&a, &b, &c), actual_sample_moment_stats ), ( expected_values, expected_common_values, expected_pop_median, expected_sample_median, expected_pop_moment_stats, expected_sample_moment_stats ) ); } // unadjusted_mean is what the mean would be if the distribution were not truncated. fn pop_truncated_geometric_dist_mean(max: f64, unadjusted_mean: f64) -> f64 { let m = max; let p = 1.0 / (unadjusted_mean + 1.0); let q = 1.0 - p; (q - q.powf(m) * q * (1.0 + m * p)) / (p - q.powf(1.0 + m) * p) } fn pop_truncated_geometric_dist_2_mean(max: f64, unadjusted_mean: f64) -> f64 { let m = max; let p = 1.0 / (unadjusted_mean + 1.0); let q = 1.0 - p; let p_2 = p * p; (2.0 - 3.0 * p + p_2 - q.powf(m) * q * (2.0 + p * (-1.0 + m * (2.0 + m * p)))) / ((1.0 - q.powf(1.0 + m)) * p_2) } fn pop_truncated_geometric_dist_3_mean(max: f64, unadjusted_mean: f64) -> f64 { let m = max; let p = 1.0 / (unadjusted_mean + 1.0); let q = 1.0 - p; let p_2 = p * p; let p_3 = p_2 * p; (6.0 - 12.0 * p + 7.0 * p_2 - p_3 - q.powf(m) * q * (6.0 + p * (-6.0 + p + m * (6.0 + p * (-3.0 + m * (3.0 + m * p)))))) / ((1.0 - q.powf(1.0 + m)) * p_3) } fn pop_truncated_geometric_dist_4_mean(max: f64, unadjusted_mean: f64) -> f64 { let m = max; let p = 1.0 / (unadjusted_mean + 1.0); let q = 1.0 - p; let m_2 = m * m; let m_4 = m_2 * m_2; let p_2 = p * p; let p_3 = p_2 * p; let p_4 = p_2 * p_2; (1.0 / ((1.0 - q.powf(1.0 + m)) * p_4)) * (24.0 - 60.0 * p + 50.0 * p_2 - 15.0 * p_3 + p_4 - q.powf(m) * q * (24.0 + p * (-36.0 + 24.0 * m + 2.0 * (7.0 + 6.0 * (-2.0 + m) * m) * p + (-1.0 + 2.0 * m * (2.0 + m * (-3.0 + 2.0 * m))) * p_2 + m_4 * p_3))) } fn pop_truncated_geometric_dist_moment_stats( min: f64, max: f64, unadjusted_mean: f64, ) -> MomentStats { assert!(min <= max); assert!(min <= unadjusted_mean); // unadjusted_mean may be arbitrarily large let unadjusted_mean = unadjusted_mean - min; let max = max - min; let mut stats = moment_stats_from_raw_moments( pop_truncated_geometric_dist_mean(max, unadjusted_mean), pop_truncated_geometric_dist_2_mean(max, unadjusted_mean), pop_truncated_geometric_dist_3_mean(max, unadjusted_mean), pop_truncated_geometric_dist_4_mean(max, unadjusted_mean), ); stats.mean = NiceFloat(stats.mean.0 + min); stats } pub fn truncated_geometric_dist_assertions( xs: I, min: I::Item, max: I::Item, um_numerator: u64, um_denominator: u64, expected_values: &[I::Item], expected_common_values: &[(I::Item, usize)], expected_pop_median: (I::Item, Option), expected_sample_median: (I::Item, Option), expected_pop_moment_stats: MomentStats, expected_sample_moment_stats: MomentStats, ) where I::Item: CheckedToF64 + PrimitiveInt, { let min_64 = min.checked_to_f64(); let max_64 = max.checked_to_f64(); let unadjusted_mean = um_numerator as f64 / um_denominator as f64; let actual_values = xs.clone().take(20).collect_vec(); let actual_common_values = common_values_map(1000000, 10, xs.clone()); let actual_sample_median = median(xs.clone().take(1000000)); let actual_sample_moment_stats = moment_stats(xs.take(1000000)); assert_eq!( ( actual_values.as_slice(), actual_common_values.as_slice(), truncated_geometric_median(min, max, unadjusted_mean), actual_sample_median, pop_truncated_geometric_dist_moment_stats(min_64, max_64, unadjusted_mean), actual_sample_moment_stats ), ( expected_values, expected_common_values, expected_pop_median, expected_sample_median, expected_pop_moment_stats, expected_sample_moment_stats ) ); } pub fn negative_truncated_geometric_dist_assertions< I: Clone + Iterator, S: CheckedToF64 + PrimitiveSigned + UnsignedAbs + WrappingFrom, U: CheckedToF64 + PrimitiveUnsigned, >( xs: I, abs_min: S, abs_max: S, abs_um_numerator: u64, abs_um_denominator: u64, expected_values: &[S], expected_common_values: &[(S, usize)], expected_pop_median: (S, Option), expected_sample_median: (S, Option), expected_pop_moment_stats: MomentStats, expected_sample_moment_stats: MomentStats, ) { let abs_min_64 = -abs_min.checked_to_f64(); let abs_max_64 = -abs_max.checked_to_f64(); let abs_unadjusted_mean = abs_um_numerator as f64 / abs_um_denominator as f64; let actual_values = xs.clone().take(20).collect_vec(); let actual_common_values = common_values_map(1000000, 10, xs.clone()); let actual_sample_median = median(xs.clone().take(1000000)); let actual_sample_moment_stats = moment_stats(xs.take(1000000)); let mut pop_sample_moment_stats = pop_truncated_geometric_dist_moment_stats(abs_min_64, abs_max_64, abs_unadjusted_mean); pop_sample_moment_stats.mean = NiceFloat(-pop_sample_moment_stats.mean.0); pop_sample_moment_stats.skewness = NiceFloat(-pop_sample_moment_stats.skewness.0); let (x, y) = truncated_geometric_median( abs_min.unsigned_abs(), abs_max.unsigned_abs(), abs_unadjusted_mean, ); let (x, y) = y.map_or((S::wrapping_from(x.wrapping_neg()), None), |y| { ( S::wrapping_from(y.wrapping_neg()), Some(S::wrapping_from(x.wrapping_neg())), ) }); assert_eq!( ( actual_values.as_slice(), actual_common_values.as_slice(), (x, y), actual_sample_median, pop_sample_moment_stats, actual_sample_moment_stats ), ( expected_values, expected_common_values, expected_pop_median, expected_sample_median, expected_pop_moment_stats, expected_sample_moment_stats ) ); } fn pop_double_nonzero_truncated_geometric_dist_mean(b: f64, a: f64, unadjusted_mean: f64) -> f64 { let p = 1.0 / (unadjusted_mean + 1.0); let q = 1.0 - p; let qpa = q.powf(a); let qpb = q.powf(b); (qpa * (1.0 + a * p) - qpb * (1.0 + b * p)) / ((-2.0 + qpa + qpb) * p) } fn pop_double_nonzero_truncated_geometric_dist_2_mean(b: f64, a: f64, unadjusted_mean: f64) -> f64 { let p = 1.0 / (unadjusted_mean + 1.0); let q = 1.0 - p; let qpa = q.powf(a); let qpb = q.powf(b); (2.0 + (p * (2.0 - qpa + a * qpa * (2.0 + a * p) + qpb * (-1.0 + b * (2.0 + b * p)))) / (-2.0 + qpa + qpb)) / (p * p) } fn pop_double_nonzero_truncated_geometric_dist_3_mean(b: f64, a: f64, unadjusted_mean: f64) -> f64 { let p = 1.0 / (unadjusted_mean + 1.0); let q = 1.0 - p; let qpa = q.powf(a); let qpb = q.powf(b); (qpa * (6.0 + p * (-6.0 + p + a * (6.0 + p * (-3.0 + a * (3.0 + a * p))))) - qpb * (6.0 + p * (-6.0 + p + b * (6.0 + p * (-3.0 + b * (3.0 + b * p)))))) / ((-2.0 + qpa + qpb) * p * p * p) } fn pop_double_nonzero_truncated_geometric_dist_4_mean(b: f64, a: f64, unadjusted_mean: f64) -> f64 { let p = 1.0 / (unadjusted_mean + 1.0); let q = 1.0 - p; let a_2 = a * a; let a_3 = a_2 * a; let a_4 = a_2 * a_2; let b_2 = b * b; let b_4 = b_2 * b_2; let p_2 = p * p; let p_3 = p_2 * p; let p_4 = p_2 * p_2; let qpa = q.powf(a); let qpb = q.powf(b); 1.0 / p_4 * (24.0 + 1.0 / (-2.0 + qpa + qpb) * p * (-6.0 * a_2 * qpa * (-2.0 + p) * p + 4.0 * a_3 * qpa * p_2 + a_4 * qpa * p_3 - (-2.0 + qpa) * (36.0 + (-14.0 + p) * p) + 4.0 * a * qpa * (6.0 + (-6.0 + p) * p) + qpb * (-36.0 + 24.0 * b + 2.0 * (7.0 + 6.0 * (-2.0 + b) * b) * p + (-1.0 + 2.0 * b * (2.0 + b * (-3.0 + 2.0 * b))) * p_2 + b_4 * p_3))) } fn pop_double_nonzero_truncated_geometric_dist_moment_stats( min: f64, max: f64, unadjusted_mean: f64, ) -> MomentStats { assert!(min < 0.0); assert!(max > 0.0); assert!(unadjusted_mean > 1.0); // unadjusted_mean may be arbitrarily large moment_stats_from_raw_moments( pop_double_nonzero_truncated_geometric_dist_mean(-min, max, unadjusted_mean - 1.0), pop_double_nonzero_truncated_geometric_dist_2_mean(-min, max, unadjusted_mean - 1.0), pop_double_nonzero_truncated_geometric_dist_3_mean(-min, max, unadjusted_mean - 1.0), pop_double_nonzero_truncated_geometric_dist_4_mean(-min, max, unadjusted_mean - 1.0), ) } pub fn double_nonzero_truncated_geometric_dist_assertions( xs: I, min: I::Item, max: I::Item, um_numerator: u64, um_denominator: u64, expected_values: &[I::Item], expected_common_values: &[(I::Item, usize)], expected_abs_mean: NiceFloat, expected_pop_median: (I::Item, Option), expected_sample_median: (I::Item, Option), expected_pop_moment_stats: MomentStats, expected_sample_moment_stats: MomentStats, ) where I::Item: CheckedToF64 + PrimitiveSigned, { let min_64 = min.checked_to_f64(); let max_64 = max.checked_to_f64(); let unadjusted_mean = um_numerator as f64 / um_denominator as f64; let actual_values = xs.clone().take(20).collect_vec(); let actual_common_values = common_values_map(1000000, 10, xs.clone()); let actual_abs_mean = mean(xs.clone().map(SaturatingAbs::saturating_abs).take(1000000)); let actual_sample_median = median(xs.clone().take(1000000)); let actual_sample_moment_stats = moment_stats(xs.take(1000000)); assert_eq!( ( actual_values.as_slice(), actual_common_values.as_slice(), actual_abs_mean, double_nonzero_geometric_median(min, max, unadjusted_mean), actual_sample_median, pop_double_nonzero_truncated_geometric_dist_moment_stats( min_64, max_64, unadjusted_mean, ), actual_sample_moment_stats ), ( expected_values, expected_common_values, expected_abs_mean, expected_pop_median, expected_sample_median, expected_pop_moment_stats, expected_sample_moment_stats ) ); } fn pop_double_truncated_geometric_dist_mean(b: f64, a: f64, unadjusted_mean: f64) -> f64 { let p = 1.0 / (unadjusted_mean + 1.0); let q = 1.0 - p; let qpa = q.powf(a); q * (qpa * (1.0 + a * p) - q.powf(b) * (1.0 + b * p)) / (p * (-2.0 + qpa + q.powf(1.0 + b) + p - qpa * p)) } #[allow(clippy::suspicious_operation_groupings)] fn pop_double_truncated_geometric_dist_2_mean(b: f64, a: f64, unadjusted_mean: f64) -> f64 { let p = 1.0 / (unadjusted_mean + 1.0); let q = 1.0 - p; let qpa = q.powf(a); let qpb = q.powf(b); q * (2.0 * (-2.0 + qpa + qpb) + p * (2.0 - qpa + a * qpa * (2.0 + a * p) + qpb * (-1.0 + b * (2.0 + b * p)))) / (p * p * (-2.0 + qpa + q.powf(1.0 + b) + p - qpa * p)) } fn pop_double_truncated_geometric_dist_3_mean(b: f64, a: f64, unadjusted_mean: f64) -> f64 { let p = 1.0 / (unadjusted_mean + 1.0); let q = 1.0 - p; let qpa = q.powf(a); let qpb = q.powf(b); q * (qpa * (6.0 + p * (-6.0 + p + a * (6.0 + p * (-3.0 + a * (3.0 + a * p))))) - qpb * (6.0 + p * (-6.0 + p + b * (6.0 + p * (-3.0 + b * (3.0 + b * p)))))) / (p * p * p * (-2.0 + qpa + q.powf(1.0 + b) + p - qpa * p)) } fn pop_double_truncated_geometric_dist_4_mean(b: f64, a: f64, unadjusted_mean: f64) -> f64 { let p = 1.0 / (unadjusted_mean + 1.0); let q = 1.0 - p; let qpa = q.powf(a); let qpb = q.powf(b); let a_2 = a * a; let a_3 = a_2 * a; let a_4 = a_2 * a_2; let b_2 = b * b; let b_4 = b_2 * b_2; let p_2 = p * p; let p_3 = p_2 * p; let p_4 = p_2 * p_2; q * (24.0 * (-2.0 + qpa + qpb) + p * (-6.0 * a_2 * qpa * (-2.0 + p) * p + 4.0 * a_3 * qpa * p_2 + a_4 * qpa * p_3 - (-2.0 + qpa) * (36.0 + (-14.0 + p) * p) + 4.0 * a * qpa * (6.0 + (-6.0 + p) * p) + qpb * (-36.0 + 24.0 * b + 2.0 * (7.0 + 6.0 * (-2.0 + b) * b) * p + (-1.0 + 2.0 * b * (2.0 + b * (-3.0 + 2.0 * b))) * p_2 + b_4 * p_3))) / (p_4 * (-2.0 + qpa + q.powf(1.0 + b) + p - qpa * p)) } fn pop_double_truncated_geometric_dist_moment_stats( min: f64, max: f64, unadjusted_mean: f64, ) -> MomentStats { assert!(min < 0.0); assert!(max > 0.0); assert!(unadjusted_mean > 0.0); // unadjusted_mean may be arbitrarily large moment_stats_from_raw_moments( pop_double_truncated_geometric_dist_mean(-min, max, unadjusted_mean), pop_double_truncated_geometric_dist_2_mean(-min, max, unadjusted_mean), pop_double_truncated_geometric_dist_3_mean(-min, max, unadjusted_mean), pop_double_truncated_geometric_dist_4_mean(-min, max, unadjusted_mean), ) } pub fn double_truncated_geometric_dist_assertions( xs: I, min: I::Item, max: I::Item, um_numerator: u64, um_denominator: u64, expected_values: &[I::Item], expected_common_values: &[(I::Item, usize)], expected_natural_mean: NiceFloat, expected_pop_median: (I::Item, Option), expected_sample_median: (I::Item, Option), expected_pop_moment_stats: MomentStats, expected_sample_moment_stats: MomentStats, ) where I::Item: CheckedToF64 + PrimitiveSigned, { let min_64 = min.checked_to_f64(); let max_64 = max.checked_to_f64(); let unadjusted_mean = um_numerator as f64 / um_denominator as f64; let actual_values = xs.clone().take(20).collect_vec(); let actual_common_values = common_values_map(1000000, 10, xs.clone()); let actual_natural_mean = mean(xs.clone().filter(|&x| x >= I::Item::ZERO).take(1000000)); let actual_sample_median = median(xs.clone().take(1000000)); let actual_sample_moment_stats = moment_stats(xs.take(1000000)); assert_eq!( ( actual_values.as_slice(), actual_common_values.as_slice(), actual_natural_mean, double_geometric_median(min, max, unadjusted_mean), actual_sample_median, pop_double_truncated_geometric_dist_moment_stats(min_64, max_64, unadjusted_mean), actual_sample_moment_stats ), ( expected_values, expected_common_values, expected_natural_mean, expected_pop_median, expected_sample_median, expected_pop_moment_stats, expected_sample_moment_stats ) ); } malachite-base-0.4.16/src/test_util/vecs/exhaustive/mod.rs000064400000000000000000000021101046102023000216220ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use std::fmt::Debug; pub fn exhaustive_vecs_helper_helper>>(xss: I, out: &[&[T]]) where T: Clone + Debug + Eq, { let xss = xss.take(20).collect_vec(); assert_eq!(xss.iter().map(Vec::as_slice).collect_vec().as_slice(), out); } pub fn exhaustive_vecs_small_helper_helper>>( xss: I, out_len: usize, out: &[&[T]], ) where T: Clone + Debug + Eq, { let xss_prefix = xss.clone().take(20).collect_vec(); assert_eq!( xss_prefix .iter() .map(Vec::as_slice) .collect_vec() .as_slice(), out ); assert_eq!(xss.count(), out_len); } malachite-base-0.4.16/src/test_util/vecs/mod.rs000064400000000000000000000006341046102023000174460ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . pub mod exhaustive; pub mod random; malachite-base-0.4.16/src/test_util/vecs/random/mod.rs000064400000000000000000000025341046102023000207270ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::test_util::stats::common_values_map::common_values_map_debug; use crate::test_util::stats::median; use itertools::Itertools; use std::fmt::Debug; use std::hash::Hash; pub fn random_vecs_helper_helper>>( xss: I, expected_values: &[&[T]], expected_common_values: &[(&[T], usize)], expected_median: (&[T], Option<&[T]>), ) where T: Clone + Debug + Eq + Hash + Ord, { let values = xss.clone().take(20).collect_vec(); let values = values.iter().map(Vec::as_slice).collect_vec(); let common_values = common_values_map_debug(1000000, 10, xss.clone()); let common_values = common_values .iter() .map(|(xs, f)| (xs.as_slice(), *f)) .collect_vec(); let (a, ob) = median(xss.take(1000000)); let median = (a.as_slice(), ob.as_deref()); assert_eq!( (values.as_slice(), common_values.as_slice(), median), (expected_values, expected_common_values, expected_median) ); } malachite-base-0.4.16/src/tuples/exhaustive.rs000064400000000000000000002715061046102023000174240ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::iterators::bit_distributor::{BitDistributor, BitDistributorOutputType}; use crate::iterators::iterator_cache::IteratorCache; use crate::num::arithmetic::traits::CheckedPow; use crate::num::conversion::traits::{ExactFrom, WrappingFrom}; use crate::num::logic::traits::SignificantBits; use crate::vecs::exhaustive::{ fixed_length_ordered_unique_indices_helper, next_bit_pattern, unique_indices, UniqueIndices, }; use alloc::vec; use alloc::vec::Vec; use core::cmp::max; use core::fmt::Debug; use core::iter::{once, Once}; use core::marker::PhantomData; use core::mem::take; /// Generates the only unit: `()`. /// /// The output length is 1. /// /// # Worst-case complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::tuples::exhaustive::exhaustive_units; /// /// assert_eq!(exhaustive_units().collect_vec(), &[()]); /// ``` pub fn exhaustive_units() -> Once<()> { once(()) } // hack for macro pub_test! { #[inline] clone_helper(x: &T, _i: usize) -> T { x.clone() }} /// Defines lexicographic tuple generators. /// /// Malachite provides [`lex_pairs`] and [`lex_pairs_from_single`], but you can also define /// `lex_triples`, `lex_quadruples`, and so on, and `lex_triples_from_single`, /// `lex_quadruples_from_single`, and so on, in your program using the code below. The documentation /// for [`lex_pairs`] and [`lex_pairs_from_single`] describes these other functions as well. /// /// See usage examples [here](self#lex_pairs) and [here](self#lex_pairs_from_single). /// /// ``` /// use malachite_base::iterators::iterator_cache::IteratorCache; /// use malachite_base::lex_tuples; /// /// fn clone_helper(x: &T, _i: usize) -> T { /// x.clone() /// } /// /// lex_tuples!( /// (pub(crate)), /// 3, /// LexTriples, /// LexTriplesFromSingle, /// lex_triples, /// lex_triples_from_single, /// (T, T, T), /// [0, X, I, xs, x], /// [1, Y, J, ys, y], /// [2, Z, K, zs, z] /// ); /// lex_tuples!( /// (pub(crate)), /// 4, /// LexQuadruples, /// LexQuadruplesFromSingle, /// lex_quadruples, /// lex_quadruples_from_single, /// (T, T, T, T), /// [0, X, I, xs, x], /// [1, Y, J, ys, y], /// [2, Z, K, zs, z], /// [3, W, L, ws, w] /// ); /// lex_tuples!( /// (pub(crate)), /// 5, /// LexQuintuples, /// LexQuintuplesFromSingle, /// lex_quintuples, /// lex_quintuples_from_single, /// (T, T, T, T, T), /// [0, X, I, xs, x], /// [1, Y, J, ys, y], /// [2, Z, K, zs, z], /// [3, W, L, ws, w], /// [4, V, M, vs, v] /// ); /// lex_tuples!( /// (pub(crate)), /// 6, /// LexSextuples, /// LexSextuplesFromSingle, /// lex_sextuples, /// lex_sextuples_from_single, /// (T, T, T, T, T, T), /// [0, X, I, xs, x], /// [1, Y, J, ys, y], /// [2, Z, K, zs, z], /// [3, W, L, ws, w], /// [4, V, M, vs, v], /// [5, U, N, us, u] /// ); /// lex_tuples!( /// (pub(crate)), /// 7, /// LexSeptuples, /// LexSeptuplesFromSingle, /// lex_septuples, /// lex_septuples_from_single, /// (T, T, T, T, T, T, T), /// [0, X, I, xs, x], /// [1, Y, J, ys, y], /// [2, Z, K, zs, z], /// [3, W, L, ws, w], /// [4, V, M, vs, v], /// [5, U, N, us, u], /// [6, T, O, ts, t] /// ); /// lex_tuples!( /// (pub(crate)), /// 8, /// LexOctuples, /// LexOctuplesFromSingle, /// lex_octuples, /// lex_octuples_from_single, /// (T, T, T, T, T, T, T, T), /// [0, X, I, xs, x], /// [1, Y, J, ys, y], /// [2, Z, K, zs, z], /// [3, W, L, ws, w], /// [4, V, M, vs, v], /// [5, U, N, us, u], /// [6, T, O, ts, t], /// [7, S, P, ss, s] /// ); /// ``` #[macro_export] macro_rules! lex_tuples { ( ($($vis:tt)*), $k: expr, $exhaustive_struct: ident, $exhaustive_struct_from_single: ident, $exhaustive_fn: ident, $exhaustive_fn_from_single: ident, $single_out: tt, $([$i: expr, $t: ident, $it: ident, $xs: ident, $x:ident]),* ) => { /// This documentation applies not only to `LexPairs`, but also to `LexTriples`, /// `LexQuadruples`, and so on. See `lex_tuples` for more information. /// /// Generates all $n$-tuples with elements from $n$ iterators, in lexicographic order. /// /// The order is lexicographic with respect to the order of the element iterators. #[derive(Clone, Debug)] $($vis)* struct $exhaustive_struct<$($t: Clone, $it: Iterator,)*> { first: bool, done: bool, $($xs: IteratorCache<$it>,)* counters: [usize; $k], } impl<$($t: Clone, $it: Iterator,)*> $exhaustive_struct<$($t, $it,)*> { fn increment_counters(&mut self) -> bool { for (i, counter) in self.counters.iter_mut().enumerate().rev() { *counter += 1; let no_carry = match i { $( $i => self.$xs.get(*counter).is_some(), )* _ => unreachable!(), }; if no_carry { return false; } else if i == 0 { return true; } *counter = 0; } false } } impl<$($t: Clone, $it: Iterator,)*> Iterator for $exhaustive_struct<$($t, $it,)*> { type Item = ($($t,)*); fn next(&mut self) -> Option { if self.done { None } else if self.first { self.first = false; $( let $x; )* $( if let Some(x) = self.$xs.get(0) { $x = x.clone(); } else { self.done = true; return None; } )* Some(($($x,)*)) } else if self.increment_counters() { self.done = true; None } else { Some(($(self.$xs.get(self.counters[$i]).unwrap().clone(),)*)) } } } /// This documentation applies not only to `lex_pairs`, but also to `lex_triples`, /// `lex_quadruples`, and so on. See [`lex_tuples`] for more information. /// /// Generates all $n$-tuples with elements from $n$ iterators, in lexicographic order. /// /// The order is lexicographic with respect to the order of the element iterators. /// /// All of `ys`, `zs`, ... (but not necessarily `xs`) must be finite. If `xs` is finite, the /// output length is the product of the lengths of all the input iterators. If `xs` is /// infinite, the output is also infinite. /// /// If any of `xs`, `ys`, `zs`, ... is empty, the output is also empty. /// /// # Examples /// See [here](self#lex_pairs). #[allow(dead_code)] $($vis)* const fn $exhaustive_fn<$($t: Clone, $it: Iterator,)*>( $($xs: $it,)* ) -> $exhaustive_struct<$($t, $it,)*> { $exhaustive_struct { first: true, done: false, $($xs: IteratorCache::new($xs),)* counters: [$($i * 0,)*], } } /// This documentation applies not only to `LexPairsFromSingle`, but also to /// `LexTriplesFromSingle`, `LexQuadruplesFromSingle`, and so on. See [`lex_tuples`] for /// more information. /// /// Generates all $n$-tuples with elements a single iterator, in lexicographic order. /// /// The order is lexicographic with respect to the order of the element iterator. #[derive(Clone, Debug)] $($vis)* struct $exhaustive_struct_from_single> { first: bool, done: bool, xs: IteratorCache, counters: [usize; $k], } impl> $exhaustive_struct_from_single { fn increment_counters(&mut self) -> bool { for (i, counter) in self.counters.iter_mut().enumerate().rev() { *counter += 1; if self.xs.get(*counter).is_some() { return false; } else if i == 0 { return true; } *counter = 0; } false } } impl> Iterator for $exhaustive_struct_from_single { type Item = $single_out; fn next(&mut self) -> Option<$single_out> { if self.done { None } else if self.first { self.first = false; if let Some(x) = self.xs.get(0) { Some(($(clone_helper(x, $i),)*)) } else { self.done = true; None } } else if self.increment_counters() { self.done = true; None } else { Some(($(self.xs.get(self.counters[$i]).unwrap().clone(),)*)) } } } /// This documentation applies not only to `lex_pairs_from_single`, but also to /// `lex_triples_from_single`, `lex_quadruples_from_single`, and so on. See [`lex_tuples`] /// for more information. /// /// Generates all $n$-tuples with elements from a single iterator, in lexicographic order. /// /// The order is lexicographic with respect to the order of the element iterator. /// /// `xs` must be finite. /// /// The output length is $k^n$, where $k$ is `xs.count()` and $n$ is `len`. /// /// If `xs` is empty, the output is also empty. /// /// # Examples /// See [here](self#lex_pairs_from_single). #[allow(dead_code)] $($vis)* const fn $exhaustive_fn_from_single>( xs: I ) -> $exhaustive_struct_from_single { $exhaustive_struct_from_single { first: true, done: false, xs: IteratorCache::new(xs), counters: [$($i * 0,)*], } } } } lex_tuples!( (pub), 2, LexPairs, LexPairsFromSingle, lex_pairs, lex_pairs_from_single, (T, T), [0, X, I, xs, x], [1, Y, J, ys, y] ); lex_tuples!( (pub(crate)), 4, LexQuadruples, LexQuadruplesFromSingle, lex_quadruples, lex_quadruples_from_single, (T, T, T, T), [0, X, I, xs, x], [1, Y, J, ys, y], [2, Z, K, zs, z], [3, W, L, ws, w] ); /// Defines custom lexicographic tuple generators. /// /// You can define custom tuple generators like `lex_triples_xxy` in your program using the code /// below. /// /// See usage examples [here](self#lex_triples_xxy). /// /// ``` /// use malachite_base::iterators::iterator_cache::IteratorCache; /// use malachite_base::lex_custom_tuples; /// /// fn unwrap_triple((a, b, c): (Option, Option, Option)) -> (X, Y, Z) { /// (a.unwrap(), b.unwrap(), c.unwrap()) /// } /// /// lex_custom_tuples! { /// (pub), /// LexTriplesXXY, /// (X, X, Y), /// (None, None, None), /// unwrap_triple, /// lex_triples_xxy, /// [X, I, xs, [0, x_0], [1, x_1]], /// [Y, J, ys, [2, y_2]] /// } /// lex_custom_tuples!( /// (pub), /// LexTriplesXYX, /// (X, Y, X), /// (None, None, None), /// unwrap_triple, /// lex_triples_xyx, /// [X, I, xs, [0, x_0], [2, x_2]], /// [Y, J, ys, [1, y_1]] /// ); /// lex_custom_tuples!( /// (pub), /// LexTriplesXYY, /// (X, Y, Y), /// (None, None, None), /// unwrap_triple, /// lex_triples_xyy, /// [X, I, xs, [0, x_0]], /// [Y, J, ys, [1, y_1], [2, y_2]] /// ); /// ``` #[macro_export] macro_rules! lex_custom_tuples { ( ($($vis:tt)*), $exhaustive_struct: ident, $out_t: ty, $nones: expr, $unwrap_tuple: ident, $exhaustive_fn: ident, $([$t: ident, $it: ident, $xs: ident, $([$i: tt, $x: ident]),*]),* ) => { // Generates all $n$-tuples with elements from $m$ iterators, where $m \leq n$, in // lexicographic order. // // The order is lexicographic with respect to the order of the element iterators. // // The mapping from iterators to tuple slots is indicated by the struct name; for example, // in `LexTriplesXYX` there are two iterators, `X`, and `Y`; `X` generates the elements in // the first and third slots of the output triples, and `Y` generates the elements in the // second slots. #[derive(Clone, Debug)] $($vis)* struct $exhaustive_struct<$($t: Clone, $it: Iterator,)*> { first: bool, done: bool, $($xs: IteratorCache<$it>,)* counters: Vec, } impl<$($t: Clone, $it: Iterator,)*> $exhaustive_struct<$($t, $it,)*> { fn increment_counters(&mut self) -> bool { for (i, counter) in self.counters.iter_mut().enumerate().rev() { *counter += 1; let no_carry = match i { $( $($i)|* => self.$xs.get(*counter).is_some(), )* _ => unreachable!(), }; if no_carry { return false; } else if i == 0 { return true; } *counter = 0; } false } } impl<$($t: Clone, $it: Iterator,)*> Iterator for $exhaustive_struct<$($t, $it,)*> { type Item = $out_t; fn next(&mut self) -> Option { if self.done { None } else if self.first { self.first = false; $($(let $x;)*)* $( if let Some(x) = self.$xs.get(0) { $($x = x.clone();)* } else { self.done = true; return None; } )* let mut out = $nones; $($(out.$i = Some($x);)*)* Some($unwrap_tuple(out)) } else if self.increment_counters() { self.done = true; None } else { let mut out = $nones; $($(out.$i = self.$xs.get(self.counters[$i]).cloned();)*)* Some($unwrap_tuple(out)) } } } // Generates all $n$-tuples with elements from $m$ iterators, where $m \leq n$, in // lexicographic order. // // The order is lexicographic with respect to the order of the element iterators. // // The mapping from iterators to tuple slots is indicated by the function name; for example, // `lex_triples_xyx` takes two iterators, `xs`, and `ys`; `xs` generates the elements in the // first and third slots of the output triples, and `ys` generates the elements in the // second slots. // // Let `xs` be the input iterator mapped to the first slot of the output tuples. All the // input iterators, except possibly `xs`, must be finite. If `xs` is finite, the output // length is the product of the lengths of all the input iterators. If `xs` is infinite, the // output is also infinite. // // If any of the input iterators is empty, the output is also empty. // // # Examples // See [here](self#lex_triples_xyx). $($vis)* fn $exhaustive_fn<$($t: Clone, $it: Iterator,)*>( $($xs: $it,)* ) -> $exhaustive_struct<$($t, $it,)*> { $exhaustive_struct { first: true, done: false, $($xs: IteratorCache::new($xs),)* counters: vec![$($(($i * 0),)*)*], } } } } /// Defines exhaustive tuple generators that generate tuples from a single iterator. /// /// Malachite provides [`exhaustive_pairs_from_single`] and [`exhaustive_pairs_1_input`], but you /// can also define `exhaustive_triples_from_single`, `exhaustive_quadruples_from_single`, and so /// on, and `exhaustive_triples_1_input`, `exhaustive_quadruples_1_input`, and so on, in your /// program using the code below. The documentation for [`exhaustive_pairs_from_single`] and /// [`exhaustive_pairs_1_input`] describes these other functions as well. /// /// See usage examples [here](self#exhaustive_pairs_from_single) and /// [here](self#exhaustive_pairs_1_input). /// /// ``` /// use malachite_base::exhaustive_tuples_1_input; /// use malachite_base::iterators::bit_distributor::{BitDistributor, BitDistributorOutputType}; /// use malachite_base::iterators::iterator_cache::IteratorCache; /// use malachite_base::num::arithmetic::traits::CheckedPow; /// use malachite_base::num::conversion::traits::{ExactFrom, WrappingFrom}; /// use malachite_base::num::logic::traits::SignificantBits; /// use std::cmp::max; /// use std::marker::PhantomData; /// /// exhaustive_tuples_1_input!( /// (pub(crate)), /// ExhaustiveTriples1Input, /// exhaustive_triples_1_input, /// exhaustive_triples_from_single, /// (I::Item, I::Item, I::Item), /// [0, output_type_x], /// [1, output_type_y], /// [2, output_type_z] /// ); /// exhaustive_tuples_1_input!( /// (pub(crate)), /// ExhaustiveQuadruples1Input, /// exhaustive_quadruples_1_input, /// exhaustive_quadruples_from_single, /// (I::Item, I::Item, I::Item, I::Item), /// [0, output_type_x], /// [1, output_type_y], /// [2, output_type_z], /// [3, output_type_w] /// ); /// exhaustive_tuples_1_input!( /// (pub(crate)), /// ExhaustiveQuintuples1Input, /// exhaustive_quintuples_1_input, /// exhaustive_quintuples_from_single, /// (I::Item, I::Item, I::Item, I::Item, I::Item), /// [0, output_type_x], /// [1, output_type_y], /// [2, output_type_z], /// [3, output_type_w], /// [4, output_type_v] /// ); /// exhaustive_tuples_1_input!( /// (pub(crate)), /// ExhaustiveSextuples1Input, /// exhaustive_sextuples_1_input, /// exhaustive_sextuples_from_single, /// (I::Item, I::Item, I::Item, I::Item, I::Item, I::Item), /// [0, output_type_x], /// [1, output_type_y], /// [2, output_type_z], /// [3, output_type_w], /// [4, output_type_v], /// [5, output_type_u] /// ); /// exhaustive_tuples_1_input!( /// (pub(crate)), /// ExhaustiveSeptuples1Input, /// exhaustive_septuples_1_input, /// exhaustive_septuples_from_single, /// ( /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item /// ), /// [0, output_type_x], /// [1, output_type_y], /// [2, output_type_z], /// [3, output_type_w], /// [4, output_type_v], /// [5, output_type_u], /// [6, output_type_t] /// ); /// exhaustive_tuples_1_input!( /// (pub(crate)), /// ExhaustiveOctuples1Input, /// exhaustive_octuples_1_input, /// exhaustive_octuples_from_single, /// ( /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item /// ), /// [0, output_type_x], /// [1, output_type_y], /// [2, output_type_z], /// [3, output_type_w], /// [4, output_type_v], /// [5, output_type_u], /// [6, output_type_t], /// [7, output_type_s] /// ); /// ``` #[macro_export] macro_rules! exhaustive_tuples_1_input { ( ($($vis:tt)*), $exhaustive_struct: ident, $exhaustive_fn: ident, $exhaustive_fn_from_single: ident, $out_type: ty, $([$i: tt, $out_x: ident]),* ) => { /// This documentation applies not only to `ExhaustivePairs1Input`, but also to /// `ExhaustiveTriples1Input`, `ExhaustiveQuadruples1Input`, and so on. See /// [`exhaustive_tuples_1_input`] for more information. /// /// Generates all $n$-tuples of a given length with elements from a single iterator. #[derive(Clone, Debug)] $($vis)* struct $exhaustive_struct where I::Item: Clone, { i: u64, limit: Option, distributor: BitDistributor, xs: IteratorCache, xs_done: bool, phantom: PhantomData<*const I::Item>, } impl Iterator for $exhaustive_struct where I::Item: Clone, { type Item = $out_type; fn next(&mut self) -> Option { if Some(self.i) == self.limit { None } else { if self.i == u64::MAX { panic!("Too many iterations"); } loop { let mut all_are_valid = true; $( if all_are_valid && self.xs.get(self.distributor.get_output($i)).is_none() { all_are_valid = false; } )* if all_are_valid { break; } else if !self.xs_done { let xs_len = self.xs.known_len().unwrap(); $( let _max_index = $i; )* let size = _max_index + 1; self.limit = CheckedPow::checked_pow( u64::exact_from(xs_len), u64::exact_from(size) ); if Some(self.i) == self.limit { return None; } self.xs_done = true; // xs_len > 0 at this point self.distributor.set_max_bits( &[0], max(1, usize::wrapping_from((xs_len - 1).significant_bits())), ); } else { self.distributor.increment_counter(); } } let result = Some( ($(self.xs.get(self.distributor.get_output($i)).unwrap().clone(),)*) ); self.i += 1; self.distributor.increment_counter(); result } } } /// This documentation applies not only to `exhaustive_pairs_1_input`, but also to /// `exhaustive_triples_1_input`, `exhaustive_quadruples_1_input`, and so on. See /// [`exhaustive_tuples_1_input`] for more information. /// /// Generates all length-$n$ tuples with elements from a single iterator. /// /// These functions differ from `exhaustive_[n-tuples]_from_single` in that different /// [`BitDistributorOutputType`]s may be specified for each output element. /// /// The $i$th parameter `output_types_[x_i]` is a [`BitDistributorOutputType`] that /// determines how quickly the $i$th output slot advances through the iterator; see the /// [`BitDistributor`] documentation for a description of the different types. /// /// If `xs` is finite, the output length is $k^n$, where $k$ is `xs.count()` and $n$ is the /// width of the tuples. If `xs` is infinite, the output is also infinite. /// /// If `xs` is empty, the output is also empty. /// /// # Examples /// See [here](self#exhaustive_pairs_1_input). #[allow(dead_code)] $($vis)* fn $exhaustive_fn( xs: I, $($out_x: BitDistributorOutputType,)* ) -> $exhaustive_struct where I::Item: Clone, { $exhaustive_struct { i: 0, limit: None, distributor: BitDistributor::new(&[$($out_x,)*]), xs: IteratorCache::new(xs), xs_done: false, phantom: PhantomData, } } /// This documentation applies not only to `exhaustive_pairs_from_single`, but also to /// `exhaustive_triples_from_single`, `exhaustive_quadruples_from_single`, and so on. See /// [`exhaustive_tuples_1_input`] for more information. /// /// Generates all $n$-tuples with elements from a single iterator. /// /// If `xs` is finite, the output length is $k^n$, where $k$ is `xs.count()` and $n$ is the /// width of the tuples. If `xs` is infinite, the output is also infinite. /// /// If `xs` is empty, the output is also empty. /// /// # Examples /// See [here](self#exhaustive_pairs_from_single). #[allow(dead_code)] #[inline] $($vis)* fn $exhaustive_fn_from_single(xs: I) -> $exhaustive_struct where I::Item: Clone, { $exhaustive_fn(xs, $(BitDistributorOutputType::normal(1 + $i * 0)),*) } } } exhaustive_tuples_1_input!( (pub), ExhaustivePairs1Input, exhaustive_pairs_1_input, exhaustive_pairs_from_single, (I::Item, I::Item), [0, output_type_x], [1, output_type_y] ); /// Defines exhaustive tuple generators. /// /// Malachite provides [`exhaustive_pairs`] and [`exhaustive_pairs_custom_output`], but you can also /// define `exhaustive_triples`, `exhaustive_quadruples`, and so on, and /// `exhaustive_triples_custom_output`, `exhaustive_quadruples_custom_output`, and so on, in your /// program using the code below. The documentation for [`exhaustive_pairs`] and /// [`exhaustive_pairs_custom_output`] describes these other functions as well. /// /// See usage examples [here](self#exhaustive_pairs) and /// [here](self#exhaustive_pairs_custom_output). /// /// ``` /// use malachite_base::exhaustive_tuples; /// use malachite_base::iterators::bit_distributor::{BitDistributor, BitDistributorOutputType}; /// use malachite_base::iterators::iterator_cache::IteratorCache; /// use malachite_base::num::conversion::traits::{ExactFrom, WrappingFrom}; /// use malachite_base::num::logic::traits::SignificantBits; /// use std::cmp::max; /// /// exhaustive_tuples!( /// (pub(crate)), /// ExhaustiveTriples, /// exhaustive_triples, /// exhaustive_triples_custom_output, /// [0, X, I, xs, xs_done, output_type_x], /// [1, Y, J, ys, ys_done, output_type_y], /// [2, Z, K, zs, zs_done, output_type_z] /// ); /// exhaustive_tuples!( /// (pub(crate)), /// ExhaustiveQuadruples, /// exhaustive_quadruples, /// exhaustive_quadruples_custom_output, /// [0, X, I, xs, xs_done, output_type_x], /// [1, Y, J, ys, ys_done, output_type_y], /// [2, Z, K, zs, zs_done, output_type_z], /// [3, W, L, ws, ws_done, output_type_w] /// ); /// exhaustive_tuples!( /// (pub(crate)), /// ExhaustiveQuintuples, /// exhaustive_quintuples, /// exhaustive_quintuples_custom_output, /// [0, X, I, xs, xs_done, output_type_x], /// [1, Y, J, ys, ys_done, output_type_y], /// [2, Z, K, zs, zs_done, output_type_z], /// [3, W, L, ws, ws_done, output_type_w], /// [4, V, M, vs, vs_done, output_type_v] /// ); /// exhaustive_tuples!( /// (pub(crate)), /// ExhaustiveSextuples, /// exhaustive_sextuples, /// exhaustive_sextuples_custom_output, /// [0, X, I, xs, xs_done, output_type_x], /// [1, Y, J, ys, ys_done, output_type_y], /// [2, Z, K, zs, zs_done, output_type_z], /// [3, W, L, ws, ws_done, output_type_w], /// [4, V, M, vs, vs_done, output_type_v], /// [5, U, N, us, us_done, output_type_u] /// ); /// exhaustive_tuples!( /// (pub(crate)), /// ExhaustiveSeptuples, /// exhaustive_septuples, /// exhaustive_septuples_custom_output, /// [0, X, I, xs, xs_done, output_type_x], /// [1, Y, J, ys, ys_done, output_type_y], /// [2, Z, K, zs, zs_done, output_type_z], /// [3, W, L, ws, ws_done, output_type_w], /// [4, V, M, vs, vs_done, output_type_v], /// [5, U, N, us, us_done, output_type_u], /// [6, T, O, ts, ts_done, output_type_t] /// ); /// exhaustive_tuples!( /// (pub(crate)), /// ExhaustiveOctuples, /// exhaustive_octuples, /// exhaustive_octuples_custom_output, /// [0, X, I, xs, xs_done, output_type_x], /// [1, Y, J, ys, ys_done, output_type_y], /// [2, Z, K, zs, zs_done, output_type_z], /// [3, W, L, ws, ws_done, output_type_w], /// [4, V, M, vs, vs_done, output_type_v], /// [5, U, N, us, us_done, output_type_u], /// [6, T, O, ts, ts_done, output_type_t], /// [7, S, P, ss, ss_done, output_type_s] /// ); /// ``` #[macro_export] macro_rules! exhaustive_tuples { ( ($($vis:tt)*), $exhaustive_struct: ident, $exhaustive_fn: ident, $exhaustive_fn_custom_output: ident, $([$i: tt, $t: ident, $it: ident, $xs: ident, $xs_done: ident, $out_x: ident]),* ) => { /// This documentation applies not only to `ExhaustivePairs`, but also to /// `ExhaustiveTriples`, `ExhaustiveQuadruples`, and so on. See [`exhaustive_tuples`] for /// more information. /// /// Generates all $n$-tuples with elements from $n$ iterators. #[derive(Clone, Debug)] $($vis)* struct $exhaustive_struct<$($t: Clone, $it: Iterator,)*> { i: u64, limit: Option, distributor: BitDistributor, $( $xs: IteratorCache<$it>, $xs_done: bool, )* } impl<$($t: Clone, $it: Iterator,)*> $exhaustive_struct<$($t, $it,)*> { fn try_getting_limit(&mut self) { let mut all_limits_known = true; $( if let Some(xs_len) = self.$xs.known_len() { if xs_len == 0 { self.limit = Some(0); return; } } else { all_limits_known = false; } )* if !all_limits_known { return; } let mut product = 1u64; $( let xs_len = u64::exact_from(self.$xs.known_len().unwrap()); if let Some(new_product) = product.checked_mul(u64::exact_from(xs_len)) { product = new_product; } else { return; } )* self.limit = Some(product); } } impl<$($t: Clone, $it: Iterator,)*> Iterator for $exhaustive_struct<$($t, $it,)*> { type Item = ($($t,)*); fn next(&mut self) -> Option { if Some(self.i) == self.limit { None } else { if self.i == u64::MAX { panic!("Too many iterations"); } loop { $( if self.$xs.get(self.distributor.get_output($i)).is_none() { if !self.$xs_done { let xs_len = self.$xs.known_len().unwrap(); self.try_getting_limit(); if Some(self.i) == self.limit { return None; } self.$xs_done = true; self.distributor.set_max_bits( &[$i], max( 1, usize::wrapping_from((xs_len - 1).significant_bits()) ), ); } else { self.distributor.increment_counter(); } continue; } )* break; } let result = Some( ($(self.$xs.get(self.distributor.get_output($i)).unwrap().clone(),)*) ); self.i += 1; self.distributor.increment_counter(); result } } } /// This documentation applies not only to `exhaustive_pairs_custom_output`, but also to /// `exhaustive_triples_custom_output`, `exhaustive_quadruples_custom_output`, and so on. /// See [`exhaustive_tuples`] for more information. /// /// Generates all $n$-tuples with elements from $n$ iterators, possibly with different /// output growth rates. /// /// The $i$th `output_type_[x_i]` parameter is a [`BitDistributorOutputType`] that /// determines how quickly the $i$th output slot advances through its iterator; see the /// [`BitDistributor`] documentation for a description of the different types. /// /// If all of `xs`, `ys`, `zs`, ... are finite, the output length is the product of their /// lengths. If any of `xs`, `ys`, `zs`, ... are infinite, the output is also infinite. /// /// If any of `xs`, `ys`, `zs`, ... is empty, the output is also empty. /// /// # Examples /// See [here](self#exhaustive_pairs_custom_output). #[allow(dead_code)] $($vis)* fn $exhaustive_fn_custom_output<$($t: Clone, $it: Iterator,)*>( $($xs: $it,)* $($out_x: BitDistributorOutputType,)* ) -> $exhaustive_struct<$($t, $it,)*> { $exhaustive_struct { i: 0, limit: None, distributor: BitDistributor::new(&[$($out_x,)*]), $( $xs: IteratorCache::new($xs), $xs_done: false, )* } } /// This documentation applies not only to `exhaustive_pairs`, but also to /// `exhaustive_triples`, `exhaustive_quadruples`, and so on. See [`exhaustive_tuples`] for /// more information. /// /// Generates all $n$-tuples with elements from $n$ iterators. /// /// If all of `xs`, `ys`, `zs`, ... are finite, the output length is the product of their /// lengths. If any of `xs`, `ys`, `zs`, ... are infinite, the output is also infinite. /// /// If any of `xs`, `ys`, `zs`, ... is empty, the output is also empty. /// /// # Examples /// See [here](self#exhaustive_pairs). #[allow(dead_code)] #[inline] $($vis)* fn $exhaustive_fn<$($t: Clone, $it: Iterator,)*>( $($xs: $it,)* ) -> $exhaustive_struct<$($t, $it,)*> { $exhaustive_fn_custom_output( $($xs,)* $(BitDistributorOutputType::normal(1 + 0 * $i),)* ) } } } exhaustive_tuples!( (pub), ExhaustivePairs, exhaustive_pairs, exhaustive_pairs_custom_output, [0, X, I, xs, xs_done, output_type_x], [1, Y, J, ys, ys_done, output_type_y] ); #[cfg(feature = "test_build")] exhaustive_tuples!( (pub), ExhaustiveTriples, exhaustive_triples, exhaustive_triples_custom_output, [0, X, I, xs, xs_done, output_type_x], [1, Y, J, ys, ys_done, output_type_y], [2, Z, K, zs, zs_done, output_type_z] ); #[cfg(not(feature = "test_build"))] exhaustive_tuples!( (pub(crate)), ExhaustiveTriples, exhaustive_triples, exhaustive_triples_custom_output, [0, X, I, xs, xs_done, output_type_x], [1, Y, J, ys, ys_done, output_type_y], [2, Z, K, zs, zs_done, output_type_z] ); #[cfg(feature = "test_build")] exhaustive_tuples!( (pub), ExhaustiveQuadruples, exhaustive_quadruples, exhaustive_quadruples_custom_output, [0, X, I, xs, xs_done, output_type_x], [1, Y, J, ys, ys_done, output_type_y], [2, Z, K, zs, zs_done, output_type_z], [3, W, L, ws, ws_done, output_type_w] ); /// Defines custom exhaustive tuple generators. /// /// You can define custom tuple generators like `exhaustive_triples_xyx` or /// `exhaustive_triples_xyx_custom_output` in your program using the code below. /// /// See usage examples [here](self#exhaustive_triples_xyx) and /// [here](self#exhaustive_triples_xyx_custom_output). /// /// ``` /// use malachite_base::custom_tuples; /// use malachite_base::iterators::bit_distributor::{BitDistributor, BitDistributorOutputType}; /// use malachite_base::iterators::iterator_cache::IteratorCache; /// use malachite_base::num::conversion::traits::{ExactFrom, WrappingFrom}; /// use malachite_base::num::logic::traits::SignificantBits; /// use std::cmp::max; /// /// #[allow(clippy::missing_const_for_fn)] /// fn unwrap_triple((a, b, c): (Option, Option, Option)) -> (X, Y, Z) { /// (a.unwrap(), b.unwrap(), c.unwrap()) /// } /// /// #[allow(clippy::missing_const_for_fn)] /// fn unwrap_quadruple( /// (a, b, c, d): (Option, Option, Option, Option), /// ) -> (X, Y, Z, W) { /// (a.unwrap(), b.unwrap(), c.unwrap(), d.unwrap()) /// } /// /// #[allow(clippy::missing_const_for_fn)] /// fn unwrap_quintuple( /// (a, b, c, d, e): (Option, Option, Option, Option, Option), /// ) -> (X, Y, Z, W, V) { /// (a.unwrap(), b.unwrap(), c.unwrap(), d.unwrap(), e.unwrap()) /// } /// /// custom_tuples!( /// (pub), /// ExhaustiveTriplesXXY, /// (X, X, Y), /// (None, None, None), /// unwrap_triple, /// exhaustive_triples_xxy, /// exhaustive_triples_xxy_custom_output, /// [X, I, xs, xs_done, [0, output_type_xs_0], [1, output_type_xs_1]], /// [Y, J, ys, ys_done, [2, output_type_ys_2]] /// ); /// custom_tuples!( /// (pub), /// ExhaustiveTriplesXYX, /// (X, Y, X), /// (None, None, None), /// unwrap_triple, /// exhaustive_triples_xyx, /// exhaustive_triples_xyx_custom_output, /// [X, I, xs, xs_done, [0, output_type_xs_0], [2, output_type_ys_1]], /// [Y, J, ys, ys_done, [1, output_type_xs_2]] /// ); /// custom_tuples!( /// (pub), /// ExhaustiveTriplesXYY, /// (X, Y, Y), /// (None, None, None), /// unwrap_triple, /// exhaustive_triples_xyy, /// exhaustive_triples_xyy_custom_output, /// [X, I, xs, xs_done, [0, output_type_xs_0]], /// [Y, J, ys, ys_done, [1, output_type_ys_1], [2, output_type_ys_2]] /// ); /// custom_tuples!( /// (pub), /// ExhaustiveQuadruplesXXXY, /// (X, X, X, Y), /// (None, None, None, None), /// unwrap_quadruple, /// exhaustive_quadruples_xxxy, /// exhaustive_quadruples_xxxy_custom_output, /// [X, I, xs, xs_done, [0, output_type_xs_0], [1, output_type_xs_1], [2, output_type_xs_2]], /// [Y, J, ys, ys_done, [3, output_type_ys_3]] /// ); /// custom_tuples!( /// (pub), /// ExhaustiveQuadruplesXXYX, /// (X, X, Y, X), /// (None, None, None, None), /// unwrap_quadruple, /// exhaustive_quadruples_xxyx, /// exhaustive_quadruples_xxyx_custom_output, /// [X, I, xs, xs_done, [0, output_type_xs_0], [1, output_type_xs_1], [3, output_type_xs_3]], /// [Y, J, ys, ys_done, [2, output_type_ys_2]] /// ); /// custom_tuples!( /// (pub), /// ExhaustiveQuadruplesXXYZ, /// (X, X, Y, Z), /// (None, None, None, None), /// unwrap_quadruple, /// exhaustive_quadruples_xxyz, /// exhaustive_quadruples_xxyz_custom_output, /// [X, I, xs, xs_done, [0, output_type_xs_0], [1, output_type_xs_1]], /// [Y, J, ys, ys_done, [2, output_type_ys_2]], /// [Z, K, zs, zs_done, [3, output_type_zs_3]] /// ); /// custom_tuples!( /// (pub), /// ExhaustiveQuadruplesXYXZ, /// (X, Y, X, Z), /// (None, None, None, None), /// unwrap_quadruple, /// exhaustive_quadruples_xyxz, /// exhaustive_quadruples_xyxz_custom_output, /// [X, I, xs, xs_done, [0, output_type_xs_0], [2, output_type_xs_2]], /// [Y, J, ys, ys_done, [1, output_type_ys_1]], /// [Z, K, zs, zs_done, [3, output_type_zs_3]] /// ); /// custom_tuples!( /// (pub), /// ExhaustiveQuadruplesXYYX, /// (X, Y, Y, X), /// (None, None, None, None), /// unwrap_quadruple, /// exhaustive_quadruples_xyyx, /// exhaustive_quadruples_xyyx_custom_output, /// [X, I, xs, xs_done, [0, output_type_xs_0], [3, output_type_xs_3]], /// [Y, J, ys, ys_done, [1, output_type_ys_1], [2, output_type_ys_2]] /// ); /// custom_tuples!( /// (pub), /// ExhaustiveQuadruplesXYYZ, /// (X, Y, Y, Z), /// (None, None, None, None), /// unwrap_quadruple, /// exhaustive_quadruples_xyyz, /// exhaustive_quadruples_xyyz_custom_output, /// [X, I, xs, xs_done, [0, output_type_xs_0]], /// [Y, J, ys, ys_done, [1, output_type_ys_1], [2, output_type_ys_2]], /// [Z, K, zs, zs_done, [3, output_type_zs_3]] /// ); /// custom_tuples!( /// (pub), /// ExhaustiveQuadruplesXYZZ, /// (X, Y, Z, Z), /// (None, None, None, None), /// unwrap_quadruple, /// exhaustive_quadruples_xyzz, /// exhaustive_quadruples_xyzz_custom_output, /// [X, I, xs, xs_done, [0, output_type_xs_0]], /// [Y, J, ys, ys_done, [1, output_type_ys_1]], /// [Z, K, zs, zs_done, [2, output_type_zs_2], [3, output_type_zs_3]] /// ); /// custom_tuples!( /// (pub), /// ExhaustiveQuintuplesXYYYZ, /// (X, Y, Y, Y, Z), /// (None, None, None, None, None), /// unwrap_quintuple, /// exhaustive_quintuples_xyyyz, /// exhaustive_quintuples_xyyyz_custom_output, /// [X, I, xs, xs_done, [0, output_type_xs_0]], /// [Y, J, ys, ys_done, [1, output_type_ys_1], [2, output_type_ys_2], [3, output_type_ys_3]], /// [Z, K, zs, zs_done, [4, output_type_zs_4]] /// ); /// ``` #[macro_export] macro_rules! custom_tuples { ( ($($vis:tt)*), $exhaustive_struct: ident, $out_t: ty, $nones: expr, $unwrap_tuple: ident, $exhaustive_fn: ident, $exhaustive_custom_fn: ident, $([$t: ident, $it: ident, $xs: ident, $xs_done: ident, $([$i: tt, $out_x: ident]),*]),* ) => { // Generates all $n$-tuples with elements from $m$ iterators, where $m \leq n$. // // The mapping from iterators to tuple slots is indicated by the struct name; for example, // in `TriplesXYX` there are two iterators, `X`, and `Y`; `X` generates the elements in the // first and third slots of the output triples, and `Y` generates the elements in the second // slots. #[derive(Clone, Debug)] $($vis)* struct $exhaustive_struct<$($t: Clone, $it: Iterator,)*> { i: u64, limit: Option, distributor: BitDistributor, $( $xs: IteratorCache<$it>, $xs_done: bool, )* } impl<$($t: Clone, $it: Iterator,)*> $exhaustive_struct<$($t, $it,)*> { fn try_getting_limit(&mut self) { let mut all_limits_known = true; $( if let Some(xs_len) = self.$xs.known_len() { if xs_len == 0 { self.limit = Some(0); return; } } else { all_limits_known = false; } )* if !all_limits_known { return; } let mut product = 1u64; $( let xs_len = u64::exact_from(self.$xs.known_len().unwrap()); $( let _x = $i; if let Some(new_product) = product.checked_mul(xs_len) { product = new_product; } else { return; } )* )* self.limit = Some(product); } } impl<$($t: Clone, $it: Iterator,)*> Iterator for $exhaustive_struct<$($t, $it,)*> { type Item = $out_t; fn next(&mut self) -> Option { if Some(self.i) == self.limit { None } else { if self.i == u64::MAX { panic!("Too many iterations"); } loop { $( $( if self.$xs.get(self.distributor.get_output($i)).is_none() { if !self.$xs_done { let xs_len = self.$xs.known_len().unwrap(); self.try_getting_limit(); if Some(self.i) == self.limit { return None; } self.$xs_done = true; self.distributor.set_max_bits( &[$i], max( 1, usize::wrapping_from( (xs_len - 1).significant_bits() ) ), ); } else { self.distributor.increment_counter(); } continue; } )* )* break; } let mut out = $nones; $( $( let x = self.$xs.get(self.distributor.get_output($i)).unwrap(); out.$i = Some(x.clone()); )* )* self.i += 1; self.distributor.increment_counter(); Some($unwrap_tuple(out)) } } } // Generates all $n$-tuples with elements from $m$ iterators, where $m \leq n$, possibly // with different output growth rates. // // The mapping from iterators to tuple slots is indicated by the function name; for example, // `exhaustive_triples_xyx_custom_output` takes two iterators, `xs`, and `ys`; `xs` // generates the elements in the first and third slots of the output triples, and `ys` // generates the elements in the second slots. // // Let $i$ be the index of the input iterators and $j$ be the index of the output slots. So // for `exhaustive_triples_xyx_custom_output`, $i=0$ corresponds to $j=0$ and $j=2$, and // $i=1$ corresponds to $j=1$. // // The $j$th `output_type_[i_j]` parameter is a // [`BitDistributorOutputType`](crate::iterators::bit_distributor::BitDistributorOutputType) // that determines how quickly the $j$th output slot advances through its iterator; see the // [`BitDistributor`](crate::iterators::bit_distributor::BitDistributor) documentation for a // description of the different types. // // If all of `xs`, `ys`, `zs`, ... are finite, then the output length may be obtained by // raising the length of each input iterator to power of the number of outputs it maps to, // and taking the product of the resulting values. // // If any of `xs`, `ys`, `zs`, ... are infinite, the output is also infinite. // // If any of `xs`, `ys`, `zs`, ... is empty, the output is also empty. // // # Examples // See [here](self#exhaustive_triples_xyx_custom_output). #[allow(dead_code)] $($vis)* fn $exhaustive_custom_fn<$($t: Clone, $it: Iterator,)*>( $($xs: $it,)* $($($out_x: BitDistributorOutputType,)*)* ) -> $exhaustive_struct<$($t, $it,)*> { $exhaustive_struct { i: 0, limit: None, distributor: BitDistributor::new(&[$($($out_x,)*)*]), $( $xs: IteratorCache::new($xs), $xs_done: false, )* } } // Generates all $n$-tuples with elements from $m$ iterators, where $m \leq n$. // // The mapping from iterators to tuple slots is indicated by the function name; for example, // `exhaustive_triples_xyx` takes two iterators, `xs`, and `ys`; `xs` generates the elements // in the first and third slots of the output triples, and `ys` generates the elements in // the second slots. // // If all of `xs`, `ys`, `zs`, ... are finite, then the output length may be obtained by // raising the length of each input iterator to power of the number of outputs it maps to, // and taking the product of the resulting values. // // If any of `xs`, `ys`, `zs`, ... are infinite, the output is also infinite. // // If any of `xs`, `ys`, `zs`, ... is empty, the output is also empty. // // # Examples // See [here](self#exhaustive_triples_xyx). #[allow(dead_code)] #[inline] $($vis)* fn $exhaustive_fn<$($t: Clone, $it: Iterator,)*>( $($xs: $it,)* ) -> $exhaustive_struct<$($t, $it,)*> { $exhaustive_custom_fn( $($xs,)* $($(BitDistributorOutputType::normal(1 + 0 * $i),)*)* ) } } } #[cfg(feature = "test_build")] #[allow(clippy::missing_const_for_fn)] fn unwrap_triple((a, b, c): (Option, Option, Option)) -> (X, Y, Z) { (a.unwrap(), b.unwrap(), c.unwrap()) } #[cfg(feature = "test_build")] custom_tuples!( (pub), ExhaustiveTriplesXYY, (X, Y, Y), (None, None, None), unwrap_triple, exhaustive_triples_xyy, exhaustive_triples_xyy_custom_output, [X, I, xs, xs_done, [0, output_type_xs_0]], [Y, J, ys, ys_done, [1, output_type_ys_1], [2, output_type_ys_2]] ); /// A trait used by dependent-pairs structs. /// /// Given a reference to an `x`, produces an iterator of `ys`. /// /// See [`LexDependentPairs`] and [`ExhaustiveDependentPairs`]. pub trait ExhaustiveDependentPairsYsGenerator> { fn get_ys(&self, x: &X) -> J; } /// Generates pairs $(x, y)$, where the possible values of $y$ depend on the value of $x$. All $y$ /// values are output before proceeding to the next $x$. /// /// This `struct` is created by; [`lex_dependent_pairs`]; see its documentation for more. #[derive(Clone, Debug)] pub struct LexDependentPairs< X: Clone, Y, S: ExhaustiveDependentPairsYsGenerator, I: Iterator, J: Iterator, > { done: bool, stop_after_empty_ys: bool, xs: I, ys: Option, x: Option, ys_generator: S, } impl< X: Clone, Y, S: ExhaustiveDependentPairsYsGenerator, I: Iterator, J: Iterator, > LexDependentPairs { fn advance_xs(&mut self) -> bool { if let Some(next_x) = self.xs.next() { self.x = Some(next_x); self.ys = Some(self.ys_generator.get_ys(self.x.as_ref().unwrap())); false } else { true } } } impl< X: Clone, Y, S: ExhaustiveDependentPairsYsGenerator, I: Iterator, J: Iterator, > Iterator for LexDependentPairs { type Item = (X, Y); fn next(&mut self) -> Option<(X, Y)> { if self.done { None } else { let mut new_ys = false; if self.x.is_none() { if self.advance_xs() { self.done = true; return None; } new_ys = true; } loop { if let Some(y) = self.ys.as_mut().unwrap().next() { return Some((self.x.as_ref().unwrap().clone(), y)); } else if self.stop_after_empty_ys && new_ys || self.advance_xs() { self.done = true; return None; } new_ys = true; } } } } /// Generates pairs $(x, y)$, where the possible values of $y$ depend on the value of $x$. All $y$ /// values are output before proceeding to the next $x$. /// /// This function takes an iterator `xs` that produces $x$ values, along with a `ys_generator` that /// creates an iterator of $y$ values when given a reference to an $x$ value. The resulting iterator /// first generates all pairs generated by the first $x$ value, then all pairs generated by the /// second $x$ value, and so on. /// /// It's called `lex_dependent_pairs` because if the `xs` iterator produces elements in some order, /// and each `ys` iterator produces elements in some order (uniform across all `ys`), then the /// resulting pairs are output in lexicographic order with respect to the $x$ and $y$ orders. /// /// Each `ys` iterator produced by `ys_generator` must be finite; if some `ys` is infinite, then no /// further `xs` value will be used. For a similar function that works with infinite `ys`, see /// [`exhaustive_dependent_pairs`]. /// /// If, after a certain point, all the generated `ys` are empty, the output iterator will hang /// trying to find another $(x, y)$ to output. To get around this, try /// [`lex_dependent_pairs_stop_after_empty_ys`]. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::tuples::exhaustive::{ /// lex_dependent_pairs, ExhaustiveDependentPairsYsGenerator, /// }; /// use maplit::hashmap; /// use std::collections::HashMap; /// use std::hash::Hash; /// use std::iter::Cloned; /// use std::slice::Iter; /// /// #[derive(Clone, Debug)] /// struct DPGeneratorFromMap { /// map: HashMap, /// } /// /// impl /// ExhaustiveDependentPairsYsGenerator>> /// for DPGeneratorFromMap /// { /// #[inline] /// fn get_ys(&self, x: &X) -> Cloned> { /// self.map[x].iter().cloned() /// } /// } /// /// let xs = ["a", "b", "c", "b", "a"].iter().cloned(); /// let xss = lex_dependent_pairs( /// xs, /// DPGeneratorFromMap { /// map: hashmap! { /// "a" => &[2, 3, 4][..], /// "b" => &[20][..], /// "c" => &[30, 40][..] /// }, /// }, /// ) /// .take(20) /// .collect_vec(); /// assert_eq!( /// xss.as_slice(), /// &[ /// ("a", 2), /// ("a", 3), /// ("a", 4), /// ("b", 20), /// ("c", 30), /// ("c", 40), /// ("b", 20), /// ("a", 2), /// ("a", 3), /// ("a", 4) /// ] /// ); /// /// let xs = [1, 2, 3, 2, 3, 2, 2].iter().cloned(); /// let xss = lex_dependent_pairs( /// xs, /// DPGeneratorFromMap { /// map: hashmap! { /// 1 => &[100, 101, 102][..], /// 2 => &[][..], /// 3 => &[300, 301, 302][..] /// }, /// }, /// ) /// .take(20) /// .collect_vec(); /// assert_eq!( /// xss.as_slice(), /// &[(1, 100), (1, 101), (1, 102), (3, 300), (3, 301), (3, 302), (3, 300), (3, 301), (3, 302),] /// ); /// ``` #[inline] pub const fn lex_dependent_pairs< X: Clone, Y, S: ExhaustiveDependentPairsYsGenerator, I: Iterator, J: Iterator, >( xs: I, ys_generator: S, ) -> LexDependentPairs { LexDependentPairs { done: false, stop_after_empty_ys: false, xs, ys: None, x: None, ys_generator, } } /// Generates pairs $(x, y)$, where the possible values of $y$ depend on the value of $x$. $x$ /// values with no corresponding $y$ values are treated specially. /// /// See [`lex_dependent_pairs`] for context. /// /// If the output iterator encounters an $x$ value whose corresponding `ys` iterator is empty, the /// output iterator stops iterating altogether. This prevents the iterator from getting stuck if all /// `ys` iterators after a certain point are empty. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::tuples::exhaustive::{ /// lex_dependent_pairs_stop_after_empty_ys, ExhaustiveDependentPairsYsGenerator, /// }; /// use maplit::hashmap; /// use std::collections::HashMap; /// use std::hash::Hash; /// use std::iter::Cloned; /// use std::slice::Iter; /// /// #[derive(Clone, Debug)] /// struct DPGeneratorFromMap { /// map: HashMap, /// } /// /// impl /// ExhaustiveDependentPairsYsGenerator>> /// for DPGeneratorFromMap /// { /// #[inline] /// fn get_ys(&self, x: &X) -> Cloned> { /// self.map[x].iter().cloned() /// } /// } /// /// let xs = [1, 2, 3, 2, 3, 2, 2].iter().cloned(); /// let xss = lex_dependent_pairs_stop_after_empty_ys( /// xs, /// DPGeneratorFromMap { /// map: hashmap! { /// 1 => &[100, 101, 102][..], /// 2 => &[][..], /// 3 => &[300, 301, 302][..] /// }, /// }, /// ) /// .take(20) /// .collect_vec(); /// // Stops after seeing 2, which maps to an empty iterator /// assert_eq!(xss.as_slice(), &[(1, 100), (1, 101), (1, 102)]); /// ``` #[inline] pub const fn lex_dependent_pairs_stop_after_empty_ys< X: Clone, Y, S: ExhaustiveDependentPairsYsGenerator, I: Iterator, J: Iterator, >( xs: I, ys_generator: S, ) -> LexDependentPairs { LexDependentPairs { done: false, stop_after_empty_ys: true, xs, ys: None, x: None, ys_generator, } } /// Generates pairs $(x, y)$, where the possible values of $y$ depend on the value of $x$. /// /// This `struct` is created by [`exhaustive_dependent_pairs`]; see its documentation for more. #[derive(Clone, Debug)] pub struct ExhaustiveDependentPairs< X: Clone, Y, G: Iterator, S: ExhaustiveDependentPairsYsGenerator, I: Iterator, J: Iterator, > { done: bool, xs_done: bool, stop_after_empty_ys: bool, index_generator: G, xs: I, xs_yss: Vec<(X, J, bool)>, ys_generator: S, } impl< X: Clone, Y, G: Iterator, S: ExhaustiveDependentPairsYsGenerator, I: Iterator, J: Iterator, > Iterator for ExhaustiveDependentPairs { type Item = (X, Y); fn next(&mut self) -> Option<(X, Y)> { if self.done { None } else { let original_i = self.index_generator.next().unwrap(); loop { let mut i = original_i; let mut xs_yss_len = self.xs_yss.len(); if self.xs_done { i %= xs_yss_len; } else if i >= xs_yss_len { for x in (&mut self.xs).take(i - xs_yss_len + 1) { let ys = self.ys_generator.get_ys(&x); self.xs_yss.push((x, ys, true)); } xs_yss_len = self.xs_yss.len(); if xs_yss_len == 0 { self.done = true; return None; } else if i >= xs_yss_len { self.xs_done = true; i %= xs_yss_len; } } let t = &mut self.xs_yss[i]; if let Some(y) = t.1.next() { // t has been used t.2 = false; return Some((t.0.clone(), y)); } else if self.stop_after_empty_ys && t.2 { self.done = true; return None; } self.xs_yss.remove(i); if self.xs_done && self.xs_yss.is_empty() { self.done = true; return None; } } } } } /// Generates pairs $(x, y)$, where the possible values of $y$ depend on the value of $x$. /// /// This function takes an iterator `xs` that produces $x$ values, along with a `ys_generator` that /// creates an iterator of $y$ values when given a reference to an $x$ value. The resulting iterator /// does not use all of an $x$'s $y$s immediately. Instead, it uses an `index_generator` (an /// iterator of `usize`s) to determine which $x$ value's iterator should be advanced. This /// arrangement allows for an $x$ to map to infinitely many `ys`. /// /// `index_generator` must generate every natural number infinitely many times. Good generators can /// be created using [`ruler_sequence`](crate::num::iterators::ruler_sequence) or /// [`bit_distributor_sequence`](crate::num::iterators::bit_distributor_sequence). The slower the /// sequence's growth rate, the more this iterator will prefer to use initial $x$ values before /// exploring later ones. /// /// If you want all of an $x$ value's $y$s to be used before moving on to the next $x$, use /// [`lex_dependent_pairs`] instead. /// /// If, after a certain point, all the generated `ys` are empty, the output iterator will hang /// trying to find another $(x, y)$ to output. To get around this, try /// [`exhaustive_dependent_pairs_stop_after_empty_ys`]. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::exhaustive::exhaustive_positive_primitive_ints; /// use malachite_base::num::iterators::ruler_sequence; /// use malachite_base::tuples::exhaustive::{ /// exhaustive_dependent_pairs, ExhaustiveDependentPairsYsGenerator, /// }; /// use maplit::hashmap; /// use std::collections::HashMap; /// use std::hash::Hash; /// use std::iter::Cloned; /// use std::slice::Iter; /// /// #[derive(Clone, Debug)] /// pub struct MultiplesGeneratorHelper { /// u: u64, /// step: u64, /// } /// /// impl Iterator for MultiplesGeneratorHelper { /// type Item = u64; /// /// fn next(&mut self) -> Option { /// let next = self.u; /// self.u += self.step; /// Some(next) /// } /// } /// /// #[derive(Clone, Debug)] /// struct MultiplesGenerator {} /// /// impl ExhaustiveDependentPairsYsGenerator /// for MultiplesGenerator /// { /// #[inline] /// fn get_ys(&self, x: &u64) -> MultiplesGeneratorHelper { /// MultiplesGeneratorHelper { u: *x, step: *x } /// } /// } /// /// #[derive(Clone, Debug)] /// struct DPGeneratorFromMap { /// map: HashMap, /// } /// /// impl /// ExhaustiveDependentPairsYsGenerator>> /// for DPGeneratorFromMap /// { /// #[inline] /// fn get_ys(&self, x: &X) -> Cloned> { /// self.map[x].iter().cloned() /// } /// } /// /// // All (x, y) where x is a positive natural and y is a positive multiple of x. It would be /// // easier to do /// // /// // exhaustive_pairs_from_single(exhaustive_positive_primitive_ints::()) /// // .map(|(x, y)| (x, x * y)) /// // /// // in this case. /// let xs = exhaustive_positive_primitive_ints::(); /// let xss = exhaustive_dependent_pairs(ruler_sequence(), xs.clone(), MultiplesGenerator {}) /// .take(50) /// .collect_vec(); /// assert_eq!( /// xss.as_slice(), /// &[ /// (1, 1), /// (2, 2), /// (1, 2), /// (3, 3), /// (1, 3), /// (2, 4), /// (1, 4), /// (4, 4), /// (1, 5), /// (2, 6), /// (1, 6), /// (3, 6), /// (1, 7), /// (2, 8), /// (1, 8), /// (5, 5), /// (1, 9), /// (2, 10), /// (1, 10), /// (3, 9), /// (1, 11), /// (2, 12), /// (1, 12), /// (4, 8), /// (1, 13), /// (2, 14), /// (1, 14), /// (3, 12), /// (1, 15), /// (2, 16), /// (1, 16), /// (6, 6), /// (1, 17), /// (2, 18), /// (1, 18), /// (3, 15), /// (1, 19), /// (2, 20), /// (1, 20), /// (4, 12), /// (1, 21), /// (2, 22), /// (1, 22), /// (3, 18), /// (1, 23), /// (2, 24), /// (1, 24), /// (5, 10), /// (1, 25), /// (2, 26) /// ] /// ); /// /// let xs = [1, 2, 3, 2, 3, 2, 2].iter().cloned(); /// let xss = exhaustive_dependent_pairs( /// ruler_sequence(), /// xs, /// DPGeneratorFromMap { /// map: hashmap! { 1 => &[100, 101, 102][..], 2 => &[][..], 3 => &[300, 301, 302][..] }, /// }, /// ) /// .take(20) /// .collect_vec(); /// assert_eq!( /// xss.as_slice(), /// &[(1, 100), (3, 300), (1, 101), (3, 300), (1, 102), (3, 301), (3, 302), (3, 301), (3, 302)] /// ); /// ``` #[inline] pub const fn exhaustive_dependent_pairs< X: Clone, Y, G: Iterator, S: ExhaustiveDependentPairsYsGenerator, I: Iterator, J: Iterator, >( index_generator: G, xs: I, ys_generator: S, ) -> ExhaustiveDependentPairs { ExhaustiveDependentPairs { done: false, xs_done: false, stop_after_empty_ys: false, index_generator, xs, xs_yss: Vec::new(), ys_generator, } } /// Generates pairs $(x, y)$, where the possible values of $y$ depend on the value of $x$. $x$ /// values with no corresponding $y$ values are treated specially. /// /// See [`exhaustive_dependent_pairs`] for context. /// /// If the output iterator encounters an $x$ value whose corresponding `ys` iterator is empty, the /// output iterator stops iterating altogether. This prevents the iterator from getting stuck if all /// `ys` iterators after a certain point are empty. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::iterators::ruler_sequence; /// use malachite_base::tuples::exhaustive::{ /// exhaustive_dependent_pairs_stop_after_empty_ys, ExhaustiveDependentPairsYsGenerator, /// }; /// use maplit::hashmap; /// use std::collections::HashMap; /// use std::hash::Hash; /// use std::iter::Cloned; /// use std::slice::Iter; /// /// #[derive(Clone, Debug)] /// pub struct MultiplesGeneratorHelper { /// u: u64, /// step: u64, /// } /// /// impl Iterator for MultiplesGeneratorHelper { /// type Item = u64; /// /// fn next(&mut self) -> Option { /// let next = self.u; /// self.u += self.step; /// Some(next) /// } /// } /// /// #[derive(Clone, Debug)] /// struct DPGeneratorFromMap { /// map: HashMap, /// } /// /// impl /// ExhaustiveDependentPairsYsGenerator>> /// for DPGeneratorFromMap /// { /// #[inline] /// fn get_ys(&self, x: &X) -> Cloned> { /// self.map[x].iter().cloned() /// } /// } /// /// let xs = [1, 2, 3, 2, 3, 2, 2].iter().cloned(); /// let xss = exhaustive_dependent_pairs_stop_after_empty_ys( /// ruler_sequence(), /// xs, /// DPGeneratorFromMap { /// map: hashmap! { /// 1 => &[100, 101, 102][..], /// 2 => &[][..], /// 3 => &[300, 301, 302][..] /// }, /// }, /// ) /// .take(20) /// .collect_vec(); /// assert_eq!(xss.as_slice(), &[(1, 100)]); /// ``` #[inline] pub const fn exhaustive_dependent_pairs_stop_after_empty_ys< X: Clone, Y, G: Iterator, S: ExhaustiveDependentPairsYsGenerator, I: Iterator, J: Iterator, >( index_generator: G, xs: I, ys_generator: S, ) -> ExhaustiveDependentPairs { ExhaustiveDependentPairs { done: false, xs_done: false, stop_after_empty_ys: true, index_generator, xs, xs_yss: Vec::new(), ys_generator, } } /// Defines lexicographic ordered unique tuple generators. /// /// Malachite provides [`lex_ordered_unique_pairs`], but you can also define /// `lex_ordered_unique_triples`, `lex_ordered_unique_quadruples`, and so on, in your program using /// the code below. The documentation for [`lex_ordered_unique_pairs`] describes these other /// functions as well. /// /// See usage examples [here](self#lex_ordered_unique_quadruples). /// /// ``` /// use malachite_base::iterators::iterator_cache::IteratorCache; /// use malachite_base::lex_ordered_unique_tuples; /// use malachite_base::vecs::exhaustive::fixed_length_ordered_unique_indices_helper; /// use std::marker::PhantomData; /// /// lex_ordered_unique_tuples!( /// (pub(crate)), /// LexOrderedUniqueTriples, /// 3, /// (I::Item, I::Item, I::Item), /// lex_ordered_unique_triples, /// [0, 1, 2] /// ); /// lex_ordered_unique_tuples!( /// (pub(crate)), /// LexOrderedUniqueQuadruples, /// 4, /// (I::Item, I::Item, I::Item, I::Item), /// lex_ordered_unique_quadruples, /// [0, 1, 2, 3] /// ); /// lex_ordered_unique_tuples!( /// (pub(crate)), /// LexOrderedUniqueQuintuples, /// 5, /// (I::Item, I::Item, I::Item, I::Item, I::Item), /// lex_ordered_unique_quintuples, /// [0, 1, 2, 3, 4] /// ); /// lex_ordered_unique_tuples!( /// (pub(crate)), /// LexOrderedUniqueSextuples, /// 6, /// (I::Item, I::Item, I::Item, I::Item, I::Item, I::Item), /// lex_ordered_unique_sextuples, /// [0, 1, 2, 3, 4, 5] /// ); /// lex_ordered_unique_tuples!( /// (pub(crate)), /// LexOrderedUniqueSeptuples, /// 7, /// ( /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item /// ), /// lex_ordered_unique_septuples, /// [0, 1, 2, 3, 4, 5, 6] /// ); /// lex_ordered_unique_tuples!( /// (pub(crate)), /// LexOrderedUniqueOctuples, /// 8, /// ( /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item /// ), /// lex_ordered_unique_octuples, /// [0, 1, 2, 3, 4, 5, 6, 7] /// ); /// ``` #[macro_export] macro_rules! lex_ordered_unique_tuples { ( ($($vis:tt)*), $struct: ident, $k: expr, $out_t: ty, $fn: ident, [$($i: expr),*] ) => { /// This documentation applies not only to `LexOrderedUniquePairs`, but also to /// `LexOrderedUniqueTriples`, `LexOrderedUniqueQuadruples`, and so on. See /// [`lex_ordered_unique_tuples`] for more information. /// /// Generates all $k$-tuples of elements from an iterator, where the tuples have no /// repetitions and are ordered the same way as in the iterator. /// /// The tuples are generated in lexicographic order with respect to the order of the element /// iterator. #[derive(Clone, Debug)] $($vis)* struct $struct where I::Item: Clone { first: bool, done: bool, xs: IteratorCache, indices: [usize; $k], phantom: PhantomData<*const I::Item>, } impl Iterator for $struct where I::Item: Clone { type Item = $out_t; fn next(&mut self) -> Option { if self.done { return None; } if self.first { self.first = false; self.xs.get($k); if let Some(n) = self.xs.known_len() { if n < $k { self.done = true; return None; } } } else { if let Some(n) = self.xs.known_len() { if fixed_length_ordered_unique_indices_helper(n, $k, &mut self.indices) { self.done = true; return None; } } else { *self.indices.last_mut().unwrap() += 1; } } if let Some(&last_index) = self.indices.last() { // Give known len a chance to be set self.xs.get(last_index + 1); } Some(($(self.xs.assert_get(self.indices[$i]).clone(),)*)) } } /// This documentation applies not only to `lex_ordered_unique_pairs`, but also to /// `lex_ordered_unique_triples`, `lex_ordered_unique_quadruples`, and so on. See /// [`lex_ordered_unique_tuples`] for more information. /// /// Generates $k$-tuples of elements from a single iterator, such that each tuple has no /// repeated elements, and the elements in each [`Vec`] are ordered the same way as they are /// in the source iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The order is lexicographic with respect to the order of the element iterator. /// /// If the input iterator is infinite, the output length is also infinite. /// /// If the input iterator length is $n$, the output length is $\binom{n}{k}$. /// /// If `xs` is empty, the output is also empty. /// /// # Examples /// See [here](self#lex_ordered_unique_quadruples). $($vis)* const fn $fn(xs: I) -> $struct where I::Item: Clone { $struct { first: true, done: false, xs: IteratorCache::new(xs), indices: [$($i),*], phantom: PhantomData, } } } } lex_ordered_unique_tuples!( (pub), LexOrderedUniquePairs, 2, (I::Item, I::Item), lex_ordered_unique_pairs, [0, 1] ); /// Defines exhaustive ordered unique tuple generators. /// /// Malachite provides [`exhaustive_ordered_unique_pairs`], but you can also define /// `exhaustive_ordered_unique_triples`, `exhaustive_ordered_unique_quadruples`, and so on, in your /// program using the code below. The documentation for [`exhaustive_ordered_unique_pairs`] /// describes these other functions as well. /// /// See usage examples [here](self#exhaustive_ordered_unique_quadruples). /// /// ``` /// use malachite_base::exhaustive_ordered_unique_tuples; /// use malachite_base::iterators::iterator_cache::IteratorCache; /// use malachite_base::vecs::exhaustive::next_bit_pattern; /// /// exhaustive_ordered_unique_tuples!( /// (pub(crate)), /// ExhaustiveOrderedUniqueTriples, /// 3, /// (I::Item, I::Item, I::Item), /// exhaustive_ordered_unique_triples, /// [0, 1, 2] /// ); /// exhaustive_ordered_unique_tuples!( /// (pub(crate)), /// ExhaustiveOrderedUniqueQuadruples, /// 4, /// (I::Item, I::Item, I::Item, I::Item), /// exhaustive_ordered_unique_quadruples, /// [0, 1, 2, 3] /// ); /// exhaustive_ordered_unique_tuples!( /// (pub(crate)), /// ExhaustiveOrderedUniqueQuintuples, /// 5, /// (I::Item, I::Item, I::Item, I::Item, I::Item), /// exhaustive_ordered_unique_quintuples, /// [0, 1, 2, 3, 4] /// ); /// exhaustive_ordered_unique_tuples!( /// (pub(crate)), /// ExhaustiveOrderedUniqueSextuples, /// 6, /// (I::Item, I::Item, I::Item, I::Item, I::Item, I::Item), /// exhaustive_ordered_unique_sextuples, /// [0, 1, 2, 3, 4, 5] /// ); /// exhaustive_ordered_unique_tuples!( /// (pub(crate)), /// ExhaustiveOrderedUniqueSeptuples, /// 7, /// ( /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item /// ), /// exhaustive_ordered_unique_septuples, /// [0, 1, 2, 3, 4, 5, 6] /// ); /// exhaustive_ordered_unique_tuples!( /// (pub(crate)), /// ExhaustiveOrderedUniqueOctuples, /// 8, /// ( /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item /// ), /// exhaustive_ordered_unique_octuples, /// [0, 1, 2, 3, 4, 5, 6, 7] /// ); /// ``` #[macro_export] macro_rules! exhaustive_ordered_unique_tuples { ( ($($vis:tt)*), $struct: ident, $k: expr, $out_t: ty, $fn: ident, [$($i: expr),*] ) => { /// This documentation applies not only to `ExhaustiveOrderedUniquePairs`, but also to /// `ExhaustiveOrderedUniqueTriples`, `ExhaustiveOrderedUniqueQuadruples`, and so on. See /// [`exhaustive_ordered_unique_tuples`] for more information. /// /// Generates all $k$-tuples of elements from an iterator, where the tuples have no /// repetitions and are ordered the same way as in the iterator. #[derive(Clone)] pub struct $struct where I::Item: Clone, { done: bool, first: bool, xs: IteratorCache, pattern: Vec, } impl Iterator for $struct where I::Item: Clone, { type Item = $out_t; fn next(&mut self) -> Option { if self.done { return None; } else if self.first { self.first = false; } else { let mut c = $k; next_bit_pattern(&mut self.pattern, &mut c, $k, $k); } if !self.pattern.is_empty() && self.xs.get(self.pattern.len() - 1).is_none() { self.done = true; return None; } let mut results = self.pattern.iter().enumerate().filter_map(|(i, &b)| { if b { Some(self.xs.assert_get(i).clone()) } else { None } }); Some(($(((results.next().unwrap(), $i).0)),*)) } } /// This documentation applies not only to `exhaustive_ordered_unique_pairs`, but also to /// `exhaustive_ordered_unique_triples`, `exhaustive_ordered_unique_quadruples`, and so on. /// See [`exhaustive_ordered_unique_tuples`] for more information. /// /// Generates $k$-tuples of elements from a single iterator, such that each tuple has no /// repeated elements, and the elements in each [`Vec`] are ordered the same way as they are /// in the source iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// If the input iterator is infinite, the output length is also infinite. /// /// If the input iterator length is $n$, the output length is $\binom{n}{k}$. /// /// If `xs` is empty, the output is also empty. /// /// # Examples /// See [here](self#exhaustive_ordered_unique_quadruples). pub fn $fn(xs: I) -> $struct where I::Item: Clone, { $struct { done: false, first: true, xs: IteratorCache::new(xs), pattern: vec![true; $k], } } } } exhaustive_ordered_unique_tuples!( (pub), ExhaustiveOrderedUniquePairs, 2, (I::Item, I::Item), exhaustive_ordered_unique_pairs, [0, 1] ); /// Defines lexicographic unique tuple generators. /// /// Malachite provides [`lex_unique_pairs`], but you can also define `lex_unique_triples`, /// `lex_unique_quadruples`, and so on, in your program using the code below. The documentation for /// [`lex_unique_pairs`] describes these other functions as well. /// /// See usage examples [here](self#lex_unique_pairs). /// /// ``` /// use malachite_base::iterators::iterator_cache::IteratorCache; /// use malachite_base::lex_unique_tuples; /// use malachite_base::vecs::exhaustive::{unique_indices, UniqueIndices}; /// /// lex_unique_tuples!( /// (pub(crate)), /// LexUniqueTriples, /// 3, /// (I::Item, I::Item, I::Item), /// lex_unique_triples, /// [0, 1, 2] /// ); /// lex_unique_tuples!( /// (pub(crate)), /// LexUniqueQuadruples, /// 4, /// (I::Item, I::Item, I::Item, I::Item), /// lex_unique_quadruples, /// [0, 1, 2, 3] /// ); /// lex_unique_tuples!( /// (pub(crate)), /// LexUniqueQuintuples, /// 5, /// (I::Item, I::Item, I::Item, I::Item, I::Item), /// lex_unique_quintuples, /// [0, 1, 2, 3, 4] /// ); /// lex_unique_tuples!( /// (pub(crate)), /// LexUniqueSextuples, /// 6, /// (I::Item, I::Item, I::Item, I::Item, I::Item, I::Item), /// lex_unique_sextuples, /// [0, 1, 2, 3, 4, 5] /// ); /// lex_unique_tuples!( /// (pub(crate)), /// LexUniqueSeptuples, /// 7, /// ( /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item /// ), /// lex_unique_septuples, /// [0, 1, 2, 3, 4, 5, 6] /// ); /// lex_unique_tuples!( /// (pub(crate)), /// LexUniqueOctuples, /// 8, /// ( /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item /// ), /// lex_unique_octuples, /// [0, 1, 2, 3, 4, 5, 6, 7] /// ); /// ``` #[macro_export] macro_rules! lex_unique_tuples { ( ($($vis:tt)*), $struct: ident, $k: expr, $out_t: ty, $fn: ident, [$($i: expr),*] ) => { /// This documentation applies not only to `LexUniquePairs`, but also to `LexUniqueTriples`, /// `LexUniqueQuadruples`, and so on. See [`lex_unique_tuples`] for more information. /// /// Generates all $k$-tuples of elements from an iterator, where the tuples have no /// repetitions. /// /// The tuples are generated in lexicographic order with respect to the order of the element /// iterator. #[derive(Clone)] $($vis)* struct $struct where I::Item: Clone { first: bool, xs: IteratorCache, indices: UniqueIndices, } impl Iterator for $struct where I::Item: Clone { type Item = $out_t; fn next(&mut self) -> Option { if self.first { let nonempty = !self.indices.used.is_empty(); if nonempty && self.xs.get(self.indices.get_n() - 1).is_none() { self.indices.done = true; } self.first = false; } if self.xs.get(self.indices.get_n()).is_some() { self.indices.increment_n(); } self.indices.next().map(|indices| { let mut results = indices.into_iter().map(|i| self.xs.assert_get(i).clone()); ($(((results.next().unwrap(), $i).0)),*) }) } } /// This documentation applies not only to `lex_unique_pairs`, but also to /// `lex_unique_triples`, `lex_unique_quadruples`, and so on. See [`lex_unique_tuples`] for /// more information. /// /// Generates $k$-tuples of elements from a single iterator, such that each tuple has no /// repeated elements. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The order is lexicographic with respect to the order of the element iterator. /// /// If the input iterator is infinite, the output length is also infinite. /// /// If the input iterator length is $n$, the output length is $\frac{n!}{k!}$. /// /// If `xs` is empty, the output is also empty. /// /// # Examples /// See [here](self#lex_unique_quadruples). #[inline] $($vis)* fn $fn(xs: I) -> $struct where I::Item: Clone { $struct { first: true, xs: IteratorCache::new(xs), // Initial n is k, but will grow to reach actual n (or forever, if n is infinite) indices: unique_indices($k, $k), } } } } lex_unique_tuples!( (pub), LexUniquePairs, 2, (I::Item, I::Item), lex_unique_pairs, [0, 1] ); /// Generates all pairs of elements from an iterator, where the pairs have no repetitions. /// /// This `struct` is created by [`exhaustive_unique_pairs`]; see its documentation for more. #[derive(Clone)] pub struct ExhaustiveUniquePairs where I::Item: Clone, { next: Option<(I::Item, I::Item)>, ps: ExhaustiveOrderedUniquePairs, } impl Iterator for ExhaustiveUniquePairs where I::Item: Clone, { type Item = (I::Item, I::Item); fn next(&mut self) -> Option<(I::Item, I::Item)> { if self.next.is_some() { take(&mut self.next) } else if let Some(p) = self.ps.next() { self.next = Some((p.1.clone(), p.0.clone())); Some(p) } else { None } } } /// Generates pairs of elements from a single iterator, such that each pair has no repeated /// elements. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// If the input iterator is infinite, the output length is also infinite. /// /// If the input iterator length is $n$, the output length is $\tfrac{1}{2}{n!}$. /// /// If `xs` is empty, the output is also empty. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::tuples::exhaustive::exhaustive_unique_pairs; /// /// let xss = exhaustive_unique_pairs(1..=6).take(20).collect_vec(); /// assert_eq!( /// xss.into_iter().collect_vec().as_slice(), /// &[ /// (1, 2), /// (2, 1), /// (1, 3), /// (3, 1), /// (2, 3), /// (3, 2), /// (1, 4), /// (4, 1), /// (2, 4), /// (4, 2), /// (3, 4), /// (4, 3), /// (1, 5), /// (5, 1), /// (2, 5), /// (5, 2), /// (3, 5), /// (5, 3), /// (4, 5), /// (5, 4) /// ] /// ); /// ``` pub fn exhaustive_unique_pairs(xs: I) -> ExhaustiveUniquePairs where I::Item: Clone, { ExhaustiveUniquePairs { next: None, ps: exhaustive_ordered_unique_pairs(xs), } } /// Defines lexicographic unique tuple generators. /// /// Malachite provides [`exhaustive_unique_pairs`], but you can also define /// `exhaustive_unique_triples`, `lex_unique_quadruples`, and so on, in your program using the code /// below. /// /// See usage examples [here](self#lex_unique_quadruples). /// /// ``` /// use malachite_base::exhaustive_unique_tuples; /// use malachite_base::num::iterators::{ruler_sequence, RulerSequence}; /// use malachite_base::tuples::exhaustive::{ /// exhaustive_dependent_pairs, ExhaustiveDependentPairs, /// }; /// use malachite_base::vecs::exhaustive::{ /// exhaustive_ordered_unique_vecs_fixed_length, ExhaustiveOrderedUniqueCollections, /// ExhaustiveUniqueVecsGenerator, /// }; /// use malachite_base::vecs::ExhaustiveVecPermutations; /// /// exhaustive_unique_tuples!( /// (pub(crate)), /// ExhaustiveUniqueTriples, /// 3, /// (I::Item, I::Item, I::Item), /// exhaustive_unique_triples, /// [0, 1, 2] /// ); /// exhaustive_unique_tuples!( /// (pub(crate)), /// ExhaustiveUniqueQuadruples, /// 4, /// (I::Item, I::Item, I::Item, I::Item), /// exhaustive_unique_quadruples, /// [0, 1, 2, 3] /// ); /// exhaustive_unique_tuples!( /// (pub(crate)), /// ExhaustiveUniqueQuintuples, /// 5, /// (I::Item, I::Item, I::Item, I::Item, I::Item), /// exhaustive_unique_quintuples, /// [0, 1, 2, 3, 4] /// ); /// exhaustive_unique_tuples!( /// (pub(crate)), /// ExhaustiveUniqueSextuples, /// 6, /// (I::Item, I::Item, I::Item, I::Item, I::Item, I::Item), /// exhaustive_unique_sextuples, /// [0, 1, 2, 3, 4, 5] /// ); /// exhaustive_unique_tuples!( /// (pub(crate)), /// ExhaustiveUniqueSeptuples, /// 7, /// ( /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item /// ), /// exhaustive_unique_septuples, /// [0, 1, 2, 3, 4, 5, 6] /// ); /// exhaustive_unique_tuples!( /// (pub(crate)), /// ExhaustiveUniqueOctuples, /// 8, /// ( /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item /// ), /// exhaustive_unique_octuples, /// [0, 1, 2, 3, 4, 5, 6, 7] /// ); /// ``` #[macro_export] macro_rules! exhaustive_unique_tuples { ( ($($vis:tt)*), $struct: ident, $k: expr, $out_t: ty, $fn: ident, [$($i: expr),*] ) => { // Generates all $k$-tuples of elements from an iterator, where the tuples have no // repetitions. #[derive(Clone)] $($vis)* struct $struct where I::Item: Clone { xss: ExhaustiveDependentPairs< Vec, Vec, RulerSequence, ExhaustiveUniqueVecsGenerator, ExhaustiveOrderedUniqueCollections>, ExhaustiveVecPermutations, > } impl Iterator for $struct where I::Item: Clone { type Item = $out_t; fn next(&mut self) -> Option { self.xss.next().map(|mut p| { let mut drain = p.1.drain(..); ($(((drain.next().unwrap(), $i).0)),*) }) } } // Generates $k$-tuples of elements from a single iterator, such that each tuple has no // repeated elements. // // The source iterator should not repeat any elements, but this is not enforced. // // If the input iterator is infinite, the output length is also infinite. // // If the input iterator length is $n$, the output length is $\frac{n!}{k!}$. // // If `xs` is empty, the output is also empty. // // # Examples // See [here](self#exhaustive_unique_quadruples). $($vis)* fn $fn(xs: I) -> $struct where I::Item: Clone { $struct { xss: exhaustive_dependent_pairs( ruler_sequence(), exhaustive_ordered_unique_vecs_fixed_length($k, xs), ExhaustiveUniqueVecsGenerator::new(), ) } } } } malachite-base-0.4.16/src/tuples/mod.rs000064400000000000000000000564361046102023000160210ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . /// Generates all singletons (1-element tuples) with values from a given iterator. /// /// This `struct` is created by [`singletons`]; see its documentation for more. #[derive(Clone, Debug, Eq, PartialEq)] pub struct Singletons { xs: I, } impl Iterator for Singletons { type Item = (I::Item,); #[inline] fn next(&mut self) -> Option<(I::Item,)> { self.xs.next().map(|x| (x,)) } } /// Generates all singletons (1-element tuples) with values from a given iterator. /// /// The elements appear in the same order as they do in the given iterator, but wrapped in `(_,)`. /// /// The output length is `xs.count()`. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::tuples::singletons; /// /// assert_eq!( /// singletons([1, 2, 3].iter().cloned()).collect_vec(), /// &[(1,), (2,), (3,)] /// ); /// ``` #[inline] pub const fn singletons(xs: I) -> Singletons { Singletons { xs } } /// Iterators that generate tuples without repetition. /// /// To reduce binary size and lower compilation time, many of the functions described here are not /// actually defined in Malachite, but may be created in your program using macros exported from /// Malachite. To do this, see the documentation for `lex_tuples` and `lex_custom_tuples`. /// /// # lex_pairs /// ``` /// use itertools::Itertools; /// use malachite_base::tuples::exhaustive::lex_pairs; /// /// assert_eq!( /// lex_pairs('a'..'f', 0..3).collect_vec(), /// &[ /// ('a', 0), /// ('a', 1), /// ('a', 2), /// ('b', 0), /// ('b', 1), /// ('b', 2), /// ('c', 0), /// ('c', 1), /// ('c', 2), /// ('d', 0), /// ('d', 1), /// ('d', 2), /// ('e', 0), /// ('e', 1), /// ('e', 2) /// ] /// ); /// ``` /// /// # lex_pairs_from_single /// ``` /// use itertools::Itertools; /// use malachite_base::tuples::exhaustive::lex_pairs_from_single; /// /// assert_eq!( /// lex_pairs_from_single(0..3).collect_vec(), /// &[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)] /// ); /// ``` /// /// # lex_triples_xyx /// ``` /// use itertools::Itertools; /// use malachite_base::iterators::iterator_cache::IteratorCache; /// use malachite_base::lex_custom_tuples; /// /// fn unwrap_triple((a, b, c): (Option, Option, Option)) -> (X, Y, Z) { /// (a.unwrap(), b.unwrap(), c.unwrap()) /// } /// /// lex_custom_tuples!( /// (pub(crate)), /// LexTriplesXYX, /// (X, Y, X), /// (None, None, None), /// unwrap_triple, /// lex_triples_xyx, /// [X, I, xs, [0, x_0], [2, x_2]], /// [Y, J, ys, [1, y_1]] /// ); /// /// // We are generating triples of `char`, `i8`, and `char` using two input iterators. The first /// // iterator, `xs`, the chars 'a' through 'c', and the second, `ys`, produces the three numbers /// // 0, 1, and 2. The function we're using is `lex_triples_xyx`, meaning that the first element of /// // the output triples will be taken from `xs`, the second element from `ys`, and the third also /// // from `xs`. /// let ts = lex_triples_xyx('a'..='c', 0..3); /// assert_eq!( /// ts.collect_vec(), /// &[ /// ('a', 0, 'a'), /// ('a', 0, 'b'), /// ('a', 0, 'c'), /// ('a', 1, 'a'), /// ('a', 1, 'b'), /// ('a', 1, 'c'), /// ('a', 2, 'a'), /// ('a', 2, 'b'), /// ('a', 2, 'c'), /// ('b', 0, 'a'), /// ('b', 0, 'b'), /// ('b', 0, 'c'), /// ('b', 1, 'a'), /// ('b', 1, 'b'), /// ('b', 1, 'c'), /// ('b', 2, 'a'), /// ('b', 2, 'b'), /// ('b', 2, 'c'), /// ('c', 0, 'a'), /// ('c', 0, 'b'), /// ('c', 0, 'c'), /// ('c', 1, 'a'), /// ('c', 1, 'b'), /// ('c', 1, 'c'), /// ('c', 2, 'a'), /// ('c', 2, 'b'), /// ('c', 2, 'c') /// ] /// ); /// ``` /// /// # exhaustive_pairs_from_single /// ``` /// use itertools::Itertools; /// use malachite_base::tuples::exhaustive::exhaustive_pairs_from_single; /// /// assert_eq!( /// exhaustive_pairs_from_single(0..4).collect_vec(), /// &[ /// (0, 0), /// (0, 1), /// (1, 0), /// (1, 1), /// (0, 2), /// (0, 3), /// (1, 2), /// (1, 3), /// (2, 0), /// (2, 1), /// (3, 0), /// (3, 1), /// (2, 2), /// (2, 3), /// (3, 2), /// (3, 3) /// ] /// ); /// ``` /// /// # exhaustive_pairs_1_input /// ``` /// use itertools::Itertools; /// use malachite_base::chars::exhaustive::exhaustive_ascii_chars; /// use malachite_base::exhaustive_tuples_1_input; /// use malachite_base::iterators::bit_distributor::{BitDistributor, BitDistributorOutputType}; /// use malachite_base::iterators::iterator_cache::IteratorCache; /// use malachite_base::num::arithmetic::traits::CheckedPow; /// use malachite_base::num::conversion::traits::{ExactFrom, WrappingFrom}; /// use malachite_base::num::logic::traits::SignificantBits; /// use std::cmp::max; /// use std::marker::PhantomData; /// /// exhaustive_tuples_1_input!( /// (pub(crate)), /// ExhaustiveTriples1Input, /// exhaustive_triples_1_input, /// exhaustive_triples_from_single, /// (I::Item, I::Item, I::Item), /// [0, output_type_x], /// [1, output_type_y], /// [2, output_type_z] /// ); /// /// // We are generating triples of `char`s using one input iterator, which produces all ASCII /// // `char`s. The third element has a tiny output type, so it will grow more slowly than the other /// // two elements (though it doesn't look that way from the first few tuples). /// let ts = exhaustive_triples_1_input( /// exhaustive_ascii_chars(), /// BitDistributorOutputType::normal(1), /// BitDistributorOutputType::normal(1), /// BitDistributorOutputType::tiny(), /// ); /// assert_eq!( /// ts.take(20).collect_vec(), /// &[ /// ('a', 'a', 'a'), /// ('a', 'a', 'b'), /// ('a', 'a', 'c'), /// ('a', 'a', 'd'), /// ('a', 'b', 'a'), /// ('a', 'b', 'b'), /// ('a', 'b', 'c'), /// ('a', 'b', 'd'), /// ('a', 'a', 'e'), /// ('a', 'a', 'f'), /// ('a', 'a', 'g'), /// ('a', 'a', 'h'), /// ('a', 'b', 'e'), /// ('a', 'b', 'f'), /// ('a', 'b', 'g'), /// ('a', 'b', 'h'), /// ('b', 'a', 'a'), /// ('b', 'a', 'b'), /// ('b', 'a', 'c'), /// ('b', 'a', 'd') /// ] /// ); /// ``` /// /// # exhaustive_pairs /// ``` /// use itertools::Itertools; /// use malachite_base::tuples::exhaustive::exhaustive_pairs; /// /// let xss = exhaustive_pairs(['a', 'b', 'c'].iter().cloned(), 0..3).collect_vec(); /// assert_eq!( /// xss, /// &[('a', 0), ('a', 1), ('b', 0), ('b', 1), ('a', 2), ('b', 2), ('c', 0), ('c', 1), ('c', 2)] /// ); /// ``` /// /// # exhaustive_pairs_custom_output /// ``` /// use itertools::Itertools; /// use malachite_base::iterators::bit_distributor::BitDistributorOutputType; /// use malachite_base::tuples::exhaustive::exhaustive_pairs_custom_output; /// /// let xss = exhaustive_pairs_custom_output( /// ['a', 'b', 'c'].iter().cloned(), /// 0..3, /// BitDistributorOutputType::normal(1), /// BitDistributorOutputType::tiny(), /// ) /// .collect_vec(); /// assert_eq!( /// xss, /// &[('a', 0), ('a', 1), ('a', 2), ('b', 0), ('b', 1), ('b', 2), ('c', 0), ('c', 1), ('c', 2)] /// ); /// ``` /// /// # exhaustive_triples_xyx /// ``` /// use itertools::Itertools; /// use malachite_base::chars::exhaustive::exhaustive_ascii_chars; /// use malachite_base::custom_tuples; /// use malachite_base::iterators::bit_distributor::{BitDistributor, BitDistributorOutputType}; /// use malachite_base::iterators::iterator_cache::IteratorCache; /// use malachite_base::num::conversion::traits::{ExactFrom, WrappingFrom}; /// use malachite_base::num::logic::traits::SignificantBits; /// use std::cmp::max; /// /// #[allow(clippy::missing_const_for_fn)] /// fn unwrap_triple((a, b, c): (Option, Option, Option)) -> (X, Y, Z) { /// (a.unwrap(), b.unwrap(), c.unwrap()) /// } /// /// custom_tuples!( /// (pub(crate)), /// ExhaustiveTriplesXYX, /// (X, Y, X), /// (None, None, None), /// unwrap_triple, /// exhaustive_triples_xyx, /// exhaustive_triples_xyx_custom_output, /// [X, I, xs, xs_done, [0, output_type_xs_0], [2, output_type_ys_1]], /// [Y, J, ys, ys_done, [1, output_type_xs_2]] /// ); /// /// // We are generating triples of `char`, `i8`, and `char` using two input iterators. The first /// // iterator, `xs`, produces all ASCII `char`s, and the second, `ys`, produces the three numbers /// // 0, 1, and 2. The function we're using is `exhaustive_triples_xyx`, meaning that the first /// // element of the output triples will be taken from `xs`, the second element from `ys`, and the /// // third also from `xs`. /// let ts = exhaustive_triples_xyx(exhaustive_ascii_chars(), 0..3); /// assert_eq!( /// ts.take(20).collect_vec(), /// &[ /// ('a', 0, 'a'), /// ('a', 0, 'b'), /// ('a', 1, 'a'), /// ('a', 1, 'b'), /// ('b', 0, 'a'), /// ('b', 0, 'b'), /// ('b', 1, 'a'), /// ('b', 1, 'b'), /// ('a', 0, 'c'), /// ('a', 0, 'd'), /// ('a', 1, 'c'), /// ('a', 1, 'd'), /// ('b', 0, 'c'), /// ('b', 0, 'd'), /// ('b', 1, 'c'), /// ('b', 1, 'd'), /// ('a', 2, 'a'), /// ('a', 2, 'b'), /// ('b', 2, 'a'), /// ('b', 2, 'b') /// ] /// ); /// ``` /// /// # exhaustive_triples_xyx_custom_output /// ``` /// use itertools::Itertools; /// use malachite_base::chars::exhaustive::exhaustive_ascii_chars; /// use malachite_base::custom_tuples; /// use malachite_base::iterators::bit_distributor::{BitDistributor, BitDistributorOutputType}; /// use malachite_base::iterators::iterator_cache::IteratorCache; /// use malachite_base::num::conversion::traits::{ExactFrom, WrappingFrom}; /// use malachite_base::num::logic::traits::SignificantBits; /// use std::cmp::max; /// /// #[allow(clippy::missing_const_for_fn)] /// fn unwrap_triple((a, b, c): (Option, Option, Option)) -> (X, Y, Z) { /// (a.unwrap(), b.unwrap(), c.unwrap()) /// } /// /// custom_tuples!( /// (pub(crate)), /// ExhaustiveTriplesXYX, /// (X, Y, X), /// (None, None, None), /// unwrap_triple, /// exhaustive_triples_xyx, /// exhaustive_triples_xyx_custom_output, /// [X, I, xs, xs_done, [0, output_type_xs_0], [2, output_type_ys_1]], /// [Y, J, ys, ys_done, [1, output_type_xs_2]] /// ); /// /// // We are generating triples of `char`, `i8`, and `char` using two input iterators. The first /// // iterator, `xs`, produces all ASCII `char`s, and the second, `ys`, produces the three numbers /// // 0, 1, and 2. The function we're using is `exhaustive_triples_xyx_custom_output`, meaning that /// // the first element of the output triples will be taken from `xs`, the second element from /// // `ys`, and the third also from `xs`. /// // /// // The third element has a tiny output type, so it will grow more slowly than the other two /// // elements (though it doesn't look that way from the first few tuples). /// let ts = exhaustive_triples_xyx_custom_output( /// exhaustive_ascii_chars(), /// 0..3, /// BitDistributorOutputType::normal(1), /// BitDistributorOutputType::normal(1), /// BitDistributorOutputType::tiny(), /// ); /// assert_eq!( /// ts.take(20).collect_vec(), /// &[ /// ('a', 0, 'a'), /// ('a', 0, 'b'), /// ('a', 0, 'c'), /// ('a', 0, 'd'), /// ('a', 1, 'a'), /// ('a', 1, 'b'), /// ('a', 1, 'c'), /// ('a', 1, 'd'), /// ('a', 0, 'e'), /// ('a', 0, 'f'), /// ('a', 0, 'g'), /// ('a', 0, 'h'), /// ('a', 1, 'e'), /// ('a', 1, 'f'), /// ('a', 1, 'g'), /// ('a', 1, 'h'), /// ('b', 0, 'a'), /// ('b', 0, 'b'), /// ('b', 0, 'c'), /// ('b', 0, 'd') /// ] /// ); /// ``` /// /// # lex_ordered_unique_quadruples /// ``` /// use itertools::Itertools; /// use malachite_base::iterators::iterator_cache::IteratorCache; /// use malachite_base::lex_ordered_unique_tuples; /// use malachite_base::vecs::exhaustive::fixed_length_ordered_unique_indices_helper; /// use std::marker::PhantomData; /// /// lex_ordered_unique_tuples!( /// (pub(crate)), /// LexOrderedUniqueQuadruples, /// 4, /// (I::Item, I::Item, I::Item, I::Item), /// lex_ordered_unique_quadruples, /// [0, 1, 2, 3] /// ); /// /// let xss = lex_ordered_unique_quadruples(1..=6).collect_vec(); /// assert_eq!( /// xss.into_iter().collect_vec().as_slice(), /// &[ /// (1, 2, 3, 4), /// (1, 2, 3, 5), /// (1, 2, 3, 6), /// (1, 2, 4, 5), /// (1, 2, 4, 6), /// (1, 2, 5, 6), /// (1, 3, 4, 5), /// (1, 3, 4, 6), /// (1, 3, 5, 6), /// (1, 4, 5, 6), /// (2, 3, 4, 5), /// (2, 3, 4, 6), /// (2, 3, 5, 6), /// (2, 4, 5, 6), /// (3, 4, 5, 6) /// ] /// ); /// ``` /// /// # exhaustive_ordered_unique_quadruples /// ``` /// use itertools::Itertools; /// use malachite_base::exhaustive_ordered_unique_tuples; /// use malachite_base::iterators::iterator_cache::IteratorCache; /// use malachite_base::vecs::exhaustive::next_bit_pattern; /// /// exhaustive_ordered_unique_tuples!( /// (pub(crate)), /// ExhaustiveOrderedUniqueQuadruples, /// 4, /// (I::Item, I::Item, I::Item, I::Item), /// exhaustive_ordered_unique_quadruples, /// [0, 1, 2, 3] /// ); /// /// let xss = exhaustive_ordered_unique_quadruples(1..=6).collect_vec(); /// assert_eq!( /// xss.into_iter().collect_vec().as_slice(), /// &[ /// (1, 2, 3, 4), /// (1, 2, 3, 5), /// (1, 2, 4, 5), /// (1, 3, 4, 5), /// (2, 3, 4, 5), /// (1, 2, 3, 6), /// (1, 2, 4, 6), /// (1, 3, 4, 6), /// (2, 3, 4, 6), /// (1, 2, 5, 6), /// (1, 3, 5, 6), /// (2, 3, 5, 6), /// (1, 4, 5, 6), /// (2, 4, 5, 6), /// (3, 4, 5, 6) /// ] /// ); /// ``` /// /// # lex_unique_quadruples /// ``` /// use itertools::Itertools; /// use malachite_base::iterators::iterator_cache::IteratorCache; /// use malachite_base::lex_unique_tuples; /// use malachite_base::vecs::exhaustive::{unique_indices, UniqueIndices}; /// /// lex_unique_tuples!( /// (pub(crate)), /// LexUniqueQuadruples, /// 4, /// (I::Item, I::Item, I::Item, I::Item), /// lex_unique_quadruples, /// [0, 1, 2, 3] /// ); /// /// let xss = lex_unique_quadruples(1..=6).take(20).collect_vec(); /// assert_eq!( /// xss.into_iter().collect_vec().as_slice(), /// &[ /// (1, 2, 3, 4), /// (1, 2, 3, 5), /// (1, 2, 3, 6), /// (1, 2, 4, 3), /// (1, 2, 4, 5), /// (1, 2, 4, 6), /// (1, 2, 5, 3), /// (1, 2, 5, 4), /// (1, 2, 5, 6), /// (1, 2, 6, 3), /// (1, 2, 6, 4), /// (1, 2, 6, 5), /// (1, 3, 2, 4), /// (1, 3, 2, 5), /// (1, 3, 2, 6), /// (1, 3, 4, 2), /// (1, 3, 4, 5), /// (1, 3, 4, 6), /// (1, 3, 5, 2), /// (1, 3, 5, 4) /// ] /// ); /// ``` /// /// # exhaustive_unique_quadruples /// ``` /// use itertools::Itertools; /// use malachite_base::exhaustive_unique_tuples; /// use malachite_base::num::iterators::{ruler_sequence, RulerSequence}; /// use malachite_base::tuples::exhaustive::{ /// exhaustive_dependent_pairs, ExhaustiveDependentPairs, /// }; /// use malachite_base::vecs::exhaustive::{ /// exhaustive_ordered_unique_vecs_fixed_length, ExhaustiveOrderedUniqueCollections, /// ExhaustiveUniqueVecsGenerator, /// }; /// use malachite_base::vecs::ExhaustiveVecPermutations; /// /// exhaustive_unique_tuples!( /// (pub(crate)), /// ExhaustiveUniqueQuadruples, /// 4, /// (I::Item, I::Item, I::Item, I::Item), /// exhaustive_unique_quadruples, /// [0, 1, 2, 3] /// ); /// /// let xss = exhaustive_unique_quadruples(1..=6).take(20).collect_vec(); /// assert_eq!( /// xss.into_iter().collect_vec().as_slice(), /// &[ /// (1, 2, 3, 4), /// (1, 2, 3, 5), /// (1, 2, 4, 3), /// (1, 2, 4, 5), /// (1, 3, 2, 4), /// (1, 2, 5, 3), /// (1, 3, 4, 2), /// (1, 3, 4, 5), /// (1, 4, 2, 3), /// (1, 3, 2, 5), /// (1, 4, 3, 2), /// (1, 2, 5, 4), /// (2, 1, 3, 4), /// (1, 3, 5, 2), /// (2, 1, 4, 3), /// (2, 3, 4, 5), /// (2, 3, 1, 4), /// (1, 5, 2, 3), /// (2, 3, 4, 1), /// (1, 4, 2, 5) /// ] /// ); /// ``` pub mod exhaustive; #[cfg(feature = "random")] /// Iterators that generate tuples randomly. /// /// # random_pairs /// ``` /// use itertools::Itertools; /// use malachite_base::chars::random::random_char_inclusive_range; /// use malachite_base::num::random::random_unsigned_inclusive_range; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::tuples::random::random_pairs; /// /// let ps = random_pairs( /// EXAMPLE_SEED, /// &|seed| random_unsigned_inclusive_range::(seed, 0, 2), /// &|seed| random_char_inclusive_range(seed, 'x', 'z'), /// ); /// assert_eq!( /// ps.take(20).collect_vec().as_slice(), /// &[ /// (1, 'z'), /// (1, 'x'), /// (1, 'z'), /// (1, 'y'), /// (2, 'x'), /// (0, 'z'), /// (0, 'z'), /// (0, 'z'), /// (2, 'z'), /// (0, 'y'), /// (2, 'x'), /// (0, 'x'), /// (2, 'z'), /// (0, 'z'), /// (2, 'x'), /// (2, 'x'), /// (2, 'y'), /// (1, 'y'), /// (0, 'x'), /// (2, 'x') /// ] /// ); /// ``` /// /// # random_pairs_from_single /// ``` /// use itertools::Itertools; /// use malachite_base::num::random::random_unsigned_inclusive_range; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::tuples::random::random_pairs_from_single; /// /// let ps = random_pairs_from_single(random_unsigned_inclusive_range::(EXAMPLE_SEED, 0, 2)); /// assert_eq!( /// ps.take(20).collect_vec().as_slice(), /// &[ /// (1, 0), /// (1, 2), /// (1, 1), /// (0, 1), /// (0, 2), /// (1, 0), /// (1, 2), /// (2, 0), /// (1, 0), /// (2, 2), /// (2, 1), /// (0, 2), /// (2, 1), /// (1, 1), /// (0, 0), /// (2, 0), /// (2, 2), /// (1, 0), /// (1, 1), /// (0, 2) /// ] /// ); /// ``` /// /// # random_triples_xyx /// ``` /// use itertools::Itertools; /// use malachite_base::chars::random::random_char_inclusive_range; /// use malachite_base::num::random::random_unsigned_inclusive_range; /// use malachite_base::random::{Seed, EXAMPLE_SEED}; /// use malachite_base::random_custom_tuples; /// /// random_custom_tuples!( /// (pub(crate)), /// RandomTriplesXYX, /// (X, Y, X), /// random_triples_xyx, /// [X, I, xs, xs_gen, [x_0, x_0], [x_2, y_1]], /// [Y, J, ys, ys_gen, [y_1, x_2]] /// ); /// /// // We are generating triples of `char`s using two input iterators. The first iterator, `xs`, /// // produces all ASCII `char`s, and the second, `ys`, produces the three numbers 0, 1, and 2. The /// // function we're using is `random_triples_xyx`, meaning that the first element of the /// // output triples will be taken from `xs`, the second element from `ys`, and the third also from /// // `xs`. /// let ts = random_triples_xyx( /// EXAMPLE_SEED, /// &|seed| random_char_inclusive_range(seed, 'x', 'z'), /// &|seed| random_unsigned_inclusive_range::(seed, 0, 2), /// ); /// assert_eq!( /// ts.take(20).collect_vec().as_slice(), /// &[ /// ('y', 2, 'y'), /// ('y', 0, 'y'), /// ('z', 2, 'x'), /// ('x', 1, 'x'), /// ('z', 0, 'x'), /// ('z', 2, 'x'), /// ('z', 2, 'x'), /// ('z', 2, 'z'), /// ('z', 2, 'y'), /// ('x', 1, 'z'), /// ('z', 0, 'x'), /// ('y', 0, 'z'), /// ('y', 2, 'z'), /// ('x', 2, 'z'), /// ('z', 0, 'y'), /// ('z', 0, 'y'), /// ('y', 1, 'x'), /// ('z', 1, 'z'), /// ('x', 0, 'z'), /// ('z', 0, 'x') /// ] /// ); /// ``` /// /// # random_ordered_unique_quadruples /// ``` /// use itertools::Itertools; /// use malachite_base::num::random::random_unsigned_inclusive_range; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::random_ordered_unique_tuples; /// use malachite_base::sets::random::{ /// random_b_tree_sets_fixed_length, RandomBTreeSetsFixedLength, /// }; /// /// random_ordered_unique_tuples!( /// (pub(crate)), /// RandomOrderedUniqueQuadruples, /// 4, /// (I::Item, I::Item, I::Item, I::Item), /// random_ordered_unique_quadruples, /// [0, 1, 2, 3] /// ); /// /// let qs = random_ordered_unique_quadruples(random_unsigned_inclusive_range::( /// EXAMPLE_SEED, /// 1, /// 10, /// )); /// assert_eq!( /// qs.take(20).collect_vec().as_slice(), /// &[ /// (2, 5, 6, 8), /// (3, 5, 7, 9), /// (1, 2, 6, 8), /// (3, 4, 6, 7), /// (3, 6, 9, 10), /// (4, 6, 8, 10), /// (3, 6, 8, 10), /// (2, 5, 9, 10), /// (2, 3, 8, 10), /// (1, 3, 7, 8), /// (1, 2, 6, 10), /// (2, 5, 8, 9), /// (1, 8, 9, 10), /// (1, 3, 7, 8), /// (2, 3, 4, 5), /// (1, 3, 4, 8), /// (3, 6, 7, 9), /// (5, 6, 7, 8), /// (3, 4, 5, 9), /// (4, 6, 9, 10) /// ] /// ); /// ``` /// /// # random_unique_quadruples /// ``` /// use itertools::Itertools; /// use malachite_base::num::random::random_unsigned_inclusive_range; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::random_unique_tuples; /// use std::collections::HashMap; /// use std::hash::Hash; /// /// random_unique_tuples!( /// (pub(crate)), /// RandomOrderedUniqueQuadruples, /// 4, /// (I::Item, I::Item, I::Item, I::Item), /// random_unique_quadruples, /// [0, 1, 2, 3] /// ); /// /// let qs = random_unique_quadruples(random_unsigned_inclusive_range::(EXAMPLE_SEED, 1, 10)); /// assert_eq!( /// qs.take(20).collect_vec().as_slice(), /// &[ /// (2, 8, 6, 5), /// (7, 5, 3, 9), /// (2, 8, 6, 1), /// (3, 7, 4, 6), /// (3, 10, 6, 9), /// (6, 10, 4, 8), /// (6, 10, 8, 3), /// (10, 2, 9, 5), /// (8, 10, 2, 3), /// (8, 1, 7, 3), /// (2, 6, 1, 10), /// (9, 5, 8, 2), /// (8, 1, 9, 10), /// (7, 3, 8, 1), /// (3, 2, 5, 4), /// (3, 8, 4, 1), /// (9, 7, 6, 3), /// (5, 7, 8, 6), /// (5, 3, 9, 4), /// (9, 10, 4, 6) /// ] /// ); /// ``` pub mod random; malachite-base-0.4.16/src/tuples/random.rs000064400000000000000000000563141046102023000165150ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::random::Seed; use std::cmp::Ordering::*; use std::iter::{repeat, Repeat}; /// Generates random units; repeats `()`. /// /// $P(()) = 1$. /// /// The output length is infinite. /// /// # Expected complexity per iteration /// Constant time and additional memory. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::tuples::random::random_units; /// /// assert_eq!(random_units().take(10).collect_vec(), &[(); 10]); /// ``` pub fn random_units() -> Repeat<()> { repeat(()) } // hack for macro #[doc(hidden)] #[inline] pub fn next_helper(x: &mut I, _i: usize) -> Option { x.next() } /// Defines random tuple generators. /// /// Malachite provides [`random_pairs`] and [`random_pairs_from_single`], but you can also define /// `random_triples`, `random_quadruples`, and so on, and `random_triples_from_single`, /// `random_quadruples_from_single`, and so on, in your program using the code below. The /// documentation for [`random_pairs`] and [`random_pairs_from_single`] describes these other /// functions as well. /// /// See usage examples [here](self#random_pairs) and [here](self#random_pairs_from_single). /// /// ``` /// use malachite_base::random::Seed; /// use malachite_base::random_tuples; /// use malachite_base::tuples::random::next_helper; /// /// random_tuples!( /// (pub(crate)), /// RandomTriples, /// RandomTriplesFromSingle, /// random_triples, /// random_triples_from_single, /// (I::Item, I::Item, I::Item), /// [0, X, I, xs, xs_gen], /// [1, Y, J, ys, ys_gen], /// [2, Z, K, zs, zs_gen] /// ); /// random_tuples!( /// (pub(crate)), /// RandomQuadruples, /// RandomQuadruplesFromSingle, /// random_quadruples, /// random_quadruples_from_single, /// (I::Item, I::Item, I::Item, I::Item), /// [0, X, I, xs, xs_gen], /// [1, Y, J, ys, ys_gen], /// [2, Z, K, zs, zs_gen], /// [3, W, L, ws, ws_gen] /// ); /// random_tuples!( /// (pub(crate)), /// RandomQuintuples, /// RandomQuintuplesFromSingle, /// random_quintuples, /// random_quintuples_from_single, /// (I::Item, I::Item, I::Item, I::Item, I::Item), /// [0, X, I, xs, xs_gen], /// [1, Y, J, ys, ys_gen], /// [2, Z, K, zs, zs_gen], /// [3, W, L, ws, ws_gen], /// [4, V, M, vs, vs_gen] /// ); /// random_tuples!( /// (pub(crate)), /// RandomSextuples, /// RandomSextuplesFromSingle, /// random_sextuples, /// random_sextuples_from_single, /// (I::Item, I::Item, I::Item, I::Item, I::Item, I::Item), /// [0, X, I, xs, xs_gen], /// [1, Y, J, ys, ys_gen], /// [2, Z, K, zs, zs_gen], /// [3, W, L, ws, ws_gen], /// [4, V, M, vs, vs_gen], /// [5, U, N, us, us_gen] /// ); /// random_tuples!( /// (pub(crate)), /// RandomSeptuples, /// RandomSeptuplesFromSingle, /// random_septuples, /// random_septuples_from_single, /// ( /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item /// ), /// [0, X, I, xs, xs_gen], /// [1, Y, J, ys, ys_gen], /// [2, Z, K, zs, zs_gen], /// [3, W, L, ws, ws_gen], /// [4, V, M, vs, vs_gen], /// [5, U, N, us, us_gen], /// [6, T, O, ts, ts_gen] /// ); /// random_tuples!( /// (pub(crate)), /// RandomOctuples, /// RandomOctuplesFromSingle, /// random_octuples, /// random_octuples_from_single, /// ( /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item /// ), /// [0, X, I, xs, xs_gen], /// [1, Y, J, ys, ys_gen], /// [2, Z, K, zs, zs_gen], /// [3, W, L, ws, ws_gen], /// [4, V, M, vs, vs_gen], /// [5, U, N, us, us_gen], /// [6, T, O, ts, ts_gen], /// [7, S, P, ss, ss_gen] /// ); /// ``` #[macro_export] macro_rules! random_tuples { ( ($($vis:tt)*), $random_struct: ident, $random_struct_from_single: ident, $random_fn: ident, $random_fn_from_single: ident, $single_out: tt, $([$i: expr, $t: ident, $it: ident, $xs: ident, $xs_gen:ident]),* ) => { /// This documentation applies not only to `RandomPairs`, but also to `RandomTriples`, /// `RandomQuadruples`, and so on. See [`random_tuples`] for more information. /// /// Generates random $n$-tuples using elements from $n$ iterators. #[derive(Clone, Debug)] #[allow(dead_code)] $($vis)* struct $random_struct<$($t: Clone, $it: Iterator,)*> { $($xs: $it,)* } impl<$($t: Clone, $it: Iterator,)*> Iterator for $random_struct<$($t, $it,)*> { type Item = ($($t,)*); #[inline] fn next(&mut self) -> Option { Some(($(self.$xs.next().unwrap()),*)) } } /// This documentation applies not only to `random_pairs`, but also to `random_triples`, /// `random_quadruples`, and so on. See [`random_tuples`] for more information. /// /// Generates random $n$-tuples with elements from $n$ iterators. /// /// The probability of a particular $n$-tuple being generated is the product of the /// probabilities of each of its elements. /// /// `xs`, `ys`, `zs`, ... must be infinite. /// /// # Examples /// See [here](self#random_pairs). #[allow(dead_code)] $($vis)* fn $random_fn<$($t: Clone, $it: Iterator,)*>( seed: Seed, $($xs_gen: &dyn Fn(Seed) -> $it,)* ) -> $random_struct<$($t, $it,)*> { $random_struct { $($xs: $xs_gen(seed.fork(stringify!($xs))),)* } } /// This documentation applies not only to `RandomPairsFromSingle`, but also to /// `RandomTriplesFromSingle`, `RandomQuadruplesFromSingle`, and so on. See /// [`random_tuples`] for more information. /// /// Generates random $n$-tuples using elements from a single iterator. #[derive(Clone, Debug)] #[allow(dead_code)] $($vis)* struct $random_struct_from_single { xs: I } impl Iterator for $random_struct_from_single { type Item = $single_out; #[inline] fn next(&mut self) -> Option<$single_out> { Some(($(next_helper(&mut self.xs, $i).unwrap(),)*)) } } /// This documentation applies not only to `random_pairs_from_single`, but also to /// `random_triples_from_single`, `random_quadruples_from_single`, and so on. See /// [`random_tuples`] for more information. /// /// Generates random $n$-tuples using elements from a single iterator. /// /// The probability of a particular $n$-tuple being generated is the product of the /// probabilities of each of its elements. /// /// `xs` must be infinite. /// /// # Examples /// See [here](self#random_pairs_from_single). #[allow(dead_code)] #[inline] $($vis)* const fn $random_fn_from_single(xs: I) -> $random_struct_from_single { $random_struct_from_single { xs } } } } random_tuples!( (pub), RandomPairs, RandomPairsFromSingle, random_pairs, random_pairs_from_single, (I::Item, I::Item), [0, X, I, xs, xs_gen], [1, Y, J, ys, ys_gen] ); /// Defines custom random tuple generators. /// /// You can define custom tuple generators like `random_triples_xyx` in your program using the code /// below. /// /// See usage examples [here](self#random_triples_xyx). /// /// ``` /// use malachite_base::random::Seed; /// use malachite_base::random_custom_tuples; /// /// random_custom_tuples!( /// (pub(crate)), /// RandomTriplesXXY, /// (X, X, Y), /// random_triples_xxy, /// [X, I, xs, xs_gen, [x_0, x_0], [x_1, x_1]], /// [Y, J, ys, ys_gen, [y_2, y_2]] /// ); /// random_custom_tuples!( /// (pub(crate)), /// RandomTriplesXYX, /// (X, Y, X), /// random_triples_xyx, /// [X, I, xs, xs_gen, [x_0, x_0], [x_2, y_1]], /// [Y, J, ys, ys_gen, [y_1, x_2]] /// ); /// random_custom_tuples!( /// (pub(crate)), /// RandomTriplesXYY, /// (X, Y, Y), /// random_triples_xyy, /// [X, I, xs, xs_gen, [x_0, x_0]], /// [Y, J, ys, ys_gen, [y_1, y_1], [y_2, y_2]] /// ); /// random_custom_tuples!( /// (pub(crate)), /// RandomQuadruplesXXXY, /// (X, X, X, Y), /// random_quadruples_xxxy, /// [X, I, xs, xs_gen, [x_0, x_0], [x_1, x_1], [x_2, x_2]], /// [Y, J, ys, ys_gen, [y_3, y_3]] /// ); /// random_custom_tuples!( /// (pub(crate)), /// RandomQuadruplesXXYX, /// (X, X, Y, X), /// random_quadruples_xxyx, /// [X, I, xs, xs_gen, [x_0, x_0], [x_1, x_1], [x_3, y_2]], /// [Y, J, ys, ys_gen, [y_2, x_3]] /// ); /// random_custom_tuples!( /// (pub(crate)), /// RandomQuadruplesXXYZ, /// (X, X, Y, Z), /// random_quadruples_xxyz, /// [X, I, xs, xs_gen, [x_0, x_0], [x_1, x_1]], /// [Y, J, ys, ys_gen, [y_2, y_2]], /// [Z, K, zs, zs_gen, [z_3, z_3]] /// ); /// random_custom_tuples!( /// (pub(crate)), /// RandomQuadruplesXYXZ, /// (X, Y, X, Z), /// random_quadruples_xyxz, /// [X, I, xs, xs_gen, [x_0, x_0], [x_2, y_1]], /// [Y, J, ys, ys_gen, [y_1, x_2]], /// [Z, K, zs, zs_gen, [z_3, z_3]] /// ); /// random_custom_tuples!( /// (pub(crate)), /// RandomQuadruplesXYYX, /// (X, Y, Y, X), /// random_quadruples_xyyx, /// [X, I, xs, xs_gen, [x_0, x_0], [x_3, y_1]], /// [Y, J, ys, ys_gen, [y_1, y_2], [y_2, x_3]] /// ); /// random_custom_tuples!( /// (pub(crate)), /// RandomQuadruplesXYYZ, /// (X, Y, Y, Z), /// random_quadruples_xyyz, /// [X, I, xs, xs_gen, [x_0, x_0]], /// [Y, J, ys, ys_gen, [y_1, y_1], [y_2, y_2]], /// [Z, K, zs, zs_gen, [z_3, z_3]] /// ); /// random_custom_tuples!( /// (pub(crate)), /// RandomQuadruplesXYZZ, /// (X, Y, Z, Z), /// random_quadruples_xyzz, /// [X, I, xs, xs_gen, [x_0, x_0]], /// [Y, J, ys, ys_gen, [y_1, y_1]], /// [Z, K, zs, zs_gen, [z_2, z_2], [z_3, z_3]] /// ); /// random_custom_tuples!( /// (pub(crate)), /// RandomQuintuplesXYYYZ, /// (X, Y, Y, Y, Z), /// random_quintuples_xyyyz, /// [X, I, xs, xs_gen, [x_0, x_0]], /// [Y, J, ys, ys_gen, [y_1, y_1], [y_2, y_2], [y_3, y_3]], /// [Z, K, zs, zs_gen, [z_4, z_4]] /// ); /// ``` #[macro_export] macro_rules! random_custom_tuples { ( ($($vis:tt)*), $random_struct: ident, $out_t: ty, $random_fn: ident, $([$t: ident, $it: ident, $xs: ident, $xs_gen: ident, $([$x: ident, $x_ord: ident]),*]),* ) => { // Generates random $n$-tuples with elements from $m$ iterators, where $m \leq n$. // // The mapping from iterators to tuple slots is indicated by the struct name; for example, // in `RandomTriplesXYX` there are two iterators, `X`, and `Y`; `X` generates the elements // in the first and third slots of the output triples, and `Y` generates the elements in the // second slots. #[derive(Clone, Debug)] $($vis)* struct $random_struct<$($t: Clone, $it: Iterator,)*> { $($xs: $it,)* } impl<$($t: Clone, $it: Iterator,)*> Iterator for $random_struct<$($t, $it,)*> { type Item = $out_t; fn next(&mut self) -> Option { $( $( let $x = self.$xs.next().unwrap(); )* )* Some(($($($x_ord,)*)*)) } } // Generates random $n$-tuples with elements from $m$ iterators, where $m \leq n$. // // The mapping from iterators to tuple slots is indicated by the function name; for example, // `random_triples_xyx` takes two iterators, `xs`, and `ys`; `xs` generates the elements in // the first and third slots of the output triples, and `ys` generates the elements in the // second slots. // // The probability of a particular $n$-tuple being generated is the product of the // probabilities of each of its elements. // // `xs`, `ys`, `zs`, ... must be infinite. // // # Examples // See [here](self#random_triples_xyx). $($vis)* fn $random_fn<$($t: Clone, $it: Iterator,)*>( seed: Seed, $($xs_gen: &dyn Fn(Seed) -> $it,)* ) -> $random_struct<$($t, $it,)*> { $random_struct { $($xs: $xs_gen(seed.fork(stringify!($xs))),)* } } } } /// Generates random pairs using elements from a single iterator, where the first element is less /// than the second. #[derive(Clone, Debug)] pub struct RandomOrderedUniquePairs where I::Item: Ord, { xs: I, } impl Iterator for RandomOrderedUniquePairs where I::Item: Ord, { type Item = (I::Item, I::Item); #[inline] fn next(&mut self) -> Option { let mut out_0 = None; let out_1; loop { let x = self.xs.next().unwrap(); if out_0.is_none() { out_0 = Some(x); } else { match x.cmp(out_0.as_ref().unwrap()) { Equal => {} Greater => { out_1 = x; break; } Less => { out_1 = out_0.unwrap(); out_0 = Some(x); break; } } } } Some((out_0.unwrap(), out_1)) } } /// Generates random pairs using elements from a single iterator, where the first element of each /// pair is less than the second. /// /// The input iterator must generate at least two distinct elements; otherwise, this iterator will /// hang. /// /// $$ /// P((x\_0, x\_1)) = 2P(x\_0)P(x\_1). /// $$ /// /// The above formula assumes that the pair is valid, \emph{i.e.} its first element is less than its /// second. The probability of an invalid pair is zero. /// /// `xs` must be infinite. #[inline] pub const fn random_ordered_unique_pairs(xs: I) -> RandomOrderedUniquePairs where I::Item: Ord, { RandomOrderedUniquePairs { xs } } /// Defines random ordered unique tuple generators. /// /// Malachite provides [`random_ordered_unique_pairs`], but you can also define /// `random_ordered_unique_triples`, `random_ordered_unique_quadruples`, and so on, in your program /// using the code below. /// /// See usage examples [here](self#random_ordered_unique_quadruples). /// /// ``` /// use malachite_base::random_ordered_unique_tuples; /// use malachite_base::sets::random::{ /// random_b_tree_sets_fixed_length, RandomBTreeSetsFixedLength, /// }; /// /// random_ordered_unique_tuples!( /// (pub(crate)), /// RandomOrderedUniqueTriples, /// 3, /// (I::Item, I::Item, I::Item), /// random_ordered_unique_triples, /// [0, 1, 2] /// ); /// random_ordered_unique_tuples!( /// (pub(crate)), /// RandomOrderedUniqueQuadruples, /// 4, /// (I::Item, I::Item, I::Item, I::Item), /// random_ordered_unique_quadruples, /// [0, 1, 2, 3] /// ); /// random_ordered_unique_tuples!( /// (pub(crate)), /// RandomOrderedUniqueQuintuples, /// 5, /// (I::Item, I::Item, I::Item, I::Item, I::Item), /// random_ordered_unique_quintuples, /// [0, 1, 2, 3, 4] /// ); /// random_ordered_unique_tuples!( /// (pub(crate)), /// RandomOrderedUniqueSextuples, /// 6, /// (I::Item, I::Item, I::Item, I::Item, I::Item, I::Item), /// random_ordered_unique_sextuples, /// [0, 1, 2, 3, 4, 5] /// ); /// random_ordered_unique_tuples!( /// (pub(crate)), /// RandomOrderedUniqueSeptuples, /// 7, /// ( /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item /// ), /// random_ordered_unique_septuples, /// [0, 1, 2, 3, 4, 5, 6] /// ); /// random_ordered_unique_tuples!( /// (pub(crate)), /// RandomOrderedUniqueOctuples, /// 8, /// ( /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item /// ), /// random_ordered_unique_octuples, /// [0, 1, 2, 3, 4, 5, 6, 7] /// ); /// ``` #[macro_export] macro_rules! random_ordered_unique_tuples { ( ($($vis:tt)*), $struct: ident, $k: expr, $out_t: ty, $fn: ident, [$($i: expr),*] ) => { // Generates random $n$-tuples using elements from a single iterator, where the tuples have // no repeated elements, and the elements are in ascending order. #[derive(Clone, Debug)] $($vis)* struct $struct where I::Item: Ord { xs: RandomBTreeSetsFixedLength, } impl Iterator for $struct where I::Item: Ord { type Item = $out_t; #[inline] fn next(&mut self) -> Option { let mut elements = self.xs.next().unwrap().into_iter(); Some(($(((elements.next().unwrap(), $i).0)),*)) } } // Generates random $n$-tuples using elements from a single iterator, where the tuples have // no repeated elements, and the elements are in ascending order. // // The input iterator must generate at least `len` distinct elements; otherwise, this // iterator will hang. // // $$ // P((x\_i)\_{i=0}^{n-1}) = n!\prod\_{i=0}^{n-1}P(x\_i). // $$ // // The above formula assumes that the tuple is valid, \emph{i.e.} its elements are strictly // increasing. The probability of an invalid tuple is zero. // // `xs` must be infinite. // // # Examples // See [here](self#random_ordered_unique_quadruples). #[inline] $($vis)* fn $fn(xs: I) -> $struct where I::Item: Ord, { $struct { xs: random_b_tree_sets_fixed_length($k, xs), } } } } /// Generates random pairs using elements from a single iterator, where the first element is not /// equal to the second. #[derive(Clone, Debug)] pub struct RandomUniquePairs where I::Item: Eq, { xs: I, } impl Iterator for RandomUniquePairs where I::Item: Eq, { type Item = (I::Item, I::Item); #[inline] fn next(&mut self) -> Option { let mut out_0 = None; let out_1; loop { let x = self.xs.next().unwrap(); if let Some(out_0) = out_0.as_ref() { if x != *out_0 { out_1 = x; break; } } else { out_0 = Some(x); } } Some((out_0.unwrap(), out_1)) } } /// Generates random pairs using elements from a single iterator, where the two elements of each /// pair are unequal. /// /// The input iterator must generate at least two distinct elements; otherwise, this iterator will /// hang. /// /// `xs` must be infinite. #[inline] pub const fn random_unique_pairs(xs: I) -> RandomUniquePairs where I::Item: Eq, { RandomUniquePairs { xs } } /// Defines random unique tuple generators. /// /// Malachite provides [`random_unique_pairs`], but you can also define `random_unique_triples`, /// `random_unique_quadruples`, and so on, in your program using the code below. /// /// See usage examples [here](self#random_unique_quadruples). /// /// ``` /// use malachite_base::random_unique_tuples; /// use std::collections::HashMap; /// use std::hash::Hash; /// /// random_unique_tuples!( /// (pub(crate)), /// RandomOrderedUniqueTriples, /// 3, /// (I::Item, I::Item, I::Item), /// random_unique_triples, /// [0, 1, 2] /// ); /// random_unique_tuples!( /// (pub(crate)), /// RandomOrderedUniqueQuadruples, /// 4, /// (I::Item, I::Item, I::Item, I::Item), /// random_unique_quadruples, /// [0, 1, 2, 3] /// ); /// random_unique_tuples!( /// (pub(crate)), /// RandomOrderedUniqueQuintuples, /// 5, /// (I::Item, I::Item, I::Item, I::Item, I::Item), /// random_unique_quintuples, /// [0, 1, 2, 3, 4] /// ); /// random_unique_tuples!( /// (pub(crate)), /// RandomOrderedUniqueSextuples, /// 6, /// (I::Item, I::Item, I::Item, I::Item, I::Item, I::Item), /// random_unique_sextuples, /// [0, 1, 2, 3, 4, 5] /// ); /// random_unique_tuples!( /// (pub(crate)), /// RandomOrderedUniqueSeptuples, /// 7, /// ( /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item /// ), /// random_unique_septuples, /// [0, 1, 2, 3, 4, 5, 6] /// ); /// random_unique_tuples!( /// (pub(crate)), /// RandomOrderedUniqueOctuples, /// 8, /// ( /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item, /// I::Item /// ), /// random_unique_octuples, /// [0, 1, 2, 3, 4, 5, 6, 7] /// ); /// ``` #[macro_export] macro_rules! random_unique_tuples { ( ($($vis:tt)*), $struct: ident, $k: expr, $out_t: ty, $fn: ident, [$($i: tt),*] ) => { #[derive(Clone, Debug)] $($vis)* struct $struct where I::Item: Eq + Hash { xs: I, } impl Iterator for $struct where I::Item: Eq + Hash { type Item = $out_t; #[inline] fn next(&mut self) -> Option { let mut xs_to_indices = HashMap::with_capacity($k); let mut i = 0; while i < $k { xs_to_indices .entry(self.xs.next().unwrap()) .or_insert_with(|| { i += 1; i - 1 }); } let mut out = ($((None, $i).0),*); for (x, i) in xs_to_indices { match i { $($i => {out.$i = Some(x)},)* _ => {} } } Some(($(out.$i.unwrap()),*)) } } #[inline] $($vis)* fn $fn(xs: I) -> $struct where I::Item: Eq + Hash, { $struct { xs } } } } malachite-base-0.4.16/src/unions/exhaustive.rs000064400000000000000000000263251046102023000174200ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::unions::Union2; /// Defines exhaustive union generators. /// /// Malachite provides [`lex_union2s`] and [`exhaustive_union2s`], but you can also define /// `lex_union3s`, `lex_union4s`, and so on, and `exhaustive_union3s`, `exhaustive_union4s`, and so /// on, in your program using the code below. The documentation for [`lex_union2s`] and /// [`exhaustive_union2s`] describes these other functions as well. /// /// See usage examples [here](self#lex_union2s) and [here](self#exhaustive_union2s). /// /// ``` /// use malachite_base::unions::UnionFromStrError; /// use malachite_base::{exhaustive_unions, union_struct}; /// use std::fmt::{self, Display, Formatter}; /// use std::str::FromStr; /// /// union_struct!( /// (pub(crate)), /// Union3, /// Union3, /// [A, A, 'A', a], /// [B, B, 'B', b], /// [C, C, 'C', c] /// ); /// union_struct!( /// (pub(crate)), /// Union4, /// Union4, /// [A, A, 'A', a], /// [B, B, 'B', b], /// [C, C, 'C', c], /// [D, D, 'D', d] /// ); /// union_struct!( /// (pub(crate)), /// Union5, /// Union5, /// [A, A, 'A', a], /// [B, B, 'B', b], /// [C, C, 'C', c], /// [D, D, 'D', d], /// [E, E, 'E', e] /// ); /// union_struct!( /// (pub(crate)), /// Union6, /// Union6, /// [A, A, 'A', a], /// [B, B, 'B', b], /// [C, C, 'C', c], /// [D, D, 'D', d], /// [E, E, 'E', e], /// [F, F, 'F', f] /// ); /// union_struct!( /// (pub(crate)), /// Union7, /// Union7, /// [A, A, 'A', a], /// [B, B, 'B', b], /// [C, C, 'C', c], /// [D, D, 'D', d], /// [E, E, 'E', e], /// [F, F, 'F', f], /// [G, G, 'G', g] /// ); /// union_struct!( /// (pub(crate)), /// Union8, /// Union8, /// [A, A, 'A', a], /// [B, B, 'B', b], /// [C, C, 'C', c], /// [D, D, 'D', d], /// [E, E, 'E', e], /// [F, F, 'F', f], /// [G, G, 'G', g], /// [H, H, 'H', h] /// ); /// /// exhaustive_unions!( /// (pub(crate)), /// Union3, /// LexUnion3s, /// ExhaustiveUnion3s, /// lex_union3s, /// exhaustive_union3s, /// 3, /// [0, X, I, A, xs, xs_done], /// [1, Y, J, B, ys, ys_done], /// [2, Z, K, C, zs, zs_done] /// ); /// exhaustive_unions!( /// (pub(crate)), /// Union4, /// LexUnion4s, /// ExhaustiveUnion4s, /// lex_union4s, /// exhaustive_union4s, /// 4, /// [0, X, I, A, xs, xs_done], /// [1, Y, J, B, ys, ys_done], /// [2, Z, K, C, zs, zs_done], /// [3, W, L, D, ws, ws_done] /// ); /// exhaustive_unions!( /// (pub(crate)), /// Union5, /// LexUnion5s, /// ExhaustiveUnion5s, /// lex_union5s, /// exhaustive_union5s, /// 5, /// [0, X, I, A, xs, xs_done], /// [1, Y, J, B, ys, ys_done], /// [2, Z, K, C, zs, zs_done], /// [3, W, L, D, ws, ws_done], /// [4, V, M, E, vs, vs_done] /// ); /// exhaustive_unions!( /// (pub(crate)), /// Union6, /// LexUnion6s, /// ExhaustiveUnion6s, /// lex_union6s, /// exhaustive_union6s, /// 6, /// [0, X, I, A, xs, xs_done], /// [1, Y, J, B, ys, ys_done], /// [2, Z, K, C, zs, zs_done], /// [3, W, L, D, ws, ws_done], /// [4, V, M, E, vs, vs_done], /// [5, U, N, F, us, us_done] /// ); /// exhaustive_unions!( /// (pub(crate)), /// Union7, /// LexUnion7s, /// ExhaustiveUnion7s, /// lex_union7s, /// exhaustive_union7s, /// 7, /// [0, X, I, A, xs, xs_done], /// [1, Y, J, B, ys, ys_done], /// [2, Z, K, C, zs, zs_done], /// [3, W, L, D, ws, ws_done], /// [4, V, M, E, vs, vs_done], /// [5, U, N, F, us, us_done], /// [6, T, O, G, ts, ts_done] /// ); /// exhaustive_unions!( /// (pub(crate)), /// Union8, /// LexUnion8s, /// ExhaustiveUnion8s, /// lex_union8s, /// exhaustive_union8s, /// 8, /// [0, X, I, A, xs, xs_done], /// [1, Y, J, B, ys, ys_done], /// [2, Z, K, C, zs, zs_done], /// [3, W, L, D, ws, ws_done], /// [4, V, M, E, vs, vs_done], /// [5, U, N, F, us, us_done], /// [6, T, O, G, ts, ts_done], /// [7, S, P, H, ss, ss_done] /// ); /// ``` #[macro_export] macro_rules! exhaustive_unions { ( ($($vis:tt)*), $union: ident, $lex_struct: ident, $exhaustive_struct: ident, $lex_fn: ident, $exhaustive_fn: ident, $n: expr, $([$i: expr, $t: ident, $it: ident, $variant: ident, $xs: ident, $xs_done:ident]),* ) => { /// This documentation applies not only to `LexUnion2s`, but also to `LexUnion3s`, /// `LexUnion4s`, and so on. See [`exhaustive_unions`] for more information. /// /// Generates all $n$-unions with elements from $n$ iterators, in lexicographic order. /// /// The order is lexicographic with respect to the order of the element iterators. All of /// the first variant's elements are generated first, followed by the second variant's /// elements, and so on. #[allow(dead_code)] #[derive(Clone, Debug)] $($vis)* struct $lex_struct<$($t, $it: Iterator),*> { i: u64, $($xs: $it,)* } impl<$($t, $it: Iterator),*> Iterator for $lex_struct<$($t, $it),*> { type Item = $union<$($t),*>; fn next(&mut self) -> Option { loop { match self.i { $( $i => { let next = self.$xs.next().map($union::$variant); if next.is_some() { return next; } }, )* _ => return None, } self.i += 1; } } } /// This documentation applies not only to `lex_union2s`, but also to `lex_union3s`, /// `lex_union4s`, and so on. See [`exhaustive_unions`] for more information. /// /// Generates all $n$-unions with elements from $n$ iterators, in lexicographic order. /// /// The order is lexicographic with respect to the order of the element iterators. All of /// the first variant's elements are generated first, followed by the second variant's /// elements, and so on. This means that all of the iterators, except possibly the last one, /// must be finite. For functions that support multiple infinite element iterators, try /// `exhaustive_union[n]s`. /// /// If the last iterator is finite, the output length is the sum of the lengths of all the /// input iterators. If the last iterator is infinite, the output is also infinite. /// /// If all of the input iterators are empty, the output is also empty. /// /// # Examples /// See [here](self#lex_union2s). #[allow(dead_code)] #[inline] $($vis)* const fn $lex_fn<$($t, $it: Iterator),*>($($xs: $it),*) -> $lex_struct<$($t, $it),*> { $lex_struct { i: 0, $($xs,)* } } /// This documentation applies not only to `ExhaustiveUnion2s`, but also to /// `ExhaustiveUnion3s`, `ExhaustiveUnion4s`, and so on. See [`exhaustive_unions`] for more /// information. /// /// Generates all $n$-unions with elements from $n$ iterators. #[allow(dead_code)] #[derive(Clone, Debug)] $($vis)* struct $exhaustive_struct<$($t, $it: Iterator),*> { done: bool, i: u64, $( $xs: $it, $xs_done: bool, )* } impl<$($t, $it: Iterator),*> Iterator for $exhaustive_struct<$($t, $it),*> { type Item = $union<$($t),*>; fn next(&mut self) -> Option { if self.done { None } else { let original_i = self.i; loop { let mut next = None; match self.i { $( $i => if !self.$xs_done { next = self.$xs.next().map($union::$variant); self.$xs_done = next.is_none(); }, )* _ => unreachable!(), } self.i += 1; if self.i == $n { self.i = 0; } if next.is_some() { return next; } if self.i == original_i { self.done = true; return None; } } } } } /// This documentation applies not only to `exhaustive_union2s`, but also to /// `exhaustive_union3s`, `exhaustive_union4s`, and so on. See [`exhaustive_unions`] for /// more information. /// /// Generates all $n$-unions with elements from $n$ iterators. /// /// The input iterators are advanced in a round-robin fashion. First an element from the /// first variant's iterator is selected, followed by an element from the second variant's /// iterator, and so on until an element has been selected from each iterator. Then another /// element from the first iterator is selected, etc. Iterators that have been exhausted are /// skipped. [`exhaustive_union2s`] behaves just like /// [`Itertools::interleave`]([`itertools::Itertools::interleave`]). /// /// If all input iterators are finite, the output length is the sum of the lengths of the /// iterators. If any iterator is infinite, the output is also infinite. /// /// If all of the input iterators are empty, the output is also empty. /// /// # Examples /// See [here](self#exhaustive_union2s). #[allow(dead_code)] #[inline] $($vis)* const fn $exhaustive_fn<$($t, $it: Iterator),*>($($xs: $it),*) -> $exhaustive_struct<$($t, $it),*> { $exhaustive_struct { done: false, i: 0, $( $xs, $xs_done: false, )* } } } } exhaustive_unions!( (pub), Union2, LexUnion2s, ExhaustiveUnion2s, lex_union2s, exhaustive_union2s, 2, [0, X, I, A, xs, xs_done], [1, Y, J, B, ys, ys_done] ); malachite-base-0.4.16/src/unions/mod.rs000064400000000000000000000177571046102023000160230ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use alloc::string::String; use alloc::string::ToString; use core::fmt::{self, Display, Formatter}; use core::str::FromStr; /// This is the error type for the unions' [`FromStr`] implementations. #[derive(Clone, Debug, Eq, Hash, PartialEq)] pub enum UnionFromStrError { /// For when the union's variant can't be determined. Generic(String), /// For when the union's variant can be determined but the wrapped value can't be parsed. Specific(E), } /// Defines unions. /// /// Malachite provides [`Union2`], but you can also define `Union3`, `Union4`, and so on, in your /// program using the code below. The documentation for [`Union2`] and describes these other `enum`s /// as well. /// /// ``` /// use malachite_base::union_struct; /// use malachite_base::unions::UnionFromStrError; /// use std::fmt::{self, Display, Formatter}; /// use std::str::FromStr; /// /// union_struct!( /// (pub(crate)), /// Union3, /// Union3, /// [A, A, 'A', a], /// [B, B, 'B', b], /// [C, C, 'C', c] /// ); /// union_struct!( /// (pub(crate)), /// Union4, /// Union4, /// [A, A, 'A', a], /// [B, B, 'B', b], /// [C, C, 'C', c], /// [D, D, 'D', d] /// ); /// union_struct!( /// (pub(crate)), /// Union5, /// Union5, /// [A, A, 'A', a], /// [B, B, 'B', b], /// [C, C, 'C', c], /// [D, D, 'D', d], /// [E, E, 'E', e] /// ); /// union_struct!( /// (pub(crate)), /// Union6, /// Union6, /// [A, A, 'A', a], /// [B, B, 'B', b], /// [C, C, 'C', c], /// [D, D, 'D', d], /// [E, E, 'E', e], /// [F, F, 'F', f] /// ); /// union_struct!( /// (pub(crate)), /// Union7, /// Union7, /// [A, A, 'A', a], /// [B, B, 'B', b], /// [C, C, 'C', c], /// [D, D, 'D', d], /// [E, E, 'E', e], /// [F, F, 'F', f], /// [G, G, 'G', g] /// ); /// union_struct!( /// (pub(crate)), /// Union8, /// Union8, /// [A, A, 'A', a], /// [B, B, 'B', b], /// [C, C, 'C', c], /// [D, D, 'D', d], /// [E, E, 'E', e], /// [F, F, 'F', f], /// [G, G, 'G', g], /// [H, H, 'H', h] /// ); /// ``` #[macro_export] macro_rules! union_struct { ( ($($vis:tt)*), $name: ident, $single: ty, $([$t: ident, $cons: ident, $c: expr, $x: ident]),* ) => { #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] /// This is a union, or sum type, of $n$ values. It is essentially a generic enum. $($vis)* enum $name<$($t),*> { $($cons($t)),* } impl $single { /// Given a union whose variants all have the same type, unwraps it into a value of that /// type. /// /// # Worst-case complexity /// Constant time and additional memory. /// /// # Examples /// See [here](self#unwrap). #[allow(clippy::missing_const_for_fn)] // Can't be const because of destructor $($vis)* fn unwrap(self) -> T { match self { $( $name::$cons($x) => $x ),* } } } impl<$($t: Display),*> Display for $name<$($t),*> { /// Converts a union to a [`String`]. /// /// # Examples /// See [here](self#fmt). #[inline] fn fmt(&self, f: &mut Formatter) -> fmt::Result { match self { $( $name::$cons($x) => f.write_fmt(format_args!("{}({})", $c, $x)) ),* } } } impl<$($t: FromStr),*> FromStr for $name<$($t),*> { type Err = UnionFromStrError<$name<$($t::Err),*>>; /// Converts a string to a union. /// /// If the string does not represent a valid union, an error value is returned. /// /// # Examples /// See [here](self#from_str). #[inline] fn from_str(src: &str) -> Result<$name<$($t),*>, Self::Err> { if src.is_empty() { return Err(UnionFromStrError::Generic(String::new())); } let (head, tail) = src.split_at(1); let tail = if let Some(tail) = tail.strip_prefix('(') { tail } else { return Err(UnionFromStrError::Generic(src.to_string())); }; let tail = if let Some(tail) = tail.strip_suffix(')') { tail } else { return Err(UnionFromStrError::Generic(src.to_string())); }; match head.chars().next().unwrap() { $( $c => $t::from_str(tail) .map($name::$cons) .map_err(|e| UnionFromStrError::Specific($name::$cons(e))), )* _ => Err(UnionFromStrError::Generic(src.to_string())) } } } } } union_struct!((pub), Union2, Union2, [A, A, 'A', a], [B, B, 'B', b]); /// Iterators that generate unions without repetition. /// /// # lex_union2s /// ``` /// use itertools::Itertools; /// use malachite_base::bools::exhaustive::exhaustive_bools; /// use malachite_base::unions::exhaustive::lex_union2s; /// use malachite_base::unions::Union2; /// /// let u2s = lex_union2s(exhaustive_bools(), 0..4).collect_vec(); /// assert_eq!( /// u2s.as_slice(), /// &[ /// Union2::A(false), /// Union2::A(true), /// Union2::B(0), /// Union2::B(1), /// Union2::B(2), /// Union2::B(3) /// ] /// ); /// ``` /// /// # exhaustive_union2s /// ``` /// use itertools::Itertools; /// use malachite_base::bools::exhaustive::exhaustive_bools; /// use malachite_base::unions::exhaustive::exhaustive_union2s; /// use malachite_base::unions::Union2; /// /// let u2s = exhaustive_union2s(exhaustive_bools(), 0..4).collect_vec(); /// assert_eq!( /// u2s.as_slice(), /// &[ /// Union2::A(false), /// Union2::B(0), /// Union2::A(true), /// Union2::B(1), /// Union2::B(2), /// Union2::B(3) /// ] /// ); /// ``` pub mod exhaustive; #[cfg(feature = "random")] /// Iterators that generate unions randomly. /// /// # random_union2s /// ``` /// use itertools::Itertools; /// use malachite_base::chars::random::random_char_inclusive_range; /// use malachite_base::num::random::random_unsigned_inclusive_range; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::unions::random::random_union2s; /// use malachite_base::unions::Union2; /// /// let us = random_union2s( /// EXAMPLE_SEED, /// &|seed| random_char_inclusive_range(seed, 'a', 'z'), /// &|seed| random_unsigned_inclusive_range::(seed, 1, 10), /// ); /// assert_eq!( /// us.take(20).collect_vec().as_slice(), /// &[ /// Union2::A('v'), /// Union2::B(3), /// Union2::A('c'), /// Union2::A('q'), /// Union2::A('i'), /// Union2::A('e'), /// Union2::A('p'), /// Union2::A('g'), /// Union2::A('s'), /// Union2::B(7), /// Union2::A('n'), /// Union2::A('t'), /// Union2::B(9), /// Union2::A('m'), /// Union2::A('z'), /// Union2::B(7), /// Union2::B(9), /// Union2::A('o'), /// Union2::A('m'), /// Union2::B(3), /// ], /// ); /// ``` pub mod random; malachite-base-0.4.16/src/unions/random.rs000064400000000000000000000146721046102023000165150ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::random::{random_unsigned_range, RandomUnsignedRange}; use crate::random::Seed; use crate::unions::Union2; /// Defines random union generators. /// /// Malachite provides [`random_union2s`], but you can also define `random_union3s`, /// `random_union4s`, and so on, in your program using the code below. The documentation for /// [`random_union2s`] describes these other functions as well. /// /// See usage examples [here](self#random_union2s). /// /// ``` /// use malachite_base::num::random::{random_unsigned_range, RandomUnsignedRange}; /// use malachite_base::random::Seed; /// use malachite_base::unions::UnionFromStrError; /// use malachite_base::{random_unions, union_struct}; /// use std::fmt::{self, Display, Formatter}; /// use std::str::FromStr; /// /// union_struct!( /// (pub(crate)), /// Union3, /// Union3, /// [A, A, 'A', a], /// [B, B, 'B', b], /// [C, C, 'C', c] /// ); /// union_struct!( /// (pub(crate)), /// Union4, /// Union4, /// [A, A, 'A', a], /// [B, B, 'B', b], /// [C, C, 'C', c], /// [D, D, 'D', d] /// ); /// union_struct!( /// (pub(crate)), /// Union5, /// Union5, /// [A, A, 'A', a], /// [B, B, 'B', b], /// [C, C, 'C', c], /// [D, D, 'D', d], /// [E, E, 'E', e] /// ); /// union_struct!( /// (pub(crate)), /// Union6, /// Union6, /// [A, A, 'A', a], /// [B, B, 'B', b], /// [C, C, 'C', c], /// [D, D, 'D', d], /// [E, E, 'E', e], /// [F, F, 'F', f] /// ); /// union_struct!( /// (pub(crate)), /// Union7, /// Union7, /// [A, A, 'A', a], /// [B, B, 'B', b], /// [C, C, 'C', c], /// [D, D, 'D', d], /// [E, E, 'E', e], /// [F, F, 'F', f], /// [G, G, 'G', g] /// ); /// union_struct!( /// (pub(crate)), /// Union8, /// Union8, /// [A, A, 'A', a], /// [B, B, 'B', b], /// [C, C, 'C', c], /// [D, D, 'D', d], /// [E, E, 'E', e], /// [F, F, 'F', f], /// [G, G, 'G', g], /// [H, H, 'H', h] /// ); /// /// random_unions!( /// (pub(crate)), /// Union3, /// RandomUnion3s, /// random_union3s, /// 3, /// [0, X, I, A, xs, xs_gen], /// [1, Y, J, B, ys, ys_gen], /// [2, Z, K, C, zs, zs_gen] /// ); /// random_unions!( /// (pub(crate)), /// Union4, /// RandomUnion4s, /// random_union4s, /// 4, /// [0, X, I, A, xs, xs_gen], /// [1, Y, J, B, ys, ys_gen], /// [2, Z, K, C, zs, zs_gen], /// [3, W, L, D, ws, ws_gen] /// ); /// random_unions!( /// (pub(crate)), /// Union5, /// RandomUnion5s, /// random_union5s, /// 5, /// [0, X, I, A, xs, xs_gen], /// [1, Y, J, B, ys, ys_gen], /// [2, Z, K, C, zs, zs_gen], /// [3, W, L, D, ws, ws_gen], /// [4, V, M, E, vs, vs_gen] /// ); /// random_unions!( /// (pub(crate)), /// Union6, /// RandomUnion6s, /// random_union6s, /// 6, /// [0, X, I, A, xs, xs_gen], /// [1, Y, J, B, ys, ys_gen], /// [2, Z, K, C, zs, zs_gen], /// [3, W, L, D, ws, ws_gen], /// [4, V, M, E, vs, vs_gen], /// [5, U, N, F, us, us_gen] /// ); /// random_unions!( /// (pub(crate)), /// Union7, /// RandomUnion7s, /// random_union7s, /// 7, /// [0, X, I, A, xs, xs_gen], /// [1, Y, J, B, ys, ys_gen], /// [2, Z, K, C, zs, zs_gen], /// [3, W, L, D, ws, ws_gen], /// [4, V, M, E, vs, vs_gen], /// [5, U, N, F, us, us_gen], /// [6, T, O, G, ts, ts_gen] /// ); /// random_unions!( /// (pub(crate)), /// Union8, /// RandomUnion8s, /// random_union8s, /// 8, /// [0, X, I, A, xs, xs_gen], /// [1, Y, J, B, ys, ys_gen], /// [2, Z, K, C, zs, zs_gen], /// [3, W, L, D, ws, ws_gen], /// [4, V, M, E, vs, vs_gen], /// [5, U, N, F, us, us_gen], /// [6, T, O, G, ts, ts_gen], /// [7, S, P, H, ss, ss_gen] /// ); /// ``` #[macro_export] macro_rules! random_unions { ( ($($vis:tt)*), $union: ident, $random_struct: ident, $random_fn: ident, $n: expr, $([$i: expr, $t: ident, $it: ident, $variant: ident, $xs: ident, $xs_gen: ident]),* ) => { /// This documentation applies not only to `RandomUnion2s`, but also to `RandomUnion3s`, /// `RandomUnion4s`, and so on. See [`random_unions`] for more information. /// /// Generates random $n$-unions with elements from $n$ iterators. #[derive(Clone, Debug)] $($vis)* struct $random_struct<$($t, $it: Iterator),*> { indices: RandomUnsignedRange, $($xs: $it,)* } impl<$($t, $it: Iterator),*> Iterator for $random_struct<$($t, $it),*> { type Item = $union<$($t),*>; fn next(&mut self) -> Option { match self.indices.next().unwrap() { $($i => self.$xs.next().map($union::$variant),)* _ => unreachable!(), } } } /// This documentation applies not only to `random_union2s`, but also to `random_union3s`, /// `random_union4s`, and so on. See [`random_unions`] for more information. /// /// Generates random $n$-unions with elements from $n$ iterators. /// /// The probability of a particular $n$-union being generated is the probability of its /// element divided by $n$. /// /// `xs`, `ys`, `zs`, ... must be infinite. /// /// # Examples /// See [here](self#random_union2s). $($vis)* fn $random_fn<$($t, $it: Iterator),*>( seed: Seed, $($xs_gen: &dyn Fn(Seed) -> $it),* ) -> $random_struct<$($t, $it),*> { $random_struct { indices: random_unsigned_range(seed.fork("indices"), 0, $n), $($xs: $xs_gen(seed.fork(stringify!($xs))),)* } } } } random_unions!( (pub), Union2, RandomUnion2s, random_union2s, 2, [0, X, I, A, xs, xs_gen], [1, Y, J, B, ys, ys_gen] ); malachite-base-0.4.16/src/vecs/exhaustive.rs000064400000000000000000004263531046102023000170520ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::iterators::bit_distributor::{BitDistributor, BitDistributorOutputType}; use crate::iterators::iterator_cache::IteratorCache; use crate::num::arithmetic::traits::CheckedPow; use crate::num::conversion::traits::{ExactFrom, SaturatingFrom, WrappingFrom}; use crate::num::exhaustive::{ exhaustive_unsigneds, primitive_int_increasing_inclusive_range, primitive_int_increasing_range, PrimitiveIntIncreasingRange, }; use crate::num::iterators::{ruler_sequence, RulerSequence}; use crate::num::logic::traits::SignificantBits; use crate::tuples::exhaustive::{ exhaustive_dependent_pairs, exhaustive_dependent_pairs_stop_after_empty_ys, lex_dependent_pairs_stop_after_empty_ys, ExhaustiveDependentPairs, ExhaustiveDependentPairsYsGenerator, LexDependentPairs, }; use crate::vecs::{exhaustive_vec_permutations, ExhaustiveVecPermutations}; use alloc::vec; use alloc::vec::Vec; use core::cmp::{ max, min, Ordering::{self, *}, }; use core::iter::{empty, once, FromIterator, Once, Zip}; use core::marker::PhantomData; use core::mem::take; use core::ops::RangeFrom; use itertools::{repeat_n, Itertools}; #[doc(hidden)] pub fn validate_oi_map>(max_input_index: usize, xs: I) { let mut oi_unique = hashbrown::HashSet::new(); oi_unique.extend(xs); let oi_sorted_unique = oi_unique.into_iter().sorted().collect_vec(); assert_eq!(oi_sorted_unique.len(), max_input_index + 1); assert_eq!(*oi_sorted_unique.first().unwrap(), 0); assert_eq!(*oi_sorted_unique.last().unwrap(), max_input_index); } #[doc(hidden)] #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] pub struct LexFixedLengthVecsOutput { pub input_index: usize, pub counter: usize, } /// Defines lexicographic fixed-length [`Vec`] generators. /// /// Malachite provides [`lex_vecs_length_2`] and [`lex_vecs_fixed_length_2_inputs`], but you can /// also define `lex_vecs_length_3`, `lex_vecs_length_4`, and so on, and /// `lex_vecs_fixed_length_3_inputs`, `lex_vecs_fixed_length_4_inputs`, and so on, in your program /// using the code below. The documentation for [`lex_vecs_length_2`] and /// [`lex_vecs_fixed_length_2_inputs`] describes these other functions as well. /// /// See usage examples [here](self#lex_vecs_length_2) and /// [here](self#lex_vecs_fixed_length_2_inputs). /// /// ``` /// use malachite_base::iterators::iterator_cache::IteratorCache; /// use malachite_base::lex_vecs_fixed_length; /// use malachite_base::vecs::exhaustive::{validate_oi_map, LexFixedLengthVecsOutput}; /// /// lex_vecs_fixed_length!( /// (pub(crate)), /// LexFixedLengthVecs3Inputs, /// lex_vecs_fixed_length_3_inputs, /// lex_vecs_length_3, /// [0, I, xs, xs_outputs], /// [1, J, ys, ys_outputs], /// [2, K, zs, zs_outputs] /// ); /// lex_vecs_fixed_length!( /// (pub(crate)), /// LexFixedLengthVecs4Inputs, /// lex_vecs_fixed_length_4_inputs, /// lex_vecs_length_4, /// [0, I, xs, xs_outputs], /// [1, J, ys, ys_outputs], /// [2, K, zs, zs_outputs], /// [3, L, ws, ws_outputs] /// ); /// lex_vecs_fixed_length!( /// (pub(crate)), /// LexFixedLengthVecs5Inputs, /// lex_vecs_fixed_length_5_inputs, /// lex_vecs_length_5, /// [0, I, xs, xs_outputs], /// [1, J, ys, ys_outputs], /// [2, K, zs, zs_outputs], /// [3, L, ws, ws_outputs], /// [4, M, vs, vs_outputs] /// ); /// lex_vecs_fixed_length!( /// (pub(crate)), /// LexFixedLengthVecs6Inputs, /// lex_vecs_fixed_length_6_inputs, /// lex_vecs_length_6, /// [0, I, xs, xs_outputs], /// [1, J, ys, ys_outputs], /// [2, K, zs, zs_outputs], /// [3, L, ws, ws_outputs], /// [4, M, vs, vs_outputs], /// [5, N, us, us_outputs] /// ); /// lex_vecs_fixed_length!( /// (pub(crate)), /// LexFixedLengthVecs7Inputs, /// lex_vecs_fixed_length_7_inputs, /// lex_vecs_length_7, /// [0, I, xs, xs_outputs], /// [1, J, ys, ys_outputs], /// [2, K, zs, zs_outputs], /// [3, L, ws, ws_outputs], /// [4, M, vs, vs_outputs], /// [5, N, us, us_outputs], /// [6, O, ts, ts_outputs] /// ); /// lex_vecs_fixed_length!( /// (pub(crate)), /// LexFixedLengthVecs8Inputs, /// lex_vecs_fixed_length_8_inputs, /// lex_vecs_length_8, /// [0, I, xs, xs_outputs], /// [1, J, ys, ys_outputs], /// [2, K, zs, zs_outputs], /// [3, L, ws, ws_outputs], /// [4, M, vs, vs_outputs], /// [5, N, us, us_outputs], /// [6, O, ts, ts_outputs], /// [7, P, ss, ss_outputs] /// ); /// ``` #[macro_export] macro_rules! lex_vecs_fixed_length { ( ($($vis:tt)*), $exhaustive_struct: ident, $exhaustive_custom_fn: ident, $exhaustive_1_to_1_fn: ident, $([$i: expr, $it: ident, $xs: ident, $xs_outputs: ident]),* ) => { /// This documentation applies not only to `LexFixedLengthVecs2Inputs`, but also to /// `LexFixedLengthVecs3Inputs`, `LexFixedLengthVecs4Inputs`, and so on. See /// [`lex_vecs_fixed_length`] for more information. /// /// Generates all [`Vec`]s of a given length with elements from $m$ iterators, in /// lexicographic order. /// /// The order is lexicographic with respect to the order of the element iterators. /// /// The fixed length $n$ of the [`Vec`]s is greater than or equal to $m$. #[derive(Clone, Debug)] $($vis)* struct $exhaustive_struct,)*> { first: bool, done: bool, $( $xs: IteratorCache<$it>, $xs_outputs: Vec, )* outputs: Vec, } impl,)*> $exhaustive_struct { fn increment_counters(&mut self) -> bool { for (i, output) in self.outputs.iter_mut().enumerate().rev() { output.counter += 1; let no_carry = match output.input_index { $( $i => self.$xs.get(output.counter).is_some(), )* _ => unreachable!(), }; if no_carry { return false; } else if i == 0 { return true; } output.counter = 0; } false } } impl,)*> Iterator for $exhaustive_struct { type Item = Vec; fn next(&mut self) -> Option> { if self.done { None } else if self.first { self.first = false; let mut next = vec![None; self.outputs.len()]; $( if let Some(x) = self.$xs.get(0) { for &output_index in &self.$xs_outputs { next[output_index] = Some(x.clone()); } } else { self.done = true; return None; } )* Some(next.into_iter().map(Option::unwrap).collect()) } else { if self.increment_counters() { self.done = true; return None; } let mut next = Vec::with_capacity(self.outputs.len()); for &output in &self.outputs { let x = match output.input_index { $( $i => self.$xs.get(output.counter), )* _ => unreachable!(), }; next.push(x.unwrap().clone()); } Some(next) } } } /// This documentation applies not only to `lex_vecs_fixed_length_2_inputs`, but also to /// `lex_vecs_fixed_length_3_inputs`, `lex_vecs_fixed_length_4_inputs`, and so on. See /// [`lex_vecs_fixed_length`] for more information. /// /// Generates all length-$n$ [`Vec`]s with elements from $m$ iterators, where $m \leq n$, in /// lexicographic order. /// /// The order is lexicographic with respect to the order of the element iterators. /// /// The `output_to_input_map` parameter defines which iterators are mapped to which slot in /// the output [`Vec`]s. The length of the output [`Vec`]s, $n$, is specified by the length /// of `output_to_input_map`. /// /// The $i$th element of `output_to_input_map` is an index from 0 to $m-1$ which specifies /// which iterator the $i$th output slot is populated with. Together, the elements must /// include all indices from 0 to $m-1$, inclusive, possibly with repetitions. /// /// Let `xs` be the input iterator mapped to the first slot of the output [`Vec`]s. All the /// input iterators, except possibly `xs`, must be finite. If `xs` is finite, the output /// length is the product of the lengths of all the input iterators. If `xs` is infinite, /// the output is also infinite. /// /// If any of the input iterators is empty, the output is also empty. /// /// # Examples /// See [here](self#lex_vecs_fixed_length_2_inputs). #[allow(dead_code)] $($vis)* fn $exhaustive_custom_fn,)*>( $($xs: $it,)* output_to_input_map: &[usize], ) -> $exhaustive_struct { $( let _max_input_index = $i; )* validate_oi_map(_max_input_index, output_to_input_map.iter().cloned()); $( let $xs_outputs = output_to_input_map .iter() .enumerate() .filter_map(|(o, i)| if *i == $i { Some(o) } else { None }) .collect(); )* $exhaustive_struct { first: true, done: false, $( $xs: IteratorCache::new($xs), $xs_outputs, )* outputs: output_to_input_map .iter() .map(|&i| LexFixedLengthVecsOutput { input_index: i, counter: 0, }) .collect(), } } /// This documentation applies not only to `lex_vecs_length_2`, but also to /// `lex_vecs_length_3`, `lex_vecs_length_4`, and so on. See [`lex_vecs_fixed_length`] for /// more information. /// /// Generates all length-$n$ [`Vec`]s with elements from $n$ iterators, in lexicographic /// order. /// /// The order is lexicographic with respect to the order of the element iterators. /// /// All of `ys`, `zs`, ... (but not necessarily `xs`) must be finite. If `xs` is finite, the /// output length is the product of the lengths of all the input iterators. If `xs` is /// infinite, the output is also infinite. /// /// If any of `xs`, `ys`, `zs`, ... is empty, the output is also empty. /// /// # Examples /// See [here](self#lex_vecs_length_2). #[allow(dead_code)] #[inline] $($vis)* fn $exhaustive_1_to_1_fn,)*>( $($xs: $it,)* ) -> $exhaustive_struct { $exhaustive_custom_fn($($xs,)* &[$($i,)*]) } } } lex_vecs_fixed_length!( (pub), LexFixedLengthVecs2Inputs, lex_vecs_fixed_length_2_inputs, lex_vecs_length_2, [0, I, xs, xs_outputs], [1, J, ys, ys_outputs] ); #[doc(hidden)] #[derive(Clone, Debug)] pub struct LexFixedLengthVecsFromSingleG where I::Item: Clone, { first: bool, done: bool, xs: IteratorCache, counters: Vec, phantom: PhantomData<*const I::Item>, } impl LexFixedLengthVecsFromSingleG where I::Item: Clone, { fn increment_counters(&mut self) -> bool { for (i, counter) in self.counters.iter_mut().enumerate().rev() { *counter += 1; if self.xs.get(*counter).is_some() { return false; } else if i == 0 { return true; } *counter = 0; } false } } impl Iterator for LexFixedLengthVecsFromSingleG where I::Item: Clone, { type Item = Vec; fn next(&mut self) -> Option> { if self.done { None } else if self.first { self.first = false; if let Some(x) = self.xs.get(0) { Some(repeat_n(x, self.counters.len()).cloned().collect()) } else { self.done = true; None } } else if self.increment_counters() { self.done = true; None } else { let xs = &mut self.xs; Some( self.counters .iter() .map(|&c| xs.get(c).unwrap().clone()) .collect(), ) } } } fn lex_vecs_fixed_length_from_single_g( len: u64, xs: I, ) -> LexFixedLengthVecsFromSingleG where I::Item: Clone, { LexFixedLengthVecsFromSingleG { first: true, done: false, xs: IteratorCache::new(xs), counters: vec![0; usize::exact_from(len)], phantom: PhantomData, } } /// Generates all [`Vec`]s of a given length with elements from a single iterator, in lexicographic /// order. /// /// The order is lexicographic with respect to the order of the element iterator. /// /// This `struct` is created by the [`lex_vecs_fixed_length_from_single`]; see its documentation for /// more. #[derive(Clone, Debug)] pub enum LexFixedLengthVecsFromSingle where I::Item: Clone, { Zero(Once>), One(I), GreaterThanOne(LexFixedLengthVecsFromSingleG), } impl Iterator for LexFixedLengthVecsFromSingle where I::Item: Clone, { type Item = Vec; fn next(&mut self) -> Option> { match self { LexFixedLengthVecsFromSingle::Zero(ref mut xs) => xs.next(), LexFixedLengthVecsFromSingle::One(ref mut xs) => xs.next().map(|x| vec![x]), LexFixedLengthVecsFromSingle::GreaterThanOne(ref mut xs) => xs.next(), } } } /// Generates all [`Vec`]s of a given length with elements from a single iterator, in lexicographic /// order. /// /// The order is lexicographic with respect to the order of the element iterator. /// /// `xs` must be finite. /// /// The output length is $k^n$, where $k$ is `xs.count()` and $n$ is `len`. /// /// If `len` is 0, the output consists of one empty [`Vec`]. /// /// If `xs` is empty, the output is also empty, unless `len` is 0. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::vecs::exhaustive::lex_vecs_fixed_length_from_single; /// /// let xss = lex_vecs_fixed_length_from_single(2, 0..4).collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[0, 0], /// &[0, 1], /// &[0, 2], /// &[0, 3], /// &[1, 0], /// &[1, 1], /// &[1, 2], /// &[1, 3], /// &[2, 0], /// &[2, 1], /// &[2, 2], /// &[2, 3], /// &[3, 0], /// &[3, 1], /// &[3, 2], /// &[3, 3] /// ] /// ); /// ``` pub fn lex_vecs_fixed_length_from_single( len: u64, xs: I, ) -> LexFixedLengthVecsFromSingle where I::Item: Clone, { match len { 0 => LexFixedLengthVecsFromSingle::Zero(once(Vec::new())), 1 => LexFixedLengthVecsFromSingle::One(xs), len => LexFixedLengthVecsFromSingle::GreaterThanOne(lex_vecs_fixed_length_from_single_g( len, xs, )), } } /// Defines exhaustive fixed-length [`Vec`] generators. /// /// Malachite provides [`exhaustive_vecs_length_2`] and [`exhaustive_vecs_fixed_length_2_inputs`], /// but you can also define `exhaustive_vecs_length_3`, `exhaustive_vecs_length_4`, and so on, and /// `exhaustive_vecs_fixed_length_3_inputs`, `exhaustive_vecs_fixed_length_4_inputs`, and so on, in /// your program using the code below. The documentation for [`exhaustive_vecs_length_2`] and /// [`exhaustive_vecs_fixed_length_2_inputs`] describes these other functions as well. /// /// See usage examples [here](self#exhaustive_vecs_length_2) and /// [here](self#exhaustive_vecs_fixed_length_2_inputs). /// /// ``` /// use itertools::Itertools; /// use malachite_base::exhaustive_vecs_fixed_length; /// use malachite_base::iterators::bit_distributor::{BitDistributor, BitDistributorOutputType}; /// use malachite_base::iterators::iterator_cache::IteratorCache; /// use malachite_base::num::conversion::traits::{ExactFrom, WrappingFrom}; /// use malachite_base::num::logic::traits::SignificantBits; /// use malachite_base::vecs::exhaustive::validate_oi_map; /// use std::cmp::max; /// /// exhaustive_vecs_fixed_length!( /// (pub(crate)), /// ExhaustiveFixedLengthVecs3Inputs, /// exhaustive_vecs_fixed_length_3_inputs, /// exhaustive_vecs_length_3, /// [0, I, xs, xs_done, xs_outputs], /// [1, J, ys, ys_done, ys_outputs], /// [2, K, zs, zs_done, zs_outputs] /// ); /// exhaustive_vecs_fixed_length!( /// (pub(crate)), /// ExhaustiveFixedLengthVecs4Inputs, /// exhaustive_vecs_fixed_length_4_inputs, /// exhaustive_vecs_length_4, /// [0, I, xs, xs_done, xs_outputs], /// [1, J, ys, ys_done, ys_outputs], /// [2, K, zs, zs_done, zs_outputs], /// [3, L, ws, ws_done, ws_outputs] /// ); /// exhaustive_vecs_fixed_length!( /// (pub(crate)), /// ExhaustiveFixedLengthVecs5Inputs, /// exhaustive_vecs_fixed_length_5_inputs, /// exhaustive_vecs_length_5, /// [0, I, xs, xs_done, xs_outputs], /// [1, J, ys, ys_done, ys_outputs], /// [2, K, zs, zs_done, zs_outputs], /// [3, L, ws, ws_done, ws_outputs], /// [4, M, vs, vs_done, vs_outputs] /// ); /// exhaustive_vecs_fixed_length!( /// (pub(crate)), /// ExhaustiveFixedLengthVecs6Inputs, /// exhaustive_vecs_fixed_length_6_inputs, /// exhaustive_vecs_length_6, /// [0, I, xs, xs_done, xs_outputs], /// [1, J, ys, ys_done, ys_outputs], /// [2, K, zs, zs_done, zs_outputs], /// [3, L, ws, ws_done, ws_outputs], /// [4, M, vs, vs_done, vs_outputs], /// [5, N, us, us_done, us_outputs] /// ); /// exhaustive_vecs_fixed_length!( /// (pub(crate)), /// ExhaustiveFixedLengthVecs7, /// exhaustive_vecs_fixed_length_7_inputs, /// exhaustive_vecs_length_7, /// [0, I, xs, xs_done, xs_outputs], /// [1, J, ys, ys_done, ys_outputs], /// [2, K, zs, zs_done, zs_outputs], /// [3, L, ws, ws_done, ws_outputs], /// [4, M, vs, vs_done, vs_outputs], /// [5, N, us, us_done, us_outputs], /// [6, O, ts, ts_done, ts_outputs] /// ); /// exhaustive_vecs_fixed_length!( /// (pub(crate)), /// ExhaustiveFixedLengthVecs8Inputs, /// exhaustive_vecs_fixed_length_8_inputs, /// exhaustive_vecs_length_8, /// [0, I, xs, xs_done, xs_outputs], /// [1, J, ys, ys_done, ys_outputs], /// [2, K, zs, zs_done, zs_outputs], /// [3, L, ws, ws_done, ws_outputs], /// [4, M, vs, vs_done, vs_outputs], /// [5, N, us, us_done, us_outputs], /// [6, O, ts, ts_done, ts_outputs], /// [7, P, ss, ss_done, ss_outputs] /// ); /// ``` #[macro_export] macro_rules! exhaustive_vecs_fixed_length { ( ($($vis:tt)*), $exhaustive_struct: ident, $exhaustive_custom_fn: ident, $exhaustive_1_to_1_fn: ident, $([$i: expr, $it: ident, $xs: ident, $xs_done: ident, $outputs: ident]),* ) => { /// This documentation applies not only to `ExhaustiveFixedLengthVecs2Inputs`, but also to /// `ExhaustiveFixedLengthVecs3Inputs`, `ExhaustiveFixedLengthVecs4Inputs`, and so on. See /// [`exhaustive_vecs_fixed_length`] for more information. /// /// Generates all [`Vec`]s of a given length with elements from $m$ iterators. /// /// The fixed length $n$ of the [`Vec`]s is greater than or equal to $m$. #[derive(Clone, Debug)] $($vis)* struct $exhaustive_struct,)*> { i: u64, len: u64, limit: Option, distributor: BitDistributor, $( $xs: IteratorCache<$it>, $xs_done: bool, $outputs: Vec, )* } impl,)*> $exhaustive_struct { fn try_getting_limit(&mut self) { let mut all_limits_known = true; $( if let Some(xs_len) = self.$xs.known_len() { if xs_len == 0 { self.limit = Some(0); return; } } else { all_limits_known = false; } )* if !all_limits_known { return; } let mut product = 1u64; $( let xs_len = u64::exact_from(self.$xs.known_len().unwrap()); for _ in 0..self.$outputs.len() { if let Some(new_product) = product.checked_mul(xs_len) { product = new_product; } else { return; } } )* self.limit = Some(product); } } impl,)*> Iterator for $exhaustive_struct { type Item = Vec; fn next(&mut self) -> Option> { if Some(self.i) == self.limit { None } else { if self.i == u64::MAX { panic!("Too many iterations"); } loop { let mut all_are_valid = true; $( for &output_index in &self.$outputs { if self.$xs.get( self.distributor.get_output(output_index) ).is_none() { all_are_valid = false; break; } } if !all_are_valid { if self.i == 0 { self.limit = Some(0); return None; } else if !self.$xs_done { self.try_getting_limit(); if Some(self.i) == self.limit { return None; } self.$xs_done = true; let xs_len = self.$xs.known_len().unwrap(); // xs_len > 0 at this point self.distributor.set_max_bits( &self.$outputs, max( 1, usize::wrapping_from((xs_len - 1).significant_bits()) ) ); } else { self.distributor.increment_counter(); } continue; } )* break; } let mut out = vec![None; usize::exact_from(self.len)]; $( for &output_index in &self.$outputs { let x = self.$xs.get(self.distributor.get_output(output_index)); out[output_index] = Some(x.unwrap().clone()); } )* self.i += 1; self.distributor.increment_counter(); Some(out.into_iter().map(Option::unwrap).collect()) } } } /// This documentation applies not only to `exhaustive_vecs_fixed_length_2_inputs`, but also /// to `exhaustive_vecs_fixed_length_3_inputs`, `exhaustive_vecs_fixed_length_4_inputs`, and /// so on. See [`exhaustive_vecs_fixed_length`] for more information. /// /// Generates all [`Vec`]s of a given length with elements from $m$ iterators, where $m \leq /// n$. /// /// The `output_types` parameter defines which iterators are mapped to which slot in the /// output [`Vec`]s, and how quickly each output slot advances through its iterator. The /// length of the output [`Vec`]s, $n$, is specified by the length of `output_types`. /// /// The $i$th element of `output_types` is a pair of [`BitDistributorOutputType`] and /// `usize`. The [`BitDistributorOutputType`] determines how quickly the $i$th output slot /// advances through its iterator; see the [`BitDistributor`] documentation for a /// description of the different types. The `usize` is an index from 0 to $m-1$ which /// specifies which iterator the $i$th output slot is populated with. Together, the `usize`s /// must include all indices from 0 to $m-1$, inclusive, possibly with repetitions. /// /// If all of `xs`, `ys`, `zs`, ... are finite, the output length is the product of their /// lengths. If any of `xs`, `ys`, `zs`, ... are infinite, the output is also infinite. /// /// If any of `xs`, `ys`, `zs`, ... is empty, the output is also empty. /// /// # Panics /// Panics if the `usize`s in `output_types` do not include all indices from 0 to $m-1$, /// inclusive, possibly with repetitions. In particular, the length of `output_types` must /// be at least $m$. /// /// # Examples /// See [here](self#exhaustive_vecs_fixed_length_2_inputs). #[allow(dead_code)] $($vis)* fn $exhaustive_custom_fn,)*> ( $($xs: $it,)* output_types: &[(BitDistributorOutputType, usize)], ) -> $exhaustive_struct { $( let _max_input_index = $i; )* let output_to_input_map = output_types.iter().map(|(_, i)| *i).collect_vec(); validate_oi_map(_max_input_index, output_to_input_map.iter().cloned()); $exhaustive_struct { i: 0, len: u64::exact_from(output_types.len()), limit: None, distributor: BitDistributor::new(output_types.iter().map(|(ot, _)| *ot) .collect_vec().as_slice()), $( $xs: IteratorCache::new($xs), $xs_done: false, $outputs: output_types.iter().enumerate() .filter_map(|(o, (_, i))| if *i == $i { Some(o) } else { None }).collect(), )* } } /// This documentation applies not only to `exhaustive_vecs_length_2`, but also to /// `exhaustive_vecs_length_3`, `exhaustive_vecs_length_4`, and so on. See /// [`exhaustive_vecs_fixed_length`] for more information. /// /// Generates all length-$n$ [`Vec`]s with elements from $n$ iterators. /// /// If all of `xs`, `ys`, `zs`, ... are finite, the output length is the product of their /// lengths. If any of `xs`, `ys`, `zs`, ... are infinite, the output is also infinite. /// /// If any of `xs`, `ys`, `zs`, ... is empty, the output is also empty. /// /// # Examples /// See [here](self#exhaustive_vecs_length_2). #[allow(dead_code)] #[inline] $($vis)* fn $exhaustive_1_to_1_fn,)*> ( $($xs: $it,)* ) -> $exhaustive_struct { $exhaustive_custom_fn( $($xs,)* &[$((BitDistributorOutputType::normal(1), $i),)*] ) } } } exhaustive_vecs_fixed_length!( (pub), ExhaustiveFixedLengthVecs2Inputs, exhaustive_vecs_fixed_length_2_inputs, exhaustive_vecs_length_2, [0, I, xs, xs_done, xs_outputs], [1, J, ys, ys_done, ys_outputs] ); #[doc(hidden)] #[derive(Clone, Debug)] pub struct ExhaustiveFixedLengthVecs1InputG where I::Item: Clone, { i: u64, len: u64, limit: Option, distributor: BitDistributor, xs: IteratorCache, xs_done: bool, phantom: PhantomData<*const I::Item>, } impl Iterator for ExhaustiveFixedLengthVecs1InputG where I::Item: Clone, { type Item = Vec; fn next(&mut self) -> Option> { if Some(self.i) == self.limit { None } else { assert!(self.i != u64::MAX, "Too many iterations"); loop { let mut all_are_valid = true; for i in 0..usize::exact_from(self.len) { if self.xs.get(self.distributor.get_output(i)).is_none() { all_are_valid = false; break; } } if all_are_valid { break; } else if !self.xs_done { let xs_len = self.xs.known_len().unwrap(); self.limit = CheckedPow::checked_pow(u64::exact_from(xs_len), self.len); if Some(self.i) == self.limit { return None; } self.xs_done = true; // xs_len > 0 at this point self.distributor.set_max_bits( &[0], max(1, usize::wrapping_from((xs_len - 1).significant_bits())), ); } else { self.distributor.increment_counter(); } } let out = (0..usize::exact_from(self.len)) .map(|i| self.xs.get(self.distributor.get_output(i)).unwrap().clone()) .collect(); self.i += 1; self.distributor.increment_counter(); Some(out) } } } fn exhaustive_vecs_fixed_length_1_input_g( xs: I, output_types: &[BitDistributorOutputType], ) -> ExhaustiveFixedLengthVecs1InputG where I::Item: Clone, { ExhaustiveFixedLengthVecs1InputG { i: 0, len: u64::exact_from(output_types.len()), limit: None, distributor: BitDistributor::new(output_types), xs: IteratorCache::new(xs), xs_done: false, phantom: PhantomData, } } /// Generates all [`Vec`]s of a given length with elements from a single iterator. /// /// This `struct` is created by [`exhaustive_vecs_fixed_length_from_single`]; see its documentation /// for more. #[allow(clippy::large_enum_variant)] #[derive(Clone, Debug)] pub enum ExhaustiveFixedLengthVecs1Input where I::Item: Clone, { Zero(Once>), One(I), GreaterThanOne(ExhaustiveFixedLengthVecs1InputG), } impl Iterator for ExhaustiveFixedLengthVecs1Input where I::Item: Clone, { type Item = Vec; fn next(&mut self) -> Option> { match self { ExhaustiveFixedLengthVecs1Input::Zero(ref mut xs) => xs.next(), ExhaustiveFixedLengthVecs1Input::One(ref mut xs) => xs.next().map(|x| vec![x]), ExhaustiveFixedLengthVecs1Input::GreaterThanOne(ref mut xs) => xs.next(), } } } /// Generates all length-$n$ [`Vec`]s with elements from a single iterator. /// /// This function differs from [`exhaustive_vecs_fixed_length_from_single`] in that different /// [`BitDistributorOutputType`]s may be specified for each output element. /// /// The $i$th element of `output_types` is a [`BitDistributorOutputType`] that determines how /// quickly the $i$th output slot advances through the iterator; see the [`BitDistributor`] /// documentation for a description of the different types. The length of the output [`Vec`]s, $n$, /// is specified by the length of `output_types`. /// /// If `xs` is finite, the output length is $k^n$, where $k$ is `xs.count()` and $n$ is `len`. If /// `xs` is infinite, the output is also infinite. /// /// If `len` is 0, the output consists of one empty [`Vec`]. /// /// If `xs` is empty, the output is also empty, unless `len` is 0. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::chars::exhaustive::exhaustive_ascii_chars; /// use malachite_base::iterators::bit_distributor::BitDistributorOutputType; /// use malachite_base::vecs::exhaustive::exhaustive_vecs_fixed_length_1_input; /// /// // We are generating length-3 [`Vec`]s of chars using one input iterator, which produces all /// // ASCII chars. The third element has a tiny output type, so it will grow more slowly than the /// // other two elements (though it doesn't look that way from the first few [`Vec`]s). /// let xss = exhaustive_vecs_fixed_length_1_input( /// exhaustive_ascii_chars(), /// &[ /// BitDistributorOutputType::normal(1), /// BitDistributorOutputType::normal(1), /// BitDistributorOutputType::tiny(), /// ], /// ); /// let xss_prefix = xss.take(20).collect_vec(); /// assert_eq!( /// xss_prefix /// .iter() /// .map(Vec::as_slice) /// .collect_vec() /// .as_slice(), /// &[ /// &['a', 'a', 'a'], /// &['a', 'a', 'b'], /// &['a', 'a', 'c'], /// &['a', 'a', 'd'], /// &['a', 'b', 'a'], /// &['a', 'b', 'b'], /// &['a', 'b', 'c'], /// &['a', 'b', 'd'], /// &['a', 'a', 'e'], /// &['a', 'a', 'f'], /// &['a', 'a', 'g'], /// &['a', 'a', 'h'], /// &['a', 'b', 'e'], /// &['a', 'b', 'f'], /// &['a', 'b', 'g'], /// &['a', 'b', 'h'], /// &['b', 'a', 'a'], /// &['b', 'a', 'b'], /// &['b', 'a', 'c'], /// &['b', 'a', 'd'] /// ] /// ); /// ``` pub fn exhaustive_vecs_fixed_length_1_input( xs: I, output_types: &[BitDistributorOutputType], ) -> ExhaustiveFixedLengthVecs1Input where I::Item: Clone, { match output_types.len() { 0 => ExhaustiveFixedLengthVecs1Input::Zero(once(Vec::new())), 1 => ExhaustiveFixedLengthVecs1Input::One(xs), _ => ExhaustiveFixedLengthVecs1Input::GreaterThanOne( exhaustive_vecs_fixed_length_1_input_g(xs, output_types), ), } } /// Generates all [`Vec`]s of a given length with elements from a single iterator. /// /// If `xs` is finite, the output length is $\ell^n$, where $\ell$ is `xs.count()` and $n$ is `len`. /// If `xs` is infinite, the output is also infinite. /// /// If `len` is 0, the output consists of one empty [`Vec`]. /// /// If `xs` is empty, the output is also empty, unless `len` is 0. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::vecs::exhaustive::exhaustive_vecs_fixed_length_from_single; /// /// let xss = exhaustive_vecs_fixed_length_from_single(2, 0..4).collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[0, 0], /// &[0, 1], /// &[1, 0], /// &[1, 1], /// &[0, 2], /// &[0, 3], /// &[1, 2], /// &[1, 3], /// &[2, 0], /// &[2, 1], /// &[3, 0], /// &[3, 1], /// &[2, 2], /// &[2, 3], /// &[3, 2], /// &[3, 3] /// ] /// ); /// ``` #[inline] pub fn exhaustive_vecs_fixed_length_from_single( len: u64, xs: I, ) -> ExhaustiveFixedLengthVecs1Input where I::Item: Clone, { exhaustive_vecs_fixed_length_1_input( xs, &vec![BitDistributorOutputType::normal(1); usize::exact_from(len)], ) } #[derive(Clone, Debug)] struct LexVecsGenerator> { ys: J, } impl> ExhaustiveDependentPairsYsGenerator, LexFixedLengthVecsFromSingle> for LexVecsGenerator { #[inline] fn get_ys(&self, &x: &u64) -> LexFixedLengthVecsFromSingle { lex_vecs_fixed_length_from_single(x, self.ys.clone()) } } #[inline] const fn shortlex_vecs_from_element_iterator_helper< T: Clone, I: Iterator, J: Clone + Iterator, >( xs: I, ys: J, ) -> LexDependentPairs, LexVecsGenerator, I, LexFixedLengthVecsFromSingle> { lex_dependent_pairs_stop_after_empty_ys(xs, LexVecsGenerator { ys }) } /// Generates all [`Vec`]s with elements from a specified iterator and with lengths from another /// iterator. #[derive(Clone, Debug)] pub struct ShortlexVecs, J: Clone + Iterator>( LexDependentPairs, LexVecsGenerator, I, LexFixedLengthVecsFromSingle>, ); impl, J: Clone + Iterator> Iterator for ShortlexVecs { type Item = Vec; #[inline] fn next(&mut self) -> Option> { self.0.next().map(|p| p.1) } } /// Generates all [`Vec`]s with elements from a specified iterator and with lengths from another /// iterator. /// /// The length-generating iterator is `xs`, and the element-generating iterator is `ys`. /// /// If the provided lengths are $\ell_0, \ell_1, \ell_2, \ldots$, then first all [`Vec`]s with /// length $\ell_0$ will be generated, in lexicographic order; then all [`Vec`]s with length /// $\ell_2$, and so on. If the lengths iterator has repetitions, then the generated [`Vec`]s will /// be repeated too. /// /// `ys` must be finite; if it's infinite, the output will never get past the first nonzero $\ell$. /// /// There's one quirk if `ys` is empty: then the iterator will stop as soon as it encounters a /// nonzero $\ell$, even if there are zeros later on. This prevents the iterator hanging when given /// an empty `ys` and lengths $0, 1, 2, \ldots$. /// /// If `ys` is empty, the output length is the amount of zeros generated by `xs` before the first /// nonzero length. If `ys` is nonempty and `xs` is infinite, the output is infinite. Finally, if /// `ys` is nonempty and `xs` is finite, the output length is /// $$ /// \sum_{k=0}^{m-1} n^{\ell_k}, /// $$ /// where $n$ is `ys.count()` and $m$ is `xs.count()`. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::bools::exhaustive::exhaustive_bools; /// use malachite_base::nevers::nevers; /// use malachite_base::vecs::exhaustive::shortlex_vecs_from_length_iterator; /// /// let xss = shortlex_vecs_from_length_iterator([2, 1, 2].iter().cloned(), exhaustive_bools()) /// .collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[false, false][..], /// &[false, true], /// &[true, false], /// &[true, true], /// &[false], /// &[true], /// &[false, false], /// &[false, true], /// &[true, false], /// &[true, true] /// ] /// ); /// /// let xss = /// shortlex_vecs_from_length_iterator([0, 0, 1, 0].iter().cloned(), nevers()).collect_vec(); /// // Stops after first empty ys /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[&[], &[]] /// ); /// ``` #[inline] pub const fn shortlex_vecs_from_length_iterator< T: Clone, I: Iterator, J: Clone + Iterator, >( xs: I, ys: J, ) -> ShortlexVecs { ShortlexVecs(shortlex_vecs_from_element_iterator_helper(xs, ys)) } /// Generates [`Vec`]s with elements from a specified iterator, in shortlex order. /// /// Shortlex order means that the [`Vec`]s are output from shortest to longest, and [`Vec`]s of the /// same length are output in lexicographic order with respect to the ordering of the [`Vec`] /// elements specified by the input iterator. /// /// `xs` must be finite; if it's infinite, only [`Vec`]s of length 0 and 1 are ever produced. /// /// If `xs` is empty, the output length is 1; otherwise, the output is infinite. /// /// The lengths of the output [`Vec`]s grow logarithmically. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::bools::exhaustive::exhaustive_bools; /// use malachite_base::vecs::exhaustive::shortlex_vecs; /// /// let bss = shortlex_vecs(exhaustive_bools()).take(20).collect_vec(); /// assert_eq!( /// bss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[][..], /// &[false], /// &[true], /// &[false, false], /// &[false, true], /// &[true, false], /// &[true, true], /// &[false, false, false], /// &[false, false, true], /// &[false, true, false], /// &[false, true, true], /// &[true, false, false], /// &[true, false, true], /// &[true, true, false], /// &[true, true, true], /// &[false, false, false, false], /// &[false, false, false, true], /// &[false, false, true, false], /// &[false, false, true, true], /// &[false, true, false, false] /// ] /// ); /// ``` #[inline] pub fn shortlex_vecs( xs: I, ) -> ShortlexVecs, I> where I::Item: Clone, { shortlex_vecs_from_length_iterator(exhaustive_unsigneds(), xs) } /// Generates all [`Vec`]s with a minimum length and with elements from a specified iterator, in /// shortlex order. /// /// Shortlex order means that the [`Vec`]s are output from shortest to longest, and [`Vec`]s of the /// same length are output in lexicographic order with respect to the ordering of the [`Vec`] /// elements specified by the input iterator. /// /// `xs` must be finite; if it's infinite, only [`Vec`]s of length `min_length` (or 0 and 1, if /// `min_length` is 0) are ever produced. /// /// If `xs` is empty and `min_length` is 0, the output length is 1; if `xs` is empty and /// `min_length` is greater than 0, the output is empty; otherwise, the output is infinite. /// /// The lengths of the output [`Vec`]s grow logarithmically. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::bools::exhaustive::exhaustive_bools; /// use malachite_base::vecs::exhaustive::shortlex_vecs_min_length; /// /// let bss = shortlex_vecs_min_length(2, exhaustive_bools()) /// .take(20) /// .collect_vec(); /// assert_eq!( /// bss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[false, false][..], /// &[false, true], /// &[true, false], /// &[true, true], /// &[false, false, false], /// &[false, false, true], /// &[false, true, false], /// &[false, true, true], /// &[true, false, false], /// &[true, false, true], /// &[true, true, false], /// &[true, true, true], /// &[false, false, false, false], /// &[false, false, false, true], /// &[false, false, true, false], /// &[false, false, true, true], /// &[false, true, false, false], /// &[false, true, false, true], /// &[false, true, true, false], /// &[false, true, true, true] /// ] /// ); /// ``` #[inline] pub fn shortlex_vecs_min_length( min_length: u64, xs: I, ) -> ShortlexVecs, I> where I::Item: Clone, { shortlex_vecs_from_length_iterator( primitive_int_increasing_inclusive_range(min_length, u64::MAX), xs, ) } /// Generates all [`Vec`]s with lengths in $[a, b)$ and with elements from a specified iterator, in /// shortlex order. /// /// Shortlex order means that the [`Vec`]s are output from shortest to longest, and [`Vec`]s of the /// same length are output in lexicographic order with respect to the ordering of the [`Vec`] /// elements specified by the input iterator. /// /// `xs` must be finite; if it's infinite and $a < b$, only [`Vec`]s of length `a` (or 0 and 1, if /// `a` is 0) are ever produced. /// /// The output length is /// $$ /// \sum_{k=a}^{b-1} n^k, /// $$ /// where $k$ is `xs.count()`. /// /// The lengths of the output [`Vec`]s grow logarithmically. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::bools::exhaustive::exhaustive_bools; /// use malachite_base::vecs::exhaustive::shortlex_vecs_length_range; /// /// let bss = shortlex_vecs_length_range(2, 4, exhaustive_bools()).collect_vec(); /// assert_eq!( /// bss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[false, false][..], /// &[false, true], /// &[true, false], /// &[true, true], /// &[false, false, false], /// &[false, false, true], /// &[false, true, false], /// &[false, true, true], /// &[true, false, false], /// &[true, false, true], /// &[true, true, false], /// &[true, true, true] /// ] /// ); /// ``` #[inline] pub fn shortlex_vecs_length_range( a: u64, mut b: u64, xs: I, ) -> ShortlexVecs, I> where I::Item: Clone, { if a > b { b = a; } shortlex_vecs_from_length_iterator(primitive_int_increasing_range(a, b), xs) } /// Generates all [`Vec`]s with lengths in $[a, b]$ and with elements from a specified iterator, in /// shortlex order. /// /// Shortlex order means that the [`Vec`]s are output from shortest to longest, and [`Vec`]s of the /// same length are output in lexicographic order with respect to the ordering of the [`Vec`] /// elements specified by the input iterator. /// /// `xs` must be finite; if it's infinite, only [`Vec`]s of length `a` (or 0 and 1, if `a` is 0) are /// ever produced. /// /// The output length is /// $$ /// \sum_{k=a}^b n^k, /// $$ /// where $k$ is `xs.count()`. /// /// The lengths of the output [`Vec`]s grow logarithmically. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::bools::exhaustive::exhaustive_bools; /// use malachite_base::vecs::exhaustive::shortlex_vecs_length_inclusive_range; /// /// let bss = shortlex_vecs_length_inclusive_range(2, 3, exhaustive_bools()).collect_vec(); /// assert_eq!( /// bss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[false, false][..], /// &[false, true], /// &[true, false], /// &[true, true], /// &[false, false, false], /// &[false, false, true], /// &[false, true, false], /// &[false, true, true], /// &[true, false, false], /// &[true, false, true], /// &[true, true, false], /// &[true, true, true] /// ] /// ); /// ``` #[inline] pub fn shortlex_vecs_length_inclusive_range( mut a: u64, mut b: u64, xs: I, ) -> ShortlexVecs, I> where I::Item: Clone, { if a > b { a = 1; b = 0; } shortlex_vecs_from_length_iterator(primitive_int_increasing_range(a, b.saturating_add(1)), xs) } #[doc(hidden)] #[derive(Clone, Debug)] struct ExhaustiveVecsGenerator> { ys: J, } impl> ExhaustiveDependentPairsYsGenerator, ExhaustiveFixedLengthVecs1Input> for ExhaustiveVecsGenerator { #[inline] fn get_ys(&self, &x: &u64) -> ExhaustiveFixedLengthVecs1Input { exhaustive_vecs_fixed_length_1_input( self.ys.clone(), &vec![BitDistributorOutputType::normal(1); usize::exact_from(x)], ) } } #[inline] const fn exhaustive_vecs_from_element_iterator_helper< T: Clone, I: Iterator, J: Clone + Iterator, >( xs: I, ys: J, ) -> ExhaustiveDependentPairs< u64, Vec, RulerSequence, ExhaustiveVecsGenerator, I, ExhaustiveFixedLengthVecs1Input, > { exhaustive_dependent_pairs_stop_after_empty_ys( ruler_sequence(), xs, ExhaustiveVecsGenerator { ys }, ) } /// Generates all [`Vec`]s with elements from a specified iterator and with lengths from another /// iterator. #[derive(Clone, Debug)] pub struct ExhaustiveVecs, J: Clone + Iterator>( ExhaustiveDependentPairs< u64, Vec, RulerSequence, ExhaustiveVecsGenerator, I, ExhaustiveFixedLengthVecs1Input, >, ); impl, J: Clone + Iterator> Iterator for ExhaustiveVecs { type Item = Vec; #[inline] fn next(&mut self) -> Option> { self.0.next().map(|p| p.1) } } /// Generates all [`Vec`]s with elements from a specified iterator and with lengths from another /// iterator. /// /// The length-generating iterator is `xs`, and the element-generating iterator is `ys`. /// /// If the lengths iterator has repetitions, then the generated [`Vec`]s will be repeated too. /// /// There's one quirk if `ys` is empty: then the iterator will stop at some point after it /// encounters a nonzero $\ell$, even if there are zeros later on. This prevents the iterator /// hanging when given an empty `ys` and lengths $0, 1, 2, \ldots$. /// /// - If `ys` is empty, the output length is finite. /// - If `ys` is infinite, the output length is infinite. /// - If `ys` is nonempty and finite, and `xs` is infinite, the output is infinite. /// - If `ys` is nonempty and finite, and `xs` is finite, the output length is /// $$ /// \sum_{k=0}^{m-1} n^{\ell_k}, /// $$ /// where $n$ is `ys.count()` and $m$ is `xs.count()`. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::bools::exhaustive::exhaustive_bools; /// use malachite_base::nevers::nevers; /// use malachite_base::vecs::exhaustive::exhaustive_vecs_from_length_iterator; /// /// let xss = exhaustive_vecs_from_length_iterator([2, 1, 2].iter().cloned(), exhaustive_bools()) /// .collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[false, false][..], /// &[false], /// &[false, true], /// &[false, false], /// &[true, false], /// &[true], /// &[true, true], /// &[false, true], /// &[true, false], /// &[true, true] /// ] /// ); /// /// let xss = /// exhaustive_vecs_from_length_iterator([0, 0, 1, 0].iter().cloned(), nevers()).collect_vec(); /// // Stops at some point after first empty ys /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[&[], &[]] /// ); /// ``` #[inline] pub const fn exhaustive_vecs_from_length_iterator< T: Clone, I: Iterator, J: Clone + Iterator, >( lengths: I, xs: J, ) -> ExhaustiveVecs { ExhaustiveVecs(exhaustive_vecs_from_element_iterator_helper(lengths, xs)) } /// Generates all [`Vec`]s with elements from a specified iterator. /// /// If `xs` is empty, the output length is 1; otherwise, the output is infinite. /// /// The lengths of the output [`Vec`]s grow logarithmically. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::exhaustive::exhaustive_unsigneds; /// use malachite_base::vecs::exhaustive::exhaustive_vecs; /// /// let xss = exhaustive_vecs(exhaustive_unsigneds::()) /// .take(20) /// .collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[][..], /// &[0], /// &[1], /// &[0, 0, 0], /// &[2], /// &[0, 0], /// &[3], /// &[0, 0, 0, 0], /// &[4], /// &[0, 1], /// &[5], /// &[0, 0, 1], /// &[6], /// &[1, 0], /// &[7], /// &[0, 0, 0, 0, 0], /// &[8], /// &[1, 1], /// &[9], /// &[0, 1, 0] /// ] /// ); /// ``` #[inline] pub fn exhaustive_vecs( xs: I, ) -> ExhaustiveVecs, I> where I::Item: Clone, { exhaustive_vecs_from_length_iterator(exhaustive_unsigneds(), xs) } /// Generates all [`Vec`]s with a minimum length and with elements from a specified iterator. /// /// If `xs` is empty and `min_length` is 0, the output length is 1; if `xs` is empty and /// `min_length` is greater than 0, the output is empty; otherwise, the output is infinite. /// /// The lengths of the output [`Vec`]s grow logarithmically. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::exhaustive::exhaustive_unsigneds; /// use malachite_base::vecs::exhaustive::exhaustive_vecs_min_length; /// /// let xss = exhaustive_vecs_min_length(2, exhaustive_unsigneds::()) /// .take(20) /// .collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[0, 0][..], /// &[0, 0, 0], /// &[0, 1], /// &[0, 0, 0, 0], /// &[1, 0], /// &[0, 0, 1], /// &[1, 1], /// &[0, 0, 0, 0, 0], /// &[0, 2], /// &[0, 1, 0], /// &[0, 3], /// &[0, 0, 0, 1], /// &[1, 2], /// &[0, 1, 1], /// &[1, 3], /// &[0, 0, 0, 0, 0, 0], /// &[2, 0], /// &[1, 0, 0], /// &[2, 1], /// &[0, 0, 1, 0] /// ] /// ); /// ``` #[inline] pub fn exhaustive_vecs_min_length( min_length: u64, xs: I, ) -> ExhaustiveVecs, I> where I::Item: Clone, { exhaustive_vecs_from_length_iterator( primitive_int_increasing_inclusive_range(min_length, u64::MAX), xs, ) } /// Generates all [`Vec`]s with lengths in $[a, b)$ and with elements from a specified iterator. /// /// - If $a \geq b$, the output length is 0. /// - If $a = 0$ and $b = 1$, the output length is 1. /// - If $a < b$, $b > 1$, and `xs` is infinite, the output length is infinite. /// - If `xs` is finite, the output length is /// $$ /// \sum_{k=a}^{b-1} n^k, /// $$ /// where $k$ is `xs.count()`. /// /// The lengths of the output [`Vec`]s grow logarithmically. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::exhaustive::exhaustive_unsigneds; /// use malachite_base::vecs::exhaustive::exhaustive_vecs_length_range; /// /// let xss = exhaustive_vecs_length_range(2, 4, exhaustive_unsigneds::()) /// .take(20) /// .collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[0, 0][..], /// &[0, 0, 0], /// &[0, 1], /// &[1, 0], /// &[1, 1], /// &[0, 0, 1], /// &[0, 2], /// &[0, 1, 0], /// &[0, 3], /// &[0, 1, 1], /// &[1, 2], /// &[1, 3], /// &[2, 0], /// &[1, 0, 0], /// &[2, 1], /// &[3, 0], /// &[3, 1], /// &[1, 0, 1], /// &[2, 2], /// &[2, 3] /// ] /// ); /// ``` #[inline] pub fn exhaustive_vecs_length_range( a: u64, mut b: u64, xs: I, ) -> ExhaustiveVecs, I> where I::Item: Clone, { if a > b { b = a; } exhaustive_vecs_from_length_iterator(primitive_int_increasing_range(a, b), xs) } /// Generates all [`Vec`]s with lengths in $[a, b]$ and with elements from a specified iterator. /// /// - If $a > b$, the output length is 0. /// - If $a = b = 0$, the output length is 1. /// - If $a < b$, $b > 0$, and `xs` is infinite, the output length is infinite. /// - If `xs` is finite, the output length is /// $$ /// \sum_{k=a}^b n^k, /// $$ /// where $k$ is `xs.count()`. /// /// The lengths of the output [`Vec`]s grow logarithmically. /// /// # Panics /// Panics if $a > b$. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::exhaustive::exhaustive_unsigneds; /// use malachite_base::vecs::exhaustive::exhaustive_vecs_length_inclusive_range; /// /// let xss = exhaustive_vecs_length_inclusive_range(2, 4, exhaustive_unsigneds::()) /// .take(20) /// .collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[0, 0][..], /// &[0, 0, 0], /// &[0, 1], /// &[0, 0, 0, 0], /// &[1, 0], /// &[0, 0, 1], /// &[1, 1], /// &[0, 2], /// &[0, 3], /// &[0, 1, 0], /// &[1, 2], /// &[0, 0, 0, 1], /// &[1, 3], /// &[0, 1, 1], /// &[2, 0], /// &[1, 0, 0], /// &[2, 1], /// &[1, 0, 1], /// &[3, 0], /// &[0, 0, 1, 0] /// ] /// ); /// ``` #[inline] pub fn exhaustive_vecs_length_inclusive_range( mut a: u64, mut b: u64, xs: I, ) -> ExhaustiveVecs, I> where I::Item: Clone, { if a > b { a = 1; b = 0; } exhaustive_vecs_from_length_iterator(primitive_int_increasing_range(a, b.saturating_add(1)), xs) } /// Generates all collections of elements from an iterator, where the collections are of a fixed /// length, have no repetitions, and are ordered the same way as in the iterator. #[derive(Clone, Debug)] pub struct LexFixedLengthOrderedUniqueCollections> where I::Item: Clone, { first: bool, done: bool, xs: IteratorCache, indices: Vec, phantom_i: PhantomData<*const I::Item>, phantom_c: PhantomData<*const C>, } impl> LexFixedLengthOrderedUniqueCollections where I::Item: Clone, { pub fn new(k: u64, xs: I) -> LexFixedLengthOrderedUniqueCollections { LexFixedLengthOrderedUniqueCollections { first: true, done: false, xs: IteratorCache::new(xs), indices: (0..usize::exact_from(k)).collect(), phantom_i: PhantomData, phantom_c: PhantomData, } } } #[doc(hidden)] pub fn fixed_length_ordered_unique_indices_helper( n: usize, k: usize, indices: &mut [usize], ) -> bool { let mut expected_j = n - 1; let mut i = k - 1; // Find longest suffix of the form [..., n - 3, n - 2, n - 1]. After this loop, i is the index // right before this longest suffix. loop { if expected_j != indices[i] { break; } if i == 0 { return true; } i -= 1; expected_j -= 1; } let mut j = indices[i] + 1; for index in &mut indices[i..] { *index = j; j += 1; } false } impl> Iterator for LexFixedLengthOrderedUniqueCollections where I::Item: Clone, { type Item = C; fn next(&mut self) -> Option { if self.done { return None; } let k = self.indices.len(); if self.first { self.first = false; self.xs.get(k); if let Some(n) = self.xs.known_len() { if n < k { self.done = true; return None; } } } else { if k == 0 { self.done = true; return None; } if let Some(n) = self.xs.known_len() { if fixed_length_ordered_unique_indices_helper(n, k, &mut self.indices) { self.done = true; return None; } } else { *self.indices.last_mut().unwrap() += 1; } } if let Some(&last_index) = self.indices.last() { // Give known len a chance to be set self.xs.get(last_index + 1); } Some( self.indices .iter() .map(|&i| self.xs.assert_get(i).clone()) .collect(), ) } } /// Generates [`Vec`]s of a given length with elements from a single iterator, such that each /// [`Vec`] has no repeated elements, and the elements in each [`Vec`] are ordered the same way as /// they are in the source iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The order is lexicographic with respect to the order of the element iterator. /// /// If $k$ is 0, the output length is 1. /// /// If $k$ is nonzero and the input iterator is infinite, the output length is also infinite. /// /// If $k$ is nonzero and the input iterator length is $n$, the output length is $\binom{n}{k}$. /// /// If $k$ is 0, the output consists of one empty [`Vec`]. /// /// If `xs` is empty, the output is also empty, unless $k$ is 0. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::vecs::exhaustive::lex_ordered_unique_vecs_fixed_length; /// /// let xss = lex_ordered_unique_vecs_fixed_length(4, 1..=6).collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[1, 2, 3, 4], /// &[1, 2, 3, 5], /// &[1, 2, 3, 6], /// &[1, 2, 4, 5], /// &[1, 2, 4, 6], /// &[1, 2, 5, 6], /// &[1, 3, 4, 5], /// &[1, 3, 4, 6], /// &[1, 3, 5, 6], /// &[1, 4, 5, 6], /// &[2, 3, 4, 5], /// &[2, 3, 4, 6], /// &[2, 3, 5, 6], /// &[2, 4, 5, 6], /// &[3, 4, 5, 6] /// ] /// ); /// ``` #[inline] pub fn lex_ordered_unique_vecs_fixed_length( k: u64, xs: I, ) -> LexFixedLengthOrderedUniqueCollections> where I::Item: Clone, { LexFixedLengthOrderedUniqueCollections::new(k, xs) } /// Generates all collections of elements from an iterator in shortlex order, where the collections /// have no repetitions and are ordered the same way as in the iterator. #[derive(Clone)] pub struct ShortlexOrderedUniqueCollections> where I::Item: Clone, { current_len: u64, max_len: u64, xs: I, current_xss: LexFixedLengthOrderedUniqueCollections, } impl> ShortlexOrderedUniqueCollections where I::Item: Clone, { pub(crate) fn new(a: u64, b: u64, xs: I) -> ShortlexOrderedUniqueCollections { ShortlexOrderedUniqueCollections { current_len: a, max_len: b, xs: xs.clone(), current_xss: LexFixedLengthOrderedUniqueCollections::new(a, xs), } } } impl> Iterator for ShortlexOrderedUniqueCollections where I::Item: Clone, { type Item = C; fn next(&mut self) -> Option { if self.current_len > self.max_len { return None; } if let Some(next) = self.current_xss.next() { Some(next) } else { self.current_len += 1; if self.current_len > self.max_len { return None; } self.current_xss = LexFixedLengthOrderedUniqueCollections { first: true, done: false, xs: IteratorCache::new(self.xs.clone()), indices: (0..usize::exact_from(self.current_len)).collect(), phantom_i: PhantomData, phantom_c: PhantomData, }; if let Some(next) = self.current_xss.next() { Some(next) } else { // Prevent any further iteration self.max_len = 0; self.current_len = 1; None } } } } /// Generates [`Vec`]s with elements from a single iterator, such that each [`Vec`] has no repeated /// elements, and the elements in each [`Vec`] are ordered the same way as they are in the source /// iterator. /// /// The [`Vec`]s are generated in order of increasing length, and within each length they are /// ordered lexicographically with respect to the order of the element iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, [`Vec`]s of length 2 and above will never be /// generated. /// /// If the input iterator is infinite, the output length is also infinite. /// /// If the input iterator length is $n$, the output length is $2^n$. /// /// If `xs` is empty, the output consists of a single empty [`Vec`]. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::vecs::exhaustive::shortlex_ordered_unique_vecs; /// /// let xss = shortlex_ordered_unique_vecs(1..=4).collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[][..], /// &[1], /// &[2], /// &[3], /// &[4], /// &[1, 2], /// &[1, 3], /// &[1, 4], /// &[2, 3], /// &[2, 4], /// &[3, 4], /// &[1, 2, 3], /// &[1, 2, 4], /// &[1, 3, 4], /// &[2, 3, 4], /// &[1, 2, 3, 4] /// ] /// ); /// ``` #[inline] pub fn shortlex_ordered_unique_vecs( xs: I, ) -> ShortlexOrderedUniqueCollections> where I::Item: Clone, { shortlex_ordered_unique_vecs_length_inclusive_range(0, u64::MAX, xs) } /// Generates [`Vec`]s with a mininum length, with elements from a single iterator, such that each /// [`Vec`] has no repeated elements, and the elements in each [`Vec`] are ordered the same way as /// they are in the source iterator. /// /// The [`Vec`]s are generated in order of increasing length, and within each length they are /// ordered lexicographically with respect to the order of the element iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, [`Vec`]s of length `\max(2, \ell + 1)` and /// above will never be generated. /// /// If the input iterator is infinite, the output length is also infinite. /// /// If the input iterator length is $n$ and the `min_length` is $\ell$, the output length is /// $$ /// \sum_{i=\ell}^n \binom{n}{i}. /// $$ /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::vecs::exhaustive::shortlex_ordered_unique_vecs_min_length; /// /// let xss = shortlex_ordered_unique_vecs_min_length(2, 1..=4).collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[1, 2][..], /// &[1, 3], /// &[1, 4], /// &[2, 3], /// &[2, 4], /// &[3, 4], /// &[1, 2, 3], /// &[1, 2, 4], /// &[1, 3, 4], /// &[2, 3, 4], /// &[1, 2, 3, 4] /// ] /// ); /// ``` #[inline] pub fn shortlex_ordered_unique_vecs_min_length( min_length: u64, xs: I, ) -> ShortlexOrderedUniqueCollections> where I::Item: Clone, { shortlex_ordered_unique_vecs_length_inclusive_range(min_length, u64::MAX, xs) } /// Generates [`Vec`]s, with lengths in a range $[a, b)$, with elements from a single iterator, such /// that each [`Vec`] has no repeated elements, and the elements in each [`Vec`] are ordered the /// same way as they are in the source iterator. /// /// The [`Vec`]s are generated in order of increasing length, and within each length they are /// ordered lexicographically with respect to the order of the element iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, [`Vec`]s of length `\max(2, a + 1)` and above /// will never be generated. /// /// If $a \leq b$, the output is empty. /// /// If $a = 0$ and $b = 1$, the output consists of a single empty [`Vec`]. /// /// If the input iterator is infinite and $0 < a < b$, the output length is also infinite. /// /// If the input iterator length is $n$, the output length is /// $$ /// \sum_{i=a}^{b - 1} \binom{n}{i}. /// $$ /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::vecs::exhaustive::shortlex_ordered_unique_vecs_length_range; /// /// let xss = shortlex_ordered_unique_vecs_length_range(2, 4, 1..=4).collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[1, 2][..], /// &[1, 3], /// &[1, 4], /// &[2, 3], /// &[2, 4], /// &[3, 4], /// &[1, 2, 3], /// &[1, 2, 4], /// &[1, 3, 4], /// &[2, 3, 4], /// ] /// ); /// ``` #[inline] pub fn shortlex_ordered_unique_vecs_length_range( mut a: u64, mut b: u64, xs: I, ) -> ShortlexOrderedUniqueCollections> where I::Item: Clone, { if b == 0 { // Transform an empty (x, 0) range into (2, 1), which is also empty but doesn't cause // overflow a = 2; b = 1; } shortlex_ordered_unique_vecs_length_inclusive_range(a, b - 1, xs) } /// Generates [`Vec`]s, with lengths in a range $[a, b]$, with elements from a single iterator, such /// that each [`Vec`] has no repeated elements, and the elements in each [`Vec`] are ordered the /// same way as they are in the source iterator. /// /// The [`Vec`]s are generated in order of increasing length, and within each length they are /// ordered lexicographically with respect to the order of the element iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, [`Vec`]s of length `\max(2, a + 1)` and above /// will never be generated. /// /// If $a < b$, the output is empty. /// /// If $a = b = 0$, the output consists of a single empty [`Vec`]. /// /// If the input iterator is infinite and $0 < a \leq b$, the output length is also infinite. /// /// If the input iterator length is $n$, the output length is /// $$ /// \sum_{i=a}^b \binom{n}{i}. /// $$ /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::vecs::exhaustive::shortlex_ordered_unique_vecs_length_inclusive_range; /// /// let xss = shortlex_ordered_unique_vecs_length_inclusive_range(2, 3, 1..=4).collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[1, 2][..], /// &[1, 3], /// &[1, 4], /// &[2, 3], /// &[2, 4], /// &[3, 4], /// &[1, 2, 3], /// &[1, 2, 4], /// &[1, 3, 4], /// &[2, 3, 4], /// ] /// ); /// ``` #[inline] pub fn shortlex_ordered_unique_vecs_length_inclusive_range( a: u64, b: u64, xs: I, ) -> ShortlexOrderedUniqueCollections> where I::Item: Clone, { ShortlexOrderedUniqueCollections::new(a, b, xs) } /// Generates all collections of elements from an iterator in lexicographic order, where the /// collections have no repetitions and are ordered the same way as in the iterator. #[derive(Clone, Debug)] pub struct LexOrderedUniqueCollections> where I::Item: Clone, { done: bool, first: bool, min_len: usize, max_len: usize, xs: IteratorCache, indices: Vec, phantom_i: PhantomData<*const I::Item>, phantom_c: PhantomData<*const C>, } impl> LexOrderedUniqueCollections where I::Item: Clone, { pub(crate) fn new(a: u64, b: u64, xs: I) -> LexOrderedUniqueCollections { LexOrderedUniqueCollections { done: a > b, first: true, min_len: usize::exact_from(a), max_len: usize::exact_from(b), xs: IteratorCache::new(xs), indices: (0..usize::exact_from(a)).collect(), phantom_i: PhantomData, phantom_c: PhantomData, } } } impl> Iterator for LexOrderedUniqueCollections where I::Item: Clone, { type Item = C; fn next(&mut self) -> Option { if self.done { return None; } let k = self.indices.len(); if self.first { self.first = false; self.xs.get(k); if let Some(n) = self.xs.known_len() { if n < k { self.done = true; return None; } } } else if k == 0 { if self.xs.get(0).is_none() { self.done = true; return None; } self.indices.push(0); } else { let last_i = *self.indices.last().unwrap(); let next_i = last_i + 1; if k < self.max_len && self.xs.get(next_i).is_some() { // For example, if xs is [0, 1, 2, 3] and max_len is 4, then the next set of indices // after [0, 1] is [0, 1, 2]. self.indices.push(next_i); } else if k == self.min_len { // For example, if xs is [0, 1, 2, 3] and min_len is 2, then the next set of indices // after [1, 3] is [2, 3]. if let Some(n) = self.xs.known_len() { if fixed_length_ordered_unique_indices_helper(n, k, &mut self.indices) { self.done = true; return None; } } else { *self.indices.last_mut().unwrap() += 1; } } else if self.xs.get(next_i).is_some() { // For example, if xs is [0, 1, 2, 3] and max_len is 3, then the next set of indices // after [1, 2, 3] is [1, 2, 4]. *self.indices.last_mut().unwrap() = next_i; } else { let x = self.indices.pop(); if let Some(last) = self.indices.last_mut() { // For example, if xs is [0, 1, 2, 3] and max_len is 3, then the next set of // indices after [0, 1, 2] is [0, 1, 3]. *last += 1; } else { let next_x = x.unwrap() + 1; if self.xs.get(next_x).is_none() { // For example, if xs is [0, 1, 2, 3], then nothing comes after the indices // [3]. self.done = true; return None; } // For example, if xs is [0, 1, 2, 3] and max_len is 1, then the next set of // indices after [0] is [1]. self.indices.push(next_x); } } } if let Some(&last_index) = self.indices.last() { // Give known len a chance to be set self.xs.get(last_index + 1); } Some( self.indices .iter() .map(|&i| self.xs.assert_get(i).clone()) .collect(), ) } } /// Generates [`Vec`]s with elements from a single iterator, such that each [`Vec`] has no repeated /// elements, and the elements in each [`Vec`] are ordered the same way as they are in the source /// iterator. /// /// The [`Vec`]s are ordered lexicographically with respect to the order of the element iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, only prefixes of the iterator will be /// generated. /// /// If the input iterator is infinite, the output length is also infinite. /// /// If the input iterator length is $n$, the output length is $2^n$. /// /// If `xs` is empty, the output consists of a single empty [`Vec`]. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::vecs::exhaustive::lex_ordered_unique_vecs; /// /// let xss = lex_ordered_unique_vecs(1..=4).collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[][..], /// &[1], /// &[1, 2], /// &[1, 2, 3], /// &[1, 2, 3, 4], /// &[1, 2, 4], /// &[1, 3], /// &[1, 3, 4], /// &[1, 4], /// &[2], /// &[2, 3], /// &[2, 3, 4], /// &[2, 4], /// &[3], /// &[3, 4], /// &[4] /// ] /// ); /// ``` #[inline] pub fn lex_ordered_unique_vecs( xs: I, ) -> LexOrderedUniqueCollections> where I::Item: Clone, { lex_ordered_unique_vecs_length_inclusive_range(0, u64::MAX, xs) } /// Generates [`Vec`]s with a mininum length, with elements from a single iterator, such that each /// [`Vec`] has no repeated elements, and the elements in each [`Vec`] are ordered the same way as /// they are in the source iterator. /// /// The [`Vec`]s are ordered lexicographically with respect to the order of the element iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, only prefixes of the iterator will be /// generated. /// /// If the input iterator is infinite, the output length is also infinite. /// /// If the input iterator length is $n$ and the `min_length` is $\ell$, the output length is /// $$ /// \sum_{i=\ell}^n \binom{n}{i}. /// $$ /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::vecs::exhaustive::lex_ordered_unique_vecs_min_length; /// /// let xss = lex_ordered_unique_vecs_min_length(2, 1..=4).collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[1, 2][..], /// &[1, 2, 3], /// &[1, 2, 3, 4], /// &[1, 2, 4], /// &[1, 3], /// &[1, 3, 4], /// &[1, 4], /// &[2, 3], /// &[2, 3, 4], /// &[2, 4], /// &[3, 4], /// ] /// ); /// ``` #[inline] pub fn lex_ordered_unique_vecs_min_length( min_length: u64, xs: I, ) -> LexOrderedUniqueCollections> where I::Item: Clone, { lex_ordered_unique_vecs_length_inclusive_range(min_length, u64::MAX, xs) } /// Generates [`Vec`]s, with lengths in a range $[a, b)$, with elements from a single iterator, such /// that each [`Vec`] has no repeated elements, and the elements in each [`Vec`] are ordered the /// same way as they are in the source iterator. /// /// The [`Vec`]s are ordered lexicographically with respect to the order of the element iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, only prefixes of the iterator will be /// generated. /// /// If $a \leq b$, the output is empty. /// /// If $a = 0$ and $b = 1$, the output consists of a single empty [`Vec`]. /// /// If the input iterator is infinite and $0 < a < b$, the output length is also infinite. /// /// If the input iterator length is $n$, the output length is /// $$ /// \sum_{i=a}^{b - 1} \binom{n}{i}. /// $$ /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::vecs::exhaustive::lex_ordered_unique_vecs_length_range; /// /// let xss = lex_ordered_unique_vecs_length_range(2, 4, 1..=4).collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[1, 2][..], /// &[1, 2, 3], /// &[1, 2, 4], /// &[1, 3], /// &[1, 3, 4], /// &[1, 4], /// &[2, 3], /// &[2, 3, 4], /// &[2, 4], /// &[3, 4], /// ] /// ); /// ``` #[inline] pub fn lex_ordered_unique_vecs_length_range( mut a: u64, mut b: u64, xs: I, ) -> LexOrderedUniqueCollections> where I::Item: Clone, { if b == 0 { // Transform an empty (x, 0) range into (2, 1), which is also empty but doesn't cause // overflow a = 2; b = 1; } lex_ordered_unique_vecs_length_inclusive_range(a, b - 1, xs) } /// Generates [`Vec`]s, with lengths in a range $[a, b]$, with elements from a single iterator, such /// that each [`Vec`] has no repeated elements, and the elements in each [`Vec`] are ordered the /// same way as they are in the source iterator. /// /// The [`Vec`]s are ordered lexicographically with respect to the order of the element iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, only prefixes of the iterator will be /// generated. /// /// If $a < b$, the output is empty. /// /// If $a = b = 0$, the output consists of a single empty [`Vec`]. /// /// If the input iterator is infinite and $0 < a \leq b$, the output length is also infinite. /// /// If the input iterator length is $n$, the output length is /// $$ /// \sum_{i=a}^b \binom{n}{i}. /// $$ /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::vecs::exhaustive::lex_ordered_unique_vecs_length_inclusive_range; /// /// let xss = lex_ordered_unique_vecs_length_inclusive_range(2, 3, 1..=4).collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[1, 2][..], /// &[1, 2, 3], /// &[1, 2, 4], /// &[1, 3], /// &[1, 3, 4], /// &[1, 4], /// &[2, 3], /// &[2, 3, 4], /// &[2, 4], /// &[3, 4], /// ] /// ); /// ``` #[inline] pub fn lex_ordered_unique_vecs_length_inclusive_range( a: u64, b: u64, xs: I, ) -> LexOrderedUniqueCollections> where I::Item: Clone, { LexOrderedUniqueCollections::new(a, b, xs) } /// This function is used for iterating through all bit patterns with a specified number of minimum /// and maximum `true` bits. /// /// Given an existing bit pattern, and a reference `bit_count`, which must equal the number of /// `true`s in the pattern, mutates the pattern into the next pattern with a valid number of `true` /// bits. See the unit tests for many examples. /// /// # Worst-case complexity /// $$ /// T(k) = O(k) /// $$ /// /// $$ /// M(k) = O(k) /// $$ /// /// where $T$ is time, $M$ is additional memory, and $k$ is the length of `pattern`. The memory /// usage is only linear when the pattern vector needs to be reallocated, which happens rarely. /// /// # Panics /// Panics if `max_bits` is zero. (However, `min_bits` may be zero.) /// /// # Examples /// ``` /// use malachite_base::vecs::exhaustive::next_bit_pattern; /// /// // Suppose we are generating all bit patterns with 2 to 4 true bits, inclusive. Suppose our /// // current pattern is `1111000`. Then, the lexicographically next largest valid pattern is /// // `10000001`. (All patterns of the form `1111xxx`, where the `x`s are not all zero, have too /// // many ones. That brings us to `10000000`, which has too few ones, and then `10000001`.) /// // /// // The patterns are represented "in reverse", with least-significant bits appearing first. /// let mut pattern = vec![false, false, false, true, true, true, true]; /// let mut bit_count = 4; /// next_bit_pattern(&mut pattern, &mut bit_count, 2, 4); /// assert_eq!( /// pattern, /// &[true, false, false, false, false, false, false, true] /// ); /// assert_eq!(bit_count, 2); /// ``` pub fn next_bit_pattern( pattern: &mut Vec, bit_count: &mut usize, min_bits: usize, max_bits: usize, ) { assert_ne!(max_bits, 0); match pattern.first() { None => { pattern.push(true); *bit_count = 1; } Some(&false) => { if *bit_count < max_bits { pattern[0] = true; *bit_count += 1; } else { let leading_false_count = pattern.iter().take_while(|&&b| !b).count(); let true_after_false_count = pattern[leading_false_count..] .iter() .take_while(|&&b| b) .count(); let tf_count = leading_false_count + true_after_false_count; if tf_count == pattern.len() { for b in &mut *pattern { *b = false; } pattern.push(true); *bit_count = 1; } else { for b in &mut pattern[leading_false_count..tf_count] { *b = false; } pattern[tf_count] = true; *bit_count -= true_after_false_count - 1; } if *bit_count < min_bits { let diff = min_bits - *bit_count; for b in &mut pattern[..diff] { *b = true; } *bit_count += diff; } } } Some(&true) => { let leading_true_count = pattern.iter().take_while(|&&b| b).count(); for b in &mut pattern[..leading_true_count] { *b = false; } if leading_true_count == pattern.len() { pattern.push(true); } else { pattern[leading_true_count] = true; } *bit_count -= leading_true_count - 1; if *bit_count < min_bits { let diff = min_bits - *bit_count; for b in &mut pattern[..diff] { *b = true; } *bit_count += diff; } } } } #[derive(Clone)] #[doc(hidden)] pub struct ExhaustiveOrderedUniqueCollectionsGreaterThanOne> where I::Item: Clone, { done: bool, first: bool, min_bits: usize, max_bits: usize, xs: IteratorCache, pattern: Vec, bit_count: usize, phantom: PhantomData<*const C>, } impl> Iterator for ExhaustiveOrderedUniqueCollectionsGreaterThanOne where I::Item: Clone, { type Item = C; fn next(&mut self) -> Option { if self.done { return None; } else if self.first { self.first = false; } else { next_bit_pattern( &mut self.pattern, &mut self.bit_count, self.min_bits, self.max_bits, ); } if !self.pattern.is_empty() && self.xs.get(self.pattern.len() - 1).is_none() { self.done = true; return None; } Some( self.pattern .iter() .enumerate() .filter_map(|(i, &b)| { if b { Some(self.xs.assert_get(i).clone()) } else { None } }) .collect(), ) } } /// Generates all collections of elements from an iterator, where the collections have no /// repetitions and are ordered the same way as in the iterator. #[derive(Clone)] pub enum ExhaustiveOrderedUniqueCollections> where I::Item: Clone, { None, Zero(bool), ZeroOne(bool, I), One(I), GreaterThanOne(ExhaustiveOrderedUniqueCollectionsGreaterThanOne), } impl> ExhaustiveOrderedUniqueCollections where I::Item: Clone, { pub(crate) fn new(a: u64, b: u64, xs: I) -> ExhaustiveOrderedUniqueCollections { match (a, b) { (a, b) if a > b => ExhaustiveOrderedUniqueCollections::None, (0, 0) => ExhaustiveOrderedUniqueCollections::Zero(false), (0, 1) => ExhaustiveOrderedUniqueCollections::ZeroOne(true, xs), (1, 1) => ExhaustiveOrderedUniqueCollections::One(xs), (a, b) => ExhaustiveOrderedUniqueCollections::GreaterThanOne( ExhaustiveOrderedUniqueCollectionsGreaterThanOne { done: false, first: true, min_bits: usize::saturating_from(a), max_bits: usize::saturating_from(b), xs: IteratorCache::new(xs), pattern: vec![true; usize::saturating_from(a)], bit_count: usize::saturating_from(a), phantom: PhantomData, }, ), } } } impl> Iterator for ExhaustiveOrderedUniqueCollections where I::Item: Clone, { type Item = C; fn next(&mut self) -> Option { match self { ExhaustiveOrderedUniqueCollections::None => None, ExhaustiveOrderedUniqueCollections::Zero(ref mut done) => { if *done { None } else { *done = true; Some(empty().collect()) } } ExhaustiveOrderedUniqueCollections::ZeroOne(ref mut first, ref mut xs) => { if *first { *first = false; Some(empty().collect()) } else { xs.next().map(|x| once(x).collect()) } } ExhaustiveOrderedUniqueCollections::One(ref mut xs) => { xs.next().map(|x| once(x).collect()) } ExhaustiveOrderedUniqueCollections::GreaterThanOne(ref mut xs) => xs.next(), } } } /// Generates [`Vec`]s of a given length with elements from a single iterator, such that each /// [`Vec`] has no repeated elements, and the elements in each [`Vec`] are ordered the same way as /// they are in the source iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// If $k$ is 0, the output length is 1. /// /// If $k$ is nonzero and the input iterator is infinite, the output length is also infinite. /// /// If $k$ is nonzero and the input iterator length is $n$, the output length is $\binom{n}{k}$. /// /// If $k$ is 0, the output consists of one empty [`Vec`]. /// /// If `xs` is empty, the output is also empty, unless $k$ is 0. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::vecs::exhaustive::exhaustive_ordered_unique_vecs_fixed_length; /// /// let xss = exhaustive_ordered_unique_vecs_fixed_length(4, 1..=6).collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[1, 2, 3, 4], /// &[1, 2, 3, 5], /// &[1, 2, 4, 5], /// &[1, 3, 4, 5], /// &[2, 3, 4, 5], /// &[1, 2, 3, 6], /// &[1, 2, 4, 6], /// &[1, 3, 4, 6], /// &[2, 3, 4, 6], /// &[1, 2, 5, 6], /// &[1, 3, 5, 6], /// &[2, 3, 5, 6], /// &[1, 4, 5, 6], /// &[2, 4, 5, 6], /// &[3, 4, 5, 6] /// ] /// ); /// ``` #[inline] pub fn exhaustive_ordered_unique_vecs_fixed_length( k: u64, xs: I, ) -> ExhaustiveOrderedUniqueCollections> where I::Item: Clone, { exhaustive_ordered_unique_vecs_length_inclusive_range(k, k, xs) } /// Generates [`Vec`]s with elements from a single iterator, such that each [`Vec`] has no repeated /// elements, and the elements in each [`Vec`] are ordered the same way as they are in the source /// iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, only prefixes of the iterator will be /// generated. /// /// If the input iterator is infinite, the output length is also infinite. /// /// If the input iterator length is $n$, the output length is $2^n$. /// /// If `xs` is empty, the output consists of a single empty [`Vec`]. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::vecs::exhaustive::exhaustive_ordered_unique_vecs; /// /// let xss = exhaustive_ordered_unique_vecs(1..=4).collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[][..], /// &[1], /// &[2], /// &[1, 2], /// &[3], /// &[1, 3], /// &[2, 3], /// &[1, 2, 3], /// &[4], /// &[1, 4], /// &[2, 4], /// &[1, 2, 4], /// &[3, 4], /// &[1, 3, 4], /// &[2, 3, 4], /// &[1, 2, 3, 4] /// ] /// ); /// ``` #[inline] pub fn exhaustive_ordered_unique_vecs( xs: I, ) -> ExhaustiveOrderedUniqueCollections> where I::Item: Clone, { exhaustive_ordered_unique_vecs_length_inclusive_range(0, u64::MAX, xs) } /// Generates [`Vec`]s with a mininum length, with elements from a single iterator, such that each /// [`Vec`] has no repeated elements, and the elements in each [`Vec`] are ordered the same way as /// they are in the source iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, only prefixes of the iterator will be /// generated. /// /// If the input iterator is infinite, the output length is also infinite. /// /// If the input iterator length is $n$ and the `min_length` is $\ell$, the output length is /// $$ /// \sum_{i=\ell}^n \binom{n}{i}. /// $$ /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::vecs::exhaustive::exhaustive_ordered_unique_vecs_min_length; /// /// let xss = exhaustive_ordered_unique_vecs_min_length(2, 1..=4).collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[1, 2][..], /// &[1, 3], /// &[2, 3], /// &[1, 2, 3], /// &[1, 4], /// &[2, 4], /// &[1, 2, 4], /// &[3, 4], /// &[1, 3, 4], /// &[2, 3, 4], /// &[1, 2, 3, 4] /// ] /// ); /// ``` #[inline] pub fn exhaustive_ordered_unique_vecs_min_length( min_length: u64, xs: I, ) -> ExhaustiveOrderedUniqueCollections> where I::Item: Clone, { exhaustive_ordered_unique_vecs_length_inclusive_range(min_length, u64::MAX, xs) } /// Generates [`Vec`]s, with lengths in a range $[a, b)$, with elements from a single iterator, such /// that each [`Vec`] has no repeated elements, and the elements in each [`Vec`] are ordered the /// same way as they are in the source iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, only prefixes of the iterator will be /// generated. /// /// If $a \leq b$, the output is empty. /// /// If $a = 0$ and $b = 1$, the output consists of a single empty [`Vec`]. /// /// If the input iterator is infinite and $0 < a < b$, the output length is also infinite. /// /// If the input iterator length is $n$, the output length is /// $$ /// \sum_{i=a}^{b - 1} \binom{n}{i}. /// $$ /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::vecs::exhaustive::exhaustive_ordered_unique_vecs_length_range; /// /// let xss = exhaustive_ordered_unique_vecs_length_range(2, 4, 1..=4).collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[1, 2][..], /// &[1, 3], /// &[2, 3], /// &[1, 2, 3], /// &[1, 4], /// &[2, 4], /// &[1, 2, 4], /// &[3, 4], /// &[1, 3, 4], /// &[2, 3, 4] /// ] /// ); /// ``` #[inline] pub fn exhaustive_ordered_unique_vecs_length_range( a: u64, b: u64, xs: I, ) -> ExhaustiveOrderedUniqueCollections> where I::Item: Clone, { if a >= b { ExhaustiveOrderedUniqueCollections::None } else { exhaustive_ordered_unique_vecs_length_inclusive_range(a, b - 1, xs) } } /// Generates [`Vec`]s, with lengths in a range $[a, b]$, with elements from a single iterator, such /// that each [`Vec`] has no repeated elements, and the elements in each [`Vec`] are ordered the /// same way as they are in the source iterator. /// /// The [`Vec`]s are ordered lexicographically with respect to the order of the element iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, only prefixes of the iterator will be /// generated. /// /// If $a < b$, the output is empty. /// /// If $a = b = 0$, the output consists of a single empty [`Vec`]. /// /// If the input iterator is infinite and $0 < a \leq b$, the output length is also infinite. /// /// If the input iterator length is $n$, the output length is /// $$ /// \sum_{i=a}^b \binom{n}{i}. /// $$ /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::vecs::exhaustive::exhaustive_ordered_unique_vecs_length_inclusive_range; /// /// let xss = exhaustive_ordered_unique_vecs_length_inclusive_range(2, 3, 1..=4).collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[1, 2][..], /// &[1, 3], /// &[2, 3], /// &[1, 2, 3], /// &[1, 4], /// &[2, 4], /// &[1, 2, 4], /// &[3, 4], /// &[1, 3, 4], /// &[2, 3, 4] /// ] /// ); /// ``` #[inline] pub fn exhaustive_ordered_unique_vecs_length_inclusive_range( a: u64, b: u64, xs: I, ) -> ExhaustiveOrderedUniqueCollections> where I::Item: Clone, { ExhaustiveOrderedUniqueCollections::new(a, b, xs) } fn fixed_length_unique_indices_helper(indices: &mut [usize], used: &mut [bool]) -> bool { let n = used.len(); let k = indices.len(); assert!(k <= n); for i in (0..k).rev() { let x = indices[i]; used[x] = false; for y in x + 1..n { if !used[y] { indices[i] = y; used[y] = true; let mut p = 0; for j in &mut indices[i + 1..k] { while used[p] { p += 1; } *j = p; used[p] = true; } return false; } } } true } #[doc(hidden)] #[derive(Clone, Debug)] pub struct UniqueIndices { pub done: bool, first: bool, indices: Vec, pub used: Vec, } impl UniqueIndices { #[doc(hidden)] pub fn get_n(&self) -> usize { self.used.len() } #[doc(hidden)] pub fn increment_n(&mut self) { self.used.push(false); } } impl Iterator for UniqueIndices { type Item = Vec; fn next(&mut self) -> Option> { if self.done { None } else if self.first { self.first = false; Some(self.indices.clone()) } else if fixed_length_unique_indices_helper(&mut self.indices, &mut self.used) { self.done = true; None } else { Some(self.indices.clone()) } } } #[doc(hidden)] pub fn unique_indices(n: usize, k: usize) -> UniqueIndices { UniqueIndices { done: n == 0 && k != 0, first: true, indices: (0..k).collect_vec(), used: repeat_n(true, k) .chain(repeat_n(false, n - k)) .collect_vec(), } } /// Generates all [`Vec`]s of elements from an iterator, where the [`Vec`]s are of a fixed length /// and have no repetitions. #[derive(Clone)] pub struct LexUniqueVecsFixedLength where I::Item: Clone, { first: bool, xs: IteratorCache, indices: UniqueIndices, } impl Iterator for LexUniqueVecsFixedLength where I::Item: Clone, { type Item = Vec; fn next(&mut self) -> Option { if self.first { if !self.indices.used.is_empty() && self.xs.get(self.indices.get_n() - 1).is_none() { self.indices.done = true; } self.first = false; } if self.xs.get(self.indices.get_n()).is_some() { self.indices.increment_n(); } self.indices.next().map(|indices| { indices .into_iter() .map(|i| self.xs.assert_get(i).clone()) .collect_vec() }) } } /// Generates [`Vec`]s of a given length with elements from a single iterator, such that each /// [`Vec`] has no repeated elements. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The order is lexicographic with respect to the order of the element iterator. /// /// If $k$ is 0, the output length is 1. /// /// If $k$ is nonzero and the input iterator is infinite, the output length is also infinite. /// /// If $k$ is nonzero and the input iterator length is $n$, the output length is /// $$ /// (n)_ k = \prod_ {i=0}^{k-1}(n - i) = frac{n!}{(n-k)!}. /// $$ /// /// If $k$ is 0, the output consists of one empty [`Vec`]. /// /// If `xs` is empty, the output is also empty, unless $k$ is 0. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::vecs::exhaustive::lex_unique_vecs_fixed_length; /// /// let xss = lex_unique_vecs_fixed_length(4, 1..=6) /// .take(20) /// .collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[1, 2, 3, 4], /// &[1, 2, 3, 5], /// &[1, 2, 3, 6], /// &[1, 2, 4, 3], /// &[1, 2, 4, 5], /// &[1, 2, 4, 6], /// &[1, 2, 5, 3], /// &[1, 2, 5, 4], /// &[1, 2, 5, 6], /// &[1, 2, 6, 3], /// &[1, 2, 6, 4], /// &[1, 2, 6, 5], /// &[1, 3, 2, 4], /// &[1, 3, 2, 5], /// &[1, 3, 2, 6], /// &[1, 3, 4, 2], /// &[1, 3, 4, 5], /// &[1, 3, 4, 6], /// &[1, 3, 5, 2], /// &[1, 3, 5, 4], /// ] /// ); /// ``` #[inline] pub fn lex_unique_vecs_fixed_length(k: u64, xs: I) -> LexUniqueVecsFixedLength where I::Item: Clone, { let k = usize::exact_from(k); LexUniqueVecsFixedLength { first: true, xs: IteratorCache::new(xs), // Initial n is k, but will grow to reach actual n (or forever, if n is infinite) indices: unique_indices(k, k), } } /// Generates all [`Vec`]s of elements from an iterator in shortlex order, where the [`Vec`]s have /// no repetitions. #[derive(Clone)] pub struct ShortlexUniqueVecs where I::Item: Clone, { current_len: u64, max_len: u64, xs: I, current_xss: LexUniqueVecsFixedLength, } impl ShortlexUniqueVecs where I::Item: Clone, { fn new(a: u64, b: u64, xs: I) -> ShortlexUniqueVecs { ShortlexUniqueVecs { current_len: a, max_len: b, xs: xs.clone(), current_xss: lex_unique_vecs_fixed_length(a, xs), } } } impl Iterator for ShortlexUniqueVecs where I::Item: Clone, { type Item = Vec; fn next(&mut self) -> Option> { if self.current_len > self.max_len { return None; } if let Some(next) = self.current_xss.next() { Some(next) } else { self.current_len += 1; if self.current_len > self.max_len { return None; } self.current_xss = lex_unique_vecs_fixed_length(self.current_len, self.xs.clone()); if let Some(next) = self.current_xss.next() { Some(next) } else { // Prevent any further iteration self.max_len = 0; self.current_len = 1; None } } } } /// Generates [`Vec`]s with elements from a single iterator, such that each [`Vec`] has no repeated /// elements. /// /// The [`Vec`]s are generated in order of increasing length, and within each length they are /// ordered lexicographically with respect to the order of the element iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, [`Vec`]s of length 2 and above will never be /// generated. /// /// If the input iterator is infinite, the output length is also infinite. /// /// If the input iterator length is $n$, the output length is /// $$ /// \sum_ {k=0}^n \frac{n!}{k!} /// $$ /// $$ /// = \\begin{cases} /// 1 & \text{if} \\quad n = 0, \\\\ /// 2 & \text{if} \\quad n = 1, \\\\ /// \operatorname{round}(en!) & \\text{otherwise}. /// \\end{cases} /// $$ /// /// See . /// /// If `xs` is empty, the output consists of a single empty [`Vec`]. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::vecs::exhaustive::shortlex_unique_vecs; /// /// let xss = shortlex_unique_vecs(1..=4).take(20).collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[][..], /// &[1], /// &[2], /// &[3], /// &[4], /// &[1, 2], /// &[1, 3], /// &[1, 4], /// &[2, 1], /// &[2, 3], /// &[2, 4], /// &[3, 1], /// &[3, 2], /// &[3, 4], /// &[4, 1], /// &[4, 2], /// &[4, 3], /// &[1, 2, 3], /// &[1, 2, 4], /// &[1, 3, 2] /// ] /// ); /// ``` #[inline] pub fn shortlex_unique_vecs(xs: I) -> ShortlexUniqueVecs where I::Item: Clone, { shortlex_unique_vecs_length_inclusive_range(0, u64::MAX, xs) } /// Generates [`Vec`]s with a mininum length, with elements from a single iterator, such that each /// [`Vec`] has no repeated elements. /// /// The [`Vec`]s are generated in order of increasing length, and within each length they are /// ordered lexicographically with respect to the order of the element iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, [`Vec`]s of length `\max(2, \ell + 1)` and /// above will never be generated. /// /// If the input iterator is infinite, the output length is also infinite. /// /// If the input iterator length is $n$ and the `min_length` is $\ell$, the output length is /// $$ /// \sum_ {k=\ell}^n \frac{n!}{k!}. /// $$ /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::vecs::exhaustive::shortlex_unique_vecs_min_length; /// /// let xss = shortlex_unique_vecs_min_length(2, 1..=4) /// .take(20) /// .collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[1, 2][..], /// &[1, 3], /// &[1, 4], /// &[2, 1], /// &[2, 3], /// &[2, 4], /// &[3, 1], /// &[3, 2], /// &[3, 4], /// &[4, 1], /// &[4, 2], /// &[4, 3], /// &[1, 2, 3], /// &[1, 2, 4], /// &[1, 3, 2], /// &[1, 3, 4], /// &[1, 4, 2], /// &[1, 4, 3], /// &[2, 1, 3], /// &[2, 1, 4] /// ] /// ); /// ``` #[inline] pub fn shortlex_unique_vecs_min_length( min_length: u64, xs: I, ) -> ShortlexUniqueVecs where I::Item: Clone, { shortlex_unique_vecs_length_inclusive_range(min_length, u64::MAX, xs) } /// Generates [`Vec`]s, with lengths in a range $[a, b)$, with elements from a single iterator, such /// that each [`Vec`] has no repeated elements. /// /// The [`Vec`]s are generated in order of increasing length, and within each length they are /// ordered lexicographically with respect to the order of the element iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, [`Vec`]s of length `\max(2, a + 1)` and above /// will never be generated. /// /// If $a \leq b$, the output is empty. /// /// If $a = 0$ and $b = 1$, the output consists of a single empty [`Vec`]. /// /// If the input iterator is infinite and $0 < a < b$, the output length is also infinite. /// /// If the input iterator length is $n$, the output length is /// $$ /// \sum_{i=a}^{b - 1} \frac{n!}{k!}. /// $$ /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::vecs::exhaustive::shortlex_unique_vecs_length_range; /// /// let xss = shortlex_unique_vecs_length_range(2, 4, 1..=4) /// .take(20) /// .collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[1, 2][..], /// &[1, 3], /// &[1, 4], /// &[2, 1], /// &[2, 3], /// &[2, 4], /// &[3, 1], /// &[3, 2], /// &[3, 4], /// &[4, 1], /// &[4, 2], /// &[4, 3], /// &[1, 2, 3], /// &[1, 2, 4], /// &[1, 3, 2], /// &[1, 3, 4], /// &[1, 4, 2], /// &[1, 4, 3], /// &[2, 1, 3], /// &[2, 1, 4] /// ] /// ); /// ``` #[inline] pub fn shortlex_unique_vecs_length_range( mut a: u64, mut b: u64, xs: I, ) -> ShortlexUniqueVecs where I::Item: Clone, { if b == 0 { // Transform an empty (x, 0) range into (2, 1), which is also empty but doesn't cause // overflow a = 2; b = 1; } shortlex_unique_vecs_length_inclusive_range(a, b - 1, xs) } /// Generates [`Vec`]s, with lengths in a range $[a, b]$, with elements from a single iterator, such /// that each [`Vec`] has no repeated elements. /// /// The [`Vec`]s are generated in order of increasing length, and within each length they are /// ordered lexicographically with respect to the order of the element iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, [`Vec`]s of length `\max(2, a + 1)` and above /// will never be generated. /// /// If $a < b$, the output is empty. /// /// If $a = b = 0$, the output consists of a single empty [`Vec`]. /// /// If the input iterator is infinite and $0 < a \leq b$, the output length is also infinite. /// /// If the input iterator length is $n$, the output length is /// $$ /// \sum_{i=a}^b \frac{n!}{k!}. /// $$ /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::vecs::exhaustive::shortlex_unique_vecs_length_inclusive_range; /// /// let xss = shortlex_unique_vecs_length_inclusive_range(2, 3, 1..=4) /// .take(20) /// .collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[1, 2][..], /// &[1, 3], /// &[1, 4], /// &[2, 1], /// &[2, 3], /// &[2, 4], /// &[3, 1], /// &[3, 2], /// &[3, 4], /// &[4, 1], /// &[4, 2], /// &[4, 3], /// &[1, 2, 3], /// &[1, 2, 4], /// &[1, 3, 2], /// &[1, 3, 4], /// &[1, 4, 2], /// &[1, 4, 3], /// &[2, 1, 3], /// &[2, 1, 4] /// ] /// ); /// ``` #[inline] pub fn shortlex_unique_vecs_length_inclusive_range( a: u64, b: u64, xs: I, ) -> ShortlexUniqueVecs where I::Item: Clone, { ShortlexUniqueVecs::new(a, b, xs) } fn compare_indexed_vecs_lex(xs: &[(usize, T)], ys: &[(usize, T)]) -> Ordering { let xs_len = xs.len(); let ys_len = ys.len(); for i in 0..min(xs_len, ys_len) { let o = xs[i].0.cmp(&ys[i].0); if o != Equal { return o; } } xs_len.cmp(&ys_len) } /// Generates all collections of elements from an iterator in lexicographic order, where the /// collections have no repetitions. #[derive(Clone)] pub struct LexUniqueVecs where I::Item: Clone, { done: bool, first: bool, min: usize, max: usize, xs_for_prefix: I, xs: I, phase_1_vec: Option>, xsss: Vec, I>>>, next_xss: Vec>>, } impl Iterator for LexUniqueVecs where I::Item: Clone, { type Item = Vec; fn next(&mut self) -> Option> { if self.done { return None; } if self.first { self.first = false; return self.phase_1_vec.clone(); } if let Some(prefix) = self.phase_1_vec.as_mut() { if prefix.len() < self.max { if let Some(x) = self.xs_for_prefix.next() { prefix.push(x); return Some(prefix.clone()); } self.max = prefix.len(); } } if self.phase_1_vec.is_some() { for k in self.min..=self.max { let mut xss = lex_unique_vecs_fixed_length(u64::exact_from(k), (0..).zip(self.xs.clone())); // Skip over first Vec of length k, which was already generated in phase 1 xss.next(); self.next_xss.push(xss.next()); self.xsss.push(xss); } self.phase_1_vec = None; } let mut min_i = None; let mut i_done = None; for i in 0..self.next_xss.len() { let choose = if let Some(xs) = &self.next_xss[i] { if let Some(min_i) = min_i { let ys: &Option> = &self.next_xss[min_i]; compare_indexed_vecs_lex(xs, ys.as_ref().unwrap()) == Less } else { true } } else { i_done = Some(i); false }; if choose { min_i = Some(i); } } if let Some(i) = min_i { self.next_xss.push(self.xsss[i].next()); let xs = self .next_xss .swap_remove(i) .map(|xs| xs.into_iter().map(|p| p.1).collect()); if let Some(i_done) = i_done { self.xsss.remove(i_done); self.next_xss.remove(i_done); } xs } else { self.done = true; None } } } /// Generates [`Vec`]s with elements from a single iterator, such that each [`Vec`] has no repeated /// elements. /// /// The [`Vec`]s are ordered lexicographically with respect to the order of the element iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, only prefixes of the iterator will be /// generated. /// /// If the input iterator is infinite, the output length is also infinite. /// /// If the input iterator length is $n$, the output length is /// $$ /// \sum_ {k=0}^n \frac{n!}{k!} /// $$ /// $$ /// = \\begin{cases} /// 1 & \text{if} \\quad n = 0, \\\\ /// 2 & \text{if} \\quad n = 1, \\\\ /// \operatorname{round}(en!) & \\text{otherwise}. /// \\end{cases} /// $$ /// /// See . /// /// If `xs` is empty, the output consists of a single empty [`Vec`]. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::vecs::exhaustive::lex_unique_vecs; /// /// let xss = lex_unique_vecs(1..=4).take(20).collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[][..], /// &[1], /// &[1, 2], /// &[1, 2, 3], /// &[1, 2, 3, 4], /// &[1, 2, 4], /// &[1, 2, 4, 3], /// &[1, 3], /// &[1, 3, 2], /// &[1, 3, 2, 4], /// &[1, 3, 4], /// &[1, 3, 4, 2], /// &[1, 4], /// &[1, 4, 2], /// &[1, 4, 2, 3], /// &[1, 4, 3], /// &[1, 4, 3, 2], /// &[2], /// &[2, 1], /// &[2, 1, 3] /// ] /// ); /// ``` #[inline] pub fn lex_unique_vecs(xs: I) -> LexUniqueVecs where I::Item: Clone, { lex_unique_vecs_length_inclusive_range(0, u64::MAX, xs) } /// Generates [`Vec`]s with a mininum length, with elements from a single iterator, such that each /// [`Vec`] has no repeated elements. /// /// The [`Vec`]s are ordered lexicographically with respect to the order of the element iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, only prefixes of the iterator will be /// generated. /// /// If the input iterator is infinite, the output length is also infinite. /// /// If the input iterator length is $n$ and the `min_length` is $\ell$, the output length is /// $$ /// \sum_{i=\ell}^n \frac{n!}{k!}. /// $$ /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::vecs::exhaustive::lex_unique_vecs_min_length; /// /// let xss = lex_unique_vecs_min_length(2, 1..=4).take(20).collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[1, 2][..], /// &[1, 2, 3], /// &[1, 2, 3, 4], /// &[1, 2, 4], /// &[1, 2, 4, 3], /// &[1, 3], /// &[1, 3, 2], /// &[1, 3, 2, 4], /// &[1, 3, 4], /// &[1, 3, 4, 2], /// &[1, 4], /// &[1, 4, 2], /// &[1, 4, 2, 3], /// &[1, 4, 3], /// &[1, 4, 3, 2], /// &[2, 1], /// &[2, 1, 3], /// &[2, 1, 3, 4], /// &[2, 1, 4], /// &[2, 1, 4, 3] /// ] /// ); /// ``` #[inline] pub fn lex_unique_vecs_min_length(min_length: u64, xs: I) -> LexUniqueVecs where I::Item: Clone, { lex_unique_vecs_length_inclusive_range(min_length, u64::MAX, xs) } /// Generates [`Vec`]s, with lengths in a range $[a, b)$, with elements from a single iterator, such /// that each [`Vec`] has no repeated elements. /// /// The [`Vec`]s are ordered lexicographically with respect to the order of the element iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, only prefixes of the iterator will be /// generated. /// /// If $a \leq b$, the output is empty. /// /// If $a = 0$ and $b = 1$, the output consists of a single empty [`Vec`]. /// /// If the input iterator is infinite and $0 < a < b$, the output length is also infinite. /// /// If the input iterator length is $n$, the output length is /// $$ /// \sum_{i=a}^{b - 1} \frac{n!}{k!}. /// $$ /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::vecs::exhaustive::lex_unique_vecs_length_range; /// /// let xss = lex_unique_vecs_length_range(2, 4, 1..=4) /// .take(20) /// .collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[1, 2][..], /// &[1, 2, 3], /// &[1, 2, 4], /// &[1, 3], /// &[1, 3, 2], /// &[1, 3, 4], /// &[1, 4], /// &[1, 4, 2], /// &[1, 4, 3], /// &[2, 1], /// &[2, 1, 3], /// &[2, 1, 4], /// &[2, 3], /// &[2, 3, 1], /// &[2, 3, 4], /// &[2, 4], /// &[2, 4, 1], /// &[2, 4, 3], /// &[3, 1], /// &[3, 1, 2] /// ] /// ); /// ``` #[inline] pub fn lex_unique_vecs_length_range( mut a: u64, mut b: u64, xs: I, ) -> LexUniqueVecs where I::Item: Clone, { if b == 0 { // Transform an empty (x, 0) range into (2, 1), which is also empty but doesn't cause // overflow a = 2; b = 1; } lex_unique_vecs_length_inclusive_range(a, b - 1, xs) } /// Generates [`Vec`]s with a mininum length, with elements from a single iterator, such that each /// [`Vec`] has no repeated elements. /// /// The [`Vec`]s are ordered lexicographically with respect to the order of the element iterator. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// The iterator should be finite; if it is infinite, only prefixes of the iterator will be /// generated. /// /// If the input iterator is infinite, the output length is also infinite. /// /// If the input iterator length is $n$ and the `min_length` is $\ell$, the output length is /// $$ /// \sum_{i=\ell}^n \frac{n!}{k!}. /// $$ /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::vecs::exhaustive::lex_unique_vecs_min_length; /// /// let xss = lex_unique_vecs_min_length(2, 1..=4).take(20).collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[1, 2][..], /// &[1, 2, 3], /// &[1, 2, 3, 4], /// &[1, 2, 4], /// &[1, 2, 4, 3], /// &[1, 3], /// &[1, 3, 2], /// &[1, 3, 2, 4], /// &[1, 3, 4], /// &[1, 3, 4, 2], /// &[1, 4], /// &[1, 4, 2], /// &[1, 4, 2, 3], /// &[1, 4, 3], /// &[1, 4, 3, 2], /// &[2, 1], /// &[2, 1, 3], /// &[2, 1, 3, 4], /// &[2, 1, 4], /// &[2, 1, 4, 3] /// ] /// ); /// ``` #[inline] pub fn lex_unique_vecs_length_inclusive_range( a: u64, b: u64, xs: I, ) -> LexUniqueVecs where I::Item: Clone, { let a = usize::exact_from(a); let b = usize::exact_from(b); let mut xs_for_prefix = xs.clone(); let phase_1_vec = (&mut xs_for_prefix).take(a).collect_vec(); LexUniqueVecs { done: a > b || phase_1_vec.len() < a, first: true, min: a, max: b, xs_for_prefix, xs, phase_1_vec: Some(phase_1_vec), xsss: Vec::new(), next_xss: Vec::new(), } } #[doc(hidden)] #[derive(Clone)] pub struct ExhaustiveUniqueVecs2 where I::Item: Clone, { next: Option<(I::Item, I::Item)>, ps: ExhaustiveOrderedUniqueCollections>, } impl Iterator for ExhaustiveUniqueVecs2 where I::Item: Clone, { type Item = Vec; fn next(&mut self) -> Option> { if self.next.is_some() { let (a, b) = take(&mut self.next).unwrap(); Some(vec![a, b]) } else if let Some(p) = self.ps.next() { self.next = Some((p[1].clone(), p[0].clone())); Some(p) } else { None } } } fn exhaustive_unique_vecs_2(xs: I) -> ExhaustiveUniqueVecs2 where I::Item: Clone, { ExhaustiveUniqueVecs2 { next: None, ps: exhaustive_ordered_unique_vecs_fixed_length(2, xs), } } #[doc(hidden)] #[derive(Clone, Debug)] pub struct ExhaustiveUniqueVecsGenerator> { phantom_t: PhantomData, phantom_i: PhantomData, } impl> ExhaustiveUniqueVecsGenerator { #[doc(hidden)] #[inline] pub const fn new() -> ExhaustiveUniqueVecsGenerator { ExhaustiveUniqueVecsGenerator { phantom_i: PhantomData, phantom_t: PhantomData, } } } impl> ExhaustiveDependentPairsYsGenerator, Vec, ExhaustiveVecPermutations> for ExhaustiveUniqueVecsGenerator { #[inline] fn get_ys(&self, xs: &Vec) -> ExhaustiveVecPermutations { exhaustive_vec_permutations(xs.clone()) } } /// Generates all fixed-length [`Vec`]s of elements from an iterator, where the [`Vec`]s have no /// repetitions and are ordered the same way as in the iterator. #[derive(Clone)] pub enum ExhaustiveUniqueVecsFixedLength where I::Item: Clone, { Zero(bool), One(I), Two(ExhaustiveUniqueVecs2), GreaterThanTwo( ExhaustiveDependentPairs< Vec, Vec, RulerSequence, ExhaustiveUniqueVecsGenerator, ExhaustiveOrderedUniqueCollections>, ExhaustiveVecPermutations, >, ), } impl Iterator for ExhaustiveUniqueVecsFixedLength where I::Item: Clone, { type Item = Vec; fn next(&mut self) -> Option> { match self { ExhaustiveUniqueVecsFixedLength::Zero(done) => { if *done { None } else { *done = true; Some(Vec::new()) } } ExhaustiveUniqueVecsFixedLength::One(xs) => xs.next().map(|x| vec![x]), ExhaustiveUniqueVecsFixedLength::Two(ps) => ps.next(), ExhaustiveUniqueVecsFixedLength::GreaterThanTwo(xss) => xss.next().map(|p| p.1), } } } /// Generates [`Vec`]s of a given length with elements from a single iterator, such that each /// [`Vec`] has no repeated elements. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// If $k$ is 0, the output length is 1. /// /// If $k$ is nonzero and the input iterator is infinite, the output length is also infinite. /// /// If $k$ is nonzero and the input iterator length is $n$, the output length is /// $$ /// (n)_ k = \prod_ {i=0}^{k-1}(n - i) = frac{n!}{(n-k)!}. /// $$ /// /// If $k$ is 0, the output consists of one empty [`Vec`]. /// /// If `xs` is empty, the output is also empty, unless $k$ is 0. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::vecs::exhaustive::exhaustive_unique_vecs_fixed_length; /// /// let xss = exhaustive_unique_vecs_fixed_length(4, 1..=6) /// .take(20) /// .collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[1, 2, 3, 4], /// &[1, 2, 3, 5], /// &[1, 2, 4, 3], /// &[1, 2, 4, 5], /// &[1, 3, 2, 4], /// &[1, 2, 5, 3], /// &[1, 3, 4, 2], /// &[1, 3, 4, 5], /// &[1, 4, 2, 3], /// &[1, 3, 2, 5], /// &[1, 4, 3, 2], /// &[1, 2, 5, 4], /// &[2, 1, 3, 4], /// &[1, 3, 5, 2], /// &[2, 1, 4, 3], /// &[2, 3, 4, 5], /// &[2, 3, 1, 4], /// &[1, 5, 2, 3], /// &[2, 3, 4, 1], /// &[1, 4, 2, 5] /// ] /// ); /// ``` pub fn exhaustive_unique_vecs_fixed_length( k: u64, xs: I, ) -> ExhaustiveUniqueVecsFixedLength where I::Item: Clone, { match k { 0 => ExhaustiveUniqueVecsFixedLength::Zero(false), 1 => ExhaustiveUniqueVecsFixedLength::One(xs), 2 => ExhaustiveUniqueVecsFixedLength::Two(exhaustive_unique_vecs_2(xs)), k => ExhaustiveUniqueVecsFixedLength::GreaterThanTwo(exhaustive_dependent_pairs( ruler_sequence(), exhaustive_ordered_unique_vecs_fixed_length(k, xs), ExhaustiveUniqueVecsGenerator::new(), )), } } /// Generates all [`Vec`]s of elements from an iterator, where the [`Vec`]s have no repetitions and /// are ordered the same way as in the iterator. #[derive(Clone)] pub struct ExhaustiveUniqueVecs where I::Item: Clone, { xs: ExhaustiveDependentPairs< Vec, Vec, RulerSequence, ExhaustiveUniqueVecsGenerator, ExhaustiveOrderedUniqueCollections>, ExhaustiveVecPermutations, >, } impl Iterator for ExhaustiveUniqueVecs where I::Item: Clone, { type Item = Vec; #[inline] fn next(&mut self) -> Option> { self.xs.next().map(|p| p.1) } } /// Generates [`Vec`]s with elements from a single iterator, such that each [`Vec`] has no repeated /// elements. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// If the input iterator is infinite, the output length is also infinite. /// /// If the input iterator length is $n$, the output length is /// $$ /// \sum_ {k=0}^n \frac{n!}{k!} /// $$ /// $$ /// = \\begin{cases} /// 1 & \text{if} \\quad n = 0, \\\\ /// 2 & \text{if} \\quad n = 1, \\\\ /// \operatorname{round}(en!) & \\text{otherwise}. /// \\end{cases} /// $$ /// /// See . /// /// If `xs` is empty, the output consists of a single empty [`Vec`]. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::vecs::exhaustive::exhaustive_unique_vecs; /// /// let xss = exhaustive_unique_vecs(1..=4).take(20).collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[][..], /// &[1], /// &[2], /// &[3], /// &[1, 2], /// &[1, 3], /// &[2, 1], /// &[1, 2, 3], /// &[3, 1], /// &[2, 3], /// &[3, 2], /// &[4], /// &[1, 3, 2], /// &[1, 4], /// &[2, 1, 3], /// &[3, 4], /// &[2, 3, 1], /// &[4, 1], /// &[3, 1, 2], /// &[2, 4] /// ] /// ); /// ``` #[inline] pub fn exhaustive_unique_vecs(xs: I) -> ExhaustiveUniqueVecs where I::Item: Clone, { ExhaustiveUniqueVecs { xs: exhaustive_dependent_pairs( ruler_sequence(), exhaustive_ordered_unique_vecs(xs), ExhaustiveUniqueVecsGenerator::new(), ), } } /// Generates [`Vec`]s with a mininum length, with elements from a single iterator, such that each /// [`Vec`] has no repeated elements. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// If the input iterator is infinite, the output length is also infinite. /// /// If the input iterator length is $n$ and the `min_length` is $\ell$, the output length is /// $$ /// \sum_ {k=\ell}^n \frac{n!}{k!}. /// $$ /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::vecs::exhaustive::exhaustive_unique_vecs_min_length; /// /// let xss = exhaustive_unique_vecs_min_length(2, 1..=4) /// .take(20) /// .collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[1, 2][..], /// &[1, 3], /// &[2, 1], /// &[2, 3], /// &[3, 1], /// &[3, 2], /// &[1, 2, 3], /// &[1, 2, 4], /// &[1, 3, 2], /// &[1, 4], /// &[2, 1, 3], /// &[2, 4], /// &[2, 3, 1], /// &[4, 1], /// &[3, 1, 2], /// &[3, 4], /// &[3, 2, 1], /// &[4, 2], /// &[1, 4, 2], /// &[1, 3, 4] /// ] /// ); /// ``` #[inline] pub fn exhaustive_unique_vecs_min_length( min_length: u64, xs: I, ) -> ExhaustiveUniqueVecs where I::Item: Clone, { ExhaustiveUniqueVecs { xs: exhaustive_dependent_pairs( ruler_sequence(), exhaustive_ordered_unique_vecs_min_length(min_length, xs), ExhaustiveUniqueVecsGenerator::new(), ), } } /// Generates [`Vec`]s, with lengths in a range $[a, b)$, with elements from a single iterator, such /// that each [`Vec`] has no repeated elements. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// If $a \leq b$, the output is empty. /// /// If $a = 0$ and $b = 1$, the output consists of a single empty [`Vec`]. /// /// If the input iterator is infinite and $0 < a < b$, the output length is also infinite. /// /// If the input iterator length is $n$, the output length is /// $$ /// \sum_{i=a}^{b - 1} \frac{n!}{k!}. /// $$ /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::vecs::exhaustive::exhaustive_unique_vecs_length_range; /// /// let xss = exhaustive_unique_vecs_length_range(2, 4, 1..=4) /// .take(20) /// .collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[1, 2][..], /// &[1, 3], /// &[2, 1], /// &[2, 3], /// &[3, 1], /// &[3, 2], /// &[1, 2, 3], /// &[1, 2, 4], /// &[1, 3, 2], /// &[1, 4], /// &[2, 1, 3], /// &[2, 4], /// &[2, 3, 1], /// &[4, 1], /// &[3, 1, 2], /// &[3, 4], /// &[3, 2, 1], /// &[4, 2], /// &[1, 4, 2], /// &[1, 3, 4] /// ] /// ); /// ``` #[inline] pub fn exhaustive_unique_vecs_length_range( a: u64, b: u64, xs: I, ) -> ExhaustiveUniqueVecs where I::Item: Clone, { ExhaustiveUniqueVecs { xs: exhaustive_dependent_pairs( ruler_sequence(), exhaustive_ordered_unique_vecs_length_range(a, b, xs), ExhaustiveUniqueVecsGenerator::new(), ), } } /// Generates [`Vec`]s, with lengths in a range $[a, b]$, with elements from a single iterator, such /// that each [`Vec`] has no repeated elements. /// /// The source iterator should not repeat any elements, but this is not enforced. /// /// If $a < b$, the output is empty. /// /// If $a = b = 0$, the output consists of a single empty [`Vec`]. /// /// If the input iterator is infinite and $0 < a \leq b$, the output length is also infinite. /// /// If the input iterator length is $n$, the output length is /// $$ /// \sum_{i=a}^b \frac{n!}{k!}. /// $$ /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::vecs::exhaustive::exhaustive_unique_vecs_length_inclusive_range; /// /// let xss = exhaustive_unique_vecs_length_inclusive_range(2, 3, 1..=4) /// .take(20) /// .collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[1, 2][..], /// &[1, 3], /// &[2, 1], /// &[2, 3], /// &[3, 1], /// &[3, 2], /// &[1, 2, 3], /// &[1, 2, 4], /// &[1, 3, 2], /// &[1, 4], /// &[2, 1, 3], /// &[2, 4], /// &[2, 3, 1], /// &[4, 1], /// &[3, 1, 2], /// &[3, 4], /// &[3, 2, 1], /// &[4, 2], /// &[1, 4, 2], /// &[1, 3, 4] /// ] /// ); /// ``` #[inline] pub fn exhaustive_unique_vecs_length_inclusive_range( a: u64, b: u64, xs: I, ) -> ExhaustiveUniqueVecs where I::Item: Clone, { ExhaustiveUniqueVecs { xs: exhaustive_dependent_pairs( ruler_sequence(), exhaustive_ordered_unique_vecs_length_inclusive_range(a, b, xs), ExhaustiveUniqueVecsGenerator::new(), ), } } /// Generates all $k$-compositions of a number: all length-$k$ [`Vec`]s of positive [`usize`]s whose /// sum is a given number. #[derive(Clone, Debug)] pub struct LexKCompositions { done: bool, first: bool, xs: Vec, } impl Iterator for LexKCompositions { type Item = Vec; fn next(&mut self) -> Option> { if self.done { return None; } else if self.first { self.first = false; return Some(self.xs.clone()); } let last_not_one_index = self.xs.iter().rposition(|&x| x != 1); if last_not_one_index.is_none() || last_not_one_index == Some(0) { self.done = true; return None; } let last_not_one_index = last_not_one_index.unwrap(); self.xs[last_not_one_index - 1] += 1; let last_not_one = self.xs[last_not_one_index]; let (last, init) = self.xs.split_last_mut().unwrap(); *last = last_not_one - 1; for x in &mut init[last_not_one_index..] { *x = 1; } Some(self.xs.clone()) } } /// Generates all $k$-compositions of a number: given $n$ and $k$, generates all length-$k$ [`Vec`]s /// of positive [`usize`]s whose sum is $n$. /// /// The [`Vec`]s are output in lexicographic order. /// /// If $k = 0$ and $n \neq 0$, or if $n < k$, then the output is empty. /// /// The output length is /// $$ /// \binom{n-1}{k-1}. /// $$ /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::vecs::exhaustive::lex_k_compositions; /// /// let xss = lex_k_compositions(5, 3).collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[&[1, 1, 3], &[1, 2, 2], &[1, 3, 1], &[2, 1, 2], &[2, 2, 1], &[3, 1, 1]] /// ); /// ``` pub fn lex_k_compositions(n: usize, k: usize) -> LexKCompositions { if k == 0 && n != 0 || n < k { return LexKCompositions { done: true, first: true, xs: Vec::new(), }; } let mut xs = vec![1; k]; if k != 0 { xs[k - 1] = n + 1 - k; } LexKCompositions { done: false, first: true, xs, } } #[doc(hidden)] #[derive(Clone, Debug)] pub struct LexKCompositionsGenerator { k: usize, } impl ExhaustiveDependentPairsYsGenerator, LexKCompositions> for LexKCompositionsGenerator { #[inline] fn get_ys(&self, &n: &usize) -> LexKCompositions { lex_k_compositions(n, self.k) } } /// Generates $k$-compositions of $n$ for all $n$ in a given range: all length-$k$ [`Vec`]s of /// positive [`usize`]s whose sum is in a given range. #[derive(Clone, Debug)] pub struct ExhaustiveCombinedKCompositions { xs: ExhaustiveDependentPairs< usize, Vec, RulerSequence, LexKCompositionsGenerator, PrimitiveIntIncreasingRange, LexKCompositions, >, } impl Iterator for ExhaustiveCombinedKCompositions { type Item = Vec; #[inline] fn next(&mut self) -> Option> { self.xs.next().map(|p| p.1) } } /// Given $n_\text{min}$, $n_\text{max}$, and $k$, generates all length-$k$ [`Vec`]s of positive /// [`usize`]s whose sum is in the closed interval $[n_\text{min}, n_\text{max}]$. /// /// The output length is /// $$ /// \sum_{n=n_\text{min}}^{n_\text{max}} \binom{n-1}{k-1}. /// $$ /// /// # Panics /// Panics if $n_\text{min} > n_\text{max}$. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::vecs::exhaustive::exhaustive_combined_k_compositions; /// /// let xss = exhaustive_combined_k_compositions(4, 6, 3).collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[1, 1, 2], /// &[1, 1, 3], /// &[1, 2, 1], /// &[1, 1, 4], /// &[2, 1, 1], /// &[1, 2, 2], /// &[1, 3, 1], /// &[1, 2, 3], /// &[2, 1, 2], /// &[1, 3, 2], /// &[2, 2, 1], /// &[3, 1, 1], /// &[1, 4, 1], /// &[2, 1, 3], /// &[2, 2, 2], /// &[2, 3, 1], /// &[3, 1, 2], /// &[3, 2, 1], /// &[4, 1, 1] /// ] /// ); /// ``` #[inline] pub fn exhaustive_combined_k_compositions( n_min: usize, n_max: usize, k: usize, ) -> ExhaustiveCombinedKCompositions { ExhaustiveCombinedKCompositions { xs: exhaustive_dependent_pairs( ruler_sequence(), primitive_int_increasing_inclusive_range(n_min, n_max), LexKCompositionsGenerator { k }, ), } } malachite-base-0.4.16/src/vecs/mod.rs000064400000000000000000000450341046102023000154350ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . #[cfg(feature = "random")] use crate::num::conversion::traits::ExactFrom; #[cfg(feature = "random")] use crate::num::random::{random_unsigneds_less_than, RandomUnsignedsLessThan}; #[cfg(feature = "random")] use crate::random::Seed; use crate::slices::advance_indices; use alloc::string::String; use alloc::vec::Vec; use core::str::FromStr; #[cfg(feature = "random")] use rand::prelude::SliceRandom; #[cfg(feature = "random")] use rand_chacha::ChaCha20Rng; /// Inserts several copies of a value at the left (beginning) of a [`Vec`]. /// /// Using this function is more efficient than inserting the values one by one. /// /// # Worst-case complexity /// $T(n) = O(n + m)$ /// /// $M(n) = O(n + m)$ /// /// where $T$ is time, $M$ is additional memory, $n$ = `xs.len()` before the function is called, and /// $m$ = `pad_size`. /// /// # Examples /// ``` /// use malachite_base::vecs::vec_pad_left; /// /// let mut xs = vec![1, 2, 3]; /// vec_pad_left::(&mut xs, 5, 10); /// assert_eq!(xs, [10, 10, 10, 10, 10, 1, 2, 3]); /// ``` pub fn vec_pad_left(xs: &mut Vec, pad_size: usize, pad_value: T) { let old_len = xs.len(); xs.resize(old_len + pad_size, pad_value); for i in (0..old_len).rev() { xs.swap(i, i + pad_size); } } /// Deletes several values from the left (beginning) of a [`Vec`]. /// /// Using this function is more efficient than deleting the values one by one. /// /// # Worst-case complexity /// $T(n) = O(\operatorname{max}(1, n - m))$ /// /// $M(n) = O(1)$ /// /// where $T$ is time, $M$ is additional memory, $n$ = `xs.len()` before the function is called, and /// $m$ = `delete_size`. /// /// # Panics /// Panics if `delete_size` is greater than `xs.len()`. /// /// # Examples /// ``` /// use malachite_base::vecs::vec_delete_left; /// /// let mut xs = vec![1, 2, 3, 4, 5]; /// vec_delete_left::(&mut xs, 3); /// assert_eq!(xs, [4, 5]); /// ``` pub fn vec_delete_left(xs: &mut Vec, delete_size: usize) { let old_len = xs.len(); xs.copy_within(delete_size..old_len, 0); xs.truncate(old_len - delete_size); } /// Converts a string to an `Vec`, where `T` implements [`FromStr`]. /// /// If the string does not represent a valid `Vec`, `None` is returned. /// /// If `T` does not implement [`FromStr`], try using [`vec_from_str_custom`] instead. /// /// Substrings representing `T`s may contain commas. Sometimes this may lead to ambiguities: for /// example, the two `Vec<&str>`s `vec!["a, b"]` and `vec!["a", "b"]` both have the string /// representation `"[a, b]"`. The parser is greedy, so it will interpet this string as `vec!["a", /// "b"]`. /// /// # Examples /// ``` /// use malachite_base::nevers::Never; /// use malachite_base::vecs::vec_from_str; /// /// assert_eq!(vec_from_str::("[]"), Some(vec![])); /// assert_eq!(vec_from_str("[5, 6, 7]"), Some(vec![5, 6, 7])); /// assert_eq!( /// vec_from_str("[false, false, true]"), /// Some(vec![false, false, true]) /// ); /// assert_eq!(vec_from_str::("[false, false, true"), None); /// ``` #[inline] pub fn vec_from_str(src: &str) -> Option> { vec_from_str_custom(&(|t| t.parse().ok()), src) } /// Converts a string to an `Vec`, given a function to parse a string into a `T`. /// /// If the string does not represent a valid `Option`, `None` is returned. /// /// If `f` just uses [`FromStr::from_str`], you can use [`vec_from_str`] instead. /// /// Substrings representing `T`s may contain commas. Sometimes this may lead to ambiguities: for /// example, the two `Vec<&str>`s `vec!["a, b"]` and `vec!["a", "b"]` both have the string /// representation `"[a, b]"`. The parser is greedy, so it will interpet this string as `vec!["a", /// "b"]`. /// /// # Examples /// ``` /// use malachite_base::options::option_from_str; /// use malachite_base::orderings::ordering_from_str; /// use malachite_base::vecs::{vec_from_str, vec_from_str_custom}; /// use std::cmp::Ordering::*; /// /// assert_eq!( /// vec_from_str_custom(&ordering_from_str, "[Less, Greater]"), /// Some(vec![Less, Greater]), /// ); /// assert_eq!( /// vec_from_str_custom(&option_from_str, "[Some(false), None]"), /// Some(vec![Some(false), None]), /// ); /// assert_eq!( /// vec_from_str_custom(&vec_from_str, "[[], [3], [2, 5]]"), /// Some(vec![vec![], vec![3], vec![2, 5]]), /// ); /// assert_eq!( /// vec_from_str_custom(&option_from_str::, "[Some(fals), None]"), /// None /// ); /// ``` pub fn vec_from_str_custom(f: &dyn Fn(&str) -> Option, src: &str) -> Option> { if !src.starts_with('[') || !src.ends_with(']') { return None; } let mut xs = Vec::new(); let mut buffer = String::new(); for token in src[1..src.len() - 1].split(", ") { if !buffer.is_empty() { buffer.push_str(", "); } buffer.push_str(token); if let Some(x) = f(&buffer) { xs.push(x); buffer.clear(); } } if buffer.is_empty() { Some(xs) } else { None } } #[cfg(feature = "random")] /// Uniformly generates a random value from a nonempty [`Vec`]. /// /// This `struct` is created by [`random_values_from_vec`]; see its documentation for more. #[derive(Clone, Debug)] pub struct RandomValuesFromVec { xs: Vec, indices: RandomUnsignedsLessThan, } #[cfg(feature = "random")] impl Iterator for RandomValuesFromVec { type Item = T; #[inline] fn next(&mut self) -> Option { Some(self.xs[usize::exact_from(self.indices.next().unwrap())].clone()) } } #[cfg(feature = "random")] /// Uniformly generates a random value from a nonempty [`Vec`]. /// /// The iterator owns the data. It may be more convenient for the iterator to return references to a /// pre-existing slice, in which case you may use /// [`random_values_from_slice`](crate::slices::random_values_from_slice) instead. /// /// The output length is infinite. /// /// $P(x) = 1/n$, where $n$ is `xs.len()`. /// /// # Panics /// Panics if `xs` is empty. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::vecs::random_values_from_vec; /// /// let xs = vec![2, 3, 5, 7, 11]; /// assert_eq!( /// random_values_from_vec(EXAMPLE_SEED, xs) /// .take(10) /// .collect_vec(), /// &[3, 7, 3, 5, 11, 3, 5, 11, 2, 2] /// ); /// ``` #[inline] pub fn random_values_from_vec(seed: Seed, xs: Vec) -> RandomValuesFromVec { assert!(!xs.is_empty(), "empty Vec"); let indices = random_unsigneds_less_than(seed, u64::exact_from(xs.len())); RandomValuesFromVec { xs, indices } } /// Generates every permutation of a [`Vec`]. /// /// This `struct` is created by [`exhaustive_vec_permutations`]; see its documentation for more. #[derive(Clone, Debug, Eq, Hash, PartialEq)] pub struct ExhaustiveVecPermutations { xs: Vec, indices: Vec, done: bool, } impl Iterator for ExhaustiveVecPermutations { type Item = Vec; fn next(&mut self) -> Option> { if self.done { None } else { let out = Some(self.indices.iter().map(|&i| self.xs[i].clone()).collect()); self.done = advance_indices(&mut self.indices); out } } } /// Generates every permutation of a [`Vec`]. /// /// The permutations are [`Vec`]s of cloned items. It may be more convenient for the iterator to /// return references to a slice, in which case you may use /// [`exhaustive_slice_permutations`](crate::slices::exhaustive_slice_permutations) instead. /// /// The permutations are generated in lexicographic order with respect to the ordering in the /// [`Vec`]. /// /// The output length is $n!$, where $n$ is `xs.len()`. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::vecs::exhaustive_vec_permutations; /// /// let css: Vec = exhaustive_vec_permutations(vec!['a', 'b', 'c', 'd']) /// .map(|ds| ds.into_iter().collect()) /// .collect(); /// assert_eq!( /// css.iter().map(String::as_str).collect_vec().as_slice(), /// [ /// "abcd", "abdc", "acbd", "acdb", "adbc", "adcb", "bacd", "badc", "bcad", "bcda", "bdac", /// "bdca", "cabd", "cadb", "cbad", "cbda", "cdab", "cdba", "dabc", "dacb", "dbac", "dbca", /// "dcab", "dcba" /// ] /// ); /// ``` pub fn exhaustive_vec_permutations(xs: Vec) -> ExhaustiveVecPermutations { let len = xs.len(); ExhaustiveVecPermutations { xs, indices: (0..len).collect(), done: false, } } #[cfg(feature = "random")] /// Uniformly generates a random [`Vec`] of values cloned from an original [`Vec`]. /// /// This `struct` is created by [`random_vec_permutations`]; see its documentation for more. #[derive(Clone, Debug)] pub struct RandomVecPermutations { xs: Vec, indices: Vec, rng: ChaCha20Rng, } #[cfg(feature = "random")] impl Iterator for RandomVecPermutations { type Item = Vec; fn next(&mut self) -> Option> { self.indices.shuffle(&mut self.rng); Some(self.indices.iter().map(|&i| self.xs[i].clone()).collect()) } } #[cfg(feature = "random")] /// Uniformly generates a random [`Vec`] of values cloned from an original [`Vec`]. /// /// The permutations are [`Vec`]s of cloned items. It may be more convenient for the iterator to /// return references to a slice, in which case you may use /// [`random_slice_permutations`](crate::slices::random_slice_permutations) instead. /// /// The output length is infinite. /// /// $P(p) = 1/n!$, where $n$ is `xs.len()`. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::vecs::random_vec_permutations; /// /// let css: Vec = random_vec_permutations(EXAMPLE_SEED, vec!['a', 'b', 'c', 'd']) /// .take(20) /// .map(|ds| ds.into_iter().collect()) /// .collect(); /// assert_eq!( /// css.iter().map(String::as_str).collect_vec().as_slice(), /// [ /// "cadb", "cbad", "cadb", "badc", "acdb", "cbad", "dabc", "dbca", "cdba", "cdab", "bacd", /// "cabd", "adbc", "cdab", "dcab", "abcd", "abcd", "dacb", "bcad", "adcb" /// ] /// ); /// ``` pub fn random_vec_permutations(seed: Seed, xs: Vec) -> RandomVecPermutations { let len = xs.len(); RandomVecPermutations { xs, indices: (0..len).collect(), rng: seed.get_rng(), } } /// Iterators that generate [`Vec`]s without repetition. /// /// # lex_vecs_length_2 /// ``` /// use itertools::Itertools; /// use malachite_base::vecs::exhaustive::lex_vecs_length_2; /// /// let xss = lex_vecs_length_2( /// ['a', 'b', 'c'].iter().cloned(), /// ['x', 'y', 'z'].iter().cloned(), /// ) /// .collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &['a', 'x'], /// &['a', 'y'], /// &['a', 'z'], /// &['b', 'x'], /// &['b', 'y'], /// &['b', 'z'], /// &['c', 'x'], /// &['c', 'y'], /// &['c', 'z'] /// ] /// ); /// ``` /// /// # lex_vecs_fixed_length_2_inputs /// ``` /// use itertools::Itertools; /// use malachite_base::chars::exhaustive::exhaustive_ascii_chars; /// use malachite_base::vecs::exhaustive::lex_vecs_fixed_length_2_inputs; /// /// // We are generating length-3 `Vec`s of `char`s using two input iterators. The first iterator /// // (with index 0) produces all ASCII `char`s, and the second (index 1) produces the three /// // `char`s `'x'`, `'y'`, and `'z'`. The elements of `output_types` are 0, 1, and 0, meaning that /// // the first element of the output `Vec`s will be taken from iterator 0, the second element from /// // iterator 1, and the third also from iterator 0. /// let xss = lex_vecs_fixed_length_2_inputs( /// exhaustive_ascii_chars(), /// ['x', 'y', 'z'].iter().cloned(), /// &[0, 1, 0], /// ); /// let xss_prefix = xss.take(20).collect_vec(); /// assert_eq!( /// xss_prefix /// .iter() /// .map(Vec::as_slice) /// .collect_vec() /// .as_slice(), /// &[ /// &['a', 'x', 'a'], /// &['a', 'x', 'b'], /// &['a', 'x', 'c'], /// &['a', 'x', 'd'], /// &['a', 'x', 'e'], /// &['a', 'x', 'f'], /// &['a', 'x', 'g'], /// &['a', 'x', 'h'], /// &['a', 'x', 'i'], /// &['a', 'x', 'j'], /// &['a', 'x', 'k'], /// &['a', 'x', 'l'], /// &['a', 'x', 'm'], /// &['a', 'x', 'n'], /// &['a', 'x', 'o'], /// &['a', 'x', 'p'], /// &['a', 'x', 'q'], /// &['a', 'x', 'r'], /// &['a', 'x', 's'], /// &['a', 'x', 't'] /// ] /// ); /// ``` /// /// # exhaustive_vecs_length_2 /// ``` /// use itertools::Itertools; /// use malachite_base::vecs::exhaustive::exhaustive_vecs_length_2; /// /// let xss = exhaustive_vecs_length_2( /// ['a', 'b', 'c'].iter().cloned(), /// ['x', 'y', 'z'].iter().cloned(), /// ) /// .collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &['a', 'x'], /// &['a', 'y'], /// &['b', 'x'], /// &['b', 'y'], /// &['a', 'z'], /// &['b', 'z'], /// &['c', 'x'], /// &['c', 'y'], /// &['c', 'z'] /// ] /// ); /// ``` /// /// # exhaustive_vecs_fixed_length_2_inputs /// ``` /// use itertools::Itertools; /// use malachite_base::chars::exhaustive::exhaustive_ascii_chars; /// use malachite_base::iterators::bit_distributor::BitDistributorOutputType; /// use malachite_base::vecs::exhaustive::exhaustive_vecs_fixed_length_2_inputs; /// /// // We are generating length-3 `Vec`s of `char`s using two input iterators. The first iterator /// // (with index 0) produces all ASCII `char`s, and the second (index 1) produces the three /// // `char`s `'x'`, `'y'`, and `'z'`. The elements of `output_types` have the indices 0, 1, and 0, /// // meaning that the first element of the output `Vec`s will be taken from iterator 0, the second /// // element from iterator 1, and the third also from iterator 0. The third element has a tiny /// // output type, so it will grow more slowly than the other two elements (though it doesn't look /// // that way from the first few `Vec`s). /// let xss = exhaustive_vecs_fixed_length_2_inputs( /// exhaustive_ascii_chars(), /// ['x', 'y', 'z'].iter().cloned(), /// &[ /// (BitDistributorOutputType::normal(1), 0), /// (BitDistributorOutputType::normal(1), 1), /// (BitDistributorOutputType::tiny(), 0), /// ], /// ); /// let xss_prefix = xss.take(20).collect_vec(); /// assert_eq!( /// xss_prefix /// .iter() /// .map(Vec::as_slice) /// .collect_vec() /// .as_slice(), /// &[ /// &['a', 'x', 'a'], /// &['a', 'x', 'b'], /// &['a', 'x', 'c'], /// &['a', 'x', 'd'], /// &['a', 'y', 'a'], /// &['a', 'y', 'b'], /// &['a', 'y', 'c'], /// &['a', 'y', 'd'], /// &['a', 'x', 'e'], /// &['a', 'x', 'f'], /// &['a', 'x', 'g'], /// &['a', 'x', 'h'], /// &['a', 'y', 'e'], /// &['a', 'y', 'f'], /// &['a', 'y', 'g'], /// &['a', 'y', 'h'], /// &['b', 'x', 'a'], /// &['b', 'x', 'b'], /// &['b', 'x', 'c'], /// &['b', 'x', 'd'] /// ] /// ); /// ``` pub mod exhaustive; #[cfg(feature = "random")] /// Iterators that generate [`Vec`]s randomly. /// /// # random_vecs_length_2 /// ``` /// use itertools::Itertools; /// use malachite_base::chars::random::random_char_inclusive_range; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::vecs::random::random_vecs_length_2; /// /// let xss = random_vecs_length_2( /// EXAMPLE_SEED, /// &|seed| random_char_inclusive_range(seed, 'a', 'c'), /// &|seed| random_char_inclusive_range(seed, 'x', 'z'), /// ) /// .take(20) /// .collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &['b', 'z'], /// &['b', 'x'], /// &['b', 'z'], /// &['b', 'y'], /// &['c', 'x'], /// &['a', 'z'], /// &['a', 'z'], /// &['a', 'z'], /// &['c', 'z'], /// &['a', 'y'], /// &['c', 'x'], /// &['a', 'x'], /// &['c', 'z'], /// &['a', 'z'], /// &['c', 'x'], /// &['c', 'x'], /// &['c', 'y'], /// &['b', 'y'], /// &['a', 'x'], /// &['c', 'x'] /// ] /// ); /// ``` /// /// # random_vecs_fixed_length_2_inputs /// ``` /// use itertools::Itertools; /// use malachite_base::chars::random::{random_ascii_chars, random_char_inclusive_range}; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::vecs::random::random_vecs_fixed_length_2_inputs; /// /// // We are generating length-3 `Vec`s of `char`s using two input iterators. The first iterator /// // (with index 0) produces random ASCII `char`s, and the second (index 1) produces the three /// // `char`s `'x'`, `'y'`, and `'z'`, uniformly at random. The elements of `output_types` are 0, /// // 1, and 0, meaning that the first element of the output `Vec`s will be taken from iterator 0, /// // the second element from iterator 1, and the third also from iterator 0. /// let xss = random_vecs_fixed_length_2_inputs( /// EXAMPLE_SEED, /// &random_ascii_chars, /// &|seed| random_char_inclusive_range(seed, 'x', 'z'), /// &[0, 1, 0], /// ) /// .take(20) /// .collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &['U', 'z', '\u{16}'], /// &[' ', 'x', 'D'], /// &['<', 'z', ']'], /// &['a', 'y', 'e'], /// &['_', 'x', 'M'], /// &[',', 'z', 'O'], /// &['\u{1d}', 'z', 'V'], /// &['(', 'z', '\u{10}'], /// &['&', 'z', 'U'], /// &['{', 'y', 'P'], /// &['-', 'x', 'K'], /// &['Z', 'x', '\u{4}'], /// &['X', 'z', '\u{19}'], /// &['_', 'z', ','], /// &['\u{1d}', 'x', ','], /// &['?', 'x', '\''], /// &['[', 'y', 'N'], /// &['|', 'y', '}'], /// &['*', 'x', '\u{15}'], /// &['z', 'x', 't'] /// ] /// ); /// ``` pub mod random; malachite-base-0.4.16/src/vecs/random.rs000064400000000000000000001510501046102023000161320ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::conversion::traits::ExactFrom; use crate::num::random::geometric::{ geometric_random_unsigned_inclusive_range, geometric_random_unsigneds, GeometricRandomNaturalValues, }; use crate::num::random::{ random_unsigned_inclusive_range, random_unsigned_range, RandomUnsignedInclusiveRange, RandomUnsignedRange, }; use crate::random::Seed; use crate::sets::random::{ random_b_tree_sets_fixed_length, random_b_tree_sets_from_length_iterator, RandomBTreeSets, RandomBTreeSetsFixedLength, }; use crate::vecs::exhaustive::validate_oi_map; use std::cmp::Ordering::*; use std::collections::HashMap; use std::hash::Hash; use std::iter::{repeat, Repeat}; /// Generates random [`Vec`]s of a given length using elements from a single iterator. /// /// This `struct` is created by [`random_vecs_fixed_length_from_single`]; see its documentation for /// more. #[derive(Clone, Debug)] pub struct RandomFixedLengthVecsFromSingle { len: u64, xs: I, } impl Iterator for RandomFixedLengthVecsFromSingle { type Item = Vec; #[inline] fn next(&mut self) -> Option> { Some((&mut self.xs).take(usize::exact_from(self.len)).collect()) } } /// Randomly generates [`Vec`]s of a given length using elements from a single iterator. /// /// The probability of a particular length-$n$ [`Vec`] being generated is the product of the /// probabilities of each of its elements. /// /// If `len` is 0, the output consists of the empty list, repeated. /// /// `xs` must be infinite. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::random::random_unsigned_inclusive_range; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::vecs::random::random_vecs_fixed_length_from_single; /// /// let xss = random_vecs_fixed_length_from_single( /// 2, /// random_unsigned_inclusive_range::(EXAMPLE_SEED, 1, 100), /// ) /// .take(10) /// .collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[95, 24], /// &[99, 71], /// &[93, 53], /// &[85, 34], /// &[48, 2], /// &[55, 11], /// &[48, 18], /// &[90, 93], /// &[67, 93], /// &[93, 95] /// ] /// ); /// ``` #[inline] pub const fn random_vecs_fixed_length_from_single( len: u64, xs: I, ) -> RandomFixedLengthVecsFromSingle { RandomFixedLengthVecsFromSingle { len, xs } } /// Defines random fixed-length [`Vec`] generators. /// /// Malachite provides [`random_vecs_length_2`] and [`random_vecs_fixed_length_2_inputs`], but you /// can also define `random_vecs_length_3`, `random_vecs_length_4`, and so on, and /// `random_vecs_fixed_length_3_inputs`, `random_vecs_fixed_length_4_inputs`, and so on, in your /// program using the code below. The documentation for [`random_vecs_length_2`] and /// [`random_vecs_fixed_length_2_inputs`] describes these other functions as well. /// /// See usage examples [here](self#lex_vecs_length_2) and /// [here](self#random_vecs_fixed_length_2_inputs). /// /// ``` /// use malachite_base::random::Seed; /// use malachite_base::random_vecs_fixed_length; /// use malachite_base::vecs::exhaustive::validate_oi_map; /// /// random_vecs_fixed_length!( /// (pub(crate)), /// RandomFixedLengthVecs3Inputs, /// random_vecs_fixed_length_3_inputs, /// random_vecs_length_3, /// [0, I, xs, xs_gen], /// [1, J, ys, ys_gen], /// [2, K, zs, zs_gen] /// ); /// random_vecs_fixed_length!( /// (pub(crate)), /// RandomFixedLengthVecs4Inputs, /// random_vecs_fixed_length_4_inputs, /// random_vecs_length_4, /// [0, I, xs, xs_gen], /// [1, J, ys, ys_gen], /// [2, K, zs, zs_gen], /// [3, L, ws, ws_gen] /// ); /// random_vecs_fixed_length!( /// (pub(crate)), /// RandomFixedLengthVecs5Inputs, /// random_vecs_fixed_length_5_inputs, /// random_vecs_length_5, /// [0, I, xs, xs_gen], /// [1, J, ys, ys_gen], /// [2, K, zs, zs_gen], /// [3, L, ws, ws_gen], /// [4, M, vs, vs_gen] /// ); /// random_vecs_fixed_length!( /// (pub(crate)), /// RandomFixedLengthVecs6Inputs, /// random_vecs_fixed_length_6_inputs, /// random_vecs_length_6, /// [0, I, xs, xs_gen], /// [1, J, ys, ys_gen], /// [2, K, zs, zs_gen], /// [3, L, ws, ws_gen], /// [4, M, vs, vs_gen], /// [5, N, us, us_gen] /// ); /// random_vecs_fixed_length!( /// (pub(crate)), /// RandomFixedLengthVecs7Inputs, /// random_vecs_fixed_length_7_inputs, /// random_vecs_length_7, /// [0, I, xs, xs_gen], /// [1, J, ys, ys_gen], /// [2, K, zs, zs_gen], /// [3, L, ws, ws_gen], /// [4, M, vs, vs_gen], /// [5, N, us, us_gen], /// [6, O, ts, ts_gen] /// ); /// random_vecs_fixed_length!( /// (pub(crate)), /// RandomFixedLengthVecs8Inputs, /// random_vecs_fixed_length_8_inputs, /// random_vecs_length_8, /// [0, I, xs, xs_gen], /// [1, J, ys, ys_gen], /// [2, K, zs, zs_gen], /// [3, L, ws, ws_gen], /// [4, M, vs, vs_gen], /// [5, N, us, us_gen], /// [6, O, ts, ts_gen], /// [7, P, ss, ss_gen] /// ); /// ``` #[macro_export] macro_rules! random_vecs_fixed_length { ( ($($vis:tt)*), $random_struct: ident, $random_fn: ident, $random_1_to_1_fn: ident, $([$i: expr, $it: ident, $xs: ident, $xs_gen: ident]),* ) => { /// This documentation applies not only to `RandomFixedLengthVecs2Inputs`, but also to /// `RandomFixedLengthVecs3Inputs`, `RandomFixedLengthVecs4Inputs`, and so on. See /// [`random_vecs_fixed_length`] for more information. /// /// Generates random [`Vec`]s of a given length using elements from $m$ iterators. /// /// The fixed length $n$ of the [`Vec`]s is greater than or equal to $m$. #[derive(Clone, Debug)] $($vis)* struct $random_struct),*> { $($xs: $it,)* output_to_input_map: Vec, } impl),*> Iterator for $random_struct { type Item = Vec; #[inline] fn next(&mut self) -> Option> { let mut out = Vec::with_capacity(self.output_to_input_map.len()); for &i in &self.output_to_input_map { out.push( match i { $( $i => self.$xs.next(), )* _ => unreachable!(), } .unwrap(), ); } Some(out) } } /// This documentation applies not only to `random_vecs_fixed_length_2_inputs`, but also to /// `random_vecs_fixed_length_3_inputs`, `random_vecs_fixed_length_4_inputs`, and so on. See /// [`random_vecs_fixed_length`] for more information. /// /// Generates random length-$n$ [`Vec`]s using elements from $m$ iterators, where $m \leq /// n$. /// /// The `output_to_input_map` parameter defines which iterators are mapped to which slot in /// the output [`Vec`]s. The length of the output [`Vec`]s, $n$, is specified by the length /// of `output_to_input_map`. /// /// The $i$th element of `output_to_input_map` is an index from 0 to $m-1$ which specifies /// which iterator the $i$th output slot is populated with. Together, the elements must /// include all indices from 0 to $m-1$, inclusive, possibly with repetitions. /// /// `xs` must be infinite. /// /// # Examples /// See [here](self#random_vecs_fixed_length_2_inputs). #[allow(dead_code)] $($vis)* fn $random_fn),*>( seed: Seed, $($xs_gen: &dyn Fn(Seed) -> $it,)* output_to_input_map: &[usize], ) -> $random_struct { $( let _max_input_index = $i; )* validate_oi_map(_max_input_index, output_to_input_map.iter().cloned()); $random_struct { $($xs: $xs_gen(seed.fork(stringify!($xs))),)* output_to_input_map: output_to_input_map.to_vec(), } } /// This documentation applies not only to `random_vecs_length_2`, but also to /// `random_vecs_length_3`, `random_vecs_length_4`, and so on. See /// [`random_vecs_fixed_length`] for more information. /// /// Generates random length-$n$ [`Vec`]s with elements from $n$ iterators. /// /// The probability of a particular length-$n$ [`Vec`] being generated is the product of the /// probabilities of each of its elements. /// /// `xs`, `ys`, `zs`, ... must be infinite. /// /// # Examples /// See [here](self#random_vecs_length_2). #[allow(dead_code)] #[inline] $($vis)* fn $random_1_to_1_fn),*>( seed: Seed, $($xs_gen: &dyn Fn(Seed) -> $it,)* ) -> $random_struct { $random_fn(seed, $($xs_gen,)* &[$($i),*]) } } } random_vecs_fixed_length!( (pub), RandomFixedLengthVecs2Inputs, random_vecs_fixed_length_2_inputs, random_vecs_length_2, [0, I, xs, xs_gen], [1, J, ys, ys_gen] ); /// Generates random [`Vec`]s using elements from an iterator and with lengths from another /// iterator. #[derive(Clone, Debug)] pub struct RandomVecs, J: Iterator> { lengths: I, xs: J, } impl, J: Iterator> Iterator for RandomVecs { type Item = Vec; fn next(&mut self) -> Option> { Some( (&mut self.xs) .take(usize::exact_from(self.lengths.next().unwrap())) .collect(), ) } } /// Generates random [`Vec`]s using elements from an iterator and with lengths from another /// iterator. /// /// The probability of a particular [`Vec`] being generated is the product of the probabilities of /// each of its elements, multiplied by the probability of its length being generated. /// /// `lengths` and `xs` must be infinite. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::random::random_primitive_ints; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::vecs::random::random_vecs_from_length_iterator; /// use malachite_base::vecs::random_values_from_vec; /// /// let xs = random_vecs_from_length_iterator( /// EXAMPLE_SEED, /// &|seed| random_values_from_vec(seed, vec![0, 2, 4]), /// &random_primitive_ints::, /// ); /// let values = xs.take(20).collect_vec(); /// assert_eq!( /// values.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[85, 11][..], /// &[136, 200, 235, 134], /// &[203, 223], /// &[38, 235, 217, 177], /// &[162, 32, 166, 234], /// &[30, 218], /// &[], /// &[90, 106], /// &[], /// &[9, 216, 204, 151], /// &[213, 97, 253, 78], /// &[91, 39], /// &[191, 175, 170, 232], /// &[233, 2], /// &[35, 22, 217, 198], /// &[114, 17, 32, 173], /// &[114, 65, 121, 222], /// &[], /// &[173, 25, 144, 148], /// &[] /// ] /// ); /// ``` #[inline] pub fn random_vecs_from_length_iterator, J: Iterator>( seed: Seed, lengths_gen: &dyn Fn(Seed) -> I, xs_gen: &dyn Fn(Seed) -> J, ) -> RandomVecs { RandomVecs { lengths: lengths_gen(seed.fork("lengths")), xs: xs_gen(seed.fork("xs")), } } /// Generates random [`Vec`]s using elements from an iterator. /// /// The lengths of the [`Vec`]s are sampled from a geometric distribution with a specified mean $m$, /// equal to `mean_length_numerator / mean_length_denominator`. $m$ must be greater than 0. /// /// $$ /// P((x\_i)\_{i=0}^{n-1}) = \frac{m^n}{(m+1)^{n+1}}\prod_{i=0}^{n-1}P(x_i). /// $$ /// /// `xs_gen` must be infinite. /// /// # Panics /// Panics if `mean_length_numerator` or `mean_length_denominator` are zero, or, if after being /// reduced to lowest terms, their sum is greater than or equal to $2^{64}$. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::random::random_primitive_ints; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::vecs::random::random_vecs; /// /// let xs = random_vecs(EXAMPLE_SEED, &random_primitive_ints::, 4, 1); /// let values = xs.take(20).collect_vec(); /// assert_eq!( /// values.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[][..], /// &[85, 11, 136, 200, 235, 134, 203, 223, 38, 235, 217, 177, 162, 32], /// &[166, 234, 30, 218], /// &[90, 106, 9, 216], /// &[204], /// &[], /// &[151, 213, 97, 253, 78], /// &[91, 39], /// &[191, 175, 170, 232], /// &[], /// &[233, 2, 35, 22, 217, 198], /// &[], /// &[], /// &[114, 17, 32, 173, 114, 65, 121, 222, 173, 25, 144], /// &[148, 79, 115, 52, 73, 69, 137, 91], /// &[], /// &[153, 178, 112], /// &[], /// &[34, 95, 106, 167, 197], /// &[130, 168, 122, 207, 172, 177, 86, 150, 221] /// ] /// ); /// ``` #[inline] pub fn random_vecs( seed: Seed, xs_gen: &dyn Fn(Seed) -> I, mean_length_numerator: u64, mean_length_denominator: u64, ) -> RandomVecs, I> { random_vecs_from_length_iterator( seed, &|seed_2| { geometric_random_unsigneds(seed_2, mean_length_numerator, mean_length_denominator) }, xs_gen, ) } /// Generates random [`Vec`]s with a minimum length, using elements from an iterator. /// /// The lengths of the [`Vec`]s are sampled from a geometric distribution with a specified mean $m$, /// equal to `mean_length_numerator / mean_length_denominator`. $m$ must be greater than /// `min_length`. /// /// $$ /// P((x\_i)\_{i=0}^{n-1}) = \\begin{cases} /// \frac{(m-a)^{n-a}}{(m+1-a)^{n+1-a}}\prod_{i=0}^{n-1}P(x_i) & \text{if} \\quad n\geq a, \\\\ /// 0 & \\text{otherwise}, /// \\end{cases} /// $$ /// where $a$ is `min_length`. /// /// `xs_gen` must be infinite. /// /// # Panics /// Panics if `mean_length_numerator` or `mean_length_denominator` are zero, if their ratio is less /// than or equal to `min_length`, or if they are too large and manipulating them leads to /// arithmetic overflow. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::random::random_primitive_ints; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::vecs::random::random_vecs_min_length; /// /// let xs = random_vecs_min_length(EXAMPLE_SEED, 2, &random_primitive_ints::, 6, 1); /// let values = xs.take(20).collect_vec(); /// assert_eq!( /// values.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[85, 11][..], /// &[136, 200, 235, 134, 203, 223, 38, 235, 217, 177, 162, 32, 166, 234, 30, 218], /// &[90, 106, 9, 216, 204, 151], /// &[213, 97, 253, 78, 91, 39], /// &[191, 175, 170], /// &[232, 233], /// &[2, 35, 22, 217, 198, 114, 17], /// &[32, 173, 114, 65], /// &[121, 222, 173, 25, 144, 148], /// &[79, 115], /// &[52, 73, 69, 137, 91, 153, 178, 112], /// &[34, 95], /// &[106, 167], /// &[197, 130, 168, 122, 207, 172, 177, 86, 150, 221, 218, 101, 115], /// &[74, 9, 123, 109, 52, 201, 159, 247, 250, 48], /// &[133, 235], /// &[196, 40, 97, 104, 68], /// &[190, 216], /// &[7, 216, 157, 43, 43, 112, 217], /// &[24, 11, 103, 211, 84, 135, 55, 29, 206, 89, 65] /// ] /// ); /// ``` #[inline] pub fn random_vecs_min_length( seed: Seed, min_length: u64, xs_gen: &dyn Fn(Seed) -> I, mean_length_numerator: u64, mean_length_denominator: u64, ) -> RandomVecs, I> { random_vecs_from_length_iterator( seed, &|seed_2| { geometric_random_unsigned_inclusive_range( seed_2, min_length, u64::MAX, mean_length_numerator, mean_length_denominator, ) }, xs_gen, ) } /// Generates random [`Vec`]s with lengths in $[a, b)$, using elements from an iterator. /// /// The lengths of the [`Vec`]s are sampled from a uniform distribution on $[a, b)$. $a$ must be /// less than $b$. /// /// $$ /// P((x\_i)\_{i=0}^{n-1}) = \\begin{cases} /// \frac{1}{b-a}\prod_{i=0}^{n-1}P(x_i) & \text{if} \\quad a \leq n < b, \\\\ /// 0 & \\text{otherwise}. /// \\end{cases} /// $$ /// /// `xs_gen` must be infinite. /// /// # Panics /// Panics if $a \geq b$. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::random::random_primitive_ints; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::vecs::random::random_vecs_length_range; /// /// let xs = random_vecs_length_range(EXAMPLE_SEED, 2, 5, &random_primitive_ints::); /// let values = xs.take(20).collect_vec(); /// assert_eq!( /// values.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[85, 11, 136][..], /// &[200, 235, 134, 203], /// &[223, 38, 235], /// &[217, 177, 162, 32], /// &[166, 234, 30, 218], /// &[90, 106, 9], /// &[216, 204], /// &[151, 213, 97], /// &[253, 78], /// &[91, 39, 191, 175], /// &[170, 232, 233, 2], /// &[35, 22, 217], /// &[198, 114, 17, 32], /// &[173, 114, 65], /// &[121, 222, 173, 25], /// &[144, 148, 79, 115], /// &[52, 73, 69, 137], /// &[91, 153], /// &[178, 112, 34, 95], /// &[106, 167] /// ] /// ); /// ``` #[inline] pub fn random_vecs_length_range( seed: Seed, a: u64, b: u64, xs_gen: &dyn Fn(Seed) -> I, ) -> RandomVecs, I> { random_vecs_from_length_iterator(seed, &|seed_2| random_unsigned_range(seed_2, a, b), xs_gen) } /// Generates random [`Vec`]s with lengths in $[a, b]$, using elements from an iterator. /// /// The lengths of the [`Vec`]s are sampled from a uniform distribution on $[a, b]$. $a$ must be /// less than or equal to $b$. /// /// $$ /// P((x\_i)\_{i=0}^{n-1}) = \\begin{cases} /// \frac{1}{b-a+1}\prod_{i=0}^{n-1}P(x_i) & \text{if} \\quad a \leq n \leq b, \\\\ /// 0 & \\text{otherwise}. /// \\end{cases} /// $$ /// /// `xs_gen` must be infinite. /// /// # Panics /// Panics if $a > b$. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::random::random_primitive_ints; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::vecs::random::random_vecs_length_inclusive_range; /// /// let xs = random_vecs_length_inclusive_range(EXAMPLE_SEED, 2, 4, &random_primitive_ints::); /// let values = xs.take(20).collect_vec(); /// assert_eq!( /// values.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[85, 11, 136][..], /// &[200, 235, 134, 203], /// &[223, 38, 235], /// &[217, 177, 162, 32], /// &[166, 234, 30, 218], /// &[90, 106, 9], /// &[216, 204], /// &[151, 213, 97], /// &[253, 78], /// &[91, 39, 191, 175], /// &[170, 232, 233, 2], /// &[35, 22, 217], /// &[198, 114, 17, 32], /// &[173, 114, 65], /// &[121, 222, 173, 25], /// &[144, 148, 79, 115], /// &[52, 73, 69, 137], /// &[91, 153], /// &[178, 112, 34, 95], /// &[106, 167] /// ] /// ); /// ``` #[inline] pub fn random_vecs_length_inclusive_range( seed: Seed, a: u64, b: u64, xs_gen: &dyn Fn(Seed) -> I, ) -> RandomVecs, I> { random_vecs_from_length_iterator( seed, &|seed_2| random_unsigned_inclusive_range(seed_2, a, b), xs_gen, ) } #[doc(hidden)] #[derive(Clone, Debug)] pub struct RandomOrderedUniqueVecsLength2 where I::Item: Ord, { xs: I, } impl Iterator for RandomOrderedUniqueVecsLength2 where I::Item: Ord, { type Item = Vec; #[inline] fn next(&mut self) -> Option> { let mut out = Vec::with_capacity(2); loop { let x = self.xs.next().unwrap(); if out.is_empty() { out.push(x); } else { match x.cmp(&out[0]) { Equal => {} Greater => { out.push(x); break; } Less => { out.insert(0, x); break; } } } } Some(out) } } #[doc(hidden)] #[derive(Clone, Debug)] pub struct RandomOrderedUniqueVecsFixedLengthGreaterThan2 where I::Item: Ord, { xs: RandomBTreeSetsFixedLength, } impl Iterator for RandomOrderedUniqueVecsFixedLengthGreaterThan2 where I::Item: Ord, { type Item = Vec; #[inline] fn next(&mut self) -> Option> { Some(self.xs.next().unwrap().into_iter().collect()) } } /// Generates random [`Vec`]s of a fixed length, where the [`Vec`]s have no repeated elements, and /// the elements are in ascending order. /// /// This `struct` is created by [`random_ordered_unique_vecs_fixed_length`]; see its documentation /// for more. #[derive(Clone, Debug)] pub enum RandomOrderedUniqueVecsFixedLength where I::Item: Ord, { Zero, One(I), Two(RandomOrderedUniqueVecsLength2), GreaterThan2(RandomOrderedUniqueVecsFixedLengthGreaterThan2), } impl Iterator for RandomOrderedUniqueVecsFixedLength where I::Item: Ord, { type Item = Vec; #[inline] fn next(&mut self) -> Option> { match self { RandomOrderedUniqueVecsFixedLength::Zero => Some(vec![]), RandomOrderedUniqueVecsFixedLength::One(ref mut xs) => xs.next().map(|x| vec![x]), RandomOrderedUniqueVecsFixedLength::Two(ref mut xs) => xs.next(), RandomOrderedUniqueVecsFixedLength::GreaterThan2(ref mut xs) => xs.next(), } } } /// Randomly generates [`Vec`]s of a given length, where the [`Vec`]s have no repeated elements, and /// the elements are in ascending order. /// /// The input iterator must generate at least `len` distinct elements; otherwise, this iterator will /// hang. /// /// $$ /// P((x\_i)\_{i=0}^{n-1}) = n!\prod\_{i=0}^{n-1}P(x\_i). /// $$ /// /// The above formula assumes that the [`Vec`] is valid, \emph{i.e.} its elements are strictly /// increasing. The probability of an invalid [`Vec`] is zero. /// /// If `len` is 0, the output consists of the empty list, repeated. /// /// `xs` must be infinite. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::random::random_unsigned_inclusive_range; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::vecs::random::random_ordered_unique_vecs_fixed_length; /// /// let xss = random_ordered_unique_vecs_fixed_length( /// 2, /// random_unsigned_inclusive_range::(EXAMPLE_SEED, 1, 100), /// ) /// .take(10) /// .collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[24, 95], /// &[71, 99], /// &[53, 93], /// &[34, 85], /// &[2, 48], /// &[11, 55], /// &[18, 48], /// &[90, 93], /// &[67, 93], /// &[93, 95] /// ] /// ); /// ``` #[inline] pub fn random_ordered_unique_vecs_fixed_length( len: u64, xs: I, ) -> RandomOrderedUniqueVecsFixedLength where I::Item: Ord, { match len { 0 => RandomOrderedUniqueVecsFixedLength::Zero, 1 => RandomOrderedUniqueVecsFixedLength::One(xs), 2 => RandomOrderedUniqueVecsFixedLength::Two(RandomOrderedUniqueVecsLength2 { xs }), len => RandomOrderedUniqueVecsFixedLength::GreaterThan2( RandomOrderedUniqueVecsFixedLengthGreaterThan2 { xs: random_b_tree_sets_fixed_length(len, xs), }, ), } } /// Generates random [`Vec`]s with lengths from an iterator, where the [`Vec`]s have no repeated /// elements, and the elements are in ascending order. #[derive(Clone, Debug)] pub struct RandomOrderedUniqueVecs, J: Iterator> { xs: RandomBTreeSets, } impl, J: Iterator> Iterator for RandomOrderedUniqueVecs { type Item = Vec; #[inline] fn next(&mut self) -> Option> { Some(self.xs.next().unwrap().into_iter().collect()) } } /// Generates random [`Vec`]s using elements from an iterator and with lengths from another /// iterator, where the [`Vec`]s have no repeated elements, and the elements are in ascending order. /// /// The input iterator must generate at least many distinct elements as any number generated by the /// lengths iterator; otherwise, this iterator will hang. /// /// $$ /// P((x\_i)\_{i=0}^{n-1}) = n!P(n)\prod\_{i=0}^{n-1}P(x\_i). /// $$ /// /// The above formula assumes that the [`Vec`] is valid, \emph{i.e.} its elements are strictly /// increasing. The probability of an invalid [`Vec`] is zero. /// /// `lengths` and `xs` must be infinite. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::random::random_primitive_ints; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::vecs::random::random_ordered_unique_vecs_from_length_iterator; /// use malachite_base::vecs::random_values_from_vec; /// /// let xs = random_ordered_unique_vecs_from_length_iterator( /// EXAMPLE_SEED, /// &|seed| random_values_from_vec(seed, vec![0, 2, 4]), /// &random_primitive_ints::, /// ); /// let values = xs.take(20).collect_vec(); /// assert_eq!( /// values.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[11, 85][..], /// &[134, 136, 200, 235], /// &[203, 223], /// &[38, 177, 217, 235], /// &[32, 162, 166, 234], /// &[30, 218], /// &[], /// &[90, 106], /// &[], /// &[9, 151, 204, 216], /// &[78, 97, 213, 253], /// &[39, 91], /// &[170, 175, 191, 232], /// &[2, 233], /// &[22, 35, 198, 217], /// &[17, 32, 114, 173], /// &[65, 114, 121, 222], /// &[], /// &[25, 144, 148, 173], /// &[] /// ] /// ); /// ``` #[inline] pub fn random_ordered_unique_vecs_from_length_iterator< T: Ord, I: Iterator, J: Iterator, >( seed: Seed, lengths_gen: &dyn Fn(Seed) -> I, xs_gen: &dyn Fn(Seed) -> J, ) -> RandomOrderedUniqueVecs { RandomOrderedUniqueVecs { xs: random_b_tree_sets_from_length_iterator(seed, lengths_gen, xs_gen), } } /// Generates random [`Vec`]s using elements from an iterator, where the [`Vec`]s have no repeated /// elements, and the elements are in ascending order. /// /// The lengths of the [`Vec`]s are sampled from a geometric distribution with a specified mean $m$, /// equal to `mean_length_numerator / mean_length_denominator`. $m$ must be greater than 0. /// /// Strictly speaking, the input iterator must generate infinitely many distinct elements. In /// practice it only needs to generate $k$ distinct elements, where $k$ is the largest length /// actually sampled from the geometric distribution. For example, if `mean_length_numerator / /// mean_length_denominator` is significantly lower than 256, then it's ok to use /// `random_unsigneds::`. /// /// $$ /// P((x\_i)\_{i=0}^{n-1}) = n!P_g(n)\prod\_{i=0}^{n-1}P(x\_i), /// $$ /// where $P_g(n)$ is the probability function described in [`geometric_random_unsigneds`]. /// /// `xs_gen` must be infinite. /// /// # Panics /// Panics if `mean_length_numerator` or `mean_length_denominator` are zero, or, if after being /// reduced to lowest terms, their sum is greater than or equal to $2^{64}$. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::random::random_primitive_ints; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::vecs::random::random_ordered_unique_vecs; /// /// let xs = random_ordered_unique_vecs(EXAMPLE_SEED, &random_primitive_ints::, 4, 1); /// let values = xs.take(20).collect_vec(); /// assert_eq!( /// values.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[][..], /// &[11, 32, 38, 85, 134, 136, 162, 166, 177, 200, 203, 217, 223, 235], /// &[30, 90, 218, 234], /// &[9, 106, 204, 216], /// &[151], /// &[], /// &[78, 91, 97, 213, 253], /// &[39, 191], /// &[170, 175, 232, 233], /// &[], /// &[2, 22, 35, 114, 198, 217], /// &[], /// &[], /// &[17, 25, 32, 65, 79, 114, 121, 144, 148, 173, 222], /// &[52, 69, 73, 91, 115, 137, 153, 178], /// &[], /// &[34, 95, 112], /// &[], /// &[106, 130, 167, 168, 197], /// &[86, 101, 122, 150, 172, 177, 207, 218, 221] /// ] /// ); /// ``` #[inline] pub fn random_ordered_unique_vecs( seed: Seed, xs_gen: &dyn Fn(Seed) -> I, mean_length_numerator: u64, mean_length_denominator: u64, ) -> RandomOrderedUniqueVecs, I> where I::Item: Ord, { random_ordered_unique_vecs_from_length_iterator( seed, &|seed_2| { geometric_random_unsigneds(seed_2, mean_length_numerator, mean_length_denominator) }, xs_gen, ) } /// Generates random [`Vec`]s with a minimum length, using elements from an iterator, where the /// [`Vec`]s have no repeated elements, and the elements are in ascending order. /// /// Strictly speaking, the input iterator must generate infinitely many distinct elements. In /// practice it only needs to generate $k$ distinct elements, where $k$ is the largest length /// actually sampled from the geometric distribution. For example, if `mean_length_numerator / /// mean_length_denominator` is significantly lower than 256, then it's ok to use /// `random_unsigneds::`. /// /// $$ /// P((x\_i)\_{i=0}^{n-1}) = n!P_g(n)\prod\_{i=0}^{n-1}P(x\_i), /// $$ /// where $P_g(n)$ is the probability function described in /// [`geometric_random_unsigned_inclusive_range`], with $a$ equal to `min_length` and `b` to /// `u64::MAX`. /// /// `xs_gen` must be infinite. /// /// # Panics /// Panics if `mean_length_numerator` or `mean_length_denominator` are zero, if their ratio is less /// than or equal to `min_length`, or if they are too large and manipulating them leads to /// arithmetic overflow. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::random::random_primitive_ints; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::vecs::random::random_ordered_unique_vecs_min_length; /// /// let xs = /// random_ordered_unique_vecs_min_length(EXAMPLE_SEED, 2, &random_primitive_ints::, 6, 1); /// let values = xs.take(20).collect_vec(); /// assert_eq!( /// values.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[11, 85][..], /// &[30, 32, 38, 90, 134, 136, 162, 166, 177, 200, 203, 217, 218, 223, 234, 235], /// &[9, 106, 151, 204, 213, 216], /// &[39, 78, 91, 97, 191, 253], /// &[170, 175, 232], /// &[2, 233], /// &[17, 22, 32, 35, 114, 198, 217], /// &[65, 114, 121, 173], /// &[25, 79, 144, 148, 173, 222], /// &[52, 115], /// &[34, 69, 73, 91, 112, 137, 153, 178], /// &[95, 106], /// &[167, 197], /// &[74, 86, 101, 115, 122, 130, 150, 168, 172, 177, 207, 218, 221], /// &[9, 48, 52, 109, 123, 133, 159, 201, 247, 250], /// &[196, 235], /// &[40, 68, 97, 104, 190], /// &[7, 216], /// &[11, 24, 43, 112, 157, 216, 217], /// &[29, 51, 55, 65, 84, 89, 103, 135, 191, 206, 211] /// ] /// ); /// ``` #[inline] pub fn random_ordered_unique_vecs_min_length( seed: Seed, min_length: u64, xs_gen: &dyn Fn(Seed) -> I, mean_length_numerator: u64, mean_length_denominator: u64, ) -> RandomOrderedUniqueVecs, I> where I::Item: Ord, { random_ordered_unique_vecs_from_length_iterator( seed, &|seed_2| { geometric_random_unsigned_inclusive_range( seed_2, min_length, u64::MAX, mean_length_numerator, mean_length_denominator, ) }, xs_gen, ) } /// Generates random [`Vec`]s with lengths in $[a, b)$, using elements from an iterator, where the /// [`Vec`]s have no repeated elements, and the elements are in ascending order. /// /// The lengths of the [`Vec`]s are sampled from a uniform distribution on $[a, b)$. $a$ must be /// less than $b$. /// /// The input iterator must generate at least $b$ distinct elements. /// /// $$ /// P((x\_i)\_{i=0}^{n-1}, a, b) = \frac{n!}{b - a}\prod\_{i=0}^{n-1}P(x\_i). /// $$ /// /// `xs_gen` must be infinite. /// /// # Panics /// Panics if $a \geq b$. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::random::random_primitive_ints; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::vecs::random::random_ordered_unique_vecs_length_range; /// /// let xs = /// random_ordered_unique_vecs_length_range(EXAMPLE_SEED, 2, 5, &random_primitive_ints::); /// let values = xs.take(20).collect_vec(); /// assert_eq!( /// values.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[11, 85, 136][..], /// &[134, 200, 203, 235], /// &[38, 223, 235], /// &[32, 162, 177, 217], /// &[30, 166, 218, 234], /// &[9, 90, 106], /// &[204, 216], /// &[97, 151, 213], /// &[78, 253], /// &[39, 91, 175, 191], /// &[2, 170, 232, 233], /// &[22, 35, 217], /// &[17, 32, 114, 198], /// &[65, 114, 173], /// &[25, 121, 173, 222], /// &[79, 115, 144, 148], /// &[52, 69, 73, 137], /// &[91, 153], /// &[34, 95, 112, 178], /// &[106, 167] /// ] /// ); /// ``` #[inline] pub fn random_ordered_unique_vecs_length_range( seed: Seed, a: u64, b: u64, xs_gen: &dyn Fn(Seed) -> I, ) -> RandomOrderedUniqueVecs, I> where I::Item: Ord, { random_ordered_unique_vecs_from_length_iterator( seed, &|seed_2| random_unsigned_range(seed_2, a, b), xs_gen, ) } /// Generates random [`Vec`]s with lengths in $[a, b]$, using elements from an iterator, where the /// [`Vec`]s have no repeated elements, and the elements are in ascending order. /// /// The lengths of the [`Vec`]s are sampled from a uniform distribution on $[a, b]$. $a$ must be /// less than or equal to $b$. /// /// The input iterator must generate at least $b$ distinct elements. /// /// $$ /// P((x\_i)\_{i=0}^{n-1}, a, b) = \frac{n!}{b - a + 1}\prod\_{i=0}^{n-1}P(x\_i). /// $$ /// /// `xs_gen` must be infinite. /// /// # Panics /// Panics if $a > b$. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::random::random_primitive_ints; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::vecs::random::random_ordered_unique_vecs_length_inclusive_range; /// /// let xs = random_ordered_unique_vecs_length_inclusive_range( /// EXAMPLE_SEED, /// 2, /// 4, /// &random_primitive_ints::, /// ); /// let values = xs.take(20).collect_vec(); /// assert_eq!( /// values.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[11, 85, 136][..], /// &[134, 200, 203, 235], /// &[38, 223, 235], /// &[32, 162, 177, 217], /// &[30, 166, 218, 234], /// &[9, 90, 106], /// &[204, 216], /// &[97, 151, 213], /// &[78, 253], /// &[39, 91, 175, 191], /// &[2, 170, 232, 233], /// &[22, 35, 217], /// &[17, 32, 114, 198], /// &[65, 114, 173], /// &[25, 121, 173, 222], /// &[79, 115, 144, 148], /// &[52, 69, 73, 137], /// &[91, 153], /// &[34, 95, 112, 178], /// &[106, 167] /// ] /// ); /// ``` #[inline] pub fn random_ordered_unique_vecs_length_inclusive_range( seed: Seed, a: u64, b: u64, xs_gen: &dyn Fn(Seed) -> I, ) -> RandomOrderedUniqueVecs, I> where I::Item: Ord, { random_ordered_unique_vecs_from_length_iterator( seed, &|seed_2| random_unsigned_inclusive_range(seed_2, a, b), xs_gen, ) } #[doc(hidden)] #[derive(Clone, Debug)] pub struct RandomUniqueVecsLength2 where I::Item: Eq, { xs: I, } impl Iterator for RandomUniqueVecsLength2 where I::Item: Eq, { type Item = Vec; #[inline] fn next(&mut self) -> Option> { let mut out = Vec::with_capacity(2); loop { let x = self.xs.next().unwrap(); if out.is_empty() { out.push(x); } else if x != out[0] { out.push(x); return Some(out); } } } } /// Generates random [`Vec`]s with lengths from an iterator, where the [`Vec`]s have no repeated /// elements. #[derive(Clone, Debug)] pub struct RandomUniqueVecs, J: Iterator> { lengths: I, xs: J, } impl, J: Iterator> Iterator for RandomUniqueVecs { type Item = Vec; fn next(&mut self) -> Option> { // We avoid cloning the T values. We first move them into a HashMap, then into a // Vec>, then into the output Vec. let len = usize::exact_from(self.lengths.next().unwrap()); let mut xs_to_indices = HashMap::with_capacity(len); let mut i = 0; while i < len { xs_to_indices .entry(self.xs.next().unwrap()) .or_insert_with(|| { i += 1; i - 1 }); } let mut out = Vec::with_capacity(len); out.resize_with(len, || None); for (x, i) in xs_to_indices { out[i] = Some(x); } Some(out.into_iter().map(Option::unwrap).collect()) } } /// Generates random [`Vec`]s using elements from an iterator and with lengths from another /// iterator, where the [`Vec`]s have no repeated elements. /// /// The input iterator must generate at least many distinct elements as any number generated by the /// lengths iterator; otherwise, this iterator will hang. /// /// `lengths` and `xs` must be infinite. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::random::random_primitive_ints; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::vecs::random::random_unique_vecs_from_length_iterator; /// use malachite_base::vecs::random_values_from_vec; /// /// let xs = random_unique_vecs_from_length_iterator( /// EXAMPLE_SEED, /// &|seed| random_values_from_vec(seed, vec![0, 2, 4]), /// &random_primitive_ints::, /// ); /// let values = xs.take(20).collect_vec(); /// assert_eq!( /// values.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[85, 11][..], /// &[136, 200, 235, 134], /// &[203, 223], /// &[38, 235, 217, 177], /// &[162, 32, 166, 234], /// &[30, 218], /// &[], /// &[90, 106], /// &[], /// &[9, 216, 204, 151], /// &[213, 97, 253, 78], /// &[91, 39], /// &[191, 175, 170, 232], /// &[233, 2], /// &[35, 22, 217, 198], /// &[114, 17, 32, 173], /// &[114, 65, 121, 222], /// &[], /// &[173, 25, 144, 148], /// &[] /// ] /// ); /// ``` #[inline] pub fn random_unique_vecs_from_length_iterator< T: Eq + Hash, I: Iterator, J: Iterator, >( seed: Seed, lengths_gen: &dyn Fn(Seed) -> I, xs_gen: &dyn Fn(Seed) -> J, ) -> RandomUniqueVecs { RandomUniqueVecs { lengths: lengths_gen(seed.fork("lengths")), xs: xs_gen(seed.fork("xs")), } } /// Generates random [`Vec`]s of a fixed length, where the [`Vec`]s have no repeated elements. /// /// This `enum` is created by [`random_unique_vecs_fixed_length`]; see its documentation for more. #[derive(Clone, Debug)] pub enum RandomUniqueVecsFixedLength where I::Item: Eq + Hash, { Zero, One(I), Two(RandomUniqueVecsLength2), GreaterThan2(RandomUniqueVecs, I>), } impl Iterator for RandomUniqueVecsFixedLength where I::Item: Eq + Hash, { type Item = Vec; #[inline] fn next(&mut self) -> Option> { match self { RandomUniqueVecsFixedLength::Zero => Some(vec![]), RandomUniqueVecsFixedLength::One(ref mut xs) => xs.next().map(|x| vec![x]), RandomUniqueVecsFixedLength::Two(ref mut xs) => xs.next(), RandomUniqueVecsFixedLength::GreaterThan2(ref mut xs) => xs.next(), } } } /// Randomly generates [`Vec`]s of a given length, where the [`Vec`]s have no repeated elements. /// /// The input iterator must generate at least `len` distinct elements; otherwise, this iterator will /// hang. /// /// If `len` is 0, the output consists of the empty list, repeated. /// /// `xs` must be infinite. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::random::random_unsigned_inclusive_range; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::vecs::random::random_unique_vecs_fixed_length; /// /// let xss = random_unique_vecs_fixed_length( /// 2, /// random_unsigned_inclusive_range::(EXAMPLE_SEED, 1, 100), /// ) /// .take(10) /// .collect_vec(); /// assert_eq!( /// xss.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[95, 24], /// &[99, 71], /// &[93, 53], /// &[85, 34], /// &[48, 2], /// &[55, 11], /// &[48, 18], /// &[90, 93], /// &[67, 93], /// &[93, 95] /// ] /// ); /// ``` #[inline] pub fn random_unique_vecs_fixed_length( len: u64, xs: I, ) -> RandomUniqueVecsFixedLength where I::Item: Eq + Hash, { match len { 0 => RandomUniqueVecsFixedLength::Zero, 1 => RandomUniqueVecsFixedLength::One(xs), 2 => RandomUniqueVecsFixedLength::Two(RandomUniqueVecsLength2 { xs }), len => RandomUniqueVecsFixedLength::GreaterThan2(RandomUniqueVecs { lengths: repeat(len), xs, }), } } /// Generates random [`Vec`]s using elements from an iterator, where the [`Vec`]s have no repeated /// elements. /// /// The lengths of the [`Vec`]s are sampled from a geometric distribution with a specified mean $m$, /// equal to `mean_length_numerator / mean_length_denominator`. $m$ must be greater than 0. /// /// Strictly speaking, the input iterator must generate infinitely many distinct elements. In /// practice it only needs to generate $k$ distinct elements, where $k$ is the largest length /// actually sampled from the geometric distribution. For example, if `mean_length_numerator / /// mean_length_denominator` is significantly lower than 256, then it's ok to use /// `random_unsigneds::`. /// /// `xs_gen` must be infinite. /// /// # Panics /// Panics if `mean_length_numerator` or `mean_length_denominator` are zero, or, if after being /// reduced to lowest terms, their sum is greater than or equal to $2^{64}$. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::random::random_primitive_ints; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::vecs::random::random_unique_vecs; /// /// let xs = random_unique_vecs(EXAMPLE_SEED, &random_primitive_ints::, 4, 1); /// let values = xs.take(20).collect_vec(); /// assert_eq!( /// values.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[][..], /// &[85, 11, 136, 200, 235, 134, 203, 223, 38, 217, 177, 162, 32, 166], /// &[234, 30, 218, 90], /// &[106, 9, 216, 204], /// &[151], /// &[], /// &[213, 97, 253, 78, 91], /// &[39, 191], /// &[175, 170, 232, 233], /// &[], /// &[2, 35, 22, 217, 198, 114], /// &[], /// &[], /// &[17, 32, 173, 114, 65, 121, 222, 25, 144, 148, 79], /// &[115, 52, 73, 69, 137, 91, 153, 178], /// &[], /// &[112, 34, 95], /// &[], /// &[106, 167, 197, 130, 168], /// &[122, 207, 172, 177, 86, 150, 221, 218, 101] /// ] /// ); /// ``` #[inline] pub fn random_unique_vecs( seed: Seed, xs_gen: &dyn Fn(Seed) -> I, mean_length_numerator: u64, mean_length_denominator: u64, ) -> RandomUniqueVecs, I> where I::Item: Eq + Hash, { random_unique_vecs_from_length_iterator( seed, &|seed_2| { geometric_random_unsigneds(seed_2, mean_length_numerator, mean_length_denominator) }, xs_gen, ) } /// Generates random [`Vec`]s with a minimum length, using elements from an iterator, where the /// [`Vec`]s have no repeated elements. /// /// Strictly speaking, the input iterator must generate infinitely many distinct elements. In /// practice it only needs to generate $k$ distinct elements, where $k$ is the largest length /// actually sampled from the geometric distribution. For example, if `mean_length_numerator / /// mean_length_denominator` is significantly lower than 256, then it's ok to use /// `random_unsigneds::`. /// /// `xs_gen` must be infinite. /// /// # Panics /// Panics if `mean_length_numerator` or `mean_length_denominator` are zero, if their ratio is less /// than or equal to `min_length`, or if they are too large and manipulating them leads to /// arithmetic overflow. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::random::random_primitive_ints; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::vecs::random::random_unique_vecs_min_length; /// /// let xs = random_unique_vecs_min_length(EXAMPLE_SEED, 2, &random_primitive_ints::, 6, 1); /// let values = xs.take(20).collect_vec(); /// assert_eq!( /// values.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[85, 11][..], /// &[136, 200, 235, 134, 203, 223, 38, 217, 177, 162, 32, 166, 234, 30, 218, 90], /// &[106, 9, 216, 204, 151, 213], /// &[97, 253, 78, 91, 39, 191], /// &[175, 170, 232], /// &[233, 2], /// &[35, 22, 217, 198, 114, 17, 32], /// &[173, 114, 65, 121], /// &[222, 173, 25, 144, 148, 79], /// &[115, 52], /// &[73, 69, 137, 91, 153, 178, 112, 34], /// &[95, 106], /// &[167, 197], /// &[130, 168, 122, 207, 172, 177, 86, 150, 221, 218, 101, 115, 74], /// &[9, 123, 109, 52, 201, 159, 247, 250, 48, 133], /// &[235, 196], /// &[40, 97, 104, 68, 190], /// &[216, 7], /// &[216, 157, 43, 112, 217, 24, 11], /// &[103, 211, 84, 135, 55, 29, 206, 89, 65, 191, 51] /// ] /// ); /// ``` #[inline] pub fn random_unique_vecs_min_length( seed: Seed, min_length: u64, xs_gen: &dyn Fn(Seed) -> I, mean_length_numerator: u64, mean_length_denominator: u64, ) -> RandomUniqueVecs, I> where I::Item: Eq + Hash, { random_unique_vecs_from_length_iterator( seed, &|seed_2| { geometric_random_unsigned_inclusive_range( seed_2, min_length, u64::MAX, mean_length_numerator, mean_length_denominator, ) }, xs_gen, ) } /// Generates random [`Vec`]s with lengths in $[a, b)$, using elements from an iterator, where the /// [`Vec`]s have no repeated elements. /// /// The lengths of the [`Vec`]s are sampled from a uniform distribution on $[a, b)$. $a$ must be /// less than $b$. /// /// The input iterator must generate at least $b$ distinct elements. /// /// `xs_gen` must be infinite. /// /// # Panics /// Panics if $a \geq b$. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::random::random_primitive_ints; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::vecs::random::random_unique_vecs_length_range; /// /// let xs = random_unique_vecs_length_range(EXAMPLE_SEED, 2, 5, &random_primitive_ints::); /// let values = xs.take(20).collect_vec(); /// assert_eq!( /// values.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[85, 11, 136][..], /// &[200, 235, 134, 203], /// &[223, 38, 235], /// &[217, 177, 162, 32], /// &[166, 234, 30, 218], /// &[90, 106, 9], /// &[216, 204], /// &[151, 213, 97], /// &[253, 78], /// &[91, 39, 191, 175], /// &[170, 232, 233, 2], /// &[35, 22, 217], /// &[198, 114, 17, 32], /// &[173, 114, 65], /// &[121, 222, 173, 25], /// &[144, 148, 79, 115], /// &[52, 73, 69, 137], /// &[91, 153], /// &[178, 112, 34, 95], /// &[106, 167] /// ] /// ); /// ``` #[inline] pub fn random_unique_vecs_length_range( seed: Seed, a: u64, b: u64, xs_gen: &dyn Fn(Seed) -> I, ) -> RandomUniqueVecs, I> where I::Item: Eq + Hash, { random_unique_vecs_from_length_iterator( seed, &|seed_2| random_unsigned_range(seed_2, a, b), xs_gen, ) } /// Generates random [`Vec`]s with lengths in $[a, b]$, using elements from an iterator, where the /// [`Vec`]s have no repeated elements. /// /// The lengths of the [`Vec`]s are sampled from a uniform distribution on $[a, b]$. $a$ must be /// less than or equal to $b$. /// /// The input iterator must generate at least $b$ distinct elements. /// /// `xs_gen` must be infinite. /// /// # Panics /// Panics if $a > b$. /// /// # Examples /// ``` /// use itertools::Itertools; /// use malachite_base::num::random::random_primitive_ints; /// use malachite_base::random::EXAMPLE_SEED; /// use malachite_base::vecs::random::random_unique_vecs_length_inclusive_range; /// /// let xs = /// random_unique_vecs_length_inclusive_range(EXAMPLE_SEED, 2, 4, &random_primitive_ints::); /// let values = xs.take(20).collect_vec(); /// assert_eq!( /// values.iter().map(Vec::as_slice).collect_vec().as_slice(), /// &[ /// &[85, 11, 136][..], /// &[200, 235, 134, 203], /// &[223, 38, 235], /// &[217, 177, 162, 32], /// &[166, 234, 30, 218], /// &[90, 106, 9], /// &[216, 204], /// &[151, 213, 97], /// &[253, 78], /// &[91, 39, 191, 175], /// &[170, 232, 233, 2], /// &[35, 22, 217], /// &[198, 114, 17, 32], /// &[173, 114, 65], /// &[121, 222, 173, 25], /// &[144, 148, 79, 115], /// &[52, 73, 69, 137], /// &[91, 153], /// &[178, 112, 34, 95], /// &[106, 167] /// ] /// ); /// ``` #[inline] pub fn random_unique_vecs_length_inclusive_range( seed: Seed, a: u64, b: u64, xs_gen: &dyn Fn(Seed) -> I, ) -> RandomUniqueVecs, I> where I::Item: Eq + Hash, { random_unique_vecs_from_length_iterator( seed, &|seed_2| random_unsigned_inclusive_range(seed_2, a, b), xs_gen, ) } malachite-base-0.4.16/tests/bools/constants.rs000064400000000000000000000012141046102023000174130ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::comparison::traits::{Max, Min}; use malachite_base::named::Named; #[test] fn test_min() { assert_eq!(bool::MIN, false); } #[test] fn test_max() { assert_eq!(bool::MAX, true); } #[test] pub fn test_named() { assert_eq!(bool::NAME, "bool"); } malachite-base-0.4.16/tests/bools/exhaustive.rs000064400000000000000000000010651046102023000175700ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::bools::exhaustive::exhaustive_bools; #[test] fn test_exhaustive_bools() { assert_eq!(exhaustive_bools().collect_vec(), &[false, true]); } malachite-base-0.4.16/tests/bools/not_assign.rs000064400000000000000000000016221046102023000175460ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::logic::traits::NotAssign; use malachite_base::test_util::generators::bool_gen; #[test] fn test_not_assign() { let test = |mut b: bool, out| { b.not_assign(); assert_eq!(b, out); }; test(false, true); test(true, false); } #[test] fn not_assign_properties() { bool_gen().test_properties(|b| { let mut mut_b = b; mut_b.not_assign(); assert_ne!(mut_b, b); assert_eq!(mut_b, !b); mut_b.not_assign(); assert_eq!(mut_b, b); }); } malachite-base-0.4.16/tests/bools/random/get_weighted_random_bool.rs000064400000000000000000000027051046102023000236770ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::random::get_weighted_random_bool; use malachite_base::num::random::VariableRangeGenerator; use malachite_base::random::EXAMPLE_SEED; fn get_weighted_random_bool_helper(n: u64, d: u64, out: bool) { assert_eq!( get_weighted_random_bool(&mut VariableRangeGenerator::new(EXAMPLE_SEED), n, d), out ); } #[test] fn test_get_weighted_random_bool() { get_weighted_random_bool_helper(0, 1, false); get_weighted_random_bool_helper(1, 1, true); get_weighted_random_bool_helper(1, 2, false); get_weighted_random_bool_helper(1, 100, false); get_weighted_random_bool_helper(99, 100, true); } #[test] #[should_panic] fn get_weighted_random_bool_fail_1() { get_weighted_random_bool(&mut VariableRangeGenerator::new(EXAMPLE_SEED), 0, 0); } #[test] #[should_panic] fn get_weighted_random_bool_fail_2() { get_weighted_random_bool(&mut VariableRangeGenerator::new(EXAMPLE_SEED), 1, 0); } #[test] #[should_panic] fn get_weighted_random_bool_fail_3() { get_weighted_random_bool(&mut VariableRangeGenerator::new(EXAMPLE_SEED), 2, 1); } malachite-base-0.4.16/tests/bools/random/random_bools.rs000064400000000000000000000027061046102023000213440ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::random::random_bools; use malachite_base::num::float::NiceFloat; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::moments::{uniform_bool_assertions, MomentStats}; #[test] fn test_random_bools() { uniform_bool_assertions( random_bools(EXAMPLE_SEED), false, true, &[ true, false, false, false, true, true, true, false, true, true, true, true, false, true, true, true, true, false, true, false, ], &[(true, 500473), (false, 499527)], (false, Some(true)), (true, None), MomentStats { mean: NiceFloat(0.5), standard_deviation: NiceFloat(0.5), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.9999999999999998), }, MomentStats { mean: NiceFloat(0.5004730000000077), standard_deviation: NiceFloat(0.5000000262710417), skewness: NiceFloat(-0.0018920008465908307), excess_kurtosis: NiceFloat(-1.999996420332894), }, ); } malachite-base-0.4.16/tests/bools/random/weighted_random_bools.rs000064400000000000000000000051451046102023000232240ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::bools::random::weighted_random_bools; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::common_values_map::common_values_map; use malachite_base::test_util::stats::median; fn weighted_random_bools_helper( p_numerator: u64, p_denominator: u64, expected_values: &[bool], expected_common_values: &[(bool, usize)], expected_median: (bool, Option), ) { let xs = weighted_random_bools(EXAMPLE_SEED, p_numerator, p_denominator); let values = xs.clone().take(20).collect_vec(); let common_values = common_values_map(1000000, 10, xs.clone()); let median = median(xs.take(1000000)); assert_eq!( (values.as_slice(), common_values.as_slice(), median), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_weighted_random_bools() { // p = 0 weighted_random_bools_helper(0, 1, &[false; 20], &[(false, 1000000)], (false, None)); // p = 1 weighted_random_bools_helper(1, 1, &[true; 20], &[(true, 1000000)], (true, None)); // p = 1/2 weighted_random_bools_helper( 1, 2, &[ false, true, true, true, false, false, false, true, false, false, false, false, true, false, false, false, false, true, false, true, ], &[(false, 500473), (true, 499527)], (false, None), ); // p = 1/51 weighted_random_bools_helper( 1, 51, &[ false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, ], &[(false, 980406), (true, 19594)], (false, None), ); // w = 50/51 weighted_random_bools_helper( 50, 51, &[ true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, true, true, true, ], &[(true, 980602), (false, 19398)], (true, None), ); } #[test] #[should_panic] fn weighted_random_bools_fail_1() { weighted_random_bools(EXAMPLE_SEED, 1, 0); } #[test] #[should_panic] fn weighted_random_bools_fail_2() { weighted_random_bools(EXAMPLE_SEED, 2, 1); } malachite-base-0.4.16/tests/chars/char_type.rs000064400000000000000000000051661046102023000173510ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::chars::exhaustive::chars_increasing; use malachite_base::chars::CharType; use std::collections::HashSet; #[test] fn test_char_type() { let char_types = [ CharType::AsciiLower, CharType::AsciiUpper, CharType::AsciiNumeric, CharType::AsciiNonAlphanumericGraphic, CharType::NonAsciiGraphic, CharType::NonGraphic, ]; let mut remaining_chars: HashSet<_> = chars_increasing().collect(); let mut n = remaining_chars.len(); let mut frequencies = Vec::new(); for &char_type in &char_types { remaining_chars.retain(|&c| !char_type.contains(c)); let frequency = n - remaining_chars.len(); n = remaining_chars.len(); frequencies.push((char_type, frequency)); } assert_eq!(n, 0); assert_eq!( frequencies, &[ (CharType::AsciiLower, 26), (CharType::AsciiUpper, 26), (CharType::AsciiNumeric, 10), (CharType::AsciiNonAlphanumericGraphic, 33), (CharType::NonAsciiGraphic, 147502), (CharType::NonGraphic, 964467) ] ); let first_chars = char_types.iter().map(|&char_type| { ( char_type, chars_increasing().find(|&c| char_type.contains(c)).unwrap(), ) }); assert_eq!( first_chars.collect_vec(), &[ (CharType::AsciiLower, 'a'), (CharType::AsciiUpper, 'A'), (CharType::AsciiNumeric, '0'), (CharType::AsciiNonAlphanumericGraphic, ' '), (CharType::NonAsciiGraphic, '¡'), (CharType::NonGraphic, '\u{0}') ] ); let last_chars = char_types.iter().map(|&char_type| { ( char_type, chars_increasing() .rev() .find(|&c| char_type.contains(c)) .unwrap(), ) }); assert_eq!( last_chars.collect_vec(), &[ (CharType::AsciiLower, 'z'), (CharType::AsciiUpper, 'Z'), (CharType::AsciiNumeric, '9'), (CharType::AsciiNonAlphanumericGraphic, '~'), (CharType::NonAsciiGraphic, '𲎯'), (CharType::NonGraphic, '\u{10ffff}') ] ); } malachite-base-0.4.16/tests/chars/constants.rs000064400000000000000000000012171046102023000174000ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::comparison::traits::Min; use malachite_base::named::Named; #[test] fn test_min() { assert_eq!(char::MIN, '\u{0}'); } #[test] fn test_max() { assert_eq!(char::MAX, '\u{10ffff}'); } #[test] pub fn test_named() { assert_eq!(bool::NAME, "bool"); } malachite-base-0.4.16/tests/chars/crement/char_to_contiguous_range.rs000064400000000000000000000026071046102023000240770ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::chars::constants::{ CHAR_JUST_ABOVE_SURROGATES, CHAR_JUST_BELOW_SURROGATES, NUMBER_OF_CHARS, }; use malachite_base::chars::crement::{char_to_contiguous_range, contiguous_range_to_char}; use malachite_base::test_util::generators::{char_gen, char_pair_gen}; #[test] fn test_char_to_contiguous_range() { let test = |c, out| { assert_eq!(char_to_contiguous_range(c), out); }; test('\u{0}', 0); test('a', 97); test('A', 65); test(CHAR_JUST_BELOW_SURROGATES, 55295); test(CHAR_JUST_ABOVE_SURROGATES, 55296); test(char::MAX, 1112063); } #[test] fn char_to_contiguous_range_properties() { char_gen().test_properties_no_exhaustive_limit(|c| { let u = char_to_contiguous_range(c); assert_eq!(contiguous_range_to_char(u), Some(c)); assert!(u < NUMBER_OF_CHARS); }); char_pair_gen().test_properties(|(c, d)| { assert_eq!( c.cmp(&d), char_to_contiguous_range(c).cmp(&char_to_contiguous_range(d)) ); }); } malachite-base-0.4.16/tests/chars/crement/contiguous_range_to_char.rs000064400000000000000000000032111046102023000240670ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::chars::constants::{ CHAR_JUST_ABOVE_SURROGATES, CHAR_JUST_BELOW_SURROGATES, NUMBER_OF_CHARS, }; use malachite_base::chars::crement::{char_to_contiguous_range, contiguous_range_to_char}; use malachite_base::test_util::generators::{ unsigned_gen, unsigned_gen_var_2, unsigned_pair_gen_var_1, }; #[test] fn test_contiguous_range_to_char() { let test = |u, out| { assert_eq!(contiguous_range_to_char(u), out); }; test(0, Some('\u{0}')); test(97, Some('a')); test(65, Some('A')); test(55295, Some(CHAR_JUST_BELOW_SURROGATES)); test(55296, Some(CHAR_JUST_ABOVE_SURROGATES)); test(NUMBER_OF_CHARS - 1, Some(char::MAX)); test(NUMBER_OF_CHARS, None); test(u32::MAX, None); } #[test] fn contiguous_range_to_char_properties() { unsigned_gen().test_properties(|u| { assert_eq!(contiguous_range_to_char(u).is_some(), u < NUMBER_OF_CHARS); }); unsigned_gen_var_2().test_properties(|u| { assert_eq!( char_to_contiguous_range(contiguous_range_to_char(u).unwrap()), u ); }); unsigned_pair_gen_var_1().test_properties(|(u, v)| { assert_eq!( u.cmp(&v), contiguous_range_to_char(u).cmp(&contiguous_range_to_char(v)) ); }); } malachite-base-0.4.16/tests/chars/crement/crement.rs000064400000000000000000000037231046102023000204620ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::chars::constants::{CHAR_JUST_ABOVE_SURROGATES, CHAR_JUST_BELOW_SURROGATES}; use malachite_base::chars::crement::{decrement_char, increment_char}; use malachite_base::test_util::generators::{char_gen_var_1, char_gen_var_2}; #[test] fn test_increment_char() { let test = |mut c: char, out| { increment_char(&mut c); assert_eq!(c, out); }; test('\u{0}', '\u{1}'); test('a', 'b'); test('A', 'B'); test(CHAR_JUST_BELOW_SURROGATES, CHAR_JUST_ABOVE_SURROGATES); test('\u{10fffe}', char::MAX); } #[test] #[should_panic] fn increment_char_fail() { let mut c = char::MAX; increment_char(&mut c); } #[test] fn test_decrement_char() { let test = |mut c: char, out| { decrement_char(&mut c); assert_eq!(c, out); }; test('\u{1}', '\u{0}'); test('b', 'a'); test('B', 'A'); test(CHAR_JUST_ABOVE_SURROGATES, CHAR_JUST_BELOW_SURROGATES); test(char::MAX, '\u{10fffe}'); } #[test] #[should_panic] fn decrement_char_fail() { let mut c = '\u{0}'; decrement_char(&mut c); } #[test] fn increment_char_properties() { char_gen_var_1().test_properties_no_exhaustive_limit(|c| { let mut mut_c = c; increment_char(&mut mut_c); assert_ne!(mut_c, c); decrement_char(&mut mut_c); assert_eq!(mut_c, c); }); } #[test] fn decrement_char_properties() { char_gen_var_2().test_properties_no_exhaustive_limit(|c| { let mut mut_c = c; decrement_char(&mut mut_c); assert_ne!(mut_c, c); increment_char(&mut mut_c); assert_eq!(mut_c, c); }); } malachite-base-0.4.16/tests/chars/exhaustive/ascii_chars_increasing.rs000064400000000000000000000016321046102023000242240ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::chars::exhaustive::ascii_chars_increasing; #[test] fn test_ascii_chars_increasing() { assert_eq!( ascii_chars_increasing().collect::(), "\u{0}\u{1}\u{2}\u{3}\u{4}\u{5}\u{6}\u{7}\u{8}\t\n\u{b}\u{c}\r\u{e}\u{f}\u{10}\u{11}\u{12}\ \u{13}\u{14}\u{15}\u{16}\u{17}\u{18}\u{19}\u{1a}\u{1b}\u{1c}\u{1d}\u{1e}\u{1f} !\"#$%&\'()*\ +,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u{7f}" ); assert_eq!(ascii_chars_increasing().count(), 1 << 7); } malachite-base-0.4.16/tests/chars/exhaustive/chars_increasing.rs000064400000000000000000000071611046102023000230570ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::chars::constants::NUMBER_OF_CHARS; use malachite_base::chars::exhaustive::chars_increasing; use malachite_base::num::conversion::traits::ExactFrom; #[test] fn test_chars_increasing() { assert_eq!( chars_increasing().take(200).collect::(), "\u{0}\u{1}\u{2}\u{3}\u{4}\u{5}\u{6}\u{7}\u{8}\t\n\u{b}\u{c}\r\u{e}\u{f}\u{10}\u{11}\u{12}\ \u{13}\u{14}\u{15}\u{16}\u{17}\u{18}\u{19}\u{1a}\u{1b}\u{1c}\u{1d}\u{1e}\u{1f} !\"#$%&\'()*\ +,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u{7f}\ \u{80}\u{81}\u{82}\u{83}\u{84}\u{85}\u{86}\u{87}\u{88}\u{89}\u{8a}\u{8b}\u{8c}\u{8d}\u{8e}\ \u{8f}\u{90}\u{91}\u{92}\u{93}\u{94}\u{95}\u{96}\u{97}\u{98}\u{99}\u{9a}\u{9b}\u{9c}\u{9d}\ \u{9e}\u{9f}\u{a0}¡¢£¤¥¦§¨©ª«¬\u{ad}®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇ" ); assert_eq!( chars_increasing().rev().take(200).collect::(), "\u{10ffff}\u{10fffe}\u{10fffd}\u{10fffc}\u{10fffb}\u{10fffa}\u{10fff9}\u{10fff8}\u{10fff7}\ \u{10fff6}\u{10fff5}\u{10fff4}\u{10fff3}\u{10fff2}\u{10fff1}\u{10fff0}\u{10ffef}\u{10ffee}\ \u{10ffed}\u{10ffec}\u{10ffeb}\u{10ffea}\u{10ffe9}\u{10ffe8}\u{10ffe7}\u{10ffe6}\u{10ffe5}\ \u{10ffe4}\u{10ffe3}\u{10ffe2}\u{10ffe1}\u{10ffe0}\u{10ffdf}\u{10ffde}\u{10ffdd}\u{10ffdc}\ \u{10ffdb}\u{10ffda}\u{10ffd9}\u{10ffd8}\u{10ffd7}\u{10ffd6}\u{10ffd5}\u{10ffd4}\u{10ffd3}\ \u{10ffd2}\u{10ffd1}\u{10ffd0}\u{10ffcf}\u{10ffce}\u{10ffcd}\u{10ffcc}\u{10ffcb}\u{10ffca}\ \u{10ffc9}\u{10ffc8}\u{10ffc7}\u{10ffc6}\u{10ffc5}\u{10ffc4}\u{10ffc3}\u{10ffc2}\u{10ffc1}\ \u{10ffc0}\u{10ffbf}\u{10ffbe}\u{10ffbd}\u{10ffbc}\u{10ffbb}\u{10ffba}\u{10ffb9}\u{10ffb8}\ \u{10ffb7}\u{10ffb6}\u{10ffb5}\u{10ffb4}\u{10ffb3}\u{10ffb2}\u{10ffb1}\u{10ffb0}\u{10ffaf}\ \u{10ffae}\u{10ffad}\u{10ffac}\u{10ffab}\u{10ffaa}\u{10ffa9}\u{10ffa8}\u{10ffa7}\u{10ffa6}\ \u{10ffa5}\u{10ffa4}\u{10ffa3}\u{10ffa2}\u{10ffa1}\u{10ffa0}\u{10ff9f}\u{10ff9e}\u{10ff9d}\ \u{10ff9c}\u{10ff9b}\u{10ff9a}\u{10ff99}\u{10ff98}\u{10ff97}\u{10ff96}\u{10ff95}\u{10ff94}\ \u{10ff93}\u{10ff92}\u{10ff91}\u{10ff90}\u{10ff8f}\u{10ff8e}\u{10ff8d}\u{10ff8c}\u{10ff8b}\ \u{10ff8a}\u{10ff89}\u{10ff88}\u{10ff87}\u{10ff86}\u{10ff85}\u{10ff84}\u{10ff83}\u{10ff82}\ \u{10ff81}\u{10ff80}\u{10ff7f}\u{10ff7e}\u{10ff7d}\u{10ff7c}\u{10ff7b}\u{10ff7a}\u{10ff79}\ \u{10ff78}\u{10ff77}\u{10ff76}\u{10ff75}\u{10ff74}\u{10ff73}\u{10ff72}\u{10ff71}\u{10ff70}\ \u{10ff6f}\u{10ff6e}\u{10ff6d}\u{10ff6c}\u{10ff6b}\u{10ff6a}\u{10ff69}\u{10ff68}\u{10ff67}\ \u{10ff66}\u{10ff65}\u{10ff64}\u{10ff63}\u{10ff62}\u{10ff61}\u{10ff60}\u{10ff5f}\u{10ff5e}\ \u{10ff5d}\u{10ff5c}\u{10ff5b}\u{10ff5a}\u{10ff59}\u{10ff58}\u{10ff57}\u{10ff56}\u{10ff55}\ \u{10ff54}\u{10ff53}\u{10ff52}\u{10ff51}\u{10ff50}\u{10ff4f}\u{10ff4e}\u{10ff4d}\u{10ff4c}\ \u{10ff4b}\u{10ff4a}\u{10ff49}\u{10ff48}\u{10ff47}\u{10ff46}\u{10ff45}\u{10ff44}\u{10ff43}\ \u{10ff42}\u{10ff41}\u{10ff40}\u{10ff3f}\u{10ff3e}\u{10ff3d}\u{10ff3c}\u{10ff3b}\u{10ff3a}\ \u{10ff39}\u{10ff38}" ); assert_eq!( chars_increasing().count(), usize::exact_from(NUMBER_OF_CHARS) ); } malachite-base-0.4.16/tests/chars/exhaustive/exhaustive_ascii_chars.rs000064400000000000000000000016321046102023000242670ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::chars::exhaustive::exhaustive_ascii_chars; #[test] fn test_exhaustive_ascii_chars() { assert_eq!( exhaustive_ascii_chars().collect::(), "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 !\"#$%&\'()*+,-./:;<=>?@[\\\ ]^_`{|}~\u{0}\u{1}\u{2}\u{3}\u{4}\u{5}\u{6}\u{7}\u{8}\t\n\u{b}\u{c}\r\u{e}\u{f}\u{10}\u{11}\ \u{12}\u{13}\u{14}\u{15}\u{16}\u{17}\u{18}\u{19}\u{1a}\u{1b}\u{1c}\u{1d}\u{1e}\u{1f}\u{7f}" ); assert_eq!(exhaustive_ascii_chars().count(), 1 << 7); } malachite-base-0.4.16/tests/chars/exhaustive/exhaustive_chars.rs000064400000000000000000000116271046102023000231240ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::chars::constants::NUMBER_OF_CHARS; use malachite_base::chars::exhaustive::exhaustive_chars; use malachite_base::num::conversion::traits::ExactFrom; #[test] fn test_exhaustive_chars() { assert_eq!( exhaustive_chars().take(200).collect::(), "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 !\"#$%&\'()*+,-./:;<=>?@[\\\ ]^_`{|}~¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóô\ õö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊ" ); assert_eq!( exhaustive_chars().count(), usize::exact_from(NUMBER_OF_CHARS) ); let mut chars = exhaustive_chars() .skip(usize::exact_from(NUMBER_OF_CHARS) - 200) .collect_vec(); chars.reverse(); assert_eq!( chars.iter().collect::(), "\u{10ffff}\u{10fffe}\u{10fffd}\u{10fffc}\u{10fffb}\u{10fffa}\u{10fff9}\u{10fff8}\u{10fff7}\ \u{10fff6}\u{10fff5}\u{10fff4}\u{10fff3}\u{10fff2}\u{10fff1}\u{10fff0}\u{10ffef}\u{10ffee}\ \u{10ffed}\u{10ffec}\u{10ffeb}\u{10ffea}\u{10ffe9}\u{10ffe8}\u{10ffe7}\u{10ffe6}\u{10ffe5}\ \u{10ffe4}\u{10ffe3}\u{10ffe2}\u{10ffe1}\u{10ffe0}\u{10ffdf}\u{10ffde}\u{10ffdd}\u{10ffdc}\ \u{10ffdb}\u{10ffda}\u{10ffd9}\u{10ffd8}\u{10ffd7}\u{10ffd6}\u{10ffd5}\u{10ffd4}\u{10ffd3}\ \u{10ffd2}\u{10ffd1}\u{10ffd0}\u{10ffcf}\u{10ffce}\u{10ffcd}\u{10ffcc}\u{10ffcb}\u{10ffca}\ \u{10ffc9}\u{10ffc8}\u{10ffc7}\u{10ffc6}\u{10ffc5}\u{10ffc4}\u{10ffc3}\u{10ffc2}\u{10ffc1}\ \u{10ffc0}\u{10ffbf}\u{10ffbe}\u{10ffbd}\u{10ffbc}\u{10ffbb}\u{10ffba}\u{10ffb9}\u{10ffb8}\ \u{10ffb7}\u{10ffb6}\u{10ffb5}\u{10ffb4}\u{10ffb3}\u{10ffb2}\u{10ffb1}\u{10ffb0}\u{10ffaf}\ \u{10ffae}\u{10ffad}\u{10ffac}\u{10ffab}\u{10ffaa}\u{10ffa9}\u{10ffa8}\u{10ffa7}\u{10ffa6}\ \u{10ffa5}\u{10ffa4}\u{10ffa3}\u{10ffa2}\u{10ffa1}\u{10ffa0}\u{10ff9f}\u{10ff9e}\u{10ff9d}\ \u{10ff9c}\u{10ff9b}\u{10ff9a}\u{10ff99}\u{10ff98}\u{10ff97}\u{10ff96}\u{10ff95}\u{10ff94}\ \u{10ff93}\u{10ff92}\u{10ff91}\u{10ff90}\u{10ff8f}\u{10ff8e}\u{10ff8d}\u{10ff8c}\u{10ff8b}\ \u{10ff8a}\u{10ff89}\u{10ff88}\u{10ff87}\u{10ff86}\u{10ff85}\u{10ff84}\u{10ff83}\u{10ff82}\ \u{10ff81}\u{10ff80}\u{10ff7f}\u{10ff7e}\u{10ff7d}\u{10ff7c}\u{10ff7b}\u{10ff7a}\u{10ff79}\ \u{10ff78}\u{10ff77}\u{10ff76}\u{10ff75}\u{10ff74}\u{10ff73}\u{10ff72}\u{10ff71}\u{10ff70}\ \u{10ff6f}\u{10ff6e}\u{10ff6d}\u{10ff6c}\u{10ff6b}\u{10ff6a}\u{10ff69}\u{10ff68}\u{10ff67}\ \u{10ff66}\u{10ff65}\u{10ff64}\u{10ff63}\u{10ff62}\u{10ff61}\u{10ff60}\u{10ff5f}\u{10ff5e}\ \u{10ff5d}\u{10ff5c}\u{10ff5b}\u{10ff5a}\u{10ff59}\u{10ff58}\u{10ff57}\u{10ff56}\u{10ff55}\ \u{10ff54}\u{10ff53}\u{10ff52}\u{10ff51}\u{10ff50}\u{10ff4f}\u{10ff4e}\u{10ff4d}\u{10ff4c}\ \u{10ff4b}\u{10ff4a}\u{10ff49}\u{10ff48}\u{10ff47}\u{10ff46}\u{10ff45}\u{10ff44}\u{10ff43}\ \u{10ff42}\u{10ff41}\u{10ff40}\u{10ff3f}\u{10ff3e}\u{10ff3d}\u{10ff3c}\u{10ff3b}\u{10ff3a}\ \u{10ff39}\u{10ff38}" ); assert_eq!( exhaustive_chars().skip(94).take(200).collect::(), "~¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùú\ ûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕ\ ŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨ" ); assert_eq!( exhaustive_chars().skip(141698).take(200).collect::(), "𰲠𰲡𰲢𰲣𰲤𰲥𰲦𰲧𰲨𰲩𰲪𰲫𰲬𰲭𰲮𰲯𰲰𰲱𰲲𰲳𰲴𰲵𰲶𰲷𰲸𰲹𰲺𰲻𰲼𰲽𰲾𰲿𰳀𰳁𰳂𰳃𰳄𰳅𰳆𰳇𰳈𰳉𰳊𰳋𰳌𰳍𰳎𰳏𰳐𰳑𰳒𰳓𰳔𰳕𰳖𰳗𰳘𰳙𰳚𰳛𰳜𰳝𰳞𰳟𰳠𰳡𰳢𰳣𰳤𰳥𰳦𰳧𰳨𰳩𰳪𰳫𰳬𰳭𰳮𰳯𰳰𰳱𰳲𰳳𰳴𰳵𰳶𰳷𰳸\ 𰳹𰳺𰳻𰳼𰳽𰳾𰳿𰴀𰴁𰴂𰴃𰴄𰴅𰴆𰴇𰴈𰴉𰴊𰴋𰴌𰴍𰴎𰴏𰴐𰴑𰴒𰴓𰴔𰴕𰴖𰴗𰴘𰴙𰴚𰴛𰴜𰴝𰴞𰴟𰴠𰴡𰴢𰴣𰴤𰴥𰴦𰴧𰴨𰴩𰴪𰴫𰴬𰴭𰴮𰴯𰴰𰴱𰴲𰴳𰴴𰴵𰴶𰴷𰴸𰴹𰴺𰴻𰴼𰴽𰴾𰴿𰵀𰵁𰵂𰵃𰵄𰵅𰵆𰵇𰵈𰵉𰵊𰵋𰵌𰵍𰵎𰵏𰵐𰵑𰵒\ 𰵓𰵔𰵕𰵖𰵗𰵘𰵙𰵚𰵛𰵜𰵝𰵞𰵟𰵠𰵡𰵢𰵣𰵤𰵥𰵦𰵧" ); } malachite-base-0.4.16/tests/chars/is_graphic.rs000064400000000000000000000617201046102023000175010ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::chars::char_is_graphic; use malachite_base::chars::exhaustive::{ascii_chars_increasing, chars_increasing}; use malachite_base::iterators::matching_intervals_in_iterator; #[test] fn test_is_graphic() { let test = |c, out| { assert_eq!(char_is_graphic(c), out); }; test(' ', true); test('a', true); test('A', true); test('0', true); test('!', true); test('ñ', true); test('\0', false); test('\n', false); test('\u{5f771}', false); assert_eq!( ascii_chars_increasing() .filter(|&c| char_is_graphic(c)) .count(), 95 ); assert_eq!( chars_increasing().filter(|&c| char_is_graphic(c)).count(), 147597 ); assert_eq!( matching_intervals_in_iterator(chars_increasing(), |&c| { char_is_graphic(c) }) .iter() .map(|i| (i.0 as u32, i.1 as u32)) .collect_vec(), &[ (32, 126), (161, 172), (174, 767), (880, 887), (890, 895), (900, 906), (908, 908), (910, 929), (931, 1154), (1162, 1327), (1329, 1366), (1369, 1418), (1421, 1423), (1470, 1470), (1472, 1472), (1475, 1475), (1478, 1478), (1488, 1514), (1519, 1524), (1542, 1551), (1563, 1563), (1565, 1610), (1632, 1647), (1649, 1749), (1758, 1758), (1765, 1766), (1769, 1769), (1774, 1805), (1808, 1808), (1810, 1839), (1869, 1957), (1969, 1969), (1984, 2026), (2036, 2042), (2046, 2069), (2074, 2074), (2084, 2084), (2088, 2088), (2096, 2110), (2112, 2136), (2142, 2142), (2144, 2154), (2160, 2190), (2208, 2249), (2307, 2361), (2363, 2363), (2365, 2368), (2377, 2380), (2382, 2384), (2392, 2401), (2404, 2432), (2434, 2435), (2437, 2444), (2447, 2448), (2451, 2472), (2474, 2480), (2482, 2482), (2486, 2489), (2493, 2493), (2495, 2496), (2503, 2504), (2507, 2508), (2510, 2510), (2524, 2525), (2527, 2529), (2534, 2557), (2563, 2563), (2565, 2570), (2575, 2576), (2579, 2600), (2602, 2608), (2610, 2611), (2613, 2614), (2616, 2617), (2622, 2624), (2649, 2652), (2654, 2654), (2662, 2671), (2674, 2676), (2678, 2678), (2691, 2691), (2693, 2701), (2703, 2705), (2707, 2728), (2730, 2736), (2738, 2739), (2741, 2745), (2749, 2752), (2761, 2761), (2763, 2764), (2768, 2768), (2784, 2785), (2790, 2801), (2809, 2809), (2818, 2819), (2821, 2828), (2831, 2832), (2835, 2856), (2858, 2864), (2866, 2867), (2869, 2873), (2877, 2877), (2880, 2880), (2887, 2888), (2891, 2892), (2908, 2909), (2911, 2913), (2918, 2935), (2947, 2947), (2949, 2954), (2958, 2960), (2962, 2965), (2969, 2970), (2972, 2972), (2974, 2975), (2979, 2980), (2984, 2986), (2990, 3001), (3007, 3007), (3009, 3010), (3014, 3016), (3018, 3020), (3024, 3024), (3046, 3066), (3073, 3075), (3077, 3084), (3086, 3088), (3090, 3112), (3114, 3129), (3133, 3133), (3137, 3140), (3160, 3162), (3165, 3165), (3168, 3169), (3174, 3183), (3191, 3200), (3202, 3212), (3214, 3216), (3218, 3240), (3242, 3251), (3253, 3257), (3261, 3262), (3264, 3265), (3267, 3268), (3271, 3272), (3274, 3275), (3293, 3294), (3296, 3297), (3302, 3311), (3313, 3315), (3330, 3340), (3342, 3344), (3346, 3386), (3389, 3389), (3391, 3392), (3398, 3400), (3402, 3404), (3406, 3407), (3412, 3414), (3416, 3425), (3430, 3455), (3458, 3459), (3461, 3478), (3482, 3505), (3507, 3515), (3517, 3517), (3520, 3526), (3536, 3537), (3544, 3550), (3558, 3567), (3570, 3572), (3585, 3632), (3634, 3635), (3647, 3654), (3663, 3675), (3713, 3714), (3716, 3716), (3718, 3722), (3724, 3747), (3749, 3749), (3751, 3760), (3762, 3763), (3773, 3773), (3776, 3780), (3782, 3782), (3792, 3801), (3804, 3807), (3840, 3863), (3866, 3892), (3894, 3894), (3896, 3896), (3898, 3911), (3913, 3948), (3967, 3967), (3973, 3973), (3976, 3980), (4030, 4037), (4039, 4044), (4046, 4058), (4096, 4140), (4145, 4145), (4152, 4152), (4155, 4156), (4159, 4183), (4186, 4189), (4193, 4208), (4213, 4225), (4227, 4228), (4231, 4236), (4238, 4252), (4254, 4293), (4295, 4295), (4301, 4301), (4304, 4680), (4682, 4685), (4688, 4694), (4696, 4696), (4698, 4701), (4704, 4744), (4746, 4749), (4752, 4784), (4786, 4789), (4792, 4798), (4800, 4800), (4802, 4805), (4808, 4822), (4824, 4880), (4882, 4885), (4888, 4954), (4960, 4988), (4992, 5017), (5024, 5109), (5112, 5117), (5120, 5759), (5761, 5788), (5792, 5880), (5888, 5905), (5909, 5909), (5919, 5937), (5940, 5942), (5952, 5969), (5984, 5996), (5998, 6000), (6016, 6067), (6070, 6070), (6078, 6085), (6087, 6088), (6100, 6108), (6112, 6121), (6128, 6137), (6144, 6154), (6160, 6169), (6176, 6264), (6272, 6276), (6279, 6312), (6314, 6314), (6320, 6389), (6400, 6430), (6435, 6438), (6441, 6443), (6448, 6449), (6451, 6456), (6464, 6464), (6468, 6509), (6512, 6516), (6528, 6571), (6576, 6601), (6608, 6618), (6622, 6678), (6681, 6682), (6686, 6741), (6743, 6743), (6753, 6753), (6755, 6756), (6765, 6770), (6784, 6793), (6800, 6809), (6816, 6829), (6916, 6963), (6971, 6971), (6973, 6977), (6979, 6988), (6992, 7018), (7028, 7038), (7042, 7073), (7078, 7079), (7082, 7082), (7086, 7141), (7143, 7143), (7146, 7148), (7150, 7150), (7154, 7155), (7164, 7211), (7220, 7221), (7227, 7241), (7245, 7304), (7312, 7354), (7357, 7367), (7379, 7379), (7393, 7393), (7401, 7404), (7406, 7411), (7413, 7415), (7418, 7418), (7424, 7615), (7680, 7957), (7960, 7965), (7968, 8005), (8008, 8013), (8016, 8023), (8025, 8025), (8027, 8027), (8029, 8029), (8031, 8061), (8064, 8116), (8118, 8132), (8134, 8147), (8150, 8155), (8157, 8175), (8178, 8180), (8182, 8190), (8208, 8231), (8240, 8286), (8304, 8305), (8308, 8334), (8336, 8348), (8352, 8384), (8448, 8587), (8592, 9254), (9280, 9290), (9312, 11123), (11126, 11157), (11159, 11502), (11506, 11507), (11513, 11557), (11559, 11559), (11565, 11565), (11568, 11623), (11631, 11632), (11648, 11670), (11680, 11686), (11688, 11694), (11696, 11702), (11704, 11710), (11712, 11718), (11720, 11726), (11728, 11734), (11736, 11742), (11776, 11869), (11904, 11929), (11931, 12019), (12032, 12245), (12272, 12287), (12289, 12329), (12336, 12351), (12353, 12438), (12443, 12543), (12549, 12591), (12593, 12686), (12688, 12771), (12783, 12830), (12832, 42124), (42128, 42182), (42192, 42539), (42560, 42606), (42611, 42611), (42622, 42653), (42656, 42735), (42738, 42743), (42752, 42954), (42960, 42961), (42963, 42963), (42965, 42969), (42994, 43009), (43011, 43013), (43015, 43018), (43020, 43044), (43047, 43051), (43056, 43065), (43072, 43127), (43136, 43203), (43214, 43225), (43250, 43262), (43264, 43301), (43310, 43334), (43346, 43347), (43359, 43388), (43395, 43442), (43444, 43445), (43450, 43451), (43454, 43469), (43471, 43481), (43486, 43492), (43494, 43518), (43520, 43560), (43567, 43568), (43571, 43572), (43584, 43586), (43588, 43595), (43597, 43597), (43600, 43609), (43612, 43643), (43645, 43695), (43697, 43697), (43701, 43702), (43705, 43709), (43712, 43712), (43714, 43714), (43739, 43755), (43758, 43765), (43777, 43782), (43785, 43790), (43793, 43798), (43808, 43814), (43816, 43822), (43824, 43883), (43888, 44004), (44006, 44007), (44009, 44012), (44016, 44025), (44032, 55203), (55216, 55238), (55243, 55291), (63744, 64109), (64112, 64217), (64256, 64262), (64275, 64279), (64285, 64285), (64287, 64310), (64312, 64316), (64318, 64318), (64320, 64321), (64323, 64324), (64326, 64450), (64467, 64911), (64914, 64967), (64975, 64975), (65008, 65023), (65040, 65049), (65072, 65106), (65108, 65126), (65128, 65131), (65136, 65140), (65142, 65276), (65281, 65437), (65440, 65470), (65474, 65479), (65482, 65487), (65490, 65495), (65498, 65500), (65504, 65510), (65512, 65518), (65532, 65533), (65536, 65547), (65549, 65574), (65576, 65594), (65596, 65597), (65599, 65613), (65616, 65629), (65664, 65786), (65792, 65794), (65799, 65843), (65847, 65934), (65936, 65948), (65952, 65952), (66000, 66044), (66176, 66204), (66208, 66256), (66273, 66299), (66304, 66339), (66349, 66378), (66384, 66421), (66432, 66461), (66463, 66499), (66504, 66517), (66560, 66717), (66720, 66729), (66736, 66771), (66776, 66811), (66816, 66855), (66864, 66915), (66927, 66938), (66940, 66954), (66956, 66962), (66964, 66965), (66967, 66977), (66979, 66993), (66995, 67001), (67003, 67004), (67072, 67382), (67392, 67413), (67424, 67431), (67456, 67461), (67463, 67504), (67506, 67514), (67584, 67589), (67592, 67592), (67594, 67637), (67639, 67640), (67644, 67644), (67647, 67669), (67671, 67742), (67751, 67759), (67808, 67826), (67828, 67829), (67835, 67867), (67871, 67897), (67903, 67903), (67968, 68023), (68028, 68047), (68050, 68096), (68112, 68115), (68117, 68119), (68121, 68149), (68160, 68168), (68176, 68184), (68192, 68255), (68288, 68324), (68331, 68342), (68352, 68405), (68409, 68437), (68440, 68466), (68472, 68497), (68505, 68508), (68521, 68527), (68608, 68680), (68736, 68786), (68800, 68850), (68858, 68899), (68912, 68921), (69216, 69246), (69248, 69289), (69293, 69293), (69296, 69297), (69376, 69415), (69424, 69445), (69457, 69465), (69488, 69505), (69510, 69513), (69552, 69579), (69600, 69622), (69632, 69632), (69634, 69687), (69703, 69709), (69714, 69743), (69745, 69746), (69749, 69749), (69762, 69810), (69815, 69816), (69819, 69820), (69822, 69825), (69840, 69864), (69872, 69881), (69891, 69926), (69932, 69932), (69942, 69959), (69968, 70002), (70004, 70006), (70018, 70069), (70079, 70088), (70093, 70094), (70096, 70111), (70113, 70132), (70144, 70161), (70163, 70190), (70194, 70195), (70197, 70197), (70200, 70205), (70207, 70208), (70272, 70278), (70280, 70280), (70282, 70285), (70287, 70301), (70303, 70313), (70320, 70366), (70368, 70370), (70384, 70393), (70402, 70403), (70405, 70412), (70415, 70416), (70419, 70440), (70442, 70448), (70450, 70451), (70453, 70457), (70461, 70461), (70463, 70463), (70465, 70468), (70471, 70472), (70475, 70477), (70480, 70480), (70493, 70499), (70656, 70711), (70720, 70721), (70725, 70725), (70727, 70747), (70749, 70749), (70751, 70753), (70784, 70831), (70833, 70834), (70841, 70841), (70843, 70844), (70846, 70846), (70849, 70849), (70852, 70855), (70864, 70873), (71040, 71086), (71088, 71089), (71096, 71099), (71102, 71102), (71105, 71131), (71168, 71218), (71227, 71228), (71230, 71230), (71233, 71236), (71248, 71257), (71264, 71276), (71296, 71338), (71340, 71340), (71342, 71343), (71350, 71350), (71352, 71353), (71360, 71369), (71424, 71450), (71456, 71457), (71462, 71462), (71472, 71494), (71680, 71726), (71736, 71736), (71739, 71739), (71840, 71922), (71935, 71942), (71945, 71945), (71948, 71955), (71957, 71958), (71960, 71983), (71985, 71989), (71991, 71992), (71997, 71997), (71999, 72002), (72004, 72006), (72016, 72025), (72096, 72103), (72106, 72147), (72156, 72159), (72161, 72164), (72192, 72192), (72203, 72242), (72249, 72250), (72255, 72262), (72272, 72272), (72279, 72280), (72284, 72329), (72343, 72343), (72346, 72354), (72368, 72440), (72448, 72457), (72704, 72712), (72714, 72751), (72766, 72766), (72768, 72773), (72784, 72812), (72816, 72847), (72873, 72873), (72881, 72881), (72884, 72884), (72960, 72966), (72968, 72969), (72971, 73008), (73030, 73030), (73040, 73049), (73056, 73061), (73063, 73064), (73066, 73102), (73107, 73108), (73110, 73110), (73112, 73112), (73120, 73129), (73440, 73458), (73461, 73464), (73474, 73488), (73490, 73525), (73534, 73535), (73537, 73537), (73539, 73561), (73648, 73648), (73664, 73713), (73727, 74649), (74752, 74862), (74864, 74868), (74880, 75075), (77712, 77810), (77824, 78895), (78913, 78918), (82944, 83526), (92160, 92728), (92736, 92766), (92768, 92777), (92782, 92862), (92864, 92873), (92880, 92909), (92917, 92917), (92928, 92975), (92983, 92997), (93008, 93017), (93019, 93025), (93027, 93047), (93053, 93071), (93760, 93850), (93952, 94026), (94032, 94087), (94099, 94111), (94176, 94179), (94192, 94193), (94208, 100343), (100352, 101589), (101632, 101640), (110576, 110579), (110581, 110587), (110589, 110590), (110592, 110882), (110898, 110898), (110928, 110930), (110933, 110933), (110948, 110951), (110960, 111355), (113664, 113770), (113776, 113788), (113792, 113800), (113808, 113817), (113820, 113820), (113823, 113823), (118608, 118723), (118784, 119029), (119040, 119078), (119081, 119140), (119142, 119142), (119146, 119149), (119171, 119172), (119180, 119209), (119214, 119274), (119296, 119361), (119365, 119365), (119488, 119507), (119520, 119539), (119552, 119638), (119648, 119672), (119808, 119892), (119894, 119964), (119966, 119967), (119970, 119970), (119973, 119974), (119977, 119980), (119982, 119993), (119995, 119995), (119997, 120003), (120005, 120069), (120071, 120074), (120077, 120084), (120086, 120092), (120094, 120121), (120123, 120126), (120128, 120132), (120134, 120134), (120138, 120144), (120146, 120485), (120488, 120779), (120782, 121343), (121399, 121402), (121453, 121460), (121462, 121475), (121477, 121483), (122624, 122654), (122661, 122666), (122928, 122989), (123136, 123180), (123191, 123197), (123200, 123209), (123214, 123215), (123536, 123565), (123584, 123627), (123632, 123641), (123647, 123647), (124112, 124139), (124144, 124153), (124896, 124902), (124904, 124907), (124909, 124910), (124912, 124926), (124928, 125124), (125127, 125135), (125184, 125251), (125259, 125259), (125264, 125273), (125278, 125279), (126065, 126132), (126209, 126269), (126464, 126467), (126469, 126495), (126497, 126498), (126500, 126500), (126503, 126503), (126505, 126514), (126516, 126519), (126521, 126521), (126523, 126523), (126530, 126530), (126535, 126535), (126537, 126537), (126539, 126539), (126541, 126543), (126545, 126546), (126548, 126548), (126551, 126551), (126553, 126553), (126555, 126555), (126557, 126557), (126559, 126559), (126561, 126562), (126564, 126564), (126567, 126570), (126572, 126578), (126580, 126583), (126585, 126588), (126590, 126590), (126592, 126601), (126603, 126619), (126625, 126627), (126629, 126633), (126635, 126651), (126704, 126705), (126976, 127019), (127024, 127123), (127136, 127150), (127153, 127167), (127169, 127183), (127185, 127221), (127232, 127405), (127462, 127490), (127504, 127547), (127552, 127560), (127568, 127569), (127584, 127589), (127744, 128727), (128732, 128748), (128752, 128764), (128768, 128886), (128891, 128985), (128992, 129003), (129008, 129008), (129024, 129035), (129040, 129095), (129104, 129113), (129120, 129159), (129168, 129197), (129200, 129201), (129280, 129619), (129632, 129645), (129648, 129660), (129664, 129672), (129680, 129725), (129727, 129733), (129742, 129755), (129760, 129768), (129776, 129784), (129792, 129938), (129940, 129994), (130032, 130041), (131072, 173791), (173824, 177977), (177984, 178205), (178208, 183969), (183984, 191456), (191472, 192093), (194560, 195101), (196608, 201546), (201552, 205743) ][..] ); } malachite-base-0.4.16/tests/chars/random/graphic_weighted_random_ascii_chars.rs000064400000000000000000000116021046102023000260300ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::chars::random::graphic_weighted_random_ascii_chars; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; fn graphic_weighted_random_ascii_chars_helper( p_numerator: u64, p_denominator: u64, expected_values: &str, expected_common_values: &[(char, usize)], expected_median: (char, Option), ) { let xs = graphic_weighted_random_ascii_chars(EXAMPLE_SEED, p_numerator, p_denominator); let values = xs.clone().take(200).collect::(); let common_values = common_values_map_debug(1000000, 10, xs.clone()); let median = median(xs.take(1000000)); assert_eq!( (values.as_str(), common_values.as_slice(), median), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_graphic_weighted_random_ascii_chars() { // p = 1/2 graphic_weighted_random_ascii_chars_helper( 1, 2, "\u{1b}x\u{8}1\r4\u{2}N\u{11}\u{11}(\u{13}bcXr$g)\t7/E\u{11}+fY\u{10}Po\u{1}\u{17}\u{17}\ \u{13}o\u{1}.\u{0}\u{b}\u{3}$\u{6}\nV2R.\u{f}\u{5}\u{19}$\u{1f}V=\u{1c}\u{6}\u{15}\u{6}\ \u{11}\r\u{19}6\u{2}\u{19}=\u{12}\u{18}Dq\u{6}S<\u{6}\u{1d}C\u{b}M\u{8}\u{15}\u{16}\u{f}W_\ \u{0}\u{12}%\u{18}\u{10}\u{10}OX?\u{1f}\u{12}b\u{c}}\u{10}rJa\u{e}D\u{1e}`o635\u{2}Q:w\u{3}\ \u{1}3m\u{5}Y\u{1f}=\u{7}8\tn\r\u{1}\nq\u{13}\u{3}\t\u{f}fR:/\u{f}2\u{2}\u{1c}6\u{13}\u{13}\ z\u{15}r\u{f}\u{4}<\u{1d}pr\u{2}+UFFc;8P:", &[ ('d', 10548), ('C', 10506), ('7', 10501), ('R', 10486), ('D', 10484), ('q', 10476), ('1', 10468), ('6', 10463), ('\'', 10452), ('$', 10448), ], ('N', None), ); } #[test] #[should_panic] fn graphic_weighted_random_ascii_chars_fail_1() { graphic_weighted_random_ascii_chars(EXAMPLE_SEED, 1, 0); } #[test] #[should_panic] fn graphic_weighted_random_ascii_chars_fail_2() { graphic_weighted_random_ascii_chars(EXAMPLE_SEED, 2, 1); } malachite-base-0.4.16/tests/chars/random/graphic_weighted_random_char_inclusive_range.rs000064400000000000000000000241371046102023000277410ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::chars::random::graphic_weighted_random_char_inclusive_range; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; fn graphic_weighted_random_char_inclusive_range_helper( a: char, b: char, p_numerator: u64, p_denominator: u64, expected_values: &str, expected_common_values: &[(char, usize)], expected_median: (char, Option), ) { let xs = graphic_weighted_random_char_inclusive_range( EXAMPLE_SEED, a, b, p_numerator, p_denominator, ); let values = xs.clone().take(200).collect::(); let common_values = common_values_map_debug(1000000, 10, xs.clone()); let median = median(xs.take(1000000)); assert_eq!( (values.as_str(), common_values.as_slice(), median), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_graphic_weighted_random_char_inclusive_range() { // 'a', '\u{7f}', p = 1/2 graphic_weighted_random_char_inclusive_range_helper( 'a', '\u{7f}', 1, 2, "\u{7f}y\u{7f}g\u{7f}c\u{7f}k\u{7f}\u{7f}}\u{7f}ccjlybr\u{7f}tue\u{7f}}ye\u{7f}oz\u{7f}\ \u{7f}\u{7f}\u{7f}d\u{7f}f\u{7f}\u{7f}\u{7f}f\u{7f}\u{7f}fmxr\u{7f}\u{7f}\u{7f}g\u{7f}hy\ \u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}q\u{7f}\u{7f}t\u{7f}\u{7f}pk\u{7f}oh\u{7f}\u{7f}i\ \u{7f}q\u{7f}\u{7f}\u{7f}\u{7f}nf\u{7f}\u{7f}l\u{7f}\u{7f}\u{7f}sqf\u{7f}\u{7f}t\u{7f}d\ \u{7f}emm\u{7f}|\u{7f}{z|wu\u{7f}dsc\u{7f}\u{7f}f{\u{7f}t\u{7f}r\u{7f}t\u{7f}q\u{7f}\u{7f}\ \u{7f}h\u{7f}\u{7f}\u{7f}\u{7f}klx~\u{7f}x\u{7f}\u{7f}c\u{7f}\u{7f}u\u{7f}l\u{7f}\u{7f}y\ \u{7f}~d\u{7f}~\u{7f}f\u{7f}\u{7f}m\u{7f}xf\u{7f}lkvcu{e\u{7f}\u{7f}b\u{7f}\u{7f}yh\u{7f}\ \u{7f}nz\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}e\u{7f}vu\u{7f}\u{7f}}\u{7f}y\u{7f}u\u{7f}\u{7f}", &[ ('\u{7f}', 499332), ('a', 16868), ('t', 16831), ('j', 16829), ('r', 16822), ('i', 16816), ('f', 16806), ('{', 16780), ('s', 16763), ('d', 16749), ], ('~', None), ); // 'a', '\u{7f}', p = 1/51 graphic_weighted_random_char_inclusive_range_helper( 'a', '\u{7f}', 1, 51, "\u{7f}\u{7f}y\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\ \u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\ \u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}g\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\ \u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\ \u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\ \u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\ \u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\ \u{7f}\u{7f}c\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\ \u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}k\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\ \u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\ \u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\ \u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\ \u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\ \u{7f}\u{7f}", &[ ('\u{7f}', 980198), ('h', 697), ('n', 691), ('i', 681), ('w', 680), ('r', 677), ('a', 675), ('|', 674), ('q', 673), ('e', 670), ], ('\u{7f}', None), ); // 'a', '\u{7f}', p = 50/51 graphic_weighted_random_char_inclusive_range_helper( 'a', '\u{7f}', 50, 51, "ygck}ccjlybrtue}yeozdfffmxrghyqtpkohiqnflsqftdemm|{z|wudscf{trtqh\u{7f}klx~xculy~d~fmxflkv\ cu{ebyhnzevu}yuzvtuz}{b~yyzin}zsjthazlcluvu}a\u{7f}yvhhbgevdxo}unwjqepanjmpckouxtwwbi{nla\ \u{7f}cs{vphyrdaqhzndmqdqg\u{7f}{{mfwk|xf", &[ ('a', 32996), ('f', 32964), ('q', 32960), ('{', 32942), ('s', 32886), ('t', 32809), ('d', 32768), ('n', 32767), ('p', 32766), ('i', 32765), ], ('p', None), ); // '\u{100}', '\u{3ff}', p = 1/2 graphic_weighted_random_char_inclusive_range_helper( '\u{100}', '\u{3ff}', 1, 2, "\u{31b}ǘ\u{324}ɂ\u{35a}Ŝ\u{367}Ȣ\u{337}\u{342}Ι\u{36e}Ƙƣʅΰǟ˳ˊ\u{315}ȇʰɥ\u{32c}ΈϞƃ\u{30b}ʌμ\ \u{346}\u{36a}\u{328}\u{334}Ƣ\u{380}ϳ\u{32e}\u{359}\u{36b}Ϫ\u{333}\u{312}ǰɪŗŽ\u{302}\u{305}\ \u{32e}ƽ\u{357}ɥϻ\u{349}\u{35f}\u{316}\u{33a}\u{383}\u{301}\u{31d}ƚ\u{360}\u{35d}ʧ\u{30c}\ \u{30c}ƙϮ\u{34a}șϒ\u{367}\u{35f}Ϣ\u{308}ć\u{353}\u{333}\u{381}\u{30f}ɾɢ\u{367}\u{340}ǧ\ \u{356}\u{30c}\u{351}ǁʴȶ\u{33e}\u{358}Ɛ\u{351}ď\u{366}ȭˬɂ\u{38b}ϰ\u{342}ȁʺċλǿ\u{30c}αăǰ\ \u{31c}\u{327}ʹʃ\u{34a}Ű\u{36a}ǐ\u{33f}Ƭ\u{34c}ɖ\u{361}\u{335}\u{318}Ͼ\u{349}\u{35d}\u{330}\ \u{35c}ƾƱǒȆ\u{320}Ɉ\u{348}\u{324}Ϫ\u{31d}\u{35c}ʶ\u{332}ť\u{33d}\u{300}ˍ\u{326}ďǑ\u{329}ɶ\ \u{33d}Ɂ\u{31f}\u{363}ȭ\u{320}ƭğ\u{321}Ⱦ˹ĺǗʋdž˺\u{31a}\u{35c}ʐ\u{304}\u{365}Ǎŋ\u{34f}\u{31f}\ ɽɷ\u{31e}\u{32a}\u{31a}\u{307}\u{319}ϲ\u{310}Ÿȃ\u{369}\u{359}Ĩ\u{33e}Ş\u{38d}˭\u{31e}\ \u{321}", &[ ('\u{326}', 4271), ('\u{357}', 4238), ('\u{33b}', 4235), ('\u{36b}', 4235), ('\u{348}', 4228), ('\u{30b}', 4225), ('\u{304}', 4224), ('\u{30d}', 4224), ('\u{327}', 4221), ('\u{325}', 4217), ], ('\u{319}', None), ); // '\u{100}', '\u{3ff}', p = 1/51 graphic_weighted_random_char_inclusive_range_helper( '\u{100}', '\u{3ff}', 1, 51, "\u{31b}\u{324}ǘ\u{35a}\u{367}\u{337}\u{342}\u{36e}\u{315}\u{32c}\u{30b}\u{346}\u{36a}\ \u{328}\u{334}\u{380}\u{32e}\u{359}\u{36b}\u{333}\u{312}\u{302}\u{305}\u{32e}\u{357}\u{349}\ \u{35f}\u{316}\u{33a}\u{383}\u{301}\u{31d}\u{360}\u{35d}\u{30c}\u{30c}\u{34a}\u{367}ɂ\ \u{35f}\u{308}\u{353}\u{333}\u{381}\u{30f}\u{367}\u{340}\u{356}\u{30c}\u{351}\u{33e}\u{358}\ \u{351}\u{366}\u{38b}\u{342}\u{30c}\u{31c}\u{327}\u{34a}\u{36a}\u{33f}\u{34c}\u{361}\u{335}\ \u{318}\u{349}\u{35d}\u{330}\u{35c}\u{320}\u{348}\u{324}\u{31d}\u{35c}\u{332}\u{33d}\u{300}\ \u{326}\u{329}\u{33d}\u{31f}\u{363}\u{320}\u{321}\u{31a}\u{35c}\u{304}\u{365}\u{34f}\u{31f}\ \u{31e}\u{32a}\u{31a}\u{307}\u{319}\u{310}\u{369}\u{359}\u{33e}\u{38d}\u{31e}\u{321}\u{339}\ \u{330}\u{30f}\u{303}\u{345}Ŝ\u{32f}\u{35f}\u{33e}\u{30c}\u{313}\u{365}\u{356}\u{36c}\ \u{36f}\u{304}\u{314}\u{369}\u{310}\u{339}\u{33f}\u{354}\u{347}\u{378}\u{366}\u{380}Ȣ\ \u{326}\u{313}\u{383}\u{36c}\u{336}\u{357}\u{31e}\u{324}\u{317}\u{351}\u{323}\u{328}\u{330}\ \u{307}\u{336}\u{326}\u{32a}\u{350}\u{342}\u{315}\u{36b}\u{32b}\u{382}\u{34b}\u{33d}\u{34a}\ \u{314}\u{322}\u{311}\u{364}\u{34c}\u{322}\u{337}\u{30c}\u{362}\u{317}\u{300}\u{348}\u{367}\ \u{35b}\u{353}\u{32e}\u{328}\u{346}\u{328}\u{324}\u{329}\u{379}\u{366}\u{328}\u{30f}\u{31e}\ \u{368}\u{368}\u{38b}\u{318}\u{353}\u{35d}\u{31e}\u{360}\u{33c}\u{315}\u{33c}\u{31f}\u{323}\ \u{38b}\u{379}\u{38d}\u{365}\u{340}", &[ ('\u{30d}', 8469), ('\u{326}', 8280), ('\u{327}', 8268), ('\u{357}', 8250), ('\u{30c}', 8244), ('\u{325}', 8242), ('\u{30a}', 8232), ('\u{30b}', 8232), ('\u{35d}', 8222), ('\u{36b}', 8221), ], ('\u{33b}', None), ); // '\u{100}', '\u{3ff}', p = 50/51 graphic_weighted_random_char_inclusive_range_helper( '\u{100}', '\u{3ff}', 50, 51, "ǘɂŜȢΙƘƣʅΰǟ˳ˊȇʰɥΈϞƃʌμƢϳϪǰɪŗŽƽɥϻƚʧƙϮșϒϢćɾɢǧǁʴȶƐďȭˬɂϰȁʺċλǿαăǰʹʃŰǐƬɖϾ\u{31b}ƾƱǒȆɈϪʶťˍďǑɶɁȭƭğȾ˹\ ĺǗʋdž˺ʐǍŋɽɷϲŸȃĨŞ˭ƪřœɃˡϹƤǁĥɨʎʄˬıɐƺˀǍǷěέƼȞŞȩǀ΄ʱDZȭ\u{324}ʚǃϧśŅˊljΰϿǟϵȟǘĹϋȎʜɴϻϝͺĪƕ˪ϥŪˍʸĻέ˙ĠĢĄšǝ˿Ί\ \u{35a}ΗʩNJŰŦʝŋƶˈąŠɂŻDZƲɛΚʜťγ\u{367}ϽϹčLJīϥſʏȵ", &[ ('Ώ', 1637), ('Ɣ', 1627), ('ɭ', 1618), ('Έ', 1616), ('Ɯ', 1613), ('Ȓ', 1610), ('Ǧ', 1609), ('˵', 1608), ('˷', 1607), ('ƒ', 1606), ], ('ɉ', None), ); } #[test] #[should_panic] fn graphic_weighted_random_char_inclusive_range_fail_1() { graphic_weighted_random_char_inclusive_range(EXAMPLE_SEED, 'a', '\u{80}', 1, 0); } #[test] #[should_panic] fn graphic_weighted_random_char_inclusive_range_fail_2() { graphic_weighted_random_char_inclusive_range(EXAMPLE_SEED, 'a', '\u{80}', 2, 1); } #[test] #[should_panic] fn graphic_weighted_random_char_inclusive_range_fail_3() { graphic_weighted_random_char_inclusive_range(EXAMPLE_SEED, '\u{80}', 'a', 1, 1); } #[test] #[should_panic] fn graphic_weighted_random_char_inclusive_range_fail_4() { graphic_weighted_random_char_inclusive_range(EXAMPLE_SEED, 'a', 'z', 1, 1); } malachite-base-0.4.16/tests/chars/random/graphic_weighted_random_char_range.rs000064400000000000000000000235741046102023000256640ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::chars::random::graphic_weighted_random_char_range; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; fn graphic_weighted_random_char_range_helper( a: char, b: char, p_numerator: u64, p_denominator: u64, expected_values: &str, expected_common_values: &[(char, usize)], expected_median: (char, Option), ) { let xs = graphic_weighted_random_char_range(EXAMPLE_SEED, a, b, p_numerator, p_denominator); let values = xs.clone().take(200).collect::(); let common_values = common_values_map_debug(1000000, 10, xs.clone()); let median = median(xs.take(1000000)); assert_eq!( (values.as_str(), common_values.as_slice(), median), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_graphic_weighted_random_char_range() { // 'a', '\u{80}', p = 1/2 graphic_weighted_random_char_range_helper( 'a', '\u{80}', 1, 2, "\u{7f}y\u{7f}g\u{7f}c\u{7f}k\u{7f}\u{7f}}\u{7f}ccjlybr\u{7f}tue\u{7f}}ye\u{7f}oz\u{7f}\ \u{7f}\u{7f}\u{7f}d\u{7f}f\u{7f}\u{7f}\u{7f}f\u{7f}\u{7f}fmxr\u{7f}\u{7f}\u{7f}g\u{7f}hy\ \u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}q\u{7f}\u{7f}t\u{7f}\u{7f}pk\u{7f}oh\u{7f}\u{7f}i\ \u{7f}q\u{7f}\u{7f}\u{7f}\u{7f}nf\u{7f}\u{7f}l\u{7f}\u{7f}\u{7f}sqf\u{7f}\u{7f}t\u{7f}d\ \u{7f}emm\u{7f}|\u{7f}{z|wu\u{7f}dsc\u{7f}\u{7f}f{\u{7f}t\u{7f}r\u{7f}t\u{7f}q\u{7f}\u{7f}\ \u{7f}h\u{7f}\u{7f}\u{7f}\u{7f}klx~\u{7f}x\u{7f}\u{7f}c\u{7f}\u{7f}u\u{7f}l\u{7f}\u{7f}y\ \u{7f}~d\u{7f}~\u{7f}f\u{7f}\u{7f}m\u{7f}xf\u{7f}lkvcu{e\u{7f}\u{7f}b\u{7f}\u{7f}yh\u{7f}\ \u{7f}nz\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}e\u{7f}vu\u{7f}\u{7f}}\u{7f}y\u{7f}u\u{7f}\u{7f}", &[ ('\u{7f}', 499332), ('a', 16868), ('t', 16831), ('j', 16829), ('r', 16822), ('i', 16816), ('f', 16806), ('{', 16780), ('s', 16763), ('d', 16749), ], ('~', None), ); // 'a', '\u{80}', p = 1/51 graphic_weighted_random_char_range_helper( 'a', '\u{80}', 1, 51, "\u{7f}\u{7f}y\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\ \u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\ \u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}g\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\ \u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\ \u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\ \u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\ \u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\ \u{7f}\u{7f}c\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\ \u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}k\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\ \u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\ \u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\ \u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\ \u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\ \u{7f}\u{7f}", &[ ('\u{7f}', 980198), ('h', 697), ('n', 691), ('i', 681), ('w', 680), ('r', 677), ('a', 675), ('|', 674), ('q', 673), ('e', 670), ], ('\u{7f}', None), ); // 'a', '\u{80}', p = 50/51 graphic_weighted_random_char_range_helper( 'a', '\u{80}', 50, 51, "ygck}ccjlybrtue}yeozdfffmxrghyqtpkohiqnflsqftdemm|{z|wudscf{trtqh\u{7f}klx~xculy~d~fmxflkv\ cu{ebyhnzevu}yuzvtuz}{b~yyzin}zsjthazlcluvu}a\u{7f}yvhhbgevdxo}unwjqepanjmpckouxtwwbi{nla\ \u{7f}cs{vphyrdaqhzndmqdqg\u{7f}{{mfwk|xf", &[ ('a', 32996), ('f', 32964), ('q', 32960), ('{', 32942), ('s', 32886), ('t', 32809), ('d', 32768), ('n', 32767), ('p', 32766), ('i', 32765), ], ('p', None), ); // '\u{100}', '\u{400}', w = 1/2 graphic_weighted_random_char_range_helper( '\u{100}', '\u{400}', 1, 2, "\u{31b}ǘ\u{324}ɂ\u{35a}Ŝ\u{367}Ȣ\u{337}\u{342}Ι\u{36e}Ƙƣʅΰǟ˳ˊ\u{315}ȇʰɥ\u{32c}ΈϞƃ\u{30b}ʌμ\ \u{346}\u{36a}\u{328}\u{334}Ƣ\u{380}ϳ\u{32e}\u{359}\u{36b}Ϫ\u{333}\u{312}ǰɪŗŽ\u{302}\u{305}\ \u{32e}ƽ\u{357}ɥϻ\u{349}\u{35f}\u{316}\u{33a}\u{383}\u{301}\u{31d}ƚ\u{360}\u{35d}ʧ\u{30c}\ \u{30c}ƙϮ\u{34a}șϒ\u{367}\u{35f}Ϣ\u{308}ć\u{353}\u{333}\u{381}\u{30f}ɾɢ\u{367}\u{340}ǧ\ \u{356}\u{30c}\u{351}ǁʴȶ\u{33e}\u{358}Ɛ\u{351}ď\u{366}ȭˬɂ\u{38b}ϰ\u{342}ȁʺċλǿ\u{30c}αăǰ\ \u{31c}\u{327}ʹʃ\u{34a}Ű\u{36a}ǐ\u{33f}Ƭ\u{34c}ɖ\u{361}\u{335}\u{318}Ͼ\u{349}\u{35d}\u{330}\ \u{35c}ƾƱǒȆ\u{320}Ɉ\u{348}\u{324}Ϫ\u{31d}\u{35c}ʶ\u{332}ť\u{33d}\u{300}ˍ\u{326}ďǑ\u{329}ɶ\ \u{33d}Ɂ\u{31f}\u{363}ȭ\u{320}ƭğ\u{321}Ⱦ˹ĺǗʋdž˺\u{31a}\u{35c}ʐ\u{304}\u{365}Ǎŋ\u{34f}\u{31f}\ ɽɷ\u{31e}\u{32a}\u{31a}\u{307}\u{319}ϲ\u{310}Ÿȃ\u{369}\u{359}Ĩ\u{33e}Ş\u{38d}˭\u{31e}\ \u{321}", &[ ('\u{326}', 4271), ('\u{357}', 4238), ('\u{33b}', 4235), ('\u{36b}', 4235), ('\u{348}', 4228), ('\u{30b}', 4225), ('\u{304}', 4224), ('\u{30d}', 4224), ('\u{327}', 4221), ('\u{325}', 4217), ], ('\u{319}', None), ); // '\u{100}', '\u{400}', p = 1/51 graphic_weighted_random_char_range_helper( '\u{100}', '\u{400}', 1, 51, "\u{31b}\u{324}ǘ\u{35a}\u{367}\u{337}\u{342}\u{36e}\u{315}\u{32c}\u{30b}\u{346}\u{36a}\ \u{328}\u{334}\u{380}\u{32e}\u{359}\u{36b}\u{333}\u{312}\u{302}\u{305}\u{32e}\u{357}\u{349}\ \u{35f}\u{316}\u{33a}\u{383}\u{301}\u{31d}\u{360}\u{35d}\u{30c}\u{30c}\u{34a}\u{367}ɂ\ \u{35f}\u{308}\u{353}\u{333}\u{381}\u{30f}\u{367}\u{340}\u{356}\u{30c}\u{351}\u{33e}\u{358}\ \u{351}\u{366}\u{38b}\u{342}\u{30c}\u{31c}\u{327}\u{34a}\u{36a}\u{33f}\u{34c}\u{361}\u{335}\ \u{318}\u{349}\u{35d}\u{330}\u{35c}\u{320}\u{348}\u{324}\u{31d}\u{35c}\u{332}\u{33d}\u{300}\ \u{326}\u{329}\u{33d}\u{31f}\u{363}\u{320}\u{321}\u{31a}\u{35c}\u{304}\u{365}\u{34f}\u{31f}\ \u{31e}\u{32a}\u{31a}\u{307}\u{319}\u{310}\u{369}\u{359}\u{33e}\u{38d}\u{31e}\u{321}\u{339}\ \u{330}\u{30f}\u{303}\u{345}Ŝ\u{32f}\u{35f}\u{33e}\u{30c}\u{313}\u{365}\u{356}\u{36c}\ \u{36f}\u{304}\u{314}\u{369}\u{310}\u{339}\u{33f}\u{354}\u{347}\u{378}\u{366}\u{380}Ȣ\ \u{326}\u{313}\u{383}\u{36c}\u{336}\u{357}\u{31e}\u{324}\u{317}\u{351}\u{323}\u{328}\u{330}\ \u{307}\u{336}\u{326}\u{32a}\u{350}\u{342}\u{315}\u{36b}\u{32b}\u{382}\u{34b}\u{33d}\u{34a}\ \u{314}\u{322}\u{311}\u{364}\u{34c}\u{322}\u{337}\u{30c}\u{362}\u{317}\u{300}\u{348}\u{367}\ \u{35b}\u{353}\u{32e}\u{328}\u{346}\u{328}\u{324}\u{329}\u{379}\u{366}\u{328}\u{30f}\u{31e}\ \u{368}\u{368}\u{38b}\u{318}\u{353}\u{35d}\u{31e}\u{360}\u{33c}\u{315}\u{33c}\u{31f}\u{323}\ \u{38b}\u{379}\u{38d}\u{365}\u{340}", &[ ('\u{30d}', 8469), ('\u{326}', 8280), ('\u{327}', 8268), ('\u{357}', 8250), ('\u{30c}', 8244), ('\u{325}', 8242), ('\u{30a}', 8232), ('\u{30b}', 8232), ('\u{35d}', 8222), ('\u{36b}', 8221), ], ('\u{33b}', None), ); // '\u{100}', '\u{400}', p = 50/51 graphic_weighted_random_char_range_helper( '\u{100}', '\u{400}', 50, 51, "ǘɂŜȢΙƘƣʅΰǟ˳ˊȇʰɥΈϞƃʌμƢϳϪǰɪŗŽƽɥϻƚʧƙϮșϒϢćɾɢǧǁʴȶƐďȭˬɂϰȁʺċλǿαăǰʹʃŰǐƬɖϾ\u{31b}ƾƱǒȆɈϪʶťˍďǑɶɁȭƭğȾ˹\ ĺǗʋdž˺ʐǍŋɽɷϲŸȃĨŞ˭ƪřœɃˡϹƤǁĥɨʎʄˬıɐƺˀǍǷěέƼȞŞȩǀ΄ʱDZȭ\u{324}ʚǃϧśŅˊljΰϿǟϵȟǘĹϋȎʜɴϻϝͺĪƕ˪ϥŪˍʸĻέ˙ĠĢĄšǝ˿Ί\ \u{35a}ΗʩNJŰŦʝŋƶˈąŠɂŻDZƲɛΚʜťγ\u{367}ϽϹčLJīϥſʏȵ", &[ ('Ώ', 1637), ('Ɣ', 1627), ('ɭ', 1618), ('Έ', 1616), ('Ɯ', 1613), ('Ȓ', 1610), ('Ǧ', 1609), ('˵', 1608), ('˷', 1607), ('ƒ', 1606), ], ('ɉ', None), ); } #[test] #[should_panic] fn graphic_weighted_random_char_range_fail_1() { graphic_weighted_random_char_range(EXAMPLE_SEED, 'a', '\u{80}', 1, 0); } #[test] #[should_panic] fn graphic_weighted_random_char_range_fail_2() { graphic_weighted_random_char_range(EXAMPLE_SEED, 'a', '\u{80}', 2, 1); } #[test] #[should_panic] fn graphic_weighted_random_char_range_fail_3() { graphic_weighted_random_char_range(EXAMPLE_SEED, '\u{80}', 'a', 1, 1); } #[test] #[should_panic] fn graphic_weighted_random_char_range_fail_4() { graphic_weighted_random_char_range(EXAMPLE_SEED, 'a', 'z', 1, 1); } malachite-base-0.4.16/tests/chars/random/graphic_weighted_random_chars.rs000064400000000000000000000153251046102023000246660ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::chars::random::graphic_weighted_random_chars; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; fn graphic_weighted_random_chars_helper( p_numerator: u64, p_denominator: u64, expected_values: &str, expected_common_values: &[(char, usize)], expected_median: (char, Option), ) { let xs = graphic_weighted_random_chars(EXAMPLE_SEED, p_numerator, p_denominator); let values = xs.clone().take(200).collect::(); let common_values = common_values_map_debug(1000000, 10, xs.clone()); let median = median(xs.take(1000000)); assert_eq!( (values.as_str(), common_values.as_slice(), median), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_graphic_weighted_random_chars() { // p = 1/2 graphic_weighted_random_chars_helper( 1, 2, "\u{8daa8}𘋈\u{3805c}𰒏\u{d7447}礝\u{e75f4}깶\u{38f35}\u{d36da}ꅊ\u{8c379}杽쭡𬝱╱𣑺⢍𰰬\u{3899f}瀋𱽊ՠ\ \u{71fe9}𦧴𪂆𦾸\u{c760b}𥳓𡸦\u{c5038}\u{53690}\u{eea10}\u{36080}𲄱\u{f2260}𠵀\u{160ea}\u{361e7}\ \u{5aa82}𱸆\u{dfef7}\u{c0a1d}厩𡗐𫈃⋓\u{f9b20}\u{aaecc}\u{6e0f8}𑌡\u{eaa03}𐦽⎑\u{19dce}\u{332d6}\ \u{61ee4}\u{7720d}\u{b184a}\u{f69ce}\u{751fd}𢰁\u{ec70b}\u{f1b30}摖\u{34bae}\u{d830b}𰾓𘀤\ \u{a044b}𱡫蚇\u{a81cf}\u{74eca}𓎙\u{fc609}𦤋\u{6e154}\u{4c9c4}\u{67d8a}\u{c87ff}𗄤𦁥\u{1aacd}\ \u{1013c4}𢎬\u{5f1c1}\u{7bf68}\u{5319c}뛟䂈𣋩\u{c5a5e}\u{d4fed}Ộ\u{14e64}쀠\u{89ea2}𠊅𫬒𫺇\ \u{3a82a}𔕽\u{6220a}憓쇧𮢚ㆎ쭈\u{68db2}𤣷𬁴𐓴\u{57a9e}\u{87fd2}ჵ𢰨\u{11c91}𮬜\u{9e6cd}🡗\u{ce878}𧗟\ \u{6ad98}죗\u{6e7e1}\u{c0136}\u{9f180}呷\u{b1905}\u{4247b}\u{d35c0}\u{857d4}𭁽䍫𨷥姗\u{9cdeb}𠣞\ \u{fda2c}\u{54070}𧷁\u{ba590}\u{8d48b}𱩕\u{50ede}𭌶\u{f13ea}\u{a4714}𐍊\u{e1c36}䆟𫷏\u{f3b0a}𒿐\ \u{b300c}뎜\u{c5205}\u{e5d53}𢶥\u{43743}𝕻𓉪\u{d9078}𦰥㨠ֆ뇵𫄐𧳜𝑫\u{cc033}\u{57e04}𠉤\u{90835}\ \u{c51ea}譁𤎌\u{b986c}\u{83547}𝅘𝅥𠂗\u{eda4}\u{b4c98}\u{fb04e}\u{12a4c}\u{ac2de}鎌\u{c512c}录𰗶\ \u{4005e}\u{9d70a}𦣱\u{cc2f3}𢋽\u{68a20}🄘\u{c9e61}\u{475b0}", &[ ('שּׁ', 13), ('𘕒', 13), ('𣱵', 13), ('𧀂', 13), ('𩆍', 13), ('𪾣', 13), ('𬃔', 13), ('༈', 12), ('Ṿ', 12), ('㏠', 12) ], ('𰆁', None) ); // p = 1/51 graphic_weighted_random_chars_helper( 1, 51, "\u{8daa8}\u{3805c}𘋈\u{d7447}\u{e75f4}\u{38f35}\u{d36da}\u{8c379}\u{3899f}\u{71fe9}\ \u{c760b}\u{c5038}\u{53690}\u{eea10}\u{36080}\u{f2260}\u{160ea}\u{361e7}\u{5aa82}\u{dfef7}\ \u{c0a1d}\u{f9b20}\u{aaecc}\u{6e0f8}\u{eaa03}\u{19dce}\u{332d6}\u{61ee4}\u{7720d}\u{b184a}\ \u{f69ce}\u{751fd}\u{ec70b}\u{f1b30}\u{34bae}\u{d830b}\u{a044b}\u{a81cf}𰒏\u{74eca}\ \u{fc609}\u{6e154}\u{4c9c4}\u{67d8a}\u{c87ff}\u{1aacd}\u{1013c4}\u{5f1c1}\u{7bf68}\ \u{5319c}\u{c5a5e}\u{d4fed}\u{14e64}\u{89ea2}\u{3a82a}\u{6220a}\u{68db2}\u{57a9e}\u{87fd2}\ \u{11c91}\u{9e6cd}\u{ce878}\u{6ad98}\u{6e7e1}\u{c0136}\u{9f180}\u{b1905}\u{4247b}\u{d35c0}\ \u{857d4}\u{9cdeb}\u{fda2c}\u{54070}\u{ba590}\u{8d48b}\u{50ede}\u{f13ea}\u{a4714}\u{e1c36}\ \u{f3b0a}\u{b300c}\u{c5205}\u{e5d53}\u{43743}\u{d9078}\u{cc033}\u{57e04}\u{90835}\u{c51ea}\ \u{b986c}\u{83547}\u{eda4}\u{b4c98}\u{fb04e}\u{12a4c}\u{ac2de}\u{c512c}\u{4005e}\u{9d70a}\ \u{cc2f3}\u{68a20}\u{c9e61}\u{475b0}\u{fc93b}\u{47840}\u{75aff}\u{420a6}\u{34056}礝\ \u{bb2d7}\u{e7bd0}\u{8fa93}\u{6eddb}\u{3a98a}\u{57fa6}\u{53434}\u{f7b00}\u{b8cef}\u{1007c}\ \u{9b254}\u{e8ab1}\u{f7f42}\u{e0cf2}\u{f7637}\u{1e0f3}\u{8bf53}\u{355f5}\u{74b61}\u{b4e32}\ 깶\u{a8491}\u{ddbb2}\u{10ae4f}\u{9074b}\u{f7a96}\u{404a9}\u{190b9}\u{ad6fb}\u{80af6}\ \u{71938}\u{41da0}\u{6fbe0}\u{101754}\u{786b9}\u{107252}\u{f0b67}\u{94a8c}\u{7efc6}\ \u{c0020}\u{aafcb}\u{ae1c8}\u{cb360}\u{cdff6}\u{f6ae7}\u{c438a}\u{b8107}\u{87007}\u{a0449}\ \u{106a6b}\u{d67b4}\u{5151c}\u{109779}\u{ccb94}\u{d0f86}\u{10de9d}\u{9ebd3}\u{c4077}\ \u{66470}\u{bb11d}\u{762b1}\u{c196b}\u{4f551}\u{4e038}\u{b77b5}\u{a0973}\u{f980d}\u{ee89e}\ \u{53f2d}\u{116d7}\u{1aeee}\u{33312}\u{3689f}\u{1658e}\u{ab097}\u{7b8d6}\u{51a55}\u{13b41}\ \u{3bee4}\u{fb838}\u{43aa6}\u{bb5ff}\u{5413d}\u{7cd9b}\u{b2111}\u{88727}\u{f4884}\u{df9cf}\ \u{b627a}\u{2f3b9}\u{e7877}", &[ ('\u{7a4b8}', 9), ('\u{9cc20}', 9), ('\u{37684}', 8), ('\u{3d034}', 8), ('\u{6441c}', 8), ('\u{6a52a}', 8), ('\u{7a8d2}', 8), ('\u{9b28c}', 8), ('\u{a735f}', 8), ('\u{c6073}', 8), ], ('\u{97cbe}', Some('\u{97cbf}')), ); // p = 50/51 graphic_weighted_random_chars_helper( 50, 51, "𘋈𰒏礝깶ꅊ杽쭡𬝱╱𣑺⢍𰰬瀋𱽊ՠ𦧴𪂆𦾸𥳓𡸦𲄱𠵀𱸆厩𡗐𫈃⋓𑌡𐦽⎑𢰁摖𰾓𘀤𱡫蚇𓎙𦤋𗄤𦁥𢎬뛟䂈𣋩Ộ쀠𠊅𫬒𫺇𔕽憓쇧𮢚ㆎ쭈𤣷𬁴𐓴ჵ𢰨𮬜🡗𧗟죗呷\u{8daa8}𭁽䍫𨷥姗𠣞𧷁𱩕𭌶𐍊䆟𫷏𒿐뎜𢶥𝕻\ 𓉪𦰥㨠ֆ뇵𫄐𧳜𝑫𠉤譁𤎌𝅘𝅥𠂗鎌录𰗶𦣱𢋽🄘𧍽𬚜𭙆𑈦蠄𲈽𩿙鐕🔩ㅏ考𥘡ꔻ𦱊𧭄歡𡴹퉵𦇀𥢞笄羽𢓃𝀖𢴼𗍾𣦹𲆀𭔺敄\u{3805c}罯𦶐𣱦𣞝𤮞𘕒ᕳ붙삑𖭭𨃐闒贜𩋅𓄬𮈯𥟽𪆚𤯆𑲌𭏛𰘜𤔈掠𠦜✂㕶굦𗾉𦮽㾓𘀠\ 褲𖡶𮯉𧹐𑂤튟\u{d7447}䯸🈸𫍤𠬟𘦕釾쥚違혁𨀨𬲝𛁹𡚂🆀裴𧚼Ǐ𫼍䖈೨\u{e75f4}꺏𱽡𡈙䔨팚𐧚羫𡇼𭀯", &[ ('𘚺', 23), ('𢤒', 20), ('𤉺', 20), ('ﱺ', 19), ('𖠖', 19), ('𢓆', 19), ('𤌅', 19), ('𤦵', 19), ('𦱃', 19), ('𭦕', 19) ], ('🍄', None) ); } #[test] #[should_panic] fn graphic_weighted_random_chars_fail_1() { graphic_weighted_random_chars(EXAMPLE_SEED, 0, 0); } #[test] #[should_panic] fn graphic_weighted_random_chars_fail_2() { graphic_weighted_random_chars(EXAMPLE_SEED, 1, 0); } #[test] #[should_panic] fn graphic_weighted_random_chars_fail_3() { graphic_weighted_random_chars(EXAMPLE_SEED, 2, 1); } malachite-base-0.4.16/tests/chars/random/random_ascii_chars.rs000064400000000000000000000034531046102023000224600ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::chars::random::random_ascii_chars; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; #[test] fn test_random_ascii_chars() { let xs = random_ascii_chars(EXAMPLE_SEED); let values = xs.clone().take(200).collect::(); let common_values = common_values_map_debug(1000000, 10, xs.clone()); let median = median(xs.take(1000000)); assert_eq!( (values.as_str(), common_values.as_slice(), median), ( "q^\u{17}bF\\4T!/\u{1}q6\n/\u{11}Y\\wB\\r\\^\u{15}3\'.\'r\u{7}$\u{17}S:\rr@I(\u{10}\ \u{11}}\u{b}\u{7}0z5.n1\u{10}At<9.w\\?b\u{15}(\\hJ\u{10}cO\\^5Edc\u{1f}kq{t=z./\u{5}x\ \u{1}dZrJ%\u{5}`=VU_\u{7f}b;\u{13}\u{6}U.k\r\u{6}PBk]$p\u{1a}+FOH.\r,a\u{1}=DZZ\u{16}\ \u{18}cY\t\u{1e}\u{19}&<,\u{13}%\u{c}{Z!$Z,\u{17}\u{8}?\u{3}\u{4}]\u{1}H\u{c}(K*|l\ \u{15}8^:\u{e}\u{7f}D(P\u{1}XEk!$\u{14}/];E9d\u{e})|v\u{e}W*).\u{19}\u{11}5\u{7f}b8\ \u{18}:", &[ ('\u{2}', 8077), ('y', 8039), ('0', 8015), ('q', 7966), ('\u{8}', 7937), ('M', 7933), ('2', 7928), ('[', 7927), ('R', 7925), ('f', 7924) ][..], ('?', None) ) ); } malachite-base-0.4.16/tests/chars/random/random_char_inclusive_range.rs000064400000000000000000000122511046102023000243560ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::chars::random::random_char_inclusive_range; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; fn random_char_inclusive_range_helper( a: char, b: char, expected_values: &str, expected_common_values: &[(char, usize)], expected_median: (char, Option), ) { let xs = random_char_inclusive_range(EXAMPLE_SEED, a, b); let values = xs.clone().take(200).collect::(); let common_values = common_values_map_debug(1000000, 10, xs.clone()); let median = median(xs.take(1000000)); assert_eq!( (values.as_str(), common_values.as_slice(), median), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_random_char_inclusive_range() { random_char_inclusive_range_helper( 'a', 'a', "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ aaaaaaaaaaaaaaaaaaa", &[('a', 1000000)], ('a', None), ); random_char_inclusive_range_helper( 'a', 'c', "babcbbabacbabccabacccbaccbbbaacaccbabbaccacabcbbccbbbacabbbcabbcbbbcbcbbcabbbcabcbaacabbbc\ bccccccbacabaacbcababbaabcacabbbabaaacbccccbccabbaaacabaabccacabccccabbcacccaaccaccaccbbbca\ abcbaabcccbccbbbabc", &[('b', 333784), ('c', 333516), ('a', 332700)], ('b', None), ); random_char_inclusive_range_helper( 'a', 'z', "rlewrsgkdlbeouylrelopxqkoonftexoshqulgvonioatekqesxybqjsrbsajhpzzvzpcxcuyfkcsrexwwcjymyxhj\ pxkbyhasvvkwucaopwwpxyncdkvllxbdavqlxlsaxglzyhrulnqvqdipeklnnbgdhejggrhwgjjmmpndcjsvlqypdqq\ odasmavfvcmxcvoopcr", &[ ('x', 38904), ('q', 38795), ('s', 38687), ('w', 38660), ('d', 38655), ('f', 38647), ('a', 38592), ('n', 38569), ('j', 38531), ('z', 38530), ], ('n', None), ); random_char_inclusive_range_helper( '!', '9', "2,%723\'+$,\"%/59,2%,/081+//.&4%8/3(15,\'6/.)/!4%+1%389\"1*32\"3!*(060#8#59&+#32%877#*9-98\ (*08+\"9(!366+75#!/077089.#$+6,,8\"$!61,8,3!8\',9(25,.161$)0%+,..\"\'$(%*\'\'2(7\'**--0.$#*\ 36,190$11/$!3-!6&6#-8#6//0#2#5\"!", &[ ('8', 40444), ('1', 40300), ('7', 40244), ('3', 40201), ('&', 40174), ('$', 40171), ('.', 40117), ('*', 40111), ('!', 40107), ('#', 40076), ], ('-', None), ); random_char_inclusive_range_helper( '\u{D7FF}', '\u{E000}', "\u{e000}\u{d7ff}\u{d7ff}\u{d7ff}\u{e000}\u{e000}\u{e000}\u{d7ff}\u{e000}\u{e000}\u{e000}\ \u{e000}\u{d7ff}\u{e000}\u{e000}\u{e000}\u{e000}\u{d7ff}\u{e000}\u{d7ff}\u{d7ff}\u{d7ff}\ \u{e000}\u{d7ff}\u{d7ff}\u{d7ff}\u{e000}\u{e000}\u{d7ff}\u{e000}\u{e000}\u{d7ff}\u{d7ff}\ \u{d7ff}\u{e000}\u{d7ff}\u{d7ff}\u{e000}\u{e000}\u{e000}\u{d7ff}\u{e000}\u{d7ff}\u{d7ff}\ \u{e000}\u{d7ff}\u{e000}\u{e000}\u{d7ff}\u{d7ff}\u{d7ff}\u{e000}\u{d7ff}\u{e000}\u{d7ff}\ \u{e000}\u{e000}\u{d7ff}\u{d7ff}\u{d7ff}\u{d7ff}\u{e000}\u{d7ff}\u{e000}\u{e000}\u{e000}\ \u{e000}\u{d7ff}\u{e000}\u{d7ff}\u{e000}\u{d7ff}\u{d7ff}\u{d7ff}\u{d7ff}\u{d7ff}\u{d7ff}\ \u{e000}\u{d7ff}\u{d7ff}\u{d7ff}\u{e000}\u{e000}\u{e000}\u{d7ff}\u{e000}\u{e000}\u{d7ff}\ \u{e000}\u{e000}\u{d7ff}\u{d7ff}\u{e000}\u{d7ff}\u{e000}\u{d7ff}\u{d7ff}\u{d7ff}\u{e000}\ \u{e000}\u{e000}\u{e000}\u{d7ff}\u{e000}\u{d7ff}\u{e000}\u{d7ff}\u{d7ff}\u{d7ff}\u{e000}\ \u{d7ff}\u{d7ff}\u{e000}\u{d7ff}\u{d7ff}\u{e000}\u{e000}\u{d7ff}\u{e000}\u{d7ff}\u{d7ff}\ \u{e000}\u{e000}\u{e000}\u{d7ff}\u{e000}\u{e000}\u{e000}\u{e000}\u{d7ff}\u{e000}\u{e000}\ \u{e000}\u{d7ff}\u{e000}\u{d7ff}\u{d7ff}\u{d7ff}\u{d7ff}\u{e000}\u{d7ff}\u{d7ff}\u{e000}\ \u{e000}\u{e000}\u{d7ff}\u{e000}\u{d7ff}\u{e000}\u{d7ff}\u{d7ff}\u{e000}\u{e000}\u{e000}\ \u{d7ff}\u{d7ff}\u{e000}\u{e000}\u{e000}\u{d7ff}\u{e000}\u{d7ff}\u{e000}\u{e000}\u{e000}\ \u{e000}\u{d7ff}\u{e000}\u{e000}\u{d7ff}\u{e000}\u{d7ff}\u{e000}\u{d7ff}\u{d7ff}\u{e000}\ \u{e000}\u{d7ff}\u{d7ff}\u{e000}\u{e000}\u{d7ff}\u{e000}\u{e000}\u{e000}\u{d7ff}\u{d7ff}\ \u{e000}\u{d7ff}\u{d7ff}\u{e000}\u{e000}\u{e000}\u{d7ff}\u{e000}\u{d7ff}\u{e000}\u{e000}\ \u{e000}\u{d7ff}", &[('\u{e000}', 500473), ('\u{d7ff}', 499527)], ('\u{e000}', None), ); } #[test] #[should_panic] fn random_char_inclusive_range_fail() { random_char_inclusive_range(EXAMPLE_SEED, 'b', 'a'); } malachite-base-0.4.16/tests/chars/random/random_char_range.rs000064400000000000000000000120731046102023000222770ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::chars::random::random_char_range; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; fn random_char_range_helper( a: char, b: char, expected_values: &str, expected_common_values: &[(char, usize)], expected_median: (char, Option), ) { let xs = random_char_range(EXAMPLE_SEED, a, b); let values = xs.clone().take(200).collect::(); let common_values = common_values_map_debug(1000000, 10, xs.clone()); let median = median(xs.take(1000000)); assert_eq!( (values.as_str(), common_values.as_slice(), median), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_random_char_range() { random_char_range_helper( 'a', 'b', "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ aaaaaaaaaaaaaaaaaaa", &[('a', 1000000)], ('a', None), ); random_char_range_helper( 'a', 'd', "babcbbabacbabccabacccbaccbbbaacaccbabbaccacabcbbccbbbacabbbcabbcbbbcbcbbcabbbcabcbaacabbbc\ bccccccbacabaacbcababbaabcacabbbabaaacbccccbccabbaaacabaabccacabccccabbcacccaaccaccaccbbbca\ abcbaabcccbccbbbabc", &[('b', 333784), ('c', 333516), ('a', 332700)], ('b', None), ); random_char_range_helper( 'a', 'z', "rlewrsgkdlbeouylrelopxqkoonftexoshqulgvonioatekqesxybqjsrbsajhpvpcxcuyfkcsrexwwcjymyxhjpxk\ byhasvvkwucaopwwpxyncdkvllxbdavqlxlsaxglyhrulnqvqdipeklnnbgdhejggrhwgjjmmpndcjsvlqypdqqodas\ mavfvcmxcvoopcrcuba", &[ ('x', 40444), ('q', 40300), ('w', 40244), ('s', 40201), ('f', 40174), ('d', 40171), ('n', 40117), ('j', 40111), ('a', 40107), ('c', 40076), ], ('m', None), ); random_char_range_helper( '!', '9', "2,%723\'+$,\"%/5,2%,/081+//.&4%8/3(15,\'6/.)/!4%+1%38\"1*32\"3!*(060#8#5&+#32%877#*-8(*08+\ \"(!366+75#!/07708.#$+6,,8\"$!61,8,3!8\',(25,.161$)0%+,..\"\'$(%*\'\'2(7\'**--0.$#*36,10$11\ /$!3-!6&6#-8#6//0#2#5\"!#8/)%238/", &[ ('8', 42093), ('1', 42031), ('$', 41908), ('3', 41887), ('&', 41836), ('7', 41830), ('!', 41753), ('.', 41753), ('*', 41699), ('+', 41673), ], ('-', None), ); random_char_range_helper( '\u{D7FF}', '\u{E001}', "\u{e000}\u{d7ff}\u{d7ff}\u{d7ff}\u{e000}\u{e000}\u{e000}\u{d7ff}\u{e000}\u{e000}\u{e000}\ \u{e000}\u{d7ff}\u{e000}\u{e000}\u{e000}\u{e000}\u{d7ff}\u{e000}\u{d7ff}\u{d7ff}\u{d7ff}\ \u{e000}\u{d7ff}\u{d7ff}\u{d7ff}\u{e000}\u{e000}\u{d7ff}\u{e000}\u{e000}\u{d7ff}\u{d7ff}\ \u{d7ff}\u{e000}\u{d7ff}\u{d7ff}\u{e000}\u{e000}\u{e000}\u{d7ff}\u{e000}\u{d7ff}\u{d7ff}\ \u{e000}\u{d7ff}\u{e000}\u{e000}\u{d7ff}\u{d7ff}\u{d7ff}\u{e000}\u{d7ff}\u{e000}\u{d7ff}\ \u{e000}\u{e000}\u{d7ff}\u{d7ff}\u{d7ff}\u{d7ff}\u{e000}\u{d7ff}\u{e000}\u{e000}\u{e000}\ \u{e000}\u{d7ff}\u{e000}\u{d7ff}\u{e000}\u{d7ff}\u{d7ff}\u{d7ff}\u{d7ff}\u{d7ff}\u{d7ff}\ \u{e000}\u{d7ff}\u{d7ff}\u{d7ff}\u{e000}\u{e000}\u{e000}\u{d7ff}\u{e000}\u{e000}\u{d7ff}\ \u{e000}\u{e000}\u{d7ff}\u{d7ff}\u{e000}\u{d7ff}\u{e000}\u{d7ff}\u{d7ff}\u{d7ff}\u{e000}\ \u{e000}\u{e000}\u{e000}\u{d7ff}\u{e000}\u{d7ff}\u{e000}\u{d7ff}\u{d7ff}\u{d7ff}\u{e000}\ \u{d7ff}\u{d7ff}\u{e000}\u{d7ff}\u{d7ff}\u{e000}\u{e000}\u{d7ff}\u{e000}\u{d7ff}\u{d7ff}\ \u{e000}\u{e000}\u{e000}\u{d7ff}\u{e000}\u{e000}\u{e000}\u{e000}\u{d7ff}\u{e000}\u{e000}\ \u{e000}\u{d7ff}\u{e000}\u{d7ff}\u{d7ff}\u{d7ff}\u{d7ff}\u{e000}\u{d7ff}\u{d7ff}\u{e000}\ \u{e000}\u{e000}\u{d7ff}\u{e000}\u{d7ff}\u{e000}\u{d7ff}\u{d7ff}\u{e000}\u{e000}\u{e000}\ \u{d7ff}\u{d7ff}\u{e000}\u{e000}\u{e000}\u{d7ff}\u{e000}\u{d7ff}\u{e000}\u{e000}\u{e000}\ \u{e000}\u{d7ff}\u{e000}\u{e000}\u{d7ff}\u{e000}\u{d7ff}\u{e000}\u{d7ff}\u{d7ff}\u{e000}\ \u{e000}\u{d7ff}\u{d7ff}\u{e000}\u{e000}\u{d7ff}\u{e000}\u{e000}\u{e000}\u{d7ff}\u{d7ff}\ \u{e000}\u{d7ff}\u{d7ff}\u{e000}\u{e000}\u{e000}\u{d7ff}\u{e000}\u{d7ff}\u{e000}\u{e000}\ \u{e000}\u{d7ff}", &[('\u{e000}', 500473), ('\u{d7ff}', 499527)], ('\u{e000}', None), ); } #[test] #[should_panic] fn random_char_range_fail() { random_char_range(EXAMPLE_SEED, 'a', 'a'); } malachite-base-0.4.16/tests/chars/random/random_chars.rs000064400000000000000000000064201046102023000213050ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::chars::random::random_chars; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; #[test] fn test_random_chars() { let xs = random_chars(EXAMPLE_SEED); let values = xs.clone().take(200).collect::(); let common_values = common_values_map_debug(1000000, 10, xs.clone()); let median = median(xs.take(1000000)); assert_eq!( (values.as_str(), common_values.as_slice(), median), ( "\u{5f771}\u{87234}\u{bcd36}\u{9e195}\u{5da07}\u{36553}\u{45028}\u{1cdfd}\u{d8530}\ \u{c7f2e}\u{ba4bc}\u{ff677}\u{a12e2}\u{d775c}\u{f827b}\u{bdf7a}簅\u{15aca}\u{4e5e2}\ \u{bb286}\u{18eeb}\u{bac4f}\u{5b55a}\u{65709}\u{b2626}\u{31a93}\u{8757b}\u{b3524}\ \u{fcc17}\u{32c01}\u{aada8}\u{57e7c}\u{eb738}栨\u{51a21}\u{ef6af}\u{b9caa}\u{d5099}\ \u{e397f}\u{32518}\u{6952d}\u{93ad5}\u{65c6e}\u{dc7bd}\u{aec4c}\u{dd524}\u{c0bc1}\ \u{795d0}\u{dbb9d}\u{a50fb}紐\u{4effe}\u{794af}\u{1b5a0}\u{56be3}\u{78fc9}\u{5870a}\ \u{106f48}\u{dfffa}\u{3cc01}\u{91290}\u{4628e}\u{bee71}\u{70e90}\u{b48bb}\u{3a445}\ \u{10a645}𬆠\u{e59de}\u{61b5a}\u{f4783}\u{c5ab2}幔\u{fdb07}\u{abccb}\u{ba750}\u{88d5a}\ \u{a706e}\u{969a2}\u{1089e3}\u{102189}\u{5f066}\u{10ea66}\u{435bb}\u{bcbd6}\u{4bc59}𱆞\ \u{f50a0}\u{47bc1}\u{5fd98}\u{91a7a}\u{100a8d}\u{e0017}\u{9db06}\u{1ab04}\u{780f6}ㅚ\ \u{5fc0a}\u{fb714}\u{c62cd}\u{b22dc}\u{10364e}\u{ee477}\u{f0983}\u{b5c36}\u{41f7b}\ \u{bdf28}\u{b27f7}\u{94dc8}\u{73381}\u{34609}\u{52911}\u{e56bf}\u{100af4}\u{396ff}\ \u{1051a8}𬅑\u{815dc}\u{fd1e7}\u{e6e9c}攠\u{eceaa}\u{10029d}\u{5e236}\u{d963b}\u{bbb1a}\ \u{108b67}\u{e5bc3}\u{97108}𢔱\u{9f166}\u{dedb4}\u{52752}\u{45bf5}\u{86d73}\u{ff2fd}쫵\ \u{78f74}\u{93bc0}\u{c308f}\u{e8b6}\u{89619}\u{1cdf9}\u{b9c86}\u{9f375}\u{c2487}\ \u{e1c3e}\u{f6e29}\u{79cc5}𬑎\u{9a803}\u{bf22e}\u{7e88e}\u{c50e8}\u{58c32}\u{79248}𰥦\ \u{b238b}\u{104b92}\u{8cc78}\u{eecc5}𢇡\u{e1fb6}\u{625ab}\u{a1988}䮨\u{bbaa5}\u{143be}\ \u{a12d4}\u{1028e1}\u{1c105}\u{9493f}\u{efa70}\u{13487}紋\u{b1948}\u{89052}\u{8c3cb}\ \u{b82d2}\u{729c3}\u{10c5ba}\u{dec07}𰢫\u{d277f}\u{3e5dc}\u{52431}\u{4867e}\u{75774}𪲨\ \u{b865a}\u{105191}\u{93891}\u{c4975}\u{c2f58}\u{d387c}\u{157dd}\u{77a83}\u{d6eec}\ \u{b2581}\u{9bb09}", &[ ('\u{1e21d}', 8), ('\u{bd934}', 8), ('\u{dc941}', 8), ('䄡', 7), ('霜', 7), ('𐊩', 7), ('𣡝', 7), ('𦇍', 7), ('𩩻', 7), ('𰊻', 7) ][..], ('\u{88629}', Some('\u{8862a}')) ) ); } malachite-base-0.4.16/tests/comparison/macros.rs000064400000000000000000000055561046102023000177340ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ signed_gen, signed_pair_gen, signed_triple_gen, unsigned_gen, unsigned_pair_gen_var_27, unsigned_triple_gen_var_19, }; use std::cmp::{max, min}; #[test] pub fn test_min() { assert_eq!(min!(4), 4); assert_eq!(min!(4, 5, 6), 4); } #[test] pub fn test_max() { assert_eq!(max!(4), 4); assert_eq!(max!(4, 5, 6), 6); } fn unsigned_max_properties_helper() { unsigned_gen::().test_properties(|x| { assert_eq!(max!(x), x); }); unsigned_pair_gen_var_27::().test_properties(|(x, y)| { assert_eq!(max!(x, y), max(x, y)); }); unsigned_triple_gen_var_19::().test_properties(|(x, y, z)| { assert_eq!(max!(x, y, z), max(max(x, y), z)); assert_eq!(max!(x, y, z), max(x, max(y, z))); }); } fn signed_max_properties_helper() { signed_gen::().test_properties(|x| { assert_eq!(max!(x), x); }); signed_pair_gen::().test_properties(|(x, y)| { assert_eq!(max!(x, y), max(x, y)); }); signed_triple_gen::().test_properties(|(x, y, z)| { assert_eq!(max!(x, y, z), max(max(x, y), z)); assert_eq!(max!(x, y, z), max(x, max(y, z))); }); } #[test] fn max_properties() { apply_fn_to_unsigneds!(unsigned_max_properties_helper); apply_fn_to_signeds!(signed_max_properties_helper); } fn unsigned_min_properties_helper() { unsigned_gen::().test_properties(|x| { assert_eq!(min!(x), x); }); unsigned_pair_gen_var_27::().test_properties(|(x, y)| { assert_eq!(min!(x, y), min(x, y)); }); unsigned_triple_gen_var_19::().test_properties(|(x, y, z)| { assert_eq!(min!(x, y, z), min(min(x, y), z)); assert_eq!(min!(x, y, z), min(x, min(y, z))); }); } fn signed_min_properties_helper() { signed_gen::().test_properties(|x| { assert_eq!(min!(x), x); }); signed_pair_gen::().test_properties(|(x, y)| { assert_eq!(min!(x, y), min(x, y)); }); signed_triple_gen::().test_properties(|(x, y, z)| { assert_eq!(min!(x, y, z), min(min(x, y), z)); assert_eq!(min!(x, y, z), min(x, min(y, z))); }); } #[test] fn min_properties() { apply_fn_to_unsigneds!(unsigned_min_properties_helper); apply_fn_to_signeds!(signed_min_properties_helper); } malachite-base-0.4.16/tests/extra_variadic/mod.rs000064400000000000000000000227601046102023000200360ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::iterators::bit_distributor::{BitDistributor, BitDistributorOutputType}; use malachite_base::iterators::iterator_cache::IteratorCache; use malachite_base::num::arithmetic::traits::CheckedPow; use malachite_base::num::conversion::traits::{ExactFrom, WrappingFrom}; use malachite_base::num::iterators::{ruler_sequence, RulerSequence}; use malachite_base::num::logic::traits::SignificantBits; use malachite_base::num::random::{random_unsigned_range, RandomUnsignedRange}; use malachite_base::random::Seed; use malachite_base::sets::random::{random_b_tree_sets_fixed_length, RandomBTreeSetsFixedLength}; use malachite_base::tuples::exhaustive::{ clone_helper, exhaustive_dependent_pairs, ExhaustiveDependentPairs, }; use malachite_base::tuples::random::next_helper; use malachite_base::unions::UnionFromStrError; use malachite_base::vecs::exhaustive::{ exhaustive_ordered_unique_vecs_fixed_length, fixed_length_ordered_unique_indices_helper, next_bit_pattern, unique_indices, validate_oi_map, ExhaustiveOrderedUniqueCollections, ExhaustiveUniqueVecsGenerator, LexFixedLengthVecsOutput, UniqueIndices, }; use malachite_base::vecs::ExhaustiveVecPermutations; use std::cmp::max; use std::collections::HashMap; use std::fmt::{self, Display, Formatter}; use std::hash::Hash; use std::marker::PhantomData; use std::str::FromStr; fn unwrap_triple((a, b, c): (Option, Option, Option)) -> (X, Y, Z) { (a.unwrap(), b.unwrap(), c.unwrap()) } lex_custom_tuples! { (pub(crate)), LexTriplesXXY, (X, X, Y), (None, None, None), unwrap_triple, lex_triples_xxy, [X, I, xs, [0, x_0], [1, x_1]], [Y, J, ys, [2, y_2]] } lex_custom_tuples!( (pub(crate)), LexTriplesXYX, (X, Y, X), (None, None, None), unwrap_triple, lex_triples_xyx, [X, I, xs, [0, x_0], [2, x_2]], [Y, J, ys, [1, y_1]] ); lex_tuples!( (pub(crate)), 3, LexTriples, LexTriplesFromSingle, lex_triples, lex_triples_from_single, (T, T, T), [0, X, I, xs, x], [1, Y, J, ys, y], [2, Z, K, zs, z] ); lex_tuples!( (pub(crate)), 4, LexQuadruples, LexQuadruplesFromSingle, lex_quadruples, lex_quadruples_from_single, (T, T, T, T), [0, X, I, xs, x], [1, Y, J, ys, y], [2, Z, K, zs, z], [3, W, L, ws, w] ); lex_tuples!( (pub(crate)), 5, LexQuintuples, LexQuintuplesFromSingle, lex_quintuples, lex_quintuples_from_single, (T, T, T, T, T), [0, X, I, xs, x], [1, Y, J, ys, y], [2, Z, K, zs, z], [3, W, L, ws, w], [4, V, M, vs, v] ); lex_tuples!( (pub(crate)), 8, LexOctuples, LexOctuplesFromSingle, lex_octuples, lex_octuples_from_single, (T, T, T, T, T, T, T, T), [0, X, I, xs, x], [1, Y, J, ys, y], [2, Z, K, zs, z], [3, W, L, ws, w], [4, V, M, vs, v], [5, U, N, us, u], [6, T, O, ts, t], [7, S, P, ss, s] ); exhaustive_tuples_1_input!( (pub(crate)), ExhaustiveTriples1Input, exhaustive_triples_1_input, exhaustive_triples_from_single, (I::Item, I::Item, I::Item), [0, output_type_x], [1, output_type_y], [2, output_type_z] ); exhaustive_tuples_1_input!( (pub(crate)), ExhaustiveQuadruples1Input, exhaustive_quadruples_1_input, exhaustive_quadruples_from_single, (I::Item, I::Item, I::Item, I::Item), [0, output_type_x], [1, output_type_y], [2, output_type_z], [3, output_type_w] ); exhaustive_tuples_1_input!( (pub(crate)), ExhaustiveQuintuples1Input, exhaustive_quintuples_1_input, exhaustive_quintuples_from_single, (I::Item, I::Item, I::Item, I::Item, I::Item), [0, output_type_x], [1, output_type_y], [2, output_type_z], [3, output_type_w], [4, output_type_v] ); exhaustive_tuples_1_input!( (pub(crate)), ExhaustiveOctuples1Input, exhaustive_octuples_1_input, exhaustive_octuples_from_single, ( I::Item, I::Item, I::Item, I::Item, I::Item, I::Item, I::Item, I::Item ), [0, output_type_x], [1, output_type_y], [2, output_type_z], [3, output_type_w], [4, output_type_v], [5, output_type_u], [6, output_type_t], [7, output_type_s] ); custom_tuples!( (pub(crate)), ExhaustiveTriplesXXY, (X, X, Y), (None, None, None), unwrap_triple, exhaustive_triples_xxy, exhaustive_triples_xxy_custom_output, [X, I, xs, xs_done, [0, output_type_xs_0], [1, output_type_xs_1]], [Y, J, ys, ys_done, [2, output_type_ys_2]] ); custom_tuples!( (pub(crate)), ExhaustiveTriplesXYX, (X, Y, X), (None, None, None), unwrap_triple, exhaustive_triples_xyx, exhaustive_triples_xyx_custom_output, [X, I, xs, xs_done, [0, output_type_xs_0], [2, output_type_ys_1]], [Y, J, ys, ys_done, [1, output_type_xs_2]] ); lex_ordered_unique_tuples!( (pub(crate)), LexOrderedUniqueTriples, 3, (I::Item, I::Item, I::Item), lex_ordered_unique_triples, [0, 1, 2] ); lex_ordered_unique_tuples!( (pub(crate)), LexOrderedUniqueQuadruples, 4, (I::Item, I::Item, I::Item, I::Item), lex_ordered_unique_quadruples, [0, 1, 2, 3] ); lex_ordered_unique_tuples!( (pub(crate)), LexOrderedUniqueQuintuples, 5, (I::Item, I::Item, I::Item, I::Item, I::Item), lex_ordered_unique_quintuples, [0, 1, 2, 3, 4] ); exhaustive_ordered_unique_tuples!( (pub(crate)), ExhaustiveOrderedUniqueTriples, 3, (I::Item, I::Item, I::Item), exhaustive_ordered_unique_triples, [0, 1, 2] ); exhaustive_ordered_unique_tuples!( (pub(crate)), ExhaustiveOrderedUniqueQuadruples, 4, (I::Item, I::Item, I::Item, I::Item), exhaustive_ordered_unique_quadruples, [0, 1, 2, 3] ); exhaustive_ordered_unique_tuples!( (pub(crate)), ExhaustiveOrderedUniqueQuintuples, 5, (I::Item, I::Item, I::Item, I::Item, I::Item), exhaustive_ordered_unique_quintuples, [0, 1, 2, 3, 4] ); lex_unique_tuples!( (pub(crate)), LexUniqueTriples, 3, (I::Item, I::Item, I::Item), lex_unique_triples, [0, 1, 2] ); lex_unique_tuples!( (pub(crate)), LexUniqueQuadruples, 4, (I::Item, I::Item, I::Item, I::Item), lex_unique_quadruples, [0, 1, 2, 3] ); lex_unique_tuples!( (pub(crate)), LexUniqueQuintuples, 5, (I::Item, I::Item, I::Item, I::Item, I::Item), lex_unique_quintuples, [0, 1, 2, 3, 4] ); exhaustive_unique_tuples!( (pub(crate)), ExhaustiveUniqueTriples, 3, (I::Item, I::Item, I::Item), exhaustive_unique_triples, [0, 1, 2] ); exhaustive_unique_tuples!( (pub(crate)), ExhaustiveUniqueQuadruples, 4, (I::Item, I::Item, I::Item, I::Item), exhaustive_unique_quadruples, [0, 1, 2, 3] ); exhaustive_unique_tuples!( (pub(crate)), ExhaustiveUniqueQuintuples, 5, (I::Item, I::Item, I::Item, I::Item, I::Item), exhaustive_unique_quintuples, [0, 1, 2, 3, 4] ); random_tuples!( (pub(crate)), RandomTriples, RandomTriplesFromSingle, random_triples, random_triples_from_single, (I::Item, I::Item, I::Item), [0, X, I, xs, xs_gen], [1, Y, J, ys, ys_gen], [2, Z, K, zs, zs_gen] ); random_custom_tuples!( (pub(crate)), RandomTriplesXXY, (X, X, Y), random_triples_xxy, [X, I, xs, xs_gen, [x_0, x_0], [x_1, x_1]], [Y, J, ys, ys_gen, [y_2, y_2]] ); random_custom_tuples!( (pub(crate)), RandomTriplesXYX, (X, Y, X), random_triples_xyx, [X, I, xs, xs_gen, [x_0, x_0], [x_2, y_1]], [Y, J, ys, ys_gen, [y_1, x_2]] ); random_ordered_unique_tuples!( (pub(crate)), RandomOrderedUniqueTriples, 3, (I::Item, I::Item, I::Item), random_ordered_unique_triples, [0, 1, 2] ); random_unique_tuples!( (pub(crate)), RandomUniqueTriples, 3, (I::Item, I::Item, I::Item), random_unique_triples, [0, 1, 2] ); exhaustive_unions!( (pub(crate)), Union3, LexUnion3s, ExhaustiveUnion3s, lex_union3s, exhaustive_union3s, 3, [0, X, I, A, xs, xs_done], [1, Y, J, B, ys, ys_done], [2, Z, K, C, zs, zs_done] ); union_struct!( (pub(crate)), Union3, Union3, [A, A, 'A', a], [B, B, 'B', b], [C, C, 'C', c] ); random_unions!( (pub(crate)), Union3, RandomUnion3s, random_union3s, 3, [0, X, I, A, xs, xs_gen], [1, Y, J, B, ys, ys_gen], [2, Z, K, C, zs, zs_gen] ); lex_vecs_fixed_length!( (pub(crate)), LexFixedLengthVecs3Inputs, lex_vecs_fixed_length_3_inputs, lex_vecs_length_3, [0, I, xs, xs_outputs], [1, J, ys, ys_outputs], [2, K, zs, zs_outputs] ); exhaustive_vecs_fixed_length!( (pub(crate)), ExhaustiveFixedLengthVecs3Inputs, exhaustive_vecs_fixed_length_3_inputs, exhaustive_vecs_length_3, [0, I, xs, xs_done, xs_outputs], [1, J, ys, ys_done, ys_outputs], [2, K, zs, zs_done, zs_outputs] ); random_vecs_fixed_length!( (pub(crate)), RandomFixedLengthVecs3Inputs, random_vecs_fixed_length_3_inputs, random_vecs_length_3, [0, I, xs, xs_gen], [1, J, ys, ys_gen], [2, K, zs, zs_gen] ); malachite-base-0.4.16/tests/iterators/bit_distributor/bit_map_as_slice.rs000064400000000000000000000267071046102023000250000ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::iterators::bit_distributor::{BitDistributor, BitDistributorOutputType}; fn bit_distributor_helper(bit_distributor: &BitDistributor, bit_map: &[usize]) { assert_eq!(bit_distributor.bit_map_as_slice(), bit_map); } #[test] fn test_bit_map_as_slice() { bit_distributor_helper( &BitDistributor::new(&[BitDistributorOutputType::normal(1)]), &[0; 64], ); bit_distributor_helper( &BitDistributor::new(&[BitDistributorOutputType::normal(1); 2]), &[ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, ], ); bit_distributor_helper( &BitDistributor::new(&[BitDistributorOutputType::normal(1); 3]), &[ 2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2, ], ); bit_distributor_helper( &BitDistributor::new(&[BitDistributorOutputType::normal(1); 5]), &[ 4, 3, 2, 1, 0, 4, 3, 2, 1, 0, 4, 3, 2, 1, 0, 4, 3, 2, 1, 0, 4, 3, 2, 1, 0, 4, 3, 2, 1, 0, 4, 3, 2, 1, 0, 4, 3, 2, 1, 0, 4, 3, 2, 1, 0, 4, 3, 2, 1, 0, 4, 3, 2, 1, 0, 4, 3, 2, 1, 0, 4, 3, 2, 1, ], ); bit_distributor_helper( &BitDistributor::new(&[BitDistributorOutputType::normal(2); 2]), &[ 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, ], ); bit_distributor_helper( &BitDistributor::new(&[ BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(2), ]), &[ 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, ], ); bit_distributor_helper( &BitDistributor::new(&[ BitDistributorOutputType::normal(2), BitDistributorOutputType::normal(1), ]), &[ 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ], ); bit_distributor_helper( &BitDistributor::new(&[ BitDistributorOutputType::normal(2), BitDistributorOutputType::normal(3), ]), &[ 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, ], ); bit_distributor_helper( &BitDistributor::new(&[ BitDistributorOutputType::normal(1), BitDistributorOutputType::tiny(), ]), &[ 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, ], ); bit_distributor_helper( &BitDistributor::new(&[ BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ]), &[ 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, ], ); bit_distributor_helper( &BitDistributor::new(&[ BitDistributorOutputType::normal(1), BitDistributorOutputType::tiny(), BitDistributorOutputType::tiny(), ]), &[ 2, 1, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, ], ); bit_distributor_helper( &BitDistributor::new(&[ BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(1), BitDistributorOutputType::tiny(), BitDistributorOutputType::tiny(), ]), &[ 3, 2, 1, 3, 0, 1, 0, 2, 1, 0, 1, 0, 1, 0, 1, 3, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 3, ], ); let mut bit_distributor = BitDistributor::new(&[BitDistributorOutputType::normal(1)]); bit_distributor.set_max_bits(&[0], 5); bit_distributor_helper( &bit_distributor, &[ 0, 0, 0, 0, 0, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, ], ); let mut bit_distributor = BitDistributor::new(&[BitDistributorOutputType::normal(1); 2]); bit_distributor.set_max_bits(&[1], 2); bit_distributor_helper( &bit_distributor, &[ 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ], ); let mut bit_distributor = BitDistributor::new(&[BitDistributorOutputType::normal(1); 2]); bit_distributor.set_max_bits(&[0], 2); bit_distributor_helper( &bit_distributor, &[ 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ], ); let mut bit_distributor = BitDistributor::new(&[ BitDistributorOutputType::normal(1), BitDistributorOutputType::tiny(), ]); bit_distributor.set_max_bits(&[0], 2); bit_distributor_helper( &bit_distributor, &[ 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ], ); let mut bit_distributor = BitDistributor::new(&[ BitDistributorOutputType::normal(1), BitDistributorOutputType::tiny(), ]); bit_distributor.set_max_bits(&[1], 2); bit_distributor_helper( &bit_distributor, &[ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ], ); let mut bit_distributor = BitDistributor::new(&[BitDistributorOutputType::normal(1); 5]); bit_distributor.set_max_bits(&[0], 2); bit_distributor.set_max_bits(&[1], 1); bit_distributor.set_max_bits(&[2], 5); bit_distributor.set_max_bits(&[3], 3); bit_distributor.set_max_bits(&[4], 4); bit_distributor_helper( &bit_distributor, &[ 4, 3, 2, 1, 0, 4, 3, 2, 0, 4, 3, 2, 4, 2, 2, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, usize::MAX, ], ); let mut bit_distributor = BitDistributor::new(&[BitDistributorOutputType::normal(2); 2]); bit_distributor.set_max_bits(&[0], 5); bit_distributor_helper( &bit_distributor, &[ 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ], ); let mut bit_distributor = BitDistributor::new(&[ BitDistributorOutputType::normal(1), BitDistributorOutputType::tiny(), BitDistributorOutputType::tiny(), ]); bit_distributor.set_max_bits(&[0], 5); bit_distributor_helper( &bit_distributor, &[ 2, 1, 0, 2, 0, 0, 0, 1, 0, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, ], ); } malachite-base-0.4.16/tests/iterators/bit_distributor/get_output.rs000064400000000000000000000337661046102023000237250ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::iterators::bit_distributor::{BitDistributor, BitDistributorOutputType}; fn bit_distributor_helper(mut bit_distributor: BitDistributor, expected_outputs: &[&[usize]]) { let mut outputs = Vec::new(); for _ in 0..20 { outputs.push( (0..bit_distributor.output_types.len()) .map(|i| bit_distributor.get_output(i)) .collect::>(), ); bit_distributor.increment_counter(); } assert_eq!(outputs, expected_outputs); } #[test] fn test_get_output() { bit_distributor_helper( BitDistributor::new(&[BitDistributorOutputType::normal(1)]), &[ &[0], &[1], &[2], &[3], &[4], &[5], &[6], &[7], &[8], &[9], &[10], &[11], &[12], &[13], &[14], &[15], &[16], &[17], &[18], &[19], ], ); bit_distributor_helper( BitDistributor::new(&[BitDistributorOutputType::normal(1); 2]), &[ &[0, 0], &[0, 1], &[1, 0], &[1, 1], &[0, 2], &[0, 3], &[1, 2], &[1, 3], &[2, 0], &[2, 1], &[3, 0], &[3, 1], &[2, 2], &[2, 3], &[3, 2], &[3, 3], &[0, 4], &[0, 5], &[1, 4], &[1, 5], ], ); bit_distributor_helper( BitDistributor::new(&[BitDistributorOutputType::normal(1); 3]), &[ &[0, 0, 0], &[0, 0, 1], &[0, 1, 0], &[0, 1, 1], &[1, 0, 0], &[1, 0, 1], &[1, 1, 0], &[1, 1, 1], &[0, 0, 2], &[0, 0, 3], &[0, 1, 2], &[0, 1, 3], &[1, 0, 2], &[1, 0, 3], &[1, 1, 2], &[1, 1, 3], &[0, 2, 0], &[0, 2, 1], &[0, 3, 0], &[0, 3, 1], ], ); bit_distributor_helper( BitDistributor::new(&[BitDistributorOutputType::normal(1); 5]), &[ &[0, 0, 0, 0, 0], &[0, 0, 0, 0, 1], &[0, 0, 0, 1, 0], &[0, 0, 0, 1, 1], &[0, 0, 1, 0, 0], &[0, 0, 1, 0, 1], &[0, 0, 1, 1, 0], &[0, 0, 1, 1, 1], &[0, 1, 0, 0, 0], &[0, 1, 0, 0, 1], &[0, 1, 0, 1, 0], &[0, 1, 0, 1, 1], &[0, 1, 1, 0, 0], &[0, 1, 1, 0, 1], &[0, 1, 1, 1, 0], &[0, 1, 1, 1, 1], &[1, 0, 0, 0, 0], &[1, 0, 0, 0, 1], &[1, 0, 0, 1, 0], &[1, 0, 0, 1, 1], ], ); bit_distributor_helper( BitDistributor::new(&[BitDistributorOutputType::normal(2); 2]), &[ &[0, 0], &[0, 1], &[0, 2], &[0, 3], &[1, 0], &[1, 1], &[1, 2], &[1, 3], &[2, 0], &[2, 1], &[2, 2], &[2, 3], &[3, 0], &[3, 1], &[3, 2], &[3, 3], &[0, 4], &[0, 5], &[0, 6], &[0, 7], ], ); bit_distributor_helper( BitDistributor::new(&[ BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(2), ]), &[ &[0, 0], &[0, 1], &[0, 2], &[0, 3], &[1, 0], &[1, 1], &[1, 2], &[1, 3], &[0, 4], &[0, 5], &[0, 6], &[0, 7], &[1, 4], &[1, 5], &[1, 6], &[1, 7], &[0, 8], &[0, 9], &[0, 10], &[0, 11], ], ); bit_distributor_helper( BitDistributor::new(&[ BitDistributorOutputType::normal(2), BitDistributorOutputType::normal(1), ]), &[ &[0, 0], &[0, 1], &[1, 0], &[1, 1], &[2, 0], &[2, 1], &[3, 0], &[3, 1], &[0, 2], &[0, 3], &[1, 2], &[1, 3], &[2, 2], &[2, 3], &[3, 2], &[3, 3], &[4, 0], &[4, 1], &[5, 0], &[5, 1], ], ); bit_distributor_helper( BitDistributor::new(&[ BitDistributorOutputType::normal(2), BitDistributorOutputType::normal(3), ]), &[ &[0, 0], &[0, 1], &[0, 2], &[0, 3], &[0, 4], &[0, 5], &[0, 6], &[0, 7], &[1, 0], &[1, 1], &[1, 2], &[1, 3], &[1, 4], &[1, 5], &[1, 6], &[1, 7], &[2, 0], &[2, 1], &[2, 2], &[2, 3], ], ); bit_distributor_helper( BitDistributor::new(&[ BitDistributorOutputType::normal(1), BitDistributorOutputType::tiny(), ]), &[ &[0, 0], &[0, 1], &[0, 2], &[0, 3], &[1, 0], &[1, 1], &[1, 2], &[1, 3], &[0, 4], &[0, 5], &[0, 6], &[0, 7], &[1, 4], &[1, 5], &[1, 6], &[1, 7], &[2, 0], &[2, 1], &[2, 2], &[2, 3], ], ); bit_distributor_helper( BitDistributor::new(&[ BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ]), &[ &[0, 0], &[1, 0], &[2, 0], &[3, 0], &[0, 1], &[1, 1], &[2, 1], &[3, 1], &[4, 0], &[5, 0], &[6, 0], &[7, 0], &[4, 1], &[5, 1], &[6, 1], &[7, 1], &[0, 2], &[1, 2], &[2, 2], &[3, 2], ], ); bit_distributor_helper( BitDistributor::new(&[ BitDistributorOutputType::normal(1), BitDistributorOutputType::tiny(), BitDistributorOutputType::tiny(), ]), &[ &[0, 0, 0], &[0, 0, 1], &[0, 1, 0], &[0, 1, 1], &[1, 0, 0], &[1, 0, 1], &[1, 1, 0], &[1, 1, 1], &[0, 0, 2], &[0, 0, 3], &[0, 1, 2], &[0, 1, 3], &[1, 0, 2], &[1, 0, 3], &[1, 1, 2], &[1, 1, 3], &[2, 0, 0], &[2, 0, 1], &[2, 1, 0], &[2, 1, 1], ], ); bit_distributor_helper( BitDistributor::new(&[ BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(1), BitDistributorOutputType::tiny(), BitDistributorOutputType::tiny(), ]), &[ &[0, 0, 0, 0], &[0, 0, 0, 1], &[0, 0, 1, 0], &[0, 0, 1, 1], &[0, 1, 0, 0], &[0, 1, 0, 1], &[0, 1, 1, 0], &[0, 1, 1, 1], &[0, 0, 0, 2], &[0, 0, 0, 3], &[0, 0, 1, 2], &[0, 0, 1, 3], &[0, 1, 0, 2], &[0, 1, 0, 3], &[0, 1, 1, 2], &[0, 1, 1, 3], &[1, 0, 0, 0], &[1, 0, 0, 1], &[1, 0, 1, 0], &[1, 0, 1, 1], ], ); let mut bit_distributor = BitDistributor::new(&[BitDistributorOutputType::normal(1)]); bit_distributor.set_max_bits(&[0], 5); bit_distributor_helper( bit_distributor, &[ &[0], &[1], &[2], &[3], &[4], &[5], &[6], &[7], &[8], &[9], &[10], &[11], &[12], &[13], &[14], &[15], &[16], &[17], &[18], &[19], ], ); let mut bit_distributor = BitDistributor::new(&[BitDistributorOutputType::normal(1); 2]); bit_distributor.set_max_bits(&[1], 2); bit_distributor_helper( bit_distributor, &[ &[0, 0], &[0, 1], &[1, 0], &[1, 1], &[0, 2], &[0, 3], &[1, 2], &[1, 3], &[2, 0], &[2, 1], &[3, 0], &[3, 1], &[2, 2], &[2, 3], &[3, 2], &[3, 3], &[4, 0], &[4, 1], &[5, 0], &[5, 1], ], ); let mut bit_distributor = BitDistributor::new(&[BitDistributorOutputType::normal(1); 2]); bit_distributor.set_max_bits(&[0], 2); bit_distributor_helper( bit_distributor, &[ &[0, 0], &[0, 1], &[1, 0], &[1, 1], &[0, 2], &[0, 3], &[1, 2], &[1, 3], &[2, 0], &[2, 1], &[3, 0], &[3, 1], &[2, 2], &[2, 3], &[3, 2], &[3, 3], &[0, 4], &[0, 5], &[1, 4], &[1, 5], ], ); let mut bit_distributor = BitDistributor::new(&[ BitDistributorOutputType::normal(1), BitDistributorOutputType::tiny(), ]); bit_distributor.set_max_bits(&[0], 2); bit_distributor_helper( bit_distributor, &[ &[0, 0], &[0, 1], &[0, 2], &[0, 3], &[1, 0], &[1, 1], &[1, 2], &[1, 3], &[0, 4], &[0, 5], &[0, 6], &[0, 7], &[1, 4], &[1, 5], &[1, 6], &[1, 7], &[2, 0], &[2, 1], &[2, 2], &[2, 3], ], ); let mut bit_distributor = BitDistributor::new(&[ BitDistributorOutputType::normal(1), BitDistributorOutputType::tiny(), ]); bit_distributor.set_max_bits(&[1], 2); bit_distributor_helper( bit_distributor, &[ &[0, 0], &[0, 1], &[0, 2], &[0, 3], &[1, 0], &[1, 1], &[1, 2], &[1, 3], &[2, 0], &[2, 1], &[2, 2], &[2, 3], &[3, 0], &[3, 1], &[3, 2], &[3, 3], &[4, 0], &[4, 1], &[4, 2], &[4, 3], ], ); let mut bit_distributor = BitDistributor::new(&[BitDistributorOutputType::normal(1); 5]); bit_distributor.set_max_bits(&[0], 2); bit_distributor.set_max_bits(&[1], 1); bit_distributor.set_max_bits(&[2], 5); bit_distributor.set_max_bits(&[3], 3); bit_distributor.set_max_bits(&[4], 4); bit_distributor_helper( bit_distributor, &[ &[0, 0, 0, 0, 0], &[0, 0, 0, 0, 1], &[0, 0, 0, 1, 0], &[0, 0, 0, 1, 1], &[0, 0, 1, 0, 0], &[0, 0, 1, 0, 1], &[0, 0, 1, 1, 0], &[0, 0, 1, 1, 1], &[0, 1, 0, 0, 0], &[0, 1, 0, 0, 1], &[0, 1, 0, 1, 0], &[0, 1, 0, 1, 1], &[0, 1, 1, 0, 0], &[0, 1, 1, 0, 1], &[0, 1, 1, 1, 0], &[0, 1, 1, 1, 1], &[1, 0, 0, 0, 0], &[1, 0, 0, 0, 1], &[1, 0, 0, 1, 0], &[1, 0, 0, 1, 1], ], ); let mut bit_distributor = BitDistributor::new(&[BitDistributorOutputType::normal(2); 2]); bit_distributor.set_max_bits(&[0], 5); bit_distributor_helper( bit_distributor, &[ &[0, 0], &[0, 1], &[0, 2], &[0, 3], &[1, 0], &[1, 1], &[1, 2], &[1, 3], &[2, 0], &[2, 1], &[2, 2], &[2, 3], &[3, 0], &[3, 1], &[3, 2], &[3, 3], &[0, 4], &[0, 5], &[0, 6], &[0, 7], ], ); let mut bit_distributor = BitDistributor::new(&[ BitDistributorOutputType::normal(1), BitDistributorOutputType::tiny(), BitDistributorOutputType::tiny(), ]); bit_distributor.set_max_bits(&[0], 5); bit_distributor_helper( bit_distributor, &[ &[0, 0, 0], &[0, 0, 1], &[0, 1, 0], &[0, 1, 1], &[1, 0, 0], &[1, 0, 1], &[1, 1, 0], &[1, 1, 1], &[0, 0, 2], &[0, 0, 3], &[0, 1, 2], &[0, 1, 3], &[1, 0, 2], &[1, 0, 3], &[1, 1, 2], &[1, 1, 3], &[2, 0, 0], &[2, 0, 1], &[2, 1, 0], &[2, 1, 1], ], ); } #[test] #[should_panic] fn get_output_fail() { let bd = BitDistributor::new(&[BitDistributorOutputType::normal(2); 3]); bd.get_output(4); } malachite-base-0.4.16/tests/iterators/bit_distributor/increment_counter.rs000064400000000000000000000015101046102023000252270ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::iterators::bit_distributor::{BitDistributor, BitDistributorOutputType}; #[test] fn test_increment_counter() { let mut bd = BitDistributor::new(&[BitDistributorOutputType::normal(1)]); let mut outputs = Vec::new(); for _ in 0..20 { outputs.push(bd.get_output(0)); bd.increment_counter(); } assert_eq!( outputs, &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] ); } malachite-base-0.4.16/tests/iterators/bit_distributor/new.rs000064400000000000000000000014151046102023000223010ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::iterators::bit_distributor::{BitDistributor, BitDistributorOutputType}; #[test] fn test_bit_distributor() { BitDistributor::new(&[BitDistributorOutputType::normal(1)]); } #[test] #[should_panic] fn bit_distributor_fail_1() { BitDistributor::new(&[]); } #[test] #[should_panic] fn bit_distributor_fail_2() { BitDistributor::new(&[BitDistributorOutputType::tiny(); 2]); } malachite-base-0.4.16/tests/iterators/bit_distributor/set_max_bits.rs000064400000000000000000000030341046102023000241700ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::iterators::bit_distributor::{BitDistributor, BitDistributorOutputType}; #[test] fn test_set_max_bits() { let mut bd = BitDistributor::new(&[BitDistributorOutputType::normal(2); 3]); assert_eq!( bd.bit_map_as_slice(), &[ 2, 2, 1, 1, 0, 0, 2, 2, 1, 1, 0, 0, 2, 2, 1, 1, 0, 0, 2, 2, 1, 1, 0, 0, 2, 2, 1, 1, 0, 0, 2, 2, 1, 1, 0, 0, 2, 2, 1, 1, 0, 0, 2, 2, 1, 1, 0, 0, 2, 2, 1, 1, 0, 0, 2, 2, 1, 1, 0, 0, 2, 2, 1, 1 ][..] ); bd.set_max_bits(&[0, 2], 5); assert_eq!( bd.bit_map_as_slice(), &[ 2, 2, 1, 1, 0, 0, 2, 2, 1, 1, 0, 0, 2, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ][..] ); } #[test] #[should_panic] fn set_max_bits_fail_1() { let mut bd = BitDistributor::new(&[BitDistributorOutputType::normal(2); 3]); bd.set_max_bits(&[0], 0); } #[test] #[should_panic] fn set_max_bits_fail_2() { let mut bd = BitDistributor::new(&[BitDistributorOutputType::normal(2); 3]); bd.set_max_bits(&[0, 3], 2); } malachite-base-0.4.16/tests/iterators/comparison/delta_directions.rs000064400000000000000000000026501046102023000237700ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::iterators::comparison::delta_directions; use std::cmp::Ordering::{self, *}; fn delta_directions_helper(xs: &[u8], result: &[Ordering]) { assert_eq!(delta_directions(xs.iter()).collect_vec(), result); assert_eq!(result.len(), xs.len().saturating_sub(1)); assert_eq!( delta_directions(xs.iter().rev()) .map(Ordering::reverse) .collect_vec(), result.iter().copied().rev().collect_vec() ); } #[test] fn test_delta_directions() { delta_directions_helper(&[], &[]); delta_directions_helper(&[5], &[]); delta_directions_helper(&[5, 6], &[Greater]); delta_directions_helper(&[5, 5], &[Equal]); delta_directions_helper(&[5, 4], &[Less]); delta_directions_helper(&[1, 2, 3, 4], &[Greater; 3]); delta_directions_helper(&[1, 2, 2, 4], &[Greater, Equal, Greater]); delta_directions_helper(&[1, 3, 2, 4], &[Greater, Less, Greater]); delta_directions_helper( &[3, 1, 4, 1, 5, 9], &[Less, Greater, Less, Greater, Greater], ); } malachite-base-0.4.16/tests/iterators/comparison/is_strictly_ascending.rs000064400000000000000000000026301046102023000250350ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::iterators::comparison::{ is_strictly_ascending, is_strictly_descending, is_weakly_ascending, is_weakly_descending, }; fn is_strictly_ascending_helper(xs: &[u8], result: bool) { assert_eq!(is_strictly_ascending(xs.iter()), result); assert_eq!(is_strictly_descending(xs.iter().rev()), result); if xs.len() < 2 { assert!(result); } if result { assert!(is_weakly_ascending(xs.iter())); if xs.len() > 1 { assert!(!is_weakly_descending(xs.iter())); } } } #[test] fn test_is_strictly_ascending() { is_strictly_ascending_helper(&[], true); is_strictly_ascending_helper(&[5], true); is_strictly_ascending_helper(&[5, 6], true); is_strictly_ascending_helper(&[5, 5], false); is_strictly_ascending_helper(&[5, 4], false); is_strictly_ascending_helper(&[1, 2, 3, 4], true); is_strictly_ascending_helper(&[1, 2, 2, 4], false); is_strictly_ascending_helper(&[1, 3, 2, 4], false); is_strictly_ascending_helper(&[3, 1, 4, 1, 5, 9], false); } malachite-base-0.4.16/tests/iterators/comparison/is_strictly_descending.rs000064400000000000000000000026431046102023000252110ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::iterators::comparison::{ is_strictly_ascending, is_strictly_descending, is_weakly_ascending, is_weakly_descending, }; fn is_strictly_descending_helper(xs: &[u8], result: bool) { assert_eq!(is_strictly_descending(xs.iter()), result); assert_eq!(is_strictly_ascending(xs.iter().rev()), result); if xs.len() < 2 { assert!(result); } if result { assert!(is_weakly_descending(xs.iter())); if xs.len() > 1 { assert!(!is_weakly_ascending(xs.iter())); } } } #[test] fn test_is_strictly_descending() { is_strictly_descending_helper(&[], true); is_strictly_descending_helper(&[5], true); is_strictly_descending_helper(&[6, 5], true); is_strictly_descending_helper(&[6, 6], false); is_strictly_descending_helper(&[6, 7], false); is_strictly_descending_helper(&[4, 3, 2, 1], true); is_strictly_descending_helper(&[4, 2, 2, 1], false); is_strictly_descending_helper(&[4, 2, 3, 1], false); is_strictly_descending_helper(&[3, 1, 4, 1, 5, 9], false); } malachite-base-0.4.16/tests/iterators/comparison/is_strictly_zigzagging.rs000064400000000000000000000027311046102023000252440ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::iterators::comparison::{ is_strictly_zigzagging, is_weakly_ascending, is_weakly_descending, is_weakly_zigzagging, }; fn is_strictly_zigzagging_helper(xs: &[u8], result: bool) { assert_eq!(is_strictly_zigzagging(xs.iter()), result); assert_eq!(is_strictly_zigzagging(xs.iter().rev()), result); if xs.len() < 2 { assert!(result); } if result { assert!(is_weakly_zigzagging(xs.iter())); if xs.len() > 2 { assert!(!is_weakly_ascending(xs.iter())); assert!(!is_weakly_descending(xs.iter())); } } } #[test] fn test_is_strictly_zigzagging() { is_strictly_zigzagging_helper(&[], true); is_strictly_zigzagging_helper(&[5], true); is_strictly_zigzagging_helper(&[5, 6], true); is_strictly_zigzagging_helper(&[5, 5], false); is_strictly_zigzagging_helper(&[5, 4], true); is_strictly_zigzagging_helper(&[1, 2, 3, 4], false); is_strictly_zigzagging_helper(&[1, 2, 2, 4], false); is_strictly_zigzagging_helper(&[1, 3, 2, 4], true); is_strictly_zigzagging_helper(&[3, 1, 4, 1, 5, 9], false); } malachite-base-0.4.16/tests/iterators/comparison/is_weakly_ascending.rs000064400000000000000000000024151046102023000244550ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::iterators::comparison::{ is_strictly_ascending, is_weakly_ascending, is_weakly_descending, }; fn is_weakly_ascending_helper(xs: &[u8], result: bool) { assert_eq!(is_weakly_ascending(xs.iter()), result); assert_eq!(is_weakly_descending(xs.iter().rev()), result); if xs.len() < 2 { assert!(result); } if !result { assert!(!is_strictly_ascending(xs.iter())); } } #[test] fn test_is_weakly_ascending() { is_weakly_ascending_helper(&[], true); is_weakly_ascending_helper(&[5], true); is_weakly_ascending_helper(&[5, 6], true); is_weakly_ascending_helper(&[5, 5], true); is_weakly_ascending_helper(&[5, 4], false); is_weakly_ascending_helper(&[1, 2, 3, 4], true); is_weakly_ascending_helper(&[1, 2, 2, 4], true); is_weakly_ascending_helper(&[1, 3, 2, 4], false); is_weakly_ascending_helper(&[3, 1, 4, 1, 5, 9], false); } malachite-base-0.4.16/tests/iterators/comparison/is_weakly_descending.rs000064400000000000000000000024321046102023000246240ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::iterators::comparison::{ is_strictly_descending, is_weakly_ascending, is_weakly_descending, }; fn is_weakly_descending_helper(xs: &[u8], result: bool) { assert_eq!(is_weakly_descending(xs.iter()), result); assert_eq!(is_weakly_ascending(xs.iter().rev()), result); if xs.len() < 2 { assert!(result); } if !result { assert!(!is_strictly_descending(xs.iter())); } } #[test] fn test_is_weakly_descending() { is_weakly_descending_helper(&[], true); is_weakly_descending_helper(&[5], true); is_weakly_descending_helper(&[6, 5], true); is_weakly_descending_helper(&[6, 6], true); is_weakly_descending_helper(&[6, 7], false); is_weakly_descending_helper(&[4, 3, 2, 1], true); is_weakly_descending_helper(&[4, 2, 2, 1], true); is_weakly_descending_helper(&[4, 2, 3, 1], false); is_weakly_descending_helper(&[3, 1, 4, 1, 5, 9], false); } malachite-base-0.4.16/tests/iterators/comparison/is_weakly_zigzagging.rs000064400000000000000000000023761046102023000246700ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::iterators::comparison::{is_strictly_zigzagging, is_weakly_zigzagging}; fn is_weakly_zigzagging_helper(xs: &[u8], result: bool) { assert_eq!(is_weakly_zigzagging(xs.iter()), result); assert_eq!(is_weakly_zigzagging(xs.iter().rev()), result); if xs.len() < 3 { assert!(result); } if !result { assert!(!is_strictly_zigzagging(xs.iter())); } } #[test] fn test_is_weakly_zigzagging() { is_weakly_zigzagging_helper(&[], true); is_weakly_zigzagging_helper(&[5], true); is_weakly_zigzagging_helper(&[5, 6], true); is_weakly_zigzagging_helper(&[5, 5], true); is_weakly_zigzagging_helper(&[5, 4], true); is_weakly_zigzagging_helper(&[1, 2, 3, 4], false); is_weakly_zigzagging_helper(&[1, 2, 2, 4], true); is_weakly_zigzagging_helper(&[1, 3, 2, 4], true); is_weakly_zigzagging_helper(&[3, 1, 4, 1, 5, 9], false); } malachite-base-0.4.16/tests/iterators/count_is_at_least.rs000064400000000000000000000022261046102023000220000ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::iterators::count_is_at_least; use std::iter::repeat; fn count_is_at_least_helper(xs: &[u8], n: usize, result: bool) { assert_eq!(count_is_at_least(xs.iter(), n), result); assert_eq!(count_is_at_least(xs.iter().rev(), n), result); } #[test] fn test_count_is_at_least() { count_is_at_least_helper(&[], 0, true); count_is_at_least_helper(&[], 1, false); count_is_at_least_helper(&[5], 0, true); count_is_at_least_helper(&[5], 1, true); count_is_at_least_helper(&[5], 2, false); count_is_at_least_helper(&[1, 2, 3, 4], 4, true); count_is_at_least_helper(&[1, 2, 3, 4], 5, false); count_is_at_least_helper(&[4; 100], 90, true); count_is_at_least_helper(&[4; 100], 101, false); assert_eq!(count_is_at_least(repeat(10), 20), true); } malachite-base-0.4.16/tests/iterators/count_is_at_most.rs000064400000000000000000000022741046102023000216550ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::iterators::count_is_at_most; use std::iter::repeat; fn count_is_at_most_helper(xs: &[u8], n: usize, result: bool) { assert_eq!(count_is_at_most(xs.iter(), n), result); assert_eq!(count_is_at_most(xs.iter().rev(), n), result); } #[test] fn test_count_is_at_most() { count_is_at_most_helper(&[], 0, true); count_is_at_most_helper(&[], 1, true); count_is_at_most_helper(&[5], 0, false); count_is_at_most_helper(&[5], 1, true); count_is_at_most_helper(&[5], 2, true); count_is_at_most_helper(&[1, 2, 3, 4], 3, false); count_is_at_most_helper(&[1, 2, 3, 4], 4, true); count_is_at_most_helper(&[1, 2, 3, 4], 5, true); count_is_at_most_helper(&[4; 100], 120, true); count_is_at_most_helper(&[4; 100], 90, false); assert_eq!(count_is_at_most(repeat(10), 20), false); } malachite-base-0.4.16/tests/iterators/first_and_last.rs000064400000000000000000000013611046102023000212740ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::iterators::first_and_last; fn first_and_last_helper(xs: &[u8], result: Option<(u8, u8)>) { assert_eq!(first_and_last(&mut xs.iter().copied()), result); } #[test] fn test_first_and_last() { first_and_last_helper(&[1, 2, 10, 11, 12, 7, 8, 16, 5], Some((1, 5))); first_and_last_helper(&[5], Some((5, 5))); first_and_last_helper(&[], None); } malachite-base-0.4.16/tests/iterators/is_constant.rs000064400000000000000000000024051046102023000206240ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::iterators::comparison::{is_weakly_ascending, is_weakly_descending}; use malachite_base::iterators::is_constant; fn is_constant_helper(xs: &[u8], result: bool) { assert_eq!(is_constant(xs.iter()), result); assert_eq!(is_constant(xs.iter().rev()), result); assert_eq!( is_weakly_ascending(xs.iter()) && is_weakly_descending(xs.iter()), result ); if xs.len() < 2 { assert!(result); } } #[test] fn test_is_constant() { is_constant_helper(&[], true); is_constant_helper(&[5], true); is_constant_helper(&[5, 6], false); is_constant_helper(&[5, 5], true); is_constant_helper(&[5, 4], false); is_constant_helper(&[1; 4], true); is_constant_helper(&[1, 2, 3, 4], false); is_constant_helper(&[1, 2, 2, 4], false); is_constant_helper(&[4; 100], true); assert_eq!(is_constant([1, 2].iter().cycle()), false); } malachite-base-0.4.16/tests/iterators/is_unique.rs000064400000000000000000000017571046102023000203120ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::iterators::is_unique; fn is_unique_helper(xs: &[u8], result: bool) { assert_eq!(is_unique(xs.iter()), result); assert_eq!(is_unique(xs.iter().rev()), result); } #[test] fn test_is_unique() { is_unique_helper(&[], true); is_unique_helper(&[5], true); is_unique_helper(&[5, 6], true); is_unique_helper(&[5, 5], false); is_unique_helper(&[5, 4], true); is_unique_helper(&[1, 2, 3, 4], true); is_unique_helper(&[1, 2, 2, 4], false); is_unique_helper(&[1, 2, 3, 1], false); is_unique_helper(&[4; 100], false); assert_eq!(is_unique([1, 2].iter().cycle()), false); } malachite-base-0.4.16/tests/iterators/iter_windows.rs000064400000000000000000000026171046102023000210220ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::iterators::iter_windows; use std::fmt::Debug; fn iter_windows_helper(size: usize, xs: I, out: &[&[I::Item]]) where I::Item: Clone + Debug + Eq, { let windows = iter_windows(size, xs) .map(|ws| ws.iter().cloned().collect_vec()) .collect_vec(); assert_eq!( windows.iter().map(Vec::as_slice).collect_vec().as_slice(), out ); } #[test] fn test_iter_windows() { iter_windows_helper(1, 0..=5, &[&[0], &[1], &[2], &[3], &[4], &[5]]); iter_windows_helper(2, 0..=5, &[&[0, 1], &[1, 2], &[2, 3], &[3, 4], &[4, 5]]); iter_windows_helper(3, 0..=5, &[&[0, 1, 2], &[1, 2, 3], &[2, 3, 4], &[3, 4, 5]]); iter_windows_helper(4, 0..=5, &[&[0, 1, 2, 3], &[1, 2, 3, 4], &[2, 3, 4, 5]]); iter_windows_helper(5, 0..=5, &[&[0, 1, 2, 3, 4], &[1, 2, 3, 4, 5]]); iter_windows_helper(6, 0..=5, &[&[0, 1, 2, 3, 4, 5]]); iter_windows_helper(7, 0..=5, &[]); } #[test] #[should_panic] fn iter_windows_fail() { iter_windows(0, 0..10); } malachite-base-0.4.16/tests/iterators/iterator_cache.rs000064400000000000000000000034131046102023000212540ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::__std_iter::empty; use malachite_base::iterators::iterator_cache::IteratorCache; use malachite_base::nevers::Never; use malachite_base::num::exhaustive::exhaustive_signeds; #[test] fn test_iterator_cache() { let mut xs = IteratorCache::new(empty::()); assert_eq!(xs.known_len(), None); assert_eq!(xs.get(1), None); assert_eq!(xs.known_len(), Some(0)); assert_eq!(xs.get(0), None); let mut xs = IteratorCache::new([1, 2, 3].iter().copied()); assert_eq!(xs.known_len(), None); assert_eq!(xs.get(1), Some(&2)); assert_eq!(xs.assert_get(1), &2); assert_eq!(xs.known_len(), None); assert_eq!(xs.get(0), Some(&1)); assert_eq!(xs.assert_get(0), &1); assert_eq!(xs.get(3), None); assert_eq!(xs.known_len(), Some(3)); assert_eq!(xs.get(2), Some(&3)); assert_eq!(xs.assert_get(2), &3); let mut xs = IteratorCache::new(exhaustive_signeds::()); assert_eq!(xs.get(1), Some(&1)); assert_eq!(xs.assert_get(1), &1); assert_eq!(xs.known_len(), None); assert_eq!(xs.get(0), Some(&0)); assert_eq!(xs.assert_get(0), &0); assert_eq!(xs.get(3), Some(&2)); assert_eq!(xs.assert_get(3), &2); assert_eq!(xs.get(100), Some(&-50)); assert_eq!(xs.assert_get(100), &-50); assert_eq!(xs.known_len(), None); } #[test] #[should_panic] fn iterator_cache_fail() { IteratorCache::new(empty::()).assert_get(0); } malachite-base-0.4.16/tests/iterators/matching_intervals_in_iterator.rs000064400000000000000000000020521046102023000245560ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::iterators::matching_intervals_in_iterator; fn matching_intervals_in_iterator_helper bool>(xs: &[u8], f: F, result: &[(u8, u8)]) { assert_eq!( matching_intervals_in_iterator(xs.iter().copied(), f).as_slice(), result ); } #[test] fn test_matching_intervals_in_iterator() { let xs = &[1, 2, 10, 11, 12, 7, 8, 16, 5]; matching_intervals_in_iterator_helper(xs, |&x| x >= 10, &[(10, 12), (16, 16)]); matching_intervals_in_iterator_helper(xs, |&x| x < 10, &[(1, 2), (7, 8), (5, 5)]); matching_intervals_in_iterator_helper(xs, |&x| x >= 100, &[]); matching_intervals_in_iterator_helper(xs, |&x| x < 100, &[(1, 5)]); } malachite-base-0.4.16/tests/iterators/nonzero_values.rs000064400000000000000000000013751046102023000213560ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::iterators::nonzero_values; #[test] pub fn test_nonzero_values() { let test = |xs: &[u32], out: &[u32]| { assert_eq!(nonzero_values(xs.iter().copied()).collect_vec(), out); }; test(&[], &[]); test(&[1, 2, 3], &[1, 2, 3]); test(&[1, 0, 3], &[1, 3]); test(&[1, 2, 0, 0, 0], &[1, 2]); test(&[0, 0, 0], &[]); } malachite-base-0.4.16/tests/iterators/prefix_to_string.rs000064400000000000000000000016451046102023000216720ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::iterators::prefix_to_string; #[test] fn test_prefix_to_string() { let test = |xs: &[u32], max_len: usize, out: &str| { assert_eq!(prefix_to_string(xs.iter(), max_len), out); }; test(&[], 1, "[]"); test(&[1, 2, 3, 4], 1, "[1, ...]"); test(&[1, 2, 3, 4], 2, "[1, 2, ...]"); test(&[1, 2, 3, 4], 3, "[1, 2, 3, ...]"); test(&[1, 2, 3, 4], 4, "[1, 2, 3, 4]"); test(&[1, 2, 3, 4], 10, "[1, 2, 3, 4]"); } #[test] #[should_panic] fn prefix_to_string_fail() { prefix_to_string([1, 2, 3].iter(), 0); } malachite-base-0.4.16/tests/iterators/thue_morse_sequence.rs000064400000000000000000000033341046102023000223440ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::iterators::thue_morse_sequence; #[test] pub fn test_thue_morse_sequence() { let s: String = thue_morse_sequence() .take(1000) .map(|b| if b { '1' } else { '0' }) .collect(); assert_eq!( s, "01101001100101101001011001101001100101100110100101101001100101101001011001101001011010011\ 001011001101001100101101001011001101001100101100110100101101001100101100110100110010110100\ 101100110100101101001100101101001011001101001100101100110100101101001100101101001011001101\ 001011010011001011001101001100101101001011001101001011010011001011010010110011010011001011\ 001101001011010011001011001101001100101101001011001101001100101100110100101101001100101101\ 001011001101001011010011001011001101001100101101001011001101001100101100110100101101001100\ 101100110100110010110100101100110100101101001100101101001011001101001100101100110100101101\ 001100101100110100110010110100101100110100110010110011010010110100110010110100101100110100\ 101101001100101100110100110010110100101100110100101101001100101101001011001101001100101100\ 110100101101001100101101001011001101001011010011001011001101001100101101001011001101001100\ 101100110100101101001100101100110100110010110100101100110100101101001100101101001011001101\ 00110010110" ); } malachite-base-0.4.16/tests/iterators/with_special_value.rs000064400000000000000000000105661046102023000221560ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use core::hash::Hash; use itertools::Itertools; use malachite_base::iterators::with_special_value; use malachite_base::num::random::random_primitive_ints; use malachite_base::options::random::random_options; use malachite_base::random::{Seed, EXAMPLE_SEED}; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; use std::fmt::Debug; fn with_special_value_helper( special_value: I::Item, p_special_numerator: u64, p_special_denominator: u64, xs_gen: &dyn Fn(Seed) -> I, expected_values: &[I::Item], expected_common_values: &[(I::Item, usize)], expected_median: (I::Item, Option), ) where I::Item: Clone + Debug + Eq + Hash + Ord, { let xs = with_special_value( EXAMPLE_SEED, special_value, p_special_numerator, p_special_denominator, xs_gen, ); let values = xs.clone().take(20).collect_vec(); let common_values = common_values_map_debug(1000000, 10, xs.clone()); let median = median(xs.take(1000000)); assert_eq!( (values.as_slice(), common_values.as_slice(), median), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_with_special_value() { // special_value = 0, p = 1/2 with_special_value_helper( 0, 1, 2, &random_primitive_ints::, &[0, 0, 0, 85, 0, 11, 0, 0, 0, 136, 200, 235, 0, 0, 134, 0, 0, 0, 0, 0], &[ (0, 501536), (81, 2080), (208, 2071), (35, 2070), (211, 2051), (112, 2043), (162, 2043), (143, 2041), (220, 2040), (73, 2038), ], (0, None), ); // special_value = 0, p = 50/51 with_special_value_helper( 0, 50, 51, &random_primitive_ints::, &[0; 20], &[ (0, 980537), (18, 101), (25, 99), (116, 97), (226, 97), (237, 97), (23, 95), (185, 95), (30, 94), (73, 94), ], (0, None), ); // p = special_value = 0, 1/51 with_special_value_helper( 0, 1, 51, &random_primitive_ints::, &[ 85, 11, 136, 200, 235, 134, 203, 223, 38, 235, 217, 177, 162, 32, 166, 234, 30, 218, 90, 106, ], &[ (0, 23543), (58, 4029), (81, 4001), (194, 3979), (66, 3971), (64, 3969), (143, 3965), (4, 3962), (196, 3951), (208, 3939), ], (125, None), ); // special_value = 0, p = 1/11 with_special_value_helper( Some(0), 1, 11, &|seed| random_options(seed, 1, 11, &random_primitive_ints::), &[ Some(229), Some(58), Some(126), Some(0), Some(192), Some(140), Some(235), Some(50), Some(162), Some(5), Some(14), Some(107), Some(218), Some(0), Some(96), Some(86), Some(51), Some(240), Some(0), Some(186), ], &[ (Some(0), 94315), (None, 82945), (Some(186), 3381), (Some(193), 3376), (Some(55), 3364), (Some(83), 3364), (Some(245), 3360), (Some(148), 3352), (Some(143), 3345), (Some(136), 3339), ], (Some(101), None), ); } #[test] #[should_panic] fn with_special_value_fail_1() { with_special_value(EXAMPLE_SEED, 0, 1, 0, &random_primitive_ints::); } #[test] #[should_panic] fn with_special_value_fail_2() { with_special_value(EXAMPLE_SEED, 0, 2, 1, &random_primitive_ints::); } malachite-base-0.4.16/tests/iterators/with_special_values.rs000064400000000000000000000113071046102023000223330ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use core::hash::Hash; use itertools::Itertools; use malachite_base::iterators::with_special_values; use malachite_base::num::random::random_primitive_ints; use malachite_base::options::random::random_options; use malachite_base::random::{Seed, EXAMPLE_SEED}; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; use std::fmt::Debug; fn with_special_values_helper( special_values: &[I::Item], p_special_numerator: u64, p_special_denominator: u64, xs_gen: &dyn Fn(Seed) -> I, expected_values: &[I::Item], expected_common_values: &[(I::Item, usize)], expected_median: (I::Item, Option), ) where I::Item: Clone + Debug + Eq + Hash + Ord, { let xs = with_special_values( EXAMPLE_SEED, special_values.to_vec(), p_special_numerator, p_special_denominator, xs_gen, ); let values = xs.clone().take(20).collect_vec(); let common_values = common_values_map_debug(1000000, 10, xs.clone()); let median = median(xs.take(1000000)); assert_eq!( (values.as_slice(), common_values.as_slice(), median), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_with_special_values() { // special_values = &[0, 1, 2], p = 1/2 with_special_values_helper( &[0, 1, 2], 1, 2, &random_primitive_ints::, &[2, 0, 2, 85, 0, 11, 1, 2, 0, 136, 200, 235, 0, 0, 134, 2, 0, 0, 0, 0], &[ (2, 168816), (0, 168721), (1, 167914), (81, 2080), (208, 2071), (35, 2070), (211, 2051), (112, 2043), (162, 2043), (143, 2041), ], (2, None), ); // special_values = &[0, 1], p = 50/51 with_special_values_helper( &[0, 1], 50, 51, &random_primitive_ints::, &[0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0], &[ (1, 490697), (0, 489910), (18, 101), (25, 99), (116, 97), (226, 97), (237, 97), (23, 95), (185, 95), (30, 94), ], (1, None), ); // p = special_values = &[0, 1, 2, 3], 1/51 with_special_values_helper( &[0, 1, 2, 3], 1, 51, &random_primitive_ints::, &[ 85, 11, 136, 200, 235, 134, 203, 223, 38, 235, 217, 177, 162, 32, 166, 234, 30, 218, 90, 106, ], &[ (2, 8933), (0, 8779), (1, 8736), (3, 8736), (58, 4029), (81, 4001), (194, 3979), (66, 3971), (64, 3969), (143, 3965), ], (125, None), ); // special_values = &[None, Some(0), Some(1)], p = 1/11 with_special_values_helper( &[None, Some(0), Some(1)], 1, 11, &|seed| random_options(seed, 1, 11, &random_primitive_ints::), &[ Some(229), Some(58), Some(126), Some(1), Some(192), Some(140), Some(235), Some(50), Some(162), Some(5), Some(14), Some(107), Some(218), None, Some(96), Some(86), Some(51), Some(240), Some(1), Some(186), ], &[ (None, 113578), (Some(1), 33583), (Some(0), 33308), (Some(186), 3381), (Some(193), 3376), (Some(55), 3364), (Some(83), 3364), (Some(245), 3360), (Some(148), 3352), (Some(143), 3345), ], (Some(101), None), ); } #[test] #[should_panic] fn with_special_values_fail_1() { with_special_values(EXAMPLE_SEED, vec![0, 1], 1, 0, &random_primitive_ints::); } #[test] #[should_panic] fn with_special_values_fail_2() { with_special_values(EXAMPLE_SEED, vec![0, 1], 2, 1, &random_primitive_ints::); } #[test] #[should_panic] fn with_special_values_fail_3() { with_special_values(EXAMPLE_SEED, vec![], 1, 2, &random_primitive_ints::); } malachite-base-0.4.16/tests/lib.rs000064400000000000000000000670161046102023000150430ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . #![warn( clippy::cast_lossless, clippy::explicit_into_iter_loop, clippy::explicit_iter_loop, clippy::filter_map_next, clippy::large_digit_groups, clippy::manual_filter_map, clippy::manual_find_map, clippy::map_flatten, clippy::map_unwrap_or, clippy::match_same_arms, clippy::missing_const_for_fn, clippy::mut_mut, clippy::needless_borrow, clippy::needless_continue, clippy::needless_pass_by_value, clippy::print_stdout, clippy::redundant_closure_for_method_calls, clippy::single_match_else, clippy::trait_duplication_in_bounds, clippy::type_repetition_in_bounds, clippy::uninlined_format_args, clippy::unused_self, clippy::if_not_else, clippy::manual_assert, clippy::range_plus_one, clippy::redundant_else, clippy::semicolon_if_nothing_returned, clippy::cloned_instead_of_copied, clippy::flat_map_option, clippy::unnecessary_wraps, clippy::unnested_or_patterns, clippy::trivially_copy_pass_by_ref )] #![allow( clippy::assertions_on_constants, // Compile-time asserts still useful clippy::bool_assert_comparison, // Often clearer than using ! clippy::cognitive_complexity, clippy::excessive_precision, clippy::float_cmp, clippy::too_many_arguments, clippy::upper_case_acronyms, unstable_name_collisions )] extern crate core; extern crate itertools; #[macro_use] extern crate malachite_base; #[macro_use] extern crate maplit; extern crate rand; extern crate rand_chacha; use malachite_base::iterators::bit_distributor::BitDistributorOutputType; fn get_sample_output_types(len: usize) -> Vec> { if len == 2 { vec![ vec![BitDistributorOutputType::normal(1); 2], vec![BitDistributorOutputType::normal(2); 2], vec![BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(2)], vec![BitDistributorOutputType::normal(1), BitDistributorOutputType::tiny()], ] } else if len == 3 { vec![ vec![BitDistributorOutputType::normal(1); 3], vec![BitDistributorOutputType::normal(2); 3], vec![ BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(2), BitDistributorOutputType::normal(3), ], vec![ BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(1), ], vec![ BitDistributorOutputType::normal(1), BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ], vec![ BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(1), BitDistributorOutputType::tiny(), ], vec![ BitDistributorOutputType::normal(1), BitDistributorOutputType::tiny(), BitDistributorOutputType::tiny(), ], vec![ BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), BitDistributorOutputType::tiny(), ], vec![ BitDistributorOutputType::tiny(), BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ], ] } else { panic!() } } pub mod bools { pub mod constants; pub mod exhaustive; pub mod not_assign; pub mod random { pub mod get_weighted_random_bool; pub mod random_bools; pub mod weighted_random_bools; } } pub mod comparison { pub mod macros; } pub mod chars { pub mod char_type; pub mod constants; pub mod crement { pub mod char_to_contiguous_range; pub mod contiguous_range_to_char; #[allow(clippy::module_inception)] pub mod crement; } pub mod exhaustive { pub mod ascii_chars_increasing; pub mod chars_increasing; pub mod exhaustive_ascii_chars; pub mod exhaustive_chars; } pub mod is_graphic; pub mod random { pub mod graphic_weighted_random_ascii_chars; pub mod graphic_weighted_random_char_inclusive_range; pub mod graphic_weighted_random_char_range; pub mod graphic_weighted_random_chars; pub mod random_ascii_chars; pub mod random_char_inclusive_range; pub mod random_char_range; pub mod random_chars; } } pub mod extra_variadic; pub mod iterators { pub mod bit_distributor { pub mod bit_map_as_slice; pub mod get_output; pub mod increment_counter; pub mod new; pub mod set_max_bits; } pub mod comparison { pub mod delta_directions; pub mod is_strictly_ascending; pub mod is_strictly_descending; pub mod is_strictly_zigzagging; pub mod is_weakly_ascending; pub mod is_weakly_descending; pub mod is_weakly_zigzagging; } pub mod count_is_at_least; pub mod count_is_at_most; pub mod first_and_last; pub mod is_constant; pub mod is_unique; pub mod iter_windows; pub mod iterator_cache; pub mod matching_intervals_in_iterator; pub mod nonzero_values; pub mod prefix_to_string; pub mod thue_morse_sequence; pub mod with_special_value; pub mod with_special_values; } pub mod named; pub mod nevers { #[allow(clippy::module_inception)] pub mod nevers; } pub mod num { pub mod arithmetic { pub mod abs; pub mod abs_diff; pub mod add_mul; pub mod arithmetic_checked_shl; pub mod arithmetic_checked_shr; pub mod binomial_coefficient; pub mod ceiling; pub mod checked_abs; pub mod checked_add_mul; pub mod checked_neg; pub mod checked_pow; pub mod checked_square; pub mod checked_sub_mul; pub mod coprime_with; pub mod div_exact; pub mod div_mod; pub mod div_round; pub mod divisible_by; pub mod divisible_by_power_of_2; pub mod eq_mod; pub mod eq_mod_power_of_2; pub mod extended_gcd; pub mod factorial; pub mod floor; pub mod gcd; pub mod is_power_of_2; pub mod kronecker_symbol; pub mod lcm; pub mod log_base; pub mod log_base_2; pub mod log_base_power_of_2; pub mod mod_add; pub mod mod_inverse; pub mod mod_is_reduced; pub mod mod_mul; pub mod mod_neg; pub mod mod_op; pub mod mod_pow; pub mod mod_power_of_2; pub mod mod_power_of_2_add; pub mod mod_power_of_2_inverse; pub mod mod_power_of_2_is_reduced; pub mod mod_power_of_2_mul; pub mod mod_power_of_2_neg; pub mod mod_power_of_2_pow; pub mod mod_power_of_2_shl; pub mod mod_power_of_2_shr; pub mod mod_power_of_2_square; pub mod mod_power_of_2_sub; pub mod mod_shl; pub mod mod_shr; pub mod mod_square; pub mod mod_sub; pub mod neg; pub mod next_power_of_2; pub mod overflowing_abs; pub mod overflowing_add; pub mod overflowing_add_mul; pub mod overflowing_div; pub mod overflowing_mul; pub mod overflowing_neg; pub mod overflowing_pow; pub mod overflowing_square; pub mod overflowing_sub; pub mod overflowing_sub_mul; pub mod parity; pub mod pow; pub mod power_of_2; pub mod primorial; pub mod reciprocal; pub mod root; pub mod rotate; pub mod round_to_multiple; pub mod round_to_multiple_of_power_of_2; pub mod saturating_abs; pub mod saturating_add; pub mod saturating_add_mul; pub mod saturating_mul; pub mod saturating_neg; pub mod saturating_pow; pub mod saturating_square; pub mod saturating_sub; pub mod saturating_sub_mul; pub mod shl_round; pub mod shr_round; pub mod sign; pub mod sqrt; pub mod square; pub mod sub_mul; pub mod wrapping_abs; pub mod wrapping_add; pub mod wrapping_add_mul; pub mod wrapping_div; pub mod wrapping_mul; pub mod wrapping_neg; pub mod wrapping_pow; pub mod wrapping_square; pub mod wrapping_sub; pub mod wrapping_sub_mul; pub mod x_mul_y_to_zz; pub mod xx_add_yy_to_zz; pub mod xx_div_mod_y_to_qr; pub mod xx_sub_yy_to_zz; pub mod xxx_add_yyy_to_zzz; pub mod xxx_sub_yyy_to_zzz; pub mod xxxx_add_yyyy_to_zzzz; } pub mod basic { pub mod constants; } pub mod comparison { pub mod cmp_abs_partial_cmp_abs_and_comparators; pub mod eq_abs_partial_eq_abs_and_comparators; } pub mod conversion { pub mod digits { pub mod general_digits { pub mod from_digits; pub mod to_digits; } pub mod power_of_2_digits { pub mod from_power_of_2_digits; pub mod power_of_2_digit_iterable; pub mod to_power_of_2_digits; } } pub mod froms { pub mod convertible_from; pub mod from; pub mod overflowing_from; pub mod rounding_from; pub mod saturating_from; pub mod try_from_and_exact_from; pub mod wrapping_from; } pub mod half { pub mod join_halves; pub mod lower_half; pub mod split_in_half; pub mod upper_half; } pub mod is_integer; pub mod mantissa_and_exponent { pub mod integer_mantissa_and_exponent; pub mod raw_mantissa_and_exponent; pub mod sci_mantissa_and_exponent; } pub mod slice { pub mod from_other_type_slice; pub mod vec_from_other_type; pub mod vec_from_other_type_slice; } pub mod string { pub mod from_sci_string; pub mod from_string; pub mod options { pub mod from_sci_string_options; pub mod to_sci_options; } pub mod to_sci; pub mod to_string; } } pub mod exhaustive { pub mod exhaustive_finite_primitive_floats; pub mod exhaustive_natural_signeds; pub mod exhaustive_negative_finite_primitive_floats; pub mod exhaustive_negative_primitive_floats; pub mod exhaustive_negative_signeds; pub mod exhaustive_nonzero_finite_primitive_floats; pub mod exhaustive_nonzero_finite_primitive_floats_in_range; pub mod exhaustive_nonzero_primitive_floats; pub mod exhaustive_nonzero_signeds; pub mod exhaustive_positive_finite_primitive_floats; pub mod exhaustive_positive_finite_primitive_floats_in_range; pub mod exhaustive_positive_primitive_floats; pub mod exhaustive_positive_primitive_ints; pub mod exhaustive_primitive_float_inclusive_range; pub mod exhaustive_primitive_float_range; pub mod exhaustive_primitive_floats; pub mod exhaustive_primitive_floats_with_sci_exponent; pub mod exhaustive_primitive_floats_with_sci_exponent_and_precision; pub mod exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range; pub mod exhaustive_primitive_floats_with_sci_exponent_in_range; pub mod exhaustive_signed_inclusive_range; pub mod exhaustive_signed_range; pub mod exhaustive_signeds; pub mod exhaustive_unsigneds; pub mod finite_primitive_floats_increasing; pub mod negative_finite_primitive_floats_increasing; pub mod negative_primitive_floats_increasing; pub mod nonzero_finite_primitive_floats_increasing; pub mod nonzero_primitive_floats_increasing; pub mod positive_finite_primitive_floats_increasing; pub mod positive_primitive_floats_increasing; pub mod primitive_float_increasing_inclusive_range; pub mod primitive_float_increasing_range; pub mod primitive_floats_increasing; pub mod primitive_int_increasing_inclusive_range; pub mod primitive_int_increasing_range; } pub mod factorization { pub mod prime_indicator_sequence; pub mod prime_indicator_sequence_less_than; pub mod prime_sieve; pub mod primes; } pub mod float { pub mod basic { pub mod abs_negative_zero; pub mod from_ordered_representation; pub mod is_negative_zero; pub mod max_precision_for_sci_exponent; pub mod next_higher; pub mod next_lower; pub mod precision; pub mod to_ordered_representation; } pub mod nice_float { pub mod cmp; pub mod eq; pub mod from_str; pub mod hash; pub mod to_string; } } pub mod iterators { pub mod bit_distributor_sequence; pub mod iterator_to_bit_chunks; pub mod ruler_sequence; } pub mod logic { pub mod bit_access { pub mod assign_bit; pub mod clear_bit; pub mod flip_bit; pub mod get_bit; pub mod set_bit; } pub mod bit_block_access { pub mod assign_bits; pub mod get_bits; } pub mod bit_convertible { pub mod from_bits; pub mod to_bits; } pub mod bit_iterable; pub mod bit_scan { pub mod index_of_next_false_bit; pub mod index_of_next_true_bit; } pub mod get_highest_bit; pub mod hamming_distance; pub mod low_mask; pub mod not_assign; pub mod significant_bits; } pub mod random { pub mod geometric { pub mod geometric_random_natural_signeds; pub mod geometric_random_negative_signeds; pub mod geometric_random_nonzero_signeds; pub mod geometric_random_positive_signeds; pub mod geometric_random_positive_unsigneds; pub mod geometric_random_signed_inclusive_range; pub mod geometric_random_signed_range; pub mod geometric_random_signeds; pub mod geometric_random_unsigned_inclusive_range; pub mod geometric_random_unsigned_range; pub mod geometric_random_unsigneds; pub mod get_geometric_random_signed_from_inclusive_range; pub mod mean; } pub mod random_finite_primitive_floats; pub mod random_highest_bit_set_unsigneds; pub mod random_natural_signeds; pub mod random_negative_finite_primitive_floats; pub mod random_negative_primitive_floats; pub mod random_negative_signeds; pub mod random_nonzero_finite_primitive_floats; pub mod random_nonzero_primitive_floats; pub mod random_nonzero_signeds; pub mod random_positive_finite_primitive_floats; pub mod random_positive_primitive_floats; pub mod random_positive_signeds; pub mod random_positive_unsigneds; pub mod random_primitive_float_inclusive_range; pub mod random_primitive_float_range; pub mod random_primitive_floats; pub mod random_primitive_ints; pub mod random_signed_bit_chunks; pub mod random_signed_inclusive_range; pub mod random_signed_range; pub mod random_unsigned_bit_chunks; pub mod random_unsigned_inclusive_range; pub mod random_unsigned_range; pub mod random_unsigneds_less_than; pub mod special_random_finite_primitive_floats; pub mod special_random_negative_finite_primitive_floats; pub mod special_random_negative_primitive_floats; pub mod special_random_nonzero_finite_primitive_floats; pub mod special_random_nonzero_primitive_floats; pub mod special_random_positive_finite_primitive_floats; pub mod special_random_positive_primitive_floats; pub mod special_random_primitive_float_inclusive_range; pub mod special_random_primitive_float_range; pub mod special_random_primitive_floats; pub mod striped { pub mod get_striped_bool_vec; pub mod get_striped_unsigned_vec; pub mod striped_bit_source; pub mod striped_random_bool_vecs; pub mod striped_random_bool_vecs_from_length_iterator; pub mod striped_random_bool_vecs_length_inclusive_range; pub mod striped_random_bool_vecs_length_range; pub mod striped_random_bool_vecs_min_length; pub mod striped_random_fixed_length_bool_vecs; pub mod striped_random_fixed_length_unsigned_vecs; pub mod striped_random_natural_signeds; pub mod striped_random_negative_signeds; pub mod striped_random_nonzero_signeds; pub mod striped_random_positive_signeds; pub mod striped_random_positive_unsigneds; pub mod striped_random_signed_inclusive_range; pub mod striped_random_signed_range; pub mod striped_random_signeds; pub mod striped_random_unsigned_bit_chunks; pub mod striped_random_unsigned_inclusive_range; pub mod striped_random_unsigned_range; pub mod striped_random_unsigned_vecs; pub mod striped_random_unsigned_vecs_from_length_iterator; pub mod striped_random_unsigned_vecs_length_inclusive_range; pub mod striped_random_unsigned_vecs_length_range; pub mod striped_random_unsigned_vecs_min_length; pub mod striped_random_unsigneds; } pub mod variable_range_generator { pub mod next_bit_chunk; pub mod next_bool; pub mod next_in_inclusive_range; pub mod next_in_range; pub mod next_less_than; } } } pub mod options { pub mod exhaustive { pub mod exhaustive_options; pub mod exhaustive_somes; } pub mod option_from_str; pub mod random { pub mod random_options; pub mod random_somes; } } pub mod orderings { pub mod exhaustive; pub mod ordering_from_str; pub mod random; } pub mod random { pub mod fork; pub mod from_bytes; pub mod get_rng; pub mod next; } pub mod rational_sequences { pub mod access { pub mod get; pub mod mutate; } pub mod basic { pub mod component_len; pub mod is_empty; pub mod is_finite; pub mod iter; pub mod len; } pub mod comparison { pub mod cmp; pub mod eq; pub mod hash; } pub mod conversion { pub mod clone; pub mod from_vec; pub mod from_vecs; pub mod to_vecs; } pub mod exhaustive; pub mod random; pub mod to_string; } pub mod rounding_modes { pub mod clone; pub mod cmp; pub mod eq; pub mod exhaustive; pub mod from_str; pub mod hash; pub mod neg; pub mod random; pub mod size; pub mod to_string; } pub mod sets { pub mod exhaustive { pub mod exhaustive_b_tree_sets; pub mod exhaustive_b_tree_sets_fixed_length; pub mod exhaustive_b_tree_sets_length_inclusive_range; pub mod exhaustive_b_tree_sets_length_range; pub mod exhaustive_b_tree_sets_min_length; pub mod exhaustive_hash_sets; pub mod exhaustive_hash_sets_fixed_length; pub mod exhaustive_hash_sets_length_inclusive_range; pub mod exhaustive_hash_sets_length_range; pub mod exhaustive_hash_sets_min_length; pub mod lex_b_tree_sets; pub mod lex_b_tree_sets_fixed_length; pub mod lex_b_tree_sets_length_inclusive_range; pub mod lex_b_tree_sets_length_range; pub mod lex_b_tree_sets_min_length; pub mod lex_hash_sets; pub mod lex_hash_sets_fixed_length; pub mod lex_hash_sets_length_inclusive_range; pub mod lex_hash_sets_length_range; pub mod lex_hash_sets_min_length; pub mod shortlex_b_tree_sets; pub mod shortlex_b_tree_sets_length_inclusive_range; pub mod shortlex_b_tree_sets_length_range; pub mod shortlex_b_tree_sets_min_length; pub mod shortlex_hash_sets; pub mod shortlex_hash_sets_length_inclusive_range; pub mod shortlex_hash_sets_length_range; pub mod shortlex_hash_sets_min_length; } pub mod random { pub mod random_b_tree_sets; pub mod random_b_tree_sets_fixed_length; pub mod random_b_tree_sets_from_length_iterator; pub mod random_b_tree_sets_length_inclusive_range; pub mod random_b_tree_sets_length_range; pub mod random_b_tree_sets_min_length; pub mod random_hash_sets; pub mod random_hash_sets_fixed_length; pub mod random_hash_sets_from_length_iterator; pub mod random_hash_sets_length_inclusive_range; pub mod random_hash_sets_length_range; pub mod random_hash_sets_min_length; } } pub mod slices { pub mod exhaustive_slice_permutations; pub mod min_repeating_len; pub mod random_slice_permutations; pub mod slice_leading_zeros; pub mod slice_move_left; pub mod slice_set_zero; pub mod slice_test_zero; pub mod slice_trailing_zeros; pub mod split_into_chunks; } pub mod strings { pub mod exhaustive { pub mod exhaustive_fixed_length_strings; pub mod exhaustive_fixed_length_strings_using_chars; pub mod exhaustive_strings; pub mod exhaustive_strings_using_chars; pub mod lex_fixed_length_strings; pub mod lex_fixed_length_strings_using_chars; pub mod shortlex_strings; pub mod shortlex_strings_using_chars; } pub mod random { pub mod random_fixed_length_strings; pub mod random_fixed_length_strings_using_chars; pub mod random_strings; pub mod random_strings_using_chars; } pub mod string_is_subset; pub mod string_sort; pub mod string_unique; pub mod strings_from_char_vecs; pub mod to_binary_string; pub mod to_debug_string; pub mod to_lower_hex_string; pub mod to_octal_string; pub mod to_upper_hex_string; } pub mod tuples { pub mod exhaustive { pub mod exhaustive_custom_tuples; pub mod exhaustive_dependent_pairs; pub mod exhaustive_ordered_unique_tuples; pub mod exhaustive_tuples_1_input; pub mod exhaustive_tuples_custom_output; pub mod exhaustive_tuples_from_single; pub mod exhaustive_unique_tuples; pub mod exhaustive_units; pub mod lex_custom_tuples; pub mod lex_dependent_pairs; pub mod lex_ordered_unique_tuples; pub mod lex_tuples; pub mod lex_tuples_from_single; pub mod lex_unique_tuples; } pub mod random { pub mod random_custom_tuples; pub mod random_ordered_unique_tuples; pub mod random_tuples; pub mod random_tuples_from_single; pub mod random_unique_tuples; pub mod random_units; } pub mod singletons; } pub mod unions { pub mod clone; pub mod debug; pub mod display; pub mod eq; pub mod exhaustive { pub mod exhaustive_unions; pub mod lex_unions; } pub mod from_str; pub mod ord; pub mod random { pub mod random_unions; } pub mod unwrap; } pub mod vecs { pub mod exhaustive { pub mod exhaustive_combined_k_compositions; pub mod exhaustive_ordered_unique_vecs; pub mod exhaustive_ordered_unique_vecs_fixed_length; pub mod exhaustive_ordered_unique_vecs_length_inclusive_range; pub mod exhaustive_ordered_unique_vecs_length_range; pub mod exhaustive_ordered_unique_vecs_min_length; pub mod exhaustive_unique_vecs; pub mod exhaustive_unique_vecs_fixed_length; pub mod exhaustive_unique_vecs_length_inclusive_range; pub mod exhaustive_unique_vecs_length_range; pub mod exhaustive_unique_vecs_min_length; pub mod exhaustive_vecs; pub mod exhaustive_vecs_fixed_length_from_single; pub mod exhaustive_vecs_fixed_length_m_inputs; pub mod exhaustive_vecs_from_length_iterator; pub mod exhaustive_vecs_length_inclusive_range; pub mod exhaustive_vecs_length_n; pub mod exhaustive_vecs_length_range; pub mod exhaustive_vecs_min_length; pub mod lex_k_compositions; pub mod lex_ordered_unique_vecs; pub mod lex_ordered_unique_vecs_fixed_length; pub mod lex_ordered_unique_vecs_length_inclusive_range; pub mod lex_ordered_unique_vecs_length_range; pub mod lex_ordered_unique_vecs_min_length; pub mod lex_unique_vecs; pub mod lex_unique_vecs_fixed_length; pub mod lex_unique_vecs_length_inclusive_range; pub mod lex_unique_vecs_length_range; pub mod lex_unique_vecs_min_length; pub mod lex_vecs_fixed_length_from_single; pub mod lex_vecs_fixed_length_m_inputs; pub mod lex_vecs_length_n; pub mod next_bit_pattern; pub mod shortlex_ordered_unique_vecs; pub mod shortlex_ordered_unique_vecs_length_inclusive_range; pub mod shortlex_ordered_unique_vecs_length_range; pub mod shortlex_ordered_unique_vecs_min_length; pub mod shortlex_unique_vecs; pub mod shortlex_unique_vecs_length_inclusive_range; pub mod shortlex_unique_vecs_length_range; pub mod shortlex_unique_vecs_min_length; pub mod shortlex_vecs; pub mod shortlex_vecs_from_length_iterator; pub mod shortlex_vecs_length_inclusive_range; pub mod shortlex_vecs_length_range; pub mod shortlex_vecs_min_length; } pub mod exhaustive_vec_permutations; pub mod random { pub mod random_ordered_unique_vecs; pub mod random_ordered_unique_vecs_fixed_length; pub mod random_ordered_unique_vecs_from_length_iterator; pub mod random_ordered_unique_vecs_length_inclusive_range; pub mod random_ordered_unique_vecs_length_range; pub mod random_ordered_unique_vecs_min_length; pub mod random_unique_vecs; pub mod random_unique_vecs_fixed_length; pub mod random_unique_vecs_from_length_iterator; pub mod random_unique_vecs_length_inclusive_range; pub mod random_unique_vecs_length_range; pub mod random_unique_vecs_min_length; pub mod random_vecs; pub mod random_vecs_fixed_length; pub mod random_vecs_fixed_length_from_single; pub mod random_vecs_fixed_length_m_inputs; pub mod random_vecs_from_length_iterator; pub mod random_vecs_length_inclusive_range; pub mod random_vecs_length_range; pub mod random_vecs_min_length; } pub mod random_values_from_vec; pub mod random_vec_permutations; pub mod vec_delete_left; pub mod vec_from_str; pub mod vec_pad_left; } malachite-base-0.4.16/tests/named/mod.rs000064400000000000000000000012001046102023000161170ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::named::Named; use malachite_base::rounding_modes::RoundingMode; #[test] pub fn test_named() { fn test(out: &str) { assert_eq!(T::NAME, out); } test::("String"); test::("RoundingMode"); } malachite-base-0.4.16/tests/nevers/nevers.rs000064400000000000000000000010011046102023000170570ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::nevers::nevers; #[test] fn test_nevers() { assert_eq!(nevers().collect_vec(), &[]); } malachite-base-0.4.16/tests/num/arithmetic/abs.rs000064400000000000000000000054071046102023000177660ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::UnsignedAbs; use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::conversion::traits::ExactFrom; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::generators::{primitive_float_gen, signed_gen_var_1}; use std::cmp::Ordering::*; fn abs_signed_helper() { let test = |n: T, out| { assert_eq!(n.abs(), out); let mut n = n; n.abs_assign(); assert_eq!(n, out); }; test(T::ZERO, T::ZERO); test(T::ONE, T::ONE); test(T::exact_from(100), T::exact_from(100)); test(T::NEGATIVE_ONE, T::ONE); test(T::exact_from(-100), T::exact_from(100)); } fn abs_primitive_float_helper() { let test = |n: T, out| { assert_eq!(NiceFloat(n.abs()), NiceFloat(out)); let mut n = n; n.abs_assign(); assert_eq!(NiceFloat(n), NiceFloat(out)); }; test(T::ZERO, T::ZERO); test(T::NEGATIVE_ZERO, T::ZERO); test(T::INFINITY, T::INFINITY); test(T::NEGATIVE_INFINITY, T::INFINITY); test(T::NAN, T::NAN); test(T::ONE, T::ONE); test(T::NEGATIVE_ONE, T::ONE); test(T::from(100.0f32), T::from(100.0f32)); test(T::from(-100.0f32), T::from(100.0f32)); } #[test] fn test_abs() { apply_fn_to_signeds!(abs_signed_helper); apply_fn_to_primitive_floats!(abs_primitive_float_helper); } fn abs_assign_properties_signed_helper< U, S: ExactFrom + PrimitiveSigned + UnsignedAbs, >() { signed_gen_var_1::().test_properties(|n| { let mut abs = n; abs.abs_assign(); assert_eq!(abs, n.abs()); assert_eq!(abs.abs(), abs); assert_eq!(abs == n, n >= S::ZERO); assert_eq!(S::exact_from(n.unsigned_abs()), abs); }); } fn abs_assign_properties_primitive_float_helper() { primitive_float_gen::().test_properties(|f| { let mut abs = f; abs.abs_assign(); assert_eq!(NiceFloat(abs), NiceFloat(f.abs())); assert_eq!(NiceFloat(abs.abs()), NiceFloat(abs)); assert_eq!(NiceFloat(abs) == NiceFloat(f), f.sign() != Less); }); } #[test] fn abs_assign_properties() { apply_fn_to_unsigned_signed_pairs!(abs_assign_properties_signed_helper); apply_fn_to_primitive_floats!(abs_assign_properties_primitive_float_helper); } malachite-base-0.4.16/tests/num/arithmetic/abs_diff.rs000064400000000000000000000072251046102023000207560ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::{AbsDiff, UnsignedAbs}; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::ExactFrom; use malachite_base::test_util::generators::{ signed_gen, signed_pair_gen, unsigned_gen, unsigned_pair_gen_var_27, }; use std::cmp::{max, min}; #[test] fn test_abs_diff() { fn test_unsigned(x: T, y: T, out: T) { assert_eq!(x.abs_diff(y), out); let mut x = x; x.abs_diff_assign(y); assert_eq!(x, out); } test_unsigned::(1, 100, 99); test_unsigned::(100, 1, 99); test_unsigned::(10, 10, 0); test_unsigned::(0, u32::MAX, u32::MAX); test_unsigned::(u32::MAX, 0, u32::MAX); test_unsigned::(u32::MAX, u32::MAX, 0); fn test_signed, U: PrimitiveUnsigned>( x: T, y: T, out: U, ) { assert_eq!(x.abs_diff(y), out); } test_signed::(1, 100, 99); test_signed::(1, -100, 101); test_signed::(-1, 100, 101); test_signed::(-1, -100, 99); test_signed::(100, 1, 99); test_signed::(100, -1, 101); test_signed::(-100, 1, 101); test_signed::(-100, -1, 99); test_signed::(10, 10, 0); test_signed::(10, -10, 20); test_signed::(-10, 10, 20); test_signed::(-10, -10, 0); test_signed::(0, i32::MAX, u32::exact_from(i32::MAX)); test_signed::(0, -i32::MAX, u32::exact_from(i32::MAX)); test_signed::(i32::MAX, 0, u32::exact_from(i32::MAX)); test_signed::(-i32::MAX, 0, u32::exact_from(i32::MAX)); test_signed::(i32::MAX, i32::MAX, 0); test_signed::(i32::MAX, -i32::MAX, u32::MAX - 1); test_signed::(-i32::MAX, i32::MAX, u32::MAX - 1); test_signed::(-i32::MAX, -i32::MAX, 0); test_signed::(i64::MIN, i64::MAX, u64::MAX); test_signed::(i64::MIN, -i64::MAX, 1); } fn abs_diff_properties_unsigned_helper() { unsigned_pair_gen_var_27::().test_properties(|(x, y)| { let diff = x.abs_diff(y); let mut mut_x = x; mut_x.abs_diff_assign(y); assert_eq!(mut_x, diff); assert_eq!(y.abs_diff(x), diff); assert_eq!(max(x, y) - min(x, y), diff); }); unsigned_gen::().test_properties(|x| { assert_eq!(x.abs_diff(T::ZERO), x); assert_eq!(T::ZERO.abs_diff(x), x); assert_eq!(x.abs_diff(x), T::ZERO); }); } fn abs_diff_properties_signed_helper< U: PrimitiveUnsigned, T: AbsDiff + UnsignedAbs + PrimitiveSigned, >() { signed_pair_gen::().test_properties(|(x, y)| { let diff = x.abs_diff(y); assert_eq!(y.abs_diff(x), diff); }); signed_gen::().test_properties(|x| { assert_eq!(x.abs_diff(T::ZERO), x.unsigned_abs()); assert_eq!(T::ZERO.abs_diff(x), x.unsigned_abs()); assert_eq!(x.abs_diff(x), U::ZERO); }); } #[test] fn abs_diff_properties() { apply_fn_to_unsigneds!(abs_diff_properties_unsigned_helper); apply_fn_to_unsigned_signed_pairs!(abs_diff_properties_signed_helper); } malachite-base-0.4.16/tests/num/arithmetic/add_mul.rs000064400000000000000000000074441046102023000206310ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::generators::{ primitive_float_triple_gen, signed_pair_gen, signed_triple_gen_var_1, unsigned_pair_gen_var_27, unsigned_triple_gen_var_1, }; #[test] fn test_add_mul() { fn test_i(x: T, y: T, z: T, out: T) { assert_eq!(x.add_mul(y, z), out); let mut x = x; x.add_mul_assign(y, z); assert_eq!(x, out); } test_i::(2, 3, 7, 23); test_i::(7, 5, 10, 57); test_i::(123, 456, 789, 359907); test_i::(123, -456, 789, -359661); test_i::(-123, 456, 789, 359661); test_i::(127, -2, 100, -73); test_i::(-127, 2, 100, 73); test_i::(-128, 1, 0, -128); fn test_f(x: T, y: T, z: T, out: T) { assert_eq!(NiceFloat(x.add_mul(y, z)), NiceFloat(out)); let mut x = x; x.add_mul_assign(y, z); assert_eq!(NiceFloat(x), NiceFloat(out)); } test_f::(1.0, 2.0, 3.0, 7.0); test_f::(1.0, f32::INFINITY, 2.0, f32::INFINITY); test_f::(f32::NAN, 1.0, 2.0, f32::NAN); } fn add_mul_properties_helper_unsigned() { unsigned_triple_gen_var_1::().test_properties(|(x, y, z)| { let result = x.add_mul(y, z); let mut x_alt = x; x_alt.add_mul_assign(y, z); assert_eq!(x_alt, result); assert_eq!(x.add_mul(z, y), result); assert_eq!(result.sub_mul(y, z), x); assert_eq!(x.checked_add_mul(y, z), Some(result)); assert_eq!(x.saturating_add_mul(y, z), result); assert_eq!(x.wrapping_add_mul(y, z), result); assert_eq!(x.overflowing_add_mul(y, z), (result, false)); }); unsigned_pair_gen_var_27::().test_properties(|(a, b)| { assert_eq!(a.add_mul(T::ZERO, b), a); assert_eq!(a.add_mul(b, T::ZERO), a); }); } fn add_mul_properties_helper_signed() { signed_triple_gen_var_1::().test_properties(|(x, y, z)| { let result = x.add_mul(y, z); let mut x_alt = x; x_alt.add_mul_assign(y, z); assert_eq!(x_alt, result); assert_eq!(x.add_mul(z, y), result); assert_eq!(result.sub_mul(y, z), x); assert_eq!(x.checked_add_mul(y, z), Some(result)); assert_eq!(x.saturating_add_mul(y, z), result); assert_eq!(x.wrapping_add_mul(y, z), result); assert_eq!(x.overflowing_add_mul(y, z), (result, false)); }); signed_pair_gen::().test_properties(|(a, b)| { assert_eq!(a.add_mul(T::ZERO, b), a); assert_eq!(a.add_mul(b, T::ZERO), a); }); } fn add_mul_properties_helper_primitive_float() { primitive_float_triple_gen::().test_properties(|(x, y, z)| { let result = x.add_mul(y, z); let mut x_alt = x; x_alt.add_mul_assign(y, z); assert_eq!(NiceFloat(x_alt), NiceFloat(result)); assert_eq!(NiceFloat(x.add_mul(z, y)), NiceFloat(result)); }); } #[test] fn add_mul_properties() { apply_fn_to_unsigneds!(add_mul_properties_helper_unsigned); apply_fn_to_signeds!(add_mul_properties_helper_signed); apply_fn_to_primitive_floats!(add_mul_properties_helper_primitive_float); } malachite-base-0.4.16/tests/num/arithmetic/arithmetic_checked_shl.rs000064400000000000000000000136131046102023000236640ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::{ArithmeticCheckedShl, ArithmeticCheckedShr}; use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::ExactFrom; use malachite_base::num::logic::traits::LeadingZeros; use malachite_base::test_util::generators::{ signed_gen, signed_gen_var_5, signed_pair_gen_var_2, signed_unsigned_pair_gen_var_1, unsigned_gen, unsigned_gen_var_5, unsigned_pair_gen_var_2, unsigned_signed_pair_gen_var_1, }; use std::ops::Shr; #[test] fn test_arithmetic_checked_shl() { fn test + PrimitiveInt, U: PrimitiveInt>( t: T, u: U, out: Option, ) { assert_eq!(t.arithmetic_checked_shl(u), out); } test::(0, 0, Some(0)); test::(3, 6, Some(192)); test::(3, 7, None); test::(3, 100, None); test::(0, 100, Some(0)); test::(100, -3, Some(12)); test::(100, -100, Some(0)); test::(3, 5, Some(96)); test::(3, 6, None); test::(-3, 5, Some(-96)); test::(-3, 6, None); test::(3, 100, None); test::(-3, 100, None); test::(0, 100, Some(0)); test::(3, 5, Some(96)); test::(3, 6, None); test::(-3, 5, Some(-96)); test::(-3, 6, None); test::(3, 100, None); test::(-3, 100, None); test::(0, 100, Some(0)); test::(100, -3, Some(12)); test::(-100, -3, Some(-13)); test::(100, -100, Some(0)); test::(-100, -100, Some(-1)); } fn arithmetic_checked_shl_properties_helper_unsigned_unsigned< T: ArithmeticCheckedShl + PrimitiveUnsigned + Shr, U: PrimitiveUnsigned, >() where u64: ExactFrom, { unsigned_pair_gen_var_2::().test_properties(|(n, u)| { if let Some(shifted) = n.arithmetic_checked_shl(u) { assert!(shifted >= n); if n != T::ZERO { assert_eq!(shifted >> u, n); } } else { assert_ne!(n, T::ZERO); assert!(LeadingZeros::leading_zeros(n) < u64::exact_from(u)); } }); unsigned_gen::().test_properties(|n| { assert_eq!(n.arithmetic_checked_shl(U::ZERO), Some(n)); }); unsigned_gen_var_5::().test_properties(|u| { assert_eq!(T::ZERO.arithmetic_checked_shl(u), Some(T::ZERO)); }); } // Type repetition to avoid long line #[allow( clippy::type_repetition_in_bounds, clippy::trait_duplication_in_bounds, clippy::multiple_bound_locations )] fn arithmetic_checked_shl_properties_helper_unsigned_signed< T: ArithmeticCheckedShl + ArithmeticCheckedShr, U: PrimitiveSigned, >() where u64: ExactFrom, T: PrimitiveUnsigned, { unsigned_signed_pair_gen_var_1::().test_properties(|(n, i)| { let shifted = n.arithmetic_checked_shl(i); if shifted.is_none() { assert_ne!(n, T::ZERO); } if i != U::MIN { assert_eq!(n.arithmetic_checked_shr(-i), shifted); } }); unsigned_gen::().test_properties(|n| { assert_eq!(n.arithmetic_checked_shl(U::ZERO), Some(n)); }); signed_gen_var_5::().test_properties(|i| { assert_eq!(T::ZERO.arithmetic_checked_shl(i), Some(T::ZERO)); }); } fn arithmetic_checked_shl_properties_helper_signed_unsigned< T: ArithmeticCheckedShl + PrimitiveSigned + Shr, U: PrimitiveUnsigned, >() where u64: ExactFrom, { signed_unsigned_pair_gen_var_1::().test_properties(|(n, u)| { if let Some(shifted) = n.arithmetic_checked_shl(u) { assert!(shifted.ge_abs(&n)); if n != T::ZERO { assert_eq!(shifted >> u, n); } } else { assert_ne!(n, T::ZERO); } }); signed_gen::().test_properties(|n| { assert_eq!(n.arithmetic_checked_shl(U::ZERO), Some(n)); }); unsigned_gen_var_5::().test_properties(|u| { assert_eq!(T::ZERO.arithmetic_checked_shl(u), Some(T::ZERO)); }); } fn arithmetic_checked_shl_properties_helper_signed_signed< T: ArithmeticCheckedShl + ArithmeticCheckedShr + PrimitiveSigned, U: PrimitiveSigned, >() where u64: ExactFrom, { signed_pair_gen_var_2::().test_properties(|(n, i)| { let shifted = n.arithmetic_checked_shl(i); if shifted.is_none() { assert_ne!(n, T::ZERO); } if i != U::MIN { assert_eq!(n.arithmetic_checked_shr(-i), shifted); } }); signed_gen::().test_properties(|n| { assert_eq!(n.arithmetic_checked_shl(U::ZERO), Some(n)); }); signed_gen_var_5::().test_properties(|i| { assert_eq!(T::ZERO.arithmetic_checked_shl(i), Some(T::ZERO)); }); } #[test] fn arithmetic_checked_shl_properties() { apply_fn_to_unsigneds_and_unsigneds!( arithmetic_checked_shl_properties_helper_unsigned_unsigned ); apply_fn_to_unsigneds_and_signeds!(arithmetic_checked_shl_properties_helper_unsigned_signed); apply_fn_to_signeds_and_unsigneds!(arithmetic_checked_shl_properties_helper_signed_unsigned); apply_fn_to_signeds_and_signeds!(arithmetic_checked_shl_properties_helper_signed_signed); } malachite-base-0.4.16/tests/num/arithmetic/arithmetic_checked_shr.rs000064400000000000000000000067701046102023000237000ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::{ArithmeticCheckedShl, ArithmeticCheckedShr}; use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::ExactFrom; use malachite_base::test_util::generators::{ signed_gen, signed_gen_var_5, signed_pair_gen_var_2, unsigned_gen, unsigned_signed_pair_gen_var_1, }; #[test] fn test_arithmetic_checked_shr() { fn test + PrimitiveInt, U: PrimitiveInt>( t: T, u: U, out: Option, ) { assert_eq!(t.arithmetic_checked_shr(u), out); } test::(100, 3, Some(12)); test::(100, 100, Some(0)); test::(3, -5, Some(96)); test::(3, -6, None); test::(-3, -5, Some(-96)); test::(-3, -6, None); test::(3, -100, None); test::(-3, -100, None); test::(0, -100, Some(0)); test::(100, 3, Some(12)); test::(-100, 3, Some(-13)); test::(100, 100, Some(0)); test::(-100, 100, Some(-1)); } // Type repetition to avoid long line #[allow( clippy::type_repetition_in_bounds, clippy::trait_duplication_in_bounds, clippy::multiple_bound_locations )] fn arithmetic_checked_shr_properties_helper_unsigned_signed< T: ArithmeticCheckedShl + ArithmeticCheckedShr, U: PrimitiveSigned, >() where u64: ExactFrom, T: PrimitiveUnsigned, { unsigned_signed_pair_gen_var_1::().test_properties(|(n, i)| { let shifted = n.arithmetic_checked_shr(i); if shifted.is_none() { assert_ne!(n, T::ZERO); } if i != U::MIN { assert_eq!(n.arithmetic_checked_shl(-i), shifted); } }); unsigned_gen::().test_properties(|n| { assert_eq!(n.arithmetic_checked_shr(U::ZERO), Some(n)); }); signed_gen_var_5::().test_properties(|i| { assert_eq!(T::ZERO.arithmetic_checked_shr(i), Some(T::ZERO)); }); } fn arithmetic_checked_shr_properties_helper_signed_signed< T: ArithmeticCheckedShl + ArithmeticCheckedShr + PrimitiveSigned, U: PrimitiveSigned, >() where u64: ExactFrom, { signed_pair_gen_var_2::().test_properties(|(n, i)| { let shifted = n.arithmetic_checked_shr(i); if shifted.is_none() { assert_ne!(n, T::ZERO); } if i != U::MIN { assert_eq!(n.arithmetic_checked_shl(-i), shifted); } }); signed_gen::().test_properties(|n| { assert_eq!(n.arithmetic_checked_shr(U::ZERO), Some(n)); }); signed_gen_var_5::().test_properties(|i| { assert_eq!(T::ZERO.arithmetic_checked_shr(i), Some(T::ZERO)); }); } #[test] fn arithmetic_checked_shr_properties() { apply_fn_to_unsigneds_and_signeds!(arithmetic_checked_shr_properties_helper_unsigned_signed); apply_fn_to_signeds_and_signeds!(arithmetic_checked_shr_properties_helper_signed_signed); } malachite-base-0.4.16/tests/num/arithmetic/binomial_coefficient.rs000064400000000000000000000206571046102023000233550ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::BinomialCoefficient; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ signed_gen, signed_gen_var_2, signed_pair_gen_var_11, signed_pair_gen_var_12, unsigned_gen, unsigned_gen_var_1, unsigned_pair_gen_var_28, unsigned_pair_gen_var_44, }; use std::panic::catch_unwind; #[test] fn test_binomial_coefficient() { fn test_u(n: T, k: T, out: T) { assert_eq!(T::binomial_coefficient(n, k), out); } test_u::(0, 0, 1); test_u::(1, 0, 1); test_u::(1, 1, 1); test_u::(2, 0, 1); test_u::(2, 1, 2); test_u::(2, 2, 1); test_u::(3, 0, 1); test_u::(3, 1, 3); test_u::(3, 2, 3); test_u::(3, 3, 1); test_u::(4, 0, 1); test_u::(4, 1, 4); test_u::(4, 2, 6); test_u::(4, 3, 4); test_u::(4, 4, 1); test_u::(1, 2, 0); test_u::(10, 5, 252); test_u::(100, 50, 100891344545564193334812497256); fn test_i(n: T, k: T, out: T) { assert_eq!(T::binomial_coefficient(n, k), out); } test_i::(0, 0, 1); test_i::(1, 0, 1); test_i::(1, 1, 1); test_i::(2, 0, 1); test_i::(2, 1, 2); test_i::(2, 2, 1); test_i::(3, 0, 1); test_i::(3, 1, 3); test_i::(3, 2, 3); test_i::(3, 3, 1); test_i::(4, 0, 1); test_i::(4, 1, 4); test_i::(4, 2, 6); test_i::(4, 3, 4); test_i::(4, 4, 1); test_i::(1, 2, 0); test_i::(10, 5, 252); test_i::(100, 50, 100891344545564193334812497256); test_i::(-1, 0, 1); test_i::(-1, 1, -1); test_i::(-2, 0, 1); test_i::(-2, 1, -2); test_i::(-2, 2, 3); test_i::(-3, 0, 1); test_i::(-3, 1, -3); test_i::(-3, 2, 6); test_i::(-3, 3, -10); test_i::(-1, 2, 1); test_i::(-10, 5, -2002); test_i::(-80, 50, 1828256793482238093393785743858493760); test_i::(-128, 1, -128); test_i::(-2, 127, -128); } #[test] pub fn binomial_coefficient_fail() { assert_panic!(u8::binomial_coefficient(11, 5)); assert_panic!(u128::binomial_coefficient(1000000, 1000)); assert_panic!(i8::binomial_coefficient(11, 5)); assert_panic!(i128::binomial_coefficient(1000000, 1000)); assert_panic!(i8::binomial_coefficient(1, -1)); } #[test] fn test_checked_binomial_coefficient() { fn test_u(n: T, k: T, out: Option) { assert_eq!(T::checked_binomial_coefficient(n, k), out); } test_u::(0, 0, Some(1)); test_u::(1, 0, Some(1)); test_u::(1, 1, Some(1)); test_u::(2, 0, Some(1)); test_u::(2, 1, Some(2)); test_u::(2, 2, Some(1)); test_u::(3, 0, Some(1)); test_u::(3, 1, Some(3)); test_u::(3, 2, Some(3)); test_u::(3, 3, Some(1)); test_u::(4, 0, Some(1)); test_u::(4, 1, Some(4)); test_u::(4, 2, Some(6)); test_u::(4, 3, Some(4)); test_u::(4, 4, Some(1)); test_u::(1, 2, Some(0)); test_u::(10, 5, Some(252)); test_u::(100, 50, Some(100891344545564193334812497256)); test_u::(11, 5, None); test_u::(1000000, 1000, None); fn test_i(n: T, k: T, out: Option) { assert_eq!(T::checked_binomial_coefficient(n, k), out); } test_i::(0, 0, Some(1)); test_i::(1, 0, Some(1)); test_i::(1, 1, Some(1)); test_i::(2, 0, Some(1)); test_i::(2, 1, Some(2)); test_i::(2, 2, Some(1)); test_i::(3, 0, Some(1)); test_i::(3, 1, Some(3)); test_i::(3, 2, Some(3)); test_i::(3, 3, Some(1)); test_i::(4, 0, Some(1)); test_i::(4, 1, Some(4)); test_i::(4, 2, Some(6)); test_i::(4, 3, Some(4)); test_i::(4, 4, Some(1)); test_i::(1, 2, Some(0)); test_i::(10, 5, Some(252)); test_i::(100, 50, Some(100891344545564193334812497256)); test_i::(-1, 0, Some(1)); test_i::(-1, 1, Some(-1)); test_i::(-2, 0, Some(1)); test_i::(-2, 1, Some(-2)); test_i::(-2, 2, Some(3)); test_i::(-3, 0, Some(1)); test_i::(-3, 1, Some(-3)); test_i::(-3, 2, Some(6)); test_i::(-3, 3, Some(-10)); test_i::(-1, 2, Some(1)); test_i::(-10, 5, Some(-2002)); test_i::(-80, 50, Some(1828256793482238093393785743858493760)); test_i::(-128, 1, Some(-128)); test_i::(-2, 127, Some(-128)); test_i::(11, 5, None); test_i::(1000000, 1000, None); test_i::(1, -1, None); } fn binomial_coefficient_helper_unsigned() { unsigned_pair_gen_var_44::().test_properties(|(n, k)| { let b = T::binomial_coefficient(n, k); assert_eq!(b == T::ZERO, n < k); if n >= k { assert_eq!(T::binomial_coefficient(n, n - k), b); } if n != T::ZERO && k != T::ZERO { let c = T::binomial_coefficient(n - T::ONE, k - T::ONE); assert_eq!(T::binomial_coefficient(n - T::ONE, k) + c, b); let gcd = n.gcd(k); assert_eq!(c / (k / gcd) * (n / gcd), b); } }); unsigned_gen::().test_properties(|n| { assert_eq!(T::binomial_coefficient(n, T::ZERO), T::ONE); assert_eq!(T::binomial_coefficient(n, T::ONE), n); }); unsigned_gen_var_1::().test_properties(|n| { assert_eq!(T::binomial_coefficient(n, n), T::ONE); assert_eq!(T::binomial_coefficient(n, n - T::ONE), n); assert_eq!(T::binomial_coefficient(T::ZERO, n), T::ZERO); }); } fn binomial_coefficient_helper_signed() { signed_pair_gen_var_12::().test_properties(|(n, k)| { let b = T::binomial_coefficient(n, k); assert_eq!(b == T::ZERO, n >= T::ZERO && n < k); if n >= k { assert_eq!(T::binomial_coefficient(n, n - k), b); } if n != T::MIN && k != T::ZERO { if let Some(c) = T::checked_binomial_coefficient(n - T::ONE, k) { assert_eq!(c + T::binomial_coefficient(n - T::ONE, k - T::ONE), b); } } if n != T::MIN { if let Some(s) = (n - T::ONE).checked_add(k) { if let Some(mut b_alt) = T::checked_binomial_coefficient(s, k) { if k.odd() { b_alt.neg_assign(); } assert_eq!(T::binomial_coefficient(-n, k), b_alt); } } } }); signed_gen::().test_properties(|n| { assert_eq!(T::binomial_coefficient(n, T::ONE), n); assert_eq!(T::binomial_coefficient(n, T::ZERO), T::ONE); }); signed_gen_var_2::().test_properties(|n| { assert_eq!(T::binomial_coefficient(n, n), T::ONE); if n != T::ZERO { assert_eq!(T::binomial_coefficient(n, n - T::ONE), n); assert_eq!(T::binomial_coefficient(T::ZERO, n), T::ZERO); } }); } #[test] fn binomial_coefficient_properties() { apply_fn_to_unsigneds!(binomial_coefficient_helper_unsigned); apply_fn_to_signeds!(binomial_coefficient_helper_signed); } fn checked_binomial_coefficient_helper_unsigned() { unsigned_pair_gen_var_28::().test_properties(|(n, k)| { if let Some(b) = T::checked_binomial_coefficient(n, k) { assert_eq!(T::binomial_coefficient(n, k), b); } }); } fn checked_binomial_coefficient_helper_signed() { signed_pair_gen_var_11::().test_properties(|(n, k)| { if let Some(b) = T::checked_binomial_coefficient(n, k) { assert_eq!(T::binomial_coefficient(n, k), b); } }); } #[test] fn checked_binomial_coefficient_properties() { apply_fn_to_unsigneds!(checked_binomial_coefficient_helper_unsigned); apply_fn_to_signeds!(checked_binomial_coefficient_helper_signed); } malachite-base-0.4.16/tests/num/arithmetic/ceiling.rs000064400000000000000000000034141046102023000206270ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::generators::primitive_float_gen; fn ceiling_assign_primitive_float_helper() { let test = |n: T, out| { assert_eq!(NiceFloat(n.ceiling()), NiceFloat(out)); let mut n = n; n.ceiling_assign(); assert_eq!(NiceFloat(n), NiceFloat(out)); }; test(T::ZERO, T::ZERO); test(T::NEGATIVE_ZERO, T::NEGATIVE_ZERO); test(T::INFINITY, T::INFINITY); test(T::NEGATIVE_INFINITY, T::NEGATIVE_INFINITY); test(T::NAN, T::NAN); test(T::ONE, T::ONE); test(T::NEGATIVE_ONE, T::NEGATIVE_ONE); test(T::from(1.5f32), T::from(2.0f32)); test(T::from(-1.5f32), T::from(-1.0f32)); } #[test] fn test_ceiling() { apply_fn_to_primitive_floats!(ceiling_assign_primitive_float_helper); } fn ceiling_assign_properties_helper() { primitive_float_gen::().test_properties(|f| { let mut ceiling = f; ceiling.ceiling_assign(); assert_eq!(NiceFloat(ceiling), NiceFloat(f.ceiling())); assert_eq!(NiceFloat(ceiling.ceiling()), NiceFloat(ceiling)); assert_eq!(NiceFloat(-ceiling), NiceFloat((-f).floor())); assert_eq!(f.sign(), ceiling.sign()); }); } #[test] fn ceiling_assign_properties() { apply_fn_to_primitive_floats!(ceiling_assign_properties_helper); } malachite-base-0.4.16/tests/num/arithmetic/checked_abs.rs000064400000000000000000000015661046102023000214360ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; fn checked_abs_helper() { let test = |n: T, out| { assert_eq!(n.checked_abs(), out); }; test(T::ZERO, Some(T::ZERO)); test(T::ONE, Some(T::ONE)); test(T::exact_from(100), Some(T::exact_from(100))); test(T::NEGATIVE_ONE, Some(T::ONE)); test(T::exact_from(-100), Some(T::exact_from(100))); test(T::MIN, None); } #[test] fn test_checked_abs() { apply_fn_to_signeds!(checked_abs_helper); } malachite-base-0.4.16/tests/num/arithmetic/checked_add_mul.rs000064400000000000000000000056251046102023000222760ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ signed_pair_gen, signed_triple_gen, unsigned_pair_gen_var_27, unsigned_triple_gen_var_19, }; #[test] fn test_checked_add_mul() { fn test(x: T, y: T, z: T, out: Option) { assert_eq!(x.checked_add_mul(y, z), out); } test::(2, 3, 7, Some(23)); test::(7, 5, 10, Some(57)); test::(123, 456, 789, Some(359907)); test::(123, -456, 789, Some(-359661)); test::(-123, 456, 789, Some(359661)); test::(127, -2, 100, Some(-73)); test::(-127, 2, 100, Some(73)); test::(-128, 1, 0, Some(-128)); test::(2, 20, 20, None); test::(-127, -2, 100, None); test::(127, 1, 100, None); test::(-127, -1, 100, None); test::(-127, -10, 100, None); } fn checked_add_mul_properties_helper_unsigned() { unsigned_triple_gen_var_19::().test_properties(|(x, y, z)| { let result = x.checked_add_mul(y, z); assert_eq!(x.checked_add_mul(z, y), result); assert_eq!(result.is_none(), x.overflowing_add_mul(y, z).1); }); unsigned_pair_gen_var_27::().test_properties(|(a, b)| { assert_eq!(a.checked_add_mul(T::ZERO, b), Some(a)); assert_eq!(a.checked_add_mul(T::ONE, b), a.checked_add(b)); assert_eq!(T::ZERO.checked_add_mul(a, b), a.checked_mul(b)); assert_eq!(a.checked_add_mul(b, T::ZERO), Some(a)); assert_eq!(a.checked_add_mul(b, T::ONE), a.checked_add(b)); }); } fn checked_add_mul_properties_helper_signed() { signed_triple_gen::().test_properties(|(x, y, z)| { let result = x.checked_add_mul(y, z); assert_eq!(x.checked_add_mul(z, y), result); assert_eq!(result.is_none(), x.overflowing_add_mul(y, z).1); }); signed_pair_gen::().test_properties(|(a, b)| { assert_eq!(a.checked_add_mul(T::ZERO, b), Some(a)); assert_eq!(a.checked_add_mul(T::ONE, b), a.checked_add(b)); assert_eq!(T::ZERO.checked_add_mul(a, b), a.checked_mul(b)); assert_eq!(a.checked_add_mul(b, T::ZERO), Some(a)); assert_eq!(a.checked_add_mul(b, T::ONE), a.checked_add(b)); }); } #[test] fn checked_add_mul_properties() { apply_fn_to_unsigneds!(checked_add_mul_properties_helper_unsigned); apply_fn_to_signeds!(checked_add_mul_properties_helper_signed); } malachite-base-0.4.16/tests/num/arithmetic/checked_neg.rs000064400000000000000000000016001046102023000214270ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; fn checked_neg_helper() { let test = |n: T, out| { assert_eq!(n.checked_neg(), out); }; test(T::ZERO, Some(T::ZERO)); test(T::ONE, Some(T::NEGATIVE_ONE)); test(T::exact_from(100), Some(T::exact_from(-100))); test(T::NEGATIVE_ONE, Some(T::ONE)); test(T::exact_from(-100), Some(T::exact_from(100))); test(T::MIN, None); } #[test] fn test_checked_neg() { apply_fn_to_signeds!(checked_neg_helper); } malachite-base-0.4.16/tests/num/arithmetic/checked_pow.rs000064400000000000000000000045531046102023000214750ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{signed_unsigned_pair_gen, unsigned_pair_gen}; #[test] fn test_checked_pow() { fn test(x: T, y: u64, out: Option) { assert_eq!(x.checked_pow(y), out); } test::(0, 0, Some(1)); test::(123, 0, Some(1)); test::(123, 1, Some(123)); test::(0, 123, Some(0)); test::(1, 123, Some(1)); test::(-1, 123, Some(-1)); test::(-1, 124, Some(1)); test::(3, 3, Some(27)); test::(-10, 9, Some(-1000000000)); test::(-10, 10, None); test::(-10, 9, None); test::(10, 9, None); test::(123, 456, None); test::(0, u64::MAX, Some(0)); test::(1, u64::MAX, Some(1)); test::(123, u64::MAX, None); test::(0, u64::MAX, Some(0)); test::(1, u64::MAX, Some(1)); test::(-1, u64::MAX, Some(-1)); test::(-1, u64::MAX - 1, Some(1)); test::(123, u64::MAX, None); test::(-123, u64::MAX, None); test::(-123, u64::MAX - 1, None); } fn checked_pow_properties_helper_unsigned() { unsigned_pair_gen::().test_properties(|(x, y)| { let power = x.checked_pow(y); if let Some(power) = power { if y != 0 { assert!(power >= x); } assert_eq!(power, x.pow(y)); } }); } fn checked_pow_properties_helper_signed() { signed_unsigned_pair_gen::().test_properties(|(x, y)| { let power = x.checked_pow(y); if let Some(power) = power { assert_eq!(power, x.pow(y)); } }); } #[test] fn checked_pow_properties() { apply_fn_to_unsigneds!(checked_pow_properties_helper_unsigned); apply_fn_to_signeds!(checked_pow_properties_helper_signed); } malachite-base-0.4.16/tests/num/arithmetic/checked_square.rs000064400000000000000000000037721046102023000221720ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{signed_gen, unsigned_gen}; #[test] fn test_checked_square() { fn test(x: T, out: Option) { assert_eq!(x.checked_square(), out); } test::(0, Some(0)); test::(1, Some(1)); test::(2, Some(4)); test::(3, Some(9)); test::(10, Some(100)); test::(123, Some(15129)); test::(1000, Some(1000000)); test::(-1, Some(1)); test::(-2, Some(4)); test::(-3, Some(9)); test::(-10, Some(100)); test::(-123, Some(15129)); test::(-1000, Some(1000000)); test::(1000, None); test::(-1000, None); } fn unsigned_checked_square_properties_helper() { unsigned_gen::().test_properties(|x| { let square = x.checked_square(); assert_eq!(square, x.checked_pow(2)); if let Some(square) = square { assert_eq!(x.square(), square); } }); } fn signed_checked_square_properties_helper() { signed_gen::().test_properties(|x| { let square = x.checked_square(); assert_eq!(square, x.checked_pow(2)); if let Some(square) = square { assert_eq!(x.square(), square); } }); } #[test] fn checked_square_properties() { apply_fn_to_unsigneds!(unsigned_checked_square_properties_helper); apply_fn_to_signeds!(signed_checked_square_properties_helper); } malachite-base-0.4.16/tests/num/arithmetic/checked_sub_mul.rs000064400000000000000000000054171046102023000223360ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ signed_pair_gen, signed_triple_gen, unsigned_pair_gen_var_27, unsigned_triple_gen_var_19, }; #[test] fn test_checked_sub_mul() { fn test(x: T, y: T, z: T, out: Option) { assert_eq!(x.checked_sub_mul(y, z), out); } test::(100, 3, 7, Some(79)); test::(60, 5, 10, Some(10)); test::(1000000, 456, 789, Some(640216)); test::(123, -456, 789, Some(359907)); test::(-123, 456, 789, Some(-359907)); test::(127, 2, 100, Some(-73)); test::(-127, -2, 100, Some(73)); test::(-128, 1, 0, Some(-128)); test::(2, 10, 5, None); test::(-127, 2, 100, None); test::(-127, 1, 100, None); test::(127, -1, 100, None); test::(127, -10, 100, None); } fn checked_sub_mul_properties_helper_unsigned() { unsigned_triple_gen_var_19::().test_properties(|(x, y, z)| { let result = x.checked_sub_mul(y, z); assert_eq!(x.checked_sub_mul(z, y), result); assert_eq!(result.is_none(), x.overflowing_sub_mul(y, z).1); }); unsigned_pair_gen_var_27::().test_properties(|(a, b)| { assert_eq!(a.checked_sub_mul(T::ZERO, b), Some(a)); assert_eq!(a.checked_sub_mul(T::ONE, b), a.checked_sub(b)); assert_eq!(a.checked_sub_mul(b, T::ZERO), Some(a)); assert_eq!(a.checked_sub_mul(b, T::ONE), a.checked_sub(b)); }); } fn checked_sub_mul_properties_helper_signed() { signed_triple_gen::().test_properties(|(x, y, z)| { let result = x.checked_sub_mul(y, z); assert_eq!(x.checked_sub_mul(z, y), result); assert_eq!(result.is_none(), x.overflowing_sub_mul(y, z).1); }); signed_pair_gen::().test_properties(|(a, b)| { assert_eq!(a.checked_sub_mul(T::ZERO, b), Some(a)); assert_eq!(a.checked_sub_mul(T::ONE, b), a.checked_sub(b)); assert_eq!(a.checked_sub_mul(b, T::ZERO), Some(a)); assert_eq!(a.checked_sub_mul(b, T::ONE), a.checked_sub(b)); }); } #[test] fn checked_sub_mul_properties() { apply_fn_to_unsigneds!(checked_sub_mul_properties_helper_unsigned); apply_fn_to_signeds!(checked_sub_mul_properties_helper_signed); } malachite-base-0.4.16/tests/num/arithmetic/coprime_with.rs000064400000000000000000000037661046102023000217200ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::coprime_with::{ coprime_with_check_2, coprime_with_check_2_3, coprime_with_check_2_3_5, }; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{unsigned_gen, unsigned_pair_gen_var_27}; #[test] fn test_coprime_with() { fn test(x: T, y: T, out: bool) { assert_eq!(x.coprime_with(y), out); } test::(0, 0, false); test::(0, 1, true); test::(0, 6, false); test::(6, 0, false); test::(1, 6, true); test::(6, 1, true); test::(8, 12, false); test::(54, 24, false); test::(42, 56, false); test::(48, 18, false); test::(3, 5, true); test::(12, 60, false); test::(12, 90, false); test::(25, 14, true); } fn coprime_with_properties_helper() { unsigned_pair_gen_var_27::().test_properties(|(x, y)| { let c = x.coprime_with(y); assert_eq!(x.gcd(y) == T::ONE, c); assert_eq!(coprime_with_check_2(x, y), c); assert_eq!(coprime_with_check_2_3(x, y), c); assert_eq!(coprime_with_check_2_3_5(x, y), c); assert_eq!(y.coprime_with(x), c); }); unsigned_gen::().test_properties(|x| { assert_eq!(x.coprime_with(x), x == T::ONE); assert!(x.coprime_with(T::ONE)); assert_eq!(x.coprime_with(T::ZERO), x == T::ONE); if x != T::MAX { assert!(x.coprime_with(x + T::ONE)); } }); } #[test] fn coprime_with_properties() { apply_fn_to_unsigneds!(coprime_with_properties_helper); } malachite-base-0.4.16/tests/num/arithmetic/div_exact.rs000064400000000000000000000122511046102023000211620ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::rounding_modes::RoundingMode::*; use malachite_base::test_util::generators::{ signed_gen, signed_gen_var_6, signed_pair_gen_var_3, unsigned_gen, unsigned_gen_var_1, unsigned_pair_gen_var_11, }; use std::panic::catch_unwind; #[test] fn test_div_exact() { fn test(x: T, y: T, out: T) { assert_eq!(x.div_exact(y), out); let mut x = x; x.div_exact_assign(y); assert_eq!(x, out); } test::(0, 123, 0); test::(123, 1, 123); test::(123, 123, 1); test::(56088, 123, 456); test::(0, 1000000000000, 0); test::(1000000000000, 1, 1000000000000); test::(1000000000000, 1000000000000, 1); test::(123000000000000, 1000000000000, 123); test::(123000000000000, 123, 1000000000000); test::(121932631112635269000000, 123456789000, 987654321000); test::(0x1fffffffe, 0xffffffff, 2); test::(18446744065119617025, 0xffffffff, 0xffffffff); test::(0, -123, 0); test::(123, -1, -123); test::(123, -123, -1); test::(56088, -123, -456); test::(0, -1000000000000, 0); test::(1000000000000, -1, -1000000000000); test::(1000000000000, -1000000000000, -1); test::(123000000000000, -1000000000000, -123); test::(123000000000000, -123, -1000000000000); test::(121932631112635269000000, -123456789000, -987654321000); test::(0x1fffffffe, -0xffffffff, -2); test::(18446744065119617025, -0xffffffff, -0xffffffff); test::(-123, 1, -123); test::(-123, 123, -1); test::(-56088, 123, -456); test::(-1000000000000, 1, -1000000000000); test::(-1000000000000, 1000000000000, -1); test::(-123000000000000, 1000000000000, -123); test::(-123000000000000, 123, -1000000000000); test::(-121932631112635269000000, 123456789000, -987654321000); test::(-0x1fffffffe, 0xffffffff, -2); test::(-18446744065119617025, 0xffffffff, -0xffffffff); test::(-123, -1, 123); test::(-123, -123, 1); test::(-56088, -123, 456); test::(-1000000000000, -1, 1000000000000); test::(-1000000000000, -1000000000000, 1); test::(-123000000000000, -1000000000000, 123); test::(-123000000000000, -123, 1000000000000); test::(-121932631112635269000000, -123456789000, 987654321000); test::(-0x1fffffffe, -0xffffffff, 2); test::(-18446744065119617025, -0xffffffff, 0xffffffff); } fn div_exact_fail_helper() { assert_panic!(T::ONE.div_exact(T::ZERO)); assert_panic!({ let mut n = T::ONE; n.div_exact_assign(T::ZERO); }); } #[test] pub fn div_exact_fail() { apply_fn_to_primitive_ints!(div_exact_fail_helper); } fn div_exact_properties_helper_unsigned() { unsigned_pair_gen_var_11::().test_properties(|(x, y)| { let mut mut_x = x; mut_x.div_exact_assign(y); let q = mut_x; assert_eq!(x.div_exact(y), q); assert_eq!(x.div_round(y, Exact).0, q); assert_eq!(q * y, x); }); unsigned_gen::().test_properties(|x| { assert_eq!(x.div_exact(T::ONE), x); assert_panic!(x.div_exact(T::ZERO)); assert_panic!({ let mut y = x; y.div_exact_assign(T::ZERO); }); }); unsigned_gen_var_1::().test_properties(|x| { assert_eq!(T::ZERO.div_exact(x), T::ZERO); assert_eq!(x.div_exact(x), T::ONE); }); } fn div_exact_properties_helper_signed() { signed_pair_gen_var_3::().test_properties(|(x, y)| { let mut mut_x = x; mut_x.div_exact_assign(y); let q = mut_x; assert_eq!(x.div_exact(y), q); assert_eq!(x.div_round(y, Exact).0, q); assert_eq!(q * y, x); if x != T::MIN { assert_eq!((-x).div_exact(y), -q); } if y != T::MIN && q != T::MIN { assert_eq!(x.div_exact(-y), -q); } }); signed_gen::().test_properties(|x| { assert_eq!(x.div_exact(T::ONE), x); assert_panic!(x.div_exact(T::ZERO)); assert_panic!({ let mut y = x; y.div_exact_assign(T::ZERO); }); }); signed_gen_var_6::().test_properties(|x| { assert_eq!(T::ZERO.div_exact(x), T::ZERO); assert_eq!(x.div_exact(x), T::ONE); }); } #[test] fn div_exact_properties() { apply_fn_to_unsigneds!(div_exact_properties_helper_unsigned); apply_fn_to_signeds!(div_exact_properties_helper_signed); } malachite-base-0.4.16/tests/num/arithmetic/div_mod.rs000064400000000000000000001123221046102023000206350ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::rounding_modes::RoundingMode::*; use malachite_base::test_util::generators::{ signed_gen, signed_gen_var_6, signed_pair_gen_var_4, unsigned_gen, unsigned_gen_var_1, unsigned_pair_gen_var_12, }; use std::panic::catch_unwind; #[test] fn test_div_mod_and_div_rem_unsigned() { fn test(n: T, d: T, q: T, r: T) { assert_eq!(n.div_mod(d), (q, r)); let mut mut_n = n; assert_eq!(mut_n.div_assign_mod(d), r); assert_eq!(mut_n, q); assert_eq!(n.div_rem(d), (q, r)); let mut mut_n = n; assert_eq!(mut_n.div_assign_rem(d), r); assert_eq!(mut_n, q); } test::(0, 1, 0, 0); test::(0, 123, 0, 0); test::(1, 1, 1, 0); test::(123, 1, 123, 0); test::(123, 123, 1, 0); test::(123, 456, 0, 123); test::(456, 123, 3, 87); test::(u32::MAX, 1, u32::MAX, 0); test::(0xffffffff, 0xffffffff, 1, 0); test::(1000000000000, 1, 1000000000000, 0); test::(1000000000000, 3, 333333333333, 1); test::(1000000000000, 123, 8130081300, 100); test::(1000000000000, 0xffffffff, 232, 3567587560); test::(1000000000000000000000000, 1, 1000000000000000000000000, 0); test::(1000000000000000000000000, 3, 333333333333333333333333, 1); test::(1000000000000000000000000, 123, 8130081300813008130081, 37); test::( 1000000000000000000000000, 0xffffffff, 232830643708079, 3167723695, ); test::( 1000000000000000000000000, 1234567890987, 810000006723, 530068894399, ); test::( 253640751230376270397812803167, 2669936877441, 94998781946290113, 1520301762334, ); test::(3768477692975601, 11447376614057827956, 0, 3768477692975601); test::(3356605361737854, 3081095617839357, 1, 275509743898497); test::( 1098730198198174614195, 953382298040157850476, 1, 145347900158016763719, ); test::( 69738658860594537152875081748, 69738658860594537152875081748, 1, 0, ); test::(1000000000000000000000000, 1000000000000000000000000, 1, 0); test::(0, 1000000000000000000000000, 0, 0); test::(123, 1000000000000000000000000, 0, 123); } fn div_mod_and_div_rem_properties_helper_unsigned() { unsigned_pair_gen_var_12::().test_properties(|(x, y)| { let mut mut_x = x; let r = mut_x.div_assign_mod(y); let q = mut_x; assert_eq!(x.div_mod(y), (q, r)); let mut mut_x = x; let r_alt = mut_x.div_assign_rem(y); let q_alt = mut_x; assert_eq!((q_alt, r_alt), (q, r)); assert_eq!(x.div_rem(y), (q, r)); assert_eq!((x / y, x % y), (q, r)); assert!(r < y); assert_eq!(q * y + r, x); }); unsigned_gen::().test_properties(|x| { assert_eq!(x.div_mod(T::ONE), (x, T::ZERO)); assert_panic!(x.div_mod(T::ZERO)); assert_panic!({ let mut y = x; y.div_assign_mod(T::ZERO) }); }); unsigned_gen_var_1::().test_properties(|x| { assert_eq!(x.div_mod(x), (T::ONE, T::ZERO)); assert_eq!(T::ZERO.div_mod(x), (T::ZERO, T::ZERO)); if x > T::ONE { assert_eq!(T::ONE.div_mod(x), (T::ZERO, T::ONE)); } }); } #[test] fn test_div_mod_signed() { fn test(n: T, d: T, q: T, r: T) { assert_eq!(n.div_mod(d), (q, r)); let mut mut_n = n; assert_eq!(mut_n.div_assign_mod(d), r); assert_eq!(mut_n, q); } test::(0, 1, 0, 0); test::(0, 123, 0, 0); test::(1, 1, 1, 0); test::(123, 1, 123, 0); test::(123, 123, 1, 0); test::(123, 456, 0, 123); test::(456, 123, 3, 87); test::(0xffffffff, 1, 0xffffffff, 0); test::(0xffffffff, 0xffffffff, 1, 0); test::(1000000000000, 1, 1000000000000, 0); test::(1000000000000, 3, 333333333333, 1); test::(1000000000000, 123, 8130081300, 100); test::(1000000000000, 0xffffffff, 232, 3567587560); test::(1000000000000000000000000, 1, 1000000000000000000000000, 0); test::(1000000000000000000000000, 3, 333333333333333333333333, 1); test::(1000000000000000000000000, 123, 8130081300813008130081, 37); test::( 1000000000000000000000000, 0xffffffff, 232830643708079, 3167723695, ); test::( 1000000000000000000000000, 1234567890987, 810000006723, 530068894399, ); test::( 253640751230376270397812803167, 2669936877441, 94998781946290113, 1520301762334, ); test::(3768477692975601, 11447376614057827956, 0, 3768477692975601); test::(3356605361737854, 3081095617839357, 1, 275509743898497); test::( 1098730198198174614195, 953382298040157850476, 1, 145347900158016763719, ); test::( 69738658860594537152875081748, 69738658860594537152875081748, 1, 0, ); test::(1000000000000000000000000, 1000000000000000000000000, 1, 0); test::(0, 1000000000000000000000000, 0, 0); test::(123, 1000000000000000000000000, 0, 123); test::(0, -1, 0, 0); test::(0, -123, 0, 0); test::(1, -1, -1, 0); test::(123, -1, -123, 0); test::(123, -123, -1, 0); test::(123, -456, -1, -333); test::(456, -123, -4, -36); test::(0xffffffff, -1, -0xffffffff, 0); test::(0xffffffff, -0xffffffff, -1, 0); test::(1000000000000, -1, -1000000000000, 0); test::(1000000000000, -3, -333333333334, -2); test::(1000000000000, -123, -8130081301, -23); test::(1000000000000, -0xffffffff, -233, -727379735); test::(1000000000000000000000000, -1, -1000000000000000000000000, 0); test::(1000000000000000000000000, -3, -333333333333333333333334, -2); test::( 1000000000000000000000000, -123, -8130081300813008130082, -86, ); test::( 1000000000000000000000000, -0xffffffff, -232830643708080, -1127243600, ); test::( 1000000000000000000000000, -1234567890987, -810000006724, -704498996588, ); test::( 253640751230376270397812803167, -2669936877441, -94998781946290114, -1149635115107, ); test::( 3768477692975601, -11447376614057827956, -1, -11443608136364852355, ); test::(3356605361737854, -3081095617839357, -2, -2805585873940860); test::( 1098730198198174614195, -953382298040157850476, -2, -808034397882141086757, ); test::( 69738658860594537152875081748, -69738658860594537152875081748, -1, 0, ); test::(1000000000000000000000000, -1000000000000000000000000, -1, 0); test::(0, -1000000000000000000000000, 0, 0); test::( 123, -1000000000000000000000000, -1, -999999999999999999999877, ); test::(-1, 1, -1, 0); test::(-123, 1, -123, 0); test::(-123, 123, -1, 0); test::(-123, 456, -1, 333); test::(-456, 123, -4, 36); test::(-0xffffffff, -1, 0xffffffff, 0); test::(-0xffffffff, 0xffffffff, -1, 0); test::(-1000000000000, 1, -1000000000000, 0); test::(-1000000000000, 3, -333333333334, 2); test::(-1000000000000, 123, -8130081301, 23); test::(-1000000000000, 0xffffffff, -233, 727379735); test::(-1000000000000000000000000, 1, -1000000000000000000000000, 0); test::(-1000000000000000000000000, 3, -333333333333333333333334, 2); test::(-1000000000000000000000000, 123, -8130081300813008130082, 86); test::( -1000000000000000000000000, 0xffffffff, -232830643708080, 1127243600, ); test::( -1000000000000000000000000, 1234567890987, -810000006724, 704498996588, ); test::( -253640751230376270397812803167, 2669936877441, -94998781946290114, 1149635115107, ); test::( -3768477692975601, 11447376614057827956, -1, 11443608136364852355, ); test::(-3356605361737854, 3081095617839357, -2, 2805585873940860); test::( -1098730198198174614195, 953382298040157850476, -2, 808034397882141086757, ); test::( -69738658860594537152875081748, 69738658860594537152875081748, -1, 0, ); test::(-1000000000000000000000000, 1000000000000000000000000, -1, 0); test::( -123, 1000000000000000000000000, -1, 999999999999999999999877, ); test::(-1, -1, 1, 0); test::(-123, -1, 123, 0); test::(-123, -123, 1, 0); test::(-123, -456, 0, -123); test::(-456, -123, 3, -87); test::(-0xffffffff, -1, 0xffffffff, 0); test::(-0xffffffff, -0xffffffff, 1, 0); test::(-1000000000000, -1, 1000000000000, 0); test::(-1000000000000, -3, 333333333333, -1); test::(-1000000000000, -123, 8130081300, -100); test::(-1000000000000, -0xffffffff, 232, -3567587560); test::(-1000000000000000000000000, -1, 1000000000000000000000000, 0); test::(-1000000000000000000000000, -3, 333333333333333333333333, -1); test::( -1000000000000000000000000, -123, 8130081300813008130081, -37, ); test::( -1000000000000000000000000, -0xffffffff, 232830643708079, -3167723695, ); test::( -1000000000000000000000000, -1234567890987, 810000006723, -530068894399, ); test::( -253640751230376270397812803167, -2669936877441, 94998781946290113, -1520301762334, ); test::( -3768477692975601, -11447376614057827956, 0, -3768477692975601, ); test::(-3356605361737854, -3081095617839357, 1, -275509743898497); test::( -1098730198198174614195, -953382298040157850476, 1, -145347900158016763719, ); test::( -69738658860594537152875081748, -69738658860594537152875081748, 1, 0, ); test::(-1000000000000000000000000, -1000000000000000000000000, 1, 0); test::(-123, -1000000000000000000000000, 0, -123); } fn div_mod_fail_helper() { assert_panic!(T::ONE.div_mod(T::ZERO)); assert_panic!({ let mut n = T::ONE; n.div_assign_mod(T::ZERO); }); } fn div_mod_signed_fail_helper() { assert_panic!(T::MIN.div_mod(T::NEGATIVE_ONE)); assert_panic!({ let mut n = T::MIN; n.div_assign_mod(T::NEGATIVE_ONE); }); } #[test] pub fn div_mod_fail() { apply_fn_to_primitive_ints!(div_mod_fail_helper); apply_fn_to_signeds!(div_mod_signed_fail_helper); } fn div_mod_properties_helper_signed() { signed_pair_gen_var_4::().test_properties(|(x, y)| { let mut mut_x = x; let r = mut_x.div_assign_mod(y); let q = mut_x; assert_eq!(x.div_mod(y), (q, r)); let (q_alt, r_alt) = (x.div_round(y, Floor).0, x.mod_op(y)); assert_eq!(q_alt, q); assert_eq!(r_alt, r); assert!(r.lt_abs(&y)); assert!(r == T::ZERO || (r > T::ZERO) == (y > T::ZERO)); if let Some(product) = q.checked_mul(y) { assert_eq!(product + r, x); } else if q > T::ZERO { assert_eq!((q - T::ONE) * y + r + y, x); } else { assert_eq!((q + T::ONE) * y + r - y, x); } if x != T::MIN { let (neg_q, neg_r) = (-x).div_mod(y); assert_eq!(x.ceiling_div_mod(y), (-neg_q, -neg_r)); } if y != T::MIN && (x != T::MIN || y != T::ONE) { let (neg_q, r) = x.div_mod(-y); assert_eq!(x.ceiling_div_mod(y), (-neg_q, r)); } }); signed_gen::().test_properties(|x| { let (q, r) = x.div_mod(T::ONE); assert_eq!(q, x); assert_eq!(r, T::ZERO); if x != T::MIN { let (q, r) = x.div_mod(T::NEGATIVE_ONE); assert_eq!(q, -x); assert_eq!(r, T::ZERO); } assert_panic!(x.div_mod(T::ZERO)); assert_panic!({ let mut y = x; y.div_assign_mod(T::ZERO) }); }); signed_gen_var_6::().test_properties(|x| { assert_eq!(x.div_mod(T::ONE), (x, T::ZERO)); assert_eq!(x.div_mod(x), (T::ONE, T::ZERO)); assert_eq!(T::ZERO.div_mod(x), (T::ZERO, T::ZERO)); if x != T::MIN { assert_eq!(x.div_mod(T::NEGATIVE_ONE), (-x, T::ZERO)); assert_eq!(x.div_mod(-x), (T::NEGATIVE_ONE, T::ZERO)); } if x > T::ONE { assert_eq!(T::ONE.div_mod(x), (T::ZERO, T::ONE)); assert_eq!(T::NEGATIVE_ONE.div_mod(x), (T::NEGATIVE_ONE, x - T::ONE)); } }); } #[test] fn div_mod_properties() { apply_fn_to_unsigneds!(div_mod_and_div_rem_properties_helper_unsigned); apply_fn_to_signeds!(div_mod_properties_helper_signed); } #[test] fn test_div_rem_signed() { fn test(n: T, d: T, q: T, r: T) { assert_eq!(n.div_rem(d), (q, r)); let mut mut_n = n; assert_eq!(mut_n.div_assign_rem(d), r); assert_eq!(mut_n, q); } test::(0, 1, 0, 0); test::(0, 123, 0, 0); test::(1, 1, 1, 0); test::(123, 1, 123, 0); test::(123, 123, 1, 0); test::(123, 456, 0, 123); test::(456, 123, 3, 87); test::(0xffffffff, 1, 0xffffffff, 0); test::(0xffffffff, 0xffffffff, 1, 0); test::(1000000000000, 1, 1000000000000, 0); test::(1000000000000, 3, 333333333333, 1); test::(1000000000000, 123, 8130081300, 100); test::(1000000000000, 0xffffffff, 232, 3567587560); test::(1000000000000000000000000, 1, 1000000000000000000000000, 0); test::(1000000000000000000000000, 3, 333333333333333333333333, 1); test::(1000000000000000000000000, 123, 8130081300813008130081, 37); test::( 1000000000000000000000000, 0xffffffff, 232830643708079, 3167723695, ); test::( 1000000000000000000000000, 1234567890987, 810000006723, 530068894399, ); test::( 253640751230376270397812803167, 2669936877441, 94998781946290113, 1520301762334, ); test::(3768477692975601, 11447376614057827956, 0, 3768477692975601); test::(3356605361737854, 3081095617839357, 1, 275509743898497); test::( 1098730198198174614195, 953382298040157850476, 1, 145347900158016763719, ); test::( 69738658860594537152875081748, 69738658860594537152875081748, 1, 0, ); test::(1000000000000000000000000, 1000000000000000000000000, 1, 0); test::(0, 1000000000000000000000000, 0, 0); test::(123, 1000000000000000000000000, 0, 123); test::(0, -1, 0, 0); test::(0, -123, 0, 0); test::(1, -1, -1, 0); test::(123, -1, -123, 0); test::(123, -123, -1, 0); test::(123, -456, 0, 123); test::(456, -123, -3, 87); test::(0xffffffff, -1, -0xffffffff, 0); test::(0xffffffff, -0xffffffff, -1, 0); test::(1000000000000, -1, -1000000000000, 0); test::(1000000000000, -3, -333333333333, 1); test::(1000000000000, -123, -8130081300, 100); test::(1000000000000, -0xffffffff, -232, 3567587560); test::(1000000000000000000000000, -1, -1000000000000000000000000, 0); test::(1000000000000000000000000, -3, -333333333333333333333333, 1); test::(1000000000000000000000000, -123, -8130081300813008130081, 37); test::( 1000000000000000000000000, -0xffffffff, -232830643708079, 3167723695, ); test::( 1000000000000000000000000, -1234567890987, -810000006723, 530068894399, ); test::( 253640751230376270397812803167, -2669936877441, -94998781946290113, 1520301762334, ); test::(3768477692975601, -11447376614057827956, 0, 3768477692975601); test::(3356605361737854, -3081095617839357, -1, 275509743898497); test::( 1098730198198174614195, -953382298040157850476, -1, 145347900158016763719, ); test::( 69738658860594537152875081748, -69738658860594537152875081748, -1, 0, ); test::(1000000000000000000000000, -1000000000000000000000000, -1, 0); test::(0, -1000000000000000000000000, 0, 0); test::(123, -1000000000000000000000000, 0, 123); test::(-1, 1, -1, 0); test::(-123, 1, -123, 0); test::(-123, 123, -1, 0); test::(-123, 456, 0, -123); test::(-456, 123, -3, -87); test::(-0xffffffff, 1, -0xffffffff, 0); test::(-0xffffffff, 0xffffffff, -1, 0); test::(-1000000000000, 1, -1000000000000, 0); test::(-1000000000000, 3, -333333333333, -1); test::(-1000000000000, 123, -8130081300, -100); test::(-1000000000000, 0xffffffff, -232, -3567587560); test::(-1000000000000000000000000, 1, -1000000000000000000000000, 0); test::(-1000000000000000000000000, 3, -333333333333333333333333, -1); test::( -1000000000000000000000000, 123, -8130081300813008130081, -37, ); test::( -1000000000000000000000000, 0xffffffff, -232830643708079, -3167723695, ); test::( -1000000000000000000000000, 1234567890987, -810000006723, -530068894399, ); test::( -253640751230376270397812803167, 2669936877441, -94998781946290113, -1520301762334, ); test::( -3768477692975601, 11447376614057827956, 0, -3768477692975601, ); test::(-3356605361737854, 3081095617839357, -1, -275509743898497); test::( -1098730198198174614195, 953382298040157850476, -1, -145347900158016763719, ); test::( -69738658860594537152875081748, 69738658860594537152875081748, -1, 0, ); test::(-1000000000000000000000000, 1000000000000000000000000, -1, 0); test::(-123, 1000000000000000000000000, 0, -123); test::(-1, -1, 1, 0); test::(-123, -1, 123, 0); test::(-123, -123, 1, 0); test::(-123, -456, 0, -123); test::(-456, -123, 3, -87); test::(-0xffffffff, -1, 0xffffffff, 0); test::(-0xffffffff, -0xffffffff, 1, 0); test::(-1000000000000, -1, 1000000000000, 0); test::(-1000000000000, -3, 333333333333, -1); test::(-1000000000000, -123, 8130081300, -100); test::(-1000000000000, -0xffffffff, 232, -3567587560); test::(-1000000000000000000000000, -1, 1000000000000000000000000, 0); test::(-1000000000000000000000000, -3, 333333333333333333333333, -1); test::( -1000000000000000000000000, -123, 8130081300813008130081, -37, ); test::( -1000000000000000000000000, -0xffffffff, 232830643708079, -3167723695, ); test::( -1000000000000000000000000, -1234567890987, 810000006723, -530068894399, ); test::( -253640751230376270397812803167, -2669936877441, 94998781946290113, -1520301762334, ); test::( -3768477692975601, -11447376614057827956, 0, -3768477692975601, ); test::(-3356605361737854, -3081095617839357, 1, -275509743898497); test::( -1098730198198174614195, -953382298040157850476, 1, -145347900158016763719, ); test::( -69738658860594537152875081748, -69738658860594537152875081748, 1, 0, ); test::(-1000000000000000000000000, -1000000000000000000000000, 1, 0); test::(-123, -1000000000000000000000000, 0, -123); } fn div_rem_fail_helper() { assert_panic!(T::ONE.div_rem(T::ZERO)); assert_panic!({ let mut n = T::ONE; n.div_assign_rem(T::ZERO); }); } fn div_rem_signed_fail_helper() { assert_panic!(T::MIN.div_rem(T::NEGATIVE_ONE)); assert_panic!({ let mut n = T::MIN; n.div_assign_rem(T::NEGATIVE_ONE); }); } #[test] pub fn div_rem_fail() { apply_fn_to_primitive_ints!(div_rem_fail_helper); apply_fn_to_signeds!(div_rem_signed_fail_helper); } fn div_rem_properties_helper_signed() { signed_pair_gen_var_4::().test_properties(|(x, y)| { let mut mut_x = x; let r = mut_x.div_assign_rem(y); let q = mut_x; assert_eq!(x.div_rem(y), (q, r)); assert_eq!((x / y, x % y), (q, r)); assert!(r.lt_abs(&y)); assert!(r == T::ZERO || (r > T::ZERO) == (x > T::ZERO)); assert_eq!(q * y + r, x); if x != T::MIN { assert_eq!((-x).div_rem(y), (-q, -r)); } if y != T::MIN && (x != T::MIN || y != T::ONE) { assert_eq!(x.div_rem(-y), (-q, r)); } }); signed_gen::().test_properties(|x| { let (q, r) = x.div_rem(T::ONE); assert_eq!(q, x); assert_eq!(r, T::ZERO); if x != T::MIN { let (q, r) = x.div_rem(T::NEGATIVE_ONE); assert_eq!(q, -x); assert_eq!(r, T::ZERO); } assert_panic!(x.div_rem(T::ZERO)); assert_panic!({ let mut y = x; y.div_assign_rem(T::ZERO) }); }); signed_gen_var_6::().test_properties(|x| { assert_eq!(x.div_rem(T::ONE), (x, T::ZERO)); assert_eq!(x.div_rem(x), (T::ONE, T::ZERO)); assert_eq!(T::ZERO.div_rem(x), (T::ZERO, T::ZERO)); if x != T::MIN { assert_eq!(x.div_rem(T::NEGATIVE_ONE), (-x, T::ZERO)); assert_eq!(x.div_rem(-x), (T::NEGATIVE_ONE, T::ZERO)); } if x > T::ONE { assert_eq!(T::ONE.div_rem(x), (T::ZERO, T::ONE)); assert_eq!(T::NEGATIVE_ONE.div_rem(x), (T::ZERO, T::NEGATIVE_ONE)); } }); } #[test] fn div_rem_properties() { apply_fn_to_signeds!(div_rem_properties_helper_signed); } #[test] fn test_ceiling_div_neg_mod() { fn test(n: T, d: T, q: T, r: T) { assert_eq!(n.ceiling_div_neg_mod(d), (q, r)); let mut mut_n = n; assert_eq!(mut_n.ceiling_div_assign_neg_mod(d), r); assert_eq!(mut_n, q); } test::(0, 1, 0, 0); test::(0, 123, 0, 0); test::(1, 1, 1, 0); test::(123, 1, 123, 0); test::(123, 123, 1, 0); test::(123, 456, 1, 333); test::(456, 123, 4, 36); test::(0xffffffff, 1, 0xffffffff, 0); test::(0xffffffff, 0xffffffff, 1, 0); test::(1000000000000, 1, 1000000000000, 0); test::(1000000000000, 3, 333333333334, 2); test::(1000000000000, 123, 8130081301, 23); test::(1000000000000, 0xffffffff, 233, 727379735); test::(1000000000000000000000000, 1, 1000000000000000000000000, 0); test::(1000000000000000000000000, 3, 333333333333333333333334, 2); test::(1000000000000000000000000, 123, 8130081300813008130082, 86); test::( 1000000000000000000000000, 0xffffffff, 232830643708080, 1127243600, ); test::( 1000000000000000000000000, 1234567890987, 810000006724, 704498996588, ); test::( 253640751230376270397812803167, 2669936877441, 94998781946290114, 1149635115107, ); test::( 3768477692975601, 11447376614057827956, 1, 11443608136364852355, ); test::(3356605361737854, 3081095617839357, 2, 2805585873940860); test::( 1098730198198174614195, 953382298040157850476, 2, 808034397882141086757, ); test::( 69738658860594537152875081748, 69738658860594537152875081748, 1, 0, ); test::(1000000000000000000000000, 1000000000000000000000000, 1, 0); test::(0, 1000000000000000000000000, 0, 0); test::(123, 1000000000000000000000000, 1, 999999999999999999999877); } fn ceiling_div_neg_mod_fail_helper() { assert_panic!(T::ONE.ceiling_div_neg_mod(T::ZERO)); assert_panic!({ let mut n = T::ONE; n.ceiling_div_assign_neg_mod(T::ZERO); }); } #[test] pub fn ceiling_div_neg_mod_fail() { apply_fn_to_unsigneds!(ceiling_div_neg_mod_fail_helper); } fn ceiling_div_neg_mod_properties_helper() { unsigned_pair_gen_var_12::().test_properties(|(x, y)| { let mut mut_x = x; let r = mut_x.ceiling_div_assign_neg_mod(y); let q = mut_x; assert_eq!(x.ceiling_div_neg_mod(y), (q, r)); let (q_alt, r_alt) = (x.div_round(y, Ceiling).0, x.neg_mod(y)); assert_eq!(q_alt, q); assert_eq!(r_alt, r); assert!(r < y); if let Some(product) = q.checked_mul(y) { assert_eq!(product - r, x); } else { assert_eq!((q - T::ONE) * y - r + y, x); } }); unsigned_gen::().test_properties(|x| { assert_eq!(x.ceiling_div_neg_mod(T::ONE), (x, T::ZERO)); assert_panic!(x.ceiling_div_neg_mod(T::ZERO)); assert_panic!({ let mut y = x; y.ceiling_div_assign_neg_mod(T::ZERO) }); }); unsigned_gen_var_1::().test_properties(|x| { assert_eq!(x.ceiling_div_neg_mod(x), (T::ONE, T::ZERO)); assert_eq!(T::ZERO.ceiling_div_neg_mod(x), (T::ZERO, T::ZERO)); if x > T::ONE { assert_eq!(T::ONE.ceiling_div_neg_mod(x), (T::ONE, x - T::ONE)); } }); } #[test] fn ceiling_div_neg_mod_properties() { apply_fn_to_unsigneds!(ceiling_div_neg_mod_properties_helper); } #[test] fn test_ceiling_div_mod() { fn test(n: T, d: T, q: T, r: T) { assert_eq!(n.ceiling_div_mod(d), (q, r)); let mut mut_n = n; assert_eq!(mut_n.ceiling_div_assign_mod(d), r); assert_eq!(mut_n, q); } test::(0, 1, 0, 0); test::(0, 123, 0, 0); test::(1, 1, 1, 0); test::(123, 1, 123, 0); test::(123, 123, 1, 0); test::(123, 456, 1, -333); test::(456, 123, 4, -36); test::(0xffffffff, 1, 0xffffffff, 0); test::(0xffffffff, 0xffffffff, 1, 0); test::(1000000000000, 1, 1000000000000, 0); test::(1000000000000, 3, 333333333334, -2); test::(1000000000000, 123, 8130081301, -23); test::(1000000000000, 0xffffffff, 233, -727379735); test::(1000000000000000000000000, 1, 1000000000000000000000000, 0); test::(1000000000000000000000000, 3, 333333333333333333333334, -2); test::(1000000000000000000000000, 123, 8130081300813008130082, -86); test::( 1000000000000000000000000, 0xffffffff, 232830643708080, -1127243600, ); test::( 1000000000000000000000000, 1234567890987, 810000006724, -704498996588, ); test::( 253640751230376270397812803167, 2669936877441, 94998781946290114, -1149635115107, ); test::( 3768477692975601, 11447376614057827956, 1, -11443608136364852355, ); test::(3356605361737854, 3081095617839357, 2, -2805585873940860); test::( 1098730198198174614195, 953382298040157850476, 2, -808034397882141086757, ); test::( 69738658860594537152875081748, 69738658860594537152875081748, 1, 0, ); test::(1000000000000000000000000, 1000000000000000000000000, 1, 0); test::(0, 1000000000000000000000000, 0, 0); test::(123, 1000000000000000000000000, 1, -999999999999999999999877); test::(0, -1, 0, 0); test::(0, -123, 0, 0); test::(1, -1, -1, 0); test::(123, -1, -123, 0); test::(123, -123, -1, 0); test::(123, -456, 0, 123); test::(456, -123, -3, 87); test::(0xffffffff, -1, -0xffffffff, 0); test::(0xffffffff, -0xffffffff, -1, 0); test::(1000000000000, -1, -1000000000000, 0); test::(1000000000000, -3, -333333333333, 1); test::(1000000000000, -123, -8130081300, 100); test::(1000000000000, -0xffffffff, -232, 3567587560); test::(1000000000000000000000000, -1, -1000000000000000000000000, 0); test::(1000000000000000000000000, -3, -333333333333333333333333, 1); test::(1000000000000000000000000, -123, -8130081300813008130081, 37); test::( 1000000000000000000000000, -0xffffffff, -232830643708079, 3167723695, ); test::( 1000000000000000000000000, -1234567890987, -810000006723, 530068894399, ); test::( 253640751230376270397812803167, -2669936877441, -94998781946290113, 1520301762334, ); test::(3768477692975601, -11447376614057827956, 0, 3768477692975601); test::(3356605361737854, -3081095617839357, -1, 275509743898497); test::( 1098730198198174614195, -953382298040157850476, -1, 145347900158016763719, ); test::( 69738658860594537152875081748, -69738658860594537152875081748, -1, 0, ); test::(1000000000000000000000000, -1000000000000000000000000, -1, 0); test::(0, -1000000000000000000000000, 0, 0); test::(123, -1000000000000000000000000, 0, 123); test::(-1, 1, -1, 0); test::(-123, 1, -123, 0); test::(-123, 123, -1, 0); test::(-123, 456, 0, -123); test::(-456, 123, -3, -87); test::(-0xffffffff, 1, -0xffffffff, 0); test::(-0xffffffff, 0xffffffff, -1, 0); test::(-1000000000000, 1, -1000000000000, 0); test::(-1000000000000, 3, -333333333333, -1); test::(-1000000000000, 123, -8130081300, -100); test::(-1000000000000, 0xffffffff, -232, -3567587560); test::(-1000000000000000000000000, 1, -1000000000000000000000000, 0); test::(-1000000000000000000000000, 3, -333333333333333333333333, -1); test::( -1000000000000000000000000, 123, -8130081300813008130081, -37, ); test::( -1000000000000000000000000, 0xffffffff, -232830643708079, -3167723695, ); test::( -1000000000000000000000000, 1234567890987, -810000006723, -530068894399, ); test::( -253640751230376270397812803167, 2669936877441, -94998781946290113, -1520301762334, ); test::( -3768477692975601, 11447376614057827956, 0, -3768477692975601, ); test::(-3356605361737854, 3081095617839357, -1, -275509743898497); test::( -1098730198198174614195, 953382298040157850476, -1, -145347900158016763719, ); test::( -69738658860594537152875081748, 69738658860594537152875081748, -1, 0, ); test::(-1000000000000000000000000, 1000000000000000000000000, -1, 0); test::(0, 1000000000000000000000000, 0, 0); test::(-123, 1000000000000000000000000, 0, -123); test::(-1, -1, 1, 0); test::(-123, -1, 123, 0); test::(-123, -123, 1, 0); test::(-123, -456, 1, 333); test::(-456, -123, 4, 36); test::(-0xffffffff, -1, 0xffffffff, 0); test::(-0xffffffff, -0xffffffff, 1, 0); test::(-1000000000000, -1, 1000000000000, 0); test::(-1000000000000, -3, 333333333334, 2); test::(-1000000000000, -123, 8130081301, 23); test::(-1000000000000, -0xffffffff, 233, 727379735); test::(-1000000000000000000000000, -1, 1000000000000000000000000, 0); test::(-1000000000000000000000000, -3, 333333333333333333333334, 2); test::(-1000000000000000000000000, -123, 8130081300813008130082, 86); test::( -1000000000000000000000000, -0xffffffff, 232830643708080, 1127243600, ); test::( -1000000000000000000000000, -1234567890987, 810000006724, 704498996588, ); test::( -253640751230376270397812803167, -2669936877441, 94998781946290114, 1149635115107, ); test::( -3768477692975601, -11447376614057827956, 1, 11443608136364852355, ); test::(-3356605361737854, -3081095617839357, 2, 2805585873940860); test::( -1098730198198174614195, -953382298040157850476, 2, 808034397882141086757, ); test::( -69738658860594537152875081748, -69738658860594537152875081748, 1, 0, ); test::(-1000000000000000000000000, -1000000000000000000000000, 1, 0); test::(0, -1000000000000000000000000, 0, 0); test::( -123, -1000000000000000000000000, 1, 999999999999999999999877, ); } fn ceiling_div_mod_fail_helper() { assert_panic!(T::ONE.ceiling_div_mod(T::ZERO)); assert_panic!({ let mut n = T::ONE; n.ceiling_div_assign_mod(T::ZERO); }); assert_panic!(T::MIN.ceiling_div_mod(T::NEGATIVE_ONE)); assert_panic!({ let mut n = T::MIN; n.ceiling_div_assign_mod(T::NEGATIVE_ONE); }); } #[test] pub fn ceiling_div_mod_fail() { apply_fn_to_signeds!(ceiling_div_mod_fail_helper); } fn ceiling_div_mod_properties_helper() { signed_pair_gen_var_4::().test_properties(|(x, y)| { let mut mut_x = x; let r = mut_x.ceiling_div_assign_mod(y); let q = mut_x; assert_eq!(x.ceiling_div_mod(y), (q, r)); let (q_alt, r_alt) = (x.div_round(y, Ceiling).0, x.ceiling_mod(y)); assert_eq!(q_alt, q); assert_eq!(r_alt, r); assert!(r.lt_abs(&y)); assert!(r == T::ZERO || (r > T::ZERO) != (y > T::ZERO)); if let Some(product) = q.checked_mul(y) { assert_eq!(product + r, x); } else if q > T::ZERO { assert_eq!((q - T::ONE) * y + r + y, x); } else { assert_eq!((q + T::ONE) * y + r - y, x); } if x != T::MIN { let (neg_q, neg_r) = (-x).ceiling_div_mod(y); assert_eq!(x.div_mod(y), (-neg_q, -neg_r)); } if y != T::MIN && (x != T::MIN || y != T::ONE) { let (neg_q, r) = x.ceiling_div_mod(-y); assert_eq!(x.div_mod(y), (-neg_q, r)); } }); signed_gen::().test_properties(|x| { let (q, r) = x.ceiling_div_mod(T::ONE); assert_eq!(q, x); assert_eq!(r, T::ZERO); if x != T::MIN { let (q, r) = x.ceiling_div_mod(T::NEGATIVE_ONE); assert_eq!(q, -x); assert_eq!(r, T::ZERO); } assert_panic!(x.ceiling_div_mod(T::ZERO)); assert_panic!({ let mut y = x; y.ceiling_div_assign_mod(T::ZERO) }); }); signed_gen_var_6::().test_properties(|x| { assert_eq!(x.ceiling_div_mod(T::ONE), (x, T::ZERO)); if x != T::MIN { assert_eq!(x.ceiling_div_mod(T::NEGATIVE_ONE), (-x, T::ZERO)); } assert_eq!(x.ceiling_div_mod(x), (T::ONE, T::ZERO)); if x != T::MIN { assert_eq!(x.ceiling_div_mod(-x), (T::NEGATIVE_ONE, T::ZERO)); } assert_eq!(T::ZERO.ceiling_div_mod(x), (T::ZERO, T::ZERO)); }); } #[test] fn ceiling_div_mod_properties() { apply_fn_to_signeds!(ceiling_div_mod_properties_helper); } malachite-base-0.4.16/tests/num/arithmetic/div_round.rs000064400000000000000000001112431046102023000212060ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::rounding_modes::exhaustive::exhaustive_rounding_modes; use malachite_base::rounding_modes::RoundingMode::{self, *}; use malachite_base::test_util::generators::{ signed_pair_gen_var_3, signed_pair_gen_var_5, signed_rounding_mode_pair_gen, signed_rounding_mode_pair_gen_var_1, signed_rounding_mode_pair_gen_var_2, signed_rounding_mode_pair_gen_var_3, signed_signed_rounding_mode_triple_gen_var_1, unsigned_pair_gen_var_11, unsigned_pair_gen_var_12, unsigned_pair_gen_var_13, unsigned_rounding_mode_pair_gen, unsigned_rounding_mode_pair_gen_var_1, unsigned_unsigned_rounding_mode_triple_gen_var_1, }; use std::cmp::Ordering::{self, *}; use std::panic::catch_unwind; #[test] fn test_div_round_unsigned() { fn test(n: T, d: T, rm: RoundingMode, q: T, o: Ordering) { assert_eq!(n.div_round(d, rm), (q, o)); let mut mut_n = n; assert_eq!(mut_n.div_round_assign(d, rm), o); assert_eq!(mut_n, q); } test::(0, 1, Down, 0, Equal); test::(0, 1, Floor, 0, Equal); test::(0, 1, Up, 0, Equal); test::(0, 1, Ceiling, 0, Equal); test::(0, 1, Nearest, 0, Equal); test::(0, 1, Exact, 0, Equal); test::(0, 123, Down, 0, Equal); test::(0, 123, Floor, 0, Equal); test::(0, 123, Up, 0, Equal); test::(0, 123, Ceiling, 0, Equal); test::(0, 123, Nearest, 0, Equal); test::(0, 123, Exact, 0, Equal); test::(1, 1, Down, 1, Equal); test::(1, 1, Floor, 1, Equal); test::(1, 1, Up, 1, Equal); test::(1, 1, Ceiling, 1, Equal); test::(1, 1, Nearest, 1, Equal); test::(1, 1, Exact, 1, Equal); test::(123, 1, Down, 123, Equal); test::(123, 1, Floor, 123, Equal); test::(123, 1, Up, 123, Equal); test::(123, 1, Ceiling, 123, Equal); test::(123, 1, Nearest, 123, Equal); test::(123, 1, Exact, 123, Equal); test::(123, 2, Down, 61, Less); test::(123, 2, Floor, 61, Less); test::(123, 2, Up, 62, Greater); test::(123, 2, Ceiling, 62, Greater); test::(123, 2, Nearest, 62, Greater); test::(125, 2, Down, 62, Less); test::(125, 2, Floor, 62, Less); test::(125, 2, Up, 63, Greater); test::(125, 2, Ceiling, 63, Greater); test::(125, 2, Nearest, 62, Less); test::(123, 123, Down, 1, Equal); test::(123, 123, Floor, 1, Equal); test::(123, 123, Up, 1, Equal); test::(123, 123, Ceiling, 1, Equal); test::(123, 123, Nearest, 1, Equal); test::(123, 123, Exact, 1, Equal); test::(123, 456, Down, 0, Less); test::(123, 456, Floor, 0, Less); test::(123, 456, Up, 1, Greater); test::(123, 456, Ceiling, 1, Greater); test::(123, 456, Nearest, 0, Less); test::(1000000000000, 1, Down, 1000000000000, Equal); test::(1000000000000, 1, Floor, 1000000000000, Equal); test::(1000000000000, 1, Up, 1000000000000, Equal); test::(1000000000000, 1, Ceiling, 1000000000000, Equal); test::(1000000000000, 1, Nearest, 1000000000000, Equal); test::(1000000000000, 1, Exact, 1000000000000, Equal); test::(1000000000000, 3, Down, 333333333333, Less); test::(1000000000000, 3, Floor, 333333333333, Less); test::(1000000000000, 3, Up, 333333333334, Greater); test::(1000000000000, 3, Ceiling, 333333333334, Greater); test::(1000000000000, 3, Nearest, 333333333333, Less); test::(999999999999, 2, Down, 499999999999, Less); test::(999999999999, 2, Floor, 499999999999, Less); test::(999999999999, 2, Up, 500000000000, Greater); test::(999999999999, 2, Ceiling, 500000000000, Greater); test::(999999999999, 2, Nearest, 500000000000, Greater); test::(1000000000001, 2, Down, 500000000000, Less); test::(1000000000001, 2, Floor, 500000000000, Less); test::(1000000000001, 2, Up, 500000000001, Greater); test::(1000000000001, 2, Ceiling, 500000000001, Greater); test::(1000000000001, 2, Nearest, 500000000000, Less); test::( 1000000000000000000000000, 0xffffffff, Down, 232830643708079, Less, ); test::( 1000000000000000000000000, 0xffffffff, Floor, 232830643708079, Less, ); test::( 1000000000000000000000000, 0xffffffff, Up, 232830643708080, Greater, ); test::( 1000000000000000000000000, 0xffffffff, Ceiling, 232830643708080, Greater, ); test::( 1000000000000000000000000, 0xffffffff, Nearest, 232830643708080, Greater, ); test::( 1000000000000000000000000, 1000000000000, Down, 1000000000000, Equal, ); test::( 1000000000000000000000000, 1000000000000, Floor, 1000000000000, Equal, ); test::( 1000000000000000000000000, 1000000000000, Up, 1000000000000, Equal, ); test::( 1000000000000000000000000, 1000000000000, Ceiling, 1000000000000, Equal, ); test::( 1000000000000000000000000, 1000000000000, Nearest, 1000000000000, Equal, ); test::( 1000000000000000000000000, 1000000000000, Exact, 1000000000000, Equal, ); test::( 1000000000000000000000000, 1000000000001, Down, 999999999999, Less, ); test::( 1000000000000000000000000, 1000000000001, Floor, 999999999999, Less, ); test::( 1000000000000000000000000, 1000000000001, Up, 1000000000000, Greater, ); test::( 1000000000000000000000000, 1000000000001, Ceiling, 1000000000000, Greater, ); test::( 1000000000000000000000000, 1000000000001, Nearest, 999999999999, Less, ); test::( 2999999999999999999999999, 2000000000000000000000000, Nearest, 1, Less, ); test::( 3000000000000000000000000, 2000000000000000000000000, Nearest, 2, Greater, ); test::( 3000000000000000000000001, 2000000000000000000000000, Nearest, 2, Greater, ); } #[test] fn test_div_round_signed() { fn test(n: T, d: T, rm: RoundingMode, q: T, o: Ordering) { assert_eq!(n.div_round(d, rm), (q, o)); let mut mut_n = n; assert_eq!(mut_n.div_round_assign(d, rm), o); assert_eq!(mut_n, q); } test::(0, 1, Down, 0, Equal); test::(0, 1, Floor, 0, Equal); test::(0, 1, Up, 0, Equal); test::(0, 1, Ceiling, 0, Equal); test::(0, 1, Nearest, 0, Equal); test::(0, 1, Exact, 0, Equal); test::(0, 123, Down, 0, Equal); test::(0, 123, Floor, 0, Equal); test::(0, 123, Up, 0, Equal); test::(0, 123, Ceiling, 0, Equal); test::(0, 123, Nearest, 0, Equal); test::(0, 123, Exact, 0, Equal); test::(1, 1, Down, 1, Equal); test::(1, 1, Floor, 1, Equal); test::(1, 1, Up, 1, Equal); test::(1, 1, Ceiling, 1, Equal); test::(1, 1, Nearest, 1, Equal); test::(1, 1, Exact, 1, Equal); test::(123, 1, Down, 123, Equal); test::(123, 1, Floor, 123, Equal); test::(123, 1, Up, 123, Equal); test::(123, 1, Ceiling, 123, Equal); test::(123, 1, Nearest, 123, Equal); test::(123, 1, Exact, 123, Equal); test::(123, 2, Down, 61, Less); test::(123, 2, Floor, 61, Less); test::(123, 2, Up, 62, Greater); test::(123, 2, Ceiling, 62, Greater); test::(123, 2, Nearest, 62, Greater); test::(125, 2, Down, 62, Less); test::(125, 2, Floor, 62, Less); test::(125, 2, Up, 63, Greater); test::(125, 2, Ceiling, 63, Greater); test::(125, 2, Nearest, 62, Less); test::(123, 123, Down, 1, Equal); test::(123, 123, Floor, 1, Equal); test::(123, 123, Up, 1, Equal); test::(123, 123, Ceiling, 1, Equal); test::(123, 123, Nearest, 1, Equal); test::(123, 123, Exact, 1, Equal); test::(123, 456, Down, 0, Less); test::(123, 456, Floor, 0, Less); test::(123, 456, Up, 1, Greater); test::(123, 456, Ceiling, 1, Greater); test::(123, 456, Nearest, 0, Less); test::(1000000000000, 1, Down, 1000000000000, Equal); test::(1000000000000, 1, Floor, 1000000000000, Equal); test::(1000000000000, 1, Up, 1000000000000, Equal); test::(1000000000000, 1, Ceiling, 1000000000000, Equal); test::(1000000000000, 1, Nearest, 1000000000000, Equal); test::(1000000000000, 1, Exact, 1000000000000, Equal); test::(1000000000000, 3, Down, 333333333333, Less); test::(1000000000000, 3, Floor, 333333333333, Less); test::(1000000000000, 3, Up, 333333333334, Greater); test::(1000000000000, 3, Ceiling, 333333333334, Greater); test::(1000000000000, 3, Nearest, 333333333333, Less); test::(999999999999, 2, Down, 499999999999, Less); test::(999999999999, 2, Floor, 499999999999, Less); test::(999999999999, 2, Up, 500000000000, Greater); test::(999999999999, 2, Ceiling, 500000000000, Greater); test::(999999999999, 2, Nearest, 500000000000, Greater); test::(1000000000001, 2, Down, 500000000000, Less); test::(1000000000001, 2, Floor, 500000000000, Less); test::(1000000000001, 2, Up, 500000000001, Greater); test::(1000000000001, 2, Ceiling, 500000000001, Greater); test::(1000000000001, 2, Nearest, 500000000000, Less); test::( 1000000000000000000000000, 0xffffffff, Down, 232830643708079, Less, ); test::( 1000000000000000000000000, 0xffffffff, Floor, 232830643708079, Less, ); test::( 1000000000000000000000000, 0xffffffff, Up, 232830643708080, Greater, ); test::( 1000000000000000000000000, 0xffffffff, Ceiling, 232830643708080, Greater, ); test::( 1000000000000000000000000, 0xffffffff, Nearest, 232830643708080, Greater, ); test::( 1000000000000000000000000, 1000000000000, Down, 1000000000000, Equal, ); test::( 1000000000000000000000000, 1000000000000, Floor, 1000000000000, Equal, ); test::( 1000000000000000000000000, 1000000000000, Up, 1000000000000, Equal, ); test::( 1000000000000000000000000, 1000000000000, Ceiling, 1000000000000, Equal, ); test::( 1000000000000000000000000, 1000000000000, Nearest, 1000000000000, Equal, ); test::( 1000000000000000000000000, 1000000000000, Exact, 1000000000000, Equal, ); test::( 1000000000000000000000000, 1000000000001, Down, 999999999999, Less, ); test::( 1000000000000000000000000, 1000000000001, Floor, 999999999999, Less, ); test::( 1000000000000000000000000, 1000000000001, Up, 1000000000000, Greater, ); test::( 1000000000000000000000000, 1000000000001, Ceiling, 1000000000000, Greater, ); test::( 1000000000000000000000000, 1000000000001, Nearest, 999999999999, Less, ); test::( 2999999999999999999999999, 2000000000000000000000000, Nearest, 1, Less, ); test::( 3000000000000000000000000, 2000000000000000000000000, Nearest, 2, Greater, ); test::( 3000000000000000000000001, 2000000000000000000000000, Nearest, 2, Greater, ); test::(0, -1, Down, 0, Equal); test::(0, -1, Floor, 0, Equal); test::(0, -1, Up, 0, Equal); test::(0, -1, Ceiling, 0, Equal); test::(0, -1, Nearest, 0, Equal); test::(0, -1, Exact, 0, Equal); test::(0, -123, Down, 0, Equal); test::(0, -123, Floor, 0, Equal); test::(0, -123, Up, 0, Equal); test::(0, -123, Ceiling, 0, Equal); test::(0, -123, Nearest, 0, Equal); test::(0, -123, Exact, 0, Equal); test::(1, -1, Down, -1, Equal); test::(1, -1, Floor, -1, Equal); test::(1, -1, Up, -1, Equal); test::(1, -1, Ceiling, -1, Equal); test::(1, -1, Nearest, -1, Equal); test::(1, -1, Exact, -1, Equal); test::(123, -1, Down, -123, Equal); test::(123, -1, Floor, -123, Equal); test::(123, -1, Up, -123, Equal); test::(123, -1, Ceiling, -123, Equal); test::(123, -1, Nearest, -123, Equal); test::(123, -1, Exact, -123, Equal); test::(123, -2, Down, -61, Greater); test::(123, -2, Floor, -62, Less); test::(123, -2, Up, -62, Less); test::(123, -2, Ceiling, -61, Greater); test::(123, -2, Nearest, -62, Less); test::(125, -2, Down, -62, Greater); test::(125, -2, Floor, -63, Less); test::(125, -2, Up, -63, Less); test::(125, -2, Ceiling, -62, Greater); test::(125, -2, Nearest, -62, Greater); test::(123, -123, Down, -1, Equal); test::(123, -123, Floor, -1, Equal); test::(123, -123, Up, -1, Equal); test::(123, -123, Ceiling, -1, Equal); test::(123, -123, Nearest, -1, Equal); test::(123, -123, Exact, -1, Equal); test::(123, -456, Down, 0, Greater); test::(123, -456, Floor, -1, Less); test::(123, -456, Up, -1, Less); test::(123, -456, Ceiling, 0, Greater); test::(123, -456, Nearest, 0, Greater); test::(1000000000000, -1, Down, -1000000000000, Equal); test::(1000000000000, -1, Floor, -1000000000000, Equal); test::(1000000000000, -1, Up, -1000000000000, Equal); test::(1000000000000, -1, Ceiling, -1000000000000, Equal); test::(1000000000000, -1, Nearest, -1000000000000, Equal); test::(1000000000000, -1, Exact, -1000000000000, Equal); test::(1000000000000, -3, Down, -333333333333, Greater); test::(1000000000000, -3, Floor, -333333333334, Less); test::(1000000000000, -3, Up, -333333333334, Less); test::(1000000000000, -3, Ceiling, -333333333333, Greater); test::(1000000000000, -3, Nearest, -333333333333, Greater); test::(999999999999, -2, Down, -499999999999, Greater); test::(999999999999, -2, Floor, -500000000000, Less); test::(999999999999, -2, Up, -500000000000, Less); test::(999999999999, -2, Ceiling, -499999999999, Greater); test::(999999999999, -2, Nearest, -500000000000, Less); test::(1000000000001, -2, Down, -500000000000, Greater); test::(1000000000001, -2, Floor, -500000000001, Less); test::(1000000000001, -2, Up, -500000000001, Less); test::(1000000000001, -2, Ceiling, -500000000000, Greater); test::(1000000000001, -2, Nearest, -500000000000, Greater); test::( 1000000000000000000000000, -0xffffffff, Down, -232830643708079, Greater, ); test::( 1000000000000000000000000, -0xffffffff, Floor, -232830643708080, Less, ); test::( 1000000000000000000000000, -0xffffffff, Up, -232830643708080, Less, ); test::( 1000000000000000000000000, -0xffffffff, Ceiling, -232830643708079, Greater, ); test::( 1000000000000000000000000, -0xffffffff, Nearest, -232830643708080, Less, ); test::( 1000000000000000000000000, -1000000000000, Down, -1000000000000, Equal, ); test::( 1000000000000000000000000, -1000000000000, Floor, -1000000000000, Equal, ); test::( 1000000000000000000000000, -1000000000000, Up, -1000000000000, Equal, ); test::( 1000000000000000000000000, -1000000000000, Ceiling, -1000000000000, Equal, ); test::( 1000000000000000000000000, -1000000000000, Nearest, -1000000000000, Equal, ); test::( 1000000000000000000000000, -1000000000000, Exact, -1000000000000, Equal, ); test::( 1000000000000000000000000, -1000000000001, Down, -999999999999, Greater, ); test::( 1000000000000000000000000, -1000000000001, Floor, -1000000000000, Less, ); test::( 1000000000000000000000000, -1000000000001, Up, -1000000000000, Less, ); test::( 1000000000000000000000000, -1000000000001, Ceiling, -999999999999, Greater, ); test::( 1000000000000000000000000, -1000000000001, Nearest, -999999999999, Greater, ); test::( 2999999999999999999999999, -2000000000000000000000000, Nearest, -1, Greater, ); test::( 3000000000000000000000000, -2000000000000000000000000, Nearest, -2, Less, ); test::( 3000000000000000000000001, -2000000000000000000000000, Nearest, -2, Less, ); test::(-1, 1, Down, -1, Equal); test::(-1, 1, Floor, -1, Equal); test::(-1, 1, Up, -1, Equal); test::(-1, 1, Ceiling, -1, Equal); test::(-1, 1, Nearest, -1, Equal); test::(-1, 1, Exact, -1, Equal); test::(-123, 1, Down, -123, Equal); test::(-123, 1, Floor, -123, Equal); test::(-123, 1, Up, -123, Equal); test::(-123, 1, Ceiling, -123, Equal); test::(-123, 1, Nearest, -123, Equal); test::(-123, 1, Exact, -123, Equal); test::(-123, 2, Down, -61, Greater); test::(-123, 2, Floor, -62, Less); test::(-123, 2, Up, -62, Less); test::(-123, 2, Ceiling, -61, Greater); test::(-123, 2, Nearest, -62, Less); test::(-125, 2, Down, -62, Greater); test::(-125, 2, Floor, -63, Less); test::(-125, 2, Up, -63, Less); test::(-125, 2, Ceiling, -62, Greater); test::(-125, 2, Nearest, -62, Greater); test::(-123, 123, Down, -1, Equal); test::(-123, 123, Floor, -1, Equal); test::(-123, 123, Up, -1, Equal); test::(-123, 123, Ceiling, -1, Equal); test::(-123, 123, Nearest, -1, Equal); test::(-123, 123, Exact, -1, Equal); test::(-123, 456, Down, 0, Greater); test::(-123, 456, Floor, -1, Less); test::(-123, 456, Up, -1, Less); test::(-123, 456, Ceiling, 0, Greater); test::(-123, 456, Nearest, 0, Greater); test::(-1000000000000, 1, Down, -1000000000000, Equal); test::(-1000000000000, 1, Floor, -1000000000000, Equal); test::(-1000000000000, 1, Up, -1000000000000, Equal); test::(-1000000000000, 1, Ceiling, -1000000000000, Equal); test::(-1000000000000, 1, Nearest, -1000000000000, Equal); test::(-1000000000000, 1, Exact, -1000000000000, Equal); test::(-1000000000000, 3, Down, -333333333333, Greater); test::(-1000000000000, 3, Floor, -333333333334, Less); test::(-1000000000000, 3, Up, -333333333334, Less); test::(-1000000000000, 3, Ceiling, -333333333333, Greater); test::(-1000000000000, 3, Nearest, -333333333333, Greater); test::(-999999999999, 2, Down, -499999999999, Greater); test::(-999999999999, 2, Floor, -500000000000, Less); test::(-999999999999, 2, Up, -500000000000, Less); test::(-999999999999, 2, Ceiling, -499999999999, Greater); test::(-999999999999, 2, Nearest, -500000000000, Less); test::(-1000000000001, 2, Down, -500000000000, Greater); test::(-1000000000001, 2, Floor, -500000000001, Less); test::(-1000000000001, 2, Up, -500000000001, Less); test::(-1000000000001, 2, Ceiling, -500000000000, Greater); test::(-1000000000001, 2, Nearest, -500000000000, Greater); test::( -1000000000000000000000000, 0xffffffff, Down, -232830643708079, Greater, ); test::( -1000000000000000000000000, 0xffffffff, Floor, -232830643708080, Less, ); test::( -1000000000000000000000000, 0xffffffff, Up, -232830643708080, Less, ); test::( -1000000000000000000000000, 0xffffffff, Ceiling, -232830643708079, Greater, ); test::( -1000000000000000000000000, 0xffffffff, Nearest, -232830643708080, Less, ); test::( -1000000000000000000000000, 1000000000000, Down, -1000000000000, Equal, ); test::( -1000000000000000000000000, 1000000000000, Floor, -1000000000000, Equal, ); test::( -1000000000000000000000000, 1000000000000, Up, -1000000000000, Equal, ); test::( -1000000000000000000000000, 1000000000000, Ceiling, -1000000000000, Equal, ); test::( -1000000000000000000000000, 1000000000000, Nearest, -1000000000000, Equal, ); test::( -1000000000000000000000000, 1000000000000, Exact, -1000000000000, Equal, ); test::( -1000000000000000000000000, 1000000000001, Down, -999999999999, Greater, ); test::( -1000000000000000000000000, 1000000000001, Floor, -1000000000000, Less, ); test::( -1000000000000000000000000, 1000000000001, Up, -1000000000000, Less, ); test::( -1000000000000000000000000, 1000000000001, Ceiling, -999999999999, Greater, ); test::( -1000000000000000000000000, 1000000000001, Nearest, -999999999999, Greater, ); test::( -2999999999999999999999999, 2000000000000000000000000, Nearest, -1, Greater, ); test::( -3000000000000000000000000, 2000000000000000000000000, Nearest, -2, Less, ); test::( -3000000000000000000000001, 2000000000000000000000000, Nearest, -2, Less, ); test::(-1, -1, Down, 1, Equal); test::(-1, -1, Floor, 1, Equal); test::(-1, -1, Up, 1, Equal); test::(-1, -1, Ceiling, 1, Equal); test::(-1, -1, Nearest, 1, Equal); test::(-1, -1, Exact, 1, Equal); test::(-123, -1, Down, 123, Equal); test::(-123, -1, Floor, 123, Equal); test::(-123, -1, Up, 123, Equal); test::(-123, -1, Ceiling, 123, Equal); test::(-123, -1, Nearest, 123, Equal); test::(-123, -1, Exact, 123, Equal); test::(-123, -2, Down, 61, Less); test::(-123, -2, Floor, 61, Less); test::(-123, -2, Up, 62, Greater); test::(-123, -2, Ceiling, 62, Greater); test::(-123, -2, Nearest, 62, Greater); test::(-125, -2, Down, 62, Less); test::(-125, -2, Floor, 62, Less); test::(-125, -2, Up, 63, Greater); test::(-125, -2, Ceiling, 63, Greater); test::(-125, -2, Nearest, 62, Less); test::(-123, -123, Down, 1, Equal); test::(-123, -123, Floor, 1, Equal); test::(-123, -123, Up, 1, Equal); test::(-123, -123, Ceiling, 1, Equal); test::(-123, -123, Nearest, 1, Equal); test::(-123, -123, Exact, 1, Equal); test::(-123, -456, Down, 0, Less); test::(-123, -456, Floor, 0, Less); test::(-123, -456, Up, 1, Greater); test::(-123, -456, Ceiling, 1, Greater); test::(-123, -456, Nearest, 0, Less); test::(-1000000000000, -1, Down, 1000000000000, Equal); test::(-1000000000000, -1, Floor, 1000000000000, Equal); test::(-1000000000000, -1, Up, 1000000000000, Equal); test::(-1000000000000, -1, Ceiling, 1000000000000, Equal); test::(-1000000000000, -1, Nearest, 1000000000000, Equal); test::(-1000000000000, -1, Exact, 1000000000000, Equal); test::(-1000000000000, -3, Down, 333333333333, Less); test::(-1000000000000, -3, Floor, 333333333333, Less); test::(-1000000000000, -3, Up, 333333333334, Greater); test::(-1000000000000, -3, Ceiling, 333333333334, Greater); test::(-1000000000000, -3, Nearest, 333333333333, Less); test::(-999999999999, -2, Down, 499999999999, Less); test::(-999999999999, -2, Floor, 499999999999, Less); test::(-999999999999, -2, Up, 500000000000, Greater); test::(-999999999999, -2, Ceiling, 500000000000, Greater); test::(-999999999999, -2, Nearest, 500000000000, Greater); test::(-1000000000001, -2, Down, 500000000000, Less); test::(-1000000000001, -2, Floor, 500000000000, Less); test::(-1000000000001, -2, Up, 500000000001, Greater); test::(-1000000000001, -2, Ceiling, 500000000001, Greater); test::(-1000000000001, -2, Nearest, 500000000000, Less); test::( -1000000000000000000000000, -0xffffffff, Down, 232830643708079, Less, ); test::( -1000000000000000000000000, -0xffffffff, Floor, 232830643708079, Less, ); test::( -1000000000000000000000000, -0xffffffff, Up, 232830643708080, Greater, ); test::( -1000000000000000000000000, -0xffffffff, Ceiling, 232830643708080, Greater, ); test::( -1000000000000000000000000, -0xffffffff, Nearest, 232830643708080, Greater, ); test::( -1000000000000000000000000, -1000000000000, Down, 1000000000000, Equal, ); test::( -1000000000000000000000000, -1000000000000, Floor, 1000000000000, Equal, ); test::( -1000000000000000000000000, -1000000000000, Up, 1000000000000, Equal, ); test::( -1000000000000000000000000, -1000000000000, Ceiling, 1000000000000, Equal, ); test::( -1000000000000000000000000, -1000000000000, Nearest, 1000000000000, Equal, ); test::( -1000000000000000000000000, -1000000000000, Exact, 1000000000000, Equal, ); test::( -1000000000000000000000000, -1000000000001, Down, 999999999999, Less, ); test::( -1000000000000000000000000, -1000000000001, Floor, 999999999999, Less, ); test::( -1000000000000000000000000, -1000000000001, Up, 1000000000000, Greater, ); test::( -1000000000000000000000000, -1000000000001, Ceiling, 1000000000000, Greater, ); test::( -1000000000000000000000000, -1000000000001, Nearest, 999999999999, Less, ); test::( -2999999999999999999999999, -2000000000000000000000000, Nearest, 1, Less, ); test::( -3000000000000000000000000, -2000000000000000000000000, Nearest, 2, Greater, ); test::( -3000000000000000000000001, -2000000000000000000000000, Nearest, 2, Greater, ); test::(-128, 1, Down, -128, Equal); test::(-128, 1, Up, -128, Equal); test::(-128, 1, Floor, -128, Equal); test::(-128, 1, Ceiling, -128, Equal); test::(-128, 1, Nearest, -128, Equal); test::(-128, 1, Exact, -128, Equal); } fn div_round_fail_helper() { assert_panic!(T::exact_from(10).div_round(T::ZERO, Floor)); assert_panic!(T::exact_from(10).div_round(T::exact_from(3), Exact)); assert_panic!(T::exact_from(10).div_round_assign(T::ZERO, Floor)); assert_panic!(T::exact_from(10).div_round_assign(T::exact_from(3), Exact)); } fn div_round_signed_fail_helper() { assert_panic!(T::MIN.div_round(T::NEGATIVE_ONE, Floor)); assert_panic!({ let mut n = T::MIN; n.div_round_assign(T::NEGATIVE_ONE, Floor); }); } #[test] fn div_round_fail() { apply_fn_to_primitive_ints!(div_round_fail_helper); apply_fn_to_signeds!(div_round_signed_fail_helper); } fn div_round_properties_helper_unsigned() { unsigned_unsigned_rounding_mode_triple_gen_var_1::().test_properties(|(x, y, rm)| { let mut mut_x = x; let o = mut_x.div_round_assign(y, rm); let q = mut_x; assert_eq!(x.div_round(y, rm), (q, o)); assert!(q <= x); assert_eq!(x.divisible_by(y), o == Equal); match rm { Floor | Down => assert_ne!(o, Greater), Ceiling | Up => assert_ne!(o, Less), Exact => assert_eq!(o, Equal), _ => {} } if let Some(product) = q.checked_mul(y) { assert_eq!(product.cmp(&x), o); } if o == Equal { for rm in exhaustive_rounding_modes() { assert_eq!(x.div_round(y, rm), (q, Equal)); } } else { assert_panic!(x.div_round(y, Exact)); } }); unsigned_pair_gen_var_12::().test_properties(|(x, y)| { assert_eq!(x.ceiling_div_neg_mod(y).0, x.div_round(y, Ceiling).0); }); unsigned_pair_gen_var_11::().test_properties(|(x, y)| { let q = x.div_exact(y); let o = Equal; assert_eq!(x.div_round(y, Down), (q, o)); assert_eq!(x.div_round(y, Up), (q, o)); assert_eq!(x.div_round(y, Floor), (q, o)); assert_eq!(x.div_round(y, Ceiling), (q, o)); assert_eq!(x.div_round(y, Nearest), (q, o)); assert_eq!(x.div_round(y, Exact), (q, o)); }); unsigned_pair_gen_var_13::().test_properties(|(x, y)| { let down = x.div_round(y, Down); assert_eq!(down.1, Less); let up = (down.0 + T::ONE, Greater); assert_eq!(x.div_round(y, Up), up); assert_eq!(x.div_round(y, Floor), down); assert_eq!(x.div_round(y, Ceiling), up); let nearest = x.div_round(y, Nearest); assert!(nearest == down || nearest == up); }); unsigned_rounding_mode_pair_gen::().test_properties(|(x, rm)| { assert_eq!(x.div_round(T::ONE, rm), (x, Equal)); assert_panic!(x.div_round(T::ZERO, rm)); assert_panic!({ let mut y = x; y.div_round_assign(T::ZERO, rm) }); }); unsigned_rounding_mode_pair_gen_var_1::().test_properties(|(x, rm)| { assert_eq!(T::ZERO.div_round(x, rm), (T::ZERO, Equal)); assert_eq!(x.div_round(x, rm), (T::ONE, Equal)); }); } fn div_round_properties_helper_signed() { signed_signed_rounding_mode_triple_gen_var_1::().test_properties(|(x, y, rm)| { let mut mut_x = x; let o = mut_x.div_round_assign(y, rm); let q = mut_x; assert_eq!(x.div_round(y, rm), (q, o)); assert!(q.le_abs(&x)); assert_eq!(x.divisible_by(y), o == Equal); if x != T::MIN { let (q_alt, o_alt) = (-x).div_round(y, -rm); assert_eq!(-q_alt, q); assert_eq!(o_alt.reverse(), o); } if y != T::MIN && (x != T::MIN || (y != T::ONE && y != T::NEGATIVE_ONE)) { let (q_alt, o_alt) = x.div_round(-y, -rm); assert_eq!(-q_alt, q); assert_eq!(o_alt.reverse(), o); } match ((x >= T::ZERO) == (y >= T::ZERO), rm) { (_, Floor) | (true, Down) | (false, Up) => { assert_ne!(o, Greater); } (_, Ceiling) | (true, Up) | (false, Down) => { assert_ne!(o, Less); } (_, Exact) => assert_eq!(o, Equal), _ => {} } if let Some(product) = q.checked_mul(y) { assert_eq!(product.cmp(&x), if y >= T::ZERO { o } else { o.reverse() }); } if o == Equal { for rm in exhaustive_rounding_modes() { assert_eq!(x.div_round(y, rm), (q, Equal)); } } else { assert_panic!(x.div_round(y, Exact)); } }); signed_pair_gen_var_3::().test_properties(|(x, y)| { let q = x.div_exact(y); let o = Equal; assert_eq!(x.div_round(y, Down), (q, o)); assert_eq!(x.div_round(y, Up), (q, o)); assert_eq!(x.div_round(y, Floor), (q, o)); assert_eq!(x.div_round(y, Ceiling), (q, o)); assert_eq!(x.div_round(y, Nearest), (q, o)); assert_eq!(x.div_round(y, Exact), (q, o)); }); signed_pair_gen_var_5::().test_properties(|(x, y)| { let down = x.div_round(y, Down); let up = if (x >= T::ZERO) == (y >= T::ZERO) { (down.0 + T::ONE, Greater) } else { (down.0 - T::ONE, Less) }; let floor = x.div_round(y, Floor); let ceiling = (floor.0 + T::ONE, Greater); assert_eq!(x.div_round(y, Up), up); assert_eq!(x.div_round(y, Ceiling), ceiling); let nearest = x.div_round(y, Nearest); assert!(nearest == down || nearest == up); }); signed_rounding_mode_pair_gen::().test_properties(|(x, rm)| { assert_eq!(x.div_round(T::ONE, rm), (x, Equal)); assert_panic!(x.div_round(T::ZERO, rm)); assert_panic!({ let mut y = x; y.div_round_assign(T::ZERO, rm) }); }); signed_rounding_mode_pair_gen_var_2::().test_properties(|(x, rm)| { assert_eq!(x.div_round(T::NEGATIVE_ONE, rm), (-x, Equal)); }); signed_rounding_mode_pair_gen_var_1::().test_properties(|(x, rm)| { assert_eq!(T::ZERO.div_round(x, rm), (T::ZERO, Equal)); assert_eq!(x.div_round(x, rm), (T::ONE, Equal)); }); signed_rounding_mode_pair_gen_var_3::().test_properties(|(x, rm)| { assert_eq!(x.div_round(-x, rm), (T::NEGATIVE_ONE, Equal)); assert_eq!((-x).div_round(x, rm), (T::NEGATIVE_ONE, Equal)); }); } #[test] fn div_round_properties() { apply_fn_to_unsigneds!(div_round_properties_helper_unsigned); apply_fn_to_signeds!(div_round_properties_helper_signed); } malachite-base-0.4.16/tests/num/arithmetic/divisible_by.rs000064400000000000000000000167001046102023000216630ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ signed_gen, signed_gen_var_6, signed_pair_gen, signed_pair_gen_var_3, signed_pair_gen_var_5, unsigned_gen, unsigned_gen_var_1, unsigned_pair_gen_var_11, unsigned_pair_gen_var_13, unsigned_pair_gen_var_27, }; #[test] fn test_divisible_by() { fn test(x: T, y: T, out: bool) { assert_eq!(x.divisible_by(y), out); } test::(0, 0, true); test::(1, 0, false); test::(1000000000000, 0, false); test::(0, 1, true); test::(0, 123, true); test::(1, 1, true); test::(123, 1, true); test::(123, 123, true); test::(123, 456, false); test::(456, 123, false); test::(369, 123, true); test::(0xffffffff, 1, true); test::(u32::MAX, u32::MAX, true); test::(1000000000000, 1, true); test::(1000000000000, 3, false); test::(1000000000002, 3, true); test::(1000000000000, 123, false); test::(1000000000000, 0xffffffff, false); test::(1000000000000000000000000, 1, true); test::(1000000000000000000000000, 3, false); test::(1000000000000000000000002, 3, true); test::(1000000000000000000000000, 123, false); test::(1000000000000000000000000, 0xffffffff, false); test::(1000000000000000000000000, 1000000000000, true); test::(1000000000000000000000000, 1000000000001, false); test::(1000000000000, 0, false); test::(0, -1, true); test::(0, -123, true); test::(1, -1, true); test::(123, -1, true); test::(123, -123, true); test::(123, -456, false); test::(456, -123, false); test::(369, -123, true); test::(0xffffffff, -1, true); test::(0xffffffff, -0xffffffff, true); test::(1000000000000, -1, true); test::(1000000000000, -3, false); test::(1000000000002, -3, true); test::(1000000000000, -123, false); test::(1000000000000, -0xffffffff, false); test::(1000000000000000000000000, -1, true); test::(1000000000000000000000000, -3, false); test::(1000000000000000000000002, -3, true); test::(1000000000000000000000000, -123, false); test::(1000000000000000000000000, -0xffffffff, false); test::(1000000000000000000000000, -1000000000000, true); test::(1000000000000000000000000, -1000000000001, false); test::(-1, 0, false); test::(-1000000000000, 0, false); test::(-1, 1, true); test::(-123, 1, true); test::(-123, 123, true); test::(-123, 456, false); test::(-456, 123, false); test::(-369, 123, true); test::(-0xffffffff, 1, true); test::(-0xffffffff, 0xffffffff, true); test::(-1000000000000, 1, true); test::(-1000000000000, 3, false); test::(-1000000000002, 3, true); test::(-1000000000000, 123, false); test::(-1000000000000, 0xffffffff, false); test::(-1000000000000000000000000, 1, true); test::(-1000000000000000000000000, 3, false); test::(-1000000000000000000000002, 3, true); test::(-1000000000000000000000000, 123, false); test::(-1000000000000000000000000, 0xffffffff, false); test::(-1000000000000000000000000, 1000000000000, true); test::(-1000000000000000000000000, 1000000000001, false); test::(-1, -1, true); test::(-123, -1, true); test::(-123, -123, true); test::(-123, -456, false); test::(-456, -123, false); test::(-369, -123, true); test::(-0xffffffff, -1, true); test::(-0xffffffff, -0xffffffff, true); test::(-1000000000000, -1, true); test::(-1000000000000, -3, false); test::(-1000000000002, -3, true); test::(-1000000000000, -123, false); test::(-1000000000000, -0xffffffff, false); test::(-1000000000000000000000000, -1, true); test::(-1000000000000000000000000, -3, false); test::(-1000000000000000000000002, -3, true); test::(-1000000000000000000000000, -123, false); test::(-1000000000000000000000000, -0xffffffff, false); test::(-1000000000000000000000000, -1000000000000, true); test::(-1000000000000000000000000, -1000000000001, false); } fn divisible_by_properties_helper_unsigned() { unsigned_pair_gen_var_27::().test_properties(|(x, y)| { let divisible = x.divisible_by(y); assert_eq!(x == T::ZERO || y != T::ZERO && x % y == T::ZERO, divisible); }); unsigned_pair_gen_var_11::().test_properties(|(x, y)| { assert!(x.divisible_by(y)); assert!(x == T::ZERO || y != T::ZERO && x % y == T::ZERO); }); unsigned_pair_gen_var_13::().test_properties(|(x, y)| { assert!(!x.divisible_by(y)); assert!(x != T::ZERO && (y == T::ZERO || x % y != T::ZERO)); }); unsigned_gen::().test_properties(|n| { assert!(n.divisible_by(T::ONE)); }); unsigned_gen_var_1::().test_properties(|n| { assert!(!n.divisible_by(T::ZERO)); assert!(T::ZERO.divisible_by(n)); if n > T::ONE { assert!(!T::ONE.divisible_by(n)); } assert!(n.divisible_by(n)); }); } fn divisible_by_properties_helper_signed() { signed_pair_gen::().test_properties(|(x, y)| { let divisible = x.divisible_by(y); assert_eq!( x == T::ZERO || x == T::MIN && y == T::NEGATIVE_ONE || y != T::ZERO && x % y == T::ZERO, divisible ); if x != T::MIN { assert_eq!((-x).divisible_by(y), divisible); } if y != T::MIN { assert_eq!(x.divisible_by(-y), divisible); } }); signed_pair_gen_var_3::().test_properties(|(x, y)| { assert!(x.divisible_by(y)); assert!( x == T::ZERO || x == T::MIN && y == T::NEGATIVE_ONE || y != T::ZERO && x % y == T::ZERO ); }); signed_pair_gen_var_5::().test_properties(|(x, y)| { assert!(!x.divisible_by(y)); assert!( x != T::ZERO && (x != T::MIN || y != T::NEGATIVE_ONE) && (y == T::ZERO || x % y != T::ZERO) ); }); signed_gen::().test_properties(|n| { assert!(n.divisible_by(T::ONE)); assert!(n.divisible_by(T::NEGATIVE_ONE)); }); signed_gen_var_6::().test_properties(|n| { assert!(!n.divisible_by(T::ZERO)); assert!(T::ZERO.divisible_by(n)); if n > T::ONE { assert!(!T::ONE.divisible_by(n)); } assert!(n.divisible_by(n)); }); } #[test] fn divisible_by_properties() { apply_fn_to_unsigneds!(divisible_by_properties_helper_unsigned); apply_fn_to_signeds!(divisible_by_properties_helper_signed); } malachite-base-0.4.16/tests/num/arithmetic/divisible_by_power_of_2.rs000064400000000000000000000113031046102023000237760ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ signed_gen, signed_unsigned_pair_gen_var_1, signed_unsigned_pair_gen_var_8, signed_unsigned_pair_gen_var_9, unsigned_gen, unsigned_pair_gen_var_14, unsigned_pair_gen_var_15, unsigned_pair_gen_var_2, }; fn divisible_by_power_of_2_primitive_helper() { let test = |n: T, pow, out| { assert_eq!(n.divisible_by_power_of_2(pow), out); }; test(T::ZERO, 0, true); test(T::ZERO, 10, true); test(T::ZERO, 100, true); test(T::exact_from(123), 0, true); test(T::exact_from(123), 1, false); if T::WIDTH >= u64::WIDTH { test(T::exact_from(1000000000000u64), 0, true); test(T::exact_from(1000000000000u64), 12, true); test(T::exact_from(1000000000000u64), 13, false); } test(T::MAX, 0, true); test(T::MAX, 1, false); test(T::power_of_2(T::WIDTH >> 1), 0, true); test(T::power_of_2(T::WIDTH >> 1), T::WIDTH >> 1, true); test(T::power_of_2(T::WIDTH >> 1), (T::WIDTH >> 1) + 1, false); } fn divisible_by_power_of_2_signed_helper() { let test = |n: T, pow, out| { assert_eq!(n.divisible_by_power_of_2(pow), out); }; test(T::exact_from(-123), 0, true); test(T::exact_from(-123), 1, false); if T::WIDTH >= u64::WIDTH { test(T::exact_from(-1000000000000i64), 0, true); test(T::exact_from(-1000000000000i64), 12, true); test(T::exact_from(-1000000000000i64), 13, false); } test(T::MIN + T::ONE, 0, true); test(T::MIN + T::ONE, 1, false); test(T::MIN, 0, true); test(T::MIN, T::WIDTH - 1, true); test(T::MIN, T::WIDTH, false); } #[test] fn test_divisible_by_power_of_2() { apply_fn_to_primitive_ints!(divisible_by_power_of_2_primitive_helper); apply_fn_to_signeds!(divisible_by_power_of_2_signed_helper); } fn divisible_by_power_of_2_properties_helper_unsigned() { unsigned_pair_gen_var_2::().test_properties(|(x, pow)| { let divisible = x.divisible_by_power_of_2(pow); if x != T::ZERO { assert_eq!(x.trailing_zeros() >= pow, divisible); } }); unsigned_pair_gen_var_15::().test_properties(|(x, pow)| { assert!(x.divisible_by_power_of_2(pow)); if x != T::ZERO { assert!(x.trailing_zeros() >= pow); } }); unsigned_pair_gen_var_14::().test_properties(|(x, pow)| { assert!(!x.divisible_by_power_of_2(pow)); if x != T::ZERO { assert!(x.trailing_zeros() < pow); } }); unsigned_gen::().test_properties(|x| { assert!(x.divisible_by_power_of_2(0)); }); unsigned_gen().test_properties(|pow| { assert!(T::ZERO.divisible_by_power_of_2(pow)); }); } fn divisible_by_power_of_2_properties_helper_signed() { signed_unsigned_pair_gen_var_1::().test_properties(|(x, pow)| { let divisible = x.divisible_by_power_of_2(pow); if x != T::ZERO { assert_eq!(x.trailing_zeros() >= pow, divisible); } if x != T::MIN { assert_eq!((-x).divisible_by_power_of_2(pow), divisible); } }); signed_unsigned_pair_gen_var_9::().test_properties(|(x, pow)| { assert!(x.divisible_by_power_of_2(pow)); if x != T::ZERO { assert!(x.trailing_zeros() >= pow); } if x != T::MIN { assert!((-x).divisible_by_power_of_2(pow)); } }); signed_unsigned_pair_gen_var_8::().test_properties(|(x, pow)| { assert!(!x.divisible_by_power_of_2(pow)); if x != T::ZERO { assert!(x.trailing_zeros() < pow); } if x != T::MIN { assert!(!(-x).divisible_by_power_of_2(pow)); } }); signed_gen::().test_properties(|x| { assert!(x.divisible_by_power_of_2(0)); }); unsigned_gen().test_properties(|pow| { assert!(T::ZERO.divisible_by_power_of_2(pow)); }); } #[test] fn divisible_by_power_of_2_properties() { apply_fn_to_unsigneds!(divisible_by_power_of_2_properties_helper_unsigned); apply_fn_to_signeds!(divisible_by_power_of_2_properties_helper_signed); } malachite-base-0.4.16/tests/num/arithmetic/eq_mod.rs000064400000000000000000000260111046102023000204570ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::UnsignedAbs; use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::WrappingFrom; use malachite_base::test_util::generators::{ signed_pair_gen, signed_quadruple_gen, signed_triple_gen, signed_triple_gen_var_4, signed_triple_gen_var_5, unsigned_pair_gen_var_27, unsigned_quadruple_gen_var_10, unsigned_triple_gen_var_19, unsigned_triple_gen_var_7, unsigned_triple_gen_var_8, }; #[test] fn test_eq_mod() { fn test(x: T, y: T, m: T, out: bool) { assert_eq!(x.eq_mod(y, m), out); } test::(0, 0, 0, true); test::(0, 1, 0, false); test::(57, 57, 0, true); test::(57, 58, 0, false); test::(1000000000000, 57, 0, false); test::(0, 256, 256, true); test::(0, 256, 512, false); test::(13, 23, 10, true); test::(13, 24, 10, false); test::(13, 21, 1, true); test::(13, 21, 2, true); test::(13, 21, 4, true); test::(13, 21, 8, true); test::(13, 21, 16, false); test::(13, 21, 3, false); test::(1000000000001, 1, 4096, true); test::(1000000000001, 1, 8192, false); test::(12345678987654321, 321, 1000, true); test::(12345678987654321, 322, 1000, false); test::(1234, 1234, 1000000000000, true); test::(1234, 1235, 1000000000000, false); test::(1000000001234, 1000000002234, 1000, true); test::(1000000001234, 1000000002235, 1000, false); test::(1000000001234, 1234, 1000000000000, true); test::(1000000001234, 1235, 1000000000000, false); test::(1000000001234, 5000000001234, 1000000000000, true); test::(1000000001234, 5000000001235, 1000000000000, false); test::(0, -1, 0, false); test::(57, -57, 0, false); test::(57, -58, 0, false); test::(1000000000000, -57, 0, false); test::(0, -256, 256, true); test::(0, -256, 512, false); test::(13, -27, 10, true); test::(13, -28, 10, false); test::(29, -27, 1, true); test::(29, -27, 2, true); test::(29, -27, 4, true); test::(29, -27, 8, true); test::(29, -27, 16, false); test::(29, -27, 3, false); test::(999999999999, -1, 4096, true); test::(999999999999, -1, 8192, false); test::(12345678987654321, -679, 1000, true); test::(12345678987654321, -680, 1000, false); test::(1000000001234, -999999999766, 1000, true); test::(1000000001234, -999999999767, 1000, false); test::(1000000001234, -999999998766, 1000000000000, true); test::(1000000001234, -999999998767, 1000000000000, false); test::(-57, 57, 0, false); test::(-57, 58, 0, false); test::(-1000000000000, 57, 0, false); test::(-13, 27, 10, true); test::(-13, 28, 10, false); test::(-29, 27, 1, true); test::(-29, 27, 2, true); test::(-29, 27, 4, true); test::(-29, 27, 8, true); test::(-29, 27, 16, false); test::(-29, 27, 3, false); test::(-999999999999, 1, 4096, true); test::(-999999999999, 1, 8192, false); test::(-12345678987654321, 679, 1000, true); test::(-12345678987654321, 680, 1000, false); test::(-1000000001234, 999999999766, 1000, true); test::(-1000000001234, 999999999767, 1000, false); test::(-1000000001234, 999999998766, 1000000000000, true); test::(-1000000001234, 999999998767, 1000000000000, false); test::(-57, -57, 0, true); test::(-57, -58, 0, false); test::(-1000000000000, -57, 0, false); test::(-13, -23, 10, true); test::(-13, -24, 10, false); test::(-13, -21, 1, true); test::(-13, -21, 2, true); test::(-13, -21, 4, true); test::(-13, -21, 8, true); test::(-13, -21, 16, false); test::(-13, -21, 3, false); test::(-1000000000001, -1, 4096, true); test::(-1000000000001, -1, 8192, false); test::(-12345678987654321, -321, 1000, true); test::(-12345678987654321, -322, 1000, false); test::(-1234, -1234, 1000000000000, true); test::(-1234, -1235, 1000000000000, false); test::(-1000000001234, -1000000002234, 1000, true); test::(-1000000001234, -1000000002235, 1000, false); test::(-1000000001234, -1234, 1000000000000, true); test::(-1000000001234, -1235, 1000000000000, false); test::(-1000000001234, -5000000001234, 1000000000000, true); test::(-1000000001234, -5000000001235, 1000000000000, false); test::(0, 256, -256, true); test::(0, 256, -512, false); test::(13, 23, -10, true); test::(13, 24, -10, false); test::(13, 21, -1, true); test::(13, 21, -2, true); test::(13, 21, -4, true); test::(13, 21, -8, true); test::(13, 21, -16, false); test::(13, 21, -3, false); test::(1000000000001, 1, -4096, true); test::(1000000000001, 1, -8192, false); test::(12345678987654321, 321, -1000, true); test::(12345678987654321, 322, -1000, false); test::(1234, 1234, -1000000000000, true); test::(1234, 1235, -1000000000000, false); test::(1000000001234, 1000000002234, -1000, true); test::(1000000001234, 1000000002235, -1000, false); test::(1000000001234, 1234, -1000000000000, true); test::(1000000001234, 1235, -1000000000000, false); test::(1000000001234, 5000000001234, -1000000000000, true); test::(1000000001234, 5000000001235, -1000000000000, false); test::(0, -256, -256, true); test::(0, -256, -512, false); test::(13, -27, -10, true); test::(13, -28, -10, false); test::(29, -27, -1, true); test::(29, -27, -2, true); test::(29, -27, -4, true); test::(29, -27, -8, true); test::(29, -27, -16, false); test::(29, -27, -3, false); test::(999999999999, -1, -4096, true); test::(999999999999, -1, -8192, false); test::(12345678987654321, -679, -1000, true); test::(12345678987654321, -680, -1000, false); test::(1000000001234, -999999999766, -1000, true); test::(1000000001234, -999999999767, -1000, false); test::(1000000001234, -999999998766, -1000000000000, true); test::(1000000001234, -999999998767, -1000000000000, false); test::(-13, 27, -10, true); test::(-13, 28, -10, false); test::(-29, 27, -1, true); test::(-29, 27, -2, true); test::(-29, 27, -4, true); test::(-29, 27, -8, true); test::(-29, 27, -16, false); test::(-29, 27, -3, false); test::(-999999999999, 1, -4096, true); test::(-999999999999, 1, -8192, false); test::(-12345678987654321, 679, -1000, true); test::(-12345678987654321, 680, -1000, false); test::(-1000000001234, 999999999766, -1000, true); test::(-1000000001234, 999999999767, -1000, false); test::(-1000000001234, 999999998766, -1000000000000, true); test::(-1000000001234, 999999998767, -1000000000000, false); test::(-13, -23, -10, true); test::(-13, -24, -10, false); test::(-13, -21, -1, true); test::(-13, -21, -2, true); test::(-13, -21, -4, true); test::(-13, -21, -8, true); test::(-13, -21, -16, false); test::(-13, -21, -3, false); test::(-1000000000001, -1, -4096, true); test::(-1000000000001, -1, -8192, false); test::(-12345678987654321, -321, -1000, true); test::(-12345678987654321, -322, -1000, false); test::(-1234, -1234, -1000000000000, true); test::(-1234, -1235, -1000000000000, false); test::(-1000000001234, -1000000002234, -1000, true); test::(-1000000001234, -1000000002235, -1000, false); test::(-1000000001234, -1234, -1000000000000, true); test::(-1000000001234, -1235, -1000000000000, false); test::(-1000000001234, -5000000001234, -1000000000000, true); test::(-1000000001234, -5000000001235, -1000000000000, false); } fn eq_mod_properties_helper_unsigned() { unsigned_triple_gen_var_19::().test_properties(|(x, y, m)| { let equal = x.eq_mod(y, m); assert_eq!(y.eq_mod(x, m), equal); }); unsigned_triple_gen_var_7::().test_properties(|(x, y, m)| { assert!(x.eq_mod(y, m)); assert!(y.eq_mod(x, m)); }); unsigned_triple_gen_var_8::().test_properties(|(x, y, m)| { assert!(!x.eq_mod(y, m)); assert!(!y.eq_mod(x, m)); }); unsigned_pair_gen_var_27::().test_properties(|(x, y)| { assert!(x.eq_mod(y, T::ONE)); assert_eq!(x.eq_mod(y, T::ZERO), x == y); assert_eq!(x.eq_mod(T::ZERO, y), x.divisible_by(y)); assert!(x.eq_mod(x, y)); }); unsigned_quadruple_gen_var_10::().test_properties(|(x, y, z, m)| { if x.eq_mod(y, m) && y.eq_mod(z, m) { assert!(x.eq_mod(z, m)); } }); } fn eq_mod_properties_helper_signed< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + UnsignedAbs + WrappingFrom, >() { signed_triple_gen::().test_properties(|(x, y, m)| { let equal = x.eq_mod(y, m); assert_eq!(y.eq_mod(x, m), equal); if x != S::MIN && y != S::MIN { assert_eq!((-x).eq_mod(-y, m), equal); } if m != S::MIN { assert_eq!(x.eq_mod(y, -m), equal); } }); signed_triple_gen_var_4::().test_properties(|(x, y, m)| { assert!(x.eq_mod(y, m)); assert!(y.eq_mod(x, m)); }); signed_triple_gen_var_5::().test_properties(|(x, y, m)| { assert!(!x.eq_mod(y, m)); assert!(!y.eq_mod(x, m)); }); signed_pair_gen::().test_properties(|(x, y)| { assert!(x.eq_mod(y, S::ONE)); assert_eq!(x.eq_mod(y, S::ZERO), x == y); assert_eq!(x.eq_mod(S::ZERO, y), x.divisible_by(y)); assert!(x.eq_mod(x, y)); }); signed_quadruple_gen::().test_properties(|(x, y, z, m)| { if x.eq_mod(y, m) && y.eq_mod(z, m) { assert!(x.eq_mod(z, m)); } }); } #[test] fn eq_mod_properties() { apply_fn_to_unsigneds!(eq_mod_properties_helper_unsigned); apply_fn_to_unsigned_signed_pairs!(eq_mod_properties_helper_signed); } malachite-base-0.4.16/tests/num/arithmetic/eq_mod_power_of_2.rs000064400000000000000000000251421046102023000226040ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::WrappingFrom; use malachite_base::test_util::generators::{ signed_pair_gen, signed_signed_signed_unsigned_quadruple_gen_var_1, signed_signed_unsigned_triple_gen_var_1, signed_signed_unsigned_triple_gen_var_2, signed_signed_unsigned_triple_gen_var_3, signed_unsigned_pair_gen_var_1, unsigned_pair_gen_var_2, unsigned_pair_gen_var_27, unsigned_quadruple_gen_var_2, unsigned_triple_gen_var_10, unsigned_triple_gen_var_4, unsigned_triple_gen_var_9, }; fn eq_mod_power_of_2_primitive_helper() { let test = |n: T, other, pow, out| { assert_eq!(n.eq_mod_power_of_2(other, pow), out); }; test(T::ZERO, T::power_of_2(T::WIDTH >> 1), T::WIDTH >> 1, true); test( T::ZERO, T::power_of_2(T::WIDTH >> 1), (T::WIDTH >> 1) + 1, false, ); test(T::exact_from(13), T::exact_from(21), 0, true); test(T::exact_from(13), T::exact_from(21), 1, true); test(T::exact_from(13), T::exact_from(21), 2, true); test(T::exact_from(13), T::exact_from(21), 3, true); test(T::exact_from(13), T::exact_from(21), 4, false); test(T::exact_from(13), T::exact_from(21), 100, false); test(T::MAX, T::MAX, T::WIDTH, true); test(T::MAX, T::MAX, 100, true); if T::WIDTH >= u64::WIDTH { test(T::exact_from(1000000000001u64), T::ONE, 12, true); test(T::exact_from(1000000000001u64), T::ONE, 13, false); test( T::exact_from(281474976710672u64), T::exact_from(844424930131984u64), 49, true, ); test( T::exact_from(281474976710672u64), T::exact_from(844424930131984u64), 50, false, ); } } fn eq_mod_power_of_2_signed_helper() { let test = |n: T, other, pow, out| { assert_eq!(n.eq_mod_power_of_2(other, pow), out); }; test(T::ZERO, -T::power_of_2(T::WIDTH >> 1), T::WIDTH >> 1, true); test( T::ZERO, -T::power_of_2(T::WIDTH >> 1), (T::WIDTH >> 1) + 1, false, ); test(T::exact_from(-13), T::exact_from(27), 0, true); test(T::exact_from(-13), T::exact_from(27), 1, true); test(T::exact_from(-13), T::exact_from(27), 2, true); test(T::exact_from(-13), T::exact_from(27), 3, true); test(T::exact_from(-13), T::exact_from(27), 4, false); test(T::exact_from(-13), T::exact_from(27), 100, false); test(T::exact_from(13), T::exact_from(-27), 0, true); test(T::exact_from(13), T::exact_from(-27), 1, true); test(T::exact_from(13), T::exact_from(-27), 2, true); test(T::exact_from(13), T::exact_from(-27), 3, true); test(T::exact_from(13), T::exact_from(-27), 4, false); test(T::exact_from(13), T::exact_from(-27), 100, false); test( T::NEGATIVE_ONE, T::power_of_2(T::WIDTH >> 1) - T::ONE, T::WIDTH >> 1, true, ); test( T::power_of_2(T::WIDTH >> 1) - T::ONE, T::NEGATIVE_ONE, T::WIDTH >> 1, true, ); if T::WIDTH >= u64::WIDTH { test( T::exact_from(-1000000000001i64), T::exact_from(4095), 13, true, ); test( T::exact_from(-1000000000001i64), T::exact_from(4095), 14, false, ); test( T::exact_from(1000000000001i64), T::exact_from(-4095), 13, true, ); test( T::exact_from(1000000000001i64), T::exact_from(-4095), 14, false, ); } test(T::exact_from(-13), T::exact_from(-21), 0, true); test(T::exact_from(-13), T::exact_from(-21), 1, true); test(T::exact_from(-13), T::exact_from(-21), 2, true); test(T::exact_from(-13), T::exact_from(-21), 3, true); test(T::exact_from(-13), T::exact_from(-21), 4, false); test(T::exact_from(-13), T::exact_from(-21), 100, false); test( T::power_of_2(T::WIDTH >> 1) - T::ONE, T::power_of_2(T::WIDTH >> 1) - T::ONE, T::WIDTH >> 1, true, ); if T::WIDTH >= u64::WIDTH { test(T::exact_from(-1000000000001i64), T::NEGATIVE_ONE, 12, true); test(T::exact_from(-1000000000001i64), T::NEGATIVE_ONE, 13, false); test( T::exact_from(-281474976710672i64), T::exact_from(-844424930131984i64), 49, true, ); test( T::exact_from(-281474976710672i64), T::exact_from(-844424930131984i64), 50, false, ); } if T::WIDTH >= u128::WIDTH { test( T::exact_from(1311693408901639117i128), T::exact_from(-17135050664807912499i128), 64, true, ); test( T::exact_from(1311693408901639117i128), T::exact_from(-17135050663395328000i128), 64, false, ); test( T::exact_from(1311693408901639117i128), T::exact_from(-17135050664807912499i128), 65, false, ); test( T::exact_from(1311693408901639117i128), T::exact_from(-17135050664807912499i128), 128, false, ); test( T::exact_from(5633680281231555440641310720i128), T::exact_from(-5634717283396403096794955776i128), 80, true, ); test( T::exact_from(-1311693408901639117i128), T::exact_from(17135050664807912499i128), 64, true, ); test( T::exact_from(-1311693408901639117i128), T::exact_from(17135050663395328000i128), 64, false, ); test( T::exact_from(-1311693408901639117i128), T::exact_from(17135050664807912499i128), 65, false, ); test( T::exact_from(-1311693408901639117i128), T::exact_from(17135050664807912499i128), 128, false, ); test( T::exact_from(-5633680281231555440641310720i128), T::exact_from(5634717283396403096794955776i128), 80, true, ); } } #[test] fn test_eq_mod_power_of_2() { apply_fn_to_primitive_ints!(eq_mod_power_of_2_primitive_helper); apply_fn_to_signeds!(eq_mod_power_of_2_signed_helper); } fn eq_mod_power_of_2_properties_helper_unsigned() { unsigned_triple_gen_var_4::().test_properties(|(x, y, pow)| { let eq_mod_power_of_2 = x.eq_mod_power_of_2(y, pow); assert_eq!(y.eq_mod_power_of_2(x, pow), eq_mod_power_of_2); assert_eq!( x.mod_power_of_2(pow) == y.mod_power_of_2(pow), eq_mod_power_of_2 ); }); unsigned_triple_gen_var_9::().test_properties(|(x, y, pow)| { assert!(x.eq_mod_power_of_2(y, pow)); assert!(y.eq_mod_power_of_2(x, pow)); assert_eq!(x.mod_power_of_2(pow), y.mod_power_of_2(pow)); }); unsigned_triple_gen_var_10::().test_properties(|(x, y, pow)| { assert!(!x.eq_mod_power_of_2(y, pow)); assert!(!y.eq_mod_power_of_2(x, pow)); assert_ne!(x.mod_power_of_2(pow), y.mod_power_of_2(pow)); }); unsigned_pair_gen_var_2::().test_properties(|(n, pow)| { assert!(n.eq_mod_power_of_2(n, pow)); assert_eq!( n.eq_mod_power_of_2(T::ZERO, pow), n.divisible_by_power_of_2(pow) ); assert_eq!( T::ZERO.eq_mod_power_of_2(n, pow), n.divisible_by_power_of_2(pow) ); }); unsigned_quadruple_gen_var_2::().test_properties(|(x, y, z, pow)| { if x.eq_mod_power_of_2(y, pow) && y.eq_mod_power_of_2(z, pow) { assert!(x.eq_mod_power_of_2(z, pow)); } }); unsigned_pair_gen_var_27::().test_properties(|(x, y)| { assert!(x.eq_mod_power_of_2(y, 0)); }); } fn eq_mod_power_of_2_properties_helper_signed< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >() { signed_signed_unsigned_triple_gen_var_2::().test_properties(|(x, y, pow)| { let eq_mod_power_of_2 = x.eq_mod_power_of_2(y, pow); assert_eq!(y.eq_mod_power_of_2(x, pow), eq_mod_power_of_2); assert_eq!( U::wrapping_from(x).mod_power_of_2(pow) == U::wrapping_from(y).mod_power_of_2(pow), eq_mod_power_of_2, ); }); signed_signed_unsigned_triple_gen_var_1::().test_properties(|(x, y, pow)| { assert!(x.eq_mod_power_of_2(y, pow)); assert!(y.eq_mod_power_of_2(x, pow)); assert_eq!( U::wrapping_from(x).mod_power_of_2(pow), U::wrapping_from(y).mod_power_of_2(pow), ); }); signed_signed_unsigned_triple_gen_var_3::().test_properties(|(x, y, pow)| { assert!(!x.eq_mod_power_of_2(y, pow)); assert!(!y.eq_mod_power_of_2(x, pow)); assert_ne!( U::wrapping_from(x).mod_power_of_2(pow), U::wrapping_from(y).mod_power_of_2(pow), ); }); signed_unsigned_pair_gen_var_1::().test_properties(|(n, pow)| { assert!(n.eq_mod_power_of_2(n, pow)); assert_eq!( n.eq_mod_power_of_2(S::ZERO, pow), n.divisible_by_power_of_2(pow) ); assert_eq!( S::ZERO.eq_mod_power_of_2(n, pow), n.divisible_by_power_of_2(pow) ); }); signed_signed_signed_unsigned_quadruple_gen_var_1::().test_properties( |(x, y, z, pow)| { if x.eq_mod_power_of_2(y, pow) && y.eq_mod_power_of_2(z, pow) { assert!(x.eq_mod_power_of_2(z, pow)); } }, ); signed_pair_gen::().test_properties(|(x, y)| { assert!(x.eq_mod_power_of_2(y, 0)); }); } #[test] fn eq_mod_power_of_2_properties() { apply_fn_to_unsigneds!(eq_mod_power_of_2_properties_helper_unsigned); apply_fn_to_unsigned_signed_pairs!(eq_mod_power_of_2_properties_helper_signed); } malachite-base-0.4.16/tests/num/arithmetic/extended_gcd.rs000064400000000000000000000214301046102023000216300ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::extended_gcd::extended_gcd_unsigned_binary; use malachite_base::num::arithmetic::traits::{ExtendedGcd, UnsignedAbs}; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::WrappingFrom; use malachite_base::test_util::generators::{ signed_gen, signed_pair_gen, unsigned_gen, unsigned_pair_gen_var_27, }; use malachite_base::test_util::num::arithmetic::extended_gcd::extended_gcd_unsigned_euclidean; use std::cmp::min; #[test] fn test_extended_gcd() { fn test_u< U: ExtendedGcd + PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + UnsignedAbs + WrappingFrom, >( a: U, b: U, gcd: U, x: S, y: S, ) { assert_eq!(a.extended_gcd(b), (gcd, x, y)); assert_eq!(extended_gcd_unsigned_euclidean(a, b), (gcd, x, y)); assert_eq!(extended_gcd_unsigned_binary::(a, b), (gcd, x, y)); } test_u::(0, 0, 0, 0, 0); test_u::(0, 1, 1, 0, 1); test_u::(1, 0, 1, 1, 0); test_u::(1, 1, 1, 0, 1); test_u::(0, 6, 6, 0, 1); test_u::(6, 0, 6, 1, 0); test_u::(1, 6, 1, 1, 0); test_u::(6, 1, 1, 0, 1); test_u::(6, 6, 6, 0, 1); test_u::(8, 12, 4, -1, 1); test_u::(54, 24, 6, 1, -2); test_u::(42, 56, 14, -1, 1); test_u::(48, 18, 6, -1, 3); test_u::(3, 5, 1, 2, -1); test_u::(12, 60, 12, 1, 0); test_u::(12, 90, 6, -7, 1); test_u::(240, 46, 2, -9, 47); fn test_s + PrimitiveSigned>( a: S, b: S, gcd: U, x: S, y: S, ) { assert_eq!(a.extended_gcd(b), (gcd, x, y)); } test_s::<_, i8>(0, 0, 0, 0, 0); test_s::<_, i8>(0, 1, 1, 0, 1); test_s::<_, i8>(0, -1, 1, 0, -1); test_s::<_, i8>(1, 0, 1, 1, 0); test_s::<_, i8>(-1, 0, 1, -1, 0); test_s::<_, i8>(1, 1, 1, 0, 1); test_s::<_, i8>(1, -1, 1, 0, -1); test_s::<_, i8>(-1, 1, 1, 0, 1); test_s::<_, i8>(-1, -1, 1, 0, -1); test_s::<_, i16>(0, 6, 6, 0, 1); test_s::<_, i16>(0, -6, 6, 0, -1); test_s::<_, i32>(6, 0, 6, 1, 0); test_s::<_, i32>(-6, 0, 6, -1, 0); test_s::<_, i64>(1, 6, 1, 1, 0); test_s::<_, i64>(1, -6, 1, 1, 0); test_s::<_, i64>(-1, 6, 1, -1, 0); test_s::<_, i64>(-1, -6, 1, -1, 0); test_s::<_, isize>(6, 1, 1, 0, 1); test_s::<_, isize>(6, -1, 1, 0, -1); test_s::<_, isize>(-6, 1, 1, 0, 1); test_s::<_, isize>(-6, -1, 1, 0, -1); test_s::<_, i128>(6, 6, 6, 0, 1); test_s::<_, i128>(6, -6, 6, 0, -1); test_s::<_, i128>(-6, 6, 6, 0, 1); test_s::<_, i128>(-6, -6, 6, 0, -1); test_s::<_, i128>(8, 12, 4, -1, 1); test_s::<_, i8>(54, 24, 6, 1, -2); test_s::<_, i16>(42, 56, 14, -1, 1); test_s::<_, i32>(48, 18, 6, -1, 3); test_s::<_, i64>(3, 5, 1, 2, -1); test_s::<_, i128>(12, 90, 6, -7, 1); test_s::<_, i16>(240, 46, 2, -9, 47); test_s::<_, i16>(240, -46, 2, -9, -47); test_s::<_, i16>(-240, 46, 2, 9, 47); test_s::<_, i16>(-240, -46, 2, 9, -47); test_s::<_, i8>(-128, -128, 128, 0, -1); test_s::<_, i8>(0, -128, 128, 0, -1); test_s::<_, i8>(-128, 0, 128, -1, 0); test_s::<_, isize>(12, 60, 12, 1, 0); test_s::<_, isize>(-12, 60, 12, -1, 0); test_s::<_, isize>(12, -60, 12, 1, 0); test_s::<_, isize>(-12, -60, 12, -1, 0); test_s::<_, isize>(60, 12, 12, 0, 1); test_s::<_, isize>(-60, 12, 12, 0, 1); test_s::<_, isize>(60, -12, 12, 0, -1); test_s::<_, isize>(-60, -12, 12, 0, -1); } fn extended_gcd_properties_helper_unsigned< U: ExtendedGcd + PrimitiveUnsigned + WrappingFrom, S: TryFrom + PrimitiveSigned + UnsignedAbs + WrappingFrom, >() { unsigned_pair_gen_var_27::().test_properties(|(a, b)| { let (gcd, x, y) = a.extended_gcd(b); assert_eq!(a.gcd(b), gcd); assert_eq!( S::wrapping_from(a) .wrapping_mul(x) .wrapping_add(S::wrapping_from(b).wrapping_mul(y)), S::wrapping_from(gcd) ); if let (Ok(a), Ok(b), Ok(gcd)) = (S::try_from(a), S::try_from(b), S::try_from(gcd)) { if let (Some(ax), Some(by)) = (a.checked_mul(x), b.checked_mul(y)) { assert_eq!(ax + by, gcd); } } // uniqueness if a != U::ZERO && b != U::ZERO && gcd != min(a, b) { assert!(x.unsigned_abs() <= (b / gcd) >> 1); assert!(y.unsigned_abs() <= (a / gcd) >> 1); } let reverse = b.extended_gcd(a); if a == b { assert_eq!(reverse, (gcd, x, y)); } else { assert_eq!(reverse, (gcd, y, x)); } assert_eq!(extended_gcd_unsigned_euclidean(a, b), (gcd, x, y)); assert_eq!(extended_gcd_unsigned_binary::(a, b), (gcd, x, y)); }); unsigned_gen::().test_properties(|x| { if x != U::ZERO { assert_eq!(x.extended_gcd(x), (x, S::ZERO, S::ONE)); assert_eq!(x.extended_gcd(U::ZERO), (x, S::ONE, S::ZERO)); assert_eq!(U::ZERO.extended_gcd(x), (x, S::ZERO, S::ONE)); } if x != U::ONE { assert_eq!(U::ONE.extended_gcd(x), (U::ONE, S::ONE, S::ZERO)); } assert_eq!(x.extended_gcd(U::ONE), (U::ONE, S::ZERO, S::ONE)); }); } fn extended_gcd_properties_helper_signed< U: TryFrom + PrimitiveUnsigned, S: ExtendedGcd + PrimitiveSigned + UnsignedAbs, >() { signed_pair_gen::().test_properties(|(a, b)| { let (gcd, x, y) = a.extended_gcd(b); assert!(gcd >= U::ZERO); let abs_a = a.unsigned_abs(); let abs_b = b.unsigned_abs(); assert_eq!(abs_a.gcd(abs_b), gcd); let s_gcd = a.wrapping_mul(x).wrapping_add(b.wrapping_mul(y)); assert_eq!(s_gcd.unsigned_abs(), gcd); if let (Some(ax), Some(by)) = (a.checked_mul(x), b.checked_mul(y)) { assert_eq!(U::exact_from(ax + by), gcd); } // uniqueness if a != S::ZERO && b != S::ZERO && gcd != min(abs_a, abs_b) { assert!(x.unsigned_abs() <= (abs_b / gcd) >> 1); assert!(y.unsigned_abs() <= (abs_a / gcd) >> 1); } let reverse = b.extended_gcd(a); if a == b { assert_eq!(reverse, (gcd, x, y)); } else if b != S::MIN && a == -b { assert_eq!(reverse, (gcd, x, -y)); } else { assert_eq!(reverse, (gcd, y, x)); } }); signed_gen::().test_properties(|x| { if x != S::ZERO { assert_eq!( x.extended_gcd(x), ( x.unsigned_abs(), S::ZERO, if x >= S::ZERO { S::ONE } else { S::NEGATIVE_ONE } ) ); if x != S::MIN { assert_eq!( x.extended_gcd(-x), ( x.unsigned_abs(), S::ZERO, if x < S::ZERO { S::ONE } else { S::NEGATIVE_ONE } ) ); } assert_eq!( x.extended_gcd(S::ZERO), ( x.unsigned_abs(), if x >= S::ZERO { S::ONE } else { S::NEGATIVE_ONE }, S::ZERO ) ); assert_eq!( S::ZERO.extended_gcd(x), ( x.unsigned_abs(), S::ZERO, if x >= S::ZERO { S::ONE } else { S::NEGATIVE_ONE } ) ); } if x.unsigned_abs() != U::ONE { assert_eq!(S::ONE.extended_gcd(x), (U::ONE, S::ONE, S::ZERO)); } assert_eq!(x.extended_gcd(S::ONE), (U::ONE, S::ZERO, S::ONE)); }); } #[test] fn extended_gcd_properties() { apply_fn_to_unsigned_signed_pairs!(extended_gcd_properties_helper_unsigned); apply_fn_to_unsigned_signed_pairs!(extended_gcd_properties_helper_signed); } malachite-base-0.4.16/tests/num/arithmetic/factorial.rs000064400000000000000000000257741046102023000211760ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::factorial::checked_multifactorial_naive; use malachite_base::num::arithmetic::traits::Parity; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ unsigned_gen, unsigned_gen_var_23, unsigned_gen_var_24, unsigned_gen_var_25, unsigned_pair_gen_var_12, unsigned_pair_gen_var_43, }; use malachite_base::test_util::num::arithmetic::factorial::{ checked_double_factorial_naive, checked_factorial_naive, checked_subfactorial_naive, }; use std::panic::catch_unwind; #[test] fn test_factorial() { fn test(n: u64, out: T) { assert_eq!(T::factorial(n), out); } test::(0, 1); test::(1, 1); test::(2, 2); test::(3, 6); test::(4, 24); test::(5, 120); test::(10, 3628800); } fn factorial_fail_helper() { assert_panic!(T::factorial(100)); } #[test] fn factorial_fail() { apply_fn_to_unsigneds!(factorial_fail_helper); } #[test] fn test_checked_factorial() { fn test(n: u64, out: Option) { assert_eq!(T::checked_factorial(n), out); assert_eq!(checked_factorial_naive(n), out); } test::(0, Some(1)); test::(1, Some(1)); test::(2, Some(2)); test::(3, Some(6)); test::(4, Some(24)); test::(5, Some(120)); test::(10, Some(3628800)); test::(6, None); test::(100, None); } #[test] fn test_double_factorial() { fn test(n: u64, out: T) { assert_eq!(T::double_factorial(n), out); } test::(0, 1); test::(1, 1); test::(2, 2); test::(3, 3); test::(4, 8); test::(5, 15); test::(6, 48); test::(7, 105); test::(19, 654729075); test::(20, 3715891200); } fn double_factorial_fail_helper() { assert_panic!(T::double_factorial(100)); } #[test] fn double_factorial_fail() { apply_fn_to_unsigneds!(double_factorial_fail_helper); } #[test] fn test_checked_double_factorial() { fn test(n: u64, out: Option) { assert_eq!(T::checked_double_factorial(n), out); assert_eq!(checked_double_factorial_naive(n), out); } test::(0, Some(1)); test::(1, Some(1)); test::(2, Some(2)); test::(3, Some(3)); test::(4, Some(8)); test::(5, Some(15)); test::(6, Some(48)); test::(7, Some(105)); test::(19, Some(654729075)); test::(20, Some(3715891200)); test::(8, None); test::(100, None); } #[test] fn test_multifactorial() { fn test(n: u64, m: u64, out: T) { assert_eq!(T::multifactorial(n, m), out); } test::(0, 1, 1); test::(1, 1, 1); test::(2, 1, 2); test::(3, 1, 6); test::(4, 1, 24); test::(5, 1, 120); test::(0, 2, 1); test::(1, 2, 1); test::(2, 2, 2); test::(3, 2, 3); test::(4, 2, 8); test::(5, 2, 15); test::(6, 2, 48); test::(7, 2, 105); test::(0, 3, 1); test::(1, 3, 1); test::(2, 3, 2); test::(3, 3, 3); test::(4, 3, 4); test::(5, 3, 10); test::(6, 3, 18); test::(7, 3, 28); test::(8, 3, 80); test::(9, 3, 162); test::(10, 1, 3628800); test::(20, 2, 3715891200); test::(25, 3, 608608000); } fn multifactorial_fail_helper() { assert_panic!(T::multifactorial(1, 0)); assert_panic!(T::multifactorial(100, 1)); } #[test] fn multifactorial_fail() { apply_fn_to_unsigneds!(multifactorial_fail_helper); } #[test] fn test_checked_multifactorial() { fn test(n: u64, m: u64, out: Option) { assert_eq!(T::checked_multifactorial(n, m), out); assert_eq!(checked_multifactorial_naive(n, m), out); } test::(0, 1, Some(1)); test::(1, 1, Some(1)); test::(2, 1, Some(2)); test::(3, 1, Some(6)); test::(4, 1, Some(24)); test::(5, 1, Some(120)); test::(0, 2, Some(1)); test::(1, 2, Some(1)); test::(2, 2, Some(2)); test::(3, 2, Some(3)); test::(4, 2, Some(8)); test::(5, 2, Some(15)); test::(6, 2, Some(48)); test::(7, 2, Some(105)); test::(0, 3, Some(1)); test::(1, 3, Some(1)); test::(2, 3, Some(2)); test::(3, 3, Some(3)); test::(4, 3, Some(4)); test::(5, 3, Some(10)); test::(6, 3, Some(18)); test::(7, 3, Some(28)); test::(8, 3, Some(80)); test::(9, 3, Some(162)); test::(10, 1, Some(3628800)); test::(20, 2, Some(3715891200)); test::(25, 3, Some(608608000)); test::(6, 1, None); test::(8, 2, None); test::(10, 3, None); test::(100, 1, None); test::(100, 2, None); test::(100, 3, None); } fn checked_multifactorial_fail_helper() { assert_panic!(T::checked_multifactorial(1, 0)); } #[test] fn checked_multifactorial_fail() { apply_fn_to_unsigneds!(checked_multifactorial_fail_helper); } #[test] fn test_subfactorial() { fn test(n: u64, out: T) { assert_eq!(T::subfactorial(n), out); } test::(0, 1); test::(1, 0); test::(2, 1); test::(3, 2); test::(4, 9); test::(5, 44); test::(10, 1334961); } fn subfactorial_fail_helper() { assert_panic!(T::subfactorial(100)); } #[test] fn subfactorial_fail() { apply_fn_to_unsigneds!(subfactorial_fail_helper); } #[test] fn test_checked_subfactorial() { fn test(n: u64, out: Option) { assert_eq!(T::checked_subfactorial(n), out); assert_eq!(checked_subfactorial_naive(n), out); } test::(0, Some(1)); test::(1, Some(0)); test::(2, Some(1)); test::(3, Some(2)); test::(4, Some(9)); test::(5, Some(44)); test::(10, Some(1334961)); test::(6, None); test::(100, None); } fn factorial_properties_helper() { unsigned_gen_var_23::().test_properties(|n| { let f = T::factorial(n); assert_eq!(T::checked_factorial(n), Some(f)); assert_eq!(T::multifactorial(n, 1), f); assert_ne!(f, T::ZERO); if n != 0 { assert_eq!(f / T::factorial(n - 1), T::exact_from(n)); } }); } #[test] fn factorial_properties() { apply_fn_to_unsigneds!(factorial_properties_helper); } fn checked_factorial_properties_helper() { unsigned_gen().test_properties(|n| { let of = T::checked_factorial(n); assert_eq!(checked_factorial_naive(n), of); assert_eq!(T::checked_multifactorial(n, 1), of); assert_ne!(of, Some(T::ZERO)); if let Some(f) = of { assert_eq!(T::factorial(n), f); } if n != u64::MAX && of.is_none() { assert!(T::checked_factorial(n + 1).is_none()); } }); } #[test] fn checked_factorial_properties() { apply_fn_to_unsigneds!(checked_factorial_properties_helper); } fn double_factorial_properties_helper() { unsigned_gen_var_24::().test_properties(|n| { let f = T::double_factorial(n); assert_eq!(T::checked_double_factorial(n), Some(f)); assert_eq!(T::multifactorial(n, 2), f); assert_ne!(f, T::ZERO); if n > 1 { assert_eq!(f / T::double_factorial(n - 2), T::exact_from(n)); } }); } #[test] fn double_factorial_properties() { apply_fn_to_unsigneds!(double_factorial_properties_helper); } fn checked_double_factorial_properties_helper() { unsigned_gen().test_properties(|n| { let of = T::checked_double_factorial(n); assert_eq!(checked_double_factorial_naive(n), of); assert_eq!(T::checked_multifactorial(n, 2), of); assert_ne!(of, Some(T::ZERO)); if let Some(f) = of { assert_eq!(T::double_factorial(n), f); } if n != u64::MAX && of.is_none() { assert!(T::checked_double_factorial(n + 1).is_none()); } }); } #[test] fn checked_double_factorial_properties() { apply_fn_to_unsigneds!(checked_double_factorial_properties_helper); } fn multifactorial_properties_helper() { unsigned_pair_gen_var_43::().test_properties(|(n, m)| { let f = T::multifactorial(n, m); assert_eq!(T::checked_multifactorial(n, m), Some(f)); assert_ne!(f, T::ZERO); if n >= m { assert_eq!(f / T::multifactorial(n - m, m), T::exact_from(n)); } }); } #[test] fn multifactorial_properties() { apply_fn_to_unsigneds!(multifactorial_properties_helper); } fn checked_multifactorial_properties_helper() { unsigned_pair_gen_var_12::().test_properties(|(n, m)| { let of = T::checked_multifactorial(n, m); assert_eq!(checked_multifactorial_naive(n, m), of); assert_ne!(of, Some(T::ZERO)); if let Some(f) = of { assert_eq!(T::multifactorial(n, m), f); } if n != u64::MAX && of.is_none() { assert!(T::checked_multifactorial(n + 1, m).is_none()); } }); } #[test] fn checked_multifactorial_properties() { apply_fn_to_unsigneds!(checked_multifactorial_properties_helper); } fn subfactorial_properties_helper() { unsigned_gen_var_25::().test_properties(|n| { let f = T::subfactorial(n); assert_eq!(T::checked_subfactorial(n), Some(f)); if n != 1 { assert_ne!(f, T::ZERO); } if n != 0 && n != 2 { let g = if n.even() { f - T::ONE } else { f + T::ONE }; assert_eq!(g / T::subfactorial(n - 1), T::exact_from(n)); } }); } #[test] fn subfactorial_properties() { apply_fn_to_unsigneds!(subfactorial_properties_helper); } fn checked_subfactorial_properties_helper() { unsigned_gen().test_properties(|n| { let of = T::checked_subfactorial(n); assert_eq!(checked_subfactorial_naive(n), of); if n != 1 { assert_ne!(of, Some(T::ZERO)); } if let Some(f) = of { assert_eq!(T::subfactorial(n), f); } if n != u64::MAX && of.is_none() { assert!(T::checked_subfactorial(n + 1).is_none()); } }); } #[test] fn checked_subfactorial_properties() { apply_fn_to_unsigneds!(checked_subfactorial_properties_helper); } malachite-base-0.4.16/tests/num/arithmetic/floor.rs000064400000000000000000000033611046102023000203370ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::generators::primitive_float_gen; fn floor_assign_primitive_float_helper() { let test = |n: T, out| { assert_eq!(NiceFloat(n.floor()), NiceFloat(out)); let mut n = n; n.floor_assign(); assert_eq!(NiceFloat(n), NiceFloat(out)); }; test(T::ZERO, T::ZERO); test(T::NEGATIVE_ZERO, T::NEGATIVE_ZERO); test(T::INFINITY, T::INFINITY); test(T::NEGATIVE_INFINITY, T::NEGATIVE_INFINITY); test(T::NAN, T::NAN); test(T::ONE, T::ONE); test(T::NEGATIVE_ONE, T::NEGATIVE_ONE); test(T::from(1.5f32), T::from(1.0f32)); test(T::from(-1.5f32), T::from(-2.0f32)); } #[test] fn test_floor_assign() { apply_fn_to_primitive_floats!(floor_assign_primitive_float_helper); } fn floor_assign_properties_helper() { primitive_float_gen::().test_properties(|f| { let mut floor = f; floor.floor_assign(); assert_eq!(NiceFloat(floor), NiceFloat(f.floor())); assert_eq!(NiceFloat(floor.floor()), NiceFloat(floor)); assert_eq!(NiceFloat(-floor), NiceFloat((-f).ceiling())); assert_eq!(f.sign(), floor.sign()); }); } #[test] fn floor_assign_properties() { apply_fn_to_primitive_floats!(floor_assign_properties_helper); } malachite-base-0.4.16/tests/num/arithmetic/gcd.rs000064400000000000000000000043411046102023000177520ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::gcd::{gcd_binary, gcd_euclidean, gcd_fast_a, gcd_fast_b}; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ unsigned_gen, unsigned_pair_gen_var_27, unsigned_triple_gen_var_19, }; #[test] fn test_gcd() { fn test(x: T, y: T, out: T) { assert_eq!(x.gcd(y), out); let mut x = x; x.gcd_assign(y); assert_eq!(x, out); } test::(0, 0, 0); test::(0, 6, 6); test::(6, 0, 6); test::(1, 6, 1); test::(6, 1, 1); test::(8, 12, 4); test::(54, 24, 6); test::(42, 56, 14); test::(48, 18, 6); test::(3, 5, 1); test::(12, 60, 12); test::(12, 90, 6); } fn gcd_properties_helper() { unsigned_pair_gen_var_27::().test_properties(|(x, y)| { let gcd = x.gcd(y); assert_eq!(gcd_euclidean(x, y), gcd); assert_eq!(gcd_binary(x, y), gcd); assert_eq!(gcd_fast_a(x, y), gcd); assert_eq!(gcd_fast_b(x, y), gcd); let mut x_mut = x; x_mut.gcd_assign(y); assert_eq!(x_mut, gcd); assert_eq!(y.gcd(x), gcd); assert!(x.divisible_by(gcd)); assert!(y.divisible_by(gcd)); if gcd != T::ZERO { assert!((x.div_exact(gcd)).coprime_with(y.div_exact(gcd))); } assert_eq!(gcd == T::ZERO, x == T::ZERO && y == T::ZERO); }); unsigned_gen::().test_properties(|x| { assert_eq!(x.gcd(x), x); assert_eq!(x.gcd(T::ONE), T::ONE); assert_eq!(x.gcd(T::ZERO), x); }); unsigned_triple_gen_var_19::().test_properties(|(x, y, z)| { assert_eq!(x.gcd(y).gcd(z), x.gcd(y.gcd(z))); }); } #[test] fn gcd_properties() { apply_fn_to_unsigneds!(gcd_properties_helper); } malachite-base-0.4.16/tests/num/arithmetic/is_power_of_2.rs000064400000000000000000000027561046102023000217610ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::test_util::generators::primitive_float_gen; fn is_power_of_2_helper() { let test = |n: T, out| { assert_eq!(n.is_power_of_2(), out); }; test(T::ZERO, false); test(T::NEGATIVE_ZERO, false); test(T::INFINITY, false); test(T::NEGATIVE_INFINITY, false); test(T::NAN, false); test(T::NEGATIVE_ONE, false); test(T::from(1.5f32), false); test(T::from(-1.5f32), false); test(T::ONE, true); test(T::TWO, true); test(T::from(4.0f32), true); test(T::from(0.5f32), true); test(T::from(0.25f32), true); } #[test] fn test_is_power_of_2() { apply_fn_to_primitive_floats!(is_power_of_2_helper); } fn is_power_of_2_properties_helper() { primitive_float_gen::().test_properties(|f| { if f.is_power_of_2() { assert_eq!(f.precision(), 1); assert_eq!(T::power_of_2(f.checked_log_base_2().unwrap()), f); } }); } #[test] fn is_power_of_2_properties() { apply_fn_to_primitive_floats!(is_power_of_2_properties_helper); } malachite-base-0.4.16/tests/num/arithmetic/kronecker_symbol.rs000064400000000000000000000750551046102023000225770ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::kronecker_symbol::{ jacobi_symbol_unsigned_double_fast_2, jacobi_symbol_unsigned_simple, }; use malachite_base::num::arithmetic::traits::{ModPowerOf2, UnsignedAbs}; use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::comparison::traits::PartialOrdAbs; use malachite_base::num::conversion::traits::{HasHalf, JoinHalves, WrappingFrom}; use malachite_base::test_util::generators::{ signed_gen, signed_gen_var_13, signed_pair_gen, signed_pair_gen_var_10, signed_pair_gen_var_8, signed_pair_gen_var_9, signed_triple_gen, signed_triple_gen_var_6, signed_triple_gen_var_7, unsigned_gen, unsigned_gen_var_22, unsigned_pair_gen_var_27, unsigned_pair_gen_var_40, unsigned_pair_gen_var_41, unsigned_pair_gen_var_42, unsigned_quadruple_gen_var_12, unsigned_triple_gen_var_19, unsigned_triple_gen_var_22, unsigned_triple_gen_var_23, }; use malachite_base::test_util::num::arithmetic::kronecker_symbol::{ jacobi_symbol_unsigned_double_fast_1, jacobi_symbol_unsigned_double_simple, jacobi_symbol_unsigned_fast_1, jacobi_symbol_unsigned_fast_2_1, jacobi_symbol_unsigned_fast_2_2, jacobi_symbol_unsigned_fast_2_3, jacobi_symbol_unsigned_fast_2_4, }; use std::panic::catch_unwind; #[test] fn test_jacobi_symbol() { fn test_u(a: T, n: T, s: i8) { assert_eq!(a.legendre_symbol(n), s); assert_eq!(a.jacobi_symbol(n), s); assert_eq!(a.kronecker_symbol(n), s); assert_eq!(jacobi_symbol_unsigned_simple(a, n), s); assert_eq!(jacobi_symbol_unsigned_fast_1(a, n), s); assert_eq!(jacobi_symbol_unsigned_fast_2_1(a, n), s); assert_eq!(jacobi_symbol_unsigned_fast_2_2(a, n), s); assert_eq!(jacobi_symbol_unsigned_fast_2_3(a, n), s); assert_eq!(jacobi_symbol_unsigned_fast_2_4(a, n), s); } test_u::(0, 1, 1); test_u::(0, 3, 0); test_u::(1, 3, 1); test_u::(2, 3, -1); test_u::(0, 5, 0); test_u::(1, 5, 1); test_u::(2, 5, -1); test_u::(3, 5, -1); test_u::(4, 5, 1); test_u::(0, 7, 0); test_u::(1, 7, 1); test_u::(2, 7, 1); test_u::(3, 7, -1); test_u::(4, 7, 1); test_u::(5, 7, -1); test_u::(6, 7, -1); test_u::(0, 9, 0); test_u::(1, 9, 1); test_u::(2, 9, 1); test_u::(3, 9, 0); test_u::(4, 9, 1); test_u::(5, 9, 1); test_u::(6, 9, 0); test_u::(7, 9, 1); test_u::(8, 9, 1); test_u::(7, 7, 0); test_u::(8, 7, 1); test_u::(9, 7, 1); test_u::(10, 7, -1); test_u::(11, 7, 1); test_u::(12, 7, -1); test_u::(13, 7, -1); test_u::(9, 9, 0); test_u::(10, 9, 1); test_u::(11, 9, 1); test_u::(12, 9, 0); test_u::(13, 9, 1); test_u::(14, 9, 1); test_u::(15, 9, 0); test_u::(16, 9, 1); test_u::(17, 9, 1); test_u::(1001, 9907, -1); test_u::(10908, 9907, -1); fn test_s + PrimitiveSigned>( a: S, n: S, s: i8, ) { assert_eq!(a.legendre_symbol(n), s); assert_eq!(a.jacobi_symbol(n), s); assert_eq!(a.kronecker_symbol(n), s); } test_s::(0, 1, 1); test_s::(0, 3, 0); test_s::(1, 3, 1); test_s::(2, 3, -1); test_s::(0, 5, 0); test_s::(1, 5, 1); test_s::(2, 5, -1); test_s::(3, 5, -1); test_s::(4, 5, 1); test_s::(0, 7, 0); test_s::(1, 7, 1); test_s::(2, 7, 1); test_s::(3, 7, -1); test_s::(4, 7, 1); test_s::(5, 7, -1); test_s::(6, 7, -1); test_s::(0, 9, 0); test_s::(1, 9, 1); test_s::(2, 9, 1); test_s::(3, 9, 0); test_s::(4, 9, 1); test_s::(5, 9, 1); test_s::(6, 9, 0); test_s::(7, 9, 1); test_s::(8, 9, 1); test_s::(7, 7, 0); test_s::(8, 7, 1); test_s::(9, 7, 1); test_s::(10, 7, -1); test_s::(11, 7, 1); test_s::(12, 7, -1); test_s::(13, 7, -1); test_s::(9, 9, 0); test_s::(10, 9, 1); test_s::(11, 9, 1); test_s::(12, 9, 0); test_s::(13, 9, 1); test_s::(14, 9, 1); test_s::(15, 9, 0); test_s::(16, 9, 1); test_s::(17, 9, 1); test_s::(-7, 7, 0); test_s::(-6, 7, 1); test_s::(-5, 7, 1); test_s::(-4, 7, -1); test_s::(-3, 7, 1); test_s::(-2, 7, -1); test_s::(-1, 7, -1); test_s::(-9, 9, 0); test_s::(-8, 9, 1); test_s::(-7, 9, 1); test_s::(-6, 9, 0); test_s::(-5, 9, 1); test_s::(-4, 9, 1); test_s::(-3, 9, 0); test_s::(-2, 9, 1); test_s::(-1, 9, 1); test_s::(1001, 9907, -1); test_s::(10908, 9907, -1); test_s::(-8906, 9907, -1); } fn jacobi_symbol_fail_helper() { assert_panic!(T::ONE.jacobi_symbol(T::TWO)); } fn jacobi_symbol_fail_helper_signed() { assert_panic!(T::ONE.jacobi_symbol(T::NEGATIVE_ONE)); } #[test] fn jacobi_symbol_fail() { apply_fn_to_primitive_ints!(jacobi_symbol_fail_helper); apply_fn_to_signeds!(jacobi_symbol_fail_helper_signed); } #[test] fn test_jacobi_symbol_unsigned_double() { fn test + JoinHalves + PrimitiveUnsigned>( x_1: T, x_0: T, y_1: T, y_0: T, s: i8, ) { assert_eq!( jacobi_symbol_unsigned_double_simple::(x_1, x_0, y_1, y_0), s ); assert_eq!(jacobi_symbol_unsigned_double_fast_1(x_1, x_0, y_1, y_0), s); assert_eq!(jacobi_symbol_unsigned_double_fast_2(x_1, x_0, y_1, y_0), s); } // - fast_1: y_1 == T::ZERO || y_0 == T::ZERO first time // - fast_2: y_1 == T::ZERO && y_0 == T::ONE test::(0, 0, 0, 1, 1); // - fast_1: y_1 != T::ZERO && y_0 != T::ZERO first time // - fast_1: x_1 != T::ZERO && x_0 != T::ZERO // - fast_1: x_0 != T::ZERO first time // - fast_1: c != T::WIDTH first time // - fast_1: diff_0 != T::ZERO && diff_1 != T::ZERO // - fast_1: diff_1.get_highest_bit() // - fast_1: y_1 != T::ZERO && y_0 != T::ZERO second time // - fast_1: x_0 == T::ZERO second time // - fast_1: c != T::WIDTH second time // - fast_1: bit.even() // - fast_2: y_1 != T::ZERO || y_0 != T::ONE // - fast_2: x_0 != T::ZERO first time // - fast_2: x_0.odd() // - fast_2: x_1 == T::ZERO second time // - fast_2: y_1 != T::ZERO // - fast_2: skip_loop // - fast_2: y_0 != T::ONE second time // - fast_2: x_0 == T::ZERO fourth time // - fast_2: x_1 != T::ZERO fourth time // - fast_2: !bit.get_bit(1) test::(0, 3, 2, 3, 1); // - fast_1: x_1 == T::ZERO || x_0 == T::ZERO // - fast_2: x_0 == T::ZERO first time // - fast_2: x_1 == T::ZERO first time test::(0, 0, 0, 3, 0); // - fast_1: t != T::ZERO // - fast_1: c == T::WIDTH third time // - fast_2: y_0 == T::ONE second time test::(0, 1, 1, 1, 1); // - fast_1: c != T::WIDTH third time test::(0, 1, 1, 3, 1); // - fast_1: x_0 == T::ZERO first time // - fast_2: x_1 != T::ZERO first time // - fast_2: y_0 == T::ONE first time test::(1, 0, 0, 3, 1); // - fast_1: bit.odd() // - fast_2: x_1 != T::ZERO second time // - fast_2: !skip_loop // - fast_2: x_0 != T::ZERO fourth time // - fast_2: bit.get_bit(1) test::(1, 1, 0, 3, -1); // - fast_1: t == T::ZERO // - fast_2: x_1 == y_1 first time // - fast_2: x_1 == y_1 second time // - fast_2: x_0 >= y_0 // - fast_2: x_0 == T::ZERO third time test::(1, 1, 1, 1, 0); // - fast_1: y_1 == T::ZERO || y_0 == T::ZERO second time test::(0, 1, 2, 1, 1); // - fast_1: x_0 != T::ZERO second time // - fast_1: c == T::WIDTH second time // - fast_2: x_1 != y_1 first time // - fast_2: x_1 != T::ZERO third time // - fast_2: y_0 == T::ZERO test::(1, 1, 2, 1, 1); // - fast_1: !diff_1.get_highest_bit() test::(2, 1, 0, 3, 0); // - fast_1: diff_0 == T::ZERO || diff_1 == T::ZERO test::(2, 1, 2, 1, 0); // - fast_1: c == T::WIDTH first time // - fast_2: x_0.even() // - fast_2: y_0 != T::ZERO test::(242, 128, 173, 173, -1); // - fast_2: y_1 == T::ZERO test::(0, 1, 0, 3, 1); // - fast_2: x_0 < y_0 // - fast_2: x_0 != T::ZERO third time // - fast_2: x_0 == T::ONE test::(1, 1, 1, 3, 1); // - fast_2: x_0 != T::ONE test::(1, 1, 1, 7, -1); // - fast_2: x_1 != y_1 second time test::(1, 1, 2, 3, 1); // - fast_2: x_0 == T::ZERO second time test::(2, 1, 1, 1, 1); // - fast_2: x_0 != T::ZERO second time // - fast_2: x_1 == T::ZERO third time test::(2, 1, 1, 3, -1); // - fast_2: y_0 != T::ONE first time test::(3, 0, 0, 3, 0); } // Odd n is already tested in test_jacobi_symbol, so here we just test even n #[test] fn test_kronecker_symbol() { fn test_u(a: T, n: T, s: i8) { assert_eq!(a.kronecker_symbol(n), s); } test_u::(0, 2, 0); test_u::(1, 2, 1); test_u::(2, 2, 0); test_u::(3, 2, -1); test_u::(4, 2, 0); test_u::(5, 2, -1); test_u::(6, 2, 0); test_u::(7, 2, 1); test_u::(0, 4, 0); test_u::(1, 4, 1); test_u::(2, 4, 0); test_u::(3, 4, 1); test_u::(0, 6, 0); test_u::(1, 6, 1); test_u::(2, 6, 0); test_u::(3, 6, 0); test_u::(4, 6, 0); test_u::(5, 6, 1); test_u::(6, 6, 0); test_u::(7, 6, 1); test_u::(8, 6, 0); test_u::(9, 6, 0); test_u::(10, 6, 0); test_u::(11, 6, 1); test_u::(12, 6, 0); test_u::(13, 6, -1); test_u::(14, 6, 0); test_u::(15, 6, 0); test_u::(16, 6, 0); test_u::(17, 6, -1); test_u::(18, 6, 0); test_u::(19, 6, -1); test_u::(20, 6, 0); test_u::(21, 6, 0); test_u::(22, 6, 0); test_u::(23, 6, -1); test_u::(1001, 9908, -1); test_u::(10909, 9908, -1); fn test_s + PrimitiveSigned>( a: S, n: S, s: i8, ) { assert_eq!(a.kronecker_symbol(n), s); } test_s::(0, 2, 0); test_s::(1, 2, 1); test_s::(2, 2, 0); test_s::(3, 2, -1); test_s::(4, 2, 0); test_s::(5, 2, -1); test_s::(6, 2, 0); test_s::(7, 2, 1); test_s::(0, 4, 0); test_s::(1, 4, 1); test_s::(2, 4, 0); test_s::(3, 4, 1); test_s::(0, 6, 0); test_s::(1, 6, 1); test_s::(2, 6, 0); test_s::(3, 6, 0); test_s::(4, 6, 0); test_s::(5, 6, 1); test_s::(6, 6, 0); test_s::(7, 6, 1); test_s::(8, 6, 0); test_s::(9, 6, 0); test_s::(10, 6, 0); test_s::(11, 6, 1); test_s::(12, 6, 0); test_s::(13, 6, -1); test_s::(14, 6, 0); test_s::(15, 6, 0); test_s::(16, 6, 0); test_s::(17, 6, -1); test_s::(18, 6, 0); test_s::(19, 6, -1); test_s::(20, 6, 0); test_s::(21, 6, 0); test_s::(22, 6, 0); test_s::(23, 6, -1); test_s::(-1, 2, 1); test_s::(-2, 2, 0); test_s::(-3, 2, -1); test_s::(-4, 2, 0); test_s::(-5, 2, -1); test_s::(-6, 2, 0); test_s::(-7, 2, 1); test_s::(-1, 4, 1); test_s::(-2, 4, 0); test_s::(-3, 4, 1); test_s::(-1, 6, -1); test_s::(-2, 6, 0); test_s::(-3, 6, 0); test_s::(-4, 6, 0); test_s::(-5, 6, -1); test_s::(-6, 6, 0); test_s::(-7, 6, -1); test_s::(-8, 6, 0); test_s::(-9, 6, 0); test_s::(-10, 6, 0); test_s::(-11, 6, -1); test_s::(-12, 6, 0); test_s::(-13, 6, 1); test_s::(-14, 6, 0); test_s::(-15, 6, 0); test_s::(-16, 6, 0); test_s::(-17, 6, 1); test_s::(-18, 6, 0); test_s::(-19, 6, 1); test_s::(-20, 6, 0); test_s::(-21, 6, 0); test_s::(-22, 6, 0); test_s::(-23, 6, 1); test_s::(0, -2, 0); test_s::(1, -2, 1); test_s::(2, -2, 0); test_s::(3, -2, -1); test_s::(4, -2, 0); test_s::(5, -2, -1); test_s::(6, -2, 0); test_s::(7, -2, 1); test_s::(0, -4, 0); test_s::(1, -4, 1); test_s::(2, -4, 0); test_s::(3, -4, 1); test_s::(0, -6, 0); test_s::(1, -6, 1); test_s::(2, -6, 0); test_s::(3, -6, 0); test_s::(4, -6, 0); test_s::(5, -6, 1); test_s::(6, -6, 0); test_s::(7, -6, 1); test_s::(8, -6, 0); test_s::(9, -6, 0); test_s::(10, -6, 0); test_s::(11, -6, 1); test_s::(12, -6, 0); test_s::(13, -6, -1); test_s::(14, -6, 0); test_s::(15, -6, 0); test_s::(16, -6, 0); test_s::(17, -6, -1); test_s::(18, -6, 0); test_s::(19, -6, -1); test_s::(20, -6, 0); test_s::(21, -6, 0); test_s::(22, -6, 0); test_s::(23, -6, -1); test_s::(-1, -2, -1); test_s::(-2, -2, 0); test_s::(-3, -2, 1); test_s::(-4, -2, 0); test_s::(-5, -2, 1); test_s::(-6, -2, 0); test_s::(-7, -2, -1); test_s::(-1, -4, -1); test_s::(-2, -4, 0); test_s::(-3, -4, -1); test_s::(-1, -6, 1); test_s::(-2, -6, 0); test_s::(-3, -6, 0); test_s::(-4, -6, 0); test_s::(-5, -6, 1); test_s::(-6, -6, 0); test_s::(-7, -6, 1); test_s::(-8, -6, 0); test_s::(-9, -6, 0); test_s::(-10, -6, 0); test_s::(-11, -6, 1); test_s::(-12, -6, 0); test_s::(-13, -6, -1); test_s::(-14, -6, 0); test_s::(-15, -6, 0); test_s::(-16, -6, 0); test_s::(-17, -6, -1); test_s::(-18, -6, 0); test_s::(-19, -6, -1); test_s::(-20, -6, 0); test_s::(-21, -6, 0); test_s::(-22, -6, 0); test_s::(-23, -6, -1); test_s::(1001, -9908, -1); test_s::(10909, -9908, -1); test_s::(-8907, -9908, 1); } fn jacobi_symbol_properties_helper_unsigned() { unsigned_pair_gen_var_40::().test_properties(|(a, n)| { let s = a.jacobi_symbol(n); assert_eq!(a.legendre_symbol(n), s); assert_eq!(a.kronecker_symbol(n), s); assert_eq!(jacobi_symbol_unsigned_simple(a, n), s); assert_eq!(jacobi_symbol_unsigned_fast_1(a, n), s); assert_eq!(jacobi_symbol_unsigned_fast_2_1(a, n), s); assert_eq!(jacobi_symbol_unsigned_fast_2_2(a, n), s); assert_eq!(jacobi_symbol_unsigned_fast_2_3(a, n), s); assert_eq!(jacobi_symbol_unsigned_fast_2_4(a, n), s); assert!(s.le_abs(&1i8)); if let Some(b) = a.checked_add(n) { assert_eq!(b.jacobi_symbol(n), s); } if let Some(b) = a.checked_sub(n) { assert_eq!(b.jacobi_symbol(n), s); } assert_eq!(s != 0, a.coprime_with(n)); if let Some(b) = a.checked_mul(T::TWO) { let n_mod_8: u8 = n.mod_power_of_2(3).wrapping_into(); assert_eq!( b.jacobi_symbol(n), if n_mod_8 == 1 || n_mod_8 == 7 { s } else { -s } ); } }); unsigned_pair_gen_var_41::().test_properties(|(m, n)| { let n_mod_4: u8 = n.mod_power_of_2(2).wrapping_into(); let m_mod_4: u8 = m.mod_power_of_2(2).wrapping_into(); assert_eq!( m.jacobi_symbol(n) * n.jacobi_symbol(m), if n_mod_4 == 1 || m_mod_4 == 1 { 1 } else { -1 } ); }); unsigned_triple_gen_var_22::().test_properties(|(a, b, n)| { if let Some(c) = a.checked_mul(b) { assert_eq!(c.jacobi_symbol(n), a.jacobi_symbol(n) * b.jacobi_symbol(n)); } }); unsigned_triple_gen_var_23::().test_properties(|(a, m, n)| { if let Some(o) = m.checked_mul(n) { assert_eq!(a.jacobi_symbol(o), a.jacobi_symbol(m) * a.jacobi_symbol(n)); } }); unsigned_gen_var_22::().test_properties(|n| { if n != T::ONE { assert_eq!(T::ZERO.jacobi_symbol(n), 0); assert_eq!(n.jacobi_symbol(n), 0); } assert_eq!(T::ONE.jacobi_symbol(n), 1); assert_eq!(n.jacobi_symbol(T::ONE), 1); let n_mod_4: u8 = n.mod_power_of_2(2).wrapping_into(); assert_eq!( (n - T::ONE).jacobi_symbol(n), if n_mod_4 == 1 { 1 } else { -1 } ); let n_mod_8: u8 = n.mod_power_of_2(3).wrapping_into(); assert_eq!( T::TWO.jacobi_symbol(n), if n_mod_8 == 1 || n_mod_8 == 7 { 1 } else { -1 } ); }); } fn jacobi_symbol_properties_double_helper_unsigned< T: PrimitiveUnsigned, D: HasHalf + JoinHalves + PrimitiveUnsigned, >() { unsigned_quadruple_gen_var_12::().test_properties(|(x_1, x_0, y_1, y_0)| { let s = jacobi_symbol_unsigned_double_simple::(x_1, x_0, y_1, y_0); assert_eq!(jacobi_symbol_unsigned_double_fast_1(x_1, x_0, y_1, y_0), s); assert_eq!(jacobi_symbol_unsigned_double_fast_2(x_1, x_0, y_1, y_0), s); }); } fn jacobi_symbol_properties_helper_signed< U: PrimitiveUnsigned + WrappingFrom, S: ModPowerOf2 + PrimitiveSigned + UnsignedAbs + WrappingFrom, >() { signed_pair_gen_var_8::().test_properties(|(a, n)| { let s = a.jacobi_symbol(n); assert_eq!(a.legendre_symbol(n), s); assert_eq!(a.kronecker_symbol(n), s); assert!(s.le_abs(&1i8)); if let Some(b) = a.checked_add(n) { assert_eq!(b.jacobi_symbol(n), s); } if let Some(b) = a.checked_sub(n) { assert_eq!(b.jacobi_symbol(n), s); } assert_eq!(s != 0, a.unsigned_abs().coprime_with(n.unsigned_abs())); if let Some(b) = a.checked_mul(S::TWO) { let n_mod_8: u8 = n.mod_power_of_2(3).wrapping_into(); assert_eq!( b.jacobi_symbol(n), if n_mod_8 == 1 || n_mod_8 == 7 { s } else { -s } ); } if let Some(b) = a.checked_neg() { let n_mod_4: u8 = n.mod_power_of_2(2).wrapping_into(); assert_eq!(b.jacobi_symbol(n), if n_mod_4 == 1 { s } else { -s }); } }); signed_pair_gen_var_9::().test_properties(|(m, n)| { let n_mod_4: u8 = n.mod_power_of_2(2).wrapping_into(); let m_mod_4: u8 = m.mod_power_of_2(2).wrapping_into(); assert_eq!( m.jacobi_symbol(n) * n.jacobi_symbol(m), if n_mod_4 == 1 || m_mod_4 == 1 { 1 } else { -1 } ); }); signed_triple_gen_var_6::().test_properties(|(a, b, n)| { if let Some(c) = a.checked_mul(b) { assert_eq!(c.jacobi_symbol(n), a.jacobi_symbol(n) * b.jacobi_symbol(n)); } }); signed_triple_gen_var_7::().test_properties(|(a, m, n)| { if let Some(o) = m.checked_mul(n) { assert_eq!(a.jacobi_symbol(o), a.jacobi_symbol(m) * a.jacobi_symbol(n)); } }); signed_gen_var_13::().test_properties(|n| { if n != S::ONE { assert_eq!(S::ZERO.jacobi_symbol(n), 0); assert_eq!(n.jacobi_symbol(n), 0); } assert_eq!(S::ONE.jacobi_symbol(n), 1); assert_eq!(n.jacobi_symbol(S::ONE), 1); let n_mod_4: u8 = n.mod_power_of_2(2).wrapping_into(); assert_eq!( S::NEGATIVE_ONE.jacobi_symbol(n), if n_mod_4 == 1 { 1 } else { -1 } ); let n_mod_8: u8 = n.mod_power_of_2(3).wrapping_into(); assert_eq!( S::TWO.jacobi_symbol(n), if n_mod_8 == 1 || n_mod_8 == 7 { 1 } else { -1 } ); }); } #[test] fn jacobi_symbol_properties() { apply_fn_to_unsigneds!(jacobi_symbol_properties_helper_unsigned); jacobi_symbol_properties_double_helper_unsigned::(); jacobi_symbol_properties_double_helper_unsigned::(); jacobi_symbol_properties_double_helper_unsigned::(); jacobi_symbol_properties_double_helper_unsigned::(); apply_fn_to_unsigned_signed_pairs!(jacobi_symbol_properties_helper_signed); } fn kronecker_symbol_properties_helper_unsigned() { unsigned_pair_gen_var_27::().test_properties(|(a, n)| { let s = a.kronecker_symbol(n); assert!(s.le_abs(&1i8)); assert_eq!(s != 0, a.coprime_with(n)); let n_mod_4: u8 = n.mod_power_of_2(2).wrapping_into(); if n_mod_4 == 2 { if let Some(four_n) = n.checked_mul(T::from(4u8)) { if let Some(b) = a.checked_add(four_n) { assert_eq!(b.kronecker_symbol(n), s); } if let Some(b) = a.checked_sub(four_n) { assert_eq!(b.kronecker_symbol(n), s); } } } else { if let Some(b) = a.checked_add(n) { assert_eq!(b.kronecker_symbol(n), s); } if let Some(b) = a.checked_sub(n) { assert_eq!(b.kronecker_symbol(n), s); } } let a_mod_4: u8 = a.mod_power_of_2(2).wrapping_into(); if a != T::ZERO && a_mod_4 != 3 { if a_mod_4 == 2 { if let Some(four_a) = a.checked_mul(T::from(4u8)) { if let Some(m) = n.checked_add(four_a) { assert_eq!(a.kronecker_symbol(m), s); } if let Some(m) = n.checked_sub(four_a) { assert_eq!(a.kronecker_symbol(m), s); } } } else { if let Some(m) = n.checked_add(a) { assert_eq!(a.kronecker_symbol(m), s); } if let Some(m) = n.checked_sub(a) { assert_eq!(a.kronecker_symbol(m), s); } } } }); unsigned_triple_gen_var_19::().test_properties(|(x, y, z)| { if let Some(p) = x.checked_mul(y) { assert_eq!( p.kronecker_symbol(z), x.kronecker_symbol(z) * y.kronecker_symbol(z) ); } if let Some(p) = y.checked_mul(z) { assert_eq!( x.kronecker_symbol(p), x.kronecker_symbol(y) * x.kronecker_symbol(z) ); } }); unsigned_pair_gen_var_42::().test_properties(|(m, n)| { let n_odd = if n == T::ZERO { T::ONE } else { n >> n.trailing_zeros() }; let m_odd = if m == T::ZERO { T::ONE } else { m >> m.trailing_zeros() }; let n_odd_mod_4: u8 = n_odd.mod_power_of_2(2).wrapping_into(); let m_odd_mod_4: u8 = m_odd.mod_power_of_2(2).wrapping_into(); let p = if n_odd_mod_4 == 1 || m_odd_mod_4 == 1 { 1 } else { -1 }; assert_eq!(m.kronecker_symbol(n) * n.kronecker_symbol(m), p); }); unsigned_gen().test_properties(|n| { if n != T::ONE { assert_eq!(T::ZERO.kronecker_symbol(n), 0); assert_eq!(n.kronecker_symbol(n), 0); } assert_eq!(T::ONE.kronecker_symbol(n), 1); assert_eq!(n.kronecker_symbol(T::ONE), 1); }); } fn kronecker_symbol_properties_helper_signed< U: PrimitiveUnsigned + WrappingFrom, S: ModPowerOf2 + PrimitiveSigned + UnsignedAbs + WrappingFrom, >() { signed_pair_gen::().test_properties(|(a, n)| { let s = a.kronecker_symbol(n); assert!(s.le_abs(&1i8)); assert_eq!(s != 0, a.unsigned_abs().coprime_with(n.unsigned_abs())); let n_mod_4: u8 = n.mod_power_of_2(2).wrapping_into(); if n_mod_4 == 2 { if let Some(four_n) = n.checked_mul(S::from(4i8)) { if let Some(b) = a.checked_add(four_n) { if n > S::ZERO || a.sign() == b.sign() { assert_eq!(b.kronecker_symbol(n), s); } } if let Some(b) = a.checked_sub(four_n) { if n > S::ZERO || a.sign() == b.sign() { assert_eq!(b.kronecker_symbol(n), s); } } } } else { if let Some(b) = a.checked_add(n) { if n > S::ZERO || a.sign() == b.sign() { assert_eq!(b.kronecker_symbol(n), s); } } if let Some(b) = a.checked_sub(n) { if n > S::ZERO || a.sign() == b.sign() { assert_eq!(b.kronecker_symbol(n), s); } } } let a_mod_4: u8 = a.mod_power_of_2(2).wrapping_into(); if a != S::ZERO && a_mod_4 != 3 { if let Some(abs_a) = a.checked_abs() { if a_mod_4 == 2 { if let Some(four_abs_a) = abs_a.checked_mul(S::from(4i8)) { if let Some(m) = n.checked_add(four_abs_a) { assert_eq!(a.kronecker_symbol(m), s); } if let Some(m) = n.checked_sub(four_abs_a) { assert_eq!(a.kronecker_symbol(m), s); } } } else { if let Some(m) = n.checked_add(abs_a) { assert_eq!(a.kronecker_symbol(m), s); } if let Some(m) = n.checked_sub(abs_a) { assert_eq!(a.kronecker_symbol(m), s); } } } } let m = a; if let Some(m_abs) = m.checked_abs() { let m_odd = if m == S::ZERO { S::ONE } else { m >> m.trailing_zeros() }; let m_odd_mod_4: u8 = m_odd.mod_power_of_2(2).wrapping_into(); // -m won't overflow since m.checked_abs() is Some let m_star = if m_odd_mod_4 == 1 { m } else { -m }; assert_eq!(m_star.kronecker_symbol(n), n.kronecker_symbol(m_abs)); } }); signed_triple_gen::().test_properties(|(x, y, z)| { if !(z == S::NEGATIVE_ONE && (x == S::ZERO && y < S::ZERO || x < S::ZERO && y == S::ZERO)) { if let Some(p) = x.checked_mul(y) { assert_eq!( p.kronecker_symbol(z), x.kronecker_symbol(z) * y.kronecker_symbol(z) ); } } let y_odd_mod_4: u8 = if y == S::ZERO { 0 } else { (y >> y.trailing_zeros()).mod_power_of_2(2).wrapping_into() }; let z_odd_mod_4: u8 = if z == S::ZERO { 0 } else { (z >> z.trailing_zeros()).mod_power_of_2(2).wrapping_into() }; if !(x == S::NEGATIVE_ONE && (y == S::ZERO && z_odd_mod_4 == 3 || y_odd_mod_4 == 3 && z == S::ZERO)) { if let Some(p) = y.checked_mul(z) { assert_eq!( x.kronecker_symbol(p), x.kronecker_symbol(y) * x.kronecker_symbol(z) ); } } }); signed_pair_gen_var_10::().test_properties(|(m, n)| { let n_odd = if n == S::ZERO { S::ONE } else { n >> n.trailing_zeros() }; let m_odd = if m == S::ZERO { S::ONE } else { m >> m.trailing_zeros() }; let n_odd_mod_4: u8 = n_odd.mod_power_of_2(2).wrapping_into(); let m_odd_mod_4: u8 = m_odd.mod_power_of_2(2).wrapping_into(); let p = if n_odd_mod_4 == 1 || m_odd_mod_4 == 1 { 1 } else { -1 }; assert_eq!( m.kronecker_symbol(n) * n.kronecker_symbol(m), if m < S::ZERO && n < S::ZERO { -p } else { p } ); if let Some(m_abs) = m.checked_abs() { assert_eq!(m.kronecker_symbol(n) * n.kronecker_symbol(m_abs), p); } }); signed_gen().test_properties(|n| { if n != S::ONE && n != S::NEGATIVE_ONE { assert_eq!(S::ZERO.kronecker_symbol(n), 0); assert_eq!(n.kronecker_symbol(n), 0); } assert_eq!(S::ONE.kronecker_symbol(n), 1); assert_eq!(n.kronecker_symbol(S::ONE), 1); let n_odd = if n == S::ZERO { S::ONE } else { n >> n.trailing_zeros() }; let n_odd_mod_4: u8 = n_odd.mod_power_of_2(2).wrapping_into(); assert_eq!( S::NEGATIVE_ONE.kronecker_symbol(n), if n_odd_mod_4 == 1 { 1 } else { -1 } ); assert_eq!( n.kronecker_symbol(S::NEGATIVE_ONE), if n >= S::ZERO { 1 } else { -1 } ); }); } #[test] fn kronecker_symbol_properties() { apply_fn_to_unsigneds!(kronecker_symbol_properties_helper_unsigned); apply_fn_to_unsigned_signed_pairs!(kronecker_symbol_properties_helper_signed); } malachite-base-0.4.16/tests/num/arithmetic/lcm.rs000064400000000000000000000073151046102023000177740ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ unsigned_gen, unsigned_pair_gen_var_33, unsigned_pair_gen_var_34, unsigned_triple_gen_var_19, }; use std::panic::catch_unwind; #[test] fn test_lcm() { fn test(x: T, y: T, out: T) { assert_eq!(x.lcm(y), out); let mut x = x; x.lcm_assign(y); assert_eq!(x, out); } test::(0, 0, 0); test::(0, 6, 0); test::(6, 0, 0); test::(1, 6, 6); test::(6, 1, 6); test::(8, 12, 24); test::(54, 24, 216); test::(42, 56, 168); test::(48, 18, 144); test::(3, 5, 15); test::(12, 60, 60); test::(12, 90, 180); } fn lcm_fail_helper() { assert_panic!(T::MAX.lcm(T::TWO)); assert_panic!({ let mut x = T::MAX; x.lcm_assign(T::TWO); }); } #[test] fn lcm_fail() { apply_fn_to_unsigneds!(lcm_fail_helper); } #[test] fn test_checked_lcm() { fn test(x: T, y: T, out: Option) { assert_eq!(x.checked_lcm(y), out); } test::(0, 0, Some(0)); test::(0, 6, Some(0)); test::(6, 0, Some(0)); test::(1, 6, Some(6)); test::(6, 1, Some(6)); test::(8, 12, Some(24)); test::(54, 24, Some(216)); test::(42, 56, Some(168)); test::(48, 18, Some(144)); test::(3, 5, Some(15)); test::(12, 60, Some(60)); test::(12, 90, Some(180)); test::(usize::MAX, 2, None); } fn lcm_properties_helper() { unsigned_pair_gen_var_34::().test_properties(|(x, y)| { let lcm = x.lcm(y); let mut x_mut = x; x_mut.lcm_assign(y); assert_eq!(x_mut, lcm); assert_eq!(y.lcm(x), lcm); assert!(lcm.divisible_by(x)); assert!(lcm.divisible_by(y)); let gcd = x.gcd(y); if x != T::ZERO { assert_eq!(lcm / x * gcd, y); } if y != T::ZERO { assert_eq!(lcm / y * gcd, x); } if gcd != T::ZERO { assert_eq!(x / gcd * y, lcm); } }); unsigned_gen::().test_properties(|x| { assert_eq!(x.lcm(x), x); assert_eq!(x.lcm(T::ONE), x); assert_eq!(x.lcm(T::ZERO), T::ZERO); }); } #[test] fn lcm_properties() { apply_fn_to_unsigneds!(lcm_properties_helper); } fn checked_lcm_properties_helper() { unsigned_pair_gen_var_33::().test_properties(|(x, y)| { let lcm = x.checked_lcm(y); assert_eq!(y.checked_lcm(x), lcm); if let Some(lcm) = lcm { assert_eq!(x.lcm(y), lcm); } }); unsigned_gen::().test_properties(|x| { assert_eq!(x.checked_lcm(x), Some(x)); assert_eq!(x.checked_lcm(T::ONE), Some(x)); assert_eq!(x.checked_lcm(T::ZERO), Some(T::ZERO)); }); unsigned_triple_gen_var_19::().test_properties(|(x, y, z)| { if x != T::ZERO && y != T::ZERO && z != T::ZERO { assert_eq!( x.checked_lcm(y).and_then(|n| n.checked_lcm(z)), y.checked_lcm(z).and_then(|n| x.checked_lcm(n)) ); } }); } #[test] fn checked_lcm_properties() { apply_fn_to_unsigneds!(checked_lcm_properties_helper); } malachite-base-0.4.16/tests/num/arithmetic/log_base.rs000064400000000000000000000160411046102023000207700ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::log_base::{ceiling_log_base_naive, checked_log_base_naive}; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ unsigned_gen_var_1, unsigned_gen_var_6, unsigned_pair_gen_var_24, }; use std::panic::catch_unwind; fn floor_log_base_helper() { let test = |n: T, base, out| { assert_eq!(n.floor_log_base(base), out); }; test(T::ONE, T::TWO, 0); test(T::ONE, T::exact_from(5), 0); test(T::TWO, T::TWO, 1); test(T::TWO, T::exact_from(3), 0); test(T::exact_from(3), T::TWO, 1); test(T::exact_from(3), T::exact_from(3), 1); test(T::exact_from(3), T::exact_from(4), 0); test(T::exact_from(100), T::exact_from(2), 6); test(T::exact_from(100), T::exact_from(3), 4); test(T::exact_from(100), T::exact_from(4), 3); test(T::exact_from(100), T::exact_from(5), 2); test(T::exact_from(100), T::exact_from(10), 2); test(T::exact_from(100), T::exact_from(11), 1); } #[test] fn test_floor_log_base() { apply_fn_to_unsigneds!(floor_log_base_helper); } fn floor_log_base_fail_helper() { assert_panic!(T::ZERO.floor_log_base(T::TWO)); assert_panic!(T::TWO.floor_log_base(T::ZERO)); assert_panic!(T::TWO.floor_log_base(T::ONE)); } #[test] fn floor_log_base_fail() { apply_fn_to_unsigneds!(floor_log_base_fail_helper); } fn ceiling_log_base_helper() { let test = |n: T, pow, out| { assert_eq!(n.ceiling_log_base(pow), out); }; test(T::ONE, T::TWO, 0); test(T::ONE, T::exact_from(5), 0); test(T::TWO, T::TWO, 1); test(T::TWO, T::exact_from(3), 1); test(T::exact_from(3), T::TWO, 2); test(T::exact_from(3), T::exact_from(3), 1); test(T::exact_from(3), T::exact_from(4), 1); test(T::exact_from(100), T::exact_from(2), 7); test(T::exact_from(100), T::exact_from(3), 5); test(T::exact_from(100), T::exact_from(4), 4); test(T::exact_from(100), T::exact_from(5), 3); test(T::exact_from(100), T::exact_from(10), 2); test(T::exact_from(100), T::exact_from(11), 2); } #[test] fn test_ceiling_log_base() { apply_fn_to_unsigneds!(ceiling_log_base_helper); } fn ceiling_log_base_fail_helper() { assert_panic!(T::ZERO.ceiling_log_base(T::TWO)); assert_panic!(T::TWO.ceiling_log_base(T::ZERO)); assert_panic!(T::TWO.ceiling_log_base(T::ONE)); } #[test] fn ceiling_log_base_fail() { apply_fn_to_unsigneds!(ceiling_log_base_fail_helper); } fn checked_log_base_helper() { let test = |n: T, pow, out| { assert_eq!(n.checked_log_base(pow), out); }; test(T::ONE, T::TWO, Some(0)); test(T::ONE, T::exact_from(5), Some(0)); test(T::TWO, T::TWO, Some(1)); test(T::TWO, T::exact_from(3), None); test(T::exact_from(3), T::TWO, None); test(T::exact_from(3), T::exact_from(3), Some(1)); test(T::exact_from(3), T::exact_from(4), None); test(T::exact_from(100), T::exact_from(2), None); test(T::exact_from(100), T::exact_from(3), None); test(T::exact_from(100), T::exact_from(4), None); test(T::exact_from(100), T::exact_from(5), None); test(T::exact_from(100), T::exact_from(10), Some(2)); test(T::exact_from(100), T::exact_from(11), None); } #[test] fn test_checked_log_base() { apply_fn_to_unsigneds!(checked_log_base_helper); } fn checked_log_base_fail_helper() { assert_panic!(T::ZERO.checked_log_base(T::TWO)); assert_panic!(T::TWO.checked_log_base(T::ZERO)); assert_panic!(T::TWO.checked_log_base(T::ONE)); } #[test] fn checked_log_base_fail() { apply_fn_to_unsigneds!(checked_log_base_fail_helper); } fn floor_log_base_properties_helper() { unsigned_pair_gen_var_24::().test_properties(|(n, base)| { let floor_log = n.floor_log_base(base); assert!(floor_log < T::WIDTH); assert_eq!(floor_log == 0, n < base); if let Some(pow) = base.checked_pow(floor_log) { assert!(pow <= n); } if let Some(pow) = base.checked_pow(floor_log + 1) { assert!(pow > n); } let ceiling_log = n.ceiling_log_base(base); assert!(ceiling_log == floor_log || ceiling_log == floor_log + 1); }); unsigned_gen_var_1::().test_properties(|n| { assert_eq!(n.floor_log_base(T::TWO), n.floor_log_base_2()); }); unsigned_gen_var_6().test_properties(|n| { assert_eq!(T::ONE.floor_log_base(n), 0); assert_eq!(n.floor_log_base(n), 1); }); } #[test] fn floor_log_base_properties() { apply_fn_to_unsigneds!(floor_log_base_properties_helper); } fn ceiling_log_base_properties_helper() { unsigned_pair_gen_var_24::().test_properties(|(n, base)| { let ceiling_log = n.ceiling_log_base(base); assert!(ceiling_log <= T::WIDTH); assert_eq!(ceiling_log, ceiling_log_base_naive(n, base)); assert_eq!(ceiling_log == 0, n == T::ONE); if let Some(pow) = base.checked_pow(ceiling_log) { assert!(pow >= n); } if n != T::ONE { if let Some(pow) = base.checked_pow(ceiling_log - 1) { assert!(pow < n); } } let floor_log = n.floor_log_base(base); assert!(ceiling_log == floor_log || ceiling_log == floor_log + 1); }); unsigned_gen_var_1::().test_properties(|n| { assert_eq!(n.ceiling_log_base(T::TWO), n.ceiling_log_base_2()); }); unsigned_gen_var_6().test_properties(|n| { assert_eq!(T::ONE.ceiling_log_base(n), 0); assert_eq!(n.ceiling_log_base(n), 1); }); } #[test] fn ceiling_log_base_properties() { apply_fn_to_unsigneds!(ceiling_log_base_properties_helper); } fn checked_log_base_properties_helper() { unsigned_pair_gen_var_24::().test_properties(|(n, base)| { let checked_log = n.checked_log_base(base); assert_eq!(checked_log, checked_log_base_naive(n, base)); if let Some(log) = checked_log { assert_eq!(base.pow(log), n); assert!(log <= T::WIDTH); assert_eq!(log == 0, n == T::ONE); assert_eq!(n.floor_log_base(base), log); assert_eq!(n.ceiling_log_base(base), log); } }); unsigned_gen_var_1::().test_properties(|n| { assert_eq!(n.checked_log_base(T::TWO), n.checked_log_base_2()); }); unsigned_gen_var_6().test_properties(|n| { assert_eq!(T::ONE.checked_log_base(n), Some(0)); assert_eq!(n.checked_log_base(n), Some(1)); }); } #[test] fn checked_log_base_properties() { apply_fn_to_unsigneds!(checked_log_base_properties_helper); } malachite-base-0.4.16/tests/num/arithmetic/log_base_2.rs000064400000000000000000000252361046102023000212170ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{primitive_float_gen_var_18, unsigned_gen_var_1}; use std::panic::catch_unwind; fn floor_log_base_2_helper_unsigned() { let test = |n: T, out| { assert_eq!(n.floor_log_base_2(), out); }; test(T::ONE, 0); test(T::TWO, 1); test(T::exact_from(3), 1); test(T::exact_from(4), 2); test(T::exact_from(5), 2); test(T::exact_from(100), 6); test(T::exact_from(128), 7); test(T::MAX, T::WIDTH - 1); } fn floor_log_base_2_helper_primitive_float() { let test = |n: T, out| { assert_eq!(n.floor_log_base_2(), out); }; test(T::ONE, 0); test(T::TWO, 1); test(T::from(3.0f32), 1); test(T::from(4.0f32), 2); test(T::from(5.0f32), 2); test(T::from(100.0f32), 6); test(T::from(128.0f32), 7); test(T::from(0.4f32), -2); test(T::from(0.5f32), -1); test(T::from(0.6f32), -1); test(T::MAX_FINITE, T::MAX_EXPONENT); test(T::MIN_POSITIVE_SUBNORMAL, T::MIN_EXPONENT); } #[test] fn test_floor_log_base_2() { apply_fn_to_unsigneds!(floor_log_base_2_helper_unsigned); apply_fn_to_primitive_floats!(floor_log_base_2_helper_primitive_float); } fn floor_log_base_2_fail_helper_unsigned() { assert_panic!(T::ZERO.floor_log_base_2()); } fn floor_log_base_2_fail_helper_primitive_float() { assert_panic!(T::ZERO.floor_log_base_2()); assert_panic!(T::NAN.floor_log_base_2()); assert_panic!(T::INFINITY.floor_log_base_2()); assert_panic!(T::NEGATIVE_INFINITY.floor_log_base_2()); } #[test] fn floor_log_base_2_fail() { apply_fn_to_unsigneds!(floor_log_base_2_fail_helper_unsigned); apply_fn_to_primitive_floats!(floor_log_base_2_fail_helper_primitive_float); } fn ceiling_log_base_2_helper_unsigned() { let test = |n: T, out| { assert_eq!(n.ceiling_log_base_2(), out); }; test(T::ONE, 0); test(T::TWO, 1); test(T::exact_from(3), 2); test(T::exact_from(4), 2); test(T::exact_from(5), 3); test(T::exact_from(100), 7); test(T::exact_from(128), 7); test(T::MAX, T::WIDTH); } fn ceiling_log_base_2_helper_primitive_float() { let test = |n: T, out| { assert_eq!(n.ceiling_log_base_2(), out); }; test(T::ONE, 0); test(T::TWO, 1); test(T::from(3.0f32), 2); test(T::from(4.0f32), 2); test(T::from(5.0f32), 3); test(T::from(100.0f32), 7); test(T::from(128.0f32), 7); test(T::from(0.4f32), -1); test(T::from(0.5f32), -1); test(T::from(0.6f32), 0); test(T::MAX_FINITE, T::MAX_EXPONENT + 1); test(T::MIN_POSITIVE_SUBNORMAL, T::MIN_EXPONENT); } #[test] fn test_ceiling_log_base_2() { apply_fn_to_unsigneds!(ceiling_log_base_2_helper_unsigned); apply_fn_to_primitive_floats!(ceiling_log_base_2_helper_primitive_float); } fn ceiling_log_base_2_fail_helper_unsigned() { assert_panic!(T::ZERO.ceiling_log_base_2()); } fn ceiling_log_base_2_fail_helper_primitive_float() { assert_panic!(T::ZERO.ceiling_log_base_2()); assert_panic!(T::NAN.ceiling_log_base_2()); assert_panic!(T::INFINITY.ceiling_log_base_2()); assert_panic!(T::NEGATIVE_INFINITY.ceiling_log_base_2()); } #[test] fn ceiling_log_base_2_fail() { apply_fn_to_unsigneds!(ceiling_log_base_2_fail_helper_unsigned); apply_fn_to_primitive_floats!(ceiling_log_base_2_fail_helper_primitive_float); } fn checked_log_base_2_helper_unsigned() { let test = |n: T, out| { assert_eq!(n.checked_log_base_2(), out); }; test(T::ONE, Some(0)); test(T::TWO, Some(1)); test(T::exact_from(3), None); test(T::exact_from(4), Some(2)); test(T::exact_from(5), None); test(T::exact_from(100), None); test(T::exact_from(128), Some(7)); test(T::MAX, None); } fn checked_log_base_2_helper_primitive_float() { let test = |n: T, out| { assert_eq!(n.checked_log_base_2(), out); }; test(T::ONE, Some(0)); test(T::TWO, Some(1)); test(T::from(3.0f32), None); test(T::from(4.0f32), Some(2)); test(T::from(5.0f32), None); test(T::from(100.0f32), None); test(T::from(128.0f32), Some(7)); test(T::from(0.4f32), None); test(T::from(0.5f32), Some(-1)); test(T::from(0.6f32), None); test(T::MAX_FINITE, None); test(T::MIN_POSITIVE_SUBNORMAL, Some(T::MIN_EXPONENT)); } #[test] fn test_checked_log_base_2() { apply_fn_to_unsigneds!(checked_log_base_2_helper_unsigned); apply_fn_to_primitive_floats!(checked_log_base_2_helper_primitive_float); } fn checked_log_base_2_fail_helper_unsigned() { assert_panic!(T::ZERO.checked_log_base_2()); } fn checked_log_base_2_fail_helper_primitive_float() { assert_panic!(T::ZERO.checked_log_base_2()); assert_panic!(T::NAN.checked_log_base_2()); assert_panic!(T::INFINITY.checked_log_base_2()); assert_panic!(T::NEGATIVE_INFINITY.checked_log_base_2()); } #[test] fn checked_log_base_2_fail() { apply_fn_to_unsigneds!(checked_log_base_2_fail_helper_unsigned); apply_fn_to_primitive_floats!(checked_log_base_2_fail_helper_primitive_float); } fn floor_log_base_2_properties_helper_unsigned() { unsigned_gen_var_1::().test_properties(|n| { let floor_log_base_2 = n.floor_log_base_2(); assert_eq!(floor_log_base_2, n.significant_bits() - 1); assert!(floor_log_base_2 < T::WIDTH); assert_eq!(floor_log_base_2 == 0, n == T::ONE); assert!(T::power_of_2(floor_log_base_2) <= n); if floor_log_base_2 < T::WIDTH - 1 { assert!(T::power_of_2(floor_log_base_2 + 1) > n); } let ceiling_log_base_2 = n.ceiling_log_base_2(); if n.is_power_of_2() { assert_eq!(ceiling_log_base_2, floor_log_base_2); } else { assert_eq!(ceiling_log_base_2, floor_log_base_2 + 1); } }); } fn floor_log_base_2_properties_helper_primitive_float() { primitive_float_gen_var_18::().test_properties(|n| { let floor_log_base_2 = n.floor_log_base_2(); assert!(floor_log_base_2 <= T::MAX_EXPONENT); assert!(floor_log_base_2 >= T::MIN_EXPONENT); assert_eq!(floor_log_base_2 == 0, n >= T::ONE && n < T::TWO); assert!(T::power_of_2(floor_log_base_2) <= n); if floor_log_base_2 < T::MAX_EXPONENT { assert!(T::power_of_2(floor_log_base_2 + 1) > n); } let ceiling_log_base_2 = n.ceiling_log_base_2(); if n.is_power_of_2() { assert_eq!(ceiling_log_base_2, floor_log_base_2); } else { assert_eq!(ceiling_log_base_2, floor_log_base_2 + 1); } }); } #[test] fn floor_log_base_2_properties() { apply_fn_to_unsigneds!(floor_log_base_2_properties_helper_unsigned); apply_fn_to_primitive_floats!(floor_log_base_2_properties_helper_primitive_float); } fn ceiling_log_base_2_properties_helper_unsigned() { unsigned_gen_var_1::().test_properties(|n| { let ceiling_log_base_2 = n.ceiling_log_base_2(); assert!(ceiling_log_base_2 <= T::WIDTH); assert_eq!(ceiling_log_base_2 == 0, n == T::ONE); if ceiling_log_base_2 < T::WIDTH { assert!(T::power_of_2(ceiling_log_base_2) >= n); } if ceiling_log_base_2 != 0 { assert!(T::power_of_2(ceiling_log_base_2 - 1) < n); } let floor_log_base_2 = n.floor_log_base_2(); if n.is_power_of_2() { assert_eq!(floor_log_base_2, ceiling_log_base_2); } else { assert_eq!(floor_log_base_2, ceiling_log_base_2 - 1); } }); } fn ceiling_log_base_2_properties_helper_primitive_float() { primitive_float_gen_var_18::().test_properties(|n| { let ceiling_log_base_2 = n.ceiling_log_base_2(); assert!(ceiling_log_base_2 <= T::MAX_EXPONENT + 1); assert!(ceiling_log_base_2 >= T::MIN_EXPONENT); assert_eq!(ceiling_log_base_2 == 0, n > T::ONE / T::TWO && n <= T::ONE); if ceiling_log_base_2 < T::MAX_EXPONENT { assert!(T::power_of_2(ceiling_log_base_2) >= n); } if ceiling_log_base_2 > T::MIN_EXPONENT { assert!(T::power_of_2(ceiling_log_base_2 - 1) < n); } let floor_log_base_2 = n.floor_log_base_2(); if n.is_power_of_2() { assert_eq!(floor_log_base_2, ceiling_log_base_2); } else { assert_eq!(floor_log_base_2, ceiling_log_base_2 - 1); } }); } #[test] fn ceiling_log_base_2_properties() { apply_fn_to_unsigneds!(ceiling_log_base_2_properties_helper_unsigned); apply_fn_to_primitive_floats!(ceiling_log_base_2_properties_helper_primitive_float); } fn checked_log_base_2_properties_helper_unsigned() { unsigned_gen_var_1::().test_properties(|n| { let checked_log_base_2 = n.checked_log_base_2(); assert_eq!(checked_log_base_2.is_some(), n.is_power_of_2()); if let Some(log_base_2) = checked_log_base_2 { assert_eq!(T::power_of_2(log_base_2), n); assert!(log_base_2 <= T::WIDTH); assert_eq!(log_base_2 == 0, n == T::ONE); assert_eq!(n.floor_log_base_2(), log_base_2); assert_eq!(n.ceiling_log_base_2(), log_base_2); } }); } fn checked_log_base_2_properties_helper_primitive_float() { primitive_float_gen_var_18::().test_properties(|n| { let checked_log_base_2 = n.checked_log_base_2(); assert_eq!(checked_log_base_2.is_some(), n.is_power_of_2()); if let Some(log_base_2) = checked_log_base_2 { assert_eq!(T::power_of_2(log_base_2), n); assert!(log_base_2 <= T::MAX_EXPONENT); assert!(log_base_2 >= T::MIN_EXPONENT); assert_eq!(log_base_2 == 0, n == T::ONE); assert_eq!(n.floor_log_base_2(), log_base_2); assert_eq!(n.ceiling_log_base_2(), log_base_2); } }); } #[test] fn checked_log_base_2_properties() { apply_fn_to_unsigneds!(checked_log_base_2_properties_helper_unsigned); apply_fn_to_primitive_floats!(checked_log_base_2_properties_helper_primitive_float); } malachite-base-0.4.16/tests/num/arithmetic/log_base_power_of_2.rs000064400000000000000000000464261046102023000231230ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::log_base_power_of_2::ceiling_log_base_power_of_2_naive; use malachite_base::num::arithmetic::traits::DivisibleBy; use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::ExactFrom; use malachite_base::test_util::generators::{ primitive_float_gen_var_18, primitive_float_unsigned_pair_gen_var_3, unsigned_gen_var_1, unsigned_gen_var_11, unsigned_pair_gen_var_21, }; use std::panic::catch_unwind; fn floor_log_base_power_of_2_helper_unsigned() { let test = |n: T, pow, out| { assert_eq!(n.floor_log_base_power_of_2(pow), out); }; test(T::ONE, 1, 0); test(T::ONE, 5, 0); test(T::TWO, 1, 1); test(T::TWO, 2, 0); test(T::exact_from(3), 1, 1); test(T::exact_from(3), 2, 0); test(T::exact_from(4), 1, 2); test(T::exact_from(4), 2, 1); test(T::exact_from(4), 3, 0); test(T::exact_from(5), 1, 2); test(T::exact_from(5), 2, 1); test(T::exact_from(5), 3, 0); test(T::exact_from(100), 1, 6); test(T::exact_from(100), 2, 3); test(T::exact_from(100), 3, 2); test(T::exact_from(100), 4, 1); test(T::exact_from(100), 7, 0); test(T::exact_from(128), 1, 7); test(T::exact_from(128), 2, 3); test(T::exact_from(128), 3, 2); test(T::exact_from(128), 4, 1); test(T::exact_from(128), 7, 1); test(T::MAX, 1, T::WIDTH - 1); } fn floor_log_base_power_of_2_helper_primitive_float() { let test = |n: T, pow, out| { assert_eq!(n.floor_log_base_power_of_2(pow), out); }; test(T::ONE, 1, 0); test(T::ONE, 5, 0); test(T::TWO, 1, 1); test(T::TWO, 2, 0); test(T::from(3.0f32), 1, 1); test(T::from(3.0f32), 2, 0); test(T::from(4.0f32), 1, 2); test(T::from(4.0f32), 2, 1); test(T::from(4.0f32), 3, 0); test(T::from(5.0f32), 1, 2); test(T::from(5.0f32), 2, 1); test(T::from(5.0f32), 3, 0); test(T::from(100.0f32), 1, 6); test(T::from(100.0f32), 2, 3); test(T::from(100.0f32), 3, 2); test(T::from(100.0f32), 4, 1); test(T::from(100.0f32), 7, 0); test(T::from(128.0f32), 1, 7); test(T::from(128.0f32), 2, 3); test(T::from(128.0f32), 3, 2); test(T::from(128.0f32), 4, 1); test(T::from(128.0f32), 7, 1); test(T::from(0.1f32), 1, -4); test(T::from(0.1f32), 2, -2); test(T::from(0.1f32), 3, -2); test(T::from(0.1f32), 4, -1); test(T::MIN_POSITIVE_SUBNORMAL, 1, T::MIN_EXPONENT); test(T::MAX_FINITE, 1, T::MAX_EXPONENT); } #[test] fn test_floor_log_base_power_of_2() { apply_fn_to_unsigneds!(floor_log_base_power_of_2_helper_unsigned); apply_fn_to_primitive_floats!(floor_log_base_power_of_2_helper_primitive_float); } fn floor_log_base_power_of_2_fail_helper_unsigned() { assert_panic!(T::ZERO.floor_log_base_power_of_2(2)); assert_panic!(T::TWO.floor_log_base_power_of_2(0)); } fn floor_log_base_power_of_2_fail_helper_primitive_float() { assert_panic!(T::ZERO.floor_log_base_power_of_2(2)); assert_panic!(T::NEGATIVE_ONE.floor_log_base_power_of_2(2)); assert_panic!(T::NEGATIVE_INFINITY.floor_log_base_power_of_2(2)); assert_panic!(T::INFINITY.floor_log_base_power_of_2(2)); assert_panic!(T::NAN.floor_log_base_power_of_2(2)); assert_panic!(T::TWO.floor_log_base_power_of_2(0)); } #[test] fn floor_log_base_power_of_2_fail() { apply_fn_to_unsigneds!(floor_log_base_power_of_2_fail_helper_unsigned); apply_fn_to_primitive_floats!(floor_log_base_power_of_2_fail_helper_primitive_float); } fn ceiling_log_base_power_of_2_helper_unsigned() { let test = |n: T, pow, out| { assert_eq!(n.ceiling_log_base_power_of_2(pow), out); }; test(T::ONE, 1, 0); test(T::ONE, 5, 0); test(T::TWO, 1, 1); test(T::TWO, 2, 1); test(T::exact_from(3), 1, 2); test(T::exact_from(3), 2, 1); test(T::exact_from(4), 1, 2); test(T::exact_from(4), 2, 1); test(T::exact_from(4), 3, 1); test(T::exact_from(5), 1, 3); test(T::exact_from(5), 2, 2); test(T::exact_from(5), 3, 1); test(T::exact_from(100), 1, 7); test(T::exact_from(100), 2, 4); test(T::exact_from(100), 3, 3); test(T::exact_from(100), 4, 2); test(T::exact_from(100), 7, 1); test(T::exact_from(128), 1, 7); test(T::exact_from(128), 2, 4); test(T::exact_from(128), 3, 3); test(T::exact_from(128), 4, 2); test(T::exact_from(128), 7, 1); test(T::MAX, 1, T::WIDTH); } fn ceiling_log_base_power_of_2_helper_primitive_float() { let test = |n: T, pow, out| { assert_eq!(n.ceiling_log_base_power_of_2(pow), out); }; test(T::ONE, 1, 0); test(T::ONE, 5, 0); test(T::TWO, 1, 1); test(T::TWO, 2, 1); test(T::from(3.0f32), 1, 2); test(T::from(3.0f32), 2, 1); test(T::from(4.0f32), 1, 2); test(T::from(4.0f32), 2, 1); test(T::from(4.0f32), 3, 1); test(T::from(5.0f32), 1, 3); test(T::from(5.0f32), 2, 2); test(T::from(5.0f32), 3, 1); test(T::from(100.0f32), 1, 7); test(T::from(100.0f32), 2, 4); test(T::from(100.0f32), 3, 3); test(T::from(100.0f32), 4, 2); test(T::from(100.0f32), 7, 1); test(T::from(128.0f32), 1, 7); test(T::from(128.0f32), 2, 4); test(T::from(128.0f32), 3, 3); test(T::from(128.0f32), 4, 2); test(T::from(128.0f32), 7, 1); test(T::from(0.1f32), 1, -3); test(T::from(0.1f32), 2, -1); test(T::from(0.1f32), 3, -1); test(T::from(0.1f32), 4, 0); test(T::MIN_POSITIVE_SUBNORMAL, 1, T::MIN_EXPONENT); test(T::MAX_FINITE, 1, T::MAX_EXPONENT + 1); } #[test] fn test_ceiling_log_base_power_of_2() { apply_fn_to_unsigneds!(ceiling_log_base_power_of_2_helper_unsigned); apply_fn_to_primitive_floats!(ceiling_log_base_power_of_2_helper_primitive_float); } fn ceiling_log_base_power_of_2_fail_helper_unsigned() { assert_panic!(T::ZERO.ceiling_log_base_power_of_2(2)); assert_panic!(T::TWO.ceiling_log_base_power_of_2(0)); } fn ceiling_log_base_power_of_2_fail_helper_primitive_float() { assert_panic!(T::ZERO.ceiling_log_base_power_of_2(2)); assert_panic!(T::NEGATIVE_ONE.ceiling_log_base_power_of_2(2)); assert_panic!(T::NEGATIVE_INFINITY.ceiling_log_base_power_of_2(2)); assert_panic!(T::INFINITY.ceiling_log_base_power_of_2(2)); assert_panic!(T::NAN.ceiling_log_base_power_of_2(2)); assert_panic!(T::TWO.ceiling_log_base_power_of_2(0)); } #[test] fn ceiling_log_base_power_of_2_fail() { apply_fn_to_unsigneds!(ceiling_log_base_power_of_2_fail_helper_unsigned); apply_fn_to_primitive_floats!(ceiling_log_base_power_of_2_fail_helper_primitive_float); } fn checked_log_base_power_of_2_helper_unsigned() { let test = |n: T, pow, out| { assert_eq!(n.checked_log_base_power_of_2(pow), out); }; test(T::ONE, 1, Some(0)); test(T::ONE, 5, Some(0)); test(T::TWO, 1, Some(1)); test(T::TWO, 2, None); test(T::exact_from(3), 1, None); test(T::exact_from(3), 2, None); test(T::exact_from(4), 1, Some(2)); test(T::exact_from(4), 2, Some(1)); test(T::exact_from(4), 3, None); test(T::exact_from(5), 1, None); test(T::exact_from(5), 2, None); test(T::exact_from(5), 3, None); test(T::exact_from(100), 1, None); test(T::exact_from(100), 2, None); test(T::exact_from(100), 3, None); test(T::exact_from(100), 4, None); test(T::exact_from(100), 7, None); test(T::exact_from(128), 1, Some(7)); test(T::exact_from(128), 2, None); test(T::exact_from(128), 3, None); test(T::exact_from(128), 4, None); test(T::exact_from(128), 7, Some(1)); test(T::MAX, 1, None); } fn checked_log_base_power_of_2_helper_primitive_float() { let test = |n: T, pow, out| { assert_eq!(n.checked_log_base_power_of_2(pow), out); }; test(T::ONE, 1, Some(0)); test(T::ONE, 5, Some(0)); test(T::TWO, 1, Some(1)); test(T::TWO, 2, None); test(T::from(3.0f32), 1, None); test(T::from(3.0f32), 2, None); test(T::from(4.0f32), 1, Some(2)); test(T::from(4.0f32), 2, Some(1)); test(T::from(4.0f32), 3, None); test(T::from(5.0f32), 1, None); test(T::from(5.0f32), 2, None); test(T::from(5.0f32), 3, None); test(T::from(100.0f32), 1, None); test(T::from(100.0f32), 2, None); test(T::from(100.0f32), 3, None); test(T::from(100.0f32), 4, None); test(T::from(100.0f32), 7, None); test(T::from(128.0f32), 1, Some(7)); test(T::from(128.0f32), 2, None); test(T::from(128.0f32), 3, None); test(T::from(128.0f32), 4, None); test(T::from(128.0f32), 7, Some(1)); test(T::from(0.1f32), 1, None); test(T::from(0.1f32), 2, None); test(T::from(0.1f32), 3, None); test(T::from(0.1f32), 4, None); test(T::MIN_POSITIVE_SUBNORMAL, 1, Some(T::MIN_EXPONENT)); test(T::MAX_FINITE, 1, None); } #[test] fn test_checked_log_base_power_of_2() { apply_fn_to_unsigneds!(checked_log_base_power_of_2_helper_unsigned); apply_fn_to_primitive_floats!(checked_log_base_power_of_2_helper_primitive_float); } fn checked_log_base_power_of_2_fail_helper_unsigned() { assert_panic!(T::ZERO.checked_log_base_power_of_2(2)); assert_panic!(T::TWO.checked_log_base_power_of_2(0)); } fn checked_log_base_power_of_2_fail_helper_primitive_float() { assert_panic!(T::ZERO.checked_log_base_power_of_2(2)); assert_panic!(T::NEGATIVE_ONE.checked_log_base_power_of_2(2)); assert_panic!(T::NEGATIVE_INFINITY.checked_log_base_power_of_2(2)); assert_panic!(T::INFINITY.checked_log_base_power_of_2(2)); assert_panic!(T::NAN.checked_log_base_power_of_2(2)); assert_panic!(T::TWO.checked_log_base_power_of_2(0)); } #[test] fn checked_log_base_power_of_2_fail() { apply_fn_to_unsigneds!(checked_log_base_power_of_2_fail_helper_unsigned); apply_fn_to_primitive_floats!(checked_log_base_power_of_2_fail_helper_primitive_float); } fn floor_log_base_power_of_2_properties_helper_unsigned() { unsigned_pair_gen_var_21::().test_properties(|(n, pow)| { let floor_log = n.floor_log_base_power_of_2(pow); assert!(floor_log < T::WIDTH); assert_eq!(floor_log == 0, n.significant_bits() - 1 < pow); if pow < T::WIDTH { assert_eq!(n.floor_log_base(T::power_of_2(pow)), floor_log); } let product = floor_log * pow; if product < T::WIDTH { assert!(T::power_of_2(product) <= n); } let product_2 = product + pow; if product_2 < T::WIDTH { assert!(T::power_of_2(product_2) > n); } let ceiling_log = n.ceiling_log_base_power_of_2(pow); if n.is_power_of_2() && (n.significant_bits() - 1).divisible_by(pow) { assert_eq!(ceiling_log, floor_log); } else { assert_eq!(ceiling_log, floor_log + 1); } }); unsigned_gen_var_1::().test_properties(|n| { assert_eq!(n.floor_log_base_power_of_2(1), n.floor_log_base_2()); assert_eq!(n.floor_log_base_power_of_2(T::WIDTH), 0); }); unsigned_gen_var_11().test_properties(|pow| { assert_eq!(T::ONE.floor_log_base_power_of_2(pow), 0); if pow < T::WIDTH { assert_eq!(T::power_of_2(pow).floor_log_base_power_of_2(pow), 1); } }); } fn floor_log_base_power_of_2_properties_helper_primitive_float() { primitive_float_unsigned_pair_gen_var_3::().test_properties(|(n, pow)| { let floor_log = n.floor_log_base_power_of_2(pow); assert!(floor_log <= T::MAX_EXPONENT); assert!(floor_log >= T::MIN_EXPONENT); let i_pow = i64::exact_from(pow); if i_pow >= T::MIN_EXPONENT && i_pow <= T::MAX_EXPONENT { assert_eq!(floor_log == 0, n >= T::ONE && n < T::power_of_2(i_pow)); } let product = floor_log * i_pow; if product >= T::MIN_EXPONENT && product <= T::MAX_EXPONENT { assert!(T::power_of_2(product) <= n); } let product_2 = product + i_pow; if product_2 >= T::MIN_EXPONENT && product_2 <= T::MAX_EXPONENT { assert!(T::power_of_2(product_2) > n); } let ceiling_log = n.ceiling_log_base_power_of_2(pow); if n.is_power_of_2() && n.floor_log_base_2().divisible_by(i_pow) { assert_eq!(ceiling_log, floor_log); } else { assert_eq!(ceiling_log, floor_log + 1); } }); primitive_float_gen_var_18::().test_properties(|n| { assert_eq!(n.floor_log_base_power_of_2(1), n.floor_log_base_2()); }); unsigned_gen_var_11().test_properties(|pow| { assert_eq!(T::ONE.floor_log_base_power_of_2(pow), 0); }); } #[test] fn floor_log_base_power_of_2_properties_unsigned() { apply_fn_to_unsigneds!(floor_log_base_power_of_2_properties_helper_unsigned); apply_fn_to_primitive_floats!(floor_log_base_power_of_2_properties_helper_primitive_float); } fn ceiling_log_base_power_of_2_properties_helper_unsigned() { unsigned_pair_gen_var_21::().test_properties(|(n, pow)| { let ceiling_log = n.ceiling_log_base_power_of_2(pow); assert!(ceiling_log <= T::WIDTH); assert_eq!(ceiling_log, ceiling_log_base_power_of_2_naive(n, pow)); assert_eq!(ceiling_log == 0, n == T::ONE); if pow < T::WIDTH { assert_eq!(n.ceiling_log_base(T::power_of_2(pow)), ceiling_log); } let product = ceiling_log * pow; if product < T::WIDTH { assert!(T::power_of_2(product) >= n); } if product != 0 { assert!(T::power_of_2(product - pow) < n); } let floor_log = n.floor_log_base_power_of_2(pow); if n.is_power_of_2() && (n.significant_bits() - 1).divisible_by(pow) { assert_eq!(floor_log, ceiling_log); } else { assert_eq!(floor_log, ceiling_log - 1); } }); unsigned_gen_var_1::().test_properties(|n| { assert_eq!(n.ceiling_log_base_power_of_2(1), n.ceiling_log_base_2()); assert_eq!( n.ceiling_log_base_power_of_2(T::WIDTH), u64::from(n != T::ONE) ); }); unsigned_gen_var_11().test_properties(|pow| { assert_eq!(T::ONE.ceiling_log_base_power_of_2(pow), 0); if pow < T::WIDTH { assert_eq!(T::power_of_2(pow).ceiling_log_base_power_of_2(pow), 1); } }); } fn ceiling_log_base_power_of_2_properties_helper_primitive_float() { primitive_float_unsigned_pair_gen_var_3::().test_properties(|(n, pow)| { let ceiling_log = n.ceiling_log_base_power_of_2(pow); assert!(ceiling_log <= T::MAX_EXPONENT + 1); assert!(ceiling_log >= T::MIN_EXPONENT); let i_pow = i64::exact_from(pow); if i_pow >= T::MIN_EXPONENT && i_pow <= T::MAX_EXPONENT { assert_eq!( ceiling_log == 0, n > T::ONE / T::power_of_2(i_pow) && n <= T::ONE ); } let product = ceiling_log * i_pow; if product >= T::MIN_EXPONENT && product <= T::MAX_EXPONENT { assert!(T::power_of_2(product) >= n); } let product_2 = product - i_pow; if product_2 >= T::MIN_EXPONENT && product_2 <= T::MAX_EXPONENT { assert!(T::power_of_2(product_2) < n); } let floor_log = n.floor_log_base_power_of_2(pow); if n.is_power_of_2() && n.floor_log_base_2().divisible_by(i_pow) { assert_eq!(floor_log, ceiling_log); } else { assert_eq!(floor_log, ceiling_log - 1); } }); primitive_float_gen_var_18::().test_properties(|n| { assert_eq!(n.ceiling_log_base_power_of_2(1), n.ceiling_log_base_2()); }); unsigned_gen_var_11().test_properties(|pow| { assert_eq!(T::ONE.ceiling_log_base_power_of_2(pow), 0); }); } #[test] fn ceiling_log_base_power_of_2_properties() { apply_fn_to_unsigneds!(ceiling_log_base_power_of_2_properties_helper_unsigned); apply_fn_to_primitive_floats!(ceiling_log_base_power_of_2_properties_helper_primitive_float); } fn checked_log_base_power_of_2_properties_helper_unsigned() { unsigned_pair_gen_var_21::().test_properties(|(n, pow)| { let checked_log = n.checked_log_base_power_of_2(pow); assert_eq!( checked_log.is_some(), n.is_power_of_2() && (n.significant_bits() - 1).divisible_by(pow) ); if pow < T::WIDTH { assert_eq!(n.checked_log_base(T::power_of_2(pow)), checked_log); } if let Some(log) = checked_log { assert_eq!(T::power_of_2(log * pow), n); assert!(log <= T::WIDTH); assert_eq!(log == 0, n == T::ONE); assert_eq!(n.floor_log_base_power_of_2(pow), log); assert_eq!(n.ceiling_log_base_power_of_2(pow), log); } }); unsigned_gen_var_1::().test_properties(|n| { assert_eq!(n.checked_log_base_power_of_2(1), n.checked_log_base_2()); assert_eq!( n.checked_log_base_power_of_2(T::WIDTH), if n == T::ONE { Some(0) } else { None } ); }); unsigned_gen_var_11().test_properties(|pow| { assert_eq!(T::ONE.checked_log_base_power_of_2(pow), Some(0)); if pow < T::WIDTH { assert_eq!(T::power_of_2(pow).checked_log_base_power_of_2(pow), Some(1)); } }); } fn checked_log_base_power_of_2_properties_helper_primitive_float() { primitive_float_unsigned_pair_gen_var_3::().test_properties(|(n, pow)| { let checked_log = n.checked_log_base_power_of_2(pow); let i_pow = i64::exact_from(pow); assert_eq!( checked_log.is_some(), n.is_power_of_2() && n.checked_log_base_2().unwrap().divisible_by(i_pow) ); if let Some(log) = checked_log { assert_eq!(T::power_of_2(log * i_pow), n); assert!(log <= T::MAX_EXPONENT); assert!(log >= T::MIN_EXPONENT); assert_eq!(log == 0, n == T::ONE); assert_eq!(n.floor_log_base_power_of_2(pow), log); assert_eq!(n.ceiling_log_base_power_of_2(pow), log); } }); primitive_float_gen_var_18::().test_properties(|n| { assert_eq!(n.checked_log_base_power_of_2(1), n.checked_log_base_2()); }); unsigned_gen_var_11().test_properties(|pow| { assert_eq!(T::ONE.checked_log_base_power_of_2(pow), Some(0)); let i_pow = i64::exact_from(pow); if i_pow >= T::MIN_EXPONENT && i_pow <= T::MAX_EXPONENT { assert_eq!( T::power_of_2(i_pow).checked_log_base_power_of_2(pow), Some(1) ); } }); } #[test] fn checked_log_base_power_of_2_properties() { apply_fn_to_unsigneds!(checked_log_base_power_of_2_properties_helper_unsigned); apply_fn_to_primitive_floats!(checked_log_base_power_of_2_properties_helper_primitive_float); } malachite-base-0.4.16/tests/num/arithmetic/mod_add.rs000064400000000000000000000067271046102023000206160ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ unsigned_pair_gen_var_16, unsigned_pair_gen_var_27, unsigned_quadruple_gen_var_4, unsigned_triple_gen_var_12, }; use std::panic::catch_unwind; fn mod_add_helper() { let test = |x: T, y: T, m, out| { assert_eq!(x.mod_add(y, m), out); let mut x = x; x.mod_add_assign(y, m); assert_eq!(x, out); }; test(T::ZERO, T::ZERO, T::ONE, T::ZERO); test( T::ZERO, T::exact_from(3), T::exact_from(5), T::exact_from(3), ); test( T::exact_from(7), T::exact_from(5), T::exact_from(10), T::TWO, ); test( T::exact_from(100), T::exact_from(100), T::exact_from(123), T::exact_from(77), ); test(T::MAX - T::ONE, T::ONE, T::MAX, T::ZERO); test(T::MAX - T::ONE, T::MAX - T::ONE, T::MAX, T::MAX - T::TWO); } #[test] fn test_mod_add() { apply_fn_to_unsigneds!(mod_add_helper); } fn mod_add_fail_helper() { assert_panic!(T::ZERO.mod_add(T::ZERO, T::ZERO)); assert_panic!(T::from(123u8).mod_add(T::from(200u8), T::from(200u8))); assert_panic!(T::from(200u8).mod_add(T::from(123u8), T::from(200u8))); } #[test] fn mod_add_fail() { apply_fn_to_unsigneds!(mod_add_fail_helper); } fn mod_add_assign_fail_helper() { assert_panic!({ let mut x = T::ZERO; x.mod_add_assign(T::ZERO, T::ZERO); }); assert_panic!({ let mut x = T::from(123u8); x.mod_add_assign(T::from(200u8), T::from(200u8)); }); assert_panic!({ let mut x = T::from(200u8); x.mod_add_assign(T::from(123u8), T::from(200u8)); }); } #[test] fn mod_add_assign_fail() { apply_fn_to_unsigneds!(mod_add_assign_fail_helper); } fn mod_add_properties_helper() { unsigned_triple_gen_var_12::().test_properties(|(x, y, m)| { assert!(x.mod_is_reduced(&m)); assert!(y.mod_is_reduced(&m)); let sum = x.mod_add(y, m); assert!(sum.mod_is_reduced(&m)); let mut x_alt = x; x_alt.mod_add_assign(y, m); assert_eq!(x_alt, sum); assert_eq!(sum.mod_sub(y, m), x); assert_eq!(sum.mod_sub(x, m), y); assert_eq!(y.mod_add(x, m), sum); assert_eq!(x.mod_sub(y.mod_neg(m), m), sum); }); unsigned_pair_gen_var_16::().test_properties(|(x, m)| { assert_eq!(x.mod_add(T::ZERO, m), x); assert_eq!(T::ZERO.mod_add(x, m), x); assert_eq!(x.mod_add(x.mod_neg(m), m), T::ZERO); }); unsigned_pair_gen_var_27::().test_properties(|(x, y)| { assert_panic!(x.mod_add(y, T::ZERO)); assert_panic!({ let mut x = x; x.mod_add_assign(y, T::ZERO); }); }); unsigned_quadruple_gen_var_4::().test_properties(|(x, y, z, m)| { assert_eq!(x.mod_add(y, m).mod_add(z, m), x.mod_add(y.mod_add(z, m), m)); }); } #[test] fn mod_add_properties() { apply_fn_to_unsigneds!(mod_add_properties_helper); } malachite-base-0.4.16/tests/num/arithmetic/mod_inverse.rs000064400000000000000000000060361046102023000215320ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::mod_inverse::mod_inverse_binary; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::WrappingFrom; use malachite_base::test_util::generators::{ unsigned_gen, unsigned_gen_var_6, unsigned_pair_gen_var_38, }; use malachite_base::test_util::num::arithmetic::mod_inverse::mod_inverse_euclidean; use std::panic::catch_unwind; fn mod_inverse_helper< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >() { let test = |n: U, m, out| { assert_eq!(n.mod_inverse(m), out); assert_eq!(mod_inverse_euclidean::(n, m), out); assert_eq!(mod_inverse_binary::(n, m), out); }; test(U::ONE, U::exact_from(5), Some(U::ONE)); test(U::exact_from(7), U::exact_from(10), Some(U::exact_from(3))); test(U::exact_from(6), U::exact_from(10), None); test( U::exact_from(100), U::exact_from(101), Some(U::exact_from(100)), ); test(U::ONE, U::MAX, Some(U::ONE)); test(U::MAX - U::ONE, U::MAX, Some(U::MAX - U::ONE)); } #[test] fn test_mod_inverse() { apply_fn_to_unsigned_signed_pairs!(mod_inverse_helper); } fn mod_inverse_fail_helper() { assert_panic!(T::ZERO.mod_inverse(T::ZERO)); assert_panic!(T::ZERO.mod_inverse(T::from(10u8))); assert_panic!(T::from(123u8).mod_inverse(T::from(123u8))); } #[test] fn mod_inverse_fail() { apply_fn_to_unsigneds!(mod_inverse_fail_helper); } fn mod_inverse_properties_helper< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >() { unsigned_pair_gen_var_38::().test_properties(|(n, m)| { assert!(n.mod_is_reduced(&m)); let inverse = n.mod_inverse(m); assert_eq!(mod_inverse_euclidean::(n, m), inverse); assert_eq!(mod_inverse_binary::(n, m), inverse); assert_eq!(inverse.is_some(), n.coprime_with(m)); if let Some(inverse) = inverse { assert!(inverse.mod_is_reduced(&m)); assert_eq!(inverse.mod_inverse(m), Some(n)); assert_eq!(n.mod_mul(inverse, m), U::ONE); assert_eq!((m - n).mod_inverse(m), Some(m - inverse)); } }); unsigned_gen_var_6::().test_properties(|m| { assert_eq!(U::ONE.mod_inverse(m), Some(U::ONE)); assert_eq!((m - U::ONE).mod_inverse(m), Some(m - U::ONE)); }); unsigned_gen::().test_properties(|x| { assert_panic!(x.mod_inverse(U::ZERO)); }); } #[test] fn mod_inverse_properties() { apply_fn_to_unsigned_signed_pairs!(mod_inverse_properties_helper); } malachite-base-0.4.16/tests/num/arithmetic/mod_is_reduced.rs000064400000000000000000000030201046102023000221530ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::unsigned_pair_gen_var_12; use std::panic::catch_unwind; fn mod_is_reduced_helper() { let test = |n: T, m, out| { assert_eq!(n.mod_is_reduced(&m), out); }; test(T::ZERO, T::exact_from(5), true); test(T::exact_from(100), T::exact_from(100), false); test(T::exact_from(100), T::exact_from(101), true); test(T::MAX - T::ONE, T::MAX - T::ONE, false); test(T::MAX - T::ONE, T::MAX, true); test(T::MAX, T::MAX, false); } #[test] fn test_mod_is_reduced() { apply_fn_to_unsigneds!(mod_is_reduced_helper); } fn mod_is_reduced_fail_helper() { assert_panic!(T::ZERO.mod_is_reduced(&T::ZERO)); } #[test] fn mod_is_reduced_fail() { apply_fn_to_unsigneds!(mod_is_reduced_fail_helper); } fn mod_is_reduced_properties_helper() { unsigned_pair_gen_var_12::().test_properties(|(n, m)| { assert_eq!(n.mod_is_reduced(&m), n % m == n); }); } #[test] fn mod_is_reduced_properties() { apply_fn_to_unsigneds!(mod_is_reduced_properties_helper); } malachite-base-0.4.16/tests/num/arithmetic/mod_mul.rs000064400000000000000000000206621046102023000206550ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::mod_mul::{ fast_mod_mul, limbs_invert_limb_u32, limbs_invert_limb_u64, limbs_mod_preinverted, naive_mod_mul, test_invert_u32_table, test_invert_u64_table, }; use malachite_base::num::arithmetic::traits::ModMulPrecomputed; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::{HasHalf, JoinHalves, SplitInHalf}; use malachite_base::num::logic::traits::LeadingZeros; use malachite_base::test_util::generators::{ unsigned_gen_var_12, unsigned_pair_gen_var_16, unsigned_pair_gen_var_27, unsigned_quadruple_gen_var_4, unsigned_quadruple_gen_var_5, unsigned_triple_gen_var_12, }; use malachite_base::test_util::num::arithmetic::mod_mul::limbs_invert_limb_naive; use std::panic::catch_unwind; #[test] fn test_test_invert_u32_table() { test_invert_u32_table(); } #[test] fn test_test_invert_u64_table() { test_invert_u64_table(); } #[test] fn test_limbs_invert_limb_u32() { let test = |x, out| { assert_eq!(limbs_invert_limb_u32(x), out); assert_eq!(limbs_invert_limb_naive::(x), out); }; test(0x80000000, u32::MAX); test(0x80000001, 0xfffffffc); test(u32::MAX - 1, 2); test(u32::MAX, 1); test(0x89abcdef, 0xdc08767e); } #[test] #[should_panic] fn limbs_invert_limb_u32_fail() { limbs_invert_limb_u32(123); } #[test] fn test_limbs_invert_limb_u64() { let test = |x, out| { assert_eq!(limbs_invert_limb_u64(x), out); assert_eq!(limbs_invert_limb_naive::(x), out); }; test(0x8000000000000000, u64::MAX); test(0x8000000000000001, 0xfffffffffffffffc); test(0xfffffffffffffffe, 2); test(u64::MAX, 1); test(0x89abcdefedcba987, 0xdc08767b33d7ec8f); } #[test] #[should_panic] fn limbs_invert_limb_u64_fail() { limbs_invert_limb_u64(123); } #[test] fn test_limbs_mod_preinverted() { fn test< T: TryFrom
+ PrimitiveUnsigned, DT: From + HasHalf + JoinHalves + PrimitiveUnsigned + SplitInHalf, >( x_1: T, x_0: T, d: T, out: T, ) { let d_inv = limbs_invert_limb_naive::(d << LeadingZeros::leading_zeros(d)); assert_eq!(limbs_mod_preinverted::(x_1, x_0, d, d_inv), out); assert_eq!(T::exact_from(DT::join_halves(x_1, x_0) % DT::from(d)), out); } test::(0, 0, 1, 0); test::(0, 1, 1, 0); test::(1, 0, 2, 0); test::(1, 7, 2, 1); test::(0x78, 0x9a, 0xbc, 0x2a); test::(0x12, 0x34, 0x33, 0x13); } fn mod_mul_helper() { let test = |x: T, y: T, m, out| { assert_eq!(x.mod_mul(y, m), out); let mut mut_x = x; mut_x.mod_mul_assign(y, m); assert_eq!(mut_x, out); let data = T::precompute_mod_mul_data(&m); assert_eq!(x.mod_mul_precomputed(y, m, &data), out); let mut mut_x = x; mut_x.mod_mul_precomputed_assign(y, m, &data); assert_eq!(mut_x, out); assert_eq!(naive_mod_mul(x, y, m), out); }; test(T::ZERO, T::ZERO, T::ONE, T::ZERO); test(T::TWO, T::exact_from(3), T::exact_from(7), T::exact_from(6)); test( T::exact_from(7), T::exact_from(3), T::exact_from(10), T::ONE, ); test( T::exact_from(100), T::exact_from(100), T::exact_from(123), T::exact_from(37), ); test(T::MAX - T::ONE, T::MAX - T::ONE, T::MAX, T::ONE); } #[test] fn test_mod_mul() { apply_fn_to_unsigneds!(mod_mul_helper); } fn mod_mul_fail_helper() { assert_panic!(T::ZERO.mod_mul(T::ZERO, T::ZERO)); assert_panic!(T::from(123u8).mod_mul(T::from(200u8), T::from(200u8))); assert_panic!(T::from(200u8).mod_mul(T::from(123u8), T::from(200u8))); } #[test] fn mod_mul_fail() { apply_fn_to_unsigneds!(mod_mul_fail_helper); } fn mod_mul_assign_fail_helper() { assert_panic!({ let mut x = T::ZERO; x.mod_mul_assign(T::ZERO, T::ZERO); }); assert_panic!({ let mut x = T::from(123u8); x.mod_mul_assign(T::from(200u8), T::from(200u8)); }); assert_panic!({ let mut x = T::from(200u8); x.mod_mul_assign(T::from(123u8), T::from(200u8)); }); } #[test] fn mod_mul_assign_fail() { apply_fn_to_unsigneds!(mod_mul_assign_fail_helper); } #[test] fn invert_limb_u32_properties() { unsigned_gen_var_12().test_properties(|x| { let inverse = limbs_invert_limb_u32(x); assert_eq!(limbs_invert_limb_naive::(x), inverse); assert_ne!(inverse, 0); }); } #[test] fn invert_limb_u64_properties() { unsigned_gen_var_12().test_properties(|x| { let inverse = limbs_invert_limb_u64(x); assert_eq!(limbs_invert_limb_naive::(x), inverse); assert_ne!(inverse, 0); }); } fn mod_mul_preinverted_properties_helper< T: TryFrom
+ PrimitiveUnsigned, DT: From + HasHalf + JoinHalves + PrimitiveUnsigned + SplitInHalf, >() { unsigned_quadruple_gen_var_5::().test_properties(|(x_1, x_0, d, d_inv)| { let r = limbs_mod_preinverted::(x_1, x_0, d, d_inv); let n = DT::join_halves(x_1, x_0); assert_eq!(T::exact_from(n % DT::from(d)), r); assert!(r < d); let q = DT::join_halves(x_1, x_0) / DT::from(d); assert_eq!(q * DT::from(d) + DT::from(r), n); }); } #[test] fn mod_mul_preinverted_properties() { mod_mul_preinverted_properties_helper::(); mod_mul_preinverted_properties_helper::(); mod_mul_preinverted_properties_helper::(); mod_mul_preinverted_properties_helper::(); } fn mod_mul_properties_helper() { unsigned_triple_gen_var_12::().test_properties(|(x, y, m)| { assert!(x.mod_is_reduced(&m)); assert!(y.mod_is_reduced(&m)); let product = x.mod_mul(y, m); assert!(product.mod_is_reduced(&m)); let mut x_alt = x; x_alt.mod_mul_assign(y, m); assert_eq!(x_alt, product); let data = T::precompute_mod_mul_data(&m); assert_eq!(x.mod_mul_precomputed(y, m, &data), product); let mut x_alt = x; x_alt.mod_mul_precomputed_assign(y, m, &data); assert_eq!(x_alt, product); assert_eq!(naive_mod_mul(x, y, m), product); assert_eq!(y.mod_mul(x, m), product); assert_eq!(x.mod_mul(y.mod_neg(m), m), product.mod_neg(m)); assert_eq!(x.mod_neg(m).mod_mul(y, m), product.mod_neg(m)); }); unsigned_pair_gen_var_16::().test_properties(|(x, m)| { assert_eq!(x.mod_mul(T::ZERO, m), T::ZERO); assert_eq!(T::ZERO.mod_mul(x, m), T::ZERO); if m > T::ONE { assert_eq!(x.mod_mul(T::ONE, m), x); assert_eq!(T::ONE.mod_mul(x, m), x); } }); unsigned_pair_gen_var_27::().test_properties(|(x, y)| { assert_panic!(x.mod_mul(y, T::ZERO)); assert_panic!({ let mut x = x; x.mod_mul_assign(y, T::ZERO); }); }); unsigned_quadruple_gen_var_4::().test_properties(|(x, y, z, m)| { assert_eq!(x.mod_mul(y, m).mod_mul(z, m), x.mod_mul(y.mod_mul(z, m), m)); assert_eq!( x.mod_mul(y.mod_add(z, m), m), x.mod_mul(y, m).mod_add(x.mod_mul(z, m), m) ); assert_eq!( x.mod_add(y, m).mod_mul(z, m), x.mod_mul(z, m).mod_add(y.mod_mul(z, m), m) ); }); } fn mod_mul_properties_fast_helper< T: TryFrom
+ ModMulPrecomputed + PrimitiveUnsigned, DT: From + HasHalf + JoinHalves + PrimitiveUnsigned + SplitInHalf, >() { unsigned_triple_gen_var_12::().test_properties(|(x, y, m)| { let product = x.mod_mul(y, m); assert_eq!( fast_mod_mul::(x, y, m, T::precompute_mod_mul_data(&m)), product ); }); } #[test] fn mod_mul_properties() { apply_fn_to_unsigneds!(mod_mul_properties_helper); mod_mul_properties_fast_helper::(); mod_mul_properties_fast_helper::(); } malachite-base-0.4.16/tests/num/arithmetic/mod_neg.rs000064400000000000000000000051721046102023000206300ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ unsigned_gen, unsigned_gen_var_1, unsigned_gen_var_6, unsigned_pair_gen_var_16, }; use std::panic::catch_unwind; fn mod_neg_helper() { let test = |n: T, m, out| { assert_eq!(n.mod_neg(m), out); let mut n = n; n.mod_neg_assign(m); assert_eq!(n, out); }; test(T::ZERO, T::exact_from(5), T::ZERO); test(T::exact_from(7), T::exact_from(10), T::exact_from(3)); test(T::exact_from(100), T::exact_from(101), T::ONE); test(T::MAX - T::ONE, T::MAX, T::ONE); test(T::ONE, T::MAX, T::MAX - T::ONE); } #[test] fn test_mod_neg() { apply_fn_to_unsigneds!(mod_neg_helper); } fn mod_neg_fail_helper() { assert_panic!(T::ZERO.mod_neg(T::ZERO)); assert_panic!(T::from(123u8).mod_neg(T::from(123u8))); } #[test] fn mod_neg_fail() { apply_fn_to_unsigneds!(mod_neg_fail_helper); } fn mod_neg_assign_fail_helper() { assert_panic!({ let mut x = T::ZERO; x.mod_neg_assign(T::ZERO); }); assert_panic!({ let mut x = T::from(123u8); x.mod_neg_assign(T::from(123u8)); }); } #[test] fn mod_neg_assign_fail() { apply_fn_to_unsigneds!(mod_neg_assign_fail_helper); } fn mod_neg_properties_helper() { unsigned_pair_gen_var_16::().test_properties(|(n, m)| { assert!(n.mod_is_reduced(&m)); let neg = n.mod_neg(m); assert!(neg.mod_is_reduced(&m)); let mut n_alt = n; n_alt.mod_neg_assign(m); assert_eq!(n_alt, neg); assert_eq!(neg.mod_neg(m), n); assert_eq!(n.mod_add(neg, m), T::ZERO); assert_eq!(n == neg, n == T::ZERO || m.even() && n == m >> 1); }); unsigned_gen_var_1::().test_properties(|m| { assert_eq!(T::ZERO.mod_neg(m), T::ZERO); }); unsigned_gen_var_6::().test_properties(|m| { assert_eq!(T::ONE.mod_neg(m), m - T::ONE); assert_eq!((m - T::ONE).mod_neg(m), T::ONE); }); unsigned_gen::().test_properties(|x| { assert_panic!(x.mod_neg(T::ZERO)); }); } #[test] fn mod_neg_properties() { apply_fn_to_unsigneds!(mod_neg_properties_helper); } malachite-base-0.4.16/tests/num/arithmetic/mod_op.rs000064400000000000000000000521231046102023000204730ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ signed_gen, signed_gen_var_6, signed_pair_gen_var_4, signed_pair_gen_var_6, unsigned_gen, unsigned_gen_var_1, unsigned_pair_gen_var_12, }; use std::panic::catch_unwind; #[test] fn test_mod_op_unsigned() { fn test(n: T, d: T, r: T) { assert_eq!(n.mod_op(d), r); let mut mut_n = n; mut_n.mod_assign(d); assert_eq!(mut_n, r); } test::(0, 1, 0); test::(0, 123, 0); test::(1, 1, 0); test::(123, 1, 0); test::(123, 123, 0); test::(123, 456, 123); test::(456, 123, 87); test::(u32::MAX, 1, 0); test::(0xffffffff, 0xffffffff, 0); test::(1000000000000, 1, 0); test::(1000000000000, 3, 1); test::(1000000000000, 123, 100); test::(1000000000000, 0xffffffff, 3567587560); test::(1000000000000000000000000, 1, 0); test::(1000000000000000000000000, 3, 1); test::(1000000000000000000000000, 123, 37); test::(1000000000000000000000000, 0xffffffff, 3167723695); test::(1000000000000000000000000, 1234567890987, 530068894399); test::(253640751230376270397812803167, 2669936877441, 1520301762334); test::(3768477692975601, 11447376614057827956, 3768477692975601); test::(3356605361737854, 3081095617839357, 275509743898497); test::( 1098730198198174614195, 953382298040157850476, 145347900158016763719, ); test::( 69738658860594537152875081748, 69738658860594537152875081748, 0, ); test::(1000000000000000000000000, 1000000000000000000000000, 0); test::(0, 1000000000000000000000000, 0); test::(123, 1000000000000000000000000, 123); } #[test] fn test_div_mod_signed() { fn test(n: T, d: T, r: T) { assert_eq!(n.mod_op(d), r); let mut mut_n = n; mut_n.mod_assign(d); assert_eq!(mut_n, r); } test::(0, 1, 0); test::(0, 123, 0); test::(1, 1, 0); test::(123, 1, 0); test::(123, 123, 0); test::(123, 456, 123); test::(456, 123, 87); test::(0xffffffff, 1, 0); test::(0xffffffff, 0xffffffff, 0); test::(1000000000000, 1, 0); test::(1000000000000, 3, 1); test::(1000000000000, 123, 100); test::(1000000000000, 0xffffffff, 3567587560); test::(1000000000000000000000000, 1, 0); test::(1000000000000000000000000, 3, 1); test::(1000000000000000000000000, 123, 37); test::(1000000000000000000000000, 0xffffffff, 3167723695); test::(1000000000000000000000000, 1234567890987, 530068894399); test::(253640751230376270397812803167, 2669936877441, 1520301762334); test::(3768477692975601, 11447376614057827956, 3768477692975601); test::(3356605361737854, 3081095617839357, 275509743898497); test::( 1098730198198174614195, 953382298040157850476, 145347900158016763719, ); test::( 69738658860594537152875081748, 69738658860594537152875081748, 0, ); test::(1000000000000000000000000, 1000000000000000000000000, 0); test::(0, 1000000000000000000000000, 0); test::(123, 1000000000000000000000000, 123); test::(0, -1, 0); test::(0, -123, 0); test::(1, -1, 0); test::(123, -1, 0); test::(123, -123, 0); test::(123, -456, -333); test::(456, -123, -36); test::(0xffffffff, -1, 0); test::(0xffffffff, -0xffffffff, 0); test::(1000000000000, -1, 0); test::(1000000000000, -3, -2); test::(1000000000000, -123, -23); test::(1000000000000, -0xffffffff, -727379735); test::(1000000000000000000000000, -1, 0); test::(1000000000000000000000000, -3, -2); test::(1000000000000000000000000, -123, -86); test::(1000000000000000000000000, -0xffffffff, -1127243600); test::(1000000000000000000000000, -1234567890987, -704498996588); test::( 253640751230376270397812803167, -2669936877441, -1149635115107, ); test::( 3768477692975601, -11447376614057827956, -11443608136364852355, ); test::(3356605361737854, -3081095617839357, -2805585873940860); test::( 1098730198198174614195, -953382298040157850476, -808034397882141086757, ); test::( 69738658860594537152875081748, -69738658860594537152875081748, 0, ); test::(1000000000000000000000000, -1000000000000000000000000, 0); test::(0, -1000000000000000000000000, 0); test::(123, -1000000000000000000000000, -999999999999999999999877); test::(-1, 1, 0); test::(-123, 1, 0); test::(-123, 123, 0); test::(-123, 456, 333); test::(-456, 123, 36); test::(-0xffffffff, -1, 0); test::(-0xffffffff, 0xffffffff, 0); test::(-1000000000000, 1, 0); test::(-1000000000000, 3, 2); test::(-1000000000000, 123, 23); test::(-1000000000000, 0xffffffff, 727379735); test::(-1000000000000000000000000, 1, 0); test::(-1000000000000000000000000, 3, 2); test::(-1000000000000000000000000, 123, 86); test::(-1000000000000000000000000, 0xffffffff, 1127243600); test::(-1000000000000000000000000, 1234567890987, 704498996588); test::( -253640751230376270397812803167, 2669936877441, 1149635115107, ); test::( -3768477692975601, 11447376614057827956, 11443608136364852355, ); test::(-3356605361737854, 3081095617839357, 2805585873940860); test::( -1098730198198174614195, 953382298040157850476, 808034397882141086757, ); test::( -69738658860594537152875081748, 69738658860594537152875081748, 0, ); test::(-1000000000000000000000000, 1000000000000000000000000, 0); test::(-123, 1000000000000000000000000, 999999999999999999999877); test::(-1, -1, 0); test::(-123, -1, 0); test::(-123, -123, 0); test::(-123, -456, -123); test::(-456, -123, -87); test::(-0xffffffff, -1, 0); test::(-0xffffffff, -0xffffffff, 0); test::(-1000000000000, -1, 0); test::(-1000000000000, -3, -1); test::(-1000000000000, -123, -100); test::(-1000000000000, -0xffffffff, -3567587560); test::(-1000000000000000000000000, -1, 0); test::(-1000000000000000000000000, -3, -1); test::(-1000000000000000000000000, -123, -37); test::(-1000000000000000000000000, -0xffffffff, -3167723695); test::(-1000000000000000000000000, -1234567890987, -530068894399); test::( -253640751230376270397812803167, -2669936877441, -1520301762334, ); test::(-3768477692975601, -11447376614057827956, -3768477692975601); test::(-3356605361737854, -3081095617839357, -275509743898497); test::( -1098730198198174614195, -953382298040157850476, -145347900158016763719, ); test::( -69738658860594537152875081748, -69738658860594537152875081748, 0, ); test::(-1000000000000000000000000, -1000000000000000000000000, 0); test::(-123, -1000000000000000000000000, -123); test::(-128, -1, 0); } fn mod_fail_helper() { assert_panic!(T::ONE.mod_op(T::ZERO)); assert_panic!({ let mut n = T::ONE; n.mod_assign(T::ZERO); }); } #[test] pub fn mod_fail() { apply_fn_to_primitive_ints!(mod_fail_helper); } #[test] fn test_neg_mod() { fn test(n: T, d: T, r: T) { assert_eq!(n.neg_mod(d), r); let mut mut_n = n; mut_n.neg_mod_assign(d); assert_eq!(mut_n, r); } test::(0, 1, 0); test::(0, 123, 0); test::(1, 1, 0); test::(123, 1, 0); test::(123, 123, 0); test::(123, 456, 333); test::(456, 123, 36); test::(0xffffffff, 1, 0); test::(0xffffffff, 0xffffffff, 0); test::(1000000000000, 1, 0); test::(1000000000000, 3, 2); test::(1000000000000, 123, 23); test::(1000000000000, 0xffffffff, 727379735); test::(1000000000000000000000000, 1, 0); test::(1000000000000000000000000, 3, 2); test::(1000000000000000000000000, 123, 86); test::(1000000000000000000000000, 0xffffffff, 1127243600); test::(1000000000000000000000000, 1234567890987, 704498996588); test::(253640751230376270397812803167, 2669936877441, 1149635115107); test::(3768477692975601, 11447376614057827956, 11443608136364852355); test::(3356605361737854, 3081095617839357, 2805585873940860); test::( 1098730198198174614195, 953382298040157850476, 808034397882141086757, ); test::( 69738658860594537152875081748, 69738658860594537152875081748, 0, ); test::(1000000000000000000000000, 1000000000000000000000000, 0); test::(0, 1000000000000000000000000, 0); test::(123, 1000000000000000000000000, 999999999999999999999877); } fn neg_mod_fail_helper() { assert_panic!(T::ONE.neg_mod(T::ZERO)); assert_panic!({ let mut n = T::ONE; n.neg_mod_assign(T::ZERO); }); } #[test] pub fn neg_mod_fail() { apply_fn_to_unsigneds!(neg_mod_fail_helper); } #[test] fn test_ceiling_mod() { fn test(n: T, d: T, r: T) { assert_eq!(n.ceiling_mod(d), r); let mut mut_n = n; mut_n.ceiling_mod_assign(d); assert_eq!(mut_n, r); } test::(0, 1, 0); test::(0, 123, 0); test::(1, 1, 0); test::(123, 1, 0); test::(123, 123, 0); test::(123, 456, -333); test::(456, 123, -36); test::(0xffffffff, 1, 0); test::(0xffffffff, 0xffffffff, 0); test::(1000000000000, 1, 0); test::(1000000000000, 3, -2); test::(1000000000000, 123, -23); test::(1000000000000, 0xffffffff, -727379735); test::(1000000000000000000000000, 1, 0); test::(1000000000000000000000000, 3, -2); test::(1000000000000000000000000, 123, -86); test::(1000000000000000000000000, 0xffffffff, -1127243600); test::(1000000000000000000000000, 1234567890987, -704498996588); test::( 253640751230376270397812803167, 2669936877441, -1149635115107, ); test::( 3768477692975601, 11447376614057827956, -11443608136364852355, ); test::(3356605361737854, 3081095617839357, -2805585873940860); test::( 1098730198198174614195, 953382298040157850476, -808034397882141086757, ); test::( 69738658860594537152875081748, 69738658860594537152875081748, 0, ); test::(1000000000000000000000000, 1000000000000000000000000, 0); test::(0, 1000000000000000000000000, 0); test::(123, 1000000000000000000000000, -999999999999999999999877); test::(0, -1, 0); test::(0, -123, 0); test::(1, -1, 0); test::(123, -1, 0); test::(123, -123, 0); test::(123, -456, 123); test::(456, -123, 87); test::(0xffffffff, -1, 0); test::(0xffffffff, -0xffffffff, 0); test::(1000000000000, -1, 0); test::(1000000000000, -3, 1); test::(1000000000000, -123, 100); test::(1000000000000, -0xffffffff, 3567587560); test::(1000000000000000000000000, -1, 0); test::(1000000000000000000000000, -3, 1); test::(1000000000000000000000000, -123, 37); test::(1000000000000000000000000, -0xffffffff, 3167723695); test::(1000000000000000000000000, -1234567890987, 530068894399); test::( 253640751230376270397812803167, -2669936877441, 1520301762334, ); test::(3768477692975601, -11447376614057827956, 3768477692975601); test::(3356605361737854, -3081095617839357, 275509743898497); test::( 1098730198198174614195, -953382298040157850476, 145347900158016763719, ); test::( 69738658860594537152875081748, -69738658860594537152875081748, 0, ); test::(1000000000000000000000000, -1000000000000000000000000, 0); test::(0, -1000000000000000000000000, 0); test::(123, -1000000000000000000000000, 123); test::(-1, 1, 0); test::(-123, 1, 0); test::(-123, 123, 0); test::(-123, 456, -123); test::(-456, 123, -87); test::(-0xffffffff, 1, 0); test::(-0xffffffff, 0xffffffff, 0); test::(-1000000000000, 1, 0); test::(-1000000000000, 3, -1); test::(-1000000000000, 123, -100); test::(-1000000000000, 0xffffffff, -3567587560); test::(-1000000000000000000000000, 1, 0); test::(-1000000000000000000000000, 3, -1); test::(-1000000000000000000000000, 123, -37); test::(-1000000000000000000000000, 0xffffffff, -3167723695); test::(-1000000000000000000000000, 1234567890987, -530068894399); test::( -253640751230376270397812803167, 2669936877441, -1520301762334, ); test::(-3768477692975601, 11447376614057827956, -3768477692975601); test::(-3356605361737854, 3081095617839357, -275509743898497); test::( -1098730198198174614195, 953382298040157850476, -145347900158016763719, ); test::( -69738658860594537152875081748, 69738658860594537152875081748, 0, ); test::(-1000000000000000000000000, 1000000000000000000000000, 0); test::(0, 1000000000000000000000000, 0); test::(-123, 1000000000000000000000000, -123); test::(-1, -1, 0); test::(-123, -1, 0); test::(-123, -123, 0); test::(-123, -456, 333); test::(-456, -123, 36); test::(-0xffffffff, -1, 0); test::(-0xffffffff, -0xffffffff, 0); test::(-1000000000000, -1, 0); test::(-1000000000000, -3, 2); test::(-1000000000000, -123, 23); test::(-1000000000000, -0xffffffff, 727379735); test::(-1000000000000000000000000, -1, 0); test::(-1000000000000000000000000, -3, 2); test::(-1000000000000000000000000, -123, 86); test::(-1000000000000000000000000, -0xffffffff, 1127243600); test::(-1000000000000000000000000, -1234567890987, 704498996588); test::( -253640751230376270397812803167, -2669936877441, 1149635115107, ); test::( -3768477692975601, -11447376614057827956, 11443608136364852355, ); test::(-3356605361737854, -3081095617839357, 2805585873940860); test::( -1098730198198174614195, -953382298040157850476, 808034397882141086757, ); test::( -69738658860594537152875081748, -69738658860594537152875081748, 0, ); test::(-1000000000000000000000000, -1000000000000000000000000, 0); test::(0, -1000000000000000000000000, 0); test::(-123, -1000000000000000000000000, 999999999999999999999877); test::(-128, -1, 0); } fn ceiling_mod_fail_helper() { assert_panic!(T::ONE.ceiling_mod(T::ZERO)); assert_panic!({ let mut n = T::ONE; n.ceiling_mod_assign(T::ZERO); }); } #[test] pub fn ceiling_mod_fail() { apply_fn_to_signeds!(ceiling_mod_fail_helper); } fn mod_properties_helper_unsigned() { unsigned_pair_gen_var_12::().test_properties(|(x, y)| { let mut mut_x = x; mut_x.mod_assign(y); let r = mut_x; assert_eq!(x.mod_op(y), r); let mut mut_x = x; mut_x %= y; assert_eq!(mut_x, r); assert_eq!(x % y, r); assert_eq!(x.div_mod(y).1, r); assert_eq!(x.div_rem(y).1, r); assert!(r < y); }); unsigned_gen::().test_properties(|x| { assert_eq!(x.mod_op(T::ONE), T::ZERO); assert_panic!(x.mod_op(T::ZERO)); assert_panic!({ let mut y = x; y.mod_assign(T::ZERO); }); }); unsigned_gen_var_1::().test_properties(|x| { assert_eq!(x.mod_op(x), T::ZERO); assert_eq!(T::ZERO.mod_op(x), T::ZERO); if x > T::ONE { assert_eq!(T::ONE.mod_op(x), T::ONE); } }); } fn mod_properties_helper_signed() { signed_pair_gen_var_6::().test_properties(|(x, y)| { let mut mut_x = x; mut_x.mod_assign(y); let r = mut_x; assert_eq!(x.mod_op(y), r); assert!(r.lt_abs(&y)); assert!(r == T::ZERO || (r > T::ZERO) == (y > T::ZERO)); if x != T::MIN { assert_eq!(x.ceiling_mod(y), -(-x).mod_op(y)); } if y != T::MIN { assert_eq!(x.ceiling_mod(y), x.mod_op(-y)); } }); signed_pair_gen_var_4::().test_properties(|(x, y)| { assert_eq!(x.mod_op(y), x.div_mod(y).1); }); signed_gen::().test_properties(|x| { assert_eq!(x.mod_op(T::ONE), T::ZERO); assert_eq!(x.mod_op(T::NEGATIVE_ONE), T::ZERO); assert_panic!(x.mod_op(T::ZERO)); assert_panic!({ let mut y = x; y.mod_assign(T::ZERO); }); }); signed_gen_var_6::().test_properties(|x| { assert_eq!(x.mod_op(T::ONE), T::ZERO); assert_eq!(x.mod_op(x), T::ZERO); assert_eq!(T::ZERO.mod_op(x), T::ZERO); assert_eq!(x.mod_op(T::NEGATIVE_ONE), T::ZERO); if x != T::MIN { assert_eq!(x.mod_op(-x), T::ZERO); } if x > T::ONE { assert_eq!(T::ONE.mod_op(x), T::ONE); assert_eq!(T::NEGATIVE_ONE.mod_op(x), x - T::ONE); } }); } #[test] fn mod_properties() { apply_fn_to_unsigneds!(mod_properties_helper_unsigned); apply_fn_to_signeds!(mod_properties_helper_signed); } fn neg_mod_properties_helper() { unsigned_pair_gen_var_12::().test_properties(|(x, y)| { let mut mut_x = x; mut_x.neg_mod_assign(y); let r = mut_x; assert_eq!(x.neg_mod(y), r); assert_eq!(x.ceiling_div_neg_mod(y).1, r); assert!(r < y); }); unsigned_gen::().test_properties(|x| { assert_eq!(x.neg_mod(T::ONE), T::ZERO); assert_panic!(x.neg_mod(T::ZERO)); assert_panic!({ let mut y = x; y.neg_mod_assign(T::ZERO); }); }); unsigned_gen_var_1::().test_properties(|x| { assert_eq!(x.neg_mod(x), T::ZERO); assert_eq!(T::ZERO.neg_mod(x), T::ZERO); if x > T::ONE { assert_eq!(T::ONE.neg_mod(x), x - T::ONE); } }); } #[test] fn neg_mod_properties() { apply_fn_to_unsigneds!(neg_mod_properties_helper); } fn ceiling_mod_properties_helper() { signed_pair_gen_var_6::().test_properties(|(x, y)| { let mut mut_x = x; mut_x.ceiling_mod_assign(y); let r = mut_x; assert_eq!(x.ceiling_mod(y), r); assert!(r.lt_abs(&y)); assert!(r == T::ZERO || (r > T::ZERO) != (y > T::ZERO)); if x != T::MIN { assert_eq!(x.mod_op(y), -(-x).ceiling_mod(y)); } if y != T::MIN { assert_eq!(x.mod_op(y), x.ceiling_mod(-y)); } }); signed_pair_gen_var_4::().test_properties(|(x, y)| { assert_eq!(x.ceiling_mod(y), x.ceiling_div_mod(y).1); }); signed_gen::().test_properties(|x| { assert_eq!(x.ceiling_mod(T::ONE), T::ZERO); assert_eq!(x.ceiling_mod(T::NEGATIVE_ONE), T::ZERO); }); signed_gen_var_6::().test_properties(|x| { assert_eq!(x.ceiling_mod(T::ONE), T::ZERO); assert_eq!(x.ceiling_mod(T::NEGATIVE_ONE), T::ZERO); assert_eq!(x.ceiling_mod(x), T::ZERO); if x != T::MIN { assert_eq!(x.ceiling_mod(-x), T::ZERO); } assert_eq!(T::ZERO.ceiling_mod(x), T::ZERO); }); } #[test] fn ceiling_mod_properties() { apply_fn_to_signeds!(ceiling_mod_properties_helper); } malachite-base-0.4.16/tests/num/arithmetic/mod_pow.rs000064400000000000000000000126031046102023000206610ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::mod_pow::simple_binary_mod_pow; use malachite_base::num::arithmetic::traits::Parity; use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ unsigned_pair_gen, unsigned_pair_gen_var_12, unsigned_pair_gen_var_16, unsigned_quadruple_gen_var_6, unsigned_quadruple_gen_var_7, unsigned_triple_gen_var_14, unsigned_triple_gen_var_15, }; use malachite_base::test_util::num::arithmetic::mod_pow::naive_mod_pow; use std::panic::catch_unwind; fn mod_pow_helper() { let test = |x: T, exp: u64, m, out| { assert_eq!(naive_mod_pow(x, exp, m), out); assert_eq!(simple_binary_mod_pow(x, exp, m), out); assert_eq!(x.mod_pow(exp, m), out); let mut mut_x = x; mut_x.mod_pow_assign(exp, m); assert_eq!(mut_x, out); let data = T::precompute_mod_pow_data(&m); assert_eq!(x.mod_pow_precomputed(exp, m, &data), out); let mut mut_x = x; mut_x.mod_pow_precomputed_assign(exp, m, &data); assert_eq!(mut_x, out); }; test(T::ZERO, 0, T::ONE, T::ZERO); test(T::ZERO, 0, T::exact_from(10), T::ONE); test(T::ZERO, 1, T::exact_from(10), T::ZERO); test(T::TWO, 10, T::exact_from(10), T::exact_from(4)); if T::WIDTH > u8::WIDTH { test(T::exact_from(4), 13, T::exact_from(497), T::exact_from(445)); test( T::exact_from(10), 1000, T::exact_from(30), T::exact_from(10), ); test(T::TWO, 340, T::exact_from(341), T::ONE); test(T::exact_from(5), 216, T::exact_from(217), T::ONE); } if T::WIDTH > u16::WIDTH { test( T::TWO, 1000000, T::exact_from(1000000000), T::exact_from(747109376), ); } } #[test] fn test_mod_pow() { apply_fn_to_unsigneds!(mod_pow_helper); } fn mod_pow_fail_helper() { assert_panic!(T::ZERO.mod_pow(10, T::ZERO)); assert_panic!(T::from(123u8).mod_pow(10, T::from(123u8))); } #[test] fn mod_pow_fail() { apply_fn_to_unsigneds!(mod_pow_fail_helper); } fn mod_pow_assign_fail_helper() { assert_panic!({ let mut x = T::ZERO; x.mod_pow_assign(10, T::ZERO); }); assert_panic!({ let mut x = T::from(123u8); x.mod_pow_assign(10, T::from(123u8)); }); } #[test] fn mod_pow_assign_fail() { apply_fn_to_unsigneds!(mod_pow_assign_fail_helper); } fn mod_pow_properties_helper_helper T>( x: T, exp: u64, m: T, f: F, ) { assert!(x.mod_is_reduced(&m)); let power = x.mod_pow(exp, m); assert!(power.mod_is_reduced(&m)); let mut x_alt = x; x_alt.mod_pow_assign(exp, m); assert_eq!(x_alt, power); let data = T::precompute_mod_pow_data(&m); assert_eq!(x.mod_pow_precomputed(exp, m, &data), power); let mut x_alt = x; x_alt.mod_pow_precomputed_assign(exp, m, &data); assert_eq!(x_alt, power); assert_eq!(f(x, exp, m), power); if exp.even() { assert_eq!(x.mod_neg(m).mod_pow(exp, m), power); } else { assert_eq!(x.mod_neg(m).mod_pow(exp, m), power.mod_neg(m)); } } fn mod_pow_properties_helper() { unsigned_triple_gen_var_15::().test_properties(|(x, exp, m)| { mod_pow_properties_helper_helper(x, exp, m, simple_binary_mod_pow); }); unsigned_triple_gen_var_14::() .test_properties(|(x, exp, m)| mod_pow_properties_helper_helper(x, exp, m, naive_mod_pow)); unsigned_pair_gen_var_12::().test_properties(|(exp, m)| { assert_eq!(T::ZERO.mod_pow(exp, m), T::from(exp == 0 && m != T::ONE)); if m != T::ONE { assert_eq!(T::ONE.mod_pow(exp, m), T::ONE); } }); unsigned_pair_gen_var_16::().test_properties(|(x, m)| { assert_eq!(x.mod_pow(0, m), T::from(m != T::ONE)); assert_eq!(x.mod_pow(1, m), x); assert_eq!(x.mod_pow(2, m), x.mod_mul(x, m)); }); unsigned_pair_gen::().test_properties(|(x, y)| { assert_panic!(x.mod_pow(y, T::ZERO)); assert_panic!({ let mut x = x; x.mod_pow_assign(y, T::ZERO); }); }); unsigned_quadruple_gen_var_6::().test_properties(|(x, y, exp, m)| { assert_eq!( x.mod_mul(y, m).mod_pow(exp, m), x.mod_pow(exp, m).mod_mul(y.mod_pow(exp, m), m) ); }); unsigned_quadruple_gen_var_7::().test_properties(|(x, e, f, m)| { if let Some(sum) = e.checked_add(f) { assert_eq!( x.mod_pow(sum, m), x.mod_pow(e, m).mod_mul(x.mod_pow(f, m), m) ); } if let Some(product) = e.checked_mul(f) { assert_eq!(x.mod_pow(product, m), x.mod_pow(e, m).mod_pow(f, m)); } }); } #[test] fn mod_pow_properties() { apply_fn_to_unsigneds!(mod_pow_properties_helper); } malachite-base-0.4.16/tests/num/arithmetic/mod_power_of_2.rs000064400000000000000000000543501046102023000221220ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::{ModPowerOf2, ModPowerOf2IsReduced}; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::traits::Zero; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::{ExactFrom, WrappingFrom}; use malachite_base::test_util::generators::{ signed_gen, signed_unsigned_pair_gen_var_1, signed_unsigned_pair_gen_var_10, signed_unsigned_pair_gen_var_11, signed_unsigned_pair_gen_var_4, unsigned_gen, unsigned_pair_gen_var_2, unsigned_pair_gen_var_20, unsigned_triple_gen_var_13, unsigned_triple_gen_var_4, }; use std::cmp::min; use std::fmt::Debug; use std::panic::catch_unwind; #[test] fn test_mod_power_of_2_and_rem_power_of_2_unsigned() { fn test(x: T, pow: u64, out: T) { assert_eq!(x.mod_power_of_2(pow), out); let mut mut_x = x; mut_x.mod_power_of_2_assign(pow); assert_eq!(mut_x, out); assert_eq!(x.rem_power_of_2(pow), out); let mut mut_x = x; mut_x.rem_power_of_2_assign(pow); assert_eq!(mut_x, out); } test::(0, 0, 0); test::(260, 8, 4); test::(1611, 4, 11); test::(123, 100, 123); test::(1000000000000, 0, 0); test::(1000000000000, 12, 0); test::(1000000000001, 12, 1); test::(999999999999, 12, 4095); test::(1000000000000, 15, 4096); test::(1000000000000, 100, 1000000000000); test::(1000000000000000000000000, 40, 1020608380928); test::(1000000000000000000000000, 64, 2003764205206896640); test::(u32::MAX, 31, 0x7fffffff); test::(u32::MAX, 32, u32::MAX); test::(0xffffffff, 33, 0xffffffff); test::(0x100000000, 31, 0); test::(0x100000000, 32, 0); test::(0x100000000, 33, 0x100000000); test::(0x100000001, 31, 1); test::(0x100000001, 32, 1); test::(0x100000001, 33, 0x100000001); } #[test] fn test_mod_power_of_2_signed() { fn test + PrimitiveSigned>( x: S, pow: u64, out: U, ) { assert_eq!(x.mod_power_of_2(pow), out); } test::<_, i8>(0, 0, 0); test::<_, i16>(2, 1, 0); test::<_, i32>(260, 8, 4); test::<_, i16>(1611, 4, 11); test::<_, i8>(123, 100, 123); test::<_, i64>(1000000000000, 0, 0); test::<_, i64>(1000000000000, 12, 0); test::<_, i64>(1000000000001, 12, 1); test::<_, i64>(999999999999, 12, 4095); test::<_, i64>(1000000000000, 15, 4096); test::<_, i64>(1000000000000, 100, 1000000000000); test::<_, i128>(1000000000000000000000000, 40, 1020608380928); test::<_, i128>(1000000000000000000000000, 64, 2003764205206896640); test::<_, i32>(0x7fffffff, 30, 0x3fffffff); test::<_, i32>(0x7fffffff, 31, 0x7fffffff); test::<_, isize>(0x7fffffff, 32, 0x7fffffff); test::<_, i64>(0x80000000, 30, 0); test::<_, i64>(0x80000000, 31, 0); test::<_, i64>(0x80000000, 32, 0x80000000); test::<_, i64>(0x80000001, 30, 1); test::<_, i64>(0x80000001, 31, 1); test::<_, i64>(0x80000001, 32, 0x80000001); test::<_, i64>(0xffffffff, 31, 0x7fffffff); test::<_, i64>(0xffffffff, 32, 0xffffffff); test::<_, i64>(0xffffffff, 33, 0xffffffff); test::<_, i64>(0x100000000, 31, 0); test::<_, i64>(0x100000000, 32, 0); test::<_, i64>(0x100000000, 33, 0x100000000); test::<_, i64>(0x100000001, 31, 1); test::<_, i64>(0x100000001, 32, 1); test::<_, i64>(0x100000001, 33, 0x100000001); test::<_, i8>(-2, 1, 0); test::<_, i16>(-260, 8, 252); test::<_, i32>(-1611, 4, 5); test::<_, i128>(-123, 100, 1267650600228229401496703205253); test::<_, i64>(-1000000000000, 0, 0); test::<_, i64>(-1000000000000, 12, 0); test::<_, i64>(-1000000000001, 12, 4095); test::<_, i64>(-999999999999, 12, 1); test::<_, i64>(-1000000000000, 15, 0x7000); test::<_, i128>(-1000000000000, 100, 1267650600228229400496703205376); test::<_, i128>(-1000000000000000000000000, 40, 78903246848); test::<_, i128>(-1000000000000000000000000, 64, 16442979868502654976); test::<_, i32>(-0x7fffffff, 30, 1); test::<_, i32>(-0x7fffffff, 31, 1); test::<_, i32>(-0x7fffffff, 32, 0x80000001); test::<_, isize>(-0x80000000, 30, 0); test::<_, isize>(-0x80000000, 31, 0); test::<_, isize>(-0x80000000, 32, 0x80000000); test::<_, i64>(-0x80000001, 30, 0x3fffffff); test::<_, i64>(-0x80000001, 31, 0x7fffffff); test::<_, i64>(-0x80000001, 32, 0x7fffffff); test::<_, i64>(-0xffffffff, 31, 1); test::<_, i64>(-0xffffffff, 32, 1); test::<_, i64>(-0xffffffff, 33, 0x100000001); test::<_, i64>(-0x100000000, 31, 0); test::<_, i64>(-0x100000000, 32, 0); test::<_, i64>(-0x100000000, 33, 0x100000000); test::<_, i64>(-0x100000001, 31, 0x7fffffff); test::<_, i64>(-0x100000001, 32, 0xffffffff); test::<_, i64>(-0x100000001, 33, 0xffffffff); } fn mod_power_of_2_signed_fail_helper() { assert_panic!(T::NEGATIVE_ONE.mod_power_of_2(200)); } #[test] fn mod_power_of_2_signed_fail() { apply_fn_to_signeds!(mod_power_of_2_signed_fail_helper); } #[test] fn test_mod_power_of_2_assign_signed() { fn test(x: T, pow: u64, out: T) { let mut mut_x = x; mut_x.mod_power_of_2_assign(pow); assert_eq!(mut_x, out); } test::(0, 0, 0); test::(2, 1, 0); test::(260, 8, 4); test::(1611, 4, 11); test::(123, 100, 123); test::(1000000000000, 0, 0); test::(1000000000000, 12, 0); test::(1000000000001, 12, 1); test::(999999999999, 12, 4095); test::(1000000000000, 15, 4096); test::(1000000000000, 100, 1000000000000); test::(1000000000000000000000000, 40, 1020608380928); test::(1000000000000000000000000, 64, 2003764205206896640); test::(0x7fffffff, 30, 0x3fffffff); test::(0x7fffffff, 31, 0x7fffffff); test::(0x7fffffff, 32, 0x7fffffff); test::(0x80000000, 30, 0); test::(0x80000000, 31, 0); test::(0x80000000, 32, 0x80000000); test::(0x80000001, 30, 1); test::(0x80000001, 31, 1); test::(0x80000001, 32, 0x80000001); test::(0xffffffff, 31, 0x7fffffff); test::(0xffffffff, 32, 0xffffffff); test::(0xffffffff, 33, 0xffffffff); test::(0x100000000, 31, 0); test::(0x100000000, 32, 0); test::(0x100000000, 33, 0x100000000); test::(0x100000001, 31, 1); test::(0x100000001, 32, 1); test::(0x100000001, 33, 0x100000001); test::(-2, 1, 0); test::(-260, 8, 252); test::(-1611, 4, 5); test::(-123, 100, 1267650600228229401496703205253); test::(-1000000000000, 0, 0); test::(-1000000000000, 12, 0); test::(-1000000000001, 12, 4095); test::(-999999999999, 12, 1); test::(-1000000000000, 15, 0x7000); test::(-1000000000000, 100, 1267650600228229400496703205376); test::(-1000000000000000000000000, 40, 78903246848); test::(-1000000000000000000000000, 64, 16442979868502654976); test::(-0x7fffffff, 30, 1); test::(-0x7fffffff, 31, 1); test::(-0x7fffffff, 32, 0x80000001); test::(-0x80000000, 30, 0); test::(-0x80000000, 31, 0); test::(-0x80000000, 32, 0x80000000); test::(-0x80000001, 30, 0x3fffffff); test::(-0x80000001, 31, 0x7fffffff); test::(-0x80000001, 32, 0x7fffffff); test::(-0xffffffff, 31, 1); test::(-0xffffffff, 32, 1); test::(-0xffffffff, 33, 0x100000001); test::(-0x100000000, 31, 0); test::(-0x100000000, 32, 0); test::(-0x100000000, 33, 0x100000000); test::(-0x100000001, 31, 0x7fffffff); test::(-0x100000001, 32, 0xffffffff); test::(-0x100000001, 33, 0xffffffff); } fn mod_power_of_2_assign_signed_fail_helper() { assert_panic!({ let mut x = T::NEGATIVE_ONE; x.mod_power_of_2_assign(200); }); assert_panic!({ let mut x = T::MIN; x.mod_power_of_2_assign(T::WIDTH); }); } #[test] fn mod_power_of_2_assign_signed_fail() { apply_fn_to_signeds!(mod_power_of_2_assign_signed_fail_helper); } #[test] fn test_rem_power_of_2_signed() { fn test(x: T, pow: u64, out: T) { assert_eq!(x.rem_power_of_2(pow), out); let mut mut_x = x; mut_x.rem_power_of_2_assign(pow); assert_eq!(mut_x, out); } test::(0, 0, 0); test::(2, 1, 0); test::(260, 8, 4); test::(1611, 4, 11); test::(123, 100, 123); test::(1000000000000, 0, 0); test::(1000000000000, 12, 0); test::(1000000000001, 12, 1); test::(999999999999, 12, 4095); test::(1000000000000, 15, 4096); test::(1000000000000, 100, 1000000000000); test::(1000000000000000000000000, 40, 1020608380928); test::(1000000000000000000000000, 64, 2003764205206896640); test::(0x7fffffff, 30, 0x3fffffff); test::(0x7fffffff, 31, 0x7fffffff); test::(0x7fffffff, 32, 0x7fffffff); test::(0x80000000, 30, 0); test::(0x80000000, 31, 0); test::(0x80000000, 32, 0x80000000); test::(0x80000001, 30, 1); test::(0x80000001, 31, 1); test::(0x80000001, 32, 0x80000001); test::(0xffffffff, 31, 0x7fffffff); test::(0xffffffff, 32, 0xffffffff); test::(0xffffffff, 33, 0xffffffff); test::(0x100000000, 31, 0); test::(0x100000000, 32, 0); test::(0x100000000, 33, 0x100000000); test::(0x100000001, 31, 1); test::(0x100000001, 32, 1); test::(0x100000001, 33, 0x100000001); test::(-2, 1, 0); test::(-260, 8, -4); test::(-1611, 4, -11); test::(-123, 100, -123); test::(-1000000000000, 0, 0); test::(-1000000000000, 12, 0); test::(-1000000000001, 12, -1); test::(-999999999999, 12, -4095); test::(-1000000000000, 15, -4096); test::(-1000000000000, 100, -1000000000000); test::(-1000000000000000000000000, 40, -1020608380928); test::(-1000000000000000000000000, 64, -2003764205206896640); test::(-0x7fffffff, 30, -0x3fffffff); test::(-0x7fffffff, 31, -0x7fffffff); test::(-0x7fffffff, 32, -0x7fffffff); test::(-0x80000000, 30, 0); test::(-0x80000000, 31, 0); test::(-0x80000000, 32, -0x80000000); test::(-0x80000001, 30, -1); test::(-0x80000001, 31, -1); test::(-0x80000001, 32, -0x80000001); test::(-0xffffffff, 31, -0x7fffffff); test::(-0xffffffff, 32, -0xffffffff); test::(-0xffffffff, 33, -0xffffffff); test::(-0x100000000, 31, 0); test::(-0x100000000, 32, 0); test::(-0x100000000, 33, -0x100000000); test::(-0x100000001, 31, -1); test::(-0x100000001, 32, -1); test::(-0x100000001, 33, -0x100000001); } #[test] fn test_neg_mod_power_of_2_unsigned() { fn test(x: T, pow: u64, out: T) { assert_eq!(x.neg_mod_power_of_2(pow), out); let mut mut_x = x; mut_x.neg_mod_power_of_2_assign(pow); assert_eq!(mut_x, out); } test::(0, 0, 0); test::(260, 8, 252); test::(1611, 4, 5); test::(1, 32, u32::MAX); test::(123, 100, 1267650600228229401496703205253); test::(1000000000000, 0, 0); test::(1000000000000, 12, 0); test::(1000000000001, 12, 4095); test::(999999999999, 12, 1); test::(1000000000000, 15, 0x7000); test::(1000000000000, 100, 1267650600228229400496703205376); test::(1000000000000000000000000, 40, 78903246848); test::(1000000000000000000000000, 64, 16442979868502654976); test::(u32::MAX, 31, 1); test::(0xffffffff, 32, 1); test::(0xffffffff, 33, 0x100000001); test::(0x100000000, 31, 0); test::(0x100000000, 32, 0); test::(0x100000000, 33, 0x100000000); test::(0x100000001, 31, 0x7fffffff); test::(0x100000001, 32, 0xffffffff); test::(0x100000001, 33, 0xffffffff); } fn neg_mod_power_of_2_fail_helper() { assert_panic!(T::ONE.neg_mod_power_of_2(200)); assert_panic!(T::MAX.neg_mod_power_of_2(T::WIDTH + 1)); assert_panic!({ let mut x = T::ONE; x.neg_mod_power_of_2_assign(200); }); assert_panic!({ let mut x = T::MAX; x.neg_mod_power_of_2_assign(T::WIDTH + 1); }); } #[test] fn neg_mod_power_of_2_fail() { apply_fn_to_unsigneds!(neg_mod_power_of_2_fail_helper); } #[test] fn test_ceiling_mod_power_of_2_signed() { fn test(x: T, pow: u64, out: T) { assert_eq!(x.ceiling_mod_power_of_2(pow), out); let mut mut_x = x; mut_x.ceiling_mod_power_of_2_assign(pow); assert_eq!(mut_x, out); } test::(0, 0, 0); test::(2, 1, 0); test::(260, 8, -252); test::(1611, 4, -5); test::(123, 100, -1267650600228229401496703205253); test::(1000000000000, 0, 0); test::(1000000000000, 12, 0); test::(1000000000001, 12, -4095); test::(999999999999, 12, -1); test::(1000000000000, 15, -0x7000); test::(1000000000000, 100, -1267650600228229400496703205376); test::(1000000000000000000000000, 40, -78903246848); test::(1000000000000000000000000, 64, -16442979868502654976); test::(0x7fffffff, 30, -1); test::(0x7fffffff, 31, -1); test::(0x7fffffff, 32, -0x80000001); test::(0x80000000, 30, 0); test::(0x80000000, 31, 0); test::(0x80000000, 32, -0x80000000); test::(0x80000001, 30, -0x3fffffff); test::(0x80000001, 31, -0x7fffffff); test::(0x80000001, 32, -0x7fffffff); test::(0xffffffff, 31, -1); test::(0xffffffff, 32, -1); test::(0xffffffff, 33, -0x100000001); test::(0x100000000, 31, 0); test::(0x100000000, 32, 0); test::(0x100000000, 33, -0x100000000); test::(0x100000001, 31, -0x7fffffff); test::(0x100000001, 32, -0xffffffff); test::(0x100000001, 33, -0xffffffff); test::(-2, 1, 0); test::(-260, 8, -4); test::(-1611, 4, -11); test::(-123, 100, -123); test::(-1000000000000, 0, 0); test::(-1000000000000, 12, 0); test::(-1000000000001, 12, -1); test::(-999999999999, 12, -4095); test::(-1000000000000, 15, -4096); test::(-1000000000000, 100, -1000000000000); test::(-1000000000000000000000000, 40, -1020608380928); test::(-1000000000000000000000000, 64, -2003764205206896640); test::(-0x7fffffff, 30, -0x3fffffff); test::(-0x7fffffff, 31, -0x7fffffff); test::(-0x7fffffff, 32, -0x7fffffff); test::(-0x80000000, 31, 0); test::(-0x80000000, 30, 0); test::(-0x80000000, 31, 0); test::(-0x80000000, 32, -0x80000000); test::(-0x80000001, 30, -1); test::(-0x80000001, 31, -1); test::(-0x80000001, 32, -0x80000001); test::(-0xffffffff, 31, -0x7fffffff); test::(-0xffffffff, 32, -0xffffffff); test::(-0xffffffff, 33, -0xffffffff); test::(-0x100000000, 31, 0); test::(-0x100000000, 32, 0); test::(-0x100000000, 33, -0x100000000); test::(-0x100000001, 31, -1); test::(-0x100000001, 32, -1); test::(-0x100000001, 33, -0x100000001); } fn ceiling_mod_power_of_2_fail_helper() { assert_panic!(T::ONE.ceiling_mod_power_of_2(T::WIDTH)); assert_panic!(T::MIN.ceiling_mod_power_of_2(T::WIDTH)); assert_panic!({ let mut x = T::ONE; x.ceiling_mod_power_of_2_assign(T::WIDTH); }); assert_panic!({ let mut x = T::MIN; x.ceiling_mod_power_of_2_assign(T::WIDTH); }); } #[test] fn ceiling_mod_power_of_2_fail() { apply_fn_to_signeds!(ceiling_mod_power_of_2_fail_helper); } fn mod_power_of_2_properties_helper_unsigned() { unsigned_pair_gen_var_2::().test_properties(|(n, pow)| { let mut mut_n = n; mut_n.mod_power_of_2_assign(pow); let result = mut_n; assert!(result.mod_power_of_2_is_reduced(pow)); assert_eq!(n.mod_power_of_2(pow), result); let mut mut_n = n; mut_n.rem_power_of_2_assign(pow); assert_eq!(mut_n, result); assert_eq!(n.rem_power_of_2(pow), result); assert!(result <= n); assert_eq!(result == T::ZERO, n.divisible_by_power_of_2(pow)); assert_eq!(result.mod_power_of_2(pow), result); }); unsigned_triple_gen_var_4::().test_properties(|(x, y, pow)| { assert_eq!( x.wrapping_add(y).mod_power_of_2(pow), x.mod_power_of_2(pow) .wrapping_add(y.mod_power_of_2(pow)) .mod_power_of_2(pow) ); assert_eq!( x.wrapping_mul(y).mod_power_of_2(pow), x.mod_power_of_2(pow) .wrapping_mul(y.mod_power_of_2(pow)) .mod_power_of_2(pow) ); }); unsigned_triple_gen_var_13::().test_properties(|(n, u, v)| { assert_eq!( n.mod_power_of_2(u).mod_power_of_2(v), n.mod_power_of_2(min(u, v)) ); }); unsigned_gen::().test_properties(|n| { assert_eq!(n.mod_power_of_2(0), T::ZERO); }); unsigned_gen().test_properties(|pow| { assert_eq!(T::ZERO.mod_power_of_2(pow), T::ZERO); }); } fn mod_power_of_2_properties_helper_signed() where ::Output: ExactFrom + PrimitiveUnsigned, { signed_unsigned_pair_gen_var_10::().test_properties(|(n, pow)| { let result = n.mod_power_of_2(pow); assert!(result.mod_power_of_2_is_reduced(pow)); assert_eq!( result == ::Output::ZERO, n.divisible_by_power_of_2(pow) ); assert_eq!(result.mod_power_of_2(pow), result); }); signed_unsigned_pair_gen_var_4::().test_properties(|(n, pow)| { let mut mut_n = n; mut_n.mod_power_of_2_assign(pow); let result = mut_n; assert_eq!( n.mod_power_of_2(pow), ::Output::exact_from(result) ); assert!(result >= T::ZERO); assert_eq!(result == T::ZERO, n.divisible_by_power_of_2(pow)); assert_eq!( result.mod_power_of_2(pow), ::Output::exact_from(result) ); }); signed_gen::().test_properties(|n| { assert_eq!(n.mod_power_of_2(0), ::Output::ZERO); }); unsigned_gen().test_properties(|pow| { assert_eq!( T::ZERO.mod_power_of_2(pow), ::Output::ZERO ); }); } #[test] fn mod_power_of_2_properties() { apply_fn_to_unsigneds!(mod_power_of_2_properties_helper_unsigned); apply_fn_to_signeds!(mod_power_of_2_properties_helper_signed); } fn rem_power_of_2_properties_helper() { signed_unsigned_pair_gen_var_1::().test_properties(|(n, pow)| { let mut mut_n = n; mut_n.rem_power_of_2_assign(pow); let result = mut_n; assert_eq!(n.rem_power_of_2(pow), result); if n != T::MIN { assert_eq!((-n).rem_power_of_2(pow), -result); } assert!(result.le_abs(&n)); assert_eq!(result == T::ZERO, n.divisible_by_power_of_2(pow)); assert_eq!(result.rem_power_of_2(pow), result); assert!(result == T::ZERO || (result > T::ZERO) == (n > T::ZERO)); }); signed_gen::().test_properties(|n| { assert_eq!(n.rem_power_of_2(0), T::ZERO); }); unsigned_gen().test_properties(|pow| { assert_eq!(T::ZERO.rem_power_of_2(pow), T::ZERO); }); } #[test] fn rem_power_of_2_properties() { apply_fn_to_signeds!(rem_power_of_2_properties_helper); } fn neg_mod_power_of_2_properties_helper() { unsigned_pair_gen_var_20::().test_properties(|(n, pow)| { let mut mut_n = n; mut_n.neg_mod_power_of_2_assign(pow); let result = mut_n; assert!(result.mod_power_of_2_is_reduced(pow)); assert_eq!(n.neg_mod_power_of_2(pow), result); assert_eq!(result == T::ZERO, n.divisible_by_power_of_2(pow)); assert!(result .wrapping_add(n.mod_power_of_2(pow)) .divisible_by_power_of_2(pow)); assert_eq!(result.neg_mod_power_of_2(pow), n.mod_power_of_2(pow)); }); unsigned_gen::().test_properties(|n| { assert_eq!(n.neg_mod_power_of_2(0), T::ZERO); }); unsigned_gen().test_properties(|pow| { assert_eq!(T::ZERO.neg_mod_power_of_2(pow), T::ZERO); }); } #[test] fn neg_mod_power_of_2_properties() { apply_fn_to_unsigneds!(neg_mod_power_of_2_properties_helper); } fn ceiling_mod_power_of_2_properties_helper< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >() { signed_unsigned_pair_gen_var_11::().test_properties(|(n, pow)| { let mut mut_n = n; mut_n.ceiling_mod_power_of_2_assign(pow); let result = mut_n; assert_eq!(n.ceiling_mod_power_of_2(pow), result); assert!(result <= S::ZERO); assert_eq!(result == S::ZERO, n.divisible_by_power_of_2(pow)); }); signed_gen::().test_properties(|n| { assert_eq!(n.ceiling_mod_power_of_2(0), S::ZERO); }); unsigned_gen().test_properties(|pow| { assert_eq!(S::ZERO.ceiling_mod_power_of_2(pow), S::ZERO); }); } #[test] fn ceiling_mod_power_of_2_properties() { apply_fn_to_unsigned_signed_pairs!(ceiling_mod_power_of_2_properties_helper); } malachite-base-0.4.16/tests/num/arithmetic/mod_power_of_2_add.rs000064400000000000000000000073211046102023000227260ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ unsigned_pair_gen_var_17, unsigned_quadruple_gen_var_3, unsigned_triple_gen_var_11, }; use std::panic::catch_unwind; fn mod_power_of_2_add_helper() { let test = |x: T, y: T, pow, out| { assert_eq!(x.mod_power_of_2_add(y, pow), out); let mut x = x; x.mod_power_of_2_add_assign(y, pow); assert_eq!(x, out); }; test(T::ZERO, T::ZERO, 0, T::ZERO); test(T::ZERO, T::ONE, 1, T::ONE); test(T::ONE, T::ONE, 1, T::ZERO); test(T::ZERO, T::TWO, 5, T::TWO); test(T::exact_from(10), T::exact_from(14), 4, T::exact_from(8)); test(T::exact_from(100), T::exact_from(200), 8, T::exact_from(44)); test(T::MAX, T::ONE, T::WIDTH, T::ZERO); test(T::MAX, T::MAX, T::WIDTH, T::MAX - T::ONE); } #[test] fn test_mod_power_of_2_add() { apply_fn_to_unsigneds!(mod_power_of_2_add_helper); } fn mod_power_of_2_add_fail_helper() { assert_panic!(T::ONE.mod_power_of_2_add(T::ZERO, 0)); assert_panic!(T::ZERO.mod_power_of_2_add(T::ONE, 0)); assert_panic!(T::from(123u8).mod_power_of_2_add(T::from(200u8), 7)); assert_panic!(T::from(200u8).mod_power_of_2_add(T::from(123u8), 7)); } #[test] fn mod_power_of_2_add_fail() { apply_fn_to_unsigneds!(mod_power_of_2_add_fail_helper); } fn mod_power_of_2_add_assign_fail_helper() { assert_panic!({ let mut x = T::ONE; x.mod_power_of_2_add_assign(T::ZERO, 0); }); assert_panic!({ let mut x = T::ZERO; x.mod_power_of_2_add_assign(T::ONE, 0); }); assert_panic!({ let mut x = T::from(123u8); x.mod_power_of_2_add_assign(T::from(200u8), 7); }); assert_panic!({ let mut x = T::from(200u8); x.mod_power_of_2_add_assign(T::from(123u8), 7); }); } #[test] fn mod_power_of_2_add_assign_fail() { apply_fn_to_unsigneds!(mod_power_of_2_add_assign_fail_helper); } fn mod_power_of_2_add_properties_helper() { unsigned_triple_gen_var_11::().test_properties(|(x, y, pow)| { assert!(x.mod_power_of_2_is_reduced(pow)); assert!(y.mod_power_of_2_is_reduced(pow)); let sum = x.mod_power_of_2_add(y, pow); assert!(sum.mod_power_of_2_is_reduced(pow)); let mut x_alt = x; x_alt.mod_power_of_2_add_assign(y, pow); assert_eq!(x_alt, sum); assert_eq!(sum.mod_power_of_2_sub(y, pow), x); assert_eq!(sum.mod_power_of_2_sub(x, pow), y); assert_eq!(y.mod_power_of_2_add(x, pow), sum); assert_eq!(x.mod_power_of_2_sub(y.mod_power_of_2_neg(pow), pow), sum); }); unsigned_pair_gen_var_17::().test_properties(|(x, pow)| { assert_eq!(x.mod_power_of_2_add(T::ZERO, pow), x); assert_eq!(T::ZERO.mod_power_of_2_add(x, pow), x); assert_eq!( x.mod_power_of_2_add(x.mod_power_of_2_neg(pow), pow), T::ZERO ); }); unsigned_quadruple_gen_var_3::().test_properties(|(x, y, z, pow)| { assert_eq!( x.mod_power_of_2_add(y, pow).mod_power_of_2_add(z, pow), x.mod_power_of_2_add(y.mod_power_of_2_add(z, pow), pow) ); }); } #[test] fn mod_power_of_2_add_properties() { apply_fn_to_unsigneds!(mod_power_of_2_add_properties_helper); } malachite-base-0.4.16/tests/num/arithmetic/mod_power_of_2_inverse.rs000064400000000000000000000064071046102023000236550ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::mod_power_of_2_inverse::mod_power_of_2_inverse_fast; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::WrappingFrom; use malachite_base::test_util::generators::{unsigned_gen_var_3, unsigned_pair_gen_var_39}; use malachite_base::test_util::num::arithmetic::mod_power_of_2_inverse::*; use std::panic::catch_unwind; fn mod_power_of_2_inverse_helper< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >() { let test = |n: U, pow, out| { assert_eq!(n.mod_power_of_2_inverse(pow), out); assert_eq!(mod_power_of_2_inverse_euclidean::(n, pow), out); assert_eq!(mod_power_of_2_inverse_fast(n, pow), out); }; test(U::ONE, 5, Some(U::ONE)); test(U::exact_from(7), 5, Some(U::exact_from(23))); test(U::exact_from(31), 5, Some(U::exact_from(31))); test(U::ONE, U::WIDTH, Some(U::ONE)); test(U::MAX, U::WIDTH, Some(U::MAX)); } #[test] fn test_mod_power_of_2_inverse() { apply_fn_to_unsigned_signed_pairs!(mod_power_of_2_inverse_helper); } fn mod_power_of_2_inverse_fail_helper() { assert_panic!(T::ZERO.mod_power_of_2_inverse(5)); assert_panic!(T::from(30u8).mod_power_of_2_inverse(3)); assert_panic!(T::from(3u8).mod_power_of_2_inverse(200)); assert_panic!(T::ONE.mod_power_of_2_inverse(0)); assert_panic!(T::from(200u8).mod_power_of_2_inverse(7)); } #[test] fn mod_power_of_2_inverse_fail() { apply_fn_to_unsigneds!(mod_power_of_2_inverse_fail_helper); } fn mod_power_of_2_inverse_properties_helper< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >() { unsigned_pair_gen_var_39::().test_properties(|(n, pow)| { assert!(n.mod_power_of_2_is_reduced(pow)); let inverse = n.mod_power_of_2_inverse(pow); assert_eq!(mod_power_of_2_inverse_euclidean::(n, pow), inverse); assert_eq!(mod_power_of_2_inverse_fast(n, pow), inverse); assert_eq!(inverse.is_some(), n.odd()); if let Some(inverse) = inverse { assert!(inverse.mod_power_of_2_is_reduced(pow)); assert_eq!(inverse.mod_power_of_2_inverse(pow), Some(n)); assert_eq!(n.mod_power_of_2_mul(inverse, pow), U::ONE); assert_eq!( n.mod_power_of_2_neg(pow).mod_power_of_2_inverse(pow), Some(inverse.mod_power_of_2_neg(pow)) ); } }); unsigned_gen_var_3::().test_properties(|pow| { assert_eq!(U::ONE.mod_power_of_2_inverse(pow), Some(U::ONE)); assert_eq!( U::low_mask(pow).mod_power_of_2_inverse(pow), Some(U::low_mask(pow)) ); }); } #[test] fn mod_power_of_2_inverse_properties() { apply_fn_to_unsigned_signed_pairs!(mod_power_of_2_inverse_properties_helper); } malachite-base-0.4.16/tests/num/arithmetic/mod_power_of_2_is_reduced.rs000064400000000000000000000024561046102023000243100ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::unsigned_pair_gen_var_2; fn mod_power_of_2_is_reduced_helper() { let test = |n: T, pow, out| { assert_eq!(n.mod_power_of_2_is_reduced(pow), out); }; test(T::ZERO, 5, true); test(T::exact_from(100), 5, false); test(T::exact_from(100), 8, true); test(T::MAX, T::WIDTH - 1, false); test(T::MAX, T::WIDTH, true); } #[test] fn test_mod_power_of_2_is_reduced() { apply_fn_to_unsigneds!(mod_power_of_2_is_reduced_helper); } fn mod_power_of_2_is_reduced_properties_helper() { unsigned_pair_gen_var_2::().test_properties(|(n, pow)| { assert_eq!(n.mod_power_of_2_is_reduced(pow), n.mod_power_of_2(pow) == n); }); } #[test] fn mod_power_of_2_is_reduced_properties() { apply_fn_to_unsigneds!(mod_power_of_2_is_reduced_properties_helper); } malachite-base-0.4.16/tests/num/arithmetic/mod_power_of_2_mul.rs000064400000000000000000000104661046102023000227770ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ unsigned_pair_gen_var_17, unsigned_quadruple_gen_var_3, unsigned_triple_gen_var_11, }; use std::panic::catch_unwind; fn mod_power_of_2_mul_helper() { let test = |x: T, y: T, pow, out| { assert_eq!(x.mod_power_of_2_mul(y, pow), out); let mut x = x; x.mod_power_of_2_mul_assign(y, pow); assert_eq!(x, out); }; test(T::ZERO, T::ZERO, 0, T::ZERO); test(T::ZERO, T::ONE, 1, T::ZERO); test(T::ONE, T::ONE, 1, T::ONE); test(T::exact_from(3), T::TWO, 5, T::exact_from(6)); test(T::exact_from(10), T::exact_from(14), 4, T::exact_from(12)); test(T::exact_from(100), T::exact_from(200), 8, T::exact_from(32)); test(T::ONE << (T::WIDTH - 1), T::TWO, T::WIDTH, T::ZERO); test(T::MAX, T::MAX, T::WIDTH, T::ONE); } #[test] fn test_mod_power_of_2_mul() { apply_fn_to_unsigneds!(mod_power_of_2_mul_helper); } fn mod_power_of_2_mul_fail_helper() { assert_panic!(T::ONE.mod_power_of_2_mul(T::ZERO, 0)); assert_panic!(T::ZERO.mod_power_of_2_mul(T::ONE, 0)); assert_panic!(T::from(123u8).mod_power_of_2_mul(T::from(200u8), 7)); assert_panic!(T::from(200u8).mod_power_of_2_mul(T::from(123u8), 7)); } #[test] fn mod_power_of_2_mul_fail() { apply_fn_to_unsigneds!(mod_power_of_2_mul_fail_helper); } fn mod_power_of_2_mul_assign_fail_helper() { assert_panic!({ let mut x = T::ONE; x.mod_power_of_2_mul_assign(T::ZERO, 0); }); assert_panic!({ let mut x = T::ZERO; x.mod_power_of_2_mul_assign(T::ONE, 0); }); assert_panic!({ let mut x = T::from(123u8); x.mod_power_of_2_mul_assign(T::from(200u8), 7); }); assert_panic!({ let mut x = T::from(200u8); x.mod_power_of_2_mul_assign(T::from(123u8), 7); }); } #[test] fn mod_power_of_2_mul_assign_fail() { apply_fn_to_unsigneds!(mod_power_of_2_mul_assign_fail_helper); } fn mod_power_of_2_mul_properties_helper() { unsigned_triple_gen_var_11::().test_properties(|(x, y, pow)| { assert!(x.mod_power_of_2_is_reduced(pow)); assert!(y.mod_power_of_2_is_reduced(pow)); let product = x.mod_power_of_2_mul(y, pow); assert!(product.mod_power_of_2_is_reduced(pow)); let mut x_alt = x; x_alt.mod_power_of_2_mul_assign(y, pow); assert_eq!(x_alt, product); assert_eq!(y.mod_power_of_2_mul(x, pow), product); assert_eq!( x.mod_power_of_2_mul(y.mod_power_of_2_neg(pow), pow), product.mod_power_of_2_neg(pow) ); assert_eq!( x.mod_power_of_2_neg(pow).mod_power_of_2_mul(y, pow), product.mod_power_of_2_neg(pow) ); }); unsigned_pair_gen_var_17::().test_properties(|(x, pow)| { assert_eq!(x.mod_power_of_2_mul(T::ZERO, pow), T::ZERO); assert_eq!(T::ZERO.mod_power_of_2_mul(x, pow), T::ZERO); if pow != 0 { assert_eq!(x.mod_power_of_2_mul(T::ONE, pow), x); assert_eq!(T::ONE.mod_power_of_2_mul(x, pow), x); } }); unsigned_quadruple_gen_var_3::().test_properties(|(x, y, z, pow)| { assert_eq!( x.mod_power_of_2_mul(y, pow).mod_power_of_2_mul(z, pow), x.mod_power_of_2_mul(y.mod_power_of_2_mul(z, pow), pow) ); assert_eq!( x.mod_power_of_2_mul(y.mod_power_of_2_add(z, pow), pow), x.mod_power_of_2_mul(y, pow) .mod_power_of_2_add(x.mod_power_of_2_mul(z, pow), pow) ); assert_eq!( x.mod_power_of_2_add(y, pow).mod_power_of_2_mul(z, pow), x.mod_power_of_2_mul(z, pow) .mod_power_of_2_add(y.mod_power_of_2_mul(z, pow), pow) ); }); } #[test] fn mod_power_of_2_mul_properties() { apply_fn_to_unsigneds!(mod_power_of_2_mul_properties_helper); } malachite-base-0.4.16/tests/num/arithmetic/mod_power_of_2_neg.rs000064400000000000000000000047111046102023000227470ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::unsigned_pair_gen_var_17; use std::panic::catch_unwind; fn mod_power_of_2_neg_helper() { let test = |n: T, pow, out| { assert_eq!(n.mod_power_of_2_neg(pow), out); let mut n = n; n.mod_power_of_2_neg_assign(pow); assert_eq!(n, out); }; test(T::ZERO, 5, T::ZERO); test(T::exact_from(10), 4, T::exact_from(6)); test(T::exact_from(100), 8, T::exact_from(156)); test(T::ONE, T::WIDTH, T::MAX); test(T::MAX, T::WIDTH, T::ONE); } #[test] fn test_mod_power_of_2_neg() { apply_fn_to_unsigneds!(mod_power_of_2_neg_helper); } fn mod_power_of_2_neg_fail_helper() { assert_panic!(T::ONE.mod_power_of_2_neg(0)); assert_panic!(T::from(200u8).mod_power_of_2_neg(7)); } #[test] fn mod_power_of_2_neg_fail() { apply_fn_to_unsigneds!(mod_power_of_2_neg_fail_helper); } fn mod_power_of_2_neg_assign_fail_helper() { assert_panic!({ let mut x = T::ONE; x.mod_power_of_2_neg_assign(0); }); assert_panic!({ let mut x = T::from(200u8); x.mod_power_of_2_neg_assign(7); }); } #[test] fn mod_power_of_2_neg_assign_fail() { apply_fn_to_unsigneds!(mod_power_of_2_neg_assign_fail_helper); } fn mod_power_of_2_neg_properties_helper() { unsigned_pair_gen_var_17::().test_properties(|(n, pow)| { assert!(n.mod_power_of_2_is_reduced(pow)); let neg = n.mod_power_of_2_neg(pow); assert!(neg.mod_power_of_2_is_reduced(pow)); let mut n_alt = n; n_alt.mod_power_of_2_neg_assign(pow); assert_eq!(n_alt, neg); assert_eq!(neg, n.wrapping_neg().mod_power_of_2(pow)); assert_eq!(neg.mod_power_of_2_neg(pow), n); assert_eq!(n.mod_power_of_2_add(neg, pow), T::ZERO); assert_eq!(n == neg, n == T::ZERO || n == T::power_of_2(pow - 1)); }); } #[test] fn mod_power_of_2_neg_properties() { apply_fn_to_unsigneds!(mod_power_of_2_neg_properties_helper); } malachite-base-0.4.16/tests/num/arithmetic/mod_power_of_2_pow.rs000064400000000000000000000104661046102023000230070ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::Parity; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ unsigned_pair_gen_var_17, unsigned_pair_gen_var_23, unsigned_quadruple_gen_var_8, unsigned_quadruple_gen_var_9, unsigned_triple_gen_var_16, }; use std::panic::catch_unwind; fn mod_power_of_2_pow_helper() { let test = |x: T, exp: u64, pow: u64, out| { assert_eq!(x.mod_power_of_2_pow(exp, pow), out); let mut mut_x = x; mut_x.mod_power_of_2_pow_assign(exp, pow); assert_eq!(mut_x, out); }; test(T::ZERO, 0, 0, T::ZERO); test(T::ZERO, 0, 3, T::ONE); test(T::ZERO, 1, 3, T::ZERO); test(T::TWO, 2, 3, T::exact_from(4)); test(T::exact_from(5), 13, 3, T::exact_from(5)); test(T::exact_from(7), 1000, 6, T::ONE); test(T::exact_from(101), 1000000, 8, T::ONE); } #[test] fn test_mod_power_of_2_pow() { apply_fn_to_unsigneds!(mod_power_of_2_pow_helper); } fn mod_power_of_2_pow_fail_helper() { assert_panic!(T::ONE.mod_power_of_2_pow(10, 0)); assert_panic!(T::from(200u8).mod_power_of_2_pow(10, 7)); } #[test] fn mod_power_of_2_pow_fail() { apply_fn_to_unsigneds!(mod_power_of_2_pow_fail_helper); } fn mod_power_of_2_pow_assign_fail_helper() { assert_panic!({ let mut x = T::ONE; x.mod_power_of_2_pow_assign(10, 0); }); assert_panic!({ let mut x = T::from(200u8); x.mod_power_of_2_pow_assign(10, 7); }); } #[test] fn mod_power_of_2_pow_assign_fail() { apply_fn_to_unsigneds!(mod_power_of_2_pow_assign_fail_helper); } fn mod_power_of_2_pow_properties_helper() { unsigned_triple_gen_var_16::().test_properties(|(x, exp, pow)| { assert!(x.mod_power_of_2_is_reduced(pow)); let power = x.mod_power_of_2_pow(exp, pow); assert!(power.mod_power_of_2_is_reduced(pow)); let mut x_alt = x; x_alt.mod_power_of_2_pow_assign(exp, pow); assert_eq!(x_alt, power); if exp.even() { assert_eq!( x.mod_power_of_2_neg(pow).mod_power_of_2_pow(exp, pow), power ); } else { assert_eq!( x.mod_power_of_2_neg(pow).mod_power_of_2_pow(exp, pow), power.mod_power_of_2_neg(pow) ); } }); unsigned_pair_gen_var_23::().test_properties(|(exp, pow)| { assert_eq!( T::ZERO.mod_power_of_2_pow(exp, pow), T::from(exp == 0 && pow != 0) ); if pow != 0 { assert_eq!(T::ONE.mod_power_of_2_pow(exp, pow), T::ONE); } }); unsigned_pair_gen_var_17::().test_properties(|(x, pow)| { assert_eq!(x.mod_power_of_2_pow(0, pow), T::from(pow != 0)); assert_eq!(x.mod_power_of_2_pow(1, pow), x); assert_eq!(x.mod_power_of_2_pow(2, pow), x.mod_power_of_2_mul(x, pow)); }); unsigned_quadruple_gen_var_8::().test_properties(|(x, y, exp, pow)| { assert_eq!( x.mod_power_of_2_mul(y, pow).mod_power_of_2_pow(exp, pow), x.mod_power_of_2_pow(exp, pow) .mod_power_of_2_mul(y.mod_power_of_2_pow(exp, pow), pow) ); }); unsigned_quadruple_gen_var_9::().test_properties(|(x, e, f, pow)| { if let Some(sum) = e.checked_add(f) { assert_eq!( x.mod_power_of_2_pow(sum, pow), x.mod_power_of_2_pow(e, pow) .mod_power_of_2_mul(x.mod_power_of_2_pow(f, pow), pow) ); } if let Some(product) = e.checked_mul(f) { assert_eq!( x.mod_power_of_2_pow(product, pow), x.mod_power_of_2_pow(e, pow).mod_power_of_2_pow(f, pow) ); } }); } #[test] fn mod_power_of_2_pow_properties() { apply_fn_to_unsigneds!(mod_power_of_2_pow_properties_helper); } malachite-base-0.4.16/tests/num/arithmetic/mod_power_of_2_shl.rs000064400000000000000000000114111046102023000227570ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::{ ArithmeticCheckedShl, ModPowerOf2Shl, ModPowerOf2ShlAssign, ModPowerOf2Shr, }; use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ signed_unsigned_pair_gen_var_12, unsigned_pair_gen_var_17, unsigned_pair_gen_var_23, unsigned_signed_unsigned_triple_gen_var_1, unsigned_triple_gen_var_17, }; use std::panic::catch_unwind; #[test] fn test_mod_power_of_2_shl() { fn test< T: ModPowerOf2Shl + ModPowerOf2ShlAssign + PrimitiveUnsigned, U: PrimitiveInt, >( t: T, u: U, pow: u64, out: T, ) { assert_eq!(t.mod_power_of_2_shl(u, pow), out); let mut t = t; t.mod_power_of_2_shl_assign(u, pow); assert_eq!(t, out); } test::(0, 0, 0, 0); test::(0, 0, 5, 0); test::(12, 2, 5, 16); test::(10, 100, 4, 0); test::(10, -2, 4, 2); test::(10, -100, 4, 0); test::(10, -100, 4, 0); } fn mod_power_of_2_shl_fail_helper< T: PrimitiveUnsigned + ModPowerOf2Shl, U: PrimitiveInt, >() { assert_panic!(T::ONE.mod_power_of_2_shl(U::TWO, 0)); assert_panic!(T::from(200u8).mod_power_of_2_shl(U::TWO, 7)); } #[test] fn mod_power_of_2_shl_fail() { apply_fn_to_unsigneds_and_primitive_ints!(mod_power_of_2_shl_fail_helper); } fn mod_power_of_2_shl_assign_fail_helper< T: PrimitiveUnsigned + ModPowerOf2ShlAssign, U: PrimitiveInt, >() { assert_panic!({ let mut x = T::ONE; x.mod_power_of_2_shl_assign(U::TWO, 0); }); assert_panic!({ let mut x = T::from(200u8); x.mod_power_of_2_shl_assign(U::TWO, 7); }); } #[test] fn mod_power_of_2_shl_assign_fail() { apply_fn_to_unsigneds_and_primitive_ints!(mod_power_of_2_shl_assign_fail_helper); } fn mod_power_of_2_shl_properties_unsigned_unsigned_helper< T: ArithmeticCheckedShl + ModPowerOf2Shl + ModPowerOf2ShlAssign + PrimitiveUnsigned, U: PrimitiveUnsigned, >() { unsigned_triple_gen_var_17::().test_properties(|(n, u, pow)| { assert!(n.mod_power_of_2_is_reduced(pow)); let shifted = n.mod_power_of_2_shl(u, pow); assert!(shifted.mod_power_of_2_is_reduced(pow)); let mut shifted_alt = n; shifted_alt.mod_power_of_2_shl_assign(u, pow); assert_eq!(shifted_alt, shifted); if let Some(shifted_alt) = n.arithmetic_checked_shl(u) { assert_eq!(shifted_alt.mod_power_of_2(pow), shifted); } }); unsigned_pair_gen_var_17::().test_properties(|(n, pow)| { assert_eq!(n.mod_power_of_2_shl(U::ZERO, pow), n); }); unsigned_pair_gen_var_23::().test_properties(|(u, pow)| { assert_eq!(T::ZERO.mod_power_of_2_shl(u, pow), T::ZERO); }); } fn mod_power_of_2_shl_properties_unsigned_signed_helper< T: ArithmeticCheckedShl + ModPowerOf2Shl + ModPowerOf2Shr + ModPowerOf2ShlAssign + PrimitiveUnsigned, U: PrimitiveSigned, >() { unsigned_signed_unsigned_triple_gen_var_1::().test_properties(|(n, i, pow)| { assert!(n.mod_power_of_2_is_reduced(pow)); let shifted = n.mod_power_of_2_shl(i, pow); assert!(shifted.mod_power_of_2_is_reduced(pow)); let mut shifted_alt = n; shifted_alt.mod_power_of_2_shl_assign(i, pow); assert_eq!(shifted_alt, shifted); if let Some(shifted_alt) = n.arithmetic_checked_shl(i) { assert_eq!(shifted_alt.mod_power_of_2(pow), shifted); } if i != U::MIN { assert_eq!(n.mod_power_of_2_shr(-i, pow), shifted); } }); unsigned_pair_gen_var_17::().test_properties(|(n, pow)| { assert_eq!(n.mod_power_of_2_shl(U::ZERO, pow), n); }); signed_unsigned_pair_gen_var_12::().test_properties(|(i, pow)| { assert_eq!(T::ZERO.mod_power_of_2_shl(i, pow), T::ZERO); }); } #[test] fn mod_power_of_2_shl_properties() { apply_fn_to_unsigneds_and_unsigneds!(mod_power_of_2_shl_properties_unsigned_unsigned_helper); apply_fn_to_unsigneds_and_signeds!(mod_power_of_2_shl_properties_unsigned_signed_helper); } malachite-base-0.4.16/tests/num/arithmetic/mod_power_of_2_shr.rs000064400000000000000000000070161046102023000227730ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::{ ArithmeticCheckedShr, ModPowerOf2Shl, ModPowerOf2Shr, ModPowerOf2ShrAssign, }; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ signed_unsigned_pair_gen_var_12, unsigned_pair_gen_var_17, unsigned_signed_unsigned_triple_gen_var_1, }; use std::panic::catch_unwind; #[test] fn test_mod_power_of_2_shr() { fn test< T: ModPowerOf2Shr + ModPowerOf2ShrAssign + PrimitiveUnsigned, U: PrimitiveSigned, >( t: T, u: U, pow: u64, out: T, ) { assert_eq!(t.mod_power_of_2_shr(u, pow), out); let mut t = t; t.mod_power_of_2_shr_assign(u, pow); assert_eq!(t, out); } test::(0, 0, 0, 0); test::(0, 0, 5, 0); test::(12, -2, 5, 16); test::(10, -100, 4, 0); test::(10, 2, 4, 2); test::(10, 100, 4, 0); test::(10, 100, 4, 0); } fn mod_power_of_2_shr_fail_helper< T: PrimitiveUnsigned + ModPowerOf2Shr, U: PrimitiveSigned, >() { assert_panic!(T::ONE.mod_power_of_2_shr(U::TWO, 0)); assert_panic!(T::from(200u8).mod_power_of_2_shr(U::TWO, 7)); } #[test] fn mod_power_of_2_shr_fail() { apply_fn_to_unsigneds_and_signeds!(mod_power_of_2_shr_fail_helper); } fn mod_power_of_2_shr_assign_fail_helper< T: PrimitiveUnsigned + ModPowerOf2ShrAssign, U: PrimitiveSigned, >() { assert_panic!({ let mut x = T::ONE; x.mod_power_of_2_shr_assign(U::TWO, 0); }); assert_panic!({ let mut x = T::from(200u8); x.mod_power_of_2_shr_assign(U::TWO, 7); }); } #[test] fn mod_power_of_2_shr_assign_fail() { apply_fn_to_unsigneds_and_signeds!(mod_power_of_2_shr_assign_fail_helper); } fn mod_power_of_2_shl_properties_helper< T: ArithmeticCheckedShr + ModPowerOf2Shl + ModPowerOf2Shr + ModPowerOf2ShrAssign + PrimitiveUnsigned, U: PrimitiveSigned, >() { unsigned_signed_unsigned_triple_gen_var_1::().test_properties(|(n, i, pow)| { assert!(n.mod_power_of_2_is_reduced(pow)); let shifted = n.mod_power_of_2_shr(i, pow); assert!(shifted.mod_power_of_2_is_reduced(pow)); let mut shifted_alt = n; shifted_alt.mod_power_of_2_shr_assign(i, pow); assert_eq!(shifted_alt, shifted); if let Some(shifted_alt) = n.arithmetic_checked_shr(i) { assert_eq!(shifted_alt.mod_power_of_2(pow), shifted); } if i != U::MIN { assert_eq!(n.mod_power_of_2_shl(-i, pow), shifted); } }); unsigned_pair_gen_var_17::().test_properties(|(n, pow)| { assert_eq!(n.mod_power_of_2_shr(U::ZERO, pow), n); }); signed_unsigned_pair_gen_var_12::().test_properties(|(i, pow)| { assert_eq!(T::ZERO.mod_power_of_2_shr(i, pow), T::ZERO); }); } #[test] fn mod_power_of_2_shl_properties() { apply_fn_to_unsigneds_and_signeds!(mod_power_of_2_shl_properties_helper); } malachite-base-0.4.16/tests/num/arithmetic/mod_power_of_2_square.rs000064400000000000000000000060621046102023000234770ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ unsigned_gen_var_9, unsigned_pair_gen_var_17, unsigned_triple_gen_var_11, }; use std::panic::catch_unwind; fn mod_power_of_2_square_helper() { let test = |x: T, pow: u64, out| { assert_eq!(x.mod_power_of_2_square(pow), out); let mut mut_x = x; mut_x.mod_power_of_2_square_assign(pow); assert_eq!(mut_x, out); }; test(T::ZERO, 0, T::ZERO); test(T::ZERO, 2, T::ZERO); test(T::ONE, 2, T::ONE); test(T::TWO, 2, T::ZERO); test(T::TWO, 3, T::exact_from(4)); test(T::exact_from(5), 3, T::ONE); test(T::exact_from(100), 8, T::exact_from(16)); } #[test] fn test_mod_power_of_2_square() { apply_fn_to_unsigneds!(mod_power_of_2_square_helper); } fn mod_power_of_2_square_fail_helper() { assert_panic!(T::ONE.mod_power_of_2_square(0)); assert_panic!(T::from(200u8).mod_power_of_2_square(7)); } #[test] fn mod_power_of_2_square_fail() { apply_fn_to_unsigneds!(mod_power_of_2_square_fail_helper); } fn mod_power_of_2_square_assign_fail_helper() { assert_panic!({ let mut x = T::ONE; x.mod_power_of_2_square_assign(0); }); assert_panic!({ let mut x = T::from(200u8); x.mod_power_of_2_square_assign(7); }); } #[test] fn mod_power_of_2_square_assign_fail() { apply_fn_to_unsigneds!(mod_power_of_2_square_assign_fail_helper); } fn mod_power_of_2_square_properties_helper() { unsigned_pair_gen_var_17::().test_properties(|(x, pow)| { assert!(x.mod_power_of_2_is_reduced(pow)); let square = x.mod_power_of_2_square(pow); assert!(square.mod_power_of_2_is_reduced(pow)); let mut x_alt = x; x_alt.mod_power_of_2_square_assign(pow); assert_eq!(x_alt, square); assert_eq!(x.mod_power_of_2_pow(2, pow), x.mod_power_of_2_mul(x, pow)); assert_eq!(x.mod_power_of_2_neg(pow).mod_power_of_2_square(pow), square); }); unsigned_gen_var_9::().test_properties(|pow| { assert_eq!(T::ZERO.mod_power_of_2_square(pow), T::ZERO); if pow != 0 { assert_eq!(T::ONE.mod_power_of_2_square(pow), T::ONE); } }); unsigned_triple_gen_var_11::().test_properties(|(x, y, pow)| { assert_eq!( x.mod_power_of_2_mul(y, pow).mod_power_of_2_square(pow), x.mod_power_of_2_square(pow) .mod_power_of_2_mul(y.mod_power_of_2_square(pow), pow) ); }); } #[test] fn mod_power_of_2_square_properties() { apply_fn_to_unsigneds!(mod_power_of_2_square_properties_helper); } malachite-base-0.4.16/tests/num/arithmetic/mod_power_of_2_sub.rs000064400000000000000000000070321046102023000227660ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{unsigned_pair_gen_var_17, unsigned_triple_gen_var_11}; use std::panic::catch_unwind; fn mod_power_of_2_sub_helper() { let test = |x: T, y: T, pow, out| { assert_eq!(x.mod_power_of_2_sub(y, pow), out); let mut x = x; x.mod_power_of_2_sub_assign(y, pow); assert_eq!(x, out); }; test(T::ZERO, T::ZERO, 0, T::ZERO); test(T::ZERO, T::ONE, 1, T::ONE); test(T::ONE, T::ONE, 1, T::ZERO); test(T::exact_from(5), T::TWO, 5, T::exact_from(3)); test(T::exact_from(10), T::exact_from(14), 4, T::exact_from(12)); test( T::exact_from(100), T::exact_from(200), 8, T::exact_from(156), ); test(T::ZERO, T::ONE, T::WIDTH, T::MAX); test(T::ONE, T::MAX, T::WIDTH, T::TWO); } #[test] fn test_mod_power_of_2_sub() { apply_fn_to_unsigneds!(mod_power_of_2_sub_helper); } fn mod_power_of_2_sub_fail_helper() { assert_panic!(T::ONE.mod_power_of_2_sub(T::ZERO, 0)); assert_panic!(T::ZERO.mod_power_of_2_sub(T::ONE, 0)); assert_panic!(T::from(123u8).mod_power_of_2_sub(T::from(200u8), 7)); assert_panic!(T::from(200u8).mod_power_of_2_sub(T::from(123u8), 7)); } #[test] fn mod_power_of_2_sub_fail() { apply_fn_to_unsigneds!(mod_power_of_2_sub_fail_helper); } fn mod_power_of_2_sub_assign_fail_helper() { assert_panic!({ let mut x = T::ONE; x.mod_power_of_2_sub_assign(T::ZERO, 0); }); assert_panic!({ let mut x = T::ZERO; x.mod_power_of_2_sub_assign(T::ONE, 0); }); assert_panic!({ let mut x = T::from(123u8); x.mod_power_of_2_sub_assign(T::from(200u8), 7); }); assert_panic!({ let mut x = T::from(200u8); x.mod_power_of_2_sub_assign(T::from(123u8), 7); }); } #[test] fn mod_power_of_2_sub_assign_fail() { apply_fn_to_unsigneds!(mod_power_of_2_sub_assign_fail_helper); } fn mod_power_of_2_sub_properties_helper() { unsigned_triple_gen_var_11::().test_properties(|(x, y, pow)| { assert!(x.mod_power_of_2_is_reduced(pow)); assert!(y.mod_power_of_2_is_reduced(pow)); let diff = x.mod_power_of_2_sub(y, pow); assert!(diff.mod_power_of_2_is_reduced(pow)); let mut x_alt = x; x_alt.mod_power_of_2_sub_assign(y, pow); assert_eq!(x_alt, diff); assert_eq!(diff.mod_power_of_2_add(y, pow), x); assert_eq!(diff.mod_power_of_2_sub(x, pow), y.mod_power_of_2_neg(pow)); assert_eq!(y.mod_power_of_2_sub(x, pow), diff.mod_power_of_2_neg(pow)); assert_eq!(x.mod_power_of_2_add(y.mod_power_of_2_neg(pow), pow), diff); }); unsigned_pair_gen_var_17::().test_properties(|(x, pow)| { assert_eq!(x.mod_power_of_2_sub(T::ZERO, pow), x); assert_eq!( T::ZERO.mod_power_of_2_sub(x, pow), x.mod_power_of_2_neg(pow) ); assert_eq!(x.mod_power_of_2_sub(x, pow), T::ZERO); }); } #[test] fn mod_power_of_2_sub_properties() { apply_fn_to_unsigneds!(mod_power_of_2_sub_properties_helper); } malachite-base-0.4.16/tests/num/arithmetic/mod_shl.rs000064400000000000000000000123141046102023000206410ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::{ArithmeticCheckedShl, ModShl, ModShlAssign, ModShr}; use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::WrappingFrom; use malachite_base::test_util::generators::{ signed_gen_var_5, signed_unsigned_pair_gen_var_13, unsigned_gen_var_5, unsigned_pair_gen_var_16, unsigned_pair_gen_var_2, unsigned_pair_gen_var_25, unsigned_signed_pair_gen_var_1, unsigned_signed_unsigned_triple_gen_var_2, unsigned_triple_gen_var_18, }; use std::panic::catch_unwind; #[test] fn test_mod_shl() { fn test< T: ModShl + ModShlAssign + PrimitiveUnsigned, U: PrimitiveInt, >( t: T, u: U, m: T, out: T, ) { assert_eq!(t.mod_shl(u, m), out); let mut t = t; t.mod_shl_assign(u, m); assert_eq!(t, out); } test::(0, 0, 1, 0); test::(0, 0, 5, 0); test::(8, 2, 10, 2); test::(10, 100, 17, 7); test::(10, -2, 15, 2); test::(10, -100, 19, 0); test::(10, -100, 19, 0); } fn mod_shl_fail_helper, U: PrimitiveInt>() { assert_panic!(T::ZERO.mod_shl(U::TWO, T::ZERO)); assert_panic!(T::from(123u8).mod_shl(U::TWO, T::from(123u8))); } #[test] fn mod_shl_fail() { apply_fn_to_unsigneds_and_primitive_ints!(mod_shl_fail_helper); } fn mod_shl_assign_fail_helper, U: PrimitiveInt>() { assert_panic!({ let mut x = T::ZERO; x.mod_shl_assign(U::TWO, T::ZERO); }); assert_panic!({ let mut x = T::from(123u8); x.mod_shl_assign(U::TWO, T::from(123u8)); }); } #[test] fn mod_shl_assign_fail() { apply_fn_to_unsigneds_and_primitive_ints!(mod_shl_assign_fail_helper); } fn mod_shl_properties_unsigned_unsigned_helper< T: ArithmeticCheckedShl + ModShl + ModShlAssign + PrimitiveUnsigned, U: PrimitiveUnsigned, >() { unsigned_triple_gen_var_18::().test_properties(|(n, u, m)| { assert!(n.mod_is_reduced(&m)); let shifted = n.mod_shl(u, m); assert!(shifted.mod_is_reduced(&m)); let mut shifted_alt = n; shifted_alt.mod_shl_assign(u, m); assert_eq!(shifted_alt, shifted); if let Some(shifted_alt) = n.arithmetic_checked_shl(u) { assert_eq!(shifted_alt % m, shifted); } }); unsigned_pair_gen_var_16::().test_properties(|(n, m)| { assert_eq!(n.mod_shl(U::ZERO, m), n); }); unsigned_pair_gen_var_25::().test_properties(|(u, m)| { assert_eq!(T::ZERO.mod_shl(u, m), T::ZERO); }); unsigned_pair_gen_var_2::().test_properties(|(n, u)| { assert_panic!(n.mod_shl(u, T::ZERO)); assert_panic!({ let mut n = n; n.mod_shl_assign(u, T::ZERO); }); }); unsigned_gen_var_5::().test_properties(|u| { assert_eq!(T::ZERO.mod_shl(u, T::ONE), T::ZERO); }); } fn mod_shl_properties_unsigned_signed_helper< T: ArithmeticCheckedShl + ModShl + ModShr + ModShlAssign + PrimitiveUnsigned, U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >() { unsigned_signed_unsigned_triple_gen_var_2::().test_properties(|(n, i, m)| { assert!(n.mod_is_reduced(&m)); let shifted = n.mod_shl(i, m); assert!(shifted.mod_is_reduced(&m)); let mut shifted_alt = n; shifted_alt.mod_shl_assign(i, m); assert_eq!(shifted_alt, shifted); if let Some(shifted_alt) = n.arithmetic_checked_shl(i) { assert_eq!(shifted_alt % m, shifted); } if i != S::MIN { assert_eq!(n.mod_shr(-i, m), shifted); } }); unsigned_pair_gen_var_16::().test_properties(|(n, m)| { assert_eq!(n.mod_shl(S::ZERO, m), n); }); signed_unsigned_pair_gen_var_13::().test_properties(|(i, m)| { assert_eq!(T::ZERO.mod_shl(i, m), T::ZERO); }); unsigned_signed_pair_gen_var_1::().test_properties(|(n, i)| { assert_panic!(n.mod_shl(i, T::ZERO)); assert_panic!({ let mut n = n; n.mod_shl_assign(i, T::ZERO); }); }); signed_gen_var_5::().test_properties(|i| { assert_eq!(T::ZERO.mod_shl(i, T::ONE), T::ZERO); }); } #[test] fn mod_shl_properties() { apply_fn_to_unsigneds_and_unsigneds!(mod_shl_properties_unsigned_unsigned_helper); apply_fn_to_unsigneds_and_unsigned_signed_pairs!(mod_shl_properties_unsigned_signed_helper); } malachite-base-0.4.16/tests/num/arithmetic/mod_shr.rs000064400000000000000000000074021046102023000206510ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::{ArithmeticCheckedShr, ModShl, ModShr, ModShrAssign}; use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::WrappingFrom; use malachite_base::test_util::generators::{ signed_gen_var_5, signed_unsigned_pair_gen_var_13, unsigned_pair_gen_var_16, unsigned_signed_pair_gen_var_1, unsigned_signed_unsigned_triple_gen_var_2, }; use std::panic::catch_unwind; #[test] fn test_mod_shr() { fn test< T: ModShr + ModShrAssign + PrimitiveUnsigned, U: PrimitiveInt, >( t: T, i: U, m: T, out: T, ) { assert_eq!(t.mod_shr(i, m), out); let mut t = t; t.mod_shr_assign(i, m); assert_eq!(t, out); } test::(0, 0, 1, 0); test::(0, 0, 5, 0); test::(8, -2, 10, 2); test::(10, -100, 17, 7); test::(10, 2, 15, 2); test::(10, 100, 19, 0); test::(10, 100, 19, 0); } fn mod_shr_fail_helper, U: PrimitiveSigned>() { assert_panic!(T::ZERO.mod_shr(U::TWO, T::ZERO)); assert_panic!(T::from(123u8).mod_shr(U::TWO, T::from(123u8))); } #[test] fn mod_shr_fail() { apply_fn_to_unsigneds_and_signeds!(mod_shr_fail_helper); } fn mod_shr_assign_fail_helper, U: PrimitiveSigned>() { assert_panic!({ let mut x = T::ZERO; x.mod_shr_assign(U::TWO, T::ZERO); }); assert_panic!({ let mut x = T::from(123u8); x.mod_shr_assign(U::TWO, T::from(123u8)); }); } #[test] fn mod_shr_assign_fail() { apply_fn_to_unsigneds_and_signeds!(mod_shr_assign_fail_helper); } fn mod_shr_properties_helper< T: ArithmeticCheckedShr + ModShl + ModShr + ModShrAssign + PrimitiveUnsigned, U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >() { unsigned_signed_unsigned_triple_gen_var_2::().test_properties(|(n, i, m)| { assert!(n.mod_is_reduced(&m)); let shifted = n.mod_shr(i, m); assert!(shifted.mod_is_reduced(&m)); let mut shifted_alt = n; shifted_alt.mod_shr_assign(i, m); assert_eq!(shifted_alt, shifted); if let Some(shifted_alt) = n.arithmetic_checked_shr(i) { assert_eq!(shifted_alt % m, shifted); } if i != S::MIN { assert_eq!(n.mod_shl(-i, m), shifted); } }); unsigned_pair_gen_var_16::().test_properties(|(n, m)| { assert_eq!(n.mod_shr(S::ZERO, m), n); }); signed_unsigned_pair_gen_var_13::().test_properties(|(i, m)| { assert_eq!(T::ZERO.mod_shr(i, m), T::ZERO); }); unsigned_signed_pair_gen_var_1::().test_properties(|(n, i)| { assert_panic!(n.mod_shr(i, T::ZERO)); assert_panic!({ let mut n = n; n.mod_shr_assign(i, T::ZERO); }); }); signed_gen_var_5::().test_properties(|i| { assert_eq!(T::ZERO.mod_shl(i, T::ONE), T::ZERO); }); } #[test] fn mod_shr_properties() { apply_fn_to_unsigneds_and_unsigned_signed_pairs!(mod_shr_properties_helper); } malachite-base-0.4.16/tests/num/arithmetic/mod_square.rs000064400000000000000000000067341046102023000213640ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ unsigned_gen, unsigned_gen_var_1, unsigned_pair_gen_var_16, unsigned_triple_gen_var_12, }; use std::panic::catch_unwind; fn mod_square_helper() { let test = |x: T, m, out| { assert_eq!(x.mod_mul(x, m), out); assert_eq!(x.mod_square(m), out); let mut mut_x = x; mut_x.mod_square_assign(m); assert_eq!(mut_x, out); let data = T::precompute_mod_pow_data(&m); assert_eq!(x.mod_square_precomputed(m, &data), out); let mut mut_x = x; mut_x.mod_square_precomputed_assign(m, &data); assert_eq!(mut_x, out); }; test(T::ZERO, T::ONE, T::ZERO); test(T::ONE, T::exact_from(10), T::ONE); test(T::TWO, T::exact_from(10), T::exact_from(4)); if T::WIDTH > u8::WIDTH { test(T::exact_from(100), T::exact_from(497), T::exact_from(60)); test(T::exact_from(200), T::exact_from(497), T::exact_from(240)); test(T::exact_from(300), T::exact_from(497), T::exact_from(43)); } } #[test] fn test_mod_square() { apply_fn_to_unsigneds!(mod_square_helper); } fn mod_square_fail_helper() { assert_panic!(T::ZERO.mod_square(T::ZERO)); assert_panic!(T::from(123u8).mod_square(T::from(123u8))); } #[test] fn mod_square_fail() { apply_fn_to_unsigneds!(mod_square_fail_helper); } fn mod_square_assign_fail_helper() { assert_panic!({ let mut x = T::ZERO; x.mod_square_assign(T::ZERO); }); assert_panic!({ let mut x = T::from(123u8); x.mod_square_assign(T::from(123u8)); }); } #[test] fn mod_square_assign_fail() { apply_fn_to_unsigneds!(mod_square_assign_fail_helper); } fn mod_square_properties_helper() { unsigned_pair_gen_var_16::().test_properties(|(x, m)| { assert!(x.mod_is_reduced(&m)); let square = x.mod_square(m); assert!(square.mod_is_reduced(&m)); let mut x_alt = x; x_alt.mod_square_assign(m); assert_eq!(x_alt, square); let data = T::precompute_mod_pow_data(&m); assert_eq!(x.mod_square_precomputed(m, &data), square); let mut x_alt = x; x_alt.mod_square_precomputed_assign(m, &data); assert_eq!(x_alt, square); assert_eq!(x.mod_mul(x, m), square); assert_eq!(x.mod_neg(m).mod_square(m), square); }); unsigned_gen_var_1::().test_properties(|m| { assert_eq!(T::ZERO.mod_square(m), T::ZERO); if m != T::ONE { assert_eq!(T::ONE.mod_square(m), T::ONE); } }); unsigned_triple_gen_var_12::().test_properties(|(x, y, m)| { assert_eq!( x.mod_mul(y, m).mod_square(m), x.mod_square(m).mod_mul(y.mod_square(m), m) ); }); unsigned_gen::().test_properties(|x| { assert_panic!(x.mod_square(T::ZERO)); }); } #[test] fn mod_square_properties() { apply_fn_to_unsigneds!(mod_square_properties_helper); } malachite-base-0.4.16/tests/num/arithmetic/mod_sub.rs000064400000000000000000000064211046102023000206460ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ unsigned_pair_gen_var_16, unsigned_pair_gen_var_27, unsigned_triple_gen_var_12, }; use std::panic::catch_unwind; fn mod_sub_helper() { let test = |x: T, y: T, m, out| { assert_eq!(x.mod_sub(y, m), out); let mut x = x; x.mod_sub_assign(y, m); assert_eq!(x, out); }; test(T::ZERO, T::ZERO, T::ONE, T::ZERO); test(T::exact_from(4), T::exact_from(3), T::exact_from(5), T::ONE); test( T::exact_from(7), T::exact_from(9), T::exact_from(10), T::exact_from(8), ); test( T::exact_from(100), T::exact_from(120), T::exact_from(123), T::exact_from(103), ); test(T::ZERO, T::ONE, T::MAX, T::MAX - T::ONE); test(T::MAX - T::TWO, T::MAX - T::ONE, T::MAX, T::MAX - T::ONE); } #[test] fn test_mod_sub() { apply_fn_to_unsigneds!(mod_sub_helper); } fn mod_sub_fail_helper() { assert_panic!(T::ZERO.mod_sub(T::ZERO, T::ZERO)); assert_panic!(T::from(123u8).mod_sub(T::from(200u8), T::from(200u8))); assert_panic!(T::from(200u8).mod_sub(T::from(123u8), T::from(200u8))); } #[test] fn mod_sub_fail() { apply_fn_to_unsigneds!(mod_sub_fail_helper); } fn mod_sub_assign_fail_helper() { assert_panic!({ let mut x = T::ZERO; x.mod_sub_assign(T::ZERO, T::ZERO); }); assert_panic!({ let mut x = T::from(123u8); x.mod_sub_assign(T::from(200u8), T::from(200u8)); }); assert_panic!({ let mut x = T::from(200u8); x.mod_sub_assign(T::from(123u8), T::from(200u8)); }); } #[test] fn mod_sub_assign_fail() { apply_fn_to_unsigneds!(mod_sub_assign_fail_helper); } fn mod_sub_properties_helper() { unsigned_triple_gen_var_12::().test_properties(|(x, y, m)| { assert!(x.mod_is_reduced(&m)); assert!(y.mod_is_reduced(&m)); let diff = x.mod_sub(y, m); assert!(diff.mod_is_reduced(&m)); let mut x_alt = x; x_alt.mod_sub_assign(y, m); assert_eq!(x_alt, diff); assert_eq!(diff.mod_add(y, m), x); assert_eq!(diff.mod_sub(x, m), y.mod_neg(m)); assert_eq!(y.mod_sub(x, m), diff.mod_neg(m)); assert_eq!(x.mod_add(y.mod_neg(m), m), diff); }); unsigned_pair_gen_var_16::().test_properties(|(x, m)| { assert_eq!(x.mod_sub(T::ZERO, m), x); assert_eq!(T::ZERO.mod_sub(x, m), x.mod_neg(m)); assert_eq!(x.mod_sub(x, m), T::ZERO); }); unsigned_pair_gen_var_27::().test_properties(|(x, y)| { assert_panic!(x.mod_sub(y, T::ZERO)); assert_panic!({ let mut x = x; x.mod_sub_assign(y, T::ZERO); }); }); } #[test] fn mod_sub_properties() { apply_fn_to_unsigneds!(mod_sub_properties_helper); } malachite-base-0.4.16/tests/num/arithmetic/neg.rs000064400000000000000000000050641046102023000177710ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::generators::{primitive_float_gen, signed_gen_var_1}; fn neg_assign_helper_signed() { let test = |n: T, out| { let mut n = n; n.neg_assign(); assert_eq!(n, out); }; test(T::ZERO, T::ZERO); test(T::ONE, T::NEGATIVE_ONE); test(T::exact_from(100), T::exact_from(-100)); test(T::NEGATIVE_ONE, T::ONE); test(T::exact_from(-100), T::exact_from(100)); } fn neg_assign_helper_primitive_float() { let test = |x: T, out| { let mut x = x; x.neg_assign(); assert_eq!(NiceFloat(x), NiceFloat(out)); }; test(T::ZERO, T::NEGATIVE_ZERO); test(T::NEGATIVE_ZERO, T::ZERO); test(T::INFINITY, T::NEGATIVE_INFINITY); test(T::NEGATIVE_INFINITY, T::INFINITY); test(T::NAN, T::NAN); test(T::ONE, T::NEGATIVE_ONE); test(T::from(100.0), T::from(-100.0)); test(T::NEGATIVE_ONE, T::ONE); test(T::from(-100.0), T::from(100.0)); } #[test] fn test_neg_assign() { apply_fn_to_signeds!(neg_assign_helper_signed); apply_fn_to_primitive_floats!(neg_assign_helper_primitive_float); } fn neg_assign_properties_helper_signed() { signed_gen_var_1::().test_properties(|n| { let mut neg = n; neg.neg_assign(); assert_eq!(neg, -n); assert_eq!(-neg, n); assert_eq!(neg == n, n == T::ZERO); assert_eq!(n + neg, T::ZERO); }); } fn neg_assign_properties_helper_primitive_float() { primitive_float_gen::().test_properties(|x| { let mut neg = x; neg.neg_assign(); assert_eq!(NiceFloat(neg), NiceFloat(-x)); assert_eq!(NiceFloat(-neg), NiceFloat(x)); assert_eq!(NiceFloat(neg) == NiceFloat(x), x.is_nan()); if x.is_finite() { assert_eq!(x + neg, T::ZERO); } }); } #[test] fn neg_assign_properties() { apply_fn_to_signeds!(neg_assign_properties_helper_signed); apply_fn_to_primitive_floats!(neg_assign_properties_helper_primitive_float); } malachite-base-0.4.16/tests/num/arithmetic/next_power_of_2.rs000064400000000000000000000074311046102023000223170ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::generators::{primitive_float_gen_var_19, unsigned_gen_var_14}; use std::panic::catch_unwind; fn next_power_of_2_helper_unsigned() { let test = |n: T, out| { assert_eq!(n.next_power_of_2(), out); let mut n = n; n.next_power_of_2_assign(); assert_eq!(n, out); }; test(T::ZERO, T::ONE); test(T::ONE, T::ONE); test(T::exact_from(7), T::exact_from(8)); test(T::exact_from(8), T::exact_from(8)); test(T::exact_from(10), T::exact_from(16)); test((T::MAX >> 1u64) + T::ONE, (T::MAX >> 1u64) + T::ONE); test( (T::MAX >> 1u64) - T::exact_from(10), (T::MAX >> 1u64) + T::ONE, ); } fn next_power_of_2_helper_primitive_float() { let test = |n: T, out| { assert_eq!(NiceFloat(n.next_power_of_2()), NiceFloat(out)); let mut n = n; n.next_power_of_2_assign(); assert_eq!(NiceFloat(n), NiceFloat(out)); }; test(T::ZERO, T::MIN_POSITIVE_SUBNORMAL); test(T::ONE, T::ONE); test(T::from(7.0f32), T::from(8.0f32)); test(T::from(8.0f32), T::from(8.0f32)); test(T::from(10.0f32), T::from(16.0f32)); test(T::from(0.1f32), T::from(0.125f32)); test(T::from(0.01f32), T::from(0.015625f32)); test( T::power_of_2(T::MAX_EXPONENT), T::power_of_2(T::MAX_EXPONENT), ); } #[test] fn test_next_power_of_2() { apply_fn_to_unsigneds!(next_power_of_2_helper_unsigned); apply_fn_to_primitive_floats!(next_power_of_2_helper_primitive_float); } fn next_power_of_2_fail_helper_primitive_float() { assert_panic!(T::NEGATIVE_ZERO.next_power_of_2()); assert_panic!(T::INFINITY.next_power_of_2()); assert_panic!(T::NEGATIVE_INFINITY.next_power_of_2()); assert_panic!(T::NAN.next_power_of_2()); assert_panic!(T::NEGATIVE_ONE.next_power_of_2()); assert_panic!(T::MAX_FINITE.next_power_of_2()); let test = |x: T| { let mut x = x; x.next_power_of_2_assign(); }; assert_panic!(test(T::NEGATIVE_ZERO)); assert_panic!(test(T::INFINITY)); assert_panic!(test(T::NEGATIVE_INFINITY)); assert_panic!(test(T::NAN)); assert_panic!(test(T::NEGATIVE_ONE)); assert_panic!(test(T::MAX_FINITE)); } #[test] fn next_power_of_2_fail() { apply_fn_to_primitive_floats!(next_power_of_2_fail_helper_primitive_float); } fn next_power_of_2_properties_helper_unsigned() { unsigned_gen_var_14::().test_properties(|n| { let p = n.next_power_of_2(); assert!(p >= n); assert!(p >> 1 <= n); assert!(p.is_power_of_2()); let mut n = n; n.next_power_of_2_assign(); assert_eq!(n, p); }); } fn next_power_of_2_properties_helper_primitive_float() { primitive_float_gen_var_19::().test_properties(|x| { let p = x.next_power_of_2(); assert!(p >= x); assert!(p / T::TWO <= x); assert!(p.is_power_of_2()); let mut x = x; x.next_power_of_2_assign(); assert_eq!(x, p); }); } #[test] fn next_power_of_2_properties() { apply_fn_to_unsigneds!(next_power_of_2_properties_helper_unsigned); apply_fn_to_primitive_floats!(next_power_of_2_properties_helper_primitive_float); } malachite-base-0.4.16/tests/num/arithmetic/overflowing_abs.rs000064400000000000000000000032571046102023000224100ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::test_util::generators::signed_gen; fn overflowing_abs_helper() { let test = |n: T, out, overflow| { assert_eq!(n.overflowing_abs(), (out, overflow)); let mut n = n; assert_eq!(n.overflowing_abs_assign(), overflow); assert_eq!(n, out); }; test(T::ZERO, T::ZERO, false); test(T::ONE, T::ONE, false); test(T::exact_from(100), T::exact_from(100), false); test(T::MAX, T::MAX, false); test(T::NEGATIVE_ONE, T::ONE, false); test(T::exact_from(-100), T::exact_from(100), false); test(T::MIN, T::MIN, true); } #[test] fn test_overflowing_abs() { apply_fn_to_signeds!(overflowing_abs_helper); } fn overflowing_abs_properties_helper() { signed_gen::().test_properties(|n| { let mut abs = n; let overflow = abs.overflowing_abs_assign(); assert_eq!((abs, overflow), n.overflowing_abs()); assert_eq!(abs, n.wrapping_abs()); if n != T::MIN { assert_eq!(n.abs(), abs); } assert_eq!(abs == n, n >= T::ZERO || n == T::MIN); assert_eq!(n == T::MIN, overflow); }); } #[test] fn overflowing_abs_properties() { apply_fn_to_signeds!(overflowing_abs_properties_helper); } malachite-base-0.4.16/tests/num/arithmetic/overflowing_add.rs000064400000000000000000000040351046102023000223660ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{signed_pair_gen, unsigned_pair_gen_var_27}; #[test] fn test_overflowing_add() { fn test(x: T, y: T, out: T, overflow: bool) { assert_eq!(x.overflowing_add(y), (out, overflow)); let mut x = x; assert_eq!(x.overflowing_add_assign(y), overflow); assert_eq!(x, out); } test::(123, 456, 579, false); test::(123, 200, 67, true); test::(123, -456, -333, false); test::(123, 45, -88, true); test::(-123, -45, 88, true); } fn overflowing_add_properties_helper_unsigned() { unsigned_pair_gen_var_27::().test_properties(|(x, y)| { let mut sum = x; let overflow = sum.overflowing_add_assign(y); assert_eq!((sum, overflow), x.overflowing_add(y)); assert_eq!(x.wrapping_add(y), sum); if !overflow { assert_eq!(sum, x + y); } }); } fn overflowing_add_properties_helper_signed() { signed_pair_gen::().test_properties(|(x, y)| { let mut sum = x; let overflow = sum.overflowing_add_assign(y); assert_eq!((sum, overflow), x.overflowing_add(y)); assert_eq!(x.wrapping_add(y), sum); if !overflow { assert_eq!(sum, x + y); } }); } #[test] fn overflowing_add_properties() { apply_fn_to_unsigneds!(overflowing_add_properties_helper_unsigned); apply_fn_to_signeds!(overflowing_add_properties_helper_signed); } malachite-base-0.4.16/tests/num/arithmetic/overflowing_add_mul.rs000064400000000000000000000073421046102023000232470ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ signed_pair_gen, signed_triple_gen, unsigned_pair_gen_var_27, unsigned_triple_gen_var_19, }; #[test] fn test_overflowing_add_mul() { fn test(x: T, y: T, z: T, out: T, overflow: bool) { assert_eq!(x.overflowing_add_mul(y, z), (out, overflow)); let mut x = x; assert_eq!(x.overflowing_add_mul_assign(y, z), overflow); assert_eq!(x, out); } test::(2, 3, 7, 23, false); test::(7, 5, 10, 57, false); test::(123, 456, 789, 359907, false); test::(123, -456, 789, -359661, false); test::(-123, 456, 789, 359661, false); test::(127, -2, 100, -73, false); test::(-127, 2, 100, 73, false); test::(-128, 1, 0, -128, false); test::(2, 20, 20, 146, true); test::(-127, -2, 100, -71, true); test::(127, 1, 100, -29, true); test::(-127, -1, 100, 29, true); test::(-127, -10, 100, -103, true); } fn overflowing_add_mul_properties_helper_unsigned() { unsigned_triple_gen_var_19::().test_properties(|(x, y, z)| { let (result, overflow) = x.overflowing_add_mul(y, z); let mut x_alt = x; assert_eq!(x_alt.overflowing_add_mul_assign(y, z), overflow); assert_eq!(x_alt, result); assert_eq!(x.overflowing_add_mul(z, y), (result, overflow)); assert_eq!(result.overflowing_sub_mul(y, z), (x, overflow)); assert_eq!(x.wrapping_add_mul(y, z), result); assert_eq!(x.checked_add_mul(y, z).is_none(), overflow); }); unsigned_pair_gen_var_27::().test_properties(|(a, b)| { assert_eq!(a.overflowing_add_mul(T::ZERO, b), (a, false)); assert_eq!(a.overflowing_add_mul(T::ONE, b), a.overflowing_add(b)); assert_eq!(T::ZERO.overflowing_add_mul(a, b), a.overflowing_mul(b)); assert_eq!(a.overflowing_add_mul(b, T::ZERO), (a, false)); assert_eq!(a.overflowing_add_mul(b, T::ONE), a.overflowing_add(b)); }); } fn overflowing_add_mul_properties_helper_signed() { signed_triple_gen::().test_properties(|(x, y, z)| { let (result, overflow) = x.overflowing_add_mul(y, z); let mut x_alt = x; assert_eq!(x_alt.overflowing_add_mul_assign(y, z), overflow); assert_eq!(x_alt, result); assert_eq!(x.overflowing_add_mul(z, y), (result, overflow)); assert_eq!(result.overflowing_sub_mul(y, z), (x, overflow)); assert_eq!(x.wrapping_add_mul(y, z), result); assert_eq!(x.checked_add_mul(y, z).is_none(), overflow); }); signed_pair_gen::().test_properties(|(a, b)| { assert_eq!(a.overflowing_add_mul(T::ZERO, b), (a, false)); assert_eq!(a.overflowing_add_mul(T::ONE, b), a.overflowing_add(b)); assert_eq!(T::ZERO.overflowing_add_mul(a, b), a.overflowing_mul(b)); assert_eq!(a.overflowing_add_mul(b, T::ZERO), (a, false)); assert_eq!(a.overflowing_add_mul(b, T::ONE), a.overflowing_add(b)); }); } #[test] fn overflowing_add_mul_properties() { apply_fn_to_unsigneds!(overflowing_add_mul_properties_helper_unsigned); apply_fn_to_signeds!(overflowing_add_mul_properties_helper_signed); } malachite-base-0.4.16/tests/num/arithmetic/overflowing_div.rs000064400000000000000000000047121046102023000224220ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{signed_pair_gen_var_6, unsigned_pair_gen_var_12}; use std::panic::catch_unwind; #[test] fn test_overflowing_div() { fn test(x: T, y: T, out: T, overflow: bool) { assert_eq!(x.overflowing_div(y), (out, overflow)); let mut x = x; assert_eq!(x.overflowing_div_assign(y), overflow); assert_eq!(x, out); } test::(0, 5, 0, false); test::(123, 456, 0, false); test::(100, 3, 33, false); test::(100, -3, -33, false); test::(-100, 3, -33, false); test::(-100, -3, 33, false); test::(-128, -1, -128, true); } fn overflowing_div_assign_fail_helper() { assert_panic!({ let mut n = T::ONE; n.overflowing_div_assign(T::ZERO); }); } #[test] fn overflowing_div_assign_fail() { apply_fn_to_primitive_ints!(overflowing_div_assign_fail_helper); } fn overflowing_div_properties_helper_unsigned() { unsigned_pair_gen_var_12::().test_properties(|(x, y)| { let mut quotient = x; let overflow = quotient.overflowing_div_assign(y); assert_eq!((quotient, overflow), x.overflowing_div(y)); assert_eq!(x.wrapping_div(y), quotient); assert!(!overflow); assert_eq!(quotient, x / y); }); } fn overflowing_div_properties_helper_signed() { signed_pair_gen_var_6::().test_properties(|(x, y)| { let mut quotient = x; let overflow = quotient.overflowing_div_assign(y); assert_eq!((quotient, overflow), x.overflowing_div(y)); assert_eq!(x.wrapping_div(y), quotient); if !overflow { assert_eq!(quotient, x / y); } }); } #[test] fn overflowing_div_properties() { apply_fn_to_unsigneds!(overflowing_div_properties_helper_unsigned); apply_fn_to_signeds!(overflowing_div_properties_helper_signed); } malachite-base-0.4.16/tests/num/arithmetic/overflowing_mul.rs000064400000000000000000000041061046102023000224320ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{signed_pair_gen, unsigned_pair_gen_var_27}; #[test] fn test_overflowing_mul() { fn test(x: T, y: T, out: T, overflow: bool) { assert_eq!(x.overflowing_mul(y), (out, overflow)); let mut x = x; assert_eq!(x.overflowing_mul_assign(y), overflow); assert_eq!(x, out); } test::(123, 456, 56088, false); test::(123, 200, 24, true); test::(123, -45, -5535, false); test::(123, 45, -97, true); test::(-123, 45, 97, true); } fn overflowing_mul_properties_helper_unsigned() { unsigned_pair_gen_var_27::().test_properties(|(x, y)| { let mut product = x; let overflow = product.overflowing_mul_assign(y); assert_eq!((product, overflow), x.overflowing_mul(y)); assert_eq!(x.wrapping_mul(y), product); if !overflow { assert_eq!(product, x * y); } }); } fn overflowing_mul_properties_helper_signed() { signed_pair_gen::().test_properties(|(x, y)| { let mut product = x; let overflow = product.overflowing_mul_assign(y); assert_eq!((product, overflow), x.overflowing_mul(y)); assert_eq!(x.wrapping_mul(y), product); if !overflow { assert_eq!(product, x * y); } }); } #[test] fn overflowing_mul_properties() { apply_fn_to_unsigneds!(overflowing_mul_properties_helper_unsigned); apply_fn_to_signeds!(overflowing_mul_properties_helper_signed); } malachite-base-0.4.16/tests/num/arithmetic/overflowing_neg.rs000064400000000000000000000053721046102023000224140ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{signed_gen, unsigned_gen}; fn unsigned_overflowing_neg_helper() { let test = |n: T, out, overflow| { assert_eq!(n.overflowing_neg(), (out, overflow)); let mut n = n; assert_eq!(n.overflowing_neg_assign(), overflow); assert_eq!(n, out); }; test(T::ZERO, T::ZERO, false); test(T::ONE, T::MAX, true); test( T::exact_from(100), T::MAX - T::exact_from(100) + T::ONE, true, ); test(T::MAX, T::ONE, true); } fn signed_overflowing_neg_helper() { let test = |n: T, out, overflow| { assert_eq!(n.overflowing_neg(), (out, overflow)); let mut n = n; assert_eq!(n.overflowing_neg_assign(), overflow); assert_eq!(n, out); }; test(T::ZERO, T::ZERO, false); test(T::ONE, T::NEGATIVE_ONE, false); test(T::exact_from(100), T::exact_from(-100), false); test(T::MAX, T::MIN + T::ONE, false); test(T::NEGATIVE_ONE, T::ONE, false); test(T::exact_from(-100), T::exact_from(100), false); test(T::MIN, T::MIN, true); } #[test] fn test_overflowing_neg() { apply_fn_to_unsigneds!(unsigned_overflowing_neg_helper); apply_fn_to_signeds!(signed_overflowing_neg_helper); } fn overflowing_neg_properties_helper_unsigned() { unsigned_gen::().test_properties(|n| { let mut neg = n; let overflow = neg.overflowing_neg_assign(); assert_eq!((neg, overflow), n.overflowing_neg()); assert_eq!(neg, n.wrapping_neg()); assert_eq!(neg == n, n == T::ZERO || n == T::power_of_2(T::WIDTH - 1)); assert_eq!(n != T::ZERO, overflow); }); } fn overflowing_neg_properties_helper_signed() { signed_gen::().test_properties(|n| { let mut neg = n; let overflow = neg.overflowing_neg_assign(); assert_eq!((neg, overflow), n.overflowing_neg()); assert_eq!(neg, n.wrapping_neg()); assert_eq!(neg == n, n == T::ZERO || n == T::MIN); assert_eq!(n == T::MIN, overflow); }); } #[test] fn overflowing_neg_properties() { apply_fn_to_unsigneds!(overflowing_neg_properties_helper_unsigned); apply_fn_to_signeds!(overflowing_neg_properties_helper_signed); } malachite-base-0.4.16/tests/num/arithmetic/overflowing_pow.rs000064400000000000000000000057331046102023000224510ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{signed_unsigned_pair_gen, unsigned_pair_gen}; #[test] fn test_overflowing_pow() { fn test(x: T, y: u64, out: T, overflow: bool) { assert_eq!(x.overflowing_pow(y), (out, overflow)); let mut x = x; assert_eq!(x.overflowing_pow_assign(y), overflow); assert_eq!(x, out); } test::(0, 0, 1, false); test::(123, 0, 1, false); test::(123, 1, 123, false); test::(0, 123, 0, false); test::(1, 123, 1, false); test::(-1, 123, -1, false); test::(-1, 124, 1, false); test::(3, 3, 27, false); test::(-10, 9, -1000000000, false); test::(-10, 10, 1410065408, true); test::(-10, 9, 13824, true); test::(10, 9, -13824, true); test::(123, 456, 2409344748064316129, true); test::(0, u64::MAX, 0, false); test::(1, u64::MAX, 1, false); test::(123, u64::MAX, 3449391168254631603, true); test::(0, u64::MAX, 0, false); test::(1, u64::MAX, 1, false); test::(-1, u64::MAX, -1, false); test::(-1, u64::MAX - 1, 1, false); test::(123, u64::MAX, 3449391168254631603, true); test::(-123, u64::MAX, -3449391168254631603, true); test::(-123, u64::MAX - 1, 4527249702272692521, true); } fn overflowing_pow_properties_helper_unsigned() { unsigned_pair_gen::().test_properties(|(x, y)| { let mut power = x; let overflow = power.overflowing_pow_assign(y); assert_eq!((power, overflow), x.overflowing_pow(y)); assert_eq!(x.wrapping_pow(y), power); assert_eq!(x.checked_pow(y).is_none(), overflow); if !overflow { assert_eq!(power, x.pow(y)); } }); } fn overflowing_pow_properties_helper_signed() { signed_unsigned_pair_gen::().test_properties(|(x, y)| { let mut power = x; let overflow = power.overflowing_pow_assign(y); assert_eq!((power, overflow), x.overflowing_pow(y)); assert_eq!(x.wrapping_pow(y), power); assert_eq!(x.checked_pow(y).is_none(), overflow); if !overflow { assert_eq!(power, x.pow(y)); } }); } #[test] fn overflowing_pow_properties() { apply_fn_to_unsigneds!(overflowing_pow_properties_helper_unsigned); apply_fn_to_signeds!(overflowing_pow_properties_helper_signed); } malachite-base-0.4.16/tests/num/arithmetic/overflowing_square.rs000064400000000000000000000051541046102023000231410ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{signed_gen, unsigned_gen}; #[test] fn test_overflowing_square() { fn test(x: T, out: T, overflow: bool) { assert_eq!(x.overflowing_square(), (out, overflow)); let mut x = x; assert_eq!(x.overflowing_square_assign(), overflow); assert_eq!(x, out); } test::(0, 0, false); test::(1, 1, false); test::(2, 4, false); test::(3, 9, false); test::(10, 100, false); test::(123, 15129, false); test::(1000, 1000000, false); test::(-1, 1, false); test::(-2, 4, false); test::(-3, 9, false); test::(-10, 100, false); test::(-123, 15129, false); test::(-1000, 1000000, false); test::(1000, 16960, true); test::(-1000, 16960, true); } fn overflowing_square_properties_helper_unsigned() { unsigned_gen::().test_properties(|x| { let mut square = x; let overflow = square.overflowing_square_assign(); assert_eq!((square, overflow), x.overflowing_square()); assert_eq!((square, overflow), x.overflowing_pow(2)); assert_eq!(x.wrapping_square(), square); assert_eq!(x.checked_square().is_none(), overflow); if !overflow { assert_eq!(square, x.square()); } }); } fn overflowing_square_properties_helper_signed() { signed_gen::().test_properties(|x| { let mut square = x; let overflow = square.overflowing_square_assign(); assert_eq!((square, overflow), x.overflowing_square()); assert_eq!((square, overflow), x.overflowing_pow(2)); assert_eq!(x.wrapping_square(), square); assert_eq!(x.checked_square().is_none(), overflow); if !overflow { assert_eq!(square, x.square()); } }); } #[test] fn overflowing_square_properties() { apply_fn_to_unsigneds!(overflowing_square_properties_helper_unsigned); apply_fn_to_signeds!(overflowing_square_properties_helper_signed); } malachite-base-0.4.16/tests/num/arithmetic/overflowing_sub.rs000064400000000000000000000040471046102023000224320ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{signed_pair_gen, unsigned_pair_gen_var_27}; #[test] fn test_overflowing_sub() { fn test(x: T, y: T, out: T, overflow: bool) { assert_eq!(x.overflowing_sub(y), (out, overflow)); let mut x = x; assert_eq!(x.overflowing_sub_assign(y), overflow); assert_eq!(x, out); } test::(456, 123, 333, false); test::(123, 200, 179, true); test::(123, -456, 579, false); test::(123, -45, -88, true); test::(-123, 45, 88, true); } fn overflowing_sub_properties_helper_unsigned() { unsigned_pair_gen_var_27::().test_properties(|(x, y)| { let mut diff = x; let overflow = diff.overflowing_sub_assign(y); assert_eq!((diff, overflow), x.overflowing_sub(y)); assert_eq!(x.wrapping_sub(y), diff); if !overflow { assert_eq!(diff, x - y); } }); } fn overflowing_sub_properties_helper_signed() { signed_pair_gen::().test_properties(|(x, y)| { let mut diff = x; let overflow = diff.overflowing_sub_assign(y); assert_eq!((diff, overflow), x.overflowing_sub(y)); assert_eq!(x.wrapping_sub(y), diff); if !overflow { assert_eq!(diff, x - y); } }); } #[test] fn overflowing_sub_properties() { apply_fn_to_unsigneds!(overflowing_sub_properties_helper_unsigned); apply_fn_to_signeds!(overflowing_sub_properties_helper_signed); } malachite-base-0.4.16/tests/num/arithmetic/overflowing_sub_mul.rs000064400000000000000000000071131046102023000233040ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ signed_pair_gen, signed_triple_gen, unsigned_pair_gen_var_27, unsigned_triple_gen_var_19, }; #[test] fn test_overflowing_sub_mul() { fn test(x: T, y: T, z: T, out: T, overflow: bool) { assert_eq!(x.overflowing_sub_mul(y, z), (out, overflow)); let mut x = x; assert_eq!(x.overflowing_sub_mul_assign(y, z), overflow); assert_eq!(x, out); } test::(100, 3, 7, 79, false); test::(60, 5, 10, 10, false); test::(1000000, 456, 789, 640216, false); test::(123, -456, 789, 359907, false); test::(-123, 456, 789, -359907, false); test::(127, 2, 100, -73, false); test::(-127, -2, 100, 73, false); test::(-128, 1, 0, -128, false); test::(2, 10, 5, 208, true); test::(-127, 2, 100, -71, true); test::(-127, 1, 100, 29, true); test::(127, -1, 100, -29, true); test::(127, -10, 100, 103, true); } fn overflowing_sub_mul_properties_helper_unsigned() { unsigned_triple_gen_var_19::().test_properties(|(x, y, z)| { let (result, overflow) = x.overflowing_sub_mul(y, z); let mut x_alt = x; assert_eq!(x_alt.overflowing_sub_mul_assign(y, z), overflow); assert_eq!(x_alt, result); assert_eq!(x.overflowing_sub_mul(z, y), (result, overflow)); assert_eq!(result.overflowing_add_mul(y, z), (x, overflow)); assert_eq!(x.wrapping_sub_mul(y, z), result); assert_eq!(x.checked_sub_mul(y, z).is_none(), overflow); }); unsigned_pair_gen_var_27::().test_properties(|(a, b)| { assert_eq!(a.overflowing_sub_mul(T::ZERO, b), (a, false)); assert_eq!(a.overflowing_sub_mul(T::ONE, b), a.overflowing_sub(b)); assert_eq!(a.overflowing_sub_mul(b, T::ZERO), (a, false)); assert_eq!(a.overflowing_sub_mul(b, T::ONE), a.overflowing_sub(b)); }); } fn overflowing_sub_mul_properties_helper_signed() { signed_triple_gen::().test_properties(|(x, y, z)| { let (result, overflow) = x.overflowing_sub_mul(y, z); let mut x_alt = x; assert_eq!(x_alt.overflowing_sub_mul_assign(y, z), overflow); assert_eq!(x_alt, result); assert_eq!(x.overflowing_sub_mul(z, y), (result, overflow)); assert_eq!(result.overflowing_add_mul(y, z), (x, overflow)); assert_eq!(x.wrapping_sub_mul(y, z), result); assert_eq!(x.checked_sub_mul(y, z).is_none(), overflow); }); signed_pair_gen::().test_properties(|(a, b)| { assert_eq!(a.overflowing_sub_mul(T::ZERO, b), (a, false)); assert_eq!(a.overflowing_sub_mul(T::ONE, b), a.overflowing_sub(b)); assert_eq!(a.overflowing_sub_mul(b, T::ZERO), (a, false)); assert_eq!(a.overflowing_sub_mul(b, T::ONE), a.overflowing_sub(b)); }); } #[test] fn overflowing_sub_mul_properties() { apply_fn_to_unsigneds!(overflowing_sub_mul_properties_helper_unsigned); apply_fn_to_signeds!(overflowing_sub_mul_properties_helper_signed); } malachite-base-0.4.16/tests/num/arithmetic/parity.rs000064400000000000000000000075511046102023000205330ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{signed_gen, unsigned_gen}; fn even_primitive_helper() { let test = |n: T, out| { assert_eq!(n.even(), out); }; test(T::ZERO, true); test(T::ONE, false); test(T::TWO, true); test(T::exact_from(123), false); test(T::exact_from(124), true); test(T::MAX, false); } fn even_signed_helper() { let test = |n: T, out| { assert_eq!(n.even(), out); }; test(T::NEGATIVE_ONE, false); test(T::exact_from(-123), false); test(T::exact_from(-124), true); test(T::MIN, true); } #[test] fn test_even() { apply_fn_to_primitive_ints!(even_primitive_helper); apply_fn_to_signeds!(even_signed_helper); } fn odd_primitive_helper() { let test = |n: T, out| { assert_eq!(n.odd(), out); }; test(T::ZERO, false); test(T::ONE, true); test(T::TWO, false); test(T::exact_from(123), true); test(T::exact_from(124), false); test(T::MAX, true); } fn odd_signed_helper() { let test = |n: T, out| { assert_eq!(n.odd(), out); }; test(T::NEGATIVE_ONE, true); test(T::exact_from(-123), true); test(T::exact_from(-124), false); test(T::MIN, false); } #[test] fn test_odd() { apply_fn_to_primitive_ints!(odd_primitive_helper); apply_fn_to_signeds!(odd_signed_helper); } fn even_properties_helper_unsigned() { unsigned_gen::().test_properties(|x| { let even = x.even(); assert_eq!(x.divisible_by(T::TWO), even); assert_eq!(!x.odd(), even); if x != T::MAX { assert_eq!((x + T::ONE).odd(), even); } if x != T::ZERO { assert_eq!((x - T::ONE).odd(), even); } }); } fn even_properties_helper_signed() { signed_gen::().test_properties(|x| { let even = x.even(); assert_eq!(x.divisible_by(T::TWO), even); assert_eq!(!x.odd(), even); if x != T::MAX { assert_eq!((x + T::ONE).odd(), even); } if x != T::MIN { assert_eq!((x - T::ONE).odd(), even); assert_eq!((-x).even(), even); } }); } #[test] fn even_properties() { apply_fn_to_unsigneds!(even_properties_helper_unsigned); apply_fn_to_signeds!(even_properties_helper_signed); } fn odd_properties_helper_unsigned() { unsigned_gen::().test_properties(|x| { let odd = x.odd(); assert_ne!(x.divisible_by(T::TWO), odd); assert_eq!(!x.even(), odd); if x != T::MAX { assert_eq!((x + T::ONE).even(), odd); } if x != T::ZERO { assert_eq!((x - T::ONE).even(), odd); } }); } fn odd_properties_helper_signed() { signed_gen::().test_properties(|x| { let odd = x.odd(); assert_ne!(x.divisible_by(T::TWO), odd); assert_eq!(!x.even(), odd); if x != T::MAX { assert_eq!((x + T::ONE).even(), odd); } if x != T::MIN { assert_eq!((x - T::ONE).even(), odd); assert_eq!((-x).odd(), odd); } }); } #[test] fn odd_properties() { apply_fn_to_unsigneds!(odd_properties_helper_unsigned); apply_fn_to_signeds!(odd_properties_helper_signed); } malachite-base-0.4.16/tests/num/arithmetic/pow.rs000064400000000000000000000071101046102023000200170ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::Parity; use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::generators::{ primitive_float_pair_gen, primitive_float_signed_pair_gen, signed_unsigned_pair_gen_var_15, unsigned_pair_gen_var_29, }; #[test] fn test_pow() { fn test_primitive_int(x: T, y: u64, out: T) { assert_eq!(x.pow(y), out); let mut x = x; x.pow_assign(y); assert_eq!(x, out); } test_primitive_int::(0, 0, 1); test_primitive_int::(123, 0, 1); test_primitive_int::(123, 1, 123); test_primitive_int::(0, 123, 0); test_primitive_int::(1, 123, 1); test_primitive_int::(-1, 123, -1); test_primitive_int::(-1, 124, 1); test_primitive_int::(3, 3, 27); test_primitive_int::(-10, 9, -1000000000); test_primitive_int::(-10, 8, 100000000); fn test_i64_primitive_float(x: T, y: i64, out: T) { assert_eq!(NiceFloat(x.pow(y)), NiceFloat(out)); let mut x = x; x.pow_assign(y); assert_eq!(NiceFloat(x), NiceFloat(out)); } test_i64_primitive_float::(2.0, 5, 32.0); fn test_primitive_float_primitive_float(x: T, y: T, out: T) { assert_eq!(NiceFloat(x.pow(y)), NiceFloat(out)); let mut x = x; x.pow_assign(y); assert_eq!(NiceFloat(x), NiceFloat(out)); } test_primitive_float_primitive_float::(2.0, 5.0, 32.0); } fn pow_assign_properties_helper_unsigned() { unsigned_pair_gen_var_29::().test_properties(|(x, y)| { let mut power = x; power.pow_assign(y); assert_eq!(power, x.pow(y)); if x > T::ONE { assert_eq!(power.checked_log_base(x), Some(y)); } if y != 0 { assert_eq!(power.checked_root(y), Some(x)); } }); } fn pow_assign_properties_helper_signed() { signed_unsigned_pair_gen_var_15::().test_properties(|(x, y)| { let mut power = x; power.pow_assign(y); assert_eq!(power, x.pow(y)); if y != 0 { assert_eq!( power.checked_root(y), Some(if y.even() { x.abs() } else { x }) ); } }); } fn pow_assign_properties_helper_primitive_float() { primitive_float_signed_pair_gen::().test_properties(|(x, y)| { let mut power = x; power.pow_assign(y); assert_eq!(NiceFloat(power), NiceFloat(x.pow(y))); }); primitive_float_pair_gen::().test_properties(|(x, y)| { let mut power = x; power.pow_assign(y); assert_eq!(NiceFloat(power), NiceFloat(x.pow(y))); }); } #[test] fn pow_assign_properties() { apply_fn_to_unsigneds!(pow_assign_properties_helper_unsigned); apply_fn_to_signeds!(pow_assign_properties_helper_signed); apply_fn_to_primitive_floats!(pow_assign_properties_helper_primitive_float); } malachite-base-0.4.16/tests/num/arithmetic/power_of_2.rs000064400000000000000000000070051046102023000212560ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ signed_gen_var_11, unsigned_gen_var_15, unsigned_gen_var_16, }; use std::panic::catch_unwind; fn power_of_2_primitive_int_helper() { let test = |pow, out| { assert_eq!(T::power_of_2(pow), out); }; test(0, T::ONE); test(1, T::TWO); test(2, T::exact_from(4)); test(3, T::exact_from(8)); } fn power_of_2_unsigned_helper() { let test = |pow, out| { assert_eq!(T::power_of_2(pow), out); }; test(T::WIDTH - 1, T::ONE << (T::WIDTH - 1)); } fn power_of_2_primitive_float_helper() { let test = |pow, out| { assert_eq!(T::power_of_2(pow), out); }; test(0, T::ONE); test(1, T::TWO); test(-1, T::from(0.5f32)); test(2, T::from(4.0f32)); test(-2, T::from(0.25f32)); test(T::MIN_EXPONENT, T::MIN_POSITIVE_SUBNORMAL); } #[test] fn test_power_of_2() { apply_fn_to_primitive_ints!(power_of_2_primitive_int_helper); apply_fn_to_unsigneds!(power_of_2_unsigned_helper); apply_fn_to_primitive_floats!(power_of_2_primitive_float_helper); } fn power_of_2_unsigned_fail_helper() { assert_panic!(T::power_of_2(T::WIDTH)); } fn power_of_2_signed_fail_helper() { assert_panic!(T::power_of_2(T::WIDTH - 1)); } fn power_of_2_primitive_float_fail_helper() { assert_panic!(T::power_of_2(T::MAX_EXPONENT + 1)); assert_panic!(T::power_of_2(T::MIN_EXPONENT - 1)); assert_panic!(T::power_of_2(10000)); assert_panic!(T::power_of_2(-10000)); } #[test] fn power_of_2_fail() { apply_fn_to_unsigneds!(power_of_2_unsigned_fail_helper); apply_fn_to_signeds!(power_of_2_signed_fail_helper); apply_fn_to_primitive_floats!(power_of_2_primitive_float_fail_helper); } fn power_of_2_properties_helper_unsigned() { unsigned_gen_var_15::().test_properties(|pow| { let mut n = T::power_of_2(pow); assert_eq!(n.checked_log_base_2(), Some(pow)); assert!(n.is_power_of_2()); n.clear_bit(pow); assert_eq!(n, T::ZERO); }); } fn power_of_2_properties_helper_signed + PrimitiveUnsigned, S: PrimitiveSigned>() { unsigned_gen_var_16::().test_properties(|pow| { let mut n = S::power_of_2(pow); assert_eq!(U::exact_from(n), U::power_of_2(pow)); n.clear_bit(pow); assert_eq!(n, S::ZERO); }); } fn power_of_2_properties_helper_primitive_float() { signed_gen_var_11::().test_properties(|pow| { let n = T::power_of_2(pow); assert!(n > T::ZERO); assert!(n.is_power_of_2()); }); } #[test] fn power_of_2_properties() { apply_fn_to_unsigneds!(power_of_2_properties_helper_unsigned); apply_fn_to_unsigned_signed_pairs!(power_of_2_properties_helper_signed); apply_fn_to_primitive_floats!(power_of_2_properties_helper_primitive_float); } malachite-base-0.4.16/tests/num/arithmetic/primorial.rs000064400000000000000000000117501046102023000212150ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::ExactFrom; use malachite_base::num::factorization::traits::Primes; use malachite_base::test_util::generators::{ unsigned_gen, unsigned_gen_var_27, unsigned_gen_var_28, }; use malachite_base::test_util::num::arithmetic::primorial::{ checked_primorial_naive, checked_product_of_first_n_primes_naive, }; use std::panic::catch_unwind; #[test] fn test_primorial() { fn test(n: u64, out: T) { assert_eq!(T::primorial(n), out); } test::(0, 1); test::(1, 1); test::(2, 2); test::(3, 6); test::(4, 6); test::(5, 30); test::(20, 9699690); } fn primorial_fail_helper() { assert_panic!(T::primorial(200)); } #[test] fn primorial_fail() { apply_fn_to_unsigneds!(primorial_fail_helper); } #[test] fn test_checked_primorial() { fn test(n: u64, out: Option) { assert_eq!(T::checked_primorial(n), out); assert_eq!(checked_primorial_naive(n), out); } test::(0, Some(1)); test::(1, Some(1)); test::(2, Some(2)); test::(3, Some(6)); test::(4, Some(6)); test::(5, Some(30)); test::(20, Some(9699690)); test::(11, None); test::(200, None); } #[test] fn test_product_of_first_n_primes() { fn test(n: u64, out: T) { assert_eq!(T::product_of_first_n_primes(n), out); } test::(0, 1); test::(1, 2); test::(2, 6); test::(3, 30); test::(4, 210); test::(9, 223092870); } fn product_of_first_n_primes_fail_helper() { assert_panic!(T::product_of_first_n_primes(100)); } #[test] fn product_of_first_n_primes_fail() { apply_fn_to_unsigneds!(product_of_first_n_primes_fail_helper); } #[test] fn test_checked_product_of_first_n_primes() { fn test(n: u64, out: Option) { assert_eq!(T::checked_product_of_first_n_primes(n), out); assert_eq!(checked_product_of_first_n_primes_naive(n), out); } test::(0, Some(1)); test::(1, Some(2)); test::(2, Some(6)); test::(3, Some(30)); test::(4, Some(210)); test::(9, Some(223092870)); test::(5, None); test::(100, None); } fn primorial_properties_helper() { unsigned_gen_var_27::().test_properties(|n| { let f = T::primorial(n); assert_eq!(T::checked_primorial(n), Some(f)); assert_ne!(f, T::ZERO); // TODO compare with primorial(n - 1) depending on whether n is prime }); } #[test] fn primorial_properties() { apply_fn_to_unsigneds!(primorial_properties_helper); } fn checked_primorial_properties_helper() { unsigned_gen().test_properties(|n| { let of = T::checked_primorial(n); assert_eq!(checked_primorial_naive(n), of); assert_ne!(of, Some(T::ZERO)); if let Some(f) = of { assert_eq!(T::primorial(n), f); } if n != u64::MAX && of.is_none() { assert!(T::checked_primorial(n + 1).is_none()); } }); } #[test] fn checked_primorial_properties() { apply_fn_to_unsigneds!(checked_primorial_properties_helper); } fn product_of_first_n_primes_properties_helper() { unsigned_gen_var_28::().test_properties(|n| { let f = T::product_of_first_n_primes(n); assert_eq!(T::checked_product_of_first_n_primes(n), Some(f)); assert_ne!(f, T::ZERO); if n != 0 { let p = u64::primes().nth(usize::exact_from(n) - 1).unwrap(); assert_eq!(T::primorial(p), f); assert_eq!(f / T::product_of_first_n_primes(n - 1), T::exact_from(p)); } }); } #[test] fn product_of_first_n_primes_properties() { apply_fn_to_unsigneds!(product_of_first_n_primes_properties_helper); } fn checked_product_of_first_n_primes_properties_helper() { unsigned_gen().test_properties(|n| { let of = T::checked_product_of_first_n_primes(n); assert_eq!(checked_product_of_first_n_primes_naive(n), of); assert_ne!(of, Some(T::ZERO)); if let Some(f) = of { assert_eq!(T::product_of_first_n_primes(n), f); } if n != u64::MAX && of.is_none() { assert!(T::checked_product_of_first_n_primes(n + 1).is_none()); } }); } #[test] fn checked_product_of_first_n_primes_properties() { apply_fn_to_unsigneds!(checked_product_of_first_n_primes_properties_helper); } malachite-base-0.4.16/tests/num/arithmetic/reciprocal.rs000064400000000000000000000047241046102023000213450ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::traits::NegativeInfinity; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::generators::primitive_float_gen; #[test] fn test_reciprocal() { fn test(x: T, out: T) { assert_eq!(NiceFloat(x.reciprocal()), NiceFloat(out)); let mut x = x; x.reciprocal_assign(); assert_eq!(NiceFloat(x), NiceFloat(out)); } test::(f32::NAN, f32::NAN); test::(f32::INFINITY, 0.0); test::(f32::NEGATIVE_INFINITY, -0.0); test::(0.0, f32::INFINITY); test::(-0.0, f32::NEGATIVE_INFINITY); test::(1.0, 1.0); test::(-1.0, -1.0); test::(0.5, 2.0); test::(-0.5, -2.0); test::(core::f32::consts::SQRT_2, 0.70710677); test::(-core::f32::consts::SQRT_2, -0.70710677); test::(core::f32::consts::PI, std::f32::consts::FRAC_1_PI); test::(-core::f32::consts::PI, -std::f32::consts::FRAC_1_PI); test::(f64::NAN, f64::NAN); test::(f64::INFINITY, 0.0); test::(f64::NEGATIVE_INFINITY, -0.0); test::(0.0, f64::INFINITY); test::(-0.0, f64::NEGATIVE_INFINITY); test::(1.0, 1.0); test::(-1.0, -1.0); test::(0.5, 2.0); test::(-0.5, -2.0); test::(core::f64::consts::SQRT_2, 0.7071067811865475); test::(-core::f64::consts::SQRT_2, -0.7071067811865475); test::(core::f64::consts::PI, std::f64::consts::FRAC_1_PI); test::(-core::f64::consts::PI, -std::f64::consts::FRAC_1_PI); } fn reciprocal_properties_helper() { primitive_float_gen::().test_properties(|x| { let mut reciprocal = x; reciprocal.reciprocal_assign(); assert_eq!(NiceFloat(reciprocal), NiceFloat(x.reciprocal())); assert_eq!(NiceFloat(reciprocal), NiceFloat(x.pow(-1))); assert_eq!(NiceFloat((-x).reciprocal()), NiceFloat(-reciprocal)); }); } #[test] fn reciprocal_properties() { apply_fn_to_primitive_floats!(reciprocal_properties_helper); } malachite-base-0.4.16/tests/num/arithmetic/root.rs000064400000000000000000000571601046102023000202070ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::root::{ cbrt_chebyshev_approx_u32, cbrt_chebyshev_approx_u64, fast_ceiling_root_u32, fast_ceiling_root_u64, fast_checked_root_u32, fast_checked_root_u64, fast_floor_cbrt_u32, fast_floor_cbrt_u64, fast_floor_root_u32, fast_floor_root_u64, fast_root_rem_u32, fast_root_rem_u64, floor_root_approx_and_refine, }; use malachite_base::num::arithmetic::root::{ ceiling_root_binary, checked_root_binary, floor_root_binary, root_rem_binary, }; use malachite_base::num::arithmetic::traits::{ CeilingRoot, CheckedRoot, FloorRoot, Parity, RootRem, }; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ signed_gen, signed_gen_var_2, signed_unsigned_pair_gen_var_18, unsigned_gen, unsigned_gen_var_1, unsigned_pair_gen_var_32, }; use std::ops::Neg; use std::panic::catch_unwind; #[test] fn test_floor_root() { fn test_u(n: T, exp: u64, out: T) { assert_eq!(n.floor_root(exp), out); assert_eq!(floor_root_binary(n, exp), out); let mut n = n; n.floor_root_assign(exp); assert_eq!(n, out); } test_u::(0, 1, 0); test_u::(1, 1, 1); test_u::(2, 1, 2); test_u::(100, 1, 100); test_u::(0, 2, 0); test_u::(1, 2, 1); test_u::(2, 2, 1); test_u::(3, 2, 1); test_u::(4, 2, 2); test_u::(5, 2, 2); test_u::(0, 3, 0); test_u::(1, 3, 1); test_u::(2, 3, 1); test_u::(7, 3, 1); test_u::(8, 3, 2); test_u::(9, 3, 2); test_u::(10, 2, 3); test_u::(100, 2, 10); test_u::(100, 3, 4); test_u::(1000000000, 2, 31622); test_u::(1000000000, 3, 1000); test_u::(1000000000, 4, 177); test_u::(1000000000, 5, 63); test_u::(1000000000, 6, 31); test_u::(1000000000, 7, 19); test_u::(1000000000, 8, 13); test_u::(1000000000, 9, 10); test_u::(1000000000, 10, 7); fn test_i(n: T, exp: u64, out: T) { assert_eq!(n.floor_root(exp), out); let mut n = n; n.floor_root_assign(exp); assert_eq!(n, out); } test_i::(0, 1, 0); test_i::(1, 1, 1); test_i::(2, 1, 2); test_i::(100, 1, 100); test_i::(0, 2, 0); test_i::(0, 2, 0); test_i::(1, 2, 1); test_i::(2, 2, 1); test_i::(3, 2, 1); test_i::(4, 2, 2); test_i::(5, 2, 2); test_i::(0, 3, 0); test_i::(1, 3, 1); test_i::(2, 3, 1); test_i::(7, 3, 1); test_i::(8, 3, 2); test_i::(9, 3, 2); test_i::(10, 2, 3); test_i::(100, 2, 10); test_i::(100, 3, 4); test_i::(1000000000, 2, 31622); test_i::(1000000000, 3, 1000); test_i::(1000000000, 4, 177); test_i::(1000000000, 5, 63); test_i::(1000000000, 6, 31); test_i::(1000000000, 7, 19); test_i::(1000000000, 8, 13); test_i::(1000000000, 9, 10); test_i::(1000000000, 10, 7); test_i::(-1, 1, -1); test_i::(-2, 1, -2); test_i::(-100, 1, -100); test_i::(-1, 3, -1); test_i::(-2, 3, -2); test_i::(-7, 3, -2); test_i::(-8, 3, -2); test_i::(-9, 3, -3); test_i::(-100, 3, -5); test_i::(-1000000000, 3, -1000); test_i::(-1000000000, 5, -64); test_i::(-1000000000, 7, -20); test_i::(-1000000000, 9, -10); } fn floor_root_fail_helper_unsigned() { assert_panic!(T::ONE.floor_root(0)); } fn floor_root_fail_helper_signed() { assert_panic!(T::ONE.floor_root(0)); assert_panic!(T::NEGATIVE_ONE.floor_root(0)); assert_panic!(T::NEGATIVE_ONE.floor_root(2)); assert_panic!(T::NEGATIVE_ONE.floor_root(4)); assert_panic!(T::NEGATIVE_ONE.floor_root(100)); } #[test] pub fn floor_root_fail() { apply_fn_to_unsigneds!(floor_root_fail_helper_unsigned); apply_fn_to_signeds!(floor_root_fail_helper_signed); } #[test] fn test_ceiling_root() { fn test_u(n: T, exp: u64, out: T) { assert_eq!(n.ceiling_root(exp), out); assert_eq!(ceiling_root_binary(n, exp), out); let mut n = n; n.ceiling_root_assign(exp); assert_eq!(n, out); } test_u::(0, 1, 0); test_u::(1, 1, 1); test_u::(2, 1, 2); test_u::(100, 1, 100); test_u::(0, 2, 0); test_u::(1, 2, 1); test_u::(2, 2, 2); test_u::(3, 2, 2); test_u::(4, 2, 2); test_u::(5, 2, 3); test_u::(0, 3, 0); test_u::(1, 3, 1); test_u::(2, 3, 2); test_u::(7, 3, 2); test_u::(8, 3, 2); test_u::(9, 3, 3); test_u::(10, 2, 4); test_u::(100, 2, 10); test_u::(100, 3, 5); test_u::(1000000000, 2, 31623); test_u::(1000000000, 3, 1000); test_u::(1000000000, 4, 178); test_u::(1000000000, 5, 64); test_u::(1000000000, 6, 32); test_u::(1000000000, 7, 20); test_u::(1000000000, 8, 14); test_u::(1000000000, 9, 10); test_u::(1000000000, 10, 8); fn test_i(n: T, exp: u64, out: T) { assert_eq!(n.ceiling_root(exp), out); let mut n = n; n.ceiling_root_assign(exp); assert_eq!(n, out); } test_i::(0, 1, 0); test_i::(1, 1, 1); test_i::(2, 1, 2); test_i::(100, 1, 100); test_i::(0, 2, 0); test_i::(1, 2, 1); test_i::(2, 2, 2); test_i::(3, 2, 2); test_i::(4, 2, 2); test_i::(5, 2, 3); test_i::(0, 3, 0); test_i::(1, 3, 1); test_i::(2, 3, 2); test_i::(7, 3, 2); test_i::(8, 3, 2); test_i::(9, 3, 3); test_i::(10, 2, 4); test_i::(100, 2, 10); test_i::(100, 3, 5); test_i::(1000000000, 2, 31623); test_i::(1000000000, 3, 1000); test_i::(1000000000, 4, 178); test_i::(1000000000, 5, 64); test_i::(1000000000, 6, 32); test_i::(1000000000, 7, 20); test_i::(1000000000, 8, 14); test_i::(1000000000, 9, 10); test_i::(1000000000, 10, 8); test_i::(-1, 1, -1); test_i::(-2, 1, -2); test_i::(-100, 1, -100); test_i::(-1, 3, -1); test_i::(-2, 3, -1); test_i::(-7, 3, -1); test_i::(-8, 3, -2); test_i::(-9, 3, -2); test_i::(-100, 3, -4); test_i::(-1000000000, 3, -1000); test_i::(-1000000000, 5, -63); test_i::(-1000000000, 7, -19); test_i::(-1000000000, 9, -10); } fn ceiling_root_fail_helper_unsigned() { assert_panic!(T::ONE.ceiling_root(0)); } fn ceiling_root_fail_helper_signed() { assert_panic!(T::ONE.ceiling_root(0)); assert_panic!(T::NEGATIVE_ONE.ceiling_root(0)); assert_panic!(T::NEGATIVE_ONE.ceiling_root(2)); assert_panic!(T::NEGATIVE_ONE.ceiling_root(4)); assert_panic!(T::NEGATIVE_ONE.ceiling_root(100)); } #[test] pub fn ceiling_root_fail() { apply_fn_to_unsigneds!(ceiling_root_fail_helper_unsigned); apply_fn_to_signeds!(ceiling_root_fail_helper_signed); } #[test] fn test_checked_root() { fn test_u(n: T, exp: u64, out: Option) { assert_eq!(n.checked_root(exp), out); assert_eq!(checked_root_binary(n, exp), out); } test_u::(0, 1, Some(0)); test_u::(1, 1, Some(1)); test_u::(2, 1, Some(2)); test_u::(100, 1, Some(100)); test_u::(0, 2, Some(0)); test_u::(1, 2, Some(1)); test_u::(2, 2, None); test_u::(3, 2, None); test_u::(4, 2, Some(2)); test_u::(5, 2, None); test_u::(0, 3, Some(0)); test_u::(1, 3, Some(1)); test_u::(2, 3, None); test_u::(7, 3, None); test_u::(8, 3, Some(2)); test_u::(9, 3, None); test_u::(10, 2, None); test_u::(100, 2, Some(10)); test_u::(100, 3, None); test_u::(1000000000, 2, None); test_u::(1000000000, 3, Some(1000)); test_u::(1000000000, 4, None); test_u::(1000000000, 5, None); test_u::(1000000000, 6, None); test_u::(1000000000, 7, None); test_u::(1000000000, 8, None); test_u::(1000000000, 9, Some(10)); test_u::(1000000000, 10, None); fn test_i(n: T, exp: u64, out: Option) { assert_eq!(n.checked_root(exp), out); } test_i::(0, 1, Some(0)); test_i::(1, 1, Some(1)); test_i::(2, 1, Some(2)); test_i::(100, 1, Some(100)); test_i::(0, 2, Some(0)); test_i::(1, 2, Some(1)); test_i::(2, 2, None); test_i::(3, 2, None); test_i::(4, 2, Some(2)); test_i::(5, 2, None); test_i::(0, 3, Some(0)); test_i::(1, 3, Some(1)); test_i::(2, 3, None); test_i::(7, 3, None); test_i::(8, 3, Some(2)); test_i::(9, 3, None); test_i::(10, 2, None); test_i::(100, 2, Some(10)); test_i::(100, 3, None); test_i::(1000000000, 2, None); test_i::(1000000000, 3, Some(1000)); test_i::(1000000000, 4, None); test_i::(1000000000, 5, None); test_i::(1000000000, 6, None); test_i::(1000000000, 7, None); test_i::(1000000000, 8, None); test_i::(1000000000, 9, Some(10)); test_i::(1000000000, 10, None); test_i::(-1, 1, Some(-1)); test_i::(-2, 1, Some(-2)); test_i::(-100, 1, Some(-100)); test_i::(-1, 3, Some(-1)); test_i::(-2, 3, None); test_i::(-7, 3, None); test_i::(-8, 3, Some(-2)); test_i::(-9, 3, None); test_i::(-100, 3, None); test_i::(-1000000000, 3, Some(-1000)); test_i::(-1000000000, 5, None); test_i::(-1000000000, 7, None); test_i::(-1000000000, 9, Some(-10)); } fn checked_root_fail_helper_unsigned() { assert_panic!(T::ONE.checked_root(0)); } fn checked_root_fail_helper_signed() { assert_panic!(T::ONE.checked_root(0)); assert_panic!(T::NEGATIVE_ONE.checked_root(0)); assert_panic!(T::NEGATIVE_ONE.checked_root(2)); assert_panic!(T::NEGATIVE_ONE.checked_root(4)); assert_panic!(T::NEGATIVE_ONE.checked_root(100)); } #[test] pub fn checked_root_fail() { apply_fn_to_unsigneds!(checked_root_fail_helper_unsigned); apply_fn_to_signeds!(checked_root_fail_helper_signed); } #[test] fn test_root_rem() { fn test(n: T, exp: u64, out_root: T, out_rem: T) { assert_eq!(n.root_rem(exp), (out_root, out_rem)); assert_eq!(root_rem_binary(n, exp), (out_root, out_rem)); let mut n = n; assert_eq!(n.root_assign_rem(exp), out_rem); assert_eq!(n, out_root); } test::(0, 1, 0, 0); test::(1, 1, 1, 0); test::(2, 1, 2, 0); test::(100, 1, 100, 0); test::(0, 2, 0, 0); test::(1, 2, 1, 0); test::(2, 2, 1, 1); test::(3, 2, 1, 2); test::(4, 2, 2, 0); test::(5, 2, 2, 1); test::(0, 3, 0, 0); test::(1, 3, 1, 0); test::(2, 3, 1, 1); test::(7, 3, 1, 6); test::(8, 3, 2, 0); test::(9, 3, 2, 1); test::(10, 2, 3, 1); test::(100, 2, 10, 0); test::(100, 3, 4, 36); test::(1000000000, 2, 31622, 49116); test::(1000000000, 3, 1000, 0); test::(1000000000, 4, 177, 18493759); test::(1000000000, 5, 63, 7563457); test::(1000000000, 6, 31, 112496319); test::(1000000000, 7, 19, 106128261); test::(1000000000, 8, 13, 184269279); test::(1000000000, 9, 10, 0); test::(1000000000, 10, 7, 717524751); } fn root_rem_fail_helper() { assert_panic!(T::ONE.root_rem(0)); } #[test] pub fn root_rem_fail() { apply_fn_to_unsigneds!(root_rem_fail_helper); } fn floor_root_properties_helper_unsigned() { unsigned_pair_gen_var_32::().test_properties(|(n, exp)| { let root = n.floor_root(exp); let mut n_alt = n; n_alt.floor_root_assign(exp); assert_eq!(n_alt, root); assert_eq!(floor_root_binary(n, exp), root); let pow = root.pow(exp); let ceiling_root = n.ceiling_root(exp); if pow == n { assert_eq!(ceiling_root, root); } else { assert_eq!(ceiling_root, root + T::ONE); } assert!(pow <= n); if exp != 1 { if let Some(next_pow) = (root + T::ONE).checked_pow(exp) { assert!(next_pow > n); } } }); unsigned_gen::().test_properties(|n| { assert_eq!(n.floor_root(2), n.floor_sqrt()); assert_eq!(n.floor_root(1), n); let cbrt = n.floor_root(3); let mut n_alt = n; n_alt.floor_root_assign(3); assert_eq!(n_alt, cbrt); assert_eq!(floor_root_binary(n, 3), cbrt); let cube = cbrt.pow(3); let ceiling_cbrt = n.ceiling_root(3); if cube == n { assert_eq!(ceiling_cbrt, cbrt); } else { assert_eq!(ceiling_cbrt, cbrt + T::ONE); } assert!(cube <= n); if let Some(next_cube) = (cbrt + T::ONE).checked_pow(3) { assert!(next_cube > n); } }); } fn floor_root_properties_helper_signed() { signed_unsigned_pair_gen_var_18::().test_properties(|(n, exp)| { let root = n.floor_root(exp); let mut n_alt = n; n_alt.floor_root_assign(exp); assert_eq!(n_alt, root); if let Some(pow) = root.checked_pow(exp) { let ceiling_root = n.ceiling_root(exp); if pow == n { assert_eq!(ceiling_root, root); } else { assert_eq!(ceiling_root, root + T::ONE); } assert!(pow <= n); } if exp.odd() && n != T::MIN { assert_eq!(-(-n).ceiling_root(exp), root); } }); signed_gen::().test_properties(|n| { assert_eq!(n.floor_root(1), n); let cbrt = n.floor_root(3); let mut n_alt = n; n_alt.floor_root_assign(3); assert_eq!(n_alt, cbrt); if let Some(cube) = cbrt.checked_pow(3) { let ceiling_cbrt = n.ceiling_root(3); if cube == n { assert_eq!(ceiling_cbrt, cbrt); } else { assert_eq!(ceiling_cbrt, cbrt + T::ONE); } assert!(cube <= n); } if n != T::MIN { assert_ne!((-n).ceiling_root(3), T::MIN); assert_eq!(-(-n).ceiling_root(3), cbrt); } }); signed_gen_var_2::().test_properties(|n| { assert_eq!(n.floor_root(2), n.floor_sqrt()); }); } macro_rules! floor_root_approx_and_refine_helper { ($t:ty) => { #[allow(clippy::cast_lossless)] unsigned_pair_gen_var_32::<$t, u64>().test_properties(|(n, exp)| { assert_eq!( floor_root_approx_and_refine(|x| x as f64, |f| f as $t, n, exp), n.floor_root(exp), ); }); #[allow(clippy::cast_lossless)] unsigned_gen::<$t>().test_properties(|n| { assert_eq!( floor_root_approx_and_refine(|x| x as f64, |f| f as $t, n, 3), n.floor_root(3), ); }); }; } #[test] fn floor_root_properties() { apply_fn_to_unsigneds!(floor_root_properties_helper_unsigned); apply_fn_to_signeds!(floor_root_properties_helper_signed); unsigned_gen_var_1::().test_properties(|n| { assert_eq!(cbrt_chebyshev_approx_u32(n), n.floor_root(3)); assert_eq!(fast_floor_cbrt_u32(n), n.floor_root(3)); }); unsigned_gen_var_1::().test_properties(|n| { assert_eq!(cbrt_chebyshev_approx_u64(n), n.floor_root(3)); assert_eq!(fast_floor_cbrt_u64(n), n.floor_root(3)); }); unsigned_pair_gen_var_32::().test_properties(|(n, exp)| { assert_eq!(fast_floor_root_u32(n, exp), n.floor_root(exp)); }); unsigned_pair_gen_var_32::().test_properties(|(n, exp)| { assert_eq!(fast_floor_root_u64(n, exp), n.floor_root(exp)); }); apply_to_unsigneds!(floor_root_approx_and_refine_helper); } fn ceiling_root_properties_helper_unsigned() { unsigned_pair_gen_var_32::().test_properties(|(n, exp)| { let root = n.ceiling_root(exp); let mut n_alt = n; n_alt.ceiling_root_assign(exp); assert_eq!(n_alt, root); assert_eq!(ceiling_root_binary(n, exp), root); if let Some(pow) = root.checked_pow(exp) { let floor_root = n.floor_root(exp); if pow == n { assert_eq!(floor_root, root); } else { assert_eq!(floor_root, root - T::ONE); } assert!(pow >= n); } if exp != 1 && n != T::ZERO { assert!((root - T::ONE).pow(exp) < n); } }); unsigned_gen::().test_properties(|n| { assert_eq!(n.ceiling_root(2), n.ceiling_sqrt()); assert_eq!(n.ceiling_root(1), n); let cbrt = n.ceiling_root(3); let mut n_alt = n; n_alt.ceiling_root_assign(3); assert_eq!(n_alt, cbrt); assert_eq!(ceiling_root_binary(n, 3), cbrt); if let Some(cube) = cbrt.checked_pow(3) { let floor_cbrt = n.floor_root(3); if cube == n { assert_eq!(floor_cbrt, cbrt); } else { assert_eq!(floor_cbrt, cbrt - T::ONE); } assert!(cube >= n); } if n != T::ZERO { assert!((cbrt - T::ONE).pow(3) < n); } }); } fn ceiling_root_properties_helper_signed() { signed_unsigned_pair_gen_var_18::().test_properties(|(n, exp)| { let root = n.ceiling_root(exp); let mut n_alt = n; n_alt.ceiling_root_assign(exp); assert_eq!(n_alt, root); if let Some(pow) = root.checked_pow(exp) { let floor_root = n.floor_root(exp); if pow == n { assert_eq!(floor_root, root); } else { assert_eq!(floor_root, root - T::ONE); } assert!(pow >= n); } if exp.odd() && n != T::MIN { assert_eq!(-(-n).floor_root(exp), root); } }); signed_gen::().test_properties(|n| { assert_eq!(n.ceiling_root(1), n); let cbrt = n.ceiling_root(3); let mut n_alt = n; n_alt.ceiling_root_assign(3); assert_eq!(n_alt, cbrt); if let Some(cube) = cbrt.checked_pow(3) { let floor_cbrt = n.floor_root(3); if cube == n { assert_eq!(floor_cbrt, cbrt); } else { assert_eq!(floor_cbrt, cbrt - T::ONE); } assert!(cube >= n); } if n != T::MIN { assert_eq!(-(-n).floor_root(3), cbrt); } }); signed_gen_var_2::().test_properties(|n| { assert_eq!(n.ceiling_root(2), n.ceiling_sqrt()); }); } #[test] fn ceiling_root_properties() { apply_fn_to_unsigneds!(ceiling_root_properties_helper_unsigned); apply_fn_to_signeds!(ceiling_root_properties_helper_signed); unsigned_pair_gen_var_32::().test_properties(|(n, exp)| { assert_eq!(fast_ceiling_root_u32(n, exp), n.ceiling_root(exp)); }); unsigned_pair_gen_var_32::().test_properties(|(n, exp)| { assert_eq!(fast_ceiling_root_u64(n, exp), n.ceiling_root(exp)); }); } fn checked_root_properties_helper_unsigned() { unsigned_pair_gen_var_32::().test_properties(|(n, exp)| { let root = n.checked_root(exp); assert_eq!(checked_root_binary(n, exp), root); if let Some(root) = root { assert_eq!(root.pow(exp), n); assert_eq!(n.floor_root(exp), root); assert_eq!(n.ceiling_root(exp), root); } }); unsigned_gen::().test_properties(|n| { assert_eq!(n.checked_root(2), n.checked_sqrt()); assert_eq!(n.checked_root(1), Some(n)); let cbrt = n.checked_root(3); assert_eq!(checked_root_binary(n, 3), cbrt); if let Some(cbrt) = cbrt { assert_eq!(cbrt.pow(3), n); assert_eq!(n.floor_root(3), cbrt); assert_eq!(n.ceiling_root(3), cbrt); } }); } fn checked_root_properties_helper_signed() { signed_unsigned_pair_gen_var_18::().test_properties(|(n, exp)| { let root = n.checked_root(exp); if let Some(root) = root { assert_eq!(root.pow(exp), n); assert_eq!(n.floor_root(exp), root); assert_eq!(n.ceiling_root(exp), root); } if exp.odd() && n != T::MIN { assert_eq!((-n).checked_root(exp).map(Neg::neg), root); } }); signed_gen::().test_properties(|n| { assert_eq!(n.checked_root(1), Some(n)); let cbrt = n.checked_root(3); if let Some(cbrt) = cbrt { assert_eq!(cbrt.pow(3), n); assert_eq!(n.floor_root(3), cbrt); assert_eq!(n.ceiling_root(3), cbrt); } if n != T::MIN { assert_eq!((-n).checked_root(3).map(Neg::neg), cbrt); } }); signed_gen_var_2::().test_properties(|n| { assert_eq!(n.checked_root(2), n.checked_sqrt()); }); } #[test] fn checked_root_properties() { apply_fn_to_unsigneds!(checked_root_properties_helper_unsigned); apply_fn_to_signeds!(checked_root_properties_helper_signed); unsigned_pair_gen_var_32::().test_properties(|(n, exp)| { assert_eq!(fast_checked_root_u32(n, exp), n.checked_root(exp)); }); unsigned_pair_gen_var_32::().test_properties(|(n, exp)| { assert_eq!(fast_checked_root_u64(n, exp), n.checked_root(exp)); }); } fn root_rem_properties_helper() { unsigned_pair_gen_var_32::().test_properties(|(n, exp)| { let (root, rem) = n.root_rem(exp); let mut n_alt = n; assert_eq!(n_alt.root_assign_rem(exp), rem); assert_eq!(n_alt, root); assert_eq!(root_rem_binary(n, exp), (root, rem)); assert_eq!(n.floor_root(exp), root); assert_eq!(root.pow(exp) + rem, n); }); unsigned_gen::().test_properties(|n| { assert_eq!(n.root_rem(2), n.sqrt_rem()); assert_eq!(n.root_rem(1), (n, T::ZERO)); let (cbrt, rem) = n.root_rem(3); let mut n_alt = n; assert_eq!(n_alt.root_assign_rem(3), rem); assert_eq!(n_alt, cbrt); assert_eq!(root_rem_binary(n, 3), (cbrt, rem)); assert_eq!(n.floor_root(3), cbrt); assert_eq!(cbrt.pow(3) + rem, n); }); } #[test] fn root_rem_properties() { apply_fn_to_unsigneds!(root_rem_properties_helper); unsigned_pair_gen_var_32::().test_properties(|(n, exp)| { assert_eq!(fast_root_rem_u32(n, exp), n.root_rem(exp)); }); unsigned_pair_gen_var_32::().test_properties(|(n, exp)| { assert_eq!(fast_root_rem_u64(n, exp), n.root_rem(exp)); }); } malachite-base-0.4.16/tests/num/arithmetic/rotate.rs000064400000000000000000000134401046102023000205130ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::NegMod; use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ signed_gen, signed_unsigned_pair_gen, unsigned_gen, unsigned_pair_gen, }; #[test] fn test_rotate_left() { fn test(x: T, n: u64, out: T) { assert_eq!(x.rotate_left(n), out); let mut x = x; x.rotate_left_assign(n); assert_eq!(x, out); } test::(0, 0, 0); test::(100, 0, 100); test::(0xabcd, 0, 0xabcd); test::(0xabcd, 4, 0xbcda); test::(0xabcd, 8, 0xcdab); test::(0xabcd, 12, 0xdabc); test::(0xabcd, 16, 0xabcd); test::(0xabcd, 160, 0xabcd); test::(10, 0, 10); test::(10, 1, 20); test::(10, 2, 40); test::(10, 3, 80); test::(10, 4, -96); test::(10, 5, 65); test::(10, 6, -126); test::(10, 7, 5); test::(10, 8, 10); } #[test] fn test_rotate_right() { fn test(x: T, n: u64, out: T) { assert_eq!(x.rotate_right(n), out); let mut x = x; x.rotate_right_assign(n); assert_eq!(x, out); } test::(0, 0, 0); test::(100, 0, 100); test::(0xabcd, 0, 0xabcd); test::(0xabcd, 4, 0xdabc); test::(0xabcd, 8, 0xcdab); test::(0xabcd, 12, 0xbcda); test::(0xabcd, 16, 0xabcd); test::(0xabcd, 160, 0xabcd); test::(10, 0, 10); test::(10, 1, 5); test::(10, 2, -126); test::(10, 3, 65); test::(10, 4, -96); test::(10, 5, 80); test::(10, 6, 40); test::(10, 7, 20); test::(10, 8, 10); } fn rotate_left_properties_unsigned_helper() { unsigned_pair_gen::().test_properties(|(x, n)| { let rotated = x.rotate_left(n); let mut mut_x = x; mut_x.rotate_left_assign(n); assert_eq!(mut_x, rotated); if let Some(m) = n.checked_add(T::WIDTH) { assert_eq!(x.rotate_left(m), rotated); } assert_eq!(x.rotate_left(n & T::WIDTH_MASK), rotated); assert_eq!(x.rotate_right(n.neg_mod(T::WIDTH)), rotated); }); unsigned_gen::().test_properties(|x| { assert_eq!(x.rotate_left(0), x); assert_eq!(x.rotate_left(T::WIDTH), x); }); unsigned_gen::().test_properties(|n| { assert_eq!(T::ZERO.rotate_left(n), T::ZERO); assert_eq!(T::MAX.rotate_left(n), T::MAX); }); } fn rotate_left_properties_signed_helper() { signed_unsigned_pair_gen::().test_properties(|(x, n)| { let rotated = x.rotate_left(n); let mut mut_x = x; mut_x.rotate_left_assign(n); assert_eq!(mut_x, rotated); if let Some(m) = n.checked_add(T::WIDTH) { assert_eq!(x.rotate_left(m), rotated); } assert_eq!(x.rotate_left(n & T::WIDTH_MASK), rotated); assert_eq!(x.rotate_right(n.neg_mod(T::WIDTH)), rotated); }); signed_gen::().test_properties(|x| { assert_eq!(x.rotate_left(0), x); assert_eq!(x.rotate_left(T::WIDTH), x); }); unsigned_gen::().test_properties(|n| { assert_eq!(T::ZERO.rotate_left(n), T::ZERO); assert_eq!(T::NEGATIVE_ONE.rotate_left(n), T::NEGATIVE_ONE); }); } #[test] fn rotate_left_properties() { apply_fn_to_unsigneds!(rotate_left_properties_unsigned_helper); apply_fn_to_signeds!(rotate_left_properties_signed_helper); } fn rotate_right_properties_unsigned_helper() { unsigned_pair_gen::().test_properties(|(x, n)| { let rotated = x.rotate_right(n); let mut mut_x = x; mut_x.rotate_right_assign(n); assert_eq!(mut_x, rotated); if let Some(m) = n.checked_add(T::WIDTH) { assert_eq!(x.rotate_right(m), rotated); } assert_eq!(x.rotate_right(n & T::WIDTH_MASK), rotated); assert_eq!(x.rotate_left(n.neg_mod(T::WIDTH)), rotated); }); unsigned_gen::().test_properties(|x| { assert_eq!(x.rotate_right(0), x); assert_eq!(x.rotate_right(T::WIDTH), x); }); unsigned_gen::().test_properties(|n| { assert_eq!(T::ZERO.rotate_right(n), T::ZERO); assert_eq!(T::MAX.rotate_right(n), T::MAX); }); } fn rotate_right_properties_signed_helper() { signed_unsigned_pair_gen::().test_properties(|(x, n)| { let rotated = x.rotate_right(n); let mut mut_x = x; mut_x.rotate_right_assign(n); assert_eq!(mut_x, rotated); if let Some(m) = n.checked_add(T::WIDTH) { assert_eq!(x.rotate_right(m), rotated); } assert_eq!(x.rotate_right(n & T::WIDTH_MASK), rotated); assert_eq!(x.rotate_left(n.neg_mod(T::WIDTH)), rotated); }); signed_gen::().test_properties(|x| { assert_eq!(x.rotate_right(0), x); assert_eq!(x.rotate_right(T::WIDTH), x); }); unsigned_gen::().test_properties(|n| { assert_eq!(T::ZERO.rotate_right(n), T::ZERO); assert_eq!(T::NEGATIVE_ONE.rotate_right(n), T::NEGATIVE_ONE); }); } #[test] fn rotate_right_properties() { apply_fn_to_unsigneds!(rotate_right_properties_unsigned_helper); apply_fn_to_signeds!(rotate_right_properties_signed_helper); } malachite-base-0.4.16/tests/num/arithmetic/round_to_multiple.rs000064400000000000000000001265341046102023000227720ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::UnsignedAbs; use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::ConvertibleFrom; use malachite_base::rounding_modes::exhaustive::exhaustive_rounding_modes; use malachite_base::rounding_modes::RoundingMode::{self, *}; use malachite_base::test_util::generators::{ signed_pair_gen, signed_pair_gen_var_5, signed_rounding_mode_pair_gen, signed_signed_rounding_mode_triple_gen_var_2, unsigned_pair_gen_var_13, unsigned_pair_gen_var_27, unsigned_rounding_mode_pair_gen, unsigned_unsigned_rounding_mode_triple_gen_var_2, }; use std::cmp::Ordering::{self, *}; use std::panic::catch_unwind; #[test] fn test_round_to_multiple_unsigned() { fn test(n: T, d: T, rm: RoundingMode, q: T, o: Ordering) { assert_eq!(n.round_to_multiple(d, rm), (q, o)); let mut mut_n = n; assert_eq!(mut_n.round_to_multiple_assign(d, rm), o); assert_eq!(mut_n, q); } test::(0, 1, Down, 0, Equal); test::(0, 1, Floor, 0, Equal); test::(0, 1, Up, 0, Equal); test::(0, 1, Ceiling, 0, Equal); test::(0, 1, Nearest, 0, Equal); test::(0, 1, Exact, 0, Equal); test::(0, 123, Down, 0, Equal); test::(0, 123, Floor, 0, Equal); test::(0, 123, Up, 0, Equal); test::(0, 123, Ceiling, 0, Equal); test::(0, 123, Nearest, 0, Equal); test::(0, 123, Exact, 0, Equal); test::(1, 1, Down, 1, Equal); test::(1, 1, Floor, 1, Equal); test::(1, 1, Up, 1, Equal); test::(1, 1, Ceiling, 1, Equal); test::(1, 1, Nearest, 1, Equal); test::(1, 1, Exact, 1, Equal); test::(123, 1, Down, 123, Equal); test::(123, 1, Floor, 123, Equal); test::(123, 1, Up, 123, Equal); test::(123, 1, Ceiling, 123, Equal); test::(123, 1, Nearest, 123, Equal); test::(123, 1, Exact, 123, Equal); test::(123, 2, Down, 122, Less); test::(123, 2, Floor, 122, Less); test::(123, 2, Up, 124, Greater); test::(123, 2, Ceiling, 124, Greater); test::(123, 2, Nearest, 124, Greater); test::(125, 2, Down, 124, Less); test::(125, 2, Floor, 124, Less); test::(125, 2, Up, 126, Greater); test::(125, 2, Ceiling, 126, Greater); test::(125, 2, Nearest, 124, Less); test::(123, 123, Down, 123, Equal); test::(123, 123, Floor, 123, Equal); test::(123, 123, Up, 123, Equal); test::(123, 123, Ceiling, 123, Equal); test::(123, 123, Nearest, 123, Equal); test::(123, 123, Exact, 123, Equal); test::(123, 456, Down, 0, Less); test::(123, 456, Floor, 0, Less); test::(123, 456, Up, 456, Greater); test::(123, 456, Ceiling, 456, Greater); test::(123, 456, Nearest, 0, Less); test::(1000000000000, 1, Down, 1000000000000, Equal); test::(1000000000000, 1, Floor, 1000000000000, Equal); test::(1000000000000, 1, Up, 1000000000000, Equal); test::(1000000000000, 1, Ceiling, 1000000000000, Equal); test::(1000000000000, 1, Nearest, 1000000000000, Equal); test::(1000000000000, 1, Exact, 1000000000000, Equal); test::(1000000000000, 3, Down, 999999999999, Less); test::(1000000000000, 3, Floor, 999999999999, Less); test::(1000000000000, 3, Up, 1000000000002, Greater); test::(1000000000000, 3, Ceiling, 1000000000002, Greater); test::(1000000000000, 3, Nearest, 999999999999, Less); test::(999999999999, 2, Down, 999999999998, Less); test::(999999999999, 2, Floor, 999999999998, Less); test::(999999999999, 2, Up, 1000000000000, Greater); test::(999999999999, 2, Ceiling, 1000000000000, Greater); test::(999999999999, 2, Nearest, 1000000000000, Greater); test::(1000000000001, 2, Down, 1000000000000, Less); test::(1000000000001, 2, Floor, 1000000000000, Less); test::(1000000000001, 2, Up, 1000000000002, Greater); test::(1000000000001, 2, Ceiling, 1000000000002, Greater); test::(1000000000001, 2, Nearest, 1000000000000, Less); test::( 1000000000000000000000000, 0xffffffff, Down, 999999999999996832276305, Less, ); test::( 1000000000000000000000000, 0xffffffff, Floor, 999999999999996832276305, Less, ); test::( 1000000000000000000000000, 0xffffffff, Up, 1000000000000001127243600, Greater, ); test::( 1000000000000000000000000, 0xffffffff, Ceiling, 1000000000000001127243600, Greater, ); test::( 1000000000000000000000000, 0xffffffff, Nearest, 1000000000000001127243600, Greater, ); test::( 1000000000000000000000000, 1000000000000, Down, 1000000000000000000000000, Equal, ); test::( 1000000000000000000000000, 1000000000000, Floor, 1000000000000000000000000, Equal, ); test::( 1000000000000000000000000, 1000000000000, Up, 1000000000000000000000000, Equal, ); test::( 1000000000000000000000000, 1000000000000, Ceiling, 1000000000000000000000000, Equal, ); test::( 1000000000000000000000000, 1000000000000, Nearest, 1000000000000000000000000, Equal, ); test::( 1000000000000000000000000, 1000000000000, Exact, 1000000000000000000000000, Equal, ); test::( 1000000000000000000000000, 1000000000001, Down, 999999999999999999999999, Less, ); test::( 1000000000000000000000000, 1000000000001, Floor, 999999999999999999999999, Less, ); test::( 1000000000000000000000000, 1000000000001, Up, 1000000000001000000000000, Greater, ); test::( 1000000000000000000000000, 1000000000001, Ceiling, 1000000000001000000000000, Greater, ); test::( 1000000000000000000000000, 1000000000001, Nearest, 999999999999999999999999, Less, ); test::( 2999999999999999999999999, 2000000000000000000000000, Nearest, 2000000000000000000000000, Less, ); test::( 3000000000000000000000000, 2000000000000000000000000, Nearest, 4000000000000000000000000, Greater, ); test::( 3000000000000000000000001, 2000000000000000000000000, Nearest, 4000000000000000000000000, Greater, ); test::(0, 0, Floor, 0, Equal); test::(0, 0, Ceiling, 0, Equal); test::(0, 0, Down, 0, Equal); test::(0, 0, Up, 0, Equal); test::(0, 0, Nearest, 0, Equal); test::(0, 0, Exact, 0, Equal); test::(2, 0, Floor, 0, Less); test::(2, 0, Down, 0, Less); test::(2, 0, Nearest, 0, Less); } #[test] fn test_round_to_multiple_signed() { fn test(n: T, d: T, rm: RoundingMode, q: T, o: Ordering) { assert_eq!(n.round_to_multiple(d, rm), (q, o)); let mut mut_n = n; assert_eq!(mut_n.round_to_multiple_assign(d, rm), o); assert_eq!(mut_n, q); } test::(0, 1, Down, 0, Equal); test::(0, 1, Floor, 0, Equal); test::(0, 1, Up, 0, Equal); test::(0, 1, Ceiling, 0, Equal); test::(0, 1, Nearest, 0, Equal); test::(0, 1, Exact, 0, Equal); test::(0, 123, Down, 0, Equal); test::(0, 123, Floor, 0, Equal); test::(0, 123, Up, 0, Equal); test::(0, 123, Ceiling, 0, Equal); test::(0, 123, Nearest, 0, Equal); test::(0, 123, Exact, 0, Equal); test::(1, 1, Down, 1, Equal); test::(1, 1, Floor, 1, Equal); test::(1, 1, Up, 1, Equal); test::(1, 1, Ceiling, 1, Equal); test::(1, 1, Nearest, 1, Equal); test::(1, 1, Exact, 1, Equal); test::(123, 1, Down, 123, Equal); test::(123, 1, Floor, 123, Equal); test::(123, 1, Up, 123, Equal); test::(123, 1, Ceiling, 123, Equal); test::(123, 1, Nearest, 123, Equal); test::(123, 1, Exact, 123, Equal); test::(123, 2, Down, 122, Less); test::(123, 2, Floor, 122, Less); test::(123, 2, Up, 124, Greater); test::(123, 2, Ceiling, 124, Greater); test::(123, 2, Nearest, 124, Greater); test::(125, 2, Down, 124, Less); test::(125, 2, Floor, 124, Less); test::(125, 2, Up, 126, Greater); test::(125, 2, Ceiling, 126, Greater); test::(125, 2, Nearest, 124, Less); test::(123, 123, Down, 123, Equal); test::(123, 123, Floor, 123, Equal); test::(123, 123, Up, 123, Equal); test::(123, 123, Ceiling, 123, Equal); test::(123, 123, Nearest, 123, Equal); test::(123, 123, Exact, 123, Equal); test::(123, 456, Down, 0, Less); test::(123, 456, Floor, 0, Less); test::(123, 456, Up, 456, Greater); test::(123, 456, Ceiling, 456, Greater); test::(123, 456, Nearest, 0, Less); test::(1000000000000, 1, Down, 1000000000000, Equal); test::(1000000000000, 1, Floor, 1000000000000, Equal); test::(1000000000000, 1, Up, 1000000000000, Equal); test::(1000000000000, 1, Ceiling, 1000000000000, Equal); test::(1000000000000, 1, Nearest, 1000000000000, Equal); test::(1000000000000, 1, Exact, 1000000000000, Equal); test::(1000000000000, 3, Down, 999999999999, Less); test::(1000000000000, 3, Floor, 999999999999, Less); test::(1000000000000, 3, Up, 1000000000002, Greater); test::(1000000000000, 3, Ceiling, 1000000000002, Greater); test::(1000000000000, 3, Nearest, 999999999999, Less); test::(999999999999, 2, Down, 999999999998, Less); test::(999999999999, 2, Floor, 999999999998, Less); test::(999999999999, 2, Up, 1000000000000, Greater); test::(999999999999, 2, Ceiling, 1000000000000, Greater); test::(999999999999, 2, Nearest, 1000000000000, Greater); test::(1000000000001, 2, Down, 1000000000000, Less); test::(1000000000001, 2, Floor, 1000000000000, Less); test::(1000000000001, 2, Up, 1000000000002, Greater); test::(1000000000001, 2, Ceiling, 1000000000002, Greater); test::(1000000000001, 2, Nearest, 1000000000000, Less); test::( 1000000000000000000000000, 0xffffffff, Down, 999999999999996832276305, Less, ); test::( 1000000000000000000000000, 0xffffffff, Floor, 999999999999996832276305, Less, ); test::( 1000000000000000000000000, 0xffffffff, Up, 1000000000000001127243600, Greater, ); test::( 1000000000000000000000000, 0xffffffff, Ceiling, 1000000000000001127243600, Greater, ); test::( 1000000000000000000000000, 0xffffffff, Nearest, 1000000000000001127243600, Greater, ); test::( 1000000000000000000000000, 1000000000000, Down, 1000000000000000000000000, Equal, ); test::( 1000000000000000000000000, 1000000000000, Floor, 1000000000000000000000000, Equal, ); test::( 1000000000000000000000000, 1000000000000, Up, 1000000000000000000000000, Equal, ); test::( 1000000000000000000000000, 1000000000000, Ceiling, 1000000000000000000000000, Equal, ); test::( 1000000000000000000000000, 1000000000000, Nearest, 1000000000000000000000000, Equal, ); test::( 1000000000000000000000000, 1000000000000, Exact, 1000000000000000000000000, Equal, ); test::( 1000000000000000000000000, 1000000000001, Down, 999999999999999999999999, Less, ); test::( 1000000000000000000000000, 1000000000001, Floor, 999999999999999999999999, Less, ); test::( 1000000000000000000000000, 1000000000001, Up, 1000000000001000000000000, Greater, ); test::( 1000000000000000000000000, 1000000000001, Ceiling, 1000000000001000000000000, Greater, ); test::( 1000000000000000000000000, 1000000000001, Nearest, 999999999999999999999999, Less, ); test::( 2999999999999999999999999, 2000000000000000000000000, Nearest, 2000000000000000000000000, Less, ); test::( 3000000000000000000000000, 2000000000000000000000000, Nearest, 4000000000000000000000000, Greater, ); test::( 3000000000000000000000001, 2000000000000000000000000, Nearest, 4000000000000000000000000, Greater, ); test::(0, -1, Down, 0, Equal); test::(0, -1, Floor, 0, Equal); test::(0, -1, Up, 0, Equal); test::(0, -1, Ceiling, 0, Equal); test::(0, -1, Nearest, 0, Equal); test::(0, -1, Exact, 0, Equal); test::(0, -123, Down, 0, Equal); test::(0, -123, Floor, 0, Equal); test::(0, -123, Up, 0, Equal); test::(0, -123, Ceiling, 0, Equal); test::(0, -123, Nearest, 0, Equal); test::(0, -123, Exact, 0, Equal); test::(1, -1, Down, 1, Equal); test::(1, -1, Floor, 1, Equal); test::(1, -1, Up, 1, Equal); test::(1, -1, Ceiling, 1, Equal); test::(1, -1, Nearest, 1, Equal); test::(1, -1, Exact, 1, Equal); test::(123, -1, Down, 123, Equal); test::(123, -1, Floor, 123, Equal); test::(123, -1, Up, 123, Equal); test::(123, -1, Ceiling, 123, Equal); test::(123, -1, Nearest, 123, Equal); test::(123, -1, Exact, 123, Equal); test::(123, -2, Down, 122, Less); test::(123, -2, Floor, 122, Less); test::(123, -2, Up, 124, Greater); test::(123, -2, Ceiling, 124, Greater); test::(123, -2, Nearest, 124, Greater); test::(125, -2, Down, 124, Less); test::(125, -2, Floor, 124, Less); test::(125, -2, Up, 126, Greater); test::(125, -2, Ceiling, 126, Greater); test::(125, -2, Nearest, 124, Less); test::(123, -123, Down, 123, Equal); test::(123, -123, Floor, 123, Equal); test::(123, -123, Up, 123, Equal); test::(123, -123, Ceiling, 123, Equal); test::(123, -123, Nearest, 123, Equal); test::(123, -123, Exact, 123, Equal); test::(123, -456, Down, 0, Less); test::(123, -456, Floor, 0, Less); test::(123, -456, Up, 456, Greater); test::(123, -456, Ceiling, 456, Greater); test::(123, -456, Nearest, 0, Less); test::(1000000000000, -1, Down, 1000000000000, Equal); test::(1000000000000, -1, Floor, 1000000000000, Equal); test::(1000000000000, -1, Up, 1000000000000, Equal); test::(1000000000000, -1, Ceiling, 1000000000000, Equal); test::(1000000000000, -1, Nearest, 1000000000000, Equal); test::(1000000000000, -1, Exact, 1000000000000, Equal); test::(1000000000000, -3, Down, 999999999999, Less); test::(1000000000000, -3, Floor, 999999999999, Less); test::(1000000000000, -3, Up, 1000000000002, Greater); test::(1000000000000, -3, Ceiling, 1000000000002, Greater); test::(1000000000000, -3, Nearest, 999999999999, Less); test::(999999999999, -2, Down, 999999999998, Less); test::(999999999999, -2, Floor, 999999999998, Less); test::(999999999999, -2, Up, 1000000000000, Greater); test::(999999999999, -2, Ceiling, 1000000000000, Greater); test::(999999999999, -2, Nearest, 1000000000000, Greater); test::(1000000000001, -2, Down, 1000000000000, Less); test::(1000000000001, -2, Floor, 1000000000000, Less); test::(1000000000001, -2, Up, 1000000000002, Greater); test::(1000000000001, -2, Ceiling, 1000000000002, Greater); test::(1000000000001, -2, Nearest, 1000000000000, Less); test::( 1000000000000000000000000, -0xffffffff, Down, 999999999999996832276305, Less, ); test::( 1000000000000000000000000, -0xffffffff, Floor, 999999999999996832276305, Less, ); test::( 1000000000000000000000000, -0xffffffff, Up, 1000000000000001127243600, Greater, ); test::( 1000000000000000000000000, -0xffffffff, Ceiling, 1000000000000001127243600, Greater, ); test::( 1000000000000000000000000, -0xffffffff, Nearest, 1000000000000001127243600, Greater, ); test::( 1000000000000000000000000, 1000000000000, Down, 1000000000000000000000000, Equal, ); test::( 1000000000000000000000000, -1000000000000, Floor, 1000000000000000000000000, Equal, ); test::( 1000000000000000000000000, -1000000000000, Up, 1000000000000000000000000, Equal, ); test::( 1000000000000000000000000, -1000000000000, Ceiling, 1000000000000000000000000, Equal, ); test::( 1000000000000000000000000, 1000000000000, Nearest, 1000000000000000000000000, Equal, ); test::( 1000000000000000000000000, 1000000000000, Exact, 1000000000000000000000000, Equal, ); test::( 1000000000000000000000000, -1000000000001, Down, 999999999999999999999999, Less, ); test::( 1000000000000000000000000, -1000000000001, Floor, 999999999999999999999999, Less, ); test::( 1000000000000000000000000, -1000000000001, Up, 1000000000001000000000000, Greater, ); test::( 1000000000000000000000000, -1000000000001, Ceiling, 1000000000001000000000000, Greater, ); test::( 1000000000000000000000000, -1000000000001, Nearest, 999999999999999999999999, Less, ); test::( 2999999999999999999999999, -2000000000000000000000000, Nearest, 2000000000000000000000000, Less, ); test::( 3000000000000000000000000, -2000000000000000000000000, Nearest, 4000000000000000000000000, Greater, ); test::( 3000000000000000000000001, -2000000000000000000000000, Nearest, 4000000000000000000000000, Greater, ); test::(-1, 1, Down, -1, Equal); test::(-1, 1, Floor, -1, Equal); test::(-1, 1, Up, -1, Equal); test::(-1, 1, Ceiling, -1, Equal); test::(-1, 1, Nearest, -1, Equal); test::(-1, 1, Exact, -1, Equal); test::(-123, 1, Down, -123, Equal); test::(-123, 1, Floor, -123, Equal); test::(-123, 1, Up, -123, Equal); test::(-123, 1, Ceiling, -123, Equal); test::(-123, 1, Nearest, -123, Equal); test::(-123, 1, Exact, -123, Equal); test::(-123, 2, Down, -122, Greater); test::(-123, 2, Floor, -124, Less); test::(-123, 2, Up, -124, Less); test::(-123, 2, Ceiling, -122, Greater); test::(-123, 2, Nearest, -124, Less); test::(-125, 2, Down, -124, Greater); test::(-125, 2, Floor, -126, Less); test::(-125, 2, Up, -126, Less); test::(-125, 2, Ceiling, -124, Greater); test::(-125, 2, Nearest, -124, Greater); test::(-123, 123, Down, -123, Equal); test::(-123, 123, Floor, -123, Equal); test::(-123, 123, Up, -123, Equal); test::(-123, 123, Ceiling, -123, Equal); test::(-123, 123, Nearest, -123, Equal); test::(-123, 123, Exact, -123, Equal); test::(-123, 456, Down, 0, Greater); test::(-123, 456, Floor, -456, Less); test::(-123, 456, Up, -456, Less); test::(-123, 456, Ceiling, 0, Greater); test::(-123, 456, Nearest, 0, Greater); test::(-1000000000000, 1, Down, -1000000000000, Equal); test::(-1000000000000, 1, Floor, -1000000000000, Equal); test::(-1000000000000, 1, Up, -1000000000000, Equal); test::(-1000000000000, 1, Ceiling, -1000000000000, Equal); test::(-1000000000000, 1, Nearest, -1000000000000, Equal); test::(-1000000000000, 1, Exact, -1000000000000, Equal); test::(-1000000000000, 3, Down, -999999999999, Greater); test::(-1000000000000, 3, Floor, -1000000000002, Less); test::(-1000000000000, 3, Up, -1000000000002, Less); test::(-1000000000000, 3, Ceiling, -999999999999, Greater); test::(-1000000000000, 3, Nearest, -999999999999, Greater); test::(-999999999999, 2, Down, -999999999998, Greater); test::(-999999999999, 2, Floor, -1000000000000, Less); test::(-999999999999, 2, Up, -1000000000000, Less); test::(-999999999999, 2, Ceiling, -999999999998, Greater); test::(-999999999999, 2, Nearest, -1000000000000, Less); test::(-1000000000001, 2, Down, -1000000000000, Greater); test::(-1000000000001, 2, Floor, -1000000000002, Less); test::(-1000000000001, 2, Up, -1000000000002, Less); test::(-1000000000001, 2, Ceiling, -1000000000000, Greater); test::(-1000000000001, 2, Nearest, -1000000000000, Greater); test::( -1000000000000000000000000, 0xffffffff, Down, -999999999999996832276305, Greater, ); test::( -1000000000000000000000000, 0xffffffff, Floor, -1000000000000001127243600, Less, ); test::( -1000000000000000000000000, 0xffffffff, Up, -1000000000000001127243600, Less, ); test::( -1000000000000000000000000, 0xffffffff, Ceiling, -999999999999996832276305, Greater, ); test::( -1000000000000000000000000, 0xffffffff, Nearest, -1000000000000001127243600, Less, ); test::( -1000000000000000000000000, 1000000000000, Down, -1000000000000000000000000, Equal, ); test::( -1000000000000000000000000, 1000000000000, Floor, -1000000000000000000000000, Equal, ); test::( -1000000000000000000000000, 1000000000000, Up, -1000000000000000000000000, Equal, ); test::( -1000000000000000000000000, 1000000000000, Ceiling, -1000000000000000000000000, Equal, ); test::( -1000000000000000000000000, 1000000000000, Nearest, -1000000000000000000000000, Equal, ); test::( -1000000000000000000000000, 1000000000000, Exact, -1000000000000000000000000, Equal, ); test::( -1000000000000000000000000, 1000000000001, Down, -999999999999999999999999, Greater, ); test::( -1000000000000000000000000, 1000000000001, Floor, -1000000000001000000000000, Less, ); test::( -1000000000000000000000000, 1000000000001, Up, -1000000000001000000000000, Less, ); test::( -1000000000000000000000000, 1000000000001, Ceiling, -999999999999999999999999, Greater, ); test::( -1000000000000000000000000, 1000000000001, Nearest, -999999999999999999999999, Greater, ); test::( -2999999999999999999999999, 2000000000000000000000000, Nearest, -2000000000000000000000000, Greater, ); test::( -3000000000000000000000000, 2000000000000000000000000, Nearest, -4000000000000000000000000, Less, ); test::( -3000000000000000000000001, 2000000000000000000000000, Nearest, -4000000000000000000000000, Less, ); test::(-1, -1, Down, -1, Equal); test::(-1, -1, Floor, -1, Equal); test::(-1, -1, Up, -1, Equal); test::(-1, -1, Ceiling, -1, Equal); test::(-1, -1, Nearest, -1, Equal); test::(-1, -1, Exact, -1, Equal); test::(-123, -1, Down, -123, Equal); test::(-123, -1, Floor, -123, Equal); test::(-123, -1, Up, -123, Equal); test::(-123, -1, Ceiling, -123, Equal); test::(-123, -1, Nearest, -123, Equal); test::(-123, -1, Exact, -123, Equal); test::(-123, -2, Down, -122, Greater); test::(-123, -2, Floor, -124, Less); test::(-123, -2, Up, -124, Less); test::(-123, -2, Ceiling, -122, Greater); test::(-123, -2, Nearest, -124, Less); test::(-125, -2, Down, -124, Greater); test::(-125, -2, Floor, -126, Less); test::(-125, -2, Up, -126, Less); test::(-125, -2, Ceiling, -124, Greater); test::(-125, -2, Nearest, -124, Greater); test::(-123, -123, Down, -123, Equal); test::(-123, -123, Floor, -123, Equal); test::(-123, -123, Up, -123, Equal); test::(-123, -123, Ceiling, -123, Equal); test::(-123, -123, Nearest, -123, Equal); test::(-123, -123, Exact, -123, Equal); test::(-123, -456, Down, 0, Greater); test::(-123, -456, Floor, -456, Less); test::(-123, -456, Up, -456, Less); test::(-123, -456, Ceiling, 0, Greater); test::(-123, -456, Nearest, 0, Greater); test::(-1000000000000, -1, Down, -1000000000000, Equal); test::(-1000000000000, -1, Floor, -1000000000000, Equal); test::(-1000000000000, -1, Up, -1000000000000, Equal); test::(-1000000000000, -1, Ceiling, -1000000000000, Equal); test::(-1000000000000, -1, Nearest, -1000000000000, Equal); test::(-1000000000000, -1, Exact, -1000000000000, Equal); test::(-1000000000000, -3, Down, -999999999999, Greater); test::(-1000000000000, -3, Floor, -1000000000002, Less); test::(-1000000000000, -3, Up, -1000000000002, Less); test::(-1000000000000, -3, Ceiling, -999999999999, Greater); test::(-1000000000000, -3, Nearest, -999999999999, Greater); test::(-999999999999, -2, Down, -999999999998, Greater); test::(-999999999999, -2, Floor, -1000000000000, Less); test::(-999999999999, -2, Up, -1000000000000, Less); test::(-999999999999, -2, Ceiling, -999999999998, Greater); test::(-999999999999, -2, Nearest, -1000000000000, Less); test::(-1000000000001, -2, Down, -1000000000000, Greater); test::(-1000000000001, -2, Floor, -1000000000002, Less); test::(-1000000000001, -2, Up, -1000000000002, Less); test::(-1000000000001, -2, Ceiling, -1000000000000, Greater); test::(-1000000000001, -2, Nearest, -1000000000000, Greater); test::( -1000000000000000000000000, -0xffffffff, Down, -999999999999996832276305, Greater, ); test::( -1000000000000000000000000, -0xffffffff, Floor, -1000000000000001127243600, Less, ); test::( -1000000000000000000000000, -0xffffffff, Up, -1000000000000001127243600, Less, ); test::( -1000000000000000000000000, -0xffffffff, Ceiling, -999999999999996832276305, Greater, ); test::( -1000000000000000000000000, -0xffffffff, Nearest, -1000000000000001127243600, Less, ); test::( -1000000000000000000000000, -1000000000000, Down, -1000000000000000000000000, Equal, ); test::( -1000000000000000000000000, -1000000000000, Floor, -1000000000000000000000000, Equal, ); test::( -1000000000000000000000000, -1000000000000, Up, -1000000000000000000000000, Equal, ); test::( -1000000000000000000000000, -1000000000000, Ceiling, -1000000000000000000000000, Equal, ); test::( -1000000000000000000000000, -1000000000000, Nearest, -1000000000000000000000000, Equal, ); test::( -1000000000000000000000000, -1000000000000, Exact, -1000000000000000000000000, Equal, ); test::( -1000000000000000000000000, -1000000000001, Down, -999999999999999999999999, Greater, ); test::( -1000000000000000000000000, -1000000000001, Floor, -1000000000001000000000000, Less, ); test::( -1000000000000000000000000, -1000000000001, Up, -1000000000001000000000000, Less, ); test::( -1000000000000000000000000, -1000000000001, Ceiling, -999999999999999999999999, Greater, ); test::( -1000000000000000000000000, -1000000000001, Nearest, -999999999999999999999999, Greater, ); test::( -2999999999999999999999999, -2000000000000000000000000, Nearest, -2000000000000000000000000, Greater, ); test::( -3000000000000000000000000, -2000000000000000000000000, Nearest, -4000000000000000000000000, Less, ); test::( -3000000000000000000000001, -2000000000000000000000000, Nearest, -4000000000000000000000000, Less, ); test::(-128, 1, Down, -128, Equal); test::(-128, 1, Up, -128, Equal); test::(-128, 1, Floor, -128, Equal); test::(-128, 1, Ceiling, -128, Equal); test::(-128, 1, Nearest, -128, Equal); test::(-128, 1, Exact, -128, Equal); test::(-128, -1, Down, -128, Equal); test::(-128, -1, Up, -128, Equal); test::(-128, -1, Floor, -128, Equal); test::(-128, -1, Ceiling, -128, Equal); test::(-128, -1, Nearest, -128, Equal); test::(-128, -1, Exact, -128, Equal); test::(-128, -128, Down, -128, Equal); test::(-128, -128, Up, -128, Equal); test::(-128, -128, Floor, -128, Equal); test::(-128, -128, Ceiling, -128, Equal); test::(-128, -128, Nearest, -128, Equal); test::(-128, -128, Exact, -128, Equal); test::(0, 0, Floor, 0, Equal); test::(0, 0, Ceiling, 0, Equal); test::(0, 0, Down, 0, Equal); test::(0, 0, Up, 0, Equal); test::(0, 0, Nearest, 0, Equal); test::(0, 0, Exact, 0, Equal); test::(2, 0, Floor, 0, Less); test::(2, 0, Down, 0, Less); test::(2, 0, Nearest, 0, Less); test::(-2, 0, Ceiling, 0, Greater); test::(-2, 0, Down, 0, Greater); test::(-2, 0, Nearest, 0, Greater); } fn round_to_multiple_fail_helper() { assert_panic!(T::exact_from(10).round_to_multiple(T::ZERO, Up)); assert_panic!(T::exact_from(10).round_to_multiple(T::exact_from(3), Exact)); assert_panic!(T::MAX.round_to_multiple(T::TWO, Ceiling)); assert_panic!(T::ONE.round_to_multiple(T::ZERO, Up)); assert_panic!(T::ONE.round_to_multiple(T::ZERO, Ceiling)); assert_panic!(T::ONE.round_to_multiple(T::ZERO, Exact)); assert_panic!(T::exact_from(10).round_to_multiple_assign(T::ZERO, Up)); assert_panic!({ T::exact_from(10).round_to_multiple_assign(T::exact_from(3), Exact); }); assert_panic!({ let mut n = T::MAX; n.round_to_multiple_assign(T::TWO, Ceiling); }); assert_panic!({ let mut n = T::ONE; n.round_to_multiple_assign(T::ZERO, Up); }); assert_panic!({ let mut n = T::ONE; n.round_to_multiple_assign(T::ZERO, Ceiling); }); assert_panic!({ let mut n = T::ONE; n.round_to_multiple_assign(T::ZERO, Exact); }); } fn round_to_multiple_signed_fail_helper() { assert_panic!(T::MIN.round_to_multiple(T::exact_from(3), Floor)); assert_panic!(T::NEGATIVE_ONE.round_to_multiple(T::ZERO, Up)); assert_panic!(T::NEGATIVE_ONE.round_to_multiple(T::ZERO, Floor)); assert_panic!(T::NEGATIVE_ONE.round_to_multiple(T::ZERO, Exact)); assert_panic!({ let mut n = T::MIN; n.round_to_multiple_assign(T::exact_from(3), Floor); }); assert_panic!({ let mut n = T::NEGATIVE_ONE; n.round_to_multiple_assign(T::ZERO, Up); }); assert_panic!({ let mut n = T::NEGATIVE_ONE; n.round_to_multiple_assign(T::ZERO, Floor); }); assert_panic!({ let mut n = T::NEGATIVE_ONE; n.round_to_multiple_assign(T::ZERO, Exact); }); } #[test] fn round_to_multiple_fail() { apply_fn_to_primitive_ints!(round_to_multiple_fail_helper); apply_fn_to_signeds!(round_to_multiple_signed_fail_helper); } fn round_to_multiple_properties_helper_unsigned() { unsigned_unsigned_rounding_mode_triple_gen_var_2::().test_properties(|(x, y, rm)| { let (rounded, o) = x.round_to_multiple(y, rm); let mut mut_x = x; assert_eq!(mut_x.round_to_multiple_assign(y, rm), o); assert_eq!(mut_x, rounded); assert!(rounded.divisible_by(y)); assert_eq!(rounded.cmp(&x), o); match rm { Floor | Down => assert_ne!(o, Greater), Ceiling | Up => assert_ne!(o, Less), Exact => assert_eq!(o, Equal), _ => {} } match rm { Floor | Down => { assert!(rounded <= x); } Ceiling | Up => { assert!(rounded >= x); } Exact => assert_eq!(rounded, x), Nearest => { if y == T::ZERO { assert_eq!(rounded, T::ZERO); } else { let mut closest = None; let mut second_closest = None; if rounded <= x { if let Some(above) = rounded.checked_add(y) { closest = Some(x - rounded); second_closest = Some(above - x); } } else if let Some(below) = rounded.checked_sub(y) { closest = Some(rounded - x); second_closest = Some(x - below); } if let (Some(closest), Some(second_closest)) = (closest, second_closest) { assert!(closest <= second_closest); if closest == second_closest { assert!(rounded.div_exact(y).even()); } } } } } if o == Equal { for rm in exhaustive_rounding_modes() { assert_eq!(x.round_to_multiple(y, rm), (rounded, Equal)); } } else { assert_panic!(x.round_to_multiple(y, Exact)); } }); unsigned_pair_gen_var_27::().test_properties(|(x, y)| { if let Some(product) = x.checked_mul(y) { let xo = (product, Equal); assert_eq!(product.round_to_multiple(y, Down), xo); assert_eq!(product.round_to_multiple(y, Up), xo); assert_eq!(product.round_to_multiple(y, Floor), xo); assert_eq!(product.round_to_multiple(y, Ceiling), xo); assert_eq!(product.round_to_multiple(y, Nearest), xo); assert_eq!(product.round_to_multiple(y, Exact), xo); } }); unsigned_pair_gen_var_13::().test_properties(|(x, y)| { let down = x.round_to_multiple(y, Down); assert_eq!(down.1, Less); if let Some(up) = down.0.checked_add(y) { let up = (up, Greater); assert_eq!(x.round_to_multiple(y, Up), up); assert_eq!(x.round_to_multiple(y, Floor), down); assert_eq!(x.round_to_multiple(y, Ceiling), up); let nearest = x.round_to_multiple(y, Nearest); assert!(nearest == down || nearest == up); } }); unsigned_rounding_mode_pair_gen::().test_properties(|(n, rm)| { if rm == Floor || rm == Down || rm == Nearest { assert_eq!( n.round_to_multiple(T::ZERO, rm), (T::ZERO, if n == T::ZERO { Equal } else { Less }) ); } assert_eq!(T::ZERO.round_to_multiple(n, rm), (T::ZERO, Equal)); assert_eq!(n.round_to_multiple(T::ONE, rm), (n, Equal)); assert_eq!(n.round_to_multiple(n, rm), (n, Equal)); }); } fn round_to_multiple_properties_helper_signed< U: PrimitiveUnsigned, S: TryFrom + ConvertibleFrom + PrimitiveSigned + UnsignedAbs, >() { signed_signed_rounding_mode_triple_gen_var_2::().test_properties(|(x, y, rm)| { let (rounded, o) = x.round_to_multiple(y, rm); let mut mut_x = x; assert_eq!(mut_x.round_to_multiple_assign(y, rm), o); assert_eq!(mut_x, rounded); assert!(rounded.divisible_by(y)); assert_eq!(rounded.cmp(&x), o); match (x >= S::ZERO, rm) { (_, Floor) | (true, Down) | (false, Up) => { assert_ne!(o, Greater); } (_, Ceiling) | (true, Up) | (false, Down) => { assert_ne!(o, Less); } (_, Exact) => assert_eq!(o, Equal), _ => {} } match rm { Floor => assert!(rounded <= x), Ceiling => assert!(rounded >= x), Down => assert!(rounded.le_abs(&x)), Up => assert!(rounded.ge_abs(&x)), Exact => assert_eq!(rounded, x), Nearest => { if y == S::ZERO { assert_eq!(rounded, S::ZERO); } else { let mut closest = None; let mut second_closest = None; let (o_above, o_below) = if y >= S::ZERO { (rounded.checked_add(y), rounded.checked_sub(y)) } else { (rounded.checked_sub(y), rounded.checked_add(y)) }; if rounded <= x { if let Some(above) = o_above { closest = x.checked_sub(rounded); second_closest = above.checked_sub(x); } } else if let Some(below) = o_below { closest = rounded.checked_sub(x); second_closest = x.checked_sub(below); } if let (Some(closest), Some(second_closest)) = (closest, second_closest) { assert!(closest <= second_closest); if closest == second_closest { assert!(rounded.div_exact(y).even()); } } } } } if o == Equal { for rm in exhaustive_rounding_modes() { assert_eq!(x.round_to_multiple(y, rm), (rounded, Equal)); } } else { assert_panic!(x.round_to_multiple(y, Exact)); } }); signed_pair_gen::().test_properties(|(x, y)| { if let Some(product) = x.checked_mul(y) { let xo = (product, Equal); assert_eq!(product.round_to_multiple(y, Down), xo); assert_eq!(product.round_to_multiple(y, Up), xo); assert_eq!(product.round_to_multiple(y, Floor), xo); assert_eq!(product.round_to_multiple(y, Ceiling), xo); assert_eq!(product.round_to_multiple(y, Nearest), xo); assert_eq!(product.round_to_multiple(y, Exact), xo); } }); signed_pair_gen_var_5::().test_properties(|(x, y)| { let down = x.round_to_multiple(y, Down); assert_eq!(down.1, if x >= S::ZERO { Less } else { Greater }); if let Some(up) = if (x >= S::ZERO) == (y >= S::ZERO) { down.0.checked_add(y) } else { down.0.checked_sub(y) } { let up = (up, if x >= S::ZERO { Greater } else { Less }); assert_eq!(x.round_to_multiple(y, Up), up); if x >= S::ZERO { assert_eq!(x.round_to_multiple(y, Floor), down); assert_eq!(x.round_to_multiple(y, Ceiling), up); } else { assert_eq!(x.round_to_multiple(y, Floor), up); assert_eq!(x.round_to_multiple(y, Ceiling), down); } let nearest = x.round_to_multiple(y, Nearest); assert!(nearest == down || nearest == up); } }); signed_rounding_mode_pair_gen::().test_properties(|(n, rm)| { if rm == Down || rm == Nearest || rm == if n >= S::ZERO { Floor } else { Ceiling } { assert_eq!( n.round_to_multiple(S::ZERO, rm), (S::ZERO, n.cmp(&S::ZERO).reverse()) ); } assert_eq!(S::ZERO.round_to_multiple(n, rm), (S::ZERO, Equal)); assert_eq!(n.round_to_multiple(S::ONE, rm), (n, Equal)); assert_eq!(n.round_to_multiple(n, rm), (n, Equal)); }); } #[test] fn round_to_multiple_properties() { apply_fn_to_unsigneds!(round_to_multiple_properties_helper_unsigned); apply_fn_to_unsigned_signed_pairs!(round_to_multiple_properties_helper_signed); } malachite-base-0.4.16/tests/num/arithmetic/round_to_multiple_of_power_of_2.rs000064400000000000000000000370101046102023000255650ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::WrappingFrom; use malachite_base::rounding_modes::exhaustive::exhaustive_rounding_modes; use malachite_base::rounding_modes::RoundingMode::{self, *}; use malachite_base::test_util::generators::{ signed_rounding_mode_pair_gen, signed_unsigned_pair_gen_var_1, signed_unsigned_pair_gen_var_16, signed_unsigned_pair_gen_var_17, signed_unsigned_pair_gen_var_8, signed_unsigned_rounding_mode_triple_gen_var_1, unsigned_pair_gen_var_14, unsigned_pair_gen_var_2, unsigned_pair_gen_var_21, unsigned_rounding_mode_pair_gen, unsigned_unsigned_rounding_mode_triple_gen_var_3, }; use std::cmp::Ordering::{self, *}; use std::panic::catch_unwind; #[test] fn test_round_to_multiple_of_power_of_2() { fn test(n: T, pow: u64, rm: RoundingMode, out: T, o: Ordering) { assert_eq!(n.round_to_multiple_of_power_of_2(pow, rm), (out, o)); let mut n = n; assert_eq!(n.round_to_multiple_of_power_of_2_assign(pow, rm), o); assert_eq!(n, out); } test::(0, 10, Exact, 0, Equal); test::(17, 0, Exact, 17, Equal); test::(10, 2, Floor, 8, Less); test::(10, 2, Ceiling, 12, Greater); test::(10, 2, Down, 8, Less); test::(10, 2, Up, 12, Greater); test::(10, 2, Nearest, 8, Less); test::(12, 2, Exact, 12, Equal); test::(-10, 2, Floor, -12, Less); test::(-10, 2, Ceiling, -8, Greater); test::(-10, 2, Down, -8, Greater); test::(-10, 2, Up, -12, Less); test::(-10, 2, Nearest, -8, Greater); test::(-12, 2, Exact, -12, Equal); test::(0xff, 4, Down, 0xf0, Less); test::(0xff, 4, Floor, 0xf0, Less); test::(0xef, 4, Up, 0xf0, Greater); test::(0xef, 4, Ceiling, 0xf0, Greater); test::(0xe8, 4, Nearest, 0xe0, Less); test::(1, 8, Nearest, 0, Less); test::(0x7f, 4, Down, 0x70, Less); test::(0x7f, 4, Floor, 0x70, Less); test::(0x6f, 4, Up, 0x70, Greater); test::(0x6f, 4, Ceiling, 0x70, Greater); test::(0x68, 4, Nearest, 0x60, Less); test::(-0x7f, 4, Down, -0x70, Greater); test::(-0x7f, 4, Floor, -0x80, Less); test::(-0x7f, 4, Up, -0x80, Less); test::(-0x7f, 4, Ceiling, -0x70, Greater); test::(-0x78, 4, Nearest, -0x80, Less); } fn round_to_multiple_of_power_of_2_fail_helper() { assert_panic!(T::exact_from(10).round_to_multiple_of_power_of_2(4, Exact)); assert_panic!(T::MAX.round_to_multiple_of_power_of_2(4, Up)); assert_panic!(T::MAX.round_to_multiple_of_power_of_2(4, Ceiling)); assert_panic!(T::MAX.round_to_multiple_of_power_of_2(4, Nearest)); assert_panic!(T::ONE.round_to_multiple_of_power_of_2(T::WIDTH, Up)); assert_panic!(T::exact_from(10).round_to_multiple_of_power_of_2_assign(4, Exact)); assert_panic!({ let mut n = T::MAX; n.round_to_multiple_of_power_of_2_assign(4, Up); }); assert_panic!({ let mut n = T::MAX; n.round_to_multiple_of_power_of_2_assign(4, Ceiling); }); assert_panic!({ let mut n = T::MAX; n.round_to_multiple_of_power_of_2_assign(4, Nearest); }); assert_panic!({ let mut n = T::ONE; n.round_to_multiple_of_power_of_2_assign(T::WIDTH, Up); }); } fn round_to_multiple_of_power_of_2_signed_fail_helper() { assert_panic!((-T::MAX).round_to_multiple_of_power_of_2(T::WIDTH, Up)); assert_panic!((-T::MAX).round_to_multiple_of_power_of_2(T::WIDTH, Floor)); assert_panic!((-T::MAX).round_to_multiple_of_power_of_2_assign(T::WIDTH, Up)); assert_panic!({ (-T::MAX).round_to_multiple_of_power_of_2_assign(T::WIDTH, Floor); }); } #[test] fn round_to_multiple_of_power_of_2_fail() { apply_fn_to_primitive_ints!(round_to_multiple_of_power_of_2_fail_helper); apply_fn_to_signeds!(round_to_multiple_of_power_of_2_signed_fail_helper); } fn round_to_multiple_of_power_of_2_properties_helper_unsigned() { unsigned_unsigned_rounding_mode_triple_gen_var_3::().test_properties(|(n, pow, rm)| { let (rounded, o) = n.round_to_multiple_of_power_of_2(pow, rm); let mut mut_n = n; assert_eq!(mut_n.round_to_multiple_of_power_of_2_assign(pow, rm), o); assert_eq!(mut_n, rounded); assert!(rounded.divisible_by_power_of_2(pow)); assert_eq!(rounded.cmp(&n), o); match rm { Floor | Down => assert_ne!(o, Greater), Ceiling | Up => assert_ne!(o, Less), Exact => assert_eq!(o, Equal), _ => {} } match rm { Floor | Down => { assert!(rounded <= n); } Ceiling | Up => { assert!(rounded >= n); } Exact => assert_eq!(rounded, n), Nearest => { if let Some(k) = T::ONE.arithmetic_checked_shl(pow) { let mut closest = None; let mut second_closest = None; if rounded <= n { if let Some(above) = rounded.checked_add(k) { closest = Some(n - rounded); second_closest = Some(above - n); } } else if let Some(below) = rounded.checked_sub(k) { closest = Some(rounded - n); second_closest = Some(n - below); } if let (Some(closest), Some(second_closest)) = (closest, second_closest) { assert!(closest <= second_closest); if closest == second_closest { assert!(!rounded.get_bit(pow)); } } } } } if o == Equal { for rm in exhaustive_rounding_modes() { assert_eq!(n.round_to_multiple_of_power_of_2(pow, rm), (rounded, Equal)); } } else { assert_panic!(n.round_to_multiple_of_power_of_2(pow, Exact)); } }); unsigned_pair_gen_var_2::().test_properties(|(n, pow)| { if pow < T::WIDTH { if let Some(shifted) = n.arithmetic_checked_shl(pow) { let so = (shifted, Equal); assert_eq!(shifted.round_to_multiple_of_power_of_2(pow, Down), so); assert_eq!(shifted.round_to_multiple_of_power_of_2(pow, Up), so); assert_eq!(shifted.round_to_multiple_of_power_of_2(pow, Floor), so); assert_eq!(shifted.round_to_multiple_of_power_of_2(pow, Ceiling), so); assert_eq!(shifted.round_to_multiple_of_power_of_2(pow, Nearest), so); assert_eq!(shifted.round_to_multiple_of_power_of_2(pow, Exact), so); } } }); unsigned_pair_gen_var_14::().test_properties(|(n, pow)| { let down = n.round_to_multiple_of_power_of_2(pow, Down); assert_eq!(down.1, Less); if let Some(k) = T::ONE.arithmetic_checked_shl(pow) { if let Some(up) = down.0.checked_add(k) { let up = (up, Greater); assert_eq!(n.round_to_multiple_of_power_of_2(pow, Up), up); assert_eq!(n.round_to_multiple_of_power_of_2(pow, Floor), down); assert_eq!(n.round_to_multiple_of_power_of_2(pow, Ceiling), up); let nearest = n.round_to_multiple_of_power_of_2(pow, Nearest); assert!(nearest == down || nearest == up); } } }); unsigned_pair_gen_var_21::().test_properties(|(n, pow)| { if let Some(shift) = pow.checked_add(T::WIDTH) { assert_eq!( n.round_to_multiple_of_power_of_2(shift, Down), (T::ZERO, if n == T::ZERO { Equal } else { Less }) ); assert_eq!( n.round_to_multiple_of_power_of_2(shift, Floor), (T::ZERO, if n == T::ZERO { Equal } else { Less }) ); if let Some(extra_shift) = shift.checked_add(1) { assert_eq!( n.round_to_multiple_of_power_of_2(extra_shift, Nearest), (T::ZERO, if n == T::ZERO { Equal } else { Less }) ); } } }); unsigned_rounding_mode_pair_gen::().test_properties(|(n, rm)| { assert_eq!(n.round_to_multiple_of_power_of_2(0, rm), (n, Equal)); }); unsigned_rounding_mode_pair_gen().test_properties(|(pow, rm)| { assert_eq!( T::ZERO.round_to_multiple_of_power_of_2(pow, rm), (T::ZERO, Equal) ); }); } fn round_to_multiple_of_power_of_2_properties_helper_signed< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >() { signed_unsigned_rounding_mode_triple_gen_var_1::().test_properties(|(n, pow, rm)| { let (rounded, o) = n.round_to_multiple_of_power_of_2(pow, rm); let mut mut_n = n; assert_eq!(mut_n.round_to_multiple_of_power_of_2_assign(pow, rm), o); assert_eq!(mut_n, rounded); assert!(rounded.divisible_by_power_of_2(pow)); assert_eq!(rounded.cmp(&n), o); match (n >= S::ZERO, rm) { (_, Floor) | (true, Down) | (false, Up) => { assert_ne!(o, Greater); } (_, Ceiling) | (true, Up) | (false, Down) => { assert_ne!(o, Less); } (_, Exact) => assert_eq!(o, Equal), _ => {} } match rm { Floor => assert!(rounded <= n), Ceiling => assert!(rounded >= n), Down => assert!(rounded.le_abs(&n)), Up => assert!(rounded.ge_abs(&n)), Exact => assert_eq!(rounded, n), Nearest => { if let Some(k) = S::ONE.arithmetic_checked_shl(pow) { let mut closest = None; let mut second_closest = None; if rounded <= n { if let Some(above) = rounded.checked_add(k) { closest = Some(n - rounded); second_closest = Some(above - n); } } else if let Some(below) = rounded.checked_sub(k) { closest = Some(rounded - n); second_closest = Some(n - below); } if let (Some(closest), Some(second_closest)) = (closest, second_closest) { assert!(closest <= second_closest); if closest == second_closest { assert!(!rounded.get_bit(pow)); } } } } } if o == Equal { for rm in exhaustive_rounding_modes() { assert_eq!(n.round_to_multiple_of_power_of_2(pow, rm), (rounded, Equal)); } } else { assert_panic!(n.round_to_multiple_of_power_of_2(pow, Exact)); } }); signed_unsigned_pair_gen_var_1::().test_properties(|(n, pow)| { if pow < S::WIDTH { if let Some(shifted) = n.arithmetic_checked_shl(pow) { let so = (shifted, Equal); assert_eq!(shifted.round_to_multiple_of_power_of_2(pow, Down), so); assert_eq!(shifted.round_to_multiple_of_power_of_2(pow, Up), so); assert_eq!(shifted.round_to_multiple_of_power_of_2(pow, Floor), so); assert_eq!(shifted.round_to_multiple_of_power_of_2(pow, Ceiling), so); assert_eq!(shifted.round_to_multiple_of_power_of_2(pow, Nearest), so); assert_eq!(shifted.round_to_multiple_of_power_of_2(pow, Exact), so); } } }); signed_unsigned_pair_gen_var_8::().test_properties(|(n, pow)| { let down = n.round_to_multiple_of_power_of_2(pow, Down); assert_eq!(down.1, if n >= S::ZERO { Less } else { Greater }); if let Some(k) = S::ONE.arithmetic_checked_shl(pow) { if let Some(up) = if n >= S::ZERO { down.0.checked_add(k) } else { down.0.checked_sub(k) } { let up = (up, if n >= S::ZERO { Greater } else { Less }); assert_eq!(n.round_to_multiple_of_power_of_2(pow, Up), up); if n >= S::ZERO { assert_eq!(n.round_to_multiple_of_power_of_2(pow, Floor), down); assert_eq!(n.round_to_multiple_of_power_of_2(pow, Ceiling), up); } else { assert_eq!(n.round_to_multiple_of_power_of_2(pow, Floor), up); assert_eq!(n.round_to_multiple_of_power_of_2(pow, Ceiling), down); } let nearest = n.round_to_multiple_of_power_of_2(pow, Nearest); assert!(nearest == down || nearest == up); } } }); signed_unsigned_pair_gen_var_16::().test_properties(|(i, pow)| { if let Some(shift) = pow.checked_add(S::WIDTH - 1) { assert_eq!( i.round_to_multiple_of_power_of_2(shift, Down), (S::ZERO, if i == S::ZERO { Equal } else { Less }) ); assert_eq!( i.round_to_multiple_of_power_of_2(shift, Floor), (S::ZERO, if i == S::ZERO { Equal } else { Less }) ); if let Some(extra_shift) = shift.checked_add(1) { assert_eq!( i.round_to_multiple_of_power_of_2(extra_shift, Nearest), (S::ZERO, if i == S::ZERO { Equal } else { Less }) ); } } }); signed_unsigned_pair_gen_var_17::().test_properties(|(i, pow)| { if let Some(shift) = pow.checked_add(S::WIDTH - 1) { assert_eq!( i.round_to_multiple_of_power_of_2(shift, Down), (S::ZERO, if i == S::ZERO { Equal } else { Greater }) ); assert_eq!( i.round_to_multiple_of_power_of_2(shift, Ceiling), (S::ZERO, if i == S::ZERO { Equal } else { Greater }) ); if let Some(extra_shift) = shift.checked_add(1) { assert_eq!( i.round_to_multiple_of_power_of_2(extra_shift, Nearest), (S::ZERO, if i == S::ZERO { Equal } else { Greater }) ); } } }); signed_rounding_mode_pair_gen::().test_properties(|(n, rm)| { assert_eq!(n.round_to_multiple_of_power_of_2(0, rm), (n, Equal)); }); unsigned_rounding_mode_pair_gen().test_properties(|(pow, rm)| { assert_eq!( S::ZERO.round_to_multiple_of_power_of_2(pow, rm), (S::ZERO, Equal) ); }); } #[test] fn round_to_multiple_of_power_of_2_properties() { apply_fn_to_unsigneds!(round_to_multiple_of_power_of_2_properties_helper_unsigned); apply_fn_to_unsigned_signed_pairs!(round_to_multiple_of_power_of_2_properties_helper_signed); } malachite-base-0.4.16/tests/num/arithmetic/saturating_abs.rs000064400000000000000000000030151046102023000222200ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::test_util::generators::signed_gen; fn saturating_abs_assign_helper() { let test = |n: T, out| { assert_eq!(n.saturating_abs(), out); let mut n = n; n.saturating_abs_assign(); assert_eq!(n, out); }; test(T::ZERO, T::ZERO); test(T::ONE, T::ONE); test(T::exact_from(100), T::exact_from(100)); test(T::MAX, T::MAX); test(T::NEGATIVE_ONE, T::ONE); test(T::exact_from(-100), T::exact_from(100)); test(T::MIN, T::MAX); } #[test] fn test_saturating_abs_assign() { apply_fn_to_signeds!(saturating_abs_assign_helper); } fn saturating_abs_properties_helper() { signed_gen::().test_properties(|n| { let mut abs = n; abs.saturating_abs_assign(); assert_eq!(abs, n.saturating_abs()); assert_eq!(abs.saturating_abs(), abs); if n != T::MIN { assert_eq!(n.abs(), abs); } assert_eq!(abs == n, n >= T::ZERO); }); } #[test] fn saturating_abs_properties() { apply_fn_to_signeds!(saturating_abs_properties_helper); } malachite-base-0.4.16/tests/num/arithmetic/saturating_add.rs000064400000000000000000000037341046102023000222130ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{signed_pair_gen, unsigned_pair_gen_var_27}; #[test] fn test_saturating_add() { fn test(x: T, y: T, out: T) { assert_eq!(x.saturating_add(y), out); let mut x = x; x.saturating_add_assign(y); assert_eq!(x, out); } test::(123, 456, 579); test::(123, 200, 255); test::(123, -456, -333); test::(123, 45, 127); test::(-123, -45, -128); } fn saturating_add_properties_helper_unsigned() { unsigned_pair_gen_var_27::().test_properties(|(x, y)| { let mut sum = x; sum.saturating_add_assign(y); assert_eq!(sum, x.saturating_add(y)); assert_eq!(y.saturating_add(x), sum); assert!(sum >= x); assert!(sum >= y); if sum < T::MAX { assert_eq!(sum, x + y); } }); } fn saturating_add_properties_helper_signed() { signed_pair_gen::().test_properties(|(x, y)| { let mut sum = x; sum.saturating_add_assign(y); assert_eq!(sum, x.saturating_add(y)); assert_eq!(y.saturating_add(x), sum); if sum > T::MIN && sum < T::MAX { assert_eq!(sum, x + y); } }); } #[test] fn saturating_add_properties() { apply_fn_to_unsigneds!(saturating_add_properties_helper_unsigned); apply_fn_to_signeds!(saturating_add_properties_helper_signed); } malachite-base-0.4.16/tests/num/arithmetic/saturating_add_mul.rs000064400000000000000000000061451046102023000230670ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ signed_pair_gen, signed_triple_gen, unsigned_pair_gen_var_27, unsigned_triple_gen_var_19, }; #[test] fn test_saturating_add_mul() { fn test(x: T, y: T, z: T, out: T) { assert_eq!(x.saturating_add_mul(y, z), out); let mut x = x; x.saturating_add_mul_assign(y, z); assert_eq!(x, out); } test::(2, 3, 7, 23); test::(7, 5, 10, 57); test::(123, 456, 789, 359907); test::(123, -456, 789, -359661); test::(-123, 456, 789, 359661); test::(127, -2, 100, -73); test::(-127, 2, 100, 73); test::(-128, 1, 0, -128); test::(2, 20, 20, 255); test::(-127, -2, 100, -128); test::(127, 1, 100, 127); test::(-127, -1, 100, -128); test::(-127, -10, 100, -128); } fn saturating_add_mul_properties_helper_unsigned() { unsigned_triple_gen_var_19::().test_properties(|(x, y, z)| { let result = x.saturating_add_mul(y, z); let mut x_alt = x; x_alt.saturating_add_mul_assign(y, z); assert_eq!(x_alt, result); assert_eq!(x.saturating_add_mul(z, y), result); assert!(result >= x); }); unsigned_pair_gen_var_27::().test_properties(|(a, b)| { assert_eq!(a.saturating_add_mul(T::ZERO, b), a); assert_eq!(a.saturating_add_mul(T::ONE, b), a.saturating_add(b)); assert_eq!(T::ZERO.saturating_add_mul(a, b), a.saturating_mul(b)); assert_eq!(a.saturating_add_mul(b, T::ZERO), a); assert_eq!(a.saturating_add_mul(b, T::ONE), a.saturating_add(b)); }); } fn saturating_add_mul_properties_helper_signed() { signed_triple_gen::().test_properties(|(x, y, z)| { let result = x.saturating_add_mul(y, z); let mut x_alt = x; x_alt.saturating_add_mul_assign(y, z); assert_eq!(x_alt, result); assert_eq!(x.saturating_add_mul(z, y), result); }); signed_pair_gen::().test_properties(|(a, b)| { assert_eq!(a.saturating_add_mul(T::ZERO, b), a); assert_eq!(a.saturating_add_mul(T::ONE, b), a.saturating_add(b)); assert_eq!(T::ZERO.saturating_add_mul(a, b), a.saturating_mul(b)); assert_eq!(a.saturating_add_mul(b, T::ZERO), a); assert_eq!(a.saturating_add_mul(b, T::ONE), a.saturating_add(b)); }); } #[test] fn saturating_add_mul_properties() { apply_fn_to_unsigneds!(saturating_add_mul_properties_helper_unsigned); apply_fn_to_signeds!(saturating_add_mul_properties_helper_signed); } malachite-base-0.4.16/tests/num/arithmetic/saturating_mul.rs000064400000000000000000000041051046102023000222510ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{signed_pair_gen, unsigned_pair_gen_var_27}; #[test] fn test_saturating_mul() { fn test(x: T, y: T, out: T) { assert_eq!(x.saturating_mul(y), out); let mut x = x; x.saturating_mul_assign(y); assert_eq!(x, out); } test::(123, 456, 56088); test::(123, 200, 255); test::(123, -45, -5535); test::(123, 45, 127); test::(-123, 45, -128); } fn saturating_mul_properties_helper_unsigned() { unsigned_pair_gen_var_27::().test_properties(|(x, y)| { let mut product = x; product.saturating_mul_assign(y); assert_eq!(product, x.saturating_mul(y)); assert_eq!(y.saturating_mul(x), product); assert!(product == T::ZERO || product >= x); assert!(product == T::ZERO || product >= y); if product < T::MAX { assert_eq!(product, x * y); } }); } fn saturating_mul_properties_helper_signed() { signed_pair_gen::().test_properties(|(x, y)| { let mut product = x; product.saturating_mul_assign(y); assert_eq!(product, x.saturating_mul(y)); assert_eq!(y.saturating_mul(x), product); if product > T::MIN && product < T::MAX { assert_eq!(product, x * y); } }); } #[test] fn saturating_mul_properties() { apply_fn_to_unsigneds!(saturating_mul_properties_helper_unsigned); apply_fn_to_signeds!(saturating_mul_properties_helper_signed); } malachite-base-0.4.16/tests/num/arithmetic/saturating_neg.rs000064400000000000000000000027741046102023000222370ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::test_util::generators::signed_gen; fn saturating_neg_assign_helper() { let test = |n: T, out| { assert_eq!(n.saturating_neg(), out); let mut n = n; n.saturating_neg_assign(); assert_eq!(n, out); }; test(T::ZERO, T::ZERO); test(T::ONE, T::NEGATIVE_ONE); test(T::exact_from(100), T::exact_from(-100)); test(T::MAX, T::MIN + T::ONE); test(T::NEGATIVE_ONE, T::ONE); test(T::exact_from(-100), T::exact_from(100)); test(T::MIN, T::MAX); } #[test] fn test_saturating_neg_assign() { apply_fn_to_signeds!(saturating_neg_assign_helper); } fn saturating_neg_properties_helper() { signed_gen::().test_properties(|n| { let mut neg = n; neg.saturating_neg_assign(); assert_eq!(neg, n.saturating_neg()); if n != T::MIN { assert_eq!(neg.saturating_neg(), n); } assert_eq!(neg == n, n == T::ZERO); }); } #[test] fn saturating_neg_properties() { apply_fn_to_signeds!(saturating_neg_properties_helper); } malachite-base-0.4.16/tests/num/arithmetic/saturating_pow.rs000064400000000000000000000050441046102023000222640ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{signed_unsigned_pair_gen, unsigned_pair_gen}; #[test] fn test_saturating_pow() { fn test(x: T, y: u64, out: T) { assert_eq!(x.saturating_pow(y), out); let mut x = x; x.saturating_pow_assign(y); assert_eq!(x, out); } test::(0, 0, 1); test::(123, 0, 1); test::(123, 1, 123); test::(0, 123, 0); test::(1, 123, 1); test::(-1, 123, -1); test::(-1, 124, 1); test::(3, 3, 27); test::(-10, 9, -1000000000); test::(-10, 10, i32::MAX); test::(-10, 9, i16::MIN); test::(10, 9, i16::MAX); test::(123, 456, i64::MAX); test::(0, u64::MAX, 0); test::(1, u64::MAX, 1); test::(123, u64::MAX, u64::MAX); test::(0, u64::MAX, 0); test::(1, u64::MAX, 1); test::(-1, u64::MAX, -1); test::(-1, u64::MAX - 1, 1); test::(123, u64::MAX, i64::MAX); test::(-123, u64::MAX, i64::MIN); test::(-123, u64::MAX - 1, i64::MAX); } fn saturating_pow_properties_helper_unsigned() { unsigned_pair_gen::().test_properties(|(x, y)| { let mut power = x; power.saturating_pow_assign(y); assert_eq!(power, x.saturating_pow(y)); if y != 0 { assert!(power >= x); } if power < T::MAX { assert_eq!(power, x.pow(y)); } }); } fn saturating_pow_properties_helper_signed() { signed_unsigned_pair_gen::().test_properties(|(x, y)| { let mut power = x; power.saturating_pow_assign(y); assert_eq!(power, x.saturating_pow(y)); if power > T::MIN && power < T::MAX { assert_eq!(power, x.pow(y)); } }); } #[test] fn saturating_pow_properties() { apply_fn_to_unsigneds!(saturating_pow_properties_helper_unsigned); apply_fn_to_signeds!(saturating_pow_properties_helper_signed); } malachite-base-0.4.16/tests/num/arithmetic/saturating_square.rs000064400000000000000000000043401046102023000227550ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{signed_gen, unsigned_gen}; #[test] fn test_saturating_square() { fn test(x: T, out: T) { assert_eq!(x.saturating_square(), out); let mut x = x; x.saturating_square_assign(); assert_eq!(x, out); } test::(0, 0); test::(1, 1); test::(2, 4); test::(3, 9); test::(10, 100); test::(123, 15129); test::(1000, 1000000); test::(-1, 1); test::(-2, 4); test::(-3, 9); test::(-10, 100); test::(-123, 15129); test::(-1000, 1000000); test::(1000, u16::MAX); test::(-1000, i16::MAX); } fn saturating_square_properties_helper_unsigned() { unsigned_gen::().test_properties(|x| { let mut square = x; square.saturating_square_assign(); assert_eq!(square, x.saturating_square()); assert_eq!(square, x.saturating_pow(2)); assert!(square >= x); if square < T::MAX { assert_eq!(square, x.square()); } }); } fn saturating_square_properties_helper_signed() { signed_gen::().test_properties(|x| { let mut square = x; square.saturating_square_assign(); assert_eq!(square, x.saturating_square()); assert_eq!(square, x.saturating_pow(2)); if square > T::MIN && square < T::MAX { assert_eq!(square, x.square()); } }); } #[test] fn saturating_square_properties() { apply_fn_to_unsigneds!(saturating_square_properties_helper_unsigned); apply_fn_to_signeds!(saturating_square_properties_helper_signed); } malachite-base-0.4.16/tests/num/arithmetic/saturating_sub.rs000064400000000000000000000035571046102023000222570ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{signed_pair_gen, unsigned_pair_gen_var_27}; #[test] fn test_saturating_sub() { fn test(x: T, y: T, out: T) { assert_eq!(x.saturating_sub(y), out); let mut x = x; x.saturating_sub_assign(y); assert_eq!(x, out); } test::(456, 123, 333); test::(123, 200, 0); test::(123, -456, 579); test::(123, -45, 127); test::(-123, 45, -128); } fn saturating_sub_properties_helper_unsigned() { unsigned_pair_gen_var_27::().test_properties(|(x, y)| { let mut diff = x; diff.saturating_sub_assign(y); assert_eq!(diff, x.saturating_sub(y)); assert!(diff <= x); if diff > T::ZERO { assert_eq!(diff, x - y); } }); } fn saturating_sub_properties_helper_signed() { signed_pair_gen::().test_properties(|(x, y)| { let mut diff = x; diff.saturating_sub_assign(y); assert_eq!(diff, x.saturating_sub(y)); if diff > T::MIN && diff < T::MAX { assert_eq!(diff, x - y); } }); } #[test] fn saturating_sub_properties() { apply_fn_to_unsigneds!(saturating_sub_properties_helper_unsigned); apply_fn_to_signeds!(saturating_sub_properties_helper_signed); } malachite-base-0.4.16/tests/num/arithmetic/saturating_sub_mul.rs000064400000000000000000000057201046102023000231260ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ signed_pair_gen, signed_triple_gen, unsigned_pair_gen_var_27, unsigned_triple_gen_var_19, }; #[test] fn test_saturating_sub_mul() { fn test(x: T, y: T, z: T, out: T) { assert_eq!(x.saturating_sub_mul(y, z), out); let mut x = x; x.saturating_sub_mul_assign(y, z); assert_eq!(x, out); } test::(100, 3, 7, 79); test::(60, 5, 10, 10); test::(1000000, 456, 789, 640216); test::(123, -456, 789, 359907); test::(-123, 456, 789, -359907); test::(127, 2, 100, -73); test::(-127, -2, 100, 73); test::(-128, 1, 0, -128); test::(2, 10, 5, 0); test::(-127, 2, 100, -128); test::(-127, 1, 100, -128); test::(127, -1, 100, 127); test::(127, -10, 100, 127); } fn saturating_sub_mul_properties_helper_unsigned() { unsigned_triple_gen_var_19::().test_properties(|(x, y, z)| { let result = x.saturating_sub_mul(y, z); let mut x_alt = x; x_alt.saturating_sub_mul_assign(y, z); assert_eq!(x_alt, result); assert_eq!(x.saturating_sub_mul(z, y), result); assert!(result <= x); }); unsigned_pair_gen_var_27::().test_properties(|(a, b)| { assert_eq!(a.saturating_sub_mul(T::ZERO, b), a); assert_eq!(a.saturating_sub_mul(T::ONE, b), a.saturating_sub(b)); assert_eq!(a.saturating_sub_mul(b, T::ZERO), a); assert_eq!(a.saturating_sub_mul(b, T::ONE), a.saturating_sub(b)); }); } fn saturating_sub_mul_properties_helper_signed() { signed_triple_gen::().test_properties(|(x, y, z)| { let result = x.saturating_sub_mul(y, z); let mut x_alt = x; x_alt.saturating_sub_mul_assign(y, z); assert_eq!(x_alt, result); assert_eq!(x.saturating_sub_mul(z, y), result); }); signed_pair_gen::().test_properties(|(a, b)| { assert_eq!(a.saturating_sub_mul(T::ZERO, b), a); assert_eq!(a.saturating_sub_mul(T::ONE, b), a.saturating_sub(b)); assert_eq!(a.saturating_sub_mul(b, T::ZERO), a); assert_eq!(a.saturating_sub_mul(b, T::ONE), a.saturating_sub(b)); }); } #[test] fn saturating_sub_mul_properties() { apply_fn_to_unsigneds!(saturating_sub_mul_properties_helper_unsigned); apply_fn_to_signeds!(saturating_sub_mul_properties_helper_signed); } malachite-base-0.4.16/tests/num/arithmetic/shl_round.rs000064400000000000000000000644211046102023000212170ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::{ ArithmeticCheckedShr, ShlRound, ShlRoundAssign, ShrRound, UnsignedAbs, }; use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::ExactFrom; use malachite_base::rounding_modes::exhaustive::exhaustive_rounding_modes; use malachite_base::rounding_modes::RoundingMode::{self, *}; use malachite_base::test_util::generators::{ signed_rounding_mode_pair_gen, signed_signed_rounding_mode_triple_gen_var_4, unsigned_rounding_mode_pair_gen, unsigned_signed_rounding_mode_triple_gen_var_2, }; use std::cmp::Ordering::{self, *}; use std::panic::catch_unwind; #[test] fn test_shl_round() { fn test + ShlRoundAssign, U: PrimitiveInt>( t: T, u: U, rm: RoundingMode, out: T, o: Ordering, ) { assert_eq!(t.shl_round(u, rm), (out, o)); let mut t = t; assert_eq!(t.shl_round_assign(u, rm), o); assert_eq!(t, out); } test::(0, 0, Down, 0, Equal); test::(0, 0, Up, 0, Equal); test::(0, 0, Floor, 0, Equal); test::(0, 0, Ceiling, 0, Equal); test::(0, 0, Nearest, 0, Equal); test::(0, 0, Exact, 0, Equal); test::(0, -10, Down, 0, Equal); test::(0, -10, Up, 0, Equal); test::(0, -10, Floor, 0, Equal); test::(0, -10, Ceiling, 0, Equal); test::(0, -10, Nearest, 0, Equal); test::(0, -10, Exact, 0, Equal); test::(123, 0, Down, 123, Equal); test::(123, 0, Up, 123, Equal); test::(123, 0, Floor, 123, Equal); test::(123, 0, Ceiling, 123, Equal); test::(123, 0, Nearest, 123, Equal); test::(123, 0, Exact, 123, Equal); test::(245, -1, Down, 122, Less); test::(245, -1, Up, 123, Greater); test::(245, -1, Floor, 122, Less); test::(245, -1, Ceiling, 123, Greater); test::(245, -1, Nearest, 122, Less); test::(246, -1, Down, 123, Equal); test::(246, -1, Up, 123, Equal); test::(246, -1, Floor, 123, Equal); test::(246, -1, Ceiling, 123, Equal); test::(246, -1, Nearest, 123, Equal); test::(246, -1, Exact, 123, Equal); test::(247, -1, Down, 123, Less); test::(247, -1, Up, 124, Greater); test::(247, -1, Floor, 123, Less); test::(247, -1, Ceiling, 124, Greater); test::(247, -1, Nearest, 124, Greater); test::(491, -2, Down, 122, Less); test::(491, -2, Up, 123, Greater); test::(491, -2, Floor, 122, Less); test::(491, -2, Ceiling, 123, Greater); test::(491, -2, Nearest, 123, Greater); test::(492, -2, Down, 123, Equal); test::(492, -2, Up, 123, Equal); test::(492, -2, Floor, 123, Equal); test::(492, -2, Ceiling, 123, Equal); test::(492, -2, Nearest, 123, Equal); test::(492, -2, Exact, 123, Equal); test::(493, -2, Down, 123, Less); test::(493, -2, Up, 124, Greater); test::(493, -2, Floor, 123, Less); test::(493, -2, Ceiling, 124, Greater); test::(493, -2, Nearest, 123, Less); test::(4127195135, -25, Down, 122, Less); test::(4127195135, -25, Up, 123, Greater); test::(4127195135, -25, Floor, 122, Less); test::(4127195135, -25, Ceiling, 123, Greater); test::(4127195135, -25, Nearest, 123, Greater); test::(4127195136, -25, Down, 123, Equal); test::(4127195136, -25, Up, 123, Equal); test::(4127195136, -25, Floor, 123, Equal); test::(4127195136, -25, Ceiling, 123, Equal); test::(4127195136, -25, Nearest, 123, Equal); test::(4127195136, -25, Exact, 123, Equal); test::(4127195137, -25, Down, 123, Less); test::(4127195137, -25, Up, 124, Greater); test::(4127195137, -25, Floor, 123, Less); test::(4127195137, -25, Ceiling, 124, Greater); test::(4127195137, -25, Nearest, 123, Less); test::(8254390271, -26, Down, 122, Less); test::(8254390271, -26, Up, 123, Greater); test::(8254390271, -26, Floor, 122, Less); test::(8254390271, -26, Ceiling, 123, Greater); test::(8254390271, -26, Nearest, 123, Greater); test::(8254390272, -26, Down, 123, Equal); test::(8254390272, -26, Up, 123, Equal); test::(8254390272, -26, Floor, 123, Equal); test::(8254390272, -26, Ceiling, 123, Equal); test::(8254390272, -26, Nearest, 123, Equal); test::(8254390272, -26, Exact, 123, Equal); test::(8254390273, -26, Down, 123, Less); test::(8254390273, -26, Up, 124, Greater); test::(8254390273, -26, Floor, 123, Less); test::(8254390273, -26, Ceiling, 124, Greater); test::(8254390273, -26, Nearest, 123, Less); test::(0xffffffff, -1, Down, 0x7fffffff, Less); test::(0xffffffff, -1, Up, 0x80000000, Greater); test::(0xffffffff, -1, Floor, 0x7fffffff, Less); test::(0xffffffff, -1, Ceiling, 0x80000000, Greater); test::(0xffffffff, -1, Nearest, 0x80000000, Greater); test::(0x100000000, -1, Down, 0x80000000, Equal); test::(0x100000000, -1, Up, 0x80000000, Equal); test::(0x100000000, -1, Floor, 0x80000000, Equal); test::(0x100000000, -1, Ceiling, 0x80000000, Equal); test::(0x100000000, -1, Nearest, 0x80000000, Equal); test::(0x100000000, -1, Exact, 0x80000000, Equal); test::(0x100000001, -1, Down, 0x80000000, Less); test::(0x100000001, -1, Up, 0x80000001, Greater); test::(0x100000001, -1, Floor, 0x80000000, Less); test::(0x100000001, -1, Ceiling, 0x80000001, Greater); test::(0x100000001, -1, Nearest, 0x80000000, Less); test::(1000000000000, 0, Down, 1000000000000, Equal); test::(1000000000000, 0, Up, 1000000000000, Equal); test::(1000000000000, 0, Floor, 1000000000000, Equal); test::(1000000000000, 0, Ceiling, 1000000000000, Equal); test::(1000000000000, 0, Nearest, 1000000000000, Equal); test::(1000000000000, 0, Exact, 1000000000000, Equal); test::(7999999999999, -3, Down, 999999999999, Less); test::(7999999999999, -3, Up, 1000000000000, Greater); test::(7999999999999, -3, Floor, 999999999999, Less); test::(7999999999999, -3, Ceiling, 1000000000000, Greater); test::(7999999999999, -3, Nearest, 1000000000000, Greater); test::(8000000000000, -3, Down, 1000000000000, Equal); test::(8000000000000, -3, Up, 1000000000000, Equal); test::(8000000000000, -3, Floor, 1000000000000, Equal); test::(8000000000000, -3, Ceiling, 1000000000000, Equal); test::(8000000000000, -3, Nearest, 1000000000000, Equal); test::(8000000000000, -3, Exact, 1000000000000, Equal); test::(8000000000001, -3, Down, 1000000000000, Less); test::(8000000000001, -3, Up, 1000000000001, Greater); test::(8000000000001, -3, Floor, 1000000000000, Less); test::(8000000000001, -3, Ceiling, 1000000000001, Greater); test::(8000000000001, -3, Nearest, 1000000000000, Less); test::(1000000000000, -10, Down, 976562500, Equal); test::(1000000000000, -10, Up, 976562500, Equal); test::(1000000000000, -10, Floor, 976562500, Equal); test::(1000000000000, -10, Ceiling, 976562500, Equal); test::(1000000000000, -10, Nearest, 976562500, Equal); test::(1000000000000, -10, Exact, 976562500, Equal); test::(980657949, -72, Down, 0, Less); test::(980657949, -72, Up, 1, Greater); test::(980657949, -72, Floor, 0, Less); test::(980657949, -72, Ceiling, 1, Greater); test::(980657949, -72, Nearest, 0, Less); test::(0xffffffff, -31, Down, 1, Less); test::(0xffffffff, -31, Up, 2, Greater); test::(0xffffffff, -31, Floor, 1, Less); test::(0xffffffff, -31, Ceiling, 2, Greater); test::(0xffffffff, -31, Nearest, 2, Greater); test::(0xffffffff, -32, Down, 0, Less); test::(0xffffffff, -32, Up, 1, Greater); test::(0xffffffff, -32, Floor, 0, Less); test::(0xffffffff, -32, Ceiling, 1, Greater); test::(0xffffffff, -32, Nearest, 1, Greater); test::(0x100000000, -32, Down, 1, Equal); test::(0x100000000, -32, Up, 1, Equal); test::(0x100000000, -32, Floor, 1, Equal); test::(0x100000000, -32, Ceiling, 1, Equal); test::(0x100000000, -32, Nearest, 1, Equal); test::(0x100000000, -32, Exact, 1, Equal); test::(0x100000000, -33, Down, 0, Less); test::(0x100000000, -33, Up, 1, Greater); test::(0x100000000, -33, Floor, 0, Less); test::(0x100000000, -33, Ceiling, 1, Greater); test::(0x100000000, -33, Nearest, 0, Less); test::(0, 10, Exact, 0, Equal); test::(123, 1, Exact, 246, Equal); test::(123, 2, Exact, 492, Equal); test::(123, 25, Exact, 4127195136, Equal); test::(123, 26, Exact, 8254390272, Equal); test::(123, 100, Exact, 0, Equal); test::(0x80000000, 1, Exact, 0x100000000, Equal); test::(1000000000000, 3, Exact, 8000000000000, Equal); test::(1000000000000, 24, Exact, 16777216000000000000, Equal); test::(1000000000000, 25, Exact, 33554432000000000000, Equal); test::(1000000000000, 31, Exact, 2147483648000000000000, Equal); test::(1000000000000, 32, Exact, 4294967296000000000000, Equal); test::(1000000000000, 33, Exact, 8589934592000000000000, Equal); test::(1000000000000, 100, Exact, 0, Equal); test::(-123, 0, Down, -123, Equal); test::(-123, 0, Up, -123, Equal); test::(-123, 0, Floor, -123, Equal); test::(-123, 0, Ceiling, -123, Equal); test::(-123, 0, Nearest, -123, Equal); test::(-123, 0, Exact, -123, Equal); test::(-245, -1, Down, -122, Greater); test::(-245, -1, Up, -123, Less); test::(-245, -1, Floor, -123, Less); test::(-245, -1, Ceiling, -122, Greater); test::(-245, -1, Nearest, -122, Greater); test::(-246, -1, Down, -123, Equal); test::(-246, -1, Up, -123, Equal); test::(-246, -1, Floor, -123, Equal); test::(-246, -1, Ceiling, -123, Equal); test::(-246, -1, Nearest, -123, Equal); test::(-246, -1, Exact, -123, Equal); test::(-247, -1, Down, -123, Greater); test::(-247, -1, Up, -124, Less); test::(-247, -1, Floor, -124, Less); test::(-247, -1, Ceiling, -123, Greater); test::(-247, -1, Nearest, -124, Less); test::(-491, -2, Down, -122, Greater); test::(-491, -2, Up, -123, Less); test::(-491, -2, Floor, -123, Less); test::(-491, -2, Ceiling, -122, Greater); test::(-491, -2, Nearest, -123, Less); test::(-492, -2, Down, -123, Equal); test::(-492, -2, Up, -123, Equal); test::(-492, -2, Floor, -123, Equal); test::(-492, -2, Ceiling, -123, Equal); test::(-492, -2, Nearest, -123, Equal); test::(-492, -2, Exact, -123, Equal); test::(-493, -2, Down, -123, Greater); test::(-493, -2, Up, -124, Less); test::(-493, -2, Floor, -124, Less); test::(-493, -2, Ceiling, -123, Greater); test::(-493, -2, Nearest, -123, Greater); test::(-4127195135, -25, Down, -122, Greater); test::(-4127195135, -25, Up, -123, Less); test::(-4127195135, -25, Floor, -123, Less); test::(-4127195135, -25, Ceiling, -122, Greater); test::(-4127195135, -25, Nearest, -123, Less); test::(-4127195136, -25, Down, -123, Equal); test::(-4127195136, -25, Up, -123, Equal); test::(-4127195136, -25, Floor, -123, Equal); test::(-4127195136, -25, Ceiling, -123, Equal); test::(-4127195136, -25, Nearest, -123, Equal); test::(-4127195136, -25, Exact, -123, Equal); test::(-4127195137, -25, Down, -123, Greater); test::(-4127195137, -25, Up, -124, Less); test::(-4127195137, -25, Floor, -124, Less); test::(-4127195137, -25, Ceiling, -123, Greater); test::(-4127195137, -25, Nearest, -123, Greater); test::(-8254390271, -26, Down, -122, Greater); test::(-8254390271, -26, Up, -123, Less); test::(-8254390271, -26, Floor, -123, Less); test::(-8254390271, -26, Ceiling, -122, Greater); test::(-8254390271, -26, Nearest, -123, Less); test::(-8254390272, -26, Down, -123, Equal); test::(-8254390272, -26, Up, -123, Equal); test::(-8254390272, -26, Floor, -123, Equal); test::(-8254390272, -26, Ceiling, -123, Equal); test::(-8254390272, -26, Nearest, -123, Equal); test::(-8254390272, -26, Exact, -123, Equal); test::(-8254390273, -26, Down, -123, Greater); test::(-8254390273, -26, Up, -124, Less); test::(-8254390273, -26, Floor, -124, Less); test::(-8254390273, -26, Ceiling, -123, Greater); test::(-8254390273, -26, Nearest, -123, Greater); test::(-0xffffffff, -1, Down, -0x7fffffff, Greater); test::(-0xffffffff, -1, Up, -0x80000000, Less); test::(-0xffffffff, -1, Floor, -0x80000000, Less); test::(-0xffffffff, -1, Ceiling, -0x7fffffff, Greater); test::(-0xffffffff, -1, Nearest, -0x80000000, Less); test::(-0x100000000, -1, Down, -0x80000000, Equal); test::(-0x100000000, -1, Up, -0x80000000, Equal); test::(-0x100000000, -1, Floor, -0x80000000, Equal); test::(-0x100000000, -1, Ceiling, -0x80000000, Equal); test::(-0x100000000, -1, Nearest, -0x80000000, Equal); test::(-0x100000000, -1, Exact, -0x80000000, Equal); test::(-0x100000001, -1, Down, -0x80000000, Greater); test::(-0x100000001, -1, Up, -0x80000001, Less); test::(-0x100000001, -1, Floor, -0x80000001, Less); test::(-0x100000001, -1, Ceiling, -0x80000000, Greater); test::(-0x100000001, -1, Nearest, -0x80000000, Greater); test::(-1000000000000, 0, Down, -1000000000000, Equal); test::(-1000000000000, 0, Up, -1000000000000, Equal); test::(-1000000000000, 0, Floor, -1000000000000, Equal); test::(-1000000000000, 0, Ceiling, -1000000000000, Equal); test::(-1000000000000, 0, Nearest, -1000000000000, Equal); test::(-1000000000000, 0, Exact, -1000000000000, Equal); test::(-7999999999999, -3, Down, -999999999999, Greater); test::(-7999999999999, -3, Up, -1000000000000, Less); test::(-7999999999999, -3, Floor, -1000000000000, Less); test::(-7999999999999, -3, Ceiling, -999999999999, Greater); test::(-7999999999999, -3, Nearest, -1000000000000, Less); test::(-8000000000000, -3, Down, -1000000000000, Equal); test::(-8000000000000, -3, Up, -1000000000000, Equal); test::(-8000000000000, -3, Floor, -1000000000000, Equal); test::(-8000000000000, -3, Ceiling, -1000000000000, Equal); test::(-8000000000000, -3, Nearest, -1000000000000, Equal); test::(-8000000000000, -3, Exact, -1000000000000, Equal); test::(-8000000000001, -3, Down, -1000000000000, Greater); test::(-8000000000001, -3, Up, -1000000000001, Less); test::(-8000000000001, -3, Floor, -1000000000001, Less); test::(-8000000000001, -3, Ceiling, -1000000000000, Greater); test::(-8000000000001, -3, Nearest, -1000000000000, Greater); test::(-16777216000000000000, -24, Down, -1000000000000, Equal); test::(-16777216000000000000, -24, Up, -1000000000000, Equal); test::(-16777216000000000000, -24, Floor, -1000000000000, Equal); test::(-16777216000000000000, -24, Ceiling, -1000000000000, Equal); test::(-16777216000000000000, -24, Nearest, -1000000000000, Equal); test::(-16777216000000000000, -24, Exact, -1000000000000, Equal); test::(-33554432000000000000, -25, Down, -1000000000000, Equal); test::(-33554432000000000000, -25, Up, -1000000000000, Equal); test::(-33554432000000000000, -25, Floor, -1000000000000, Equal); test::(-33554432000000000000, -25, Ceiling, -1000000000000, Equal); test::(-33554432000000000000, -25, Nearest, -1000000000000, Equal); test::(-33554432000000000000, -25, Exact, -1000000000000, Equal); test::(-2147483648000000000000, -31, Down, -1000000000000, Equal); test::(-2147483648000000000000, -31, Up, -1000000000000, Equal); test::(-2147483648000000000000, -31, Floor, -1000000000000, Equal); test::(-2147483648000000000000, -31, Ceiling, -1000000000000, Equal); test::(-2147483648000000000000, -31, Nearest, -1000000000000, Equal); test::(-2147483648000000000000, -31, Exact, -1000000000000, Equal); test::(-4294967296000000000000, -32, Down, -1000000000000, Equal); test::(-4294967296000000000000, -32, Up, -1000000000000, Equal); test::(-4294967296000000000000, -32, Floor, -1000000000000, Equal); test::(-4294967296000000000000, -32, Ceiling, -1000000000000, Equal); test::(-4294967296000000000000, -32, Nearest, -1000000000000, Equal); test::(-4294967296000000000000, -32, Exact, -1000000000000, Equal); test::(-8589934592000000000000, -33, Down, -1000000000000, Equal); test::(-8589934592000000000000, -33, Up, -1000000000000, Equal); test::(-8589934592000000000000, -33, Floor, -1000000000000, Equal); test::(-8589934592000000000000, -33, Ceiling, -1000000000000, Equal); test::(-8589934592000000000000, -33, Nearest, -1000000000000, Equal); test::(-8589934592000000000000, -33, Exact, -1000000000000, Equal); test::(-1000000000000, -10, Down, -976562500, Equal); test::(-1000000000000, -10, Up, -976562500, Equal); test::(-1000000000000, -10, Floor, -976562500, Equal); test::(-1000000000000, -10, Ceiling, -976562500, Equal); test::(-1000000000000, -10, Nearest, -976562500, Equal); test::(-1000000000000, -10, Exact, -976562500, Equal); test::(-980657949, -72, Down, 0, Greater); test::(-980657949, -72, Up, -1, Less); test::(-980657949, -72, Floor, -1, Less); test::(-980657949, -72, Ceiling, 0, Greater); test::(-980657949, -72, Nearest, 0, Greater); test::(-0xffffffff, -31, Down, -1, Greater); test::(-0xffffffff, -31, Up, -2, Less); test::(-0xffffffff, -31, Floor, -2, Less); test::(-0xffffffff, -31, Ceiling, -1, Greater); test::(-0xffffffff, -31, Nearest, -2, Less); test::(-0xffffffff, -32, Down, 0, Greater); test::(-0xffffffff, -32, Up, -1, Less); test::(-0xffffffff, -32, Floor, -1, Less); test::(-0xffffffff, -32, Ceiling, 0, Greater); test::(-0xffffffff, -32, Nearest, -1, Less); test::(-0x100000000, -32, Down, -1, Equal); test::(-0x100000000, -32, Up, -1, Equal); test::(-0x100000000, -32, Floor, -1, Equal); test::(-0x100000000, -32, Ceiling, -1, Equal); test::(-0x100000000, -32, Nearest, -1, Equal); test::(-0x100000000, -32, Exact, -1, Equal); test::(-0x100000000, -33, Down, 0, Greater); test::(-0x100000000, -33, Up, -1, Less); test::(-0x100000000, -33, Floor, -1, Less); test::(-0x100000000, -33, Ceiling, 0, Greater); test::(-0x100000000, -33, Nearest, 0, Greater); test::(-123, 1, Exact, -246, Equal); test::(-123, 2, Exact, -492, Equal); test::(-123, 25, Exact, -4127195136, Equal); test::(-123, 26, Exact, -8254390272, Equal); test::(-0x80000000, 1, Exact, -0x100000000, Equal); test::(-1000000000000, 3, Exact, -8000000000000, Equal); test::(-1000000000000, 24, Exact, -16777216000000000000, Equal); test::(-1000000000000, 25, Exact, -33554432000000000000, Equal); test::(-1000000000000, 31, Exact, -2147483648000000000000, Equal); test::(-1000000000000, 32, Exact, -4294967296000000000000, Equal); test::(-1000000000000, 33, Exact, -8589934592000000000000, Equal); } fn shl_round_fail_helper< T: PrimitiveInt + ShlRound + ShlRoundAssign, U: PrimitiveSigned, >() { assert_panic!(T::exact_from(123).shl_round(U::NEGATIVE_ONE, Exact)); assert_panic!(T::exact_from(123).shl_round(U::exact_from(-100), Exact)); assert_panic!(T::exact_from(123).shl_round_assign(U::NEGATIVE_ONE, Exact)); assert_panic!(T::exact_from(123).shl_round_assign(U::exact_from(-100), Exact)); } #[test] fn shl_round_fail() { apply_fn_to_primitive_ints_and_signeds!(shl_round_fail_helper); } fn shl_round_properties_helper_unsigned_signed< T: ArithmeticCheckedShr + PrimitiveUnsigned + ShlRound + ShlRoundAssign + ShrRound, U: PrimitiveSigned, >() where u64: TryFrom<::Output>, { unsigned_signed_rounding_mode_triple_gen_var_2::().test_properties(|(n, i, rm)| { let mut mut_n = n; let o = mut_n.shl_round_assign(i, rm); let shifted = mut_n; assert_eq!(n.shl_round(i, rm), (shifted, o)); if i < U::ZERO { assert!(shifted <= n); } if i != U::MIN { assert_eq!(n.shr_round(-i, rm), (shifted, o)); } assert_eq!( i >= U::ZERO || n.divisible_by_power_of_2(u64::exact_from(i.unsigned_abs())), o == Equal ); if i < U::ZERO { if let Some(m) = shifted.arithmetic_checked_shr(i) { assert_eq!(m.cmp(&n), o); } } if o == Equal { for rm in exhaustive_rounding_modes() { assert_eq!(n.shl_round(i, rm), (shifted, Equal)); } } else { assert_panic!(n.shl_round(i, Exact)); } }); unsigned_rounding_mode_pair_gen::().test_properties(|(n, rm)| { assert_eq!(n.shl_round(U::ZERO, rm), (n, Equal)); }); signed_rounding_mode_pair_gen::().test_properties(|(i, rm)| { assert_eq!(T::ZERO.shl_round(i, rm), (T::ZERO, Equal)); }); } fn shl_round_properties_helper_signed_signed< T: ArithmeticCheckedShr + PrimitiveSigned + ShlRound + ShlRoundAssign + ShrRound, U: PrimitiveSigned, >() where u64: TryFrom<::Output>, { signed_signed_rounding_mode_triple_gen_var_4::().test_properties(|(n, i, rm)| { let mut mut_n = n; let o = mut_n.shl_round_assign(i, rm); let shifted = mut_n; assert_eq!(n.shl_round(i, rm), (shifted, o)); if i < U::ZERO { assert!(shifted.le_abs(&n)); } if i != U::MIN { assert_eq!(n.shr_round(-i, rm), (shifted, o)); } assert_eq!( i >= U::ZERO || n.divisible_by_power_of_2(u64::exact_from(i.unsigned_abs())), o == Equal ); if i < U::ZERO { if let Some(m) = shifted.arithmetic_checked_shr(i) { assert_eq!(m.cmp(&n), o); } } if o == Equal { for rm in exhaustive_rounding_modes() { assert_eq!(n.shl_round(i, rm), (shifted, Equal)); } } else { assert_panic!(n.shl_round(i, Exact)); } }); signed_rounding_mode_pair_gen::().test_properties(|(n, rm)| { assert_eq!(n.shl_round(U::ZERO, rm), (n, Equal)); }); signed_rounding_mode_pair_gen::().test_properties(|(i, rm)| { assert_eq!(T::ZERO.shl_round(i, rm), (T::ZERO, Equal)); }); } #[test] fn shl_round_properties() { apply_fn_to_unsigneds_and_signeds!(shl_round_properties_helper_unsigned_signed); apply_fn_to_signeds_and_signeds!(shl_round_properties_helper_signed_signed); } malachite-base-0.4.16/tests/num/arithmetic/shr_round.rs000064400000000000000000001022521046102023000212200ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::{ ArithmeticCheckedShl, ShlRound, ShrRound, ShrRoundAssign, }; use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::WrappingFrom; use malachite_base::rounding_modes::exhaustive::exhaustive_rounding_modes; use malachite_base::rounding_modes::RoundingMode::{self, *}; use malachite_base::test_util::generators::{ signed_rounding_mode_pair_gen, signed_signed_rounding_mode_triple_gen_var_3, signed_unsigned_pair_gen_var_1, signed_unsigned_pair_gen_var_16, signed_unsigned_pair_gen_var_17, signed_unsigned_pair_gen_var_8, signed_unsigned_rounding_mode_triple_gen_var_2, unsigned_pair_gen_var_14, unsigned_pair_gen_var_2, unsigned_pair_gen_var_21, unsigned_rounding_mode_pair_gen, unsigned_signed_rounding_mode_triple_gen_var_1, unsigned_unsigned_rounding_mode_triple_gen_var_4, }; use std::cmp::Ordering::{self, *}; use std::panic::catch_unwind; #[test] fn test_shr_round() { fn test + ShrRoundAssign, U: PrimitiveInt>( t: T, u: U, rm: RoundingMode, out: T, o: Ordering, ) { assert_eq!(t.shr_round(u, rm), (out, o)); let mut t = t; assert_eq!(t.shr_round_assign(u, rm), o); assert_eq!(t, out); } test::(0, 0, Down, 0, Equal); test::(0, 0, Up, 0, Equal); test::(0, 0, Floor, 0, Equal); test::(0, 0, Ceiling, 0, Equal); test::(0, 0, Nearest, 0, Equal); test::(0, 0, Exact, 0, Equal); test::(0, 10, Down, 0, Equal); test::(0, 10, Up, 0, Equal); test::(0, 10, Floor, 0, Equal); test::(0, 10, Ceiling, 0, Equal); test::(0, 10, Nearest, 0, Equal); test::(0, 10, Exact, 0, Equal); test::(123, 0, Down, 123, Equal); test::(123, 0, Up, 123, Equal); test::(123, 0, Floor, 123, Equal); test::(123, 0, Ceiling, 123, Equal); test::(123, 0, Nearest, 123, Equal); test::(123, 0, Exact, 123, Equal); test::(245, 1, Down, 122, Less); test::(245, 1, Up, 123, Greater); test::(245, 1, Floor, 122, Less); test::(245, 1, Ceiling, 123, Greater); test::(245, 1, Nearest, 122, Less); test::(246, 1, Down, 123, Equal); test::(246, 1, Up, 123, Equal); test::(246, 1, Floor, 123, Equal); test::(246, 1, Ceiling, 123, Equal); test::(246, 1, Nearest, 123, Equal); test::(246, 1, Exact, 123, Equal); test::(247, 1, Down, 123, Less); test::(247, 1, Up, 124, Greater); test::(247, 1, Floor, 123, Less); test::(247, 1, Ceiling, 124, Greater); test::(247, 1, Nearest, 124, Greater); test::(491, 2, Down, 122, Less); test::(491, 2, Up, 123, Greater); test::(491, 2, Floor, 122, Less); test::(491, 2, Ceiling, 123, Greater); test::(491, 2, Nearest, 123, Greater); test::(492, 2, Down, 123, Equal); test::(492, 2, Up, 123, Equal); test::(492, 2, Floor, 123, Equal); test::(492, 2, Ceiling, 123, Equal); test::(492, 2, Nearest, 123, Equal); test::(492, 2, Exact, 123, Equal); test::(493, 2, Down, 123, Less); test::(493, 2, Up, 124, Greater); test::(493, 2, Floor, 123, Less); test::(493, 2, Ceiling, 124, Greater); test::(493, 2, Nearest, 123, Less); test::(4127195135, 25, Down, 122, Less); test::(4127195135, 25, Up, 123, Greater); test::(4127195135, 25, Floor, 122, Less); test::(4127195135, 25, Ceiling, 123, Greater); test::(4127195135, 25, Nearest, 123, Greater); test::(4127195136, 25, Down, 123, Equal); test::(4127195136, 25, Up, 123, Equal); test::(4127195136, 25, Floor, 123, Equal); test::(4127195136, 25, Ceiling, 123, Equal); test::(4127195136, 25, Nearest, 123, Equal); test::(4127195136, 25, Exact, 123, Equal); test::(4127195137, 25, Down, 123, Less); test::(4127195137, 25, Up, 124, Greater); test::(4127195137, 25, Floor, 123, Less); test::(4127195137, 25, Ceiling, 124, Greater); test::(4127195137, 25, Nearest, 123, Less); test::(8254390271, 26, Down, 122, Less); test::(8254390271, 26, Up, 123, Greater); test::(8254390271, 26, Floor, 122, Less); test::(8254390271, 26, Ceiling, 123, Greater); test::(8254390271, 26, Nearest, 123, Greater); test::(8254390272, 26, Down, 123, Equal); test::(8254390272, 26, Up, 123, Equal); test::(8254390272, 26, Floor, 123, Equal); test::(8254390272, 26, Ceiling, 123, Equal); test::(8254390272, 26, Nearest, 123, Equal); test::(8254390272, 26, Exact, 123, Equal); test::(8254390273, 26, Down, 123, Less); test::(8254390273, 26, Up, 124, Greater); test::(8254390273, 26, Floor, 123, Less); test::(8254390273, 26, Ceiling, 124, Greater); test::(8254390273, 26, Nearest, 123, Less); test::(0xffffffff, 1, Down, 0x7fffffff, Less); test::(0xffffffff, 1, Up, 0x80000000, Greater); test::(0xffffffff, 1, Floor, 0x7fffffff, Less); test::(0xffffffff, 1, Ceiling, 0x80000000, Greater); test::(0xffffffff, 1, Nearest, 0x80000000, Greater); test::(0x100000000, 1, Down, 0x80000000, Equal); test::(0x100000000, 1, Up, 0x80000000, Equal); test::(0x100000000, 1, Floor, 0x80000000, Equal); test::(0x100000000, 1, Ceiling, 0x80000000, Equal); test::(0x100000000, 1, Nearest, 0x80000000, Equal); test::(0x100000000, 1, Exact, 0x80000000, Equal); test::(0x100000001, 1, Down, 0x80000000, Less); test::(0x100000001, 1, Up, 0x80000001, Greater); test::(0x100000001, 1, Floor, 0x80000000, Less); test::(0x100000001, 1, Ceiling, 0x80000001, Greater); test::(0x100000001, 1, Nearest, 0x80000000, Less); test::(1000000000000, 0, Down, 1000000000000, Equal); test::(1000000000000, 0, Up, 1000000000000, Equal); test::(1000000000000, 0, Floor, 1000000000000, Equal); test::(1000000000000, 0, Ceiling, 1000000000000, Equal); test::(1000000000000, 0, Nearest, 1000000000000, Equal); test::(1000000000000, 0, Exact, 1000000000000, Equal); test::(7999999999999, 3, Down, 999999999999, Less); test::(7999999999999, 3, Up, 1000000000000, Greater); test::(7999999999999, 3, Floor, 999999999999, Less); test::(7999999999999, 3, Ceiling, 1000000000000, Greater); test::(7999999999999, 3, Nearest, 1000000000000, Greater); test::(8000000000000, 3, Down, 1000000000000, Equal); test::(8000000000000, 3, Up, 1000000000000, Equal); test::(8000000000000, 3, Floor, 1000000000000, Equal); test::(8000000000000, 3, Ceiling, 1000000000000, Equal); test::(8000000000000, 3, Nearest, 1000000000000, Equal); test::(8000000000000, 3, Exact, 1000000000000, Equal); test::(8000000000001, 3, Down, 1000000000000, Less); test::(8000000000001, 3, Up, 1000000000001, Greater); test::(8000000000001, 3, Floor, 1000000000000, Less); test::(8000000000001, 3, Ceiling, 1000000000001, Greater); test::(8000000000001, 3, Nearest, 1000000000000, Less); test::(1000000000000, 10, Down, 976562500, Equal); test::(1000000000000, 10, Up, 976562500, Equal); test::(1000000000000, 10, Floor, 976562500, Equal); test::(1000000000000, 10, Ceiling, 976562500, Equal); test::(1000000000000, 10, Nearest, 976562500, Equal); test::(1000000000000, 10, Exact, 976562500, Equal); test::(980657949, 72, Down, 0, Less); test::(980657949, 72, Up, 1, Greater); test::(980657949, 72, Floor, 0, Less); test::(980657949, 72, Ceiling, 1, Greater); test::(980657949, 72, Nearest, 0, Less); test::(0xffffffff, 31, Down, 1, Less); test::(0xffffffff, 31, Up, 2, Greater); test::(0xffffffff, 31, Floor, 1, Less); test::(0xffffffff, 31, Ceiling, 2, Greater); test::(0xffffffff, 31, Nearest, 2, Greater); test::(0xffffffff, 32, Down, 0, Less); test::(0xffffffff, 32, Up, 1, Greater); test::(0xffffffff, 32, Floor, 0, Less); test::(0xffffffff, 32, Ceiling, 1, Greater); test::(0xffffffff, 32, Nearest, 1, Greater); test::(0x100000000, 32, Down, 1, Equal); test::(0x100000000, 32, Up, 1, Equal); test::(0x100000000, 32, Floor, 1, Equal); test::(0x100000000, 32, Ceiling, 1, Equal); test::(0x100000000, 32, Nearest, 1, Equal); test::(0x100000000, 32, Exact, 1, Equal); test::(0x100000000, 33, Down, 0, Less); test::(0x100000000, 33, Up, 1, Greater); test::(0x100000000, 33, Floor, 0, Less); test::(0x100000000, 33, Ceiling, 1, Greater); test::(0x100000000, 33, Nearest, 0, Less); test::(0, -10, Exact, 0, Equal); test::(123, -1, Exact, 246, Equal); test::(123, -2, Exact, 492, Equal); test::(123, -25, Exact, 4127195136, Equal); test::(123, -26, Exact, 8254390272, Equal); test::(123, -100, Exact, 0, Equal); test::(0x80000000, -1, Exact, 0x100000000, Equal); test::(1000000000000, -3, Exact, 8000000000000, Equal); test::(1000000000000, -24, Exact, 16777216000000000000, Equal); test::(1000000000000, -25, Exact, 33554432000000000000, Equal); test::(1000000000000, -31, Exact, 2147483648000000000000, Equal); test::(1000000000000, -32, Exact, 4294967296000000000000, Equal); test::(1000000000000, -33, Exact, 8589934592000000000000, Equal); test::(1000000000000, -100, Exact, 0, Equal); test::(-123, 0, Down, -123, Equal); test::(-123, 0, Up, -123, Equal); test::(-123, 0, Floor, -123, Equal); test::(-123, 0, Ceiling, -123, Equal); test::(-123, 0, Nearest, -123, Equal); test::(-123, 0, Exact, -123, Equal); test::(-245, 1, Down, -122, Greater); test::(-245, 1, Up, -123, Less); test::(-245, 1, Floor, -123, Less); test::(-245, 1, Ceiling, -122, Greater); test::(-245, 1, Nearest, -122, Greater); test::(-246, 1, Down, -123, Equal); test::(-246, 1, Up, -123, Equal); test::(-246, 1, Floor, -123, Equal); test::(-246, 1, Ceiling, -123, Equal); test::(-246, 1, Nearest, -123, Equal); test::(-246, 1, Exact, -123, Equal); test::(-247, 1, Down, -123, Greater); test::(-247, 1, Up, -124, Less); test::(-247, 1, Floor, -124, Less); test::(-247, 1, Ceiling, -123, Greater); test::(-247, 1, Nearest, -124, Less); test::(-491, 2, Down, -122, Greater); test::(-491, 2, Up, -123, Less); test::(-491, 2, Floor, -123, Less); test::(-491, 2, Ceiling, -122, Greater); test::(-491, 2, Nearest, -123, Less); test::(-492, 2, Down, -123, Equal); test::(-492, 2, Up, -123, Equal); test::(-492, 2, Floor, -123, Equal); test::(-492, 2, Ceiling, -123, Equal); test::(-492, 2, Nearest, -123, Equal); test::(-492, 2, Exact, -123, Equal); test::(-493, 2, Down, -123, Greater); test::(-493, 2, Up, -124, Less); test::(-493, 2, Floor, -124, Less); test::(-493, 2, Ceiling, -123, Greater); test::(-493, 2, Nearest, -123, Greater); test::(-4127195135, 25, Down, -122, Greater); test::(-4127195135, 25, Up, -123, Less); test::(-4127195135, 25, Floor, -123, Less); test::(-4127195135, 25, Ceiling, -122, Greater); test::(-4127195135, 25, Nearest, -123, Less); test::(-4127195136, 25, Down, -123, Equal); test::(-4127195136, 25, Up, -123, Equal); test::(-4127195136, 25, Floor, -123, Equal); test::(-4127195136, 25, Ceiling, -123, Equal); test::(-4127195136, 25, Nearest, -123, Equal); test::(-4127195136, 25, Exact, -123, Equal); test::(-4127195137, 25, Down, -123, Greater); test::(-4127195137, 25, Up, -124, Less); test::(-4127195137, 25, Floor, -124, Less); test::(-4127195137, 25, Ceiling, -123, Greater); test::(-4127195137, 25, Nearest, -123, Greater); test::(-8254390271, 26, Down, -122, Greater); test::(-8254390271, 26, Up, -123, Less); test::(-8254390271, 26, Floor, -123, Less); test::(-8254390271, 26, Ceiling, -122, Greater); test::(-8254390271, 26, Nearest, -123, Less); test::(-8254390272, 26, Down, -123, Equal); test::(-8254390272, 26, Up, -123, Equal); test::(-8254390272, 26, Floor, -123, Equal); test::(-8254390272, 26, Ceiling, -123, Equal); test::(-8254390272, 26, Nearest, -123, Equal); test::(-8254390272, 26, Exact, -123, Equal); test::(-8254390273, 26, Down, -123, Greater); test::(-8254390273, 26, Up, -124, Less); test::(-8254390273, 26, Floor, -124, Less); test::(-8254390273, 26, Ceiling, -123, Greater); test::(-8254390273, 26, Nearest, -123, Greater); test::(-0xffffffff, 1, Down, -0x7fffffff, Greater); test::(-0xffffffff, 1, Up, -0x80000000, Less); test::(-0xffffffff, 1, Floor, -0x80000000, Less); test::(-0xffffffff, 1, Ceiling, -0x7fffffff, Greater); test::(-0xffffffff, 1, Nearest, -0x80000000, Less); test::(-0x100000000, 1, Down, -0x80000000, Equal); test::(-0x100000000, 1, Up, -0x80000000, Equal); test::(-0x100000000, 1, Floor, -0x80000000, Equal); test::(-0x100000000, 1, Ceiling, -0x80000000, Equal); test::(-0x100000000, 1, Nearest, -0x80000000, Equal); test::(-0x100000000, 1, Exact, -0x80000000, Equal); test::(-0x100000001, 1, Down, -0x80000000, Greater); test::(-0x100000001, 1, Up, -0x80000001, Less); test::(-0x100000001, 1, Floor, -0x80000001, Less); test::(-0x100000001, 1, Ceiling, -0x80000000, Greater); test::(-0x100000001, 1, Nearest, -0x80000000, Greater); test::(-1000000000000, 0, Down, -1000000000000, Equal); test::(-1000000000000, 0, Up, -1000000000000, Equal); test::(-1000000000000, 0, Floor, -1000000000000, Equal); test::(-1000000000000, 0, Ceiling, -1000000000000, Equal); test::(-1000000000000, 0, Nearest, -1000000000000, Equal); test::(-1000000000000, 0, Exact, -1000000000000, Equal); test::(-7999999999999, 3, Down, -999999999999, Greater); test::(-7999999999999, 3, Up, -1000000000000, Less); test::(-7999999999999, 3, Floor, -1000000000000, Less); test::(-7999999999999, 3, Ceiling, -999999999999, Greater); test::(-7999999999999, 3, Nearest, -1000000000000, Less); test::(-8000000000000, 3, Down, -1000000000000, Equal); test::(-8000000000000, 3, Up, -1000000000000, Equal); test::(-8000000000000, 3, Floor, -1000000000000, Equal); test::(-8000000000000, 3, Ceiling, -1000000000000, Equal); test::(-8000000000000, 3, Nearest, -1000000000000, Equal); test::(-8000000000000, 3, Exact, -1000000000000, Equal); test::(-8000000000001, 3, Down, -1000000000000, Greater); test::(-8000000000001, 3, Up, -1000000000001, Less); test::(-8000000000001, 3, Floor, -1000000000001, Less); test::(-8000000000001, 3, Ceiling, -1000000000000, Greater); test::(-8000000000001, 3, Nearest, -1000000000000, Greater); test::(-16777216000000000000, 24, Down, -1000000000000, Equal); test::(-16777216000000000000, 24, Up, -1000000000000, Equal); test::(-16777216000000000000, 24, Floor, -1000000000000, Equal); test::(-16777216000000000000, 24, Ceiling, -1000000000000, Equal); test::(-16777216000000000000, 24, Nearest, -1000000000000, Equal); test::(-16777216000000000000, 24, Exact, -1000000000000, Equal); test::(-33554432000000000000, 25, Down, -1000000000000, Equal); test::(-33554432000000000000, 25, Up, -1000000000000, Equal); test::(-33554432000000000000, 25, Floor, -1000000000000, Equal); test::(-33554432000000000000, 25, Ceiling, -1000000000000, Equal); test::(-33554432000000000000, 25, Nearest, -1000000000000, Equal); test::(-33554432000000000000, 25, Exact, -1000000000000, Equal); test::(-2147483648000000000000, 31, Down, -1000000000000, Equal); test::(-2147483648000000000000, 31, Up, -1000000000000, Equal); test::(-2147483648000000000000, 31, Floor, -1000000000000, Equal); test::(-2147483648000000000000, 31, Ceiling, -1000000000000, Equal); test::(-2147483648000000000000, 31, Nearest, -1000000000000, Equal); test::(-2147483648000000000000, 31, Exact, -1000000000000, Equal); test::(-4294967296000000000000, 32, Down, -1000000000000, Equal); test::(-4294967296000000000000, 32, Up, -1000000000000, Equal); test::(-4294967296000000000000, 32, Floor, -1000000000000, Equal); test::(-4294967296000000000000, 32, Ceiling, -1000000000000, Equal); test::(-4294967296000000000000, 32, Nearest, -1000000000000, Equal); test::(-4294967296000000000000, 32, Exact, -1000000000000, Equal); test::(-8589934592000000000000, 33, Down, -1000000000000, Equal); test::(-8589934592000000000000, 33, Up, -1000000000000, Equal); test::(-8589934592000000000000, 33, Floor, -1000000000000, Equal); test::(-8589934592000000000000, 33, Ceiling, -1000000000000, Equal); test::(-8589934592000000000000, 33, Nearest, -1000000000000, Equal); test::(-8589934592000000000000, 33, Exact, -1000000000000, Equal); test::(-1000000000000, 10, Down, -976562500, Equal); test::(-1000000000000, 10, Up, -976562500, Equal); test::(-1000000000000, 10, Floor, -976562500, Equal); test::(-1000000000000, 10, Ceiling, -976562500, Equal); test::(-1000000000000, 10, Nearest, -976562500, Equal); test::(-1000000000000, 10, Exact, -976562500, Equal); test::(-980657949, 72, Down, 0, Greater); test::(-980657949, 72, Up, -1, Less); test::(-980657949, 72, Floor, -1, Less); test::(-980657949, 72, Ceiling, 0, Greater); test::(-980657949, 72, Nearest, 0, Greater); test::(-0xffffffff, 31, Down, -1, Greater); test::(-0xffffffff, 31, Up, -2, Less); test::(-0xffffffff, 31, Floor, -2, Less); test::(-0xffffffff, 31, Ceiling, -1, Greater); test::(-0xffffffff, 31, Nearest, -2, Less); test::(-0xffffffff, 32, Down, 0, Greater); test::(-0xffffffff, 32, Up, -1, Less); test::(-0xffffffff, 32, Floor, -1, Less); test::(-0xffffffff, 32, Ceiling, 0, Greater); test::(-0xffffffff, 32, Nearest, -1, Less); test::(-0x100000000, 32, Down, -1, Equal); test::(-0x100000000, 32, Up, -1, Equal); test::(-0x100000000, 32, Floor, -1, Equal); test::(-0x100000000, 32, Ceiling, -1, Equal); test::(-0x100000000, 32, Nearest, -1, Equal); test::(-0x100000000, 32, Exact, -1, Equal); test::(-0x100000000, 33, Down, 0, Greater); test::(-0x100000000, 33, Up, -1, Less); test::(-0x100000000, 33, Floor, -1, Less); test::(-0x100000000, 33, Ceiling, 0, Greater); test::(-0x100000000, 33, Nearest, 0, Greater); test::(-123, -1, Exact, -246, Equal); test::(-123, -2, Exact, -492, Equal); test::(-123, -25, Exact, -4127195136, Equal); test::(-123, -26, Exact, -8254390272, Equal); test::(-0x80000000, -1, Exact, -0x100000000, Equal); test::(-1000000000000, -3, Exact, -8000000000000, Equal); test::(-1000000000000, -24, Exact, -16777216000000000000, Equal); test::(-1000000000000, -25, Exact, -33554432000000000000, Equal); test::(-1000000000000, -31, Exact, -2147483648000000000000, Equal); test::(-1000000000000, -32, Exact, -4294967296000000000000, Equal); test::(-1000000000000, -33, Exact, -8589934592000000000000, Equal); } fn shr_round_fail_helper< T: PrimitiveInt + ShrRound + ShrRoundAssign, U: PrimitiveInt, >() { assert_panic!(T::exact_from(123).shr_round(U::ONE, Exact)); assert_panic!(T::exact_from(123).shr_round(U::exact_from(100), Exact)); assert_panic!(T::exact_from(123).shr_round_assign(U::ONE, Exact)); assert_panic!(T::exact_from(123).shr_round_assign(U::exact_from(100), Exact)); } #[test] fn shr_round_fail() { apply_fn_to_primitive_ints_and_primitive_ints!(shr_round_fail_helper); } fn shr_round_properties_helper_unsigned_unsigned< T: ArithmeticCheckedShl + PrimitiveUnsigned + ShrRound + ShrRoundAssign, U: PrimitiveUnsigned, >() { unsigned_unsigned_rounding_mode_triple_gen_var_4::().test_properties(|(n, u, rm)| { let mut mut_n = n; let o = mut_n.shr_round_assign(u, rm); let shifted = mut_n; assert_eq!(n.shr_round(u, rm), (shifted, o)); assert!(shifted <= n); assert_eq!(n.divisible_by_power_of_2(u.exact_into()), o == Equal); if let Some(m) = shifted.arithmetic_checked_shl(u) { assert_eq!(m.cmp(&n), o); } if o == Equal { for rm in exhaustive_rounding_modes() { assert_eq!(n.shr_round(u, rm), (shifted, Equal)); } } else { assert_panic!(n.shr_round(u, Exact)); } }); unsigned_pair_gen_var_2::().test_properties(|(n, u)| { if u < U::exact_from(T::WIDTH) { let no = (n, Equal); if let Some(shifted) = n.arithmetic_checked_shl(u) { assert_eq!(shifted.shr_round(u, Down), no); assert_eq!(shifted.shr_round(u, Up), no); assert_eq!(shifted.shr_round(u, Floor), no); assert_eq!(shifted.shr_round(u, Ceiling), no); assert_eq!(shifted.shr_round(u, Nearest), no); assert_eq!(shifted.shr_round(u, Exact), no); } } }); unsigned_pair_gen_var_14::().test_properties(|(n, u)| { let down = n.shr_round(u, Down); assert_eq!(down.1, Less); if let Some(up) = down.0.checked_add(T::ONE) { let up = (up, Greater); assert_eq!(n.shr_round(u, Up), up); assert_eq!(n.shr_round(u, Floor), down); assert_eq!(n.shr_round(u, Ceiling), up); let nearest = n.shr_round(u, Nearest); assert!(nearest == down || nearest == up); } }); unsigned_pair_gen_var_21::().test_properties(|(t, u)| { if let Some(shift) = u.checked_add(U::exact_from(T::WIDTH)) { assert_eq!(t.shr_round(shift, Down), (T::ZERO, Less)); assert_eq!(t.shr_round(shift, Floor), (T::ZERO, Less)); assert_eq!(t.shr_round(shift, Up), (T::ONE, Greater)); assert_eq!(t.shr_round(shift, Ceiling), (T::ONE, Greater)); if let Some(extra_shift) = shift.checked_add(U::ONE) { assert_eq!(t.shr_round(extra_shift, Nearest), (T::ZERO, Less)); } } }); unsigned_rounding_mode_pair_gen::().test_properties(|(n, rm)| { assert_eq!(n.shr_round(U::ZERO, rm), (n, Equal)); }); unsigned_rounding_mode_pair_gen::().test_properties(|(u, rm)| { assert_eq!(T::ZERO.shr_round(u, rm), (T::ZERO, Equal)); }); } fn shr_round_properties_helper_unsigned_signed< T: ArithmeticCheckedShl + PrimitiveUnsigned + ShlRound + ShrRound + ShrRoundAssign, U: PrimitiveSigned, >() { unsigned_signed_rounding_mode_triple_gen_var_1::().test_properties(|(n, i, rm)| { let mut mut_n = n; let o = mut_n.shr_round_assign(i, rm); let shifted = mut_n; assert_eq!(n.shr_round(i, rm), (shifted, o)); if i >= U::ZERO { assert!(shifted <= n); } if i != U::MIN { assert_eq!(n.shl_round(-i, rm), (shifted, o)); } assert_eq!( i <= U::ZERO || n.divisible_by_power_of_2(i.exact_into()), o == Equal ); if i >= U::ZERO { if let Some(m) = shifted.arithmetic_checked_shl(i) { assert_eq!(m.cmp(&n), o); } } if o == Equal { for rm in exhaustive_rounding_modes() { assert_eq!(n.shr_round(i, rm), (shifted, Equal)); } } else { assert_panic!(n.shr_round(i, Exact)); } }); unsigned_rounding_mode_pair_gen::().test_properties(|(n, rm)| { assert_eq!(n.shr_round(U::ZERO, rm), (n, Equal)); }); signed_rounding_mode_pair_gen::().test_properties(|(i, rm)| { assert_eq!(T::ZERO.shr_round(i, rm), (T::ZERO, Equal)); }); } fn shr_round_properties_helper_signed_unsigned< V: PrimitiveUnsigned, U: PrimitiveUnsigned + WrappingFrom, S: ArithmeticCheckedShl + PrimitiveSigned + ShrRound + ShrRoundAssign + WrappingFrom, >() { signed_unsigned_rounding_mode_triple_gen_var_2::().test_properties(|(n, u, rm)| { let mut mut_n = n; let o = mut_n.shr_round_assign(u, rm); let shifted = mut_n; assert_eq!(n.shr_round(u, rm), (shifted, o)); assert!(shifted.le_abs(&n)); if n != S::MIN { let (x, o_alt) = (-n).shr_round(u, -rm); if x != S::MIN { assert_eq!(-x, shifted); } assert_eq!(o_alt, o.reverse()); } assert_eq!(n.divisible_by_power_of_2(u.exact_into()), o == Equal); if let Some(m) = shifted.arithmetic_checked_shl(u) { assert_eq!(m.cmp(&n), o); } if o == Equal { for rm in exhaustive_rounding_modes() { assert_eq!(n.shr_round(u, rm), (shifted, Equal)); } } else { assert_panic!(n.shr_round(u, Exact)); } }); signed_unsigned_pair_gen_var_1::().test_properties(|(n, u)| { if u < V::exact_from(S::WIDTH) { let no = (n, Equal); if let Some(shifted) = n.arithmetic_checked_shl(u) { assert_eq!(shifted.shr_round(u, Down), no); assert_eq!(shifted.shr_round(u, Up), no); assert_eq!(shifted.shr_round(u, Floor), no); assert_eq!(shifted.shr_round(u, Ceiling), no); assert_eq!(shifted.shr_round(u, Nearest), no); assert_eq!(shifted.shr_round(u, Exact), no); } } }); signed_unsigned_pair_gen_var_8::().test_properties(|(n, u)| { let floor = n.shr_round(u, Floor); assert_eq!(floor.1, Less); if let Some(ceiling) = floor.0.checked_add(S::ONE) { let ceiling = (ceiling, Greater); assert_eq!(n.shr_round(u, Ceiling), ceiling); if n >= S::ZERO { assert_eq!(n.shr_round(u, Up), ceiling); assert_eq!(n.shr_round(u, Down), floor); } else { assert_eq!(n.shr_round(u, Up), floor); assert_eq!(n.shr_round(u, Down), ceiling); } let nearest = n.shr_round(u, Nearest); assert!(nearest == floor || nearest == ceiling); } }); signed_unsigned_pair_gen_var_16::().test_properties(|(i, u)| { if let Some(shift) = u.checked_add(V::exact_from(S::WIDTH - 1)) { assert_eq!(i.shr_round(shift, Down), (S::ZERO, Less)); assert_eq!(i.shr_round(shift, Floor), (S::ZERO, Less)); assert_eq!(i.shr_round(shift, Up), (S::ONE, Greater)); assert_eq!(i.shr_round(shift, Ceiling), (S::ONE, Greater)); if let Some(extra_shift) = shift.checked_add(V::ONE) { assert_eq!(i.shr_round(extra_shift, Nearest), (S::ZERO, Less)); } } }); signed_unsigned_pair_gen_var_17::().test_properties(|(i, u)| { if let Some(shift) = u.checked_add(V::exact_from(S::WIDTH - 1)) { assert_eq!(i.shr_round(shift, Down), (S::ZERO, Greater)); assert_eq!(i.shr_round(shift, Floor), (S::NEGATIVE_ONE, Less)); assert_eq!(i.shr_round(shift, Up), (S::NEGATIVE_ONE, Less)); assert_eq!(i.shr_round(shift, Ceiling), (S::ZERO, Greater)); if let Some(extra_shift) = shift.checked_add(V::ONE) { assert_eq!(i.shr_round(extra_shift, Nearest), (S::ZERO, Greater)); } } }); signed_rounding_mode_pair_gen::().test_properties(|(n, rm)| { assert_eq!(n.shr_round(V::ZERO, rm), (n, Equal)); }); unsigned_rounding_mode_pair_gen::().test_properties(|(u, rm)| { assert_eq!(S::ZERO.shr_round(u, rm), (S::ZERO, Equal)); }); } fn shr_round_properties_helper_signed_signed< T: ArithmeticCheckedShl + PrimitiveSigned + ShlRound + ShrRound + ShrRoundAssign, U: PrimitiveSigned, >() { signed_signed_rounding_mode_triple_gen_var_3::().test_properties(|(n, i, rm)| { let mut mut_n = n; let o = mut_n.shr_round_assign(i, rm); let shifted = mut_n; assert_eq!(n.shr_round(i, rm), (shifted, o)); if i >= U::ZERO { assert!(shifted.le_abs(&n)); } if i != U::MIN { assert_eq!(n.shl_round(-i, rm), (shifted, o)); } assert_eq!( i <= U::ZERO || n.divisible_by_power_of_2(i.exact_into()), o == Equal ); if i >= U::ZERO { if let Some(m) = shifted.arithmetic_checked_shl(i) { assert_eq!(m.cmp(&n), o); } } if o == Equal { for rm in exhaustive_rounding_modes() { assert_eq!(n.shr_round(i, rm), (shifted, Equal)); } } else { assert_panic!(n.shr_round(i, Exact)); } }); signed_rounding_mode_pair_gen::().test_properties(|(n, rm)| { assert_eq!(n.shr_round(U::ZERO, rm), (n, Equal)); }); signed_rounding_mode_pair_gen::().test_properties(|(i, rm)| { assert_eq!(T::ZERO.shr_round(i, rm), (T::ZERO, Equal)); }); } #[test] fn shr_round_properties() { apply_fn_to_unsigneds_and_unsigneds!(shr_round_properties_helper_unsigned_unsigned); apply_fn_to_unsigneds_and_signeds!(shr_round_properties_helper_unsigned_signed); apply_fn_to_unsigneds_and_unsigned_signed_pairs!(shr_round_properties_helper_signed_unsigned); apply_fn_to_signeds_and_signeds!(shr_round_properties_helper_signed_signed); } malachite-base-0.4.16/tests/num/arithmetic/sign.rs000064400000000000000000000052421046102023000201560ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{primitive_float_gen, signed_gen, unsigned_gen}; use std::cmp::Ordering::*; fn sign_helper_primitive_int() { let test = |n: T, out| { assert_eq!(n.sign(), out); }; test(T::ZERO, Equal); test(T::ONE, Greater); test(T::exact_from(100), Greater); test(T::MAX, Greater); } fn sign_helper_signed() { let test = |n: T, out| { assert_eq!(n.sign(), out); }; test(T::NEGATIVE_ONE, Less); test(T::exact_from(-100), Less); test(T::MIN, Less); } fn sign_helper_primitive_float() { let test = |n: T, out| { assert_eq!(n.sign(), out); }; test(T::ZERO, Greater); test(T::NEGATIVE_ZERO, Less); test(T::ONE, Greater); test(T::NEGATIVE_ONE, Less); test(T::INFINITY, Greater); test(T::NEGATIVE_INFINITY, Less); test(T::NAN, Equal); } #[test] fn test_sign() { apply_fn_to_primitive_ints!(sign_helper_primitive_int); apply_fn_to_signeds!(sign_helper_signed); apply_fn_to_primitive_floats!(sign_helper_primitive_float); } fn sign_properties_helper_unsigned() { unsigned_gen::().test_properties(|n| { let sign = n.sign(); assert_ne!(sign, Less); assert_eq!(n.partial_cmp(&T::ZERO), Some(sign)); }); } fn sign_properties_helper_signed() { signed_gen::().test_properties(|n| { let sign = n.sign(); assert_eq!(n.partial_cmp(&T::ZERO), Some(sign)); if n != T::MIN { assert_eq!((-n).sign(), sign.reverse()); } }); } fn sign_properties_helper_primitive_float() { primitive_float_gen::().test_properties(|f| { let sign = f.sign(); if !f.is_nan() { assert_eq!((-f).sign(), sign.reverse()); } }); } #[test] fn sign_properties() { apply_fn_to_unsigneds!(sign_properties_helper_unsigned); apply_fn_to_signeds!(sign_properties_helper_signed); apply_fn_to_primitive_floats!(sign_properties_helper_primitive_float); } malachite-base-0.4.16/tests/num/arithmetic/sqrt.rs000064400000000000000000000306631046102023000202140ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::sqrt::sqrt_rem_newton; use malachite_base::num::arithmetic::sqrt::{ ceiling_sqrt_binary, checked_sqrt_binary, floor_sqrt_binary, sqrt_rem_binary, }; use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::WrappingFrom; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::generators::{ primitive_float_gen, signed_gen_var_2, unsigned_gen, unsigned_gen_var_17, }; use std::panic::catch_unwind; #[test] fn test_sqrt_rem_newton() { fn test, S: PrimitiveSigned + WrappingFrom>( n: U, sqrt: U, rem: U, ) { let (actual_sqrt, actual_rem) = sqrt_rem_newton::(n); assert_eq!(actual_sqrt, sqrt); assert_eq!(actual_rem, rem); assert_eq!(n.sqrt_rem(), (sqrt, rem)); } // - no initial underestimate test::(2000000000, 44721, 32159); test::(u32::MAX, 65535, 131070); // - initial underestimate test::(1073741824, 32768, 0); test::(10000000000000000000, 3162277660, 1064924400); test::(u64::MAX, 4294967295, 8589934590); } #[test] fn sqrt_rem_newton_fail() { assert_panic!(sqrt_rem_newton::(1)); assert_panic!(sqrt_rem_newton::(1)); } #[test] fn test_floor_sqrt() { fn test_u(n: T, out: T) { assert_eq!(n.floor_sqrt(), out); assert_eq!(floor_sqrt_binary(n), out); let mut n = n; n.floor_sqrt_assign(); assert_eq!(n, out); } test_u::(0, 0); test_u::(1, 1); test_u::(2, 1); test_u::(3, 1); test_u::(4, 2); test_u::(5, 2); test_u::(10, 3); test_u::(100, 10); test_u::(1000000000, 31622); test_u::(152415765279683, 12345677); test_u::(152415765279684, 12345678); test_u::(152415765279685, 12345678); fn test_i(n: T, out: T) { assert_eq!(n.floor_sqrt(), out); let mut n = n; n.floor_sqrt_assign(); assert_eq!(n, out); } test_i::(0, 0); test_i::(1, 1); test_i::(2, 1); test_i::(3, 1); test_i::(4, 2); test_i::(5, 2); test_i::(10, 3); test_i::(100, 10); test_i::(1000000000, 31622); test_i::(152415765279683, 12345677); test_i::(152415765279684, 12345678); test_i::(152415765279685, 12345678); } fn floor_sqrt_fail_helper() { assert_panic!(T::NEGATIVE_ONE.floor_sqrt()); } #[test] pub fn floor_sqrt_fail() { apply_fn_to_signeds!(floor_sqrt_fail_helper); } #[test] fn test_ceiling_sqrt() { fn test_u(n: T, out: T) { assert_eq!(n.ceiling_sqrt(), out); assert_eq!(ceiling_sqrt_binary(n), out); let mut n = n; n.ceiling_sqrt_assign(); assert_eq!(n, out); } test_u::(0, 0); test_u::(1, 1); test_u::(2, 2); test_u::(3, 2); test_u::(4, 2); test_u::(5, 3); test_u::(10, 4); test_u::(100, 10); test_u::(1000000000, 31623); test_u::(152415765279683, 12345678); test_u::(152415765279684, 12345678); test_u::(152415765279685, 12345679); fn test_i(n: T, out: T) { assert_eq!(n.ceiling_sqrt(), out); let mut n = n; n.ceiling_sqrt_assign(); assert_eq!(n, out); } test_i::(0, 0); test_i::(1, 1); test_i::(2, 2); test_i::(3, 2); test_i::(4, 2); test_i::(5, 3); test_i::(10, 4); test_i::(100, 10); test_i::(1000000000, 31623); test_i::(152415765279683, 12345678); test_i::(152415765279684, 12345678); test_i::(152415765279685, 12345679); } fn ceiling_sqrt_fail_helper() { assert_panic!(T::NEGATIVE_ONE.ceiling_sqrt()); } #[test] pub fn ceiling_sqrt_fail() { apply_fn_to_signeds!(ceiling_sqrt_fail_helper); } #[test] fn test_checked_sqrt() { fn test_u(n: T, out: Option) { assert_eq!(n.checked_sqrt(), out); assert_eq!(checked_sqrt_binary(n), out); } test_u::(0, Some(0)); test_u::(1, Some(1)); test_u::(2, None); test_u::(3, None); test_u::(4, Some(2)); test_u::(5, None); test_u::(10, None); test_u::(100, Some(10)); test_u::(1000000000, None); test_u::(152415765279683, None); test_u::(152415765279684, Some(12345678)); test_u::(152415765279685, None); fn test_i(n: T, out: Option) { assert_eq!(n.checked_sqrt(), out); } test_i::(0, Some(0)); test_i::(1, Some(1)); test_i::(2, None); test_i::(3, None); test_i::(4, Some(2)); test_i::(5, None); test_i::(10, None); test_i::(100, Some(10)); test_i::(1000000000, None); test_i::(152415765279683, None); test_i::(152415765279684, Some(12345678)); test_i::(152415765279685, None); } fn checked_sqrt_fail_helper() { assert_panic!(T::NEGATIVE_ONE.checked_sqrt()); } #[test] pub fn checked_sqrt_fail() { apply_fn_to_signeds!(checked_sqrt_fail_helper); } #[test] fn test_sqrt_rem() { fn test(n: T, sqrt: T, rem: T) { let (actual_sqrt, actual_rem) = n.sqrt_rem(); assert_eq!(actual_sqrt, sqrt); assert_eq!(actual_rem, rem); assert_eq!(sqrt_rem_binary(n), (sqrt, rem)); let mut n = n; assert_eq!(n.sqrt_assign_rem(), rem); assert_eq!(n, sqrt); } test::(0, 0, 0); test::(1, 1, 0); test::(2, 1, 1); test::(3, 1, 2); test::(4, 2, 0); test::(5, 2, 1); test::(10, 3, 1); test::(100, 10, 0); test::(1000000000, 31622, 49116); test::(152415765279683, 12345677, 24691354); test::(152415765279684, 12345678, 0); test::(152415765279685, 12345678, 1); } #[test] fn test_sqrt() { fn test(n: T, out: T) { assert_eq!(NiceFloat(n.sqrt()), NiceFloat(out)); let mut n = n; n.sqrt_assign(); assert_eq!(NiceFloat(n), NiceFloat(out)); } test::(0.0, 0.0); test::(-0.0, -0.0); test::(1.0, 1.0); test::(f32::INFINITY, f32::INFINITY); test::(f32::NAN, f32::NAN); test::(2.0, std::f32::consts::SQRT_2); test::(-1.0, f32::NAN); } fn floor_sqrt_properties_helper_unsigned() { unsigned_gen::().test_properties(|n| { let sqrt = n.floor_sqrt(); let mut n_alt = n; n_alt.floor_sqrt_assign(); assert_eq!(n_alt, sqrt); assert_eq!(floor_sqrt_binary(n), sqrt); assert_eq!(n.floor_root(2), sqrt); let square = sqrt.square(); let ceiling_sqrt = n.ceiling_sqrt(); if square == n { assert_eq!(ceiling_sqrt, sqrt); } else { assert_eq!(ceiling_sqrt, sqrt + T::ONE); } assert!(square <= n); if let Some(next_square) = (sqrt + T::ONE).checked_square() { assert!(next_square > n); } }); } fn floor_sqrt_properties_helper_signed() { signed_gen_var_2::().test_properties(|n| { let sqrt = n.floor_sqrt(); let mut n_alt = n; n_alt.floor_sqrt_assign(); assert_eq!(n_alt, sqrt); assert_eq!(n.floor_root(2), sqrt); let square = sqrt.square(); let ceiling_sqrt = n.ceiling_sqrt(); if square == n { assert_eq!(ceiling_sqrt, sqrt); } else { assert_eq!(ceiling_sqrt, sqrt + T::ONE); } assert!(square <= n); if let Some(next_square) = (sqrt + T::ONE).checked_square() { assert!(next_square > n); } }); } #[test] fn floor_sqrt_properties() { apply_fn_to_unsigneds!(floor_sqrt_properties_helper_unsigned); apply_fn_to_signeds!(floor_sqrt_properties_helper_signed); } fn ceiling_sqrt_properties_helper_unsigned() { unsigned_gen::().test_properties(|n| { let sqrt = n.ceiling_sqrt(); let mut n_alt = n; n_alt.ceiling_sqrt_assign(); assert_eq!(n_alt, sqrt); assert_eq!(ceiling_sqrt_binary(n), sqrt); assert_eq!(n.ceiling_root(2), sqrt); if let Some(square) = sqrt.checked_square() { let floor_sqrt = n.floor_sqrt(); if square == n { assert_eq!(floor_sqrt, sqrt); } else { assert_eq!(floor_sqrt, sqrt - T::ONE); } assert!(square >= n); } if n != T::ZERO { assert!((sqrt - T::ONE).square() < n); } }); } fn ceiling_sqrt_properties_helper_signed() { signed_gen_var_2::().test_properties(|n| { let sqrt = n.ceiling_sqrt(); let mut n_alt = n; n_alt.ceiling_sqrt_assign(); assert_eq!(n_alt, sqrt); assert_eq!(n.ceiling_root(2), sqrt); if let Some(square) = sqrt.checked_square() { let floor_sqrt = n.floor_sqrt(); if square == n { assert_eq!(floor_sqrt, sqrt); } else { assert_eq!(floor_sqrt, sqrt - T::ONE); } assert!(square >= n); } if n != T::ZERO { assert!((sqrt - T::ONE).square() < n); } }); } #[test] fn ceiling_sqrt_properties() { apply_fn_to_unsigneds!(ceiling_sqrt_properties_helper_unsigned); apply_fn_to_signeds!(ceiling_sqrt_properties_helper_signed); } fn checked_sqrt_properties_helper_unsigned() { unsigned_gen::().test_properties(|n| { let sqrt = n.checked_sqrt(); assert_eq!(checked_sqrt_binary(n), sqrt); assert_eq!(n.checked_root(2), sqrt); if let Some(sqrt) = sqrt { assert_eq!(sqrt.square(), n); assert_eq!(n.floor_sqrt(), sqrt); assert_eq!(n.ceiling_sqrt(), sqrt); } }); } fn checked_sqrt_properties_helper_signed() { signed_gen_var_2::().test_properties(|n| { let sqrt = n.checked_sqrt(); assert_eq!(n.checked_root(2), sqrt); if let Some(sqrt) = sqrt { assert_eq!(sqrt.square(), n); assert_eq!(n.floor_sqrt(), sqrt); assert_eq!(n.ceiling_sqrt(), sqrt); } }); } #[test] fn checked_sqrt_properties() { apply_fn_to_unsigneds!(checked_sqrt_properties_helper_unsigned); apply_fn_to_signeds!(checked_sqrt_properties_helper_signed); } fn sqrt_rem_properties_helper() { unsigned_gen::().test_properties(|n| { let (sqrt, rem) = n.sqrt_rem(); let mut n_alt = n; assert_eq!(n_alt.sqrt_assign_rem(), rem); assert_eq!(n_alt, sqrt); assert_eq!(sqrt_rem_binary(n), (sqrt, rem)); assert_eq!(n.root_rem(2), (sqrt, rem)); assert_eq!(n.floor_sqrt(), sqrt); assert!(rem <= sqrt << 1); assert_eq!(sqrt.square() + rem, n); }); } fn sqrt_rem_properties_helper_extra< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >() { unsigned_gen_var_17::().test_properties(|n| { assert_eq!(sqrt_rem_newton::(n), n.sqrt_rem()); }); } #[test] fn sqrt_rem_properties() { apply_fn_to_unsigneds!(sqrt_rem_properties_helper); sqrt_rem_properties_helper_extra::(); sqrt_rem_properties_helper_extra::(); } fn sqrt_assign_properties_helper() { primitive_float_gen::().test_properties(|f| { let mut sqrt = f; sqrt.sqrt_assign(); assert_eq!(NiceFloat(sqrt), NiceFloat(f.sqrt())); assert!(sqrt.is_nan() || sqrt >= T::ZERO); }); } #[test] fn sqrt_assign_properties() { apply_fn_to_primitive_floats!(sqrt_assign_properties_helper); } malachite-base-0.4.16/tests/num/arithmetic/square.rs000064400000000000000000000105461046102023000205210ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::UnsignedAbs; use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::traits::NegativeInfinity; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::WrappingFrom; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::generators::{ primitive_float_gen, signed_gen_var_10, unsigned_gen_var_21, }; #[test] fn test_square() { fn test_i(x: T, out: T) { assert_eq!(x.square(), out); let mut x = x; x.square_assign(); assert_eq!(x, out); } test_i::(0, 0); test_i::(1, 1); test_i::(2, 4); test_i::(3, 9); test_i::(10, 100); test_i::(123, 15129); test_i::(1000, 1000000); test_i::(-1, 1); test_i::(-2, 4); test_i::(-3, 9); test_i::(-10, 100); test_i::(-123, 15129); test_i::(-1000, 1000000); fn test_f(x: T, out: T) { assert_eq!(NiceFloat(x.square()), NiceFloat(out)); let mut x = x; x.square_assign(); assert_eq!(NiceFloat(x), NiceFloat(out)); } test_f::(f32::NAN, f32::NAN); test_f::(f32::INFINITY, f32::INFINITY); test_f::(f32::NEGATIVE_INFINITY, f32::INFINITY); test_f::(0.0, 0.0); test_f::(-0.0, 0.0); test_f::(1.0, 1.0); test_f::(-1.0, 1.0); test_f::(0.5, 0.25); test_f::(-0.5, 0.25); test_f::(core::f32::consts::SQRT_2, 1.9999999); test_f::(-core::f32::consts::SQRT_2, 1.9999999); test_f::(core::f32::consts::PI, 9.869605); test_f::(-core::f32::consts::PI, 9.869605); test_f::(f64::NAN, f64::NAN); test_f::(f64::INFINITY, f64::INFINITY); test_f::(f64::NEGATIVE_INFINITY, f64::INFINITY); test_f::(0.0, 0.0); test_f::(-0.0, 0.0); test_f::(1.0, 1.0); test_f::(-1.0, 1.0); test_f::(0.5, 0.25); test_f::(-0.5, 0.25); test_f::(core::f64::consts::SQRT_2, 2.0000000000000004); test_f::(-core::f64::consts::SQRT_2, 2.0000000000000004); test_f::(core::f64::consts::PI, 9.869604401089358); test_f::(-core::f64::consts::PI, 9.869604401089358); } fn square_properties_helper_unsigned() { unsigned_gen_var_21::().test_properties(|x| { let mut square = x; square.square_assign(); assert_eq!(square, x.square()); assert_eq!(square, x.pow(2)); assert_eq!(square.checked_sqrt(), Some(x)); if x > T::ONE { assert_eq!(square.checked_log_base(x), Some(2)); } }); } fn square_properties_helper_signed< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + UnsignedAbs + WrappingFrom, >() { signed_gen_var_10::().test_properties(|x| { let mut square = x; square.square_assign(); assert_eq!(square, x.square()); assert_eq!(square, x.pow(2)); if x != S::MIN { assert_eq!((-x).square(), square); } assert_eq!( U::wrapping_from(square).checked_sqrt().unwrap(), x.unsigned_abs() ); }); } fn square_properties_helper_primitive_float() { primitive_float_gen::().test_properties(|x| { let mut square = x; square.square_assign(); assert_eq!(NiceFloat(square), NiceFloat(x.square())); assert_eq!(NiceFloat(square), NiceFloat(x.pow(2))); assert_eq!(NiceFloat((-x).square()), NiceFloat(square)); }); } #[test] fn square_properties() { apply_fn_to_unsigneds!(square_properties_helper_unsigned); apply_fn_to_unsigned_signed_pairs!(square_properties_helper_signed); apply_fn_to_primitive_floats!(square_properties_helper_primitive_float); } malachite-base-0.4.16/tests/num/arithmetic/sub_mul.rs000064400000000000000000000075571046102023000206770ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::traits::NegativeInfinity; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::generators::{ primitive_float_triple_gen, signed_pair_gen, signed_triple_gen_var_2, unsigned_pair_gen_var_27, unsigned_triple_gen_var_2, }; #[test] fn test_sub_mul() { fn test_i(x: T, y: T, z: T, out: T) { assert_eq!(x.sub_mul(y, z), out); let mut x = x; x.sub_mul_assign(y, z); assert_eq!(x, out); } test_i::(100, 3, 7, 79); test_i::(60, 5, 10, 10); test_i::(1000000, 456, 789, 640216); test_i::(123, -456, 789, 359907); test_i::(-123, 456, 789, -359907); test_i::(127, 2, 100, -73); test_i::(-127, -2, 100, 73); test_i::(-128, 1, 0, -128); fn test_f(x: T, y: T, z: T, out: T) { assert_eq!(NiceFloat(x.sub_mul(y, z)), NiceFloat(out)); let mut x = x; x.sub_mul_assign(y, z); assert_eq!(NiceFloat(x), NiceFloat(out)); } test_f::(1.0, 2.0, 3.0, -5.0); test_f::(1.0, f32::INFINITY, 2.0, f32::NEGATIVE_INFINITY); test_f::(f32::NAN, 1.0, 2.0, f32::NAN); } fn sub_mul_properties_helper_unsigned() { unsigned_triple_gen_var_2::().test_properties(|(x, y, z)| { let result = x.sub_mul(y, z); let mut x_alt = x; x_alt.sub_mul_assign(y, z); assert_eq!(x_alt, result); assert_eq!(x.sub_mul(z, y), result); assert_eq!(result.add_mul(y, z), x); assert_eq!(x.checked_sub_mul(y, z), Some(result)); assert_eq!(x.saturating_sub_mul(y, z), result); assert_eq!(x.wrapping_sub_mul(y, z), result); assert_eq!(x.overflowing_sub_mul(y, z), (result, false)); }); unsigned_pair_gen_var_27::().test_properties(|(a, b)| { assert_eq!(a.sub_mul(T::ZERO, b), a); assert_eq!(a.sub_mul(b, T::ZERO), a); }); } fn sub_mul_properties_helper_signed() { signed_triple_gen_var_2::().test_properties(|(x, y, z)| { let result = x.sub_mul(y, z); let mut x_alt = x; x_alt.sub_mul_assign(y, z); assert_eq!(x_alt, result); assert_eq!(x.sub_mul(z, y), result); assert_eq!(result.add_mul(y, z), x); assert_eq!(x.checked_sub_mul(y, z), Some(result)); assert_eq!(x.saturating_sub_mul(y, z), result); assert_eq!(x.wrapping_sub_mul(y, z), result); assert_eq!(x.overflowing_sub_mul(y, z), (result, false)); }); signed_pair_gen::().test_properties(|(a, b)| { assert_eq!(a.sub_mul(T::ZERO, b), a); assert_eq!(a.sub_mul(b, T::ZERO), a); }); } fn sub_mul_properties_helper_primitive_float() { primitive_float_triple_gen::().test_properties(|(x, y, z)| { let result = x.sub_mul(y, z); let mut x_alt = x; x_alt.sub_mul_assign(y, z); assert_eq!(NiceFloat(x_alt), NiceFloat(result)); assert_eq!(NiceFloat(x.sub_mul(z, y)), NiceFloat(result)); }); } #[test] fn sub_mul_properties() { apply_fn_to_unsigneds!(sub_mul_properties_helper_unsigned); apply_fn_to_signeds!(sub_mul_properties_helper_signed); apply_fn_to_primitive_floats!(sub_mul_properties_helper_primitive_float); } malachite-base-0.4.16/tests/num/arithmetic/wrapping_abs.rs000064400000000000000000000027611046102023000216750ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::test_util::generators::signed_gen; fn wrapping_abs_helper() { let test = |n: T, out| { assert_eq!(n.wrapping_abs(), out); let mut n = n; n.wrapping_abs_assign(); assert_eq!(n, out); }; test(T::ZERO, T::ZERO); test(T::ONE, T::ONE); test(T::exact_from(100), T::exact_from(100)); test(T::MAX, T::MAX); test(T::NEGATIVE_ONE, T::ONE); test(T::exact_from(-100), T::exact_from(100)); test(T::MIN, T::MIN); } #[test] fn test_wrapping_abs() { apply_fn_to_signeds!(wrapping_abs_helper); } fn wrapping_abs_properties_helper() { signed_gen::().test_properties(|n| { let mut abs = n; abs.wrapping_abs_assign(); assert_eq!(abs, n.wrapping_abs()); assert_eq!(abs.wrapping_abs(), abs); if n != T::MIN { assert_eq!(n.abs(), abs); } assert_eq!(abs == n, n >= T::ZERO || n == T::MIN); }); } #[test] fn wrapping_abs_properties() { apply_fn_to_signeds!(wrapping_abs_properties_helper); } malachite-base-0.4.16/tests/num/arithmetic/wrapping_add.rs000064400000000000000000000040151046102023000216520ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{signed_pair_gen, unsigned_pair_gen_var_27}; #[test] fn test_wrapping_add() { fn test(x: T, y: T, out: T) { assert_eq!(x.wrapping_add(y), out); let mut x = x; x.wrapping_add_assign(y); assert_eq!(x, out); } test::(123, 456, 579); test::(123, 200, 67); test::(123, -456, -333); test::(123, 45, -88); test::(-123, -45, 88); } fn wrapping_add_properties_helper_unsigned() { unsigned_pair_gen_var_27::().test_properties(|(x, y)| { let mut sum = x; sum.wrapping_add_assign(y); assert_eq!(sum, x.wrapping_add(y)); assert_eq!(sum, x.wrapping_sub(y.wrapping_neg())); assert_eq!(sum.wrapping_sub(x), y); assert_eq!(sum.wrapping_sub(y), x); assert_eq!(y.wrapping_add(x), sum); }); } fn wrapping_add_properties_helper_signed() { signed_pair_gen::().test_properties(|(x, y)| { let mut sum = x; sum.wrapping_add_assign(y); assert_eq!(sum, x.wrapping_add(y)); assert_eq!(sum, x.wrapping_sub(y.wrapping_neg())); assert_eq!(sum.wrapping_sub(x), y); assert_eq!(sum.wrapping_sub(y), x); assert_eq!(y.wrapping_add(x), sum); }); } #[test] fn wrapping_add_properties() { apply_fn_to_unsigneds!(wrapping_add_properties_helper_unsigned); apply_fn_to_signeds!(wrapping_add_properties_helper_signed); } malachite-base-0.4.16/tests/num/arithmetic/wrapping_add_mul.rs000064400000000000000000000063521046102023000225350ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ signed_pair_gen, signed_triple_gen, unsigned_pair_gen_var_27, unsigned_triple_gen_var_19, }; #[test] fn test_wrapping_add_mul() { fn test(x: T, y: T, z: T, out: T) { assert_eq!(x.wrapping_add_mul(y, z), out); let mut x = x; x.wrapping_add_mul_assign(y, z); assert_eq!(x, out); } test::(2, 3, 7, 23); test::(7, 5, 10, 57); test::(123, 456, 789, 359907); test::(123, -456, 789, -359661); test::(-123, 456, 789, 359661); test::(127, -2, 100, -73); test::(-127, 2, 100, 73); test::(-128, 1, 0, -128); test::(2, 20, 20, 146); test::(-127, -2, 100, -71); test::(127, 1, 100, -29); test::(-127, -1, 100, 29); test::(-127, -10, 100, -103); } fn wrapping_add_mul_properties_helper_unsigned() { unsigned_triple_gen_var_19::().test_properties(|(x, y, z)| { let result = x.wrapping_add_mul(y, z); let mut x_alt = x; x_alt.wrapping_add_mul_assign(y, z); assert_eq!(x_alt, result); assert_eq!(x.wrapping_add_mul(z, y), result); assert_eq!(result.wrapping_sub_mul(y, z), x); assert_eq!(x.overflowing_add_mul(y, z).0, result); }); unsigned_pair_gen_var_27::().test_properties(|(a, b)| { assert_eq!(a.wrapping_add_mul(T::ZERO, b), a); assert_eq!(a.wrapping_add_mul(T::ONE, b), a.wrapping_add(b)); assert_eq!(T::ZERO.wrapping_add_mul(a, b), a.wrapping_mul(b)); assert_eq!(a.wrapping_add_mul(b, T::ZERO), a); assert_eq!(a.wrapping_add_mul(b, T::ONE), a.wrapping_add(b)); }); } fn wrapping_add_mul_properties_helper_signed() { signed_triple_gen::().test_properties(|(x, y, z)| { let result = x.wrapping_add_mul(y, z); let mut x_alt = x; x_alt.wrapping_add_mul_assign(y, z); assert_eq!(x_alt, result); assert_eq!(x.wrapping_add_mul(z, y), result); assert_eq!(result.wrapping_sub_mul(y, z), x); assert_eq!(x.overflowing_add_mul(y, z).0, result); }); signed_pair_gen::().test_properties(|(a, b)| { assert_eq!(a.wrapping_add_mul(T::ZERO, b), a); assert_eq!(a.wrapping_add_mul(T::ONE, b), a.wrapping_add(b)); assert_eq!(T::ZERO.wrapping_add_mul(a, b), a.wrapping_mul(b)); assert_eq!(a.wrapping_add_mul(b, T::ZERO), a); assert_eq!(a.wrapping_add_mul(b, T::ONE), a.wrapping_add(b)); }); } #[test] fn wrapping_add_mul_properties() { apply_fn_to_unsigneds!(wrapping_add_mul_properties_helper_unsigned); apply_fn_to_signeds!(wrapping_add_mul_properties_helper_signed); } malachite-base-0.4.16/tests/num/arithmetic/wrapping_div.rs000064400000000000000000000051411046102023000217050ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ signed_gen, signed_pair_gen_var_6, unsigned_gen, unsigned_pair_gen_var_12, }; use std::panic::catch_unwind; #[test] fn test_wrapping_div() { fn test(x: T, y: T, out: T) { assert_eq!(x.wrapping_div(y), out); let mut x = x; x.wrapping_div_assign(y); assert_eq!(x, out); } test::(0, 5, 0); test::(123, 456, 0); test::(100, 3, 33); test::(100, -3, -33); test::(-100, 3, -33); test::(-100, -3, 33); test::(-128, -1, -128); } fn wrapping_div_assign_fail_helper() { assert_panic!({ let mut n = T::ONE; n.wrapping_div_assign(T::ZERO); }); } #[test] fn wrapping_div_assign_fail() { apply_fn_to_primitive_ints!(wrapping_div_assign_fail_helper); } fn wrapping_div_properties_helper_unsigned() { unsigned_pair_gen_var_12::().test_properties(|(x, y)| { let mut quotient = x; quotient.wrapping_div_assign(y); assert_eq!(quotient, x.wrapping_div(y)); assert_eq!(x / y, quotient); }); unsigned_gen::().test_properties(|x| { assert_panic!(x.wrapping_div(T::ZERO)); assert_panic!({ let mut y = x; y.wrapping_div_assign(T::ZERO); }); }); } fn wrapping_div_properties_helper_signed() { signed_pair_gen_var_6::().test_properties(|(x, y)| { let mut quotient = x; quotient.wrapping_div_assign(y); assert_eq!(quotient, x.wrapping_div(y)); if x != T::MIN || y != T::NEGATIVE_ONE { assert_eq!(x / y, quotient); } }); signed_gen::().test_properties(|x| { assert_panic!(x.wrapping_div(T::ZERO)); assert_panic!({ let mut y = x; y.wrapping_div_assign(T::ZERO); }); }); } #[test] fn wrapping_div_properties() { apply_fn_to_unsigneds!(wrapping_div_properties_helper_unsigned); apply_fn_to_signeds!(wrapping_div_properties_helper_signed); } malachite-base-0.4.16/tests/num/arithmetic/wrapping_mul.rs000064400000000000000000000034101046102023000217150ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{signed_pair_gen, unsigned_pair_gen_var_27}; #[test] fn test_wrapping_mul() { fn test(x: T, y: T, out: T) { assert_eq!(x.wrapping_mul(y), out); let mut x = x; x.wrapping_mul_assign(y); assert_eq!(x, out); } test::(123, 456, 56088); test::(123, 200, 24); test::(123, -45, -5535); test::(123, 45, -97); test::(-123, 45, 97); } fn wrapping_mul_properties_helper_unsigned() { unsigned_pair_gen_var_27::().test_properties(|(x, y)| { let mut product = x; product.wrapping_mul_assign(y); assert_eq!(product, x.wrapping_mul(y)); assert_eq!(y.wrapping_mul(x), product); }); } fn wrapping_mul_properties_helper_signed() { signed_pair_gen::().test_properties(|(x, y)| { let mut product = x; product.wrapping_mul_assign(y); assert_eq!(product, x.wrapping_mul(y)); assert_eq!(y.wrapping_mul(x), product); }); } #[test] fn wrapping_mul_properties() { apply_fn_to_unsigneds!(wrapping_mul_properties_helper_unsigned); apply_fn_to_signeds!(wrapping_mul_properties_helper_signed); } malachite-base-0.4.16/tests/num/arithmetic/wrapping_neg.rs000064400000000000000000000047331046102023000217020ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{signed_gen, unsigned_gen}; fn unsigned_wrapping_neg_helper() { let test = |n: T, out| { assert_eq!(n.wrapping_neg(), out); let mut n = n; n.wrapping_neg_assign(); assert_eq!(n, out); }; test(T::ZERO, T::ZERO); test(T::ONE, T::MAX); test(T::exact_from(100), T::MAX - T::exact_from(100) + T::ONE); test(T::MAX, T::ONE); } fn signed_wrapping_neg_helper() { let test = |n: T, out| { assert_eq!(n.wrapping_neg(), out); let mut n = n; n.wrapping_neg_assign(); assert_eq!(n, out); }; test(T::ZERO, T::ZERO); test(T::ONE, T::NEGATIVE_ONE); test(T::exact_from(100), T::exact_from(-100)); test(T::MAX, T::MIN + T::ONE); test(T::NEGATIVE_ONE, T::ONE); test(T::exact_from(-100), T::exact_from(100)); test(T::MIN, T::MIN); } #[test] fn test_wrapping_neg() { apply_fn_to_unsigneds!(unsigned_wrapping_neg_helper); apply_fn_to_signeds!(signed_wrapping_neg_helper); } fn wrapping_neg_properties_helper_unsigned() { unsigned_gen::().test_properties(|n| { let mut neg = n; neg.wrapping_neg_assign(); assert_eq!(neg, n.wrapping_neg()); assert_eq!(neg.wrapping_neg(), n); assert_eq!(neg == n, n == T::ZERO || n == T::power_of_2(T::WIDTH - 1)); assert_eq!(n.wrapping_add(neg), T::ZERO); }); } fn wrapping_neg_properties_helper_signed() { signed_gen::().test_properties(|n| { let mut neg = n; neg.wrapping_neg_assign(); assert_eq!(neg, n.wrapping_neg()); assert_eq!(neg.wrapping_neg(), n); assert_eq!(neg == n, n == T::ZERO || n == T::MIN); assert_eq!(n.wrapping_add(neg), T::ZERO); }); } #[test] fn wrapping_neg_properties() { apply_fn_to_unsigneds!(wrapping_neg_properties_helper_unsigned); apply_fn_to_signeds!(wrapping_neg_properties_helper_signed); } malachite-base-0.4.16/tests/num/arithmetic/wrapping_pow.rs000064400000000000000000000051761046102023000217400ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::Parity; use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{signed_unsigned_pair_gen, unsigned_pair_gen}; #[test] fn test_wrapping_pow() { fn test(x: T, y: u64, out: T) { assert_eq!(x.wrapping_pow(y), out); let mut x = x; x.wrapping_pow_assign(y); assert_eq!(x, out); } test::(0, 0, 1); test::(123, 0, 1); test::(123, 1, 123); test::(0, 123, 0); test::(1, 123, 1); test::(-1, 123, -1); test::(-1, 124, 1); test::(3, 3, 27); test::(-10, 9, -1000000000); test::(-10, 10, 1410065408); test::(-10, 9, 13824); test::(10, 9, -13824); test::(123, 456, 2409344748064316129); test::(0, u64::MAX, 0); test::(1, u64::MAX, 1); test::(123, u64::MAX, 3449391168254631603); test::(0, u64::MAX, 0); test::(1, u64::MAX, 1); test::(-1, u64::MAX, -1); test::(-1, u64::MAX - 1, 1); test::(123, u64::MAX, 3449391168254631603); test::(-123, u64::MAX, -3449391168254631603); test::(-123, u64::MAX - 1, 4527249702272692521); } fn wrapping_pow_properties_helper_unsigned() { unsigned_pair_gen::().test_properties(|(x, y)| { let mut power = x; power.wrapping_pow_assign(y); assert_eq!(power, x.wrapping_pow(y)); }); } fn wrapping_pow_properties_helper_signed() { signed_unsigned_pair_gen::().test_properties(|(x, y)| { let mut power = x; power.wrapping_pow_assign(y); assert_eq!(power, x.wrapping_pow(y)); if x != T::MIN { let neg_pow = (-x).wrapping_pow(y); if y.even() { assert_eq!(neg_pow, power); } else { assert_eq!(neg_pow, power.wrapping_neg()); } } }); } #[test] fn wrapping_pow_properties() { apply_fn_to_unsigneds!(wrapping_pow_properties_helper_unsigned); apply_fn_to_signeds!(wrapping_pow_properties_helper_signed); } malachite-base-0.4.16/tests/num/arithmetic/wrapping_square.rs000064400000000000000000000041041046102023000224210ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{signed_gen, unsigned_gen}; #[test] fn test_wrapping_square() { fn test(x: T, out: T) { assert_eq!(x.wrapping_square(), out); let mut x = x; x.wrapping_square_assign(); assert_eq!(x, out); } test::(0, 0); test::(1, 1); test::(2, 4); test::(3, 9); test::(10, 100); test::(123, 15129); test::(1000, 1000000); test::(-1, 1); test::(-2, 4); test::(-3, 9); test::(-10, 100); test::(-123, 15129); test::(-1000, 1000000); test::(1000, 16960); test::(-1000, 16960); } fn wrapping_square_properties_helper_unsigned() { unsigned_gen::().test_properties(|x| { let mut square = x; square.wrapping_square_assign(); assert_eq!(square, x.wrapping_square()); assert_eq!(square, x.wrapping_pow(2)); }); } fn wrapping_square_properties_helper_signed() { signed_gen::().test_properties(|x| { let mut square = x; square.wrapping_square_assign(); assert_eq!(square, x.wrapping_square()); assert_eq!(square, x.wrapping_pow(2)); if x != T::MIN { assert_eq!((-x).wrapping_square(), square); } }); } #[test] fn saturating_square_properties() { apply_fn_to_unsigneds!(wrapping_square_properties_helper_unsigned); apply_fn_to_signeds!(wrapping_square_properties_helper_signed); } malachite-base-0.4.16/tests/num/arithmetic/wrapping_sub.rs000064400000000000000000000037371046102023000217250ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{signed_pair_gen, unsigned_pair_gen_var_27}; #[test] fn test_wrapping_sub() { fn test(x: T, y: T, out: T) { assert_eq!(x.wrapping_sub(y), out); let mut x = x; x.wrapping_sub_assign(y); assert_eq!(x, out); } test::(456, 123, 333); test::(123, 200, 179); test::(123, -456, 579); test::(123, -45, -88); test::(-123, 45, 88); } fn wrapping_sub_properties_helper_unsigned() { unsigned_pair_gen_var_27::().test_properties(|(x, y)| { let mut diff = x; diff.wrapping_sub_assign(y); assert_eq!(diff, x.wrapping_sub(y)); assert_eq!(diff, x.wrapping_add(y.wrapping_neg())); assert_eq!(diff.wrapping_add(y), x); assert_eq!(y.wrapping_sub(x), diff.wrapping_neg()); }); } fn wrapping_sub_properties_helper_signed() { signed_pair_gen::().test_properties(|(x, y)| { let mut diff = x; diff.wrapping_sub_assign(y); assert_eq!(diff, x.wrapping_sub(y)); assert_eq!(diff, x.wrapping_add(y.wrapping_neg())); assert_eq!(diff.wrapping_add(y), x); assert_eq!(y.wrapping_sub(x), diff.wrapping_neg()); }); } #[test] fn wrapping_sub_properties() { apply_fn_to_unsigneds!(wrapping_sub_properties_helper_unsigned); apply_fn_to_signeds!(wrapping_sub_properties_helper_signed); } malachite-base-0.4.16/tests/num/arithmetic/wrapping_sub_mul.rs000064400000000000000000000065171046102023000226010ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ signed_pair_gen, signed_triple_gen, unsigned_pair_gen_var_27, unsigned_triple_gen_var_19, }; #[test] fn test_wrapping_sub_mul() { fn test(x: T, y: T, z: T, out: T) { assert_eq!(x.wrapping_sub_mul(y, z), out); let mut x = x; x.wrapping_sub_mul_assign(y, z); assert_eq!(x, out); } test::(100, 3, 7, 79); test::(60, 5, 10, 10); test::(1000000, 456, 789, 640216); test::(123, -456, 789, 359907); test::(-123, 456, 789, -359907); test::(127, 2, 100, -73); test::(-127, -2, 100, 73); test::(-128, 1, 0, -128); test::(2, 10, 5, 208); test::(-127, 2, 100, -71); test::(-127, 1, 100, 29); test::(127, -1, 100, -29); test::(127, -10, 100, 103); } fn wrapping_sub_mul_properties_helper_unsigned() { unsigned_triple_gen_var_19::().test_properties(|(x, y, z)| { let result = x.wrapping_sub_mul(y, z); let mut x_alt = x; x_alt.wrapping_sub_mul_assign(y, z); assert_eq!(x_alt, result); assert_eq!(x.wrapping_sub_mul(z, y), result); assert_eq!(result.wrapping_add_mul(y, z), x); assert_eq!(x.overflowing_sub_mul(y, z).0, result); }); unsigned_pair_gen_var_27::().test_properties(|(a, b)| { assert_eq!(a.wrapping_sub_mul(T::ZERO, b), a); assert_eq!(a.wrapping_sub_mul(T::ONE, b), a.wrapping_sub(b)); assert_eq!( T::ZERO.wrapping_sub_mul(a, b), a.wrapping_mul(b).wrapping_neg() ); assert_eq!(a.wrapping_sub_mul(b, T::ZERO), a); assert_eq!(a.wrapping_sub_mul(b, T::ONE), a.wrapping_sub(b)); }); } fn wrapping_sub_mul_properties_helper_signed() { signed_triple_gen::().test_properties(|(x, y, z)| { let result = x.wrapping_sub_mul(y, z); let mut x_alt = x; x_alt.wrapping_sub_mul_assign(y, z); assert_eq!(x_alt, result); assert_eq!(x.wrapping_sub_mul(z, y), result); assert_eq!(result.wrapping_add_mul(y, z), x); assert_eq!(x.overflowing_sub_mul(y, z).0, result); }); signed_pair_gen::().test_properties(|(a, b)| { assert_eq!(a.wrapping_sub_mul(T::ZERO, b), a); assert_eq!(a.wrapping_sub_mul(T::ONE, b), a.wrapping_sub(b)); assert_eq!( T::ZERO.wrapping_sub_mul(a, b), a.wrapping_mul(b).wrapping_neg() ); assert_eq!(a.wrapping_sub_mul(b, T::ZERO), a); assert_eq!(a.wrapping_sub_mul(b, T::ONE), a.wrapping_sub(b)); }); } #[test] fn wrapping_sub_mul_properties() { apply_fn_to_unsigneds!(wrapping_sub_mul_properties_helper_unsigned); apply_fn_to_signeds!(wrapping_sub_mul_properties_helper_signed); } malachite-base-0.4.16/tests/num/arithmetic/x_mul_y_to_zz.rs000064400000000000000000000037571046102023000221300ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::x_mul_y_to_zz::explicit_x_mul_y_to_zz; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ unsigned_gen, unsigned_pair_gen_var_27, unsigned_triple_gen_var_19, }; #[test] fn test_x_mul_y_to_zz() { fn test(x: T, y: T, z_1: T, z_0: T) { assert_eq!(T::x_mul_y_to_zz(x, y), (z_1, z_0)); assert_eq!(explicit_x_mul_y_to_zz(x, y), (z_1, z_0)); } test::(0, 0, 0, 0); test::(15, 3, 0, 45); test::(0x78, 0x9a, 0x48, 0x30); test::(u8::MAX, 0, 0, 0); test::(u8::MAX, 1, 0, u8::MAX); test(u16::MAX, u16::MAX, u16::MAX - 1, 1); } fn x_mul_y_to_zz_properties_helper() { unsigned_pair_gen_var_27::().test_properties(|(x, y)| { let p = T::x_mul_y_to_zz(x, y); assert_eq!(explicit_x_mul_y_to_zz(x, y), p); assert_eq!(T::x_mul_y_to_zz(y, x), p); }); unsigned_gen::().test_properties(|x| { assert_eq!(T::x_mul_y_to_zz(x, T::ZERO), (T::ZERO, T::ZERO)); assert_eq!(T::x_mul_y_to_zz(T::ZERO, x), (T::ZERO, T::ZERO)); assert_eq!(T::x_mul_y_to_zz(x, T::ONE), (T::ZERO, x)); assert_eq!(T::x_mul_y_to_zz(T::ONE, x), (T::ZERO, x)); }); unsigned_triple_gen_var_19::().test_properties(|(x, y, z)| { let product_1 = T::x_mul_y_to_zz(x, y).1; let product_2 = T::x_mul_y_to_zz(y, z).1; assert_eq!(product_1.wrapping_mul(z), x.wrapping_mul(product_2)); }); } #[test] fn x_mul_y_to_zz_properties() { apply_fn_to_unsigneds!(x_mul_y_to_zz_properties_helper); } malachite-base-0.4.16/tests/num/arithmetic/xx_add_yy_to_zz.rs000064400000000000000000000055771046102023000224460ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::xx_add_yy_to_zz::explicit_xx_add_yy_to_zz; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ unsigned_pair_gen_var_27, unsigned_quadruple_gen_var_10, unsigned_sextuple_gen_var_1, }; #[test] fn test_xx_add_yy_to_zz() { fn test(x_1: T, x_0: T, y_1: T, y_0: T, z_1: T, z_0: T) { assert_eq!(T::xx_add_yy_to_zz(x_1, x_0, y_1, y_0), (z_1, z_0)); assert_eq!(explicit_xx_add_yy_to_zz(x_1, x_0, y_1, y_0), (z_1, z_0)); } test::(0, 0, 0, 0, 0, 0); test::(0x12, 0x34, 0x33, 0x33, 0x45, 0x67); test::(0x78, 0x9a, 0xbc, 0xde, 0x35, 0x78); test::(u8::MAX, u8::MAX, 0, 1, 0, 0); test( u16::MAX, u16::MAX, u16::MAX, u16::MAX, u16::MAX, u16::MAX - 1, ); } fn xx_add_yy_to_zz_properties_helper() { unsigned_quadruple_gen_var_10::().test_properties(|(x_1, x_0, y_1, y_0)| { let (z_1, z_0) = T::xx_add_yy_to_zz(x_1, x_0, y_1, y_0); assert_eq!(explicit_xx_add_yy_to_zz(x_1, x_0, y_1, y_0), (z_1, z_0)); assert_eq!(T::xx_sub_yy_to_zz(z_1, z_0, y_1, y_0), (x_1, x_0)); assert_eq!(T::xx_sub_yy_to_zz(z_1, z_0, x_1, x_0), (y_1, y_0)); assert_eq!(T::xx_add_yy_to_zz(y_1, y_0, x_1, x_0), (z_1, z_0)); assert_eq!(T::xx_add_yy_to_zz(x_1, y_0, y_1, x_0), (z_1, z_0)); let (neg_y_1, neg_y_0) = T::xx_sub_yy_to_zz(T::ZERO, T::ZERO, y_1, y_0); assert_eq!(T::xx_sub_yy_to_zz(x_1, x_0, neg_y_1, neg_y_0), (z_1, z_0)); }); unsigned_pair_gen_var_27::().test_properties(|(x_1, x_0)| { assert_eq!(T::xx_add_yy_to_zz(x_1, x_0, T::ZERO, T::ZERO), (x_1, x_0)); assert_eq!(T::xx_add_yy_to_zz(T::ZERO, T::ZERO, x_1, x_0), (x_1, x_0)); let (neg_x_1, neg_x_0) = T::xx_sub_yy_to_zz(T::ZERO, T::ZERO, x_1, x_0); assert_eq!( T::xx_add_yy_to_zz(x_1, x_0, neg_x_1, neg_x_0), (T::ZERO, T::ZERO) ); }); unsigned_sextuple_gen_var_1::().test_properties(|(x_1, x_0, y_1, y_0, z_1, z_0)| { let (sum_1_1, sum_1_0) = T::xx_add_yy_to_zz(x_1, x_0, y_1, y_0); let (sum_2_1, sum_2_0) = T::xx_add_yy_to_zz(y_1, y_0, z_1, z_0); assert_eq!( T::xx_add_yy_to_zz(sum_1_1, sum_1_0, z_1, z_0), T::xx_add_yy_to_zz(x_1, x_0, sum_2_1, sum_2_0) ); }); } #[test] fn xx_add_yy_to_zz_properties() { apply_fn_to_unsigneds!(xx_add_yy_to_zz_properties_helper); } malachite-base-0.4.16/tests/num/arithmetic/xx_div_mod_y_to_qr.rs000064400000000000000000000045341046102023000231150ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::xx_div_mod_y_to_qr::explicit_xx_div_mod_y_to_qr; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{unsigned_gen_var_1, unsigned_triple_gen_var_15}; use std::panic::catch_unwind; #[test] fn test_xx_div_mod_y_to_qr() { fn test(x_1: T, x_0: T, y: T, q: T, r: T) { assert_eq!(T::xx_div_mod_y_to_qr(x_1, x_0, y), (q, r)); assert_eq!(explicit_xx_div_mod_y_to_qr(x_1, x_0, y), (q, r)); } test::(0, 0, 1, 0, 0); test::(0, 1, 1, 1, 0); test::(1, 0, 2, 0x8000, 0); test::(1, 7, 2, 0x8003, 1); test::(0x78, 0x9a, 0xbc, 0xa4, 0x2a); test::(0x12, 0x34, 0x33, 0x5a5a5a5a5a5a5a5b, 0x13); } fn xx_div_mod_y_to_qr_fail_helper() { assert_panic!(T::xx_div_mod_y_to_qr( T::exact_from(3), T::exact_from(5), T::ZERO )); assert_panic!(T::xx_div_mod_y_to_qr( T::exact_from(3), T::exact_from(5), T::TWO )); } #[test] fn xx_div_mod_y_to_qr_fail() { apply_fn_to_unsigneds!(xx_div_mod_y_to_qr_fail_helper); } fn xx_div_mod_y_to_qr_properties_helper() { unsigned_triple_gen_var_15::().test_properties(|(x_1, x_0, y)| { let (q, r) = T::xx_div_mod_y_to_qr(x_1, x_0, y); assert_eq!(explicit_xx_div_mod_y_to_qr(x_1, x_0, y), (q, r)); assert!(r < y); let (product_1, product_0) = T::x_mul_y_to_zz(q, y); assert_eq!( T::xx_add_yy_to_zz(product_1, product_0, T::ZERO, r), (x_1, x_0) ); }); unsigned_gen_var_1::().test_properties(|a| { assert_eq!( T::xx_div_mod_y_to_qr(T::ZERO, T::ZERO, a), (T::ZERO, T::ZERO) ); assert_eq!(T::xx_div_mod_y_to_qr(T::ZERO, a, a), (T::ONE, T::ZERO)); }); } #[test] fn xx_div_mod_y_to_qr_properties() { apply_fn_to_unsigneds!(xx_div_mod_y_to_qr_properties_helper); } malachite-base-0.4.16/tests/num/arithmetic/xx_sub_yy_to_zz.rs000064400000000000000000000044061046102023000224750ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::xx_sub_yy_to_zz::explicit_xx_sub_yy_to_zz; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ unsigned_pair_gen_var_27, unsigned_quadruple_gen_var_10, }; #[test] fn test_xx_sub_yy_to_zz() { fn test(x_1: T, x_0: T, y_1: T, y_0: T, z_1: T, z_0: T) { assert_eq!(T::xx_sub_yy_to_zz(x_1, x_0, y_1, y_0), (z_1, z_0)); assert_eq!(explicit_xx_sub_yy_to_zz(x_1, x_0, y_1, y_0), (z_1, z_0)); } test::(0, 0, 0, 0, 0, 0); test::(0x67, 0x89, 0x33, 0x33, 0x34, 0x56); test::(0x78, 0x9a, 0xbc, 0xde, 0xbb, 0xbc); test::(0, 0, 0, 1, u8::MAX, u8::MAX); test(u16::MAX, u16::MAX, u16::MAX, u16::MAX, 0, 0); } fn xx_sub_yy_to_zz_properties_helper() { unsigned_quadruple_gen_var_10::().test_properties(|(x_1, x_0, y_1, y_0)| { let (z_1, z_0) = T::xx_sub_yy_to_zz(x_1, x_0, y_1, y_0); assert_eq!(explicit_xx_sub_yy_to_zz(x_1, x_0, y_1, y_0), (z_1, z_0)); assert_eq!(T::xx_add_yy_to_zz(z_1, z_0, y_1, y_0), (x_1, x_0)); assert_eq!( T::xx_sub_yy_to_zz(z_1, z_0, x_1, x_0), T::xx_sub_yy_to_zz(T::ZERO, T::ZERO, y_1, y_0) ); assert_eq!( T::xx_sub_yy_to_zz(y_1, y_0, x_1, x_0), T::xx_sub_yy_to_zz(T::ZERO, T::ZERO, z_1, z_0) ); let (neg_y_1, neg_y_0) = T::xx_sub_yy_to_zz(T::ZERO, T::ZERO, y_1, y_0); assert_eq!(T::xx_add_yy_to_zz(x_1, x_0, neg_y_1, neg_y_0), (z_1, z_0)); }); unsigned_pair_gen_var_27::().test_properties(|(x_1, x_0)| { assert_eq!(T::xx_sub_yy_to_zz(x_1, x_0, T::ZERO, T::ZERO), (x_1, x_0)); assert_eq!(T::xx_sub_yy_to_zz(x_1, x_0, x_1, x_0), (T::ZERO, T::ZERO)); }); } #[test] fn xx_sub_yy_to_zz_properties() { apply_fn_to_unsigneds!(xx_sub_yy_to_zz_properties_helper); } malachite-base-0.4.16/tests/num/arithmetic/xxx_add_yyy_to_zzz.rs000064400000000000000000000067321046102023000232130ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ unsigned_nonuple_gen_var_1, unsigned_sextuple_gen_var_1, unsigned_triple_gen_var_19, }; #[test] #[allow(clippy::too_many_arguments)] fn test_xxx_add_yyy_to_zzz() { fn test( x_2: T, x_1: T, x_0: T, y_2: T, y_1: T, y_0: T, z_2: T, z_1: T, z_0: T, ) { assert_eq!( T::xxx_add_yyy_to_zzz(x_2, x_1, x_0, y_2, y_1, y_0), (z_2, z_1, z_0) ); } test::(0, 0, 0, 0, 0, 0, 0, 0, 0); test::(0x12, 0x34, 0x56, 0x33, 0x33, 0x33, 0x45, 0x67, 0x89); test::(0x78, 0x9a, 0xbc, 0xde, 0xfe, 0xdc, 0x57, 0x99, 0x98); test::(u8::MAX, u8::MAX, u8::MAX, 0, 0, 1, 0, 0, 0); test( u16::MAX, u16::MAX, u16::MAX, u16::MAX, u16::MAX, u16::MAX, u16::MAX, u16::MAX, u16::MAX - 1, ); } fn xxx_add_yyy_to_zzz_properties_helper() { unsigned_sextuple_gen_var_1::().test_properties(|(x_2, x_1, x_0, y_2, y_1, y_0)| { let (z_2, z_1, z_0) = T::xxx_add_yyy_to_zzz(x_2, x_1, x_0, y_2, y_1, y_0); assert_eq!( T::xxx_sub_yyy_to_zzz(z_2, z_1, z_0, y_2, y_1, y_0), (x_2, x_1, x_0) ); assert_eq!( T::xxx_sub_yyy_to_zzz(z_2, z_1, z_0, x_2, x_1, x_0), (y_2, y_1, y_0) ); assert_eq!( T::xxx_add_yyy_to_zzz(y_2, y_1, y_0, x_2, x_1, x_0), (z_2, z_1, z_0) ); let (neg_y_2, neg_y_1, neg_y_0) = T::xxx_sub_yyy_to_zzz(T::ZERO, T::ZERO, T::ZERO, y_2, y_1, y_0); assert_eq!( T::xxx_sub_yyy_to_zzz(x_2, x_1, x_0, neg_y_2, neg_y_1, neg_y_0), (z_2, z_1, z_0) ); }); unsigned_triple_gen_var_19::().test_properties(|(x_2, x_1, x_0)| { assert_eq!( T::xxx_add_yyy_to_zzz(x_2, x_1, x_0, T::ZERO, T::ZERO, T::ZERO), (x_2, x_1, x_0) ); assert_eq!( T::xxx_add_yyy_to_zzz(T::ZERO, T::ZERO, T::ZERO, x_2, x_1, x_0), (x_2, x_1, x_0) ); let (neg_x_2, neg_x_1, neg_x_0) = T::xxx_sub_yyy_to_zzz(T::ZERO, T::ZERO, T::ZERO, x_2, x_1, x_0); assert_eq!( T::xxx_add_yyy_to_zzz(x_2, x_1, x_0, neg_x_2, neg_x_1, neg_x_0), (T::ZERO, T::ZERO, T::ZERO) ); }); unsigned_nonuple_gen_var_1::().test_properties( |(x_2, x_1, x_0, y_2, y_1, y_0, z_2, z_1, z_0)| { let (sum_1_2, sum_1_1, sum_1_0) = T::xxx_add_yyy_to_zzz(x_2, x_1, x_0, y_2, y_1, y_0); let (sum_2_2, sum_2_1, sum_2_0) = T::xxx_add_yyy_to_zzz(y_2, y_1, y_0, z_2, z_1, z_0); assert_eq!( T::xxx_add_yyy_to_zzz(sum_1_2, sum_1_1, sum_1_0, z_2, z_1, z_0), T::xxx_add_yyy_to_zzz(x_2, x_1, x_0, sum_2_2, sum_2_1, sum_2_0) ); }, ); } #[test] fn xxx_add_yyy_to_zzz_properties() { apply_fn_to_unsigneds!(xxx_add_yyy_to_zzz_properties_helper); } malachite-base-0.4.16/tests/num/arithmetic/xxx_sub_yyy_to_zzz.rs000064400000000000000000000053471046102023000232550ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ unsigned_sextuple_gen_var_1, unsigned_triple_gen_var_19, }; #[test] #[allow(clippy::too_many_arguments)] fn test_xxx_sub_yyy_to_zzz() { fn test( x_2: T, x_1: T, x_0: T, y_2: T, y_1: T, y_0: T, z_2: T, z_1: T, z_0: T, ) { assert_eq!( T::xxx_sub_yyy_to_zzz(x_2, x_1, x_0, y_2, y_1, y_0), (z_2, z_1, z_0) ); } test::(0, 0, 0, 0, 0, 0, 0, 0, 0); test::(0x67, 0x89, 0xab, 0x33, 0x33, 0x33, 0x34, 0x56, 0x78); test::(0x78, 0x9a, 0xbc, 0xde, 0xfe, 0xdc, 0x99, 0x9b, 0xe0); test::(0, 0, 0, 0, 0, 1, u8::MAX, u8::MAX, u8::MAX); test( u16::MAX, u16::MAX, u16::MAX, u16::MAX, u16::MAX, u16::MAX, 0, 0, 0, ); } fn xxx_sub_yyy_to_zzz_properties_helper() { unsigned_sextuple_gen_var_1::().test_properties(|(x_2, x_1, x_0, y_2, y_1, y_0)| { let (z_2, z_1, z_0) = T::xxx_sub_yyy_to_zzz(x_2, x_1, x_0, y_2, y_1, y_0); assert_eq!( T::xxx_add_yyy_to_zzz(z_2, z_1, z_0, y_2, y_1, y_0), (x_2, x_1, x_0) ); assert_eq!( T::xxx_sub_yyy_to_zzz(z_2, z_1, z_0, x_2, x_1, x_0), T::xxx_sub_yyy_to_zzz(T::ZERO, T::ZERO, T::ZERO, y_2, y_1, y_0) ); assert_eq!( T::xxx_sub_yyy_to_zzz(y_2, y_1, y_0, x_2, x_1, x_0), T::xxx_sub_yyy_to_zzz(T::ZERO, T::ZERO, T::ZERO, z_2, z_1, z_0) ); let (neg_y_2, neg_y_1, neg_y_0) = T::xxx_sub_yyy_to_zzz(T::ZERO, T::ZERO, T::ZERO, y_2, y_1, y_0); assert_eq!( T::xxx_add_yyy_to_zzz(x_2, x_1, x_0, neg_y_2, neg_y_1, neg_y_0), (z_2, z_1, z_0) ); }); unsigned_triple_gen_var_19::().test_properties(|(x_2, x_1, x_0)| { assert_eq!( T::xxx_sub_yyy_to_zzz(x_2, x_1, x_0, T::ZERO, T::ZERO, T::ZERO), (x_2, x_1, x_0) ); assert_eq!( T::xxx_sub_yyy_to_zzz(x_2, x_1, x_0, x_2, x_1, x_0), (T::ZERO, T::ZERO, T::ZERO) ); }); } #[test] fn xxx_sub_yyy_to_zzz_properties() { apply_fn_to_unsigneds!(xxx_sub_yyy_to_zzz_properties_helper); } malachite-base-0.4.16/tests/num/arithmetic/xxxx_add_yyyy_to_zzzz.rs000064400000000000000000000113741046102023000237640ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ unsigned_duodecuple_gen_var_1, unsigned_octuple_gen_var_1, unsigned_quadruple_gen_var_10, }; #[test] #[allow(clippy::too_many_arguments)] fn test_xxxx_add_yyyy_to_zzzz() { fn test( x_3: T, x_2: T, x_1: T, x_0: T, y_3: T, y_2: T, y_1: T, y_0: T, z_3: T, z_2: T, z_1: T, z_0: T, ) { assert_eq!( T::xxxx_add_yyyy_to_zzzz(x_3, x_2, x_1, x_0, y_3, y_2, y_1, y_0), (z_3, z_2, z_1, z_0) ); } test::(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); test::( 0x12, 0x34, 0x56, 0x78, 0x33, 0x33, 0x33, 0x33, 0x45, 0x67, 0x89, 0xab, ); test::( 0x78, 0x9a, 0xbc, 0xde, 0xfe, 0xdc, 0xba, 0x98, 0x77, 0x77, 0x77, 0x76, ); test::(u8::MAX, u8::MAX, u8::MAX, u8::MAX, 0, 0, 0, 1, 0, 0, 0, 0); test( u16::MAX, u16::MAX, u16::MAX, u16::MAX, u16::MAX, u16::MAX, u16::MAX, u16::MAX, u16::MAX, u16::MAX, u16::MAX, u16::MAX - 1, ); } fn xxxx_sub_yyyy_to_zzzz( x_3: T, x_2: T, x_1: T, x_0: T, y_3: T, y_2: T, y_1: T, y_0: T, ) -> (T, T, T, T) { let (z_0, borrow_1) = x_0.overflowing_sub(y_0); let (mut z_1, mut borrow_2) = x_1.overflowing_sub(y_1); if borrow_1 { borrow_2 |= z_1.overflowing_sub_assign(T::ONE); } let (mut z_2, mut borrow_3) = x_2.overflowing_sub(y_2); if borrow_2 { borrow_3 |= z_2.overflowing_sub_assign(T::ONE); } let mut z_3 = x_3.wrapping_sub(y_3); if borrow_3 { z_3.wrapping_sub_assign(T::ONE); } (z_3, z_2, z_1, z_0) } fn xxxx_add_yyyy_to_zzzz_properties_helper() { unsigned_octuple_gen_var_1::().test_properties( |(x_3, x_2, x_1, x_0, y_3, y_2, y_1, y_0)| { let (z_3, z_2, z_1, z_0) = T::xxxx_add_yyyy_to_zzzz(x_3, x_2, x_1, x_0, y_3, y_2, y_1, y_0); assert_eq!( xxxx_sub_yyyy_to_zzzz(z_3, z_2, z_1, z_0, y_3, y_2, y_1, y_0), (x_3, x_2, x_1, x_0) ); assert_eq!( xxxx_sub_yyyy_to_zzzz(z_3, z_2, z_1, z_0, x_3, x_2, x_1, x_0), (y_3, y_2, y_1, y_0) ); assert_eq!( T::xxxx_add_yyyy_to_zzzz(y_3, y_2, y_1, y_0, x_3, x_2, x_1, x_0), (z_3, z_2, z_1, z_0) ); let (neg_y_3, neg_y_2, neg_y_1, neg_y_0) = xxxx_sub_yyyy_to_zzzz(T::ZERO, T::ZERO, T::ZERO, T::ZERO, y_3, y_2, y_1, y_0); assert_eq!( xxxx_sub_yyyy_to_zzzz(x_3, x_2, x_1, x_0, neg_y_3, neg_y_2, neg_y_1, neg_y_0), (z_3, z_2, z_1, z_0) ); }, ); unsigned_quadruple_gen_var_10::().test_properties(|(x_3, x_2, x_1, x_0)| { assert_eq!( T::xxxx_add_yyyy_to_zzzz(x_3, x_2, x_1, x_0, T::ZERO, T::ZERO, T::ZERO, T::ZERO), (x_3, x_2, x_1, x_0) ); assert_eq!( T::xxxx_add_yyyy_to_zzzz(T::ZERO, T::ZERO, T::ZERO, T::ZERO, x_3, x_2, x_1, x_0), (x_3, x_2, x_1, x_0) ); let (neg_x_3, neg_x_2, neg_x_1, neg_x_0) = xxxx_sub_yyyy_to_zzzz(T::ZERO, T::ZERO, T::ZERO, T::ZERO, x_3, x_2, x_1, x_0); assert_eq!( T::xxxx_add_yyyy_to_zzzz(x_3, x_2, x_1, x_0, neg_x_3, neg_x_2, neg_x_1, neg_x_0), (T::ZERO, T::ZERO, T::ZERO, T::ZERO) ); }); unsigned_duodecuple_gen_var_1::().test_properties( |(x_3, x_2, x_1, x_0, y_3, y_2, y_1, y_0, z_3, z_2, z_1, z_0)| { let (sum_1_3, sum_1_2, sum_1_1, sum_1_0) = T::xxxx_add_yyyy_to_zzzz(x_3, x_2, x_1, x_0, y_3, y_2, y_1, y_0); let (sum_2_3, sum_2_2, sum_2_1, sum_2_0) = T::xxxx_add_yyyy_to_zzzz(y_3, y_2, y_1, y_0, z_3, z_2, z_1, z_0); assert_eq!( T::xxxx_add_yyyy_to_zzzz(sum_1_3, sum_1_2, sum_1_1, sum_1_0, z_3, z_2, z_1, z_0), T::xxxx_add_yyyy_to_zzzz(x_3, x_2, x_1, x_0, sum_2_3, sum_2_2, sum_2_1, sum_2_0) ); }, ); } #[test] fn xxxx_add_yyyy_to_zzzz_properties() { apply_fn_to_unsigneds!(xxxx_add_yyyy_to_zzzz_properties_helper); } malachite-base-0.4.16/tests/num/basic/constants.rs000064400000000000000000000116451046102023000201660ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::named::Named; use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::traits::{ Infinity, NaN, NegativeInfinity, NegativeOne, NegativeZero, One, OneHalf, Two, Zero, }; use malachite_base::num::float::NiceFloat; macro_rules! test_unsigned_constants { ($t: ident) => { assert_eq!($t::ZERO, 0); assert_eq!($t::ONE, 1); assert_eq!($t::TWO, 2); }; } macro_rules! test_signed_constants { ($t: ident) => { test_unsigned_constants!($t); assert_eq!($t::NEGATIVE_ONE, -1); }; } macro_rules! test_float_constants { ($t: ident) => { assert_eq!($t::ZERO, 0.0); assert_eq!($t::ONE, 1.0); assert_eq!($t::TWO, 2.0); assert_eq!($t::NEGATIVE_ONE, -1.0); assert_eq!($t::NEGATIVE_ZERO, -0.0); assert_eq!($t::ONE_HALF, 0.5); }; } #[test] fn test_constants() { apply_to_unsigneds!(test_unsigned_constants); apply_to_signeds!(test_signed_constants); apply_to_primitive_floats!(test_float_constants); } #[test] fn test_width_constants() { assert_eq!(u8::WIDTH, 8); assert_eq!(u8::LOG_WIDTH, 3); assert_eq!(u8::WIDTH_MASK, 0x7); assert_eq!(u16::WIDTH, 16); assert_eq!(u16::LOG_WIDTH, 4); assert_eq!(u16::WIDTH_MASK, 0xf); assert_eq!(u32::WIDTH, 32); assert_eq!(u32::LOG_WIDTH, 5); assert_eq!(u32::WIDTH_MASK, 0x1f); assert_eq!(u64::WIDTH, 64); assert_eq!(u64::LOG_WIDTH, 6); assert_eq!(u64::WIDTH_MASK, 0x3f); assert_eq!(u128::WIDTH, 128); assert_eq!(u128::LOG_WIDTH, 7); assert_eq!(u128::WIDTH_MASK, 0x7f); assert_eq!(i8::WIDTH, 8); assert_eq!(i8::LOG_WIDTH, 3); assert_eq!(i8::WIDTH_MASK, 0x7); assert_eq!(i16::WIDTH, 16); assert_eq!(i16::LOG_WIDTH, 4); assert_eq!(i16::WIDTH_MASK, 0xf); assert_eq!(i32::WIDTH, 32); assert_eq!(i32::LOG_WIDTH, 5); assert_eq!(i32::WIDTH_MASK, 0x1f); assert_eq!(i64::WIDTH, 64); assert_eq!(i64::LOG_WIDTH, 6); assert_eq!(i64::WIDTH_MASK, 0x3f); assert_eq!(i128::WIDTH, 128); assert_eq!(i128::LOG_WIDTH, 7); assert_eq!(i128::WIDTH_MASK, 0x7f); } #[test] fn test_other_float_constants() { assert_eq!(f32::WIDTH, 32); assert_eq!(f32::EXPONENT_WIDTH, 8); assert_eq!(f32::MANTISSA_WIDTH, 23); assert_eq!(f32::MIN_NORMAL_EXPONENT, -126); assert_eq!(f32::MIN_EXPONENT, -149); assert_eq!(f32::MAX_EXPONENT, 127); assert_eq!(NiceFloat(f32::MIN_POSITIVE_SUBNORMAL), NiceFloat(1.0e-45)); assert_eq!(NiceFloat(f32::MAX_SUBNORMAL), NiceFloat(1.1754942e-38)); assert_eq!( NiceFloat(f32::MIN_POSITIVE_NORMAL), NiceFloat(1.1754944e-38) ); assert_eq!(NiceFloat(f32::MAX_FINITE), NiceFloat(3.4028235e38)); assert_eq!(NiceFloat(Infinity::INFINITY), NiceFloat(f32::INFINITY)); assert_eq!( NiceFloat(f32::NEGATIVE_INFINITY), NiceFloat(f32::NEG_INFINITY) ); assert_eq!(NiceFloat(NaN::NAN), NiceFloat(f32::NAN)); assert_eq!(f32::SMALLEST_UNREPRESENTABLE_UINT, 0x1000001); assert_eq!(f32::LARGEST_ORDERED_REPRESENTATION, 0xff000001); assert_eq!(f64::WIDTH, 64); assert_eq!(f64::EXPONENT_WIDTH, 11); assert_eq!(f64::MANTISSA_WIDTH, 52); assert_eq!(f64::MIN_NORMAL_EXPONENT, -1022); assert_eq!(f64::MIN_EXPONENT, -1074); assert_eq!(f64::MAX_EXPONENT, 1023); assert_eq!(NiceFloat(f64::MIN_POSITIVE_SUBNORMAL), NiceFloat(5.0e-324)); assert_eq!( NiceFloat(f64::MAX_SUBNORMAL), NiceFloat(2.225073858507201e-308) ); assert_eq!( NiceFloat(f64::MIN_POSITIVE_NORMAL), NiceFloat(2.2250738585072014e-308) ); assert_eq!( NiceFloat(f64::MAX_FINITE), NiceFloat(1.7976931348623157e308) ); assert_eq!(NiceFloat(Infinity::INFINITY), NiceFloat(f64::INFINITY)); assert_eq!( NiceFloat(f64::NEGATIVE_INFINITY), NiceFloat(f64::NEG_INFINITY) ); assert_eq!(NiceFloat(NaN::NAN), NiceFloat(f64::NAN)); assert_eq!(f32::SMALLEST_UNREPRESENTABLE_UINT, 0x1000001); assert_eq!(f64::LARGEST_ORDERED_REPRESENTATION, 0xffe0000000000001); } #[test] pub fn test_named() { fn test(out: &str) { assert_eq!(T::NAME, out); } test::("u8"); test::("u16"); test::("u32"); test::("u64"); test::("u128"); test::("usize"); test::("i8"); test::("i16"); test::("i32"); test::("i64"); test::("i128"); test::("isize"); test::("f32"); test::("f64"); } malachite-base-0.4.16/tests/num/comparison/cmp_abs_partial_cmp_abs_and_comparators.rs000064400000000000000000000107371046102023000273040ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::UnsignedAbs; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::comparison::traits::OrdAbs; use malachite_base::test_util::generators::{ signed_gen, signed_pair_gen, signed_triple_gen, unsigned_gen, unsigned_pair_gen_var_27, unsigned_triple_gen_var_19, }; use std::cmp::Ordering::{self, *}; #[test] pub fn test_cmp_abs_partial_cmp_abs_and_comparators() { fn test(x: T, y: T, cmp: Ordering, lt: bool, gt: bool, le: bool, ge: bool) { assert_eq!(x.cmp_abs(&y), cmp); assert_eq!(x.partial_cmp_abs(&y), Some(cmp)); assert_eq!(lt, x.lt_abs(&y)); assert_eq!(gt, x.gt_abs(&y)); assert_eq!(le, x.le_abs(&y)); assert_eq!(ge, x.ge_abs(&y)); } test(123u16, 123u16, Equal, false, false, true, true); test(123u16, 456u16, Less, true, false, true, false); test(456u16, 123u16, Greater, false, true, false, true); test(123i64, 123i64, Equal, false, false, true, true); test(123i64, 456i64, Less, true, false, true, false); test(456i64, 123i64, Greater, false, true, false, true); test(123i64, -123i64, Equal, false, false, true, true); test(123i64, -456i64, Less, true, false, true, false); test(456i64, -123i64, Greater, false, true, false, true); test(-123i64, 123i64, Equal, false, false, true, true); test(-123i64, 456i64, Less, true, false, true, false); test(-456i64, 123i64, Greater, false, true, false, true); test(-123i64, -123i64, Equal, false, false, true, true); test(-123i64, -456i64, Less, true, false, true, false); test(-456i64, -123i64, Greater, false, true, false, true); } fn properties_helper_unsigned() { unsigned_pair_gen_var_27::().test_properties(|(x, y)| { let cmp = x.cmp_abs(&y); assert_eq!(x.cmp(&y), cmp); assert_eq!(x.partial_cmp_abs(&y), Some(cmp)); assert_eq!(x.lt_abs(&y), cmp == Less); assert_eq!(x.gt_abs(&y), cmp == Greater); assert_eq!(x.le_abs(&y), cmp != Greater); assert_eq!(x.ge_abs(&y), cmp != Less); assert_eq!(y.cmp_abs(&x), cmp.reverse()); }); unsigned_gen::().test_properties(|x| { assert_eq!(x.cmp_abs(&x), Equal); assert!(x.le_abs(&x)); assert!(x.ge_abs(&x)); assert!(!x.lt_abs(&x)); assert!(!x.gt_abs(&x)); assert!(x.le_abs(&T::MAX)); assert!(x.ge_abs(&T::ZERO)); }); unsigned_triple_gen_var_19::().test_properties(|(x, y, z)| { if x < y && y < z { assert!(x < z); } else if x > y && y > z { assert!(x > z); } }); } fn properties_helper_signed() where ::Output: Ord, { signed_pair_gen::().test_properties(|(x, y)| { let cmp = x.cmp_abs(&y); if x != T::MIN { if y != T::MIN { assert_eq!(x.unsigned_abs().cmp(&y.unsigned_abs()), cmp); } assert_eq!((-x).cmp_abs(&y), cmp); } if y != T::MIN { assert_eq!(x.cmp_abs(&-y), cmp); } assert_eq!(x.partial_cmp_abs(&y), Some(cmp)); assert_eq!(x.lt_abs(&y), cmp == Less); assert_eq!(x.gt_abs(&y), cmp == Greater); assert_eq!(x.le_abs(&y), cmp != Greater); assert_eq!(x.ge_abs(&y), cmp != Less); assert_eq!(y.cmp_abs(&x), cmp.reverse()); }); signed_gen::().test_properties(|x| { assert_eq!(x.cmp_abs(&x), Equal); assert!(x.le_abs(&x)); assert!(x.ge_abs(&x)); assert!(!x.lt_abs(&x)); assert!(!x.gt_abs(&x)); assert!(x.le_abs(&T::MIN)); assert!(x.ge_abs(&T::ZERO)); }); signed_triple_gen::().test_properties(|(x, y, z)| { if x < y && y < z { assert!(x < z); } else if x > y && y > z { assert!(x > z); } }); } #[test] fn ord_abs_partial_ord_abs_and_comparators_properties() { apply_fn_to_unsigneds!(properties_helper_unsigned); apply_fn_to_signeds!(properties_helper_signed); } malachite-base-0.4.16/tests/num/comparison/eq_abs_partial_eq_abs_and_comparators.rs000064400000000000000000000056221046102023000267550ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::UnsignedAbs; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::comparison::traits::EqAbs; use malachite_base::test_util::generators::{ signed_gen, signed_pair_gen, signed_triple_gen, unsigned_gen, unsigned_pair_gen_var_27, unsigned_triple_gen_var_19, }; #[test] pub fn test_eq_abs_partial_eq_abs_and_comparators() { fn test(x: T, y: T, eq: bool, ne: bool) { assert_eq!(x.eq_abs(&y), eq); assert_eq!(y.eq_abs(&x), eq); assert_eq!(ne, x.ne_abs(&y)); } test(123u16, 123u16, true, false); test(123u16, 456u16, false, true); test(123i64, 123i64, true, false); test(123i64, 456i64, false, true); test(123i64, -123i64, true, false); test(123i64, -456i64, false, true); test(-123i64, 123i64, true, false); test(-123i64, 456i64, false, true); test(-123i64, -123i64, true, false); test(-123i64, -456i64, false, true); } fn properties_helper_unsigned() { unsigned_pair_gen_var_27::().test_properties(|(x, y)| { let eq = x.eq_abs(&y); assert_eq!(x == y, eq); assert_eq!(y.eq_abs(&x), eq); assert_eq!(y == x, eq); assert_eq!(x.ne_abs(&y), !eq); }); unsigned_gen::().test_properties(|x| { assert!(x.eq_abs(&x)); assert!(!x.ne_abs(&x)); }); unsigned_triple_gen_var_19::().test_properties(|(x, y, z)| { if x == y && y == z { assert!(x == z); } }); } fn properties_helper_signed() where ::Output: Eq, { signed_pair_gen::().test_properties(|(x, y)| { let eq = x.eq_abs(&y); if x != T::MIN { if y != T::MIN { assert_eq!(x.unsigned_abs().eq(&y.unsigned_abs()), eq); } assert_eq!((-x).eq_abs(&y), eq); } if y != T::MIN { assert_eq!(x.eq_abs(&-y), eq); } assert_eq!(y.eq_abs(&x), eq); assert_eq!(x.ne_abs(&y), !eq); }); signed_gen::().test_properties(|x| { assert!(x.eq_abs(&x)); assert!(!x.ne_abs(&x)); }); signed_triple_gen::().test_properties(|(x, y, z)| { if x == y && y == z { assert!(x == z); } }); } #[test] fn eq_abs_partial_eq_abs_and_comparators_properties() { apply_fn_to_unsigneds!(properties_helper_unsigned); apply_fn_to_signeds!(properties_helper_signed); } malachite-base-0.4.16/tests/num/conversion/digits/general_digits/from_digits.rs000064400000000000000000000145161046102023000260270ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::repeat_n; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::{Digits, SaturatingFrom}; use malachite_base::slices::{slice_leading_zeros, slice_trailing_zeros}; use malachite_base::test_util::generators::{ unsigned_pair_gen_var_10, unsigned_vec_unsigned_pair_gen_var_7, unsigned_vec_unsigned_pair_gen_var_8, unsigned_vec_unsigned_pair_gen_var_9, }; use std::panic::catch_unwind; #[test] pub fn test_from_digits_asc() { fn test_ok + PrimitiveUnsigned, U: PrimitiveUnsigned>( base: U, digits: &[U], out: T, ) { assert_eq!(T::from_digits_asc(&base, digits.iter().copied()), Some(out)); } test_ok::(64, &[], 0); test_ok::(64, &[0, 0, 0], 0); test_ok::(64, &[2], 2); test_ok::(8, &[3, 7, 1], 123); test_ok::(256, &[64, 66, 15], 1000000); test_ok::(256, &[64, 66, 15], 1000000); test_ok::(2, &[0, 0, 0, 1, 0, 1, 1, 1, 1, 1], 1000); test_ok::(3, &[], 0); test_ok::(3, &[2], 2); test_ok::(3, &[0, 1, 1, 0, 0, 1, 1, 2, 0, 0, 2], 123456); test_ok::(10, &[6, 5, 4, 3, 2, 1], 123456); test_ok::(100, &[56, 34, 12], 123456); test_ok::(123, &[87, 19, 8], 123456); test_ok::(123, &[87, 19, 8, 0, 0, 0], 123456); fn test_err + PrimitiveUnsigned, U: PrimitiveUnsigned>(base: U, digits: &[U]) { assert_eq!(T::from_digits_asc(&base, digits.iter().copied()), None); } test_err::(64, &[1; 1000]); test_err::(2, &[2]); test_err::(1000, &[1, 2, 3]); } fn from_digits_asc_fail_helper + PrimitiveUnsigned, U: PrimitiveUnsigned>() { assert_panic!({ let digits: &[U] = &[U::ONE]; T::from_digits_asc(&U::ZERO, digits.iter().copied()); }); assert_panic!({ let digits: &[U] = &[U::ONE]; T::from_digits_asc(&U::ONE, digits.iter().copied()); }); } #[test] pub fn test_from_digits_desc() { fn test_ok + PrimitiveUnsigned, U: PrimitiveUnsigned>( base: U, digits: &[U], out: T, ) { assert_eq!( T::from_digits_desc(&base, digits.iter().copied()), Some(out) ); } test_ok::(64, &[], 0); test_ok::(64, &[0, 0, 0], 0); test_ok::(64, &[2], 2); test_ok::(8, &[1, 7, 3], 123); test_ok::(256, &[15, 66, 64], 1000000); test_ok::(256, &[15, 66, 64], 1000000); test_ok::(2, &[1, 1, 1, 1, 1, 0, 1, 0, 0, 0], 1000); test_ok::(3, &[], 0); test_ok::(3, &[2], 2); test_ok::(3, &[2, 0, 0, 2, 1, 1, 0, 0, 1, 1, 0], 123456); test_ok::(10, &[1, 2, 3, 4, 5, 6], 123456); test_ok::(100, &[12, 34, 56], 123456); test_ok::(123, &[8, 19, 87], 123456); test_ok::(123, &[0, 0, 0, 8, 19, 87], 123456); fn test_err + PrimitiveUnsigned, U: PrimitiveUnsigned>(base: U, digits: &[U]) { assert_eq!(T::from_digits_desc(&base, digits.iter().copied()), None); } test_err::(64, &[1; 1000]); test_err::(2, &[2]); test_err::(1000, &[1, 2, 3]); } fn from_digits_desc_fail_helper + PrimitiveUnsigned, U: PrimitiveUnsigned>() { assert_panic!({ let digits: &[U] = &[U::ONE]; T::from_digits_desc(&U::ZERO, digits.iter().copied()); }); assert_panic!({ let digits: &[U] = &[U::ONE]; T::from_digits_desc(&U::ONE, digits.iter().copied()); }); } #[test] fn from_digits_asc_fail() { apply_fn_to_unsigneds_and_unsigneds!(from_digits_asc_fail_helper); } #[test] fn from_digits_desc_fail() { apply_fn_to_unsigneds_and_unsigneds!(from_digits_desc_fail_helper); } fn from_digits_asc_helper< T: Digits + PrimitiveUnsigned, U: PrimitiveUnsigned + SaturatingFrom, >() { unsigned_vec_unsigned_pair_gen_var_9::().test_properties(|(digits, base)| { T::from_digits_asc(&base, digits.iter().copied()); }); unsigned_vec_unsigned_pair_gen_var_8::().test_properties(|(digits, base)| { let n = T::from_digits_asc(&base, digits.iter().copied()).unwrap(); assert_eq!( T::from_digits_desc(&base, digits.iter().rev().copied()).unwrap(), n ); let trailing_zeros = slice_trailing_zeros(&digits); assert_eq!( Digits::::to_digits_asc(&n, &base), &digits[..digits.len() - trailing_zeros] ); }); unsigned_pair_gen_var_10::().test_properties(|(base, u)| { assert_eq!( T::from_digits_asc(&base, repeat_n(U::ZERO, u)).unwrap(), T::ZERO ); }); } #[test] fn from_digits_asc_properties() { apply_fn_to_unsigneds_and_unsigneds!(from_digits_asc_helper); } fn from_digits_desc_helper< T: Digits + PrimitiveUnsigned, U: PrimitiveUnsigned + SaturatingFrom, >() { unsigned_vec_unsigned_pair_gen_var_9::().test_properties(|(digits, base)| { T::from_digits_asc(&base, digits.iter().copied()); }); unsigned_vec_unsigned_pair_gen_var_7::().test_properties(|(digits, base)| { let n = T::from_digits_desc(&base, digits.iter().copied()).unwrap(); assert_eq!( T::from_digits_asc(&base, digits.iter().rev().copied()).unwrap(), n ); let leading_zeros = slice_leading_zeros(&digits); assert_eq!( Digits::::to_digits_desc(&n, &base), &digits[leading_zeros..] ); }); unsigned_pair_gen_var_10::().test_properties(|(base, u)| { assert_eq!( T::from_digits_desc(&base, repeat_n(U::ZERO, u)).unwrap(), T::ZERO ); }); } #[test] fn from_digits_desc_properties() { apply_fn_to_unsigneds_and_unsigneds!(from_digits_desc_helper); } malachite-base-0.4.16/tests/num/conversion/digits/general_digits/to_digits.rs000064400000000000000000000134331046102023000255030ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::digits::general_digits::unsigned_to_digits_asc_naive; use malachite_base::num::conversion::traits::{Digits, ExactFrom, SaturatingFrom, WrappingFrom}; use malachite_base::test_util::generators::{ unsigned_gen, unsigned_gen_var_4, unsigned_pair_gen_var_6, }; use std::panic::catch_unwind; #[test] pub fn test_to_digits_asc() { fn test + PrimitiveUnsigned, U: PrimitiveUnsigned>(x: T, base: U, out: &[U]) { assert_eq!(x.to_digits_asc(&base), out); } test::(0, 64, &[]); test::(2, 64, &[2]); test::(123, 8, &[3, 7, 1]); test::(1000000, 256, &[64, 66, 15]); test::(1000000, 256, &[64, 66, 15]); test::(1000, 2, &[0, 0, 0, 1, 0, 1, 1, 1, 1, 1]); test::(0, 3, &[]); test::(2, 3, &[2]); test::(123456, 3, &[0, 1, 1, 0, 0, 1, 1, 2, 0, 0, 2]); test::(123456, 10, &[6, 5, 4, 3, 2, 1]); test::(123456, 100, &[56, 34, 12]); test::(123456, 123, &[87, 19, 8]); } fn to_digits_asc_fail_helper + PrimitiveUnsigned, U: PrimitiveUnsigned>() { assert_panic!(T::exact_from(100).to_digits_asc(&U::ZERO)); assert_panic!(T::exact_from(100).to_digits_asc(&U::ONE)); if T::WIDTH < U::WIDTH { assert_panic!(T::exact_from(100).to_digits_asc(&U::power_of_2(T::WIDTH))); } } #[test] fn to_digits_asc_fail() { apply_fn_to_unsigneds_and_unsigneds!(to_digits_asc_fail_helper); } #[test] pub fn test_to_digits_desc() { fn test + PrimitiveUnsigned, U: PrimitiveUnsigned>(x: T, base: U, out: &[U]) { assert_eq!(x.to_digits_desc(&base), out); } test::(0, 64, &[]); test::(2, 64, &[2]); test::(123, 8, &[1, 7, 3]); test::(1000000, 256, &[15, 66, 64]); test::(1000000, 256, &[15, 66, 64]); test::(1000, 2, &[1, 1, 1, 1, 1, 0, 1, 0, 0, 0]); test::(0, 3, &[]); test::(2, 3, &[2]); test::(123456, 3, &[2, 0, 0, 2, 1, 1, 0, 0, 1, 1, 0]); test::(123456, 10, &[1, 2, 3, 4, 5, 6]); test::(123456, 100, &[12, 34, 56]); test::(123456, 123, &[8, 19, 87]); } fn to_digits_desc_fail_helper + PrimitiveUnsigned, U: PrimitiveUnsigned>() { assert_panic!(T::exact_from(100).to_digits_desc(&U::ZERO)); assert_panic!(T::exact_from(100).to_digits_desc(&U::ONE)); if T::WIDTH < U::WIDTH { assert_panic!(T::exact_from(100).to_digits_desc(&U::power_of_2(T::WIDTH))); } } #[test] fn to_digits_desc_fail() { apply_fn_to_unsigneds_and_unsigneds!(to_digits_desc_fail_helper); } fn to_digits_asc_helper< T: Digits + ExactFrom + PrimitiveUnsigned, U: PrimitiveUnsigned + SaturatingFrom + WrappingFrom, >() { unsigned_pair_gen_var_6::().test_properties(|(u, base)| { let digits = u.to_digits_asc(&base); assert_eq!(unsigned_to_digits_asc_naive(&u, base), digits); assert_eq!( T::from_digits_asc(&base, digits.iter().copied()).unwrap(), u ); if u != T::ZERO { assert_ne!(*digits.last().unwrap(), U::ZERO); } assert_eq!( digits.iter().copied().rev().collect_vec(), u.to_digits_desc(&base) ); if u != T::ZERO { assert_eq!( u64::exact_from(digits.len()), u.floor_log_base(T::exact_from(base)) + 1 ); } assert!(digits.iter().all(|&digit| digit <= base)); }); unsigned_gen::().test_properties(|u| { assert_eq!( u.to_digits_asc(&U::TWO) .into_iter() .map(|digit| digit == U::ONE) .collect_vec(), u.to_bits_asc() ); }); unsigned_gen_var_4::().test_properties(|base| { assert!(T::ZERO.to_digits_asc(&base).is_empty()); }); } #[test] fn to_digits_asc_properties() { apply_fn_to_unsigneds_and_unsigneds!(to_digits_asc_helper); } fn to_digits_desc_helper< T: Digits + ExactFrom + PrimitiveUnsigned, U: PrimitiveUnsigned + SaturatingFrom, >() { unsigned_pair_gen_var_6::().test_properties(|(u, base)| { let digits = u.to_digits_desc(&base); assert_eq!( T::from_digits_desc(&base, digits.iter().copied()).unwrap(), u ); if u != T::ZERO { assert_ne!(digits[0], U::ZERO); } assert_eq!( digits.iter().copied().rev().collect_vec(), u.to_digits_asc(&base) ); if u != T::ZERO { assert_eq!( u64::exact_from(digits.len()), u.floor_log_base(T::exact_from(base)) + 1 ); } assert!(digits.iter().all(|&digit| digit <= base)); }); unsigned_gen::().test_properties(|u| { assert_eq!( u.to_digits_desc(&U::TWO) .into_iter() .map(|digit| digit == U::ONE) .collect_vec(), u.to_bits_desc() ); }); unsigned_gen_var_4::().test_properties(|base| { assert!(T::ZERO.to_digits_desc(&base).is_empty()); }); } #[test] fn to_digits_desc_properties() { apply_fn_to_unsigneds_and_unsigneds!(to_digits_desc_helper); } malachite-base-0.4.16/tests/num/conversion/digits/power_of_2_digits/from_power_of_2_digits.rs000064400000000000000000000140501046102023000305650ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::repeat_n; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::PowerOf2Digits; use malachite_base::slices::{slice_leading_zeros, slice_trailing_zeros}; use malachite_base::test_util::generators::{ unsigned_pair_gen_var_5, unsigned_vec_unsigned_pair_gen_var_2, unsigned_vec_unsigned_pair_gen_var_3, unsigned_vec_unsigned_pair_gen_var_6, }; use std::panic::catch_unwind; #[test] pub fn test_from_power_of_2_digits_asc() { fn test_ok + PrimitiveUnsigned, U: PrimitiveUnsigned>( log_base: u64, digits: &[U], out: T, ) { assert_eq!( T::from_power_of_2_digits_asc(log_base, digits.iter().copied()).unwrap(), out ); } test_ok::(6, &[], 0); test_ok::(6, &[2], 2); test_ok::(3, &[3, 7, 1], 123); test_ok::(8, &[64, 66, 15], 1000000); test_ok::(8, &[64, 66, 15], 1000000); test_ok::(1, &[0, 0, 0, 1, 0, 1, 1, 1, 1, 1], 1000); fn test_err + PrimitiveUnsigned, U: PrimitiveUnsigned>( log_base: u64, digits: &[U], ) { assert_eq!( T::from_power_of_2_digits_asc(log_base, digits.iter().copied()), None ); } test_err::(4, &[1; 100]); test_err::(1, &[2]); } fn from_power_of_2_digits_asc_fail_helper< T: PowerOf2Digits + PrimitiveUnsigned, U: PrimitiveUnsigned, >() { assert_panic!({ let digits: &[U] = &[U::ONE]; T::from_power_of_2_digits_asc(U::WIDTH + 1, digits.iter().copied()); }); assert_panic!({ let digits: &[U] = &[U::ONE]; T::from_power_of_2_digits_asc(0, digits.iter().copied()); }); } #[test] fn from_power_of_2_digits_asc_fail() { apply_fn_to_unsigneds_and_unsigneds!(from_power_of_2_digits_asc_fail_helper); } #[test] pub fn test_from_power_of_2_digits_desc() { fn test_ok + PrimitiveUnsigned, U: PrimitiveUnsigned>( log_base: u64, digits: &[U], out: T, ) { assert_eq!( T::from_power_of_2_digits_desc(log_base, digits.iter().copied()).unwrap(), out ); } test_ok::(6, &[], 0); test_ok::(6, &[2], 2); test_ok::(3, &[1, 7, 3], 123); test_ok::(8, &[15, 66, 64], 1000000); test_ok::(8, &[15, 66, 64], 1000000); test_ok::(1, &[1, 1, 1, 1, 1, 0, 1, 0, 0, 0], 1000); fn test_err + PrimitiveUnsigned, U: PrimitiveUnsigned>( log_base: u64, digits: &[U], ) { assert_eq!( T::from_power_of_2_digits_desc(log_base, digits.iter().copied()), None ); } test_err::(4, &[1; 100]); test_err::(1, &[2]); } fn from_power_of_2_digits_desc_fail_helper< T: PowerOf2Digits + PrimitiveUnsigned, U: PrimitiveUnsigned, >() { assert_panic!({ let digits: &[U] = &[U::ONE]; T::from_power_of_2_digits_desc(U::WIDTH + 1, digits.iter().copied()); }); assert_panic!({ let digits: &[U] = &[U::ONE]; T::from_power_of_2_digits_desc(0, digits.iter().copied()); }); } #[test] fn from_power_of_2_digits_desc_fail() { apply_fn_to_unsigneds_and_unsigneds!(from_power_of_2_digits_desc_fail_helper); } fn from_power_of_2_digits_asc_helper< T: PowerOf2Digits + PrimitiveUnsigned, U: PrimitiveUnsigned, >() { unsigned_vec_unsigned_pair_gen_var_6::().test_properties(|(digits, log_base)| { T::from_power_of_2_digits_asc(log_base, digits.iter().copied()); }); unsigned_vec_unsigned_pair_gen_var_2::().test_properties(|(digits, log_base)| { let n = T::from_power_of_2_digits_asc(log_base, digits.iter().copied()).unwrap(); assert_eq!( T::from_power_of_2_digits_desc(log_base, digits.iter().rev().copied()).unwrap(), n ); let trailing_zeros = slice_trailing_zeros(&digits); assert_eq!( PowerOf2Digits::::to_power_of_2_digits_asc(&n, log_base), &digits[..digits.len() - trailing_zeros] ); }); unsigned_pair_gen_var_5::().test_properties(|(u, log_base)| { assert_eq!( T::from_power_of_2_digits_asc(log_base, repeat_n(U::ZERO, u)).unwrap(), T::ZERO ); }); } #[test] fn from_power_of_2_digits_asc_properties() { apply_fn_to_unsigneds_and_unsigneds!(from_power_of_2_digits_asc_helper); } fn from_power_of_2_digits_desc_helper< T: PowerOf2Digits + PrimitiveUnsigned, U: PrimitiveUnsigned, >() { unsigned_vec_unsigned_pair_gen_var_6::().test_properties(|(digits, log_base)| { T::from_power_of_2_digits_desc(log_base, digits.iter().copied()); }); unsigned_vec_unsigned_pair_gen_var_3::().test_properties(|(digits, log_base)| { let n = T::from_power_of_2_digits_desc(log_base, digits.iter().copied()).unwrap(); assert_eq!( T::from_power_of_2_digits_asc(log_base, digits.iter().rev().copied()).unwrap(), n ); let leading_zeros = slice_leading_zeros(&digits); assert_eq!( PowerOf2Digits::::to_power_of_2_digits_desc(&n, log_base), &digits[leading_zeros..] ); }); unsigned_pair_gen_var_5::().test_properties(|(u, log_base)| { assert_eq!( T::from_power_of_2_digits_desc(log_base, repeat_n(U::ZERO, u)).unwrap(), T::ZERO ); }); } #[test] fn from_power_of_2_digits_desc_properties() { apply_fn_to_unsigneds_and_unsigneds!(from_power_of_2_digits_desc_helper); } malachite-base-0.4.16/tests/num/conversion/digits/power_of_2_digits/power_of_2_digit_iterable.rs000064400000000000000000000136741046102023000312410ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::DivRound; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::{ ExactFrom, PowerOf2DigitIterable, PowerOf2DigitIterator, PowerOf2Digits, }; use malachite_base::rounding_modes::RoundingMode::*; use malachite_base::test_util::common::test_double_ended_iterator_size_hint; use malachite_base::test_util::generators::{ unsigned_pair_gen_var_4, unsigned_pair_gen_var_5, unsigned_triple_gen_var_3, unsigned_unsigned_bool_vec_triple_gen_var_1, }; use std::panic::catch_unwind; #[test] pub fn test_power_of_2_digits() { assert_eq!( PowerOf2Digits::::to_power_of_2_digits_asc(&107u32, 2), &[3, 2, 2, 1] ); let mut digits = PowerOf2DigitIterable::::power_of_2_digits(107u32, 2); assert_eq!(digits.next(), Some(3)); assert_eq!(digits.next_back(), Some(1)); assert_eq!(digits.next_back(), Some(2)); assert_eq!(digits.next(), Some(2)); assert_eq!(digits.next(), None); assert_eq!(digits.next_back(), None); assert_eq!(digits.get(0), 3); assert_eq!(digits.get(1), 2); assert_eq!(digits.get(2), 2); assert_eq!(digits.get(3), 1); assert_eq!(digits.get(4), 0); assert_eq!(digits.get(5), 0); let mut digits = PowerOf2DigitIterable::::power_of_2_digits(107u32, 2); assert_eq!(digits.next_back(), Some(1)); assert_eq!(digits.next(), Some(3)); assert_eq!(digits.next(), Some(2)); assert_eq!(digits.next(), Some(2)); assert_eq!(digits.next(), None); assert_eq!(digits.next_back(), None); let mut digits = PowerOf2DigitIterable::::power_of_2_digits(0u8, 5); assert_eq!(digits.next(), None); assert_eq!(digits.next_back(), None); assert_eq!( PowerOf2Digits::::to_power_of_2_digits_asc(&105u32, 1), &[1, 0, 0, 1, 0, 1, 1] ); let mut digits = PowerOf2DigitIterable::::power_of_2_digits(105u32, 1); assert_eq!(digits.next(), Some(1)); assert_eq!(digits.next_back(), Some(1)); assert_eq!(digits.next_back(), Some(1)); assert_eq!(digits.next_back(), Some(0)); assert_eq!(digits.next(), Some(0)); assert_eq!(digits.next(), Some(0)); assert_eq!(digits.next(), Some(1)); assert_eq!(digits.next(), None); assert_eq!(digits.next_back(), None); assert_eq!(digits.get(0), 1); assert_eq!(digits.get(1), 0); assert_eq!(digits.get(2), 0); assert_eq!(digits.get(3), 1); assert_eq!(digits.get(4), 0); assert_eq!(digits.get(5), 1); assert_eq!(digits.get(6), 1); assert_eq!(digits.get(7), 0); assert_eq!(digits.get(8), 0); let mut digits = PowerOf2DigitIterable::::power_of_2_digits(105u32, 1); assert_eq!(digits.next_back(), Some(1)); assert_eq!(digits.next(), Some(1)); assert_eq!(digits.next(), Some(0)); assert_eq!(digits.next(), Some(0)); assert_eq!(digits.next_back(), Some(1)); assert_eq!(digits.next_back(), Some(0)); assert_eq!(digits.next_back(), Some(1)); assert_eq!(digits.next(), None); assert_eq!(digits.next_back(), None); } fn power_of_2_digits_fail_helper< T: PowerOf2DigitIterable + PrimitiveUnsigned, U: PrimitiveUnsigned, >() { assert_panic!(PowerOf2DigitIterable::::power_of_2_digits( T::exact_from(107), 0 )); assert_panic!(PowerOf2DigitIterable::::power_of_2_digits( T::exact_from(107), 200 )); } #[test] fn power_of_2_digits_fail() { apply_fn_to_unsigneds_and_unsigneds!(power_of_2_digits_fail_helper); } fn power_of_2_digit_iterable_helper< T: PowerOf2DigitIterable + PowerOf2Digits + PrimitiveUnsigned, U: PrimitiveUnsigned, >() where >::PowerOf2DigitIterator: Clone, { unsigned_pair_gen_var_4::().test_properties(|(u, log_base)| { test_double_ended_iterator_size_hint( PowerOf2DigitIterable::::power_of_2_digits(u, log_base), usize::exact_from(u.significant_bits().div_round(log_base, Ceiling).0), ); }); unsigned_unsigned_bool_vec_triple_gen_var_1::().test_properties( |(u, log_base, ref bs)| { let mut digits = PowerOf2DigitIterable::::power_of_2_digits(u, log_base); let mut digit_vec = Vec::new(); let mut i = 0; for &b in bs { if b { digit_vec.insert(i, digits.next().unwrap()); i += 1; } else { digit_vec.insert(i, digits.next_back().unwrap()); } } assert!(digits.next().is_none()); assert!(digits.next_back().is_none()); assert_eq!( PowerOf2Digits::::to_power_of_2_digits_asc(&u, log_base), digit_vec ); }, ); unsigned_triple_gen_var_3::().test_properties(|(u, log_base, i)| { let digits = PowerOf2DigitIterable::::power_of_2_digits(u, log_base); if i < u.significant_bits().div_round(log_base, Ceiling).0 { assert_eq!( digits.get(i), PowerOf2Digits::::to_power_of_2_digits_asc(&u, log_base)[usize::exact_from(i)] ); } else { assert_eq!(digits.get(i), U::ZERO); } }); unsigned_pair_gen_var_5::().test_properties(|(i, log_base)| { let digits = PowerOf2DigitIterable::::power_of_2_digits(T::ZERO, log_base); assert_eq!(digits.get(i), U::ZERO); }); } #[test] fn power_of_2_digit_iterable_properties() { apply_fn_to_unsigneds_and_unsigneds!(power_of_2_digit_iterable_helper); } malachite-base-0.4.16/tests/num/conversion/digits/power_of_2_digits/to_power_of_2_digits.rs000064400000000000000000000134271046102023000302530ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::num::arithmetic::traits::DivRound; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::{ExactFrom, PowerOf2Digits}; use malachite_base::rounding_modes::RoundingMode::*; use malachite_base::test_util::generators::{ unsigned_gen, unsigned_gen_var_3, unsigned_pair_gen_var_4, }; use std::panic::catch_unwind; #[test] pub fn test_to_power_of_2_digits_asc() { fn test + PrimitiveUnsigned, U: PrimitiveUnsigned>( x: T, log_base: u64, out: &[U], ) { assert_eq!( PowerOf2Digits::::to_power_of_2_digits_asc(&x, log_base), out ); } test::(0, 6, &[]); test::(2, 6, &[2]); test::(123, 3, &[3, 7, 1]); test::(1000000, 8, &[64, 66, 15]); test::(1000000, 8, &[64, 66, 15]); test::(1000, 1, &[0, 0, 0, 1, 0, 1, 1, 1, 1, 1]); } fn to_power_of_2_digits_asc_fail_helper< T: PowerOf2Digits + PrimitiveUnsigned, U: PrimitiveUnsigned, >() { assert_panic!(PowerOf2Digits::::to_power_of_2_digits_asc( &T::exact_from(100), U::WIDTH + 1 )); assert_panic!(PowerOf2Digits::::to_power_of_2_digits_asc( &T::exact_from(100), 0 )); } #[test] fn to_power_of_2_digits_asc_fail() { apply_fn_to_unsigneds_and_unsigneds!(to_power_of_2_digits_asc_fail_helper); } #[test] pub fn test_to_power_of_2_digits_desc() { fn test + PrimitiveUnsigned, U: PrimitiveUnsigned>( x: T, log_base: u64, out: &[U], ) { assert_eq!( PowerOf2Digits::::to_power_of_2_digits_desc(&x, log_base), out ); } test::(0, 6, &[]); test::(2, 6, &[2]); test::(123, 3, &[1, 7, 3]); test::(1000000, 8, &[15, 66, 64]); test::(1000000, 8, &[15, 66, 64]); test::(1000, 1, &[1, 1, 1, 1, 1, 0, 1, 0, 0, 0]); } fn to_power_of_2_digits_desc_fail_helper< T: PowerOf2Digits + PrimitiveUnsigned, U: PrimitiveUnsigned, >() { assert_panic!(PowerOf2Digits::::to_power_of_2_digits_desc( &T::exact_from(100), U::WIDTH + 1 )); assert_panic!(PowerOf2Digits::::to_power_of_2_digits_desc( &T::exact_from(100), 0 )); } #[test] fn to_power_of_2_digits_desc_fail() { apply_fn_to_unsigneds_and_unsigneds!(to_power_of_2_digits_desc_fail_helper); } fn to_power_of_2_digits_asc_helper< T: PowerOf2Digits + PrimitiveUnsigned, U: PrimitiveUnsigned, >() { unsigned_pair_gen_var_4::().test_properties(|(u, log_base)| { let digits = PowerOf2Digits::::to_power_of_2_digits_asc(&u, log_base); assert_eq!( T::from_power_of_2_digits_asc(log_base, digits.iter().copied()).unwrap(), u ); if u != T::ZERO { assert_ne!(*digits.last().unwrap(), U::ZERO); } assert_eq!( digits.iter().copied().rev().collect_vec(), u.to_power_of_2_digits_desc(log_base) ); if u != T::ZERO { assert_eq!( u64::exact_from(digits.len()), u.floor_log_base_power_of_2(log_base) + 1 ); } assert!(digits .iter() .all(|digit| digit.significant_bits() <= log_base)); }); unsigned_gen::().test_properties(|u| { assert_eq!( u.to_power_of_2_digits_asc(1) .into_iter() .map(|digit: U| digit == U::ONE) .collect_vec(), u.to_bits_asc() ); }); unsigned_gen_var_3::().test_properties(|log_base| { assert!(PowerOf2Digits::::to_power_of_2_digits_asc(&T::ZERO, log_base).is_empty()); }); } #[test] fn to_power_of_2_digits_asc_properties() { apply_fn_to_unsigneds_and_unsigneds!(to_power_of_2_digits_asc_helper); } fn to_power_of_2_digits_desc_helper< T: PowerOf2Digits + PrimitiveUnsigned, U: PrimitiveUnsigned, >() { unsigned_pair_gen_var_4::().test_properties(|(u, log_base)| { let digits = PowerOf2Digits::::to_power_of_2_digits_desc(&u, log_base); assert_eq!( T::from_power_of_2_digits_desc(log_base, digits.iter().copied()).unwrap(), u ); if u != T::ZERO { assert_ne!(digits[0], U::ZERO); } if u != T::ZERO { assert_eq!( u64::exact_from(digits.len()), u.floor_log_base_power_of_2(log_base) + 1 ); } assert_eq!( digits.len(), usize::exact_from(u.significant_bits().div_round(log_base, Ceiling).0) ); assert!(digits .iter() .all(|digit| digit.significant_bits() <= log_base)); }); unsigned_gen::().test_properties(|u| { assert_eq!( u.to_power_of_2_digits_desc(1) .into_iter() .map(|digit: U| digit == U::ONE) .collect_vec(), u.to_bits_desc() ); }); unsigned_gen_var_3::().test_properties(|log_base| { assert!(PowerOf2Digits::::to_power_of_2_digits_desc(&T::ZERO, log_base).is_empty()); }); } #[test] fn to_power_of_2_digits_desc_properties() { apply_fn_to_unsigneds_and_unsigneds!(to_power_of_2_digits_desc_helper); } malachite-base-0.4.16/tests/num/conversion/froms/convertible_from.rs000064400000000000000000000120031046102023000237300ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::traits::NegativeInfinity; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::ConvertibleFrom; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::generators::{primitive_float_gen, signed_gen, unsigned_gen}; use std::fmt::Debug; #[test] pub fn test_convertible_from() { fn test_single + Copy + Debug>(n: T) { assert!(T::convertible_from(n)); } test_single(0u8); test_single(5u64); test_single(1000u32); test_single(123u8); test_single(-123i16); test_single(i64::MIN); test_single(usize::MAX); fn test_double>(n_in: T, convertible: bool) { assert_eq!(U::convertible_from(n_in), convertible); } test_double::<_, u16>(0u8, true); test_double::<_, i32>(1000u16, true); test_double::<_, i8>(-5i16, true); test_double::<_, u64>(255u8, true); test_double::<_, u32>(-1i8, false); test_double::<_, u16>(u32::MAX, false); test_double::<_, u32>(i32::MIN, false); test_double::<_, u16>(i32::MIN, false); test_double::<_, i16>(i32::MIN, false); test_double::<_, u32>(-5i32, false); test_double::<_, i32>(3000000000u32, false); test_double::<_, i8>(-1000i16, false); test_double::<_, u8>(0.0f32, true); test_double::<_, u8>(-0.0f32, true); test_double::<_, u8>(123.0f32, true); test_double::<_, i8>(-123.0f32, true); test_double::<_, u8>(-123.0f32, false); test_double::<_, u8>(500.0f32, false); test_double::<_, u8>(123.1f32, false); test_double::<_, u8>(f32::NAN, false); test_double::<_, u8>(f32::INFINITY, false); test_double::<_, u8>(f32::NEGATIVE_INFINITY, false); test_double::<_, u8>(255.0f32, true); test_double::<_, u8>(256.0f32, false); test_double::<_, i8>(127.0f32, true); test_double::<_, i8>(128.0f32, false); test_double::<_, i8>(-128.0f32, true); test_double::<_, i8>(-129.0f32, false); test_double::<_, f32>(0u8, true); test_double::<_, f32>(123u8, true); test_double::<_, f32>(-123i8, true); test_double::<_, f32>(u128::MAX, false); test_double::<_, f32>(i128::MIN, true); test_double::<_, f32>(i128::MIN + 1, false); test_double::<_, f32>(u32::MAX, false); test_double::<_, f32>(i32::MIN, true); test_double::<_, f32>(i32::MIN + 1, false); } fn convertible_from_helper_primitive_int_unsigned< T: TryFrom + ConvertibleFrom + PrimitiveInt, U: PrimitiveUnsigned, >() { unsigned_gen::().test_properties(|u| { let convertible = T::convertible_from(u); assert_eq!(convertible, T::try_from(u).is_ok()); }); } fn convertible_from_helper_primitive_int_signed< T: TryFrom + ConvertibleFrom + PrimitiveInt, U: PrimitiveSigned, >() { signed_gen::().test_properties(|i| { let convertible = T::convertible_from(i); assert_eq!(convertible, T::try_from(i).is_ok()); }); } fn convertible_from_helper_primitive_int_primitive_float< T: TryFrom> + ConvertibleFrom + PrimitiveInt, U: PrimitiveFloat, >() { primitive_float_gen::().test_properties(|f| { let convertible = T::convertible_from(f); assert_eq!(convertible, T::try_from(NiceFloat(f)).is_ok()); }); } fn convertible_from_helper_primitive_float_unsigned< T: ConvertibleFrom + PrimitiveFloat, U: PrimitiveUnsigned, >() where NiceFloat: TryFrom, { unsigned_gen::().test_properties(|u| { let convertible = T::convertible_from(u); assert_eq!(convertible, NiceFloat::::try_from(u).is_ok()); }); } fn convertible_from_helper_primitive_float_signed< T: ConvertibleFrom + PrimitiveFloat, U: PrimitiveSigned, >() where NiceFloat: TryFrom, { signed_gen::().test_properties(|i| { let convertible = T::convertible_from(i); assert_eq!(convertible, NiceFloat::::try_from(i).is_ok()); }); } #[test] fn convertible_from_properties() { apply_fn_to_primitive_ints_and_unsigneds!(convertible_from_helper_primitive_int_unsigned); apply_fn_to_primitive_ints_and_signeds!(convertible_from_helper_primitive_int_signed); apply_fn_to_primitive_ints_and_primitive_floats!( convertible_from_helper_primitive_int_primitive_float ); apply_fn_to_primitive_floats_and_unsigneds!(convertible_from_helper_primitive_float_unsigned); apply_fn_to_primitive_floats_and_signeds!(convertible_from_helper_primitive_float_signed); } malachite-base-0.4.16/tests/num/conversion/froms/from.rs000064400000000000000000000104471046102023000213460ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::{ FromOtherTypeSlice, JoinHalves, SplitInHalf, VecFromOtherType, VecFromOtherTypeSlice, }; use std::fmt::Debug; fn split_in_half_helper(n: T, out: (T::Half, T::Half)) where T::Half: PrimitiveUnsigned, { assert_eq!(n.split_in_half(), out); } #[test] pub fn test_split_in_half() { split_in_half_helper(0u64, (0u32, 0u32)); split_in_half_helper(1u64, (0u32, 1u32)); split_in_half_helper(u16::from(u8::MAX), (0, u8::MAX)); split_in_half_helper(u16::from(u8::MAX) + 1, (1, 0)); split_in_half_helper(u16::MAX, (u8::MAX, u8::MAX)); split_in_half_helper(258u16, (1u8, 2u8)); split_in_half_helper(0xabcd1234u32, (0xabcd, 0x1234)); } fn lower_half_helper(n: T, out: T::Half) where T::Half: PrimitiveUnsigned, { assert_eq!(n.lower_half(), out); } #[test] pub fn test_lower_half() { lower_half_helper(0u64, 0u32); lower_half_helper(1u64, 1u32); lower_half_helper(u16::from(u8::MAX), u8::MAX); lower_half_helper(u16::from(u8::MAX) + 1, 0); lower_half_helper(u16::MAX, u8::MAX); lower_half_helper(258u16, 2u8); lower_half_helper(0xabcd1234u32, 0x1234); } fn upper_half_helper(n: T, out: T::Half) where T::Half: PrimitiveUnsigned, { assert_eq!(n.upper_half(), out); } #[test] pub fn test_upper_half() { upper_half_helper(0u64, 0u32); upper_half_helper(1u64, 0u32); upper_half_helper(u16::from(u8::MAX), 0); upper_half_helper(u16::from(u8::MAX) + 1, 1); upper_half_helper(u16::MAX, u8::MAX); upper_half_helper(258u16, 1u8); upper_half_helper(0xabcd1234u32, 0xabcd); } fn join_halves_helper(upper: T::Half, lower: T::Half, out: T) { assert_eq!(T::join_halves(upper, lower), out); } #[test] pub fn test_join_halves() { join_halves_helper(0u32, 0u32, 0u64); join_halves_helper(0u32, 1u32, 1u64); join_halves_helper(0, u8::MAX, u16::from(u8::MAX)); join_halves_helper(1, 0, u16::from(u8::MAX) + 1); join_halves_helper(u8::MAX, u8::MAX, u16::MAX); join_halves_helper(1, 2, 258u16); join_halves_helper(0xabcd, 0x1234, 0xabcd1234u32); } #[test] pub fn test_from_other_type_slice() { fn test>(slice: &[T], n: U) { assert_eq!(U::from_other_type_slice(slice), n); } test::(&[], 0); test::(&[123], 123); test::(&[123, 456], 123); test::(&[0xab], 0xab); test::(&[0xab, 0xcd], 0xcdab); test::(&[0xab, 0xcd, 0xef], 0xcdab); test::( &[0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67], 0x67452301efcdab, ); test::( &[0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xff], 0x8967452301efcdab, ); test::(&[], 0); test::(&[0xabcd, 0xef01], 0xcd); test::(&[0x1234567890a9cdef012345678909bcde], 0xde); } #[test] pub fn test_vec_from_other_type_slice() { fn test>(slice: &[T], vec: &[U]) { assert_eq!(U::vec_from_other_type_slice(slice), vec); } test::(&[123, 456], &[123, 456]); test::( &[0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xff], &[0xcdab, 0x01ef, 0x4523, 0x8967, 0xff], ); test::(&[0xab], &[0xab]); test::( &[0xcdab, 0x01ef, 0x4523, 0x8967], &[0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89], ); } #[test] pub fn test_vec_from_other_type() { fn test>(value: T, vec: &[U]) { assert_eq!(U::vec_from_other_type(value), vec); } test::(123, &[123]); test::(0xab, &[0xab]); test::(0xcdab, &[0xab, 0xcd]); } malachite-base-0.4.16/tests/num/conversion/froms/overflowing_from.rs000064400000000000000000000051711046102023000237650ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::{ConvertibleFrom, OverflowingFrom, WrappingFrom}; use malachite_base::test_util::generators::{signed_gen, unsigned_gen}; use std::fmt::Debug; #[test] pub fn test_overflowing_from() { fn test_single>(n: T) { assert_eq!(T::overflowing_from(n), (n, false)); } test_single(0u8); test_single(5u64); test_single(1000u32); test_single(123u8); test_single(-123i16); test_single(i64::MIN); test_single(usize::MAX); fn test_double>(n_in: T, n_out: (U, bool)) { assert_eq!(U::overflowing_from(n_in), n_out); } test_double(0u8, (0u16, false)); test_double(1000u16, (1000i32, false)); test_double(-5i16, (-5i8, false)); test_double(255u8, (255u64, false)); test_double(-1i8, (u32::MAX, true)); test_double(u32::MAX, (u16::MAX, true)); test_double(i32::MIN, (0x80000000u32, true)); test_double(i32::MIN, (0u16, true)); test_double(i32::MIN, (0i16, true)); test_double(-5i32, (0xfffffffbu32, true)); test_double(3000000000u32, (-1294967296i32, true)); test_double(-1000i16, (24i8, true)); } fn overflowing_from_helper_primitive_int_unsigned< T: ConvertibleFrom + OverflowingFrom + WrappingFrom + PrimitiveInt, U: PrimitiveUnsigned, >() { unsigned_gen::().test_properties(|u| { let result = T::overflowing_from(u); assert_eq!(result, (T::wrapping_from(u), !T::convertible_from(u))); }); } fn overflowing_from_helper_primitive_int_signed< T: ConvertibleFrom + OverflowingFrom + WrappingFrom + PrimitiveInt, U: PrimitiveSigned, >() { signed_gen::().test_properties(|i| { let result = T::overflowing_from(i); assert_eq!(result, (T::wrapping_from(i), !T::convertible_from(i))); }); } #[test] fn overflowing_from_properties() { apply_fn_to_primitive_ints_and_unsigneds!(overflowing_from_helper_primitive_int_unsigned); apply_fn_to_primitive_ints_and_signeds!(overflowing_from_helper_primitive_int_signed); } malachite-base-0.4.16/tests/num/conversion/froms/rounding_from.rs000064400000000000000000000552101046102023000232500ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::Parity; use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::traits::NegativeInfinity; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::{ConvertibleFrom, RoundingFrom, WrappingFrom}; use malachite_base::num::float::NiceFloat; use malachite_base::rounding_modes::exhaustive::exhaustive_rounding_modes; use malachite_base::rounding_modes::RoundingMode::{self, *}; use malachite_base::test_util::generators::{ primitive_float_gen_var_13, primitive_float_gen_var_14, primitive_float_gen_var_15, primitive_float_gen_var_16, primitive_float_gen_var_17, primitive_float_rounding_mode_pair_gen_var_3, signed_gen_var_7, signed_gen_var_8, signed_gen_var_9, signed_rounding_mode_pair_gen_var_4, unsigned_gen_var_18, unsigned_gen_var_19, unsigned_gen_var_20, unsigned_rounding_mode_pair_gen_var_2, }; use std::cmp::Ordering::{self, *}; use std::panic::catch_unwind; #[test] pub fn test_rounding_from() { fn test_from_floating_point>( n_in: T, rm: RoundingMode, n_out: U, o: Ordering, ) { assert_eq!(U::rounding_from(n_in, rm), (n_out, o)); } test_from_floating_point::(0.0, Down, 0, Equal); test_from_floating_point::(0.0, Floor, 0, Equal); test_from_floating_point::(0.0, Up, 0, Equal); test_from_floating_point::(0.0, Ceiling, 0, Equal); test_from_floating_point::(0.0, Nearest, 0, Equal); test_from_floating_point::(0.0, Exact, 0, Equal); test_from_floating_point::(-0.0, Down, 0, Equal); test_from_floating_point::(-0.0, Floor, 0, Equal); test_from_floating_point::(-0.0, Up, 0, Equal); test_from_floating_point::(-0.0, Ceiling, 0, Equal); test_from_floating_point::(-0.0, Nearest, 0, Equal); test_from_floating_point::(-0.0, Exact, 0, Equal); test_from_floating_point::(100.0, Down, 100, Equal); test_from_floating_point::(100.0, Floor, 100, Equal); test_from_floating_point::(100.0, Up, 100, Equal); test_from_floating_point::(100.0, Ceiling, 100, Equal); test_from_floating_point::(100.0, Nearest, 100, Equal); test_from_floating_point::(100.0, Exact, 100, Equal); test_from_floating_point::(100.1, Down, 100, Less); test_from_floating_point::(100.1, Floor, 100, Less); test_from_floating_point::(100.1, Up, 101, Greater); test_from_floating_point::(100.1, Ceiling, 101, Greater); test_from_floating_point::(100.1, Nearest, 100, Less); test_from_floating_point::(100.9, Down, 100, Less); test_from_floating_point::(100.9, Floor, 100, Less); test_from_floating_point::(100.9, Up, 101, Greater); test_from_floating_point::(100.9, Ceiling, 101, Greater); test_from_floating_point::(100.9, Nearest, 101, Greater); test_from_floating_point::(100.5, Down, 100, Less); test_from_floating_point::(100.5, Floor, 100, Less); test_from_floating_point::(100.5, Up, 101, Greater); test_from_floating_point::(100.5, Ceiling, 101, Greater); test_from_floating_point::(100.5, Nearest, 100, Less); test_from_floating_point::(101.5, Down, 101, Less); test_from_floating_point::(101.5, Floor, 101, Less); test_from_floating_point::(101.5, Up, 102, Greater); test_from_floating_point::(101.5, Ceiling, 102, Greater); test_from_floating_point::(101.5, Nearest, 102, Greater); test_from_floating_point::(256.0, Down, 255, Less); test_from_floating_point::(256.0, Floor, 255, Less); test_from_floating_point::(256.0, Nearest, 255, Less); test_from_floating_point::(-100.0, Down, 0, Greater); test_from_floating_point::(-100.0, Ceiling, 0, Greater); test_from_floating_point::(-100.0, Nearest, 0, Greater); test_from_floating_point::(128.0, Down, 127, Less); test_from_floating_point::(128.0, Floor, 127, Less); test_from_floating_point::(128.0, Nearest, 127, Less); test_from_floating_point::(-129.0, Down, -128, Greater); test_from_floating_point::(-129.0, Ceiling, -128, Greater); test_from_floating_point::(-129.0, Nearest, -128, Greater); test_from_floating_point::(f32::INFINITY, Down, 255, Less); test_from_floating_point::(f32::INFINITY, Floor, 255, Less); test_from_floating_point::(f32::INFINITY, Nearest, 255, Less); test_from_floating_point::(f32::NEGATIVE_INFINITY, Down, 0, Greater); test_from_floating_point::(f32::NEGATIVE_INFINITY, Ceiling, 0, Greater); test_from_floating_point::(f32::NEGATIVE_INFINITY, Nearest, 0, Greater); test_from_floating_point::(f32::INFINITY, Down, 127, Less); test_from_floating_point::(f32::INFINITY, Floor, 127, Less); test_from_floating_point::(f32::INFINITY, Nearest, 127, Less); test_from_floating_point::(f32::NEGATIVE_INFINITY, Down, -128, Greater); test_from_floating_point::(f32::NEGATIVE_INFINITY, Ceiling, -128, Greater); test_from_floating_point::(f32::NEGATIVE_INFINITY, Nearest, -128, Greater); fn test_from_primitive_int>( n_in: T, rm: RoundingMode, n_out: U, o: Ordering, ) { let (x, actual_o) = U::rounding_from(n_in, rm); assert_eq!((NiceFloat(x), actual_o), (NiceFloat(n_out), o)); } test_from_primitive_int::(0, Down, 0.0, Equal); test_from_primitive_int::(0, Floor, 0.0, Equal); test_from_primitive_int::(0, Up, 0.0, Equal); test_from_primitive_int::(0, Ceiling, 0.0, Equal); test_from_primitive_int::(0, Nearest, 0.0, Equal); test_from_primitive_int::(0, Exact, 0.0, Equal); test_from_primitive_int::(100, Down, 100.0, Equal); test_from_primitive_int::(100, Floor, 100.0, Equal); test_from_primitive_int::(100, Up, 100.0, Equal); test_from_primitive_int::(100, Ceiling, 100.0, Equal); test_from_primitive_int::(100, Nearest, 100.0, Equal); test_from_primitive_int::(100, Exact, 100.0, Equal); test_from_primitive_int::(-100, Down, -100.0, Equal); test_from_primitive_int::(-100, Floor, -100.0, Equal); test_from_primitive_int::(-100, Up, -100.0, Equal); test_from_primitive_int::(-100, Ceiling, -100.0, Equal); test_from_primitive_int::(-100, Nearest, -100.0, Equal); test_from_primitive_int::(-100, Exact, -100.0, Equal); test_from_primitive_int::(i32::MIN, Down, -2147483600.0, Equal); test_from_primitive_int::(i32::MIN, Floor, -2147483600.0, Equal); test_from_primitive_int::(i32::MIN, Up, -2147483600.0, Equal); test_from_primitive_int::(i32::MIN, Ceiling, -2147483600.0, Equal); test_from_primitive_int::(i32::MIN, Nearest, -2147483600.0, Equal); test_from_primitive_int::(i32::MIN, Exact, -2147483600.0, Equal); test_from_primitive_int::(i32::MAX, Down, 2147483500.0, Less); test_from_primitive_int::(i32::MAX, Floor, 2147483500.0, Less); test_from_primitive_int::(i32::MAX, Up, 2147483600.0, Greater); test_from_primitive_int::(i32::MAX, Ceiling, 2147483600.0, Greater); test_from_primitive_int::(i32::MAX, Nearest, 2147483600.0, Greater); test_from_primitive_int::(u128::MAX, Down, 3.4028235e38, Less); test_from_primitive_int::(u128::MAX, Floor, 3.4028235e38, Less); test_from_primitive_int::(u128::MAX, Up, f32::INFINITY, Greater); test_from_primitive_int::(u128::MAX, Ceiling, f32::INFINITY, Greater); test_from_primitive_int::(u128::MAX, Nearest, 3.4028235e38, Less); } #[test] fn exact_from_fail() { assert_panic!(u8::rounding_from(100.1f32, Exact)); assert_panic!(u8::rounding_from(256.0f32, Exact)); assert_panic!(u8::rounding_from(256.0f32, Up)); assert_panic!(u8::rounding_from(256.0f32, Ceiling)); assert_panic!(u8::rounding_from(-100.0f32, Exact)); assert_panic!(u8::rounding_from(-100.0f32, Up)); assert_panic!(u8::rounding_from(-100.0f32, Floor)); assert_panic!(i8::rounding_from(128.0f32, Exact)); assert_panic!(i8::rounding_from(128.0f32, Up)); assert_panic!(i8::rounding_from(128.0f32, Ceiling)); assert_panic!(i8::rounding_from(-129.0f32, Exact)); assert_panic!(i8::rounding_from(-129.0f32, Up)); assert_panic!(i8::rounding_from(-129.0f32, Floor)); assert_panic!(u8::rounding_from(f32::NAN, Down)); assert_panic!(u8::rounding_from(f32::NAN, Floor)); assert_panic!(u8::rounding_from(f32::NAN, Up)); assert_panic!(u8::rounding_from(f32::NAN, Ceiling)); assert_panic!(u8::rounding_from(f32::NAN, Nearest)); assert_panic!(u8::rounding_from(f32::NAN, Exact)); assert_panic!(u8::rounding_from(f32::INFINITY, Up)); assert_panic!(u8::rounding_from(f32::INFINITY, Ceiling)); assert_panic!(u8::rounding_from(f32::INFINITY, Exact)); assert_panic!(u8::rounding_from(f32::NEGATIVE_INFINITY, Up)); assert_panic!(u8::rounding_from(f32::NEGATIVE_INFINITY, Floor)); assert_panic!(u8::rounding_from(f32::NEGATIVE_INFINITY, Exact)); assert_panic!(i8::rounding_from(f32::INFINITY, Up)); assert_panic!(i8::rounding_from(f32::INFINITY, Ceiling)); assert_panic!(i8::rounding_from(f32::INFINITY, Exact)); assert_panic!(i8::rounding_from(f32::NEGATIVE_INFINITY, Up)); assert_panic!(i8::rounding_from(f32::NEGATIVE_INFINITY, Floor)); assert_panic!(i8::rounding_from(f32::NEGATIVE_INFINITY, Exact)); assert_panic!(u8::rounding_from(f32::NAN, Down)); assert_panic!(f32::rounding_from(u32::MAX, Exact)); assert_panic!(f32::rounding_from(u128::MAX, Exact)); } fn rounding_from_helper_unsigned_primitive_float< T: ConvertibleFrom + PrimitiveUnsigned + RoundingFrom, U: PrimitiveFloat + RoundingFrom, >() where NiceFloat: TryFrom, { primitive_float_rounding_mode_pair_gen_var_3::().test_properties(|(f, rm)| { let (rounded, o) = T::rounding_from(f, rm); match (f >= U::ZERO, rm) { (_, Floor) | (true, Down) | (false, Up) => { assert_ne!(o, Greater); } (_, Ceiling) | (true, Up) | (false, Down) => { assert_ne!(o, Less); } (_, Exact) => assert_eq!(o, Equal), _ => {} } if o == Equal { for rm in exhaustive_rounding_modes() { assert_eq!(T::rounding_from(f, rm), (rounded, Equal)); } } else { assert_panic!(T::rounding_from(f, Exact)); } }); primitive_float_gen_var_13::().test_properties(|f| { let no = T::rounding_from(f, Exact); assert_eq!(no, T::rounding_from(f, Floor)); assert_eq!(no, T::rounding_from(f, Ceiling)); assert_eq!(no, T::rounding_from(f, Down)); assert_eq!(no, T::rounding_from(f, Up)); assert_eq!(no, T::rounding_from(f, Nearest)); }); let f_max = U::rounding_from(T::MAX, Down).0; primitive_float_gen_var_15::().test_properties(|f| { if f >= U::ZERO && f <= f_max { let n_floor = T::rounding_from(f, Floor); assert_eq!(n_floor.1, Less); if let Some(n_ceiling) = n_floor.0.checked_add(T::ONE) { let n_ceiling = (n_ceiling, Greater); assert_eq!(n_ceiling, T::rounding_from(f, Ceiling)); assert_eq!(n_floor, T::rounding_from(f, Down)); assert_eq!(n_ceiling, T::rounding_from(f, Up)); let n_nearest = T::rounding_from(f, Nearest); assert!(n_nearest == n_floor || n_nearest == n_ceiling); } } }); primitive_float_gen_var_16::().test_properties(|f| { let floor = T::rounding_from(f, Floor); let ceiling = (floor.0 + T::ONE, Greater); let nearest = T::rounding_from(f, Nearest); assert_eq!(nearest, if floor.0.even() { floor } else { ceiling }); }); } fn rounding_from_helper_signed_primitive_float< T: ConvertibleFrom + PrimitiveSigned + RoundingFrom, U: PrimitiveFloat + RoundingFrom, >() where NiceFloat: TryFrom, { primitive_float_rounding_mode_pair_gen_var_3::().test_properties(|(f, rm)| { let (rounded, o) = T::rounding_from(f, rm); match (f >= U::ZERO, rm) { (_, Floor) | (true, Down) | (false, Up) => { assert_ne!(o, Greater); } (_, Ceiling) | (true, Up) | (false, Down) => { assert_ne!(o, Less); } (_, Exact) => assert_eq!(o, Equal), _ => {} } if o == Equal { for rm in exhaustive_rounding_modes() { assert_eq!(T::rounding_from(f, rm), (rounded, Equal)); } } else { assert_panic!(T::rounding_from(f, Exact)); } }); primitive_float_gen_var_14::().test_properties(|f| { let no = T::rounding_from(f, Exact); assert_eq!(no, T::rounding_from(f, Floor)); assert_eq!(no, T::rounding_from(f, Ceiling)); assert_eq!(no, T::rounding_from(f, Down)); assert_eq!(no, T::rounding_from(f, Up)); assert_eq!(no, T::rounding_from(f, Nearest)); }); let f_min = U::rounding_from(T::MIN, Down).0; let f_max = U::rounding_from(T::MAX, Down).0; primitive_float_gen_var_15::().test_properties(|f| { if f >= f_min && f <= f_max { let n_floor = T::rounding_from(f, Floor); if let Some(n_ceiling) = n_floor.0.checked_add(T::ONE) { let n_ceiling = (n_ceiling, Greater); assert_eq!(n_ceiling, T::rounding_from(f, Ceiling)); if f >= U::ZERO { assert_eq!(n_floor, T::rounding_from(f, Down)); assert_eq!(n_ceiling, T::rounding_from(f, Up)); } else { assert_eq!(n_ceiling, T::rounding_from(f, Down)); assert_eq!(n_floor, T::rounding_from(f, Up)); } let n_nearest = T::rounding_from(f, Nearest); assert!(n_nearest == n_floor || n_nearest == n_ceiling); } } }); primitive_float_gen_var_17::().test_properties(|f| { let floor = T::rounding_from(f, Floor); let ceiling = (floor.0 + T::ONE, Greater); let nearest = T::rounding_from(f, Nearest); assert_eq!(nearest, if floor.0.even() { floor } else { ceiling }); }); } fn rounding_from_helper_primitive_float_unsigned< T: ConvertibleFrom + PrimitiveFloat + RoundingFrom, U: TryFrom> + PrimitiveUnsigned + RoundingFrom, >() { unsigned_rounding_mode_pair_gen_var_2::().test_properties(|(u, rm)| { let (rounded, o) = T::rounding_from(u, rm); match rm { Floor | Down => assert_ne!(o, Greater), Ceiling | Up => assert_ne!(o, Less), Exact => assert_eq!(o, Equal), _ => {} } if o == Equal { for rm in exhaustive_rounding_modes() { assert_eq!(T::rounding_from(u, rm), (rounded, Equal)); } } else { assert_panic!(T::rounding_from(u, Exact)); } }); unsigned_gen_var_18::().test_properties(|u| { let (f, o) = T::rounding_from(u, Exact); let (f_alt, o_alt) = T::rounding_from(u, Floor); assert_eq!(NiceFloat(f_alt), NiceFloat(f)); assert_eq!(o_alt, o); let (f_alt, o_alt) = T::rounding_from(u, Ceiling); assert_eq!(NiceFloat(f_alt), NiceFloat(f)); assert_eq!(o_alt, o); let (f_alt, o_alt) = T::rounding_from(u, Down); assert_eq!(NiceFloat(f_alt), NiceFloat(f)); assert_eq!(o_alt, o); let (f_alt, o_alt) = T::rounding_from(u, Up); assert_eq!(NiceFloat(f_alt), NiceFloat(f)); assert_eq!(o_alt, o); let (f_alt, o_alt) = T::rounding_from(u, Nearest); assert_eq!(NiceFloat(f_alt), NiceFloat(f)); assert_eq!(o_alt, o); assert_eq!(U::rounding_from(f, Exact), (u, Equal)); }); if U::WIDTH > T::MANTISSA_WIDTH { unsigned_gen_var_19::().test_properties(|u| { let (f_below, o) = T::rounding_from(u, Floor); assert_eq!(o, Less); let f_above = f_below.next_higher(); let (f_alt, o) = T::rounding_from(u, Ceiling); assert_eq!(NiceFloat(f_alt), NiceFloat(f_above)); assert_eq!(o, Greater); let (f_alt, o) = T::rounding_from(u, Down); assert_eq!(NiceFloat(f_alt), NiceFloat(f_below)); assert_eq!(o, Less); let (f_alt, o) = T::rounding_from(u, Up); assert_eq!(NiceFloat(f_alt), NiceFloat(f_above)); assert_eq!(o, Greater); let (f_nearest, o) = T::rounding_from(u, Nearest); assert!( (NiceFloat(f_nearest), o) == (NiceFloat(f_below), Less) || (NiceFloat(f_nearest), o) == (NiceFloat(f_above), Greater) ); }); unsigned_gen_var_20::().test_properties(|u| { let (floor, o) = T::rounding_from(u, Floor); assert_eq!(o, Less); let ceiling = floor.next_higher(); let (nearest, o) = T::rounding_from(u, Nearest); assert_eq!( (NiceFloat(nearest), o), if floor.to_bits().even() { (NiceFloat(floor), Less) } else { (NiceFloat(ceiling), Greater) } ); }); } } fn rounding_from_helper_primitive_float_signed< T: ConvertibleFrom + PrimitiveFloat + RoundingFrom, U: PrimitiveUnsigned + WrappingFrom, S: TryFrom> + PrimitiveSigned + RoundingFrom + WrappingFrom, >() { signed_rounding_mode_pair_gen_var_4::().test_properties(|(i, rm)| { let (rounded, o) = T::rounding_from(i, rm); match (i >= S::ZERO, rm) { (_, Floor) | (true, Down) | (false, Up) => { assert_ne!(o, Greater); } (_, Ceiling) | (true, Up) | (false, Down) => { assert_ne!(o, Less); } (_, Exact) => assert_eq!(o, Equal), _ => {} } if o == Equal { for rm in exhaustive_rounding_modes() { assert_eq!(T::rounding_from(i, rm), (rounded, Equal)); } } else { assert_panic!(T::rounding_from(i, Exact)); } }); signed_gen_var_7::().test_properties(|i| { let (f, o) = T::rounding_from(i, Exact); let (f_alt, o_alt) = T::rounding_from(i, Floor); assert_eq!(NiceFloat(f_alt), NiceFloat(f)); assert_eq!(o_alt, o); let (f_alt, o_alt) = T::rounding_from(i, Ceiling); assert_eq!(NiceFloat(f_alt), NiceFloat(f)); assert_eq!(o_alt, o); let (f_alt, o_alt) = T::rounding_from(i, Down); assert_eq!(NiceFloat(f_alt), NiceFloat(f)); assert_eq!(o_alt, o); let (f_alt, o_alt) = T::rounding_from(i, Up); assert_eq!(NiceFloat(f_alt), NiceFloat(f)); assert_eq!(o_alt, o); let (f_alt, o_alt) = T::rounding_from(i, Nearest); assert_eq!(NiceFloat(f_alt), NiceFloat(f)); assert_eq!(o_alt, o); assert_eq!(S::rounding_from(f, Exact), (i, Equal)); }); if S::WIDTH > T::MANTISSA_WIDTH { signed_gen_var_8::().test_properties(|i| { let (f_below, o) = T::rounding_from(i, Floor); assert_eq!(o, Less); let f_above = f_below.next_higher(); let (f_alt, o_alt) = T::rounding_from(i, Ceiling); assert_eq!(NiceFloat(f_alt), NiceFloat(f_above)); assert_eq!(o_alt, Greater); if i >= S::ZERO { let (f_alt, o_alt) = T::rounding_from(i, Down); assert_eq!(NiceFloat(f_below), NiceFloat(f_alt)); assert_eq!(o_alt, Less); let (f_alt, o_alt) = T::rounding_from(i, Up); assert_eq!(NiceFloat(f_above), NiceFloat(f_alt)); assert_eq!(o_alt, Greater); } else { let (f_alt, o_alt) = T::rounding_from(i, Down); assert_eq!(NiceFloat(f_above), NiceFloat(f_alt)); assert_eq!(o_alt, Greater); let (f_alt, o_alt) = T::rounding_from(i, Up); assert_eq!(NiceFloat(f_below), NiceFloat(f_alt)); assert_eq!(o_alt, Less); } let (f_nearest, o_alt) = T::rounding_from(i, Nearest); assert!( (NiceFloat(f_nearest), o_alt) == (NiceFloat(f_below), Less) || (NiceFloat(f_nearest), o_alt) == (NiceFloat(f_above), Greater) ); }); signed_gen_var_9::().test_properties(|i| { let (floor, o) = T::rounding_from(i, Floor); assert_eq!(o, Less); let ceiling = floor.next_higher(); let (nearest, o) = T::rounding_from(i, Nearest); assert_eq!( (NiceFloat(nearest), o), if floor.to_bits().even() { (NiceFloat(floor), Less) } else { (NiceFloat(ceiling), Greater) } ); }); } } #[test] fn rounding_from_properties() { apply_fn_to_unsigneds_and_primitive_floats!(rounding_from_helper_unsigned_primitive_float); apply_fn_to_signeds_and_primitive_floats!(rounding_from_helper_signed_primitive_float); apply_fn_to_primitive_floats_and_unsigneds!(rounding_from_helper_primitive_float_unsigned); apply_fn_to_primitive_floats_and_unsigned_signed_pairs!( rounding_from_helper_primitive_float_signed ); } malachite-base-0.4.16/tests/num/conversion/froms/saturating_from.rs000064400000000000000000000055121046102023000236040ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::{ConvertibleFrom, SaturatingFrom}; use malachite_base::test_util::generators::{signed_gen, unsigned_gen}; use std::fmt::Debug; #[test] pub fn test_saturating_from() { fn test_single>(n: T) { assert_eq!(T::saturating_from(n), n); } test_single(0u8); test_single(5u64); test_single(1000u32); test_single(123u8); test_single(-123i16); test_single(i64::MIN); test_single(usize::MAX); fn test_double>(n_in: T, n_out: U) { assert_eq!(U::saturating_from(n_in), n_out); } test_double(0u8, 0u16); test_double(1000u16, 1000i32); test_double(-5i16, -5i8); test_double(255u8, 255u64); test_double(-1i8, 0u32); test_double(u32::MAX, u16::MAX); test_double(i32::MIN, 0u32); test_double(i32::MIN, 0u16); test_double(i32::MIN, i16::MIN); test_double(-5i32, 0u32); test_double(3000000000u32, i32::MAX); test_double(-1000i16, i8::MIN); } fn saturating_from_helper_primitive_int_unsigned< T: TryFrom + ConvertibleFrom + SaturatingFrom + PrimitiveInt, U: TryFrom + PrimitiveUnsigned, >() { unsigned_gen::().test_properties(|u| { let result = T::saturating_from(u); if let Ok(u_u) = T::try_from(u) { assert_eq!(result, u_u); } if let Ok(result_t) = U::try_from(result) { assert!(result_t.le_abs(&u)); assert_eq!(result_t == u, T::convertible_from(u)); } }); } fn saturating_from_helper_primitive_int_signed< T: TryFrom + ConvertibleFrom + SaturatingFrom + PrimitiveInt, U: TryFrom + PrimitiveSigned, >() { signed_gen::().test_properties(|i| { let result = T::saturating_from(i); if let Ok(i_u) = T::try_from(i) { assert_eq!(result, i_u); } if let Ok(result_t) = U::try_from(result) { assert!(result_t.le_abs(&i)); assert_eq!(result_t == i, T::convertible_from(i)); } }); } #[test] fn saturating_from_properties() { apply_fn_to_primitive_ints_and_unsigneds!(saturating_from_helper_primitive_int_unsigned); apply_fn_to_primitive_ints_and_signeds!(saturating_from_helper_primitive_int_signed); } malachite-base-0.4.16/tests/num/conversion/froms/try_from_and_exact_from.rs000064400000000000000000000245101046102023000252710ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::traits::NegativeInfinity; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::from::{ PrimitiveFloatFromSignedError, PrimitiveFloatFromUnsignedError, SignedFromFloatError, UnsignedFromFloatError, }; use malachite_base::num::conversion::traits::{ConvertibleFrom, ExactFrom, RoundingFrom}; use malachite_base::num::float::NiceFloat; use malachite_base::rounding_modes::RoundingMode::*; use malachite_base::test_util::generators::{ primitive_float_gen, primitive_float_gen_var_13, primitive_float_gen_var_14, signed_gen, signed_gen_var_7, unsigned_gen, unsigned_gen_var_18, }; use std::fmt::Debug; use std::panic::catch_unwind; #[allow(clippy::needless_pass_by_value)] #[test] pub fn test_try_from() { fn test_double_primitive_int< T: PrimitiveFloat, U: TryFrom, Error = E> + Copy + Debug + Eq, E: Debug + Eq, >( n_in: T, n_out: Result, ) { assert_eq!(U::try_from(NiceFloat(n_in)), n_out); } test_double_primitive_int::<_, u8, _>(0.0f32, Ok(0)); test_double_primitive_int::<_, u8, _>(-0.0f32, Ok(0)); test_double_primitive_int::<_, u8, _>(123.0f32, Ok(123)); test_double_primitive_int::<_, i8, _>(-123.0f32, Ok(-123)); test_double_primitive_int::<_, u8, _>(-123.0f32, Err(UnsignedFromFloatError::FloatNegative)); test_double_primitive_int::<_, u8, _>( 500.0f32, Err(UnsignedFromFloatError::FloatNonIntegerOrOutOfRange), ); test_double_primitive_int::<_, u8, _>( 123.1f32, Err(UnsignedFromFloatError::FloatNonIntegerOrOutOfRange), ); test_double_primitive_int::<_, u8, _>( f32::NAN, Err(UnsignedFromFloatError::FloatInfiniteOrNan), ); test_double_primitive_int::<_, u8, _>( f32::INFINITY, Err(UnsignedFromFloatError::FloatInfiniteOrNan), ); test_double_primitive_int::<_, u8, _>( f32::NEGATIVE_INFINITY, Err(UnsignedFromFloatError::FloatInfiniteOrNan), ); test_double_primitive_int::<_, u8, _>(255.0f32, Ok(255)); test_double_primitive_int::<_, u8, _>( 256.0f32, Err(UnsignedFromFloatError::FloatNonIntegerOrOutOfRange), ); test_double_primitive_int::<_, i8, _>(127.0f32, Ok(127)); test_double_primitive_int::<_, i8, _>( 128.0f32, Err(SignedFromFloatError::FloatNonIntegerOrOutOfRange), ); test_double_primitive_int::<_, i8, _>(-128.0f32, Ok(-128)); test_double_primitive_int::<_, i8, _>( -129.0f32, Err(SignedFromFloatError::FloatNonIntegerOrOutOfRange), ); fn test_double_primitive_float( n_in: T, n_out: Result, ) where NiceFloat: TryFrom, { assert_eq!(NiceFloat::::try_from(n_in), n_out.map(NiceFloat)); } test_double_primitive_float::<_, f32, _>(0u8, Ok(0.0)); test_double_primitive_float::<_, f32, _>(123u8, Ok(123.0)); test_double_primitive_float::<_, f32, _>(-123i8, Ok(-123.0)); test_double_primitive_float::<_, f32, _>(u128::MAX, Err(PrimitiveFloatFromUnsignedError)); test_double_primitive_float::<_, f32, _>(i128::MIN, Ok(-1.7014118e38)); test_double_primitive_float::<_, f32, _>(i128::MIN + 1, Err(PrimitiveFloatFromSignedError)); test_double_primitive_float::<_, f32, _>(u32::MAX, Err(PrimitiveFloatFromUnsignedError)); test_double_primitive_float::<_, f32, _>(i32::MIN, Ok(-2147483600.0)); test_double_primitive_float::<_, f32, _>(i32::MIN + 1, Err(PrimitiveFloatFromSignedError)); } #[test] pub fn test_exact_from() { fn test_single>(n: T) { assert_eq!(T::exact_from(n), n); } test_single(0u8); test_single(5u64); test_single(1000u32); test_single(123u8); test_single(-123i16); test_single(i64::MIN); test_single(usize::MAX); fn test_double_primitive_int< T: PrimitiveFloat, U: Copy + Debug + Eq + TryFrom>, >( n_in: T, n_out: U, ) { assert_eq!(U::exact_from(NiceFloat(n_in)), n_out); } test_double_primitive_int(0.0f32, 0u8); test_double_primitive_int(-0.0f32, 0u8); test_double_primitive_int(123.0f32, 123u8); test_double_primitive_int(-123.0f32, -123i8); test_double_primitive_int(255.0f32, 255u8); test_double_primitive_int(127.0f32, 127i8); test_double_primitive_int(-128.0f32, -128i8); fn test_double_primitive_float(n_in: T, n_out: U) where NiceFloat: TryFrom, { assert_eq!(NiceFloat::::exact_from(n_in), NiceFloat(n_out)); } test_double_primitive_float(0u8, 0.0f32); test_double_primitive_float(123u8, 123.0f32); test_double_primitive_float(-123i8, -123.0f32); test_double_primitive_float(i128::MIN, -1.7014118e38f32); test_double_primitive_float(i32::MIN, -2147483600.0f32); } #[test] fn exact_from_fail() { assert_panic!(u32::exact_from(-1i8)); assert_panic!(u16::exact_from(u32::MAX)); assert_panic!(u32::exact_from(i32::MIN)); assert_panic!(u16::exact_from(i32::MIN)); assert_panic!(i16::exact_from(i32::MIN)); assert_panic!(u32::exact_from(-5i32)); assert_panic!(i32::exact_from(3000000000u32)); assert_panic!(i8::exact_from(-1000i16)); assert_panic!(u8::exact_from(NiceFloat(-123.0f32))); assert_panic!(u8::exact_from(NiceFloat(500.0f32))); assert_panic!(u8::exact_from(NiceFloat(123.1f32))); assert_panic!(u8::exact_from(NiceFloat(f32::NAN))); assert_panic!(u8::exact_from(NiceFloat(f32::INFINITY))); assert_panic!(u8::exact_from(NiceFloat(f32::NEGATIVE_INFINITY))); assert_panic!(u8::exact_from(NiceFloat(256.0f32))); assert_panic!(i8::exact_from(NiceFloat(128.0f32))); assert_panic!(i8::exact_from(NiceFloat(-129.0f32))); assert_panic!(NiceFloat::::exact_from(u128::MAX)); assert_panic!(NiceFloat::::exact_from(i128::MIN + 1)); assert_panic!(NiceFloat::::exact_from(u32::MAX)); assert_panic!(NiceFloat::::exact_from(i32::MIN + 1)); } fn try_from_and_exact_from_helper_unsigned_primitive_float< T: TryFrom, Error = UnsignedFromFloatError> + PrimitiveUnsigned + RoundingFrom, U: PrimitiveFloat + RoundingFrom, >() where NiceFloat: TryFrom, { primitive_float_gen::().test_properties(|f| { let f = NiceFloat(f); let result = T::try_from(f); if let Ok(u) = result { assert_eq!(u, T::exact_from(f)); assert_eq!( NiceFloat(f.0.abs_negative_zero()), NiceFloat::::exact_from(u) ); } }); primitive_float_gen_var_13::().test_properties(|f| { let f = NiceFloat(f); let u = T::exact_from(f); assert_eq!(NiceFloat::::exact_from(u), f); assert_eq!(T::try_from(f).unwrap(), u); assert_eq!(T::rounding_from(f.0, Exact).0, u); }); } fn try_from_and_exact_from_helper_signed_primitive_float< T: TryFrom, Error = SignedFromFloatError> + PrimitiveSigned + RoundingFrom, U: PrimitiveFloat + RoundingFrom, >() where NiceFloat: TryFrom, { primitive_float_gen::().test_properties(|f| { let f = NiceFloat(f); let result = T::try_from(f); if let Ok(i) = result { assert_eq!(i, T::exact_from(f)); assert_eq!( NiceFloat(f.0.abs_negative_zero()), NiceFloat::::exact_from(i) ); } }); primitive_float_gen_var_14::().test_properties(|f| { let f = NiceFloat(f); let i = T::exact_from(f); assert_eq!(NiceFloat::::exact_from(i), f); assert_eq!(T::try_from(f).unwrap(), i); assert_eq!(T::rounding_from(f.0, Exact).0, i); }); } fn try_from_and_exact_from_helper_primitive_float_unsigned< T: ConvertibleFrom + PrimitiveFloat + RoundingFrom, U: PrimitiveUnsigned + RoundingFrom + TryFrom>, >() where NiceFloat: TryFrom, { unsigned_gen::().test_properties(|u| { let result = NiceFloat::::try_from(u); if let Ok(f) = result { assert_eq!(f, NiceFloat::::exact_from(u)); assert_eq!(u, U::exact_from(f)); } }); unsigned_gen_var_18::().test_properties(|u| { let f = NiceFloat::::exact_from(u); assert_eq!(U::exact_from(f), u); assert_eq!(NiceFloat::::try_from(u).unwrap(), f); assert_eq!(NiceFloat(T::rounding_from(u, Exact).0), f); }); } fn try_from_and_exact_from_helper_primitive_float_signed< T: ConvertibleFrom + PrimitiveFloat + RoundingFrom, U: PrimitiveSigned + RoundingFrom + TryFrom>, >() where NiceFloat: TryFrom, { signed_gen::().test_properties(|i| { let result = NiceFloat::::try_from(i); if let Ok(f) = result { assert_eq!(f, NiceFloat::::exact_from(i)); assert_eq!(i, U::exact_from(f)); } }); signed_gen_var_7::().test_properties(|i| { let f = NiceFloat::::exact_from(i); assert_eq!(U::exact_from(f), i); assert_eq!(NiceFloat::::try_from(i).unwrap(), f); assert_eq!(NiceFloat(T::rounding_from(i, Exact).0), f); }); } #[test] fn try_from_and_exact_from_properties() { apply_fn_to_unsigneds_and_primitive_floats!( try_from_and_exact_from_helper_unsigned_primitive_float ); apply_fn_to_signeds_and_primitive_floats!( try_from_and_exact_from_helper_signed_primitive_float ); apply_fn_to_primitive_floats_and_unsigneds!( try_from_and_exact_from_helper_primitive_float_unsigned ); apply_fn_to_primitive_floats_and_signeds!( try_from_and_exact_from_helper_primitive_float_signed ); } malachite-base-0.4.16/tests/num/conversion/froms/wrapping_from.rs000064400000000000000000000045711046102023000232560ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::{OverflowingFrom, WrappingFrom}; use malachite_base::test_util::generators::{signed_gen, unsigned_gen}; use std::fmt::Debug; #[test] pub fn test_wrapping_from() { fn test_single>(n: T) { assert_eq!(T::wrapping_from(n), n); } test_single(0u8); test_single(5u64); test_single(1000u32); test_single(123u8); test_single(-123i16); test_single(i64::MIN); test_single(usize::MAX); fn test_double>(n_in: T, n_out: U) { assert_eq!(U::wrapping_from(n_in), n_out); } test_double(0u8, 0u16); test_double(1000u16, 1000i32); test_double(-5i16, -5i8); test_double(255u8, 255u64); test_double(-1i8, u32::MAX); test_double(u32::MAX, u16::MAX); test_double(i32::MIN, 0x80000000u32); test_double(i32::MIN, 0u16); test_double(i32::MIN, 0i16); test_double(-5i32, 0xfffffffbu32); test_double(3000000000u32, -1294967296i32); test_double(-1000i16, 24i8); } fn wrapping_from_helper_primitive_int_unsigned< T: OverflowingFrom + WrappingFrom + PrimitiveInt, U: PrimitiveUnsigned, >() { unsigned_gen::().test_properties(|u| { let result = T::wrapping_from(u); assert_eq!(result, T::overflowing_from(u).0); }); } fn wrapping_from_helper_primitive_int_signed< T: OverflowingFrom + WrappingFrom + PrimitiveInt, U: PrimitiveSigned, >() { signed_gen::().test_properties(|i| { let result = T::wrapping_from(i); assert_eq!(result, T::overflowing_from(i).0); }); } #[test] fn wrapping_from_properties() { apply_fn_to_primitive_ints_and_unsigneds!(wrapping_from_helper_primitive_int_unsigned); apply_fn_to_primitive_ints_and_signeds!(wrapping_from_helper_primitive_int_signed); } malachite-base-0.4.16/tests/num/conversion/half/join_halves.rs000064400000000000000000000036011046102023000224620ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::{HasHalf, JoinHalves, SplitInHalf}; use malachite_base::test_util::generators::{unsigned_gen, unsigned_pair_gen_var_27}; fn join_halves_helper(upper: T::Half, lower: T::Half, out: T) { assert_eq!(T::join_halves(upper, lower), out); } #[test] pub fn test_join_halves() { join_halves_helper(0u32, 0u32, 0u64); join_halves_helper(0u32, 1u32, 1u64); join_halves_helper(0, u8::MAX, u16::from(u8::MAX)); join_halves_helper(1, 0, u16::from(u8::MAX) + 1); join_halves_helper(u8::MAX, u8::MAX, u16::MAX); join_halves_helper(1, 2, 258u16); join_halves_helper(0xabcd, 0x1234, 0xabcd1234u32); } fn join_halves_properties_helper< T: From + HasHalf + JoinHalves + PrimitiveUnsigned + SplitInHalf, HT: PrimitiveUnsigned, >() { unsigned_pair_gen_var_27::().test_properties(|(x, y)| { let joined = T::join_halves(x, y); assert_eq!((T::from(x) << (T::WIDTH >> 1)) + T::from(y), joined); assert_eq!(joined.upper_half(), x); assert_eq!(joined.lower_half(), y); }); unsigned_gen::().test_properties(|x| { assert_eq!(T::join_halves(HT::ZERO, x), T::from(x)); }); } #[test] fn join_halves_properties() { join_halves_properties_helper::(); join_halves_properties_helper::(); join_halves_properties_helper::(); join_halves_properties_helper::(); } malachite-base-0.4.16/tests/num/conversion/half/lower_half.rs000064400000000000000000000030171046102023000223040ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::{JoinHalves, SplitInHalf}; use malachite_base::test_util::generators::unsigned_gen; fn lower_half_test_helper(n: T, out: T::Half) where T::Half: PrimitiveUnsigned, { assert_eq!(n.lower_half(), out); } #[test] pub fn test_lower_half() { lower_half_test_helper(0u64, 0u32); lower_half_test_helper(1u64, 1u32); lower_half_test_helper(u16::from(u8::MAX), u8::MAX); lower_half_test_helper(u16::from(u8::MAX) + 1, 0); lower_half_test_helper(u16::MAX, u8::MAX); lower_half_test_helper(258u16, 2u8); lower_half_test_helper(0xabcd1234u32, 0x1234); } fn lower_half_properties_helper() { unsigned_gen::().test_properties(|n| { let lower = n.lower_half(); assert_eq!(T::join_halves(n.upper_half(), lower), n); }); } #[test] fn lower_half_properties() { lower_half_properties_helper::(); lower_half_properties_helper::(); lower_half_properties_helper::(); lower_half_properties_helper::(); } malachite-base-0.4.16/tests/num/conversion/half/split_in_half.rs000064400000000000000000000032031046102023000227720ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::{JoinHalves, SplitInHalf}; use malachite_base::test_util::generators::unsigned_gen; fn split_in_half_test_helper(n: T, out: (T::Half, T::Half)) where T::Half: PrimitiveUnsigned, { assert_eq!(n.split_in_half(), out); } #[test] pub fn test_split_in_half() { split_in_half_test_helper(0u64, (0u32, 0u32)); split_in_half_test_helper(1u64, (0u32, 1u32)); split_in_half_test_helper(u16::from(u8::MAX), (0, u8::MAX)); split_in_half_test_helper(u16::from(u8::MAX) + 1, (1, 0)); split_in_half_test_helper(u16::MAX, (u8::MAX, u8::MAX)); split_in_half_test_helper(258u16, (1u8, 2u8)); split_in_half_test_helper(0xabcd1234u32, (0xabcd, 0x1234)); } fn split_in_half_properties_helper() { unsigned_gen::().test_properties(|n| { let (upper, lower) = n.split_in_half(); assert_eq!(T::join_halves(upper, lower), n); }); } #[test] fn split_in_half_properties() { split_in_half_properties_helper::(); split_in_half_properties_helper::(); split_in_half_properties_helper::(); split_in_half_properties_helper::(); } malachite-base-0.4.16/tests/num/conversion/half/upper_half.rs000064400000000000000000000030111046102023000223010ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::{JoinHalves, SplitInHalf}; use malachite_base::test_util::generators::unsigned_gen; fn upper_half_test_helper(n: T, out: T::Half) where T::Half: PrimitiveUnsigned, { assert_eq!(n.upper_half(), out); } #[test] pub fn test_upper_half() { upper_half_test_helper(0u64, 0u32); upper_half_test_helper(1u64, 0u32); upper_half_test_helper(u16::from(u8::MAX), 0); upper_half_test_helper(u16::from(u8::MAX) + 1, 1); upper_half_test_helper(u16::MAX, u8::MAX); upper_half_test_helper(258u16, 1u8); upper_half_test_helper(0xabcd1234u32, 0xabcd); } fn upper_half_properties_helper() { unsigned_gen::().test_properties(|n| { let upper = n.upper_half(); assert_eq!(T::join_halves(upper, n.lower_half()), n); }); } #[test] fn upper_half_properties() { upper_half_properties_helper::(); upper_half_properties_helper::(); upper_half_properties_helper::(); upper_half_properties_helper::(); } malachite-base-0.4.16/tests/num/conversion/is_integer.rs000064400000000000000000000046111046102023000214010ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::traits::NegativeInfinity; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{primitive_float_gen, signed_gen, unsigned_gen}; #[test] pub fn test_is_integer() { fn test_u(u: T, is_integer: bool) { assert_eq!(u.is_integer(), is_integer); } test_u::(0, true); test_u::(1, true); test_u::(100, true); fn test_i(i: T, is_integer: bool) { assert_eq!(i.is_integer(), is_integer); } test_i::(0, true); test_i::(1, true); test_i::(100, true); test_i::(-1, true); test_i::(-100, true); fn test_f(f: T, is_integer: bool) { assert_eq!(f.is_integer(), is_integer); } test_f::(0.0, true); test_f::(1.0, true); test_f::(100.0, true); test_f::(-1.0, true); test_f::(-100.0, true); test_f::(0.1, false); test_f::(100.1, false); test_f::(-0.1, false); test_f::(-100.1, false); test_f::(f32::NAN, false); test_f::(f32::INFINITY, false); test_f::(f32::NEGATIVE_INFINITY, false); } fn is_integer_unsigned() { unsigned_gen::().test_properties(|u| { assert!(u.is_integer()); }); } fn is_integer_signed() { signed_gen::().test_properties(|i| { assert!(i.is_integer()); }); } fn is_integer_primitive_float() { primitive_float_gen::().test_properties(|f| { assert_eq!( f.is_integer(), f.is_finite() && (f == T::ZERO || f.integer_exponent() >= 0) ); }); } #[test] fn is_integer_properties() { apply_fn_to_unsigneds!(is_integer_unsigned); apply_fn_to_signeds!(is_integer_signed); apply_fn_to_primitive_floats!(is_integer_primitive_float); } malachite-base-0.4.16/tests/num/conversion/mantissa_and_exponent/integer_mantissa_and_exponent.rs000064400000000000000000000222371046102023000317340ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::Parity; use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::float::NiceFloat; use malachite_base::num::logic::traits::SignificantBits; use malachite_base::test_util::generators::{ primitive_float_gen_var_12, unsigned_gen_var_1, unsigned_pair_gen_var_2, unsigned_pair_gen_var_30, unsigned_signed_pair_gen_var_1, unsigned_signed_pair_gen_var_2, }; use std::cmp::Ordering::*; use std::panic::catch_unwind; #[test] pub fn test_integer_mantissa_and_exponent() { fn test_unsigned(x: T, mantissa: T, exponent: u64) { assert_eq!(x.integer_mantissa(), mantissa); assert_eq!(x.integer_exponent(), exponent); assert_eq!(x.integer_mantissa_and_exponent(), (mantissa, exponent)); } test_unsigned::(1, 1, 0); test_unsigned::(2, 1, 1); test_unsigned::(3, 3, 0); test_unsigned::(100, 25, 2); test_unsigned::(65536, 1, 16); fn test_primitive_float(x: T, mantissa: u64, exponent: i64) { assert_eq!(x.integer_mantissa(), mantissa); assert_eq!(x.integer_exponent(), exponent); assert_eq!(x.integer_mantissa_and_exponent(), (mantissa, exponent)); } test_primitive_float::(1.0, 1, 0); test_primitive_float::(core::f32::consts::PI, 13176795, -22); test_primitive_float::(0.1, 13421773, -27); test_primitive_float::(10.0, 5, 1); test_primitive_float::(f32::MIN_POSITIVE_SUBNORMAL, 1, -149); test_primitive_float::(f32::MAX_SUBNORMAL, 0x7fffff, -149); test_primitive_float::(f32::MIN_POSITIVE_NORMAL, 1, -126); test_primitive_float::(f32::MAX_FINITE, 0xffffff, 104); test_primitive_float::(1.0, 1, 0); test_primitive_float::(core::f64::consts::PI, 884279719003555, -48); test_primitive_float::(0.1, 3602879701896397, -55); test_primitive_float::(10.0, 5, 1); test_primitive_float::(f64::MIN_POSITIVE_SUBNORMAL, 1, -1074); test_primitive_float::(f64::MAX_SUBNORMAL, 0xfffffffffffff, -1074); test_primitive_float::(f64::MIN_POSITIVE_NORMAL, 1, -1022); test_primitive_float::(f64::MAX_FINITE, 0x1fffffffffffff, 971); } fn integer_mantissa_and_exponent_unsigned_fail_helper() { assert_panic!(T::ZERO.integer_mantissa_and_exponent()); } fn integer_mantissa_and_exponent_primitive_float_fail_helper() { assert_panic!(T::NAN.integer_mantissa_and_exponent()); assert_panic!(T::INFINITY.integer_mantissa_and_exponent()); assert_panic!(T::NEGATIVE_INFINITY.integer_mantissa_and_exponent()); assert_panic!(T::ZERO.integer_mantissa_and_exponent()); assert_panic!(T::NEGATIVE_ZERO.integer_mantissa_and_exponent()); } #[test] pub fn integer_mantissa_and_exponent_fail() { apply_fn_to_unsigneds!(integer_mantissa_and_exponent_unsigned_fail_helper); apply_fn_to_primitive_floats!(integer_mantissa_and_exponent_primitive_float_fail_helper); } #[test] pub fn test_from_integer_mantissa_and_exponent() { fn test_unsigned(mantissa: T, exponent: u64, x: Option) { assert_eq!(T::from_integer_mantissa_and_exponent(mantissa, exponent), x); } test_unsigned::(0, 0, Some(0)); test_unsigned::(1, 0, Some(1)); test_unsigned::(1, 1, Some(2)); test_unsigned::(3, 0, Some(3)); test_unsigned::(25, 2, Some(100)); test_unsigned::(1, 16, Some(65536)); test_unsigned::(1, 100, None); fn test_primitive_float(mantissa: u64, exponent: i64, x: Option) { assert_eq!( T::from_integer_mantissa_and_exponent(mantissa, exponent).map(NiceFloat), x.map(NiceFloat) ); } test_primitive_float::(0, 5, Some(0.0)); test_primitive_float::(1, 0, Some(1.0)); test_primitive_float::(4, -2, Some(1.0)); test_primitive_float::(13176795, -22, Some(core::f32::consts::PI)); test_primitive_float::(13421773, -27, Some(0.1)); test_primitive_float::(5, 1, Some(10.0)); test_primitive_float::(1, -149, Some(f32::MIN_POSITIVE_SUBNORMAL)); test_primitive_float::(4, -151, Some(f32::MIN_POSITIVE_SUBNORMAL)); test_primitive_float::(0x7fffff, -149, Some(f32::MAX_SUBNORMAL)); test_primitive_float::(1, -126, Some(f32::MIN_POSITIVE_NORMAL)); test_primitive_float::(0xffffff, 104, Some(f32::MAX_FINITE)); test_primitive_float::(1, 127, Some(1.7014118e38)); test_primitive_float::(5, 10000, None); test_primitive_float::(5, -10000, None); test_primitive_float::(u64::MAX, -32, None); // precision too high test_primitive_float::(3, -150, None); // precision too high test_primitive_float::(1, 128, None); // precision too high test_primitive_float::(0, 5, Some(0.0)); test_primitive_float::(1, 0, Some(1.0)); test_primitive_float::(4, -2, Some(1.0)); test_primitive_float::(884279719003555, -48, Some(core::f64::consts::PI)); test_primitive_float::(3602879701896397, -55, Some(0.1)); test_primitive_float::(5, 1, Some(10.0)); test_primitive_float::(1, -1074, Some(f64::MIN_POSITIVE_SUBNORMAL)); test_primitive_float::(4, -1076, Some(f64::MIN_POSITIVE_SUBNORMAL)); test_primitive_float::(0xfffffffffffff, -1074, Some(f64::MAX_SUBNORMAL)); test_primitive_float::(1, -1022, Some(f64::MIN_POSITIVE_NORMAL)); test_primitive_float::(0x1fffffffffffff, 971, Some(f64::MAX_FINITE)); test_primitive_float::(1, 1023, Some(8.98846567431158e307)); test_primitive_float::(5, 10000, None); test_primitive_float::(5, -10000, None); test_primitive_float::(u64::MAX, -64, None); // precision too high test_primitive_float::(3, -1075, None); // precision too high test_primitive_float::(1, 1024, None); // precision too high } fn integer_mantissa_and_exponent_properties_helper_unsigned() { unsigned_gen_var_1::().test_properties(|x| { let (mantissa, exponent) = x.integer_mantissa_and_exponent(); assert_eq!(x.integer_mantissa(), mantissa); assert_eq!(x.integer_exponent(), exponent); assert_eq!( T::from_integer_mantissa_and_exponent(mantissa, exponent).unwrap(), x ); assert!(exponent < T::WIDTH); assert!(mantissa.odd()); }); } fn integer_mantissa_and_exponent_properties_helper_primitive_float() { primitive_float_gen_var_12::().test_properties(|x| { let (mantissa, exponent) = x.integer_mantissa_and_exponent(); assert_eq!(x.integer_mantissa(), mantissa); assert_eq!(x.integer_exponent(), exponent); assert_eq!( NiceFloat(T::from_integer_mantissa_and_exponent(mantissa, exponent).unwrap()), NiceFloat(x.abs()) ); assert!(exponent >= T::MIN_EXPONENT); assert!(exponent <= T::MAX_EXPONENT); assert!(mantissa.significant_bits() <= T::MANTISSA_WIDTH + 1); assert!(mantissa.odd()); }); } #[test] fn integer_mantissa_and_exponent_properties() { apply_fn_to_unsigneds!(integer_mantissa_and_exponent_properties_helper_unsigned); apply_fn_to_primitive_floats!(integer_mantissa_and_exponent_properties_helper_primitive_float); } fn from_integer_mantissa_and_exponent_properties_helper_unsigned() { unsigned_pair_gen_var_2::().test_properties(|(mantissa, exponent)| { T::from_integer_mantissa_and_exponent(mantissa, exponent); }); unsigned_pair_gen_var_30::().test_properties(|(mantissa, exponent)| { let f = T::from_integer_mantissa_and_exponent(mantissa, exponent).unwrap(); if mantissa.odd() { assert_eq!(f.integer_mantissa_and_exponent(), (mantissa, exponent)); } }); } fn from_integer_mantissa_and_exponent_properties_helper_primitive_float() { unsigned_signed_pair_gen_var_1().test_properties(|(mantissa, exponent)| { T::from_integer_mantissa_and_exponent(mantissa, exponent); }); unsigned_signed_pair_gen_var_2::().test_properties(|(mantissa, exponent)| { let f = T::from_integer_mantissa_and_exponent(mantissa, exponent).unwrap(); assert!(!f.is_nan()); assert_eq!(f.sign(), Greater); if !f.is_nan() && mantissa.odd() { assert_eq!(f.integer_mantissa_and_exponent(), (mantissa, exponent)); } }); } #[test] fn from_integer_mantissa_and_exponent_properties() { apply_fn_to_unsigneds!(from_integer_mantissa_and_exponent_properties_helper_unsigned); apply_fn_to_primitive_floats!( from_integer_mantissa_and_exponent_properties_helper_primitive_float ); } malachite-base-0.4.16/tests/num/conversion/mantissa_and_exponent/raw_mantissa_and_exponent.rs000064400000000000000000000141731046102023000310700ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::PowerOf2; use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::traits::NegativeInfinity; use malachite_base::num::float::NiceFloat; use malachite_base::num::logic::traits::SignificantBits; use malachite_base::test_util::generators::{primitive_float_gen, unsigned_pair_gen_var_26}; use std::cmp::Ordering::*; use std::panic::catch_unwind; #[test] pub fn test_raw_mantissa_and_exponent() { fn test(x: T, mantissa: u64, exponent: u64) { assert_eq!(x.raw_mantissa(), mantissa); assert_eq!(x.raw_exponent(), exponent); assert_eq!(x.raw_mantissa_and_exponent(), (mantissa, exponent)); } test::(0.0, 0, 0); test::(-0.0, 0, 0); test::(f32::NAN, 0x400000, 255); test::(f32::INFINITY, 0, 255); test::(f32::NEGATIVE_INFINITY, 0, 255); test::(1.0, 0, 127); test::(core::f32::consts::PI, 4788187, 128); test::(0.1, 5033165, 123); test::(10.0, 2097152, 130); test::(f32::MIN_POSITIVE_SUBNORMAL, 1, 0); test::(f32::MAX_SUBNORMAL, 0x7fffff, 0); test::(f32::MIN_POSITIVE_NORMAL, 0, 1); test::(f32::MAX_FINITE, 0x7fffff, 254); test::(0.0, 0, 0); test::(-0.0, 0, 0); test::(f64::NAN, 0x8000000000000, 2047); test::(f64::INFINITY, 0, 2047); test::(f64::NEGATIVE_INFINITY, 0, 2047); test::(1.0, 0, 1023); test::(core::f64::consts::PI, 2570638124657944, 1024); test::(0.1, 2702159776422298, 1019); test::(10.0, 1125899906842624, 1026); test::(f64::MIN_POSITIVE_SUBNORMAL, 1, 0); test::(f64::MAX_SUBNORMAL, 0xfffffffffffff, 0); test::(f64::MIN_POSITIVE_NORMAL, 0, 1); test::(f64::MAX_FINITE, 0xfffffffffffff, 2046); } #[test] pub fn test_raw_exponent() { fn test(x: T, exponent: u64) { assert_eq!(x.raw_exponent(), exponent); } test::(0.0, 0); test::(-0.0, 0); test::(f32::NAN, 255); test::(f32::INFINITY, 255); test::(f32::NEGATIVE_INFINITY, 255); test::(1.0, 127); test::(core::f32::consts::PI, 128); test::(0.1, 123); test::(10.0, 130); test::(f32::MIN_POSITIVE_SUBNORMAL, 0); test::(f32::MAX_SUBNORMAL, 0); test::(f32::MIN_POSITIVE_NORMAL, 1); test::(f32::MAX_FINITE, 254); test::(0.0, 0); test::(-0.0, 0); test::(f64::NAN, 2047); test::(f64::INFINITY, 2047); test::(f64::NEGATIVE_INFINITY, 2047); test::(1.0, 1023); test::(core::f64::consts::PI, 1024); test::(0.1, 1019); test::(10.0, 1026); test::(f64::MIN_POSITIVE_SUBNORMAL, 0); test::(f64::MAX_SUBNORMAL, 0); test::(f64::MIN_POSITIVE_NORMAL, 1); test::(f64::MAX_FINITE, 2046); } pub fn test_from_raw_mantissa_and_exponent() { fn test(mantissa: u64, exponent: u64, x: T) { assert_eq!( NiceFloat(T::from_raw_mantissa_and_exponent(mantissa, exponent)), NiceFloat(x) ); } test::(0, 0, 0.0); test::(0x400000, 255, f32::NAN); test::(0, 255, f32::INFINITY); test::(0, 127, 1.0); test::(4788187, 128, core::f32::consts::PI); test::(5033165, 123, 0.1); test::(2097152, 130, 10.0); test::(1, 0, f32::MIN_POSITIVE_SUBNORMAL); test::(0x7fffff, 0, f32::MAX_SUBNORMAL); test::(0, 1, f32::MIN_POSITIVE_NORMAL); test::(0x7fffff, 254, f32::MAX_FINITE); test::(0, 0, 0.0); test::(0x8000000000000, 2047, f64::NAN); test::(0, 2047, f64::INFINITY); test::(0, 1023, 1.0); test::(2570638124657944, 1024, core::f64::consts::PI); test::(2702159776422298, 1019, 0.1); test::(1125899906842624, 1026, 10.0); test::(1, 0, f64::MIN_POSITIVE_SUBNORMAL); test::(0xfffffffffffff, 0, f64::MAX_SUBNORMAL); test::(0, 1, f64::MIN_POSITIVE_NORMAL); test::(0xfffffffffffff, 2046, f64::MAX_FINITE); } fn from_raw_mantissa_and_exponent_fail_helper() { assert_panic!(T::from_raw_mantissa_and_exponent( u64::power_of_2(T::MANTISSA_WIDTH), 0 )); assert_panic!(T::from_raw_mantissa_and_exponent( 0, u64::power_of_2(T::EXPONENT_WIDTH) )); } #[test] pub fn from_raw_mantissa_and_exponent_fail() { apply_fn_to_primitive_floats!(from_raw_mantissa_and_exponent_fail_helper); } fn raw_mantissa_and_exponent_properties_helper() { primitive_float_gen::().test_properties(|x| { let (mantissa, exponent) = x.raw_mantissa_and_exponent(); assert_eq!(x.raw_mantissa(), mantissa); assert_eq!(x.raw_exponent(), exponent); assert_eq!( NiceFloat(T::from_raw_mantissa_and_exponent(mantissa, exponent)), NiceFloat(x.abs()) ); assert!(exponent.significant_bits() <= T::EXPONENT_WIDTH); assert!(mantissa.significant_bits() <= T::MANTISSA_WIDTH); }); } #[test] fn raw_mantissa_and_exponent_properties() { apply_fn_to_primitive_floats!(raw_mantissa_and_exponent_properties_helper); } fn from_raw_mantissa_and_exponent_properties_helper() { unsigned_pair_gen_var_26::().test_properties(|(mantissa, exponent)| { let f = T::from_raw_mantissa_and_exponent(mantissa, exponent); assert!(f.is_nan() || f.sign() == Greater); if !f.is_nan() { assert_eq!(f.raw_mantissa_and_exponent(), (mantissa, exponent)); } }); } #[test] fn from_raw_mantissa_and_exponent_properties() { apply_fn_to_primitive_floats!(from_raw_mantissa_and_exponent_properties_helper); } malachite-base-0.4.16/tests/num/conversion/mantissa_and_exponent/sci_mantissa_and_exponent.rs000064400000000000000000000542671046102023000310650ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::mantissa_and_exponent::{ from_sci_mantissa_and_exponent_round, sci_mantissa_and_exponent_round, }; use malachite_base::num::conversion::traits::SciMantissaAndExponent; use malachite_base::num::float::NiceFloat; use malachite_base::rounding_modes::exhaustive::exhaustive_rounding_modes; use malachite_base::rounding_modes::RoundingMode::{self, *}; use malachite_base::test_util::generators::{ primitive_float_gen_var_12, primitive_float_signed_pair_gen_var_1, primitive_float_signed_pair_gen_var_2, primitive_float_unsigned_pair_gen_var_1, primitive_float_unsigned_pair_gen_var_2, primitive_float_unsigned_rounding_mode_triple_gen_var_1, primitive_float_unsigned_rounding_mode_triple_gen_var_2, unsigned_gen_var_1, unsigned_rounding_mode_pair_gen_var_1, }; use std::cmp::Ordering::{self, *}; use std::panic::catch_unwind; #[test] pub fn test_sci_mantissa_and_exponent() { fn test_unsigned, U: PrimitiveFloat>( x: T, mantissa: U, exponent: u64, ) { assert_eq!(NiceFloat(x.sci_mantissa()), NiceFloat(mantissa)); assert_eq!(SciMantissaAndExponent::::sci_exponent(x), exponent); let (actual_mantissa, actual_exponent) = x.sci_mantissa_and_exponent(); assert_eq!(NiceFloat(actual_mantissa), NiceFloat(mantissa)); assert_eq!(actual_exponent, exponent); } test_unsigned::(1, 1.0, 0); test_unsigned::(2, 1.0, 1); test_unsigned::(3, 1.5, 1); test_unsigned::(100, 1.5625, 6); test_unsigned::(65536, 1.0, 16); test_unsigned::(u16::MAX, 1.9999695, 15); test_unsigned::(u32::MAX, 1.0, 32); test_unsigned::(u64::MAX, 1.0, 64); test_unsigned::(u16::MAX, 1.999969482421875, 15); test_unsigned::(u32::MAX, 1.9999999995343387, 31); test_unsigned::(u64::MAX, 1.0, 64); fn test_primitive_float(x: T, mantissa: T, exponent: i64) { assert_eq!(NiceFloat(x.sci_mantissa()), NiceFloat(mantissa)); assert_eq!(x.sci_exponent(), exponent); let (actual_mantissa, actual_exponent) = x.sci_mantissa_and_exponent(); assert_eq!(NiceFloat(actual_mantissa), NiceFloat(mantissa)); assert_eq!(actual_exponent, exponent); } test_primitive_float::(1.0, 1.0, 0); test_primitive_float::(core::f32::consts::PI, core::f32::consts::FRAC_PI_2, 1); test_primitive_float::(0.1, 1.6, -4); test_primitive_float::(10.0, 1.25, 3); test_primitive_float::(f32::MIN_POSITIVE_SUBNORMAL, 1.0, -149); test_primitive_float::(f32::MAX_SUBNORMAL, 1.9999998, -127); test_primitive_float::(f32::MIN_POSITIVE_NORMAL, 1.0, -126); test_primitive_float::(f32::MAX_FINITE, 1.9999999, 127); test_primitive_float::(1.0, 1.0, 0); test_primitive_float::(core::f64::consts::PI, core::f64::consts::FRAC_PI_2, 1); test_primitive_float::(0.1, 1.6, -4); test_primitive_float::(10.0, 1.25, 3); test_primitive_float::(f64::MIN_POSITIVE_SUBNORMAL, 1.0, -1074); test_primitive_float::(f64::MAX_SUBNORMAL, 1.9999999999999996, -1023); test_primitive_float::(f64::MIN_POSITIVE_NORMAL, 1.0, -1022); test_primitive_float::(f64::MAX_FINITE, 1.9999999999999998, 1023); } fn sci_mantissa_and_exponent_fail_helper_unsigned< T: PrimitiveUnsigned + SciMantissaAndExponent, U: PrimitiveFloat, >() { assert_panic!(SciMantissaAndExponent::::sci_mantissa_and_exponent( T::ZERO )); } fn sci_mantissa_and_exponent_fail_helper_primitive_float() { assert_panic!(T::NAN.sci_mantissa_and_exponent()); assert_panic!(T::INFINITY.sci_mantissa_and_exponent()); assert_panic!(T::NEGATIVE_INFINITY.sci_mantissa_and_exponent()); assert_panic!(T::ZERO.sci_mantissa_and_exponent()); assert_panic!(T::NEGATIVE_ZERO.sci_mantissa_and_exponent()); } #[test] pub fn sci_mantissa_and_exponent_fail() { apply_fn_to_unsigneds_and_primitive_floats!(sci_mantissa_and_exponent_fail_helper_unsigned); apply_fn_to_primitive_floats!(sci_mantissa_and_exponent_fail_helper_primitive_float); } #[test] pub fn test_sci_mantissa_and_exponent_round() { fn test, U: PrimitiveFloat>( x: T, rm: RoundingMode, out: Option<(U, u64, Ordering)>, ) { assert_eq!( sci_mantissa_and_exponent_round::(x, rm).map(|(m, e, o)| (NiceFloat(m), e, o)), out.map(|(m, e, o)| (NiceFloat(m), e, o)) ); } test::(1, Floor, Some((1.0, 0, Equal))); test::(1, Down, Some((1.0, 0, Equal))); test::(1, Ceiling, Some((1.0, 0, Equal))); test::(1, Up, Some((1.0, 0, Equal))); test::(1, Nearest, Some((1.0, 0, Equal))); test::(1, Exact, Some((1.0, 0, Equal))); test::(2, Floor, Some((1.0, 1, Equal))); test::(3, Floor, Some((1.5, 1, Equal))); test::(100, Floor, Some((1.5625, 6, Equal))); test::(65536, Floor, Some((1.0, 16, Equal))); test::(u16::MAX, Floor, Some((1.9999695, 15, Equal))); test::(u16::MAX, Down, Some((1.9999695, 15, Equal))); test::(u16::MAX, Ceiling, Some((1.9999695, 15, Equal))); test::(u16::MAX, Up, Some((1.9999695, 15, Equal))); test::(u16::MAX, Nearest, Some((1.9999695, 15, Equal))); test::(u16::MAX, Exact, Some((1.9999695, 15, Equal))); test::(u32::MAX, Floor, Some((1.9999999, 31, Less))); test::(u32::MAX, Down, Some((1.9999999, 31, Less))); test::(u32::MAX, Ceiling, Some((1.0, 32, Greater))); test::(u32::MAX, Up, Some((1.0, 32, Greater))); test::(u32::MAX, Nearest, Some((1.0, 32, Greater))); test::(u32::MAX, Exact, None); test::(u64::MAX, Floor, Some((1.9999999, 63, Less))); test::(u64::MAX, Down, Some((1.9999999, 63, Less))); test::(u64::MAX, Ceiling, Some((1.0, 64, Greater))); test::(u64::MAX, Up, Some((1.0, 64, Greater))); test::(u64::MAX, Nearest, Some((1.0, 64, Greater))); test::(u64::MAX, Exact, None); test::(u16::MAX, Floor, Some((1.999969482421875, 15, Equal))); test::(u16::MAX, Down, Some((1.999969482421875, 15, Equal))); test::(u16::MAX, Ceiling, Some((1.999969482421875, 15, Equal))); test::(u16::MAX, Up, Some((1.999969482421875, 15, Equal))); test::(u16::MAX, Nearest, Some((1.999969482421875, 15, Equal))); test::(u16::MAX, Exact, Some((1.999969482421875, 15, Equal))); test::(u32::MAX, Floor, Some((1.9999999995343387, 31, Equal))); test::(u32::MAX, Down, Some((1.9999999995343387, 31, Equal))); test::(u32::MAX, Ceiling, Some((1.9999999995343387, 31, Equal))); test::(u32::MAX, Up, Some((1.9999999995343387, 31, Equal))); test::(u32::MAX, Nearest, Some((1.9999999995343387, 31, Equal))); test::(u32::MAX, Exact, Some((1.9999999995343387, 31, Equal))); test::(u64::MAX, Floor, Some((1.9999999999999998, 63, Less))); test::(u64::MAX, Down, Some((1.9999999999999998, 63, Less))); test::(u64::MAX, Ceiling, Some((1.0, 64, Greater))); test::(u64::MAX, Up, Some((1.0, 64, Greater))); test::(u64::MAX, Nearest, Some((1.0, 64, Greater))); test::(u64::MAX, Exact, None); } fn sci_mantissa_and_exponent_round_fail_helper() { assert_panic!(sci_mantissa_and_exponent_round::(T::ZERO, Floor)); } #[test] pub fn sci_mantissa_and_exponent_round_fail() { apply_fn_to_unsigneds_and_primitive_floats!(sci_mantissa_and_exponent_round_fail_helper); } #[test] pub fn test_from_sci_mantissa_and_exponent() { fn test_unsigned, U: PrimitiveFloat>( mantissa: U, exponent: u64, x: Option, ) { assert_eq!(T::from_sci_mantissa_and_exponent(mantissa, exponent), x); } test_unsigned::(1.0, 0, Some(1)); test_unsigned::(1.0, 1, Some(2)); test_unsigned::(1.5, 0, Some(2)); test_unsigned::(1.5, 1, Some(3)); test_unsigned::(1.5626, 6, Some(100)); test_unsigned::(1.0, 16, Some(65536)); test_unsigned::(1.0, 100, None); test_unsigned::(1.0, 32, None); fn test_primitive_float(mantissa: T, exponent: i64, x: Option) { assert_eq!( T::from_sci_mantissa_and_exponent(mantissa, exponent).map(NiceFloat), x.map(NiceFloat) ); } test_primitive_float::(1.0, 0, Some(1.0)); test_primitive_float::(std::f32::consts::FRAC_PI_2, 1, Some(core::f32::consts::PI)); test_primitive_float::(1.6, -4, Some(0.1)); test_primitive_float::(1.25, 3, Some(10.0)); test_primitive_float::(1.0, -149, Some(f32::MIN_POSITIVE_SUBNORMAL)); test_primitive_float::(1.9999998, -127, Some(f32::MAX_SUBNORMAL)); test_primitive_float::(1.0, -126, Some(f32::MIN_POSITIVE_NORMAL)); test_primitive_float::(1.9999999, 127, Some(f32::MAX_FINITE)); test_primitive_float::(2.0, 1, None); test_primitive_float::(1.1, -2000, None); test_primitive_float::(1.1, 2000, None); test_primitive_float::(1.999, -149, None); // precision too high test_primitive_float::(1.0, 0, Some(1.0)); test_primitive_float::(std::f64::consts::FRAC_PI_2, 1, Some(core::f64::consts::PI)); test_primitive_float::(1.6, -4, Some(0.1)); test_primitive_float::(1.25, 3, Some(10.0)); test_primitive_float::(1.0, -1074, Some(f64::MIN_POSITIVE_SUBNORMAL)); test_primitive_float::(1.9999999999999996, -1023, Some(f64::MAX_SUBNORMAL)); test_primitive_float::(1.0, -1022, Some(f64::MIN_POSITIVE_NORMAL)); test_primitive_float::(1.9999999999999998, 1023, Some(f64::MAX_FINITE)); test_primitive_float::(2.0, 1, None); test_primitive_float::(1.1, -2000, None); test_primitive_float::(1.1, 2000, None); test_primitive_float::(1.999, -1074, None); // precision too high } #[test] pub fn test_from_sci_mantissa_and_exponent_round() { fn test( mantissa: U, exponent: u64, rm: RoundingMode, xo: Option<(T, Ordering)>, ) { assert_eq!( from_sci_mantissa_and_exponent_round::(mantissa, exponent, rm), xo ); } test::(1.0, 0, Floor, Some((1, Equal))); test::(1.0, 0, Down, Some((1, Equal))); test::(1.0, 0, Ceiling, Some((1, Equal))); test::(1.0, 0, Up, Some((1, Equal))); test::(1.0, 0, Nearest, Some((1, Equal))); test::(1.0, 0, Exact, Some((1, Equal))); test::(1.25, 0, Floor, Some((1, Less))); test::(1.25, 0, Down, Some((1, Less))); test::(1.25, 0, Ceiling, Some((2, Greater))); test::(1.25, 0, Up, Some((2, Greater))); test::(1.25, 0, Nearest, Some((1, Less))); test::(1.25, 0, Exact, None); test::(1.5, 0, Floor, Some((1, Less))); test::(1.5, 0, Down, Some((1, Less))); test::(1.5, 0, Ceiling, Some((2, Greater))); test::(1.5, 0, Up, Some((2, Greater))); test::(1.5, 0, Nearest, Some((2, Greater))); test::(1.5, 0, Exact, None); test::(1.75, 0, Floor, Some((1, Less))); test::(1.75, 0, Down, Some((1, Less))); test::(1.75, 0, Ceiling, Some((2, Greater))); test::(1.75, 0, Up, Some((2, Greater))); test::(1.75, 0, Nearest, Some((2, Greater))); test::(1.75, 0, Exact, None); test::(1.5, 1, Floor, Some((3, Equal))); test::(1.5, 1, Down, Some((3, Equal))); test::(1.5, 1, Ceiling, Some((3, Equal))); test::(1.5, 1, Up, Some((3, Equal))); test::(1.5, 1, Nearest, Some((3, Equal))); test::(1.5, 1, Exact, Some((3, Equal))); test::(1.0, 100, Floor, None); test::(1.0, 100, Down, None); test::(1.0, 100, Ceiling, None); test::(1.0, 100, Up, None); test::(1.0, 100, Nearest, None); test::(1.0, 100, Exact, None); } fn from_sci_mantissa_and_exponent_round_fail_helper() { assert_panic!(from_sci_mantissa_and_exponent_round::( U::ZERO, 0, Floor )); } #[test] pub fn from_sci_mantissa_and_exponent_round_fail() { apply_fn_to_unsigneds_and_primitive_floats!(from_sci_mantissa_and_exponent_round_fail_helper); } fn sci_mantissa_and_exponent_properties_helper_unsigned< T: PrimitiveUnsigned + SciMantissaAndExponent, U: PrimitiveFloat, >() { unsigned_gen_var_1::().test_properties(|x| { let (mantissa, exponent) = SciMantissaAndExponent::::sci_mantissa_and_exponent(x); assert_eq!(NiceFloat(x.sci_mantissa()), NiceFloat(mantissa)); assert_eq!(SciMantissaAndExponent::::sci_exponent(x), exponent); assert_eq!( sci_mantissa_and_exponent_round(x, Nearest).map(|(m, e, _)| (NiceFloat(m), e)), Some((NiceFloat(mantissa), exponent)) ); assert!(exponent <= T::WIDTH); assert!(mantissa >= U::ONE); assert!(mantissa < U::TWO); }); } fn sci_mantissa_and_exponent_properties_helper_primitive_float() { primitive_float_gen_var_12::().test_properties(|x| { let (mantissa, exponent) = x.sci_mantissa_and_exponent(); assert_eq!(NiceFloat(x.sci_mantissa()), NiceFloat(mantissa)); assert_eq!(x.sci_exponent(), exponent); assert_eq!( NiceFloat(T::from_sci_mantissa_and_exponent(mantissa, exponent).unwrap()), NiceFloat(x.abs()) ); assert!(exponent >= T::MIN_EXPONENT); assert!(exponent <= T::MAX_EXPONENT); assert!(mantissa >= T::ONE); assert!(mantissa < T::TWO); let precision = x.precision(); assert_eq!(mantissa.precision(), precision); assert!(precision <= T::max_precision_for_sci_exponent(exponent)); }); } #[test] fn sci_mantissa_and_exponent_properties() { apply_fn_to_unsigneds_and_primitive_floats!( sci_mantissa_and_exponent_properties_helper_unsigned ); apply_fn_to_primitive_floats!(sci_mantissa_and_exponent_properties_helper_primitive_float); } fn sci_mantissa_and_exponent_properties_round_helper() { unsigned_rounding_mode_pair_gen_var_1::().test_properties(|(x, rm)| { if let Some((mantissa, exponent, o)) = sci_mantissa_and_exponent_round::(x, rm) { assert!(mantissa >= U::ONE); assert!(mantissa < U::TWO); match rm { Floor | Down => assert_ne!(o, Greater), Ceiling | Up => assert_ne!(o, Less), Exact => assert_eq!(o, Equal), _ => {} } if o == Equal { for rm in exhaustive_rounding_modes() { assert_eq!( sci_mantissa_and_exponent_round(x, rm), Some((mantissa, exponent, Equal)) ); } } else { assert!(sci_mantissa_and_exponent_round::(x, Exact).is_none(),); } } }); unsigned_gen_var_1::().test_properties(|n| { let (floor_mantissa, floor_exponent, o_floor) = sci_mantissa_and_exponent_round::(n, Floor).unwrap(); assert_ne!(o_floor, Greater); assert_eq!( sci_mantissa_and_exponent_round::(n, Down).unwrap(), (floor_mantissa, floor_exponent, o_floor) ); let (ceiling_mantissa, ceiling_exponent, o_ceiling) = sci_mantissa_and_exponent_round::(n, Ceiling).unwrap(); assert_ne!(o_ceiling, Less); assert_eq!( sci_mantissa_and_exponent_round::(n, Up).unwrap(), (ceiling_mantissa, ceiling_exponent, o_ceiling) ); let (nearest_mantissa, nearest_exponent, o_nearest) = sci_mantissa_and_exponent_round::(n, Nearest).unwrap(); if let Some((mantissa, exponent, o)) = sci_mantissa_and_exponent_round::(n, Exact) { assert_eq!(o, Equal); assert_eq!(floor_mantissa, mantissa); assert_eq!(ceiling_mantissa, mantissa); assert_eq!(nearest_mantissa, mantissa); assert_eq!(floor_exponent, exponent); assert_eq!(ceiling_exponent, exponent); assert_eq!(nearest_exponent, exponent); } else { assert_ne!( (floor_mantissa, floor_exponent), (ceiling_mantissa, ceiling_exponent) ); assert!( (nearest_mantissa, nearest_exponent, o_nearest) == (floor_mantissa, floor_exponent, Less) || (nearest_mantissa, nearest_exponent, o_nearest) == (ceiling_mantissa, ceiling_exponent, Greater) ); if ceiling_mantissa == U::ONE { assert_eq!(floor_mantissa, U::TWO.next_lower()); assert_eq!(floor_exponent, ceiling_exponent - 1); } else { assert_eq!(floor_mantissa, ceiling_mantissa.next_lower()); assert_eq!(floor_exponent, ceiling_exponent); } } }); } #[test] fn sci_mantissa_and_exponent_round_properties() { apply_fn_to_unsigneds_and_primitive_floats!(sci_mantissa_and_exponent_properties_round_helper); } fn from_sci_mantissa_and_exponent_properties_helper_unsigned< T: PrimitiveUnsigned + SciMantissaAndExponent, U: PrimitiveFloat, >() { primitive_float_unsigned_pair_gen_var_1::().test_properties(|(m, e)| { T::from_sci_mantissa_and_exponent(m, e); }); primitive_float_unsigned_pair_gen_var_2::().test_properties(|(m, e)| { assert!(m >= U::ONE && m < U::TWO); let on = T::from_sci_mantissa_and_exponent(m, e); assert_eq!( from_sci_mantissa_and_exponent_round(m, e, Nearest).map(|p| p.0), on ); }); } fn from_sci_mantissa_and_exponent_properties_helper_primitive_float() { primitive_float_signed_pair_gen_var_1().test_properties(|(mantissa, exponent)| { T::from_sci_mantissa_and_exponent(mantissa, exponent); }); primitive_float_signed_pair_gen_var_2::().test_properties(|(mantissa, exponent)| { let f = T::from_sci_mantissa_and_exponent(mantissa, exponent).unwrap(); assert!(!f.is_nan()); assert_eq!(f.sign(), Greater); assert_eq!(f.sci_mantissa_and_exponent(), (mantissa, exponent)); }); } #[test] fn from_sci_mantissa_and_exponent_properties() { apply_fn_to_unsigneds_and_primitive_floats!( from_sci_mantissa_and_exponent_properties_helper_unsigned ); apply_fn_to_primitive_floats!(from_sci_mantissa_and_exponent_properties_helper_primitive_float); } fn from_sci_mantissa_and_exponent_properties_round_helper< T: PrimitiveUnsigned, U: PrimitiveFloat, >() { primitive_float_unsigned_rounding_mode_triple_gen_var_1::().test_properties( |(m, e, rm)| { let on = from_sci_mantissa_and_exponent_round::(m, e, rm); if let Some((x, o)) = on { assert!(m >= U::ONE && m < U::TWO); if o == Equal { for rm in exhaustive_rounding_modes() { assert_eq!( from_sci_mantissa_and_exponent_round::(m, e, rm), Some((x, Equal)) ); } } else { assert!(from_sci_mantissa_and_exponent_round::(m, e, Exact).is_none()); } } }, ); primitive_float_unsigned_rounding_mode_triple_gen_var_2::().test_properties(|(m, e, rm)| { assert!(m >= U::ONE && m < U::TWO); from_sci_mantissa_and_exponent_round::(m, e, rm); }); primitive_float_unsigned_pair_gen_var_2::().test_properties(|(m, e)| { if let Some(ceiling_n) = from_sci_mantissa_and_exponent_round::(m, e, Ceiling) { assert_eq!( from_sci_mantissa_and_exponent_round::(m, e, Up).unwrap(), ceiling_n ); let floor_n = from_sci_mantissa_and_exponent_round::(m, e, Floor).unwrap(); assert_eq!( from_sci_mantissa_and_exponent_round::(m, e, Down).unwrap(), floor_n ); let nearest_n = from_sci_mantissa_and_exponent_round::(m, e, Nearest).unwrap(); if let Some(n) = from_sci_mantissa_and_exponent_round::(m, e, Exact) { assert_eq!(floor_n, n); assert_eq!(ceiling_n, n); assert_eq!(nearest_n, n); } else { assert!(nearest_n == floor_n || nearest_n == ceiling_n); if floor_n.0 != T::MAX { assert_eq!(ceiling_n.0, floor_n.0 + T::ONE); } } } }); } #[test] fn from_sci_mantissa_and_exponent_round_properties() { apply_fn_to_unsigneds_and_primitive_floats!( from_sci_mantissa_and_exponent_properties_round_helper ); } malachite-base-0.4.16/tests/num/conversion/slice/from_other_type_slice.rs000064400000000000000000000043511046102023000247350ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::{FromOtherTypeSlice, VecFromOtherTypeSlice}; use malachite_base::test_util::generators::common::GenConfig; use malachite_base::test_util::generators::unsigned_vec_gen; use std::fmt::Debug; #[test] pub fn test_from_other_type_slice() { fn test>(slice: &[T], n: U) { assert_eq!(U::from_other_type_slice(slice), n); } test::(&[], 0); test::(&[123], 123); test::(&[123, 456], 123); test::(&[0xab], 0xab); test::(&[0xab, 0xcd], 0xcdab); test::(&[0xab, 0xcd, 0xef], 0xcdab); test::( &[0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67], 0x67452301efcdab, ); test::( &[0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xff], 0x8967452301efcdab, ); test::(&[], 0); test::(&[0xabcd, 0xef01], 0xcd); test::(&[0x1234567890abcdef012345678909bcde], 0xde); } fn from_other_type_slice_helper< T: PrimitiveUnsigned + FromOtherTypeSlice + VecFromOtherTypeSlice, U: PrimitiveUnsigned, >() { let mut config = GenConfig::new(); config.insert("mean_length_n", 32); config.insert("mean_length_d", 1); config.insert("mean_stripe_n", 16 << U::LOG_WIDTH); config.insert("mean_stripe_d", 1); unsigned_vec_gen::().test_properties_with_config(&config, |xs| { let value = T::from_other_type_slice(&xs); let ys = T::vec_from_other_type_slice(&xs); if xs.is_empty() { assert_eq!(value, T::ZERO); } else { assert_eq!(value, ys[0]); } }); } #[test] fn from_other_type_slice_properties() { apply_fn_to_unsigneds_and_unsigneds!(from_other_type_slice_helper); } malachite-base-0.4.16/tests/num/conversion/slice/vec_from_other_type.rs000064400000000000000000000026361046102023000244170ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::{ FromOtherTypeSlice, VecFromOtherType, VecFromOtherTypeSlice, }; use malachite_base::test_util::generators::unsigned_gen; use std::fmt::Debug; #[test] pub fn test_vec_from_other_type() { fn test>(value: T, vec: &[U]) { assert_eq!(U::vec_from_other_type(value), vec); } test::(123, &[123]); test::(0xab, &[0xab]); test::(0xcdab, &[0xab, 0xcd]); } fn vec_from_other_type_helper< T: PrimitiveUnsigned + FromOtherTypeSlice, U: PrimitiveUnsigned + VecFromOtherType + VecFromOtherTypeSlice, >() { unsigned_gen::().test_properties(|x| { let xs = U::vec_from_other_type(x); assert_eq!(U::vec_from_other_type_slice(&[x]), xs); assert_eq!(T::from_other_type_slice(&xs), x); }); } #[test] fn vec_from_other_type_properties() { apply_fn_to_unsigneds_and_unsigneds!(vec_from_other_type_helper); } malachite-base-0.4.16/tests/num/conversion/slice/vec_from_other_type_slice.rs000064400000000000000000000045761046102023000256030ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::NegModPowerOf2; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::VecFromOtherTypeSlice; use malachite_base::slices::slice_test_zero; use malachite_base::test_util::generators::common::GenConfig; use malachite_base::test_util::generators::unsigned_vec_gen; use std::fmt::Debug; #[test] pub fn test_vec_from_other_type_slice() { fn test>(slice: &[T], vec: &[U]) { assert_eq!(U::vec_from_other_type_slice(slice), vec); } test::(&[123, 456], &[123, 456]); test::( &[0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xff], &[0xcdab, 0x01ef, 0x4523, 0x8967, 0xff], ); test::(&[0xab], &[0xab]); test::( &[0xcdab, 0x01ef, 0x4523, 0x8967], &[0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89], ); } fn vec_from_other_type_slice_helper< T: PrimitiveUnsigned + VecFromOtherTypeSlice, U: PrimitiveUnsigned + VecFromOtherTypeSlice, >() { let mut config = GenConfig::new(); config.insert("mean_length_n", 32); config.insert("mean_length_d", 1); config.insert("mean_stripe_n", 16 << U::LOG_WIDTH); config.insert("mean_stripe_d", 1); unsigned_vec_gen::().test_properties_with_config(&config, |xs| { let ys = T::vec_from_other_type_slice(&xs); let xs_alt = U::vec_from_other_type_slice(&ys); if U::WIDTH >= T::WIDTH { assert_eq!(xs_alt, xs); } else { let number_of_extra_zeros = xs.len().neg_mod_power_of_2(T::LOG_WIDTH - U::LOG_WIDTH); let (xs_alt_lo, xs_alt_hi) = xs_alt.split_at(xs.len()); assert_eq!(xs_alt_hi.len(), number_of_extra_zeros); assert_eq!(xs_alt_lo, xs); assert!(slice_test_zero(xs_alt_hi)); } }); } #[test] fn vec_from_other_type_slice_properties() { apply_fn_to_unsigneds_and_unsigneds!(vec_from_other_type_slice_helper); } malachite-base-0.4.16/tests/num/conversion/string/from_sci_string.rs000064400000000000000000000706421046102023000237550ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::string::options::FromSciStringOptions; use malachite_base::rounding_modes::RoundingMode::*; use malachite_base::test_util::generators::{ signed_gen, string_from_sci_string_options_pair_gen, string_from_sci_string_options_pair_gen_var_1, string_gen, string_gen_var_13, unsigned_gen, }; #[test] pub fn test_from_sci_string() { fn test(s: &str, out: Option) { assert_eq!(T::from_sci_string(s), out); assert_eq!( T::from_sci_string_with_options(s, FromSciStringOptions::default()), out ); } test::("0", Some(0)); test::("00", Some(0)); test::("+0", Some(0)); test::("-0", Some(0)); test::("0.00", Some(0)); test::("0e1", Some(0)); test::("0e+1", Some(0)); test::("0e-1", Some(0)); test::("+0e+1", Some(0)); test::("-0e+1", Some(0)); test::("+0.0e+1", Some(0)); test::("-0.0e+1", Some(0)); test::(".0", Some(0)); test::(".00", Some(0)); test::(".00e0", Some(0)); test::(".00e1", Some(0)); test::(".00e-1", Some(0)); test::("-.0", Some(0)); test::("-.00", Some(0)); test::("-.00e0", Some(0)); test::("-.00e1", Some(0)); test::("-.00e-1", Some(0)); test::("+.0", Some(0)); test::("+.00", Some(0)); test::("+.00e0", Some(0)); test::("+.00e1", Some(0)); test::("+.00e-1", Some(0)); test::("123", Some(123)); test::("00123", Some(123)); test::("+123", Some(123)); test::("123.00", Some(123)); test::("123e0", Some(123)); test::("12.3e1", Some(123)); test::("1.23e2", Some(123)); test::("1.23E2", Some(123)); test::("1.23e+2", Some(123)); test::("1.23E+2", Some(123)); test::(".123e3", Some(123)); test::("0.123e3", Some(123)); test::("+0.123e3", Some(123)); test::("0.0123e4", Some(123)); test::("1230e-1", Some(123)); test::("12300e-2", Some(123)); test::("12300E-2", Some(123)); test::("123.4", Some(123)); test::("123.8", Some(124)); test::("123.5", Some(124)); test::("124.5", Some(124)); test::("255.49", Some(255)); test::("255.5", None); test::("0.5", Some(0)); test::("0.51", Some(1)); test::("0.001", Some(0)); test::("1e-10", Some(0)); test::("-0.5", Some(0)); test::("-0.51", None); test::("-0.001", Some(0)); test::("-1e-10", Some(0)); test::("", None); test::("+", None); test::("-", None); test::("10e", None); test::("++1", None); test::("256", None); test::("-1", None); test::("1e10", None); test::("1.0.0", None); test::("1e++1", None); test::("1e0.1", None); test::("--.0", None); test::("++.0", None); test::("0.000a", None); test::("0.00ae-10", None); test::("0", Some(0)); test::("00", Some(0)); test::("+0", Some(0)); test::("-0", Some(0)); test::("0.00", Some(0)); test::("0e1", Some(0)); test::("0e+1", Some(0)); test::("0e-1", Some(0)); test::("+0e+1", Some(0)); test::("-0e+1", Some(0)); test::("+0.0e+1", Some(0)); test::("-0.0e+1", Some(0)); test::(".0", Some(0)); test::(".00", Some(0)); test::(".00e0", Some(0)); test::(".00e1", Some(0)); test::(".00e-1", Some(0)); test::("-.0", Some(0)); test::("-.00", Some(0)); test::("-.00e0", Some(0)); test::("-.00e1", Some(0)); test::("-.00e-1", Some(0)); test::("+.0", Some(0)); test::("+.00", Some(0)); test::("+.00e0", Some(0)); test::("+.00e1", Some(0)); test::("+.00e-1", Some(0)); test::("123", Some(123)); test::("00123", Some(123)); test::("+123", Some(123)); test::("123.00", Some(123)); test::("123e0", Some(123)); test::("12.3e1", Some(123)); test::("1.23e2", Some(123)); test::("1.23E2", Some(123)); test::("1.23e+2", Some(123)); test::("1.23E+2", Some(123)); test::(".123e3", Some(123)); test::("0.123e3", Some(123)); test::("+0.123e3", Some(123)); test::("0.0123e4", Some(123)); test::("1230e-1", Some(123)); test::("12300e-2", Some(123)); test::("12300E-2", Some(123)); test::("-123", Some(-123)); test::("-00123", Some(-123)); test::("-123.00", Some(-123)); test::("-123e0", Some(-123)); test::("-12.3e1", Some(-123)); test::("-1.23e2", Some(-123)); test::("-1.23E2", Some(-123)); test::("-1.23e+2", Some(-123)); test::("-1.23E+2", Some(-123)); test::("-.123e3", Some(-123)); test::("-0.123e3", Some(-123)); test::("-0.0123e4", Some(-123)); test::("-1230e-1", Some(-123)); test::("-12300e-2", Some(-123)); test::("-12300E-2", Some(-123)); test::("123.4", Some(123)); test::("123.8", Some(124)); test::("123.5", Some(124)); test::("124.5", Some(124)); test::("127.49", Some(127)); test::("127.5", None); test::("-123.4", Some(-123)); test::("-123.8", Some(-124)); test::("-123.5", Some(-124)); test::("-124.5", Some(-124)); test::("-127.49", Some(-127)); test::("-127.5", Some(-128)); test::("-128.51", None); test::("", None); test::("+", None); test::("-", None); test::("10e", None); test::("++1", None); test::("128", None); test::("-129", None); test::("1e10", None); test::("1.0.0", None); test::("1e++1", None); test::("1e0.1", None); test::("--.0", None); test::("++.0", None); test::(".+2", None); test::(".-2", None); test::("0.000a", None); test::("0.00ae-10", None); test::("0e10000000000000000000000000000", None); test::("0e-10000000000000000000000000000", None); } #[test] pub fn test_from_sci_string_with_options() { fn test(s: &str, options: FromSciStringOptions, out: Option) { assert_eq!(T::from_sci_string_with_options(s, options), out); } // For tests with the default options, see `test_from_sci_string` let mut options = FromSciStringOptions::default(); options.set_base(2); test::( "11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111\ 111111111111111111111111111111111111111", options, Some(u128::MAX), ); options.set_base(3); test::( "202201102121002021012000211012011021221022212021111001022110211020010021100121010", options, Some(u128::MAX), ); options.set_base(4); test::( "3333333333333333333333333333333333333333333333333333333333333333", options, Some(u128::MAX), ); options.set_base(5); test::( "11031110441201303134210404233413032443021130230130231310", options, Some(u128::MAX), ); options.set_base(8); test::( "3777777777777777777777777777777777777777777", options, Some(u128::MAX), ); options.set_base(16); test::("ffffffffffffffffffffffffffffffff", options, Some(u128::MAX)); options.set_base(32); test::("7vvvvvvvvvvvvvvvvvvvvvvvvv", options, Some(u128::MAX)); options.set_base(36); test::("f5lxx1zz5pnorynqglhzmsp33", options, Some(u128::MAX)); options.set_base(2); test::( "11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111\ 11111111111111111111111111111111111111", options, Some(i128::MAX), ); test::( "-1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\ 0000000000000000000000000000000000000000", options, Some(i128::MIN), ); options.set_base(3); test::( "101100201022001010121000102002120122110122221010202000122201220121120010200022001", options, Some(i128::MAX), ); test::( "-101100201022001010121000102002120122110122221010202000122201220121120010200022002", options, Some(i128::MIN), ); options.set_base(4); test::( "1333333333333333333333333333333333333333333333333333333333333333", options, Some(i128::MAX), ); test::( "-2000000000000000000000000000000000000000000000000000000000000000", options, Some(i128::MIN), ); options.set_base(5); test::( "3013030220323124042102424341431241221233040112312340402", options, Some(i128::MAX), ); test::( "-3013030220323124042102424341431241221233040112312340403", options, Some(i128::MIN), ); options.set_base(8); test::( "1777777777777777777777777777777777777777777", options, Some(i128::MAX), ); test::( "-2000000000000000000000000000000000000000000", options, Some(i128::MIN), ); options.set_base(16); test::("7fffffffffffffffffffffffffffffff", options, Some(i128::MAX)); test::( "-80000000000000000000000000000000", options, Some(i128::MIN), ); options.set_base(32); test::("3vvvvvvvvvvvvvvvvvvvvvvvvv", options, Some(i128::MAX)); test::("-40000000000000000000000000", options, Some(i128::MIN)); options.set_base(36); test::("7ksyyizzkutudzbv8aqztecjj", options, Some(i128::MAX)); test::("-7ksyyizzkutudzbv8aqztecjk", options, Some(i128::MIN)); options.set_base(2); test::("1e+5", options, Some(32)); test::("1e5", options, Some(32)); options.set_base(3); test::("1e+5", options, Some(243)); test::("1e5", options, Some(243)); options.set_base(4); test::("1e+5", options, Some(1024)); test::("1e5", options, Some(1024)); options.set_base(5); test::("1e+5", options, Some(3125)); test::("1e5", options, Some(3125)); options.set_base(8); test::("1e+5", options, Some(32768)); test::("1e5", options, Some(32768)); options.set_base(16); test::("1e+5", options, Some(1048576)); test::("1e5", options, Some(485)); options.set_base(32); test::("1e+5", options, Some(33554432)); test::("1e5", options, Some(1477)); options.set_base(36); test::("1e+5", options, Some(60466176)); test::("1E+5", options, Some(60466176)); test::("1e5", options, Some(1805)); options.set_base(16); test::("ff", options, Some(255)); test::("fF", options, Some(255)); test::("Ff", options, Some(255)); test::("FF", options, Some(255)); options = FromSciStringOptions::default(); options.set_rounding_mode(Down); test::("123.4", options, Some(123)); options.set_rounding_mode(Floor); test::("123.4", options, Some(123)); options.set_rounding_mode(Up); test::("123.4", options, Some(124)); options.set_rounding_mode(Ceiling); test::("123.4", options, Some(124)); options.set_rounding_mode(Nearest); test::("123.4", options, Some(123)); options.set_rounding_mode(Exact); test::("123.4", options, None); options.set_rounding_mode(Down); test::("123.5", options, Some(123)); options.set_rounding_mode(Floor); test::("123.5", options, Some(123)); options.set_rounding_mode(Up); test::("123.5", options, Some(124)); options.set_rounding_mode(Ceiling); test::("123.5", options, Some(124)); options.set_rounding_mode(Nearest); test::("123.5", options, Some(124)); options.set_rounding_mode(Exact); test::("123.5", options, None); options.set_rounding_mode(Down); test::("0.4", options, Some(0)); options.set_rounding_mode(Floor); test::("0.4", options, Some(0)); options.set_rounding_mode(Up); test::("0.4", options, Some(1)); options.set_rounding_mode(Ceiling); test::("0.4", options, Some(1)); options.set_rounding_mode(Nearest); test::("0.4", options, Some(0)); options.set_rounding_mode(Exact); test::("0.4", options, None); options.set_rounding_mode(Down); test::("0.04", options, Some(0)); options.set_rounding_mode(Floor); test::("0.04", options, Some(0)); options.set_rounding_mode(Up); test::("0.04", options, Some(1)); options.set_rounding_mode(Ceiling); test::("0.04", options, Some(1)); options.set_rounding_mode(Nearest); test::("0.04", options, Some(0)); options.set_rounding_mode(Exact); test::("0.04", options, None); options = FromSciStringOptions::default(); options.set_base(2); // 1/2 is 0.1 test::("1.01", options, Some(1)); test::("1.1", options, Some(2)); test::("1.11", options, Some(2)); test::("0.01", options, Some(0)); test::("0.1", options, Some(0)); test::("0.11", options, Some(1)); options.set_base(3); // 1/2 is 0.111... test::("1.1", options, Some(1)); test::("1.11", options, Some(1)); test::("1.111", options, Some(1)); test::("1.112", options, Some(2)); test::("0.1", options, Some(0)); test::("0.11", options, Some(0)); test::("0.111", options, Some(0)); test::("0.112", options, Some(1)); options = FromSciStringOptions::default(); options.set_base(2); test::("2", options, None); test::("102", options, None); test::("12e4", options, None); test::("12e-4", options, None); test::("1.2", options, None); test::("0.2", options, None); test::("0.002", options, None); options = FromSciStringOptions::default(); options.set_rounding_mode(Exact); test::("1.5", options, None); test::("1.9999999999999999999999999999", options, None); options.set_base(2); test::( "11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111\ 11111111111111111111111111111111111111", options, Some(i128::MAX), ); test::( "-1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\ 0000000000000000000000000000000000000000", options, Some(i128::MIN), ); options.set_base(3); test::( "101100201022001010121000102002120122110122221010202000122201220121120010200022001", options, Some(i128::MAX), ); test::( "-101100201022001010121000102002120122110122221010202000122201220121120010200022002", options, Some(i128::MIN), ); options.set_base(4); test::( "1333333333333333333333333333333333333333333333333333333333333333", options, Some(i128::MAX), ); test::( "-2000000000000000000000000000000000000000000000000000000000000000", options, Some(i128::MIN), ); options.set_base(5); test::( "3013030220323124042102424341431241221233040112312340402", options, Some(i128::MAX), ); test::( "-3013030220323124042102424341431241221233040112312340403", options, Some(i128::MIN), ); options.set_base(8); test::( "1777777777777777777777777777777777777777777", options, Some(i128::MAX), ); test::( "-2000000000000000000000000000000000000000000", options, Some(i128::MIN), ); options.set_base(16); test::("7fffffffffffffffffffffffffffffff", options, Some(i128::MAX)); test::( "-80000000000000000000000000000000", options, Some(i128::MIN), ); options.set_base(32); test::("3vvvvvvvvvvvvvvvvvvvvvvvvv", options, Some(i128::MAX)); test::("-40000000000000000000000000", options, Some(i128::MIN)); options.set_base(36); test::("7ksyyizzkutudzbv8aqztecjj", options, Some(i128::MAX)); test::("-7ksyyizzkutudzbv8aqztecjk", options, Some(i128::MIN)); options.set_base(2); test::("1e+5", options, Some(32)); test::("1e5", options, Some(32)); options.set_base(3); test::("1e+5", options, Some(243)); test::("1e5", options, Some(243)); options.set_base(4); test::("1e+5", options, Some(1024)); test::("1e5", options, Some(1024)); options.set_base(5); test::("1e+5", options, Some(3125)); test::("1e5", options, Some(3125)); options.set_base(8); test::("1e+5", options, Some(32768)); test::("1e5", options, Some(32768)); options.set_base(16); test::("1e+5", options, Some(1048576)); test::("1e5", options, Some(485)); options.set_base(32); test::("1e+5", options, Some(33554432)); test::("1e5", options, Some(1477)); options.set_base(36); test::("1e+5", options, Some(60466176)); test::("1E+5", options, Some(60466176)); test::("1e5", options, Some(1805)); options.set_base(2); test::("-1e+5", options, Some(-32)); test::("-1e5", options, Some(-32)); options.set_base(3); test::("-1e+5", options, Some(-243)); test::("-1e5", options, Some(-243)); options.set_base(4); test::("-1e+5", options, Some(-1024)); test::("-1e5", options, Some(-1024)); options.set_base(5); test::("-1e+5", options, Some(-3125)); test::("-1e5", options, Some(-3125)); options.set_base(8); test::("-1e+5", options, Some(-32768)); test::("-1e5", options, Some(-32768)); options.set_base(16); test::("-1e+5", options, Some(-1048576)); test::("-1e5", options, Some(-485)); options.set_base(32); test::("-1e+5", options, Some(-33554432)); test::("-1e5", options, Some(-1477)); options.set_base(36); test::("-1e+5", options, Some(-60466176)); test::("-1E+5", options, Some(-60466176)); test::("-1e5", options, Some(-1805)); options.set_base(16); test::("ff", options, Some(255)); test::("fF", options, Some(255)); test::("Ff", options, Some(255)); test::("FF", options, Some(255)); test::("-ff", options, Some(-255)); test::("-fF", options, Some(-255)); test::("-Ff", options, Some(-255)); test::("-FF", options, Some(-255)); options = FromSciStringOptions::default(); options.set_rounding_mode(Down); test::("123.4", options, Some(123)); options.set_rounding_mode(Floor); test::("123.4", options, Some(123)); options.set_rounding_mode(Up); test::("123.4", options, Some(124)); options.set_rounding_mode(Ceiling); test::("123.4", options, Some(124)); options.set_rounding_mode(Nearest); test::("123.4", options, Some(123)); options.set_rounding_mode(Exact); test::("123.4", options, None); options.set_rounding_mode(Down); test::("-123.4", options, Some(-123)); options.set_rounding_mode(Floor); test::("-123.4", options, Some(-124)); options.set_rounding_mode(Up); test::("-123.4", options, Some(-124)); options.set_rounding_mode(Ceiling); test::("-123.4", options, Some(-123)); options.set_rounding_mode(Nearest); test::("-123.4", options, Some(-123)); options.set_rounding_mode(Exact); test::("-123.4", options, None); options.set_rounding_mode(Down); test::("123.5", options, Some(123)); options.set_rounding_mode(Floor); test::("123.5", options, Some(123)); options.set_rounding_mode(Up); test::("123.5", options, Some(124)); options.set_rounding_mode(Ceiling); test::("123.5", options, Some(124)); options.set_rounding_mode(Nearest); test::("123.5", options, Some(124)); options.set_rounding_mode(Exact); test::("123.5", options, None); options.set_rounding_mode(Down); test::("-123.5", options, Some(-123)); options.set_rounding_mode(Floor); test::("-123.5", options, Some(-124)); options.set_rounding_mode(Up); test::("-123.5", options, Some(-124)); options.set_rounding_mode(Ceiling); test::("-123.5", options, Some(-123)); options.set_rounding_mode(Nearest); test::("-123.5", options, Some(-124)); options.set_rounding_mode(Exact); test::("-123.5", options, None); options.set_rounding_mode(Down); test::("0.4", options, Some(0)); options.set_rounding_mode(Floor); test::("0.4", options, Some(0)); options.set_rounding_mode(Up); test::("0.4", options, Some(1)); options.set_rounding_mode(Ceiling); test::("0.4", options, Some(1)); options.set_rounding_mode(Nearest); test::("0.4", options, Some(0)); options.set_rounding_mode(Exact); test::("0.4", options, None); options.set_rounding_mode(Down); test::("-0.4", options, Some(0)); options.set_rounding_mode(Floor); test::("-0.4", options, Some(-1)); options.set_rounding_mode(Up); test::("-0.4", options, Some(-1)); options.set_rounding_mode(Ceiling); test::("-0.4", options, Some(0)); options.set_rounding_mode(Nearest); test::("-0.4", options, Some(0)); options.set_rounding_mode(Exact); test::("-0.4", options, None); options.set_rounding_mode(Down); test::("0.04", options, Some(0)); options.set_rounding_mode(Floor); test::("0.04", options, Some(0)); options.set_rounding_mode(Up); test::("0.04", options, Some(1)); options.set_rounding_mode(Ceiling); test::("0.04", options, Some(1)); options.set_rounding_mode(Nearest); test::("0.04", options, Some(0)); options.set_rounding_mode(Exact); test::("0.04", options, None); options.set_rounding_mode(Down); test::("-0.04", options, Some(0)); options.set_rounding_mode(Floor); test::("-0.04", options, Some(-1)); options.set_rounding_mode(Up); test::("-0.04", options, Some(-1)); options.set_rounding_mode(Ceiling); test::("-0.04", options, Some(0)); options.set_rounding_mode(Nearest); test::("-0.04", options, Some(0)); options.set_rounding_mode(Exact); test::("-0.04", options, None); options = FromSciStringOptions::default(); options.set_base(2); // 1/2 is 0.1 test::("1.01", options, Some(1)); test::("1.1", options, Some(2)); test::("1.11", options, Some(2)); test::("0.01", options, Some(0)); test::("0.1", options, Some(0)); test::("0.11", options, Some(1)); test::("-1.01", options, Some(-1)); test::("-1.1", options, Some(-2)); test::("-1.11", options, Some(-2)); test::("-0.01", options, Some(0)); test::("-0.1", options, Some(0)); test::("-0.11", options, Some(-1)); options.set_base(3); // 1/2 is 0.111... test::("1.1", options, Some(1)); test::("1.11", options, Some(1)); test::("1.111", options, Some(1)); test::("1.112", options, Some(2)); test::("0.1", options, Some(0)); test::("0.11", options, Some(0)); test::("0.111", options, Some(0)); test::("0.112", options, Some(1)); test::("-1.1", options, Some(-1)); test::("-1.11", options, Some(-1)); test::("-1.111", options, Some(-1)); test::("-1.112", options, Some(-2)); test::("-0.1", options, Some(0)); test::("-0.11", options, Some(0)); test::("-0.111", options, Some(0)); test::("-0.112", options, Some(-1)); options = FromSciStringOptions::default(); options.set_base(2); test::("2", options, None); test::("102", options, None); test::("12e4", options, None); test::("12e-4", options, None); test::("1.2", options, None); test::("0.2", options, None); test::("0.002", options, None); test::("-2", options, None); test::("-102", options, None); test::("-12e4", options, None); test::("-12e-4", options, None); test::("-1.2", options, None); test::("-0.2", options, None); test::("-0.002", options, None); options.set_base(25); options.set_rounding_mode(Ceiling); test::(".be.2", options, None); options = FromSciStringOptions::default(); options.set_rounding_mode(Exact); test::("1.5", options, None); test::("1.9999999999999999999999999999", options, None); test::("-1.5", options, None); test::("-1.9999999999999999999999999999", options, None); } fn from_sci_string_helper_helper(s: &str) { if let Some(x) = T::from_sci_string(s) { assert!(!s.ends_with('+')); assert!(!s.ends_with('-')); assert!(!s.contains("++")); assert!(!s.contains("+-")); assert!(!s.contains("-+")); assert!(!s.contains("--")); assert!(!s.contains("-+")); assert!(s.chars().filter(|&c| c == '.').count() <= 1); assert!(s.chars().filter(|&c| c == '-').count() <= 2); assert!(s.chars().filter(|&c| c == '+').count() <= 2); for c in ['.', 'e', 'E', '+'] { if s.contains(c) { return; } } if s.starts_with('0') || s.starts_with("-0") { return; } assert_eq!(x.to_string(), s); } } fn from_sci_string_helper() { string_gen().test_properties(|s| { from_sci_string_helper_helper::(&s); }); string_gen_var_13().test_properties(|s| { from_sci_string_helper_helper::(&s); }); } fn from_sci_string_helper_unsigned() { unsigned_gen::().test_properties(|x| { assert_eq!(T::from_sci_string(&x.to_string()).unwrap(), x); }); } fn from_sci_string_helper_signed() { signed_gen::().test_properties(|x| { assert_eq!(T::from_sci_string(&x.to_string()).unwrap(), x); }); } #[test] fn from_sci_string_properties() { apply_fn_to_primitive_ints!(from_sci_string_helper); apply_fn_to_unsigneds!(from_sci_string_helper_unsigned); apply_fn_to_signeds!(from_sci_string_helper_signed); } fn from_sci_string_with_options_helper_helper( s: &str, options: FromSciStringOptions, ) { if let Some(x) = T::from_sci_string_with_options(s, options) { assert!(!s.ends_with('+')); assert!(!s.ends_with('-')); assert!(!s.contains("++")); assert!(!s.contains("+-")); assert!(!s.contains("-+")); assert!(!s.contains("--")); assert!(!s.contains("-+")); assert!(s.chars().filter(|&c| c == '.').count() <= 1); assert!(s.chars().filter(|&c| c == '-').count() <= 2); assert!(s.chars().filter(|&c| c == '+').count() <= 2); for c in ['.', 'e', 'E', '+'] { if s.contains(c) { return; } } if s.starts_with('0') || s.starts_with("-0") { return; } assert_eq!(x.to_string_base(options.get_base()), s.to_lowercase()); } } fn from_sci_string_with_options_helper() { string_from_sci_string_options_pair_gen().test_properties(|(s, options)| { from_sci_string_with_options_helper_helper::(&s, options); }); string_from_sci_string_options_pair_gen_var_1().test_properties(|(s, options)| { from_sci_string_with_options_helper_helper::(&s, options); }); } #[test] fn from_sci_string_with_options_properties() { apply_fn_to_primitive_ints!(from_sci_string_with_options_helper); } malachite-base-0.4.16/tests/num/conversion/string/from_string.rs000064400000000000000000000041051046102023000231060ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::conversion::string::from_string::digit_from_display_byte; use malachite_base::num::conversion::string::to_string::{ digit_to_display_byte_lower, digit_to_display_byte_upper, }; use malachite_base::test_util::generators::{unsigned_gen, unsigned_gen_var_10}; #[test] fn test_digit_from_display_byte() { let test_ok = |x, y| { assert_eq!(digit_from_display_byte(x).unwrap(), y); }; test_ok(b'0', 0); test_ok(b'1', 1); test_ok(b'2', 2); test_ok(b'3', 3); test_ok(b'4', 4); test_ok(b'5', 5); test_ok(b'6', 6); test_ok(b'7', 7); test_ok(b'8', 8); test_ok(b'9', 9); test_ok(b'a', 10); test_ok(b'b', 11); test_ok(b'c', 12); test_ok(b'x', 33); test_ok(b'y', 34); test_ok(b'z', 35); test_ok(b'A', 10); test_ok(b'B', 11); test_ok(b'C', 12); test_ok(b'X', 33); test_ok(b'Y', 34); test_ok(b'Z', 35); let test_err = |x| { assert!(digit_from_display_byte(x).is_none()); }; test_err(b' '); test_err(b'!'); } #[test] fn digit_from_display_byte_properties() { unsigned_gen().test_properties(|b| { assert_eq!( digit_from_display_byte(b).is_some(), b.is_ascii_alphanumeric() ); }); unsigned_gen_var_10().test_properties(|b| { let digit = digit_from_display_byte(b).unwrap(); assert!(b.is_ascii_alphanumeric()); // Both of the following conditions include numeric chars. if !char::from(b).is_uppercase() { assert_eq!(digit_to_display_byte_lower(digit), Some(b)); } if !char::from(b).is_lowercase() { assert_eq!(digit_to_display_byte_upper(digit), Some(b)); } }); } malachite-base-0.4.16/tests/num/conversion/string/options/from_sci_string_options.rs000064400000000000000000000033241046102023000272140ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::generators::{ from_sci_string_options_gen, from_sci_string_options_rounding_mode_pair_gen, from_sci_string_options_unsigned_pair_gen_var_1, }; #[test] fn from_sci_string_options_properties() { from_sci_string_options_gen().test_properties(|options| { let mut options_alt = options; let base = options.get_base(); assert!(base >= 2); assert!(base <= 36); options_alt.set_base(base); assert_eq!(options_alt, options); let rounding_mode = options.get_rounding_mode(); options_alt.set_rounding_mode(rounding_mode); assert_eq!(options_alt, options); }); from_sci_string_options_unsigned_pair_gen_var_1().test_properties(|(mut options, base)| { let old_options = options; let old_base = options.get_base(); options.set_base(base); assert_eq!(options.get_base(), base); options.set_base(old_base); assert_eq!(options, old_options); }); from_sci_string_options_rounding_mode_pair_gen().test_properties(|(mut options, rm)| { let old_options = options; let old_rm = options.get_rounding_mode(); options.set_rounding_mode(rm); assert_eq!(options.get_rounding_mode(), rm); options.set_rounding_mode(old_rm); assert_eq!(options, old_options); }); } malachite-base-0.4.16/tests/num/conversion/string/options/to_sci_options.rs000064400000000000000000000166201046102023000253100ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::conversion::string::options::SciSizeOptions; use malachite_base::test_util::generators::{ to_sci_options_bool_pair_gen, to_sci_options_gen, to_sci_options_rounding_mode_pair_gen, to_sci_options_signed_pair_gen_var_1, to_sci_options_unsigned_pair_gen_var_1, to_sci_options_unsigned_pair_gen_var_2, to_sci_options_unsigned_pair_gen_var_3, }; #[test] fn to_sci_options_properties() { to_sci_options_gen().test_properties(|options| { let mut options_alt = options; let base = options.get_base(); assert!(base >= 2); assert!(base <= 36); options_alt.set_base(base); assert_eq!(options_alt, options); let rounding_mode = options.get_rounding_mode(); options_alt.set_rounding_mode(rounding_mode); assert_eq!(options_alt, options); let size_options = options.get_size_options(); match size_options { SciSizeOptions::Complete => options_alt.set_size_complete(), SciSizeOptions::Precision(p) => options_alt.set_precision(p), SciSizeOptions::Scale(s) => options_alt.set_scale(s), } assert_eq!(options_alt, options); let neg_exp_threshold = options.get_neg_exp_threshold(); assert!(neg_exp_threshold < 0); options_alt.set_neg_exp_threshold(neg_exp_threshold); assert_eq!(options_alt, options); let lowercase = options.get_lowercase(); if lowercase { options_alt.set_lowercase(); } else { options_alt.set_uppercase(); } assert_eq!(options_alt, options); let e_lowercase = options.get_e_lowercase(); if e_lowercase { options_alt.set_e_lowercase(); } else { options_alt.set_e_uppercase(); } assert_eq!(options_alt, options); let force_exponent_plus_sign = options.get_force_exponent_plus_sign(); options_alt.set_force_exponent_plus_sign(force_exponent_plus_sign); assert_eq!(options_alt, options); let include_trailing_zeros = options.get_include_trailing_zeros(); options_alt.set_include_trailing_zeros(include_trailing_zeros); assert_eq!(options_alt, options); let mut options = options; let old_options = options; let old_lowercase = options.get_lowercase(); options.set_lowercase(); assert!(options.get_lowercase()); if old_lowercase { options.set_lowercase(); } else { options.set_uppercase(); } assert_eq!(options, old_options); let old_lowercase = options.get_lowercase(); options.set_uppercase(); assert!(!options.get_lowercase()); if old_lowercase { options.set_lowercase(); } else { options.set_uppercase(); } assert_eq!(options, old_options); let old_e_lowercase = options.get_e_lowercase(); options.set_e_lowercase(); assert!(options.get_e_lowercase()); if old_e_lowercase { options.set_e_lowercase(); } else { options.set_e_uppercase(); } assert_eq!(options, old_options); let old_e_lowercase = options.get_e_lowercase(); options.set_e_uppercase(); assert!(!options.get_e_lowercase()); if old_e_lowercase { options.set_e_lowercase(); } else { options.set_e_uppercase(); } assert_eq!(options, old_options); }); to_sci_options_unsigned_pair_gen_var_1().test_properties(|(mut options, base)| { let old_options = options; let old_base = options.get_base(); options.set_base(base); assert_eq!(options.get_base(), base); options.set_base(old_base); assert_eq!(options, old_options); }); to_sci_options_rounding_mode_pair_gen().test_properties(|(mut options, rm)| { let old_options = options; let old_rm = options.get_rounding_mode(); options.set_rounding_mode(rm); assert_eq!(options.get_rounding_mode(), rm); options.set_rounding_mode(old_rm); assert_eq!(options, old_options); }); to_sci_options_gen().test_properties(|mut options| { let old_options = options; let old_size_options = options.get_size_options(); options.set_size_complete(); assert_eq!(options.get_size_options(), SciSizeOptions::Complete); match old_size_options { SciSizeOptions::Complete => options.set_size_complete(), SciSizeOptions::Precision(p) => options.set_precision(p), SciSizeOptions::Scale(s) => options.set_scale(s), } assert_eq!(options, old_options); }); to_sci_options_unsigned_pair_gen_var_3().test_properties(|(mut options, precision)| { let old_options = options; let old_size_options = options.get_size_options(); options.set_precision(precision); assert_eq!( options.get_size_options(), SciSizeOptions::Precision(precision) ); match old_size_options { SciSizeOptions::Complete => options.set_size_complete(), SciSizeOptions::Precision(p) => options.set_precision(p), SciSizeOptions::Scale(s) => options.set_scale(s), } assert_eq!(options, old_options); }); to_sci_options_unsigned_pair_gen_var_2().test_properties(|(mut options, scale)| { let old_options = options; let old_size_options = options.get_size_options(); options.set_scale(scale); assert_eq!(options.get_size_options(), SciSizeOptions::Scale(scale)); match old_size_options { SciSizeOptions::Complete => options.set_size_complete(), SciSizeOptions::Precision(p) => options.set_precision(p), SciSizeOptions::Scale(s) => options.set_scale(s), } assert_eq!(options, old_options); }); to_sci_options_signed_pair_gen_var_1().test_properties(|(mut options, neg_exp_threshold)| { let old_options = options; let old_neg_exp_threshold = options.get_neg_exp_threshold(); options.set_neg_exp_threshold(neg_exp_threshold); assert_eq!(options.get_neg_exp_threshold(), neg_exp_threshold); options.set_neg_exp_threshold(old_neg_exp_threshold); assert_eq!(options, old_options); }); to_sci_options_bool_pair_gen().test_properties(|(mut options, b)| { let old_options = options; let old_force_exponent_plus_sign = options.get_force_exponent_plus_sign(); options.set_force_exponent_plus_sign(b); assert_eq!(options.get_force_exponent_plus_sign(), b); options.set_force_exponent_plus_sign(old_force_exponent_plus_sign); assert_eq!(options, old_options); let old_include_trailing_zeros = options.get_include_trailing_zeros(); options.set_include_trailing_zeros(b); assert_eq!(options.get_include_trailing_zeros(), b); options.set_include_trailing_zeros(old_include_trailing_zeros); assert_eq!(options, old_options); }); } malachite-base-0.4.16/tests/num/conversion/string/to_sci.rs000064400000000000000000001175151046102023000220470ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::{FloorLogBase, UnsignedAbs}; use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::string::options::{ FromSciStringOptions, SciSizeOptions, ToSciOptions, }; use malachite_base::rounding_modes::RoundingMode::*; use malachite_base::strings::string_is_subset; use malachite_base::test_util::generators::{ signed_gen, signed_to_sci_options_pair_gen_var_1, unsigned_gen, unsigned_to_sci_options_pair_gen_var_1, }; use malachite_base::test_util::num::conversion::string::from_sci_string::DECIMAL_SCI_STRING_CHARS; use std::collections::HashMap; use std::panic::catch_unwind; #[test] pub fn test_to_sci() { fn test(x: T, out: &str) { assert_eq!(x.to_sci().to_string(), out); assert_eq!( x.to_sci_with_options(ToSciOptions::default()).to_string(), out ); } test::(0, "0"); test::(1, "1"); test::(10, "10"); test::(100, "100"); test::(1000, "1000"); test::(10000, "10000"); test::(100000, "100000"); test::(1000000, "1000000"); test::(10000000, "10000000"); test::(100000000, "100000000"); test::(1000000000, "1000000000"); test::(10000000000, "10000000000"); test::(100000000000, "100000000000"); test::(1000000000000, "1000000000000"); test::(10000000000000, "10000000000000"); test::(100000000000000, "100000000000000"); test::(1000000000000000, "1000000000000000"); test::(10000000000000000, "1e16"); test::(100000000000000000, "1e17"); test::(u64::MAX, "1.844674407370955e19"); test::(u128::MAX, "3.402823669209385e38"); test::(999999999999999, "999999999999999"); test::(9999999999999999, "9999999999999999"); test::(99999999999999999, "1e17"); test::(999999999999999999, "1e18"); test::(0, "0"); test::(1, "1"); test::(10, "10"); test::(100, "100"); test::(1000, "1000"); test::(10000, "10000"); test::(100000, "100000"); test::(1000000, "1000000"); test::(10000000, "10000000"); test::(100000000, "100000000"); test::(1000000000, "1000000000"); test::(10000000000, "10000000000"); test::(100000000000, "100000000000"); test::(1000000000000, "1000000000000"); test::(10000000000000, "10000000000000"); test::(100000000000000, "100000000000000"); test::(1000000000000000, "1000000000000000"); test::(10000000000000000, "1e16"); test::(100000000000000000, "1e17"); test::(i64::MAX, "9.223372036854776e18"); test::(i128::MAX, "1.701411834604692e38"); test::(-1, "-1"); test::(-10, "-10"); test::(-100, "-100"); test::(-1000, "-1000"); test::(-10000, "-10000"); test::(-100000, "-100000"); test::(-1000000, "-1000000"); test::(-10000000, "-10000000"); test::(-100000000, "-100000000"); test::(-1000000000, "-1000000000"); test::(-10000000000, "-10000000000"); test::(-100000000000, "-100000000000"); test::(-1000000000000, "-1000000000000"); test::(-10000000000000, "-10000000000000"); test::(-100000000000000, "-100000000000000"); test::(-1000000000000000, "-1000000000000000"); test::(-10000000000000000, "-1e16"); test::(-100000000000000000, "-1e17"); test::(i64::MIN, "-9.223372036854776e18"); test::(i128::MIN, "-1.701411834604692e38"); test::(999999999999999, "999999999999999"); test::(9999999999999999, "9999999999999999"); test::(99999999999999999, "1e17"); test::(999999999999999999, "1e18"); } #[test] pub fn test_to_sci_with_options() { fn test(x: T, options: ToSciOptions, out: &str) { assert_eq!(x.to_sci_with_options(options).to_string(), out); } // For tests with the default options, see `test_to_sci` let mut options = ToSciOptions::default(); options.set_include_trailing_zeros(true); test::(0, options, "0.000000000000000"); test::(1, options, "1.000000000000000"); test::(10, options, "10.00000000000000"); test::(100, options, "100.0000000000000"); test::(1000, options, "1000.000000000000"); test::(10000, options, "10000.00000000000"); test::(100000, options, "100000.0000000000"); test::(1000000, options, "1000000.000000000"); test::(10000000, options, "10000000.00000000"); test::(100000000, options, "100000000.0000000"); test::(1000000000, options, "1000000000.000000"); test::(10000000000, options, "10000000000.00000"); test::(100000000000, options, "100000000000.0000"); test::(1000000000000, options, "1000000000000.000"); test::(10000000000000, options, "10000000000000.00"); test::(100000000000000, options, "100000000000000.0"); test::(1000000000000000, options, "1000000000000000"); test::(10000000000000000, options, "1.000000000000000e16"); test::(100000000000000000, options, "1.000000000000000e17"); test::(u64::MAX, options, "1.844674407370955e19"); test::(u128::MAX, options, "3.402823669209385e38"); test::(999999999999999, options, "999999999999999.0"); test::(9999999999999999, options, "9999999999999999"); test::(99999999999999999, options, "1.000000000000000e17"); test::(999999999999999999, options, "1.000000000000000e18"); options = ToSciOptions::default(); options.set_base(2); test::(u128::MAX, options, "1e128"); options.set_base(3); test::(u128::MAX, options, "2.022011021210021e80"); options.set_base(4); test::(u128::MAX, options, "1e64"); options.set_base(5); test::(u128::MAX, options, "1.103111044120131e55"); options.set_base(8); test::(u128::MAX, options, "4e42"); // When base >= 15, there is a mandatory sign after the exponent indicator "e", to distinguish // it from the digit "e" options.set_base(16); test::(u128::MAX, options, "1e+32"); options.set_base(32); test::(u128::MAX, options, "8e+25"); options.set_base(36); test::(u128::MAX, options, "f.5lxx1zz5pnorynqe+24"); // The sign can be forced in other cases too options.set_base(3); options.set_force_exponent_plus_sign(true); test::(u128::MAX, options, "2.022011021210021e+80"); // The digits can be uppercase, and so can the exponent indicator options = ToSciOptions::default(); options.set_base(36); options.set_uppercase(); test::(u128::MAX, options, "F.5LXX1ZZ5PNORYNQe+24"); options.set_lowercase(); options.set_e_uppercase(); test::(u128::MAX, options, "f.5lxx1zz5pnorynqE+24"); options.set_uppercase(); test::(u128::MAX, options, "F.5LXX1ZZ5PNORYNQE+24"); options = ToSciOptions::default(); options.set_size_complete(); options.set_base(2); test::( u128::MAX, options, "11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111\ 111111111111111111111111111111111111111", ); options.set_base(3); test::( u128::MAX, options, "202201102121002021012000211012011021221022212021111001022110211020010021100121010", ); options.set_base(4); test::( u128::MAX, options, "3333333333333333333333333333333333333333333333333333333333333333", ); options.set_base(5); test::( u128::MAX, options, "11031110441201303134210404233413032443021130230130231310", ); options.set_base(8); test::( u128::MAX, options, "3777777777777777777777777777777777777777777", ); options.set_base(16); test::(u128::MAX, options, "ffffffffffffffffffffffffffffffff"); options.set_base(32); test::(u128::MAX, options, "7vvvvvvvvvvvvvvvvvvvvvvvvv"); options.set_base(36); test::(u128::MAX, options, "f5lxx1zz5pnorynqglhzmsp33"); options = ToSciOptions::default(); options.set_precision(4); options.set_include_trailing_zeros(true); test::(0, options, "0.000"); test::(1, options, "1.000"); test::(10, options, "10.00"); test::(100, options, "100.0"); test::(1000, options, "1000"); test::(10000, options, "1.000e4"); test::(9, options, "9.000"); test::(99, options, "99.00"); test::(999, options, "999.0"); test::(9999, options, "9999"); test::(99999, options, "1.000e5"); options.set_include_trailing_zeros(false); test::(0, options, "0"); test::(1, options, "1"); test::(10, options, "10"); test::(100, options, "100"); test::(1000, options, "1000"); test::(10000, options, "1e4"); test::(9, options, "9"); test::(99, options, "99"); test::(999, options, "999"); test::(9999, options, "9999"); test::(99999, options, "1e5"); options = ToSciOptions::default(); options.set_precision(1); options.set_include_trailing_zeros(true); // doesn't matter when precision is 1 test::(0, options, "0"); test::(1, options, "1"); test::(10, options, "1e1"); test::(100, options, "1e2"); test::(1000, options, "1e3"); test::(10000, options, "1e4"); test::(9, options, "9"); test::(99, options, "1e2"); test::(999, options, "1e3"); test::(9999, options, "1e4"); test::(99999, options, "1e5"); options.set_include_trailing_zeros(false); test::(0, options, "0"); test::(1, options, "1"); test::(10, options, "1e1"); test::(100, options, "1e2"); test::(1000, options, "1e3"); test::(10000, options, "1e4"); test::(9, options, "9"); test::(99, options, "1e2"); test::(999, options, "1e3"); test::(9999, options, "1e4"); test::(99999, options, "1e5"); options = ToSciOptions::default(); options.set_scale(2); options.set_include_trailing_zeros(true); test::(0, options, "0.00"); test::(1, options, "1.00"); test::(10, options, "10.00"); test::(100, options, "100.00"); test::(1000, options, "1000.00"); test::(10000, options, "10000.00"); test::(9, options, "9.00"); test::(99, options, "99.00"); test::(999, options, "999.00"); test::(9999, options, "9999.00"); test::(99999, options, "99999.00"); options.set_include_trailing_zeros(false); test::(0, options, "0"); test::(1, options, "1"); test::(10, options, "10"); test::(100, options, "100"); test::(1000, options, "1000"); test::(10000, options, "10000"); test::(9, options, "9"); test::(99, options, "99"); test::(999, options, "999"); test::(9999, options, "9999"); test::(99999, options, "99999"); options = ToSciOptions::default(); options.set_scale(0); options.set_include_trailing_zeros(true); // doesn't matter when scale is 0 test::(0, options, "0"); test::(1, options, "1"); test::(10, options, "10"); test::(100, options, "100"); test::(1000, options, "1000"); test::(10000, options, "10000"); test::(9, options, "9"); test::(99, options, "99"); test::(999, options, "999"); test::(9999, options, "9999"); test::(99999, options, "99999"); options.set_include_trailing_zeros(false); test::(0, options, "0"); test::(1, options, "1"); test::(10, options, "10"); test::(100, options, "100"); test::(1000, options, "1000"); test::(10000, options, "10000"); test::(9, options, "9"); test::(99, options, "99"); test::(999, options, "999"); test::(9999, options, "9999"); test::(99999, options, "99999"); options = ToSciOptions::default(); options.set_precision(2); options.set_rounding_mode(Nearest); // This is the default test::(123, options, "1.2e2"); options.set_rounding_mode(Down); test::(123, options, "1.2e2"); options.set_rounding_mode(Floor); test::(123, options, "1.2e2"); options.set_rounding_mode(Up); test::(123, options, "1.3e2"); options.set_rounding_mode(Ceiling); test::(123, options, "1.3e2"); options.set_rounding_mode(Nearest); test::(135, options, "1.4e2"); options.set_rounding_mode(Down); test::(135, options, "1.3e2"); options.set_rounding_mode(Floor); test::(135, options, "1.3e2"); options.set_rounding_mode(Up); test::(135, options, "1.4e2"); options.set_rounding_mode(Ceiling); test::(135, options, "1.4e2"); options.set_rounding_mode(Exact); test::(140, options, "1.4e2"); options.set_rounding_mode(Nearest); test::(999, options, "1e3"); options.set_rounding_mode(Down); test::(999, options, "9.9e2"); options.set_rounding_mode(Floor); test::(999, options, "9.9e2"); options.set_rounding_mode(Up); test::(999, options, "1e3"); options.set_rounding_mode(Ceiling); test::(999, options, "1e3"); let mut options = ToSciOptions::default(); options.set_include_trailing_zeros(true); test::(0, options, "0.000000000000000"); test::(1, options, "1.000000000000000"); test::(10, options, "10.00000000000000"); test::(100, options, "100.0000000000000"); test::(1000, options, "1000.000000000000"); test::(10000, options, "10000.00000000000"); test::(100000, options, "100000.0000000000"); test::(1000000, options, "1000000.000000000"); test::(10000000, options, "10000000.00000000"); test::(100000000, options, "100000000.0000000"); test::(1000000000, options, "1000000000.000000"); test::(10000000000, options, "10000000000.00000"); test::(100000000000, options, "100000000000.0000"); test::(1000000000000, options, "1000000000000.000"); test::(10000000000000, options, "10000000000000.00"); test::(100000000000000, options, "100000000000000.0"); test::(1000000000000000, options, "1000000000000000"); test::(10000000000000000, options, "1.000000000000000e16"); test::(100000000000000000, options, "1.000000000000000e17"); test::(i64::MAX, options, "9.223372036854776e18"); test::(i128::MAX, options, "1.701411834604692e38"); test::(-1, options, "-1.000000000000000"); test::(-10, options, "-10.00000000000000"); test::(-100, options, "-100.0000000000000"); test::(-1000, options, "-1000.000000000000"); test::(-10000, options, "-10000.00000000000"); test::(-100000, options, "-100000.0000000000"); test::(-1000000, options, "-1000000.000000000"); test::(-10000000, options, "-10000000.00000000"); test::(-100000000, options, "-100000000.0000000"); test::(-1000000000, options, "-1000000000.000000"); test::(-10000000000, options, "-10000000000.00000"); test::(-100000000000, options, "-100000000000.0000"); test::(-1000000000000, options, "-1000000000000.000"); test::(-10000000000000, options, "-10000000000000.00"); test::(-100000000000000, options, "-100000000000000.0"); test::(-1000000000000000, options, "-1000000000000000"); test::(-10000000000000000, options, "-1.000000000000000e16"); test::(-100000000000000000, options, "-1.000000000000000e17"); test::(i64::MIN, options, "-9.223372036854776e18"); test::(i128::MIN, options, "-1.701411834604692e38"); test::(999999999999999, options, "999999999999999.0"); test::(9999999999999999, options, "9999999999999999"); test::(99999999999999999, options, "1.000000000000000e17"); test::(999999999999999999, options, "1.000000000000000e18"); test::(-999999999999999, options, "-999999999999999.0"); test::(-9999999999999999, options, "-9999999999999999"); test::(-99999999999999999, options, "-1.000000000000000e17"); test::(-999999999999999999, options, "-1.000000000000000e18"); options = ToSciOptions::default(); options.set_base(2); test::(i128::MAX, options, "1e127"); test::(i128::MIN, options, "-1e127"); options.set_base(3); test::(i128::MAX, options, "1.01100201022001e80"); test::(i128::MIN, options, "-1.01100201022001e80"); options.set_base(4); test::(i128::MAX, options, "2e63"); test::(i128::MIN, options, "-2e63"); options.set_base(5); test::(i128::MAX, options, "3.013030220323124e54"); test::(i128::MIN, options, "-3.013030220323124e54"); options.set_base(8); test::(i128::MAX, options, "2e42"); test::(i128::MIN, options, "-2e42"); // When base >= 15, there is a mandatory sign after the exponent indicator "e", to distinguish // it from the digit "e" options.set_base(16); test::(i128::MAX, options, "8e+31"); test::(i128::MIN, options, "-8e+31"); options.set_base(32); test::(i128::MAX, options, "4e+25"); test::(i128::MIN, options, "-4e+25"); options.set_base(36); test::(i128::MAX, options, "7.ksyyizzkutudzbve+24"); test::(i128::MIN, options, "-7.ksyyizzkutudzbve+24"); // The sign can be forced in other cases too options.set_base(3); options.set_force_exponent_plus_sign(true); test::(i128::MAX, options, "1.01100201022001e+80"); test::(i128::MIN, options, "-1.01100201022001e+80"); // The digits can be uppercase, and so can the exponent indicator options = ToSciOptions::default(); options.set_base(36); options.set_uppercase(); test::(i128::MAX, options, "7.KSYYIZZKUTUDZBVe+24"); test::(i128::MIN, options, "-7.KSYYIZZKUTUDZBVe+24"); options.set_lowercase(); options.set_e_uppercase(); test::(i128::MAX, options, "7.ksyyizzkutudzbvE+24"); test::(i128::MIN, options, "-7.ksyyizzkutudzbvE+24"); options.set_uppercase(); test::(i128::MAX, options, "7.KSYYIZZKUTUDZBVE+24"); test::(i128::MIN, options, "-7.KSYYIZZKUTUDZBVE+24"); options = ToSciOptions::default(); options.set_size_complete(); options.set_base(2); test::( i128::MAX, options, "11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111\ 11111111111111111111111111111111111111", ); test::( i128::MIN, options, "-1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\ 0000000000000000000000000000000000000000", ); options.set_base(3); test::( i128::MAX, options, "101100201022001010121000102002120122110122221010202000122201220121120010200022001", ); test::( i128::MIN, options, "-101100201022001010121000102002120122110122221010202000122201220121120010200022002", ); options.set_base(4); test::( i128::MAX, options, "1333333333333333333333333333333333333333333333333333333333333333", ); test::( i128::MIN, options, "-2000000000000000000000000000000000000000000000000000000000000000", ); options.set_base(5); test::( i128::MAX, options, "3013030220323124042102424341431241221233040112312340402", ); test::( i128::MIN, options, "-3013030220323124042102424341431241221233040112312340403", ); options.set_base(8); test::( i128::MAX, options, "1777777777777777777777777777777777777777777", ); test::( i128::MIN, options, "-2000000000000000000000000000000000000000000", ); options.set_base(16); test::(i128::MAX, options, "7fffffffffffffffffffffffffffffff"); test::(i128::MIN, options, "-80000000000000000000000000000000"); options.set_base(32); test::(i128::MAX, options, "3vvvvvvvvvvvvvvvvvvvvvvvvv"); test::(i128::MIN, options, "-40000000000000000000000000"); options.set_base(36); test::(i128::MAX, options, "7ksyyizzkutudzbv8aqztecjj"); test::(i128::MIN, options, "-7ksyyizzkutudzbv8aqztecjk"); options = ToSciOptions::default(); options.set_precision(4); options.set_include_trailing_zeros(true); test::(0, options, "0.000"); test::(1, options, "1.000"); test::(10, options, "10.00"); test::(100, options, "100.0"); test::(1000, options, "1000"); test::(10000, options, "1.000e4"); test::(-1, options, "-1.000"); test::(-10, options, "-10.00"); test::(-100, options, "-100.0"); test::(-1000, options, "-1000"); test::(-10000, options, "-1.000e4"); test::(9, options, "9.000"); test::(99, options, "99.00"); test::(999, options, "999.0"); test::(9999, options, "9999"); test::(99999, options, "1.000e5"); test::(-9, options, "-9.000"); test::(-99, options, "-99.00"); test::(-999, options, "-999.0"); test::(-9999, options, "-9999"); test::(-99999, options, "-1.000e5"); options.set_include_trailing_zeros(false); test::(0, options, "0"); test::(1, options, "1"); test::(10, options, "10"); test::(100, options, "100"); test::(1000, options, "1000"); test::(10000, options, "1e4"); test::(-1, options, "-1"); test::(-10, options, "-10"); test::(-100, options, "-100"); test::(-1000, options, "-1000"); test::(-10000, options, "-1e4"); test::(9, options, "9"); test::(99, options, "99"); test::(999, options, "999"); test::(9999, options, "9999"); test::(99999, options, "1e5"); test::(-9, options, "-9"); test::(-99, options, "-99"); test::(-999, options, "-999"); test::(-9999, options, "-9999"); test::(-99999, options, "-1e5"); options = ToSciOptions::default(); options.set_precision(1); options.set_include_trailing_zeros(true); // doesn't matter when precision is 1 test::(0, options, "0"); test::(1, options, "1"); test::(10, options, "1e1"); test::(100, options, "1e2"); test::(1000, options, "1e3"); test::(10000, options, "1e4"); test::(-1, options, "-1"); test::(-10, options, "-1e1"); test::(-100, options, "-1e2"); test::(-1000, options, "-1e3"); test::(-10000, options, "-1e4"); test::(9, options, "9"); test::(99, options, "1e2"); test::(999, options, "1e3"); test::(9999, options, "1e4"); test::(99999, options, "1e5"); test::(-9, options, "-9"); test::(-99, options, "-1e2"); test::(-999, options, "-1e3"); test::(-9999, options, "-1e4"); test::(-99999, options, "-1e5"); options.set_include_trailing_zeros(false); test::(0, options, "0"); test::(1, options, "1"); test::(10, options, "1e1"); test::(100, options, "1e2"); test::(1000, options, "1e3"); test::(10000, options, "1e4"); test::(-1, options, "-1"); test::(-10, options, "-1e1"); test::(-100, options, "-1e2"); test::(-1000, options, "-1e3"); test::(-10000, options, "-1e4"); test::(9, options, "9"); test::(99, options, "1e2"); test::(999, options, "1e3"); test::(9999, options, "1e4"); test::(99999, options, "1e5"); test::(-9, options, "-9"); test::(-99, options, "-1e2"); test::(-999, options, "-1e3"); test::(-9999, options, "-1e4"); test::(-99999, options, "-1e5"); options = ToSciOptions::default(); options.set_scale(2); options.set_include_trailing_zeros(true); test::(0, options, "0.00"); test::(1, options, "1.00"); test::(10, options, "10.00"); test::(100, options, "100.00"); test::(1000, options, "1000.00"); test::(10000, options, "10000.00"); test::(-1, options, "-1.00"); test::(-10, options, "-10.00"); test::(-100, options, "-100.00"); test::(-1000, options, "-1000.00"); test::(-10000, options, "-10000.00"); test::(9, options, "9.00"); test::(99, options, "99.00"); test::(999, options, "999.00"); test::(9999, options, "9999.00"); test::(99999, options, "99999.00"); test::(-9, options, "-9.00"); test::(-99, options, "-99.00"); test::(-999, options, "-999.00"); test::(-9999, options, "-9999.00"); test::(-99999, options, "-99999.00"); options.set_include_trailing_zeros(false); test::(0, options, "0"); test::(1, options, "1"); test::(10, options, "10"); test::(100, options, "100"); test::(1000, options, "1000"); test::(10000, options, "10000"); test::(-1, options, "-1"); test::(-10, options, "-10"); test::(-100, options, "-100"); test::(-1000, options, "-1000"); test::(-10000, options, "-10000"); test::(9, options, "9"); test::(99, options, "99"); test::(999, options, "999"); test::(9999, options, "9999"); test::(99999, options, "99999"); test::(-9, options, "-9"); test::(-99, options, "-99"); test::(-999, options, "-999"); test::(-9999, options, "-9999"); test::(-99999, options, "-99999"); options = ToSciOptions::default(); options.set_scale(0); options.set_include_trailing_zeros(true); // doesn't matter when scale is 0 test::(0, options, "0"); test::(1, options, "1"); test::(10, options, "10"); test::(100, options, "100"); test::(1000, options, "1000"); test::(10000, options, "10000"); test::(-1, options, "-1"); test::(-10, options, "-10"); test::(-100, options, "-100"); test::(-1000, options, "-1000"); test::(-10000, options, "-10000"); test::(9, options, "9"); test::(99, options, "99"); test::(999, options, "999"); test::(9999, options, "9999"); test::(99999, options, "99999"); test::(-9, options, "-9"); test::(-99, options, "-99"); test::(-999, options, "-999"); test::(-9999, options, "-9999"); test::(-99999, options, "-99999"); options.set_include_trailing_zeros(false); test::(0, options, "0"); test::(1, options, "1"); test::(10, options, "10"); test::(100, options, "100"); test::(1000, options, "1000"); test::(10000, options, "10000"); test::(-1, options, "-1"); test::(-10, options, "-10"); test::(-100, options, "-100"); test::(-1000, options, "-1000"); test::(-10000, options, "-10000"); test::(9, options, "9"); test::(99, options, "99"); test::(999, options, "999"); test::(9999, options, "9999"); test::(99999, options, "99999"); test::(-9, options, "-9"); test::(-99, options, "-99"); test::(-999, options, "-999"); test::(-9999, options, "-9999"); test::(-99999, options, "-99999"); options = ToSciOptions::default(); options.set_precision(2); options.set_rounding_mode(Nearest); // This is the default test::(123, options, "1.2e2"); test::(-123, options, "-1.2e2"); options.set_rounding_mode(Down); test::(123, options, "1.2e2"); test::(-123, options, "-1.2e2"); options.set_rounding_mode(Floor); test::(123, options, "1.2e2"); test::(-123, options, "-1.3e2"); options.set_rounding_mode(Up); test::(123, options, "1.3e2"); test::(-123, options, "-1.3e2"); options.set_rounding_mode(Ceiling); test::(123, options, "1.3e2"); test::(-123, options, "-1.2e2"); options.set_rounding_mode(Nearest); test::(135, options, "1.4e2"); test::(-135, options, "-1.4e2"); options.set_rounding_mode(Down); test::(135, options, "1.3e2"); test::(-135, options, "-1.3e2"); options.set_rounding_mode(Floor); test::(135, options, "1.3e2"); test::(-135, options, "-1.4e2"); options.set_rounding_mode(Up); test::(135, options, "1.4e2"); test::(-135, options, "-1.4e2"); options.set_rounding_mode(Ceiling); test::(135, options, "1.4e2"); test::(-135, options, "-1.3e2"); options.set_rounding_mode(Exact); test::(140, options, "1.4e2"); test::(-140, options, "-1.4e2"); options.set_rounding_mode(Nearest); test::(999, options, "1e3"); test::(-999, options, "-1e3"); options.set_rounding_mode(Down); test::(999, options, "9.9e2"); test::(-999, options, "-9.9e2"); options.set_rounding_mode(Floor); test::(999, options, "9.9e2"); test::(-999, options, "-1e3"); options.set_rounding_mode(Up); test::(999, options, "1e3"); test::(-999, options, "-1e3"); options.set_rounding_mode(Ceiling); test::(999, options, "1e3"); test::(-999, options, "-9.9e2"); } fn to_sci_with_options_fail_helper() { assert_panic!({ let mut options = ToSciOptions::default(); options.set_rounding_mode(Exact); options.set_precision(2); T::wrapping_from(123u8) .to_sci_with_options(options) .to_string() }); } #[test] pub fn to_sci_with_options_fail() { apply_fn_to_primitive_ints!(to_sci_with_options_fail_helper); } fn to_sci_helper_unsigned() { let mut powers_of_10 = HashMap::new(); let ten = T::from(10u8); let default_p = 16; unsigned_gen::().test_properties(|x| { assert!(x.fmt_sci_valid(ToSciOptions::default())); let s = x.to_sci().to_string(); assert_eq!( x.to_sci_with_options(ToSciOptions::default()).to_string(), s ); assert!(string_is_subset(&s, DECIMAL_SCI_STRING_CHARS)); assert!(!s.starts_with('.')); assert!(!s.ends_with('.')); assert!(!s.contains('-')); assert!(!s.contains('+')); assert!(!s.contains('E')); assert!(s.chars().filter(|&c| c == '.').count() <= 1); if let Some(x_from) = T::from_sci_string(&s) { if x == T::ZERO { assert_eq!(x_from, T::ZERO); } else { let log = x.floor_log_base(ten); if log < default_p { assert_eq!(x_from, x); } else { let pow = *powers_of_10 .entry(log - default_p + 1) .or_insert_with_key(|&p| ten.pow(p)); assert_eq!(x.round_to_multiple(pow, Nearest).0, x_from); } } } else { assert_eq!(x.significant_bits(), T::WIDTH); } }); } fn to_sci_helper_signed() where ::Output: PrimitiveUnsigned, { let mut powers_of_10 = HashMap::new(); let ten = T::from(10); let u_ten = ::Output::from(10u8); let default_p = 16; signed_gen::().test_properties(|x| { assert!(x.fmt_sci_valid(ToSciOptions::default())); let s = x.to_sci().to_string(); assert_eq!( x.to_sci_with_options(ToSciOptions::default()).to_string(), s ); assert!(string_is_subset(&s, DECIMAL_SCI_STRING_CHARS)); assert!(!s.starts_with('+')); assert!(!s.starts_with('.')); assert!(!s.ends_with('+')); assert!(!s.ends_with('-')); assert!(!s.ends_with('.')); assert!(!s.contains('E')); assert!(!s.contains("++")); assert!(!s.contains("+-")); assert!(!s.contains("-+")); assert!(!s.contains("--")); assert!(!s.contains("-+")); assert!(!s.contains("+.")); assert!(!s.contains("-.")); assert!(!s.contains("e-")); assert!(s.chars().filter(|&c| c == '.').count() <= 1); assert!(s.chars().filter(|&c| c == '-').count() <= 1); assert!(s.chars().filter(|&c| c == '+').count() <= 1); if let Some(x_from) = T::from_sci_string(&s) { if x == T::ZERO { assert_eq!(x_from, T::ZERO); } else { let log = x.unsigned_abs().floor_log_base(u_ten); if log < default_p { assert_eq!(x_from, x); } else { let pow = *powers_of_10 .entry(log - default_p + 1) .or_insert_with_key(|&p| ten.pow(p)); assert_eq!(x.round_to_multiple(pow, Nearest).0, x_from); } } } else { assert!(x.significant_bits() >= T::WIDTH - 1); } }); } #[test] fn to_sci_properties() { apply_fn_to_unsigneds!(to_sci_helper_unsigned); apply_fn_to_signeds!(to_sci_helper_signed); } fn to_sci_with_options_helper_unsigned() { let mut powers = HashMap::new(); let mut chars = HashMap::new(); unsigned_to_sci_options_pair_gen_var_1::().test_properties(|(x, options)| { assert!(x.fmt_sci_valid(options)); let s = x.to_sci_with_options(options).to_string(); let cs: &mut String = chars.entry(options.get_base()).or_insert_with_key(|&base| { let mut cs = "+-.0123456789".to_string(); if base > 10 { let limit = usize::from(base - 10); for c in ('a'..='z').take(limit) { cs.push(c); } for c in ('A'..='Z').take(limit) { cs.push(c); } } if base < 15 { cs.push('e'); cs.push('E'); } cs }); assert!(string_is_subset(&s, cs)); assert!(!s.starts_with('+')); assert!(!s.starts_with('.')); assert!(!s.ends_with('+')); assert!(!s.ends_with('.')); assert!(!s.contains('-')); assert!(!s.contains("++")); assert!(!s.contains("+.")); assert!(s.chars().filter(|&c| c == '.').count() <= 1); assert!(s.chars().filter(|&c| c == '+').count() <= 1); let mut from_options = FromSciStringOptions::default(); from_options.set_base(options.get_base()); if let Some(x_from) = T::from_sci_string_with_options(&s, from_options) { if x == T::ZERO { assert_eq!(x_from, T::ZERO); } else { let base = T::from(options.get_base()); let scale = match options.get_size_options() { SciSizeOptions::Complete | SciSizeOptions::Scale(_) => None, SciSizeOptions::Precision(p) => { let log = x.floor_log_base(base); if log >= p { Some(log - p + 1) } else { None } } }; if let Some(scale) = scale { let pow = *powers .entry((base, scale)) .or_insert_with(|| base.pow(scale)); assert_eq!( x.round_to_multiple(pow, options.get_rounding_mode()).0, x_from ); } else { assert_eq!(x_from, x); } } } else { assert_eq!(x.significant_bits(), T::WIDTH); } }); } fn to_sci_with_options_helper_signed() where ::Output: PrimitiveUnsigned, { let mut powers = HashMap::new(); let mut chars = HashMap::new(); signed_to_sci_options_pair_gen_var_1::().test_properties(|(x, options)| { assert!(x.fmt_sci_valid(options)); let s = x.to_sci_with_options(options).to_string(); let cs: &mut String = chars.entry(options.get_base()).or_insert_with_key(|&base| { let mut cs = "+-.0123456789".to_string(); if base > 10 { let limit = usize::from(base - 10); for c in ('a'..='z').take(limit) { cs.push(c); } for c in ('A'..='Z').take(limit) { cs.push(c); } } if base < 15 { cs.push('e'); cs.push('E'); } cs }); assert!(string_is_subset(&s, cs)); assert!(!s.starts_with('+')); assert!(!s.starts_with('.')); assert!(!s.ends_with('+')); assert!(!s.ends_with('-')); assert!(!s.ends_with('.')); assert!(!s.contains("++")); assert!(!s.contains("+-")); assert!(!s.contains("-+")); assert!(!s.contains("--")); assert!(!s.contains("-+")); assert!(!s.contains("+.")); assert!(!s.contains("-.")); assert!(!s.contains("e-")); assert!(!s.contains("E-")); assert!(s.chars().filter(|&c| c == '.').count() <= 1); assert!(s.chars().filter(|&c| c == '-').count() <= 1); assert!(s.chars().filter(|&c| c == '+').count() <= 1); let mut from_options = FromSciStringOptions::default(); from_options.set_base(options.get_base()); if let Some(x_from) = T::from_sci_string_with_options(&s, from_options) { if x == T::ZERO { assert_eq!(x_from, T::ZERO); } else { let base = T::wrapping_from(options.get_base()); let u_base = ::Output::from(options.get_base()); let scale = match options.get_size_options() { SciSizeOptions::Complete | SciSizeOptions::Scale(_) => None, SciSizeOptions::Precision(p) => { let log = x.unsigned_abs().floor_log_base(u_base); if log >= p { Some(log - p + 1) } else { None } } }; if let Some(scale) = scale { let pow = *powers .entry((base, scale)) .or_insert_with(|| base.pow(scale)); assert_eq!( x.round_to_multiple(pow, options.get_rounding_mode()).0, x_from ); } else { assert_eq!(x_from, x); } } } else { assert!(x.significant_bits() >= T::WIDTH - 1); } }); } #[test] fn to_sci_with_options_properties() { apply_fn_to_unsigneds!(to_sci_with_options_helper_unsigned); apply_fn_to_signeds!(to_sci_with_options_helper_signed); } malachite-base-0.4.16/tests/num/conversion/string/to_string.rs000064400000000000000000000703161046102023000225740ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::repeat_n; use malachite_base::num::arithmetic::traits::{SaturatingSubAssign, UnsignedAbs}; use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::string::to_string::{ digit_to_display_byte_lower, digit_to_display_byte_upper, BaseFmtWrapper, }; use malachite_base::num::conversion::traits::WrappingFrom; use malachite_base::strings::{ string_is_subset, ToBinaryString, ToLowerHexString, ToOctalString, ToUpperHexString, }; use malachite_base::test_util::generators::{ signed_gen, signed_gen_var_2, signed_unsigned_pair_gen_var_5, signed_unsigned_pair_gen_var_6, signed_unsigned_unsigned_triple_gen_var_3, unsigned_gen, unsigned_gen_var_7, unsigned_gen_var_8, unsigned_pair_gen_var_2, unsigned_pair_gen_var_8, unsigned_pair_gen_var_9, unsigned_triple_gen_var_6, }; use malachite_base::test_util::num::conversion::string::to_string::{ to_string_base_signed_naive, to_string_base_unsigned_naive, }; use std::cmp::max; use std::fmt::{Debug, Display}; use std::panic::catch_unwind; fn test_padding_unsigned(s: &str, s_padded: &str, width: usize) { assert!(s_padded.ends_with(&s)); assert!(s_padded.len() >= width); assert_eq!(s.len() >= width, s == s_padded); if s.len() < width { let diff = s_padded.len() - s.len(); assert!(s_padded[..diff].chars().all(|c| c == '0')); assert_eq!(&s_padded[diff..], s); } } fn test_padding_signed(mut s: &str, mut s_padded: &str, mut width: usize) { assert!(s_padded.len() >= width); assert_eq!(s.len() >= width, s == s_padded); let negative = s.starts_with('-'); assert_eq!(s_padded.starts_with('-'), negative); if negative { s = &s[1..]; s_padded = &s_padded[1..]; width.saturating_sub_assign(1); } test_padding_unsigned(s, s_padded, width); } #[test] fn test_digit_to_display_byte_lower() { let test_ok = |x, y| { assert_eq!(digit_to_display_byte_lower(x).unwrap(), y); }; test_ok(0, b'0'); test_ok(1, b'1'); test_ok(2, b'2'); test_ok(3, b'3'); test_ok(4, b'4'); test_ok(5, b'5'); test_ok(6, b'6'); test_ok(7, b'7'); test_ok(8, b'8'); test_ok(9, b'9'); test_ok(10, b'a'); test_ok(11, b'b'); test_ok(12, b'c'); test_ok(33, b'x'); test_ok(34, b'y'); test_ok(35, b'z'); let test_err = |x| { assert!(digit_to_display_byte_lower(x).is_none()); }; test_err(36); test_err(100); } #[test] fn digit_to_display_byte_lower_properties() { unsigned_gen().test_properties(|b| { assert_eq!(digit_to_display_byte_lower(b).is_some(), b < 36); }); unsigned_gen_var_7().test_properties(|b| { let display_byte = digit_to_display_byte_lower(b).unwrap(); assert!(display_byte.is_ascii_digit() || display_byte.is_ascii_lowercase()); let display_byte_upper = digit_to_display_byte_upper(b).unwrap(); assert_eq!(display_byte == display_byte_upper, b < 10); assert_eq!( char::from(display_byte).to_ascii_uppercase(), char::from(display_byte_upper) ); }); } #[test] fn test_digit_to_display_byte_upper() { let test_ok = |x, y| { assert_eq!(digit_to_display_byte_upper(x).unwrap(), y); }; test_ok(0, b'0'); test_ok(1, b'1'); test_ok(2, b'2'); test_ok(3, b'3'); test_ok(4, b'4'); test_ok(5, b'5'); test_ok(6, b'6'); test_ok(7, b'7'); test_ok(8, b'8'); test_ok(9, b'9'); test_ok(10, b'A'); test_ok(11, b'B'); test_ok(12, b'C'); test_ok(33, b'X'); test_ok(34, b'Y'); test_ok(35, b'Z'); let test_err = |x| { assert!(digit_to_display_byte_upper(x).is_none()); }; test_err(36); test_err(100); } #[test] fn digit_to_display_byte_upper_properties() { unsigned_gen().test_properties(|b| { assert_eq!( digit_to_display_byte_upper(b).is_some(), (0..36).contains(&b) ); }); unsigned_gen_var_7().test_properties(|b| { let display_byte = digit_to_display_byte_upper(b).unwrap(); assert!(display_byte.is_ascii_digit() || display_byte.is_ascii_uppercase()); let display_byte_lower = digit_to_display_byte_lower(b).unwrap(); assert_eq!(display_byte == display_byte_lower, b < 10); assert_eq!( char::from(display_byte).to_ascii_lowercase(), char::from(display_byte_lower) ); }); } #[test] pub fn test_to_string_base() { fn test_u(x: T, base: u8, out: &str) where BaseFmtWrapper: Debug + Display, u8: WrappingFrom, { assert_eq!(x.to_string_base(base), out); assert_eq!(to_string_base_unsigned_naive(x, base), out); assert_eq!(format!("{}", BaseFmtWrapper::new(x, base)), out); assert_eq!(format!("{:?}", BaseFmtWrapper::new(x, base)), out); assert_eq!(format!("{:00}", BaseFmtWrapper::new(x, base)), out); assert_eq!(format!("{:00?}", BaseFmtWrapper::new(x, base)), out); } test_u::(0, 2, "0"); test_u::(0, 3, "0"); test_u::(0, 10, "0"); test_u::(0, 16, "0"); test_u::(0, 17, "0"); test_u::(2, 3, "2"); test_u::(2, 10, "2"); test_u::(2, 16, "2"); test_u::(2, 17, "2"); test_u::(123, 8, "173"); test_u::(1000000, 10, "1000000"); test_u::(1000000, 20, "65000"); test_u::(1000000, 36, "lfls"); test_u::(1000, 2, "1111101000"); test_u::(1000, 3, "1101001"); test_u::(1000, 4, "33220"); test_u::(1000, 10, "1000"); test_u::(1000, 20, "2a0"); test_u::(1000, 36, "rs"); fn test_u_width(x: T, base: u8, width: usize, out: &str) where BaseFmtWrapper: Debug + Display, u8: WrappingFrom, { let s = x.to_string_base(base); assert_eq!( format!("{:0width$}", BaseFmtWrapper::new(x, base), width = width), out ); assert_eq!( format!("{:0width$?}", BaseFmtWrapper::new(x, base), width = width), out ); test_padding_unsigned(&s, out, width); } test_u_width::(0, 2, 0, "0"); test_u_width::(0, 2, 1, "0"); test_u_width::(0, 2, 2, "00"); test_u_width::(0, 2, 5, "00000"); test_u_width::(1000000, 36, 0, "lfls"); test_u_width::(1000000, 36, 1, "lfls"); test_u_width::(1000000, 36, 2, "lfls"); test_u_width::(1000000, 36, 3, "lfls"); test_u_width::(1000000, 36, 4, "lfls"); test_u_width::(1000000, 36, 5, "0lfls"); test_u_width::(1000000, 36, 6, "00lfls"); fn test_i(x: T, base: u8, out: &str) where BaseFmtWrapper: Debug + Display, u8: WrappingFrom<::Output>, ::Output: PrimitiveUnsigned, { assert_eq!(x.to_string_base(base), out); assert_eq!(to_string_base_signed_naive(x, base), out); assert_eq!(format!("{}", BaseFmtWrapper::new(x, base)), out); assert_eq!(format!("{:?}", BaseFmtWrapper::new(x, base)), out); assert_eq!(format!("{:00}", BaseFmtWrapper::new(x, base)), out); assert_eq!(format!("{:00?}", BaseFmtWrapper::new(x, base)), out); } test_i::(0, 2, "0"); test_i::(0, 3, "0"); test_i::(0, 10, "0"); test_i::(0, 16, "0"); test_i::(0, 17, "0"); test_i::(2, 3, "2"); test_i::(2, 10, "2"); test_i::(2, 16, "2"); test_i::(2, 17, "2"); test_i::(123, 8, "173"); test_i::(1000000, 10, "1000000"); test_i::(1000000, 20, "65000"); test_i::(1000000, 36, "lfls"); test_i::(1000, 2, "1111101000"); test_i::(1000, 3, "1101001"); test_i::(1000, 4, "33220"); test_i::(1000, 10, "1000"); test_i::(1000, 20, "2a0"); test_i::(1000, 36, "rs"); test_i::(-2, 3, "-2"); test_i::(-2, 10, "-2"); test_i::(-2, 16, "-2"); test_i::(-2, 17, "-2"); test_i::(-123, 8, "-173"); test_i::(-1000000, 10, "-1000000"); test_i::(-1000000, 20, "-65000"); test_i::(-1000000, 36, "-lfls"); test_i::(-1000, 2, "-1111101000"); test_i::(-1000, 3, "-1101001"); test_i::(-1000, 4, "-33220"); test_i::(-1000, 10, "-1000"); test_i::(-1000, 20, "-2a0"); test_i::(-1000, 36, "-rs"); fn test_i_width(x: T, base: u8, width: usize, out: &str) where BaseFmtWrapper: Debug + Display, u8: WrappingFrom, { let s = x.to_string_base(base); assert_eq!( format!("{:0width$}", BaseFmtWrapper::new(x, base), width = width), out ); assert_eq!( format!("{:0width$?}", BaseFmtWrapper::new(x, base), width = width), out ); test_padding_signed(&s, out, width); } test_i_width::(0, 2, 0, "0"); test_i_width::(0, 2, 1, "0"); test_i_width::(0, 2, 2, "00"); test_i_width::(0, 2, 5, "00000"); test_i_width::(1000000, 36, 0, "lfls"); test_i_width::(1000000, 36, 1, "lfls"); test_i_width::(1000000, 36, 2, "lfls"); test_i_width::(1000000, 36, 3, "lfls"); test_i_width::(1000000, 36, 4, "lfls"); test_i_width::(1000000, 36, 5, "0lfls"); test_i_width::(1000000, 36, 6, "00lfls"); test_i_width::(-1000000, 36, 0, "-lfls"); test_i_width::(-1000000, 36, 1, "-lfls"); test_i_width::(-1000000, 36, 2, "-lfls"); test_i_width::(-1000000, 36, 3, "-lfls"); test_i_width::(-1000000, 36, 4, "-lfls"); test_i_width::(-1000000, 36, 5, "-lfls"); test_i_width::(-1000000, 36, 6, "-0lfls"); } fn to_string_base_fail_helper() { assert_panic!(T::exact_from(100).to_string_base(0)); assert_panic!(T::exact_from(100).to_string_base(1)); assert_panic!(T::exact_from(100).to_string_base(37)); assert_panic!(T::exact_from(100).to_string_base(100)); } #[test] fn to_string_base_fail() { apply_fn_to_primitive_ints!(to_string_base_fail_helper); } fn to_string_base_helper_unsigned() where BaseFmtWrapper: Debug + Display, u8: WrappingFrom, { unsigned_pair_gen_var_8::().test_properties(|(x, base)| { let s = x.to_string_base(base); assert_eq!(to_string_base_unsigned_naive(x, base), s); assert_eq!(format!("{}", BaseFmtWrapper::new(x, base)), s); assert_eq!(format!("{:?}", BaseFmtWrapper::new(x, base)), s); assert_eq!(format!("{:00}", BaseFmtWrapper::new(x, base)), s); assert_eq!(format!("{:00?}", BaseFmtWrapper::new(x, base)), s); assert_eq!(x.to_string_base_upper(base), s.to_uppercase()); assert_eq!(T::from_string_base(base, &s).unwrap(), x); assert!(string_is_subset(&s, "0123456789abcdefghijklmnopqrstuvwxyz")); if x != T::ZERO { assert!(!s.starts_with('0')); } }); unsigned_gen::().test_properties(|x| { assert_eq!(x.to_string_base(10), x.to_string()); assert_eq!(x.to_string_base(2), x.to_binary_string()); assert_eq!(x.to_string_base(8), x.to_octal_string()); assert_eq!(x.to_string_base(16), x.to_lower_hex_string()); }); unsigned_gen_var_8().test_properties(|base| { assert_eq!(T::ZERO.to_string_base(base), "0"); assert_eq!(T::ONE.to_string_base(base), "1"); assert_eq!(T::exact_from(base).to_string_base(base), "10"); }); unsigned_triple_gen_var_6::().test_properties(|(x, base, width)| { let fx = BaseFmtWrapper::new(x, base); let s = x.to_string_base(base); let s_padded = format!("{fx:0width$}"); assert_eq!(format!("{fx:0width$?}"), s_padded); assert_eq!(T::from_string_base(base, &s).unwrap(), x); assert!(string_is_subset( &s_padded, "0123456789abcdefghijklmnopqrstuvwxyz" )); test_padding_unsigned(&s, &s_padded, width); }); unsigned_pair_gen_var_2::().test_properties(|(x, width)| { assert_eq!( format!("{:0width$}", BaseFmtWrapper::new(x, 10), width = width), format!("{x:0width$}") ); assert_eq!( format!("{:0width$}", BaseFmtWrapper::new(x, 2), width = width), format!("{x:0width$b}") ); assert_eq!( format!("{:0width$}", BaseFmtWrapper::new(x, 8), width = width), format!("{x:0width$o}") ); assert_eq!( format!("{:0width$}", BaseFmtWrapper::new(x, 16), width = width), format!("{x:0width$x}") ); }); unsigned_pair_gen_var_9::().test_properties(|(width, base)| { let s = format!( "{:0width$}", BaseFmtWrapper::new(T::ZERO, base), width = width ); assert_eq!(repeat_n('0', max(1, width)).collect::(), s); }); } fn to_string_base_helper_signed() where BaseFmtWrapper: Debug + Display, u8: WrappingFrom<::Output>, ::Output: PrimitiveUnsigned, { signed_unsigned_pair_gen_var_5::().test_properties(|(x, base)| { let s = x.to_string_base(base); assert_eq!(to_string_base_signed_naive(x, base), s); assert_eq!(format!("{}", BaseFmtWrapper::new(x, base)), s); assert_eq!(format!("{:?}", BaseFmtWrapper::new(x, base)), s); assert_eq!(format!("{:00}", BaseFmtWrapper::new(x, base)), s); assert_eq!(format!("{:00?}", BaseFmtWrapper::new(x, base)), s); assert_eq!(x.to_string_base_upper(base), s.to_uppercase()); assert_eq!(T::from_string_base(base, &s).unwrap(), x); assert!(string_is_subset( &s, "-0123456789abcdefghijklmnopqrstuvwxyz" )); assert_eq!(x < T::ZERO, s.starts_with('-')); assert!(!s.starts_with("-0")); if x != T::ZERO { assert!(!s.starts_with('0')); } }); signed_gen::().test_properties(|x| { assert_eq!(x.to_string_base(10), x.to_string()); }); signed_gen_var_2::().test_properties(|x| { assert_eq!(x.to_string_base(2), x.to_binary_string()); assert_eq!(x.to_string_base(8), x.to_octal_string()); assert_eq!(x.to_string_base(16), x.to_lower_hex_string()); }); unsigned_gen_var_8().test_properties(|base| { assert_eq!(T::ZERO.to_string_base(base), "0"); assert_eq!(T::ONE.to_string_base(base), "1"); assert_eq!(T::NEGATIVE_ONE.to_string_base(base), "-1"); assert_eq!(T::exact_from(base).to_string_base(base), "10"); }); signed_unsigned_unsigned_triple_gen_var_3::().test_properties( |(x, base, width)| { let fx = BaseFmtWrapper::new(x, base); let s = x.to_string_base(base); let s_padded = format!("{fx:0width$}"); assert!(s_padded.len() >= width); assert_eq!(s.len() >= width, s == s_padded); assert_eq!(format!("{fx:0width$?}"), s_padded); assert_eq!(T::from_string_base(base, &s).unwrap(), x); assert!(string_is_subset( &s_padded, "-0123456789abcdefghijklmnopqrstuvwxyz" )); test_padding_signed(&s, &s_padded, width); }, ); signed_unsigned_pair_gen_var_6::().test_properties(|(x, width)| { assert_eq!( format!("{:0width$}", BaseFmtWrapper::new(x, 10), width = width), format!("{x:0width$}") ); assert_eq!( format!("{:0width$}", BaseFmtWrapper::new(x, 2), width = width), format!("{x:0width$b}") ); assert_eq!( format!("{:0width$}", BaseFmtWrapper::new(x, 8), width = width), format!("{x:0width$o}") ); assert_eq!( format!("{:0width$}", BaseFmtWrapper::new(x, 16), width = width), format!("{x:0width$x}") ); }); unsigned_pair_gen_var_9::().test_properties(|(width, base)| { let s = format!( "{:0width$}", BaseFmtWrapper::new(T::ZERO, base), width = width ); assert_eq!(repeat_n('0', max(1, width)).collect::(), s); }); } #[test] fn to_string_base_properties() { apply_fn_to_unsigneds!(to_string_base_helper_unsigned); apply_fn_to_signeds!(to_string_base_helper_signed); } #[test] pub fn test_to_string_base_upper() { fn test_u(x: T, base: u8, out: &str) where BaseFmtWrapper: Debug + Display, { assert_eq!(x.to_string_base_upper(base), out); assert_eq!(format!("{:#}", BaseFmtWrapper::new(x, base)), out); assert_eq!(format!("{:#?}", BaseFmtWrapper::new(x, base)), out); } test_u::(0, 2, "0"); test_u::(0, 3, "0"); test_u::(0, 10, "0"); test_u::(0, 16, "0"); test_u::(0, 17, "0"); test_u::(2, 3, "2"); test_u::(2, 10, "2"); test_u::(2, 16, "2"); test_u::(2, 17, "2"); test_u::(123, 8, "173"); test_u::(1000000, 10, "1000000"); test_u::(1000000, 20, "65000"); test_u::(1000000, 36, "LFLS"); test_u::(1000, 2, "1111101000"); test_u::(1000, 3, "1101001"); test_u::(1000, 4, "33220"); test_u::(1000, 10, "1000"); test_u::(1000, 20, "2A0"); test_u::(1000, 36, "RS"); fn test_u_width(x: T, base: u8, width: usize, out: &str) where BaseFmtWrapper: Debug + Display, u8: WrappingFrom, { let s = x.to_string_base_upper(base); assert_eq!( format!("{:#0width$}", BaseFmtWrapper::new(x, base), width = width), out ); assert_eq!( format!("{:#0width$?}", BaseFmtWrapper::new(x, base), width = width), out ); test_padding_unsigned(&s, out, width); } test_u_width::(0, 2, 0, "0"); test_u_width::(0, 2, 1, "0"); test_u_width::(0, 2, 2, "00"); test_u_width::(0, 2, 5, "00000"); test_u_width::(1000000, 36, 0, "LFLS"); test_u_width::(1000000, 36, 1, "LFLS"); test_u_width::(1000000, 36, 2, "LFLS"); test_u_width::(1000000, 36, 3, "LFLS"); test_u_width::(1000000, 36, 4, "LFLS"); test_u_width::(1000000, 36, 5, "0LFLS"); test_u_width::(1000000, 36, 6, "00LFLS"); fn test_i(x: T, base: u8, out: &str) where BaseFmtWrapper: Debug + Display, { assert_eq!(x.to_string_base_upper(base), out); assert_eq!(format!("{:#}", BaseFmtWrapper::new(x, base)), out); assert_eq!(format!("{:#?}", BaseFmtWrapper::new(x, base)), out); } test_i::(0, 2, "0"); test_i::(0, 3, "0"); test_i::(0, 10, "0"); test_i::(0, 16, "0"); test_i::(0, 17, "0"); test_i::(2, 3, "2"); test_i::(2, 10, "2"); test_i::(2, 16, "2"); test_i::(2, 17, "2"); test_i::(123, 8, "173"); test_i::(1000000, 10, "1000000"); test_i::(1000000, 20, "65000"); test_i::(1000000, 36, "LFLS"); test_i::(1000, 2, "1111101000"); test_i::(1000, 3, "1101001"); test_i::(1000, 4, "33220"); test_i::(1000, 10, "1000"); test_i::(1000, 20, "2A0"); test_i::(1000, 36, "RS"); test_i::(-2, 3, "-2"); test_i::(-2, 10, "-2"); test_i::(-2, 16, "-2"); test_i::(-2, 17, "-2"); test_i::(-123, 8, "-173"); test_i::(-1000000, 10, "-1000000"); test_i::(-1000000, 20, "-65000"); test_i::(-1000000, 36, "-LFLS"); test_i::(-1000, 2, "-1111101000"); test_i::(-1000, 3, "-1101001"); test_i::(-1000, 4, "-33220"); test_i::(-1000, 10, "-1000"); test_i::(-1000, 20, "-2A0"); test_i::(-1000, 36, "-RS"); fn test_i_width(x: T, base: u8, width: usize, out: &str) where BaseFmtWrapper: Debug + Display, u8: WrappingFrom, { let s = x.to_string_base_upper(base); assert_eq!( format!("{:#0width$}", BaseFmtWrapper::new(x, base), width = width), out ); assert_eq!( format!("{:#0width$?}", BaseFmtWrapper::new(x, base), width = width), out ); test_padding_signed(&s, out, width); } test_i_width::(0, 2, 0, "0"); test_i_width::(0, 2, 1, "0"); test_i_width::(0, 2, 2, "00"); test_i_width::(0, 2, 5, "00000"); test_i_width::(1000000, 36, 0, "LFLS"); test_i_width::(1000000, 36, 1, "LFLS"); test_i_width::(1000000, 36, 2, "LFLS"); test_i_width::(1000000, 36, 3, "LFLS"); test_i_width::(1000000, 36, 4, "LFLS"); test_i_width::(1000000, 36, 5, "0LFLS"); test_i_width::(1000000, 36, 6, "00LFLS"); test_i_width::(-1000000, 36, 0, "-LFLS"); test_i_width::(-1000000, 36, 1, "-LFLS"); test_i_width::(-1000000, 36, 2, "-LFLS"); test_i_width::(-1000000, 36, 3, "-LFLS"); test_i_width::(-1000000, 36, 4, "-LFLS"); test_i_width::(-1000000, 36, 5, "-LFLS"); test_i_width::(-1000000, 36, 6, "-0LFLS"); } fn to_string_base_upper_fail_helper() { assert_panic!(T::exact_from(100).to_string_base_upper(0)); assert_panic!(T::exact_from(100).to_string_base_upper(1)); assert_panic!(T::exact_from(100).to_string_base_upper(37)); assert_panic!(T::exact_from(100).to_string_base_upper(100)); } #[test] fn to_string_base_upper_fail() { apply_fn_to_primitive_ints!(to_string_base_upper_fail_helper); } fn to_string_base_upper_helper_unsigned() where BaseFmtWrapper: Debug + Display, { unsigned_pair_gen_var_8::().test_properties(|(x, base)| { let s = x.to_string_base_upper(base); assert_eq!(format!("{:#}", BaseFmtWrapper::new(x, base)), s); assert_eq!(format!("{:#?}", BaseFmtWrapper::new(x, base)), s); assert_eq!(format!("{:#00}", BaseFmtWrapper::new(x, base)), s); assert_eq!(x.to_string_base(base), s.to_lowercase()); assert_eq!(T::from_string_base(base, &s).unwrap(), x); assert!(string_is_subset(&s, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ")); if x != T::ZERO { assert!(!s.starts_with('0')); } }); unsigned_gen::().test_properties(|x| { assert_eq!(x.to_string_base_upper(10), x.to_string()); assert_eq!(x.to_string_base_upper(2), x.to_binary_string()); assert_eq!(x.to_string_base_upper(8), x.to_octal_string()); assert_eq!(x.to_string_base_upper(16), x.to_upper_hex_string()); }); unsigned_gen_var_8().test_properties(|base| { assert_eq!(T::ZERO.to_string_base_upper(base), "0"); assert_eq!(T::ONE.to_string_base_upper(base), "1"); assert_eq!(T::exact_from(base).to_string_base_upper(base), "10"); }); unsigned_triple_gen_var_6::().test_properties(|(x, base, width)| { let fx = BaseFmtWrapper::new(x, base); let s = x.to_string_base_upper(base); let s_padded = format!("{fx:#0width$}"); assert_eq!(format!("{fx:#0width$?}"), s_padded); assert_eq!(T::from_string_base(base, &s).unwrap(), x); assert!(string_is_subset( &s_padded, "01234567890123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" )); test_padding_unsigned(&s, &s_padded, width); }); unsigned_pair_gen_var_2::().test_properties(|(x, width)| { assert_eq!( format!("{:#0width$}", BaseFmtWrapper::new(x, 10), width = width), format!("{x:0width$}") ); assert_eq!( format!("{:#0width$}", BaseFmtWrapper::new(x, 2), width = width), format!("{x:0width$b}") ); assert_eq!( format!("{:#0width$}", BaseFmtWrapper::new(x, 8), width = width), format!("{x:0width$o}") ); assert_eq!( format!("{:#0width$}", BaseFmtWrapper::new(x, 16), width = width), format!("{x:0width$X}") ); }); unsigned_pair_gen_var_9::().test_properties(|(width, base)| { let s = format!( "{:#0width$}", BaseFmtWrapper::new(T::ZERO, base), width = width ); assert_eq!(repeat_n('0', max(1, width)).collect::(), s); }); } fn to_string_base_upper_helper_signed() where BaseFmtWrapper: Debug + Display, { signed_unsigned_pair_gen_var_5::().test_properties(|(x, base)| { let s = x.to_string_base_upper(base); assert_eq!(format!("{:#}", BaseFmtWrapper::new(x, base)), s); assert_eq!(format!("{:#?}", BaseFmtWrapper::new(x, base)), s); assert_eq!(x.to_string_base(base), s.to_lowercase()); assert_eq!(T::from_string_base(base, &s).unwrap(), x); assert!(string_is_subset( &s, "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" )); assert_eq!(x < T::ZERO, s.starts_with('-')); assert!(!s.starts_with("-0")); if x != T::ZERO { assert!(!s.starts_with('0')); } }); signed_gen::().test_properties(|x| { assert_eq!(x.to_string_base_upper(10), x.to_string()); }); signed_gen_var_2::().test_properties(|x| { assert_eq!(x.to_string_base_upper(2), x.to_binary_string()); assert_eq!(x.to_string_base_upper(8), x.to_octal_string()); assert_eq!(x.to_string_base_upper(16), x.to_upper_hex_string()); }); unsigned_gen_var_8().test_properties(|base| { assert_eq!(T::ZERO.to_string_base_upper(base), "0"); assert_eq!(T::ONE.to_string_base_upper(base), "1"); assert_eq!(T::NEGATIVE_ONE.to_string_base_upper(base), "-1"); assert_eq!(T::exact_from(base).to_string_base_upper(base), "10"); }); signed_unsigned_unsigned_triple_gen_var_3::().test_properties( |(x, base, width)| { let fx = BaseFmtWrapper::new(x, base); let s = x.to_string_base_upper(base); let s_padded = format!("{fx:#0width$}"); assert!(s_padded.len() >= width); assert_eq!(s.len() >= width, s == s_padded); assert_eq!(format!("{fx:#0width$?}"), s_padded); assert_eq!(T::from_string_base(base, &s).unwrap(), x); assert!(string_is_subset( &s_padded, "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" )); test_padding_signed(&s, &s_padded, width); }, ); signed_unsigned_pair_gen_var_6::().test_properties(|(x, width)| { assert_eq!( format!("{:#0width$}", BaseFmtWrapper::new(x, 10), width = width), format!("{x:0width$}") ); assert_eq!( format!("{:#0width$}", BaseFmtWrapper::new(x, 2), width = width), format!("{x:0width$b}") ); assert_eq!( format!("{:#0width$}", BaseFmtWrapper::new(x, 8), width = width), format!("{x:0width$o}") ); assert_eq!( format!("{:#0width$}", BaseFmtWrapper::new(x, 16), width = width), format!("{x:0width$X}") ); }); unsigned_pair_gen_var_9::().test_properties(|(width, base)| { let s = format!( "{:#0width$}", BaseFmtWrapper::new(T::ZERO, base), width = width ); assert_eq!(repeat_n('0', max(1, width)).collect::(), s); }); } #[test] fn to_string_base_upper_properties() { apply_fn_to_unsigneds!(to_string_base_upper_helper_unsigned); apply_fn_to_signeds!(to_string_base_upper_helper_signed); } malachite-base-0.4.16/tests/num/exhaustive/exhaustive_finite_primitive_floats.rs000064400000000000000000000032231046102023000264320ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::exhaustive::exhaustive_finite_primitive_floats; use malachite_base::test_util::num::exhaustive::exhaustive_primitive_floats_helper_helper; fn exhaustive_finite_primitive_floats_helper(out: &[T]) { exhaustive_primitive_floats_helper_helper(exhaustive_finite_primitive_floats::(), out); } #[test] fn test_exhaustive_finite_primitive_floats() { exhaustive_finite_primitive_floats_helper::(&[ 0.0, -0.0, 1.0, -1.0, 2.0, -2.0, 1.5, -1.5, 0.5, -0.5, 1.25, -1.25, 3.0, -3.0, 1.75, -1.75, 4.0, -4.0, 1.125, -1.125, 2.5, -2.5, 1.375, -1.375, 0.75, -0.75, 1.625, -1.625, 3.5, -3.5, 1.875, -1.875, 0.25, -0.25, 1.0625, -1.0625, 2.25, -2.25, 1.1875, -1.1875, 0.625, -0.625, 1.3125, -1.3125, 2.75, -2.75, 1.4375, -1.4375, 6.0, -6.0, ]); exhaustive_finite_primitive_floats_helper::(&[ 0.0, -0.0, 1.0, -1.0, 2.0, -2.0, 1.5, -1.5, 0.5, -0.5, 1.25, -1.25, 3.0, -3.0, 1.75, -1.75, 4.0, -4.0, 1.125, -1.125, 2.5, -2.5, 1.375, -1.375, 0.75, -0.75, 1.625, -1.625, 3.5, -3.5, 1.875, -1.875, 0.25, -0.25, 1.0625, -1.0625, 2.25, -2.25, 1.1875, -1.1875, 0.625, -0.625, 1.3125, -1.3125, 2.75, -2.75, 1.4375, -1.4375, 6.0, -6.0, ]); } malachite-base-0.4.16/tests/num/exhaustive/exhaustive_natural_signeds.rs000064400000000000000000000041141046102023000246760ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::num::arithmetic::traits::PowerOf2; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::conversion::traits::ExactFrom; use malachite_base::num::exhaustive::{exhaustive_natural_signeds, exhaustive_negative_signeds}; fn exhaustive_natural_signeds_helper() where i8: ExactFrom, { let xs = exhaustive_natural_signeds::() .map(i8::exact_from) .take(20) .collect_vec(); assert_eq!( xs, &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] ); assert!(itertools::equal( xs, exhaustive_negative_signeds::() .map(|x| !i8::exact_from(x)) .take(20) )); } fn exhaustive_natural_signeds_long_helper(last_20: &[T]) { let expected_len = usize::power_of_2(T::WIDTH - 1); let xs = exhaustive_natural_signeds::(); assert_eq!(xs.clone().count(), expected_len); assert_eq!(xs.skip(expected_len - 20).collect_vec(), last_20); } #[test] fn test_exhaustive_natural_signeds() { apply_fn_to_signeds!(exhaustive_natural_signeds_helper); exhaustive_natural_signeds_long_helper::(&[ 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, ]); exhaustive_natural_signeds_long_helper::(&[ 32748, 32749, 32750, 32751, 0x7ff0, 0x7ff1, 0x7ff2, 0x7ff3, 0x7ff4, 0x7ff5, 0x7ff6, 0x7ff7, 0x7ff8, 0x7ff9, 0x7ffa, 0x7ffb, 0x7ffc, 0x7ffd, i16::MAX - 1, i16::MAX, ]); } malachite-base-0.4.16/tests/num/exhaustive/exhaustive_negative_finite_primitive_floats.rs000064400000000000000000000035661046102023000303260ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::exhaustive::exhaustive_negative_finite_primitive_floats; use malachite_base::test_util::num::exhaustive::exhaustive_primitive_floats_helper_helper; fn exhaustive_negative_finite_primitive_floats_helper(out: &[T]) { exhaustive_primitive_floats_helper_helper( exhaustive_negative_finite_primitive_floats::(), out, ); } #[test] fn test_exhaustive_negative_finite_primitive_floats() { exhaustive_negative_finite_primitive_floats_helper::(&[ -1.0, -2.0, -1.5, -0.5, -1.25, -3.0, -1.75, -4.0, -1.125, -2.5, -1.375, -0.75, -1.625, -3.5, -1.875, -0.25, -1.0625, -2.25, -1.1875, -0.625, -1.3125, -2.75, -1.4375, -6.0, -1.5625, -3.25, -1.6875, -0.875, -1.8125, -3.75, -1.9375, -8.0, -1.03125, -2.125, -1.09375, -0.5625, -1.15625, -2.375, -1.21875, -5.0, -1.28125, -2.625, -1.34375, -0.6875, -1.40625, -2.875, -1.46875, -0.375, -1.53125, -3.125, ]); exhaustive_negative_finite_primitive_floats_helper::(&[ -1.0, -2.0, -1.5, -0.5, -1.25, -3.0, -1.75, -4.0, -1.125, -2.5, -1.375, -0.75, -1.625, -3.5, -1.875, -0.25, -1.0625, -2.25, -1.1875, -0.625, -1.3125, -2.75, -1.4375, -6.0, -1.5625, -3.25, -1.6875, -0.875, -1.8125, -3.75, -1.9375, -8.0, -1.03125, -2.125, -1.09375, -0.5625, -1.15625, -2.375, -1.21875, -5.0, -1.28125, -2.625, -1.34375, -0.6875, -1.40625, -2.875, -1.46875, -0.375, -1.53125, -3.125, ]); } malachite-base-0.4.16/tests/num/exhaustive/exhaustive_negative_primitive_floats.rs000064400000000000000000000051371046102023000267640ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::traits::NegativeInfinity; use malachite_base::num::exhaustive::exhaustive_negative_primitive_floats; use malachite_base::test_util::num::exhaustive::exhaustive_primitive_floats_helper_helper; fn exhaustive_negative_primitive_floats_helper(out: &[T]) { exhaustive_primitive_floats_helper_helper(exhaustive_negative_primitive_floats::(), out); } #[test] fn test_exhaustive_negative_primitive_floats() { exhaustive_negative_primitive_floats_helper::(&[ f32::NEGATIVE_INFINITY, -1.0, -2.0, -1.5, -0.5, -1.25, -3.0, -1.75, -4.0, -1.125, -2.5, -1.375, -0.75, -1.625, -3.5, -1.875, -0.25, -1.0625, -2.25, -1.1875, -0.625, -1.3125, -2.75, -1.4375, -6.0, -1.5625, -3.25, -1.6875, -0.875, -1.8125, -3.75, -1.9375, -8.0, -1.03125, -2.125, -1.09375, -0.5625, -1.15625, -2.375, -1.21875, -5.0, -1.28125, -2.625, -1.34375, -0.6875, -1.40625, -2.875, -1.46875, -0.375, -1.53125, ]); exhaustive_negative_primitive_floats_helper::(&[ f64::NEGATIVE_INFINITY, -1.0, -2.0, -1.5, -0.5, -1.25, -3.0, -1.75, -4.0, -1.125, -2.5, -1.375, -0.75, -1.625, -3.5, -1.875, -0.25, -1.0625, -2.25, -1.1875, -0.625, -1.3125, -2.75, -1.4375, -6.0, -1.5625, -3.25, -1.6875, -0.875, -1.8125, -3.75, -1.9375, -8.0, -1.03125, -2.125, -1.09375, -0.5625, -1.15625, -2.375, -1.21875, -5.0, -1.28125, -2.625, -1.34375, -0.6875, -1.40625, -2.875, -1.46875, -0.375, -1.53125, ]); } malachite-base-0.4.16/tests/num/exhaustive/exhaustive_negative_signeds.rs000064400000000000000000000042611046102023000250350ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::num::arithmetic::traits::PowerOf2; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::conversion::traits::ExactFrom; use malachite_base::num::exhaustive::{exhaustive_natural_signeds, exhaustive_negative_signeds}; fn exhaustive_negative_signeds_helper() where i8: ExactFrom, { let xs = exhaustive_negative_signeds::() .map(i8::exact_from) .take(20) .collect_vec(); assert_eq!( xs, &[ -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16, -17, -18, -19, -20 ] ); assert!(itertools::equal( xs, exhaustive_natural_signeds::() .map(|x| !i8::exact_from(x)) .take(20) )); } fn exhaustive_negative_signeds_long_helper(last_20: &[T]) { let expected_len = usize::power_of_2(T::WIDTH - 1); let xs = exhaustive_negative_signeds::(); assert_eq!(xs.clone().count(), expected_len); assert_eq!(xs.skip(expected_len - 20).collect_vec(), last_20); } #[test] fn test_exhaustive_negative_signeds() { apply_fn_to_signeds!(exhaustive_negative_signeds_helper); exhaustive_negative_signeds_long_helper::(&[ -109, -110, -111, -112, -113, -114, -115, -116, -117, -118, -119, -120, -121, -122, -123, -124, -125, -126, -127, -128, ]); exhaustive_negative_signeds_long_helper::(&[ -32749, -32750, -32751, -0x7ff0, -0x7ff1, -0x7ff2, -0x7ff3, -0x7ff4, -0x7ff5, -0x7ff6, -0x7ff7, -0x7ff8, -0x7ff9, -0x7ffa, -0x7ffb, -0x7ffc, -0x7ffd, -0x7ffe, i16::MIN + 1, i16::MIN, ]); } malachite-base-0.4.16/tests/num/exhaustive/exhaustive_nonzero_finite_primitive_floats.rs000064400000000000000000000033461046102023000302120ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::exhaustive::exhaustive_nonzero_finite_primitive_floats; use malachite_base::test_util::num::exhaustive::exhaustive_primitive_floats_helper_helper; fn exhaustive_nonzero_finite_primitive_floats_helper(out: &[T]) { exhaustive_primitive_floats_helper_helper( exhaustive_nonzero_finite_primitive_floats::(), out, ); } #[test] fn test_exhaustive_nonzero_finite_primitive_floats() { exhaustive_nonzero_finite_primitive_floats_helper::(&[ 1.0, -1.0, 2.0, -2.0, 1.5, -1.5, 0.5, -0.5, 1.25, -1.25, 3.0, -3.0, 1.75, -1.75, 4.0, -4.0, 1.125, -1.125, 2.5, -2.5, 1.375, -1.375, 0.75, -0.75, 1.625, -1.625, 3.5, -3.5, 1.875, -1.875, 0.25, -0.25, 1.0625, -1.0625, 2.25, -2.25, 1.1875, -1.1875, 0.625, -0.625, 1.3125, -1.3125, 2.75, -2.75, 1.4375, -1.4375, 6.0, -6.0, 1.5625, -1.5625, ]); exhaustive_nonzero_finite_primitive_floats_helper::(&[ 1.0, -1.0, 2.0, -2.0, 1.5, -1.5, 0.5, -0.5, 1.25, -1.25, 3.0, -3.0, 1.75, -1.75, 4.0, -4.0, 1.125, -1.125, 2.5, -2.5, 1.375, -1.375, 0.75, -0.75, 1.625, -1.625, 3.5, -3.5, 1.875, -1.875, 0.25, -0.25, 1.0625, -1.0625, 2.25, -2.25, 1.1875, -1.1875, 0.625, -0.625, 1.3125, -1.3125, 2.75, -2.75, 1.4375, -1.4375, 6.0, -6.0, 1.5625, -1.5625, ]); } malachite-base-0.4.16/tests/num/exhaustive/exhaustive_nonzero_finite_primitive_floats_in_range.rs000064400000000000000000000213131046102023000320460ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::exhaustive::exhaustive_nonzero_finite_primitive_floats_in_range; use malachite_base::test_util::num::exhaustive::exhaustive_primitive_floats_helper_helper; use std::panic::catch_unwind; fn exhaustive_nonzero_finite_primitive_floats_in_range_helper( a: T, b: T, out: &[T], ) { exhaustive_primitive_floats_helper_helper( exhaustive_nonzero_finite_primitive_floats_in_range::(a, b), out, ); } #[test] fn test_exhaustive_nonzero_finite_primitive_floats_in_range() { exhaustive_nonzero_finite_primitive_floats_in_range_helper::( core::f32::consts::E, core::f32::consts::PI, &[ 3.0, 2.75, 2.875, 3.125, 2.8125, 2.9375, 3.0625, 2.71875, 2.78125, 2.84375, 2.90625, 2.96875, 3.03125, 3.09375, 2.734375, 2.765625, 2.796875, 2.828125, 2.859375, 2.890625, 2.921875, 2.953125, 2.984375, 3.015625, 3.046875, 3.078125, 3.109375, 3.140625, 2.7265625, 2.7421875, 2.7578125, 2.7734375, 2.7890625, 2.8046875, 2.8203125, 2.8359375, 2.8515625, 2.8671875, 2.8828125, 2.8984375, 2.9140625, 2.9296875, 2.9453125, 2.9609375, 2.9765625, 2.9921875, 3.0078125, 3.0234375, 3.0390625, 3.0546875, ], ); exhaustive_nonzero_finite_primitive_floats_in_range_helper::(5.0, 5.0, &[5.0]); exhaustive_nonzero_finite_primitive_floats_in_range_helper::( 1.0, 6.0, &[ 1.0, 2.0, 1.5, 4.0, 1.25, 3.0, 1.75, 1.125, 1.375, 2.5, 1.625, 6.0, 1.875, 3.5, 1.0625, 2.25, 1.1875, 2.75, 1.3125, 5.0, 1.4375, 3.25, 1.5625, 1.6875, 1.8125, 3.75, 1.9375, 4.5, 1.03125, 2.125, 1.09375, 5.5, 1.15625, 2.375, 1.21875, 4.25, 1.28125, 2.625, 1.34375, 1.40625, 1.46875, 2.875, 1.53125, 4.75, 1.59375, 3.125, 1.65625, 3.375, 1.71875, 3.625, ], ); exhaustive_nonzero_finite_primitive_floats_in_range_helper::( -6.0, -1.0, &[ -1.0, -2.0, -1.5, -4.0, -1.25, -3.0, -1.75, -1.125, -1.375, -2.5, -1.625, -6.0, -1.875, -3.5, -1.0625, -2.25, -1.1875, -2.75, -1.3125, -5.0, -1.4375, -3.25, -1.5625, -1.6875, -1.8125, -3.75, -1.9375, -4.5, -1.03125, -2.125, -1.09375, -5.5, -1.15625, -2.375, -1.21875, -4.25, -1.28125, -2.625, -1.34375, -1.40625, -1.46875, -2.875, -1.53125, -4.75, -1.59375, -3.125, -1.65625, -3.375, -1.71875, -3.625, ], ); exhaustive_nonzero_finite_primitive_floats_in_range_helper::( -6.0, 6.0, &[ 1.0, -1.0, 2.0, -2.0, 1.5, -1.5, 0.5, -0.5, 1.25, -1.25, 3.0, -3.0, 1.75, -1.75, 4.0, -4.0, 1.125, -1.125, 2.5, -2.5, 1.375, -1.375, 0.75, -0.75, 1.625, -1.625, 3.5, -3.5, 1.875, -1.875, 0.25, -0.25, 1.0625, -1.0625, 2.25, -2.25, 1.1875, -1.1875, 0.625, -0.625, 1.3125, -1.3125, 2.75, -2.75, 1.4375, -1.4375, 6.0, -6.0, 1.5625, -1.5625, ], ); exhaustive_nonzero_finite_primitive_floats_in_range_helper::( -0.1, 10.0, &[ 1.0, -0.0625, 2.0, -0.03125, 1.5, -0.09375, 0.5, -0.015625, 1.25, -0.078125, 3.0, -0.046875, 1.75, -0.0703125, 4.0, -0.0078125, 1.125, -0.0859375, 2.5, -0.0390625, 1.375, -0.06640625, 0.75, -0.0234375, 1.625, -0.07421875, 3.5, -0.0546875, 1.875, -0.08203125, 0.25, -0.00390625, 1.0625, -0.08984375, 2.25, -0.03515625, 1.1875, -0.09765625, 0.625, -0.01953125, 1.3125, -0.064453125, 2.75, -0.04296875, 1.4375, -0.068359375, 6.0, -0.01171875, 1.5625, -0.072265625, ], ); exhaustive_nonzero_finite_primitive_floats_in_range_helper::( core::f64::consts::E, core::f64::consts::PI, &[ 3.0, 2.75, 2.875, 3.125, 2.8125, 2.9375, 3.0625, 2.71875, 2.78125, 2.84375, 2.90625, 2.96875, 3.03125, 3.09375, 2.734375, 2.765625, 2.796875, 2.828125, 2.859375, 2.890625, 2.921875, 2.953125, 2.984375, 3.015625, 3.046875, 3.078125, 3.109375, 3.140625, 2.7265625, 2.7421875, 2.7578125, 2.7734375, 2.7890625, 2.8046875, 2.8203125, 2.8359375, 2.8515625, 2.8671875, 2.8828125, 2.8984375, 2.9140625, 2.9296875, 2.9453125, 2.9609375, 2.9765625, 2.9921875, 3.0078125, 3.0234375, 3.0390625, 3.0546875, ], ); exhaustive_nonzero_finite_primitive_floats_in_range_helper::(5.0, 5.0, &[5.0]); exhaustive_nonzero_finite_primitive_floats_in_range_helper::( 1.0, 6.0, &[ 1.0, 2.0, 1.5, 4.0, 1.25, 3.0, 1.75, 1.125, 1.375, 2.5, 1.625, 6.0, 1.875, 3.5, 1.0625, 2.25, 1.1875, 2.75, 1.3125, 5.0, 1.4375, 3.25, 1.5625, 1.6875, 1.8125, 3.75, 1.9375, 4.5, 1.03125, 2.125, 1.09375, 5.5, 1.15625, 2.375, 1.21875, 4.25, 1.28125, 2.625, 1.34375, 1.40625, 1.46875, 2.875, 1.53125, 4.75, 1.59375, 3.125, 1.65625, 3.375, 1.71875, 3.625, ], ); exhaustive_nonzero_finite_primitive_floats_in_range_helper::( -6.0, -1.0, &[ -1.0, -2.0, -1.5, -4.0, -1.25, -3.0, -1.75, -1.125, -1.375, -2.5, -1.625, -6.0, -1.875, -3.5, -1.0625, -2.25, -1.1875, -2.75, -1.3125, -5.0, -1.4375, -3.25, -1.5625, -1.6875, -1.8125, -3.75, -1.9375, -4.5, -1.03125, -2.125, -1.09375, -5.5, -1.15625, -2.375, -1.21875, -4.25, -1.28125, -2.625, -1.34375, -1.40625, -1.46875, -2.875, -1.53125, -4.75, -1.59375, -3.125, -1.65625, -3.375, -1.71875, -3.625, ], ); exhaustive_nonzero_finite_primitive_floats_in_range_helper::( -6.0, 6.0, &[ 1.0, -1.0, 2.0, -2.0, 1.5, -1.5, 0.5, -0.5, 1.25, -1.25, 3.0, -3.0, 1.75, -1.75, 4.0, -4.0, 1.125, -1.125, 2.5, -2.5, 1.375, -1.375, 0.75, -0.75, 1.625, -1.625, 3.5, -3.5, 1.875, -1.875, 0.25, -0.25, 1.0625, -1.0625, 2.25, -2.25, 1.1875, -1.1875, 0.625, -0.625, 1.3125, -1.3125, 2.75, -2.75, 1.4375, -1.4375, 6.0, -6.0, 1.5625, -1.5625, ], ); exhaustive_nonzero_finite_primitive_floats_in_range_helper::( -0.1, 10.0, &[ 1.0, -0.0625, 2.0, -0.03125, 1.5, -0.09375, 0.5, -0.015625, 1.25, -0.078125, 3.0, -0.046875, 1.75, -0.0703125, 4.0, -0.0078125, 1.125, -0.0859375, 2.5, -0.0390625, 1.375, -0.06640625, 0.75, -0.0234375, 1.625, -0.07421875, 3.5, -0.0546875, 1.875, -0.08203125, 0.25, -0.00390625, 1.0625, -0.08984375, 2.25, -0.03515625, 1.1875, -0.09765625, 0.625, -0.01953125, 1.3125, -0.064453125, 2.75, -0.04296875, 1.4375, -0.068359375, 6.0, -0.01171875, 1.5625, -0.072265625, ], ); } fn exhaustive_nonzero_finite_primitive_floats_in_range_fail_helper() { assert_panic!(exhaustive_nonzero_finite_primitive_floats_in_range::( T::from(1.2), T::from(1.1), )); assert_panic!(exhaustive_nonzero_finite_primitive_floats_in_range::( T::ONE, T::INFINITY, )); assert_panic!(exhaustive_nonzero_finite_primitive_floats_in_range::( T::ONE, T::NAN, )); } #[test] fn exhaustive_nonzero_finite_primitive_floats_in_range_fail() { apply_fn_to_primitive_floats!(exhaustive_nonzero_finite_primitive_floats_in_range_fail_helper); } malachite-base-0.4.16/tests/num/exhaustive/exhaustive_nonzero_primitive_floats.rs000064400000000000000000000047531046102023000266570ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::traits::NegativeInfinity; use malachite_base::num::exhaustive::exhaustive_nonzero_primitive_floats; use malachite_base::test_util::num::exhaustive::exhaustive_primitive_floats_helper_helper; fn exhaustive_nonzero_primitive_floats_helper(out: &[T]) { exhaustive_primitive_floats_helper_helper(exhaustive_nonzero_primitive_floats::(), out); } #[test] fn test_exhaustive_nonzero_primitive_floats() { exhaustive_nonzero_primitive_floats_helper::(&[ f32::INFINITY, f32::NEGATIVE_INFINITY, 1.0, -1.0, 2.0, -2.0, 1.5, -1.5, 0.5, -0.5, 1.25, -1.25, 3.0, -3.0, 1.75, -1.75, 4.0, -4.0, 1.125, -1.125, 2.5, -2.5, 1.375, -1.375, 0.75, -0.75, 1.625, -1.625, 3.5, -3.5, 1.875, -1.875, 0.25, -0.25, 1.0625, -1.0625, 2.25, -2.25, 1.1875, -1.1875, 0.625, -0.625, 1.3125, -1.3125, 2.75, -2.75, 1.4375, -1.4375, 6.0, -6.0, ]); exhaustive_nonzero_primitive_floats_helper::(&[ f64::INFINITY, f64::NEGATIVE_INFINITY, 1.0, -1.0, 2.0, -2.0, 1.5, -1.5, 0.5, -0.5, 1.25, -1.25, 3.0, -3.0, 1.75, -1.75, 4.0, -4.0, 1.125, -1.125, 2.5, -2.5, 1.375, -1.375, 0.75, -0.75, 1.625, -1.625, 3.5, -3.5, 1.875, -1.875, 0.25, -0.25, 1.0625, -1.0625, 2.25, -2.25, 1.1875, -1.1875, 0.625, -0.625, 1.3125, -1.3125, 2.75, -2.75, 1.4375, -1.4375, 6.0, -6.0, ]); } malachite-base-0.4.16/tests/num/exhaustive/exhaustive_nonzero_signeds.rs000064400000000000000000000036561046102023000247340ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::num::arithmetic::traits::PowerOf2; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::conversion::traits::ExactFrom; use malachite_base::num::exhaustive::exhaustive_nonzero_signeds; fn exhaustive_nonzero_signeds_helper() where i8: ExactFrom, { assert_eq!( exhaustive_nonzero_signeds::() .map(i8::exact_from) .take(20) .collect_vec(), &[1, -1, 2, -2, 3, -3, 4, -4, 5, -5, 6, -6, 7, -7, 8, -8, 9, -9, 10, -10] ); } fn exhaustive_nonzero_signeds_long_helper(last_20: &[T]) { let expected_len = usize::power_of_2(T::WIDTH) - 1; let xs = exhaustive_nonzero_signeds::(); assert_eq!(xs.clone().count(), expected_len); assert_eq!(xs.skip(expected_len - 20).collect_vec(), last_20); } #[test] fn test_exhaustive_nonzero_signeds() { apply_fn_to_signeds!(exhaustive_nonzero_signeds_helper); exhaustive_nonzero_signeds_long_helper::(&[ -118, 119, -119, 120, -120, 121, -121, 122, -122, 123, -123, 124, -124, 125, -125, 126, -126, 127, -127, -128, ]); exhaustive_nonzero_signeds_long_helper::(&[ -0x7ff6, 0x7ff7, -0x7ff7, 0x7ff8, -0x7ff8, 0x7ff9, -0x7ff9, 0x7ffa, -0x7ffa, 0x7ffb, -0x7ffb, 0x7ffc, -0x7ffc, 0x7ffd, -0x7ffd, i16::MAX - 1, -0x7ffe, i16::MAX, i16::MIN + 1, i16::MIN, ]); } malachite-base-0.4.16/tests/num/exhaustive/exhaustive_positive_finite_primitive_floats.rs000064400000000000000000000034021046102023000303530ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::exhaustive::exhaustive_positive_finite_primitive_floats; use malachite_base::test_util::num::exhaustive::exhaustive_primitive_floats_helper_helper; fn exhaustive_positive_finite_primitive_floats_helper(out: &[T]) { exhaustive_primitive_floats_helper_helper( exhaustive_positive_finite_primitive_floats::(), out, ); } #[test] fn test_exhaustive_positive_finite_primitive_floats() { exhaustive_positive_finite_primitive_floats_helper::(&[ 1.0, 2.0, 1.5, 0.5, 1.25, 3.0, 1.75, 4.0, 1.125, 2.5, 1.375, 0.75, 1.625, 3.5, 1.875, 0.25, 1.0625, 2.25, 1.1875, 0.625, 1.3125, 2.75, 1.4375, 6.0, 1.5625, 3.25, 1.6875, 0.875, 1.8125, 3.75, 1.9375, 8.0, 1.03125, 2.125, 1.09375, 0.5625, 1.15625, 2.375, 1.21875, 5.0, 1.28125, 2.625, 1.34375, 0.6875, 1.40625, 2.875, 1.46875, 0.375, 1.53125, 3.125, ]); exhaustive_positive_finite_primitive_floats_helper::(&[ 1.0, 2.0, 1.5, 0.5, 1.25, 3.0, 1.75, 4.0, 1.125, 2.5, 1.375, 0.75, 1.625, 3.5, 1.875, 0.25, 1.0625, 2.25, 1.1875, 0.625, 1.3125, 2.75, 1.4375, 6.0, 1.5625, 3.25, 1.6875, 0.875, 1.8125, 3.75, 1.9375, 8.0, 1.03125, 2.125, 1.09375, 0.5625, 1.15625, 2.375, 1.21875, 5.0, 1.28125, 2.625, 1.34375, 0.6875, 1.40625, 2.875, 1.46875, 0.375, 1.53125, 3.125, ]); } malachite-base-0.4.16/tests/num/exhaustive/exhaustive_positive_finite_primitive_floats_in_range.rs000064400000000000000000000170031046102023000322170ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::exhaustive::exhaustive_positive_finite_primitive_floats_in_range; use malachite_base::test_util::num::exhaustive::exhaustive_primitive_floats_helper_helper; use std::panic::catch_unwind; fn exhaustive_positive_finite_primitive_floats_in_range_helper( a: T, b: T, out: &[T], ) { exhaustive_primitive_floats_helper_helper( exhaustive_positive_finite_primitive_floats_in_range::(a, b), out, ); } #[test] fn test_exhaustive_positive_finite_primitive_floats_in_range() { exhaustive_positive_finite_primitive_floats_in_range_helper::( core::f32::consts::E, core::f32::consts::PI, &[ 3.0, 2.75, 2.875, 3.125, 2.8125, 2.9375, 3.0625, 2.71875, 2.78125, 2.84375, 2.90625, 2.96875, 3.03125, 3.09375, 2.734375, 2.765625, 2.796875, 2.828125, 2.859375, 2.890625, 2.921875, 2.953125, 2.984375, 3.015625, 3.046875, 3.078125, 3.109375, 3.140625, 2.7265625, 2.7421875, 2.7578125, 2.7734375, 2.7890625, 2.8046875, 2.8203125, 2.8359375, 2.8515625, 2.8671875, 2.8828125, 2.8984375, 2.9140625, 2.9296875, 2.9453125, 2.9609375, 2.9765625, 2.9921875, 3.0078125, 3.0234375, 3.0390625, 3.0546875, ], ); exhaustive_positive_finite_primitive_floats_in_range_helper::(5.0, 5.0, &[5.0]); exhaustive_positive_finite_primitive_floats_in_range_helper::( 1.0, 6.0, &[ 1.0, 2.0, 1.5, 4.0, 1.25, 3.0, 1.75, 1.125, 1.375, 2.5, 1.625, 6.0, 1.875, 3.5, 1.0625, 2.25, 1.1875, 2.75, 1.3125, 5.0, 1.4375, 3.25, 1.5625, 1.6875, 1.8125, 3.75, 1.9375, 4.5, 1.03125, 2.125, 1.09375, 5.5, 1.15625, 2.375, 1.21875, 4.25, 1.28125, 2.625, 1.34375, 1.40625, 1.46875, 2.875, 1.53125, 4.75, 1.59375, 3.125, 1.65625, 3.375, 1.71875, 3.625, ], ); exhaustive_positive_finite_primitive_floats_in_range_helper::( 0.01, 100.0, &[ 1.0, 2.0, 1.5, 0.5, 1.25, 3.0, 1.75, 4.0, 1.125, 2.5, 1.375, 0.75, 1.625, 3.5, 1.875, 0.25, 1.0625, 2.25, 1.1875, 0.625, 1.3125, 2.75, 1.4375, 6.0, 1.5625, 3.25, 1.6875, 0.875, 1.8125, 3.75, 1.9375, 8.0, 1.03125, 2.125, 1.09375, 0.5625, 1.15625, 2.375, 1.21875, 5.0, 1.28125, 2.625, 1.34375, 0.6875, 1.40625, 2.875, 1.46875, 0.375, 1.53125, 3.125, ], ); exhaustive_positive_finite_primitive_floats_in_range_helper::( 255.9, 256.1, &[ 255.9375, 256.0, 255.90625, 255.96875, 255.92188, 256.0625, 255.95312, 256.03125, 255.98438, 256.09375, 255.91406, 255.92969, 255.94531, 256.01562, 255.96094, 255.97656, 255.99219, 256.04688, 255.90234, 255.91016, 255.91797, 256.07812, 255.92578, 256.0078, 255.9336, 256.02344, 255.9414, 255.94922, 255.95703, 256.03906, 255.96484, 256.0547, 255.97266, 256.0703, 255.98047, 255.98828, 255.9961, 256.08594, 255.90039, 256.0039, 255.9043, 256.01172, 255.9082, 255.91211, 255.91602, 256.01953, 255.91992, 255.92383, 255.92773, 256.02734, ], ); exhaustive_positive_finite_primitive_floats_in_range_helper::( core::f64::consts::E, core::f64::consts::PI, &[ 3.0, 2.75, 2.875, 3.125, 2.8125, 2.9375, 3.0625, 2.71875, 2.78125, 2.84375, 2.90625, 2.96875, 3.03125, 3.09375, 2.734375, 2.765625, 2.796875, 2.828125, 2.859375, 2.890625, 2.921875, 2.953125, 2.984375, 3.015625, 3.046875, 3.078125, 3.109375, 3.140625, 2.7265625, 2.7421875, 2.7578125, 2.7734375, 2.7890625, 2.8046875, 2.8203125, 2.8359375, 2.8515625, 2.8671875, 2.8828125, 2.8984375, 2.9140625, 2.9296875, 2.9453125, 2.9609375, 2.9765625, 2.9921875, 3.0078125, 3.0234375, 3.0390625, 3.0546875, ], ); exhaustive_positive_finite_primitive_floats_in_range_helper::(5.0, 5.0, &[5.0]); exhaustive_positive_finite_primitive_floats_in_range_helper::( 1.0, 6.0, &[ 1.0, 2.0, 1.5, 4.0, 1.25, 3.0, 1.75, 1.125, 1.375, 2.5, 1.625, 6.0, 1.875, 3.5, 1.0625, 2.25, 1.1875, 2.75, 1.3125, 5.0, 1.4375, 3.25, 1.5625, 1.6875, 1.8125, 3.75, 1.9375, 4.5, 1.03125, 2.125, 1.09375, 5.5, 1.15625, 2.375, 1.21875, 4.25, 1.28125, 2.625, 1.34375, 1.40625, 1.46875, 2.875, 1.53125, 4.75, 1.59375, 3.125, 1.65625, 3.375, 1.71875, 3.625, ], ); exhaustive_positive_finite_primitive_floats_in_range_helper::( 0.01, 100.0, &[ 1.0, 2.0, 1.5, 0.5, 1.25, 3.0, 1.75, 4.0, 1.125, 2.5, 1.375, 0.75, 1.625, 3.5, 1.875, 0.25, 1.0625, 2.25, 1.1875, 0.625, 1.3125, 2.75, 1.4375, 6.0, 1.5625, 3.25, 1.6875, 0.875, 1.8125, 3.75, 1.9375, 8.0, 1.03125, 2.125, 1.09375, 0.5625, 1.15625, 2.375, 1.21875, 5.0, 1.28125, 2.625, 1.34375, 0.6875, 1.40625, 2.875, 1.46875, 0.375, 1.53125, 3.125, ], ); exhaustive_positive_finite_primitive_floats_in_range_helper::( 255.9, 256.1, &[ 255.9375, 256.0, 255.90625, 255.96875, 255.921875, 256.0625, 255.953125, 256.03125, 255.984375, 256.09375, 255.9140625, 255.9296875, 255.9453125, 256.015625, 255.9609375, 255.9765625, 255.9921875, 256.046875, 255.90234375, 255.91015625, 255.91796875, 256.078125, 255.92578125, 256.0078125, 255.93359375, 256.0234375, 255.94140625, 255.94921875, 255.95703125, 256.0390625, 255.96484375, 256.0546875, 255.97265625, 256.0703125, 255.98046875, 255.98828125, 255.99609375, 256.0859375, 255.900390625, 256.00390625, 255.904296875, 256.01171875, 255.908203125, 255.912109375, 255.916015625, 256.01953125, 255.919921875, 255.923828125, 255.927734375, 256.02734375, ], ); } fn exhaustive_positive_finite_primitive_floats_in_range_fail_helper() { assert_panic!(exhaustive_positive_finite_primitive_floats_in_range::( T::from(1.2), T::from(1.1), )); assert_panic!(exhaustive_positive_finite_primitive_floats_in_range::( T::from(-1.1), T::from(1.1), )); assert_panic!(exhaustive_positive_finite_primitive_floats_in_range::( T::ONE, T::INFINITY, )); assert_panic!(exhaustive_positive_finite_primitive_floats_in_range::( T::ONE, T::NAN, )); } #[test] fn exhaustive_positive_finite_primitive_floats_in_range_fail() { apply_fn_to_primitive_floats!(exhaustive_positive_finite_primitive_floats_in_range_fail_helper); } malachite-base-0.4.16/tests/num/exhaustive/exhaustive_positive_primitive_floats.rs000064400000000000000000000046611046102023000270250ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::exhaustive::exhaustive_positive_primitive_floats; use malachite_base::test_util::num::exhaustive::exhaustive_primitive_floats_helper_helper; fn exhaustive_positive_primitive_floats_helper(out: &[T]) { exhaustive_primitive_floats_helper_helper(exhaustive_positive_primitive_floats::(), out); } #[test] fn test_exhaustive_positive_primitive_floats() { exhaustive_positive_primitive_floats_helper::(&[ f32::INFINITY, 1.0, 2.0, 1.5, 0.5, 1.25, 3.0, 1.75, 4.0, 1.125, 2.5, 1.375, 0.75, 1.625, 3.5, 1.875, 0.25, 1.0625, 2.25, 1.1875, 0.625, 1.3125, 2.75, 1.4375, 6.0, 1.5625, 3.25, 1.6875, 0.875, 1.8125, 3.75, 1.9375, 8.0, 1.03125, 2.125, 1.09375, 0.5625, 1.15625, 2.375, 1.21875, 5.0, 1.28125, 2.625, 1.34375, 0.6875, 1.40625, 2.875, 1.46875, 0.375, 1.53125, ]); exhaustive_positive_primitive_floats_helper::(&[ f64::INFINITY, 1.0, 2.0, 1.5, 0.5, 1.25, 3.0, 1.75, 4.0, 1.125, 2.5, 1.375, 0.75, 1.625, 3.5, 1.875, 0.25, 1.0625, 2.25, 1.1875, 0.625, 1.3125, 2.75, 1.4375, 6.0, 1.5625, 3.25, 1.6875, 0.875, 1.8125, 3.75, 1.9375, 8.0, 1.03125, 2.125, 1.09375, 0.5625, 1.15625, 2.375, 1.21875, 5.0, 1.28125, 2.625, 1.34375, 0.6875, 1.40625, 2.875, 1.46875, 0.375, 1.53125, ]); } malachite-base-0.4.16/tests/num/exhaustive/exhaustive_positive_primitive_ints.rs000064400000000000000000000051631046102023000265100ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::num::arithmetic::traits::PowerOf2; use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::conversion::traits::ExactFrom; use malachite_base::num::exhaustive::exhaustive_positive_primitive_ints; fn exhaustive_positive_primitive_ints_helper() where u8: ExactFrom, { assert_eq!( exhaustive_positive_primitive_ints::() .map(u8::exact_from) .take(20) .collect_vec(), &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] ); } fn exhaustive_positive_primitive_ints_long_helper(last_20: &[T]) { let expected_len = if T::MIN == T::ZERO { usize::power_of_2(T::WIDTH) - 1 } else { usize::power_of_2(T::WIDTH - 1) - 1 }; let xs = exhaustive_positive_primitive_ints::(); assert_eq!(xs.clone().count(), expected_len); assert_eq!(xs.skip(expected_len - 20).collect_vec(), last_20); } #[test] fn test_exhaustive_positive_primitive_ints() { apply_fn_to_primitive_ints!(exhaustive_positive_primitive_ints_helper); exhaustive_positive_primitive_ints_long_helper::(&[ 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, ]); exhaustive_positive_primitive_ints_long_helper::(&[ 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, ]); exhaustive_positive_primitive_ints_long_helper::(&[ 65516, 65517, 65518, 65519, 0xfff0, 0xfff1, 0xfff2, 0xfff3, 0xfff4, 0xfff5, 0xfff6, 0xfff7, 0xfff8, 0xfff9, 0xfffa, 0xfffb, 0xfffc, 0xfffd, u16::MAX - 1, u16::MAX, ]); exhaustive_positive_primitive_ints_long_helper::(&[ 32748, 32749, 32750, 32751, 0x7ff0, 0x7ff1, 0x7ff2, 0x7ff3, 0x7ff4, 0x7ff5, 0x7ff6, 0x7ff7, 0x7ff8, 0x7ff9, 0x7ffa, 0x7ffb, 0x7ffc, 0x7ffd, i16::MAX - 1, i16::MAX, ]); } malachite-base-0.4.16/tests/num/exhaustive/exhaustive_primitive_float_inclusive_range.rs000064400000000000000000000403301046102023000301460ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::traits::NegativeInfinity; use malachite_base::num::exhaustive::exhaustive_primitive_float_inclusive_range; use malachite_base::test_util::num::exhaustive::exhaustive_primitive_floats_helper_helper; use std::panic::catch_unwind; fn exhaustive_primitive_float_inclusive_range_helper(a: T, b: T, out: &[T]) { exhaustive_primitive_floats_helper_helper( exhaustive_primitive_float_inclusive_range::(a, b), out, ); } #[allow(clippy::approx_constant)] #[test] fn test_exhaustive_primitive_float_inclusive_range() { exhaustive_primitive_float_inclusive_range_helper::(1.0, 1.0, &[1.0]); exhaustive_primitive_float_inclusive_range_helper::( 1.0, 2.0, &[ 1.0, 2.0, 1.5, 1.25, 1.75, 1.125, 1.375, 1.625, 1.875, 1.0625, 1.1875, 1.3125, 1.4375, 1.5625, 1.6875, 1.8125, 1.9375, 1.03125, 1.09375, 1.15625, 1.21875, 1.28125, 1.34375, 1.40625, 1.46875, 1.53125, 1.59375, 1.65625, 1.71875, 1.78125, 1.84375, 1.90625, 1.96875, 1.015625, 1.046875, 1.078125, 1.109375, 1.140625, 1.171875, 1.203125, 1.234375, 1.265625, 1.296875, 1.328125, 1.359375, 1.390625, 1.421875, 1.453125, 1.484375, 1.515625, ], ); exhaustive_primitive_float_inclusive_range_helper::( -0.1, 0.1, &[ 0.0, -0.0, 0.0625, -0.0625, 0.03125, -0.03125, 0.09375, -0.09375, 0.015625, -0.015625, 0.078125, -0.078125, 0.046875, -0.046875, 0.0703125, -0.0703125, 0.0078125, -0.0078125, 0.0859375, -0.0859375, 0.0390625, -0.0390625, 0.06640625, -0.06640625, 0.0234375, -0.0234375, 0.07421875, -0.07421875, 0.0546875, -0.0546875, 0.08203125, -0.08203125, 0.00390625, -0.00390625, 0.08984375, -0.08984375, 0.03515625, -0.03515625, 0.09765625, -0.09765625, 0.01953125, -0.01953125, 0.064453125, -0.064453125, 0.04296875, -0.04296875, 0.068359375, -0.068359375, 0.01171875, -0.01171875, ], ); exhaustive_primitive_float_inclusive_range_helper::( core::f32::consts::E, core::f32::consts::PI, &[ 3.0, 2.75, 2.875, 3.125, 2.8125, 2.9375, 3.0625, 2.71875, 2.78125, 2.84375, 2.90625, 2.96875, 3.03125, 3.09375, 2.734375, 2.765625, 2.796875, 2.828125, 2.859375, 2.890625, 2.921875, 2.953125, 2.984375, 3.015625, 3.046875, 3.078125, 3.109375, 3.140625, 2.7265625, 2.7421875, 2.7578125, 2.7734375, 2.7890625, 2.8046875, 2.8203125, 2.8359375, 2.8515625, 2.8671875, 2.8828125, 2.8984375, 2.9140625, 2.9296875, 2.9453125, 2.9609375, 2.9765625, 2.9921875, 3.0078125, 3.0234375, 3.0390625, 3.0546875, ], ); exhaustive_primitive_float_inclusive_range_helper::( 100.0, 101.0, &[ 100.0, 101.0, 100.5, 100.25, 100.75, 100.125, 100.375, 100.625, 100.875, 100.0625, 100.1875, 100.3125, 100.4375, 100.5625, 100.6875, 100.8125, 100.9375, 100.03125, 100.09375, 100.15625, 100.21875, 100.28125, 100.34375, 100.40625, 100.46875, 100.53125, 100.59375, 100.65625, 100.71875, 100.78125, 100.84375, 100.90625, 100.96875, 100.015625, 100.046875, 100.078125, 100.109375, 100.140625, 100.171875, 100.203125, 100.234375, 100.265625, 100.296875, 100.328125, 100.359375, 100.390625, 100.421875, 100.453125, 100.484375, 100.515625, ], ); exhaustive_primitive_float_inclusive_range_helper::( 1.0e38, f32::INFINITY, &[ f32::INFINITY, 1.2760589e38, 1.7014118e38, 1.0633824e38, 1.4887354e38, 1.1697206e38, 2.5521178e38, 1.3823971e38, 2.1267648e38, 1.5950736e38, 2.9774707e38, 1.0102133e38, 1.1165515e38, 1.2228898e38, 1.9140883e38, 1.329228e38, 1.4355662e38, 1.5419045e38, 2.3394413e38, 1.6482427e38, 1.0367978e38, 1.089967e38, 2.7647942e38, 1.1431361e38, 3.1901472e38, 1.1963052e38, 1.80775e38, 1.2494743e38, 1.3026434e38, 1.3558126e38, 2.0204266e38, 1.4089817e38, 2.233103e38, 1.4621508e38, 2.4457795e38, 1.5153199e38, 1.568489e38, 1.6216582e38, 2.658456e38, 1.6748273e38, 2.8711325e38, 1.0235056e38, 3.083809e38, 1.0500901e38, 1.0766747e38, 1.1032592e38, 3.2964854e38, 1.1298438e38, 1.1564284e38, 1.1830129e38, ], ); exhaustive_primitive_float_inclusive_range_helper::( -f32::MIN_POSITIVE_SUBNORMAL, f32::MIN_POSITIVE_SUBNORMAL, &[0.0, -0.0, 1.0e-45, -1.0e-45], ); exhaustive_primitive_float_inclusive_range_helper::( -0.0, f32::MIN_POSITIVE_SUBNORMAL, &[0.0, -0.0, 1.0e-45], ); exhaustive_primitive_float_inclusive_range_helper::( 0.0, f32::MIN_POSITIVE_SUBNORMAL, &[0.0, 1.0e-45], ); exhaustive_primitive_float_inclusive_range_helper::( -f32::MIN_POSITIVE_SUBNORMAL, -0.0, &[-0.0, -1.0e-45], ); exhaustive_primitive_float_inclusive_range_helper::( -f32::MIN_POSITIVE_SUBNORMAL, 0.0, &[0.0, -0.0, -1.0e-45], ); exhaustive_primitive_float_inclusive_range_helper::( f32::NEGATIVE_INFINITY, f32::INFINITY, &[ f32::INFINITY, f32::NEGATIVE_INFINITY, 0.0, -0.0, 1.0, -1.0, 2.0, -2.0, 1.5, -1.5, 0.5, -0.5, 1.25, -1.25, 3.0, -3.0, 1.75, -1.75, 4.0, -4.0, 1.125, -1.125, 2.5, -2.5, 1.375, -1.375, 0.75, -0.75, 1.625, -1.625, 3.5, -3.5, 1.875, -1.875, 0.25, -0.25, 1.0625, -1.0625, 2.25, -2.25, 1.1875, -1.1875, 0.625, -0.625, 1.3125, -1.3125, 2.75, -2.75, 1.4375, -1.4375, ], ); exhaustive_primitive_float_inclusive_range_helper::( f32::NEGATIVE_INFINITY, f32::NEGATIVE_INFINITY, &[f32::NEGATIVE_INFINITY], ); exhaustive_primitive_float_inclusive_range_helper::( f32::INFINITY, f32::INFINITY, &[f32::INFINITY], ); exhaustive_primitive_float_inclusive_range_helper::(0.0, 0.0, &[0.0]); exhaustive_primitive_float_inclusive_range_helper::(-0.0, -0.0, &[-0.0]); exhaustive_primitive_float_inclusive_range_helper::(-0.0, 0.0, &[0.0, -0.0]); exhaustive_primitive_float_inclusive_range_helper::(1.0, 1.0, &[1.0]); exhaustive_primitive_float_inclusive_range_helper::( 1.0, 2.0, &[ 1.0, 2.0, 1.5, 1.25, 1.75, 1.125, 1.375, 1.625, 1.875, 1.0625, 1.1875, 1.3125, 1.4375, 1.5625, 1.6875, 1.8125, 1.9375, 1.03125, 1.09375, 1.15625, 1.21875, 1.28125, 1.34375, 1.40625, 1.46875, 1.53125, 1.59375, 1.65625, 1.71875, 1.78125, 1.84375, 1.90625, 1.96875, 1.015625, 1.046875, 1.078125, 1.109375, 1.140625, 1.171875, 1.203125, 1.234375, 1.265625, 1.296875, 1.328125, 1.359375, 1.390625, 1.421875, 1.453125, 1.484375, 1.515625, ], ); exhaustive_primitive_float_inclusive_range_helper::( -0.1, 0.1, &[ 0.0, -0.0, 0.0625, -0.0625, 0.03125, -0.03125, 0.09375, -0.09375, 0.015625, -0.015625, 0.078125, -0.078125, 0.046875, -0.046875, 0.0703125, -0.0703125, 0.0078125, -0.0078125, 0.0859375, -0.0859375, 0.0390625, -0.0390625, 0.06640625, -0.06640625, 0.0234375, -0.0234375, 0.07421875, -0.07421875, 0.0546875, -0.0546875, 0.08203125, -0.08203125, 0.00390625, -0.00390625, 0.08984375, -0.08984375, 0.03515625, -0.03515625, 0.09765625, -0.09765625, 0.01953125, -0.01953125, 0.064453125, -0.064453125, 0.04296875, -0.04296875, 0.068359375, -0.068359375, 0.01171875, -0.01171875, ], ); exhaustive_primitive_float_inclusive_range_helper::( core::f64::consts::E, core::f64::consts::PI, &[ 3.0, 2.75, 2.875, 3.125, 2.8125, 2.9375, 3.0625, 2.71875, 2.78125, 2.84375, 2.90625, 2.96875, 3.03125, 3.09375, 2.734375, 2.765625, 2.796875, 2.828125, 2.859375, 2.890625, 2.921875, 2.953125, 2.984375, 3.015625, 3.046875, 3.078125, 3.109375, 3.140625, 2.7265625, 2.7421875, 2.7578125, 2.7734375, 2.7890625, 2.8046875, 2.8203125, 2.8359375, 2.8515625, 2.8671875, 2.8828125, 2.8984375, 2.9140625, 2.9296875, 2.9453125, 2.9609375, 2.9765625, 2.9921875, 3.0078125, 3.0234375, 3.0390625, 3.0546875, ], ); exhaustive_primitive_float_inclusive_range_helper::( 100.0, 101.0, &[ 100.0, 101.0, 100.5, 100.25, 100.75, 100.125, 100.375, 100.625, 100.875, 100.0625, 100.1875, 100.3125, 100.4375, 100.5625, 100.6875, 100.8125, 100.9375, 100.03125, 100.09375, 100.15625, 100.21875, 100.28125, 100.34375, 100.40625, 100.46875, 100.53125, 100.59375, 100.65625, 100.71875, 100.78125, 100.84375, 100.90625, 100.96875, 100.015625, 100.046875, 100.078125, 100.109375, 100.140625, 100.171875, 100.203125, 100.234375, 100.265625, 100.296875, 100.328125, 100.359375, 100.390625, 100.421875, 100.453125, 100.484375, 100.515625, ], ); exhaustive_primitive_float_inclusive_range_helper::( 1.0e308, f64::INFINITY, &[ f64::INFINITY, 1.348269851146737e308, 1.1235582092889474e308, 1.5729814930045264e308, 1.0112023883600527e308, 1.2359140302178422e308, 1.4606256720756317e308, 1.6853373139334212e308, 1.0673802988245e308, 1.1797361197533948e308, 1.2920919406822896e308, 1.4044477616111843e308, 1.516803582540079e308, 1.6291594034689738e308, 1.7415152243978685e308, 1.0392913435922764e308, 1.0954692540567238e308, 1.1516471645211711e308, 1.2078250749856185e308, 1.2640029854500659e308, 1.3201808959145132e308, 1.3763588063789606e308, 1.432536716843408e308, 1.4887146273078554e308, 1.5448925377723027e308, 1.6010704482367501e308, 1.6572483587011975e308, 1.7134262691656448e308, 1.7696041796300922e308, 1.0252468659761645e308, 1.0533358212083882e308, 1.081424776440612e308, 1.1095137316728356e308, 1.1376026869050593e308, 1.165691642137283e308, 1.1937805973695067e308, 1.2218695526017303e308, 1.249958507833954e308, 1.2780474630661777e308, 1.3061364182984014e308, 1.334225373530625e308, 1.3623143287628488e308, 1.3904032839950725e308, 1.4184922392272961e308, 1.4465811944595198e308, 1.4746701496917435e308, 1.5027591049239672e308, 1.5308480601561909e308, 1.5589370153884146e308, 1.5870259706206383e308, ], ); exhaustive_primitive_float_inclusive_range_helper::( -f64::MIN_POSITIVE_SUBNORMAL, f64::MIN_POSITIVE_SUBNORMAL, &[0.0, -0.0, 5.0e-324, -5.0e-324], ); exhaustive_primitive_float_inclusive_range_helper::( -0.0, f64::MIN_POSITIVE_SUBNORMAL, &[0.0, -0.0, 5.0e-324], ); exhaustive_primitive_float_inclusive_range_helper::( 0.0, f64::MIN_POSITIVE_SUBNORMAL, &[0.0, 5.0e-324], ); exhaustive_primitive_float_inclusive_range_helper::( -f64::MIN_POSITIVE_SUBNORMAL, -0.0, &[-0.0, -5.0e-324], ); exhaustive_primitive_float_inclusive_range_helper::( -f64::MIN_POSITIVE_SUBNORMAL, 0.0, &[0.0, -0.0, -5.0e-324], ); exhaustive_primitive_float_inclusive_range_helper::( f64::NEGATIVE_INFINITY, f64::INFINITY, &[ f64::INFINITY, f64::NEGATIVE_INFINITY, 0.0, -0.0, 1.0, -1.0, 2.0, -2.0, 1.5, -1.5, 0.5, -0.5, 1.25, -1.25, 3.0, -3.0, 1.75, -1.75, 4.0, -4.0, 1.125, -1.125, 2.5, -2.5, 1.375, -1.375, 0.75, -0.75, 1.625, -1.625, 3.5, -3.5, 1.875, -1.875, 0.25, -0.25, 1.0625, -1.0625, 2.25, -2.25, 1.1875, -1.1875, 0.625, -0.625, 1.3125, -1.3125, 2.75, -2.75, 1.4375, -1.4375, ], ); exhaustive_primitive_float_inclusive_range_helper::( f64::NEGATIVE_INFINITY, f64::NEGATIVE_INFINITY, &[f64::NEGATIVE_INFINITY], ); exhaustive_primitive_float_inclusive_range_helper::( f64::INFINITY, f64::INFINITY, &[f64::INFINITY], ); exhaustive_primitive_float_inclusive_range_helper::(0.0, 0.0, &[0.0]); exhaustive_primitive_float_inclusive_range_helper::(-0.0, -0.0, &[-0.0]); exhaustive_primitive_float_inclusive_range_helper::(-0.0, 0.0, &[0.0, -0.0]); } fn exhaustive_primitive_float_inclusive_range_fail_helper() { assert_panic!(exhaustive_primitive_float_inclusive_range::( T::ONE, T::ZERO )); assert_panic!(exhaustive_primitive_float_inclusive_range::( T::ONE, T::NAN )); } #[test] fn exhaustive_primitive_float_inclusive_range_fail() { apply_fn_to_primitive_floats!(exhaustive_primitive_float_inclusive_range_fail_helper); } malachite-base-0.4.16/tests/num/exhaustive/exhaustive_primitive_float_range.rs000064400000000000000000000365411046102023000260760ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::traits::NegativeInfinity; use malachite_base::num::exhaustive::exhaustive_primitive_float_range; use malachite_base::test_util::num::exhaustive::exhaustive_primitive_floats_helper_helper; use std::panic::catch_unwind; fn exhaustive_primitive_float_range_helper(a: T, b: T, out: &[T]) { exhaustive_primitive_floats_helper_helper(exhaustive_primitive_float_range::(a, b), out); } #[allow(clippy::approx_constant)] #[test] fn test_exhaustive_primitive_float_range() { exhaustive_primitive_float_range_helper::(1.0, 1.0, &[]); exhaustive_primitive_float_range_helper::( 1.0, 2.0, &[ 1.0, 1.5, 1.25, 1.75, 1.125, 1.375, 1.625, 1.875, 1.0625, 1.1875, 1.3125, 1.4375, 1.5625, 1.6875, 1.8125, 1.9375, 1.03125, 1.09375, 1.15625, 1.21875, 1.28125, 1.34375, 1.40625, 1.46875, 1.53125, 1.59375, 1.65625, 1.71875, 1.78125, 1.84375, 1.90625, 1.96875, 1.015625, 1.046875, 1.078125, 1.109375, 1.140625, 1.171875, 1.203125, 1.234375, 1.265625, 1.296875, 1.328125, 1.359375, 1.390625, 1.421875, 1.453125, 1.484375, 1.515625, 1.546875, ], ); exhaustive_primitive_float_range_helper::( -0.1, 0.1, &[ 0.0, -0.0, 0.0625, -0.0625, 0.03125, -0.03125, 0.09375, -0.09375, 0.015625, -0.015625, 0.078125, -0.078125, 0.046875, -0.046875, 0.0703125, -0.0703125, 0.0078125, -0.0078125, 0.0859375, -0.0859375, 0.0390625, -0.0390625, 0.06640625, -0.06640625, 0.0234375, -0.0234375, 0.07421875, -0.07421875, 0.0546875, -0.0546875, 0.08203125, -0.08203125, 0.00390625, -0.00390625, 0.08984375, -0.08984375, 0.03515625, -0.03515625, 0.09765625, -0.09765625, 0.01953125, -0.01953125, 0.064453125, -0.064453125, 0.04296875, -0.04296875, 0.068359375, -0.068359375, 0.01171875, -0.01171875, ], ); exhaustive_primitive_float_range_helper::( core::f32::consts::E, core::f32::consts::PI, &[ 3.0, 2.75, 2.875, 3.125, 2.8125, 2.9375, 3.0625, 2.71875, 2.78125, 2.84375, 2.90625, 2.96875, 3.03125, 3.09375, 2.734375, 2.765625, 2.796875, 2.828125, 2.859375, 2.890625, 2.921875, 2.953125, 2.984375, 3.015625, 3.046875, 3.078125, 3.109375, 3.140625, 2.7265625, 2.7421875, 2.7578125, 2.7734375, 2.7890625, 2.8046875, 2.8203125, 2.8359375, 2.8515625, 2.8671875, 2.8828125, 2.8984375, 2.9140625, 2.9296875, 2.9453125, 2.9609375, 2.9765625, 2.9921875, 3.0078125, 3.0234375, 3.0390625, 3.0546875, ], ); exhaustive_primitive_float_range_helper::( 100.0, 101.0, &[ 100.0, 100.5, 100.25, 100.75, 100.125, 100.375, 100.625, 100.875, 100.0625, 100.1875, 100.3125, 100.4375, 100.5625, 100.6875, 100.8125, 100.9375, 100.03125, 100.09375, 100.15625, 100.21875, 100.28125, 100.34375, 100.40625, 100.46875, 100.53125, 100.59375, 100.65625, 100.71875, 100.78125, 100.84375, 100.90625, 100.96875, 100.015625, 100.046875, 100.078125, 100.109375, 100.140625, 100.171875, 100.203125, 100.234375, 100.265625, 100.296875, 100.328125, 100.359375, 100.390625, 100.421875, 100.453125, 100.484375, 100.515625, 100.546875, ], ); exhaustive_primitive_float_range_helper::( 1.0e38, f32::INFINITY, &[ 1.2760589e38, 1.7014118e38, 1.0633824e38, 1.4887354e38, 1.1697206e38, 2.5521178e38, 1.3823971e38, 2.1267648e38, 1.5950736e38, 2.9774707e38, 1.0102133e38, 1.1165515e38, 1.2228898e38, 1.9140883e38, 1.329228e38, 1.4355662e38, 1.5419045e38, 2.3394413e38, 1.6482427e38, 1.0367978e38, 1.089967e38, 2.7647942e38, 1.1431361e38, 3.1901472e38, 1.1963052e38, 1.80775e38, 1.2494743e38, 1.3026434e38, 1.3558126e38, 2.0204266e38, 1.4089817e38, 2.233103e38, 1.4621508e38, 2.4457795e38, 1.5153199e38, 1.568489e38, 1.6216582e38, 2.658456e38, 1.6748273e38, 2.8711325e38, 1.0235056e38, 3.083809e38, 1.0500901e38, 1.0766747e38, 1.1032592e38, 3.2964854e38, 1.1298438e38, 1.1564284e38, 1.1830129e38, 1.754581e38, ], ); exhaustive_primitive_float_range_helper::( -f32::MIN_POSITIVE_SUBNORMAL, f32::MIN_POSITIVE_SUBNORMAL, &[0.0, -0.0, -1.0e-45], ); exhaustive_primitive_float_range_helper::(-0.0, f32::MIN_POSITIVE_SUBNORMAL, &[0.0, -0.0]); exhaustive_primitive_float_range_helper::(0.0, f32::MIN_POSITIVE_SUBNORMAL, &[0.0]); exhaustive_primitive_float_range_helper::(-f32::MIN_POSITIVE_SUBNORMAL, -0.0, &[-1.0e-45]); exhaustive_primitive_float_range_helper::( -f32::MIN_POSITIVE_SUBNORMAL, 0.0, &[-0.0, -1.0e-45], ); exhaustive_primitive_float_range_helper::( f32::NEGATIVE_INFINITY, f32::INFINITY, &[ f32::NEGATIVE_INFINITY, 0.0, -0.0, 1.0, -1.0, 2.0, -2.0, 1.5, -1.5, 0.5, -0.5, 1.25, -1.25, 3.0, -3.0, 1.75, -1.75, 4.0, -4.0, 1.125, -1.125, 2.5, -2.5, 1.375, -1.375, 0.75, -0.75, 1.625, -1.625, 3.5, -3.5, 1.875, -1.875, 0.25, -0.25, 1.0625, -1.0625, 2.25, -2.25, 1.1875, -1.1875, 0.625, -0.625, 1.3125, -1.3125, 2.75, -2.75, 1.4375, -1.4375, 6.0, ], ); exhaustive_primitive_float_range_helper::( f32::NEGATIVE_INFINITY, f32::NEGATIVE_INFINITY, &[], ); exhaustive_primitive_float_range_helper::(f32::INFINITY, f32::INFINITY, &[]); exhaustive_primitive_float_range_helper::(0.0, 0.0, &[]); exhaustive_primitive_float_range_helper::(-0.0, -0.0, &[]); exhaustive_primitive_float_range_helper::(-0.0, 0.0, &[-0.0]); exhaustive_primitive_float_range_helper::(1.0, 1.0, &[]); exhaustive_primitive_float_range_helper::( 1.0, 2.0, &[ 1.0, 1.5, 1.25, 1.75, 1.125, 1.375, 1.625, 1.875, 1.0625, 1.1875, 1.3125, 1.4375, 1.5625, 1.6875, 1.8125, 1.9375, 1.03125, 1.09375, 1.15625, 1.21875, 1.28125, 1.34375, 1.40625, 1.46875, 1.53125, 1.59375, 1.65625, 1.71875, 1.78125, 1.84375, 1.90625, 1.96875, 1.015625, 1.046875, 1.078125, 1.109375, 1.140625, 1.171875, 1.203125, 1.234375, 1.265625, 1.296875, 1.328125, 1.359375, 1.390625, 1.421875, 1.453125, 1.484375, 1.515625, 1.546875, ], ); exhaustive_primitive_float_range_helper::( -0.1, 0.1, &[ 0.0, -0.0, 0.0625, -0.0625, 0.03125, -0.03125, 0.09375, -0.09375, 0.015625, -0.015625, 0.078125, -0.078125, 0.046875, -0.046875, 0.0703125, -0.0703125, 0.0078125, -0.0078125, 0.0859375, -0.0859375, 0.0390625, -0.0390625, 0.06640625, -0.06640625, 0.0234375, -0.0234375, 0.07421875, -0.07421875, 0.0546875, -0.0546875, 0.08203125, -0.08203125, 0.00390625, -0.00390625, 0.08984375, -0.08984375, 0.03515625, -0.03515625, 0.09765625, -0.09765625, 0.01953125, -0.01953125, 0.064453125, -0.064453125, 0.04296875, -0.04296875, 0.068359375, -0.068359375, 0.01171875, -0.01171875, ], ); exhaustive_primitive_float_range_helper::( core::f64::consts::E, core::f64::consts::PI, &[ 3.0, 2.75, 2.875, 3.125, 2.8125, 2.9375, 3.0625, 2.71875, 2.78125, 2.84375, 2.90625, 2.96875, 3.03125, 3.09375, 2.734375, 2.765625, 2.796875, 2.828125, 2.859375, 2.890625, 2.921875, 2.953125, 2.984375, 3.015625, 3.046875, 3.078125, 3.109375, 3.140625, 2.7265625, 2.7421875, 2.7578125, 2.7734375, 2.7890625, 2.8046875, 2.8203125, 2.8359375, 2.8515625, 2.8671875, 2.8828125, 2.8984375, 2.9140625, 2.9296875, 2.9453125, 2.9609375, 2.9765625, 2.9921875, 3.0078125, 3.0234375, 3.0390625, 3.0546875, ], ); exhaustive_primitive_float_range_helper::( 100.0, 101.0, &[ 100.0, 100.5, 100.25, 100.75, 100.125, 100.375, 100.625, 100.875, 100.0625, 100.1875, 100.3125, 100.4375, 100.5625, 100.6875, 100.8125, 100.9375, 100.03125, 100.09375, 100.15625, 100.21875, 100.28125, 100.34375, 100.40625, 100.46875, 100.53125, 100.59375, 100.65625, 100.71875, 100.78125, 100.84375, 100.90625, 100.96875, 100.015625, 100.046875, 100.078125, 100.109375, 100.140625, 100.171875, 100.203125, 100.234375, 100.265625, 100.296875, 100.328125, 100.359375, 100.390625, 100.421875, 100.453125, 100.484375, 100.515625, 100.546875, ], ); exhaustive_primitive_float_range_helper::( 1.0e308, f64::INFINITY, &[ 1.348269851146737e308, 1.1235582092889474e308, 1.5729814930045264e308, 1.0112023883600527e308, 1.2359140302178422e308, 1.4606256720756317e308, 1.6853373139334212e308, 1.0673802988245e308, 1.1797361197533948e308, 1.2920919406822896e308, 1.4044477616111843e308, 1.516803582540079e308, 1.6291594034689738e308, 1.7415152243978685e308, 1.0392913435922764e308, 1.0954692540567238e308, 1.1516471645211711e308, 1.2078250749856185e308, 1.2640029854500659e308, 1.3201808959145132e308, 1.3763588063789606e308, 1.432536716843408e308, 1.4887146273078554e308, 1.5448925377723027e308, 1.6010704482367501e308, 1.6572483587011975e308, 1.7134262691656448e308, 1.7696041796300922e308, 1.0252468659761645e308, 1.0533358212083882e308, 1.081424776440612e308, 1.1095137316728356e308, 1.1376026869050593e308, 1.165691642137283e308, 1.1937805973695067e308, 1.2218695526017303e308, 1.249958507833954e308, 1.2780474630661777e308, 1.3061364182984014e308, 1.334225373530625e308, 1.3623143287628488e308, 1.3904032839950725e308, 1.4184922392272961e308, 1.4465811944595198e308, 1.4746701496917435e308, 1.5027591049239672e308, 1.5308480601561909e308, 1.5589370153884146e308, 1.5870259706206383e308, 1.615114925852862e308, ], ); exhaustive_primitive_float_range_helper::( -f64::MIN_POSITIVE_SUBNORMAL, f64::MIN_POSITIVE_SUBNORMAL, &[0.0, -0.0, -5.0e-324], ); exhaustive_primitive_float_range_helper::(-0.0, f64::MIN_POSITIVE_SUBNORMAL, &[0.0, -0.0]); exhaustive_primitive_float_range_helper::(0.0, f64::MIN_POSITIVE_SUBNORMAL, &[0.0]); exhaustive_primitive_float_range_helper::( -f64::MIN_POSITIVE_SUBNORMAL, -0.0, &[-5.0e-324], ); exhaustive_primitive_float_range_helper::( -f64::MIN_POSITIVE_SUBNORMAL, 0.0, &[-0.0, -5.0e-324], ); exhaustive_primitive_float_range_helper::( f64::NEGATIVE_INFINITY, f64::INFINITY, &[ f64::NEGATIVE_INFINITY, 0.0, -0.0, 1.0, -1.0, 2.0, -2.0, 1.5, -1.5, 0.5, -0.5, 1.25, -1.25, 3.0, -3.0, 1.75, -1.75, 4.0, -4.0, 1.125, -1.125, 2.5, -2.5, 1.375, -1.375, 0.75, -0.75, 1.625, -1.625, 3.5, -3.5, 1.875, -1.875, 0.25, -0.25, 1.0625, -1.0625, 2.25, -2.25, 1.1875, -1.1875, 0.625, -0.625, 1.3125, -1.3125, 2.75, -2.75, 1.4375, -1.4375, 6.0, ], ); exhaustive_primitive_float_range_helper::( f64::NEGATIVE_INFINITY, f64::NEGATIVE_INFINITY, &[], ); exhaustive_primitive_float_range_helper::(f64::INFINITY, f64::INFINITY, &[]); exhaustive_primitive_float_range_helper::(0.0, 0.0, &[]); exhaustive_primitive_float_range_helper::(-0.0, -0.0, &[]); exhaustive_primitive_float_range_helper::(-0.0, 0.0, &[-0.0]); } fn exhaustive_primitive_float_range_fail_helper() { assert_panic!(exhaustive_primitive_float_range::(T::ONE, T::ZERO)); assert_panic!(exhaustive_primitive_float_range::(T::ONE, T::NAN)); } #[test] fn exhaustive_primitive_float_range_fail() { apply_fn_to_primitive_floats!(exhaustive_primitive_float_range_fail_helper); } malachite-base-0.4.16/tests/num/exhaustive/exhaustive_primitive_floats.rs000064400000000000000000000046751046102023000251100ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::traits::NegativeInfinity; use malachite_base::num::exhaustive::exhaustive_primitive_floats; use malachite_base::test_util::num::exhaustive::exhaustive_primitive_floats_helper_helper; fn exhaustive_primitive_floats_helper(out: &[T]) { exhaustive_primitive_floats_helper_helper(exhaustive_primitive_floats::(), out); } #[test] fn test_exhaustive_primitive_floats() { exhaustive_primitive_floats_helper::(&[ f32::NAN, f32::INFINITY, f32::NEGATIVE_INFINITY, 0.0, -0.0, 1.0, -1.0, 2.0, -2.0, 1.5, -1.5, 0.5, -0.5, 1.25, -1.25, 3.0, -3.0, 1.75, -1.75, 4.0, -4.0, 1.125, -1.125, 2.5, -2.5, 1.375, -1.375, 0.75, -0.75, 1.625, -1.625, 3.5, -3.5, 1.875, -1.875, 0.25, -0.25, 1.0625, -1.0625, 2.25, -2.25, 1.1875, -1.1875, 0.625, -0.625, 1.3125, -1.3125, 2.75, -2.75, 1.4375, ]); exhaustive_primitive_floats_helper::(&[ f64::NAN, f64::INFINITY, f64::NEGATIVE_INFINITY, 0.0, -0.0, 1.0, -1.0, 2.0, -2.0, 1.5, -1.5, 0.5, -0.5, 1.25, -1.25, 3.0, -3.0, 1.75, -1.75, 4.0, -4.0, 1.125, -1.125, 2.5, -2.5, 1.375, -1.375, 0.75, -0.75, 1.625, -1.625, 3.5, -3.5, 1.875, -1.875, 0.25, -0.25, 1.0625, -1.0625, 2.25, -2.25, 1.1875, -1.1875, 0.625, -0.625, 1.3125, -1.3125, 2.75, -2.75, 1.4375, ]); } malachite-base-0.4.16/tests/num/exhaustive/exhaustive_primitive_floats_with_sci_exponent.rs000064400000000000000000000127771046102023000307230ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::exhaustive::exhaustive_primitive_floats_with_sci_exponent; use malachite_base::test_util::num::exhaustive::*; use std::panic::catch_unwind; fn exhaustive_primitive_floats_with_sci_exponent_helper( sci_exponent: i64, out: &[T], ) { exhaustive_primitive_floats_helper_helper_with_limit( 20, exhaustive_primitive_floats_with_sci_exponent::(sci_exponent), out, ); } #[test] fn test_exhaustive_primitive_floats_with_sci_exponent() { exhaustive_primitive_floats_with_sci_exponent_helper::( 0, &[ 1.0, 1.5, 1.25, 1.75, 1.125, 1.375, 1.625, 1.875, 1.0625, 1.1875, 1.3125, 1.4375, 1.5625, 1.6875, 1.8125, 1.9375, 1.03125, 1.09375, 1.15625, 1.21875, ], ); exhaustive_primitive_floats_with_sci_exponent_helper::( 4, &[ 16.0, 24.0, 20.0, 28.0, 18.0, 22.0, 26.0, 30.0, 17.0, 19.0, 21.0, 23.0, 25.0, 27.0, 29.0, 31.0, 16.5, 17.5, 18.5, 19.5, ], ); exhaustive_primitive_floats_with_sci_exponent_helper::( -4, &[ 0.0625, 0.09375, 0.078125, 0.109375, 0.0703125, 0.0859375, 0.1015625, 0.1171875, 0.06640625, 0.07421875, 0.08203125, 0.08984375, 0.09765625, 0.10546875, 0.11328125, 0.12109375, 0.064453125, 0.068359375, 0.072265625, 0.076171875, ], ); exhaustive_primitive_floats_with_sci_exponent_helper::(-149, &[1.0e-45]); exhaustive_primitive_floats_with_sci_exponent_helper::(-148, &[3.0e-45, 4.0e-45]); exhaustive_primitive_floats_with_sci_exponent_helper::( -147, &[6.0e-45, 8.0e-45, 7.0e-45, 1.0e-44], ); exhaustive_primitive_floats_with_sci_exponent_helper::( 127, &[ 1.7014118e38, 2.5521178e38, 2.1267648e38, 2.9774707e38, 1.9140883e38, 2.3394413e38, 2.7647942e38, 3.1901472e38, 1.80775e38, 2.0204266e38, 2.233103e38, 2.4457795e38, 2.658456e38, 2.8711325e38, 3.083809e38, 3.2964854e38, 1.754581e38, 1.8609192e38, 1.9672574e38, 2.0735957e38, ], ); exhaustive_primitive_floats_with_sci_exponent_helper::( 0, &[ 1.0, 1.5, 1.25, 1.75, 1.125, 1.375, 1.625, 1.875, 1.0625, 1.1875, 1.3125, 1.4375, 1.5625, 1.6875, 1.8125, 1.9375, 1.03125, 1.09375, 1.15625, 1.21875, ], ); exhaustive_primitive_floats_with_sci_exponent_helper::( 4, &[ 16.0, 24.0, 20.0, 28.0, 18.0, 22.0, 26.0, 30.0, 17.0, 19.0, 21.0, 23.0, 25.0, 27.0, 29.0, 31.0, 16.5, 17.5, 18.5, 19.5, ], ); exhaustive_primitive_floats_with_sci_exponent_helper::( -4, &[ 0.0625, 0.09375, 0.078125, 0.109375, 0.0703125, 0.0859375, 0.1015625, 0.1171875, 0.06640625, 0.07421875, 0.08203125, 0.08984375, 0.09765625, 0.10546875, 0.11328125, 0.12109375, 0.064453125, 0.068359375, 0.072265625, 0.076171875, ], ); exhaustive_primitive_floats_with_sci_exponent_helper::(-1074, &[5.0e-324]); exhaustive_primitive_floats_with_sci_exponent_helper::(-1073, &[1.0e-323, 1.5e-323]); exhaustive_primitive_floats_with_sci_exponent_helper::( -1072, &[2.0e-323, 3.0e-323, 2.5e-323, 3.5e-323], ); exhaustive_primitive_floats_with_sci_exponent_helper::( 1023, &[ 8.98846567431158e307, 1.348269851146737e308, 1.1235582092889474e308, 1.5729814930045264e308, 1.0112023883600527e308, 1.2359140302178422e308, 1.4606256720756317e308, 1.6853373139334212e308, 9.550244778956053e307, 1.0673802988245e308, 1.1797361197533948e308, 1.2920919406822896e308, 1.4044477616111843e308, 1.516803582540079e308, 1.6291594034689738e308, 1.7415152243978685e308, 9.269355226633816e307, 9.83113433127829e307, 1.0392913435922764e308, 1.0954692540567238e308, ], ); } fn exhaustive_primitive_floats_with_sci_exponent_fail_helper() { assert_panic!(exhaustive_primitive_floats_with_sci_exponent::(10000)); assert_panic!(exhaustive_primitive_floats_with_sci_exponent::(-10000)); } #[test] fn exhaustive_primitive_floats_with_sci_exponent_fail() { apply_fn_to_primitive_floats!(exhaustive_primitive_floats_with_sci_exponent_fail_helper); } ././@LongLink00006440000000000000000000000152000000000000007771Lustar malachite-base-0.4.16/tests/num/exhaustive/exhaustive_primitive_floats_with_sci_exponent_and_precision.rsmalachite-base-0.4.16/tests/num/exhaustive/exhaustive_primitive_floats_with_sci_exponent_and_precisi000064400000000000000000000160611046102023000326260ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::exhaustive::exhaustive_primitive_floats_with_sci_exponent_and_precision; use malachite_base::test_util::num::exhaustive::*; use std::panic::catch_unwind; fn exhaustive_primitive_floats_with_sci_exponent_and_precision_helper( sci_exponent: i64, precision: u64, out: &[T], ) { exhaustive_primitive_floats_helper_helper_with_limit( 20, exhaustive_primitive_floats_with_sci_exponent_and_precision::(sci_exponent, precision), out, ); } #[test] fn test_exhaustive_primitive_floats_with_sci_exponent_and_precision() { exhaustive_primitive_floats_with_sci_exponent_and_precision_helper::(0, 1, &[1.0]); exhaustive_primitive_floats_with_sci_exponent_and_precision_helper::(0, 2, &[1.5]); exhaustive_primitive_floats_with_sci_exponent_and_precision_helper::(0, 3, &[1.25, 1.75]); exhaustive_primitive_floats_with_sci_exponent_and_precision_helper::( 0, 4, &[1.125, 1.375, 1.625, 1.875], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_helper::( 0, 5, &[1.0625, 1.1875, 1.3125, 1.4375, 1.5625, 1.6875, 1.8125, 1.9375], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_helper::(4, 1, &[16.0]); exhaustive_primitive_floats_with_sci_exponent_and_precision_helper::(4, 2, &[24.0]); exhaustive_primitive_floats_with_sci_exponent_and_precision_helper::(4, 3, &[20.0, 28.0]); exhaustive_primitive_floats_with_sci_exponent_and_precision_helper::( 4, 4, &[18.0, 22.0, 26.0, 30.0], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_helper::( 4, 5, &[17.0, 19.0, 21.0, 23.0, 25.0, 27.0, 29.0, 31.0], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_helper::(-4, 1, &[0.0625]); exhaustive_primitive_floats_with_sci_exponent_and_precision_helper::(-4, 2, &[0.09375]); exhaustive_primitive_floats_with_sci_exponent_and_precision_helper::( -4, 3, &[0.078125, 0.109375], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_helper::( -4, 4, &[0.0703125, 0.0859375, 0.1015625, 0.1171875], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_helper::( -4, 5, &[ 0.06640625, 0.07421875, 0.08203125, 0.08984375, 0.09765625, 0.10546875, 0.11328125, 0.12109375, ], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_helper::(-149, 1, &[1.0e-45]); exhaustive_primitive_floats_with_sci_exponent_and_precision_helper::(-148, 1, &[3.0e-45]); exhaustive_primitive_floats_with_sci_exponent_and_precision_helper::(-148, 2, &[4.0e-45]); exhaustive_primitive_floats_with_sci_exponent_and_precision_helper::(-147, 1, &[6.0e-45]); exhaustive_primitive_floats_with_sci_exponent_and_precision_helper::(-147, 2, &[8.0e-45]); exhaustive_primitive_floats_with_sci_exponent_and_precision_helper::( -147, 3, &[7.0e-45, 1.0e-44], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_helper::(0, 1, &[1.0]); exhaustive_primitive_floats_with_sci_exponent_and_precision_helper::(0, 2, &[1.5]); exhaustive_primitive_floats_with_sci_exponent_and_precision_helper::(0, 3, &[1.25, 1.75]); exhaustive_primitive_floats_with_sci_exponent_and_precision_helper::( 0, 4, &[1.125, 1.375, 1.625, 1.875], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_helper::( 0, 5, &[1.0625, 1.1875, 1.3125, 1.4375, 1.5625, 1.6875, 1.8125, 1.9375], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_helper::(4, 1, &[16.0]); exhaustive_primitive_floats_with_sci_exponent_and_precision_helper::(4, 2, &[24.0]); exhaustive_primitive_floats_with_sci_exponent_and_precision_helper::(4, 3, &[20.0, 28.0]); exhaustive_primitive_floats_with_sci_exponent_and_precision_helper::( 4, 4, &[18.0, 22.0, 26.0, 30.0], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_helper::( 4, 5, &[17.0, 19.0, 21.0, 23.0, 25.0, 27.0, 29.0, 31.0], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_helper::(-4, 1, &[0.0625]); exhaustive_primitive_floats_with_sci_exponent_and_precision_helper::(-4, 2, &[0.09375]); exhaustive_primitive_floats_with_sci_exponent_and_precision_helper::( -4, 3, &[0.078125, 0.109375], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_helper::( -4, 4, &[0.0703125, 0.0859375, 0.1015625, 0.1171875], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_helper::( -4, 5, &[ 0.06640625, 0.07421875, 0.08203125, 0.08984375, 0.09765625, 0.10546875, 0.11328125, 0.12109375, ], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_helper::( -1074, 1, &[5.0e-324], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_helper::( -1073, 1, &[1.0e-323], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_helper::( -1073, 2, &[1.5e-323], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_helper::( -1072, 1, &[2.0e-323], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_helper::( -1072, 2, &[3.0e-323], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_helper::( -1072, 3, &[2.5e-323, 3.5e-323], ); } fn exhaustive_primitive_floats_with_sci_exponent_and_precision_fail_helper() { assert_panic!(exhaustive_primitive_floats_with_sci_exponent_and_precision::(0, 0)); assert_panic!(exhaustive_primitive_floats_with_sci_exponent_and_precision::(0, 100)); assert_panic!(exhaustive_primitive_floats_with_sci_exponent_and_precision::(10000, 1)); assert_panic!(exhaustive_primitive_floats_with_sci_exponent_and_precision::(-10000, 1)); assert_panic!( exhaustive_primitive_floats_with_sci_exponent_and_precision::(T::MIN_EXPONENT, 2) ); } #[test] fn exhaustive_primitive_floats_with_sci_exponent_and_precision_fail() { apply_fn_to_primitive_floats!( exhaustive_primitive_floats_with_sci_exponent_and_precision_fail_helper ); } ././@LongLink00006440000000000000000000000163000000000000007773Lustar malachite-base-0.4.16/tests/num/exhaustive/exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range.rsmalachite-base-0.4.16/tests/num/exhaustive/exhaustive_primitive_floats_with_sci_exponent_and_precisi000064400000000000000000000241511046102023000326250ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::exhaustive::*; use malachite_base::test_util::num::exhaustive::*; use std::panic::catch_unwind; fn exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range_helper< T: PrimitiveFloat, >( a: T, b: T, sci_exponent: i64, precision: u64, out: &[T], ) { exhaustive_primitive_floats_helper_helper_with_limit( 20, exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range::( a, b, sci_exponent, precision, ), out, ); } #[test] fn test_exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range() { exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range_helper::( core::f32::consts::E, core::f32::consts::PI, 1, 1, &[], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range_helper::( core::f32::consts::E, core::f32::consts::PI, 1, 2, &[3.0], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range_helper::( core::f32::consts::E, core::f32::consts::PI, 1, 3, &[], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range_helper::( core::f32::consts::E, core::f32::consts::PI, 1, 4, &[2.75], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range_helper::( core::f32::consts::E, core::f32::consts::PI, 1, 5, &[2.875, 3.125], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range_helper::( core::f32::consts::E, core::f32::consts::PI, 1, 6, &[2.8125, 2.9375, 3.0625], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range_helper::( core::f32::consts::E, core::f32::consts::PI, 1, 7, &[2.71875, 2.78125, 2.84375, 2.90625, 2.96875, 3.03125, 3.09375], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range_helper::( 1900.0, 2000.0, 10, 1, &[], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range_helper::( 1900.0, 2000.0, 10, 2, &[], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range_helper::( 1900.0, 2000.0, 10, 3, &[], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range_helper::( 1900.0, 2000.0, 10, 4, &[1920.0], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range_helper::( 1900.0, 2000.0, 10, 5, &[1984.0], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range_helper::( 1900.0, 2000.0, 10, 6, &[1952.0], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range_helper::( 1900.0, 2000.0, 10, 7, &[1904.0, 1936.0, 1968.0, 2000.0], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range_helper::( 7.0e-45, 1.0e-44, -147, 1, &[], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range_helper::( 7.0e-45, 1.0e-44, -147, 2, &[8.0e-45], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range_helper::( 7.0e-45, 1.0e-44, -147, 3, &[7.0e-45, 1.0e-44], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range_helper::( 1.0, 1.99, 0, 1, &[1.0], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range_helper::( core::f64::consts::E, core::f64::consts::PI, 1, 1, &[], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range_helper::( core::f64::consts::E, core::f64::consts::PI, 1, 2, &[3.0], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range_helper::( core::f64::consts::E, core::f64::consts::PI, 1, 3, &[], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range_helper::( core::f64::consts::E, core::f64::consts::PI, 1, 4, &[2.75], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range_helper::( core::f64::consts::E, core::f64::consts::PI, 1, 5, &[2.875, 3.125], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range_helper::( core::f64::consts::E, core::f64::consts::PI, 1, 6, &[2.8125, 2.9375, 3.0625], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range_helper::( core::f64::consts::E, core::f64::consts::PI, 1, 7, &[2.71875, 2.78125, 2.84375, 2.90625, 2.96875, 3.03125, 3.09375], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range_helper::( 1900.0, 2000.0, 10, 1, &[], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range_helper::( 1900.0, 2000.0, 10, 2, &[], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range_helper::( 1900.0, 2000.0, 10, 3, &[], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range_helper::( 1900.0, 2000.0, 10, 4, &[1920.0], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range_helper::( 1900.0, 2000.0, 10, 5, &[1984.0], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range_helper::( 1900.0, 2000.0, 10, 6, &[1952.0], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range_helper::( 1900.0, 2000.0, 10, 7, &[1904.0, 1936.0, 1968.0, 2000.0], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range_helper::( 7.0e-45, 1.0e-44, -147, 1, &[], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range_helper::( 7.0e-45, 1.0e-44, -147, 2, &[8.407790785948902e-45], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range_helper::( 7.0e-45, 1.0e-44, -147, 3, &[7.006492321624085e-45, 9.80908925027372e-45], ); exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range_helper::( 1.0, 1.99, 0, 1, &[1.0], ); } fn exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range_fail_helper< T: PrimitiveFloat, >() { assert_panic!( exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range::( T::from(1.1), T::from(1.2), 0, 0 ) ); assert_panic!( exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range::( T::from(1.1), T::from(1.2), 0, 100 ) ); assert_panic!( exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range::( T::from(1.1), T::from(1.2), 10000, 1 ) ); assert_panic!( exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range::( T::from(1.1), T::from(1.2), -10000, 1 ) ); assert_panic!( exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range::( T::MIN_POSITIVE_SUBNORMAL, T::MIN_POSITIVE_SUBNORMAL, T::MIN_EXPONENT, 2 ) ); assert_panic!( exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range::( T::from(1.2), T::from(1.1), 0, 1 ) ); assert_panic!( exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range::( T::from(1.1), T::from(1.2), 1, 1 ) ); assert_panic!( exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range::( T::from(0.1), T::from(1.2), 1, 1 ) ); assert_panic!( exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range::( T::from(-1.2), T::from(1.1), 0, 1 ) ); assert_panic!( exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range::( T::ONE, T::INFINITY, 0, 1 ) ); assert_panic!( exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range::( T::ONE, T::NAN, 0, 1 ) ); } #[test] fn exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range_fail() { apply_fn_to_primitive_floats!( exhaustive_primitive_floats_with_sci_exponent_and_precision_in_range_fail_helper ); } malachite-base-0.4.16/tests/num/exhaustive/exhaustive_primitive_floats_with_sci_exponent_in_range.rs000064400000000000000000000247001046102023000325520ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::exhaustive::exhaustive_primitive_floats_with_sci_exponent_in_range; use malachite_base::test_util::num::exhaustive::exhaustive_primitive_floats_helper_helper; use std::panic::catch_unwind; fn exhaustive_primitive_floats_with_sci_exponent_in_range_helper( a: T, b: T, sci_exponent: i64, out: &[T], ) { exhaustive_primitive_floats_helper_helper( exhaustive_primitive_floats_with_sci_exponent_in_range::(a, b, sci_exponent), out, ); } #[test] fn test_exhaustive_primitive_floats_with_sci_exponent_in_range() { exhaustive_primitive_floats_with_sci_exponent_in_range_helper::( core::f32::consts::E, core::f32::consts::PI, 1, &[ 3.0, 2.75, 2.875, 3.125, 2.8125, 2.9375, 3.0625, 2.71875, 2.78125, 2.84375, 2.90625, 2.96875, 3.03125, 3.09375, 2.734375, 2.765625, 2.796875, 2.828125, 2.859375, 2.890625, 2.921875, 2.953125, 2.984375, 3.015625, 3.046875, 3.078125, 3.109375, 3.140625, 2.7265625, 2.7421875, 2.7578125, 2.7734375, 2.7890625, 2.8046875, 2.8203125, 2.8359375, 2.8515625, 2.8671875, 2.8828125, 2.8984375, 2.9140625, 2.9296875, 2.9453125, 2.9609375, 2.9765625, 2.9921875, 3.0078125, 3.0234375, 3.0390625, 3.0546875, ], ); exhaustive_primitive_floats_with_sci_exponent_in_range_helper::( 1900.0, 2000.0, 10, &[ 1920.0, 1984.0, 1952.0, 1904.0, 1936.0, 1968.0, 2000.0, 1912.0, 1928.0, 1944.0, 1960.0, 1976.0, 1992.0, 1900.0, 1908.0, 1916.0, 1924.0, 1932.0, 1940.0, 1948.0, 1956.0, 1964.0, 1972.0, 1980.0, 1988.0, 1996.0, 1902.0, 1906.0, 1910.0, 1914.0, 1918.0, 1922.0, 1926.0, 1930.0, 1934.0, 1938.0, 1942.0, 1946.0, 1950.0, 1954.0, 1958.0, 1962.0, 1966.0, 1970.0, 1974.0, 1978.0, 1982.0, 1986.0, 1990.0, 1994.0, ], ); exhaustive_primitive_floats_with_sci_exponent_in_range_helper::( 7.0e-45, 1.0e-44, -147, &[8.0e-45, 7.0e-45, 1.0e-44], ); exhaustive_primitive_floats_with_sci_exponent_in_range_helper::( 1000000.0, 1000001.0, 19, &[ 1000000.0, 1000001.0, 1000000.5, 1000000.25, 1000000.75, 1000000.1, 1000000.4, 1000000.6, 1000000.9, 1000000.06, 1000000.2, 1000000.3, 1000000.44, 1000000.56, 1000000.7, 1000000.8, 1000000.94, ], ); exhaustive_primitive_floats_with_sci_exponent_in_range_helper::( 1.0, 1.99, 0, &[ 1.0, 1.5, 1.25, 1.75, 1.125, 1.375, 1.625, 1.875, 1.0625, 1.1875, 1.3125, 1.4375, 1.5625, 1.6875, 1.8125, 1.9375, 1.03125, 1.09375, 1.15625, 1.21875, 1.28125, 1.34375, 1.40625, 1.46875, 1.53125, 1.59375, 1.65625, 1.71875, 1.78125, 1.84375, 1.90625, 1.96875, 1.015625, 1.046875, 1.078125, 1.109375, 1.140625, 1.171875, 1.203125, 1.234375, 1.265625, 1.296875, 1.328125, 1.359375, 1.390625, 1.421875, 1.453125, 1.484375, 1.515625, 1.546875, ], ); exhaustive_primitive_floats_with_sci_exponent_in_range_helper::(5.0, 5.0, 2, &[5.0]); exhaustive_primitive_floats_with_sci_exponent_in_range_helper::( core::f64::consts::E, core::f64::consts::PI, 1, &[ 3.0, 2.75, 2.875, 3.125, 2.8125, 2.9375, 3.0625, 2.71875, 2.78125, 2.84375, 2.90625, 2.96875, 3.03125, 3.09375, 2.734375, 2.765625, 2.796875, 2.828125, 2.859375, 2.890625, 2.921875, 2.953125, 2.984375, 3.015625, 3.046875, 3.078125, 3.109375, 3.140625, 2.7265625, 2.7421875, 2.7578125, 2.7734375, 2.7890625, 2.8046875, 2.8203125, 2.8359375, 2.8515625, 2.8671875, 2.8828125, 2.8984375, 2.9140625, 2.9296875, 2.9453125, 2.9609375, 2.9765625, 2.9921875, 3.0078125, 3.0234375, 3.0390625, 3.0546875, ], ); exhaustive_primitive_floats_with_sci_exponent_in_range_helper::( 1900.0, 2000.0, 10, &[ 1920.0, 1984.0, 1952.0, 1904.0, 1936.0, 1968.0, 2000.0, 1912.0, 1928.0, 1944.0, 1960.0, 1976.0, 1992.0, 1900.0, 1908.0, 1916.0, 1924.0, 1932.0, 1940.0, 1948.0, 1956.0, 1964.0, 1972.0, 1980.0, 1988.0, 1996.0, 1902.0, 1906.0, 1910.0, 1914.0, 1918.0, 1922.0, 1926.0, 1930.0, 1934.0, 1938.0, 1942.0, 1946.0, 1950.0, 1954.0, 1958.0, 1962.0, 1966.0, 1970.0, 1974.0, 1978.0, 1982.0, 1986.0, 1990.0, 1994.0, ], ); exhaustive_primitive_floats_with_sci_exponent_in_range_helper::( 7.0e-45, 1.0e-44, -147, &[ 8.407790785948902e-45, 7.006492321624085e-45, 9.80908925027372e-45, 7.707141553786494e-45, 9.108440018111311e-45, 7.35681693770529e-45, 8.057466169867698e-45, 8.758115402030107e-45, 9.458764634192515e-45, 7.181654629664687e-45, 7.531979245745892e-45, 7.882303861827096e-45, 8.2326284779083e-45, 8.582953093989505e-45, 8.933277710070709e-45, 9.283602326151913e-45, 9.633926942233117e-45, 9.984251558314322e-45, 7.094073475644386e-45, 7.269235783684989e-45, 7.444398091725591e-45, 7.619560399766193e-45, 7.794722707806795e-45, 7.969885015847397e-45, 8.145047323887999e-45, 8.320209631928601e-45, 8.495371939969203e-45, 8.670534248009806e-45, 8.845696556050408e-45, 9.02085886409101e-45, 9.196021172131612e-45, 9.371183480172214e-45, 9.546345788212816e-45, 9.721508096253418e-45, 9.89667040429402e-45, 7.050282898634236e-45, 7.137864052654537e-45, 7.225445206674838e-45, 7.313026360695139e-45, 7.40060751471544e-45, 7.488188668735741e-45, 7.575769822756042e-45, 7.663350976776343e-45, 7.750932130796644e-45, 7.838513284816945e-45, 7.926094438837247e-45, 8.013675592857548e-45, 8.101256746877849e-45, 8.18883790089815e-45, 8.276419054918451e-45, ], ); exhaustive_primitive_floats_with_sci_exponent_in_range_helper::( 1000000.0, 1000001.0, 19, &[ 1000000.0, 1000001.0, 1000000.5, 1000000.25, 1000000.75, 1000000.125, 1000000.375, 1000000.625, 1000000.875, 1000000.0625, 1000000.1875, 1000000.3125, 1000000.4375, 1000000.5625, 1000000.6875, 1000000.8125, 1000000.9375, 1000000.03125, 1000000.09375, 1000000.15625, 1000000.21875, 1000000.28125, 1000000.34375, 1000000.40625, 1000000.46875, 1000000.53125, 1000000.59375, 1000000.65625, 1000000.71875, 1000000.78125, 1000000.84375, 1000000.90625, 1000000.96875, 1000000.015625, 1000000.046875, 1000000.078125, 1000000.109375, 1000000.140625, 1000000.171875, 1000000.203125, 1000000.234375, 1000000.265625, 1000000.296875, 1000000.328125, 1000000.359375, 1000000.390625, 1000000.421875, 1000000.453125, 1000000.484375, 1000000.515625, ], ); exhaustive_primitive_floats_with_sci_exponent_in_range_helper::( 1.0, 1.99, 0, &[ 1.0, 1.5, 1.25, 1.75, 1.125, 1.375, 1.625, 1.875, 1.0625, 1.1875, 1.3125, 1.4375, 1.5625, 1.6875, 1.8125, 1.9375, 1.03125, 1.09375, 1.15625, 1.21875, 1.28125, 1.34375, 1.40625, 1.46875, 1.53125, 1.59375, 1.65625, 1.71875, 1.78125, 1.84375, 1.90625, 1.96875, 1.015625, 1.046875, 1.078125, 1.109375, 1.140625, 1.171875, 1.203125, 1.234375, 1.265625, 1.296875, 1.328125, 1.359375, 1.390625, 1.421875, 1.453125, 1.484375, 1.515625, 1.546875, ], ); exhaustive_primitive_floats_with_sci_exponent_in_range_helper::(5.0, 5.0, 2, &[5.0]); } fn exhaustive_primitive_floats_with_sci_exponent_in_range_fail_helper() { assert_panic!(exhaustive_primitive_floats_with_sci_exponent_in_range::( T::from(1.1), T::from(1.2), 10000, )); assert_panic!(exhaustive_primitive_floats_with_sci_exponent_in_range::( T::from(1.1), T::from(1.2), -10000, )); assert_panic!(exhaustive_primitive_floats_with_sci_exponent_in_range::( T::from(-1.2), T::from(1.1), 0, ) .for_each(|_| {})); assert_panic!(exhaustive_primitive_floats_with_sci_exponent_in_range::( T::ONE, T::INFINITY, 0, ) .for_each(|_| {})); assert_panic!( exhaustive_primitive_floats_with_sci_exponent_in_range::(T::ONE, T::NAN, 0) .for_each(|_| {}) ); assert_panic!(exhaustive_primitive_floats_with_sci_exponent_in_range::( T::from(1.2), T::from(1.1), 0, ) .for_each(|_| {})); assert_panic!(exhaustive_primitive_floats_with_sci_exponent_in_range::( T::from(1.1), T::from(1.2), 1, ) .for_each(|_| {})); assert_panic!(exhaustive_primitive_floats_with_sci_exponent_in_range::( T::from(0.1), T::from(1.2), 1, ) .for_each(|_| {})); } #[test] fn exhaustive_primitive_floats_with_sci_exponent_in_range_fail() { apply_fn_to_primitive_floats!( exhaustive_primitive_floats_with_sci_exponent_in_range_fail_helper ); } malachite-base-0.4.16/tests/num/exhaustive/exhaustive_signed_inclusive_range.rs000064400000000000000000000114521046102023000262250ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::conversion::traits::{ExactFrom, WrappingFrom}; use malachite_base::num::exhaustive::exhaustive_signed_inclusive_range; use std::panic::catch_unwind; fn expected_range_len(a: T, b: T) -> usize where usize: WrappingFrom, { usize::wrapping_from(b).wrapping_sub(usize::wrapping_from(a)) + 1 } fn exhaustive_signed_inclusive_range_helper_helper(a: T, b: T, values: &[i8]) where i8: ExactFrom, usize: WrappingFrom, { let xs = exhaustive_signed_inclusive_range::(a, b) .map(i8::exact_from) .take(20) .collect_vec(); assert_eq!(xs, values); if T::WIDTH <= u16::WIDTH { assert_eq!( exhaustive_signed_inclusive_range(a, b).count(), expected_range_len(a, b) ); } } fn exhaustive_signed_inclusive_range_rev_helper(a: T, b: T, rev_values: &[T]) where usize: WrappingFrom, { let len = expected_range_len(a, b); assert_eq!(exhaustive_signed_inclusive_range(a, b).count(), len); let mut tail = exhaustive_signed_inclusive_range::(a, b) .skip(len.saturating_sub(20)) .collect_vec(); tail.reverse(); assert_eq!(tail, rev_values); } fn exhaustive_signed_inclusive_range_helper() where i8: ExactFrom, usize: WrappingFrom, { exhaustive_signed_inclusive_range_helper_helper(T::ZERO, T::ZERO, &[0]); exhaustive_signed_inclusive_range_helper_helper( T::ZERO, T::exact_from(9), &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], ); exhaustive_signed_inclusive_range_helper_helper( T::exact_from(10), T::exact_from(19), &[10, 11, 12, 13, 14, 15, 16, 17, 18, 19], ); exhaustive_signed_inclusive_range_helper_helper( T::ZERO, T::MAX, &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], ); exhaustive_signed_inclusive_range_helper_helper( T::ZERO, T::MAX - T::ONE, &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], ); exhaustive_signed_inclusive_range_helper_helper( T::exact_from(-20), T::exact_from(-11), &[-11, -12, -13, -14, -15, -16, -17, -18, -19, -20], ); exhaustive_signed_inclusive_range_helper_helper( T::exact_from(-100), T::exact_from(99), &[0, 1, -1, 2, -2, 3, -3, 4, -4, 5, -5, 6, -6, 7, -7, 8, -8, 9, -9, 10], ); exhaustive_signed_inclusive_range_helper_helper( T::MIN, T::MAX, &[0, 1, -1, 2, -2, 3, -3, 4, -4, 5, -5, 6, -6, 7, -7, 8, -8, 9, -9, 10], ); exhaustive_signed_inclusive_range_helper_helper( T::MIN + T::ONE, T::MAX - T::ONE, &[0, 1, -1, 2, -2, 3, -3, 4, -4, 5, -5, 6, -6, 7, -7, 8, -8, 9, -9, 10], ); } #[test] fn test_exhaustive_signed_inclusive_range() { apply_fn_to_signeds!(exhaustive_signed_inclusive_range_helper); exhaustive_signed_inclusive_range_rev_helper::( i8::MIN, i8::MAX, &[ -128, -127, 127, -126, 126, -125, 125, -124, 124, -123, 123, -122, 122, -121, 121, -120, 120, -119, 119, -118, ], ); exhaustive_signed_inclusive_range_rev_helper::( i8::MIN + 1, i8::MAX - 1, &[ -127, -126, 126, -125, 125, -124, 124, -123, 123, -122, 122, -121, 121, -120, 120, -119, 119, -118, 118, -117, ], ); exhaustive_signed_inclusive_range_rev_helper::( i16::MIN, i16::MAX, &[ -32768, -32767, 32767, -32766, 32766, -32765, 32765, -32764, 32764, -32763, 32763, -32762, 32762, -32761, 32761, -32760, 32760, -32759, 32759, -32758, ], ); exhaustive_signed_inclusive_range_rev_helper::( i16::MIN + 1, i16::MAX - 1, &[ -32767, -32766, 32766, -32765, 32765, -32764, 32764, -32763, 32763, -32762, 32762, -32761, 32761, -32760, 32760, -32759, 32759, -32758, 32758, -32757, ], ); } fn exhaustive_signed_inclusive_range_fail_helper() { assert_panic!(exhaustive_signed_inclusive_range::(T::ONE, T::ZERO)); } #[test] fn exhaustive_signed_inclusive_range_fail() { apply_fn_to_signeds!(exhaustive_signed_inclusive_range_fail_helper); } malachite-base-0.4.16/tests/num/exhaustive/exhaustive_signed_range.rs000064400000000000000000000111331046102023000241400ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::conversion::traits::{ExactFrom, WrappingFrom}; use malachite_base::num::exhaustive::exhaustive_signed_range; use std::panic::catch_unwind; fn expected_range_len(a: T, b: T) -> usize where usize: WrappingFrom, { usize::wrapping_from(b).wrapping_sub(usize::wrapping_from(a)) } fn exhaustive_signed_range_helper_helper(a: T, b: T, values: &[i8]) where i8: ExactFrom, usize: WrappingFrom, { let xs = exhaustive_signed_range::(a, b) .map(i8::exact_from) .take(20) .collect_vec(); assert_eq!(xs, values); if T::WIDTH <= u16::WIDTH { assert_eq!( exhaustive_signed_range(a, b).count(), expected_range_len(a, b) ); } } fn exhaustive_signed_range_rev_helper(a: T, b: T, rev_values: &[T]) where usize: WrappingFrom, { let len = expected_range_len(a, b); assert_eq!(exhaustive_signed_range(a, b).count(), len); let mut tail = exhaustive_signed_range::(a, b) .skip(len.saturating_sub(20)) .collect_vec(); tail.reverse(); assert_eq!(tail, rev_values); } fn exhaustive_signed_range_helper() where i8: ExactFrom, usize: WrappingFrom, { exhaustive_signed_range_helper_helper(T::ZERO, T::ZERO, &[]); exhaustive_signed_range_helper_helper(T::ZERO, T::ONE, &[0]); exhaustive_signed_range_helper_helper( T::ZERO, T::exact_from(10), &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], ); exhaustive_signed_range_helper_helper( T::exact_from(10), T::exact_from(20), &[10, 11, 12, 13, 14, 15, 16, 17, 18, 19], ); exhaustive_signed_range_helper_helper( T::ZERO, T::MAX, &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], ); exhaustive_signed_range_helper_helper( T::ZERO, T::MAX - T::ONE, &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], ); exhaustive_signed_range_helper_helper( T::exact_from(-20), T::exact_from(-10), &[-11, -12, -13, -14, -15, -16, -17, -18, -19, -20], ); exhaustive_signed_range_helper_helper( T::exact_from(-100), T::exact_from(100), &[0, 1, -1, 2, -2, 3, -3, 4, -4, 5, -5, 6, -6, 7, -7, 8, -8, 9, -9, 10], ); exhaustive_signed_range_helper_helper( T::MIN, T::MAX, &[0, 1, -1, 2, -2, 3, -3, 4, -4, 5, -5, 6, -6, 7, -7, 8, -8, 9, -9, 10], ); exhaustive_signed_range_helper_helper( T::MIN + T::ONE, T::MAX - T::ONE, &[0, 1, -1, 2, -2, 3, -3, 4, -4, 5, -5, 6, -6, 7, -7, 8, -8, 9, -9, 10], ); } #[test] fn test_exhaustive_signed_range() { apply_fn_to_signeds!(exhaustive_signed_range_helper); exhaustive_signed_range_rev_helper::( i8::MIN, i8::MAX, &[ -128, -127, -126, 126, -125, 125, -124, 124, -123, 123, -122, 122, -121, 121, -120, 120, -119, 119, -118, 118, ], ); exhaustive_signed_range_rev_helper::( i8::MIN + 1, i8::MAX - 1, &[ -127, -126, -125, 125, -124, 124, -123, 123, -122, 122, -121, 121, -120, 120, -119, 119, -118, 118, -117, 117, ], ); exhaustive_signed_range_rev_helper::( i16::MIN, i16::MAX, &[ -32768, -32767, -32766, 32766, -32765, 32765, -32764, 32764, -32763, 32763, -32762, 32762, -32761, 32761, -32760, 32760, -32759, 32759, -32758, 32758, ], ); exhaustive_signed_range_rev_helper::( i16::MIN + 1, i16::MAX - 1, &[ -32767, -32766, -32765, 32765, -32764, 32764, -32763, 32763, -32762, 32762, -32761, 32761, -32760, 32760, -32759, 32759, -32758, 32758, -32757, 32757, ], ); } fn exhaustive_signed_range_fail_helper() { assert_panic!(exhaustive_signed_range::(T::ONE, T::ZERO)); } #[test] fn exhaustive_signed_range_fail() { apply_fn_to_signeds!(exhaustive_signed_range_fail_helper); } malachite-base-0.4.16/tests/num/exhaustive/exhaustive_signeds.rs000064400000000000000000000035401046102023000231520ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::num::arithmetic::traits::PowerOf2; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::conversion::traits::ExactFrom; use malachite_base::num::exhaustive::exhaustive_signeds; fn exhaustive_signeds_helper() where i8: ExactFrom, { assert_eq!( exhaustive_signeds::() .map(i8::exact_from) .take(20) .collect_vec(), &[0, 1, -1, 2, -2, 3, -3, 4, -4, 5, -5, 6, -6, 7, -7, 8, -8, 9, -9, 10] ); } fn exhaustive_signeds_long_helper(last_20: &[T]) { let expected_len = usize::power_of_2(T::WIDTH); let xs = exhaustive_signeds::(); assert_eq!(xs.clone().count(), expected_len); assert_eq!(xs.skip(expected_len - 20).collect_vec(), last_20); } #[test] fn test_exhaustive_signeds() { apply_fn_to_signeds!(exhaustive_signeds_helper); exhaustive_signeds_long_helper::(&[ -118, 119, -119, 120, -120, 121, -121, 122, -122, 123, -123, 124, -124, 125, -125, 126, -126, 127, -127, -128, ]); exhaustive_signeds_long_helper::(&[ -0x7ff6, 0x7ff7, -0x7ff7, 0x7ff8, -0x7ff8, 0x7ff9, -0x7ff9, 0x7ffa, -0x7ffa, 0x7ffb, -0x7ffb, 0x7ffc, -0x7ffc, 0x7ffd, -0x7ffd, i16::MAX - 1, -0x7ffe, i16::MAX, i16::MIN + 1, i16::MIN, ]); } malachite-base-0.4.16/tests/num/exhaustive/exhaustive_unsigneds.rs000064400000000000000000000035341046102023000235200ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::num::arithmetic::traits::PowerOf2; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::ExactFrom; use malachite_base::num::exhaustive::exhaustive_unsigneds; fn exhaustive_unsigneds_helper() where u8: ExactFrom, { assert_eq!( exhaustive_unsigneds::() .map(u8::exact_from) .take(20) .collect_vec(), &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] ); } fn exhaustive_unsigneds_long_helper(last_20: &[T]) { let expected_len = usize::power_of_2(T::WIDTH); let xs = exhaustive_unsigneds::(); assert_eq!(xs.clone().count(), expected_len); assert_eq!(xs.skip(expected_len - 20).collect_vec(), last_20); } #[test] fn test_exhaustive_unsigneds() { apply_fn_to_unsigneds!(exhaustive_unsigneds_helper); exhaustive_unsigneds_long_helper::(&[ 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, ]); exhaustive_unsigneds_long_helper::(&[ 65516, 65517, 65518, 65519, 0xfff0, 0xfff1, 0xfff2, 0xfff3, 0xfff4, 0xfff5, 0xfff6, 0xfff7, 0xfff8, 0xfff9, 0xfffa, 0xfffb, 0xfffc, 0xfffd, u16::MAX - 1, u16::MAX, ]); } malachite-base-0.4.16/tests/num/exhaustive/finite_primitive_floats_increasing.rs000064400000000000000000000067731046102023000264040ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::exhaustive::finite_primitive_floats_increasing; use malachite_base::test_util::num::exhaustive::*; fn finite_primitive_floats_increasing_helper(first_20: &[T], last_20: &[T]) { exhaustive_primitive_floats_helper_helper_with_reverse( finite_primitive_floats_increasing::(), first_20, last_20, ); } #[test] fn test_finite_primitive_floats_increasing() { finite_primitive_floats_increasing_helper::( &[ -3.4028235e38, -3.4028233e38, -3.402823e38, -3.4028229e38, -3.4028227e38, -3.4028225e38, -3.4028222e38, -3.402822e38, -3.4028218e38, -3.4028216e38, -3.4028214e38, -3.4028212e38, -3.402821e38, -3.4028208e38, -3.4028206e38, -3.4028204e38, -3.4028202e38, -3.40282e38, -3.4028198e38, -3.4028196e38, ], &[ 3.4028196e38, 3.4028198e38, 3.40282e38, 3.4028202e38, 3.4028204e38, 3.4028206e38, 3.4028208e38, 3.402821e38, 3.4028212e38, 3.4028214e38, 3.4028216e38, 3.4028218e38, 3.402822e38, 3.4028222e38, 3.4028225e38, 3.4028227e38, 3.4028229e38, 3.402823e38, 3.4028233e38, 3.4028235e38, ], ); finite_primitive_floats_increasing_helper::( &[ -1.7976931348623157e308, -1.7976931348623155e308, -1.7976931348623153e308, -1.7976931348623151e308, -1.797693134862315e308, -1.7976931348623147e308, -1.7976931348623145e308, -1.7976931348623143e308, -1.7976931348623141e308, -1.797693134862314e308, -1.7976931348623137e308, -1.7976931348623135e308, -1.7976931348623133e308, -1.7976931348623131e308, -1.797693134862313e308, -1.7976931348623127e308, -1.7976931348623125e308, -1.7976931348623123e308, -1.7976931348623121e308, -1.797693134862312e308, ], &[ 1.797693134862312e308, 1.7976931348623121e308, 1.7976931348623123e308, 1.7976931348623125e308, 1.7976931348623127e308, 1.797693134862313e308, 1.7976931348623131e308, 1.7976931348623133e308, 1.7976931348623135e308, 1.7976931348623137e308, 1.797693134862314e308, 1.7976931348623141e308, 1.7976931348623143e308, 1.7976931348623145e308, 1.7976931348623147e308, 1.797693134862315e308, 1.7976931348623151e308, 1.7976931348623153e308, 1.7976931348623155e308, 1.7976931348623157e308, ], ); } malachite-base-0.4.16/tests/num/exhaustive/negative_finite_primitive_floats_increasing.rs000064400000000000000000000055311046102023000302550ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::exhaustive::negative_finite_primitive_floats_increasing; use malachite_base::test_util::num::exhaustive::*; fn negative_finite_primitive_floats_increasing_helper( first_20: &[T], last_20: &[T], ) { exhaustive_primitive_floats_helper_helper_with_reverse( negative_finite_primitive_floats_increasing::(), first_20, last_20, ); } #[test] fn test_negative_finite_primitive_floats_increasing() { negative_finite_primitive_floats_increasing_helper::( &[ -3.4028235e38, -3.4028233e38, -3.402823e38, -3.4028229e38, -3.4028227e38, -3.4028225e38, -3.4028222e38, -3.402822e38, -3.4028218e38, -3.4028216e38, -3.4028214e38, -3.4028212e38, -3.402821e38, -3.4028208e38, -3.4028206e38, -3.4028204e38, -3.4028202e38, -3.40282e38, -3.4028198e38, -3.4028196e38, ], &[ -2.8e-44, -2.7e-44, -2.5e-44, -2.4e-44, -2.2e-44, -2.1e-44, -2.0e-44, -1.8e-44, -1.7e-44, -1.5e-44, -1.4e-44, -1.3e-44, -1.1e-44, -1.0e-44, -8.0e-45, -7.0e-45, -6.0e-45, -4.0e-45, -3.0e-45, -1.0e-45, ], ); negative_finite_primitive_floats_increasing_helper::( &[ -1.7976931348623157e308, -1.7976931348623155e308, -1.7976931348623153e308, -1.7976931348623151e308, -1.797693134862315e308, -1.7976931348623147e308, -1.7976931348623145e308, -1.7976931348623143e308, -1.7976931348623141e308, -1.797693134862314e308, -1.7976931348623137e308, -1.7976931348623135e308, -1.7976931348623133e308, -1.7976931348623131e308, -1.797693134862313e308, -1.7976931348623127e308, -1.7976931348623125e308, -1.7976931348623123e308, -1.7976931348623121e308, -1.797693134862312e308, ], &[ -1.0e-322, -9.4e-323, -9.0e-323, -8.4e-323, -8.0e-323, -7.4e-323, -7.0e-323, -6.4e-323, -6.0e-323, -5.4e-323, -5.0e-323, -4.4e-323, -4.0e-323, -3.5e-323, -3.0e-323, -2.5e-323, -2.0e-323, -1.5e-323, -1.0e-323, -5.0e-324, ], ); } malachite-base-0.4.16/tests/num/exhaustive/negative_primitive_floats_increasing.rs000064400000000000000000000055471046102023000267260ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::traits::NegativeInfinity; use malachite_base::num::exhaustive::negative_primitive_floats_increasing; use malachite_base::test_util::num::exhaustive::*; fn negative_primitive_floats_increasing_helper(first_20: &[T], last_20: &[T]) { exhaustive_primitive_floats_helper_helper_with_reverse( negative_primitive_floats_increasing::(), first_20, last_20, ); } #[test] fn test_negative_primitive_floats_increasing() { negative_primitive_floats_increasing_helper::( &[ f32::NEGATIVE_INFINITY, -3.4028235e38, -3.4028233e38, -3.402823e38, -3.4028229e38, -3.4028227e38, -3.4028225e38, -3.4028222e38, -3.402822e38, -3.4028218e38, -3.4028216e38, -3.4028214e38, -3.4028212e38, -3.402821e38, -3.4028208e38, -3.4028206e38, -3.4028204e38, -3.4028202e38, -3.40282e38, -3.4028198e38, ], &[ -2.8e-44, -2.7e-44, -2.5e-44, -2.4e-44, -2.2e-44, -2.1e-44, -2.0e-44, -1.8e-44, -1.7e-44, -1.5e-44, -1.4e-44, -1.3e-44, -1.1e-44, -1.0e-44, -8.0e-45, -7.0e-45, -6.0e-45, -4.0e-45, -3.0e-45, -1.0e-45, ], ); negative_primitive_floats_increasing_helper::( &[ f64::NEGATIVE_INFINITY, -1.7976931348623157e308, -1.7976931348623155e308, -1.7976931348623153e308, -1.7976931348623151e308, -1.797693134862315e308, -1.7976931348623147e308, -1.7976931348623145e308, -1.7976931348623143e308, -1.7976931348623141e308, -1.797693134862314e308, -1.7976931348623137e308, -1.7976931348623135e308, -1.7976931348623133e308, -1.7976931348623131e308, -1.797693134862313e308, -1.7976931348623127e308, -1.7976931348623125e308, -1.7976931348623123e308, -1.7976931348623121e308, ], &[ -1.0e-322, -9.4e-323, -9.0e-323, -8.4e-323, -8.0e-323, -7.4e-323, -7.0e-323, -6.4e-323, -6.0e-323, -5.4e-323, -5.0e-323, -4.4e-323, -4.0e-323, -3.5e-323, -3.0e-323, -2.5e-323, -2.0e-323, -1.5e-323, -1.0e-323, -5.0e-324, ], ); } malachite-base-0.4.16/tests/num/exhaustive/nonzero_finite_primitive_floats_increasing.rs000064400000000000000000000070661046102023000301520ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::exhaustive::nonzero_finite_primitive_floats_increasing; use malachite_base::test_util::num::exhaustive::*; fn nonzero_finite_primitive_floats_increasing_helper( first_20: &[T], last_20: &[T], ) { exhaustive_primitive_floats_helper_helper_with_reverse( nonzero_finite_primitive_floats_increasing::(), first_20, last_20, ); } #[test] fn test_nonzero_finite_primitive_floats_increasing() { nonzero_finite_primitive_floats_increasing_helper::( &[ -3.4028235e38, -3.4028233e38, -3.402823e38, -3.4028229e38, -3.4028227e38, -3.4028225e38, -3.4028222e38, -3.402822e38, -3.4028218e38, -3.4028216e38, -3.4028214e38, -3.4028212e38, -3.402821e38, -3.4028208e38, -3.4028206e38, -3.4028204e38, -3.4028202e38, -3.40282e38, -3.4028198e38, -3.4028196e38, ], &[ 3.4028196e38, 3.4028198e38, 3.40282e38, 3.4028202e38, 3.4028204e38, 3.4028206e38, 3.4028208e38, 3.402821e38, 3.4028212e38, 3.4028214e38, 3.4028216e38, 3.4028218e38, 3.402822e38, 3.4028222e38, 3.4028225e38, 3.4028227e38, 3.4028229e38, 3.402823e38, 3.4028233e38, 3.4028235e38, ], ); nonzero_finite_primitive_floats_increasing_helper::( &[ -1.7976931348623157e308, -1.7976931348623155e308, -1.7976931348623153e308, -1.7976931348623151e308, -1.797693134862315e308, -1.7976931348623147e308, -1.7976931348623145e308, -1.7976931348623143e308, -1.7976931348623141e308, -1.797693134862314e308, -1.7976931348623137e308, -1.7976931348623135e308, -1.7976931348623133e308, -1.7976931348623131e308, -1.797693134862313e308, -1.7976931348623127e308, -1.7976931348623125e308, -1.7976931348623123e308, -1.7976931348623121e308, -1.797693134862312e308, ], &[ 1.797693134862312e308, 1.7976931348623121e308, 1.7976931348623123e308, 1.7976931348623125e308, 1.7976931348623127e308, 1.797693134862313e308, 1.7976931348623131e308, 1.7976931348623133e308, 1.7976931348623135e308, 1.7976931348623137e308, 1.797693134862314e308, 1.7976931348623141e308, 1.7976931348623143e308, 1.7976931348623145e308, 1.7976931348623147e308, 1.797693134862315e308, 1.7976931348623151e308, 1.7976931348623153e308, 1.7976931348623155e308, 1.7976931348623157e308, ], ); } malachite-base-0.4.16/tests/num/exhaustive/nonzero_primitive_floats_increasing.rs000064400000000000000000000070751046102023000266140ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::traits::NegativeInfinity; use malachite_base::num::exhaustive::nonzero_primitive_floats_increasing; use malachite_base::test_util::num::exhaustive::*; fn nonzero_primitive_floats_increasing_helper(first_20: &[T], last_20: &[T]) { exhaustive_primitive_floats_helper_helper_with_reverse( nonzero_primitive_floats_increasing::(), first_20, last_20, ); } #[test] fn test_nonzero_primitive_floats_increasing() { nonzero_primitive_floats_increasing_helper::( &[ f32::NEGATIVE_INFINITY, -3.4028235e38, -3.4028233e38, -3.402823e38, -3.4028229e38, -3.4028227e38, -3.4028225e38, -3.4028222e38, -3.402822e38, -3.4028218e38, -3.4028216e38, -3.4028214e38, -3.4028212e38, -3.402821e38, -3.4028208e38, -3.4028206e38, -3.4028204e38, -3.4028202e38, -3.40282e38, -3.4028198e38, ], &[ 3.4028198e38, 3.40282e38, 3.4028202e38, 3.4028204e38, 3.4028206e38, 3.4028208e38, 3.402821e38, 3.4028212e38, 3.4028214e38, 3.4028216e38, 3.4028218e38, 3.402822e38, 3.4028222e38, 3.4028225e38, 3.4028227e38, 3.4028229e38, 3.402823e38, 3.4028233e38, 3.4028235e38, f32::INFINITY, ], ); nonzero_primitive_floats_increasing_helper::( &[ f64::NEGATIVE_INFINITY, -1.7976931348623157e308, -1.7976931348623155e308, -1.7976931348623153e308, -1.7976931348623151e308, -1.797693134862315e308, -1.7976931348623147e308, -1.7976931348623145e308, -1.7976931348623143e308, -1.7976931348623141e308, -1.797693134862314e308, -1.7976931348623137e308, -1.7976931348623135e308, -1.7976931348623133e308, -1.7976931348623131e308, -1.797693134862313e308, -1.7976931348623127e308, -1.7976931348623125e308, -1.7976931348623123e308, -1.7976931348623121e308, ], &[ 1.7976931348623121e308, 1.7976931348623123e308, 1.7976931348623125e308, 1.7976931348623127e308, 1.797693134862313e308, 1.7976931348623131e308, 1.7976931348623133e308, 1.7976931348623135e308, 1.7976931348623137e308, 1.797693134862314e308, 1.7976931348623141e308, 1.7976931348623143e308, 1.7976931348623145e308, 1.7976931348623147e308, 1.797693134862315e308, 1.7976931348623151e308, 1.7976931348623153e308, 1.7976931348623155e308, 1.7976931348623157e308, f64::INFINITY, ], ); } malachite-base-0.4.16/tests/num/exhaustive/positive_finite_primitive_floats_increasing.rs000064400000000000000000000054111046102023000303120ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::exhaustive::positive_finite_primitive_floats_increasing; use malachite_base::test_util::num::exhaustive::*; fn positive_finite_primitive_floats_increasing_helper( first_20: &[T], last_20: &[T], ) { exhaustive_primitive_floats_helper_helper_with_reverse( positive_finite_primitive_floats_increasing::(), first_20, last_20, ); } #[test] fn test_positive_finite_primitive_floats_increasing() { positive_finite_primitive_floats_increasing_helper::( &[ 1.0e-45, 3.0e-45, 4.0e-45, 6.0e-45, 7.0e-45, 8.0e-45, 1.0e-44, 1.1e-44, 1.3e-44, 1.4e-44, 1.5e-44, 1.7e-44, 1.8e-44, 2.0e-44, 2.1e-44, 2.2e-44, 2.4e-44, 2.5e-44, 2.7e-44, 2.8e-44, ], &[ 3.4028196e38, 3.4028198e38, 3.40282e38, 3.4028202e38, 3.4028204e38, 3.4028206e38, 3.4028208e38, 3.402821e38, 3.4028212e38, 3.4028214e38, 3.4028216e38, 3.4028218e38, 3.402822e38, 3.4028222e38, 3.4028225e38, 3.4028227e38, 3.4028229e38, 3.402823e38, 3.4028233e38, 3.4028235e38, ], ); positive_finite_primitive_floats_increasing_helper::( &[ 5.0e-324, 1.0e-323, 1.5e-323, 2.0e-323, 2.5e-323, 3.0e-323, 3.5e-323, 4.0e-323, 4.4e-323, 5.0e-323, 5.4e-323, 6.0e-323, 6.4e-323, 7.0e-323, 7.4e-323, 8.0e-323, 8.4e-323, 9.0e-323, 9.4e-323, 1.0e-322, ], &[ 1.797693134862312e308, 1.7976931348623121e308, 1.7976931348623123e308, 1.7976931348623125e308, 1.7976931348623127e308, 1.797693134862313e308, 1.7976931348623131e308, 1.7976931348623133e308, 1.7976931348623135e308, 1.7976931348623137e308, 1.797693134862314e308, 1.7976931348623141e308, 1.7976931348623143e308, 1.7976931348623145e308, 1.7976931348623147e308, 1.797693134862315e308, 1.7976931348623151e308, 1.7976931348623153e308, 1.7976931348623155e308, 1.7976931348623157e308, ], ); } malachite-base-0.4.16/tests/num/exhaustive/positive_primitive_floats_increasing.rs000064400000000000000000000053151046102023000267570ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::exhaustive::positive_primitive_floats_increasing; use malachite_base::test_util::num::exhaustive::*; fn positive_primitive_floats_increasing_helper(first_20: &[T], last_20: &[T]) { exhaustive_primitive_floats_helper_helper_with_reverse( positive_primitive_floats_increasing::(), first_20, last_20, ); } #[test] fn test_positive_primitive_floats_increasing() { positive_primitive_floats_increasing_helper::( &[ 1.0e-45, 3.0e-45, 4.0e-45, 6.0e-45, 7.0e-45, 8.0e-45, 1.0e-44, 1.1e-44, 1.3e-44, 1.4e-44, 1.5e-44, 1.7e-44, 1.8e-44, 2.0e-44, 2.1e-44, 2.2e-44, 2.4e-44, 2.5e-44, 2.7e-44, 2.8e-44, ], &[ 3.4028198e38, 3.40282e38, 3.4028202e38, 3.4028204e38, 3.4028206e38, 3.4028208e38, 3.402821e38, 3.4028212e38, 3.4028214e38, 3.4028216e38, 3.4028218e38, 3.402822e38, 3.4028222e38, 3.4028225e38, 3.4028227e38, 3.4028229e38, 3.402823e38, 3.4028233e38, 3.4028235e38, f32::INFINITY, ], ); positive_primitive_floats_increasing_helper::( &[ 5.0e-324, 1.0e-323, 1.5e-323, 2.0e-323, 2.5e-323, 3.0e-323, 3.5e-323, 4.0e-323, 4.4e-323, 5.0e-323, 5.4e-323, 6.0e-323, 6.4e-323, 7.0e-323, 7.4e-323, 8.0e-323, 8.4e-323, 9.0e-323, 9.4e-323, 1.0e-322, ], &[ 1.7976931348623121e308, 1.7976931348623123e308, 1.7976931348623125e308, 1.7976931348623127e308, 1.797693134862313e308, 1.7976931348623131e308, 1.7976931348623133e308, 1.7976931348623135e308, 1.7976931348623137e308, 1.797693134862314e308, 1.7976931348623141e308, 1.7976931348623143e308, 1.7976931348623145e308, 1.7976931348623147e308, 1.797693134862315e308, 1.7976931348623151e308, 1.7976931348623153e308, 1.7976931348623155e308, 1.7976931348623157e308, f64::INFINITY, ], ); } malachite-base-0.4.16/tests/num/exhaustive/primitive_float_increasing_inclusive_range.rs000064400000000000000000000462531046102023000301150ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::traits::NegativeInfinity; use malachite_base::num::exhaustive::primitive_float_increasing_inclusive_range; use malachite_base::test_util::num::exhaustive::*; use std::panic::catch_unwind; fn primitive_float_increasing_inclusive_range_helper( a: T, b: T, first_20: &[T], last_20: &[T], ) { exhaustive_primitive_floats_helper_helper_with_reverse( primitive_float_increasing_inclusive_range::(a, b), first_20, last_20, ); } #[allow(clippy::approx_constant)] #[test] fn test_primitive_float_increasing_inclusive_range() { primitive_float_increasing_inclusive_range_helper::(1.0, 1.0, &[1.0], &[1.0]); primitive_float_increasing_inclusive_range_helper::( 1.0, 2.0, &[ 1.0, 1.0000001, 1.0000002, 1.0000004, 1.0000005, 1.0000006, 1.0000007, 1.0000008, 1.000001, 1.0000011, 1.0000012, 1.0000013, 1.0000014, 1.0000015, 1.0000017, 1.0000018, 1.0000019, 1.000002, 1.0000021, 1.0000023, ], &[ 1.9999977, 1.9999979, 1.999998, 1.9999981, 1.9999982, 1.9999983, 1.9999985, 1.9999986, 1.9999987, 1.9999988, 1.9999989, 1.999999, 1.9999992, 1.9999993, 1.9999994, 1.9999995, 1.9999996, 1.9999998, 1.9999999, 2.0, ], ); primitive_float_increasing_inclusive_range_helper::( -0.1, 0.1, &[ -0.1, -0.099999994, -0.09999999, -0.09999998, -0.09999997, -0.099999964, -0.09999996, -0.09999995, -0.09999994, -0.099999934, -0.09999993, -0.09999992, -0.09999991, -0.099999905, -0.0999999, -0.09999989, -0.09999988, -0.099999875, -0.09999987, -0.09999986, ], &[ 0.09999986, 0.09999987, 0.099999875, 0.09999988, 0.09999989, 0.0999999, 0.099999905, 0.09999991, 0.09999992, 0.09999993, 0.099999934, 0.09999994, 0.09999995, 0.09999996, 0.099999964, 0.09999997, 0.09999998, 0.09999999, 0.099999994, 0.1, ], ); primitive_float_increasing_inclusive_range_helper::( core::f32::consts::E, core::f32::consts::PI, &[ core::f32::consts::E, 2.718282, 2.7182822, 2.7182825, 2.7182827, 2.718283, 2.7182832, 2.7182834, 2.7182837, 2.718284, 2.7182841, 2.7182844, 2.7182846, 2.7182848, 2.718285, 2.7182853, 2.7182856, 2.7182858, 2.718286, 2.7182863, ], &[ 3.1415882, 3.1415884, 3.1415887, 3.141589, 3.1415892, 3.1415894, 3.1415896, 3.1415899, 3.14159, 3.1415904, 3.1415906, 3.1415908, 3.141591, 3.1415913, 3.1415915, 3.1415918, 3.141592, 3.1415923, 3.1415925, core::f32::consts::PI, ], ); primitive_float_increasing_inclusive_range_helper::( 100.0, 101.0, &[ 100.0, 100.00001, 100.000015, 100.00002, 100.00003, 100.00004, 100.000046, 100.00005, 100.00006, 100.00007, 100.00008, 100.000084, 100.00009, 100.0001, 100.00011, 100.000114, 100.00012, 100.00013, 100.00014, 100.000145, ], &[ 100.999855, 100.99986, 100.99987, 100.99988, 100.999886, 100.99989, 100.9999, 100.99991, 100.999916, 100.99992, 100.99993, 100.99994, 100.99995, 100.999954, 100.99996, 100.99997, 100.99998, 100.999985, 100.99999, 101.0, ], ); primitive_float_increasing_inclusive_range_helper::( 1.0e38, f32::INFINITY, &[ 1.0e38, 1.0000001e38, 1.0000002e38, 1.0000003e38, 1.0000004e38, 1.0000005e38, 1.0000006e38, 1.0000007e38, 1.0000008e38, 1.0000009e38, 1.000001e38, 1.0000011e38, 1.0000012e38, 1.0000013e38, 1.0000014e38, 1.0000015e38, 1.0000016e38, 1.0000017e38, 1.0000018e38, 1.0000019e38, ], &[ 3.4028198e38, 3.40282e38, 3.4028202e38, 3.4028204e38, 3.4028206e38, 3.4028208e38, 3.402821e38, 3.4028212e38, 3.4028214e38, 3.4028216e38, 3.4028218e38, 3.402822e38, 3.4028222e38, 3.4028225e38, 3.4028227e38, 3.4028229e38, 3.402823e38, 3.4028233e38, 3.4028235e38, f32::INFINITY, ], ); primitive_float_increasing_inclusive_range_helper::( -f32::MIN_POSITIVE_SUBNORMAL, f32::MIN_POSITIVE_SUBNORMAL, &[-1.0e-45, -0.0, 0.0, 1.0e-45], &[-1.0e-45, -0.0, 0.0, 1.0e-45], ); primitive_float_increasing_inclusive_range_helper::( -0.0, f32::MIN_POSITIVE_SUBNORMAL, &[-0.0, 0.0, 1.0e-45], &[-0.0, 0.0, 1.0e-45], ); primitive_float_increasing_inclusive_range_helper::( 0.0, f32::MIN_POSITIVE_SUBNORMAL, &[0.0, 1.0e-45], &[0.0, 1.0e-45], ); primitive_float_increasing_inclusive_range_helper::( -f32::MIN_POSITIVE_SUBNORMAL, -0.0, &[-1.0e-45, -0.0], &[-1.0e-45, -0.0], ); primitive_float_increasing_inclusive_range_helper::( -f32::MIN_POSITIVE_SUBNORMAL, 0.0, &[-1.0e-45, -0.0, 0.0], &[-1.0e-45, -0.0, 0.0], ); primitive_float_increasing_inclusive_range_helper::( f32::NEGATIVE_INFINITY, f32::INFINITY, &[ f32::NEGATIVE_INFINITY, -3.4028235e38, -3.4028233e38, -3.402823e38, -3.4028229e38, -3.4028227e38, -3.4028225e38, -3.4028222e38, -3.402822e38, -3.4028218e38, -3.4028216e38, -3.4028214e38, -3.4028212e38, -3.402821e38, -3.4028208e38, -3.4028206e38, -3.4028204e38, -3.4028202e38, -3.40282e38, -3.4028198e38, ], &[ 3.4028198e38, 3.40282e38, 3.4028202e38, 3.4028204e38, 3.4028206e38, 3.4028208e38, 3.402821e38, 3.4028212e38, 3.4028214e38, 3.4028216e38, 3.4028218e38, 3.402822e38, 3.4028222e38, 3.4028225e38, 3.4028227e38, 3.4028229e38, 3.402823e38, 3.4028233e38, 3.4028235e38, f32::INFINITY, ], ); primitive_float_increasing_inclusive_range_helper::( f32::NEGATIVE_INFINITY, f32::NEGATIVE_INFINITY, &[f32::NEGATIVE_INFINITY], &[f32::NEGATIVE_INFINITY], ); primitive_float_increasing_inclusive_range_helper::( f32::INFINITY, f32::INFINITY, &[f32::INFINITY], &[f32::INFINITY], ); primitive_float_increasing_inclusive_range_helper::(0.0, 0.0, &[0.0], &[0.0]); primitive_float_increasing_inclusive_range_helper::(-0.0, -0.0, &[-0.0], &[-0.0]); primitive_float_increasing_inclusive_range_helper::(-0.0, 0.0, &[-0.0, 0.0], &[-0.0, 0.0]); primitive_float_increasing_inclusive_range_helper::(1.0, 1.0, &[1.0], &[1.0]); primitive_float_increasing_inclusive_range_helper::( 1.0, 2.0, &[ 1.0, 1.0000000000000002, 1.0000000000000004, 1.0000000000000007, 1.0000000000000009, 1.000000000000001, 1.0000000000000013, 1.0000000000000016, 1.0000000000000018, 1.000000000000002, 1.0000000000000022, 1.0000000000000024, 1.0000000000000027, 1.0000000000000029, 1.000000000000003, 1.0000000000000033, 1.0000000000000036, 1.0000000000000038, 1.000000000000004, 1.0000000000000042, ], &[ 1.9999999999999958, 1.999999999999996, 1.9999999999999962, 1.9999999999999964, 1.9999999999999967, 1.999999999999997, 1.9999999999999971, 1.9999999999999973, 1.9999999999999976, 1.9999999999999978, 1.999999999999998, 1.9999999999999982, 1.9999999999999984, 1.9999999999999987, 1.999999999999999, 1.9999999999999991, 1.9999999999999993, 1.9999999999999996, 1.9999999999999998, 2.0, ], ); primitive_float_increasing_inclusive_range_helper::( -0.1, 0.1, &[ -0.1, -0.09999999999999999, -0.09999999999999998, -0.09999999999999996, -0.09999999999999995, -0.09999999999999994, -0.09999999999999992, -0.09999999999999991, -0.0999999999999999, -0.09999999999999988, -0.09999999999999987, -0.09999999999999985, -0.09999999999999984, -0.09999999999999983, -0.09999999999999981, -0.0999999999999998, -0.09999999999999978, -0.09999999999999977, -0.09999999999999976, -0.09999999999999974, ], &[ 0.09999999999999974, 0.09999999999999976, 0.09999999999999977, 0.09999999999999978, 0.0999999999999998, 0.09999999999999981, 0.09999999999999983, 0.09999999999999984, 0.09999999999999985, 0.09999999999999987, 0.09999999999999988, 0.0999999999999999, 0.09999999999999991, 0.09999999999999992, 0.09999999999999994, 0.09999999999999995, 0.09999999999999996, 0.09999999999999998, 0.09999999999999999, 0.1, ], ); primitive_float_increasing_inclusive_range_helper::( core::f64::consts::E, core::f64::consts::PI, &[ core::f64::consts::E, 2.7182818284590455, 2.718281828459046, 2.7182818284590464, 2.718281828459047, 2.7182818284590473, 2.7182818284590478, 2.718281828459048, 2.7182818284590486, 2.718281828459049, 2.7182818284590495, 2.71828182845905, 2.7182818284590504, 2.718281828459051, 2.7182818284590513, 2.7182818284590518, 2.718281828459052, 2.7182818284590526, 2.718281828459053, 2.7182818284590535, ], &[ 3.1415926535897847, 3.141592653589785, 3.1415926535897856, 3.141592653589786, 3.1415926535897865, 3.141592653589787, 3.1415926535897873, 3.141592653589788, 3.1415926535897882, 3.1415926535897887, 3.141592653589789, 3.1415926535897896, 3.14159265358979, 3.1415926535897905, 3.141592653589791, 3.1415926535897913, 3.141592653589792, 3.1415926535897922, 3.1415926535897927, core::f64::consts::PI, ], ); primitive_float_increasing_inclusive_range_helper::( 100.0, 101.0, &[ 100.0, 100.00000000000001, 100.00000000000003, 100.00000000000004, 100.00000000000006, 100.00000000000007, 100.00000000000009, 100.0000000000001, 100.00000000000011, 100.00000000000013, 100.00000000000014, 100.00000000000016, 100.00000000000017, 100.00000000000018, 100.0000000000002, 100.00000000000021, 100.00000000000023, 100.00000000000024, 100.00000000000026, 100.00000000000027, ], &[ 100.99999999999973, 100.99999999999974, 100.99999999999976, 100.99999999999977, 100.99999999999979, 100.9999999999998, 100.99999999999982, 100.99999999999983, 100.99999999999984, 100.99999999999986, 100.99999999999987, 100.99999999999989, 100.9999999999999, 100.99999999999991, 100.99999999999993, 100.99999999999994, 100.99999999999996, 100.99999999999997, 100.99999999999999, 101.0, ], ); primitive_float_increasing_inclusive_range_helper::( 1.0e308, f64::INFINITY, &[ 1.0e308, 1.0000000000000002e308, 1.0000000000000004e308, 1.0000000000000006e308, 1.0000000000000008e308, 1.000000000000001e308, 1.0000000000000012e308, 1.0000000000000014e308, 1.0000000000000016e308, 1.0000000000000018e308, 1.000000000000002e308, 1.0000000000000022e308, 1.0000000000000024e308, 1.0000000000000026e308, 1.0000000000000028e308, 1.000000000000003e308, 1.0000000000000032e308, 1.0000000000000034e308, 1.0000000000000036e308, 1.0000000000000038e308, ], &[ 1.7976931348623121e308, 1.7976931348623123e308, 1.7976931348623125e308, 1.7976931348623127e308, 1.797693134862313e308, 1.7976931348623131e308, 1.7976931348623133e308, 1.7976931348623135e308, 1.7976931348623137e308, 1.797693134862314e308, 1.7976931348623141e308, 1.7976931348623143e308, 1.7976931348623145e308, 1.7976931348623147e308, 1.797693134862315e308, 1.7976931348623151e308, 1.7976931348623153e308, 1.7976931348623155e308, 1.7976931348623157e308, f64::INFINITY, ], ); primitive_float_increasing_inclusive_range_helper::( -f64::MIN_POSITIVE_SUBNORMAL, f64::MIN_POSITIVE_SUBNORMAL, &[-5.0e-324, -0.0, 0.0, 5.0e-324], &[-5.0e-324, -0.0, 0.0, 5.0e-324], ); primitive_float_increasing_inclusive_range_helper::( -0.0, f64::MIN_POSITIVE_SUBNORMAL, &[-0.0, 0.0, 5.0e-324], &[-0.0, 0.0, 5.0e-324], ); primitive_float_increasing_inclusive_range_helper::( 0.0, f64::MIN_POSITIVE_SUBNORMAL, &[0.0, 5.0e-324], &[0.0, 5.0e-324], ); primitive_float_increasing_inclusive_range_helper::( -f64::MIN_POSITIVE_SUBNORMAL, -0.0, &[-5.0e-324, -0.0], &[-5.0e-324, -0.0], ); primitive_float_increasing_inclusive_range_helper::( -f64::MIN_POSITIVE_SUBNORMAL, 0.0, &[-5.0e-324, -0.0, 0.0], &[-5.0e-324, -0.0, 0.0], ); primitive_float_increasing_inclusive_range_helper::( f64::NEGATIVE_INFINITY, f64::INFINITY, &[ f64::NEGATIVE_INFINITY, -1.7976931348623157e308, -1.7976931348623155e308, -1.7976931348623153e308, -1.7976931348623151e308, -1.797693134862315e308, -1.7976931348623147e308, -1.7976931348623145e308, -1.7976931348623143e308, -1.7976931348623141e308, -1.797693134862314e308, -1.7976931348623137e308, -1.7976931348623135e308, -1.7976931348623133e308, -1.7976931348623131e308, -1.797693134862313e308, -1.7976931348623127e308, -1.7976931348623125e308, -1.7976931348623123e308, -1.7976931348623121e308, ], &[ 1.7976931348623121e308, 1.7976931348623123e308, 1.7976931348623125e308, 1.7976931348623127e308, 1.797693134862313e308, 1.7976931348623131e308, 1.7976931348623133e308, 1.7976931348623135e308, 1.7976931348623137e308, 1.797693134862314e308, 1.7976931348623141e308, 1.7976931348623143e308, 1.7976931348623145e308, 1.7976931348623147e308, 1.797693134862315e308, 1.7976931348623151e308, 1.7976931348623153e308, 1.7976931348623155e308, 1.7976931348623157e308, f64::INFINITY, ], ); primitive_float_increasing_inclusive_range_helper::( f64::NEGATIVE_INFINITY, f64::NEGATIVE_INFINITY, &[f64::NEGATIVE_INFINITY], &[f64::NEGATIVE_INFINITY], ); primitive_float_increasing_inclusive_range_helper::( f64::INFINITY, f64::INFINITY, &[f64::INFINITY], &[f64::INFINITY], ); primitive_float_increasing_inclusive_range_helper::(0.0, 0.0, &[0.0], &[0.0]); primitive_float_increasing_inclusive_range_helper::(-0.0, -0.0, &[-0.0], &[-0.0]); primitive_float_increasing_inclusive_range_helper::(-0.0, 0.0, &[-0.0, 0.0], &[-0.0, 0.0]); } fn primitive_float_increasing_inclusive_range_fail_helper() { assert_panic!(primitive_float_increasing_inclusive_range::( T::ONE, T::ZERO )); assert_panic!(primitive_float_increasing_inclusive_range::( T::ONE, T::NAN )); } #[test] fn primitive_float_increasing_inclusive_range_fail() { apply_fn_to_primitive_floats!(primitive_float_increasing_inclusive_range_fail_helper); } malachite-base-0.4.16/tests/num/exhaustive/primitive_float_increasing_range.rs000064400000000000000000000442141046102023000260270ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::traits::NegativeInfinity; use malachite_base::num::exhaustive::primitive_float_increasing_range; use malachite_base::test_util::num::exhaustive::*; use std::panic::catch_unwind; fn primitive_float_increasing_range_helper( a: T, b: T, first_20: &[T], last_20: &[T], ) { exhaustive_primitive_floats_helper_helper_with_reverse( primitive_float_increasing_range::(a, b), first_20, last_20, ); } #[allow(clippy::approx_constant)] #[test] fn test_primitive_float_increasing_range() { primitive_float_increasing_range_helper::(1.0, 1.0, &[], &[]); primitive_float_increasing_range_helper::( 1.0, 2.0, &[ 1.0, 1.0000001, 1.0000002, 1.0000004, 1.0000005, 1.0000006, 1.0000007, 1.0000008, 1.000001, 1.0000011, 1.0000012, 1.0000013, 1.0000014, 1.0000015, 1.0000017, 1.0000018, 1.0000019, 1.000002, 1.0000021, 1.0000023, ], &[ 1.9999976, 1.9999977, 1.9999979, 1.999998, 1.9999981, 1.9999982, 1.9999983, 1.9999985, 1.9999986, 1.9999987, 1.9999988, 1.9999989, 1.999999, 1.9999992, 1.9999993, 1.9999994, 1.9999995, 1.9999996, 1.9999998, 1.9999999, ], ); primitive_float_increasing_range_helper::( -0.1, 0.1, &[ -0.1, -0.099999994, -0.09999999, -0.09999998, -0.09999997, -0.099999964, -0.09999996, -0.09999995, -0.09999994, -0.099999934, -0.09999993, -0.09999992, -0.09999991, -0.099999905, -0.0999999, -0.09999989, -0.09999988, -0.099999875, -0.09999987, -0.09999986, ], &[ 0.09999985, 0.09999986, 0.09999987, 0.099999875, 0.09999988, 0.09999989, 0.0999999, 0.099999905, 0.09999991, 0.09999992, 0.09999993, 0.099999934, 0.09999994, 0.09999995, 0.09999996, 0.099999964, 0.09999997, 0.09999998, 0.09999999, 0.099999994, ], ); primitive_float_increasing_range_helper::( core::f32::consts::E, core::f32::consts::PI, &[ core::f32::consts::E, 2.718282, 2.7182822, 2.7182825, 2.7182827, 2.718283, 2.7182832, 2.7182834, 2.7182837, 2.718284, 2.7182841, 2.7182844, 2.7182846, 2.7182848, 2.718285, 2.7182853, 2.7182856, 2.7182858, 2.718286, 2.7182863, ], &[ 3.141588, 3.1415882, 3.1415884, 3.1415887, 3.141589, 3.1415892, 3.1415894, 3.1415896, 3.1415899, 3.14159, 3.1415904, 3.1415906, 3.1415908, 3.141591, 3.1415913, 3.1415915, 3.1415918, 3.141592, 3.1415923, 3.1415925, ], ); primitive_float_increasing_range_helper::( 100.0, 101.0, &[ 100.0, 100.00001, 100.000015, 100.00002, 100.00003, 100.00004, 100.000046, 100.00005, 100.00006, 100.00007, 100.00008, 100.000084, 100.00009, 100.0001, 100.00011, 100.000114, 100.00012, 100.00013, 100.00014, 100.000145, ], &[ 100.99985, 100.999855, 100.99986, 100.99987, 100.99988, 100.999886, 100.99989, 100.9999, 100.99991, 100.999916, 100.99992, 100.99993, 100.99994, 100.99995, 100.999954, 100.99996, 100.99997, 100.99998, 100.999985, 100.99999, ], ); primitive_float_increasing_range_helper::( 1.0e38, f32::INFINITY, &[ 1.0e38, 1.0000001e38, 1.0000002e38, 1.0000003e38, 1.0000004e38, 1.0000005e38, 1.0000006e38, 1.0000007e38, 1.0000008e38, 1.0000009e38, 1.000001e38, 1.0000011e38, 1.0000012e38, 1.0000013e38, 1.0000014e38, 1.0000015e38, 1.0000016e38, 1.0000017e38, 1.0000018e38, 1.0000019e38, ], &[ 3.4028196e38, 3.4028198e38, 3.40282e38, 3.4028202e38, 3.4028204e38, 3.4028206e38, 3.4028208e38, 3.402821e38, 3.4028212e38, 3.4028214e38, 3.4028216e38, 3.4028218e38, 3.402822e38, 3.4028222e38, 3.4028225e38, 3.4028227e38, 3.4028229e38, 3.402823e38, 3.4028233e38, 3.4028235e38, ], ); primitive_float_increasing_range_helper::( -f32::MIN_POSITIVE_SUBNORMAL, f32::MIN_POSITIVE_SUBNORMAL, &[-1.0e-45, -0.0, 0.0], &[-1.0e-45, -0.0, 0.0], ); primitive_float_increasing_range_helper::( -0.0, f32::MIN_POSITIVE_SUBNORMAL, &[-0.0, 0.0], &[-0.0, 0.0], ); primitive_float_increasing_range_helper::( 0.0, f32::MIN_POSITIVE_SUBNORMAL, &[0.0], &[0.0], ); primitive_float_increasing_range_helper::( -f32::MIN_POSITIVE_SUBNORMAL, -0.0, &[-1.0e-45], &[-1.0e-45], ); primitive_float_increasing_range_helper::( -f32::MIN_POSITIVE_SUBNORMAL, 0.0, &[-1.0e-45, -0.0], &[-1.0e-45, -0.0], ); primitive_float_increasing_range_helper::( f32::NEGATIVE_INFINITY, f32::INFINITY, &[ f32::NEGATIVE_INFINITY, -3.4028235e38, -3.4028233e38, -3.402823e38, -3.4028229e38, -3.4028227e38, -3.4028225e38, -3.4028222e38, -3.402822e38, -3.4028218e38, -3.4028216e38, -3.4028214e38, -3.4028212e38, -3.402821e38, -3.4028208e38, -3.4028206e38, -3.4028204e38, -3.4028202e38, -3.40282e38, -3.4028198e38, ], &[ 3.4028196e38, 3.4028198e38, 3.40282e38, 3.4028202e38, 3.4028204e38, 3.4028206e38, 3.4028208e38, 3.402821e38, 3.4028212e38, 3.4028214e38, 3.4028216e38, 3.4028218e38, 3.402822e38, 3.4028222e38, 3.4028225e38, 3.4028227e38, 3.4028229e38, 3.402823e38, 3.4028233e38, 3.4028235e38, ], ); primitive_float_increasing_range_helper::( f32::NEGATIVE_INFINITY, f32::NEGATIVE_INFINITY, &[], &[], ); primitive_float_increasing_range_helper::(f32::INFINITY, f32::INFINITY, &[], &[]); primitive_float_increasing_range_helper::(0.0, 0.0, &[], &[]); primitive_float_increasing_range_helper::(-0.0, -0.0, &[], &[]); primitive_float_increasing_range_helper::(-0.0, 0.0, &[-0.0], &[-0.0]); primitive_float_increasing_range_helper::(1.0, 1.0, &[], &[]); primitive_float_increasing_range_helper::( 1.0, 2.0, &[ 1.0, 1.0000000000000002, 1.0000000000000004, 1.0000000000000007, 1.0000000000000009, 1.000000000000001, 1.0000000000000013, 1.0000000000000016, 1.0000000000000018, 1.000000000000002, 1.0000000000000022, 1.0000000000000024, 1.0000000000000027, 1.0000000000000029, 1.000000000000003, 1.0000000000000033, 1.0000000000000036, 1.0000000000000038, 1.000000000000004, 1.0000000000000042, ], &[ 1.9999999999999956, 1.9999999999999958, 1.999999999999996, 1.9999999999999962, 1.9999999999999964, 1.9999999999999967, 1.999999999999997, 1.9999999999999971, 1.9999999999999973, 1.9999999999999976, 1.9999999999999978, 1.999999999999998, 1.9999999999999982, 1.9999999999999984, 1.9999999999999987, 1.999999999999999, 1.9999999999999991, 1.9999999999999993, 1.9999999999999996, 1.9999999999999998, ], ); primitive_float_increasing_range_helper::( -0.1, 0.1, &[ -0.1, -0.09999999999999999, -0.09999999999999998, -0.09999999999999996, -0.09999999999999995, -0.09999999999999994, -0.09999999999999992, -0.09999999999999991, -0.0999999999999999, -0.09999999999999988, -0.09999999999999987, -0.09999999999999985, -0.09999999999999984, -0.09999999999999983, -0.09999999999999981, -0.0999999999999998, -0.09999999999999978, -0.09999999999999977, -0.09999999999999976, -0.09999999999999974, ], &[ 0.09999999999999973, 0.09999999999999974, 0.09999999999999976, 0.09999999999999977, 0.09999999999999978, 0.0999999999999998, 0.09999999999999981, 0.09999999999999983, 0.09999999999999984, 0.09999999999999985, 0.09999999999999987, 0.09999999999999988, 0.0999999999999999, 0.09999999999999991, 0.09999999999999992, 0.09999999999999994, 0.09999999999999995, 0.09999999999999996, 0.09999999999999998, 0.09999999999999999, ], ); primitive_float_increasing_range_helper::( core::f64::consts::E, core::f64::consts::PI, &[ core::f64::consts::E, 2.7182818284590455, 2.718281828459046, 2.7182818284590464, 2.718281828459047, 2.7182818284590473, 2.7182818284590478, 2.718281828459048, 2.7182818284590486, 2.718281828459049, 2.7182818284590495, 2.71828182845905, 2.7182818284590504, 2.718281828459051, 2.7182818284590513, 2.7182818284590518, 2.718281828459052, 2.7182818284590526, 2.718281828459053, 2.7182818284590535, ], &[ 3.1415926535897842, 3.1415926535897847, 3.141592653589785, 3.1415926535897856, 3.141592653589786, 3.1415926535897865, 3.141592653589787, 3.1415926535897873, 3.141592653589788, 3.1415926535897882, 3.1415926535897887, 3.141592653589789, 3.1415926535897896, 3.14159265358979, 3.1415926535897905, 3.141592653589791, 3.1415926535897913, 3.141592653589792, 3.1415926535897922, 3.1415926535897927, ], ); primitive_float_increasing_range_helper::( 100.0, 101.0, &[ 100.0, 100.00000000000001, 100.00000000000003, 100.00000000000004, 100.00000000000006, 100.00000000000007, 100.00000000000009, 100.0000000000001, 100.00000000000011, 100.00000000000013, 100.00000000000014, 100.00000000000016, 100.00000000000017, 100.00000000000018, 100.0000000000002, 100.00000000000021, 100.00000000000023, 100.00000000000024, 100.00000000000026, 100.00000000000027, ], &[ 100.99999999999972, 100.99999999999973, 100.99999999999974, 100.99999999999976, 100.99999999999977, 100.99999999999979, 100.9999999999998, 100.99999999999982, 100.99999999999983, 100.99999999999984, 100.99999999999986, 100.99999999999987, 100.99999999999989, 100.9999999999999, 100.99999999999991, 100.99999999999993, 100.99999999999994, 100.99999999999996, 100.99999999999997, 100.99999999999999, ], ); primitive_float_increasing_range_helper::( 1.0e308, f64::INFINITY, &[ 1.0e308, 1.0000000000000002e308, 1.0000000000000004e308, 1.0000000000000006e308, 1.0000000000000008e308, 1.000000000000001e308, 1.0000000000000012e308, 1.0000000000000014e308, 1.0000000000000016e308, 1.0000000000000018e308, 1.000000000000002e308, 1.0000000000000022e308, 1.0000000000000024e308, 1.0000000000000026e308, 1.0000000000000028e308, 1.000000000000003e308, 1.0000000000000032e308, 1.0000000000000034e308, 1.0000000000000036e308, 1.0000000000000038e308, ], &[ 1.797693134862312e308, 1.7976931348623121e308, 1.7976931348623123e308, 1.7976931348623125e308, 1.7976931348623127e308, 1.797693134862313e308, 1.7976931348623131e308, 1.7976931348623133e308, 1.7976931348623135e308, 1.7976931348623137e308, 1.797693134862314e308, 1.7976931348623141e308, 1.7976931348623143e308, 1.7976931348623145e308, 1.7976931348623147e308, 1.797693134862315e308, 1.7976931348623151e308, 1.7976931348623153e308, 1.7976931348623155e308, 1.7976931348623157e308, ], ); primitive_float_increasing_range_helper::( -f64::MIN_POSITIVE_SUBNORMAL, f64::MIN_POSITIVE_SUBNORMAL, &[-5.0e-324, -0.0, 0.0], &[-5.0e-324, -0.0, 0.0], ); primitive_float_increasing_range_helper::( -0.0, f64::MIN_POSITIVE_SUBNORMAL, &[-0.0, 0.0], &[-0.0, 0.0], ); primitive_float_increasing_range_helper::( 0.0, f64::MIN_POSITIVE_SUBNORMAL, &[0.0], &[0.0], ); primitive_float_increasing_range_helper::( -f64::MIN_POSITIVE_SUBNORMAL, -0.0, &[-5.0e-324], &[-5.0e-324], ); primitive_float_increasing_range_helper::( -f64::MIN_POSITIVE_SUBNORMAL, 0.0, &[-5.0e-324, -0.0], &[-5.0e-324, -0.0], ); primitive_float_increasing_range_helper::( f64::NEGATIVE_INFINITY, f64::INFINITY, &[ f64::NEGATIVE_INFINITY, -1.7976931348623157e308, -1.7976931348623155e308, -1.7976931348623153e308, -1.7976931348623151e308, -1.797693134862315e308, -1.7976931348623147e308, -1.7976931348623145e308, -1.7976931348623143e308, -1.7976931348623141e308, -1.797693134862314e308, -1.7976931348623137e308, -1.7976931348623135e308, -1.7976931348623133e308, -1.7976931348623131e308, -1.797693134862313e308, -1.7976931348623127e308, -1.7976931348623125e308, -1.7976931348623123e308, -1.7976931348623121e308, ], &[ 1.797693134862312e308, 1.7976931348623121e308, 1.7976931348623123e308, 1.7976931348623125e308, 1.7976931348623127e308, 1.797693134862313e308, 1.7976931348623131e308, 1.7976931348623133e308, 1.7976931348623135e308, 1.7976931348623137e308, 1.797693134862314e308, 1.7976931348623141e308, 1.7976931348623143e308, 1.7976931348623145e308, 1.7976931348623147e308, 1.797693134862315e308, 1.7976931348623151e308, 1.7976931348623153e308, 1.7976931348623155e308, 1.7976931348623157e308, ], ); primitive_float_increasing_range_helper::( f64::NEGATIVE_INFINITY, f64::NEGATIVE_INFINITY, &[], &[], ); primitive_float_increasing_range_helper::(f64::INFINITY, f64::INFINITY, &[], &[]); primitive_float_increasing_range_helper::(0.0, 0.0, &[], &[]); primitive_float_increasing_range_helper::(-0.0, -0.0, &[], &[]); primitive_float_increasing_range_helper::(-0.0, 0.0, &[-0.0], &[-0.0]); } fn primitive_float_increasing_range_fail_helper() { assert_panic!(primitive_float_increasing_range::(T::ONE, T::ZERO)); assert_panic!(primitive_float_increasing_range::(T::ONE, T::NAN)); } #[test] fn primitive_float_increasing_range_fail() { apply_fn_to_primitive_floats!(primitive_float_increasing_range_fail_helper); } malachite-base-0.4.16/tests/num/exhaustive/primitive_floats_increasing.rs000064400000000000000000000070151046102023000250340ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::traits::NegativeInfinity; use malachite_base::num::exhaustive::primitive_floats_increasing; use malachite_base::test_util::num::exhaustive::*; fn primitive_floats_increasing_helper(first_20: &[T], last_20: &[T]) { exhaustive_primitive_floats_helper_helper_with_reverse( primitive_floats_increasing::(), first_20, last_20, ); } #[test] fn test_primitive_floats_increasing() { primitive_floats_increasing_helper::( &[ f32::NEGATIVE_INFINITY, -3.4028235e38, -3.4028233e38, -3.402823e38, -3.4028229e38, -3.4028227e38, -3.4028225e38, -3.4028222e38, -3.402822e38, -3.4028218e38, -3.4028216e38, -3.4028214e38, -3.4028212e38, -3.402821e38, -3.4028208e38, -3.4028206e38, -3.4028204e38, -3.4028202e38, -3.40282e38, -3.4028198e38, ], &[ 3.4028198e38, 3.40282e38, 3.4028202e38, 3.4028204e38, 3.4028206e38, 3.4028208e38, 3.402821e38, 3.4028212e38, 3.4028214e38, 3.4028216e38, 3.4028218e38, 3.402822e38, 3.4028222e38, 3.4028225e38, 3.4028227e38, 3.4028229e38, 3.402823e38, 3.4028233e38, 3.4028235e38, f32::INFINITY, ], ); primitive_floats_increasing_helper::( &[ f64::NEGATIVE_INFINITY, -1.7976931348623157e308, -1.7976931348623155e308, -1.7976931348623153e308, -1.7976931348623151e308, -1.797693134862315e308, -1.7976931348623147e308, -1.7976931348623145e308, -1.7976931348623143e308, -1.7976931348623141e308, -1.797693134862314e308, -1.7976931348623137e308, -1.7976931348623135e308, -1.7976931348623133e308, -1.7976931348623131e308, -1.797693134862313e308, -1.7976931348623127e308, -1.7976931348623125e308, -1.7976931348623123e308, -1.7976931348623121e308, ], &[ 1.7976931348623121e308, 1.7976931348623123e308, 1.7976931348623125e308, 1.7976931348623127e308, 1.797693134862313e308, 1.7976931348623131e308, 1.7976931348623133e308, 1.7976931348623135e308, 1.7976931348623137e308, 1.797693134862314e308, 1.7976931348623141e308, 1.7976931348623143e308, 1.7976931348623145e308, 1.7976931348623147e308, 1.797693134862315e308, 1.7976931348623151e308, 1.7976931348623153e308, 1.7976931348623155e308, 1.7976931348623157e308, f64::INFINITY, ], ); } malachite-base-0.4.16/tests/num/exhaustive/primitive_int_increasing_inclusive_range.rs000064400000000000000000000157751046102023000276070ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::conversion::traits::{ExactFrom, WrappingFrom}; use malachite_base::num::exhaustive::primitive_int_increasing_inclusive_range; use std::panic::catch_unwind; fn expected_range_len(a: T, b: T) -> usize where usize: WrappingFrom, { usize::wrapping_from(b).wrapping_sub(usize::wrapping_from(a)) + 1 } fn primitive_int_increasing_inclusive_range_helper_helper( a: T, b: T, values: &[i8], ) where i8: ExactFrom, usize: WrappingFrom, { let xs = primitive_int_increasing_inclusive_range::(a, b) .map(i8::exact_from) .take(20) .collect_vec(); assert_eq!(xs, values); if T::WIDTH <= u16::WIDTH { let len = expected_range_len(a, b); assert_eq!(primitive_int_increasing_inclusive_range(a, b).count(), len); let mut init = primitive_int_increasing_inclusive_range::(a, b) .rev() .skip(len.saturating_sub(20)) .map(i8::exact_from) .collect_vec(); init.reverse(); assert_eq!(xs, init); } } fn primitive_int_increasing_inclusive_range_rev_helper( a: T, b: T, rev_values: &[T], ) where usize: WrappingFrom, { let xs = primitive_int_increasing_inclusive_range::(a, b) .rev() .take(20) .collect_vec(); assert_eq!(xs, rev_values); if T::WIDTH <= u16::WIDTH { let len = expected_range_len(a, b); assert_eq!( primitive_int_increasing_inclusive_range(a, b).rev().count(), len ); let mut tail = primitive_int_increasing_inclusive_range::(a, b) .skip(len.saturating_sub(20)) .collect_vec(); tail.reverse(); assert_eq!(xs, tail); } } fn primitive_int_increasing_inclusive_range_helper() where i8: ExactFrom, usize: WrappingFrom, { primitive_int_increasing_inclusive_range_helper_helper( T::exact_from(5), T::exact_from(5), &[5], ); primitive_int_increasing_inclusive_range_helper_helper( T::ONE, T::exact_from(6), &[1, 2, 3, 4, 5, 6], ); primitive_int_increasing_inclusive_range_helper_helper( T::exact_from(10), T::exact_from(19), &[10, 11, 12, 13, 14, 15, 16, 17, 18, 19], ); primitive_int_increasing_inclusive_range_helper_helper( T::ZERO, T::MAX, &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], ); primitive_int_increasing_inclusive_range_helper_helper( T::ZERO, T::MAX - T::ONE, &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], ); } fn primitive_int_increasing_inclusive_range_helper_signed() where i8: ExactFrom, usize: WrappingFrom, { primitive_int_increasing_inclusive_range_helper_helper( T::exact_from(-20), T::exact_from(-11), &[-20, -19, -18, -17, -16, -15, -14, -13, -12, -11], ); primitive_int_increasing_inclusive_range_helper_helper( T::exact_from(-100), T::exact_from(99), &[ -100, -99, -98, -97, -96, -95, -94, -93, -92, -91, -90, -89, -88, -87, -86, -85, -84, -83, -82, -81, ], ); } #[test] fn test_primitive_int_increasing_inclusive_range() { apply_fn_to_primitive_ints!(primitive_int_increasing_inclusive_range_helper); apply_fn_to_signeds!(primitive_int_increasing_inclusive_range_helper_signed); primitive_int_increasing_inclusive_range_rev_helper::( 0, u8::MAX, &[ 255, 254, 253, 252, 251, 250, 249, 248, 247, 246, 245, 244, 243, 242, 241, 240, 239, 238, 237, 236, ], ); primitive_int_increasing_inclusive_range_rev_helper::( 0, u8::MAX - 1, &[ 254, 253, 252, 251, 250, 249, 248, 247, 246, 245, 244, 243, 242, 241, 240, 239, 238, 237, 236, 235, ], ); primitive_int_increasing_inclusive_range_rev_helper::( 0, u16::MAX, &[ 65535, 65534, 65533, 65532, 65531, 65530, 65529, 65528, 65527, 65526, 65525, 65524, 65523, 65522, 65521, 65520, 65519, 65518, 65517, 65516, ], ); primitive_int_increasing_inclusive_range_rev_helper::( 0, u16::MAX - 1, &[ 65534, 65533, 65532, 65531, 65530, 65529, 65528, 65527, 65526, 65525, 65524, 65523, 65522, 65521, 65520, 65519, 65518, 65517, 65516, 65515, ], ); primitive_int_increasing_inclusive_range_helper_helper::( i8::MIN, i8::MAX, &[ -128, -127, -126, -125, -124, -123, -122, -121, -120, -119, -118, -117, -116, -115, -114, -113, -112, -111, -110, -109, ], ); primitive_int_increasing_inclusive_range_helper_helper::( i8::MIN + 1, i8::MAX - 1, &[ -127, -126, -125, -124, -123, -122, -121, -120, -119, -118, -117, -116, -115, -114, -113, -112, -111, -110, -109, -108, ], ); primitive_int_increasing_inclusive_range_rev_helper::( i8::MIN, i8::MAX, &[ 127, 126, 125, 124, 123, 122, 121, 120, 119, 118, 117, 116, 115, 114, 113, 112, 111, 110, 109, 108, ], ); primitive_int_increasing_inclusive_range_rev_helper::( i8::MIN + 1, i8::MAX - 1, &[ 126, 125, 124, 123, 122, 121, 120, 119, 118, 117, 116, 115, 114, 113, 112, 111, 110, 109, 108, 107, ], ); primitive_int_increasing_inclusive_range_rev_helper::( i16::MIN, i16::MAX, &[ 32767, 32766, 32765, 32764, 32763, 32762, 32761, 32760, 32759, 32758, 32757, 32756, 32755, 32754, 32753, 32752, 32751, 32750, 32749, 32748, ], ); primitive_int_increasing_inclusive_range_rev_helper::( i16::MIN + 1, i16::MAX - 1, &[ 32766, 32765, 32764, 32763, 32762, 32761, 32760, 32759, 32758, 32757, 32756, 32755, 32754, 32753, 32752, 32751, 32750, 32749, 32748, 32747, ], ); } fn primitive_int_increasing_inclusive_range_fail_helper() { assert_panic!(primitive_int_increasing_inclusive_range::( T::ONE, T::ZERO )); } #[test] fn primitive_int_increasing_inclusive_range_fail() { apply_fn_to_primitive_ints!(primitive_int_increasing_inclusive_range_fail_helper); } malachite-base-0.4.16/tests/num/exhaustive/primitive_int_increasing_range.rs000064400000000000000000000151431046102023000255130ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::conversion::traits::{ExactFrom, WrappingFrom}; use malachite_base::num::exhaustive::primitive_int_increasing_range; use std::panic::catch_unwind; fn expected_range_len(a: T, b: T) -> usize where usize: WrappingFrom, { usize::wrapping_from(b).wrapping_sub(usize::wrapping_from(a)) } fn primitive_int_increasing_range_helper_helper(a: T, b: T, values: &[i8]) where i8: ExactFrom, usize: WrappingFrom, { let xs = primitive_int_increasing_range::(a, b) .map(i8::exact_from) .take(20) .collect_vec(); assert_eq!(xs, values); if T::WIDTH <= u16::WIDTH { let len = expected_range_len(a, b); assert_eq!(primitive_int_increasing_range(a, b).count(), len); let mut init = primitive_int_increasing_range::(a, b) .rev() .skip(len.saturating_sub(20)) .map(i8::exact_from) .collect_vec(); init.reverse(); assert_eq!(xs, init); } } fn primitive_int_increasing_range_rev_helper(a: T, b: T, rev_values: &[T]) where usize: WrappingFrom, { let xs = primitive_int_increasing_range::(a, b) .rev() .take(20) .collect_vec(); assert_eq!(xs, rev_values); if T::WIDTH <= u16::WIDTH { let len = expected_range_len(a, b); assert_eq!(primitive_int_increasing_range(a, b).rev().count(), len); let mut tail = primitive_int_increasing_range::(a, b) .skip(len.saturating_sub(20)) .collect_vec(); tail.reverse(); assert_eq!(xs, tail); } } fn primitive_int_increasing_range_helper() where i8: ExactFrom, usize: WrappingFrom, { primitive_int_increasing_range_helper_helper(T::exact_from(5), T::exact_from(5), &[]); primitive_int_increasing_range_helper_helper(T::exact_from(5), T::exact_from(6), &[5]); primitive_int_increasing_range_helper_helper(T::ONE, T::exact_from(7), &[1, 2, 3, 4, 5, 6]); primitive_int_increasing_range_helper_helper( T::exact_from(10), T::exact_from(20), &[10, 11, 12, 13, 14, 15, 16, 17, 18, 19], ); primitive_int_increasing_range_helper_helper( T::ZERO, T::MAX, &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], ); primitive_int_increasing_range_helper_helper( T::ZERO, T::MAX - T::ONE, &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], ); } fn primitive_int_increasing_range_helper_signed() where i8: ExactFrom, usize: WrappingFrom, { primitive_int_increasing_range_helper_helper( T::exact_from(-20), T::exact_from(-10), &[-20, -19, -18, -17, -16, -15, -14, -13, -12, -11], ); primitive_int_increasing_range_helper_helper( T::exact_from(-100), T::exact_from(100), &[ -100, -99, -98, -97, -96, -95, -94, -93, -92, -91, -90, -89, -88, -87, -86, -85, -84, -83, -82, -81, ], ); } #[test] fn test_primitive_int_increasing_range() { apply_fn_to_primitive_ints!(primitive_int_increasing_range_helper); apply_fn_to_signeds!(primitive_int_increasing_range_helper_signed); primitive_int_increasing_range_rev_helper::( 0, u8::MAX, &[ 254, 253, 252, 251, 250, 249, 248, 247, 246, 245, 244, 243, 242, 241, 240, 239, 238, 237, 236, 235, ], ); primitive_int_increasing_range_rev_helper::( 0, u8::MAX - 1, &[ 253, 252, 251, 250, 249, 248, 247, 246, 245, 244, 243, 242, 241, 240, 239, 238, 237, 236, 235, 234, ], ); primitive_int_increasing_range_rev_helper::( 0, u16::MAX, &[ 65534, 65533, 65532, 65531, 65530, 65529, 65528, 65527, 65526, 65525, 65524, 65523, 65522, 65521, 65520, 65519, 65518, 65517, 65516, 65515, ], ); primitive_int_increasing_range_rev_helper::( 0, u16::MAX - 1, &[ 65533, 65532, 65531, 65530, 65529, 65528, 65527, 65526, 65525, 65524, 65523, 65522, 65521, 65520, 65519, 65518, 65517, 65516, 65515, 65514, ], ); primitive_int_increasing_range_helper_helper::( i8::MIN, i8::MAX, &[ -128, -127, -126, -125, -124, -123, -122, -121, -120, -119, -118, -117, -116, -115, -114, -113, -112, -111, -110, -109, ], ); primitive_int_increasing_range_helper_helper::( i8::MIN + 1, i8::MAX - 1, &[ -127, -126, -125, -124, -123, -122, -121, -120, -119, -118, -117, -116, -115, -114, -113, -112, -111, -110, -109, -108, ], ); primitive_int_increasing_range_rev_helper::( i8::MIN, i8::MAX, &[ 126, 125, 124, 123, 122, 121, 120, 119, 118, 117, 116, 115, 114, 113, 112, 111, 110, 109, 108, 107, ], ); primitive_int_increasing_range_rev_helper::( i8::MIN + 1, i8::MAX - 1, &[ 125, 124, 123, 122, 121, 120, 119, 118, 117, 116, 115, 114, 113, 112, 111, 110, 109, 108, 107, 106, ], ); primitive_int_increasing_range_rev_helper::( i16::MIN, i16::MAX, &[ 32766, 32765, 32764, 32763, 32762, 32761, 32760, 32759, 32758, 32757, 32756, 32755, 32754, 32753, 32752, 32751, 32750, 32749, 32748, 32747, ], ); primitive_int_increasing_range_rev_helper::( i16::MIN + 1, i16::MAX - 1, &[ 32765, 32764, 32763, 32762, 32761, 32760, 32759, 32758, 32757, 32756, 32755, 32754, 32753, 32752, 32751, 32750, 32749, 32748, 32747, 32746, ], ); } fn primitive_int_increasing_range_fail_helper() { assert_panic!(primitive_int_increasing_range::(T::ONE, T::ZERO)); } #[test] fn primitive_int_increasing_range_fail() { apply_fn_to_primitive_ints!(primitive_int_increasing_range_fail_helper); } malachite-base-0.4.16/tests/num/factorization/prime_indicator_sequence.rs000064400000000000000000000033741046102023000250050ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::factorization::primes::prime_indicator_sequence; #[test] pub fn test_prime_indicator_sequence() { let s: String = prime_indicator_sequence() .take(1000) .map(|b| if b { '1' } else { '0' }) .collect(); assert_eq!( s, "01101010001010001010001000001010000010001010001000001000001010000010001010000010001000001\ 000000010001010001010001000000000000010001000001010000000001010000010000010001000001000001\ 010000000001010001010000000000010000000000010001010001000001010000000001000001000001000001\ 010000010001010000000001000000000000010001010001000000000000010000010000000001010001000001\ 000000010000010000010001000001000000010001000000010000000001010000000001010000010001000001\ 000000010001010001000000000001000000010001000000010001000001000000000001010000000000000000\ 010000010000000001000001000001010000010000000001000001000001010000010000010001010000000000\ 010000000001010001000001000001010000000000010001000001000000010000000001000000010000000001\ 000000010000010000010001000000010000010001000000010001000000000000010000000001000000000001\ 010000000001010001010000000001000000000000010001010001000000000000010001010001000000000000\ 000000010001000000010000000001000000010001000001000001000000000000010001000001000001000000\ 01000001000" ); } malachite-base-0.4.16/tests/num/factorization/prime_indicator_sequence_less_than.rs000064400000000000000000000063051046102023000270420ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::itertools::Itertools; use malachite_base::num::conversion::traits::ExactFrom; use malachite_base::num::factorization::primes::{ prime_indicator_sequence, prime_indicator_sequence_less_than, }; use malachite_base::test_util::generators::unsigned_gen_var_5; fn test_prime_indicator_sequence_helper(limit: u64, out: &str) { let s: String = prime_indicator_sequence_less_than(limit) .take(1000) .map(|b| if b { '1' } else { '0' }) .collect(); assert_eq!(s, out); } #[test] pub fn test_prime_indicator_sequence_less_than() { test_prime_indicator_sequence_helper(0, ""); test_prime_indicator_sequence_helper(1, ""); test_prime_indicator_sequence_helper(2, "0"); test_prime_indicator_sequence_helper(3, "01"); test_prime_indicator_sequence_helper(4, "011"); test_prime_indicator_sequence_helper(5, "0110"); test_prime_indicator_sequence_helper(6, "01101"); test_prime_indicator_sequence_helper(7, "011010"); test_prime_indicator_sequence_helper(8, "0110101"); test_prime_indicator_sequence_helper(9, "01101010"); test_prime_indicator_sequence_helper(10, "011010100"); test_prime_indicator_sequence_helper( 100, "01101010001010001010001000001010000010001010001000001000001010000010001010000010001000001\ 0000000100", ); test_prime_indicator_sequence_helper( 1000, "01101010001010001010001000001010000010001010001000001000001010000010001010000010001000001\ 000000010001010001010001000000000000010001000001010000000001010000010000010001000001000001\ 010000000001010001010000000000010000000000010001010001000001010000000001000001000001000001\ 010000010001010000000001000000000000010001010001000000000000010000010000000001010001000001\ 000000010000010000010001000001000000010001000000010000000001010000000001010000010001000001\ 000000010001010001000000000001000000010001000000010001000001000000000001010000000000000000\ 010000010000000001000001000001010000010000000001000001000001010000010000010001010000000000\ 010000000001010001000001000001010000000000010001000001000000010000000001000000010000000001\ 000000010000010000010001000000010000010001000000010001000000000000010000000001000000000001\ 010000000001010001010000000001000000000000010001010001000000000000010001010001000000000000\ 000000010001000000010000000001000000010001000001000001000000000000010001000001000001000000\ 0100000100", ); } #[test] fn prime_indicator_sequence_less_than_properties() { unsigned_gen_var_5().test_properties(|limit| { let bs = prime_indicator_sequence_less_than(limit).collect_vec(); let len = usize::exact_from(limit.saturating_sub(1)); assert_eq!(bs.len(), len); assert_eq!(prime_indicator_sequence().take(len).collect_vec(), bs); }); } malachite-base-0.4.16/tests/num/factorization/prime_sieve.rs000064400000000000000000000275351046102023000222610ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::factorization::prime_sieve::{ limbs_prime_sieve_size, limbs_prime_sieve_u32, limbs_prime_sieve_u64, }; use malachite_base::test_util::generators::unsigned_gen_var_26; use malachite_base::test_util::num::factorization::prime_sieve::{ limbs_prime_sieve_naive_1, limbs_prime_sieve_naive_2, }; #[test] fn test_limbs_prime_sieve_u32() { let test = |n, out, out_sieve: &[u32]| { let mut sieve = vec![0; limbs_prime_sieve_size::(n)]; assert_eq!(limbs_prime_sieve_u32(&mut sieve, n), out); assert_eq!(sieve, out_sieve); let mut sieve_alt = vec![0; limbs_prime_sieve_size::(n)]; assert_eq!(limbs_prime_sieve_naive_1::(&mut sieve_alt, n), out); assert_eq!(sieve, sieve_alt); let mut sieve_alt = vec![0; limbs_prime_sieve_size::(n)]; assert_eq!(limbs_prime_sieve_naive_2::(&mut sieve_alt, n), out); assert_eq!(sieve, sieve_alt); }; let test_large = |n, out| { let mut sieve = vec![0; limbs_prime_sieve_size::(n)]; assert_eq!(limbs_prime_sieve_u32(&mut sieve, n), out); let mut sieve_alt = vec![0; limbs_prime_sieve_size::(n)]; assert_eq!(limbs_prime_sieve_naive_1::(&mut sieve_alt, n), out); assert_eq!(sieve, sieve_alt); let mut sieve_alt = vec![0; limbs_prime_sieve_size::(n)]; assert_eq!(limbs_prime_sieve_naive_2::(&mut sieve_alt, n), out); assert_eq!(sieve, sieve_alt); }; // - size <= BLOCK_SIZE << 1 // - limbs == 0 in first_block_primesieve // - (bits + 1) & Limb::WIDTH_MASK != 0 in first_block_primesieve // - (bits + 1) & Limb::WIDTH_MASK != 0 test(5, 1, &[4294967294]); // - (bits + 1) & Limb::WIDTH_MASK == 0 in first_block_primesieve // - (bits + 1) & Limb::WIDTH_MASK == 0 test(97, 23, &[1762821248]); // - limbs != 0 in first_block_primesieve // - offset == 0 first time in fill_bitpattern test(101, 24, &[1762821248, 4294967294]); // - n_to_bit(SEED_LIMIT + 1) >= Limb::WIDTH in first_block_primesieve // - bit_array[index] & mask == 0 in first_block_primesieve // - lindex <= bits first time in first_block_primesieve // - lindex > bits second time in first_block_primesieve // - lindex > bits first time in first_block_primesieve test(121, 28, &[1762821248, 4294967264]); // - lindex <= bits second time in first_block_primesieve test(187, 40, &[1762821248, 4069837280]); // - limbs != 0 first time in fill_bitpattern // - limbs == 0 second time in fill_bitpattern test(197, 43, &[1762821248, 848611808, 4294967294]); // - limbs != 0 second time in fill_bitpattern test(293, 60, &[1762821248, 848611808, 3299549660, 4294967294]); // - bit_array[index] & mask != 0 in first_block_primesieve test( 529, 97, &[1762821248, 848611808, 3299549660, 2510511646, 3093902182, 4294954649], ); test( 10000, 1227, &[ 1762821248, 848611808, 3299549660, 2510511646, 3093902182, 1255657113, 1921893675, 1704310490, 2276511454, 3933052807, 3442636201, 1062642164, 1957128923, 4248324347, 2716726959, 3686403537, 3525810597, 3469209982, 3144777046, 3941341117, 1482358003, 990820275, 2682219599, 3848526070, 2757661436, 4267419563, 1005886333, 361623151, 3991325978, 3193600964, 3397105325, 3613891391, 535771113, 3287706519, 969495549, 1870576883, 3526745072, 3584421084, 3585498683, 3975838511, 3365889969, 3532586489, 1037283151, 3414129786, 4285215436, 4005484237, 1590667644, 3585963000, 3148695799, 570277455, 4005035495, 1580573621, 2816195785, 3656121683, 788406134, 4288601775, 3209020842, 1475950840, 3242065846, 4101944926, 1238805919, 2074062642, 2532965119, 3010383198, 4133027549, 1790162093, 3623277869, 1878747087, 3720235807, 3033363191, 4214476775, 2614931297, 3853071358, 3216472538, 3950886702, 2080282321, 2138895219, 667676511, 2805099227, 1743386524, 4235696025, 1592700903, 3706043128, 3619639167, 2080028206, 4197678553, 2138431973, 2627728235, 2372861911, 1911355103, 1566205629, 3013582698, 1609955564, 4047489974, 4125088590, 3923174885, 3200773946, 3589010553, 3953720370, 2080348909, 1828150423, 2537461567, 2647369563, 4126591959, 4294967295, ], ); // - size > BLOCK_SIZE << 1 // - offset != 0 first time in fill_bitpattern // - offset != 0 second time in fill_bitpattern // - offset <= Limb::WIDTH in fill_bitpattern // - offset != Limb::WIDTH in fill_bitpattern // - offset > 70 - 2 * Limb::WIDTH in fill_bitpattern // - sieve[index] & mask == 0 in block_resieve // - lindex <= bits + off in block_resieve // - lindex < off first time in block_resieve // - lindex < off second time in block_resieve // - sieve[index] & mask != 0 in block_resieve // - lindex >= off first time in block_resieve // - lindex >= off second time in block_resieve // - lindex > bits + off in block_resieve // - off >= size test_large(400000, 33858); // - Limb::WIDTH < offset < 2 * Limb::WIDTH in fill_bitpattern // - offset > 70 - Limb::WIDTH in fill_bitpattern test_large(400037, 33861); // - offset <= 70 - 2 * Limb::WIDTH in fill_bitpattern test_large(400325, 33885); // - offset <= 70 - Limb::WIDTH in fill_bitpattern // - offset != 70 - Limb::WIDTH in fill_bitpattern test_large(400421, 33891); // - offset >= 2 * Limb::WIDTH in fill_bitpattern test_large(400517, 33896); // - offset == 70 - Limb::WIDTH in fill_bitpattern test_large(401477, 33963); // - offset == 0 second time in fill_bitpattern test_large(401573, 33969); // - offset == Limb::WIDTH in fill_bitpattern test_large(401669, 33975); } #[test] fn test_limbs_prime_sieve_u64() { let test = |n, out, out_sieve: &[u64]| { let mut sieve = vec![0; limbs_prime_sieve_size::(n)]; assert_eq!(limbs_prime_sieve_u64(&mut sieve, n), out); assert_eq!(sieve, out_sieve); let mut sieve_alt = vec![0; limbs_prime_sieve_size::(n)]; assert_eq!(limbs_prime_sieve_naive_1(&mut sieve_alt, n), out); assert_eq!(sieve, sieve_alt); let mut sieve_alt = vec![0; limbs_prime_sieve_size::(n)]; assert_eq!(limbs_prime_sieve_naive_2(&mut sieve_alt, n), out); assert_eq!(sieve, sieve_alt); }; let test_large = |n, out| { let mut sieve = vec![0; limbs_prime_sieve_size::(n)]; assert_eq!(limbs_prime_sieve_u64(&mut sieve, n), out); let mut sieve_alt = vec![0; limbs_prime_sieve_size::(n)]; assert_eq!(limbs_prime_sieve_naive_1(&mut sieve_alt, n), out); assert_eq!(sieve, sieve_alt); let mut sieve_alt = vec![0; limbs_prime_sieve_size::(n)]; assert_eq!(limbs_prime_sieve_naive_2(&mut sieve_alt, n), out); assert_eq!(sieve, sieve_alt); }; // - offset == 0 first time in fill_bitpattern // - limbs == 0 first time in fill_bitpattern // - limbs != 0 first time in fill_bitpattern // - limbs == 0 second time in fill_bitpattern // - limbs != 0 second time in fill_bitpattern test(197, 43, &[3644759964122252416, 18446744073709551614]); test( 10000, 1227, &[ 3644759964122252416, 10782565419096678876, 5393006238418678630, 7319957818701628715, 16892333181782511326, 4564013345173304745, 18246414135122684635, 15832982633990452911, 14900143419172559269, 16927931203039886678, 4255540678821084403, 16529293611135626319, 18328427464153273084, 1553159608027356029, 13716411700845399322, 15521545339038054061, 14120591978486773737, 8034066538108113917, 15394971334399613936, 17076096382507834939, 15172343443912353713, 14663575776206761807, 17203423806843728588, 15401593811256715644, 2449323022019807479, 6788512015120334311, 15702923061497674953, 18419404369980956534, 6339160591512749482, 17617719310405205942, 8908031218484161951, 12929497386370857727, 7688687648106938077, 8069157299743544621, 13028195705955437343, 11231044406116339687, 13814644363045188606, 8934744539092860718, 2867648781191279475, 7487788107672218331, 6840598294930364313, 15546231849291725560, 18028892106335630894, 11286006834239234533, 8209207660800573399, 12943239133267650237, 17383837070827845868, 16849907831688649550, 15414682953334648634, 8935030532378000434, 10898314446950063255, 17723577510488942427, 18446744073709551615, ], ); // - offset != 0 first time in fill_bitpattern // - m21 != 0 in fill_bitpattern // - m21 < Limb::WIDTH in fill_bitpattern // - m21 <= 110 - Limb::WIDTH in fill_bitpattern // - offset != 0 second time in fill_bitpattern // - offset >= 2 * Limb::WIDTH in fill_bitpattern test_large(800000, 63949); // - m21 >= Limb::WIDTH in fill_bitpattern // - offset <= Limb::WIDTH in fill_bitpattern // - offset != Limb::WIDTH in fill_bitpattern // - offset <= 182 - 2 * Limb::WIDTH in fill_bitpattern test_large(800069, 63953); // - m21 > 110 - Limb::WIDTH in fill_bitpattern // - Limb::WIDTH < offset < 2 * Limb::WIDTH in fill_bitpattern // - offset <= 182 - Limb::WIDTH in fill_bitpattern // - offset != 182 - Limb::WIDTH in fill_bitpattern test_large(800261, 63971); // - offset > 182 - 2 * Limb::WIDTH in fill_bitpattern test_large(801797, 64088); // - offset > 182 - Limb::WIDTH in fill_bitpattern test_large(801989, 64100); // - m21 == 0 in fill_bitpattern test_large(805061, 64323); // - off < size // - offset == Limb::WIDTH in fill_bitpattern test_large(1800005, 135070); // - offset == 182 - Limb::WIDTH in fill_bitpattern test_large(1808261, 135646); // - offset == 0 second time in fill_bitpattern test_large(1808453, 135656); } #[test] fn limbs_prime_sieve_properties() { unsigned_gen_var_26().test_properties(|n: u64| { let mut sieve = vec![0; limbs_prime_sieve_size::(n)]; let out = limbs_prime_sieve_u32(&mut sieve, n); assert!(out < n); let mut sieve_alt = vec![0; limbs_prime_sieve_size::(n)]; assert_eq!(limbs_prime_sieve_naive_1::(&mut sieve_alt, n), out); assert_eq!(sieve, sieve_alt); let mut sieve_alt = vec![0; limbs_prime_sieve_size::(n)]; assert_eq!(limbs_prime_sieve_naive_2::(&mut sieve_alt, n), out); assert_eq!(sieve, sieve_alt); let mut sieve = vec![0; limbs_prime_sieve_size::(n)]; let out = limbs_prime_sieve_u64(&mut sieve, n); assert!(out < n); let mut sieve_alt = vec![0; limbs_prime_sieve_size::(n)]; assert_eq!(limbs_prime_sieve_naive_1::(&mut sieve_alt, n), out); assert_eq!(sieve, sieve_alt); let mut sieve_alt = vec![0; limbs_prime_sieve_size::(n)]; assert_eq!(limbs_prime_sieve_naive_2::(&mut sieve_alt, n), out); assert_eq!(sieve, sieve_alt); }); } malachite-base-0.4.16/tests/num/factorization/primes.rs000064400000000000000000000255101046102023000212400ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::iterators::comparison::is_strictly_ascending; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::WrappingFrom; use malachite_base::num::factorization::traits::Primes; use malachite_base::test_util::generators::unsigned_gen_var_5; use malachite_base::test_util::num::factorization::primes::primes_naive; fn test_primes_less_than_helper() { let test = |n: u8, out: &[u8]| { let n = T::from(n); let out = out.iter().map(|&x| T::from(x)).collect_vec(); assert_eq!(T::primes_less_than(&n).collect_vec(), out); assert_eq!(T::primes().take_while(|&p| p < n).collect_vec(), out); assert_eq!( primes_naive::().take_while(|&p| p < n).collect_vec(), out ); }; test(0, &[]); test(1, &[]); test(2, &[]); test(3, &[2]); test(4, &[2, 3]); test(5, &[2, 3]); test(6, &[2, 3, 5]); test(7, &[2, 3, 5]); test(8, &[2, 3, 5, 7]); test(9, &[2, 3, 5, 7]); test(10, &[2, 3, 5, 7]); test( 100, &[ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, ], ); } #[test] fn test_primes_less_than() { apply_fn_to_unsigneds!(test_primes_less_than_helper); } fn test_primes_less_than_or_equal_to_helper() { let test = |n: u8, out: &[u8]| { let n = T::from(n); let out = out.iter().map(|&x| T::from(x)).collect_vec(); assert_eq!(T::primes_less_than_or_equal_to(&n).collect_vec(), out); assert_eq!(T::primes().take_while(|&p| p <= n).collect_vec(), out); assert_eq!( primes_naive::().take_while(|&p| p <= n).collect_vec(), out ); }; test(0, &[]); test(1, &[]); test(2, &[2]); test(3, &[2, 3]); test(4, &[2, 3]); test(5, &[2, 3, 5]); test(6, &[2, 3, 5]); test(7, &[2, 3, 5, 7]); test(8, &[2, 3, 5, 7]); test(9, &[2, 3, 5, 7]); test(10, &[2, 3, 5, 7]); test( 100, &[ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, ], ); } #[test] fn test_primes_less_than_or_equal_to() { apply_fn_to_unsigneds!(test_primes_less_than_or_equal_to_helper); } #[test] fn test_primes() { let expected = &[ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997, 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297, 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551, 2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687, 2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, 2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861, 2879, 2887, 2897, 2903, 2909, 2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999, 3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079, 3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167, 3169, 3181, 3187, 3191, 3203, 3209, 3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271, 3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331, 3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413, 3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533, 3539, 3541, 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643, 3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797, 3803, 3821, 3823, 3833, 3847, 3851, 3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917, 3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989, 4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057, 4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129, 4133, 4139, 4153, 4157, 4159, 4177, 4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297, 4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409, 4421, 4423, 4441, 4447, 4451, 4457, 4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519, 4523, 4547, 4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621, 4637, 4639, 4643, 4649, 4651, 4657, 4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751, 4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889, 4903, 4909, 4919, 4931, 4933, 4937, 4943, 4951, 4957, 4967, 4969, 4973, 4987, 4993, 4999, 5003, 5009, 5011, 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087, 5099, 5101, 5107, 5113, 5119, 5147, 5153, 5167, 5171, 5179, 5189, 5197, 5209, 5227, 5231, 5233, 5237, 5261, 5273, 5279, 5281, 5297, 5303, 5309, 5323, 5333, 5347, 5351, 5381, 5387, 5393, 5399, 5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443, 5449, 5471, 5477, 5479, 5483, 5501, 5503, 5507, 5519, 5521, 5527, 5531, 5557, 5563, 5569, 5573, 5581, 5591, 5623, 5639, 5641, 5647, 5651, 5653, 5657, 5659, 5669, 5683, 5689, 5693, 5701, 5711, 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791, 5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, 5851, 5857, 5861, 5867, 5869, 5879, 5881, 5897, 5903, 5923, 5927, 5939, 5953, 5981, 5987, 6007, 6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073, 6079, 6089, 6091, 6101, 6113, 6121, 6131, 6133, 6143, 6151, 6163, 6173, 6197, 6199, 6203, 6211, 6217, 6221, 6229, 6247, 6257, 6263, 6269, 6271, 6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329, 6337, 6343, 6353, 6359, 6361, 6367, 6373, 6379, 6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473, 6481, 6491, 6521, 6529, 6547, 6551, 6553, 6563, 6569, 6571, 6577, 6581, 6599, 6607, 6619, 6637, 6653, 6659, 6661, 6673, 6679, 6689, 6691, 6701, 6703, 6709, 6719, 6733, 6737, 6761, 6763, 6779, 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833, 6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907, 6911, 6917, 6947, 6949, 6959, 6961, 6967, 6971, 6977, 6983, 6991, 6997, 7001, 7013, 7019, 7027, 7039, 7043, 7057, 7069, 7079, 7103, 7109, 7121, 7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207, 7211, 7213, 7219, 7229, 7237, 7243, 7247, 7253, 7283, 7297, 7307, 7309, 7321, 7331, 7333, 7349, 7351, 7369, 7393, 7411, 7417, 7433, 7451, 7457, 7459, 7477, 7481, 7487, 7489, 7499, 7507, 7517, 7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561, 7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621, 7639, 7643, 7649, 7669, 7673, 7681, 7687, 7691, 7699, 7703, 7717, 7723, 7727, 7741, 7753, 7757, 7759, 7789, 7793, 7817, 7823, 7829, 7841, 7853, 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919, ]; assert_eq!(u16::primes().take(1000).collect_vec(), expected); assert_eq!(primes_naive::().take(1000).collect_vec(), expected); assert_eq!(u8::primes().count(), 54); assert_eq!(u16::primes().count(), 6542); const U32_PRIME_COUNT: usize = 203280221; assert_eq!(u32::primes().count(), U32_PRIME_COUNT); assert_eq!( u32::primes_less_than_or_equal_to(&u32::MAX).count(), U32_PRIME_COUNT ); assert_eq!( u64::primes_less_than_or_equal_to(&u64::wrapping_from(u32::MAX)).count(), U32_PRIME_COUNT ); } fn primes_less_than_properties_helper() { unsigned_gen_var_5::().test_properties(|n| { let ps = T::primes_less_than(&n).collect_vec(); assert!(is_strictly_ascending(ps.iter())); assert_eq!( T::primes_less_than_or_equal_to(&n.saturating_sub(T::ONE)).collect_vec(), ps ); assert_eq!(T::primes().take_while(|&p| p < n).collect_vec(), ps); assert_eq!(primes_naive::().take_while(|&p| p < n).collect_vec(), ps); }); } #[test] fn primes_less_than_properties() { apply_fn_to_unsigneds!(primes_less_than_properties_helper); } fn primes_less_than_or_equal_to_properties_helper() { unsigned_gen_var_5::().test_properties(|n| { let ps = T::primes_less_than_or_equal_to(&n).collect_vec(); assert!(is_strictly_ascending(ps.iter())); assert_eq!( T::primes_less_than(&n.saturating_add(T::ONE)).collect_vec(), ps ); assert_eq!(T::primes().take_while(|&p| p <= n).collect_vec(), ps); assert_eq!( primes_naive::().take_while(|&p| p <= n).collect_vec(), ps ); }); } #[test] fn primes_less_than_or_equal_to_properties() { apply_fn_to_unsigneds!(primes_less_than_or_equal_to_properties_helper); } malachite-base-0.4.16/tests/num/float/basic/abs_negative_zero.rs000064400000000000000000000034771046102023000227510ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::generators::primitive_float_gen; fn abs_negative_zero_helper() { let test = |n: T, out| { let out = NiceFloat(out); assert_eq!(NiceFloat(n.abs_negative_zero()), out); let mut n = n; n.abs_negative_zero_assign(); assert_eq!(NiceFloat(n), out); }; test(T::ZERO, T::ZERO); test(T::NEGATIVE_ZERO, T::ZERO); test(T::NAN, T::NAN); test(T::INFINITY, T::INFINITY); test(T::NEGATIVE_INFINITY, T::NEGATIVE_INFINITY); test(T::ONE, T::ONE); test(T::NEGATIVE_ONE, T::NEGATIVE_ONE); test(T::from(1.234), T::from(1.234)); test(T::from(-1.234), T::from(-1.234)); } #[test] fn test_abs_negative_zero() { apply_fn_to_primitive_floats!(abs_negative_zero_helper); } fn abs_negative_zero_properties_helper() { primitive_float_gen::().test_properties(|x| { let y = x.abs_negative_zero(); let x = NiceFloat(x); let y = NiceFloat(y); assert!(x == y || x == NiceFloat(T::NEGATIVE_ZERO) && y == NiceFloat(T::ZERO)); assert_eq!(NiceFloat(y.0.abs_negative_zero()), y); let mut x = x.0; x.abs_negative_zero_assign(); assert_eq!(NiceFloat(x), y); }); } #[test] fn abs_negative_zero_properties() { apply_fn_to_primitive_floats!(abs_negative_zero_properties_helper); } malachite-base-0.4.16/tests/num/float/basic/from_ordered_representation.rs000064400000000000000000000103111046102023000250350ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::traits::NegativeInfinity; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::generators::{unsigned_gen_var_13, unsigned_pair_gen_var_22}; use std::panic::catch_unwind; #[allow(clippy::approx_constant)] #[test] pub fn test_from_ordered_representation() { fn test(n: u64, out: T) { assert_eq!(NiceFloat(T::from_ordered_representation(n)), NiceFloat(out)); } test::(0, f32::NEGATIVE_INFINITY); test::(1, -f32::MAX_FINITE); test::(1000000000, -458.42188); test::(1046478848, -10.0); test::(1060565029, -core::f32::consts::PI); test::(1073741824, -1.0); test::(1102263091, -0.1); test::(2130706432, -f32::MIN_POSITIVE_NORMAL); test::(2130706433, -f32::MAX_SUBNORMAL); test::(2139095039, -f32::MIN_POSITIVE_SUBNORMAL); test::(2139095040, -0.0); test::(2139095041, 0.0); test::(2139095042, f32::MIN_POSITIVE_SUBNORMAL); test::(2147483648, f32::MAX_SUBNORMAL); test::(2147483649, f32::MIN_POSITIVE_NORMAL); test::(3175926990, 0.1); test::(3204448256, 0.99999994); test::(3204448257, 1.0); test::(3204448258, 1.0000001); test::(3217625051, 3.1415925); test::(3217625052, core::f32::consts::PI); test::(3217625053, 3.141593); test::(3231711233, 10.0); test::(4278190080, f32::MAX_FINITE); test::(4278190081, f32::INFINITY); test::(0, f64::NEGATIVE_INFINITY); test::(1, -f64::MAX_FINITE); test::(4597049319638433792, -10.0); test::(4604611780675359464, -core::f64::consts::PI); test::(4611686018427387904, -1.0); test::(4626998257160447590, -0.1); test::(9214364837600034816, -f64::MIN_POSITIVE_NORMAL); test::(9214364837600034817, -f64::MAX_SUBNORMAL); test::(9218868437227405311, -f64::MIN_POSITIVE_SUBNORMAL); test::(9218868437227405312, -0.0); test::(9218868437227405313, 0.0); test::(9218868437227405314, f64::MIN_POSITIVE_SUBNORMAL); test::(9223372036854775808, f64::MAX_SUBNORMAL); test::(9223372036854775809, f64::MIN_POSITIVE_NORMAL); test::(10000000000000000000, 1.9261352099337372e-256); test::(13810738617294363035, 0.1); test::(13826050856027422720, 0.9999999999999999); test::(13826050856027422721, 1.0); test::(13826050856027422722, 1.0000000000000002); test::(13833125093779451160, 3.1415926535897927); test::(13833125093779451161, core::f64::consts::PI); test::(13833125093779451162, 3.1415926535897936); test::(13840687554816376833, 10.0); test::(18437736874454810624, f64::MAX_FINITE); test::(18437736874454810625, f64::INFINITY); } #[test] pub fn from_ordered_representation_fail() { assert_panic!(f32::from_ordered_representation(4278190082)); assert_panic!(f32::from_ordered_representation(u64::MAX)); assert_panic!(f64::from_ordered_representation(18437736874454810626)); assert_panic!(f64::from_ordered_representation(u64::MAX)); } fn from_ordered_representation_properties_helper() { unsigned_gen_var_13::().test_properties(|x| { let f = T::from_ordered_representation(x); assert!(!f.is_nan()); assert_eq!(f.to_ordered_representation(), x); }); unsigned_pair_gen_var_22::().test_properties(|(x, y)| { assert_eq!( x.cmp(&y), NiceFloat(T::from_ordered_representation(x)) .cmp(&NiceFloat(T::from_ordered_representation(y))) ); }); } #[test] fn from_ordered_representation_properties() { apply_fn_to_primitive_floats!(from_ordered_representation_properties_helper); } malachite-base-0.4.16/tests/num/float/basic/is_negative_zero.rs000064400000000000000000000026171046102023000226120ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::generators::primitive_float_gen; fn is_negative_zero_helper() { let test = |n: T, out| { assert_eq!(n.is_negative_zero(), out); }; test(T::ZERO, false); test(T::NEGATIVE_ZERO, true); test(T::NAN, false); test(T::INFINITY, false); test(T::NEGATIVE_INFINITY, false); test(T::ONE, false); test(T::NEGATIVE_ONE, false); test(T::from(1.234), false); test(T::from(-1.234), false); } #[test] fn test_is_negative_zero() { apply_fn_to_primitive_floats!(is_negative_zero_helper); } fn is_negative_zero_properties_helper() { primitive_float_gen::().test_properties(|x| { assert_eq!( x.is_negative_zero(), NiceFloat(x) != NiceFloat(x.abs_negative_zero()) ); }); } #[test] fn is_negative_zero_properties() { apply_fn_to_primitive_floats!(is_negative_zero_properties_helper); } malachite-base-0.4.16/tests/num/float/basic/max_precision_for_sci_exponent.rs000064400000000000000000000033441046102023000255400ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::conversion::traits::ExactFrom; use malachite_base::test_util::generators::signed_gen_var_11; use std::panic::catch_unwind; #[test] fn max_precision_for_sci_exponent() { fn test(n: i64, out: u64) { assert_eq!(T::max_precision_for_sci_exponent(n), out); } test::(0, 24); test::(127, 24); test::(-149, 1); test::(-148, 2); test::(-147, 3); test::(0, 53); test::(1023, 53); test::(-1074, 1); test::(-1073, 2); test::(-1072, 3); } fn max_precision_for_sci_exponent_fail_helper() { assert_panic!(T::max_precision_for_sci_exponent(10000)); assert_panic!(T::max_precision_for_sci_exponent(-10000)); } #[test] pub fn max_precision_for_sci_exponent_fail() { apply_fn_to_primitive_floats!(max_precision_for_sci_exponent_fail_helper); } fn max_precision_for_sci_exponent_properties_helper() { signed_gen_var_11::().test_properties(|exp| { let p = T::max_precision_for_sci_exponent(exp); assert_ne!(p, 0); assert!(p <= u64::exact_from(T::MAX_EXPONENT)); }); } #[test] fn max_precision_for_sci_exponent_properties() { apply_fn_to_primitive_floats!(max_precision_for_sci_exponent_properties_helper); } malachite-base-0.4.16/tests/num/float/basic/next_higher.rs000064400000000000000000000074621046102023000215650ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::traits::NegativeInfinity; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::generators::primitive_float_gen_var_9; use std::panic::catch_unwind; #[allow(clippy::approx_constant)] #[test] pub fn test_next_higher() { fn test(x: T, out: T) { assert_eq!(NiceFloat(x.next_higher()), NiceFloat(out)); } test::(f32::NEGATIVE_INFINITY, -f32::MAX_FINITE); test::(-f32::MAX_FINITE, -3.4028233e38); test::(-458.42188, -458.42184); test::(-10.0, -9.999999); test::(-core::f32::consts::PI, -3.1415925); test::(-1.0, -0.99999994); test::(-0.1, -0.099999994); test::(-f32::MIN_POSITIVE_NORMAL, -f32::MAX_SUBNORMAL); test::(-f32::MAX_SUBNORMAL, -1.1754941e-38); test::(-f32::MIN_POSITIVE_SUBNORMAL, -0.0); test::(-0.0, 0.0); test::(0.0, f32::MIN_POSITIVE_SUBNORMAL); test::(f32::MIN_POSITIVE_SUBNORMAL, 3.0e-45); test::(f32::MAX_SUBNORMAL, f32::MIN_POSITIVE_NORMAL); test::(f32::MIN_POSITIVE_NORMAL, 1.1754945e-38); test::(0.1, 0.10000001); test::(0.99999994, 1.0); test::(1.0, 1.0000001); test::(1.0000001, 1.0000002); test::(3.1415925, core::f32::consts::PI); test::(core::f32::consts::PI, 3.141593); test::(3.141593, 3.1415932); test::(10.0, 10.000001); test::(f32::MAX_FINITE, f32::INFINITY); test::(f64::NEGATIVE_INFINITY, -f64::MAX_FINITE); test::(-f64::MAX_FINITE, -1.7976931348623155e308); test::(-10.0, -9.999999999999998); test::(-core::f64::consts::PI, -3.1415926535897927); test::(-1.0, -0.9999999999999999); test::(-0.1, -0.09999999999999999); test::(-f64::MIN_POSITIVE_NORMAL, -f64::MAX_SUBNORMAL); test::(-f64::MAX_SUBNORMAL, -2.2250738585072004e-308); test::(-f64::MIN_POSITIVE_SUBNORMAL, -0.0); test::(-0.0, 0.0); test::(0.0, f64::MIN_POSITIVE_SUBNORMAL); test::(f64::MIN_POSITIVE_SUBNORMAL, 1.0e-323); test::(f64::MAX_SUBNORMAL, f64::MIN_POSITIVE_NORMAL); test::(f64::MIN_POSITIVE_NORMAL, 2.225073858507202e-308); test::(1.9261352099337372e-256, 1.9261352099337375e-256); test::(0.1, 0.10000000000000002); test::(0.9999999999999999, 1.0); test::(1.0, 1.0000000000000002); test::(1.0000000000000002, 1.0000000000000004); test::(3.1415926535897927, core::f64::consts::PI); test::(core::f64::consts::PI, 3.1415926535897936); test::(3.1415926535897936, 3.141592653589794); test::(10.0, 10.000000000000002); test::(f64::MAX_FINITE, f64::INFINITY); } fn next_higher_fail_helper() { assert_panic!(T::NAN.next_higher()); assert_panic!(T::INFINITY.next_higher()); } #[test] pub fn next_higher_fail() { apply_fn_to_primitive_floats!(next_higher_fail_helper); } fn next_higher_properties_helper() { primitive_float_gen_var_9::().test_properties(|x| { let y = x.next_higher(); assert_eq!( x.to_ordered_representation() + 1, y.to_ordered_representation() ); assert_eq!(NiceFloat(y.next_lower()), NiceFloat(x)); }); } #[test] fn next_higher_properties() { apply_fn_to_primitive_floats!(next_higher_properties_helper); } malachite-base-0.4.16/tests/num/float/basic/next_lower.rs000064400000000000000000000074621046102023000214470ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::traits::NegativeInfinity; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::generators::primitive_float_gen_var_10; use std::panic::catch_unwind; #[allow(clippy::approx_constant)] #[test] pub fn test_next_lower() { fn test(x: T, out: T) { assert_eq!(NiceFloat(x.next_lower()), NiceFloat(out)); } test::(-f32::MAX_FINITE, f32::NEGATIVE_INFINITY); test::(-458.42188, -458.4219); test::(-10.0, -10.000001); test::(-core::f32::consts::PI, -3.141593); test::(-1.0, -1.0000001); test::(-0.1, -0.10000001); test::(-f32::MIN_POSITIVE_NORMAL, -1.1754945e-38); test::(-f32::MAX_SUBNORMAL, -f32::MIN_POSITIVE_NORMAL); test::(-f32::MIN_POSITIVE_SUBNORMAL, -3.0e-45); test::(-0.0, -f32::MIN_POSITIVE_SUBNORMAL); test::(0.0, -0.0); test::(f32::MIN_POSITIVE_SUBNORMAL, 0.0); test::(f32::MAX_SUBNORMAL, 1.1754941e-38); test::(f32::MIN_POSITIVE_NORMAL, f32::MAX_SUBNORMAL); test::(0.1, 0.099999994); test::(0.99999994, 0.9999999); test::(1.0, 0.99999994); test::(1.0000001, 1.0); test::(3.1415925, 3.1415923); test::(core::f32::consts::PI, 3.1415925); test::(3.141593, core::f32::consts::PI); test::(10.0, 9.999999); test::(f32::MAX_FINITE, 3.4028233e38); test::(f32::INFINITY, f32::MAX_FINITE); test::(-f64::MAX_FINITE, f64::NEGATIVE_INFINITY); test::(-10.0, -10.000000000000002); test::(-core::f64::consts::PI, -3.1415926535897936); test::(-1.0, -1.0000000000000002); test::(-0.1, -0.10000000000000002); test::(-f64::MIN_POSITIVE_NORMAL, -2.225073858507202e-308); test::(-f64::MAX_SUBNORMAL, -f64::MIN_POSITIVE_NORMAL); test::(-f64::MIN_POSITIVE_SUBNORMAL, -1.0e-323); test::(-0.0, -f64::MIN_POSITIVE_SUBNORMAL); test::(0.0, -0.0); test::(f64::MIN_POSITIVE_SUBNORMAL, 0.0); test::(f64::MAX_SUBNORMAL, 2.2250738585072004e-308); test::(f64::MIN_POSITIVE_NORMAL, f64::MAX_SUBNORMAL); test::(1.9261352099337372e-256, 1.926135209933737e-256); test::(0.1, 0.09999999999999999); test::(0.9999999999999999, 0.9999999999999998); test::(1.0, 0.9999999999999999); test::(1.0000000000000002, 1.0); test::(3.1415926535897927, 3.1415926535897922); test::(core::f64::consts::PI, 3.1415926535897927); test::(3.1415926535897936, core::f64::consts::PI); test::(10.0, 9.999999999999998); test::(f64::MAX_FINITE, 1.7976931348623155e308); test::(f64::INFINITY, f64::MAX_FINITE); } fn next_lower_fail_helper() { assert_panic!(T::NAN.next_lower()); assert_panic!(T::NEGATIVE_INFINITY.next_lower()); } #[test] pub fn next_lower_fail() { apply_fn_to_primitive_floats!(next_lower_fail_helper); } fn next_lower_properties_helper() { primitive_float_gen_var_10::().test_properties(|x| { let y = x.next_lower(); assert_eq!( x.to_ordered_representation() - 1, y.to_ordered_representation() ); assert_eq!(NiceFloat(y.next_higher()), NiceFloat(x)); }); } #[test] fn next_lower_properties() { apply_fn_to_primitive_floats!(next_lower_properties_helper); } malachite-base-0.4.16/tests/num/float/basic/precision.rs000064400000000000000000000032571046102023000212520ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::test_util::generators::primitive_float_gen_var_12; use std::panic::catch_unwind; fn precision_helper() { let test = |n: T, out| { assert_eq!(n.precision(), out); }; test(T::ONE, 1); test(T::NEGATIVE_ONE, 1); test(T::from(3.0), 2); test(T::from(1.5), 2); test(T::from(1.234), 23); test(T::from(-1.234), 23); } #[test] fn test_precision() { apply_fn_to_primitive_floats!(precision_helper); } fn precision_fail_helper() { assert_panic!(T::NAN.precision()); assert_panic!(T::INFINITY.precision()); assert_panic!(T::NEGATIVE_INFINITY.precision()); assert_panic!(T::ZERO.precision()); assert_panic!(T::NEGATIVE_ZERO.precision()); } #[test] pub fn precision_fail() { apply_fn_to_primitive_floats!(precision_fail_helper); } fn precision_properties_helper() { primitive_float_gen_var_12::().test_properties(|x| { let precision = x.precision(); assert_ne!(precision, 0); assert!(precision <= T::max_precision_for_sci_exponent(x.sci_exponent())); assert_eq!((-x).precision(), precision); }); } #[test] fn precision_properties() { apply_fn_to_primitive_floats!(precision_properties_helper); } malachite-base-0.4.16/tests/num/float/basic/to_ordered_representation.rs000064400000000000000000000102511046102023000245170ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::traits::NegativeInfinity; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::generators::{ primitive_float_gen_var_11, primitive_float_pair_gen_var_1, }; use std::panic::catch_unwind; #[allow(clippy::approx_constant)] #[test] pub fn test_to_ordered_representation() { fn test(x: T, out: u64) { assert_eq!(x.to_ordered_representation(), out); } test::(f32::NEGATIVE_INFINITY, 0); test::(-f32::MAX_FINITE, 1); test::(-458.42188, 1000000000); test::(-10.0, 1046478848); test::(-core::f32::consts::PI, 1060565029); test::(-1.0, 1073741824); test::(-0.1, 1102263091); test::(-f32::MIN_POSITIVE_NORMAL, 2130706432); test::(-f32::MAX_SUBNORMAL, 2130706433); test::(-f32::MIN_POSITIVE_SUBNORMAL, 2139095039); test::(-0.0, 2139095040); test::(0.0, 2139095041); test::(f32::MIN_POSITIVE_SUBNORMAL, 2139095042); test::(f32::MAX_SUBNORMAL, 2147483648); test::(f32::MIN_POSITIVE_NORMAL, 2147483649); test::(0.1, 3175926990); test::(0.99999994, 3204448256); test::(1.0, 3204448257); test::(1.0000001, 3204448258); test::(3.1415925, 3217625051); test::(core::f32::consts::PI, 3217625052); test::(3.141593, 3217625053); test::(10.0, 3231711233); test::(f32::MAX_FINITE, 4278190080); test::(f32::INFINITY, 4278190081); test::(f64::NEGATIVE_INFINITY, 0); test::(-f64::MAX_FINITE, 1); test::(-10.0, 4597049319638433792); test::(-core::f64::consts::PI, 4604611780675359464); test::(-1.0, 4611686018427387904); test::(-0.1, 4626998257160447590); test::(-f64::MIN_POSITIVE_NORMAL, 9214364837600034816); test::(-f64::MAX_SUBNORMAL, 9214364837600034817); test::(-f64::MIN_POSITIVE_SUBNORMAL, 9218868437227405311); test::(-0.0, 9218868437227405312); test::(0.0, 9218868437227405313); test::(f64::MIN_POSITIVE_SUBNORMAL, 9218868437227405314); test::(f64::MAX_SUBNORMAL, 9223372036854775808); test::(f64::MIN_POSITIVE_NORMAL, 9223372036854775809); test::(1.9261352099337372e-256, 10000000000000000000); test::(0.1, 13810738617294363035); test::(0.9999999999999999, 13826050856027422720); test::(1.0, 13826050856027422721); test::(1.0000000000000002, 13826050856027422722); test::(3.1415926535897927, 13833125093779451160); test::(core::f64::consts::PI, 13833125093779451161); test::(3.1415926535897936, 13833125093779451162); test::(10.0, 13840687554816376833); test::(f64::MAX_FINITE, 18437736874454810624); test::(f64::INFINITY, 18437736874454810625); } fn to_ordered_representation_fail_helper() { assert_panic!(T::NAN.to_ordered_representation()); } #[test] pub fn to_ordered_representation_fail() { apply_fn_to_primitive_floats!(to_ordered_representation_fail_helper); } fn to_ordered_representation_properties_helper() { primitive_float_gen_var_11::().test_properties(|x| { let i = x.to_ordered_representation(); assert!(i <= T::LARGEST_ORDERED_REPRESENTATION); assert_eq!(NiceFloat(T::from_ordered_representation(i)), NiceFloat(x)); }); primitive_float_pair_gen_var_1::().test_properties(|(x, y)| { assert_eq!( NiceFloat(x).cmp(&NiceFloat(y)), x.to_ordered_representation() .cmp(&y.to_ordered_representation()) ); }); } #[test] fn to_ordered_representation_properties() { apply_fn_to_primitive_floats!(to_ordered_representation_properties_helper); } malachite-base-0.4.16/tests/num/float/nice_float/cmp.rs000064400000000000000000000033471046102023000210600ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::common::test_cmp_helper; use malachite_base::test_util::generators::{ primitive_float_gen, primitive_float_pair_gen, primitive_float_triple_gen, }; use std::cmp::Ordering::*; const TEST_STRINGS: [&str; 7] = ["-Infinity", "-5.0e5", "-0.0", "NaN", "0.0", "0.123", "Infinity"]; #[test] pub fn test_cmp() { test_cmp_helper::>(&TEST_STRINGS); test_cmp_helper::>(&TEST_STRINGS); } fn cmp_properties_helper() { primitive_float_pair_gen::().test_properties(|(x, y)| { let x = NiceFloat(x); let y = NiceFloat(y); let ord = x.cmp(&y); assert_eq!(y.cmp(&x).reverse(), ord); assert_eq!(NiceFloat(-y.0).cmp(&NiceFloat(-x.0)), ord); }); primitive_float_gen::().test_properties(|x| { let x = NiceFloat(x); assert_eq!(x.cmp(&x), Equal); }); primitive_float_triple_gen::().test_properties(|(x, y, z)| { let x = NiceFloat(x); let y = NiceFloat(y); let z = NiceFloat(z); if x < y && y < z { assert!(x < z); } else if x > y && y > z { assert!(x > z); } }); } #[test] pub fn cmp_properties() { apply_fn_to_primitive_floats!(cmp_properties_helper); } malachite-base-0.4.16/tests/num/float/nice_float/eq.rs000064400000000000000000000030571046102023000207040ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::common::test_eq_helper; use malachite_base::test_util::generators::{ primitive_float_gen, primitive_float_pair_gen, primitive_float_triple_gen, }; const TEST_STRINGS: [&str; 7] = ["-Infinity", "-5.0e5", "-0.0", "NaN", "0.0", "0.123", "Infinity"]; #[test] pub fn test_eq() { test_eq_helper::>(&TEST_STRINGS); test_eq_helper::>(&TEST_STRINGS); } #[allow(clippy::eq_op)] fn eq_properties_helper() { primitive_float_pair_gen::().test_properties(|(x, y)| { let x = NiceFloat(x); let y = NiceFloat(y); assert_eq!(x == y, y == x); }); primitive_float_gen::().test_properties(|x| { let x = NiceFloat(x); assert_eq!(x, x); }); primitive_float_triple_gen::().test_properties(|(x, y, z)| { let x = NiceFloat(x); let y = NiceFloat(y); let z = NiceFloat(z); if x == y && x == z { assert_eq!(x, z); } }); } #[test] pub fn eq_properties() { apply_fn_to_primitive_floats!(eq_properties_helper); } malachite-base-0.4.16/tests/num/float/nice_float/from_str.rs000064400000000000000000000103221046102023000221230ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::traits::NegativeInfinity; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::generators::common::GenConfig; use malachite_base::test_util::generators::{string_gen, string_gen_var_10}; use std::fmt::Debug; use std::str::FromStr; #[allow(clippy::approx_constant)] #[test] fn test_from_str() { fn test_ok(s: &str, out: NiceFloat) where ::Err: Debug, { assert_eq!(NiceFloat::::from_str(s).unwrap(), out); } test_ok::("NaN", NiceFloat(f32::NAN)); test_ok::("Infinity", NiceFloat(f32::INFINITY)); test_ok::("-Infinity", NiceFloat(f32::NEGATIVE_INFINITY)); test_ok::("0", NiceFloat(0.0)); test_ok::("00", NiceFloat(0.0)); test_ok::("0.", NiceFloat(0.0)); test_ok::(".0", NiceFloat(0.0)); test_ok::("1", NiceFloat(1.0)); test_ok::("1.0", NiceFloat(1.0)); test_ok::("1.0000", NiceFloat(1.0)); test_ok::("3.14", NiceFloat(3.14)); test_ok::("1e2", NiceFloat(100.0)); test_ok::("1e20", NiceFloat(1.0e20)); test_ok::("1.0e1000", NiceFloat(f32::INFINITY)); test_ok::("1.0e-1000", NiceFloat(0.0)); test_ok::("-0", NiceFloat(-0.0)); test_ok::("-00", NiceFloat(-0.0)); test_ok::("-0.", NiceFloat(-0.0)); test_ok::("-.0", NiceFloat(-0.0)); test_ok::("-1", NiceFloat(-1.0)); test_ok::("-1.0", NiceFloat(-1.0)); test_ok::("-1.0000", NiceFloat(-1.0)); test_ok::("-3.14", NiceFloat(-3.14)); test_ok::("-1e2", NiceFloat(-100.0)); test_ok::("-1e20", NiceFloat(-1.0e20)); test_ok::("-1.0e1000", NiceFloat(f32::NEGATIVE_INFINITY)); test_ok::("-1.0e-1000", NiceFloat(-0.0)); test_ok::("NaN", NiceFloat(f64::NAN)); test_ok::("Infinity", NiceFloat(f64::INFINITY)); test_ok::("-Infinity", NiceFloat(f64::NEGATIVE_INFINITY)); test_ok::("0", NiceFloat(0.0)); test_ok::("00", NiceFloat(0.0)); test_ok::("0.", NiceFloat(0.0)); test_ok::(".0", NiceFloat(0.0)); test_ok::("1", NiceFloat(1.0)); test_ok::("1.0", NiceFloat(1.0)); test_ok::("1.0000", NiceFloat(1.0)); test_ok::("3.14", NiceFloat(3.14)); test_ok::("1e2", NiceFloat(100.0)); test_ok::("1e20", NiceFloat(1.0e20)); test_ok::("1.0e1000", NiceFloat(f64::INFINITY)); test_ok::("1.0e-1000", NiceFloat(0.0)); test_ok::("-0", NiceFloat(-0.0)); test_ok::("-00", NiceFloat(-0.0)); test_ok::("-0.", NiceFloat(-0.0)); test_ok::("-.0", NiceFloat(-0.0)); test_ok::("-1", NiceFloat(-1.0)); test_ok::("-1.0", NiceFloat(-1.0)); test_ok::("-1.0000", NiceFloat(-1.0)); test_ok::("-3.14", NiceFloat(-3.14)); test_ok::("-1e2", NiceFloat(-100.0)); test_ok::("-1e20", NiceFloat(-1.0e20)); test_ok::("-1.0e1000", NiceFloat(f64::NEGATIVE_INFINITY)); test_ok::("-1.0e-1000", NiceFloat(-0.0)); let test_err = |s| { assert!(NiceFloat::::from_str(s).is_err()); assert!(NiceFloat::::from_str(s).is_err()); }; test_err("-"); test_err("."); test_err("e"); test_err("z"); test_err("0x01"); test_err(" 0 "); } #[allow(unused_must_use)] fn from_str_helper() { let mut config = GenConfig::new(); config.insert("mean_length_n", 128); config.insert("mean_length_d", 1); string_gen().test_properties_with_config(&config, |s| { NiceFloat::::from_str(&s); }); string_gen_var_10().test_properties_with_config(&config, |s| { NiceFloat::::from_str(&s); }); } #[test] fn from_str_properties() { apply_fn_to_primitive_floats!(from_str_helper); } malachite-base-0.4.16/tests/num/float/nice_float/hash.rs000064400000000000000000000015421046102023000212170ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::float::NiceFloat; use malachite_base::test_util::generators::primitive_float_gen; use malachite_base::test_util::hash::hash; fn hash_properties_helper() { primitive_float_gen::().test_properties(|x| { let x = NiceFloat(x); assert_eq!(hash(&x), hash(&x.clone())); }); } #[test] fn hash_properties() { apply_fn_to_primitive_floats!(hash_properties_helper); } malachite-base-0.4.16/tests/num/float/nice_float/to_string.rs000064400000000000000000000060751046102023000223120ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::traits::NegativeInfinity; use malachite_base::num::float::NiceFloat; use malachite_base::strings::string_is_subset; use malachite_base::test_util::generators::primitive_float_gen; use malachite_base::test_util::num::float::PRIMITIVE_FLOAT_CHARS; use std::fmt::Debug; use std::str::FromStr; #[test] pub fn test_to_string() { fn test(x: T, out: &str) { assert_eq!(NiceFloat(x).to_string(), out); } test::(f32::NAN, "NaN"); test::(f32::INFINITY, "Infinity"); test::(f32::NEGATIVE_INFINITY, "-Infinity"); test::(0.0, "0.0"); test::(-0.0, "-0.0"); test::(1.0, "1.0"); test::(-1.0, "-1.0"); test::(123.0, "123.0"); test::(0.123, "0.123"); test::(1000.0, "1000.0"); test::(1000000.0, "1000000.0"); test::(1.0e20, "1.0e20"); test::(f32::MIN_POSITIVE_SUBNORMAL, "1.0e-45"); test::(f32::MAX_SUBNORMAL, "1.1754942e-38"); test::(f32::MIN_POSITIVE_NORMAL, "1.1754944e-38"); test::(f32::MAX_FINITE, "3.4028235e38"); test::(2.0f32.sqrt(), "1.4142135"); test::(std::f32::consts::E, "2.7182817"); test::(std::f32::consts::PI, "3.1415927"); test::(f64::NAN, "NaN"); test::(f64::INFINITY, "Infinity"); test::(f64::NEGATIVE_INFINITY, "-Infinity"); test::(0.0, "0.0"); test::(-0.0, "-0.0"); test::(1.0, "1.0"); test::(-1.0, "-1.0"); test::(123.0, "123.0"); test::(0.123, "0.123"); test::(1000.0, "1000.0"); test::(1000000.0, "1000000.0"); test::(1.0e100, "1.0e100"); test::(f64::MIN_POSITIVE_SUBNORMAL, "5.0e-324"); test::(f64::MAX_SUBNORMAL, "2.225073858507201e-308"); test::(f64::MIN_POSITIVE_NORMAL, "2.2250738585072014e-308"); test::(f64::MAX_FINITE, "1.7976931348623157e308"); test::(2.0f64.sqrt(), "1.4142135623730951"); test::(std::f64::consts::E, "2.718281828459045"); test::(std::f64::consts::PI, "3.141592653589793"); } fn to_string_properties_helper() where ::Err: Debug, { primitive_float_gen::().test_properties(|f| { let s = NiceFloat(f).to_string(); assert_eq!(NiceFloat::from_str(&s).unwrap(), NiceFloat(f)); assert!(string_is_subset(&s, PRIMITIVE_FLOAT_CHARS)); if f.is_finite() { assert!(s.contains('.')); assert_eq!(NiceFloat(T::from_str(&s).unwrap()), NiceFloat(f)); } }); } #[test] fn to_string_properties() { apply_fn_to_primitive_floats!(to_string_properties_helper); } malachite-base-0.4.16/tests/num/iterators/bit_distributor_sequence.rs000064400000000000000000000052541046102023000242040ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::iterators::bit_distributor::BitDistributorOutputType; use malachite_base::num::iterators::bit_distributor_sequence; fn bit_distributor_sequence_helper( x_output_type: BitDistributorOutputType, y_output_type: BitDistributorOutputType, out: &[usize], ) { assert_eq!( bit_distributor_sequence(x_output_type, y_output_type) .take(50) .collect_vec(), out ); } #[test] fn test_bit_distributor_sequence() { bit_distributor_sequence_helper( BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(1), &[ 0, 1, 0, 1, 2, 3, 2, 3, 0, 1, 0, 1, 2, 3, 2, 3, 4, 5, 4, 5, 6, 7, 6, 7, 4, 5, 4, 5, 6, 7, 6, 7, 0, 1, 0, 1, 2, 3, 2, 3, 0, 1, 0, 1, 2, 3, 2, 3, 4, 5, ], ); bit_distributor_sequence_helper( BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(2), &[ 0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 2, 3, 2, 3, 2, 3, 0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 2, 3, 2, 3, 2, 3, 0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 2, 3, 2, 3, 2, 3, 0, 1, ], ); bit_distributor_sequence_helper( BitDistributorOutputType::normal(2), BitDistributorOutputType::normal(1), &[ 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, 7, 8, 9, 10, 11, 8, 9, 10, 11, 12, 13, 14, 15, 12, 13, 14, 15, 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, 7, 8, 9, ], ); bit_distributor_sequence_helper( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), &[ 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, 7, 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, 7, 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, 7, 0, 1, ], ); bit_distributor_sequence_helper( BitDistributorOutputType::normal(1), BitDistributorOutputType::tiny(), &[ 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, ], ); } #[test] #[should_panic] fn test_bit_distributor_sequence_fail() { bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::tiny(), ); } malachite-base-0.4.16/tests/num/iterators/iterator_to_bit_chunks.rs000064400000000000000000000103211046102023000236370ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::WrappingFrom; use malachite_base::num::iterators::iterator_to_bit_chunks; use std::panic::{catch_unwind, RefUnwindSafe}; fn iterator_to_bit_chunks_helper>( xs: &[T], in_chunk_size: u64, out_chunk_size: u64, out: &[U], ) { assert_eq!( iterator_to_bit_chunks::<_, T, U>(xs.iter().copied(), in_chunk_size, out_chunk_size) .map(Option::unwrap) .collect_vec() .as_slice(), out ); } #[test] fn test_iterator_to_bit_chunks() { iterator_to_bit_chunks_helper::(&[123, 456], 10, 10, &[123, 456]); iterator_to_bit_chunks_helper::(&[123, 456], 10, 10, &[123, 456]); iterator_to_bit_chunks_helper::(&[123, 456], 10, 10, &[123, 456]); iterator_to_bit_chunks_helper::( &[0b000111111, 0b110010010], 9, 3, &[0b111, 0b111, 0b000, 0b010, 0b010, 0b110], ); iterator_to_bit_chunks_helper::( &[0b000111111, 0b110010010], 9, 3, &[0b111, 0b111, 0b000, 0b010, 0b010, 0b110], ); iterator_to_bit_chunks_helper::( &[0b000111111, 0b110010010], 9, 3, &[0b111, 0b111, 0b000, 0b010, 0b010, 0b110], ); iterator_to_bit_chunks_helper::( &[0b111, 0b111, 0b000, 0b010, 0b010, 0b110], 3, 9, &[0b000111111, 0b110010010], ); iterator_to_bit_chunks_helper::( &[0b111, 0b111, 0b000, 0b010, 0b010, 0b110], 3, 9, &[0b000111111, 0b110010010], ); iterator_to_bit_chunks_helper::( &[0b111, 0b111, 0b000, 0b010, 0b010, 0b110], 3, 9, &[0b000111111, 0b110010010], ); iterator_to_bit_chunks_helper::( &[0b1010101, 0b1111101, 0b0100001, 0b110010], 7, 6, &[0b010101, 0b111011, 0b000111, 0b010010, 0b110], ); iterator_to_bit_chunks_helper::( &[0b1010101, 0b1111101, 0b0100001, 0b110010], 7, 6, &[0b010101, 0b111011, 0b000111, 0b010010, 0b110], ); iterator_to_bit_chunks_helper::( &[0b1010101, 0b1111101, 0b0100001, 0b110010], 7, 6, &[0b010101, 0b111011, 0b000111, 0b010010, 0b110], ); iterator_to_bit_chunks_helper::( &[0b010101, 0b111011, 0b000111, 0b010010, 0b110], 6, 7, &[0b1010101, 0b1111101, 0b0100001, 0b110010], ); iterator_to_bit_chunks_helper::( &[0b010101, 0b111011, 0b000111, 0b010010, 0b110], 6, 7, &[0b1010101, 0b1111101, 0b0100001, 0b110010], ); iterator_to_bit_chunks_helper::( &[0b010101, 0b111011, 0b000111, 0b010010, 0b110], 6, 7, &[0b1010101, 0b1111101, 0b0100001, 0b110010], ); // The output may have trailing zero chunks. iterator_to_bit_chunks_helper::(&[0b100], 32, 8, &[0b100, 0, 0, 0]); } fn test_iterator_to_bit_chunks_fail_helper< T: PrimitiveUnsigned + RefUnwindSafe, U: PrimitiveUnsigned + WrappingFrom, >() { let xs = [T::exact_from(12), T::exact_from(34)]; assert_panic!({ iterator_to_bit_chunks::<_, T, U>(xs.iter().copied(), 0, 4); }); assert_panic!({ iterator_to_bit_chunks::<_, T, U>(xs.iter().copied(), 4, 0); }); assert_panic!({ iterator_to_bit_chunks::<_, T, U>(xs.iter().copied(), T::WIDTH + 1, 4); }); assert_panic!({ iterator_to_bit_chunks::<_, T, U>(xs.iter().copied(), 4, U::WIDTH + 1); }); } #[test] fn iterator_to_bit_chunks_fail() { apply_fn_to_unsigneds_and_unsigneds!(test_iterator_to_bit_chunks_fail_helper); } malachite-base-0.4.16/tests/num/iterators/ruler_sequence.rs000064400000000000000000000016601046102023000221220ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::num::iterators::ruler_sequence; #[test] pub fn test_ruler_sequence() { assert_eq!( ruler_sequence::().take(100).collect_vec(), &[ 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2 ] ); } malachite-base-0.4.16/tests/num/logic/bit_access/assign_bit.rs000064400000000000000000000063611046102023000224060ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ signed_unsigned_bool_triple_gen_var_1, unsigned_unsigned_bool_triple_gen_var_1, }; use std::panic::catch_unwind; fn assign_bit_helper_unsigned() { let test = |n: u64, index, bit, out: u64| { let mut n = T::exact_from(n); n.assign_bit(index, bit); assert_eq!(n, T::exact_from(out)); }; test(100, 0, true, 101); test(0, 10, false, 0); test(0, 100, false, 0); test(101, 0, false, 100); if T::WIDTH >= u16::WIDTH { test(0, 10, true, 1024); test(1024, 10, false, 0); } if T::WIDTH >= u64::WIDTH { test(1000000000000, 10, true, 1000000001024); test(1000000001024, 10, false, 1000000000000); test(1000000001024, 100, false, 1000000001024); } } fn assign_bit_helper_signed() { assign_bit_helper_unsigned::(); let test = |n: i64, index, bit, out: i64| { let mut n = T::exact_from(n); n.assign_bit(index, bit); assert_eq!(n, T::exact_from(out)); }; test(-1, 5, true, -1); test(-1, 100, true, -1); test(-33, 5, true, -1); test(-32, 0, true, -31); test(-1, 5, false, -33); test(-31, 0, false, -32); if T::WIDTH >= u64::WIDTH { test(-1000000000000, 10, true, -999999998976); test(-1000000000000, 100, true, -1000000000000); test(-999999998976, 10, false, -1000000000000); } let mut n = T::ZERO; n.assign_bit(T::WIDTH - 1, true); assert_eq!(n, T::MIN); let mut n = T::MIN; n.assign_bit(T::WIDTH - 1, false); assert_eq!(n, T::ZERO); } #[test] fn test_assign_bit() { apply_fn_to_unsigneds!(assign_bit_helper_unsigned); apply_fn_to_signeds!(assign_bit_helper_signed); } fn assign_bit_fail_helper() { assert_panic!({ let mut n = T::exact_from(5); n.assign_bit(200, true); }); } fn assign_bit_fail_helper_signed() { assert_panic!({ let mut n = T::NEGATIVE_ONE; n.assign_bit(200, false); }); } #[test] fn assign_bit_fail() { apply_fn_to_primitive_ints!(assign_bit_fail_helper); apply_fn_to_signeds!(assign_bit_fail_helper_signed); } fn properties_helper_unsigned() { unsigned_unsigned_bool_triple_gen_var_1::().test_properties(|(mut n, index, bit)| { n.assign_bit(index, bit); }); } fn properties_helper_signed() { signed_unsigned_bool_triple_gen_var_1::().test_properties(|(mut n, index, bit)| { n.assign_bit(index, bit); }); } #[test] fn assign_bit_properties() { apply_fn_to_unsigneds!(properties_helper_unsigned); apply_fn_to_signeds!(properties_helper_signed); } malachite-base-0.4.16/tests/num/logic/bit_access/clear_bit.rs000064400000000000000000000067321046102023000222120ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ signed_unsigned_pair_gen_var_4, unsigned_pair_gen_var_2, }; use std::panic::catch_unwind; fn clear_bit_helper_unsigned() { let test = |n: u64, index, out: u64| { let mut n = T::exact_from(n); n.clear_bit(index); assert_eq!(n, T::exact_from(out)); }; test(0, 10, 0); test(0, 100, 0); test(101, 0, 100); if T::WIDTH >= u16::WIDTH { test(1024, 10, 0); } if T::WIDTH >= u64::WIDTH { test(1000000001024, 10, 1000000000000); test(1000000001024, 100, 1000000001024); } } fn clear_bit_helper_signed() { clear_bit_helper_unsigned::(); let test = |n: i64, index, out: i64| { let mut n = T::exact_from(n); n.clear_bit(index); assert_eq!(n, T::exact_from(out)); }; test(-1, 5, -33); test(-31, 0, -32); if T::WIDTH >= u64::WIDTH { test(-999999998976, 10, -1000000000000); } let mut n = T::MIN; n.clear_bit(T::WIDTH - 1); assert_eq!(n, T::ZERO); } #[test] fn test_clear_bit() { apply_fn_to_unsigneds!(clear_bit_helper_unsigned); apply_fn_to_signeds!(clear_bit_helper_signed); } fn clear_bit_fail_helper() { assert_panic!({ let mut n = T::NEGATIVE_ONE; n.clear_bit(200); }); } #[test] fn clear_bit_fail() { apply_fn_to_signeds!(clear_bit_fail_helper); } fn properties_helper_unsigned() { unsigned_pair_gen_var_2::().test_properties(|(mut n, index)| { let old_n = n; n.clear_bit(index); let result = n; let mut n = old_n; n.assign_bit(index, false); assert_eq!(n, result); assert!(result <= old_n); if old_n.get_bit(index) { assert_ne!(result, old_n); let mut n = result; n.set_bit(index); assert_eq!(n, old_n); } else { assert_eq!(result, old_n); } }); } fn properties_helper_signed() { signed_unsigned_pair_gen_var_4::().test_properties(|(mut n, index)| { let old_n = n; n.clear_bit(index); let result = n; let mut n = old_n; n.assign_bit(index, false); assert_eq!(n, result); if old_n < T::ZERO && index == T::WIDTH - 1 { assert!(result >= T::ZERO); } else { assert!(result <= old_n); } if old_n.get_bit(index) { assert_ne!(result, old_n); let mut n = result; n.set_bit(index); assert_eq!(n, old_n); } else { assert_eq!(result, old_n); } let mut n = !old_n; n.set_bit(index); n.not_assign(); assert_eq!(n, result); }); } #[test] fn clear_bit_properties() { apply_fn_to_unsigneds!(properties_helper_unsigned); apply_fn_to_signeds!(properties_helper_signed); } malachite-base-0.4.16/tests/num/logic/bit_access/flip_bit.rs000064400000000000000000000060461046102023000220540ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ signed_unsigned_pair_gen_var_2, unsigned_pair_gen_var_3, }; use std::panic::catch_unwind; fn flip_bit_helper_unsigned() { let test = |n: u64, index, out: u64| { let mut n = T::exact_from(n); n.flip_bit(index); assert_eq!(n, T::exact_from(out)); }; test(100, 0, 101); test(101, 0, 100); if T::WIDTH >= u16::WIDTH { test(0, 10, 1024); test(1024, 10, 0); } if T::WIDTH >= u64::WIDTH { test(1000000000000, 10, 1000000001024); test(1000000001024, 10, 1000000000000); } } fn flip_bit_helper_signed() { flip_bit_helper_unsigned::(); let test = |n: i64, index, out: i64| { let mut n = T::exact_from(n); n.flip_bit(index); assert_eq!(n, T::exact_from(out)); }; test(-1, 5, -33); test(-33, 5, -1); test(-32, 0, -31); test(-31, 0, -32); if T::WIDTH >= u64::WIDTH { test(-1000000000000, 10, -999999998976); test(-999999998976, 10, -1000000000000); } let mut n = T::ZERO; n.flip_bit(T::WIDTH - 1); assert_eq!(n, T::MIN); let mut n = T::MIN; n.flip_bit(T::WIDTH - 1); assert_eq!(n, T::ZERO); } #[test] fn test_flip_bit() { apply_fn_to_unsigneds!(flip_bit_helper_unsigned); apply_fn_to_signeds!(flip_bit_helper_signed); } fn flip_bit_fail_helper_unsigned() { assert_panic!(T::exact_from(5).flip_bit(200)); } fn flip_bit_fail_helper_signed() { assert_panic!(T::exact_from(5).flip_bit(200)); assert_panic!({ let mut n = T::NEGATIVE_ONE; n.flip_bit(200); }); } #[test] fn flip_bit_fail() { apply_fn_to_unsigneds!(flip_bit_fail_helper_unsigned); apply_fn_to_signeds!(flip_bit_fail_helper_signed); } fn properties_helper_unsigned() { unsigned_pair_gen_var_3::().test_properties(|(mut n, index)| { let old_n = n; n.flip_bit(index); assert_ne!(n, old_n); n.flip_bit(index); assert_eq!(n, old_n); }); } fn properties_helper_signed() { signed_unsigned_pair_gen_var_2::().test_properties(|(mut n, index)| { let old_n = n; n.flip_bit(index); assert_ne!(n, old_n); n.flip_bit(index); assert_eq!(n, old_n); }); } #[test] fn flip_bit_properties() { apply_fn_to_unsigneds!(properties_helper_unsigned); apply_fn_to_signeds!(properties_helper_signed); } malachite-base-0.4.16/tests/num/logic/bit_access/get_bit.rs000064400000000000000000000057101046102023000216760ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ signed_unsigned_pair_gen_var_1, unsigned_gen, unsigned_pair_gen_var_2, }; fn test_helper_primitive_int() { let test = |n: u64, index, out| { assert_eq!(T::exact_from(n).get_bit(index), out); }; test(0, 0, false); test(0, 100, false); test(123, 2, false); test(123, 3, true); test(123, 100, false); if T::WIDTH >= u64::WIDTH { test(1000000000000, 12, true); test(1000000000000, 100, false); } } fn test_helper_signed() { let test = |n: i64, index, out| { assert_eq!(T::exact_from(n).get_bit(index), out); }; test(-123, 0, true); test(-123, 1, false); test(-123, 100, true); if T::WIDTH >= u64::WIDTH { test(-1000000000000, 12, true); test(-1000000000000, 100, true); test(-i64::from(u32::MAX), 0, true); test(-i64::from(u32::MAX), 1, false); test(-i64::from(u32::MAX), 31, false); test(-i64::from(u32::MAX), 32, true); test(-i64::from(u32::MAX), 33, true); test(-i64::from(u32::MAX) - 1, 0, false); test(-i64::from(u32::MAX) - 1, 31, false); test(-i64::from(u32::MAX) - 1, 32, true); test(-i64::from(u32::MAX) - 1, 33, true); } } #[test] fn test_get_bit() { apply_fn_to_primitive_ints!(test_helper_primitive_int); apply_fn_to_signeds!(test_helper_signed); } fn properties_helper_unsigned() { unsigned_pair_gen_var_2::().test_properties(|(n, index)| { let bit = n.get_bit(index); if index >= T::WIDTH { assert!(!bit); } else { assert_eq!(bit, !(!n).get_bit(index)); } }); unsigned_gen::().test_properties(|n| { let significant_bits = n.significant_bits(); assert!(!n.get_bit(significant_bits)); if n != T::ZERO { assert!(n.get_bit(significant_bits - 1)); } }); } fn properties_helper_signed() { signed_unsigned_pair_gen_var_1::().test_properties(|(n, index)| { let bit = n.get_bit(index); if index >= T::WIDTH { assert_eq!(bit, n < T::ZERO); } else { assert_eq!(bit, !(!n).get_bit(index)); } }); } #[test] fn get_bit_properties() { apply_fn_to_unsigneds!(properties_helper_unsigned); apply_fn_to_signeds!(properties_helper_signed); } malachite-base-0.4.16/tests/num/logic/bit_access/set_bit.rs000064400000000000000000000070151046102023000217120ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ signed_unsigned_pair_gen_var_3, unsigned_pair_gen_var_3, }; use std::panic::catch_unwind; fn set_bit_helper_unsigned() { let test = |n: u64, index, out: u64| { let mut n = T::exact_from(n); n.set_bit(index); assert_eq!(n, T::exact_from(out)); }; test(100, 0, 101); if T::WIDTH >= u16::WIDTH { test(0, 10, 1024); } if T::WIDTH >= u64::WIDTH { test(1000000000000, 10, 1000000001024); } } fn set_bit_helper_signed() { set_bit_helper_unsigned::(); let test = |n: i64, index, out: i64| { let mut n = T::exact_from(n); n.set_bit(index); assert_eq!(n, T::exact_from(out)); }; test(-1, 5, -1); test(-1, 100, -1); test(-33, 5, -1); test(-32, 0, -31); if T::WIDTH >= u64::WIDTH { test(-1000000000000, 10, -999999998976); test(-1000000000000, 100, -1000000000000); } let mut n = T::ZERO; n.set_bit(T::WIDTH - 1); assert_eq!(n, T::MIN); } #[test] fn test_set_bit() { apply_fn_to_unsigneds!(set_bit_helper_unsigned); apply_fn_to_signeds!(set_bit_helper_signed); } fn set_bit_fail_helper() { assert_panic!({ let mut n = T::exact_from(5); n.set_bit(200); }); } #[test] fn set_bit_fail() { apply_fn_to_primitive_ints!(set_bit_fail_helper); } fn properties_helper_unsigned() { unsigned_pair_gen_var_3::().test_properties(|(mut n, index)| { let old_n = n; n.set_bit(index); let result = n; let mut n = old_n; n.assign_bit(index, true); assert_eq!(n, result); assert_ne!(result, T::ZERO); assert!(result >= old_n); if old_n.get_bit(index) { assert_eq!(result, old_n); } else { assert_ne!(result, old_n); let mut n = result; n.clear_bit(index); assert_eq!(n, old_n); } }); } fn properties_helper_signed() { signed_unsigned_pair_gen_var_3::().test_properties(|(mut n, index)| { let old_n = n; n.set_bit(index); let result = n; let mut n = old_n; n.assign_bit(index, true); assert_eq!(n, result); assert_ne!(result, T::ZERO); if old_n >= T::ZERO && index == T::WIDTH - 1 { assert!(result < T::ZERO); } else { assert!(result >= old_n); } if old_n.get_bit(index) { assert_eq!(result, old_n); } else { assert_ne!(result, old_n); let mut n = result; n.clear_bit(index); assert_eq!(n, old_n); } let mut n = !old_n; n.clear_bit(index); n.not_assign(); assert_eq!(n, result); }); } #[test] fn set_bit_properties() { apply_fn_to_unsigneds!(properties_helper_unsigned); apply_fn_to_signeds!(properties_helper_signed); } malachite-base-0.4.16/tests/num/logic/bit_block_access/assign_bits.rs000064400000000000000000000160111046102023000237340ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::UnsignedAbs; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::logic::traits::BitBlockAccess; use malachite_base::test_util::generators::{ signed_unsigned_pair_gen_var_1, signed_unsigned_unsigned_triple_gen_var_1, signed_unsigned_unsigned_unsigned_quadruple_gen_var_1, unsigned_pair_gen_var_2, unsigned_pair_gen_var_7, unsigned_quadruple_gen_var_1, unsigned_triple_gen_var_4, }; use malachite_base::test_util::num::logic::bit_block_access::assign_bits_naive; use std::cmp::min; use std::panic::catch_unwind; #[test] pub fn test_assign_bits_unsigned() { fn test + PrimitiveUnsigned>( x_in: T, start: u64, end: u64, bits: T, x_out: T, ) { let mut x = x_in; x.assign_bits(start, end, &bits); assert_eq!(x, x_out); let mut x = x_in; assign_bits_naive(&mut x, start, end, &bits); assert_eq!(x, x_out); } // - assign partially test(0xab5du16, 4, 8, 0xc, 0xabcd); test(0x5bcdu16, 12, 100, 0xa, 0xabcd); test(0xabcdu16, 5, 9, 10, 43853); test(0xabcdu16, 5, 5, 123, 0xabcd); // - assign zeros above width test(0xabcdu16, 100, 200, 0, 0xabcd); test(0xabcdu16, 8, 24, 0, 0xcd); // - assign everything test(0xabcdu16, 0, 100, 0x1234, 0x1234); test(0xab5du64, 4, 8, 0xc, 0xabcd); test(0x5bcdu64, 12, 100, 0xa, 0xabcd); test(0xabcdu64, 5, 9, 10, 43853); test(0xabcdu64, 5, 5, 123, 0xabcd); test(0xabcdu64, 100, 200, 0, 0xabcd); test(0xabcdu64, 0, 100, 0x1234, 0x1234); } #[test] pub fn test_assign_bits_signed() { fn test + PrimitiveSigned, U: PrimitiveUnsigned>( x_in: T, start: u64, end: u64, bits: U, x_out: T, ) { let mut x = x_in; x.assign_bits(start, end, &bits); assert_eq!(x, x_out); let mut x = x_in; assign_bits_naive(&mut x, start, end, &bits); assert_eq!(x, x_out); } // - *self >= 0 test(0x2b5di16, 4, 8, 0xc, 0x2bcd); // - *self < 0 // - assign within width test(-0x5413i16, 4, 8, 0xc, -0x5433); test(-0x54a3i16, 5, 9, 14, -21539); test(-0x5433i16, 5, 5, 0, -0x5433); // - assign ones above width test(-0x5433i16, 100, 104, 0xf, -0x5433); // - assign everything test(-57i8, 0, 8, 0xff, -1); test(0x2b5di64, 4, 8, 0xc, 0x2bcd); test(-0x5413i64, 4, 8, 0xc, -0x5433); test(-0x54a3i64, 5, 9, 14, -21539); test(-0x5433i64, 5, 5, 0, -0x5433); test(-0x5433i64, 100, 104, 0xf, -0x5433); test(-57i64, 0, 64, u64::MAX, -1); } fn assign_bits_fail_helper_unsigned + PrimitiveUnsigned>() { assert_panic!(T::exact_from(100).assign_bits(10, 5, &T::exact_from(3))); assert_panic!(T::exact_from(100).assign_bits(3, T::WIDTH + 3, &T::MAX)); } fn assign_bits_fail_helper_signed< U: PrimitiveUnsigned, S: BitBlockAccess + PrimitiveSigned, >() { assert_panic!(S::exact_from(100).assign_bits(7, 5, &U::exact_from(3))); assert_panic!(S::exact_from(100).assign_bits(0, S::WIDTH, &U::MAX)); assert_panic!(S::exact_from(-100).assign_bits(0, S::WIDTH + 1, &U::ZERO)); assert_panic!(S::exact_from(-100).assign_bits(S::WIDTH + 1, S::WIDTH + 2, &U::ZERO)); assert_panic!({ let half_width = S::WIDTH >> 1; S::exact_from(-100).assign_bits(half_width, 3 * half_width - 4, &U::ZERO); }); } #[test] fn assign_bits_fail() { apply_fn_to_unsigneds!(assign_bits_fail_helper_unsigned); apply_fn_to_unsigned_signed_pairs!(assign_bits_fail_helper_signed); } fn properties_helper_unsigned + PrimitiveUnsigned>() { unsigned_quadruple_gen_var_1::().test_properties(|(n, start, end, bits)| { let mut mut_n = n; mut_n.assign_bits(start, end, &bits); let mut mut_n_alt = mut_n; mut_n_alt.assign_bits(start, end, &bits); assert_eq!(mut_n_alt, mut_n); let mut mut_n_alt = n; assign_bits_naive::(&mut mut_n_alt, start, end, &bits); assert_eq!(mut_n_alt, mut_n); assert_eq!(mut_n.get_bits(start, end), bits.mod_power_of_2(end - start)); }); unsigned_triple_gen_var_4::().test_properties(|(n, bits, start)| { let mut mut_n = n; mut_n.assign_bits(start, start, &bits); assert_eq!(mut_n, n); }); unsigned_pair_gen_var_2::().test_properties(|(n, start)| { let mut mut_n = n; mut_n.assign_bits(start + T::WIDTH, start + (T::WIDTH << 1), &T::ZERO); assert_eq!(mut_n, n); }); unsigned_pair_gen_var_7::().test_properties(|(start, end)| { let mut n = T::ZERO; n.assign_bits(start, end, &T::ZERO); assert_eq!(n, T::ZERO); }); } fn properties_helper_signed< U: BitBlockAccess + PrimitiveUnsigned, T: BitBlockAccess + PrimitiveSigned + UnsignedAbs, >() { signed_unsigned_unsigned_unsigned_quadruple_gen_var_1::().test_properties( |(n, start, end, bits)| { let mut mut_n = n; mut_n.assign_bits(start, end, &bits); let mut mut_n_alt = mut_n; mut_n_alt.assign_bits(start, end, &bits); assert_eq!(mut_n_alt, mut_n); let mut mut_n_alt = n; assign_bits_naive::(&mut mut_n_alt, start, end, &bits); assert_eq!(mut_n_alt, mut_n); assert_eq!(mut_n.get_bits(start, end), bits.mod_power_of_2(end - start)); assert_eq!(mut_n >= T::ZERO, n >= T::ZERO); }, ); signed_unsigned_unsigned_triple_gen_var_1::().test_properties(|(n, bits, start)| { let mut mut_n = n; mut_n.assign_bits(start, start, &bits); assert_eq!(mut_n, n); }); signed_unsigned_pair_gen_var_1::().test_properties(|(n, start)| { let mut mut_n = n; mut_n.assign_bits( start + T::WIDTH - 1, start + (T::WIDTH << 1) - 1, &(if n >= T::ZERO { U::ZERO } else { U::MAX }), ); assert_eq!(mut_n, n); }); unsigned_pair_gen_var_7().test_properties(|(start, end)| { let mut n = T::ZERO; n.assign_bits(start, end, &U::ZERO); assert_eq!(n, T::ZERO); let mut n = T::NEGATIVE_ONE; n.assign_bits(start, min(end, start.saturating_add(T::WIDTH)), &U::MAX); assert_eq!(n, T::NEGATIVE_ONE); }); } #[test] fn assign_bits_properties() { apply_fn_to_unsigneds!(properties_helper_unsigned); apply_fn_to_unsigned_signed_pairs!(properties_helper_signed); } malachite-base-0.4.16/tests/num/logic/bit_block_access/get_bits.rs000064400000000000000000000106411046102023000232320ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::WrappingFrom; use malachite_base::num::logic::traits::BitBlockAccess; use malachite_base::test_util::generators::{ signed_unsigned_pair_gen_var_1, signed_unsigned_unsigned_triple_gen_var_2, unsigned_gen_var_5, unsigned_pair_gen_var_2, unsigned_pair_gen_var_7, unsigned_triple_gen_var_5, }; use malachite_base::test_util::num::logic::bit_block_access::get_bits_naive; use std::panic::catch_unwind; #[test] pub fn test_get_bits_unsigned() { fn test + PrimitiveUnsigned>(x: T, start: u64, end: u64, out: T) { assert_eq!(x.get_bits(start, end), out); assert_eq!(get_bits_naive::(&x, start, end), out); } test(0xabcdu16, 4, 8, 0xc); test(0xabcdu16, 12, 100, 0xa); test(0xabcdu16, 5, 9, 14); test(0xabcdu16, 5, 5, 0); test(0xabcdu16, 100, 200, 0); test(0xabcdu64, 4, 8, 0xc); test(0xabcdu64, 12, 100, 0xa); test(0xabcdu64, 5, 9, 14); test(0xabcdu64, 5, 5, 0); test(0xabcdu64, 100, 200, 0); } #[test] pub fn test_get_bits_signed() { fn test + PrimitiveSigned, U: PrimitiveUnsigned>( x: T, start: u64, end: u64, out: U, ) { assert_eq!(x.get_bits(start, end), out); assert_eq!(get_bits_naive::(&x, start, end), out); } test(-0x5433i16, 4, 8, 0xc); test(-0x5433i16, 5, 9, 14); test(-0x5433i16, 5, 5, 0); test(-0x5433i16, 100, 104, 0xf); test(-0x5433i64, 4, 8, 0xc); test(-0x5433i64, 5, 9, 14); test(-0x5433i64, 5, 5, 0); test(-0x5433i64, 100, 104, 0xf); test(-1i8, 0, 8, 0xff); } fn get_bits_fail_helper() { assert_panic!(T::exact_from(100).get_bits(10, 5)); } fn get_bits_fail_helper_signed() { assert_panic!(T::exact_from(-100).get_bits(100, 300)); } #[test] fn get_bits_fail() { apply_fn_to_primitive_ints!(get_bits_fail_helper); apply_fn_to_signeds!(get_bits_fail_helper_signed); } fn properties_helper_unsigned + PrimitiveUnsigned>() { unsigned_triple_gen_var_5::().test_properties(|(n, start, end)| { let bits = n.get_bits(start, end); assert_eq!(get_bits_naive::(&n, start, end), bits); assert!(bits <= n); assert_eq!(n.get_bits(start + T::WIDTH, end + T::WIDTH), T::ZERO); let mut n_alt = n; n_alt.assign_bits(start, end, &bits); assert_eq!(n_alt, n); }); unsigned_pair_gen_var_2::().test_properties(|(n, start)| { assert_eq!(n.get_bits(start, start), T::ZERO); }); unsigned_pair_gen_var_7().test_properties(|(start, end)| { assert_eq!(T::ZERO.get_bits(start, end), T::ZERO); }); } fn properties_helper_signed< U: PrimitiveUnsigned + WrappingFrom, S: BitBlockAccess + PrimitiveSigned + WrappingFrom, >() { signed_unsigned_unsigned_triple_gen_var_2::().test_properties(|(n, start, end)| { let bits = n.get_bits(start, end); assert_eq!(get_bits_naive::(&n, start, end), bits); let mut n_alt = n; n_alt.assign_bits(start, end, &bits); assert_eq!(n_alt, n); }); signed_unsigned_pair_gen_var_1::().test_properties(|(n, start)| { assert_eq!(n.get_bits(start, start), U::ZERO); assert_eq!( n.get_bits(start + S::WIDTH, start + (S::WIDTH << 1)), if n >= S::ZERO { U::ZERO } else { U::MAX } ); }); unsigned_pair_gen_var_7().test_properties(|(start, end)| { assert_eq!(S::ZERO.get_bits(start, end), U::ZERO); }); unsigned_gen_var_5().test_properties(|start| { assert_eq!(S::NEGATIVE_ONE.get_bits(start, start + S::WIDTH), U::MAX); }); } #[test] fn get_bits_properties() { apply_fn_to_unsigneds!(properties_helper_unsigned); apply_fn_to_unsigned_signed_pairs!(properties_helper_signed); } malachite-base-0.4.16/tests/num/logic/bit_convertible/from_bits.rs000064400000000000000000000227651046102023000233310ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::repeat_n; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{ bool_vec_gen_var_1, bool_vec_gen_var_2, bool_vec_gen_var_3, bool_vec_gen_var_4, unsigned_gen_var_5, }; use malachite_base::test_util::num::logic::bit_convertible::{ from_bits_asc_alt, from_bits_asc_signed_naive, from_bits_asc_unsigned_naive, from_bits_desc_alt, }; use std::iter::once; use std::panic::catch_unwind; #[test] pub fn test_from_bits_asc() { fn test_unsigned(bits: &[bool], out: T) { assert_eq!(T::from_bits_asc(bits.iter().copied()), out); assert_eq!( from_bits_asc_unsigned_naive::(bits.iter().copied()), out ); assert_eq!(from_bits_asc_alt::(bits.iter().copied()), out); } test_unsigned(&[], 0u8); test_unsigned(&[false], 0u8); test_unsigned(&[false, false, false], 0u8); test_unsigned(&[false; 100], 0u8); test_unsigned(&[true], 1u16); test_unsigned(&[false, true], 2u32); test_unsigned(&[true, true], 3u64); test_unsigned(&[true, true, false, true, true, true, true], 123u16); test_unsigned( &[true, true, false, true, true, true, true, false, false, false], 123u16, ); test_unsigned(&[true; 8], u8::MAX); fn test_signed(bits: &[bool], out: T) { assert_eq!(T::from_bits_asc(bits.iter().copied()), out); assert_eq!( from_bits_asc_signed_naive::(bits.iter().copied()), out ); assert_eq!(from_bits_asc_alt::(bits.iter().copied()), out); } test_signed(&[], 0i8); test_signed(&[false], 0i8); test_signed(&[false, false, false], 0i8); test_signed(&[false; 100], 0i8); test_signed(&[true, false], 1i16); test_signed(&[false, true, false], 2i32); test_signed(&[true, true, false], 3i64); test_signed(&[true], -1i16); test_signed(&[true, true, true], -1i16); test_signed(&[true; 100], -1i16); test_signed(&[false, true], -2i32); test_signed(&[true, false, true], -3i64); test_signed(&[true, true, false, true, true, true, true, false], 123i16); test_signed( &[true, true, false, true, true, true, true, false, false, false, false], 123i16, ); test_signed( &[true, false, true, false, false, false, false, true], -123i16, ); test_signed( &[true, false, true, false, false, false, false, true, true, true, true], -123i16, ); test_signed(&[true, true, true, true, true, true, true, false], i8::MAX); test_signed( &[false, false, false, false, false, false, false, true], i8::MIN, ); } fn from_bits_asc_fail_helper_unsigned() { assert_panic!(T::from_bits_asc(repeat_n(true, 200))); } fn from_bits_asc_fail_helper_signed() { assert_panic!(T::from_bits_asc( repeat_n(false, 200).chain([true, false].iter().copied()) )); assert_panic!(T::from_bits_asc(repeat_n(false, 200).chain(once(true)))); } #[test] fn from_bits_asc_fail() { apply_fn_to_unsigneds!(from_bits_asc_fail_helper_unsigned); apply_fn_to_signeds!(from_bits_asc_fail_helper_signed); } #[test] pub fn test_from_bits_desc() { fn test_unsigned(bits: &[bool], out: T) { assert_eq!(T::from_bits_desc(bits.iter().copied()), out); assert_eq!(from_bits_desc_alt::(bits.iter().copied()), out); } test_unsigned(&[], 0u8); test_unsigned(&[false], 0u8); test_unsigned(&[false, false, false], 0u8); test_unsigned(&[false; 100], 0u8); test_unsigned(&[true], 1u16); test_unsigned(&[true, false], 2u32); test_unsigned(&[true, true], 3u64); test_unsigned(&[true, true, true, true, false, true, true], 123u16); test_unsigned( &[false, false, false, true, true, true, true, false, true, true], 123u16, ); test_unsigned(&[true; 8], u8::MAX); fn test_signed(bits: &[bool], out: T) { assert_eq!(T::from_bits_desc(bits.iter().copied()), out); assert_eq!(from_bits_desc_alt::(bits.iter().copied()), out); } test_signed(&[], 0i8); test_signed(&[false], 0i8); test_signed(&[false, false, false], 0i8); test_signed(&[false; 100], 0i8); test_signed(&[false, true], 1i16); test_signed(&[false, true, false], 2i32); test_signed(&[false, true, true], 3i64); test_signed(&[true], -1i16); test_signed(&[true, true, true], -1i16); test_signed(&[true; 100], -1i16); test_signed(&[true, false], -2i32); test_signed(&[true, false, true], -3i64); test_signed(&[false, true, true, true, true, false, true, true], 123i16); test_signed( &[false, false, false, false, true, true, true, true, false, true, true], 123i16, ); test_signed( &[true, false, false, false, false, true, false, true], -123i16, ); test_signed( &[true, true, true, true, false, false, false, false, true, false, true], -123i16, ); test_signed(&[false, true, true, true, true, true, true, true], i8::MAX); test_signed( &[true, false, false, false, false, false, false, false], i8::MIN, ); } fn from_bits_desc_fail_helper_unsigned() { assert_panic!(T::from_bits_desc(repeat_n(true, 200))); } fn from_bits_desc_fail_helper_signed() { assert_panic!(T::from_bits_desc( [false, true].iter().copied().chain(repeat_n(false, 200)) )); assert_panic!(T::from_bits_desc(once(true).chain(repeat_n(false, 200)))); } #[test] fn from_bits_desc_fail() { apply_fn_to_unsigneds!(from_bits_desc_fail_helper_unsigned); apply_fn_to_signeds!(from_bits_desc_fail_helper_signed); } fn from_bits_asc_properties_helper_unsigned() { bool_vec_gen_var_1::().test_properties(|bs| { let n = T::from_bits_asc(bs.iter().copied()); assert_eq!(from_bits_asc_unsigned_naive::(bs.iter().copied()), n); assert_eq!(from_bits_asc_alt::(bs.iter().copied()), n); let trailing_falses = bs.iter().rev().take_while(|&&bit| !bit).count(); let trimmed_bits = bs[..bs.len() - trailing_falses].to_vec(); assert_eq!(n.to_bits_asc(), trimmed_bits); }); unsigned_gen_var_5().test_properties(|u| { assert_eq!(T::from_bits_desc(repeat_n(false, u)), T::ZERO); }); } fn from_bits_asc_properties_helper_signed() { bool_vec_gen_var_2::().test_properties(|bs| { let n = T::from_bits_asc(bs.iter().copied()); assert_eq!(from_bits_asc_signed_naive::(bs.iter().copied()), n); assert_eq!(from_bits_asc_alt::(bs.iter().copied()), n); let trimmed_bits = if bs.iter().all(|&bit| !bit) { Vec::new() } else { let sign_bits = if *bs.last().unwrap() { bs.iter().rev().take_while(|&&bit| bit).count() } else { bs.iter().rev().take_while(|&&bit| !bit).count() }; bs[..=bs.len() - sign_bits].to_vec() }; assert_eq!(n.to_bits_asc(), trimmed_bits); }); unsigned_gen_var_5().test_properties(|u| { assert_eq!(T::from_bits_asc(repeat_n(false, u)), T::ZERO); assert_eq!(T::from_bits_asc(repeat_n(true, u + 1)), T::NEGATIVE_ONE); }); } #[test] fn from_bits_asc_properties() { apply_fn_to_unsigneds!(from_bits_asc_properties_helper_unsigned); apply_fn_to_signeds!(from_bits_asc_properties_helper_signed); } fn from_bits_desc_properties_helper_unsigned() { bool_vec_gen_var_3::().test_properties(|bs| { let n = T::from_bits_desc(bs.iter().copied()); assert_eq!(from_bits_desc_alt::(bs.iter().copied()), n); let leading_falses = bs.iter().take_while(|&&bit| !bit).count(); let trimmed_bits = bs[leading_falses..].to_vec(); assert_eq!(n.to_bits_desc(), trimmed_bits); }); unsigned_gen_var_5().test_properties(|u| { assert_eq!(T::from_bits_desc(repeat_n(false, u)), T::ZERO); }); } fn from_bits_desc_properties_helper_signed() { bool_vec_gen_var_4::().test_properties(|bs| { let n = T::from_bits_desc(bs.iter().copied()); assert_eq!(from_bits_desc_alt::(bs.iter().copied()), n); let trimmed_bits = if bs.iter().all(|&bit| !bit) { Vec::new() } else { let sign_bits = if bs[0] { bs.iter().take_while(|&&bit| bit).count() } else { bs.iter().take_while(|&&bit| !bit).count() }; bs[sign_bits - 1..].to_vec() }; assert_eq!(n.to_bits_desc(), trimmed_bits); }); unsigned_gen_var_5().test_properties(|u| { assert_eq!(T::from_bits_desc(repeat_n(false, u)), T::ZERO); assert_eq!(T::from_bits_desc(repeat_n(true, u + 1)), T::NEGATIVE_ONE); }); } #[test] fn from_bits_desc_properties() { apply_fn_to_unsigneds!(from_bits_desc_properties_helper_unsigned); apply_fn_to_signeds!(from_bits_desc_properties_helper_signed); } malachite-base-0.4.16/tests/num/logic/bit_convertible/to_bits.rs000064400000000000000000000156111046102023000230000ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::ExactFrom; use malachite_base::test_util::generators::{signed_gen, unsigned_gen}; use malachite_base::test_util::num::logic::bit_convertible::{ to_bits_asc_alt, to_bits_asc_signed_naive, to_bits_asc_unsigned_naive, to_bits_desc_alt, to_bits_desc_signed_naive, to_bits_desc_unsigned_naive, }; #[test] pub fn test_to_bits_asc() { fn test_unsigned(x: T, out: &[bool]) { assert_eq!(x.to_bits_asc(), out); assert_eq!(to_bits_asc_unsigned_naive(x), out); assert_eq!(to_bits_asc_alt(&x), out); assert_eq!(x.bits().collect_vec(), out); } test_unsigned(0u8, &[]); test_unsigned(1u16, &[true]); test_unsigned(2u32, &[false, true]); test_unsigned(3u64, &[true, true]); test_unsigned(123u16, &[true, true, false, true, true, true, true]); test_unsigned(u8::MAX, &[true; 8]); fn test_signed(x: T, out: &[bool]) { assert_eq!(x.to_bits_asc(), out); assert_eq!(to_bits_asc_signed_naive(x), out); assert_eq!(to_bits_asc_alt(&x), out); assert_eq!(x.bits().collect_vec(), out); } test_signed(0i8, &[]); test_signed(1i16, &[true, false]); test_signed(2i32, &[false, true, false]); test_signed(3i64, &[true, true, false]); test_signed(-1i16, &[true]); test_signed(-2i32, &[false, true]); test_signed(-3i64, &[true, false, true]); test_signed(123i16, &[true, true, false, true, true, true, true, false]); test_signed( -123i16, &[true, false, true, false, false, false, false, true], ); test_signed(i8::MAX, &[true, true, true, true, true, true, true, false]); test_signed( i8::MIN, &[false, false, false, false, false, false, false, true], ); } #[test] pub fn test_to_bits_desc() { fn test_unsigned(x: T, out: &[bool]) { assert_eq!(x.to_bits_desc(), out); assert_eq!(to_bits_desc_unsigned_naive(x), out); assert_eq!(to_bits_desc_alt(&x), out); assert_eq!(x.bits().rev().collect_vec(), out); } test_unsigned(0u8, &[]); test_unsigned(1u16, &[true]); test_unsigned(2u32, &[true, false]); test_unsigned(3u64, &[true, true]); test_unsigned(123u16, &[true, true, true, true, false, true, true]); test_unsigned(u8::MAX, &[true; 8]); fn test_signed(x: T, out: &[bool]) { assert_eq!(x.to_bits_desc(), out); assert_eq!(to_bits_desc_signed_naive(x), out); assert_eq!(to_bits_desc_alt(&x), out); assert_eq!(x.bits().rev().collect_vec(), out); } test_signed(0i8, &[]); test_signed(1i16, &[false, true]); test_signed(2i32, &[false, true, false]); test_signed(3i64, &[false, true, true]); test_signed(-1i16, &[true]); test_signed(-2i32, &[true, false]); test_signed(-3i64, &[true, false, true]); test_signed(123i16, &[false, true, true, true, true, false, true, true]); test_signed( -123i16, &[true, false, false, false, false, true, false, true], ); test_signed(i8::MAX, &[false, true, true, true, true, true, true, true]); test_signed( i8::MIN, &[true, false, false, false, false, false, false, false], ); } fn to_bits_asc_properties_helper_unsigned() { unsigned_gen::().test_properties(|u| { let bits = u.to_bits_asc(); assert_eq!(to_bits_asc_unsigned_naive(u), bits); assert_eq!(to_bits_asc_alt(&u), bits); assert_eq!(u.bits().collect::>(), bits); assert_eq!( bits.iter().copied().rev().collect::>(), u.to_bits_desc() ); assert_eq!(T::from_bits_asc(bits.iter().copied()), u); if u != T::ZERO { assert_eq!(*bits.last().unwrap(), true); } assert_eq!(bits.len(), usize::exact_from(u.significant_bits())); }); } fn to_bits_asc_properties_helper_signed() { signed_gen::().test_properties(|i| { let bits = i.to_bits_asc(); assert_eq!(to_bits_asc_signed_naive(i), bits); assert_eq!(to_bits_asc_alt(&i), bits); assert_eq!(i.bits().collect::>(), bits); assert_eq!( bits.iter().copied().rev().collect::>(), i.to_bits_desc() ); assert_eq!(T::from_bits_asc(bits.iter().copied()), i); if i != T::ZERO { assert_eq!(*bits.last().unwrap(), i < T::ZERO); } let bit_len = bits.len(); assert!(bit_len <= usize::exact_from(T::WIDTH)); if bit_len > 1 { assert_ne!(bits[bit_len - 1], bits[bit_len - 2]); } }); } #[test] fn to_bits_asc_properties() { apply_fn_to_unsigneds!(to_bits_asc_properties_helper_unsigned); apply_fn_to_signeds!(to_bits_asc_properties_helper_signed); } fn to_bits_desc_properties_helper_unsigned() { unsigned_gen::().test_properties(|u| { let bits = u.to_bits_desc(); assert_eq!(to_bits_desc_unsigned_naive(u), bits); assert_eq!(to_bits_desc_alt(&u), bits); assert_eq!(u.bits().rev().collect::>(), bits); assert_eq!( bits.iter().copied().rev().collect::>(), u.to_bits_asc() ); assert_eq!(T::from_bits_desc(bits.iter().copied()), u); if u != T::ZERO { assert_eq!(bits[0], true); } assert_eq!(bits.len(), usize::exact_from(u.significant_bits())); }); } fn to_bits_desc_properties_helper_signed() { signed_gen::().test_properties(|i| { let bits = i.to_bits_desc(); assert_eq!(to_bits_desc_signed_naive(i), bits); assert_eq!(to_bits_desc_alt(&i), bits); assert_eq!(i.bits().rev().collect::>(), bits); assert_eq!( bits.iter().copied().rev().collect::>(), i.to_bits_asc() ); assert_eq!(T::from_bits_desc(bits.iter().copied()), i); if i != T::ZERO { assert_eq!(bits[0], i < T::ZERO); } let bit_len = bits.len(); assert!(bit_len <= usize::exact_from(T::WIDTH)); if bit_len > 1 { assert_ne!(bits[0], bits[1]); } }); } #[test] fn to_bits_desc_properties() { apply_fn_to_unsigneds!(to_bits_desc_properties_helper_unsigned); apply_fn_to_signeds!(to_bits_desc_properties_helper_signed); } malachite-base-0.4.16/tests/num/logic/bit_iterable.rs000064400000000000000000000141421046102023000206060ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::UnsignedAbs; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::{ExactFrom, WrappingFrom}; use malachite_base::num::logic::traits::{BitIterable, SignificantBits}; use malachite_base::test_util::common::test_double_ended_iterator_size_hint; use malachite_base::test_util::generators::{ signed_bool_vec_pair_gen_var_1, signed_gen, signed_unsigned_pair_gen_var_1, unsigned_bool_vec_pair_gen_var_1, unsigned_gen, unsigned_gen_var_5, unsigned_pair_gen_var_2, }; use std::cmp::Ordering::*; use std::ops::Index; #[test] pub fn test_bits() { let mut bits = 105u8.bits(); assert_eq!(bits.next(), Some(true)); assert_eq!(bits.next_back(), Some(true)); assert_eq!(bits.next_back(), Some(true)); assert_eq!(bits.next_back(), Some(false)); assert_eq!(bits.next(), Some(false)); assert_eq!(bits.next(), Some(false)); assert_eq!(bits.next(), Some(true)); assert_eq!(bits.next(), None); assert_eq!(bits.next_back(), None); assert_eq!(bits[0], true); assert_eq!(bits[1], false); assert_eq!(bits[2], false); assert_eq!(bits[3], true); assert_eq!(bits[4], false); assert_eq!(bits[5], true); assert_eq!(bits[6], true); assert_eq!(bits[7], false); assert_eq!(bits[8], false); let mut bits = 105u32.bits(); assert_eq!(bits.next_back(), Some(true)); assert_eq!(bits.next(), Some(true)); assert_eq!(bits.next(), Some(false)); assert_eq!(bits.next(), Some(false)); assert_eq!(bits.next_back(), Some(true)); assert_eq!(bits.next_back(), Some(false)); assert_eq!(bits.next_back(), Some(true)); assert_eq!(bits.next(), None); assert_eq!(bits.next_back(), None); let mut bits = (-105i8).bits(); assert_eq!(bits.next(), Some(true)); assert_eq!(bits.next_back(), Some(true)); assert_eq!(bits.next_back(), Some(false)); assert_eq!(bits.next_back(), Some(false)); assert_eq!(bits.next(), Some(true)); assert_eq!(bits.next(), Some(true)); assert_eq!(bits.next(), Some(false)); assert_eq!(bits.next(), Some(true)); assert_eq!(bits.next(), None); assert_eq!(bits.next_back(), None); assert_eq!(bits[0], true); assert_eq!(bits[1], true); assert_eq!(bits[2], true); assert_eq!(bits[3], false); assert_eq!(bits[4], true); assert_eq!(bits[5], false); assert_eq!(bits[6], false); assert_eq!(bits[7], true); assert_eq!(bits[8], true); let mut bits = (-105i32).bits(); assert_eq!(bits.next_back(), Some(true)); assert_eq!(bits.next(), Some(true)); assert_eq!(bits.next(), Some(true)); assert_eq!(bits.next(), Some(true)); assert_eq!(bits.next_back(), Some(false)); assert_eq!(bits.next_back(), Some(false)); assert_eq!(bits.next_back(), Some(true)); assert_eq!(bits.next_back(), Some(false)); assert_eq!(bits.next(), None); assert_eq!(bits.next_back(), None); } fn bits_properties_helper_unsigned() where T::BitIterator: Clone + Index, { unsigned_gen::().test_properties(|n| { test_double_ended_iterator_size_hint(n.bits(), usize::exact_from(n.significant_bits())); }); unsigned_bool_vec_pair_gen_var_1::().test_properties(|(n, bs)| { let mut bits = n.bits(); let mut bit_vec = Vec::new(); let mut i = 0; for b in bs { if b { bit_vec.insert(i, bits.next().unwrap()); i += 1; } else { bit_vec.insert(i, bits.next_back().unwrap()); } } assert!(bits.next().is_none()); assert!(bits.next_back().is_none()); assert_eq!(n.to_bits_asc(), bit_vec); }); unsigned_pair_gen_var_2::().test_properties(|(n, u)| { if u < n.significant_bits() { assert_eq!(n.bits()[u], n.to_bits_asc()[usize::exact_from(u)]); } else { assert_eq!(n.bits()[u], false); } }); unsigned_gen_var_5().test_properties(|u| { assert_eq!(T::ZERO.bits()[u], false); }); } fn bits_properties_helper_signed() where T::BitIterator: Clone + Index, ::Output: PrimitiveUnsigned + WrappingFrom, { signed_gen::().test_properties(|i| { let unsigned = ::Output::wrapping_from(i); let significant_bits = match i.sign() { Equal => 0, Greater => unsigned.significant_bits() + 1, Less => (!unsigned).significant_bits() + 1, }; test_double_ended_iterator_size_hint(i.bits(), usize::exact_from(significant_bits)); }); signed_bool_vec_pair_gen_var_1::().test_properties(|(n, bs)| { let mut bits = n.bits(); let mut bit_vec = Vec::new(); let mut i = 0; for b in bs { if b { bit_vec.insert(i, bits.next().unwrap()); i += 1; } else { bit_vec.insert(i, bits.next_back().unwrap()); } } assert!(bits.next().is_none()); assert!(bits.next_back().is_none()); assert_eq!(n.to_bits_asc(), bit_vec); }); signed_unsigned_pair_gen_var_1::().test_properties(|(n, u)| { if u < n.significant_bits() { assert_eq!(n.bits()[u], n.to_bits_asc()[usize::exact_from(u)]); } else { assert_eq!(n.bits()[u], n < T::ZERO); } }); unsigned_gen_var_5().test_properties(|u| { assert_eq!(T::ZERO.bits()[u], false); }); } #[test] fn bits_properties() { apply_fn_to_unsigneds!(bits_properties_helper_unsigned); apply_fn_to_signeds!(bits_properties_helper_signed); } malachite-base-0.4.16/tests/num/logic/bit_scan/index_of_next_false_bit.rs000064400000000000000000000107211046102023000246030ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::logic::traits::TrailingZeros; use malachite_base::test_util::generators::{ signed_gen_var_3, signed_unsigned_pair_gen_var_1, unsigned_gen, unsigned_pair_gen_var_2, }; #[test] pub fn test_index_of_next_false_bit() { fn test_unsigned(x: T, start: u64, out: Option) { assert_eq!(x.index_of_next_false_bit(start), out); } test_unsigned(0xb00000000u64, 0, Some(0)); test_unsigned(0xb00000000u64, 20, Some(20)); test_unsigned(0xb00000000u64, 31, Some(31)); test_unsigned(0xb00000000u64, 32, Some(34)); test_unsigned(0xb00000000u64, 33, Some(34)); test_unsigned(0xb00000000u64, 34, Some(34)); test_unsigned(0xb00000000u64, 35, Some(36)); test_unsigned(0xb00000000u64, 100, Some(100)); test_unsigned(0xb00000000u128, 0, Some(0)); test_unsigned(0xb00000000u128, 20, Some(20)); test_unsigned(0xb00000000u128, 31, Some(31)); test_unsigned(0xb00000000u128, 32, Some(34)); test_unsigned(0xb00000000u128, 33, Some(34)); test_unsigned(0xb00000000u128, 34, Some(34)); test_unsigned(0xb00000000u128, 35, Some(36)); test_unsigned(0xb00000000u128, 100, Some(100)); fn test_signed(x: T, start: u64, out: Option) { assert_eq!(x.index_of_next_false_bit(start), out); } test_signed(-0x500000000i64, 0, Some(0)); test_signed(-0x500000000i64, 20, Some(20)); test_signed(-0x500000000i64, 31, Some(31)); test_signed(-0x500000000i64, 32, Some(34)); test_signed(-0x500000000i64, 33, Some(34)); test_signed(-0x500000000i64, 34, Some(34)); test_signed(-0x500000000i64, 35, None); test_signed(-0x500000000i64, 100, None); test_signed(-0x500000000i128, 0, Some(0)); test_signed(-0x500000000i128, 20, Some(20)); test_signed(-0x500000000i128, 31, Some(31)); test_signed(-0x500000000i128, 32, Some(34)); test_signed(-0x500000000i128, 33, Some(34)); test_signed(-0x500000000i128, 34, Some(34)); test_signed(-0x500000000i128, 35, None); test_signed(-0x500000000i128, 100, None); } fn properties_helper_unsigned() { unsigned_pair_gen_var_2::().test_properties(|(n, u)| { let result = n.index_of_next_false_bit(u).unwrap(); assert!(result >= u); assert!(!n.get_bit(result)); assert_eq!(result == u, !n.get_bit(u)); assert_eq!( (!n).index_of_next_true_bit(u), if result < T::WIDTH { Some(result) } else { None } ); }); unsigned_gen::().test_properties(|n| { assert_eq!( n.index_of_next_false_bit(0), Some(TrailingZeros::trailing_zeros(!n)) ); }); unsigned_gen::().test_properties(|u| { assert_eq!(T::ZERO.index_of_next_false_bit(u), Some(u)); }); } fn properties_helper_signed() { signed_unsigned_pair_gen_var_1::().test_properties(|(n, u)| { let result = n.index_of_next_false_bit(u); assert_eq!( result.is_some(), if u >= T::WIDTH { n >= T::ZERO } else { n | T::low_mask(u) != T::NEGATIVE_ONE } ); if let Some(result) = result { assert!(result >= u); assert!(!n.get_bit(result)); assert_eq!(result == u, !n.get_bit(u)); } assert_eq!((!n).index_of_next_true_bit(u), result); }); signed_gen_var_3::().test_properties(|n| { assert_eq!( n.index_of_next_false_bit(0), Some(TrailingZeros::trailing_zeros(!n)) ); }); unsigned_gen::().test_properties(|u| { assert_eq!(T::ZERO.index_of_next_false_bit(u), Some(u)); assert_eq!(T::NEGATIVE_ONE.index_of_next_false_bit(u), None); }); } #[test] fn index_of_next_false_bit_properties() { apply_fn_to_unsigneds!(properties_helper_unsigned); apply_fn_to_signeds!(properties_helper_signed); } malachite-base-0.4.16/tests/num/logic/bit_scan/index_of_next_true_bit.rs000064400000000000000000000111001046102023000244600ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::logic::traits::TrailingZeros; use malachite_base::test_util::generators::{ signed_gen_var_3, signed_unsigned_pair_gen_var_1, unsigned_gen, unsigned_gen_var_1, unsigned_pair_gen_var_2, }; #[test] pub fn test_index_of_next_true_bit() { fn test_unsigned(x: T, start: u64, out: Option) { assert_eq!(x.index_of_next_true_bit(start), out); } test_unsigned(0xb00000000u64, 0, Some(32)); test_unsigned(0xb00000000u64, 20, Some(32)); test_unsigned(0xb00000000u64, 31, Some(32)); test_unsigned(0xb00000000u64, 32, Some(32)); test_unsigned(0xb00000000u64, 33, Some(33)); test_unsigned(0xb00000000u64, 34, Some(35)); test_unsigned(0xb00000000u64, 35, Some(35)); test_unsigned(0xb00000000u64, 36, None); test_unsigned(0xb00000000u64, 100, None); test_unsigned(0xb00000000u128, 0, Some(32)); test_unsigned(0xb00000000u128, 20, Some(32)); test_unsigned(0xb00000000u128, 31, Some(32)); test_unsigned(0xb00000000u128, 32, Some(32)); test_unsigned(0xb00000000u128, 33, Some(33)); test_unsigned(0xb00000000u128, 34, Some(35)); test_unsigned(0xb00000000u128, 35, Some(35)); test_unsigned(0xb00000000u128, 36, None); test_unsigned(0xb00000000u128, 100, None); fn test_signed(x: T, start: u64, out: Option) { assert_eq!(x.index_of_next_true_bit(start), out); } test_signed(-0x500000000i64, 0, Some(32)); test_signed(-0x500000000i64, 20, Some(32)); test_signed(-0x500000000i64, 31, Some(32)); test_signed(-0x500000000i64, 32, Some(32)); test_signed(-0x500000000i64, 33, Some(33)); test_signed(-0x500000000i64, 34, Some(35)); test_signed(-0x500000000i64, 35, Some(35)); test_signed(-0x500000000i64, 36, Some(36)); test_signed(-0x500000000i64, 100, Some(100)); test_signed(-0x500000000i128, 0, Some(32)); test_signed(-0x500000000i128, 20, Some(32)); test_signed(-0x500000000i128, 31, Some(32)); test_signed(-0x500000000i128, 32, Some(32)); test_signed(-0x500000000i128, 33, Some(33)); test_signed(-0x500000000i128, 34, Some(35)); test_signed(-0x500000000i128, 35, Some(35)); test_signed(-0x500000000i128, 36, Some(36)); test_signed(-0x500000000i128, 100, Some(100)); } fn properties_helper_unsigned() { unsigned_pair_gen_var_2::().test_properties(|(n, u)| { let result = n.index_of_next_true_bit(u); assert_eq!(result.is_some(), u < n.significant_bits()); if let Some(result) = result { assert!(result >= u); assert!(n.get_bit(result)); assert_eq!(result == u, n.get_bit(u)); } }); unsigned_gen_var_1::().test_properties(|n| { assert_eq!( n.index_of_next_true_bit(0), Some(TrailingZeros::trailing_zeros(n)) ); }); unsigned_gen::().test_properties(|u| { assert_eq!(T::ZERO.index_of_next_true_bit(u), None); }); } fn properties_helper_signed() { signed_unsigned_pair_gen_var_1::().test_properties(|(n, u)| { let result = n.index_of_next_true_bit(u); assert_eq!( result.is_some(), if u >= T::WIDTH { n < T::ZERO } else { n >> u != T::ZERO } ); if let Some(result) = result { assert!(result >= u); assert!(n.get_bit(result)); assert_eq!(result == u, n.get_bit(u)); } assert_eq!((!n).index_of_next_false_bit(u), result); }); signed_gen_var_3::().test_properties(|n| { assert_eq!( n.index_of_next_true_bit(0), Some(TrailingZeros::trailing_zeros(n)) ); }); unsigned_gen::().test_properties(|u| { assert_eq!(T::ZERO.index_of_next_true_bit(u), None); assert_eq!(T::NEGATIVE_ONE.index_of_next_true_bit(u), Some(u)); }); } #[test] fn index_of_next_true_bit_properties() { apply_fn_to_unsigneds!(properties_helper_unsigned); apply_fn_to_signeds!(properties_helper_signed); } malachite-base-0.4.16/tests/num/logic/get_highest_bit.rs000064400000000000000000000027301046102023000213110ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{signed_gen, unsigned_gen}; #[test] pub fn test_get_highest_bit() { assert_eq!(0u8.get_highest_bit(), false); assert_eq!(123u32.get_highest_bit(), false); assert_eq!(4000000000u32.get_highest_bit(), true); assert_eq!(2000000000i32.get_highest_bit(), false); assert_eq!((-2000000000i32).get_highest_bit(), true); } fn get_highest_bit_properties_helper_unsigned() { unsigned_gen::().test_properties(|u| { assert_eq!(u.get_highest_bit(), u >= T::power_of_2(T::WIDTH - 1)); }); } fn get_highest_bit_properties_helper_signed() { signed_gen::().test_properties(|i| { assert_eq!(i.get_highest_bit(), i < T::ZERO); }); } #[test] fn get_highest_bit_properties() { apply_fn_to_unsigneds!(get_highest_bit_properties_helper_unsigned); apply_fn_to_signeds!(get_highest_bit_properties_helper_signed); } malachite-base-0.4.16/tests/num/logic/hamming_distance.rs000064400000000000000000000107421046102023000214550ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::logic::traits::{CountOnes, CountZeros}; use malachite_base::test_util::generators::{ signed_gen, signed_gen_var_2, signed_gen_var_4, signed_pair_gen, signed_pair_gen_var_1, signed_triple_gen_var_3, unsigned_gen, unsigned_pair_gen_var_27, unsigned_triple_gen_var_19, }; #[test] pub fn test_hamming_distance() { fn test(x: T, y: T, out: u64) { assert_eq!(x.hamming_distance(y), out); } test(123u16, 456u16, 6); test(0xffffu32, 0xffff0000u32, 32); test(0xffffu32, u32::MAX, 16); test(0xffff0000u32, u32::MAX, 16); } #[test] pub fn test_checked_hamming_distance() { fn test(x: T, y: T, out: Option) { assert_eq!(x.checked_hamming_distance(y), out); } test(123i32, 456i32, Some(6)); test(-123i32, -456i32, Some(7)); test(0i8, 127i8, Some(7)); test(0i8, -1i8, None); test(-1i8, -128i8, Some(7)); test(0i128, i128::MAX, Some(127)); test(0i128, -1i128, None); test(-1i128, i128::MIN, Some(127)); test(0xffffi32, 0x7fff0000i32, Some(31)); test(0xffffi32, i32::MAX, Some(15)); test(0x7fff0000i32, i32::MAX, Some(16)); } fn hamming_distance_properties_helper() { unsigned_pair_gen_var_27::().test_properties(|(x, y)| { let distance = x.hamming_distance(y); assert_eq!(y.hamming_distance(x), distance); assert_eq!(distance == 0, x == y); assert_eq!(CountOnes::count_ones(x ^ y), distance); assert_eq!((!x).hamming_distance(!y), distance); }); unsigned_triple_gen_var_19::().test_properties(|(x, y, z)| { assert!(x.hamming_distance(z) <= x.hamming_distance(y) + y.hamming_distance(z)); }); unsigned_gen::().test_properties(|x| { assert_eq!(x.hamming_distance(x), 0); assert_eq!(x.hamming_distance(!x), T::WIDTH); assert_eq!(x.hamming_distance(T::ZERO), CountOnes::count_ones(x)); assert_eq!(T::ZERO.hamming_distance(x), CountOnes::count_ones(x)); }); } #[test] fn hamming_distance_properties() { apply_fn_to_unsigneds!(hamming_distance_properties_helper); } fn checked_hamming_distance_properties_helper() { signed_pair_gen::().test_properties(|(x, y)| { let distance = x.checked_hamming_distance(y); assert_eq!(y.checked_hamming_distance(x), distance); assert_eq!(distance == Some(0), x == y); assert_eq!((!x).checked_hamming_distance(!y), distance); }); signed_pair_gen_var_1::().test_properties(|(x, y)| { let distance = x.checked_hamming_distance(y).unwrap(); assert_eq!(y.checked_hamming_distance(x).unwrap(), distance); assert_eq!(distance == 0, x == y); assert_eq!(CountOnes::count_ones(x ^ y), distance); assert_eq!((!x).checked_hamming_distance(!y).unwrap(), distance); }); signed_triple_gen_var_3::().test_properties(|(x, y, z)| { assert!( x.checked_hamming_distance(z).unwrap() <= x.checked_hamming_distance(y).unwrap() + y.checked_hamming_distance(z).unwrap() ); }); signed_gen::().test_properties(|x| { assert_eq!(x.checked_hamming_distance(x), Some(0)); assert_eq!(x.checked_hamming_distance(!x), None); }); signed_gen_var_2::().test_properties(|x| { assert_eq!( x.checked_hamming_distance(T::ZERO), Some(CountOnes::count_ones(x)) ); assert_eq!( T::ZERO.checked_hamming_distance(x), Some(CountOnes::count_ones(x)) ); }); signed_gen_var_4::().test_properties(|x| { assert_eq!( x.checked_hamming_distance(T::NEGATIVE_ONE), Some(CountZeros::count_zeros(x)) ); assert_eq!( T::NEGATIVE_ONE.checked_hamming_distance(x), Some(CountZeros::count_zeros(x)) ); }); } #[test] fn checked_hamming_distance_properties() { apply_fn_to_signeds!(checked_hamming_distance_properties_helper); } malachite-base-0.4.16/tests/num/logic/low_mask.rs000064400000000000000000000046341046102023000200020ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::unsigned_gen_var_9; use std::panic::catch_unwind; fn low_mask_primitive_helper() { let test = |bits, out| { assert_eq!(T::low_mask(bits), out); }; test(0, T::ZERO); test(1, T::ONE); test(2, T::exact_from(3)); test(3, T::exact_from(7)); } fn low_mask_unsigned_helper() { let test = |bits, out| { assert_eq!(T::low_mask(bits), out); }; test(T::WIDTH - 1, (T::ONE << (T::WIDTH - 1)) - T::ONE); test(T::WIDTH, T::MAX); } fn low_mask_signed_helper() { let test = |bits, out| { assert_eq!(T::low_mask(bits), out); }; test(T::WIDTH - 1, T::MAX); test(T::WIDTH, T::NEGATIVE_ONE); } #[test] fn test_low_mask() { apply_fn_to_primitive_ints!(low_mask_primitive_helper); apply_fn_to_unsigneds!(low_mask_unsigned_helper); apply_fn_to_signeds!(low_mask_signed_helper); } fn low_mask_fail_helper() { assert_panic!(T::low_mask(T::WIDTH + 1)); } #[test] fn low_mask_fail() { apply_fn_to_primitive_ints!(low_mask_fail_helper); } fn low_mask_properties_helper_unsigned() { unsigned_gen_var_9::().test_properties(|bits| { let n = T::low_mask(bits); assert_eq!(n.count_ones(), bits); assert_eq!(n.index_of_next_false_bit(0), Some(bits)); }); } fn low_mask_properties_helper_signed() { unsigned_gen_var_9::().test_properties(|bits| { let n = T::low_mask(bits); assert_eq!(n.count_ones(), bits); assert_eq!( n.index_of_next_false_bit(0), if bits == T::WIDTH { None } else { Some(bits) } ); }); } #[test] fn low_mask_properties() { apply_fn_to_unsigneds!(low_mask_properties_helper_unsigned); apply_fn_to_signeds!(low_mask_properties_helper_signed); } malachite-base-0.4.16/tests/num/logic/not_assign.rs000064400000000000000000000034001046102023000203200ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{signed_gen, unsigned_gen}; fn not_assign_helper() { let test = |n: T| { let mut x = n; x.not_assign(); assert_eq!(x, !n); }; test(T::ZERO); test(T::ONE); test(T::exact_from(2)); test(T::exact_from(3)); test(T::exact_from(4)); test(T::exact_from(5)); test(T::exact_from(100)); test(T::exact_from(63)); test(T::exact_from(64)); test(T::MIN); test(T::MAX); } #[test] fn test_not_assign() { apply_fn_to_primitive_ints!(not_assign_helper); } fn not_assign_properties_helper_unsigned() { unsigned_gen::().test_properties(|u| { let mut x = u; x.not_assign(); assert_eq!(x, !u); x.not_assign(); assert_eq!(x, u); }); } fn not_assign_properties_helper_signed() { signed_gen::().test_properties(|i| { let mut x = i; x.not_assign(); assert_eq!(x, !i); x.not_assign(); assert_eq!(x, i); }); } #[test] fn not_assign_properties() { apply_fn_to_unsigneds!(not_assign_properties_helper_unsigned); apply_fn_to_signeds!(not_assign_properties_helper_signed); } malachite-base-0.4.16/tests/num/logic/significant_bits.rs000064400000000000000000000047331046102023000215050ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::test_util::generators::{signed_gen, unsigned_gen}; fn significant_bits_helper() { let test = |n, out| { assert_eq!(T::exact_from(n).significant_bits(), out); }; test(0, 0); test(1, 1); test(2, 2); test(3, 2); test(4, 3); test(5, 3); test(100, 7); test(63, 6); test(64, 7); } fn significant_bits_helper_unsigned() { let test = |n: T, out: u64| { assert_eq!(n.significant_bits(), out); }; test(T::MAX, T::WIDTH); } fn significant_bits_helper_signed() { let test = |n: T, out: u64| { assert_eq!(n.significant_bits(), out); }; test(T::MAX, T::WIDTH - 1); test(T::MIN, T::WIDTH); } #[test] fn test_significant_bits() { apply_fn_to_primitive_ints!(significant_bits_helper); apply_fn_to_unsigneds!(significant_bits_helper_unsigned); apply_fn_to_signeds!(significant_bits_helper_signed); } fn significant_bits_properties_helper_unsigned() { unsigned_gen::().test_properties(|u| { let significant_bits = u.significant_bits(); assert!(significant_bits <= T::WIDTH); assert_eq!(significant_bits == 0, u == T::ZERO); if u != T::ZERO { assert_eq!(significant_bits, u.floor_log_base_2() + 1); } }); } fn significant_bits_properties_helper_signed() { signed_gen::().test_properties(|i| { let significant_bits = i.significant_bits(); assert!(significant_bits <= T::WIDTH); assert_eq!(significant_bits == 0, i == T::ZERO); assert_eq!(significant_bits == T::WIDTH, i == T::MIN); assert_eq!(i.wrapping_neg().significant_bits(), significant_bits); }); } #[test] fn significant_bits_properties() { apply_fn_to_unsigneds!(significant_bits_properties_helper_unsigned); apply_fn_to_signeds!(significant_bits_properties_helper_signed); } malachite-base-0.4.16/tests/num/random/geometric/geometric_random_natural_signeds.rs000064400000000000000000000167161046102023000271130ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::geometric::geometric_random_natural_signeds; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::moments::{ truncated_geometric_dist_assertions, CheckedToF64, MomentStats, }; use std::panic::catch_unwind; fn geometric_random_natural_signeds_helper( um_numerator: u64, um_denominator: u64, expected_values: &[T], expected_common_values: &[(T, usize)], expected_pop_median: (T, Option), expected_sample_median: (T, Option), expected_pop_moment_stats: MomentStats, expected_sample_moment_stats: MomentStats, ) { truncated_geometric_dist_assertions( geometric_random_natural_signeds::(EXAMPLE_SEED, um_numerator, um_denominator), T::ZERO, T::MAX, um_numerator, um_denominator, expected_values, expected_common_values, expected_pop_median, expected_sample_median, expected_pop_moment_stats, expected_sample_moment_stats, ); } #[test] fn test_geometric_random_natural_signeds() { // i64, um = 1 / 64 let values = &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]; let common_values = &[(0, 984537), (1, 15210), (2, 253)]; let pop_median = (0, None); let sample_median = (0, None); let pop_moment_stats = MomentStats { mean: NiceFloat(0.015624999999999944), standard_deviation: NiceFloat(0.12597277731716458), skewness: NiceFloat(8.186292482887549), excess_kurtosis: NiceFloat(69.01538461538773), }; let sample_moment_stats = MomentStats { mean: NiceFloat(0.015716000000000004), standard_deviation: NiceFloat(0.1263923388462427), skewness: NiceFloat(8.160460378454996), excess_kurtosis: NiceFloat(68.31033619043119), }; geometric_random_natural_signeds_helper::( 1, 64, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i64, um = 1 let values = &[1, 0, 0, 3, 4, 4, 1, 0, 0, 1, 0, 0, 2, 2, 0, 0, 1, 0, 3, 1]; let common_values = &[ (0, 500085), (1, 249510), (2, 125328), (3, 62428), (4, 31280), (5, 15676), (6, 7853), (7, 3994), (8, 1932), (9, 942), ]; let pop_median = (0, Some(1)); let sample_median = (0, None); let pop_moment_stats = MomentStats { mean: NiceFloat(1.0), standard_deviation: NiceFloat(std::f64::consts::SQRT_2), skewness: NiceFloat(2.1213203435596424), excess_kurtosis: NiceFloat(6.5), }; let sample_moment_stats = MomentStats { mean: NiceFloat(1.0006159999999573), standard_deviation: NiceFloat(1.414547850547892), skewness: NiceFloat(2.1140569440125403), excess_kurtosis: NiceFloat(6.4341815215340805), }; geometric_random_natural_signeds_helper::( 1, 1, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i64, um = 12345/10000 let values = &[1, 3, 8, 2, 2, 0, 1, 1, 0, 0, 0, 0, 1, 1, 7, 0, 0, 3, 0, 0]; let common_values = &[ (0, 446911), (1, 246858), (2, 137217), (3, 75488), (4, 41605), (5, 23149), (6, 12981), (7, 7024), (8, 3848), (9, 2206), ]; let pop_median = (1, None); let sample_median = (1, None); let pop_moment_stats = MomentStats { mean: NiceFloat(1.2344999999999997), standard_deviation: NiceFloat(1.6608703290744884), skewness: NiceFloat(2.088663960860256), excess_kurtosis: NiceFloat(6.362517141396456), }; let sample_moment_stats = MomentStats { mean: NiceFloat(1.2380129999999983), standard_deviation: NiceFloat(1.6649767517832197), skewness: NiceFloat(2.0942793135700466), excess_kurtosis: NiceFloat(6.469904862333731), }; geometric_random_natural_signeds_helper::( 12345, 10000, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i8, um = 64 let values = &[53, 90, 125, 70, 18, 41, 109, 5, 96, 93, 33, 18, 89, 6, 17, 1, 1, 2, 123, 6]; let common_values = &[ (0, 17832), (1, 17626), (2, 17520), (3, 16976), (4, 16636), (5, 16395), (6, 16282), (7, 16231), (8, 15823), (9, 15338), ]; let pop_median = (36, None); let sample_median = (36, None); let pop_moment_stats = MomentStats { mean: NiceFloat(43.60377071780361), standard_deviation: NiceFloat(33.66417209656191), skewness: NiceFloat(0.6750025251723596), excess_kurtosis: NiceFloat(-0.5593715461161066), }; let sample_moment_stats = MomentStats { mean: NiceFloat(43.58636099999891), standard_deviation: NiceFloat(33.66410490492275), skewness: NiceFloat(0.6756300365723926), excess_kurtosis: NiceFloat(-0.5577628868956519), }; geometric_random_natural_signeds_helper::( 64, 1, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i8, um = 1000 let values = &[24, 115, 120, 25, 104, 87, 80, 112, 37, 35, 68, 76, 40, 37, 117, 65, 124, 119, 0, 91]; let common_values = &[ (0, 8435), (4, 8343), (1, 8333), (5, 8306), (18, 8302), (8, 8298), (11, 8272), (2, 8267), (7, 8259), (3, 8248), ]; let pop_median = (61, None); let sample_median = (61, None); let pop_moment_stats = MomentStats { mean: NiceFloat(62.13580429363961), standard_deviation: NiceFloat(36.93417606567501), skewness: NiceFloat(0.044319234592297266), excess_kurtosis: NiceFloat(-1.197434568717292), }; let sample_moment_stats = MomentStats { mean: NiceFloat(62.1484240000004), standard_deviation: NiceFloat(36.919219186555864), skewness: NiceFloat(0.04244530182494719), excess_kurtosis: NiceFloat(-1.196858045789015), }; geometric_random_natural_signeds_helper::( 1000, 1, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); } fn geometric_random_natural_signeds_fail_helper() { assert_panic!(geometric_random_natural_signeds::(EXAMPLE_SEED, 0, 1)); assert_panic!(geometric_random_natural_signeds::(EXAMPLE_SEED, 1, 0)); assert_panic!(geometric_random_natural_signeds::( EXAMPLE_SEED, u64::MAX, u64::MAX - 1 )); } #[test] fn geometric_random_natural_signeds_fail() { apply_fn_to_signeds!(geometric_random_natural_signeds_fail_helper); } malachite-base-0.4.16/tests/num/random/geometric/geometric_random_negative_signeds.rs000064400000000000000000000175261046102023000272470ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::UnsignedAbs; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::WrappingFrom; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::geometric::geometric_random_negative_signeds; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::moments::{ negative_truncated_geometric_dist_assertions, CheckedToF64, MomentStats, }; use std::panic::catch_unwind; fn geometric_random_negative_signeds_helper< U: CheckedToF64 + PrimitiveUnsigned, S: CheckedToF64 + PrimitiveSigned + UnsignedAbs + WrappingFrom, >( abs_um_numerator: u64, abs_um_denominator: u64, expected_values: &[S], expected_common_values: &[(S, usize)], expected_pop_median: (S, Option), expected_sample_median: (S, Option), expected_pop_moment_stats: MomentStats, expected_sample_moment_stats: MomentStats, ) { negative_truncated_geometric_dist_assertions( geometric_random_negative_signeds::(EXAMPLE_SEED, abs_um_numerator, abs_um_denominator), S::NEGATIVE_ONE, S::MIN, abs_um_numerator, abs_um_denominator, expected_values, expected_common_values, expected_pop_median, expected_sample_median, expected_pop_moment_stats, expected_sample_moment_stats, ); } #[test] fn test_geometric_random_negative_signeds() { // i64, um = -65 / 64 let values = &[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2]; let common_values = &[(-1, 984537), (-2, 15210), (-3, 253)]; let pop_median = (-1, None); let sample_median = (-1, None); let pop_moment_stats = MomentStats { mean: NiceFloat(-1.015625), standard_deviation: NiceFloat(0.12597277731716458), skewness: NiceFloat(-8.186292482887549), excess_kurtosis: NiceFloat(69.01538461538773), }; let sample_moment_stats = MomentStats { mean: NiceFloat(-1.0157160000000027), standard_deviation: NiceFloat(0.12639233884624257), skewness: NiceFloat(-8.160460378454992), excess_kurtosis: NiceFloat(68.31033619043166), }; geometric_random_negative_signeds_helper::<_, i64>( 65, 64, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i64, um = -12345/10000 let values = &[-1, -1, -1, -1, -1, -1, -1, -1, -2, -1, -1, -1, -1, -1, -2, -2, -1, -1, -1, -1]; let common_values = &[ (-1, 809395), (-2, 154707), (-3, 29037), (-4, 5577), (-5, 1053), (-6, 185), (-7, 40), (-8, 5), (-9, 1), ]; let pop_median = (-1, None); let sample_median = (-1, None); let pop_moment_stats = MomentStats { mean: NiceFloat(-1.2345), standard_deviation: NiceFloat(0.538042981554448), skewness: NiceFloat(-2.730265146765687), excess_kurtosis: NiceFloat(9.45434777164341), }; let sample_moment_stats = MomentStats { mean: NiceFloat(-1.2349320000000084), standard_deviation: NiceFloat(0.5376590410783139), skewness: NiceFloat(-2.716807176148366), excess_kurtosis: NiceFloat(9.308727522629948), }; geometric_random_negative_signeds_helper::<_, i64>( 12345, 10000, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i64, um = -2 let values = &[-2, -1, -1, -4, -5, -5, -2, -1, -1, -2, -1, -1, -3, -3, -1, -1, -2, -1, -4, -2]; let common_values = &[ (-1, 500085), (-2, 249510), (-3, 125328), (-4, 62428), (-5, 31280), (-6, 15676), (-7, 7853), (-8, 3994), (-9, 1932), (-10, 942), ]; let pop_median = (-2, Some(-1)); let sample_median = (-1, None); let pop_moment_stats = MomentStats { mean: NiceFloat(-2.0), standard_deviation: NiceFloat(std::f64::consts::SQRT_2), skewness: NiceFloat(-2.1213203435596424), excess_kurtosis: NiceFloat(6.5), }; let sample_moment_stats = MomentStats { mean: NiceFloat(-2.0006159999998947), standard_deviation: NiceFloat(1.414547850547892), skewness: NiceFloat(-2.114056944012543), excess_kurtosis: NiceFloat(6.4341815215340645), }; geometric_random_negative_signeds_helper::<_, i64>( 2, 1, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i8, um = -64 let values = &[ -53, -56, -71, -20, -113, -87, -55, -44, -4, -17, -44, -36, -5, -25, -55, -9, -114, -24, -15, -76, ]; let common_values = &[ (-1, 18323), (-2, 17814), (-3, 17620), (-4, 17269), (-5, 17057), (-6, 16684), (-7, 16509), (-8, 16164), (-9, 15914), (-10, 15665), ]; let pop_median = (-37, None); let sample_median = (-37, None); let pop_moment_stats = MomentStats { mean: NiceFloat(-44.32782748571844), standard_deviation: NiceFloat(33.57033730453578), skewness: NiceFloat(-0.6852077716881376), excess_kurtosis: NiceFloat(-0.5394700086619175), }; let sample_moment_stats = MomentStats { mean: NiceFloat(-44.31098999999839), standard_deviation: NiceFloat(33.572216166252275), skewness: NiceFloat(-0.6830069791725721), excess_kurtosis: NiceFloat(-0.5435066974705061), }; geometric_random_negative_signeds_helper::<_, i8>( 64, 1, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i8, um = -1000 let values = &[ -25, -111, -118, -26, -101, -88, -81, -112, -38, -36, -68, -76, -41, -36, -118, -66, -123, -120, -128, -92, ]; let common_values = &[ (-1, 8409), (-6, 8360), (-2, 8357), (-7, 8328), (-5, 8309), (-14, 8300), (-22, 8268), (-12, 8262), (-18, 8254), (-9, 8249), ]; let pop_median = (-62, None); let sample_median = (-63, None); let pop_moment_stats = MomentStats { mean: NiceFloat(-63.134440160748206), standard_deviation: NiceFloat(36.934145822824206), skewness: NiceFloat(-0.04436357375743275), excess_kurtosis: NiceFloat(-1.1974286638022889), }; let sample_moment_stats = MomentStats { mean: NiceFloat(-63.15733700000316), standard_deviation: NiceFloat(36.91734106024568), skewness: NiceFloat(-0.04254845146202895), excess_kurtosis: NiceFloat(-1.1968222027376492), }; geometric_random_negative_signeds_helper::<_, i8>( 1000, 1, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); } fn geometric_random_negative_signeds_fail_helper() { assert_panic!(geometric_random_negative_signeds::(EXAMPLE_SEED, 1, 0)); assert_panic!(geometric_random_negative_signeds::(EXAMPLE_SEED, 2, 3)); } #[test] fn geometric_random_negative_signeds_fail() { apply_fn_to_signeds!(geometric_random_negative_signeds_fail_helper); } malachite-base-0.4.16/tests/num/random/geometric/geometric_random_nonzero_signeds.rs000064400000000000000000000176151046102023000271360ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::geometric::geometric_random_nonzero_signeds; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::moments::{ double_nonzero_truncated_geometric_dist_assertions, CheckedToF64, MomentStats, }; use std::panic::catch_unwind; fn geometric_random_nonzero_signeds_helper( um_numerator: u64, um_denominator: u64, expected_values: &[T], expected_common_values: &[(T, usize)], expected_abs_mean: NiceFloat, expected_pop_median: (T, Option), expected_sample_median: (T, Option), expected_pop_moment_stats: MomentStats, expected_sample_moment_stats: MomentStats, ) { double_nonzero_truncated_geometric_dist_assertions( geometric_random_nonzero_signeds::(EXAMPLE_SEED, um_numerator, um_denominator), T::MIN, T::MAX, um_numerator, um_denominator, expected_values, expected_common_values, expected_abs_mean, expected_pop_median, expected_sample_median, expected_pop_moment_stats, expected_sample_moment_stats, ); } #[test] fn test_geometric_random_nonzero_signeds() { // i64, um = 65 / 64 let values = &[-1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1]; let common_values = &[(1, 492630), (-1, 491792), (2, 7695), (-2, 7623), (-3, 130), (3, 128), (4, 1), (-4, 1)]; let abs_mean = NiceFloat(1.0158400000000025); let pop_median = (-1, Some(1)); let sample_median = (1, None); let pop_moment_stats = MomentStats { mean: NiceFloat(-0.0), standard_deviation: NiceFloat(1.0234076808633008), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.863403263403264), }; let sample_moment_stats = MomentStats { mean: NiceFloat(0.0009760000000000123), standard_deviation: NiceFloat(1.0237422016660624), skewness: NiceFloat(-0.0015925396363277624), excess_kurtosis: NiceFloat(-1.8611455716465144), }; geometric_random_nonzero_signeds_helper::( 65, 64, values, common_values, abs_mean, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i64, um = 12345/10000 let values = &[-3, -1, -1, 2, -1, 1, -1, -1, -1, 1, 3, 2, -2, -1, 1, -1, -2, -1, -1, -1]; let common_values = &[ (1, 405592), (-1, 404788), (2, 76970), (-2, 76657), (-3, 14659), (3, 14550), (-4, 2798), (4, 2694), (5, 525), (-5, 504), ]; let abs_mean = NiceFloat(1.2340139999999655); let pop_median = (-1, Some(1)); let sample_median = (1, None); let pop_moment_stats = MomentStats { mean: NiceFloat(-0.0), standard_deviation: NiceFloat(1.3466553011071538), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-0.5329853284885049), }; let sample_moment_stats = MomentStats { mean: NiceFloat(0.0006879999999999908), standard_deviation: NiceFloat(1.3459834093804237), skewness: NiceFloat(-0.004555831860856982), excess_kurtosis: NiceFloat(-0.5314899892072216), }; geometric_random_nonzero_signeds_helper::( 12345, 10000, values, common_values, abs_mean, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i64, um = 2 let values = &[-2, -2, -2, 2, -3, 2, -1, -1, -1, 1, 1, 1, -2, -1, 1, -2, -1, -1, -2, -1]; let common_values = &[ (1, 250123), (-1, 250114), (2, 125321), (-2, 124779), (3, 62655), (-3, 62429), (4, 31220), (-4, 30972), (-5, 15670), (5, 15610), ]; let abs_mean = NiceFloat(1.9985919999999855); let pop_median = (-1, Some(1)); let sample_median = (1, None); let pop_moment_stats = MomentStats { mean: NiceFloat(-0.0), standard_deviation: NiceFloat(2.449489742783178), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(1.166666666666667), }; let sample_moment_stats = MomentStats { mean: NiceFloat(0.0027099999999999395), standard_deviation: NiceFloat(2.4473305141166697), skewness: NiceFloat(0.003736776778462254), excess_kurtosis: NiceFloat(1.1584370930225818), }; geometric_random_nonzero_signeds_helper::( 2, 1, values, common_values, abs_mean, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i8, um = 64 let values = &[ -3, -45, -90, 30, -33, -38, -25, 15, 40, -20, 42, -34, -74, -110, -15, 12, -76, -2, -6, -76, ]; let common_values = &[ (1, 9067), (-1, 9026), (-2, 8948), (2, 8915), (-3, 8837), (3, 8719), (5, 8571), (4, 8530), (-4, 8430), (6, 8385), ]; let abs_mean = NiceFloat(44.16314300000121); let pop_median = (-1, None); let sample_median = (-1, None); let pop_moment_stats = MomentStats { mean: NiceFloat(-0.15631902384873833), standard_deviation: NiceFloat(55.4586923219402), skewness: NiceFloat(-0.006558922726586753), excess_kurtosis: NiceFloat(-0.4026097866721505), }; let sample_moment_stats = MomentStats { mean: NiceFloat(-0.15813500000000466), standard_deviation: NiceFloat(55.40978289585497), skewness: NiceFloat(-0.008649136036163145), excess_kurtosis: NiceFloat(-0.39765880957469824), }; geometric_random_nonzero_signeds_helper::( 64, 1, values, common_values, abs_mean, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i8, um = 1000 let values = &[29, -58, 40, 58, 29, 21, -101, 50, 126, -3, 13, 22, 22, 69, 70, 62, -82, -67, 91, 87]; let common_values = &[ (3, 4314), (-1, 4293), (-4, 4243), (2, 4240), (10, 4233), (-12, 4223), (-26, 4220), (7, 4203), (-7, 4198), (-19, 4196), ]; let abs_mean = NiceFloat(62.86584099999888); let pop_median = (-1, None); let sample_median = (-1, None); let pop_moment_stats = MomentStats { mean: NiceFloat(-0.4706257221678366), standard_deviation: NiceFloat(72.86493046408025), skewness: NiceFloat(-0.0005545932485799438), excess_kurtosis: NiceFloat(-1.1684399210707623), }; let sample_moment_stats = MomentStats { mean: NiceFloat(-0.5576419999999735), standard_deviation: NiceFloat(72.84782263187428), skewness: NiceFloat(0.0014314361576379332), excess_kurtosis: NiceFloat(-1.1671979175710692), }; geometric_random_nonzero_signeds_helper::( 1000, 1, values, common_values, abs_mean, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); } fn geometric_random_nonzero_signeds_fail_helper() { assert_panic!(geometric_random_nonzero_signeds::(EXAMPLE_SEED, 1, 0)); assert_panic!(geometric_random_nonzero_signeds::(EXAMPLE_SEED, 2, 3)); } #[test] fn geometric_random_nonzero_signeds_fail() { apply_fn_to_signeds!(geometric_random_nonzero_signeds_fail_helper); } malachite-base-0.4.16/tests/num/random/geometric/geometric_random_positive_signeds.rs000064400000000000000000000164471046102023000273100ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::geometric::geometric_random_positive_signeds; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::moments::{ truncated_geometric_dist_assertions, CheckedToF64, MomentStats, }; use std::panic::catch_unwind; fn geometric_random_positive_signeds_helper( um_numerator: u64, um_denominator: u64, expected_values: &[T], expected_common_values: &[(T, usize)], expected_pop_median: (T, Option), expected_sample_median: (T, Option), expected_pop_moment_stats: MomentStats, expected_sample_moment_stats: MomentStats, ) { truncated_geometric_dist_assertions( geometric_random_positive_signeds::(EXAMPLE_SEED, um_numerator, um_denominator), T::ONE, T::MAX, um_numerator, um_denominator, expected_values, expected_common_values, expected_pop_median, expected_sample_median, expected_pop_moment_stats, expected_sample_moment_stats, ); } #[test] fn test_geometric_random_positive_signeds() { // i64, um = 65 / 64 let values = &[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2]; let common_values = &[(1, 984537), (2, 15210), (3, 253)]; let pop_median = (1, None); let sample_median = (1, None); let pop_moment_stats = MomentStats { mean: NiceFloat(1.015625), standard_deviation: NiceFloat(0.12597277731716458), skewness: NiceFloat(8.186292482887549), excess_kurtosis: NiceFloat(69.01538461538773), }; let sample_moment_stats = MomentStats { mean: NiceFloat(1.0157160000000027), standard_deviation: NiceFloat(0.12639233884624257), skewness: NiceFloat(8.160460378454992), excess_kurtosis: NiceFloat(68.31033619043166), }; geometric_random_positive_signeds_helper::( 65, 64, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i64, um = 12345/10000 let values = &[1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1]; let common_values = &[ (1, 809395), (2, 154707), (3, 29037), (4, 5577), (5, 1053), (6, 185), (7, 40), (8, 5), (9, 1), ]; let pop_median = (1, None); let sample_median = (1, None); let pop_moment_stats = MomentStats { mean: NiceFloat(1.2345), standard_deviation: NiceFloat(0.538042981554448), skewness: NiceFloat(2.730265146765687), excess_kurtosis: NiceFloat(9.45434777164341), }; let sample_moment_stats = MomentStats { mean: NiceFloat(1.2349320000000084), standard_deviation: NiceFloat(0.5376590410783139), skewness: NiceFloat(2.716807176148366), excess_kurtosis: NiceFloat(9.308727522629948), }; geometric_random_positive_signeds_helper::( 12345, 10000, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i64, um = 2 let values = &[2, 1, 1, 4, 5, 5, 2, 1, 1, 2, 1, 1, 3, 3, 1, 1, 2, 1, 4, 2]; let common_values = &[ (1, 500085), (2, 249510), (3, 125328), (4, 62428), (5, 31280), (6, 15676), (7, 7853), (8, 3994), (9, 1932), (10, 942), ]; let pop_median = (1, Some(2)); let sample_median = (1, None); let pop_moment_stats = MomentStats { mean: NiceFloat(2.0), standard_deviation: NiceFloat(std::f64::consts::SQRT_2), skewness: NiceFloat(2.1213203435596424), excess_kurtosis: NiceFloat(6.5), }; let sample_moment_stats = MomentStats { mean: NiceFloat(2.0006159999998947), standard_deviation: NiceFloat(1.414547850547892), skewness: NiceFloat(2.114056944012543), excess_kurtosis: NiceFloat(6.4341815215340645), }; geometric_random_positive_signeds_helper::( 2, 1, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i8, um = 64 let values = &[53, 56, 71, 20, 113, 87, 55, 44, 4, 17, 44, 36, 5, 25, 55, 9, 114, 24, 15, 76]; let common_values = &[ (1, 18322), (2, 17831), (3, 17675), (4, 17346), (5, 17077), (6, 16664), (7, 16584), (8, 16201), (9, 15917), (10, 15785), ]; let pop_median = (36, None); let sample_median = (36, None); let pop_moment_stats = MomentStats { mean: NiceFloat(44.12320959250907), standard_deviation: NiceFloat(33.35507189836844), skewness: NiceFloat(0.6800692970056713), excess_kurtosis: NiceFloat(-0.5495345339552125), }; let sample_moment_stats = MomentStats { mean: NiceFloat(44.11083399999909), standard_deviation: NiceFloat(33.35932545284804), skewness: NiceFloat(0.6778762972570164), excess_kurtosis: NiceFloat(-0.5537033314075828), }; geometric_random_positive_signeds_helper::( 64, 1, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i8, um = 1000 let values = &[29, 119, 12, 28, 113, 91, 84, 117, 46, 36, 71, 83, 43, 50, 127, 69, 5, 124, 10, 95]; let common_values = &[ (3, 8464), (11, 8429), (9, 8411), (26, 8407), (6, 8397), (12, 8387), (2, 8383), (8, 8363), (1, 8326), (14, 8313), ]; let pop_median = (62, None); let sample_median = (62, None); let pop_moment_stats = MomentStats { mean: NiceFloat(62.65568926722266), standard_deviation: NiceFloat(36.64581386503865), skewness: NiceFloat(0.04401709622102498), excess_kurtosis: NiceFloat(-1.1974732777225838), }; let sample_moment_stats = MomentStats { mean: NiceFloat(62.68774500000057), standard_deviation: NiceFloat(36.63525108357442), skewness: NiceFloat(0.041814478066591894), excess_kurtosis: NiceFloat(-1.1973932602500912), }; geometric_random_positive_signeds_helper::( 1000, 1, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); } fn geometric_random_positive_signeds_fail_helper() { assert_panic!(geometric_random_positive_signeds::(EXAMPLE_SEED, 1, 0)); assert_panic!(geometric_random_positive_signeds::(EXAMPLE_SEED, 2, 3)); } #[test] fn geometric_random_positive_signeds_fail() { apply_fn_to_signeds!(geometric_random_positive_signeds_fail_helper); } malachite-base-0.4.16/tests/num/random/geometric/geometric_random_positive_unsigneds.rs000064400000000000000000000165251046102023000276500ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::geometric::geometric_random_positive_unsigneds; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::moments::{ truncated_geometric_dist_assertions, CheckedToF64, MomentStats, }; use std::panic::catch_unwind; fn geometric_random_positive_unsigneds_helper( um_numerator: u64, um_denominator: u64, expected_values: &[T], expected_common_values: &[(T, usize)], expected_pop_median: (T, Option), expected_sample_median: (T, Option), expected_pop_moment_stats: MomentStats, expected_sample_moment_stats: MomentStats, ) { truncated_geometric_dist_assertions( geometric_random_positive_unsigneds::(EXAMPLE_SEED, um_numerator, um_denominator), T::ONE, T::MAX, um_numerator, um_denominator, expected_values, expected_common_values, expected_pop_median, expected_sample_median, expected_pop_moment_stats, expected_sample_moment_stats, ); } #[test] fn test_geometric_random_positive_unsigneds() { // u64, um = 65 / 64 let values = &[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2]; let common_values = &[(1, 984537), (2, 15210), (3, 253)]; let pop_median = (1, None); let sample_median = (1, None); let pop_moment_stats = MomentStats { mean: NiceFloat(1.015625), standard_deviation: NiceFloat(0.12597277731716458), skewness: NiceFloat(8.186292482887549), excess_kurtosis: NiceFloat(69.01538461538773), }; let sample_moment_stats = MomentStats { mean: NiceFloat(1.0157160000000027), standard_deviation: NiceFloat(0.12639233884624257), skewness: NiceFloat(8.160460378454992), excess_kurtosis: NiceFloat(68.31033619043166), }; geometric_random_positive_unsigneds_helper::( 65, 64, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // u64, um = 12345/10000 let values = &[1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1]; let common_values = &[ (1, 809395), (2, 154707), (3, 29037), (4, 5577), (5, 1053), (6, 185), (7, 40), (8, 5), (9, 1), ]; let pop_median = (1, None); let sample_median = (1, None); let pop_moment_stats = MomentStats { mean: NiceFloat(1.2345), standard_deviation: NiceFloat(0.538042981554448), skewness: NiceFloat(2.730265146765687), excess_kurtosis: NiceFloat(9.45434777164341), }; let sample_moment_stats = MomentStats { mean: NiceFloat(1.2349320000000084), standard_deviation: NiceFloat(0.5376590410783139), skewness: NiceFloat(2.716807176148366), excess_kurtosis: NiceFloat(9.308727522629948), }; geometric_random_positive_unsigneds_helper::( 12345, 10000, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // u64, um = 2 let values = &[2, 1, 1, 4, 5, 5, 2, 1, 1, 2, 1, 1, 3, 3, 1, 1, 2, 1, 4, 2]; let common_values = &[ (1, 500085), (2, 249510), (3, 125328), (4, 62428), (5, 31280), (6, 15676), (7, 7853), (8, 3994), (9, 1932), (10, 942), ]; let pop_median = (1, Some(2)); let sample_median = (1, None); let pop_moment_stats = MomentStats { mean: NiceFloat(2.0), standard_deviation: NiceFloat(std::f64::consts::SQRT_2), skewness: NiceFloat(2.1213203435596424), excess_kurtosis: NiceFloat(6.5), }; let sample_moment_stats = MomentStats { mean: NiceFloat(2.0006159999998947), standard_deviation: NiceFloat(1.414547850547892), skewness: NiceFloat(2.114056944012543), excess_kurtosis: NiceFloat(6.4341815215340645), }; geometric_random_positive_unsigneds_helper::( 2, 1, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // u8, um = 64 let values = &[53, 56, 71, 20, 113, 87, 55, 44, 4, 17, 44, 36, 5, 25, 55, 9, 114, 24, 15, 76]; let common_values = &[ (1, 16172), (2, 15695), (3, 15520), (4, 15241), (5, 15089), (6, 14676), (7, 14543), (8, 14211), (9, 13961), (10, 13836), ]; let pop_median = (43, None); let sample_median = (43, None); let pop_moment_stats = MomentStats { mean: NiceFloat(59.318470051671945), standard_deviation: NiceFloat(53.06875861106282), skewness: NiceFloat(1.275790253790931), excess_kurtosis: NiceFloat(1.21378930742857), }; let sample_moment_stats = MomentStats { mean: NiceFloat(59.312081000000006), standard_deviation: NiceFloat(53.01872774251563), skewness: NiceFloat(1.2706951236419683), excess_kurtosis: NiceFloat(1.1982916278084028), }; geometric_random_positive_unsigneds_helper::( 64, 1, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // u8, um = 1000 let values = &[27, 115, 1, 27, 107, 217, 210, 242, 42, 36, 197, 207, 42, 43, 250, 195, 255, 122, 5, 221]; let common_values = &[ (6, 4501), (2, 4490), (8, 4461), (21, 4453), (10, 4449), (3, 4446), (11, 4440), (13, 4422), (12, 4415), (25, 4407), ]; let pop_median = (120, None); let sample_median = (120, None); let pop_moment_stats = MomentStats { mean: NiceFloat(122.58449448192029), standard_deviation: NiceFloat(73.49201840569208), skewness: NiceFloat(0.08835569448221604), excess_kurtosis: NiceFloat(-1.1892531716440173), }; let sample_moment_stats = MomentStats { mean: NiceFloat(122.63144799999775), standard_deviation: NiceFloat(73.49633071884523), skewness: NiceFloat(0.08793356388157667), excess_kurtosis: NiceFloat(-1.1900100973541539), }; geometric_random_positive_unsigneds_helper::( 1000, 1, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); } fn geometric_random_positive_unsigneds_fail_helper() { assert_panic!(geometric_random_positive_unsigneds::(EXAMPLE_SEED, 1, 0)); assert_panic!(geometric_random_positive_unsigneds::(EXAMPLE_SEED, 2, 3)); } #[test] fn geometric_random_positive_unsigneds_fail() { apply_fn_to_unsigneds!(geometric_random_positive_unsigneds_fail_helper); } malachite-base-0.4.16/tests/num/random/geometric/geometric_random_signed_inclusive_range.rs000064400000000000000000000262641046102023000304360ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::UnsignedAbs; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::WrappingFrom; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::geometric::geometric_random_signed_inclusive_range; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::moments::{ double_truncated_geometric_dist_assertions, negative_truncated_geometric_dist_assertions, truncated_geometric_dist_assertions, CheckedToF64, MomentStats, }; use std::panic::catch_unwind; fn geometric_random_signed_inclusive_range_helper< U: CheckedToF64 + PrimitiveUnsigned, S: CheckedToF64 + PrimitiveSigned + UnsignedAbs + WrappingFrom<::Output>, >( a: S, b: S, abs_um_numerator: u64, abs_um_denominator: u64, expected_values: &[S], expected_common_values: &[(S, usize)], expected_natural_mean: Option>, expected_pop_median: (S, Option), expected_sample_median: (S, Option), expected_pop_moment_stats: MomentStats, expected_sample_moment_stats: MomentStats, ) { let xs = geometric_random_signed_inclusive_range::( EXAMPLE_SEED, a, b, abs_um_numerator, abs_um_denominator, ); if a >= S::ZERO { assert!(expected_natural_mean.is_none()); truncated_geometric_dist_assertions( xs, a, b, abs_um_numerator, abs_um_denominator, expected_values, expected_common_values, expected_pop_median, expected_sample_median, expected_pop_moment_stats, expected_sample_moment_stats, ); } else if b <= S::ONE { assert!(expected_natural_mean.is_none()); negative_truncated_geometric_dist_assertions( xs, b, a, abs_um_numerator, abs_um_denominator, expected_values, expected_common_values, expected_pop_median, expected_sample_median, expected_pop_moment_stats, expected_sample_moment_stats, ); } else { double_truncated_geometric_dist_assertions( xs, a, b, abs_um_numerator, abs_um_denominator, expected_values, expected_common_values, expected_natural_mean.unwrap(), expected_pop_median, expected_sample_median, expected_pop_moment_stats, expected_sample_moment_stats, ); } } #[test] fn test_geometric_random_signed_inclusive_range() { // i8, 5, 5, um = 10 (um is irrelevant here) let values = &[5; 20]; let common_values = &[(5, 1000000)]; let pop_median = (5, None); let sample_median = (5, None); let pop_moment_stats = MomentStats { mean: NiceFloat(5.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; let sample_moment_stats = MomentStats { mean: NiceFloat(5.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; geometric_random_signed_inclusive_range_helper::<_, i8>( 5, 5, 10, 1, values, common_values, None, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i16, 1, 6, um = 3 let values = &[2, 5, 2, 3, 4, 2, 5, 6, 1, 2, 4, 3, 3, 2, 4, 2, 5, 1, 5, 4]; let common_values = &[(1, 365286), (2, 243368), (3, 162008), (4, 108422), (5, 72522), (6, 48394)]; let pop_median = (2, None); let sample_median = (2, None); let pop_moment_stats = MomentStats { mean: NiceFloat(2.4225563909774435), standard_deviation: NiceFloat(1.4838791137635392), skewness: NiceFloat(0.8646161570662343), excess_kurtosis: NiceFloat(-0.2650814667635877), }; let sample_moment_stats = MomentStats { mean: NiceFloat(2.4247080000000336), standard_deviation: NiceFloat(1.4858025852532333), skewness: NiceFloat(0.8627980859656847), excess_kurtosis: NiceFloat(-0.27185507049284263), }; geometric_random_signed_inclusive_range_helper::<_, i16>( 1, 6, 3, 1, values, common_values, None, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i32, 10, 19, um = 30 let values = &[18, 13, 12, 14, 11, 14, 16, 12, 12, 12, 11, 11, 12, 16, 10, 12, 13, 17, 19, 18]; let common_values = &[ (10, 123089), (11, 117792), (12, 111339), (13, 106927), (14, 102009), (15, 96319), (16, 92170), (17, 86830), (18, 83895), (19, 79630), ]; let pop_median = (14, None); let sample_median = (14, None); let pop_moment_stats = MomentStats { mean: NiceFloat(14.099085006908673), standard_deviation: NiceFloat(2.8551273967321666), skewness: NiceFloat(0.17141556508548922), excess_kurtosis: NiceFloat(-1.1843121480092598), }; let sample_moment_stats = MomentStats { mean: NiceFloat(14.099542000000508), standard_deviation: NiceFloat(2.8550785526337443), skewness: NiceFloat(0.17230969046968866), excess_kurtosis: NiceFloat(-1.183362703825652), }; geometric_random_signed_inclusive_range_helper::<_, i32>( 10, 19, 30, 1, values, common_values, None, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i64, -20, -11, um = 30 let values = &[ -17, -14, -12, -14, -12, -15, -16, -13, -12, -13, -19, -11, -11, -17, -11, -19, -13, -16, -20, -19, ]; let common_values = &[ (-11, 124528), (-12, 118758), (-13, 112479), (-14, 107215), (-15, 101400), (-16, 96120), (-17, 91622), (-18, 86347), (-19, 82852), (-20, 78679), ]; let pop_median = (-15, None); let sample_median = (-15, None); let pop_moment_stats = MomentStats { mean: NiceFloat(-15.078692813090253), standard_deviation: NiceFloat(2.853334884793182), skewness: NiceFloat(-0.18019334055480088), excess_kurtosis: NiceFloat(-1.1801134249293568), }; let sample_moment_stats = MomentStats { mean: NiceFloat(-15.076649000000186), standard_deviation: NiceFloat(2.8539222266332365), skewness: NiceFloat(-0.18245914264956217), excess_kurtosis: NiceFloat(-1.1796684829530097), }; geometric_random_signed_inclusive_range_helper::<_, i64>( -20, -11, 30, 1, values, common_values, None, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i8, -100, 99, um = 30 let values = &[-32, -31, -88, 52, -40, 64, -36, -1, -7, 46, 14, 48, -61, -60, 21, -55, -69, -26, -44, 6]; let common_values = &[ (0, 16949), (-1, 16668), (1, 16340), (-2, 15893), (2, 15885), (-3, 15421), (3, 15350), (4, 14937), (-4, 14913), (5, 14576), ]; let pop_median = (0, None); let sample_median = (0, None); let pop_moment_stats = MomentStats { mean: NiceFloat(-0.06416536680865222), standard_deviation: NiceFloat(35.06981580711165), skewness: NiceFloat(-0.009387535787624381), excess_kurtosis: NiceFloat(0.331207115680745), }; let sample_moment_stats = MomentStats { mean: NiceFloat(-0.031523999999998706), standard_deviation: NiceFloat(34.99870187802065), skewness: NiceFloat(-0.009330685977635587), excess_kurtosis: NiceFloat(0.33242667080464994), }; geometric_random_signed_inclusive_range_helper::<_, i8>( -100, 99, 30, 1, values, common_values, Some(NiceFloat(26.065423999999997)), pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i8, i8::MIN, i8::MAX, um = 30 let values = &[-32, -31, -88, 52, -40, 64, -36, -1, -7, 46, 14, 48, -61, -60, 21, -55, -69, -26, -44, 6]; let common_values = &[ (0, 16612), (1, 16170), (-1, 16142), (2, 15527), (-2, 15450), (-3, 15004), (3, 14998), (4, 14694), (-4, 14522), (5, 14226), ]; let pop_median = (0, None); let sample_median = (0, None); let pop_moment_stats = MomentStats { mean: NiceFloat(-0.03203944371479178), standard_deviation: NiceFloat(38.608914337623204), skewness: NiceFloat(-0.006631455473213565), excess_kurtosis: NiceFloat(0.885187645693085), }; let sample_moment_stats = MomentStats { mean: NiceFloat(0.006649000000000714), standard_deviation: NiceFloat(38.52435386760686), skewness: NiceFloat(-0.002824821494549616), excess_kurtosis: NiceFloat(0.8938770112620578), }; geometric_random_signed_inclusive_range_helper::<_, i8>( i8::MIN, i8::MAX, 30, 1, values, common_values, Some(NiceFloat(28.03693899999907)), pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); } fn geometric_random_signed_inclusive_range_fail_helper() { assert_panic!(geometric_random_signed_inclusive_range::( EXAMPLE_SEED, T::TWO, T::ONE, 1, 1 )); assert_panic!(geometric_random_signed_inclusive_range::( EXAMPLE_SEED, T::ONE, T::ZERO, 1, 1 )); assert_panic!(geometric_random_signed_inclusive_range::( EXAMPLE_SEED, T::ZERO, T::exact_from(10), 1, 0 )); assert_panic!(geometric_random_signed_inclusive_range::( EXAMPLE_SEED, T::ONE, T::exact_from(10), 9, 10 )); assert_panic!(geometric_random_signed_inclusive_range::( EXAMPLE_SEED, T::exact_from(-10), T::NEGATIVE_ONE, 9, 10 )); assert_panic!(geometric_random_signed_inclusive_range::( EXAMPLE_SEED, T::ZERO, T::exact_from(10), u64::MAX, u64::MAX - 1 )); } #[test] fn geometric_random_signed_inclusive_range_fail() { apply_fn_to_signeds!(geometric_random_signed_inclusive_range_fail_helper); } malachite-base-0.4.16/tests/num/random/geometric/geometric_random_signed_range.rs000064400000000000000000000260241046102023000263470ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::UnsignedAbs; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::WrappingFrom; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::geometric::geometric_random_signed_range; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::moments::{ double_truncated_geometric_dist_assertions, negative_truncated_geometric_dist_assertions, truncated_geometric_dist_assertions, CheckedToF64, MomentStats, }; use std::panic::catch_unwind; fn geometric_random_signed_range_helper< U: CheckedToF64 + PrimitiveUnsigned, S: CheckedToF64 + PrimitiveSigned + UnsignedAbs + WrappingFrom<::Output>, >( a: S, b: S, abs_um_numerator: u64, abs_um_denominator: u64, expected_values: &[S], expected_common_values: &[(S, usize)], expected_natural_mean: Option>, expected_pop_median: (S, Option), expected_sample_median: (S, Option), expected_pop_moment_stats: MomentStats, expected_sample_moment_stats: MomentStats, ) { let xs = geometric_random_signed_range::( EXAMPLE_SEED, a, b, abs_um_numerator, abs_um_denominator, ); if a >= S::ZERO { assert!(expected_natural_mean.is_none()); truncated_geometric_dist_assertions( xs, a, b - S::ONE, abs_um_numerator, abs_um_denominator, expected_values, expected_common_values, expected_pop_median, expected_sample_median, expected_pop_moment_stats, expected_sample_moment_stats, ); } else if b <= S::ONE { assert!(expected_natural_mean.is_none()); negative_truncated_geometric_dist_assertions( xs, b - S::ONE, a, abs_um_numerator, abs_um_denominator, expected_values, expected_common_values, expected_pop_median, expected_sample_median, expected_pop_moment_stats, expected_sample_moment_stats, ); } else { double_truncated_geometric_dist_assertions( xs, a, b - S::ONE, abs_um_numerator, abs_um_denominator, expected_values, expected_common_values, expected_natural_mean.unwrap(), expected_pop_median, expected_sample_median, expected_pop_moment_stats, expected_sample_moment_stats, ); } } #[test] fn test_geometric_random_signed_range() { // i8, 5, 6, um = 10 (um is irrelevant here) let values = &[5; 20]; let common_values = &[(5, 1000000)]; let pop_median = (5, None); let sample_median = (5, None); let pop_moment_stats = MomentStats { mean: NiceFloat(5.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; let sample_moment_stats = MomentStats { mean: NiceFloat(5.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; geometric_random_signed_range_helper::<_, i8>( 5, 6, 10, 1, values, common_values, None, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i16, 1, 7, um = 3 let values = &[2, 5, 2, 3, 4, 2, 5, 6, 1, 2, 4, 3, 3, 2, 4, 2, 5, 1, 5, 4]; let common_values = &[(1, 365286), (2, 243368), (3, 162008), (4, 108422), (5, 72522), (6, 48394)]; let pop_median = (2, None); let sample_median = (2, None); let pop_moment_stats = MomentStats { mean: NiceFloat(2.4225563909774435), standard_deviation: NiceFloat(1.4838791137635392), skewness: NiceFloat(0.8646161570662343), excess_kurtosis: NiceFloat(-0.2650814667635877), }; let sample_moment_stats = MomentStats { mean: NiceFloat(2.4247080000000336), standard_deviation: NiceFloat(1.4858025852532333), skewness: NiceFloat(0.8627980859656847), excess_kurtosis: NiceFloat(-0.27185507049284263), }; geometric_random_signed_range_helper::<_, i16>( 1, 7, 3, 1, values, common_values, None, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i32, 10, 20, um = 30 let values = &[18, 13, 12, 14, 11, 14, 16, 12, 12, 12, 11, 11, 12, 16, 10, 12, 13, 17, 19, 18]; let common_values = &[ (10, 123089), (11, 117792), (12, 111339), (13, 106927), (14, 102009), (15, 96319), (16, 92170), (17, 86830), (18, 83895), (19, 79630), ]; let pop_median = (14, None); let sample_median = (14, None); let pop_moment_stats = MomentStats { mean: NiceFloat(14.099085006908673), standard_deviation: NiceFloat(2.8551273967321666), skewness: NiceFloat(0.17141556508548922), excess_kurtosis: NiceFloat(-1.1843121480092598), }; let sample_moment_stats = MomentStats { mean: NiceFloat(14.099542000000508), standard_deviation: NiceFloat(2.8550785526337443), skewness: NiceFloat(0.17230969046968866), excess_kurtosis: NiceFloat(-1.183362703825652), }; geometric_random_signed_range_helper::<_, i32>( 10, 20, 30, 1, values, common_values, None, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i64, -20, -10, um = 30 let values = &[ -17, -14, -12, -14, -12, -15, -16, -13, -12, -13, -19, -11, -11, -17, -11, -19, -13, -16, -20, -19, ]; let common_values = &[ (-11, 124528), (-12, 118758), (-13, 112479), (-14, 107215), (-15, 101400), (-16, 96120), (-17, 91622), (-18, 86347), (-19, 82852), (-20, 78679), ]; let pop_median = (-15, None); let sample_median = (-15, None); let pop_moment_stats = MomentStats { mean: NiceFloat(-15.078692813090253), standard_deviation: NiceFloat(2.853334884793182), skewness: NiceFloat(-0.18019334055480088), excess_kurtosis: NiceFloat(-1.1801134249293568), }; let sample_moment_stats = MomentStats { mean: NiceFloat(-15.076649000000186), standard_deviation: NiceFloat(2.8539222266332365), skewness: NiceFloat(-0.18245914264956217), excess_kurtosis: NiceFloat(-1.1796684829530097), }; geometric_random_signed_range_helper::<_, i64>( -20, -10, 30, 1, values, common_values, None, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i8, -100, 100, um = 30 let values = &[-32, -31, -88, 52, -40, 64, -36, -1, -7, 46, 14, 48, -61, -60, 21, -55, -69, -26, -44, 6]; let common_values = &[ (0, 16949), (-1, 16668), (1, 16340), (-2, 15893), (2, 15885), (-3, 15421), (3, 15350), (4, 14937), (-4, 14913), (5, 14576), ]; let pop_median = (0, None); let sample_median = (0, None); let pop_moment_stats = MomentStats { mean: NiceFloat(-0.06416536680865222), standard_deviation: NiceFloat(35.06981580711165), skewness: NiceFloat(-0.009387535787624381), excess_kurtosis: NiceFloat(0.331207115680745), }; let sample_moment_stats = MomentStats { mean: NiceFloat(-0.031523999999998706), standard_deviation: NiceFloat(34.99870187802065), skewness: NiceFloat(-0.009330685977635587), excess_kurtosis: NiceFloat(0.33242667080464994), }; geometric_random_signed_range_helper::<_, i8>( -100, 100, 30, 1, values, common_values, Some(NiceFloat(26.065423999999997)), pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i8, i8::MIN, i8::MAX, um = 30 let values = &[-32, -31, -88, 52, -40, 64, -36, -1, -7, 46, 14, 48, -61, -60, 21, -55, -69, -26, -44, 6]; let common_values = &[ (0, 16586), (1, 16346), (-1, 15948), (2, 15598), (-2, 15440), (-3, 15044), (3, 14965), (-4, 14646), (4, 14519), (-5, 14228), ]; let pop_median = (0, None); let sample_median = (0, None); let pop_moment_stats = MomentStats { mean: NiceFloat(-0.06490500492128823), standard_deviation: NiceFloat(38.55979597281242), skewness: NiceFloat(-0.013352031588210264), excess_kurtosis: NiceFloat(0.8755072180683543), }; let sample_moment_stats = MomentStats { mean: NiceFloat(-0.025164000000001106), standard_deviation: NiceFloat(38.48004061181062), skewness: NiceFloat(-0.009040591966747374), excess_kurtosis: NiceFloat(0.8847001181957856), }; geometric_random_signed_range_helper::<_, i8>( i8::MIN, i8::MAX, 30, 1, values, common_values, Some(NiceFloat(27.9829300000005)), pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); } fn geometric_random_signed_range_fail_helper() { assert_panic!(geometric_random_signed_range::( EXAMPLE_SEED, T::ONE, T::ONE, 1, 1 )); assert_panic!(geometric_random_signed_range::( EXAMPLE_SEED, T::ONE, T::ZERO, 1, 1 )); assert_panic!(geometric_random_signed_range::( EXAMPLE_SEED, T::ZERO, T::exact_from(10), 1, 0 )); assert_panic!(geometric_random_signed_range::( EXAMPLE_SEED, T::ONE, T::exact_from(10), 9, 10 )); assert_panic!(geometric_random_signed_range::( EXAMPLE_SEED, T::exact_from(-10), T::NEGATIVE_ONE, 9, 10 )); assert_panic!(geometric_random_signed_range::( EXAMPLE_SEED, T::ZERO, T::exact_from(10), u64::MAX, u64::MAX - 1 )); } #[test] fn geometric_random_signed_range_fail() { apply_fn_to_signeds!(geometric_random_signed_range_fail_helper); } malachite-base-0.4.16/tests/num/random/geometric/geometric_random_signeds.rs000064400000000000000000000176031046102023000253610ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::geometric::geometric_random_signeds; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::moments::{ double_truncated_geometric_dist_assertions, CheckedToF64, MomentStats, }; use std::panic::catch_unwind; fn geometric_random_signeds_helper( um_numerator: u64, um_denominator: u64, expected_values: &[T], expected_common_values: &[(T, usize)], expected_natural_mean: NiceFloat, expected_pop_median: (T, Option), expected_sample_median: (T, Option), expected_pop_moment_stats: MomentStats, expected_sample_moment_stats: MomentStats, ) { double_truncated_geometric_dist_assertions( geometric_random_signeds::(EXAMPLE_SEED, um_numerator, um_denominator), T::MIN, T::MAX, um_numerator, um_denominator, expected_values, expected_common_values, expected_natural_mean, expected_pop_median, expected_sample_median, expected_pop_moment_stats, expected_sample_moment_stats, ); } #[test] fn test_geometric_random_signeds() { // i64, um = 1 / 64 let values = &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; let common_values = &[(0, 969281), (-1, 15234), (1, 14983), (-2, 267), (2, 230), (3, 3), (-3, 2)]; let natural_mean = NiceFloat(0.01570299999999922); let pop_median = (0, None); let sample_median = (0, None); let pop_moment_stats = MomentStats { mean: NiceFloat(-0.0), standard_deviation: NiceFloat(0.17815241017173997), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(34.507692307692416), }; let sample_moment_stats = MomentStats { mean: NiceFloat(-0.0003219999999999915), standard_deviation: NiceFloat(0.17958265107166738), skewness: NiceFloat(-0.08440731496142939), excess_kurtosis: NiceFloat(34.08776956313593), }; geometric_random_signeds_helper::( 1, 64, values, common_values, natural_mean, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i64, um = 12345/10000 let values = &[-1, -1, 0, -3, 1, 0, 0, -4, 0, -6, 1, 4, 0, 1, -2, 4, -3, -3, 1, -3]; let common_values = &[ (0, 288130), (1, 159322), (-1, 158541), (-2, 88726), (2, 88078), (3, 48713), (-3, 48584), (-4, 26933), (4, 26804), (-5, 14960), ]; let natural_mean = NiceFloat(1.233504000000006); let pop_median = (0, None); let sample_median = (0, None); let pop_moment_stats = MomentStats { mean: NiceFloat(-0.0), standard_deviation: NiceFloat(2.3488253447202068), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(3.181258570698229), }; let sample_moment_stats = MomentStats { mean: NiceFloat(-0.0021609999999999915), standard_deviation: NiceFloat(2.3469592749549535), skewness: NiceFloat(-0.007388197841520547), excess_kurtosis: NiceFloat(3.1771115107088255), }; geometric_random_signeds_helper::( 12345, 10000, values, common_values, natural_mean, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i64, um = 2 let values = &[-5, 0, 0, 1, -1, -1, -4, 2, 4, 6, -2, -2, 0, -1, -9, -13, 0, -2, 0, -7]; let common_values = &[ (0, 200052), (-1, 133433), (1, 133168), (2, 89079), (-2, 88845), (3, 59306), (-3, 59229), (-4, 39537), (4, 39457), (-5, 26287), ]; let natural_mean = NiceFloat(1.9983939999999663); let pop_median = (0, None); let sample_median = (0, None); let pop_moment_stats = MomentStats { mean: NiceFloat(-0.0), standard_deviation: NiceFloat(3.4641016151377553), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(3.0833333333333304), }; let sample_moment_stats = MomentStats { mean: NiceFloat(-0.004637999999999956), standard_deviation: NiceFloat(3.462957476064434), skewness: NiceFloat(-0.0014668264694796887), excess_kurtosis: NiceFloat(3.1056798270038826), }; geometric_random_signeds_helper::( 2, 1, values, common_values, natural_mean, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i8, um = 64 let values = &[ -58, -18, 80, -31, -85, -74, 114, 29, 46, -28, -5, -54, -73, -67, 96, 74, -67, -20, 93, -95, ]; let common_values = &[ (0, 8916), (1, 8897), (-1, 8830), (3, 8811), (-2, 8800), (2, 8757), (-4, 8491), (4, 8459), (-3, 8413), (-5, 8336), ]; let natural_mean = NiceFloat(43.609158999998506); let pop_median = (0, None); let sample_median = (0, None); let pop_moment_stats = MomentStats { mean: NiceFloat(-0.15811030451314936), standard_deviation: NiceFloat(55.48244935032745), skewness: NiceFloat(-0.006618243685084806), excess_kurtosis: NiceFloat(-0.3947891766587368), }; let sample_moment_stats = MomentStats { mean: NiceFloat(-0.09556800000000087), standard_deviation: NiceFloat(55.48675459546383), skewness: NiceFloat(-0.007283472641276268), excess_kurtosis: NiceFloat(-0.3961004797032963), }; geometric_random_signeds_helper::( 64, 1, values, common_values, natural_mean, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i8, um = 1000 let values = &[25, -53, 39, 32, 26, 13, -94, 45, 125, 119, 11, 15, 66, 68, 60, -71, -54, 83, 76, -33]; let common_values = &[ (-2, 4277), (1, 4263), (9, 4217), (-1, 4213), (5, 4207), (-4, 4207), (0, 4206), (-6, 4200), (19, 4199), (8, 4179), ]; let natural_mean = NiceFloat(62.13860000000173); let pop_median = (0, None); let sample_median = (0, None); let pop_moment_stats = MomentStats { mean: NiceFloat(-0.4686977489785049), standard_deviation: NiceFloat(72.71434769926142), skewness: NiceFloat(-0.0006359350720949359), excess_kurtosis: NiceFloat(-1.1608263148064384), }; let sample_moment_stats = MomentStats { mean: NiceFloat(-0.446604999999992), standard_deviation: NiceFloat(72.6977982881445), skewness: NiceFloat(-0.0006088230606281416), excess_kurtosis: NiceFloat(-1.1593850084998423), }; geometric_random_signeds_helper::( 1000, 1, values, common_values, natural_mean, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); } fn geometric_random_signeds_fail_helper() { assert_panic!(geometric_random_signeds::(EXAMPLE_SEED, 0, 1)); assert_panic!(geometric_random_signeds::(EXAMPLE_SEED, 1, 0)); assert_panic!(geometric_random_signeds::( EXAMPLE_SEED, u64::MAX, u64::MAX - 1 )); } #[test] fn geometric_random_signeds_fail() { apply_fn_to_signeds!(geometric_random_signeds_fail_helper); } malachite-base-0.4.16/tests/num/random/geometric/geometric_random_unsigned_inclusive_range.rs000064400000000000000000000153451046102023000307770ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::geometric::geometric_random_unsigned_inclusive_range; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::moments::{ truncated_geometric_dist_assertions, CheckedToF64, MomentStats, }; use std::panic::catch_unwind; fn geometric_random_unsigned_inclusive_range_helper( a: T, b: T, um_numerator: u64, um_denominator: u64, expected_values: &[T], expected_common_values: &[(T, usize)], expected_pop_median: (T, Option), expected_sample_median: (T, Option), expected_pop_moment_stats: MomentStats, expected_sample_moment_stats: MomentStats, ) { truncated_geometric_dist_assertions( geometric_random_unsigned_inclusive_range::( EXAMPLE_SEED, a, b, um_numerator, um_denominator, ), a, b, um_numerator, um_denominator, expected_values, expected_common_values, expected_pop_median, expected_sample_median, expected_pop_moment_stats, expected_sample_moment_stats, ); } #[test] fn test_geometric_random_unsigned_inclusive_range() { // u8, 5, 5, um = 10 (um is irrelevant here) let values = &[5; 20]; let common_values = &[(5, 1000000)]; let pop_median = (5, None); let sample_median = (5, None); let pop_moment_stats = MomentStats { mean: NiceFloat(5.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; let sample_moment_stats = MomentStats { mean: NiceFloat(5.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; geometric_random_unsigned_inclusive_range_helper::( 5, 5, 10, 1, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // u16, 1, 6, um = 3 let values = &[2, 5, 2, 3, 4, 2, 5, 6, 1, 2, 4, 3, 3, 2, 4, 2, 5, 1, 5, 4]; let common_values = &[(1, 365286), (2, 243368), (3, 162008), (4, 108422), (5, 72522), (6, 48394)]; let pop_median = (2, None); let sample_median = (2, None); let pop_moment_stats = MomentStats { mean: NiceFloat(2.4225563909774435), standard_deviation: NiceFloat(1.4838791137635392), skewness: NiceFloat(0.8646161570662343), excess_kurtosis: NiceFloat(-0.2650814667635877), }; let sample_moment_stats = MomentStats { mean: NiceFloat(2.4247080000000336), standard_deviation: NiceFloat(1.4858025852532333), skewness: NiceFloat(0.8627980859656847), excess_kurtosis: NiceFloat(-0.27185507049284263), }; geometric_random_unsigned_inclusive_range_helper::( 1, 6, 3, 1, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // u32, 10, 19, um = 30 let values = &[18, 13, 12, 14, 11, 14, 16, 12, 12, 12, 11, 11, 12, 16, 10, 12, 13, 17, 19, 18]; let common_values = &[ (10, 123089), (11, 117792), (12, 111339), (13, 106927), (14, 102009), (15, 96319), (16, 92170), (17, 86830), (18, 83895), (19, 79630), ]; let pop_median = (14, None); let sample_median = (14, None); let pop_moment_stats = MomentStats { mean: NiceFloat(14.099085006908673), standard_deviation: NiceFloat(2.8551273967321666), skewness: NiceFloat(0.17141556508548922), excess_kurtosis: NiceFloat(-1.1843121480092598), }; let sample_moment_stats = MomentStats { mean: NiceFloat(14.099542000000508), standard_deviation: NiceFloat(2.8550785526337443), skewness: NiceFloat(0.17230969046968866), excess_kurtosis: NiceFloat(-1.183362703825652), }; geometric_random_unsigned_inclusive_range_helper::( 10, 19, 30, 1, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // u8, 0, u8::MAX, um = 1 let values = &[1, 0, 0, 3, 4, 4, 1, 0, 0, 1, 0, 0, 2, 2, 0, 0, 1, 0, 3, 1]; let common_values = &[ (0, 500085), (1, 249510), (2, 125328), (3, 62428), (4, 31280), (5, 15676), (6, 7853), (7, 3994), (8, 1932), (9, 942), ]; let pop_median = (0, Some(1)); let sample_median = (0, None); let pop_moment_stats = MomentStats { mean: NiceFloat(1.0), standard_deviation: NiceFloat(std::f64::consts::SQRT_2), skewness: NiceFloat(2.1213203435596424), excess_kurtosis: NiceFloat(6.5), }; let sample_moment_stats = MomentStats { mean: NiceFloat(1.0006159999999573), standard_deviation: NiceFloat(1.414547850547892), skewness: NiceFloat(2.1140569440125403), excess_kurtosis: NiceFloat(6.4341815215340805), }; geometric_random_unsigned_inclusive_range_helper::( 0, u8::MAX, 1, 1, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); } fn geometric_random_unsigned_inclusive_range_fail_helper() { assert_panic!(geometric_random_unsigned_inclusive_range::( EXAMPLE_SEED, T::TWO, T::ONE, 1, 1 )); assert_panic!(geometric_random_unsigned_inclusive_range::( EXAMPLE_SEED, T::ZERO, T::exact_from(10), 1, 0 )); assert_panic!(geometric_random_unsigned_inclusive_range::( EXAMPLE_SEED, T::ONE, T::exact_from(10), 9, 10 )); assert_panic!(geometric_random_unsigned_inclusive_range::( EXAMPLE_SEED, T::ZERO, T::exact_from(10), u64::MAX, u64::MAX - 1 )); } #[test] fn geometric_random_unsigned_inclusive_range_fail() { apply_fn_to_unsigneds!(geometric_random_unsigned_inclusive_range_fail_helper); } malachite-base-0.4.16/tests/num/random/geometric/geometric_random_unsigned_range.rs000064400000000000000000000152351046102023000267140ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::geometric::geometric_random_unsigned_range; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::moments::{ truncated_geometric_dist_assertions, CheckedToF64, MomentStats, }; use std::panic::catch_unwind; fn geometric_random_unsigned_range_helper( a: T, b: T, um_numerator: u64, um_denominator: u64, expected_values: &[T], expected_common_values: &[(T, usize)], expected_pop_median: (T, Option), expected_sample_median: (T, Option), expected_pop_moment_stats: MomentStats, expected_sample_moment_stats: MomentStats, ) { truncated_geometric_dist_assertions( geometric_random_unsigned_range::(EXAMPLE_SEED, a, b, um_numerator, um_denominator), a, b - T::ONE, um_numerator, um_denominator, expected_values, expected_common_values, expected_pop_median, expected_sample_median, expected_pop_moment_stats, expected_sample_moment_stats, ); } #[test] fn test_geometric_random_unsigned_range() { // u8, 5, 6, um = 10 (um is irrelevant here) let values = &[5; 20]; let common_values = &[(5, 1000000)]; let pop_median = (5, None); let sample_median = (5, None); let pop_moment_stats = MomentStats { mean: NiceFloat(5.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; let sample_moment_stats = MomentStats { mean: NiceFloat(5.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; geometric_random_unsigned_range_helper::( 5, 6, 10, 1, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // u16, 1, 7, um = 3 let values = &[2, 5, 2, 3, 4, 2, 5, 6, 1, 2, 4, 3, 3, 2, 4, 2, 5, 1, 5, 4]; let common_values = &[(1, 365286), (2, 243368), (3, 162008), (4, 108422), (5, 72522), (6, 48394)]; let pop_median = (2, None); let sample_median = (2, None); let pop_moment_stats = MomentStats { mean: NiceFloat(2.4225563909774435), standard_deviation: NiceFloat(1.4838791137635392), skewness: NiceFloat(0.8646161570662343), excess_kurtosis: NiceFloat(-0.2650814667635877), }; let sample_moment_stats = MomentStats { mean: NiceFloat(2.4247080000000336), standard_deviation: NiceFloat(1.4858025852532333), skewness: NiceFloat(0.8627980859656847), excess_kurtosis: NiceFloat(-0.27185507049284263), }; geometric_random_unsigned_range_helper::( 1, 7, 3, 1, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // u32, 10, 20, um = 30 let values = &[18, 13, 12, 14, 11, 14, 16, 12, 12, 12, 11, 11, 12, 16, 10, 12, 13, 17, 19, 18]; let common_values = &[ (10, 123089), (11, 117792), (12, 111339), (13, 106927), (14, 102009), (15, 96319), (16, 92170), (17, 86830), (18, 83895), (19, 79630), ]; let pop_median = (14, None); let sample_median = (14, None); let pop_moment_stats = MomentStats { mean: NiceFloat(14.099085006908673), standard_deviation: NiceFloat(2.8551273967321666), skewness: NiceFloat(0.17141556508548922), excess_kurtosis: NiceFloat(-1.1843121480092598), }; let sample_moment_stats = MomentStats { mean: NiceFloat(14.099542000000508), standard_deviation: NiceFloat(2.8550785526337443), skewness: NiceFloat(0.17230969046968866), excess_kurtosis: NiceFloat(-1.183362703825652), }; geometric_random_unsigned_range_helper::( 10, 20, 30, 1, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // u8, 0, u8::MAX, um = 1 let values = &[1, 0, 0, 3, 4, 4, 1, 0, 0, 1, 0, 0, 2, 2, 0, 0, 1, 0, 3, 1]; let common_values = &[ (0, 500085), (1, 249510), (2, 125328), (3, 62428), (4, 31280), (5, 15676), (6, 7853), (7, 3994), (8, 1932), (9, 942), ]; let pop_median = (0, Some(1)); let sample_median = (0, None); let pop_moment_stats = MomentStats { mean: NiceFloat(1.0), standard_deviation: NiceFloat(std::f64::consts::SQRT_2), skewness: NiceFloat(2.1213203435596424), excess_kurtosis: NiceFloat(6.5), }; let sample_moment_stats = MomentStats { mean: NiceFloat(1.0006159999999573), standard_deviation: NiceFloat(1.414547850547892), skewness: NiceFloat(2.1140569440125403), excess_kurtosis: NiceFloat(6.4341815215340805), }; geometric_random_unsigned_range_helper::( 0, u8::MAX, 1, 1, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); } fn geometric_random_unsigned_range_fail_helper() { assert_panic!(geometric_random_unsigned_range::( EXAMPLE_SEED, T::ONE, T::ONE, 1, 1 )); assert_panic!(geometric_random_unsigned_range::( EXAMPLE_SEED, T::ONE, T::ZERO, 1, 1 )); assert_panic!(geometric_random_unsigned_range::( EXAMPLE_SEED, T::ZERO, T::exact_from(10), 1, 0 )); assert_panic!(geometric_random_unsigned_range::( EXAMPLE_SEED, T::ONE, T::exact_from(10), 9, 10 )); assert_panic!(geometric_random_unsigned_range::( EXAMPLE_SEED, T::ZERO, T::exact_from(10), u64::MAX, u64::MAX - 1 )); } #[test] fn geometric_random_unsigned_range_fail() { apply_fn_to_unsigneds!(geometric_random_unsigned_range_fail_helper); } malachite-base-0.4.16/tests/num/random/geometric/geometric_random_unsigneds.rs000064400000000000000000000166411046102023000257250ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::geometric::geometric_random_unsigneds; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::moments::{ truncated_geometric_dist_assertions, CheckedToF64, MomentStats, }; use std::panic::catch_unwind; fn geometric_random_unsigneds_helper( um_numerator: u64, um_denominator: u64, expected_values: &[T], expected_common_values: &[(T, usize)], expected_pop_median: (T, Option), expected_sample_median: (T, Option), expected_pop_moment_stats: MomentStats, expected_sample_moment_stats: MomentStats, ) { truncated_geometric_dist_assertions( geometric_random_unsigneds::(EXAMPLE_SEED, um_numerator, um_denominator), T::ZERO, T::MAX, um_numerator, um_denominator, expected_values, expected_common_values, expected_pop_median, expected_sample_median, expected_pop_moment_stats, expected_sample_moment_stats, ); } #[test] fn test_geometric_random_unsigneds() { // u64, um = 1 / 64 let values = &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]; let common_values = &[(0, 984537), (1, 15210), (2, 253)]; let pop_median = (0, None); let sample_median = (0, None); let pop_moment_stats = MomentStats { mean: NiceFloat(0.015624999999999944), standard_deviation: NiceFloat(0.12597277731716458), skewness: NiceFloat(8.186292482887549), excess_kurtosis: NiceFloat(69.01538461538773), }; let sample_moment_stats = MomentStats { mean: NiceFloat(0.015716000000000004), standard_deviation: NiceFloat(0.1263923388462427), skewness: NiceFloat(8.160460378454996), excess_kurtosis: NiceFloat(68.31033619043119), }; geometric_random_unsigneds_helper::( 1, 64, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // u64, um = 1 let values = &[1, 0, 0, 3, 4, 4, 1, 0, 0, 1, 0, 0, 2, 2, 0, 0, 1, 0, 3, 1]; let common_values = &[ (0, 500085), (1, 249510), (2, 125328), (3, 62428), (4, 31280), (5, 15676), (6, 7853), (7, 3994), (8, 1932), (9, 942), ]; let pop_median = (0, Some(1)); let sample_median = (0, None); let pop_moment_stats = MomentStats { mean: NiceFloat(1.0), standard_deviation: NiceFloat(std::f64::consts::SQRT_2), skewness: NiceFloat(2.1213203435596424), excess_kurtosis: NiceFloat(6.5), }; let sample_moment_stats = MomentStats { mean: NiceFloat(1.0006159999999573), standard_deviation: NiceFloat(1.414547850547892), skewness: NiceFloat(2.1140569440125403), excess_kurtosis: NiceFloat(6.4341815215340805), }; geometric_random_unsigneds_helper::( 1, 1, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // u64, um = 12345/10000 let values = &[1, 3, 8, 2, 2, 0, 1, 1, 0, 0, 0, 0, 1, 1, 7, 0, 0, 3, 0, 0]; let common_values = &[ (0, 446911), (1, 246858), (2, 137217), (3, 75488), (4, 41605), (5, 23149), (6, 12981), (7, 7024), (8, 3848), (9, 2206), ]; let pop_median = (1, None); let sample_median = (1, None); let pop_moment_stats = MomentStats { mean: NiceFloat(1.2344999999999997), standard_deviation: NiceFloat(1.6608703290744884), skewness: NiceFloat(2.088663960860256), excess_kurtosis: NiceFloat(6.362517141396456), }; let sample_moment_stats = MomentStats { mean: NiceFloat(1.2380129999999983), standard_deviation: NiceFloat(1.6649767517832197), skewness: NiceFloat(2.0942793135700466), excess_kurtosis: NiceFloat(6.469904862333731), }; geometric_random_unsigneds_helper::( 12345, 10000, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // u8, um = 64 let values = &[181, 90, 125, 70, 146, 41, 109, 5, 224, 93, 33, 18, 89, 6, 17, 1, 129, 2, 123, 134]; let common_values = &[ (0, 15734), (1, 15591), (2, 15469), (3, 14917), (4, 14672), (5, 14340), (6, 14329), (7, 14274), (8, 13841), (9, 13586), ]; let pop_median = (43, None); let sample_median = (43, None); let pop_moment_stats = MomentStats { mean: NiceFloat(59.070796734994865), standard_deviation: NiceFloat(53.608086324088696), skewness: NiceFloat(1.2637908431790819), excess_kurtosis: NiceFloat(1.1650093560615717), }; let sample_moment_stats = MomentStats { mean: NiceFloat(59.03148100000193), standard_deviation: NiceFloat(53.60145056863821), skewness: NiceFloat(1.2649824077121026), excess_kurtosis: NiceFloat(1.1705093182268955), }; geometric_random_unsigneds_helper::( 64, 1, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // u8, um = 1000 let values = &[ 24, 115, 248, 25, 104, 215, 208, 240, 37, 35, 196, 204, 40, 37, 245, 193, 252, 119, 0, 219, ]; let common_values = &[ (18, 4482), (11, 4469), (6, 4431), (25, 4426), (0, 4424), (3, 4415), (5, 4400), (8, 4400), (20, 4396), (10, 4386), ]; let pop_median = (119, None); let sample_median = (119, None); let pop_moment_stats = MomentStats { mean: NiceFloat(122.04742583121647), standard_deviation: NiceFloat(73.7795264500733), skewness: NiceFloat(0.08861336552406392), excess_kurtosis: NiceFloat(-1.1891899016227028), }; let sample_moment_stats = MomentStats { mean: NiceFloat(122.12244000000315), standard_deviation: NiceFloat(73.78371977939058), skewness: NiceFloat(0.08799741904573245), excess_kurtosis: NiceFloat(-1.1900813344800518), }; geometric_random_unsigneds_helper::( 1000, 1, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); } fn geometric_random_unsigneds_fail_helper() { assert_panic!(geometric_random_unsigneds::(EXAMPLE_SEED, 0, 1)); assert_panic!(geometric_random_unsigneds::(EXAMPLE_SEED, 1, 0)); assert_panic!(geometric_random_unsigneds::( EXAMPLE_SEED, u64::MAX, u64::MAX - 1 )); } #[test] fn geometric_random_unsigneds_fail() { apply_fn_to_unsigneds!(geometric_random_unsigneds_fail_helper); } malachite-base-0.4.16/tests/num/random/geometric/get_geometric_random_signed_from_inclusive_range.rs000064400000000000000000000054661046102023000323210ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::random::geometric::get_geometric_random_signed_from_inclusive_range; use malachite_base::num::random::VariableRangeGenerator; use malachite_base::random::EXAMPLE_SEED; fn get_geometric_random_signed_from_inclusive_range_helper( a: i32, b: i32, abs_um_numerator: u64, abs_um_denominator: u64, out: i32, ) { assert_eq!( get_geometric_random_signed_from_inclusive_range( &mut VariableRangeGenerator::new(EXAMPLE_SEED), a, b, abs_um_numerator, abs_um_denominator ), out ); } #[test] fn test_get_geometric_random_signed_from_inclusive_range() { get_geometric_random_signed_from_inclusive_range_helper(0, 0, 2, 1, 0); get_geometric_random_signed_from_inclusive_range_helper(0, 1, 2, 1, 1); get_geometric_random_signed_from_inclusive_range_helper(0, 10, 2, 1, 1); get_geometric_random_signed_from_inclusive_range_helper(0, 10, 10, 1, 2); get_geometric_random_signed_from_inclusive_range_helper(-10, 10, 2, 1, -3); get_geometric_random_signed_from_inclusive_range_helper(-10, 10, 10, 1, 8); get_geometric_random_signed_from_inclusive_range_helper(100, 110, 101, 1, 101); get_geometric_random_signed_from_inclusive_range_helper(100, 110, 500, 1, 109); get_geometric_random_signed_from_inclusive_range_helper(-110, -100, 101, 1, -101); get_geometric_random_signed_from_inclusive_range_helper(-110, -100, 500, 1, -109); } #[test] #[should_panic] fn get_geometric_random_signed_from_inclusive_range_fail_1() { get_geometric_random_signed_from_inclusive_range( &mut VariableRangeGenerator::new(EXAMPLE_SEED), 1, 0, 1, 2, ); } #[test] #[should_panic] fn get_geometric_random_signed_from_inclusive_range_fail_2() { get_geometric_random_signed_from_inclusive_range( &mut VariableRangeGenerator::new(EXAMPLE_SEED), 1, 2, 1, 0, ); } #[test] #[should_panic] fn get_geometric_random_signed_from_inclusive_range_fail_3() { get_geometric_random_signed_from_inclusive_range( &mut VariableRangeGenerator::new(EXAMPLE_SEED), 1, 2, 0, 0, ); } #[test] #[should_panic] fn get_geometric_random_signed_from_inclusive_range_fail_4() { get_geometric_random_signed_from_inclusive_range( &mut VariableRangeGenerator::new(EXAMPLE_SEED), 1, 2, 1, 2, ); } malachite-base-0.4.16/tests/num/random/geometric/mean.rs000064400000000000000000000044211046102023000212410ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::float::NiceFloat; use malachite_base::test_util::num::random::geometric::{ adjusted_mean_to_unadjusted_mean, unadjusted_mean_to_adjusted_mean, }; #[test] pub fn test_unadjusted_mean_to_adjusted_mean() { let test = |unadjusted_mean, limit, adjusted_mean| { assert_eq!( NiceFloat(unadjusted_mean_to_adjusted_mean(unadjusted_mean, limit)), NiceFloat(adjusted_mean) ); }; test(1.0e-45, 255.0, 0.0); test(0.001, 255.0, 0.000999999999999855); test(1.0, 255.0, 1.0); test(10.0, 255.0, 9.999999993517946); test(50.0, 255.0, 48.38067332601502); test(100.0, 255.0, 78.25417704300385); test(255.0, 255.0, 106.4745261876895); test(1000000.0, 255.0, 127.49458799160993); test(1.0000000000000002, 255.0, 1.0); test(10.000000006482054, 255.0, 10.000000000000002); test(51.95952531604177, 255.0, 50.0); test(192.50163549359422, 255.0, 100.00000000000001); test(10921.900023504326, 255.0, 127.0000000000199); test(546163.2639224805, 255.0, 127.49000008135106); } #[test] pub fn test_adjusted_mean_to_unadjusted_mean() { let test = |adjusted_mean, limit, unadjusted_mean| { assert_eq!( NiceFloat(adjusted_mean_to_unadjusted_mean(adjusted_mean, limit)), NiceFloat(unadjusted_mean) ); }; test(1.0, 255.0, 1.0000000000000002); test(10.0, 255.0, 10.000000006482054); test(50.0, 255.0, 51.95952531604177); test(100.0, 255.0, 192.50163549359422); test(127.0, 255.0, 10921.900023504326); test(127.49, 255.0, 546163.2639224805); test(0.000999999999999855, 255.0, 0.0009999999999998803); test(1.0, 255.0, 1.0000000000000002); test(9.999999993517946, 255.0, 10.0); test(48.38067332601502, 255.0, 50.0); test(78.25417704300385, 255.0, 100.0); test(106.4745261876895, 255.0, 255.0); test(127.49458799160993, 255.0, 1006078.1813340919); } malachite-base-0.4.16/tests/num/random/random_finite_primitive_floats.rs000064400000000000000000000075671046102023000246370ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::random_finite_primitive_floats; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::num::random::random_primitive_floats_helper_helper; use malachite_base::test_util::stats::moments::{CheckedToF64, MomentStats}; fn random_finite_primitive_floats_helper( expected_values: &[T], expected_common_values: &[(T, usize)], expected_median: (T, Option), expected_moment_stats: MomentStats, ) { random_primitive_floats_helper_helper( random_finite_primitive_floats::(EXAMPLE_SEED), expected_values, expected_common_values, expected_median, expected_moment_stats, ); } #[test] fn test_random_finite_primitive_floats() { // f32 let values = &[ -2.3484663e-27, 2.287989e-18, -2.0729893e-12, 3.360012e28, -9.021723e-32, 3564911.2, -0.0000133769445, -1.8855448e18, 8.2494555e-29, 2.2178014e-38, -6.3067724e-34, 5.1996016e31, 7.613263e33, 0.00015323666, 9.476819e36, -0.0005665586, 8.8733265e-30, 0.09273135, -7.7748304e33, 4.3156234e-8, ]; let common_values = &[ (-66476.9, 2), (34.61204, 2), (73439.86, 2), (780.0361, 2), (-66297.14, 2), (0.2084277, 2), (13200.072, 2), (224535.31, 2), (3306.3638, 2), (5.7126203, 2), ]; let sample_median = (4.601795e-39, Some(4.606578e-39)); let sample_moment_stats = MomentStats { mean: NiceFloat(-1.871800306879315e34), standard_deviation: NiceFloat(1.8597574252028948e37), skewness: NiceFloat(-0.04588142291892213), excess_kurtosis: NiceFloat(174.30920632007357), }; random_finite_primitive_floats_helper::( values, common_values, sample_median, sample_moment_stats, ); // f64 let values = &[ 3.1062066405583414e-146, 7.268713316268922e223, 1.1685126708702853e48, -1.0824685183946233e146, 3.1146051606615834e-306, 2.2453015573637678e249, 1.2548860979388688e-35, -8.287939157477945e-27, 2.1255041535787168e-13, 4.815129234795049e-64, 1.3850402674408149e-17, -1.2535717707589619e207, -1.4941028004491903e142, 4.3666119614549075e-51, -7.063699168119983e17, -7.062565582436956e90, 1.1662950933663384e-221, 2.1976577668343595e-97, -2.821294426687019e-137, 1.225091633874841e-222, ]; let common_values = &[ (3.637321705391, 1), (30.80883877248, 1), (915366460504.2, 1), (9256888.416622, 1), (-737164661.2491, 1), (-81413.95043198, 1), (-994938.9166069, 1), (1.4299272196643, 1), (12812252.479435, 1), (1598038.5592174, 1), ]; let sample_median = (2.7723065921722726e-308, Some(2.782073119497922e-308)); let sample_moment_stats = MomentStats { mean: NiceFloat(7.922018643581054e303), standard_deviation: NiceFloat(f64::INFINITY), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; random_finite_primitive_floats_helper::( values, common_values, sample_median, sample_moment_stats, ); } malachite-base-0.4.16/tests/num/random/random_highest_bit_set_unsigneds.rs000064400000000000000000000226151046102023000251330ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::random_highest_bit_set_unsigneds; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::moments::{ uniform_primitive_int_assertions, CheckedToF64, MomentStats, }; fn random_highest_bit_set_unsigneds_helper( expected_values: &[T], expected_common_values: &[(T, usize)], expected_pop_median: (T, Option), expected_sample_median: (T, Option), expected_pop_moment_stats: MomentStats, expected_sample_moment_stats: MomentStats, ) { uniform_primitive_int_assertions( random_highest_bit_set_unsigneds(EXAMPLE_SEED), T::power_of_2(T::WIDTH - 1), T::MAX, expected_values, expected_common_values, expected_pop_median, expected_sample_median, expected_pop_moment_stats, expected_sample_moment_stats, ); } #[test] fn test_random_highest_bit_set_unsigneds() { // u8 let values = &[ 241, 222, 151, 226, 198, 220, 180, 212, 161, 175, 129, 241, 182, 138, 175, 145, 217, 220, 247, 194, ]; let common_values = &[ (130, 8077), (249, 8039), (176, 8015), (241, 7966), (136, 7937), (205, 7933), (178, 7928), (219, 7927), (210, 7925), (230, 7924), ]; let pop_median = (191, Some(192)); let sample_median = (191, None); let pop_moment_stats = MomentStats { mean: NiceFloat(191.5), standard_deviation: NiceFloat(36.94928957368463), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2001464933162425), }; let sample_moment_stats = MomentStats { mean: NiceFloat(191.47808899999873), standard_deviation: NiceFloat(36.961138429895456), skewness: NiceFloat(-0.00045403607545687984), excess_kurtosis: NiceFloat(-1.1998683031732567), }; random_highest_bit_set_unsigneds_helper::( values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // u16 let values = &[ 61297, 55435, 52113, 36166, 34170, 60868, 44820, 44177, 56814, 43920, 62926, 52397, 56477, 62030, 53767, 54475, 41390, 52238, 49476, 64068, ]; let common_values = &[ (45680, 55), (43149, 54), (51767, 54), (41030, 53), (49628, 52), (51621, 52), (59748, 52), (62186, 52), (34198, 51), (36279, 51), ]; let pop_median = (49151, Some(49152)); let sample_median = (49162, None); let pop_moment_stats = MomentStats { mean: NiceFloat(49151.5), standard_deviation: NiceFloat(9459.306805997996), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2000000022351742), }; let sample_moment_stats = MomentStats { mean: NiceFloat(49155.96401899928), standard_deviation: NiceFloat(9454.356832489304), skewness: NiceFloat(-0.0012474540243074795), excess_kurtosis: NiceFloat(-1.1990519661334587), }; random_highest_bit_set_unsigneds_helper::( values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // u32 let values = &[ 3964006257, 3276907976, 3451421022, 4073264610, 3109848542, 3140663214, 2279906674, 3612658596, 3508930337, 3808334112, 3115296257, 2693817273, 3135713082, 2512715495, 2304388648, 3178397234, 4176627051, 3554614631, 3618567415, 3594534402, ]; let common_values = &[ (2148512502, 2), (2152753653, 2), (2199919756, 2), (2200926180, 2), (2201533159, 2), (2203162873, 2), (2204334486, 2), (2243577040, 2), (2248172201, 2), (2250885871, 2), ]; let pop_median = (3221225471, Some(3221225472)); let sample_median = (3220111243, Some(3220113439)); let pop_moment_stats = MomentStats { mean: NiceFloat(3221225471.5), standard_deviation: NiceFloat(619925131.1265597), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2), }; let sample_moment_stats = MomentStats { mean: NiceFloat(3220061212.7312818), standard_deviation: NiceFloat(620056431.3063867), skewness: NiceFloat(0.0014601286400032912), excess_kurtosis: NiceFloat(-1.1999609793276904), }; random_highest_bit_set_unsigneds_helper::( values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // u64 let values = &[ 11648792314704686961, 15902849618696487087, 12062424265687245175, 10193137694460908462, 9734517988917403762, 17618716774223412528, 12117930945561730236, 13095749177794802780, 13684732338925793861, 17489043124220843898, 18428543530713567946, 9663508144831389154, 14291728674867306832, 14157636121372894287, 11041743053466742106, 11652479517924728358, 15926995443195260196, 10797926927713903617, 9340643919610687288, 13527331835876139736, ]; let common_values = &[ (9223375360960685195, 1), (9223375840468297219, 1), (9223377246635142855, 1), (9223378573599571464, 1), (9223392818083847604, 1), (9223397883812499659, 1), (9223410046446842059, 1), (9223414297499376833, 1), (9223420250639904388, 1), (9223423782640535515, 1), ]; let pop_median = (13835058055282163711, Some(13835058055282163712)); let sample_median = (13835015978121017591, Some(13835016964896634362)); let pop_moment_stats = MomentStats { mean: NiceFloat(1.3835058055282164e19), standard_deviation: NiceFloat(2.6625581641570857e18), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2), }; let sample_moment_stats = MomentStats { mean: NiceFloat(1.3835207839699462e19), standard_deviation: NiceFloat(2.6620357716239826e18), skewness: NiceFloat(-0.001163213633403464), excess_kurtosis: NiceFloat(-1.1990763518455725), }; random_highest_bit_set_unsigneds_helper::( values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // u128 let values = &[ 316819081939861044636107404782286008177, 259684029915037091022230980152781410491, 274570122163304294029662138603390933020, 227774850171603602876471193044002894743, 228075138265181566710552389938690625316, 212803339921546589345359493671973554838, 290482805477667929731925894842607922053, 194242323025343149803496343896337025882, 273877696450250650298202452211959786285, 202950956103661145939707262718357071703, 278510113161417516359560622970606220871, 245612405407790906538437072159901074531, 192996213236671200977298813427044737421, 311381173222019982206270836087375053399, 176738900463469569991939158243641249503, 288268669295331405536678348099056207715, 204463485514563745612349536646478672573, 185187345061019841391010982362414546856, 234567239495355551510783097995427525513, 322415362730128827224032220814663383318, ]; let common_values = &[ (170141233166538297897770214998043520489, 1), (170141477709687108748255943535626236844, 1), (170141963031764576849655827097535573872, 1), (170142211761517152257367037557307192382, 1), (170142224955858751899306474848524651318, 1), (170142344567707776674180030986486606478, 1), (170142519806846123597203111583658441461, 1), (170142677117909400976523007761944910786, 1), (170142818348199748232299322264932053448, 1), (170143268636071676474898792639923408007, 1), ]; let pop_median = ( 255211775190703847597530955573826158591, Some(255211775190703847597530955573826158592), ); let sample_median = ( 255126542430357640405925855455171138421, Some(255126579172819401755185863236353147245), ); let pop_moment_stats = MomentStats { mean: NiceFloat(2.5521177519070385e38), standard_deviation: NiceFloat(4.91155290355717e37), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2), }; let sample_moment_stats = MomentStats { mean: NiceFloat(2.5515158317195176e38), standard_deviation: NiceFloat(4.910082612813729e37), skewness: NiceFloat(0.0016680470828693357), excess_kurtosis: NiceFloat(-1.199401614583425), }; random_highest_bit_set_unsigneds_helper::( values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); } malachite-base-0.4.16/tests/num/random/random_natural_signeds.rs000064400000000000000000000220611046102023000230650ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::random_natural_signeds; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::moments::{ uniform_primitive_int_assertions, CheckedToF64, MomentStats, }; fn random_natural_signeds_helper( expected_values: &[T], expected_common_values: &[(T, usize)], expected_pop_median: (T, Option), expected_sample_median: (T, Option), expected_pop_moment_stats: MomentStats, expected_sample_moment_stats: MomentStats, ) { uniform_primitive_int_assertions( random_natural_signeds::(EXAMPLE_SEED), T::ZERO, T::MAX, expected_values, expected_common_values, expected_pop_median, expected_sample_median, expected_pop_moment_stats, expected_sample_moment_stats, ); } #[test] fn test_random_natural_signeds() { // i8 let values = &[113, 94, 23, 98, 70, 92, 52, 84, 33, 47, 1, 113, 54, 10, 47, 17, 89, 92, 119, 66]; let common_values = &[ (2, 8077), (121, 8039), (48, 8015), (113, 7966), (8, 7937), (77, 7933), (50, 7928), (91, 7927), (82, 7925), (102, 7924), ]; let pop_median = (63, Some(64)); let sample_median = (63, None); let pop_moment_stats = MomentStats { mean: NiceFloat(63.5), standard_deviation: NiceFloat(36.94928957368463), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2001464933162425), }; let sample_moment_stats = MomentStats { mean: NiceFloat(63.478088999999315), standard_deviation: NiceFloat(36.96113842989552), skewness: NiceFloat(-0.000454036075457304), excess_kurtosis: NiceFloat(-1.1998683031732713), }; random_natural_signeds_helper::( values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i16 let values = &[ 28529, 22667, 19345, 3398, 1402, 28100, 12052, 11409, 24046, 11152, 30158, 19629, 23709, 29262, 20999, 21707, 8622, 19470, 16708, 31300, ]; let common_values = &[ (12912, 55), (10381, 54), (18999, 54), (8262, 53), (16860, 52), (18853, 52), (26980, 52), (29418, 52), (1430, 51), (3511, 51), ]; let pop_median = (16383, Some(16384)); let sample_median = (16394, None); let pop_moment_stats = MomentStats { mean: NiceFloat(16383.5), standard_deviation: NiceFloat(9459.306805997996), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2000000022351742), }; let sample_moment_stats = MomentStats { mean: NiceFloat(16387.96401900046), standard_deviation: NiceFloat(9454.356832489306), skewness: NiceFloat(-0.0012474540243073533), excess_kurtosis: NiceFloat(-1.199051966133461), }; random_natural_signeds_helper::( values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i32 let values = &[ 1816522609, 1129424328, 1303937374, 1925780962, 962364894, 993179566, 132423026, 1465174948, 1361446689, 1660850464, 967812609, 546333625, 988229434, 365231847, 156905000, 1030913586, 2029143403, 1407130983, 1471083767, 1447050754, ]; let common_values = &[ (1028854, 2), (5270005, 2), (52436108, 2), (53442532, 2), (54049511, 2), (55679225, 2), (56850838, 2), (96093392, 2), (100688553, 2), (103402223, 2), ]; let pop_median = (1073741823, Some(1073741824)); let sample_median = (1072627595, Some(1072629791)); let pop_moment_stats = MomentStats { mean: NiceFloat(1073741823.5), standard_deviation: NiceFloat(619925131.1265597), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2), }; let sample_moment_stats = MomentStats { mean: NiceFloat(1072577564.7313439), standard_deviation: NiceFloat(620056431.3063871), skewness: NiceFloat(0.0014601286400032305), excess_kurtosis: NiceFloat(-1.1999609793276922), }; random_natural_signeds_helper::( values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i64 let values = &[ 2425420277849911153, 6679477581841711279, 2839052228832469367, 969765657606132654, 511145952062627954, 8395344737368636720, 2894558908706954428, 3872377140940026972, 4461360302071018053, 8265671087366068090, 9205171493858792138, 440136107976613346, 5068356638012531024, 4934264084518118479, 1818371016611966298, 2429107481069952550, 6703623406340484388, 1574554890859127809, 117271882755911480, 4303959799021363928, ]; let common_values = &[ (3324105909387, 1), (3803613521411, 1), (5209780367047, 1), (6536744795656, 1), (20781229071796, 1), (25846957723851, 1), (38009592066251, 1), (42260644601025, 1), (48213785128580, 1), (51745785759707, 1), ]; let pop_median = (4611686018427387903, Some(4611686018427387904)); let sample_median = (4611643941266241783, Some(4611644928041858554)); let pop_moment_stats = MomentStats { mean: NiceFloat(4.611686018427388e18), standard_deviation: NiceFloat(2.6625581641570857e18), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2), }; let sample_moment_stats = MomentStats { mean: NiceFloat(4.611835802844851e18), standard_deviation: NiceFloat(2.6620357716239764e18), skewness: NiceFloat(-0.0011632136334031786), excess_kurtosis: NiceFloat(-1.1990763518455585), }; random_natural_signeds_helper::( values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i128 let values = &[ 146677898479391812904420101066401902449, 89542846454567859290543676436897304763, 104428938702835062297974834887506827292, 57633666711134371144783889328118789015, 57933954804712334978865086222806519588, 42662156461077357613672189956089449110, 120341622017198698000238591126723816325, 24101139564873918071809040180452920154, 103736512989781418566515148496075680557, 32809772643191914208019959002472965975, 108368929700948284627873319254722115143, 75471221947321674806749768444016968803, 22855029776201969245611509711160631693, 141239989761550750474583532371490947671, 6597717003000338260251854527757143775, 118127485834862173804991044383172101987, 34322302054094513880662232930594566845, 15046161600550609659323678646530441128, 64426056034886319779095794279543419785, 152274179269659595492344917098779277590, ]; let common_values = &[ (49706069066166082911282159414761, 1), (294249217877016568639819742131116, 1), (779571295345117968523381651468144, 1), (1028301047920525679733841423086654, 1), (1041495389520167619171132640545590, 1), (1161107238544942492727270602500750, 1), (1336346376891865515807867774335733, 1), (1493657440169244835704046060805058, 1), (1634887730516500612018549047947720, 1), (2085175602444743211488924039302279, 1), ]; let pop_median = ( 85070591730234615865843651857942052863, Some(85070591730234615865843651857942052864), ); let sample_median = ( 84985358969888408674238551739287032693, Some(84985395712350170023498559520469041517), ); let pop_moment_stats = MomentStats { mean: NiceFloat(8.507059173023462e37), standard_deviation: NiceFloat(4.91155290355717e37), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2), }; let sample_moment_stats = MomentStats { mean: NiceFloat(8.501039971148385e37), standard_deviation: NiceFloat(4.910082612813726e37), skewness: NiceFloat(0.0016680470828691063), excess_kurtosis: NiceFloat(-1.199401614583414), }; random_natural_signeds_helper::( values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); } malachite-base-0.4.16/tests/num/random/random_negative_finite_primitive_floats.rs000064400000000000000000000076601046102023000265130ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::random_negative_finite_primitive_floats; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::num::random::random_primitive_floats_helper_helper; use malachite_base::test_util::stats::moments::{CheckedToF64, MomentStats}; fn random_negative_finite_primitive_floats_helper( expected_values: &[T], expected_common_values: &[(T, usize)], expected_median: (T, Option), expected_moment_stats: MomentStats, ) { random_primitive_floats_helper_helper( random_negative_finite_primitive_floats::(EXAMPLE_SEED), expected_values, expected_common_values, expected_median, expected_moment_stats, ); } #[test] fn test_random_negative_finite_primitive_floats() { // f32 let values = &[ -2.3484663e-27, -0.010641626, -5.8060583e-9, -2.8182442e-31, -10462.532, -821.12994, -6.303163e33, -9.50376e-15, -4.9561126e-11, -8.565163e-22, -6667.249, -8.632876e18, -1222.524, -2.8259287e25, -8.408057e32, -35.37676, -5.3312457e-35, -1.1431576e-12, -5.8021113e-15, -4.2578778e-14, ]; let common_values = &[ (-2.915314, 2), (-0.7262628, 2), (-1.3261845, 2), (-10.318969, 2), (-12496.082, 2), (-15.058022, 2), (-2.5221732, 2), (-20.562862, 2), (-203818.36, 2), (-26.077845, 2), ]; let sample_median = (-1.6313586, Some(-1.6313426)); let sample_moment_stats = MomentStats { mean: NiceFloat(-1.9935686121103762e36), standard_deviation: NiceFloat(1.8605029843851628e37), skewness: NiceFloat(-12.384333043431482), excess_kurtosis: NiceFloat(170.5284644692483), }; random_negative_finite_primitive_floats_helper::( values, common_values, sample_median, sample_moment_stats, ); // f64 let values = &[ -1.4470055025606618e146, -6.2410386896936294e-139, -3.235416846271215e118, -2.8486059576132576e243, -1.3007593490666564e274, -1.267802986597089e-253, -6.298463311550517e114, -2.71148919055391e49, -11845642624.881702, -6.049786340671396e-245, -9.268165817801774e-308, -7.204960592983619e278, -3.152983742246857e-31, -2.9080351183768945e-22, -5.397630931761668e186, -8.140466543599511e145, -1.5709219762031943e-140, -1.0805614483727634e203, -2.6257467421064505e300, -3.922358679765479e20, ]; let common_values = &[ (-4081294.15273, 1), (-75856946.7859, 1), (-0.785631131986, 1), (-10.70965140303, 1), (-306424.6626443, 1), (-314701.8184209, 1), (-449320.3879786, 1), (-590754505.6957, 1), (-642882447.5536, 1), (-88637.71469077, 1), ]; let sample_median = (-1.5131202036927986, Some(-1.511917932803396)); let sample_moment_stats = MomentStats { mean: NiceFloat(-1.3244537383462707e305), standard_deviation: NiceFloat(f64::INFINITY), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; random_negative_finite_primitive_floats_helper::( values, common_values, sample_median, sample_moment_stats, ); } malachite-base-0.4.16/tests/num/random/random_negative_primitive_floats.rs000064400000000000000000000076021046102023000251510ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::random_negative_primitive_floats; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::num::random::random_primitive_floats_helper_helper; use malachite_base::test_util::stats::moments::{CheckedToF64, MomentStats}; fn random_negative_primitive_floats_helper( expected_values: &[T], expected_common_values: &[(T, usize)], expected_median: (T, Option), expected_moment_stats: MomentStats, ) { random_primitive_floats_helper_helper( random_negative_primitive_floats::(EXAMPLE_SEED), expected_values, expected_common_values, expected_median, expected_moment_stats, ); } #[test] fn test_random_negative_primitive_floats() { // f32 let values = &[ -2.3484665e-27, -0.010641627, -5.8060587e-9, -2.8182444e-31, -10462.533, -821.13, -6.3031636e33, -9.5037605e-15, -4.956113e-11, -8.565164e-22, -6667.2495, -8.6328766e18, -1222.5242, -2.825929e25, -8.408058e32, -35.376762, -5.331246e-35, -1.1431577e-12, -5.8021117e-15, -4.257878e-14, ]; let common_values = &[ (-10.31897, 2), (-539.9892, 2), (-60148.51, 2), (-7.546873, 2), (-7606.816, 2), (-776.3078, 2), (-1.3261846, 2), (-12496.083, 2), (-2.5221734, 2), (-2.9153142, 2), ]; let sample_median = (-1.6313587, Some(-1.6313428)); let sample_moment_stats = MomentStats { mean: NiceFloat(-1.9935687709301062e36), standard_deviation: NiceFloat(1.8605031273250459e37), skewness: NiceFloat(-12.384332949727417), excess_kurtosis: NiceFloat(170.5284612507418), }; random_negative_primitive_floats_helper::( values, common_values, sample_median, sample_moment_stats, ); // f64 let values = &[ -1.447005502560662e146, -6.24103868969363e-139, -3.2354168462712154e118, -2.848605957613258e243, -1.3007593490666566e274, -1.2678029865970891e-253, -6.298463311550518e114, -2.7114891905539105e49, -11845642624.881704, -6.049786340671397e-245, -9.268165817801776e-308, -7.20496059298362e278, -3.1529837422468573e-31, -2.908035118376895e-22, -5.397630931761669e186, -8.140466543599512e145, -1.5709219762031945e-140, -1.0805614483727636e203, -2.6257467421064508e300, -3.9223586797654796e20, ]; let common_values = &[ (-8417229.77625, 1), (-2.510958896e45, 1), (-3208093286.102, 1), (-362.2025556776, 1), (-46.55187627446, 1), (-466061517.8385, 1), (-5.171759573816, 1), (-6666772552.184, 1), (-675858.2909992, 1), (-732009733280.7, 1), ]; let sample_median = (-1.5131202036927989, Some(-1.5119179328033963)); let sample_moment_stats = MomentStats { mean: NiceFloat(-1.324453738346271e305), standard_deviation: NiceFloat(f64::INFINITY), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; random_negative_primitive_floats_helper::( values, common_values, sample_median, sample_moment_stats, ); } malachite-base-0.4.16/tests/num/random/random_negative_signeds.rs000064400000000000000000000226111046102023000232220ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::random_negative_signeds; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::moments::{ uniform_primitive_int_assertions, CheckedToF64, MomentStats, }; fn random_negative_signeds_helper( expected_values: &[T], expected_common_values: &[(T, usize)], expected_pop_median: (T, Option), expected_sample_median: (T, Option), expected_pop_moment_stats: MomentStats, expected_sample_moment_stats: MomentStats, ) { uniform_primitive_int_assertions( random_negative_signeds::(EXAMPLE_SEED), T::MIN, T::NEGATIVE_ONE, expected_values, expected_common_values, expected_pop_median, expected_sample_median, expected_pop_moment_stats, expected_sample_moment_stats, ); } #[test] fn test_random_negative_signeds() { // i8 let values = &[ -15, -34, -105, -30, -58, -36, -76, -44, -95, -81, -127, -15, -74, -118, -81, -111, -39, -36, -9, -62, ]; let common_values = &[ (-126, 8077), (-7, 8039), (-80, 8015), (-15, 7966), (-120, 7937), (-51, 7933), (-78, 7928), (-37, 7927), (-46, 7925), (-26, 7924), ]; let pop_median = (-65, Some(-64)); let sample_median = (-65, None); let pop_moment_stats = MomentStats { mean: NiceFloat(-64.5), standard_deviation: NiceFloat(36.94928957368463), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2001464933162425), }; let sample_moment_stats = MomentStats { mean: NiceFloat(-64.5219110000005), standard_deviation: NiceFloat(36.96113842989553), skewness: NiceFloat(-0.00045403607545706974), excess_kurtosis: NiceFloat(-1.1998683031732797), }; random_negative_signeds_helper::( values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i16 let values = &[ -4239, -10101, -13423, -29370, -31366, -4668, -20716, -21359, -8722, -21616, -2610, -13139, -9059, -3506, -11769, -11061, -24146, -13298, -16060, -1468, ]; let common_values = &[ (-19856, 55), (-13769, 54), (-22387, 54), (-24506, 53), (-3350, 52), (-5788, 52), (-13915, 52), (-15908, 52), (-4224, 51), (-6649, 51), ]; let pop_median = (-16385, Some(-16384)); let sample_median = (-16374, None); let pop_moment_stats = MomentStats { mean: NiceFloat(-16384.5), standard_deviation: NiceFloat(9459.306805997996), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2000000022351742), }; let sample_moment_stats = MomentStats { mean: NiceFloat(-16380.035980999151), standard_deviation: NiceFloat(9454.356832489315), skewness: NiceFloat(-0.0012474540243074617), excess_kurtosis: NiceFloat(-1.1990519661334669), }; random_negative_signeds_helper::( values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i32 let values = &[ -330961039, -1018059320, -843546274, -221702686, -1185118754, -1154304082, -2015060622, -682308700, -786036959, -486633184, -1179671039, -1601150023, -1159254214, -1782251801, -1990578648, -1116570062, -118340245, -740352665, -676399881, -700432894, ]; let common_values = &[ (-2599452, 2), (-30488905, 2), (-41127657, 2), (-47856776, 2), (-48474862, 2), (-49257777, 2), (-60585238, 2), (-63413113, 2), (-90112461, 2), (-92925255, 2), ]; let pop_median = (-1073741825, Some(-1073741824)); let sample_median = (-1074856053, Some(-1074853857)); let pop_moment_stats = MomentStats { mean: NiceFloat(-1073741824.5), standard_deviation: NiceFloat(619925131.1265597), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2), }; let sample_moment_stats = MomentStats { mean: NiceFloat(-1074906083.2686987), standard_deviation: NiceFloat(620056431.3063879), skewness: NiceFloat(0.0014601286400033587), excess_kurtosis: NiceFloat(-1.199960979327699), }; random_negative_signeds_helper::( values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i64 let values = &[ -6797951759004864655, -2543894455013064529, -6384319808022306441, -8253606379248643154, -8712226084792147854, -828027299486139088, -6328813128147821380, -5350994895914748836, -4762011734783757755, -957700949488707718, -18200542995983670, -8783235928878162462, -4155015398842244784, -4289107952336657329, -7405001020242809510, -6794264555784823258, -2519748630514291420, -7648817145995647999, -9106100154098864328, -4919412237833411880, ]; let common_values = &[ (-32633775716835, 1), (-33530332767202, 1), (-40083601698629, 1), (-54667548368563, 1), (-55711023537196, 1), (-57995675195609, 1), (-60421027989814, 1), (-63506819698059, 1), (-68934218411234, 1), (-96764893067540, 1), ]; let pop_median = (-4611686018427387905, Some(-4611686018427387904)); let sample_median = (-4611728095588534025, Some(-4611727108812917254)); let pop_moment_stats = MomentStats { mean: NiceFloat(-4.611686018427388e18), standard_deviation: NiceFloat(2.6625581641570857e18), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2), }; let sample_moment_stats = MomentStats { mean: NiceFloat(-4.6115362340100536e18), standard_deviation: NiceFloat(2.662035771623978e18), skewness: NiceFloat(-0.0011632136334032948), excess_kurtosis: NiceFloat(-1.199076351845568), }; random_negative_signeds_helper::( values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i128 let values = &[ -23463284981077418827267202649482203279, -80598337005901372441143627278986800965, -65712244757634169433712468828377278436, -112507516749334860586903414387765316713, -112207228655756896752822217493077586140, -127479026999391874118015113759794656618, -49799561443270533731448712589160289403, -146040043895595313659878263535431185574, -66404670470687813165172155219808425171, -137331410817277317523667344713411139753, -61772253759520947103813984461161990585, -94669961513147556924937535271867136925, -147286153684267262486075794004723474035, -28901193698918481257103771344393158057, -163543466457468893471435449188126961953, -52013697625607057926696259332712003741, -135818881406374717851025070785289538883, -155095021859918622072363625069353664600, -105715127425582911952591509436340685943, -17867004190809636239342386617104828138, ]; let common_values = &[ (-5142203300700144436674870612888, 1), (-182426925066696407144329295811271, 1), (-609085828667135587396424148113815, 1), (-709584458395955034053916159170888, 1), (-793734383127263040096517829674535, 1), (-1015040108753864759296367578696398, 1), (-1102384056888326002883014030016669, 1), (-1302359298776052550565920555095243, 1), (-1597976831171503518058570309070626, 1), (-1756747886524482972001931222767918, 1), ]; let pop_median = ( -85070591730234615865843651857942052865, Some(-85070591730234615865843651857942052864), ); let sample_median = ( -85155824490580823057448751976597073035, Some(-85155787748119061708188744195415064211), ); let pop_moment_stats = MomentStats { mean: NiceFloat(-8.507059173023462e37), standard_deviation: NiceFloat(4.91155290355717e37), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2), }; let sample_moment_stats = MomentStats { mean: NiceFloat(-8.513078374898942e37), standard_deviation: NiceFloat(4.9100826128137265e37), skewness: NiceFloat(0.001668047082869008), excess_kurtosis: NiceFloat(-1.1994016145834168), }; random_negative_signeds_helper::( values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); } malachite-base-0.4.16/tests/num/random/random_nonzero_finite_primitive_floats.rs000064400000000000000000000076471046102023000264100ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::random_nonzero_finite_primitive_floats; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::num::random::random_primitive_floats_helper_helper; use malachite_base::test_util::stats::moments::{CheckedToF64, MomentStats}; fn random_nonzero_finite_primitive_floats_helper( expected_values: &[T], expected_common_values: &[(T, usize)], expected_median: (T, Option), expected_moment_stats: MomentStats, ) { random_primitive_floats_helper_helper( random_nonzero_finite_primitive_floats::(EXAMPLE_SEED), expected_values, expected_common_values, expected_median, expected_moment_stats, ); } #[test] fn test_random_nonzero_finite_primitive_floats() { // f32 let values = &[ -2.3484663e-27, 2.287989e-18, -2.0729893e-12, 3.360012e28, -9.021723e-32, 3564911.2, -0.0000133769445, -1.8855448e18, 8.2494555e-29, 2.2178014e-38, -6.3067724e-34, 5.1996016e31, 7.613263e33, 0.00015323666, 9.476819e36, -0.0005665586, 8.8733265e-30, 0.09273135, -7.7748304e33, 4.3156234e-8, ]; let common_values = &[ (-66476.9, 2), (34.61204, 2), (73439.86, 2), (780.0361, 2), (-66297.14, 2), (0.2084277, 2), (13200.072, 2), (224535.31, 2), (3306.3638, 2), (5.7126203, 2), ]; let sample_median = (4.601795e-39, Some(4.606578e-39)); let sample_moment_stats = MomentStats { mean: NiceFloat(-1.871800306879315e34), standard_deviation: NiceFloat(1.8597574252028948e37), skewness: NiceFloat(-0.04588142291892213), excess_kurtosis: NiceFloat(174.30920632007357), }; random_nonzero_finite_primitive_floats_helper::( values, common_values, sample_median, sample_moment_stats, ); // f64 let values = &[ 3.1062066405583414e-146, 7.268713316268922e223, 1.1685126708702853e48, -1.0824685183946233e146, 3.1146051606615834e-306, 2.2453015573637678e249, 1.2548860979388688e-35, -8.287939157477945e-27, 2.1255041535787168e-13, 4.815129234795049e-64, 1.3850402674408149e-17, -1.2535717707589619e207, -1.4941028004491903e142, 4.3666119614549075e-51, -7.063699168119983e17, -7.062565582436956e90, 1.1662950933663384e-221, 2.1976577668343595e-97, -2.821294426687019e-137, 1.225091633874841e-222, ]; let common_values = &[ (3.637321705391, 1), (30.80883877248, 1), (915366460504.2, 1), (9256888.416622, 1), (-737164661.2491, 1), (-81413.95043198, 1), (-994938.9166069, 1), (1.4299272196643, 1), (12812252.479435, 1), (1598038.5592174, 1), ]; let sample_median = (2.7723065921722726e-308, Some(2.782073119497922e-308)); let sample_moment_stats = MomentStats { mean: NiceFloat(7.922018643581054e303), standard_deviation: NiceFloat(f64::INFINITY), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; random_nonzero_finite_primitive_floats_helper::( values, common_values, sample_median, sample_moment_stats, ); } malachite-base-0.4.16/tests/num/random/random_nonzero_primitive_floats.rs000064400000000000000000000075641046102023000250500ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::random_nonzero_primitive_floats; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::num::random::random_primitive_floats_helper_helper; use malachite_base::test_util::stats::moments::{CheckedToF64, MomentStats}; fn random_nonzero_primitive_floats_helper( expected_values: &[T], expected_common_values: &[(T, usize)], expected_median: (T, Option), expected_moment_stats: MomentStats, ) { random_primitive_floats_helper_helper( random_nonzero_primitive_floats::(EXAMPLE_SEED), expected_values, expected_common_values, expected_median, expected_moment_stats, ); } #[test] fn test_random_nonzero_primitive_floats() { // f32 let values = &[ -2.3484665e-27, 2.2879888e-18, -2.0729896e-12, 3.3600117e28, -9.0217234e-32, 3564911.0, -0.000013376945, -1.885545e18, 8.249455e-29, 2.2178013e-38, -6.306773e-34, 5.199601e31, 7.6132625e33, 0.00015323664, 9.4768183e36, -0.0005665587, 8.873326e-30, 0.09273134, -7.774831e33, 4.315623e-8, ]; let common_values = &[ (5.71262, 2), (780.036, 2), (224535.3, 2), (58.67172, 2), (73439.85, 2), (-58.01006, 2), (-66297.15, 2), (-66476.91, 2), (13200.071, 2), (3306.3635, 2), ]; let sample_median = (4.601794e-39, Some(4.606577e-39)); let sample_moment_stats = MomentStats { mean: NiceFloat(-1.871815997376882e34), standard_deviation: NiceFloat(1.8597574260800838e37), skewness: NiceFloat(-0.04588420234596291), excess_kurtosis: NiceFloat(174.30920609573673), }; random_nonzero_primitive_floats_helper::( values, common_values, sample_median, sample_moment_stats, ); // f64 let values = &[ 3.106206640558341e-146, 7.268713316268921e223, 1.1685126708702852e48, -1.0824685183946236e146, 3.114605160661583e-306, 2.2453015573637674e249, 1.2548860979388685e-35, -8.287939157477947e-27, 2.1255041535787165e-13, 4.815129234795048e-64, 1.3850402674408148e-17, -1.253571770758962e207, -1.4941028004491906e142, 4.366611961454907e-51, -7.063699168119985e17, -7.062565582436957e90, 1.1662950933663382e-221, 2.1976577668343592e-97, -2.8212944266870196e-137, 1.2250916338748408e-222, ]; let common_values = &[ (-9967188.16722, 1), (1808.830612999, 1), (32578528203.69, 1), (5643444.695113, 1), (812845035127.8, 1), (-13741970740.45, 1), (-1434325.082519, 1), (-33781527.93352, 1), (-374012916597.5, 1), (-46629353341.91, 1), ]; let sample_median = (2.772306592172272e-308, Some(2.7820731194979217e-308)); let sample_moment_stats = MomentStats { mean: NiceFloat(7.922018643581038e303), standard_deviation: NiceFloat(f64::INFINITY), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; random_nonzero_primitive_floats_helper::( values, common_values, sample_median, sample_moment_stats, ); } malachite-base-0.4.16/tests/num/random/random_nonzero_signeds.rs000064400000000000000000000223271046102023000231160ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::random_nonzero_signeds; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::moments::{ deleted_uniform_primitive_int_assertions, CheckedToF64, MomentStats, }; fn random_nonzero_signeds_helper( expected_values: &[T], expected_common_values: &[(T, usize)], expected_pop_median: (T, Option), expected_sample_median: (T, Option), expected_pop_moment_stats: MomentStats, expected_sample_moment_stats: MomentStats, ) { deleted_uniform_primitive_int_assertions( random_nonzero_signeds::(EXAMPLE_SEED), T::MIN, T::MAX, T::ZERO, expected_values, expected_common_values, expected_pop_median, expected_sample_median, expected_pop_moment_stats, expected_sample_moment_stats, ); } #[test] fn test_random_nonzero_signeds() { // i8 let values = &[ 113, -17, 69, 108, -28, -46, -88, -95, 87, 32, 110, 83, -68, 34, 89, -18, 93, -56, -107, 115, ]; let common_values = &[ (-42, 4112), (86, 4092), (-90, 4063), (22, 4061), (126, 4061), (93, 4054), (55, 4053), (-65, 4052), (36, 4049), (42, 4047), ]; let pop_median = (-1, None); let sample_median = (-1, None); let pop_moment_stats = MomentStats { mean: NiceFloat(-0.5019607843137255), standard_deviation: NiceFloat(74.04502469734098), skewness: NiceFloat(0.00007944171209676364), excess_kurtosis: NiceFloat(-1.207067080672989), }; let sample_moment_stats = MomentStats { mean: NiceFloat(-0.5131950000000044), standard_deviation: NiceFloat(74.04373630744782), skewness: NiceFloat(-0.00024235105395531954), excess_kurtosis: NiceFloat(-1.2065292546223), }; random_nonzero_signeds_helper::( values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i16 let values = &[ -4239, 27717, -11548, -24152, 8279, 21358, 8892, -4519, -14243, 29589, -27203, -13863, -28043, 18463, -22121, 8622, 9735, -28591, 32584, -32655, ]; let common_values = &[ (27447, 34), (-898, 33), (5606, 33), (5836, 33), (-15023, 33), (-197, 32), (3582, 32), (-7314, 32), (19279, 32), (20588, 32), ]; let pop_median = (-1, None); let sample_median = (4, None); let pop_moment_stats = MomentStats { mean: NiceFloat(-0.5000076295109483), standard_deviation: NiceFloat(18918.757957822254), skewness: NiceFloat(1.2098327432880512e-9), excess_kurtosis: NiceFloat(-1.200027466379059), }; let sample_moment_stats = MomentStats { mean: NiceFloat(5.019281000000275), standard_deviation: NiceFloat(18918.558463263365), skewness: NiceFloat(-0.0001978759287576409), excess_kurtosis: NiceFloat(-1.1998315900739762), }; random_nonzero_signeds_helper::( values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i32 let values = &[ 1816522609, -1582771484, 1399726167, -296148292, 1939195997, -908487235, 1210028661, 565094807, -1873730041, -2140045496, 1999530985, -207351284, -147083662, -1197429209, -60545688, 1164671716, -1900807950, -1120015889, 130045419, -1296475448, ]; let common_values = &[ (20095656, 2), (29107328, 2), (83328146, 2), (96543416, 2), (-59532811, 2), (-72250103, 2), (-88423413, 2), (109257003, 2), (132308363, 2), (140940582, 2), ]; let pop_median = (-1, None); let sample_median = (-3037682, Some(-3035621)); let pop_moment_stats = MomentStats { mean: NiceFloat(-0.5000000001164153), standard_deviation: NiceFloat(1239850262.3974571), skewness: NiceFloat(2.8168398703367104e-19), excess_kurtosis: NiceFloat(-1.2000000004190956), }; let sample_moment_stats = MomentStats { mean: NiceFloat(-1708075.0735549931), standard_deviation: NiceFloat(1239705769.0057693), skewness: NiceFloat(0.0016706713036923025), excess_kurtosis: NiceFloat(-1.2008047456655335), }; random_nonzero_signeds_helper::( values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i64 let values = &[ -6797951759004864655, -1271947227506532265, -3901922961219270563, 2427063716414460533, -9191425414850861561, -890566981564077079, -5142919287782265230, 5002226935030621544, -4810431611861206798, -5568319649096903189, -4872912570782646188, 1513424385005459611, 2484972586252155822, -5374443828107932323, 4344958725064805398, 3252798961345668310, -7926092317508205845, -6066899635121005951, 6654913321726770291, -7940875872878966649, ]; let common_values = &[ (26914038281329, 1), (32553719576594, 1), (53892651831494, 1), (66354421349686, 1), (86226284907602, 1), (89837182726049, 1), (95691351770484, 1), (-45554336062456, 1), (-45700426911569, 1), (-50232881235535, 1), ]; let pop_median = (-1, None); let sample_median = (-5305218289400184, Some(-5271053954352614)); let pop_moment_stats = MomentStats { mean: NiceFloat(0.0), standard_deviation: NiceFloat(5.325116328314171e18), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.1999999999999997), }; let sample_moment_stats = MomentStats { mean: NiceFloat(-5606718482239710.0), standard_deviation: NiceFloat(5.325063903618647e18), skewness: NiceFloat(0.0011248693866288532), excess_kurtosis: NiceFloat(-1.200551786344892), }; random_nonzero_signeds_helper::( values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i128 let values = &[ -23463284981077418827267202649482203279, 44771423227283929645271838218448652381, -16428061189408542358428117207094319609, 92274800069126412258941638023956901490, -102717367487498748896125496933502158606, 27917752305106984883503397141734686804, -99140989835634876684435608594951128146, 60003549963171791765607325839025294358, -111914544889959057594096246794876321045, -146483304948093240780207189413481284493, -153586157979719815495295783806580152035, 33018320828004690757952445968579104952, 24887066387352849554815992782110776358, 79085537771456044427857440036467563654, 19637669411666889498466854442215856999, -102694834600182680427466985752932389987, -85298529075242965442847250193117638905, -67944983823469089095474618642592431761, 105189689748742230503365861545668092951, -81854971460639281226116917410207070376, ]; let common_values = &[ (68570815139656170990830410045915, 1), (381682482227926990846204728028719, 1), (565207126752383841908924745713103, 1), (717866653939818807939025508430762, 1), (775173738585689418081884794376186, 1), (818497230601034032775791540657915, 1), (-307666299724089175945459600408325, 1), (-413570452196184856884474016102340, 1), (-789195894019805665974324122519229, 1), (-843024079296967638987633859098218, 1), ]; let pop_median = (-1, None); let sample_median = ( -10072503186589325235371920356302834, Some(-9899574809150113239535729822182407), ); let pop_moment_stats = MomentStats { mean: NiceFloat(0.0), standard_deviation: NiceFloat(9.82310580711434e37), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.1999999999999997), }; let sample_moment_stats = MomentStats { mean: NiceFloat(8.651168263124604e34), standard_deviation: NiceFloat(9.82707680675722e37), skewness: NiceFloat(0.00010083962773749455), excess_kurtosis: NiceFloat(-1.2019920806441844), }; random_nonzero_signeds_helper::( values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); } malachite-base-0.4.16/tests/num/random/random_positive_finite_primitive_floats.rs000064400000000000000000000075771046102023000265620ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::random_positive_finite_primitive_floats; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::num::random::random_primitive_floats_helper_helper; use malachite_base::test_util::stats::moments::{CheckedToF64, MomentStats}; fn random_positive_finite_primitive_floats_helper( expected_values: &[T], expected_common_values: &[(T, usize)], expected_median: (T, Option), expected_moment_stats: MomentStats, ) { random_primitive_floats_helper_helper( random_positive_finite_primitive_floats::(EXAMPLE_SEED), expected_values, expected_common_values, expected_median, expected_moment_stats, ); } #[test] fn test_random_positive_finite_primitive_floats() { // f32 let values = &[ 9.5715654e26, 209.6476, 386935780.0, 7.965817e30, 0.00021030706, 0.0027270128, 3.4398167e-34, 2.3397111e14, 44567765000.0, 2.3479653e21, 0.00033502287, 2.4460542e-19, 0.0017637977, 7.956594e-26, 2.62625e-33, 0.059202384, 3.9310746e34, 1916542100000.0, 3.847343e14, 5.2843143e13, ]; let common_values = &[ (59.25553, 2), (68.23402, 2), (75936.53, 2), (9.581732, 2), (0.7711715, 2), (0.8694567, 2), (1.6738155, 2), (1168060.5, 2), (12.359466, 2), (146.89862, 2), ]; let sample_median = (1.3686414, Some(1.3686574)); let sample_moment_stats = MomentStats { mean: NiceFloat(2.0305910210122042e36), standard_deviation: NiceFloat(1.8908940416475047e37), skewness: NiceFloat(12.30495721768228), excess_kurtosis: NiceFloat(168.0100163146302), }; random_positive_finite_primitive_floats_helper::( values, common_values, sample_median, sample_moment_stats, ); // f64 let values = &[ 1.553103320279171e-146, 3.399767269777243e138, 6.920999672956352e-119, 7.798612728071752e-244, 1.7297528302435229e-274, 1.6730698009459568e253, 3.494622700146595e-115, 7.870553878200458e-50, 1.88707572126009e-10, 3.680784346523073e244, 2.2006770848831818e307, 3.0495236892779565e-279, 7.105167957384262e30, 7.68196442827874e21, 4.043761560817649e-187, 2.743276189070554e-146, 1.4322725127932769e140, 2.0686074901798122e-203, 7.761683804525804e-301, 5.6617484237282776e-21, ]; let common_values = &[ (66730.2435683, 1), (2.857475472056, 1), (2042187757.012, 1), (206.7039373431, 1), (2621701.092576, 1), (27.03018555735, 1), (3.025032765206, 1), (454348736.2729, 1), (5683730270.934, 1), (79306986.55539, 1), ]; let sample_median = (1.4868797963072014, Some(1.488082067196604)); let sample_moment_stats = MomentStats { mean: NiceFloat(1.3252967815615318e305), standard_deviation: NiceFloat(f64::INFINITY), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; random_positive_finite_primitive_floats_helper::( values, common_values, sample_median, sample_moment_stats, ); } malachite-base-0.4.16/tests/num/random/random_positive_primitive_floats.rs000064400000000000000000000075251046102023000252150ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::random_positive_primitive_floats; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::num::random::random_primitive_floats_helper_helper; use malachite_base::test_util::stats::moments::{CheckedToF64, MomentStats}; fn random_positive_primitive_floats_helper( expected_values: &[T], expected_common_values: &[(T, usize)], expected_median: (T, Option), expected_moment_stats: MomentStats, ) { random_primitive_floats_helper_helper( random_positive_primitive_floats::(EXAMPLE_SEED), expected_values, expected_common_values, expected_median, expected_moment_stats, ); } #[test] fn test_random_positive_primitive_floats() { // f32 let values = &[ 9.5715654e26, 209.6476, 386935780.0, 7.965817e30, 0.00021030706, 0.0027270128, 3.4398167e-34, 2.3397111e14, 44567765000.0, 2.3479653e21, 0.00033502287, 2.4460542e-19, 0.0017637977, 7.956594e-26, 2.62625e-33, 0.059202384, 3.9310746e34, 1916542100000.0, 3.847343e14, 5.2843143e13, ]; let common_values = &[ (59.25553, 2), (68.23402, 2), (75936.53, 2), (9.581732, 2), (0.7711715, 2), (0.8694567, 2), (1.6738155, 2), (1168060.5, 2), (12.359466, 2), (146.89862, 2), ]; let sample_median = (1.3686414, Some(1.3686574)); let sample_moment_stats = MomentStats { mean: NiceFloat(2.0305910210122042e36), standard_deviation: NiceFloat(1.8908940416475047e37), skewness: NiceFloat(12.30495721768228), excess_kurtosis: NiceFloat(168.0100163146302), }; random_positive_primitive_floats_helper::( values, common_values, sample_median, sample_moment_stats, ); // f64 let values = &[ 1.553103320279171e-146, 3.399767269777243e138, 6.920999672956352e-119, 7.798612728071752e-244, 1.7297528302435229e-274, 1.6730698009459568e253, 3.494622700146595e-115, 7.870553878200458e-50, 1.88707572126009e-10, 3.680784346523073e244, 2.2006770848831818e307, 3.0495236892779565e-279, 7.105167957384262e30, 7.68196442827874e21, 4.043761560817649e-187, 2.743276189070554e-146, 1.4322725127932769e140, 2.0686074901798122e-203, 7.761683804525804e-301, 5.6617484237282776e-21, ]; let common_values = &[ (66730.2435683, 1), (2.857475472056, 1), (2042187757.012, 1), (206.7039373431, 1), (2621701.092576, 1), (27.03018555735, 1), (3.025032765206, 1), (454348736.2729, 1), (5683730270.934, 1), (79306986.55539, 1), ]; let sample_median = (1.4868797963072014, Some(1.488082067196604)); let sample_moment_stats = MomentStats { mean: NiceFloat(1.3252967815615318e305), standard_deviation: NiceFloat(f64::INFINITY), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; random_positive_primitive_floats_helper::( values, common_values, sample_median, sample_moment_stats, ); } malachite-base-0.4.16/tests/num/random/random_positive_signeds.rs000064400000000000000000000217171046102023000232700ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::random_positive_signeds; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::moments::{ uniform_primitive_int_assertions, CheckedToF64, MomentStats, }; fn random_positive_signeds_helper( expected_values: &[T], expected_common_values: &[(T, usize)], expected_pop_median: (T, Option), expected_sample_median: (T, Option), expected_pop_moment_stats: MomentStats, expected_sample_moment_stats: MomentStats, ) { uniform_primitive_int_assertions( random_positive_signeds::(EXAMPLE_SEED), T::ONE, T::MAX, expected_values, expected_common_values, expected_pop_median, expected_sample_median, expected_pop_moment_stats, expected_sample_moment_stats, ); } #[test] fn test_random_positive_signeds() { // i8 let values = &[113, 94, 23, 98, 70, 92, 52, 84, 33, 47, 1, 113, 54, 10, 47, 17, 89, 92, 119, 66]; let common_values = &[ (2, 8156), (121, 8095), (48, 8062), (113, 8024), (78, 8003), (8, 7997), (91, 7995), (77, 7994), (50, 7990), (102, 7989), ]; let pop_median = (64, None); let sample_median = (64, None); let pop_moment_stats = MomentStats { mean: NiceFloat(64.0), standard_deviation: NiceFloat(36.66060555964672), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2001488095238095), }; let sample_moment_stats = MomentStats { mean: NiceFloat(63.982919000001765), standard_deviation: NiceFloat(36.67212767326611), skewness: NiceFloat(-0.0007589869063919588), excess_kurtosis: NiceFloat(-1.1997242130732357), }; random_positive_signeds_helper::( values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i16 let values = &[ 28529, 22667, 19345, 3398, 1402, 28100, 12052, 11409, 24046, 11152, 30158, 19629, 23709, 29262, 20999, 21707, 8622, 19470, 16708, 31300, ]; let common_values = &[ (12912, 55), (10381, 54), (18999, 54), (8262, 53), (16860, 52), (18853, 52), (26980, 52), (29418, 52), (1430, 51), (3511, 51), ]; let pop_median = (16384, None); let sample_median = (16394, None); let pop_moment_stats = MomentStats { mean: NiceFloat(16384.0), standard_deviation: NiceFloat(9459.018130863265), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2000000022353106), }; let sample_moment_stats = MomentStats { mean: NiceFloat(16388.51686199981), standard_deviation: NiceFloat(9454.07106153838), skewness: NiceFloat(-0.0012487208201804533), excess_kurtosis: NiceFloat(-1.1990539374536704), }; random_positive_signeds_helper::( values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i32 let values = &[ 1816522609, 1129424328, 1303937374, 1925780962, 962364894, 993179566, 132423026, 1465174948, 1361446689, 1660850464, 967812609, 546333625, 988229434, 365231847, 156905000, 1030913586, 2029143403, 1407130983, 1471083767, 1447050754, ]; let common_values = &[ (1028854, 2), (5270005, 2), (52436108, 2), (53442532, 2), (54049511, 2), (55679225, 2), (56850838, 2), (96093392, 2), (100688553, 2), (103402223, 2), ]; let pop_median = (1073741824, None); let sample_median = (1072627595, Some(1072629791)); let pop_moment_stats = MomentStats { mean: NiceFloat(1073741824.0), standard_deviation: NiceFloat(619925130.8378847), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2), }; let sample_moment_stats = MomentStats { mean: NiceFloat(1072577564.7313439), standard_deviation: NiceFloat(620056431.3063871), skewness: NiceFloat(0.0014601286400032305), excess_kurtosis: NiceFloat(-1.1999609793276922), }; random_positive_signeds_helper::( values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i64 let values = &[ 2425420277849911153, 6679477581841711279, 2839052228832469367, 969765657606132654, 511145952062627954, 8395344737368636720, 2894558908706954428, 3872377140940026972, 4461360302071018053, 8265671087366068090, 9205171493858792138, 440136107976613346, 5068356638012531024, 4934264084518118479, 1818371016611966298, 2429107481069952550, 6703623406340484388, 1574554890859127809, 117271882755911480, 4303959799021363928, ]; let common_values = &[ (3324105909387, 1), (3803613521411, 1), (5209780367047, 1), (6536744795656, 1), (20781229071796, 1), (25846957723851, 1), (38009592066251, 1), (42260644601025, 1), (48213785128580, 1), (51745785759707, 1), ]; let pop_median = (4611686018427387904, None); let sample_median = (4611643941266241783, Some(4611644928041858554)); let pop_moment_stats = MomentStats { mean: NiceFloat(4.611686018427388e18), standard_deviation: NiceFloat(2.6625581641570857e18), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2), }; let sample_moment_stats = MomentStats { mean: NiceFloat(4.611835802844851e18), standard_deviation: NiceFloat(2.6620357716239764e18), skewness: NiceFloat(-0.0011632136334031786), excess_kurtosis: NiceFloat(-1.1990763518455585), }; random_positive_signeds_helper::( values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i128 let values = &[ 146677898479391812904420101066401902449, 89542846454567859290543676436897304763, 104428938702835062297974834887506827292, 57633666711134371144783889328118789015, 57933954804712334978865086222806519588, 42662156461077357613672189956089449110, 120341622017198698000238591126723816325, 24101139564873918071809040180452920154, 103736512989781418566515148496075680557, 32809772643191914208019959002472965975, 108368929700948284627873319254722115143, 75471221947321674806749768444016968803, 22855029776201969245611509711160631693, 141239989761550750474583532371490947671, 6597717003000338260251854527757143775, 118127485834862173804991044383172101987, 34322302054094513880662232930594566845, 15046161600550609659323678646530441128, 64426056034886319779095794279543419785, 152274179269659595492344917098779277590, ]; let common_values = &[ (49706069066166082911282159414761, 1), (294249217877016568639819742131116, 1), (779571295345117968523381651468144, 1), (1028301047920525679733841423086654, 1), (1041495389520167619171132640545590, 1), (1161107238544942492727270602500750, 1), (1336346376891865515807867774335733, 1), (1493657440169244835704046060805058, 1), (1634887730516500612018549047947720, 1), (2085175602444743211488924039302279, 1), ]; let pop_median = (85070591730234615865843651857942052864, None); let sample_median = ( 84985358969888408674238551739287032693, Some(84985395712350170023498559520469041517), ); let pop_moment_stats = MomentStats { mean: NiceFloat(8.507059173023462e37), standard_deviation: NiceFloat(4.91155290355717e37), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2), }; let sample_moment_stats = MomentStats { mean: NiceFloat(8.501039971148385e37), standard_deviation: NiceFloat(4.910082612813726e37), skewness: NiceFloat(0.0016680470828691063), excess_kurtosis: NiceFloat(-1.199401614583414), }; random_positive_signeds_helper::( values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); } malachite-base-0.4.16/tests/num/random/random_positive_unsigneds.rs000064400000000000000000000220521046102023000236240ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::random_positive_unsigneds; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::moments::{ uniform_primitive_int_assertions, CheckedToF64, MomentStats, }; fn random_positive_unsigneds_helper( expected_values: &[T], expected_common_values: &[(T, usize)], expected_pop_median: (T, Option), expected_sample_median: (T, Option), expected_pop_moment_stats: MomentStats, expected_sample_moment_stats: MomentStats, ) { uniform_primitive_int_assertions( random_positive_unsigneds::(EXAMPLE_SEED), T::ONE, T::MAX, expected_values, expected_common_values, expected_pop_median, expected_sample_median, expected_pop_moment_stats, expected_sample_moment_stats, ); } #[test] fn test_random_positive_unsigneds() { // u8 let values = &[ 113, 239, 69, 108, 228, 210, 168, 161, 87, 32, 110, 83, 188, 34, 89, 238, 93, 200, 149, 115, ]; let common_values = &[ (214, 4112), (86, 4092), (166, 4063), (22, 4061), (126, 4061), (93, 4054), (55, 4053), (191, 4052), (36, 4049), (42, 4047), ]; let pop_median = (128, None); let sample_median = (128, None); let pop_moment_stats = MomentStats { mean: NiceFloat(128.0), standard_deviation: NiceFloat(73.6115932898254), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2000369094488188), }; let sample_moment_stats = MomentStats { mean: NiceFloat(127.95426100000232), standard_deviation: NiceFloat(73.62056563848995), skewness: NiceFloat(0.0005293443118466251), excess_kurtosis: NiceFloat(-1.2003369218920343), }; random_positive_unsigneds_helper::( values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // u16 let values = &[ 61297, 27717, 53988, 41384, 8279, 21358, 8892, 61017, 51293, 29589, 38333, 51673, 37493, 18463, 43415, 8622, 9735, 36945, 32584, 32881, ]; let common_values = &[ (27447, 34), (5606, 33), (5836, 33), (50513, 33), (64638, 33), (3582, 32), (19279, 32), (20588, 32), (27377, 32), (40163, 32), ]; let pop_median = (32768, None); let sample_median = (32764, None); let pop_moment_stats = MomentStats { mean: NiceFloat(32768.0), standard_deviation: NiceFloat(18918.32494346861), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2000000005588105), }; let sample_moment_stats = MomentStats { mean: NiceFloat(32769.087121000004), standard_deviation: NiceFloat(18919.668065423208), skewness: NiceFloat(0.00005282326597264531), excess_kurtosis: NiceFloat(-1.2002448370280603), }; random_positive_unsigneds_helper::( values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // u32 let values = &[ 1816522609, 2712195812, 1399726167, 3998819004, 1939195997, 3386480061, 1210028661, 565094807, 2421237255, 2154921800, 1999530985, 4087616012, 4147883634, 3097538087, 4234421608, 1164671716, 2394159346, 3174951407, 130045419, 2998491848, ]; let common_values = &[ (20095656, 2), (29107328, 2), (83328146, 2), (96543416, 2), (109257003, 2), (132308363, 2), (140940582, 2), (168698132, 2), (182460287, 2), (184573980, 2), ]; let pop_median = (2147483648, None); let sample_median = (2150296456, Some(2150302375)); let pop_moment_stats = MomentStats { mean: NiceFloat(2147483648.0), standard_deviation: NiceFloat(1239850261.9644444), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2), }; let sample_moment_stats = MomentStats { mean: NiceFloat(2148696150.6876254), standard_deviation: NiceFloat(1239453907.667566), skewness: NiceFloat(-0.0016842295222180032), excess_kurtosis: NiceFloat(-1.2007050556559806), }; random_positive_unsigneds_helper::( values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // u64 let values = &[ 11648792314704686961, 17174796846203019351, 14544821112490281053, 2427063716414460533, 9255318658858690055, 17556177092145474537, 13303824785927286386, 5002226935030621544, 13636312461848344818, 12878424424612648427, 13573831502926905428, 1513424385005459611, 2484972586252155822, 13072300245601619293, 4344958725064805398, 3252798961345668310, 10520651756201345771, 12379844438588545665, 6654913321726770291, 10505868200830584967, ]; let common_values = &[ (26914038281329, 1), (32553719576594, 1), (53892651831494, 1), (66354421349686, 1), (86226284907602, 1), (89837182726049, 1), (95691351770484, 1), (166741761063383, 1), (171574734234584, 1), (212518263578065, 1), ]; let pop_median = (9223372036854775808, None); let sample_median = (9228795451400314170, Some(9228799993322832549)); let pop_moment_stats = MomentStats { mean: NiceFloat(9.223372036854776e18), standard_deviation: NiceFloat(5.325116328314171e18), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2), }; let sample_moment_stats = MomentStats { mean: NiceFloat(9.223151767642118e18), standard_deviation: NiceFloat(5.323459825978695e18), skewness: NiceFloat(-0.0007960342667556958), excess_kurtosis: NiceFloat(-1.2005689675667335), }; random_positive_unsigneds_helper::( values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // u128 let values = &[ 316819081939861044636107404782286008177, 44771423227283929645271838218448652381, 323854305731529921104946490224673891847, 92274800069126412258941638023956901490, 237564999433439714567249110498266052850, 27917752305106984883503397141734686804, 241141377085303586778938998836817083310, 60003549963171791765607325839025294358, 228367822030979405869278360636891890411, 193799061972845222683167418018286926963, 186696208941218647968078823625188059421, 33018320828004690757952445968579104952, 24887066387352849554815992782110776358, 79085537771456044427857440036467563654, 19637669411666889498466854442215856999, 237587532320755783035907621678835821469, 254983837845695498020527357238650572551, 272337383097469374367899988789175779695, 105189689748742230503365861545668092951, 258427395460299182237257690021561141080, ]; let common_values = &[ (68570815139656170990830410045915, 1), (381682482227926990846204728028719, 1), (565207126752383841908924745713103, 1), (717866653939818807939025508430762, 1), (775173738585689418081884794376186, 1), (818497230601034032775791540657915, 1), (1224023028796761386468452212527255, 1), (1379103576141836593923341631562888, 1), (1765193876177447622538546939111747, 1), (2049979073093489039458791025727172, 1), ]; let pop_median = (170141183460469231731687303715884105728, None); let sample_median = ( 170151864710150847082485192587168481404, Some(170151925651660504506169909296979843840), ); let pop_moment_stats = MomentStats { mean: NiceFloat(1.7014118346046923e38), standard_deviation: NiceFloat(9.82310580711434e37), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2), }; let sample_moment_stats = MomentStats { mean: NiceFloat(1.702375633317502e38), standard_deviation: NiceFloat(9.815169783582294e37), skewness: NiceFloat(-0.0005571163134867303), excess_kurtosis: NiceFloat(-1.1992896928276262), }; random_positive_unsigneds_helper::( values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); } malachite-base-0.4.16/tests/num/random/random_primitive_float_inclusive_range.rs000064400000000000000000000640771046102023000263520ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::traits::NegativeInfinity; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::random_primitive_float_inclusive_range; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::num::random::random_primitive_floats_helper_helper; use malachite_base::test_util::stats::moments::{CheckedToF64, MomentStats}; use std::panic::catch_unwind; fn random_primitive_float_inclusive_range_helper( a: T, b: T, expected_values: &[T], expected_common_values: &[(T, usize)], expected_median: (T, Option), expected_moment_stats: MomentStats, ) { random_primitive_floats_helper_helper( random_primitive_float_inclusive_range::(EXAMPLE_SEED, a, b), expected_values, expected_common_values, expected_median, expected_moment_stats, ); } #[test] fn test_random_primitive_float_inclusive_range() { // f32, a = 1.0, b = 2.0 let values = &[ 1.5463697, 1.6846209, 1.6517982, 1.6963725, 1.246657, 1.0557153, 1.8866968, 1.8430634, 1.0973871, 1.4662611, 1.8181343, 1.8396878, 1.7092294, 1.6617042, 1.7495066, 1.1922526, 1.9193928, 1.1640857, 1.2869775, 1.7921972, ]; let common_values = &[ (1.262395, 4), (1.619045, 4), (1.942131, 4), (1.0062196, 4), (1.0075867, 4), (1.0664382, 4), (1.0932482, 4), (1.1049225, 4), (1.1625684, 4), (1.1672009, 4), ]; let sample_median = (1.4996792, Some(1.4996796)); let sample_moment_stats = MomentStats { mean: NiceFloat(1.4997834476890244), standard_deviation: NiceFloat(0.2887567306490316), skewness: NiceFloat(0.001395347389592521), excess_kurtosis: NiceFloat(-1.2017290675577252), }; random_primitive_float_inclusive_range_helper::( 1.0, 2.0, values, common_values, sample_median, sample_moment_stats, ); // f32, a = -0.1, b = 0.1 let values = &[ 5.664681e-11, 1.2492925e-35, 2.3242339e-29, 4.699183e-7, -2.8244436e-36, -2.264039e-37, -0.0000017299129, 1.40616e-23, 2.7418007e-27, 1.5418819e-16, -1.8473076e-36, -2.4935917e-21, -3.373897e-37, -7.5386525e-15, -2.2595721e-7, -8.293393e-39, 0.0025248893, 1.1819218e-25, 2.3384073e-23, 3.1464167e-24, ]; let common_values = &[ (0.02590246, 2), (-0.09233444, 2), (0.001610253, 2), (0.010553952, 2), (0.020663222, 2), (0.031000609, 2), (1.30495e-38, 2), (1.409154e-8, 2), (2.599722e-7, 2), (3.67508e-29, 2), ]; let sample_median = (-1.472737e-39, Some(-1.471169e-39)); let sample_moment_stats = MomentStats { mean: NiceFloat(-3.190292459186594e-6), standard_deviation: NiceFloat(0.007506907081695582), skewness: NiceFloat(-0.02559343794273501), excess_kurtosis: NiceFloat(84.97988219106435), }; random_primitive_float_inclusive_range_helper::( -0.1, 0.1, values, common_values, sample_median, sample_moment_stats, ); // f32, a = e, b = π let values = &[ 2.811021, 3.0798163, 2.8497639, 2.9021935, 3.0803769, 3.0796993, 3.088304, 2.872187, 2.8092258, 2.7708528, 3.0054183, 2.7851858, 2.745991, 2.9290476, 2.913056, 2.899723, 2.9672115, 2.875196, 3.01054, 3.0299006, ]; let common_values = &[ (2.7395, 7), (2.7335808, 7), (2.8363338, 7), (3.0879333, 7), (2.760186, 6), (2.799341, 6), (2.933202, 6), (2.978166, 6), (3.012332, 6), (3.034496, 6), ]; let sample_median = (2.9301434, Some(2.930144)); let sample_moment_stats = MomentStats { mean: NiceFloat(2.9300705904196347), standard_deviation: NiceFloat(0.12218018336191779), skewness: NiceFloat(-0.0024072138827345158), excess_kurtosis: NiceFloat(-1.1980037439170255), }; random_primitive_float_inclusive_range_helper::( core::f32::consts::E, core::f32::consts::PI, values, common_values, sample_median, sample_moment_stats, ); // f32, a = 100.0, b = 101.0 let values = &[ 100.96766, 100.552864, 100.684616, 100.34195, 100.725746, 100.24665, 100.79547, 100.21028, 100.7486, 100.09738, 100.360596, 100.518265, 100.83968, 100.47318, 100.16781, 100.6617, 100.48242, 100.192245, 100.84114, 100.095436, ]; let common_values = &[ (100.32666, 22), (100.33122, 22), (100.60651, 22), (100.29688, 21), (100.51455, 21), (100.75446, 21), (100.672554, 21), (100.863556, 21), (100.125, 20), (100.06987, 20), ]; let sample_median = (100.50014, None); let sample_moment_stats = MomentStats { mean: NiceFloat(100.5000247275421), standard_deviation: NiceFloat(0.2887172501103727), skewness: NiceFloat(0.0005303743867281354), excess_kurtosis: NiceFloat(-1.2019547226159832), }; random_primitive_float_inclusive_range_helper::( 100.0, 101.0, values, common_values, sample_median, sample_moment_stats, ); // f32, a = 1.0e38, b = Infinity let values = &[ 1.4647999e38, 3.1018272e38, 1.582411e38, 1.5544886e38, 1.5924082e38, 2.9619212e38, 2.8168304e38, 2.9816339e38, 1.2098325e38, 2.5528384e38, 1.0473973e38, 2.2168899e38, 1.8072246e38, 1.732986e38, 1.0828477e38, 1.3966511e38, 2.61352e38, 1.6959917e38, 1.727243e38, 2.8140436e38, ]; let common_values = &[ (1.223221e38, 4), (1.372136e38, 4), (1.0892582e38, 4), (1.4897022e38, 4), (1.5085965e38, 4), (1.5266252e38, 4), (1.8360457e38, 4), (2.5784374e38, 4), (2.6144523e38, 4), (2.7852527e38, 4), ]; let sample_median = (1.8507265e38, Some(1.8507311e38)); let sample_moment_stats = MomentStats { mean: NiceFloat(2.0095713198371904e38), standard_deviation: NiceFloat(7.129528670871142e37), skewness: NiceFloat(0.37808793164351623), excess_kurtosis: NiceFloat(-1.168840184381319), }; random_primitive_float_inclusive_range_helper::( 1.0e38, f32::INFINITY, values, common_values, sample_median, sample_moment_stats, ); // f32, a = -f32::MIN_POSITIVE_SUBNORMAL, b = f32::MIN_POSITIVE_SUBNORMAL let values = &[ -0.0, -1.0e-45, 1.0e-45, -0.0, 1.0e-45, 1.0e-45, 0.0, 1.0e-45, -0.0, -0.0, -1.0e-45, -0.0, -1.0e-45, 1.0e-45, 0.0, -0.0, -1.0e-45, -0.0, 0.0, 1.0e-45, ]; let common_values = &[(-0.0, 250314), (1.0e-45, 250015), (0.0, 249955), (-1.0e-45, 249716)]; let sample_median = (-0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(4.18988240833055e-49), standard_deviation: NiceFloat(9.90601474026171e-46), skewness: NiceFloat(-0.00042250825585668007), excess_kurtosis: NiceFloat(-0.9989230633891024), }; random_primitive_float_inclusive_range_helper::( -f32::MIN_POSITIVE_SUBNORMAL, f32::MIN_POSITIVE_SUBNORMAL, values, common_values, sample_median, sample_moment_stats, ); // f32, a = -0.0, b = f32::MIN_POSITIVE_SUBNORMAL let values = &[ 0.0, -0.0, 0.0, 1.0e-45, 0.0, 0.0, -0.0, 0.0, -0.0, 1.0e-45, 0.0, -0.0, 0.0, 1.0e-45, 1.0e-45, -0.0, 0.0, -0.0, 1.0e-45, 1.0e-45, ]; let common_values = &[(0.0, 333784), (1.0e-45, 333516), (-0.0, 332700)]; let sample_median = (0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(4.673554586277644e-46), standard_deviation: NiceFloat(6.606692048548519e-46), skewness: NiceFloat(0.7062350975867705), excess_kurtosis: NiceFloat(-1.5012319869365465), }; random_primitive_float_inclusive_range_helper::( -0.0, f32::MIN_POSITIVE_SUBNORMAL, values, common_values, sample_median, sample_moment_stats, ); // f32, a = 0.0, b = 0.0 let values = &[0.0; 20]; let common_values = &[(0.0, 1000000)]; let sample_median = (0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(0.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; random_primitive_float_inclusive_range_helper::( 0.0, 0.0, values, common_values, sample_median, sample_moment_stats, ); // f32, a = -f32::MIN_POSITIVE_SUBNORMAL, b = -f32::MIN_POSITIVE_SUBNORMAL let values = &[-1.0e-45; 20]; let common_values = &[(-1.0e-45, 1000000)]; let sample_median = (-1.0e-45, None); let sample_moment_stats = MomentStats { mean: NiceFloat(-1.401298464324817e-45), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; random_primitive_float_inclusive_range_helper::( -f32::MIN_POSITIVE_SUBNORMAL, -f32::MIN_POSITIVE_SUBNORMAL, values, common_values, sample_median, sample_moment_stats, ); // f32, a = -f32::MIN_POSITIVE_SUBNORMAL, b = 0.0 let values = &[ -0.0, -1.0e-45, -0.0, 0.0, -0.0, -0.0, -1.0e-45, -0.0, -1.0e-45, 0.0, -0.0, -1.0e-45, -0.0, 0.0, 0.0, -1.0e-45, -0.0, -1.0e-45, 0.0, 0.0, ]; let common_values = &[(-0.0, 333784), (0.0, 333516), (-1.0e-45, 332700)]; let sample_median = (-0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(-4.662119990808644e-46), standard_deviation: NiceFloat(6.602643154251322e-46), skewness: NiceFloat(-0.7101318209186737), excess_kurtosis: NiceFloat(-1.4957127969187527), }; random_primitive_float_inclusive_range_helper::( -f32::MIN_POSITIVE_SUBNORMAL, 0.0, values, common_values, sample_median, sample_moment_stats, ); // f32, a = -Infinity, b = Infinity let values = &[ -2.3484665e-27, 2.2879888e-18, -2.0729896e-12, 3.3600117e28, -9.0217234e-32, 3564911.0, -0.000013376945, -1.885545e18, 8.249455e-29, 2.2178013e-38, -6.306773e-34, 5.199601e31, 7.6132625e33, 0.00015323664, 9.4768183e36, -0.0005665587, 8.873326e-30, 0.09273134, -7.774831e33, 4.315623e-8, ]; let common_values = &[ (5.71262, 2), (780.036, 2), (224535.3, 2), (58.67172, 2), (73439.85, 2), (-58.01006, 2), (-66297.15, 2), (-66476.91, 2), (13200.071, 2), (3306.3635, 2), ]; let sample_median = (4.601794e-39, Some(4.606577e-39)); let sample_moment_stats = MomentStats { mean: NiceFloat(-1.871815997376882e34), standard_deviation: NiceFloat(1.8597574260800838e37), skewness: NiceFloat(-0.04588420234596291), excess_kurtosis: NiceFloat(174.30920609573673), }; random_primitive_float_inclusive_range_helper::( f32::NEGATIVE_INFINITY, f32::INFINITY, values, common_values, sample_median, sample_moment_stats, ); // f32, a = -0.0, b = -0.0 let values = &[-0.0; 20]; let common_values = &[(-0.0, 1000000)]; let sample_median = (-0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(0.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; random_primitive_float_inclusive_range_helper::( -0.0, -0.0, values, common_values, sample_median, sample_moment_stats, ); // f64, a = 1.0, b = 2.0 let values = &[ 1.5514873723431857, 1.027857700733222, 1.0138546387920868, 1.3122324563791183, 1.3405051829686652, 1.035872192413254, 1.1044047458079171, 1.1492076100807012, 1.6654435140088601, 1.0970321240173933, 1.7768534778894969, 1.7596944738316886, 1.4195592641558248, 1.6870312410839399, 1.6389477926482805, 1.7596601473487807, 1.5802838577448093, 1.6118733984422406, 1.6845629053029185, 1.7184068862055195, ]; let common_values = &[ (1.403773233, 1), (1.4279826281, 1), (1.00013172472, 1), (1.12691284792, 1), (1.18903919511, 1), (1.19748472183, 1), (1.22623118845, 1), (1.28755110409, 1), (1.29488660814, 1), (1.29653599853, 1), ]; let sample_median = (1.5009930608108493, Some(1.5009982675741425)); let sample_moment_stats = MomentStats { mean: NiceFloat(1.5004909167990677), standard_deviation: NiceFloat(0.288665614327161), skewness: NiceFloat(-0.0026087726173027), excess_kurtosis: NiceFloat(-1.199166529481062), }; random_primitive_float_inclusive_range_helper::( 1.0, 2.0, values, common_values, sample_median, sample_moment_stats, ); // f64, a = -0.1, b = 0.1 let values = &[ -7.283095678343042e-164, 4.085787276271492e-169, -1.6885972585325658e-191, -1.5059586906723643e-66, -6.637230143944272e-36, 2.0111059084569595e-54, -3.2171834547379634e-195, -1.4304898186595632e-260, -5.910214544689135e-300, 4.248352948466203e-63, -3.6882240870537675e-31, 8.12900376877632e-277, 8.630695763640745e-286, -2.7842211494385523e-123, -4.271131813514248e-164, 1.613930919542087e-167, -5.39182068994581e-107, -1.4532461060667818e-9, -1.9793582955127234e-289, 5.420373932282823e-196, ]; let common_values = &[ (5.62015686679e-6, 1), (-0.09576016351376, 1), (-3.9141428595e-60, 1), (-4.5355157777e-28, 1), (0.008342058495796, 1), (0.012335893098144, 1), (0.014079819535342, 1), (0.014718940078426, 1), (0.031741597598458, 1), (0.033991243007763, 1), ]; let sample_median = (1.566509212534917e-309, Some(1.56863192120459e-309)); let sample_moment_stats = MomentStats { mean: NiceFloat(4.4695816858634463e-7), standard_deviation: NiceFloat(0.002635102953882735), skewness: NiceFloat(0.27772415900587566), excess_kurtosis: NiceFloat(707.152044677798), }; random_primitive_float_inclusive_range_helper::( -0.1, 0.1, values, common_values, sample_median, sample_moment_stats, ); // f64, a = e, b = π let values = &[ 2.8212565731454164, 3.103466176726195, 2.888459041537496, 2.94833744629582, 2.9285662350147255, 3.059002590500268, 2.808432051804475, 3.077033595571352, 3.0898242789403123, 3.093937352570613, 2.7596383425151814, 3.1049928702292573, 2.7453107067232327, 3.0779370799622736, 2.9748071250720396, 2.927927166467895, 2.81511226878185, 2.928920013122519, 2.964625285981546, 3.046598518604858, ]; let common_values = &[ (2.7683806707, 1), (2.8058681766, 1), (2.8522842725, 1), (2.8873246989, 1), (2.72492950364, 1), (2.73164898148, 1), (2.73476073924, 1), (2.73598990929, 1), (2.73653142351, 1), (2.74563905301, 1), ]; let sample_median = (2.930132942011006, Some(2.9301336276615912)); let sample_moment_stats = MomentStats { mean: NiceFloat(2.929964069913902), standard_deviation: NiceFloat(0.12226749948876238), skewness: NiceFloat(-0.0013881669668324012), excess_kurtosis: NiceFloat(-1.2003731669148405), }; random_primitive_float_inclusive_range_helper::( core::f64::consts::E, core::f64::consts::PI, values, common_values, sample_median, sample_moment_stats, ); // f64, a = 100.0, b = 101.0 let values = &[ 100.60719315639041, 100.52293238466861, 100.39773606616421, 100.15849325452957, 100.62446491275823, 100.00756963969552, 100.87724201202582, 100.41761898323166, 100.61748356221035, 100.19203505270988, 100.00337267247278, 100.15603343751732, 100.23002386168925, 100.77135404787671, 100.23327285882462, 100.27432542366292, 100.63224218858957, 100.47879402977489, 100.50368945395086, 100.4540267175569, ]; let common_values = &[ (100.49174834, 1), (100.95678412, 1), (100.029622688, 1), (100.110761848, 1), (100.163351429, 1), (100.241016737, 1), (100.334091318, 1), (100.374320788, 1), (100.375142847, 1), (100.403842534, 1), ]; let sample_median = (100.49938135068814, Some(100.49938267498312)); let sample_moment_stats = MomentStats { mean: NiceFloat(100.49957670089151), standard_deviation: NiceFloat(0.28876054194108447), skewness: NiceFloat(0.00047268031818767473), excess_kurtosis: NiceFloat(-1.2008323763153763), }; random_primitive_float_inclusive_range_helper::( 100.0, 101.0, values, common_values, sample_median, sample_moment_stats, ); // f64, a = 1.0e38, b = Infinity let values = &[ 1.3219190533477493e200, 3.652437632585123e180, 2.0420353527516904e248, 2.505458962964126e276, 2.659899792371364e116, 2.7125386559147274e90, 9.536479965391043e185, 9.567216720381635e239, 5.16993041287954e245, 4.939547529284952e179, 3.1175116898205872e224, 1.7555281884088452e42, 5.429209768108731e84, 1.0447670959436904e299, 1.9580250342195754e105, 8.848423533619703e204, 3.4434065546244285e79, 3.6093218170205304e216, 8.464035133686624e293, 1.22423660941592e120, ]; let common_values = &[ (2.141438721e116, 1), (8.7676954155e86, 1), (1.28439118539e55, 1), (1.79171075176e53, 1), (2.10333657725e74, 1), (2.3236426209e231, 1), (2.95823857742e58, 1), (3.1078914828e141, 1), (3.38975629714e61, 1), (4.28790184556e74, 1), ]; let sample_median = (1.2523958970084127e173, Some(1.2542732495420994e173)); let sample_moment_stats = MomentStats { mean: NiceFloat(2.939399538027295e305), standard_deviation: NiceFloat(f64::INFINITY), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; random_primitive_float_inclusive_range_helper::( 1.0e38, f64::INFINITY, values, common_values, sample_median, sample_moment_stats, ); // f64, a = -f64::MIN_POSITIVE_SUBNORMAL, b = f64::MIN_POSITIVE_SUBNORMAL let values = &[ -0.0, -5.0e-324, 5.0e-324, -0.0, 5.0e-324, 5.0e-324, 0.0, 5.0e-324, -0.0, -0.0, -5.0e-324, -0.0, -5.0e-324, 5.0e-324, 0.0, -0.0, -5.0e-324, -0.0, 0.0, 5.0e-324, ]; let common_values = &[(-0.0, 250314), (5.0e-324, 250015), (0.0, 249955), (-5.0e-324, 249716)]; let sample_median = (-0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(0.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; random_primitive_float_inclusive_range_helper::( -f64::MIN_POSITIVE_SUBNORMAL, f64::MIN_POSITIVE_SUBNORMAL, values, common_values, sample_median, sample_moment_stats, ); // f64, a = -0.0, b = f64::MIN_POSITIVE_SUBNORMAL let values = &[ 0.0, -0.0, 0.0, 5.0e-324, 0.0, 0.0, -0.0, 0.0, -0.0, 5.0e-324, 0.0, -0.0, 0.0, 5.0e-324, 5.0e-324, -0.0, 0.0, -0.0, 5.0e-324, 5.0e-324, ]; let common_values = &[(0.0, 333784), (5.0e-324, 333516), (-0.0, 332700)]; let sample_median = (0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(0.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; random_primitive_float_inclusive_range_helper::( -0.0, f64::MIN_POSITIVE_SUBNORMAL, values, common_values, sample_median, sample_moment_stats, ); // f64, a = 0.0, b = 0.0 let values = &[0.0; 20]; let common_values = &[(0.0, 1000000)]; let sample_median = (0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(0.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; random_primitive_float_inclusive_range_helper::( 0.0, 0.0, values, common_values, sample_median, sample_moment_stats, ); // f64, a = -f64::MIN_POSITIVE_SUBNORMAL, b = -f64::MIN_POSITIVE_SUBNORMAL let values = &[-5.0e-324; 20]; let common_values = &[(-5.0e-324, 1000000)]; let sample_median = (-5.0e-324, None); let sample_moment_stats = MomentStats { mean: NiceFloat(-5.0e-324), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; random_primitive_float_inclusive_range_helper::( -f64::MIN_POSITIVE_SUBNORMAL, -f64::MIN_POSITIVE_SUBNORMAL, values, common_values, sample_median, sample_moment_stats, ); // f64, a = -f64::MIN_POSITIVE_SUBNORMAL, b = 0.0 let values = &[ -0.0, -5.0e-324, -0.0, 0.0, -0.0, -0.0, -5.0e-324, -0.0, -5.0e-324, 0.0, -0.0, -5.0e-324, -0.0, 0.0, 0.0, -5.0e-324, -0.0, -5.0e-324, 0.0, 0.0, ]; let common_values = &[(-0.0, 333784), (0.0, 333516), (-5.0e-324, 332700)]; let sample_median = (-0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(0.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; random_primitive_float_inclusive_range_helper::( -f64::MIN_POSITIVE_SUBNORMAL, 0.0, values, common_values, sample_median, sample_moment_stats, ); // f64, a = -Infinity, b = Infinity let values = &[ 3.106206640558341e-146, 7.268713316268921e223, 1.1685126708702852e48, -1.0824685183946236e146, 3.114605160661583e-306, 2.2453015573637674e249, 1.2548860979388685e-35, -8.287939157477947e-27, 2.1255041535787165e-13, 4.815129234795048e-64, 1.3850402674408148e-17, -1.253571770758962e207, -1.4941028004491906e142, 4.366611961454907e-51, -7.063699168119985e17, -7.062565582436957e90, 1.1662950933663382e-221, 2.1976577668343592e-97, -2.8212944266870196e-137, 1.2250916338748408e-222, ]; let common_values = &[ (-9967188.16722, 1), (1808.830612999, 1), (32578528203.69, 1), (5643444.695113, 1), (812845035127.8, 1), (-13741970740.45, 1), (-1434325.082519, 1), (-33781527.93352, 1), (-374012916597.5, 1), (-46629353341.91, 1), ]; let sample_median = (2.772306592172272e-308, Some(2.7820731194979217e-308)); let sample_moment_stats = MomentStats { mean: NiceFloat(7.922018643581038e303), standard_deviation: NiceFloat(f64::INFINITY), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; random_primitive_float_inclusive_range_helper::( f64::NEGATIVE_INFINITY, f64::INFINITY, values, common_values, sample_median, sample_moment_stats, ); // f64, a = -0.0, b = 0.0 let values = &[ 0.0, -0.0, -0.0, -0.0, 0.0, 0.0, 0.0, -0.0, 0.0, 0.0, 0.0, 0.0, -0.0, 0.0, 0.0, 0.0, 0.0, -0.0, 0.0, -0.0, ]; let common_values = &[(0.0, 500473), (-0.0, 499527)]; let sample_median = (0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(0.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; random_primitive_float_inclusive_range_helper::( -0.0, 0.0, values, common_values, sample_median, sample_moment_stats, ); } fn random_primitive_float_inclusive_range_fail_helper() { assert_panic!(random_primitive_float_inclusive_range::( EXAMPLE_SEED, T::ONE, T::ZERO )); assert_panic!(random_primitive_float_inclusive_range::( EXAMPLE_SEED, T::ONE, T::NAN )); } #[test] fn random_primitive_float_inclusive_range_fail() { apply_fn_to_primitive_floats!(random_primitive_float_inclusive_range_fail_helper); } malachite-base-0.4.16/tests/num/random/random_primitive_float_range.rs000064400000000000000000000627611046102023000242670ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::traits::NegativeInfinity; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::random_primitive_float_range; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::num::random::random_primitive_floats_helper_helper; use malachite_base::test_util::stats::moments::{CheckedToF64, MomentStats}; use std::panic::catch_unwind; fn random_primitive_float_range_helper( a: T, b: T, expected_values: &[T], expected_common_values: &[(T, usize)], expected_median: (T, Option), expected_moment_stats: MomentStats, ) { random_primitive_floats_helper_helper( random_primitive_float_range::(EXAMPLE_SEED, a, b), expected_values, expected_common_values, expected_median, expected_moment_stats, ); } #[test] fn test_random_primitive_float_range() { // f32, a = 1.0, b = 2.0 let values = &[ 1.5463697, 1.2951918, 1.7384838, 1.2143862, 1.1419607, 1.0917295, 1.7257521, 1.849941, 1.1442195, 1.363777, 1.052571, 1.0717841, 1.9104315, 1.3754328, 1.590667, 1.0705026, 1.8980603, 1.8630176, 1.0212592, 1.3380667, ]; let common_values = &[ (1.9376882, 5), (1.012385, 4), (1.439915, 4), (1.709473, 4), (1.754993, 4), (1.944844, 4), (1.971242, 4), (1.978845, 4), (1.0289025, 4), (1.0466498, 4), ]; let sample_median = (1.499921, None); let sample_moment_stats = MomentStats { mean: NiceFloat(1.49979057649457), standard_deviation: NiceFloat(0.2887387766808365), skewness: NiceFloat(0.0002622267624830283), excess_kurtosis: NiceFloat(-1.1997935828388204), }; random_primitive_float_range_helper::( 1.0, 2.0, values, common_values, sample_median, sample_moment_stats, ); // f32, a = -0.1, b = 0.1 let values = &[ 5.664681e-11, 1.2492925e-35, 2.3242339e-29, 4.699183e-7, -2.8244436e-36, -2.264039e-37, -0.0000017299129, 1.40616e-23, 2.7418007e-27, 1.5418819e-16, -1.8473076e-36, -2.4935917e-21, -3.373897e-37, -7.5386525e-15, -2.2595721e-7, -8.293393e-39, 0.0025248893, 1.1819218e-25, 2.3384073e-23, 3.1464167e-24, ]; let common_values = &[ (0.02590246, 2), (-0.09233444, 2), (0.001610253, 2), (0.010553952, 2), (0.020663222, 2), (0.031000609, 2), (1.30495e-38, 2), (1.409154e-8, 2), (2.599722e-7, 2), (3.67508e-29, 2), ]; let sample_median = (-1.472737e-39, Some(-1.471169e-39)); let sample_moment_stats = MomentStats { mean: NiceFloat(-3.190292459186594e-6), standard_deviation: NiceFloat(0.007506907081695582), skewness: NiceFloat(-0.02559343794273501), excess_kurtosis: NiceFloat(84.97988219106435), }; random_primitive_float_range_helper::( -0.1, 0.1, values, common_values, sample_median, sample_moment_stats, ); // f32, a = e, b = π let values = &[ 2.811021, 3.0798163, 2.8497639, 2.9021935, 3.0803769, 3.0796993, 3.088304, 2.872187, 2.8092258, 2.7708528, 3.0054183, 2.7851858, 2.745991, 2.9290476, 2.913056, 2.899723, 2.9672115, 2.875196, 3.01054, 3.0299006, ]; let common_values = &[ (2.7395, 7), (2.7335808, 7), (2.8363338, 7), (3.0879333, 7), (2.760186, 6), (2.799341, 6), (2.933202, 6), (2.978166, 6), (3.012332, 6), (3.034496, 6), ]; let sample_median = (2.9301434, Some(2.930144)); let sample_moment_stats = MomentStats { mean: NiceFloat(2.9300705904196347), standard_deviation: NiceFloat(0.12218018336191779), skewness: NiceFloat(-0.0024072138827345158), excess_kurtosis: NiceFloat(-1.1980037439170255), }; random_primitive_float_range_helper::( core::f32::consts::E, core::f32::consts::PI, values, common_values, sample_median, sample_moment_stats, ); // f32, a = 100.0, b = 101.0 let values = &[ 100.96766, 100.10573, 100.102974, 100.47697, 100.441444, 100.94259, 100.696365, 100.36691, 100.79254, 100.435005, 100.23124, 100.153755, 100.25385, 100.64986, 100.26314, 100.148544, 100.28187, 100.3743, 100.18771, 100.901344, ]; let common_values = &[ (100.15877, 24), (100.081535, 22), (100.26679, 21), (100.56587, 21), (100.894196, 21), (100.3593, 20), (100.4054, 20), (100.30979, 20), (100.45853, 20), (100.49529, 20), ]; let sample_median = (100.50088, None); let sample_moment_stats = MomentStats { mean: NiceFloat(100.50054111846543), standard_deviation: NiceFloat(0.2888116297082562), skewness: NiceFloat(-0.003221278138738849), excess_kurtosis: NiceFloat(-1.2016989304148467), }; random_primitive_float_range_helper::( 100.0, 101.0, values, common_values, sample_median, sample_moment_stats, ); // f32, a = 1.0e38, b = Infinity let values = &[ 1.4647999e38, 3.1018272e38, 1.582411e38, 1.5544886e38, 1.5924082e38, 2.9619212e38, 2.8168304e38, 2.9816339e38, 1.2098325e38, 2.5528384e38, 1.0473973e38, 2.2168899e38, 1.8072246e38, 1.732986e38, 1.0828477e38, 1.3966511e38, 2.61352e38, 1.6959917e38, 1.727243e38, 2.8140436e38, ]; let common_values = &[ (1.223221e38, 4), (1.372136e38, 4), (1.0892582e38, 4), (1.4897022e38, 4), (1.5085965e38, 4), (1.5266252e38, 4), (1.8360457e38, 4), (2.5784374e38, 4), (2.6144523e38, 4), (2.7852527e38, 4), ]; let sample_median = (1.8507265e38, Some(1.8507311e38)); let sample_moment_stats = MomentStats { mean: NiceFloat(2.0095713198371904e38), standard_deviation: NiceFloat(7.129528670871142e37), skewness: NiceFloat(0.37808793164351623), excess_kurtosis: NiceFloat(-1.168840184381319), }; random_primitive_float_range_helper::( 1.0e38, f32::INFINITY, values, common_values, sample_median, sample_moment_stats, ); // f32, a = -f32::MIN_POSITIVE_SUBNORMAL, b = f32::MIN_POSITIVE_SUBNORMAL let values = &[ -0.0, -1.0e-45, -0.0, 0.0, -0.0, -0.0, -1.0e-45, -0.0, -1.0e-45, 0.0, -0.0, -1.0e-45, -0.0, 0.0, 0.0, -1.0e-45, -0.0, -1.0e-45, 0.0, 0.0, ]; let common_values = &[(-0.0, 333784), (0.0, 333516), (-1.0e-45, 332700)]; let sample_median = (-0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(-4.662119990808644e-46), standard_deviation: NiceFloat(6.602643154251322e-46), skewness: NiceFloat(-0.7101318209186737), excess_kurtosis: NiceFloat(-1.4957127969187527), }; random_primitive_float_range_helper::( -f32::MIN_POSITIVE_SUBNORMAL, f32::MIN_POSITIVE_SUBNORMAL, values, common_values, sample_median, sample_moment_stats, ); // f32, a = -0.0, b = f32::MIN_POSITIVE_SUBNORMAL let values = &[ 0.0, -0.0, -0.0, -0.0, 0.0, 0.0, 0.0, -0.0, 0.0, 0.0, 0.0, 0.0, -0.0, 0.0, 0.0, 0.0, 0.0, -0.0, 0.0, -0.0, ]; let common_values = &[(0.0, 500473), (-0.0, 499527)]; let sample_median = (0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(0.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; random_primitive_float_range_helper::( -0.0, f32::MIN_POSITIVE_SUBNORMAL, values, common_values, sample_median, sample_moment_stats, ); // f32, a = 0.0, b = f32::MIN_POSITIVE_SUBNORMAL let values = &[0.0; 20]; let common_values = &[(0.0, 1000000)]; let sample_median = (0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(0.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; random_primitive_float_range_helper::( 0.0, f32::MIN_POSITIVE_SUBNORMAL, values, common_values, sample_median, sample_moment_stats, ); // f32, a = -f32::MIN_POSITIVE_SUBNORMAL, b = -0.0 let values = &[-1.0e-45; 20]; let common_values = &[(-1.0e-45, 1000000)]; let sample_median = (-1.0e-45, None); let sample_moment_stats = MomentStats { mean: NiceFloat(-1.401298464324817e-45), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; random_primitive_float_range_helper::( -f32::MIN_POSITIVE_SUBNORMAL, -0.0, values, common_values, sample_median, sample_moment_stats, ); // f32, a = -f32::MIN_POSITIVE_SUBNORMAL, b = 0.0 let values = &[ -0.0, -1.0e-45, -1.0e-45, -1.0e-45, -0.0, -0.0, -0.0, -1.0e-45, -0.0, -0.0, -0.0, -0.0, -1.0e-45, -0.0, -0.0, -0.0, -0.0, -1.0e-45, -0.0, -1.0e-45, ]; let common_values = &[(-0.0, 500473), (-1.0e-45, 499527)]; let sample_median = (-0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(-6.9998641798878095e-46), standard_deviation: NiceFloat(7.006492689759787e-46), skewness: NiceFloat(-0.0018920008465908337), excess_kurtosis: NiceFloat(-1.9999964203328955), }; random_primitive_float_range_helper::( -f32::MIN_POSITIVE_SUBNORMAL, 0.0, values, common_values, sample_median, sample_moment_stats, ); // f32, a = -Infinity, b = Infinity let values = &[ -2.3484665e-27, 2.2879888e-18, -2.0729896e-12, 3.3600117e28, -9.0217234e-32, 3564911.0, -0.000013376945, -1.885545e18, 8.249455e-29, 2.2178013e-38, -6.306773e-34, 5.199601e31, 7.6132625e33, 0.00015323664, 9.4768183e36, -0.0005665587, 8.873326e-30, 0.09273134, -7.774831e33, 4.315623e-8, ]; let common_values = &[ (5.71262, 2), (780.036, 2), (224535.3, 2), (58.67172, 2), (73439.85, 2), (-58.01006, 2), (-66297.15, 2), (-66476.91, 2), (13200.071, 2), (3306.3635, 2), ]; let sample_median = (4.601794e-39, Some(4.606577e-39)); let sample_moment_stats = MomentStats { mean: NiceFloat(-1.871815997376882e34), standard_deviation: NiceFloat(1.8597574260800838e37), skewness: NiceFloat(-0.04588420234596291), excess_kurtosis: NiceFloat(174.30920609573673), }; random_primitive_float_range_helper::( f32::NEGATIVE_INFINITY, f32::INFINITY, values, common_values, sample_median, sample_moment_stats, ); // f32, a = -0.0, b = 0.0 let values = &[-0.0; 20]; let common_values = &[(-0.0, 1000000)]; let sample_median = (-0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(0.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; random_primitive_float_range_helper::( -0.0, 0.0, values, common_values, sample_median, sample_moment_stats, ); // f64, a = 1.0, b = 2.0 let values = &[ 1.5514873723431857, 1.7356480435333936, 1.2240680379087014, 1.5721098095143498, 1.445723211731554, 1.443348441346778, 1.128043347677334, 1.9657544165271619, 1.259133073045527, 1.9463717627559034, 1.827615676661706, 1.3546147198266414, 1.3547277462886724, 1.6644379935168552, 1.7300004987549573, 1.1347106338290753, 1.6337434960012935, 1.9398684976828995, 1.5480087631774717, 1.5114010060819247, ]; let common_values = &[ (1.3443697926, 1), (1.3820769412, 1), (1.4136496448, 1), (1.05230401048, 1), (1.06345642396, 1), (1.08636222403, 1), (1.08890959097, 1), (1.10364420294, 1), (1.17100333598, 1), (1.21003284406, 1), ]; let sample_median = (1.4997587655631748, Some(1.4997590736389839)); let sample_moment_stats = MomentStats { mean: NiceFloat(1.5002317198585347), standard_deviation: NiceFloat(0.2886284765385832), skewness: NiceFloat(0.0005691088300059665), excess_kurtosis: NiceFloat(-1.1997562526471726), }; random_primitive_float_range_helper::( 1.0, 2.0, values, common_values, sample_median, sample_moment_stats, ); // f64, a = -0.1, b = 0.1 let values = &[ -7.283095678343042e-164, 4.085787276271492e-169, -1.6885972585325658e-191, -1.5059586906723643e-66, -6.637230143944272e-36, 2.0111059084569595e-54, -3.2171834547379634e-195, -1.4304898186595632e-260, -5.910214544689135e-300, 4.248352948466203e-63, -3.6882240870537675e-31, 8.12900376877632e-277, 8.630695763640745e-286, -2.7842211494385523e-123, -4.271131813514248e-164, 1.613930919542087e-167, -5.39182068994581e-107, -1.4532461060667818e-9, -1.9793582955127234e-289, 5.420373932282823e-196, ]; let common_values = &[ (5.62015686679e-6, 1), (-0.09576016351376, 1), (-3.9141428595e-60, 1), (-4.5355157777e-28, 1), (0.008342058495796, 1), (0.012335893098144, 1), (0.014079819535342, 1), (0.014718940078426, 1), (0.031741597598458, 1), (0.033991243007763, 1), ]; let sample_median = (1.566509212534917e-309, Some(1.56863192120459e-309)); let sample_moment_stats = MomentStats { mean: NiceFloat(4.4695816858634463e-7), standard_deviation: NiceFloat(0.002635102953882735), skewness: NiceFloat(0.27772415900587566), excess_kurtosis: NiceFloat(707.152044677798), }; random_primitive_float_range_helper::( -0.1, 0.1, values, common_values, sample_median, sample_moment_stats, ); // f64, a = e, b = π let values = &[ 2.8212565731454164, 3.103466176726195, 2.888459041537496, 2.94833744629582, 2.9285662350147255, 3.059002590500268, 2.808432051804475, 3.077033595571352, 3.0898242789403123, 3.093937352570613, 2.7596383425151814, 3.1049928702292573, 2.7453107067232327, 3.0779370799622736, 2.9748071250720396, 2.927927166467895, 2.81511226878185, 2.928920013122519, 2.964625285981546, 3.046598518604858, ]; let common_values = &[ (2.7683806707, 1), (2.8058681766, 1), (2.8522842725, 1), (2.8873246989, 1), (2.72492950364, 1), (2.73164898148, 1), (2.73476073924, 1), (2.73598990929, 1), (2.73653142351, 1), (2.74563905301, 1), ]; let sample_median = (2.930132942011006, Some(2.9301336276615912)); let sample_moment_stats = MomentStats { mean: NiceFloat(2.929964069913902), standard_deviation: NiceFloat(0.12226749948876238), skewness: NiceFloat(-0.0013881669668324012), excess_kurtosis: NiceFloat(-1.2003731669148405), }; random_primitive_float_range_helper::( core::f64::consts::E, core::f64::consts::PI, values, common_values, sample_median, sample_moment_stats, ); // f64, a = 100.0, b = 101.0 let values = &[ 100.29519182996388, 100.21438631278083, 100.09172953867444, 100.84994110175992, 100.36377705862755, 100.07178414494646, 100.37543295746225, 100.07050270922983, 100.86301766610865, 100.33806669965496, 100.35496099272225, 100.93577122524063, 100.00524419289253, 100.29363379918549, 100.98421354539467, 100.68228296091216, 100.93250012468873, 100.1553701412652, 100.95333990532461, 100.2218641465098, ]; let common_values = &[ (100.10137554, 1), (100.34387327, 1), (100.223865218, 1), (100.237336607, 1), (100.241016737, 1), (100.358275298, 1), (100.490668361, 1), (100.563824325, 1), (100.567992111, 1), (100.619353436, 1), ]; let sample_median = (100.49999381186375, Some(100.49999461609349)); let sample_moment_stats = MomentStats { mean: NiceFloat(100.4998603968099), standard_deviation: NiceFloat(0.28878031747138194), skewness: NiceFloat(-0.00018856944159801264), excess_kurtosis: NiceFloat(-1.2006169795569301), }; random_primitive_float_range_helper::( 100.0, 101.0, values, common_values, sample_median, sample_moment_stats, ); // f64, a = 1.0e38, b = Infinity let values = &[ 1.3219190533477493e200, 3.652437632585123e180, 2.0420353527516904e248, 2.505458962964126e276, 2.659899792371364e116, 2.7125386559147274e90, 9.536479965391043e185, 9.567216720381635e239, 5.16993041287954e245, 4.939547529284952e179, 3.1175116898205872e224, 1.7555281884088452e42, 5.429209768108731e84, 1.0447670959436904e299, 1.9580250342195754e105, 8.848423533619703e204, 3.4434065546244285e79, 3.6093218170205304e216, 8.464035133686624e293, 1.22423660941592e120, ]; let common_values = &[ (2.141438721e116, 1), (8.7676954155e86, 1), (1.28439118539e55, 1), (1.79171075176e53, 1), (2.10333657725e74, 1), (2.3236426209e231, 1), (2.95823857742e58, 1), (3.1078914828e141, 1), (3.38975629714e61, 1), (4.28790184556e74, 1), ]; let sample_median = (1.2523958970084127e173, Some(1.2542732495420994e173)); let sample_moment_stats = MomentStats { mean: NiceFloat(2.939399538027295e305), standard_deviation: NiceFloat(f64::INFINITY), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; random_primitive_float_range_helper::( 1.0e38, f64::INFINITY, values, common_values, sample_median, sample_moment_stats, ); // f64, a = -f64::MIN_POSITIVE_SUBNORMAL, b = f64::MIN_POSITIVE_SUBNORMAL let values = &[ -0.0, -5.0e-324, -0.0, 0.0, -0.0, -0.0, -5.0e-324, -0.0, -5.0e-324, 0.0, -0.0, -5.0e-324, -0.0, 0.0, 0.0, -5.0e-324, -0.0, -5.0e-324, 0.0, 0.0, ]; let common_values = &[(-0.0, 333784), (0.0, 333516), (-5.0e-324, 332700)]; let sample_median = (-0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(0.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; random_primitive_float_range_helper::( -f64::MIN_POSITIVE_SUBNORMAL, f64::MIN_POSITIVE_SUBNORMAL, values, common_values, sample_median, sample_moment_stats, ); // f64, a = -0.0, b = f64::MIN_POSITIVE_SUBNORMAL let values = &[ 0.0, -0.0, -0.0, -0.0, 0.0, 0.0, 0.0, -0.0, 0.0, 0.0, 0.0, 0.0, -0.0, 0.0, 0.0, 0.0, 0.0, -0.0, 0.0, -0.0, ]; let common_values = &[(0.0, 500473), (-0.0, 499527)]; let sample_median = (0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(0.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; random_primitive_float_range_helper::( -0.0, f64::MIN_POSITIVE_SUBNORMAL, values, common_values, sample_median, sample_moment_stats, ); // f64, a = 0.0, b = f64::MIN_POSITIVE_SUBNORMAL let values = &[0.0; 20]; let common_values = &[(0.0, 1000000)]; let sample_median = (0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(0.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; random_primitive_float_range_helper::( 0.0, f64::MIN_POSITIVE_SUBNORMAL, values, common_values, sample_median, sample_moment_stats, ); // f64, a = -f64::MIN_POSITIVE_SUBNORMAL, b = -0.0 let values = &[-5.0e-324; 20]; let common_values = &[(-5.0e-324, 1000000)]; let sample_median = (-5.0e-324, None); let sample_moment_stats = MomentStats { mean: NiceFloat(-5.0e-324), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; random_primitive_float_range_helper::( -f64::MIN_POSITIVE_SUBNORMAL, -0.0, values, common_values, sample_median, sample_moment_stats, ); // f64, a = -f64::MIN_POSITIVE_SUBNORMAL, b = 0.0 let values = &[ -0.0, -5.0e-324, -5.0e-324, -5.0e-324, -0.0, -0.0, -0.0, -5.0e-324, -0.0, -0.0, -0.0, -0.0, -5.0e-324, -0.0, -0.0, -0.0, -0.0, -5.0e-324, -0.0, -5.0e-324, ]; let common_values = &[(-0.0, 500473), (-5.0e-324, 499527)]; let sample_median = (-0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(0.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; random_primitive_float_range_helper::( -f64::MIN_POSITIVE_SUBNORMAL, 0.0, values, common_values, sample_median, sample_moment_stats, ); // f64, a = -Infinity, b = Infinity let values = &[ 3.106206640558341e-146, 7.268713316268921e223, 1.1685126708702852e48, -1.0824685183946236e146, 3.114605160661583e-306, 2.2453015573637674e249, 1.2548860979388685e-35, -8.287939157477947e-27, 2.1255041535787165e-13, 4.815129234795048e-64, 1.3850402674408148e-17, -1.253571770758962e207, -1.4941028004491906e142, 4.366611961454907e-51, -7.063699168119985e17, -7.062565582436957e90, 1.1662950933663382e-221, 2.1976577668343592e-97, -2.8212944266870196e-137, 1.2250916338748408e-222, ]; let common_values = &[ (-9967188.16722, 1), (1808.830612999, 1), (32578528203.69, 1), (5643444.695113, 1), (812845035127.8, 1), (-13741970740.45, 1), (-1434325.082519, 1), (-33781527.93352, 1), (-374012916597.5, 1), (-46629353341.91, 1), ]; let sample_median = (2.772306592172272e-308, Some(2.7820731194979217e-308)); let sample_moment_stats = MomentStats { mean: NiceFloat(7.922018643581038e303), standard_deviation: NiceFloat(f64::INFINITY), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; random_primitive_float_range_helper::( f64::NEGATIVE_INFINITY, f64::INFINITY, values, common_values, sample_median, sample_moment_stats, ); // f64, a = -0.0, b = 0.0 let values = &[-0.0; 20]; let common_values = &[(-0.0, 1000000)]; let sample_median = (-0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(0.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; random_primitive_float_range_helper::( -0.0, 0.0, values, common_values, sample_median, sample_moment_stats, ); } fn random_primitive_float_range_fail_helper() { assert_panic!(random_primitive_float_range::( EXAMPLE_SEED, T::ZERO, T::ZERO )); assert_panic!(random_primitive_float_range::( EXAMPLE_SEED, T::ONE, T::ZERO )); assert_panic!(random_primitive_float_range::( EXAMPLE_SEED, T::ONE, T::NAN )); } #[test] fn random_primitive_float_range_fail() { apply_fn_to_primitive_floats!(random_primitive_float_range_fail_helper); } malachite-base-0.4.16/tests/num/random/random_primitive_floats.rs000064400000000000000000000075041046102023000232700ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::random_primitive_floats; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::num::random::random_primitive_floats_helper_helper; use malachite_base::test_util::stats::moments::{CheckedToF64, MomentStats}; fn random_primitive_floats_helper( expected_values: &[T], expected_common_values: &[(T, usize)], expected_median: (T, Option), expected_moment_stats: MomentStats, ) { random_primitive_floats_helper_helper( random_primitive_floats::(EXAMPLE_SEED), expected_values, expected_common_values, expected_median, expected_moment_stats, ); } #[test] fn test_random_primitive_floats() { // f32 let values = &[ -2.3484665e-27, 2.2879888e-18, -2.0729896e-12, 3.3600117e28, -9.0217234e-32, 3564911.0, -0.000013376945, -1.885545e18, 8.249455e-29, 2.2178013e-38, -6.306773e-34, 5.199601e31, 7.6132625e33, 0.00015323664, 9.4768183e36, -0.0005665587, 8.873326e-30, 0.09273134, -7.774831e33, 4.315623e-8, ]; let common_values = &[ (5.71262, 2), (780.036, 2), (224535.3, 2), (58.67172, 2), (73439.85, 2), (-58.01006, 2), (-66297.15, 2), (-66476.91, 2), (13200.071, 2), (3306.3635, 2), ]; let sample_median = (4.601794e-39, Some(4.606577e-39)); let sample_moment_stats = MomentStats { mean: NiceFloat(-1.871815997376882e34), standard_deviation: NiceFloat(1.8597574260800838e37), skewness: NiceFloat(-0.04588420234596291), excess_kurtosis: NiceFloat(174.30920609573673), }; random_primitive_floats_helper::( values, common_values, sample_median, sample_moment_stats, ); // f64 let values = &[ 3.106206640558341e-146, 7.268713316268921e223, 1.1685126708702852e48, -1.0824685183946236e146, 3.114605160661583e-306, 2.2453015573637674e249, 1.2548860979388685e-35, -8.287939157477947e-27, 2.1255041535787165e-13, 4.815129234795048e-64, 1.3850402674408148e-17, -1.253571770758962e207, -1.4941028004491906e142, 4.366611961454907e-51, -7.063699168119985e17, -7.062565582436957e90, 1.1662950933663382e-221, 2.1976577668343592e-97, -2.8212944266870196e-137, 1.2250916338748408e-222, ]; let common_values = &[ (-9967188.16722, 1), (1808.830612999, 1), (32578528203.69, 1), (5643444.695113, 1), (812845035127.8, 1), (-13741970740.45, 1), (-1434325.082519, 1), (-33781527.93352, 1), (-374012916597.5, 1), (-46629353341.91, 1), ]; let sample_median = (2.772306592172272e-308, Some(2.7820731194979217e-308)); let sample_moment_stats = MomentStats { mean: NiceFloat(7.922018643581038e303), standard_deviation: NiceFloat(f64::INFINITY), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; random_primitive_floats_helper::( values, common_values, sample_median, sample_moment_stats, ); } malachite-base-0.4.16/tests/num/random/random_primitive_ints.rs000064400000000000000000000414451046102023000227570ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::random_primitive_ints; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::moments::{ uniform_primitive_int_assertions, CheckedToF64, MomentStats, }; fn random_primitive_ints_helper( expected_values: &[T], expected_common_values: &[(T, usize)], expected_pop_median: (T, Option), expected_sample_median: (T, Option), expected_pop_moment_stats: MomentStats, expected_sample_moment_stats: MomentStats, ) { uniform_primitive_int_assertions( random_primitive_ints(EXAMPLE_SEED), T::MIN, T::MAX, expected_values, expected_common_values, expected_pop_median, expected_sample_median, expected_pop_moment_stats, expected_sample_moment_stats, ); } #[test] fn test_random_primitive_ints() { // u8 let values = &[ 113, 239, 69, 108, 228, 210, 168, 161, 87, 32, 110, 83, 188, 34, 89, 238, 93, 200, 149, 115, ]; let common_values = &[ (214, 4097), (86, 4078), (166, 4049), (22, 4048), (126, 4047), (55, 4040), (93, 4037), (191, 4036), (36, 4035), (42, 4032), ]; let pop_median = (127, Some(128)); let sample_median = (127, None); let pop_moment_stats = MomentStats { mean: NiceFloat(127.5), standard_deviation: NiceFloat(73.90027063549903), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.200036621652552), }; let sample_moment_stats = MomentStats { mean: NiceFloat(127.4588370000015), standard_deviation: NiceFloat(73.908735397844), skewness: NiceFloat(0.0004407839380447086), excess_kurtosis: NiceFloat(-1.200418003526934), }; random_primitive_ints_helper::( values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // u16 let values = &[ 61297, 27717, 53988, 41384, 8279, 21358, 8892, 61017, 51293, 29589, 38333, 51673, 37493, 18463, 43415, 8622, 9735, 36945, 32584, 32881, ]; let common_values = &[ (27447, 34), (5606, 33), (5836, 33), (50513, 33), (64638, 33), (3582, 32), (19279, 32), (20588, 32), (27377, 32), (40163, 32), ]; let pop_median = (32767, Some(32768)); let sample_median = (32764, None); let pop_moment_stats = MomentStats { mean: NiceFloat(32767.5), standard_deviation: NiceFloat(18918.61361860324), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2000000005587934), }; let sample_moment_stats = MomentStats { mean: NiceFloat(32768.5946480003), standard_deviation: NiceFloat(18919.97151989925), skewness: NiceFloat(0.00005872108073206368), excess_kurtosis: NiceFloat(-1.200244178722062), }; random_primitive_ints_helper::( values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // u32 let values = &[ 1816522609, 2712195812, 1399726167, 3998819004, 1939195997, 3386480061, 1210028661, 565094807, 2421237255, 2154921800, 1999530985, 4087616012, 4147883634, 3097538087, 4234421608, 1164671716, 2394159346, 3174951407, 130045419, 2998491848, ]; let common_values = &[ (20095656, 2), (29107328, 2), (83328146, 2), (96543416, 2), (109257003, 2), (132308363, 2), (140940582, 2), (168698132, 2), (182460287, 2), (184573980, 2), ]; let pop_median = (2147483647, Some(2147483648)); let sample_median = (2150296456, Some(2150302375)); let pop_moment_stats = MomentStats { mean: NiceFloat(2147483647.5), standard_deviation: NiceFloat(1239850262.2531195), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2), }; let sample_moment_stats = MomentStats { mean: NiceFloat(2148696150.6876254), standard_deviation: NiceFloat(1239453907.667566), skewness: NiceFloat(-0.0016842295222180032), excess_kurtosis: NiceFloat(-1.2007050556559806), }; random_primitive_ints_helper::( values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // u64 let values = &[ 11648792314704686961, 17174796846203019351, 14544821112490281053, 2427063716414460533, 9255318658858690055, 17556177092145474537, 13303824785927286386, 5002226935030621544, 13636312461848344818, 12878424424612648427, 13573831502926905428, 1513424385005459611, 2484972586252155822, 13072300245601619293, 4344958725064805398, 3252798961345668310, 10520651756201345771, 12379844438588545665, 6654913321726770291, 10505868200830584967, ]; let common_values = &[ (26914038281329, 1), (32553719576594, 1), (53892651831494, 1), (66354421349686, 1), (86226284907602, 1), (89837182726049, 1), (95691351770484, 1), (166741761063383, 1), (171574734234584, 1), (212518263578065, 1), ]; let pop_median = (9223372036854775807, Some(9223372036854775808)); let sample_median = (9228795451400314170, Some(9228799993322832549)); let pop_moment_stats = MomentStats { mean: NiceFloat(9.223372036854776e18), standard_deviation: NiceFloat(5.325116328314171e18), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2), }; let sample_moment_stats = MomentStats { mean: NiceFloat(9.223151767642118e18), standard_deviation: NiceFloat(5.323459825978695e18), skewness: NiceFloat(-0.0007960342667556958), excess_kurtosis: NiceFloat(-1.2005689675667335), }; random_primitive_ints_helper::( values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // u128 let values = &[ 316819081939861044636107404782286008177, 44771423227283929645271838218448652381, 323854305731529921104946490224673891847, 92274800069126412258941638023956901490, 237564999433439714567249110498266052850, 27917752305106984883503397141734686804, 241141377085303586778938998836817083310, 60003549963171791765607325839025294358, 228367822030979405869278360636891890411, 193799061972845222683167418018286926963, 186696208941218647968078823625188059421, 33018320828004690757952445968579104952, 24887066387352849554815992782110776358, 79085537771456044427857440036467563654, 19637669411666889498466854442215856999, 237587532320755783035907621678835821469, 254983837845695498020527357238650572551, 272337383097469374367899988789175779695, 105189689748742230503365861545668092951, 258427395460299182237257690021561141080, ]; let common_values = &[ (68570815139656170990830410045915, 1), (381682482227926990846204728028719, 1), (565207126752383841908924745713103, 1), (717866653939818807939025508430762, 1), (775173738585689418081884794376186, 1), (818497230601034032775791540657915, 1), (1224023028796761386468452212527255, 1), (1379103576141836593923341631562888, 1), (1765193876177447622538546939111747, 1), (2049979073093489039458791025727172, 1), ]; let pop_median = ( 170141183460469231731687303715884105727, Some(170141183460469231731687303715884105728), ); let sample_median = ( 170151864710150847082485192587168481404, Some(170151925651660504506169909296979843840), ); let pop_moment_stats = MomentStats { mean: NiceFloat(1.7014118346046923e38), standard_deviation: NiceFloat(9.82310580711434e37), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2), }; let sample_moment_stats = MomentStats { mean: NiceFloat(1.702375633317502e38), standard_deviation: NiceFloat(9.815169783582294e37), skewness: NiceFloat(-0.0005571163134867303), excess_kurtosis: NiceFloat(-1.1992896928276262), }; random_primitive_ints_helper::( values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i8 let values = &[ 113, -17, 69, 108, -28, -46, -88, -95, 87, 32, 110, 83, -68, 34, 89, -18, 93, -56, -107, 115, ]; let common_values = &[ (-42, 4097), (86, 4078), (-90, 4049), (22, 4048), (126, 4047), (55, 4040), (93, 4037), (-65, 4036), (36, 4035), (42, 4032), ]; let pop_median = (-1, Some(0)); let sample_median = (0, None); let pop_moment_stats = MomentStats { mean: NiceFloat(-0.5), standard_deviation: NiceFloat(73.90027063549903), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.200036621652552), }; let sample_moment_stats = MomentStats { mean: NiceFloat(-0.5135149999999996), standard_deviation: NiceFloat(73.89764871907164), skewness: NiceFloat(-0.00024093275514460485), excess_kurtosis: NiceFloat(-1.199484141789355), }; random_primitive_ints_helper::( values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i16 let values = &[ -4239, 27717, -11548, -24152, 8279, 21358, 8892, -4519, -14243, 29589, -27203, -13863, -28043, 18463, -22121, 8622, 9735, -28591, 32584, -32655, ]; let common_values = &[ (27447, 34), (-898, 33), (5606, 33), (5836, 33), (-15023, 33), (-197, 32), (3582, 32), (-7314, 32), (19279, 32), (20588, 32), ]; let pop_median = (-1, Some(0)); let sample_median = (4, None); let pop_moment_stats = MomentStats { mean: NiceFloat(-0.5), standard_deviation: NiceFloat(18918.61361860324), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2000000005587934), }; let sample_moment_stats = MomentStats { mean: NiceFloat(5.11663199999982), standard_deviation: NiceFloat(18918.420140333936), skewness: NiceFloat(-0.00020582179614538415), excess_kurtosis: NiceFloat(-1.19980156293678), }; random_primitive_ints_helper::( values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i32 let values = &[ 1816522609, -1582771484, 1399726167, -296148292, 1939195997, -908487235, 1210028661, 565094807, -1873730041, -2140045496, 1999530985, -207351284, -147083662, -1197429209, -60545688, 1164671716, -1900807950, -1120015889, 130045419, -1296475448, ]; let common_values = &[ (20095656, 2), (29107328, 2), (83328146, 2), (96543416, 2), (-59532811, 2), (-72250103, 2), (-88423413, 2), (109257003, 2), (132308363, 2), (140940582, 2), ]; let pop_median = (-1, Some(0)); let sample_median = (-3037682, Some(-3035621)); let pop_moment_stats = MomentStats { mean: NiceFloat(-0.5), standard_deviation: NiceFloat(1239850262.2531195), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2), }; let sample_moment_stats = MomentStats { mean: NiceFloat(-1708075.0735549931), standard_deviation: NiceFloat(1239705769.0057693), skewness: NiceFloat(0.0016706713036923025), excess_kurtosis: NiceFloat(-1.2008047456655335), }; random_primitive_ints_helper::( values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i64 let values = &[ -6797951759004864655, -1271947227506532265, -3901922961219270563, 2427063716414460533, -9191425414850861561, -890566981564077079, -5142919287782265230, 5002226935030621544, -4810431611861206798, -5568319649096903189, -4872912570782646188, 1513424385005459611, 2484972586252155822, -5374443828107932323, 4344958725064805398, 3252798961345668310, -7926092317508205845, -6066899635121005951, 6654913321726770291, -7940875872878966649, ]; let common_values = &[ (26914038281329, 1), (32553719576594, 1), (53892651831494, 1), (66354421349686, 1), (86226284907602, 1), (89837182726049, 1), (95691351770484, 1), (-45554336062456, 1), (-45700426911569, 1), (-50232881235535, 1), ]; let pop_median = (-1, Some(0)); let sample_median = (-5305218289400184, Some(-5271053954352614)); let pop_moment_stats = MomentStats { mean: NiceFloat(0.0), standard_deviation: NiceFloat(5.325116328314171e18), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2), }; let sample_moment_stats = MomentStats { mean: NiceFloat(-5606718482239710.0), standard_deviation: NiceFloat(5.325063903618647e18), skewness: NiceFloat(0.0011248693866288532), excess_kurtosis: NiceFloat(-1.200551786344892), }; random_primitive_ints_helper::( values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i128 let values = &[ -23463284981077418827267202649482203279, 44771423227283929645271838218448652381, -16428061189408542358428117207094319609, 92274800069126412258941638023956901490, -102717367487498748896125496933502158606, 27917752305106984883503397141734686804, -99140989835634876684435608594951128146, 60003549963171791765607325839025294358, -111914544889959057594096246794876321045, -146483304948093240780207189413481284493, -153586157979719815495295783806580152035, 33018320828004690757952445968579104952, 24887066387352849554815992782110776358, 79085537771456044427857440036467563654, 19637669411666889498466854442215856999, -102694834600182680427466985752932389987, -85298529075242965442847250193117638905, -67944983823469089095474618642592431761, 105189689748742230503365861545668092951, -81854971460639281226116917410207070376, ]; let common_values = &[ (68570815139656170990830410045915, 1), (381682482227926990846204728028719, 1), (565207126752383841908924745713103, 1), (717866653939818807939025508430762, 1), (775173738585689418081884794376186, 1), (818497230601034032775791540657915, 1), (-307666299724089175945459600408325, 1), (-413570452196184856884474016102340, 1), (-789195894019805665974324122519229, 1), (-843024079296967638987633859098218, 1), ]; let pop_median = (-1, Some(0)); let sample_median = ( -10072503186589325235371920356302834, Some(-9899574809150113239535729822182407), ); let pop_moment_stats = MomentStats { mean: NiceFloat(0.0), standard_deviation: NiceFloat(9.82310580711434e37), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2), }; let sample_moment_stats = MomentStats { mean: NiceFloat(8.651168263124604e34), standard_deviation: NiceFloat(9.82707680675722e37), skewness: NiceFloat(0.00010083962773749455), excess_kurtosis: NiceFloat(-1.2019920806441844), }; random_primitive_ints_helper::( values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); } malachite-base-0.4.16/tests/num/random/random_signed_bit_chunks.rs000064400000000000000000000171101046102023000233640ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::{assert_equal, repeat_n, Itertools}; use malachite_base::bools::random::random_bools; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::conversion::traits::ExactFrom; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::random_signed_bit_chunks; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::moments::{ uniform_primitive_int_assertions, CheckedToF64, MomentStats, }; use std::panic::catch_unwind; fn random_signed_bit_chunks_helper( chunk_size: u64, expected_values: &[T], expected_common_values: &[(T, usize)], expected_pop_median: (T, Option), expected_sample_median: (T, Option), expected_pop_moment_stats: MomentStats, expected_sample_moment_stats: MomentStats, ) { let (min, max) = if chunk_size < T::WIDTH { (T::ZERO, T::low_mask(chunk_size)) } else { (T::MIN, T::MAX) }; let xs = random_signed_bit_chunks(EXAMPLE_SEED, chunk_size); uniform_primitive_int_assertions( xs.clone(), min, max, expected_values, expected_common_values, expected_pop_median, expected_sample_median, expected_pop_moment_stats, expected_sample_moment_stats, ); if chunk_size != 0 { assert_equal( random_bools(EXAMPLE_SEED) .chunks(usize::exact_from(chunk_size)) .into_iter() .take(1000000) .map(|bs| { T::from_bits_asc( bs.chain(repeat_n(false, usize::exact_from(T::WIDTH - chunk_size))), ) }), xs.take(1000000), ); } } #[test] fn test_random_signed_bit_chunks() { // i16, chunk_size = 1 let values = &[1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0]; let common_values = &[(1, 500473), (0, 499527)]; let pop_median = (0, Some(1)); let sample_median = (1, None); let pop_moment_stats = MomentStats { mean: NiceFloat(0.5), standard_deviation: NiceFloat(0.5), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.9999999999999998), }; let sample_moment_stats = MomentStats { mean: NiceFloat(0.5004730000000077), standard_deviation: NiceFloat(0.5000000262710417), skewness: NiceFloat(-0.0018920008465908307), excess_kurtosis: NiceFloat(-1.999996420332894), }; random_signed_bit_chunks_helper::( 1, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i32, chunk_size = 2 let values = &[1, 0, 3, 1, 3, 3, 2, 3, 1, 1, 0, 1, 0, 3, 2, 1, 0, 1, 2, 3]; let common_values = &[(1, 250314), (3, 250015), (2, 249955), (0, 249716)]; let pop_median = (1, Some(2)); let sample_median = (1, None); let pop_moment_stats = MomentStats { mean: NiceFloat(1.5), standard_deviation: NiceFloat(1.118033988749895), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.3599999999999999), }; let sample_moment_stats = MomentStats { mean: NiceFloat(1.5002690000000294), standard_deviation: NiceFloat(1.117793888470597), skewness: NiceFloat(-0.00003155128630032229), excess_kurtosis: NiceFloat(-1.3594490446207492), }; random_signed_bit_chunks_helper::( 2, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i64, chunk_size = 3 let values = &[1, 6, 5, 7, 6, 3, 1, 2, 4, 5, 1, 2, 6, 5, 4, 6, 0, 5, 6, 0]; let common_values = &[ (3, 125437), (6, 125372), (7, 125322), (4, 125116), (0, 125049), (5, 124759), (2, 124542), (1, 124403), ]; let pop_median = (3, Some(4)); let sample_median = (4, None); let pop_moment_stats = MomentStats { mean: NiceFloat(3.5), standard_deviation: NiceFloat(2.29128784747792), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.238095238095238), }; let sample_moment_stats = MomentStats { mean: NiceFloat(3.503543000000029), standard_deviation: NiceFloat(2.291658067611209), skewness: NiceFloat(-0.002350008016990765), excess_kurtosis: NiceFloat(-1.2376569368178467), }; random_signed_bit_chunks_helper::( 3, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i128, chunk_size = 7 let values = &[113, 94, 23, 98, 70, 92, 52, 84, 33, 47, 1, 113, 54, 10, 47, 17, 89, 92, 119, 66]; let common_values = &[ (2, 8077), (121, 8039), (48, 8015), (113, 7966), (8, 7937), (77, 7933), (50, 7928), (91, 7927), (82, 7925), (102, 7924), ]; let pop_median = (63, Some(64)); let sample_median = (63, None); let pop_moment_stats = MomentStats { mean: NiceFloat(63.5), standard_deviation: NiceFloat(36.94928957368463), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2001464933162425), }; let sample_moment_stats = MomentStats { mean: NiceFloat(63.478088999999315), standard_deviation: NiceFloat(36.96113842989552), skewness: NiceFloat(-0.000454036075457304), excess_kurtosis: NiceFloat(-1.1998683031732713), }; random_signed_bit_chunks_helper::( 7, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i8, chunk_size = 8 let values = &[ 113, -17, 69, 108, -28, -46, -88, -95, 87, 32, 110, 83, -68, 34, 89, -18, 93, -56, -107, 115, ]; let common_values = &[ (-42, 4097), (86, 4078), (-90, 4049), (22, 4048), (126, 4047), (55, 4040), (93, 4037), (-65, 4036), (36, 4035), (42, 4032), ]; let pop_median = (-1, Some(0)); let sample_median = (0, None); let pop_moment_stats = MomentStats { mean: NiceFloat(-0.5), standard_deviation: NiceFloat(73.90027063549903), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.200036621652552), }; let sample_moment_stats = MomentStats { mean: NiceFloat(-0.5135149999999996), standard_deviation: NiceFloat(73.89764871907164), skewness: NiceFloat(-0.00024093275514460485), excess_kurtosis: NiceFloat(-1.199484141789355), }; random_signed_bit_chunks_helper::( 8, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); } fn random_signed_bit_chunks_fail_helper() { assert_panic!(random_signed_bit_chunks::(EXAMPLE_SEED, 0)); assert_panic!(random_signed_bit_chunks::(EXAMPLE_SEED, T::WIDTH + 1)); } #[test] fn random_signed_bit_chunks_fail() { apply_fn_to_signeds!(random_signed_bit_chunks_fail_helper); } malachite-base-0.4.16/tests/num/random/random_signed_inclusive_range.rs000064400000000000000000000201001046102023000244010ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::random_signed_inclusive_range; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::moments::{ uniform_primitive_int_assertions, CheckedToF64, MomentStats, }; use std::panic::catch_unwind; fn random_signed_inclusive_range_helper( a: T, b: T, expected_values: &[T], expected_common_values: &[(T, usize)], expected_pop_median: (T, Option), expected_sample_median: (T, Option), expected_pop_moment_stats: MomentStats, expected_sample_moment_stats: MomentStats, ) { uniform_primitive_int_assertions( random_signed_inclusive_range::(EXAMPLE_SEED, a, b), a, b, expected_values, expected_common_values, expected_pop_median, expected_sample_median, expected_pop_moment_stats, expected_sample_moment_stats, ); } #[test] fn test_random_signed_inclusive_range() { // i8, 5, 5 let values = &[5; 20]; let common_values = &[(5, 1000000)]; let pop_median = (5, None); let sample_median = (5, None); let pop_moment_stats = MomentStats { mean: NiceFloat(5.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; let sample_moment_stats = MomentStats { mean: NiceFloat(5.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; random_signed_inclusive_range_helper::( 5, 5, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i16, 1, 6 let values = &[2, 6, 4, 2, 3, 5, 6, 2, 3, 6, 5, 1, 6, 1, 3, 6, 3, 1, 5, 1]; let common_values = &[(4, 167408), (1, 167104), (5, 166935), (6, 166549), (3, 166068), (2, 165936)]; let pop_median = (3, Some(4)); let sample_median = (4, None); let pop_moment_stats = MomentStats { mean: NiceFloat(3.5), standard_deviation: NiceFloat(1.707825127659933), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2685714285714285), }; let sample_moment_stats = MomentStats { mean: NiceFloat(3.5007809999998676), standard_deviation: NiceFloat(1.7081165966354217), skewness: NiceFloat(-0.0024015945144963404), excess_kurtosis: NiceFloat(-1.2685533575767198), }; random_signed_inclusive_range_helper::( 1, 6, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i32, 10, 19 let values = &[11, 17, 15, 14, 16, 14, 12, 18, 11, 17, 15, 10, 12, 16, 13, 15, 12, 12, 19, 15]; let common_values = &[ (15, 100442), (12, 100144), (16, 100118), (18, 100047), (11, 100023), (14, 100011), (10, 99996), (19, 99936), (17, 99715), (13, 99568), ]; let pop_median = (14, Some(15)); let sample_median = (15, None); let pop_moment_stats = MomentStats { mean: NiceFloat(14.5), standard_deviation: NiceFloat(2.8722813232690143), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2242424242424241), }; let sample_moment_stats = MomentStats { mean: NiceFloat(14.49978199999957), standard_deviation: NiceFloat(2.8719356191409076), skewness: NiceFloat(-0.00016199543215732692), excess_kurtosis: NiceFloat(-1.2237431734377722), }; random_signed_inclusive_range_helper::( 10, 19, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i64, -20, -11 let values = &[ -19, -13, -15, -16, -14, -16, -18, -12, -19, -13, -15, -20, -18, -14, -17, -15, -18, -18, -11, -15, ]; let common_values = &[ (-15, 100442), (-18, 100144), (-14, 100118), (-12, 100047), (-19, 100023), (-16, 100011), (-20, 99996), (-11, 99936), (-13, 99715), (-17, 99568), ]; let pop_median = (-16, Some(-15)); let sample_median = (-15, None); let pop_moment_stats = MomentStats { mean: NiceFloat(-15.5), standard_deviation: NiceFloat(2.8722813232690143), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2242424242424241), }; let sample_moment_stats = MomentStats { mean: NiceFloat(-15.50021800000043), standard_deviation: NiceFloat(2.8719356191409076), skewness: NiceFloat(-0.00016199543215732692), excess_kurtosis: NiceFloat(-1.2237431734377722), }; random_signed_inclusive_range_helper::( -20, -11, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i8, -100, 99 let values = &[13, -31, 8, 68, 61, -13, -68, 10, -17, 88, -66, -11, -7, 49, 15, 89, 49, 17, 46, -69]; let common_values = &[ (-33, 5190), (66, 5182), (87, 5176), (-73, 5172), (-7, 5169), (91, 5167), (-84, 5136), (26, 5132), (-12, 5125), (-14, 5125), ]; let pop_median = (-1, Some(0)); let sample_median = (-1, None); let pop_moment_stats = MomentStats { mean: NiceFloat(-0.5), standard_deviation: NiceFloat(57.73430522661548), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2000600015000376), }; let sample_moment_stats = MomentStats { mean: NiceFloat(-0.5228260000000045), standard_deviation: NiceFloat(57.74415076317745), skewness: NiceFloat(0.00018970091170297907), excess_kurtosis: NiceFloat(-1.2011004127418898), }; random_signed_inclusive_range_helper::( -100, 99, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i8, i8::MIN, i8::MAX let values = &[ -15, 111, -59, -20, 100, 82, 40, 33, -41, -96, -18, -45, 60, -94, -39, 110, -35, 72, 21, -13, ]; let common_values = &[ (86, 4097), (-42, 4078), (38, 4049), (-106, 4048), (-2, 4047), (-73, 4040), (-35, 4037), (63, 4036), (-92, 4035), (-86, 4032), ]; let pop_median = (-1, Some(0)); let sample_median = (-1, None); let pop_moment_stats = MomentStats { mean: NiceFloat(-0.5), standard_deviation: NiceFloat(73.90027063549903), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.200036621652552), }; let sample_moment_stats = MomentStats { mean: NiceFloat(-0.5411629999999936), standard_deviation: NiceFloat(73.90873539784404), skewness: NiceFloat(0.00044078393804460487), excess_kurtosis: NiceFloat(-1.200418003526936), }; random_signed_inclusive_range_helper::( i8::MIN, i8::MAX, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); } fn random_signed_inclusive_range_fail_helper() { assert_panic!(random_signed_inclusive_range::( EXAMPLE_SEED, T::TWO, T::ONE )); } #[test] fn random_signed_inclusive_range_fail() { apply_fn_to_signeds!(random_signed_inclusive_range_fail_helper); } malachite-base-0.4.16/tests/num/random/random_signed_range.rs000064400000000000000000000176361046102023000223440ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::random_signed_range; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::moments::{ uniform_primitive_int_assertions, CheckedToF64, MomentStats, }; use std::panic::catch_unwind; fn random_signed_range_helper( a: T, b: T, expected_values: &[T], expected_common_values: &[(T, usize)], expected_pop_median: (T, Option), expected_sample_median: (T, Option), expected_pop_moment_stats: MomentStats, expected_sample_moment_stats: MomentStats, ) { uniform_primitive_int_assertions( random_signed_range::(EXAMPLE_SEED, a, b), a, b - T::ONE, expected_values, expected_common_values, expected_pop_median, expected_sample_median, expected_pop_moment_stats, expected_sample_moment_stats, ); } #[test] fn test_random_signed_range() { // i8, 5, 6 let values = &[5; 20]; let common_values = &[(5, 1000000)]; let pop_median = (5, None); let sample_median = (5, None); let pop_moment_stats = MomentStats { mean: NiceFloat(5.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; let sample_moment_stats = MomentStats { mean: NiceFloat(5.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; random_signed_range_helper::( 5, 6, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i16, 1, 7 let values = &[2, 6, 4, 2, 3, 5, 6, 2, 3, 6, 5, 1, 6, 1, 3, 6, 3, 1, 5, 1]; let common_values = &[(4, 167408), (1, 167104), (5, 166935), (6, 166549), (3, 166068), (2, 165936)]; let pop_median = (3, Some(4)); let sample_median = (4, None); let pop_moment_stats = MomentStats { mean: NiceFloat(3.5), standard_deviation: NiceFloat(1.707825127659933), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2685714285714285), }; let sample_moment_stats = MomentStats { mean: NiceFloat(3.5007809999998676), standard_deviation: NiceFloat(1.7081165966354217), skewness: NiceFloat(-0.0024015945144963404), excess_kurtosis: NiceFloat(-1.2685533575767198), }; random_signed_range_helper::( 1, 7, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i32, 10, 20 let values = &[11, 17, 15, 14, 16, 14, 12, 18, 11, 17, 15, 10, 12, 16, 13, 15, 12, 12, 19, 15]; let common_values = &[ (15, 100442), (12, 100144), (16, 100118), (18, 100047), (11, 100023), (14, 100011), (10, 99996), (19, 99936), (17, 99715), (13, 99568), ]; let pop_median = (14, Some(15)); let sample_median = (15, None); let pop_moment_stats = MomentStats { mean: NiceFloat(14.5), standard_deviation: NiceFloat(2.8722813232690143), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2242424242424241), }; let sample_moment_stats = MomentStats { mean: NiceFloat(14.49978199999957), standard_deviation: NiceFloat(2.8719356191409076), skewness: NiceFloat(-0.00016199543215732692), excess_kurtosis: NiceFloat(-1.2237431734377722), }; random_signed_range_helper::( 10, 20, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i64, -20, -10 let values = &[ -19, -13, -15, -16, -14, -16, -18, -12, -19, -13, -15, -20, -18, -14, -17, -15, -18, -18, -11, -15, ]; let common_values = &[ (-15, 100442), (-18, 100144), (-14, 100118), (-12, 100047), (-19, 100023), (-16, 100011), (-20, 99996), (-11, 99936), (-13, 99715), (-17, 99568), ]; let pop_median = (-16, Some(-15)); let sample_median = (-15, None); let pop_moment_stats = MomentStats { mean: NiceFloat(-15.5), standard_deviation: NiceFloat(2.8722813232690143), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2242424242424241), }; let sample_moment_stats = MomentStats { mean: NiceFloat(-15.50021800000043), standard_deviation: NiceFloat(2.8719356191409076), skewness: NiceFloat(-0.00016199543215732692), excess_kurtosis: NiceFloat(-1.2237431734377722), }; random_signed_range_helper::( -20, -10, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i8, -100, 100 let values = &[13, -31, 8, 68, 61, -13, -68, 10, -17, 88, -66, -11, -7, 49, 15, 89, 49, 17, 46, -69]; let common_values = &[ (-33, 5190), (66, 5182), (87, 5176), (-73, 5172), (-7, 5169), (91, 5167), (-84, 5136), (26, 5132), (-12, 5125), (-14, 5125), ]; let pop_median = (-1, Some(0)); let sample_median = (-1, None); let pop_moment_stats = MomentStats { mean: NiceFloat(-0.5), standard_deviation: NiceFloat(57.73430522661548), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2000600015000376), }; let sample_moment_stats = MomentStats { mean: NiceFloat(-0.5228260000000045), standard_deviation: NiceFloat(57.74415076317745), skewness: NiceFloat(0.00018970091170297907), excess_kurtosis: NiceFloat(-1.2011004127418898), }; random_signed_range_helper::( -100, 100, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // i8, i8::MIN, i8::MAX let values = &[ -15, 111, -59, -20, 100, 82, 40, 33, -41, -96, -18, -45, 60, -94, -39, 110, -35, 72, 21, -13, ]; let common_values = &[ (86, 4112), (-42, 4092), (38, 4063), (-2, 4061), (-106, 4061), (-35, 4054), (-73, 4054), (63, 4052), (-92, 4049), (-86, 4047), ]; let pop_median = (-1, None); let sample_median = (-1, None); let pop_moment_stats = MomentStats { mean: NiceFloat(-1.0), standard_deviation: NiceFloat(73.6115932898254), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2000369094488188), }; let sample_moment_stats = MomentStats { mean: NiceFloat(-1.0481689999999793), standard_deviation: NiceFloat(73.61930013623301), skewness: NiceFloat(0.0005380412105164722), excess_kurtosis: NiceFloat(-1.2003531635142872), }; random_signed_range_helper::( i8::MIN, i8::MAX, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); } fn random_signed_range_fail_helper() { assert_panic!(random_signed_range::(EXAMPLE_SEED, T::TWO, T::TWO)); } #[test] fn random_signed_range_fail() { apply_fn_to_signeds!(random_signed_range_fail_helper); } malachite-base-0.4.16/tests/num/random/random_unsigned_bit_chunks.rs000064400000000000000000000165121046102023000237340ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::{assert_equal, Itertools}; use malachite_base::bools::random::random_bools; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::ExactFrom; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::random_unsigned_bit_chunks; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::moments::{ uniform_primitive_int_assertions, CheckedToF64, MomentStats, }; use std::panic::catch_unwind; fn random_unsigned_bit_chunks_helper( chunk_size: u64, expected_values: &[T], expected_common_values: &[(T, usize)], expected_pop_median: (T, Option), expected_sample_median: (T, Option), expected_pop_moment_stats: MomentStats, expected_sample_moment_stats: MomentStats, ) { let xs = random_unsigned_bit_chunks(EXAMPLE_SEED, chunk_size); uniform_primitive_int_assertions( xs.clone(), T::ZERO, T::low_mask(chunk_size), expected_values, expected_common_values, expected_pop_median, expected_sample_median, expected_pop_moment_stats, expected_sample_moment_stats, ); if chunk_size != 0 { assert_equal( random_bools(EXAMPLE_SEED) .chunks(usize::exact_from(chunk_size)) .into_iter() .take(1000000) .map(T::from_bits_asc), xs.take(1000000), ); } } #[test] fn test_random_unsigned_bit_chunks() { // u16, chunk_size = 1 let values = &[1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0]; let common_values = &[(1, 500473), (0, 499527)]; let pop_median = (0, Some(1)); let sample_median = (1, None); let pop_moment_stats = MomentStats { mean: NiceFloat(0.5), standard_deviation: NiceFloat(0.5), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.9999999999999998), }; let sample_moment_stats = MomentStats { mean: NiceFloat(0.5004730000000077), standard_deviation: NiceFloat(0.5000000262710417), skewness: NiceFloat(-0.0018920008465908307), excess_kurtosis: NiceFloat(-1.999996420332894), }; random_unsigned_bit_chunks_helper::( 1, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // u32, chunk_size = 2 let values = &[1, 0, 3, 1, 3, 3, 2, 3, 1, 1, 0, 1, 0, 3, 2, 1, 0, 1, 2, 3]; let common_values = &[(1, 250314), (3, 250015), (2, 249955), (0, 249716)]; let pop_median = (1, Some(2)); let sample_median = (1, None); let pop_moment_stats = MomentStats { mean: NiceFloat(1.5), standard_deviation: NiceFloat(1.118033988749895), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.3599999999999999), }; let sample_moment_stats = MomentStats { mean: NiceFloat(1.5002690000000294), standard_deviation: NiceFloat(1.117793888470597), skewness: NiceFloat(-0.00003155128630032229), excess_kurtosis: NiceFloat(-1.3594490446207492), }; random_unsigned_bit_chunks_helper::( 2, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // u64, chunk_size = 3 let values = &[1, 6, 5, 7, 6, 3, 1, 2, 4, 5, 1, 2, 6, 5, 4, 6, 0, 5, 6, 0]; let common_values = &[ (3, 125437), (6, 125372), (7, 125322), (4, 125116), (0, 125049), (5, 124759), (2, 124542), (1, 124403), ]; let pop_median = (3, Some(4)); let sample_median = (4, None); let pop_moment_stats = MomentStats { mean: NiceFloat(3.5), standard_deviation: NiceFloat(2.29128784747792), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.238095238095238), }; let sample_moment_stats = MomentStats { mean: NiceFloat(3.503543000000029), standard_deviation: NiceFloat(2.291658067611209), skewness: NiceFloat(-0.002350008016990765), excess_kurtosis: NiceFloat(-1.2376569368178467), }; random_unsigned_bit_chunks_helper::( 3, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // u128, chunk_size = 7 let values = &[113, 94, 23, 98, 70, 92, 52, 84, 33, 47, 1, 113, 54, 10, 47, 17, 89, 92, 119, 66]; let common_values = &[ (2, 8077), (121, 8039), (48, 8015), (113, 7966), (8, 7937), (77, 7933), (50, 7928), (91, 7927), (82, 7925), (102, 7924), ]; let pop_median = (63, Some(64)); let sample_median = (63, None); let pop_moment_stats = MomentStats { mean: NiceFloat(63.5), standard_deviation: NiceFloat(36.94928957368463), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2001464933162425), }; let sample_moment_stats = MomentStats { mean: NiceFloat(63.478088999999315), standard_deviation: NiceFloat(36.96113842989552), skewness: NiceFloat(-0.000454036075457304), excess_kurtosis: NiceFloat(-1.1998683031732713), }; random_unsigned_bit_chunks_helper::( 7, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // u8, chunk_size = 8 let values = &[ 113, 239, 69, 108, 228, 210, 168, 161, 87, 32, 110, 83, 188, 34, 89, 238, 93, 200, 149, 115, ]; let common_values = &[ (214, 4097), (86, 4078), (166, 4049), (22, 4048), (126, 4047), (55, 4040), (93, 4037), (191, 4036), (36, 4035), (42, 4032), ]; let pop_median = (127, Some(128)); let sample_median = (127, None); let pop_moment_stats = MomentStats { mean: NiceFloat(127.5), standard_deviation: NiceFloat(73.90027063549903), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.200036621652552), }; let sample_moment_stats = MomentStats { mean: NiceFloat(127.4588370000015), standard_deviation: NiceFloat(73.908735397844), skewness: NiceFloat(0.0004407839380447086), excess_kurtosis: NiceFloat(-1.200418003526934), }; random_unsigned_bit_chunks_helper::( 8, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); } fn random_unsigned_bit_chunks_fail_helper() { assert_panic!(random_unsigned_bit_chunks::(EXAMPLE_SEED, 0)); assert_panic!(random_unsigned_bit_chunks::(EXAMPLE_SEED, T::WIDTH + 1)); } #[test] fn random_unsigned_bit_chunks_fail() { apply_fn_to_unsigneds!(random_unsigned_bit_chunks_fail_helper); } malachite-base-0.4.16/tests/num/random/random_unsigned_inclusive_range.rs000064400000000000000000000134051046102023000247560ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::random_unsigned_inclusive_range; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::moments::{ uniform_primitive_int_assertions, CheckedToF64, MomentStats, }; use std::panic::catch_unwind; fn random_unsigned_inclusive_range_helper( a: T, b: T, expected_values: &[T], expected_common_values: &[(T, usize)], expected_pop_median: (T, Option), expected_sample_median: (T, Option), expected_pop_moment_stats: MomentStats, expected_sample_moment_stats: MomentStats, ) { uniform_primitive_int_assertions( random_unsigned_inclusive_range::(EXAMPLE_SEED, a, b), a, b, expected_values, expected_common_values, expected_pop_median, expected_sample_median, expected_pop_moment_stats, expected_sample_moment_stats, ); } #[test] fn test_random_unsigned_inclusive_range() { // u8, 5, 5 let values = &[5; 20]; let common_values = &[(5, 1000000)]; let pop_median = (5, None); let sample_median = (5, None); let pop_moment_stats = MomentStats { mean: NiceFloat(5.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; let sample_moment_stats = MomentStats { mean: NiceFloat(5.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; random_unsigned_inclusive_range_helper::( 5, 5, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // u16, 1, 6 let values = &[2, 6, 4, 2, 3, 5, 6, 2, 3, 6, 5, 1, 6, 1, 3, 6, 3, 1, 5, 1]; let common_values = &[(4, 167408), (1, 167104), (5, 166935), (6, 166549), (3, 166068), (2, 165936)]; let pop_median = (3, Some(4)); let sample_median = (4, None); let pop_moment_stats = MomentStats { mean: NiceFloat(3.5), standard_deviation: NiceFloat(1.707825127659933), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2685714285714285), }; let sample_moment_stats = MomentStats { mean: NiceFloat(3.5007809999998676), standard_deviation: NiceFloat(1.7081165966354217), skewness: NiceFloat(-0.0024015945144963404), excess_kurtosis: NiceFloat(-1.2685533575767198), }; random_unsigned_inclusive_range_helper::( 1, 6, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // u32, 10, 19 let values = &[11, 17, 15, 14, 16, 14, 12, 18, 11, 17, 15, 10, 12, 16, 13, 15, 12, 12, 19, 15]; let common_values = &[ (15, 100442), (12, 100144), (16, 100118), (18, 100047), (11, 100023), (14, 100011), (10, 99996), (19, 99936), (17, 99715), (13, 99568), ]; let pop_median = (14, Some(15)); let sample_median = (15, None); let pop_moment_stats = MomentStats { mean: NiceFloat(14.5), standard_deviation: NiceFloat(2.8722813232690143), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2242424242424241), }; let sample_moment_stats = MomentStats { mean: NiceFloat(14.49978199999957), standard_deviation: NiceFloat(2.8719356191409076), skewness: NiceFloat(-0.00016199543215732692), excess_kurtosis: NiceFloat(-1.2237431734377722), }; random_unsigned_inclusive_range_helper::( 10, 19, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // u8, 0, u8::MAX let values = &[ 113, 239, 69, 108, 228, 210, 168, 161, 87, 32, 110, 83, 188, 34, 89, 238, 93, 200, 149, 115, ]; let common_values = &[ (214, 4097), (86, 4078), (166, 4049), (22, 4048), (126, 4047), (55, 4040), (93, 4037), (191, 4036), (36, 4035), (42, 4032), ]; let pop_median = (127, Some(128)); let sample_median = (127, None); let pop_moment_stats = MomentStats { mean: NiceFloat(127.5), standard_deviation: NiceFloat(73.90027063549903), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.200036621652552), }; let sample_moment_stats = MomentStats { mean: NiceFloat(127.4588370000015), standard_deviation: NiceFloat(73.908735397844), skewness: NiceFloat(0.0004407839380447086), excess_kurtosis: NiceFloat(-1.200418003526934), }; random_unsigned_inclusive_range_helper::( 0, u8::MAX, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); } fn random_unsigned_inclusive_range_fail_helper() { assert_panic!(random_unsigned_inclusive_range::( EXAMPLE_SEED, T::TWO, T::ONE )); } #[test] fn random_unsigned_inclusive_range_fail() { apply_fn_to_unsigneds!(random_unsigned_inclusive_range_fail_helper); } malachite-base-0.4.16/tests/num/random/random_unsigned_range.rs000064400000000000000000000131661046102023000227010ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::random_unsigned_range; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::moments::{ uniform_primitive_int_assertions, CheckedToF64, MomentStats, }; use std::panic::catch_unwind; fn random_unsigned_range_helper( a: T, b: T, expected_values: &[T], expected_common_values: &[(T, usize)], expected_pop_median: (T, Option), expected_sample_median: (T, Option), expected_pop_moment_stats: MomentStats, expected_sample_moment_stats: MomentStats, ) { uniform_primitive_int_assertions( random_unsigned_range::(EXAMPLE_SEED, a, b), a, b - T::ONE, expected_values, expected_common_values, expected_pop_median, expected_sample_median, expected_pop_moment_stats, expected_sample_moment_stats, ); } #[test] fn test_random_unsigned_range() { // u8, 5, 6 let values = &[5; 20]; let common_values = &[(5, 1000000)]; let pop_median = (5, None); let sample_median = (5, None); let pop_moment_stats = MomentStats { mean: NiceFloat(5.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; let sample_moment_stats = MomentStats { mean: NiceFloat(5.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; random_unsigned_range_helper::( 5, 6, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // u16, 1, 7 let values = &[2, 6, 4, 2, 3, 5, 6, 2, 3, 6, 5, 1, 6, 1, 3, 6, 3, 1, 5, 1]; let common_values = &[(4, 167408), (1, 167104), (5, 166935), (6, 166549), (3, 166068), (2, 165936)]; let pop_median = (3, Some(4)); let sample_median = (4, None); let pop_moment_stats = MomentStats { mean: NiceFloat(3.5), standard_deviation: NiceFloat(1.707825127659933), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2685714285714285), }; let sample_moment_stats = MomentStats { mean: NiceFloat(3.5007809999998676), standard_deviation: NiceFloat(1.7081165966354217), skewness: NiceFloat(-0.0024015945144963404), excess_kurtosis: NiceFloat(-1.2685533575767198), }; random_unsigned_range_helper::( 1, 7, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // u32, 10, 20 let values = &[11, 17, 15, 14, 16, 14, 12, 18, 11, 17, 15, 10, 12, 16, 13, 15, 12, 12, 19, 15]; let common_values = &[ (15, 100442), (12, 100144), (16, 100118), (18, 100047), (11, 100023), (14, 100011), (10, 99996), (19, 99936), (17, 99715), (13, 99568), ]; let pop_median = (14, Some(15)); let sample_median = (15, None); let pop_moment_stats = MomentStats { mean: NiceFloat(14.5), standard_deviation: NiceFloat(2.8722813232690143), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2242424242424241), }; let sample_moment_stats = MomentStats { mean: NiceFloat(14.49978199999957), standard_deviation: NiceFloat(2.8719356191409076), skewness: NiceFloat(-0.00016199543215732692), excess_kurtosis: NiceFloat(-1.2237431734377722), }; random_unsigned_range_helper::( 10, 20, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // u8, 0, u8::MAX let values = &[ 113, 239, 69, 108, 228, 210, 168, 161, 87, 32, 110, 83, 188, 34, 89, 238, 93, 200, 149, 115, ]; let common_values = &[ (214, 4112), (86, 4092), (166, 4063), (22, 4061), (126, 4061), (55, 4054), (93, 4054), (191, 4052), (36, 4049), (42, 4047), ]; let pop_median = (127, None); let sample_median = (127, None); let pop_moment_stats = MomentStats { mean: NiceFloat(127.0), standard_deviation: NiceFloat(73.6115932898254), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2000369094488188), }; let sample_moment_stats = MomentStats { mean: NiceFloat(126.95183099999818), standard_deviation: NiceFloat(73.61930013623306), skewness: NiceFloat(0.0005380412105163868), excess_kurtosis: NiceFloat(-1.200353163514298), }; random_unsigned_range_helper::( 0, u8::MAX, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); } fn random_unsigned_range_fail_helper() { assert_panic!(random_unsigned_range::(EXAMPLE_SEED, T::TWO, T::TWO)); } #[test] fn random_unsigned_range_fail() { apply_fn_to_unsigneds!(random_unsigned_range_fail_helper); } malachite-base-0.4.16/tests/num/random/random_unsigneds_less_than.rs000064400000000000000000000143531046102023000237470ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::random_unsigneds_less_than; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::moments::{ uniform_primitive_int_assertions, CheckedToF64, MomentStats, }; use std::panic::catch_unwind; fn random_unsigneds_less_than_helper( limit: T, expected_values: &[T], expected_common_values: &[(T, usize)], expected_pop_median: (T, Option), expected_sample_median: (T, Option), expected_pop_moment_stats: MomentStats, expected_sample_moment_stats: MomentStats, ) { uniform_primitive_int_assertions( random_unsigneds_less_than(EXAMPLE_SEED, limit), T::ZERO, limit.wrapping_sub(T::ONE), expected_values, expected_common_values, expected_pop_median, expected_sample_median, expected_pop_moment_stats, expected_sample_moment_stats, ); } #[test] fn test_random_unsigneds_less_than() { // u8, limit = 1 let values = &[0; 20]; let common_values = &[(0, 1000000)]; let pop_median = (0, None); let sample_median = (0, None); let pop_moment_stats = MomentStats { mean: NiceFloat(0.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; let sample_moment_stats = MomentStats { mean: NiceFloat(0.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; random_unsigneds_less_than_helper::( 1, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // u16, limit = 2 let values = &[1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0]; let common_values = &[(1, 500473), (0, 499527)]; let pop_median = (0, Some(1)); let sample_median = (1, None); let pop_moment_stats = MomentStats { mean: NiceFloat(0.5), standard_deviation: NiceFloat(0.5), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.9999999999999998), }; let sample_moment_stats = MomentStats { mean: NiceFloat(0.5004730000000077), standard_deviation: NiceFloat(0.5000000262710417), skewness: NiceFloat(-0.0018920008465908307), excess_kurtosis: NiceFloat(-1.999996420332894), }; random_unsigneds_less_than_helper::( 2, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // u32, limit = 3 let values = &[1, 0, 1, 2, 1, 1, 0, 1, 0, 2, 1, 0, 1, 2, 2, 0, 1, 0, 2, 2]; let common_values = &[(1, 333784), (2, 333516), (0, 332700)]; let pop_median = (1, None); let sample_median = (1, None); let pop_moment_stats = MomentStats { mean: NiceFloat(1.0), standard_deviation: NiceFloat(0.816496580927726), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.5), }; let sample_moment_stats = MomentStats { mean: NiceFloat(1.0008159999999369), standard_deviation: NiceFloat(0.8162205586482172), skewness: NiceFloat(-0.0014985805078073927), excess_kurtosis: NiceFloat(-1.498982317720307), }; random_unsigneds_less_than_helper::( 3, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // u64, limit = 4 let values = &[1, 0, 3, 1, 3, 3, 2, 3, 1, 1, 0, 1, 0, 3, 2, 1, 0, 1, 2, 3]; let common_values = &[(1, 250314), (3, 250015), (2, 249955), (0, 249716)]; let pop_median = (1, Some(2)); let sample_median = (1, None); let pop_moment_stats = MomentStats { mean: NiceFloat(1.5), standard_deviation: NiceFloat(1.118033988749895), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.3599999999999999), }; let sample_moment_stats = MomentStats { mean: NiceFloat(1.5002690000000294), standard_deviation: NiceFloat(1.117793888470597), skewness: NiceFloat(-0.00003155128630032229), excess_kurtosis: NiceFloat(-1.3594490446207492), }; random_unsigneds_less_than_helper::( 4, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); // u128, limit = 10 let values = &[1, 7, 5, 4, 6, 4, 2, 8, 1, 7, 5, 0, 2, 6, 3, 5, 2, 2, 9, 5]; let common_values = &[ (5, 100442), (2, 100144), (6, 100118), (8, 100047), (1, 100023), (4, 100011), (0, 99996), (9, 99936), (7, 99715), (3, 99568), ]; let pop_median = (4, Some(5)); let sample_median = (5, None); let pop_moment_stats = MomentStats { mean: NiceFloat(4.5), standard_deviation: NiceFloat(2.8722813232690143), skewness: NiceFloat(0.0), excess_kurtosis: NiceFloat(-1.2242424242424241), }; let sample_moment_stats = MomentStats { mean: NiceFloat(4.499781999999947), standard_deviation: NiceFloat(2.8719356191409156), skewness: NiceFloat(-0.00016199543215745585), excess_kurtosis: NiceFloat(-1.2237431734377897), }; random_unsigneds_less_than_helper::( 10, values, common_values, pop_median, sample_median, pop_moment_stats, sample_moment_stats, ); } fn random_unsigneds_less_than_fail_helper() { assert_panic!(random_unsigneds_less_than::(EXAMPLE_SEED, T::ZERO)); } #[test] fn random_unsigneds_less_than_fail() { apply_fn_to_unsigneds!(random_unsigneds_less_than_fail_helper); } malachite-base-0.4.16/tests/num/random/special_random_finite_primitive_floats.rs000064400000000000000000000312741046102023000263270ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::special_random_finite_primitive_floats; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::num::random::special_random_primitive_floats_helper_helper; use malachite_base::test_util::stats::moments::{CheckedToF64, MomentStats}; use std::panic::catch_unwind; fn special_random_finite_primitive_floats_helper( mean_exponent_numerator: u64, mean_exponent_denominator: u64, mean_precision_numerator: u64, mean_precision_denominator: u64, mean_zero_p_numerator: u64, mean_zero_p_denominator: u64, expected_values: &[T], expected_common_values: &[(T, usize)], expected_median: (T, Option), expected_moment_stats: MomentStats, ) { special_random_primitive_floats_helper_helper( special_random_finite_primitive_floats::( EXAMPLE_SEED, mean_exponent_numerator, mean_exponent_denominator, mean_precision_numerator, mean_precision_denominator, mean_zero_p_numerator, mean_zero_p_denominator, ), expected_values, expected_common_values, expected_median, expected_moment_stats, ); } #[test] fn test_special_random_finite_primitive_floats() { // f32, mean abs of exponent = 1/64, mean precision = 65/64, mean zero P = 1/4 let values = &[ 0.0, 1.0, 1.0, -0.0, 1.0, -1.0, 0.0, -1.0, 0.0, -0.0, -1.0, -0.0, -1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 0.5, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 0.0, -1.5, -0.0, 0.0, -1.0, 1.0, -1.0, -1.0, -1.0, 0.0, 1.0, -1.0, -0.5, -1.0, -0.0, 0.0, 0.0, 1.0, ]; let common_values = &[ (1.0, 358244), (-1.0, 357926), (0.0, 125637), (-0.0, 124572), (2.0, 5538), (1.5, 5500), (0.5, 5497), (-1.5, 5454), (-2.0, 5379), (-0.5, 5357), (0.75, 102), (3.0, 98), (-4.0, 95), (-0.25, 91), (-0.75, 87), (-3.0, 86), (0.25, 79), (4.0, 75), (-1.25, 48), (1.75, 44), ]; let sample_median = (0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(0.0007401249999999665), standard_deviation: NiceFloat(0.8901654924701277), skewness: NiceFloat(-0.00169030138949471), excess_kurtosis: NiceFloat(-1.371049776159086), }; special_random_finite_primitive_floats_helper::( 1, 64, 65, 64, 1, 4, values, common_values, sample_median, sample_moment_stats, ); // f32, mean abs of exponent = 1, mean precision = 2, mean zero P = 1/10 let values = &[ 1.0, 1.25, 3.0, 0.0, -1.0, -1.0, -2.0, -3.5, 1.0, 2.0, -1.5, -2.5, -2.0, -0.0, -6.5, -1.0, -1.0, 0.0, 3.0, -0.21875, -1.0, 0.25, 1.5, 5.25, -4.0, 7.0, -0.5, 0.1875, 1.25, 0.0, -0.1875, -7.5, -0.0, 0.75, -7.0, -6.0, -3.0, 0.234375, -2.0, -0.875, -0.75, 6.0, -24.0, 24.0, -2.0, 1.5, -0.0, -1.25, 14.0, 5.0, ]; let common_values = &[ (1.0, 74789), (-1.0, 74702), (0.0, 50351), (-0.0, 49873), (1.5, 38119), (-0.5, 37713), (2.0, 37640), (-1.5, 37613), (-2.0, 37333), (0.5, 37027), (0.75, 19050), (4.0, 18892), (0.25, 18875), (-3.0, 18866), (3.0, 18821), (-0.75, 18725), (-4.0, 18663), (-0.25, 18537), (0.125, 9445), (-0.375, 9395), ]; let sample_median = (0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(-0.8271329178933905), standard_deviation: NiceFloat(427.372166726293), skewness: NiceFloat(-141.119016305626), excess_kurtosis: NiceFloat(144205.19930780405), }; special_random_finite_primitive_floats_helper::( 1, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f32, mean abs of exponent = 10, mean precision = 10, mean zero P = 1/100 let values = &[ 0.65625, 0.0000014255784, 0.013183594, -0.8125, -74240.0, -0.0078125, -0.03060913, 3.331552, 4.75, -0.000038146973, -0.3125, -27136.0, -59392.0, -1.75, -41.1875, 0.30940247, -0.0009765625, -1536.0, 0.2109375, 0.0014648438, 2.1129381e-8, -0.037109375, 5242880.0, -0.21386719, 134.21094, 4.184082, -1561370.0, -2.1420419e-7, 0.38085938, -0.007003784, -37748736.0, -6448.0, 28.25, -6.703125, -4.483364, -3.1757812, 0.000003915804, -0.020751953, 0.00011110306, -0.000053405256, 0.00019985437, -35.40625, 0.005859375, 0.0078125, 28.25, 30.0, -0.20776367, -144.0, -0.109375, -6144.0, ]; let common_values = &[ (0.0, 5098), (-0.0, 4891), (1.0, 2559), (-1.0, 2528), (0.5, 2362), (-2.0, 2312), (-1.5, 2306), (2.0, 2304), (1.5, 2275), (-0.5, 2243), (-3.0, 2204), (-4.0, 2163), (-0.25, 2129), (0.75, 2103), (3.0, 2081), (0.25, 2070), (-0.75, 2047), (4.0, 2038), (-6.0, 1943), (-8.0, 1918), ]; let sample_median = (0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(-8.736310580536276e31), standard_deviation: NiceFloat(6.494074857946111e34), skewness: NiceFloat(-779.0012319222365), excess_kurtosis: NiceFloat(633402.0042901832), }; special_random_finite_primitive_floats_helper::( 10, 1, 10, 1, 1, 100, values, common_values, sample_median, sample_moment_stats, ); // f64, mean abs of exponent = 1/64, mean precision = 65/64, mean zero P = 1/4 let values = &[ 0.0, 1.0, 1.0, -0.0, 1.0, -1.0, 0.0, -1.0, 0.0, -0.0, -1.0, -0.0, -1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 0.5, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 0.0, -1.5, -0.0, 0.0, -1.0, 1.0, -1.0, -1.0, -1.0, 0.0, 1.0, -1.0, -0.5, -1.0, -0.0, 0.0, 0.0, 1.0, ]; let common_values = &[ (1.0, 358244), (-1.0, 357926), (0.0, 125637), (-0.0, 124572), (2.0, 5538), (1.5, 5500), (0.5, 5497), (-1.5, 5454), (-2.0, 5379), (-0.5, 5357), (0.75, 102), (3.0, 98), (-4.0, 95), (-0.25, 91), (-0.75, 87), (-3.0, 86), (0.25, 79), (4.0, 75), (-1.25, 48), (1.75, 44), ]; let sample_median = (0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(0.0007401249999999665), standard_deviation: NiceFloat(0.8901654924701277), skewness: NiceFloat(-0.00169030138949471), excess_kurtosis: NiceFloat(-1.371049776159086), }; special_random_finite_primitive_floats_helper::( 1, 64, 65, 64, 1, 4, values, common_values, sample_median, sample_moment_stats, ); // f64, mean abs of exponent = 1, mean precision = 2, mean zero P = 1/10 let values = &[ 1.0, 1.25, 3.0, 0.0, -1.0, -1.0, -2.0, -3.5, 1.0, 2.0, -1.5, -2.5, -2.0, -0.0, -6.5, -1.0, -1.0, 0.0, 3.0, -0.21875, -1.0, 0.25, 1.5, 5.25, -4.0, 7.0, -0.5, 0.1875, 1.25, 0.0, -0.1875, -7.5, -0.0, 0.75, -7.0, -6.0, -3.0, 0.234375, -2.0, -0.875, -0.75, 6.0, -24.0, 24.0, -2.0, 1.5, -0.0, -1.25, 14.0, 5.0, ]; let common_values = &[ (1.0, 74789), (-1.0, 74702), (0.0, 50351), (-0.0, 49873), (1.5, 38119), (-0.5, 37713), (2.0, 37640), (-1.5, 37613), (-2.0, 37333), (0.5, 37027), (0.75, 19050), (4.0, 18892), (0.25, 18875), (-3.0, 18866), (3.0, 18821), (-0.75, 18725), (-4.0, 18663), (-0.25, 18537), (0.125, 9445), (-0.375, 9395), ]; let sample_median = (0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(-0.8271329178933905), standard_deviation: NiceFloat(427.372166726293), skewness: NiceFloat(-141.119016305626), excess_kurtosis: NiceFloat(144205.19930780405), }; special_random_finite_primitive_floats_helper::( 1, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f64, mean abs of exponent = 10, mean precision = 10, mean zero P = 1/100 let values = &[ 0.7709910366684198, 1.2504315236583352e-6, 0.00830078125, -0.8125, -85504.0, -0.0078125, -0.018890380859375, 2.5721821784973145, 5.75, -0.00003814697265625, -0.4375, -24064.0, -43008.0, -1.75, -54.6875, 0.4641265869140625, -0.0014760522753931582, -1536.0, 0.1484375, 0.00146484375, 1.9383151084184647e-8, -0.060546875, 7340032.0, -0.1982421875, 203.0546875, 4.57177734375, -1555162.0, -2.0675361156463623e-7, 0.279296875, -0.0045928955078125, -46137344.0, -5712.0, 17.75, -5.265625, -7.966220855712891, -2.99609375, 5.397188942879438e-6, -0.017333984375, 0.00011491775512695312, -0.00005845972555107437, 0.00020831823348999023, -46.78125, 0.005859375, 0.0078125, 27.25, 30.0, -0.175537109375, -208.0, -0.109375, -6144.0, ]; let common_values = &[ (0.0, 5098), (-0.0, 4891), (1.0, 2396), (-1.0, 2336), (-2.0, 2200), (-1.5, 2169), (0.5, 2116), (2.0, 2108), (-0.5, 2101), (1.5, 2085), (-3.0, 2000), (4.0, 1993), (3.0, 1969), (-0.25, 1955), (0.75, 1946), (0.25, 1917), (-4.0, 1882), (-0.75, 1863), (8.0, 1826), (-6.0, 1782), ]; let sample_median = (0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(-7.053229374417263e38), standard_deviation: NiceFloat(7.053232003373143e41), skewness: NiceFloat(-999.9984999989927), excess_kurtosis: NiceFloat(999995.0000005187), }; special_random_finite_primitive_floats_helper::( 10, 1, 10, 1, 1, 100, values, common_values, sample_median, sample_moment_stats, ); } fn special_random_finite_primitive_floats_fail_helper() { assert_panic!(special_random_finite_primitive_floats::( EXAMPLE_SEED, 0, 1, 10, 1, 1, 10 )); assert_panic!(special_random_finite_primitive_floats::( EXAMPLE_SEED, 1, 0, 10, 1, 1, 10 )); assert_panic!(special_random_finite_primitive_floats::( EXAMPLE_SEED, 10, 1, 1, 1, 1, 10 )); assert_panic!(special_random_finite_primitive_floats::( EXAMPLE_SEED, 10, 1, 1, 0, 1, 10 )); assert_panic!(special_random_finite_primitive_floats::( EXAMPLE_SEED, 10, 1, 10, 1, 1, 0 )); assert_panic!(special_random_finite_primitive_floats::( EXAMPLE_SEED, 10, 1, 10, 1, 2, 1 )); } #[test] fn special_random_finite_primitive_floats_fail() { apply_fn_to_primitive_floats!(special_random_finite_primitive_floats_fail_helper); } malachite-base-0.4.16/tests/num/random/special_random_negative_finite_primitive_floats.rs000064400000000000000000000305171046102023000302100ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::special_random_negative_finite_primitive_floats; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::num::random::special_random_primitive_floats_helper_helper; use malachite_base::test_util::stats::moments::{CheckedToF64, MomentStats}; use std::panic::catch_unwind; fn special_random_negative_finite_primitive_floats_helper( mean_exponent_numerator: u64, mean_exponent_denominator: u64, mean_precision_numerator: u64, mean_precision_denominator: u64, expected_values: &[T], expected_common_values: &[(T, usize)], expected_median: (T, Option), expected_moment_stats: MomentStats, ) { special_random_primitive_floats_helper_helper( special_random_negative_finite_primitive_floats::( EXAMPLE_SEED, mean_exponent_numerator, mean_exponent_denominator, mean_precision_numerator, mean_precision_denominator, ), expected_values, expected_common_values, expected_median, expected_moment_stats, ); } #[test] fn test_special_random_negative_finite_primitive_floats() { // f32, mean abs of exponent = 1/64, mean precision = 65/64 let values = &[ -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -0.5, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -0.5, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, ]; let common_values = &[ (-1.0, 954991), (-1.5, 14672), (-2.0, 14586), (-0.5, 14578), (-3.0, 243), (-0.25, 228), (-4.0, 226), (-0.75, 207), (-1.25, 127), (-1.75, 118), (-6.0, 6), (-0.125, 4), (-2.5, 3), (-8.0, 3), (-0.625, 3), (-0.375, 2), (-0.875, 2), (-3.5, 1), ]; let sample_median = (-1.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(-1.0157463749999305), standard_deviation: NiceFloat(0.15870215416222863), skewness: NiceFloat(-5.805128395366302), excess_kurtosis: NiceFloat(73.03005686221248), }; special_random_negative_finite_primitive_floats_helper::( 1, 64, 65, 64, values, common_values, sample_median, sample_moment_stats, ); // f32, mean abs of exponent = 1, mean precision = 2 let values = &[ -1.0, -1.5, -3.125, -1.0, -1.0, -2.0, -2.0, -1.0, -3.0, -1.0, -2.0, -3.0, -4.0, -1.5, -1.625, -2.0, -0.125, -1.0, -0.375, -1.5, -6.375, -4.0, -6.875, -0.5, -0.234375, -1.0, -0.2421875, -6.0, -0.75, -6.0, -6.0, -2.0, -0.21875, -2.0, -0.875, -0.875, -6.0, -16.0, -27.0, -2.25, -1.5, -1.5, -8.75, -4.0, -0.25, -1.5, -0.375, -0.375, -1.0, -0.09375, ]; let common_values = &[ (-1.0, 166355), (-2.0, 83686), (-0.5, 83270), (-1.5, 82925), (-3.0, 41733), (-0.75, 41659), (-4.0, 41550), (-0.25, 41388), (-1.75, 21006), (-6.0, 20858), (-0.125, 20779), (-8.0, 20769), (-0.375, 20764), (-1.25, 20753), (-12.0, 10512), (-2.5, 10508), (-0.0625, 10447), (-0.625, 10414), (-0.1875, 10394), (-16.0, 10354), ]; let sample_median = (-1.03125, None); let sample_moment_stats = MomentStats { mean: NiceFloat(-7.654060290573151), standard_deviation: NiceFloat(374.2183970257817), skewness: NiceFloat(-257.0774178486101), excess_kurtosis: NiceFloat(79059.24924350459), }; special_random_negative_finite_primitive_floats_helper::( 1, 1, 2, 1, values, common_values, sample_median, sample_moment_stats, ); // f32, mean abs of exponent = 10, mean precision = 10 let values = &[ -0.80126953, -0.0000013709068, -0.015609741, -0.98552704, -65536.0, -0.008257866, -0.017333984, -2.25, -7.7089844, -0.00004425831, -0.40625, -24576.0, -37249.0, -1.1991882, -32.085938, -0.4375, -0.0012359619, -1536.0, -0.22912993, -0.0015716553, -1.6662057e-8, -0.044523954, -5694464.0, -0.125, -180.0, -5.625, -1572864.0, -1.9092113e-7, -0.28466797, -0.0068359375, -56737790.0, -4813.375, -20.954966, -4.0, -7.3125, -3.6040926, -0.000007293769, -0.018554688, -0.00009602308, -0.000038146973, -0.00022888184, -36.324017, -0.0068359375, -0.008168057, -20.0, -21.398438, -0.21679688, -176.0, -0.11355591, -6144.0, ]; let common_values = &[ (-1.0, 5117), (-1.5, 4684), (-2.0, 4643), (-0.5, 4592), (-3.0, 4327), (-0.75, 4245), (-0.25, 4231), (-4.0, 4186), (-8.0, 3995), (-0.375, 3923), (-6.0, 3869), (-0.125, 3864), (-0.0625, 3534), (-16.0, 3502), (-0.1875, 3489), (-12.0, 3418), (-24.0, 3293), (-32.0, 3244), (-0.09375, 3209), (-0.03125, 3152), ]; let sample_median = (-1.4882812, None); let sample_moment_stats = MomentStats { mean: NiceFloat(-7.110316815188854e31), standard_deviation: NiceFloat(5.291057687231236e34), skewness: NiceFloat(-817.3228282694379), excess_kurtosis: NiceFloat(702102.631759681), }; special_random_negative_finite_primitive_floats_helper::( 10, 1, 10, 1, values, common_values, sample_median, sample_moment_stats, ); // f64, mean abs of exponent = 1/64, mean precision = 65/64 let values = &[ -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -0.5, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -0.5, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, ]; let common_values = &[ (-1.0, 954991), (-1.5, 14672), (-2.0, 14586), (-0.5, 14578), (-3.0, 243), (-0.25, 228), (-4.0, 226), (-0.75, 207), (-1.25, 127), (-1.75, 118), (-6.0, 6), (-0.125, 4), (-2.5, 3), (-8.0, 3), (-0.625, 3), (-0.375, 2), (-0.875, 2), (-3.5, 1), ]; let sample_median = (-1.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(-1.0157463749999305), standard_deviation: NiceFloat(0.15870215416222863), skewness: NiceFloat(-5.805128395366302), excess_kurtosis: NiceFloat(73.03005686221248), }; special_random_negative_finite_primitive_floats_helper::( 1, 64, 65, 64, values, common_values, sample_median, sample_moment_stats, ); // f64, mean abs of exponent = 1, mean precision = 2 let values = &[ -1.0, -1.5, -3.125, -1.0, -1.0, -2.0, -2.0, -1.0, -3.0, -1.0, -2.0, -3.0, -4.0, -1.5, -1.625, -2.0, -0.125, -1.0, -0.375, -1.5, -6.375, -4.0, -6.875, -0.5, -0.234375, -1.0, -0.2421875, -6.0, -0.75, -6.0, -6.0, -2.0, -0.21875, -2.0, -0.875, -0.875, -6.0, -16.0, -27.0, -2.25, -1.5, -1.5, -8.75, -4.0, -0.25, -1.5, -0.375, -0.375, -1.0, -0.09375, ]; let common_values = &[ (-1.0, 166355), (-2.0, 83686), (-0.5, 83270), (-1.5, 82925), (-3.0, 41733), (-0.75, 41659), (-4.0, 41550), (-0.25, 41388), (-1.75, 21006), (-6.0, 20858), (-0.125, 20779), (-8.0, 20769), (-0.375, 20764), (-1.25, 20753), (-12.0, 10512), (-2.5, 10508), (-0.0625, 10447), (-0.625, 10414), (-0.1875, 10394), (-16.0, 10354), ]; let sample_median = (-1.03125, None); let sample_moment_stats = MomentStats { mean: NiceFloat(-7.654060290573151), standard_deviation: NiceFloat(374.2183970257817), skewness: NiceFloat(-257.0774178486101), excess_kurtosis: NiceFloat(79059.24924350459), }; special_random_negative_finite_primitive_floats_helper::( 1, 1, 2, 1, values, common_values, sample_median, sample_moment_stats, ); // f64, mean abs of exponent = 10, mean precision = 10 let values = &[ -0.80126953125, -1.3709068298339844e-6, -0.0156097412109375, -0.9855270385742188, -86113.82421875, -0.012808799743652344, -0.028076171875, -2.75, -7.009765625, -0.000045569613575935364, -0.34375, -24576.0, -33101.0, -1.066680908203125, -53.0390625, -0.3125, -0.0018768310546875, -1536.0, -0.15994291007518768, -0.0014495849609375, -2.5660824576334562e-8, -0.04374957084655762, -6583296.0, -0.125, -156.0, -7.125, -1572864.0, -1.525198978780118e-7, -0.32763671875, -0.0048828125, -47710208.0, -6821.875, -19.824071884155273, -4.0, -4.6875, -2.3686094284057617, -6.33427407592535e-6, -0.0185546875, -0.00007218122482299805, -0.00003814697265625, -0.0001373291015625, -36.43232345581055, -0.0048828125, -0.011424465501870706, -28.0, -18.0546875, -0.2207733978284523, -144.0, -0.083648681640625, -4360.2293701171875, ]; let common_values = &[ (-1.0, 4779), (-1.5, 4356), (-2.0, 4315), (-0.5, 4233), (-3.0, 4023), (-0.25, 3931), (-0.75, 3911), (-4.0, 3866), (-8.0, 3705), (-0.375, 3612), (-6.0, 3588), (-0.125, 3538), (-0.0625, 3271), (-16.0, 3264), (-0.1875, 3199), (-12.0, 3152), (-24.0, 3033), (-32.0, 2974), (-0.09375, 2963), (-0.03125, 2937), ]; let sample_median = (-1.484375, None); let sample_moment_stats = MomentStats { mean: NiceFloat(-5.352183416672257e38), standard_deviation: NiceFloat(5.3521788476440196e41), skewness: NiceFloat(-999.9984999986674), excess_kurtosis: NiceFloat(999995.0000000936), }; special_random_negative_finite_primitive_floats_helper::( 10, 1, 10, 1, values, common_values, sample_median, sample_moment_stats, ); } fn special_random_negative_finite_primitive_floats_fail_helper() { assert_panic!(special_random_negative_finite_primitive_floats::( EXAMPLE_SEED, 0, 1, 10, 1 )); assert_panic!(special_random_negative_finite_primitive_floats::( EXAMPLE_SEED, 1, 0, 10, 1 )); assert_panic!(special_random_negative_finite_primitive_floats::( EXAMPLE_SEED, 10, 1, 1, 1 )); assert_panic!(special_random_negative_finite_primitive_floats::( EXAMPLE_SEED, 10, 1, 1, 0 )); } #[test] fn special_random_negative_finite_primitive_floats_fail() { apply_fn_to_primitive_floats!(special_random_negative_finite_primitive_floats_fail_helper); } malachite-base-0.4.16/tests/num/random/special_random_negative_primitive_floats.rs000064400000000000000000000332541046102023000266530ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::traits::NegativeInfinity; use malachite_base::num::random::special_random_negative_primitive_floats; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::num::random::special_random_primitive_floats_helper_helper; use malachite_base::test_util::stats::moments::{CheckedToF64, MomentStats, NAN_MOMENT_STATS}; use std::panic::catch_unwind; fn special_random_negative_primitive_floats_helper( mean_exponent_numerator: u64, mean_exponent_denominator: u64, mean_precision_numerator: u64, mean_precision_denominator: u64, mean_special_p_numerator: u64, mean_special_p_denominator: u64, expected_values: &[T], expected_common_values: &[(T, usize)], expected_median: (T, Option), expected_moment_stats: MomentStats, ) { special_random_primitive_floats_helper_helper( special_random_negative_primitive_floats::( EXAMPLE_SEED, mean_exponent_numerator, mean_exponent_denominator, mean_precision_numerator, mean_precision_denominator, mean_special_p_numerator, mean_special_p_denominator, ), expected_values, expected_common_values, expected_median, expected_moment_stats, ); } #[test] fn test_special_random_negative_primitive_floats() { // f32, mean abs of exponent = 1/64, mean precision = 65/64, mean special P = 1/4 let values = &[ f32::NEGATIVE_INFINITY, -1.5, -1.0, f32::NEGATIVE_INFINITY, -1.0, -1.0, f32::NEGATIVE_INFINITY, -1.0, f32::NEGATIVE_INFINITY, f32::NEGATIVE_INFINITY, -1.0, f32::NEGATIVE_INFINITY, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -0.5, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, f32::NEGATIVE_INFINITY, -1.0, f32::NEGATIVE_INFINITY, f32::NEGATIVE_INFINITY, -1.0, -1.0, -1.0, -1.0, -1.0, f32::NEGATIVE_INFINITY, -1.0, -1.0, -0.5, -1.0, f32::NEGATIVE_INFINITY, f32::NEGATIVE_INFINITY, f32::NEGATIVE_INFINITY, -1.0, ]; let common_values = &[ (-1.0, 716268), (f32::NEGATIVE_INFINITY, 250209), (-2.0, 10938), (-0.5, 10888), (-1.5, 10871), (-4.0, 172), (-0.25, 165), (-3.0, 161), (-0.75, 155), (-1.25, 75), (-1.75, 74), (-0.375, 6), (-3.5, 4), (-0.125, 4), (-8.0, 3), (-0.875, 2), (-1.875, 2), (-6.0, 1), (-0.625, 1), (-1.125, 1), ]; let sample_median = (-1.0, None); special_random_negative_primitive_floats_helper::( 1, 64, 65, 64, 1, 4, values, common_values, sample_median, NAN_MOMENT_STATS, ); // f32, mean abs of exponent = 1, mean precision = 2, mean special P = 1/10 let values = &[ -1.0, -1.0, -3.0, f32::NEGATIVE_INFINITY, -1.0, -1.0, -2.0, -2.0, -1.0, -3.0, -1.0, -3.0, -3.0, f32::NEGATIVE_INFINITY, -6.0, -1.125, -1.25, f32::NEGATIVE_INFINITY, -3.0, -0.125, -1.0, -0.25, -1.75, -4.0, -4.0, -4.0, -0.75, -0.125, -1.0, f32::NEGATIVE_INFINITY, -0.125, -6.0, f32::NEGATIVE_INFINITY, -0.5, -4.0, -6.5, -2.0, -0.21875, -2.0, -0.5, -0.5, -4.0, -16.0, -16.0, -3.0, -1.0, f32::NEGATIVE_INFINITY, -1.0, -10.0, -6.0, ]; let common_values = &[ (-1.0, 151036), (f32::NEGATIVE_INFINITY, 100224), (-0.5, 75239), (-2.0, 74939), (-1.5, 74396), (-0.25, 37669), (-0.75, 37538), (-3.0, 37523), (-4.0, 37411), (-0.375, 18737), (-6.0, 18708), (-0.125, 18698), (-1.25, 18586), (-8.0, 18570), (-1.75, 18339), (-3.5, 9676), (-0.0625, 9668), (-16.0, 9474), (-0.875, 9416), (-12.0, 9376), ]; let sample_median = (-1.5, None); special_random_negative_primitive_floats_helper::( 1, 1, 2, 1, 1, 10, values, common_values, sample_median, NAN_MOMENT_STATS, ); // f32, mean abs of exponent = 10, mean precision = 10, mean special P = 1/100 let values = &[ -0.6328125, -9.536743e-7, -0.013671875, -0.6875, -70208.0, -0.01550293, -0.028625488, -3.3095703, -5.775879, -0.000034958124, -0.4375, -31678.0, -49152.0, -1.0, -49.885254, -0.40625, -0.0015869141, -1889.5625, -0.14140439, -0.001449585, -1.4901161e-8, -0.03125, -5750784.0, -0.17578125, -248.0, -5.4375, -1892352.0, -1.5280966e-7, -0.2826419, -0.0057373047, -51642370.0, -6384.0, -27.875542, -6.152041, -6.0, -2.796875, -0.0000057816505, -0.029174805, -0.00011384487, -0.000039815903, -0.00012207031, -48.0, -0.00390625, -0.01171875, -20.0, -21.625, -0.171875, -197.0, -0.11743164, -5532.0, ]; let common_values = &[ (f32::NEGATIVE_INFINITY, 9989), (-1.0, 5059), (-2.0, 4689), (-0.5, 4622), (-1.5, 4576), (-4.0, 4280), (-3.0, 4153), (-0.25, 4130), (-0.75, 4105), (-8.0, 3912), (-6.0, 3841), (-0.125, 3772), (-0.375, 3663), (-16.0, 3536), (-0.1875, 3530), (-0.0625, 3441), (-12.0, 3433), (-0.09375, 3185), (-0.03125, 3176), (-32.0, 3094), ]; let sample_median = (-1.5, None); special_random_negative_primitive_floats_helper::( 10, 1, 10, 1, 1, 100, values, common_values, sample_median, NAN_MOMENT_STATS, ); // f64, mean abs of exponent = 1/64, mean precision = 65/64, mean special P = 1/4 let values = &[ f64::NEGATIVE_INFINITY, -1.5, -1.0, f64::NEGATIVE_INFINITY, -1.0, -1.0, f64::NEGATIVE_INFINITY, -1.0, f64::NEGATIVE_INFINITY, f64::NEGATIVE_INFINITY, -1.0, f64::NEGATIVE_INFINITY, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -0.5, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, f64::NEGATIVE_INFINITY, -1.0, f64::NEGATIVE_INFINITY, f64::NEGATIVE_INFINITY, -1.0, -1.0, -1.0, -1.0, -1.0, f64::NEGATIVE_INFINITY, -1.0, -1.0, -0.5, -1.0, f64::NEGATIVE_INFINITY, f64::NEGATIVE_INFINITY, f64::NEGATIVE_INFINITY, -1.0, ]; let common_values = &[ (-1.0, 716268), (f64::NEGATIVE_INFINITY, 250209), (-2.0, 10938), (-0.5, 10888), (-1.5, 10871), (-4.0, 172), (-0.25, 165), (-3.0, 161), (-0.75, 155), (-1.25, 75), (-1.75, 74), (-0.375, 6), (-3.5, 4), (-0.125, 4), (-8.0, 3), (-0.875, 2), (-1.875, 2), (-6.0, 1), (-0.625, 1), (-1.125, 1), ]; let sample_median = (-1.0, None); special_random_negative_primitive_floats_helper::( 1, 64, 65, 64, 1, 4, values, common_values, sample_median, NAN_MOMENT_STATS, ); // f64, mean abs of exponent = 1, mean precision = 2, mean special P = 1/10 let values = &[ -1.0, -1.0, -3.0, f64::NEGATIVE_INFINITY, -1.0, -1.0, -2.0, -2.0, -1.0, -3.0, -1.0, -3.0, -3.0, f64::NEGATIVE_INFINITY, -6.0, -1.125, -1.25, f64::NEGATIVE_INFINITY, -3.0, -0.125, -1.0, -0.25, -1.75, -4.0, -4.0, -4.0, -0.75, -0.125, -1.0, f64::NEGATIVE_INFINITY, -0.125, -6.0, f64::NEGATIVE_INFINITY, -0.5, -4.0, -6.5, -2.0, -0.21875, -2.0, -0.5, -0.5, -4.0, -16.0, -16.0, -3.0, -1.0, f64::NEGATIVE_INFINITY, -1.0, -10.0, -6.0, ]; let common_values = &[ (-1.0, 151036), (f64::NEGATIVE_INFINITY, 100224), (-0.5, 75239), (-2.0, 74939), (-1.5, 74396), (-0.25, 37669), (-0.75, 37538), (-3.0, 37523), (-4.0, 37411), (-0.375, 18737), (-6.0, 18708), (-0.125, 18698), (-1.25, 18586), (-8.0, 18570), (-1.75, 18339), (-3.5, 9676), (-0.0625, 9668), (-16.0, 9474), (-0.875, 9416), (-12.0, 9376), ]; let sample_median = (-1.5, None); special_random_negative_primitive_floats_helper::( 1, 1, 2, 1, 1, 10, values, common_values, sample_median, NAN_MOMENT_STATS, ); // f64, mean abs of exponent = 10, mean precision = 10, mean special P = 1/100 let values = &[ -0.6328125, -9.5367431640625e-7, -0.013671875, -0.6875, -70208.0, -0.0155029296875, -0.02862548828125, -3.3095703125, -5.77587890625, -0.0000349581241607666, -0.4375, -31678.0, -49152.0, -1.0, -49.88525390625, -0.40625, -0.0015869140625, -1889.5625, -0.141404390335083, -0.0014495849609375, -1.4901161193847656e-8, -0.03125, -5750784.0, -0.17578125, -248.0, -5.4375, -1892352.0, -1.528096618130803e-7, -0.2826418876647949, -0.0057373046875, -51642368.0, -6384.0, -27.87554168701172, -6.152040958404541, -6.0, -2.796875, -5.781650543212891e-6, -0.0291748046875, -0.0001138448715209961, -0.00003981590270996094, -0.0001220703125, -48.0, -0.00390625, -0.01171875, -20.0, -21.625, -0.171875, -205.175663292408, -0.118408203125, -6436.0, ]; let common_values = &[ (f64::NEGATIVE_INFINITY, 9989), (-1.0, 4750), (-2.0, 4357), (-0.5, 4257), (-1.5, 4256), (-4.0, 3955), (-3.0, 3844), (-0.25, 3812), (-0.75, 3799), (-8.0, 3628), (-6.0, 3535), (-0.125, 3447), (-0.375, 3398), (-16.0, 3257), (-0.1875, 3234), (-12.0, 3202), (-0.0625, 3182), (-0.09375, 2957), (-0.03125, 2919), (-32.0, 2805), ]; let sample_median = (-1.516387939453125, Some(-1.5162887573242188)); special_random_negative_primitive_floats_helper::( 10, 1, 10, 1, 1, 100, values, common_values, sample_median, NAN_MOMENT_STATS, ); } fn special_random_negative_primitive_floats_fail_helper() { assert_panic!(special_random_negative_primitive_floats::( EXAMPLE_SEED, 0, 1, 10, 1, 1, 10 )); assert_panic!(special_random_negative_primitive_floats::( EXAMPLE_SEED, 1, 0, 10, 1, 1, 10 )); assert_panic!(special_random_negative_primitive_floats::( EXAMPLE_SEED, 10, 1, 1, 1, 1, 10 )); assert_panic!(special_random_negative_primitive_floats::( EXAMPLE_SEED, 10, 1, 1, 0, 1, 10 )); assert_panic!(special_random_negative_primitive_floats::( EXAMPLE_SEED, 10, 1, 10, 1, 1, 0 )); assert_panic!(special_random_negative_primitive_floats::( EXAMPLE_SEED, 10, 1, 10, 1, 2, 1 )); } #[test] fn special_random_negative_primitive_floats_fail() { apply_fn_to_primitive_floats!(special_random_negative_primitive_floats_fail_helper); } malachite-base-0.4.16/tests/num/random/special_random_nonzero_finite_primitive_floats.rs000064400000000000000000000301301046102023000300670ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::special_random_nonzero_finite_primitive_floats; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::num::random::special_random_primitive_floats_helper_helper; use malachite_base::test_util::stats::moments::{CheckedToF64, MomentStats}; use std::panic::catch_unwind; fn special_random_nonzero_finite_primitive_floats_helper( mean_exponent_numerator: u64, mean_exponent_denominator: u64, mean_precision_numerator: u64, mean_precision_denominator: u64, expected_values: &[T], expected_common_values: &[(T, usize)], expected_median: (T, Option), expected_moment_stats: MomentStats, ) { special_random_primitive_floats_helper_helper( special_random_nonzero_finite_primitive_floats::( EXAMPLE_SEED, mean_exponent_numerator, mean_exponent_denominator, mean_precision_numerator, mean_precision_denominator, ), expected_values, expected_common_values, expected_median, expected_moment_stats, ); } #[test] fn test_special_random_nonzero_finite_primitive_floats() { // f32, mean abs of exponent = 1/64, mean precision = 65/64 let values = &[ -1.5, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -0.5, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 0.5, -1.0, 1.0, -1.5, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, 1.5, 1.0, -1.0, 1.0, 1.0, 1.0, ]; let common_values = &[ (1.0, 478216), (-1.0, 476955), (-2.0, 7440), (-1.5, 7332), (0.5, 7303), (-0.5, 7275), (1.5, 7189), (2.0, 7170), (0.25, 120), (4.0, 116), (-4.0, 114), (3.0, 111), (-3.0, 107), (0.75, 105), (-0.25, 103), (-0.75, 103), (-1.25, 62), (1.75, 61), (1.25, 50), (-1.75, 39), ]; let sample_median = (0.5, None); let sample_moment_stats = MomentStats { mean: NiceFloat(0.000541124999999992), standard_deviation: NiceFloat(1.0278732889234226), skewness: NiceFloat(-0.0043076036065952585), excess_kurtosis: NiceFloat(-1.7844456265500606), }; special_random_nonzero_finite_primitive_floats_helper::( 1, 64, 65, 64, values, common_values, sample_median, sample_moment_stats, ); // f32, mean abs of exponent = 1, mean precision = 2 let values = &[ -1.0, -1.0, -3.0, 1.0, -1.0, 2.0, -2.0, -1.0, -3.0, 1.0, 3.0, 3.0, -6.0, -1.125, 1.25, -3.0, -0.125, -1.0, -0.25, -1.75, 4.0, 4.0, -4.0, -0.75, 0.125, -1.0, -0.125, 6.0, 0.5, -4.0, -6.5, 2.0, -0.21875, 2.0, 0.5, -0.5, 4.0, -16.0, 16.0, -3.0, 1.0, 1.0, 10.0, -6.0, 0.25, 1.0, -0.390625, 0.375, 1.5, 0.09375, ]; let common_values = &[ (1.0, 84345), (-1.0, 83427), (-0.5, 42050), (2.0, 41730), (-2.0, 41718), (0.5, 41631), (1.5, 41446), (-1.5, 41312), (3.0, 20932), (-0.25, 20908), (-3.0, 20854), (-0.75, 20853), (-4.0, 20831), (0.25, 20819), (0.75, 20775), (4.0, 20696), (0.125, 10518), (0.375, 10492), (-6.0, 10471), (8.0, 10359), ]; let sample_median = (0.001953125, None); let sample_moment_stats = MomentStats { mean: NiceFloat(-0.14825837830007416), standard_deviation: NiceFloat(371.086277437807), skewness: NiceFloat(-124.2604097831067), excess_kurtosis: NiceFloat(123898.81502837151), }; special_random_nonzero_finite_primitive_floats_helper::( 1, 1, 2, 1, values, common_values, sample_median, sample_moment_stats, ); // f32, mean abs of exponent = 10, mean precision = 10 let values = &[ -0.6328125, -9.536743e-7, -0.013671875, 0.6875, -70208.0, 0.01550293, -0.028625488, -3.3095703, -5.775879, 0.000034958124, 0.4375, 31678.0, -49152.0, -1.0, 49.885254, -0.40625, -0.0015869141, -1889.5625, -0.14140439, -0.001449585, 1.4901161e-8, 0.03125, -5750784.0, -0.17578125, 248.0, -5.4375, -1892352.0, 1.5280966e-7, 0.2826419, -0.0057373047, -51642370.0, 6384.0, -27.875542, 6.152041, 6.0, -2.796875, 0.0000057816505, -0.029174805, 0.00011384487, -0.000039815903, 0.00012207031, 48.0, 0.00390625, -0.01171875, 20.0, 21.625, -0.171875, 197.0, 0.11743164, 5532.0, ]; let common_values = &[ (-1.0, 2552), (1.0, 2548), (2.0, 2409), (-0.5, 2367), (-2.0, 2335), (1.5, 2326), (0.5, 2308), (-1.5, 2290), (-4.0, 2193), (4.0, 2130), (-3.0, 2106), (3.0, 2096), (0.25, 2092), (-0.25, 2085), (-0.75, 2084), (0.75, 2065), (8.0, 2008), (6.0, 1972), (-8.0, 1945), (-0.125, 1922), ]; let sample_median = (1.6940659e-20, None); let sample_moment_stats = MomentStats { mean: NiceFloat(-3.7799889499291132e31), standard_deviation: NiceFloat(6.206676176137639e34), skewness: NiceFloat(-784.8389177089807), excess_kurtosis: NiceFloat(789333.7989913624), }; special_random_nonzero_finite_primitive_floats_helper::( 10, 1, 10, 1, values, common_values, sample_median, sample_moment_stats, ); // f64, mean abs of exponent = 1/64, mean precision = 65/64 let values = &[ -1.5, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -0.5, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 0.5, -1.0, 1.0, -1.5, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, 1.5, 1.0, -1.0, 1.0, 1.0, 1.0, ]; let common_values = &[ (1.0, 478216), (-1.0, 476955), (-2.0, 7440), (-1.5, 7332), (0.5, 7303), (-0.5, 7275), (1.5, 7189), (2.0, 7170), (0.25, 120), (4.0, 116), (-4.0, 114), (3.0, 111), (-3.0, 107), (0.75, 105), (-0.25, 103), (-0.75, 103), (-1.25, 62), (1.75, 61), (1.25, 50), (-1.75, 39), ]; let sample_median = (0.5, None); let sample_moment_stats = MomentStats { mean: NiceFloat(0.000541124999999992), standard_deviation: NiceFloat(1.0278732889234226), skewness: NiceFloat(-0.0043076036065952585), excess_kurtosis: NiceFloat(-1.7844456265500606), }; special_random_nonzero_finite_primitive_floats_helper::( 1, 64, 65, 64, values, common_values, sample_median, sample_moment_stats, ); // f64, mean abs of exponent = 1, mean precision = 2 let values = &[ -1.0, -1.0, -3.0, 1.0, -1.0, 2.0, -2.0, -1.0, -3.0, 1.0, 3.0, 3.0, -6.0, -1.125, 1.25, -3.0, -0.125, -1.0, -0.25, -1.75, 4.0, 4.0, -4.0, -0.75, 0.125, -1.0, -0.125, 6.0, 0.5, -4.0, -6.5, 2.0, -0.21875, 2.0, 0.5, -0.5, 4.0, -16.0, 16.0, -3.0, 1.0, 1.0, 10.0, -6.0, 0.25, 1.0, -0.390625, 0.375, 1.5, 0.09375, ]; let common_values = &[ (1.0, 84345), (-1.0, 83427), (-0.5, 42050), (2.0, 41730), (-2.0, 41718), (0.5, 41631), (1.5, 41446), (-1.5, 41312), (3.0, 20932), (-0.25, 20908), (-3.0, 20854), (-0.75, 20853), (-4.0, 20831), (0.25, 20819), (0.75, 20775), (4.0, 20696), (0.125, 10518), (0.375, 10492), (-6.0, 10471), (8.0, 10359), ]; let sample_median = (0.001953125, None); let sample_moment_stats = MomentStats { mean: NiceFloat(-0.14825837830007416), standard_deviation: NiceFloat(371.086277437807), skewness: NiceFloat(-124.2604097831067), excess_kurtosis: NiceFloat(123898.81502837151), }; special_random_nonzero_finite_primitive_floats_helper::( 1, 1, 2, 1, values, common_values, sample_median, sample_moment_stats, ); // f64, mean abs of exponent = 10, mean precision = 10 let values = &[ -0.6328125, -9.5367431640625e-7, -0.013671875, 0.6875, -70208.0, 0.0155029296875, -0.02862548828125, -3.3095703125, -5.77587890625, 0.0000349581241607666, 0.4375, 31678.0, -49152.0, -1.0, 49.88525390625, -0.40625, -0.0015869140625, -1889.5625, -0.141404390335083, -0.0014495849609375, 1.4901161193847656e-8, 0.03125, -5750784.0, -0.17578125, 248.0, -5.4375, -1892352.0, 1.528096618130803e-7, 0.2826418876647949, -0.0057373046875, -51642368.0, 6384.0, -27.87554168701172, 6.152040958404541, 6.0, -2.796875, 5.781650543212891e-6, -0.0291748046875, 0.0001138448715209961, -0.00003981590270996094, 0.0001220703125, 48.0, 0.00390625, -0.01171875, 20.0, 21.625, -0.171875, 205.175663292408, 0.118408203125, 6436.0, ]; let common_values = &[ (-1.0, 2444), (1.0, 2346), (2.0, 2250), (1.5, 2165), (-0.5, 2156), (-2.0, 2155), (0.5, 2150), (-1.5, 2135), (4.0, 2036), (-4.0, 1965), (0.75, 1957), (-0.25, 1953), (3.0, 1950), (-3.0, 1943), (0.25, 1899), (-0.75, 1878), (8.0, 1866), (6.0, 1819), (-8.0, 1804), (0.125, 1779), ]; let sample_median = (2.3597808514912774e-20, Some(2.371692252312041e-20)); let sample_moment_stats = MomentStats { mean: NiceFloat(5.965455610813376e38), standard_deviation: NiceFloat(5.9654493406037485e41), skewness: NiceFloat(999.998499997817), excess_kurtosis: NiceFloat(999994.9999989544), }; special_random_nonzero_finite_primitive_floats_helper::( 10, 1, 10, 1, values, common_values, sample_median, sample_moment_stats, ); } fn special_random_nonzero_finite_primitive_floats_fail_helper() { assert_panic!(special_random_nonzero_finite_primitive_floats::( EXAMPLE_SEED, 0, 1, 10, 1 )); assert_panic!(special_random_nonzero_finite_primitive_floats::( EXAMPLE_SEED, 1, 0, 10, 1 )); assert_panic!(special_random_nonzero_finite_primitive_floats::( EXAMPLE_SEED, 10, 1, 1, 1 )); assert_panic!(special_random_nonzero_finite_primitive_floats::( EXAMPLE_SEED, 10, 1, 1, 0 )); } #[test] fn special_random_nonzero_finite_primitive_floats_fail() { apply_fn_to_primitive_floats!(special_random_nonzero_finite_primitive_floats_fail_helper); } malachite-base-0.4.16/tests/num/random/special_random_nonzero_primitive_floats.rs000064400000000000000000000326001046102023000265350ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::traits::NegativeInfinity; use malachite_base::num::random::special_random_nonzero_primitive_floats; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::num::random::special_random_primitive_floats_helper_helper; use malachite_base::test_util::stats::moments::{CheckedToF64, MomentStats, NAN_MOMENT_STATS}; use std::panic::catch_unwind; fn special_random_nonzero_primitive_floats_helper( mean_exponent_numerator: u64, mean_exponent_denominator: u64, mean_precision_numerator: u64, mean_precision_denominator: u64, mean_special_p_numerator: u64, mean_special_p_denominator: u64, expected_values: &[T], expected_common_values: &[(T, usize)], expected_median: (T, Option), expected_moment_stats: MomentStats, ) { special_random_primitive_floats_helper_helper( special_random_nonzero_primitive_floats::( EXAMPLE_SEED, mean_exponent_numerator, mean_exponent_denominator, mean_precision_numerator, mean_precision_denominator, mean_special_p_numerator, mean_special_p_denominator, ), expected_values, expected_common_values, expected_median, expected_moment_stats, ); } #[test] fn test_special_random_nonzero_primitive_floats() { // f32, mean abs of exponent = 1/64, mean precision = 65/64, mean special P = 1/4 let values = &[ f32::INFINITY, 1.0, 1.0, f32::NEGATIVE_INFINITY, 1.0, -1.0, f32::INFINITY, -1.0, f32::INFINITY, f32::NEGATIVE_INFINITY, -1.0, f32::NEGATIVE_INFINITY, -1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 0.5, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, f32::INFINITY, -1.5, f32::NEGATIVE_INFINITY, f32::INFINITY, -1.0, 1.0, -1.0, -1.0, -1.0, f32::INFINITY, 1.0, -1.0, -0.5, -1.0, f32::NEGATIVE_INFINITY, f32::INFINITY, f32::INFINITY, 1.0, ]; let common_values = &[ (1.0, 358244), (-1.0, 357926), (f32::INFINITY, 125637), (f32::NEGATIVE_INFINITY, 124572), (2.0, 5538), (1.5, 5500), (0.5, 5497), (-1.5, 5454), (-2.0, 5379), (-0.5, 5357), (0.75, 102), (3.0, 98), (-4.0, 95), (-0.25, 91), (-0.75, 87), (-3.0, 86), (0.25, 79), (4.0, 75), (-1.25, 48), (1.75, 44), ]; let sample_median = (0.5, None); special_random_nonzero_primitive_floats_helper::( 1, 64, 65, 64, 1, 4, values, common_values, sample_median, NAN_MOMENT_STATS, ); // f32, mean abs of exponent = 1, mean precision = 2, mean special P = 1/10 let values = &[ 1.0, 1.25, 3.0, f32::INFINITY, -1.0, -1.0, -2.0, -3.5, 1.0, 2.0, -1.5, -2.5, -2.0, f32::NEGATIVE_INFINITY, -6.5, -1.0, -1.0, f32::INFINITY, 3.0, -0.21875, -1.0, 0.25, 1.5, 5.25, -4.0, 7.0, -0.5, 0.1875, 1.25, f32::INFINITY, -0.1875, -7.5, f32::NEGATIVE_INFINITY, 0.75, -7.0, -6.0, -3.0, 0.234375, -2.0, -0.875, -0.75, 6.0, -24.0, 24.0, -2.0, 1.5, f32::NEGATIVE_INFINITY, -1.25, 14.0, 5.0, ]; let common_values = &[ (1.0, 74789), (-1.0, 74702), (f32::INFINITY, 50351), (f32::NEGATIVE_INFINITY, 49873), (1.5, 38119), (-0.5, 37713), (2.0, 37640), (-1.5, 37613), (-2.0, 37333), (0.5, 37027), (0.75, 19050), (4.0, 18892), (0.25, 18875), (-3.0, 18866), (3.0, 18821), (-0.75, 18725), (-4.0, 18663), (-0.25, 18537), (0.125, 9445), (-0.375, 9395), ]; let sample_median = (0.0048828125, None); special_random_nonzero_primitive_floats_helper::( 1, 1, 2, 1, 1, 10, values, common_values, sample_median, NAN_MOMENT_STATS, ); // f32, mean abs of exponent = 10, mean precision = 10, mean special P = 1/100 let values = &[ 0.65625, 0.0000014255784, 0.013183594, -0.8125, -74240.0, -0.0078125, -0.03060913, 3.331552, 4.75, -0.000038146973, -0.3125, -27136.0, -59392.0, -1.75, -41.1875, 0.30940247, -0.0009765625, -1536.0, 0.2109375, 0.0014648438, 2.1129381e-8, -0.037109375, 5242880.0, -0.21386719, 134.21094, 4.184082, -1561370.0, -2.1420419e-7, 0.38085938, -0.007003784, -37748736.0, -6448.0, 28.25, -6.703125, -4.483364, -3.1757812, 0.000003915804, -0.020751953, 0.00011110306, -0.000053405256, 0.00019985437, -35.40625, 0.005859375, 0.0078125, 28.25, 30.0, -0.20776367, -144.0, -0.109375, -6144.0, ]; let common_values = &[ (f32::INFINITY, 5098), (f32::NEGATIVE_INFINITY, 4891), (1.0, 2559), (-1.0, 2528), (0.5, 2362), (-2.0, 2312), (-1.5, 2306), (2.0, 2304), (1.5, 2275), (-0.5, 2243), (-3.0, 2204), (-4.0, 2163), (-0.25, 2129), (0.75, 2103), (3.0, 2081), (0.25, 2070), (-0.75, 2047), (4.0, 2038), (-6.0, 1943), (-8.0, 1918), ]; let sample_median = (2.1684043e-19, None); special_random_nonzero_primitive_floats_helper::( 10, 1, 10, 1, 1, 100, values, common_values, sample_median, NAN_MOMENT_STATS, ); // f64, mean abs of exponent = 1/64, mean precision = 65/64, mean special P = 1/4 let values = &[ f64::INFINITY, 1.0, 1.0, f64::NEGATIVE_INFINITY, 1.0, -1.0, f64::INFINITY, -1.0, f64::INFINITY, f64::NEGATIVE_INFINITY, -1.0, f64::NEGATIVE_INFINITY, -1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 0.5, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, f64::INFINITY, -1.5, f64::NEGATIVE_INFINITY, f64::INFINITY, -1.0, 1.0, -1.0, -1.0, -1.0, f64::INFINITY, 1.0, -1.0, -0.5, -1.0, f64::NEGATIVE_INFINITY, f64::INFINITY, f64::INFINITY, 1.0, ]; let common_values = &[ (1.0, 358244), (-1.0, 357926), (f64::INFINITY, 125637), (f64::NEGATIVE_INFINITY, 124572), (2.0, 5538), (1.5, 5500), (0.5, 5497), (-1.5, 5454), (-2.0, 5379), (-0.5, 5357), (0.75, 102), (3.0, 98), (-4.0, 95), (-0.25, 91), (-0.75, 87), (-3.0, 86), (0.25, 79), (4.0, 75), (-1.25, 48), (1.75, 44), ]; let sample_median = (0.5, None); special_random_nonzero_primitive_floats_helper::( 1, 64, 65, 64, 1, 4, values, common_values, sample_median, NAN_MOMENT_STATS, ); // f64, mean abs of exponent = 1, mean precision = 2, mean special P = 1/10 let values = &[ 1.0, 1.25, 3.0, f64::INFINITY, -1.0, -1.0, -2.0, -3.5, 1.0, 2.0, -1.5, -2.5, -2.0, f64::NEGATIVE_INFINITY, -6.5, -1.0, -1.0, f64::INFINITY, 3.0, -0.21875, -1.0, 0.25, 1.5, 5.25, -4.0, 7.0, -0.5, 0.1875, 1.25, f64::INFINITY, -0.1875, -7.5, f64::NEGATIVE_INFINITY, 0.75, -7.0, -6.0, -3.0, 0.234375, -2.0, -0.875, -0.75, 6.0, -24.0, 24.0, -2.0, 1.5, f64::NEGATIVE_INFINITY, -1.25, 14.0, 5.0, ]; let common_values = &[ (1.0, 74789), (-1.0, 74702), (f64::INFINITY, 50351), (f64::NEGATIVE_INFINITY, 49873), (1.5, 38119), (-0.5, 37713), (2.0, 37640), (-1.5, 37613), (-2.0, 37333), (0.5, 37027), (0.75, 19050), (4.0, 18892), (0.25, 18875), (-3.0, 18866), (3.0, 18821), (-0.75, 18725), (-4.0, 18663), (-0.25, 18537), (0.125, 9445), (-0.375, 9395), ]; let sample_median = (0.0048828125, None); special_random_nonzero_primitive_floats_helper::( 1, 1, 2, 1, 1, 10, values, common_values, sample_median, NAN_MOMENT_STATS, ); // f64, mean abs of exponent = 10, mean precision = 10, mean special P = 1/100 let values = &[ 0.7709910366684198, 1.2504315236583352e-6, 0.00830078125, -0.8125, -85504.0, -0.0078125, -0.018890380859375, 2.5721821784973145, 5.75, -0.00003814697265625, -0.4375, -24064.0, -43008.0, -1.75, -54.6875, 0.4641265869140625, -0.0014760522753931582, -1536.0, 0.1484375, 0.00146484375, 1.9383151084184647e-8, -0.060546875, 7340032.0, -0.1982421875, 203.0546875, 4.57177734375, -1555162.0, -2.0675361156463623e-7, 0.279296875, -0.0045928955078125, -46137344.0, -5712.0, 17.75, -5.265625, -7.966220855712891, -2.99609375, 5.397188942879438e-6, -0.017333984375, 0.00011491775512695312, -0.00005845972555107437, 0.00020831823348999023, -46.78125, 0.005859375, 0.0078125, 27.25, 30.0, -0.175537109375, -208.0, -0.109375, -6144.0, ]; let common_values = &[ (f64::INFINITY, 5098), (f64::NEGATIVE_INFINITY, 4891), (1.0, 2396), (-1.0, 2336), (-2.0, 2200), (-1.5, 2169), (0.5, 2116), (2.0, 2108), (-0.5, 2101), (1.5, 2085), (-3.0, 2000), (4.0, 1993), (3.0, 1969), (-0.25, 1955), (0.75, 1946), (0.25, 1917), (-4.0, 1882), (-0.75, 1863), (8.0, 1826), (-6.0, 1782), ]; let sample_median = (2.1519930816179568e-19, Some(2.168404344971009e-19)); special_random_nonzero_primitive_floats_helper::( 10, 1, 10, 1, 1, 100, values, common_values, sample_median, NAN_MOMENT_STATS, ); } fn special_random_nonzero_primitive_floats_fail_helper() { assert_panic!(special_random_nonzero_primitive_floats::( EXAMPLE_SEED, 0, 1, 10, 1, 1, 10 )); assert_panic!(special_random_nonzero_primitive_floats::( EXAMPLE_SEED, 1, 0, 10, 1, 1, 10 )); assert_panic!(special_random_nonzero_primitive_floats::( EXAMPLE_SEED, 10, 1, 1, 1, 1, 10 )); assert_panic!(special_random_nonzero_primitive_floats::( EXAMPLE_SEED, 10, 1, 1, 0, 1, 10 )); assert_panic!(special_random_nonzero_primitive_floats::( EXAMPLE_SEED, 10, 1, 10, 1, 1, 0 )); assert_panic!(special_random_nonzero_primitive_floats::( EXAMPLE_SEED, 10, 1, 10, 1, 2, 1 )); } #[test] fn special_random_nonzero_primitive_floats_fail() { apply_fn_to_primitive_floats!(special_random_nonzero_primitive_floats_fail_helper); } malachite-base-0.4.16/tests/num/random/special_random_positive_finite_primitive_floats.rs000064400000000000000000000276151046102023000302550ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::special_random_positive_finite_primitive_floats; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::num::random::special_random_primitive_floats_helper_helper; use malachite_base::test_util::stats::moments::{CheckedToF64, MomentStats}; use std::panic::catch_unwind; fn special_random_positive_finite_primitive_floats_helper( mean_exponent_numerator: u64, mean_exponent_denominator: u64, mean_precision_numerator: u64, mean_precision_denominator: u64, expected_values: &[T], expected_common_values: &[(T, usize)], expected_median: (T, Option), expected_moment_stats: MomentStats, ) { special_random_primitive_floats_helper_helper( special_random_positive_finite_primitive_floats::( EXAMPLE_SEED, mean_exponent_numerator, mean_exponent_denominator, mean_precision_numerator, mean_precision_denominator, ), expected_values, expected_common_values, expected_median, expected_moment_stats, ); } #[test] fn test_special_random_positive_finite_primitive_floats() { // f32, mean abs of exponent = 1/64, mean precision = 65/64 let values = &[ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.5, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.5, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, ]; let common_values = &[ (1.0, 954991), (1.5, 14672), (2.0, 14586), (0.5, 14578), (3.0, 243), (0.25, 228), (4.0, 226), (0.75, 207), (1.25, 127), (1.75, 118), (6.0, 6), (0.125, 4), (2.5, 3), (8.0, 3), (0.625, 3), (0.375, 2), (0.875, 2), (3.5, 1), ]; let sample_median = (1.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(1.0157463749999305), standard_deviation: NiceFloat(0.15870215416222863), skewness: NiceFloat(5.805128395366302), excess_kurtosis: NiceFloat(73.03005686221248), }; special_random_positive_finite_primitive_floats_helper::( 1, 64, 65, 64, values, common_values, sample_median, sample_moment_stats, ); // f32, mean abs of exponent = 1, mean precision = 2 let values = &[ 1.0, 1.5, 3.125, 1.0, 1.0, 2.0, 2.0, 1.0, 3.0, 1.0, 2.0, 3.0, 4.0, 1.5, 1.625, 2.0, 0.125, 1.0, 0.375, 1.5, 6.375, 4.0, 6.875, 0.5, 0.234375, 1.0, 0.2421875, 6.0, 0.75, 6.0, 6.0, 2.0, 0.21875, 2.0, 0.875, 0.875, 6.0, 16.0, 27.0, 2.25, 1.5, 1.5, 8.75, 4.0, 0.25, 1.5, 0.375, 0.375, 1.0, 0.09375, ]; let common_values = &[ (1.0, 166355), (2.0, 83686), (0.5, 83270), (1.5, 82925), (3.0, 41733), (0.75, 41659), (4.0, 41550), (0.25, 41388), (1.75, 21006), (6.0, 20858), (0.125, 20779), (8.0, 20769), (0.375, 20764), (1.25, 20753), (12.0, 10512), (2.5, 10508), (0.0625, 10447), (0.625, 10414), (0.1875, 10394), (16.0, 10354), ]; let sample_median = (1.03125, None); let sample_moment_stats = MomentStats { mean: NiceFloat(7.654060290573151), standard_deviation: NiceFloat(374.2183970257817), skewness: NiceFloat(257.0774178486101), excess_kurtosis: NiceFloat(79059.24924350459), }; special_random_positive_finite_primitive_floats_helper::( 1, 1, 2, 1, values, common_values, sample_median, sample_moment_stats, ); // f32, mean abs of exponent = 10, mean precision = 10 let values = &[ 0.80126953, 0.0000013709068, 0.015609741, 0.98552704, 65536.0, 0.008257866, 0.017333984, 2.25, 7.7089844, 0.00004425831, 0.40625, 24576.0, 37249.0, 1.1991882, 32.085938, 0.4375, 0.0012359619, 1536.0, 0.22912993, 0.0015716553, 1.6662057e-8, 0.044523954, 5694464.0, 0.125, 180.0, 5.625, 1572864.0, 1.9092113e-7, 0.28466797, 0.0068359375, 56737790.0, 4813.375, 20.954966, 4.0, 7.3125, 3.6040926, 0.000007293769, 0.018554688, 0.00009602308, 0.000038146973, 0.00022888184, 36.324017, 0.0068359375, 0.008168057, 20.0, 21.398438, 0.21679688, 176.0, 0.11355591, 6144.0, ]; let common_values = &[ (1.0, 5117), (1.5, 4684), (2.0, 4643), (0.5, 4592), (3.0, 4327), (0.75, 4245), (0.25, 4231), (4.0, 4186), (8.0, 3995), (0.375, 3923), (6.0, 3869), (0.125, 3864), (0.0625, 3534), (16.0, 3502), (0.1875, 3489), (12.0, 3418), (24.0, 3293), (32.0, 3244), (0.09375, 3209), (0.03125, 3152), ]; let sample_median = (1.4882812, None); let sample_moment_stats = MomentStats { mean: NiceFloat(7.110316815188854e31), standard_deviation: NiceFloat(5.291057687231236e34), skewness: NiceFloat(817.3228282694379), excess_kurtosis: NiceFloat(702102.631759681), }; special_random_positive_finite_primitive_floats_helper::( 10, 1, 10, 1, values, common_values, sample_median, sample_moment_stats, ); // f64, mean abs of exponent = 1/64, mean precision = 65/64 let values = &[ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.5, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.5, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, ]; let common_values = &[ (1.0, 954991), (1.5, 14672), (2.0, 14586), (0.5, 14578), (3.0, 243), (0.25, 228), (4.0, 226), (0.75, 207), (1.25, 127), (1.75, 118), (6.0, 6), (0.125, 4), (2.5, 3), (8.0, 3), (0.625, 3), (0.375, 2), (0.875, 2), (3.5, 1), ]; let sample_median = (1.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(1.0157463749999305), standard_deviation: NiceFloat(0.15870215416222863), skewness: NiceFloat(5.805128395366302), excess_kurtosis: NiceFloat(73.03005686221248), }; special_random_positive_finite_primitive_floats_helper::( 1, 64, 65, 64, values, common_values, sample_median, sample_moment_stats, ); // f64, mean abs of exponent = 1, mean precision = 2 let values = &[ 1.0, 1.5, 3.125, 1.0, 1.0, 2.0, 2.0, 1.0, 3.0, 1.0, 2.0, 3.0, 4.0, 1.5, 1.625, 2.0, 0.125, 1.0, 0.375, 1.5, 6.375, 4.0, 6.875, 0.5, 0.234375, 1.0, 0.2421875, 6.0, 0.75, 6.0, 6.0, 2.0, 0.21875, 2.0, 0.875, 0.875, 6.0, 16.0, 27.0, 2.25, 1.5, 1.5, 8.75, 4.0, 0.25, 1.5, 0.375, 0.375, 1.0, 0.09375, ]; let common_values = &[ (1.0, 166355), (2.0, 83686), (0.5, 83270), (1.5, 82925), (3.0, 41733), (0.75, 41659), (4.0, 41550), (0.25, 41388), (1.75, 21006), (6.0, 20858), (0.125, 20779), (8.0, 20769), (0.375, 20764), (1.25, 20753), (12.0, 10512), (2.5, 10508), (0.0625, 10447), (0.625, 10414), (0.1875, 10394), (16.0, 10354), ]; let sample_median = (1.03125, None); let sample_moment_stats = MomentStats { mean: NiceFloat(7.654060290573151), standard_deviation: NiceFloat(374.2183970257817), skewness: NiceFloat(257.0774178486101), excess_kurtosis: NiceFloat(79059.24924350459), }; special_random_positive_finite_primitive_floats_helper::( 1, 1, 2, 1, values, common_values, sample_median, sample_moment_stats, ); // f64, mean abs of exponent = 10, mean precision = 10 let values = &[ 0.80126953125, 1.3709068298339844e-6, 0.0156097412109375, 0.9855270385742188, 86113.82421875, 0.012808799743652344, 0.028076171875, 2.75, 7.009765625, 0.000045569613575935364, 0.34375, 24576.0, 33101.0, 1.066680908203125, 53.0390625, 0.3125, 0.0018768310546875, 1536.0, 0.15994291007518768, 0.0014495849609375, 2.5660824576334562e-8, 0.04374957084655762, 6583296.0, 0.125, 156.0, 7.125, 1572864.0, 1.525198978780118e-7, 0.32763671875, 0.0048828125, 47710208.0, 6821.875, 19.824071884155273, 4.0, 4.6875, 2.3686094284057617, 6.33427407592535e-6, 0.0185546875, 0.00007218122482299805, 0.00003814697265625, 0.0001373291015625, 36.43232345581055, 0.0048828125, 0.011424465501870706, 28.0, 18.0546875, 0.2207733978284523, 144.0, 0.083648681640625, 4360.2293701171875, ]; let common_values = &[ (1.0, 4779), (1.5, 4356), (2.0, 4315), (0.5, 4233), (3.0, 4023), (0.25, 3931), (0.75, 3911), (4.0, 3866), (8.0, 3705), (0.375, 3612), (6.0, 3588), (0.125, 3538), (0.0625, 3271), (16.0, 3264), (0.1875, 3199), (12.0, 3152), (24.0, 3033), (32.0, 2974), (0.09375, 2963), (0.03125, 2937), ]; let sample_median = (1.484375, None); let sample_moment_stats = MomentStats { mean: NiceFloat(5.352183416672257e38), standard_deviation: NiceFloat(5.3521788476440196e41), skewness: NiceFloat(999.9984999986674), excess_kurtosis: NiceFloat(999995.0000000936), }; special_random_positive_finite_primitive_floats_helper::( 10, 1, 10, 1, values, common_values, sample_median, sample_moment_stats, ); } fn special_random_positive_finite_primitive_floats_fail_helper() { assert_panic!(special_random_positive_finite_primitive_floats::( EXAMPLE_SEED, 0, 1, 10, 1 )); assert_panic!(special_random_positive_finite_primitive_floats::( EXAMPLE_SEED, 1, 0, 10, 1 )); assert_panic!(special_random_positive_finite_primitive_floats::( EXAMPLE_SEED, 10, 1, 1, 1 )); assert_panic!(special_random_positive_finite_primitive_floats::( EXAMPLE_SEED, 10, 1, 1, 0 )); } #[test] fn special_random_positive_finite_primitive_floats_fail() { apply_fn_to_primitive_floats!(special_random_positive_finite_primitive_floats_fail_helper); } malachite-base-0.4.16/tests/num/random/special_random_positive_primitive_floats.rs000064400000000000000000000315471046102023000267160ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::random::special_random_positive_primitive_floats; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::num::random::special_random_primitive_floats_helper_helper; use malachite_base::test_util::stats::moments::{CheckedToF64, MomentStats, NAN_MOMENT_STATS}; use std::panic::catch_unwind; fn special_random_positive_primitive_floats_helper( mean_exponent_numerator: u64, mean_exponent_denominator: u64, mean_precision_numerator: u64, mean_precision_denominator: u64, mean_special_p_numerator: u64, mean_special_p_denominator: u64, expected_values: &[T], expected_common_values: &[(T, usize)], expected_median: (T, Option), expected_moment_stats: MomentStats, ) { special_random_primitive_floats_helper_helper( special_random_positive_primitive_floats::( EXAMPLE_SEED, mean_exponent_numerator, mean_exponent_denominator, mean_precision_numerator, mean_precision_denominator, mean_special_p_numerator, mean_special_p_denominator, ), expected_values, expected_common_values, expected_median, expected_moment_stats, ); } #[test] fn test_special_random_positive_primitive_floats() { // f32, mean abs of exponent = 1/64, mean precision = 65/64, mean special P = 1/4 let values = &[ f32::INFINITY, 1.5, 1.0, f32::INFINITY, 1.0, 1.0, f32::INFINITY, 1.0, f32::INFINITY, f32::INFINITY, 1.0, f32::INFINITY, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.5, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, f32::INFINITY, 1.0, f32::INFINITY, f32::INFINITY, 1.0, 1.0, 1.0, 1.0, 1.0, f32::INFINITY, 1.0, 1.0, 0.5, 1.0, f32::INFINITY, f32::INFINITY, f32::INFINITY, 1.0, ]; let common_values = &[ (1.0, 716268), (f32::INFINITY, 250209), (2.0, 10938), (0.5, 10888), (1.5, 10871), (4.0, 172), (0.25, 165), (3.0, 161), (0.75, 155), (1.25, 75), (1.75, 74), (0.375, 6), (3.5, 4), (0.125, 4), (8.0, 3), (0.875, 2), (1.875, 2), (6.0, 1), (0.625, 1), (1.125, 1), ]; let sample_median = (1.0, None); special_random_positive_primitive_floats_helper::( 1, 64, 65, 64, 1, 4, values, common_values, sample_median, NAN_MOMENT_STATS, ); // f32, mean abs of exponent = 1, mean precision = 2, mean special P = 1/10 let values = &[ 1.0, 1.0, 3.0, f32::INFINITY, 1.0, 1.0, 2.0, 2.0, 1.0, 3.0, 1.0, 3.0, 3.0, f32::INFINITY, 6.0, 1.125, 1.25, f32::INFINITY, 3.0, 0.125, 1.0, 0.25, 1.75, 4.0, 4.0, 4.0, 0.75, 0.125, 1.0, f32::INFINITY, 0.125, 6.0, f32::INFINITY, 0.5, 4.0, 6.5, 2.0, 0.21875, 2.0, 0.5, 0.5, 4.0, 16.0, 16.0, 3.0, 1.0, f32::INFINITY, 1.0, 10.0, 6.0, ]; let common_values = &[ (1.0, 151036), (f32::INFINITY, 100224), (0.5, 75239), (2.0, 74939), (1.5, 74396), (0.25, 37669), (0.75, 37538), (3.0, 37523), (4.0, 37411), (0.375, 18737), (6.0, 18708), (0.125, 18698), (1.25, 18586), (8.0, 18570), (1.75, 18339), (3.5, 9676), (0.0625, 9668), (16.0, 9474), (0.875, 9416), (12.0, 9376), ]; let sample_median = (1.5, None); special_random_positive_primitive_floats_helper::( 1, 1, 2, 1, 1, 10, values, common_values, sample_median, NAN_MOMENT_STATS, ); // f32, mean abs of exponent = 10, mean precision = 10, mean special P = 1/100 let values = &[ 0.6328125, 9.536743e-7, 0.013671875, 0.6875, 70208.0, 0.01550293, 0.028625488, 3.3095703, 5.775879, 0.000034958124, 0.4375, 31678.0, 49152.0, 1.0, 49.885254, 0.40625, 0.0015869141, 1889.5625, 0.14140439, 0.001449585, 1.4901161e-8, 0.03125, 5750784.0, 0.17578125, 248.0, 5.4375, 1892352.0, 1.5280966e-7, 0.2826419, 0.0057373047, 51642370.0, 6384.0, 27.875542, 6.152041, 6.0, 2.796875, 0.0000057816505, 0.029174805, 0.00011384487, 0.000039815903, 0.00012207031, 48.0, 0.00390625, 0.01171875, 20.0, 21.625, 0.171875, 197.0, 0.11743164, 5532.0, ]; let common_values = &[ (f32::INFINITY, 9989), (1.0, 5059), (2.0, 4689), (0.5, 4622), (1.5, 4576), (4.0, 4280), (3.0, 4153), (0.25, 4130), (0.75, 4105), (8.0, 3912), (6.0, 3841), (0.125, 3772), (0.375, 3663), (16.0, 3536), (0.1875, 3530), (0.0625, 3441), (12.0, 3433), (0.09375, 3185), (0.03125, 3176), (32.0, 3094), ]; let sample_median = (1.5, None); special_random_positive_primitive_floats_helper::( 10, 1, 10, 1, 1, 100, values, common_values, sample_median, NAN_MOMENT_STATS, ); // f64, mean abs of exponent = 1/64, mean precision = 65/64, mean special P = 1/4 let values = &[ f64::INFINITY, 1.5, 1.0, f64::INFINITY, 1.0, 1.0, f64::INFINITY, 1.0, f64::INFINITY, f64::INFINITY, 1.0, f64::INFINITY, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.5, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, f64::INFINITY, 1.0, f64::INFINITY, f64::INFINITY, 1.0, 1.0, 1.0, 1.0, 1.0, f64::INFINITY, 1.0, 1.0, 0.5, 1.0, f64::INFINITY, f64::INFINITY, f64::INFINITY, 1.0, ]; let common_values = &[ (1.0, 716268), (f64::INFINITY, 250209), (2.0, 10938), (0.5, 10888), (1.5, 10871), (4.0, 172), (0.25, 165), (3.0, 161), (0.75, 155), (1.25, 75), (1.75, 74), (0.375, 6), (3.5, 4), (0.125, 4), (8.0, 3), (0.875, 2), (1.875, 2), (6.0, 1), (0.625, 1), (1.125, 1), ]; let sample_median = (1.0, None); special_random_positive_primitive_floats_helper::( 1, 64, 65, 64, 1, 4, values, common_values, sample_median, NAN_MOMENT_STATS, ); // f64, mean abs of exponent = 1, mean precision = 2, mean special P = 1/10 let values = &[ 1.0, 1.0, 3.0, f64::INFINITY, 1.0, 1.0, 2.0, 2.0, 1.0, 3.0, 1.0, 3.0, 3.0, f64::INFINITY, 6.0, 1.125, 1.25, f64::INFINITY, 3.0, 0.125, 1.0, 0.25, 1.75, 4.0, 4.0, 4.0, 0.75, 0.125, 1.0, f64::INFINITY, 0.125, 6.0, f64::INFINITY, 0.5, 4.0, 6.5, 2.0, 0.21875, 2.0, 0.5, 0.5, 4.0, 16.0, 16.0, 3.0, 1.0, f64::INFINITY, 1.0, 10.0, 6.0, ]; let common_values = &[ (1.0, 151036), (f64::INFINITY, 100224), (0.5, 75239), (2.0, 74939), (1.5, 74396), (0.25, 37669), (0.75, 37538), (3.0, 37523), (4.0, 37411), (0.375, 18737), (6.0, 18708), (0.125, 18698), (1.25, 18586), (8.0, 18570), (1.75, 18339), (3.5, 9676), (0.0625, 9668), (16.0, 9474), (0.875, 9416), (12.0, 9376), ]; let sample_median = (1.5, None); special_random_positive_primitive_floats_helper::( 1, 1, 2, 1, 1, 10, values, common_values, sample_median, NAN_MOMENT_STATS, ); // f64, mean abs of exponent = 10, mean precision = 10, mean special P = 1/100 let values = &[ 0.6328125, 9.5367431640625e-7, 0.013671875, 0.6875, 70208.0, 0.0155029296875, 0.02862548828125, 3.3095703125, 5.77587890625, 0.0000349581241607666, 0.4375, 31678.0, 49152.0, 1.0, 49.88525390625, 0.40625, 0.0015869140625, 1889.5625, 0.141404390335083, 0.0014495849609375, 1.4901161193847656e-8, 0.03125, 5750784.0, 0.17578125, 248.0, 5.4375, 1892352.0, 1.528096618130803e-7, 0.2826418876647949, 0.0057373046875, 51642368.0, 6384.0, 27.87554168701172, 6.152040958404541, 6.0, 2.796875, 5.781650543212891e-6, 0.0291748046875, 0.0001138448715209961, 0.00003981590270996094, 0.0001220703125, 48.0, 0.00390625, 0.01171875, 20.0, 21.625, 0.171875, 205.175663292408, 0.118408203125, 6436.0, ]; let common_values = &[ (f64::INFINITY, 9989), (1.0, 4750), (2.0, 4357), (0.5, 4257), (1.5, 4256), (4.0, 3955), (3.0, 3844), (0.25, 3812), (0.75, 3799), (8.0, 3628), (6.0, 3535), (0.125, 3447), (0.375, 3398), (16.0, 3257), (0.1875, 3234), (12.0, 3202), (0.0625, 3182), (0.09375, 2957), (0.03125, 2919), (32.0, 2805), ]; let sample_median = (1.5162887573242188, Some(1.516387939453125)); special_random_positive_primitive_floats_helper::( 10, 1, 10, 1, 1, 100, values, common_values, sample_median, NAN_MOMENT_STATS, ); } fn special_random_positive_primitive_floats_fail_helper() { assert_panic!(special_random_positive_primitive_floats::( EXAMPLE_SEED, 0, 1, 10, 1, 1, 10 )); assert_panic!(special_random_positive_primitive_floats::( EXAMPLE_SEED, 1, 0, 10, 1, 1, 10 )); assert_panic!(special_random_positive_primitive_floats::( EXAMPLE_SEED, 10, 1, 1, 1, 1, 10 )); assert_panic!(special_random_positive_primitive_floats::( EXAMPLE_SEED, 10, 1, 1, 0, 1, 10 )); assert_panic!(special_random_positive_primitive_floats::( EXAMPLE_SEED, 10, 1, 10, 1, 1, 0 )); assert_panic!(special_random_positive_primitive_floats::( EXAMPLE_SEED, 10, 1, 10, 1, 2, 1 )); } #[test] fn special_random_positive_primitive_floats_fail() { apply_fn_to_primitive_floats!(special_random_positive_primitive_floats_fail_helper); } malachite-base-0.4.16/tests/num/random/special_random_primitive_float_inclusive_range.rs000064400000000000000000001557611046102023000300530ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::traits::NegativeInfinity; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::special_random_primitive_float_inclusive_range; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::num::random::special_random_primitive_floats_helper_helper; use malachite_base::test_util::stats::moments::{CheckedToF64, MomentStats}; use std::panic::catch_unwind; fn special_random_primitive_float_inclusive_range_helper( a: T, b: T, mean_exponent_numerator: u64, mean_exponent_denominator: u64, mean_precision_numerator: u64, mean_precision_denominator: u64, mean_zero_p_numerator: u64, mean_zero_p_denominator: u64, expected_values: &[T], expected_common_values: &[(T, usize)], expected_median: (T, Option), expected_moment_stats: MomentStats, ) { special_random_primitive_floats_helper_helper( special_random_primitive_float_inclusive_range::( EXAMPLE_SEED, a, b, mean_exponent_numerator, mean_exponent_denominator, mean_precision_numerator, mean_precision_denominator, mean_zero_p_numerator, mean_zero_p_denominator, ), expected_values, expected_common_values, expected_median, expected_moment_stats, ); } #[test] fn test_special_random_primitive_float_inclusive_range() { // f32, a = 1.0, b = 2.0, mean abs of exponent = 1, mean precision = 2, mean zero P = 1/10 let values = &[ 2.0, 2.0, 2.0, 1.0, 1.5, 2.0, 1.0, 1.0, 1.5, 2.0, 1.28125, 1.0, 2.0, 1.0, 1.4375, 1.8125, 1.6875, 1.0, 1.75, 1.875, 2.0, 1.0, 2.0, 1.0, 1.75, 2.0, 2.0, 2.0, 2.0, 1.75, 2.0, 1.5, 1.484375, 2.0, 1.0, 2.0, 1.75, 2.0, 1.25, 1.0, 1.5, 1.25, 1.546875, 1.0, 2.0, 2.0, 2.0, 1.4921875, 2.0, 2.0, ]; let common_values = &[ (2.0, 332566), (1.0, 222413), (1.5, 148427), (1.25, 49546), (1.75, 49274), (1.875, 16717), (1.125, 16593), (1.375, 16567), (1.625, 16551), (1.8125, 5566), (1.5625, 5553), (1.9375, 5543), (1.1875, 5451), (1.4375, 5383), (1.6875, 5367), (1.3125, 5361), (1.0625, 5322), (1.21875, 1873), (1.34375, 1871), (1.40625, 1865), ]; let sample_median = (1.5, None); let sample_moment_stats = MomentStats { mean: NiceFloat(1.5553208489836596), standard_deviation: NiceFloat(0.3974073963635055), skewness: NiceFloat(-0.20042532167244795), excess_kurtosis: NiceFloat(-1.5078861004584492), }; special_random_primitive_float_inclusive_range_helper::( 1.0, 2.0, 1, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f32, a = 1.0, b = 2.0, mean abs of exponent = 10, mean precision = 10, mean zero P = 1/100 let values = &[ 2.0, 2.0, 1.0, 1.640625, 1.375, 2.0, 1.90625, 2.0, 2.0, 1.25, 1.0, 2.0, 2.0, 1.9375, 1.5, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 1.96875, 2.0, 1.1479492, 1.4569855, 1.2559814, 1.5579834, 2.0, 2.0, 1.2250977, 1.1882324, 1.5, 2.0, 1.6498959, 2.0, 1.1252441, 2.0, 2.0, 2.0, 1.0336914, 2.0, 2.0, 2.0, 2.0, 1.5, 1.375, 2.0, 1.0, 1.125, ]; let common_values = &[ (2.0, 476330), (1.0, 52792), (1.5, 47801), (1.25, 22022), (1.75, 21892), (1.875, 10017), (1.625, 9986), (1.375, 9985), (1.125, 9951), (1.8125, 4622), (1.4375, 4596), (1.1875, 4577), (1.9375, 4552), (1.5625, 4549), (1.3125, 4532), (1.0625, 4507), (1.6875, 4455), (1.96875, 2147), (1.15625, 2105), (1.28125, 2098), ]; let sample_median = (1.9371719, Some(1.9371796)); let sample_moment_stats = MomentStats { mean: NiceFloat(1.712172784260269), standard_deviation: NiceFloat(0.34826759681331443), skewness: NiceFloat(-0.7989590190130814), excess_kurtosis: NiceFloat(-0.8454122824548973), }; special_random_primitive_float_inclusive_range_helper::( 1.0, 2.0, 10, 1, 10, 1, 1, 100, values, common_values, sample_median, sample_moment_stats, ); // f32, a = -0.1, b = 0.1, mean abs of exponent = 5, mean precision = 2, mean zero P = 1/10 let values = &[ 0.09375, 0.01171875, 0.01171875, -0.0, -0.09375, -0.01171875, -0.01171875, -0.03125, 0.03125, 0.0625, -0.0625, -0.07525635, -0.0625, 0.0, -0.09375, -0.09375, -0.09375, -0.0, 0.07525635, -0.078125, -0.05078125, 0.0625, 0.09375, 0.09375, -0.024414062, 0.09375, -0.001953125, 0.078125, 0.05078125, -0.0, -0.0625, -0.09375, 0.0, 0.024414062, -0.03125, -0.0043945312, -0.09375, 0.001953125, -0.09375, -0.003540039, -0.03125, 0.0625, -0.046875, 0.09375, -0.0625, 0.03125, 0.0, -0.0146484375, 0.0043945312, 0.09375, ]; let common_values = &[ (0.0625, 74962), (-0.0625, 74736), (-0.0, 50351), (0.09375, 50309), (-0.09375, 50178), (0.0, 49873), (0.03125, 37782), (-0.03125, 37678), (0.078125, 33219), (-0.078125, 33138), (0.046875, 25130), (-0.046875, 25053), (0.015625, 18743), (-0.015625, 18692), (0.0234375, 12593), (-0.0234375, 12549), (0.0703125, 11091), (0.0859375, 11088), (-0.0859375, 11060), (-0.0703125, 11055), ]; let sample_median = (0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(0.0000674789649248169), standard_deviation: NiceFloat(0.05672019953597066), skewness: NiceFloat(-0.001702872258409426), excess_kurtosis: NiceFloat(-1.109977309372344), }; special_random_primitive_float_inclusive_range_helper::( -0.1, 0.1, 5, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f32, a = -0.1, b = 0.1, mean abs of exponent = 10, mean precision = 10, mean zero P = 1/100 let values = &[ 0.0041503906, 0.0625, 0.00042547443, -0.0041503906, -0.0625, -0.00042547443, -0.0027618408, 0.0027618408, 0.09375, -0.09375, -0.083244324, -0.076171875, -0.00023269653, -0.00043609738, -0.0029296875, 0.083244324, -0.011459351, -0.05419922, 0.076171875, 0.00023269653, 0.00043609738, -0.000006198883, 0.0029296875, -0.0008621216, 0.011459351, 0.05419922, -0.00035095215, -0.0625, 0.000006198883, -0.0008010864, -0.00030517578, -0.00008274312, 0.0008621216, -0.0029296875, -0.04892564, -0.013671875, 0.00035095215, -0.0009398293, 0.0625, -0.07344723, 0.0008010864, -0.01953125, 0.00030517578, 0.00008274312, 0.0029296875, 0.04892564, -0.006134033, -0.0070343018, -0.005493164, -0.0000029057264, ]; let common_values = &[ (0.0625, 7060), (-0.0625, 7045), (0.09375, 6481), (-0.09375, 6468), (0.03125, 6186), (-0.03125, 6171), (0.078125, 5831), (-0.078125, 5813), (0.046875, 5527), (-0.046875, 5516), (0.015625, 5112), (-0.015625, 5103), (-0.0, 5098), (0.0, 4891), (0.0234375, 4821), (-0.0234375, 4810), (0.0078125, 4681), (-0.0078125, 4678), (0.01171875, 4123), (-0.01171875, 4120), ]; let sample_median = (0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(0.000022248151599295377), standard_deviation: NiceFloat(0.035382441406785786), skewness: NiceFloat(0.0002929225243710825), excess_kurtosis: NiceFloat(1.5823949638933827), }; special_random_primitive_float_inclusive_range_helper::( -0.1, 0.1, 10, 1, 10, 1, 1, 100, values, common_values, sample_median, sample_moment_stats, ); // f32, a = e, b = π, mean abs of exponent = 3, mean precision = 2, mean zero P = 1/10 let values = &[ 3.0, 2.859375, 3.0234375, 3.0, 2.75, 3.0, 3.0, 3.0, 2.75, 2.75, 3.078125, 3.0, 3.0, 3.0, 2.84375, 2.84375, 2.96875, 3.0, 3.125, 2.8125, 3.0, 3.0, 3.03125, 3.0, 3.125, 3.125, 2.875, 3.0, 2.75, 2.875, 3.0, 2.75, 2.9140625, 2.734375, 3.0, 3.0, 3.125, 2.9257812, 3.125, 3.0, 2.75, 3.125, 2.9921875, 3.0, 2.75, 3.0, 3.0, 3.0195312, 3.0, 2.8125, ]; let common_values = &[ (3.0, 333251), (2.75, 222162), (3.125, 74149), (2.875, 74011), (3.0625, 33262), (2.8125, 33146), (2.9375, 33097), (2.90625, 9548), (2.78125, 9377), (2.71875, 9327), (3.03125, 9327), (3.09375, 9323), (2.84375, 9315), (2.96875, 9265), (2.859375, 3186), (3.015625, 3185), (2.796875, 3180), (3.046875, 3160), (3.140625, 3157), (2.765625, 3152), ]; let sample_median = (3.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(2.923236772231216), standard_deviation: NiceFloat(0.12616339323242115), skewness: NiceFloat(-0.17689588042510748), excess_kurtosis: NiceFloat(-1.2738593390011854), }; special_random_primitive_float_inclusive_range_helper::( core::f32::consts::E, core::f32::consts::PI, 3, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f32, a = e, b = π, mean abs of exponent = 10, mean precision = 10, mean zero P = 1/100 let values = &[ 2.9238281, 2.953125, 3.0, 2.8671875, 2.8125, 3.125, 3.015625, 2.8462658, 3.140625, 2.875, 3.0, 2.75, 3.0, 2.71875, 2.75, 3.0214844, 2.970642, 3.0179443, 2.968872, 2.75, 2.9763536, 2.875, 2.890625, 2.8388672, 2.7814941, 3.087654, 3.1065063, 2.817566, 2.8125, 2.7746582, 2.746338, 3.0207214, 2.75, 2.9852295, 3.0, 2.9980469, 3.006958, 2.875, 2.8632812, 2.9277344, 3.088623, 2.8376465, 3.0, 3.0, 3.0117188, 2.75, 2.8125, 3.0, 3.0, 3.140625, ]; let common_values = &[ (3.0, 103073), (2.75, 94168), (2.875, 43152), (3.125, 42886), (3.0625, 26213), (2.8125, 25982), (2.9375, 25799), (2.90625, 10203), (2.71875, 10186), (2.84375, 10149), (3.09375, 10141), (3.03125, 10134), (2.78125, 10085), (2.96875, 10085), (3.046875, 4666), (2.734375, 4649), (2.765625, 4649), (3.109375, 4629), (2.859375, 4606), (3.140625, 4590), ]; let sample_median = (2.9375, None); let sample_moment_stats = MomentStats { mean: NiceFloat(2.925577550306893), standard_deviation: NiceFloat(0.12565616542944752), skewness: NiceFloat(-0.016691773531483878), excess_kurtosis: NiceFloat(-1.2405888218124512), }; special_random_primitive_float_inclusive_range_helper::( core::f32::consts::E, core::f32::consts::PI, 10, 1, 10, 1, 1, 100, values, common_values, sample_median, sample_moment_stats, ); // f32, a = 100.0, b = 101.0, mean abs of exponent = 7, mean precision = 2, mean zero P = 1/10 let values = &[ 100.0, 100.5625, 100.40625, 100.0, 101.0, 100.0, 100.0, 100.0, 101.0, 101.0, 100.8125, 100.0, 100.0, 100.0, 100.375, 100.875, 100.875, 100.0, 100.5, 100.75, 100.0, 100.0, 100.875, 100.0, 100.5, 100.5, 100.5, 100.0, 101.0, 100.5, 100.0, 101.0, 100.46875, 100.1875, 100.0, 100.0, 100.5, 100.546875, 100.5, 100.0, 101.0, 100.5, 100.96875, 100.0, 101.0, 100.0, 100.0, 100.296875, 100.0, 100.75, ]; let common_values = &[ (100.0, 333338), (101.0, 222241), (100.5, 148191), (100.75, 49867), (100.25, 49679), (100.625, 16568), (100.875, 16322), (100.125, 16318), (100.375, 16281), (100.6875, 5585), (100.3125, 5557), (100.5625, 5547), (100.1875, 5520), (100.9375, 5484), (100.0625, 5464), (100.8125, 5438), (100.4375, 5236), (100.71875, 1933), (100.09375, 1868), (100.34375, 1863), ]; let sample_median = (100.5, None); let sample_moment_stats = MomentStats { mean: NiceFloat(100.44460313228277), standard_deviation: NiceFloat(0.3974843507339211), skewness: NiceFloat(0.19977351658386902), excess_kurtosis: NiceFloat(-1.5086143196425152), }; special_random_primitive_float_inclusive_range_helper::( 100.0, 101.0, 7, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f32, a = 100.0, b = 101.0, mean abs of exponent = 10, mean precision = 10, mean zero P = // 1/100 let values = &[ 100.82031, 100.5625, 100.0, 100.71875, 100.75, 100.5, 100.9375, 100.88427, 100.9375, 100.5, 100.0, 101.0, 100.0, 100.125, 101.0, 100.46094, 100.51196, 100.46338, 100.80127, 101.0, 100.0, 100.5, 100.1875, 100.01172, 100.569336, 100.59958, 100.50122, 100.06665, 100.25, 100.31543, 100.47949, 100.94539, 101.0, 100.47705, 100.75, 100.72206, 100.59912, 100.5, 100.796875, 100.44531, 100.44629, 100.42285, 100.0, 100.0, 100.802734, 101.0, 100.25, 100.75, 100.0, 100.13281, ]; let common_values = &[ (100.0, 108217), (101.0, 98713), (100.5, 90150), (100.75, 40946), (100.25, 40858), (100.875, 18753), (100.125, 18677), (100.625, 18429), (100.375, 18424), (100.1875, 8582), (100.6875, 8505), (100.5625, 8500), (100.8125, 8480), (100.9375, 8342), (100.4375, 8341), (100.0625, 8329), (100.3125, 8269), (100.90625, 3936), (100.28125, 3920), (100.21875, 3910), ]; let sample_median = (100.5, None); let sample_moment_stats = MomentStats { mean: NiceFloat(100.49535768898696), standard_deviation: NiceFloat(0.32868306867221864), skewness: NiceFloat(0.008975981158852992), excess_kurtosis: NiceFloat(-1.221929691547448), }; special_random_primitive_float_inclusive_range_helper::( 100.0, 101.0, 10, 1, 10, 1, 1, 100, values, common_values, sample_median, sample_moment_stats, ); // f32, a = 1.0e38, b = Infinity, mean abs of exponent = 129, mean precision = 2, mean zero P = // 1/10 let values = &[ 2.5521178e38, 1.0633824e38, 1.0633824e38, f32::INFINITY, 1.2760589e38, 1.7014118e38, 1.2349359e38, 1.7014118e38, 1.0633824e38, 1.4887354e38, 1.0633824e38, 1.1697206e38, 1.329228e38, f32::INFINITY, 1.3026434e38, 1.2760589e38, 1.2760589e38, f32::INFINITY, 1.4887354e38, 1.7014118e38, 1.5419045e38, 2.5521178e38, 2.5521178e38, 3.2964854e38, 1.7014118e38, 1.0633824e38, 1.2760589e38, 1.2228898e38, 1.3823971e38, f32::INFINITY, 1.1763668e38, 1.2760589e38, f32::INFINITY, 1.5950736e38, 1.4887354e38, 1.2760589e38, 2.9774707e38, 2.179934e38, 2.3394413e38, 2.5521178e38, 2.1267648e38, 2.9774707e38, 1.0633824e38, 1.7014118e38, 1.7014118e38, 1.2760589e38, f32::INFINITY, 1.5809505e38, 1.1697206e38, 2.7647942e38, ]; let common_values = &[ (1.2760589e38, 171851), (1.7014118e38, 128688), (f32::INFINITY, 100224), (2.5521178e38, 85928), (1.4887354e38, 57285), (1.0633824e38, 57158), (2.9774707e38, 28779), (2.1267648e38, 28453), (1.1697206e38, 25497), (1.3823971e38, 25299), (1.5950736e38, 25002), (2.3394413e38, 9529), (1.9140883e38, 9502), (3.1901472e38, 9420), (2.7647942e38, 9406), (1.1165515e38, 7388), (1.329228e38, 7368), (1.2228898e38, 7328), (1.4355662e38, 7281), (1.6482427e38, 7214), ]; let sample_median = (1.6482427e38, None); let sample_moment_stats = MomentStats { mean: NiceFloat(f64::NAN), standard_deviation: NiceFloat(f64::NAN), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; special_random_primitive_float_inclusive_range_helper::( 1.0e38, f32::INFINITY, 129, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f32, a = -f32::MIN_POSITIVE_SUBNORMAL, b = f32::MIN_POSITIVE_SUBNORMAL, mean abs of exponent // = 150, mean precision = 2, mean zero P = 1/10 let values = &[ 1.0e-45, 1.0e-45, 1.0e-45, -0.0, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, 1.0e-45, 1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, 0.0, -1.0e-45, -1.0e-45, -1.0e-45, -0.0, 1.0e-45, -1.0e-45, -1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, -1.0e-45, 1.0e-45, -1.0e-45, 1.0e-45, 1.0e-45, -0.0, -1.0e-45, -1.0e-45, 0.0, 1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, 1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, 1.0e-45, -1.0e-45, 1.0e-45, -1.0e-45, 1.0e-45, 0.0, -1.0e-45, 1.0e-45, 1.0e-45, ]; let common_values = &[(1.0e-45, 450531), (-1.0e-45, 449245), (-0.0, 50351), (0.0, 49873)]; let sample_median = (0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(1.8020698251216835e-48), standard_deviation: NiceFloat(1.3292224464360085e-45), skewness: NiceFloat(-0.0025604536978191587), excess_kurtosis: NiceFloat(-1.8886053342505447), }; special_random_primitive_float_inclusive_range_helper::( -f32::MIN_POSITIVE_SUBNORMAL, f32::MIN_POSITIVE_SUBNORMAL, 150, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f32, a = -0.0, b = f32::MIN_POSITIVE_SUBNORMAL, mean abs of exponent = 150, mean precision = // 2, mean zero P = 1/10 let values = &[ 1.0e-45, 1.0e-45, 1.0e-45, -0.0, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 0.0, 1.0e-45, 1.0e-45, 1.0e-45, -0.0, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, -0.0, 1.0e-45, 1.0e-45, 0.0, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 0.0, 1.0e-45, 1.0e-45, 1.0e-45, ]; let common_values = &[(1.0e-45, 899776), (-0.0, 50351), (0.0, 49873)]; let sample_median = (1.0e-45, None); let sample_moment_stats = MomentStats { mean: NiceFloat(1.2608547270363571e-45), standard_deviation: NiceFloat(4.2080794564999146e-46), skewness: NiceFloat(-2.662524701673921), excess_kurtosis: NiceFloat(5.089037787023615), }; special_random_primitive_float_inclusive_range_helper::( -0.0, f32::MIN_POSITIVE_SUBNORMAL, 150, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f32, a = 0.0, b = 0.0, mean abs of exponent = 150, mean precision = 2, mean zero P = 1/10 let values = &[0.0; 50]; let common_values = &[(0.0, 1000000)]; let sample_median = (0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(0.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; special_random_primitive_float_inclusive_range_helper::( 0.0, 0.0, 150, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // -f32::MIN_POSITIVE_SUBNORMAL, b = -f32::MIN_POSITIVE_SUBNORMAL, mean abs of exponent = 150, // mean precision = 2, mean zero P = 1/10 let values = &[-1.0e-45; 50]; let common_values = &[(-1.0e-45, 1000000)]; let sample_median = (-1.0e-45, None); let sample_moment_stats = MomentStats { mean: NiceFloat(-1.401298464324817e-45), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; special_random_primitive_float_inclusive_range_helper::( -f32::MIN_POSITIVE_SUBNORMAL, -f32::MIN_POSITIVE_SUBNORMAL, 150, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f32, a = -f32::MIN_POSITIVE_SUBNORMAL, b = 0.0, mean abs of exponent = 150, mean precision = // 2, mean zero P = 1/10 let values = &[ -1.0e-45, -1.0e-45, -1.0e-45, -0.0, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, 0.0, -1.0e-45, -1.0e-45, -1.0e-45, -0.0, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -0.0, -1.0e-45, -1.0e-45, 0.0, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, 0.0, -1.0e-45, -1.0e-45, -1.0e-45, ]; let common_values = &[(-1.0e-45, 899776), (-0.0, 50351), (0.0, 49873)]; let sample_median = (-1.0e-45, None); let sample_moment_stats = MomentStats { mean: NiceFloat(-1.2608547270363571e-45), standard_deviation: NiceFloat(4.2080794564999146e-46), skewness: NiceFloat(2.662524701673921), excess_kurtosis: NiceFloat(5.089037787023615), }; special_random_primitive_float_inclusive_range_helper::( -f32::MIN_POSITIVE_SUBNORMAL, 0.0, 150, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f32, a = -Infinity, b = Infinity, mean abs of exponent = 1, mean precision = 2, mean zero P = // 1/10 let values = &[ 12.0, 1.5, 0.75, -0.0, -12.0, -1.5, -0.75, -4.0, 4.0, 2.0, -2.0, -1.2041016, -2.0, f32::NEGATIVE_INFINITY, -0.75, -0.75, -3.0, 0.0, 1.2041016, -40.0, -0.6875, 2.0, 0.75, 0.75, -1.3125, 3.0, -2.0, 40.0, 0.6875, -0.0, -0.5, -1.5, f32::NEGATIVE_INFINITY, 1.3125, -0.125, -1.125, -0.046875, 2.0, -1.5, -1.9375, -1.0, 0.5, -0.75, 1.5, -1.0, 0.125, f32::INFINITY, -1.875, 1.125, 0.046875, ]; let common_values = &[ (1.0, 49888), (-1.0, 49745), (1.5, 33700), (-1.5, 33609), (f32::NEGATIVE_INFINITY, 25322), (0.5, 25189), (-0.0, 25144), (-0.5, 25121), (f32::INFINITY, 24924), (0.0, 24834), (2.0, 24770), (-2.0, 24716), (3.0, 16990), (-3.0, 16941), (0.75, 16655), (-0.75, 16611), (4.0, 12510), (0.25, 12465), (-4.0, 12461), (-0.25, 12430), ]; let sample_median = (0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(f64::NAN), standard_deviation: NiceFloat(f64::NAN), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; special_random_primitive_float_inclusive_range_helper::( f32::NEGATIVE_INFINITY, f32::INFINITY, 1, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f32, a = -0.0, b = -0.0, mean abs of exponent = 1, mean precision = 2, mean zero P = 1/10 let values = &[-0.0; 50]; let common_values = &[(-0.0, 1000000)]; let sample_median = (-0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(0.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; special_random_primitive_float_inclusive_range_helper::( -0.0, -0.0, 1, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f64, a = 1.0, b = 2.0, mean abs of exponent = 1, mean precision = 2, mean zero P = 1/10 let values = &[ 2.0, 2.0, 2.0, 1.0, 1.5, 2.0, 1.0, 1.0, 1.5, 2.0, 1.28125, 1.0, 2.0, 1.0, 1.4375, 1.8125, 1.6875, 1.0, 1.75, 1.875, 2.0, 1.0, 2.0, 1.0, 1.75, 2.0, 2.0, 2.0, 2.0, 1.75, 2.0, 1.5, 1.484375, 2.0, 1.0, 2.0, 1.75, 2.0, 1.25, 1.0, 1.5, 1.25, 1.546875, 1.0, 2.0, 2.0, 2.0, 1.4921875, 2.0, 2.0, ]; let common_values = &[ (2.0, 332566), (1.0, 222394), (1.5, 148417), (1.75, 49426), (1.25, 49385), (1.375, 16729), (1.625, 16608), (1.125, 16560), (1.875, 16529), (1.8125, 5619), (1.5625, 5582), (1.6875, 5424), (1.9375, 5418), (1.4375, 5415), (1.0625, 5401), (1.3125, 5359), (1.1875, 5325), (1.09375, 1909), (1.65625, 1901), (1.96875, 1893), ]; let sample_median = (1.5, None); let sample_moment_stats = MomentStats { mean: NiceFloat(1.5552951797578527), standard_deviation: NiceFloat(0.39732291679015563), skewness: NiceFloat(-0.2001600069371136), excess_kurtosis: NiceFloat(-1.5071515332005163), }; special_random_primitive_float_inclusive_range_helper::( 1.0, 2.0, 1, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f64, a = 1.0, b = 2.0, mean abs of exponent = 10, mean precision = 10, mean zero P = 1/100 let values = &[ 2.0, 2.0, 1.0, 1.640625, 1.375, 2.0, 1.90625, 2.0, 2.0, 1.25, 1.0, 2.0, 2.0, 1.9375, 1.5, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 1.96875, 2.0, 1.14794921875, 1.4569854736328125, 1.2559814453125, 1.5579833984375, 2.0, 2.0, 1.22509765625, 1.0812369697232498, 1.5, 2.0, 1.1291658878326416, 2.0, 1.666259765625, 2.0, 2.0, 2.0, 1.03857421875, 2.0, 2.0, 2.0, 2.0, 1.5, 1.125, 2.0, 1.0, 1.4247607216238976, ]; let common_values = &[ (2.0, 476330), (1.0, 47627), (1.5, 43214), (1.75, 19860), (1.25, 19849), (1.875, 9069), (1.625, 9023), (1.125, 8975), (1.375, 8966), (1.5625, 4216), (1.4375, 4204), (1.3125, 4172), (1.1875, 4093), (1.9375, 4059), (1.8125, 4047), (1.6875, 4030), (1.0625, 4007), (1.09375, 1944), (1.28125, 1938), (1.53125, 1903), ]; let sample_median = (1.9375, None); let sample_moment_stats = MomentStats { mean: NiceFloat(1.714502436478215), standard_deviation: NiceFloat(0.34632959887726134), skewness: NiceFloat(-0.804949565136136), excess_kurtosis: NiceFloat(-0.8346071411985774), }; special_random_primitive_float_inclusive_range_helper::( 1.0, 2.0, 10, 1, 10, 1, 1, 100, values, common_values, sample_median, sample_moment_stats, ); // f64, a = -0.1, b = 0.1, mean abs of exponent = 5, mean precision = 2, mean zero P = 1/10 let values = &[ 0.09375, 0.01171875, 0.01171875, -0.0, -0.09375, -0.01171875, -0.01171875, -0.03125, 0.03125, 0.0625, -0.0625, -0.07525634765625, -0.0625, 0.0, -0.09375, -0.09375, -0.09375, -0.0, 0.07525634765625, -0.078125, -0.05078125, 0.0625, 0.09375, 0.09375, -0.0244140625, 0.09375, -0.001953125, 0.078125, 0.05078125, -0.0, -0.0625, -0.09375, 0.0, 0.0244140625, -0.03125, -0.00439453125, -0.09375, 0.001953125, -0.09375, -0.0035400390625, -0.03125, 0.0625, -0.046875, 0.09375, -0.0625, 0.03125, 0.0, -0.0146484375, 0.00439453125, 0.09375, ]; let common_values = &[ (0.0625, 74957), (-0.0625, 74731), (-0.0, 50351), (0.09375, 50307), (-0.09375, 50176), (0.0, 49873), (0.03125, 37778), (-0.03125, 37674), (0.078125, 33218), (-0.078125, 33137), (0.046875, 25128), (-0.046875, 25051), (0.015625, 18742), (-0.015625, 18691), (0.0234375, 12592), (-0.0234375, 12548), (0.0859375, 11149), (-0.0859375, 11121), (0.0703125, 11027), (-0.0703125, 10991), ]; let sample_median = (0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(0.00006747896492481727), standard_deviation: NiceFloat(0.05672798899804289), skewness: NiceFloat(-0.001703150825150012), excess_kurtosis: NiceFloat(-1.1100263487007116), }; special_random_primitive_float_inclusive_range_helper::( -0.1, 0.1, 5, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f64, a = -0.1, b = 0.1, mean abs of exponent = 10, mean precision = 10, mean zero P = 1/100 let values = &[ 0.005245480002486147, 0.0625, 0.00037892110412940383, -0.005245480002486147, -0.0625, -0.00037892110412940383, -0.0025482177734375, 0.0025482177734375, 0.08385447226464748, -0.08385447226464748, -0.07456207275390625, -0.076171875, -0.000156402587890625, -0.0004252493381500244, -0.0029296875, 0.07456207275390625, -0.012820055672818853, -0.05615234375, 0.076171875, 0.000156402587890625, 0.0004252493381500244, -6.198883056640625e-6, 0.0029296875, -0.00057220458984375, 0.012820055672818853, 0.05615234375, -0.0003814697265625, -0.0625, 6.198883056640625e-6, -0.00092315673828125, -0.00030517578125, -0.00007461127825081348, 0.00057220458984375, -0.0029296875, -0.05444455146789551, -0.009765625, 0.0003814697265625, -0.0007852371782064438, 0.0625, -0.07266771433324948, 0.00092315673828125, -0.02317537716589868, 0.00030517578125, 0.00007461127825081348, 0.0029296875, 0.05444455146789551, -0.007110595703125, -0.00537109375, -0.0072021484375, -2.2798776626586914e-6, ]; let common_values = &[ (0.0625, 6407), (-0.0625, 6393), (0.09375, 5870), (-0.09375, 5858), (0.03125, 5626), (-0.03125, 5611), (0.078125, 5277), (-0.078125, 5260), (-0.0, 5098), (0.046875, 4988), (-0.046875, 4978), (0.0, 4891), (0.015625, 4680), (-0.015625, 4672), (0.0234375, 4384), (-0.0234375, 4374), (0.0078125, 4263), (-0.0078125, 4260), (0.01171875, 3729), (-0.01171875, 3726), ]; let sample_median = (0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(0.000022298181036079024), standard_deviation: NiceFloat(0.035440202565071834), skewness: NiceFloat(0.00030138197742575316), excess_kurtosis: NiceFloat(1.5712669731678002), }; special_random_primitive_float_inclusive_range_helper::( -0.1, 0.1, 10, 1, 10, 1, 1, 100, values, common_values, sample_median, sample_moment_stats, ); // f64, a = e, b = π, mean abs of exponent = 3, mean precision = 2, mean zero P = 1/10 let values = &[ 3.0, 2.859375, 3.0234375, 3.0, 2.75, 3.0, 3.0, 3.0, 2.75, 2.75, 3.078125, 3.0, 3.0, 3.0, 2.84375, 2.84375, 2.96875, 3.0, 3.125, 2.8125, 3.0, 3.0, 3.03125, 3.0, 3.125, 3.125, 2.875, 3.0, 2.75, 2.875, 3.0, 2.75, 2.9140625, 2.734375, 3.0, 3.0, 3.125, 2.92578125, 3.125, 3.0, 2.75, 3.125, 2.9921875, 3.0, 2.75, 3.0, 3.0, 3.01953125, 3.0, 2.8125, ]; let common_values = &[ (3.0, 333198), (2.75, 222142), (3.125, 74385), (2.875, 73751), (2.9375, 33356), (2.8125, 33246), (3.0625, 32891), (3.03125, 9479), (2.71875, 9381), (2.84375, 9352), (2.90625, 9344), (2.78125, 9342), (2.96875, 9313), (3.09375, 9258), (2.765625, 3221), (2.921875, 3214), (3.015625, 3204), (3.046875, 3175), (2.859375, 3165), (2.734375, 3163), ]; let sample_median = (3.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(2.9232526079986494), standard_deviation: NiceFloat(0.1262248827883599), skewness: NiceFloat(-0.17691898540367232), excess_kurtosis: NiceFloat(-1.2742881322265622), }; special_random_primitive_float_inclusive_range_helper::( core::f64::consts::E, core::f64::consts::PI, 3, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f64, a = e, b = π, mean abs of exponent = 10, mean precision = 10, mean zero P = 1/100 let values = &[ 2.923828125, 2.953125, 3.0, 2.8671875, 2.8125, 3.125, 3.015625, 2.8462657928466797, 3.140625, 2.875, 3.0, 2.75, 3.0, 2.71875, 2.75, 3.021484375, 2.97064208984375, 3.0179443359375, 2.9688720703125, 2.75, 2.97635555267334, 2.875, 2.890625, 2.8388671875, 2.781494140625, 3.0876541137695312, 3.10650634765625, 2.81756591796875, 2.8125, 2.774658203125, 2.746337890625, 3.086890615457378, 2.75, 2.7857666015625, 2.9739707708358765, 2.7529093623161316, 2.7723388671875, 3.125, 2.94140625, 2.916015625, 2.776611328125, 2.823486328125, 3.0, 3.0, 3.135541538707912, 2.75, 3.0625, 2.734408974647522, 3.0, 2.789327871054411, ]; let common_values = &[ (3.0, 91105), (2.75, 83336), (2.875, 38014), (3.125, 37964), (3.0625, 23196), (2.9375, 22929), (2.8125, 22922), (3.09375, 9177), (2.78125, 9003), (2.84375, 8943), (2.90625, 8936), (2.71875, 8920), (3.03125, 8913), (2.96875, 8854), (2.765625, 4212), (2.859375, 4171), (2.953125, 4126), (2.890625, 4119), (3.015625, 4090), (2.984375, 4082), ]; let sample_median = (2.9375, None); let sample_moment_stats = MomentStats { mean: NiceFloat(2.9261256924208183), standard_deviation: NiceFloat(0.12519730680807895), skewness: NiceFloat(-0.016892719700380622), excess_kurtosis: NiceFloat(-1.2338524787684633), }; special_random_primitive_float_inclusive_range_helper::( core::f64::consts::E, core::f64::consts::PI, 10, 1, 10, 1, 1, 100, values, common_values, sample_median, sample_moment_stats, ); // f64, a = 100.0, b = 101.0, mean abs of exponent = 7, mean precision = 2, mean zero P = 1/10 let values = &[ 100.0, 100.5625, 100.40625, 100.0, 101.0, 100.0, 100.0, 100.0, 101.0, 101.0, 100.8125, 100.0, 100.0, 100.0, 100.375, 100.875, 100.875, 100.0, 100.5, 100.75, 100.0, 100.0, 100.875, 100.0, 100.5, 100.5, 100.5, 100.0, 101.0, 100.5, 100.0, 101.0, 100.46875, 100.1875, 100.0, 100.0, 100.5, 100.546875, 100.5, 100.0, 101.0, 100.5, 100.96875, 100.0, 101.0, 100.0, 100.0, 100.296875, 100.0, 100.75, ]; let common_values = &[ (100.0, 333198), (101.0, 222142), (100.5, 148136), (100.75, 49930), (100.25, 49563), (100.375, 16456), (100.875, 16346), (100.625, 16343), (100.125, 16324), (100.6875, 5638), (100.5625, 5588), (100.1875, 5508), (100.8125, 5478), (100.4375, 5449), (100.3125, 5420), (100.9375, 5417), (100.0625, 5309), (100.71875, 1910), (100.21875, 1891), (100.09375, 1867), ]; let sample_median = (100.5, None); let sample_moment_stats = MomentStats { mean: NiceFloat(100.44459040083368), standard_deviation: NiceFloat(0.39739652839770573), skewness: NiceFloat(0.20000867844534617), excess_kurtosis: NiceFloat(-1.5079346005477923), }; special_random_primitive_float_inclusive_range_helper::( 100.0, 101.0, 7, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f64, a = 100.0, b = 101.0, mean abs of exponent = 10, mean precision = 10, mean zero P = // 1/100 let values = &[ 100.8203125, 100.5625, 100.0, 100.71875, 100.75, 100.5, 100.9375, 100.88426971435547, 100.9375, 100.5, 100.0, 101.0, 100.0, 100.125, 101.0, 100.4609375, 100.511962890625, 100.46337890625, 100.80126953125, 101.0, 100.27350997924805, 100.5, 100.8125, 100.37109375, 100.3251953125, 100.13284301757812, 100.032470703125, 100.916748046875, 100.75, 100.0087890625, 100.2373046875, 100.59933795747929, 101.0, 100.89990234375, 100.71137285232544, 100.55885925889015, 100.15478515625, 100.5, 100.421875, 100.3671875, 100.8330078125, 100.9619140625, 100.0, 100.0, 100.72769894078374, 101.0, 100.25, 100.2837815284729, 100.0, 100.6954902857542, ]; let common_values = &[ (100.0, 91387), (101.0, 83529), (100.5, 76188), (100.25, 34644), (100.75, 34560), (100.375, 15817), (100.875, 15798), (100.125, 15698), (100.625, 15638), (100.6875, 7188), (100.9375, 7169), (100.5625, 7154), (100.1875, 7093), (100.0625, 7081), (100.3125, 7073), (100.8125, 7055), (100.4375, 6967), (100.34375, 3371), (100.59375, 3321), (100.21875, 3291), ]; let sample_median = (100.5, None); let sample_moment_stats = MomentStats { mean: NiceFloat(100.49597550384374), standard_deviation: NiceFloat(0.3229907369466344), skewness: NiceFloat(0.007882298769431025), excess_kurtosis: NiceFloat(-1.2073173945999414), }; special_random_primitive_float_inclusive_range_helper::( 100.0, 101.0, 10, 1, 10, 1, 1, 100, values, common_values, sample_median, sample_moment_stats, ); // f64, a = 1.0e38, b = Infinity, mean abs of exponent = 129, mean precision = 2, mean zero P = // 1/10 let values = &[ 4.0833884030512616e39, 1.0633823966279327e38, 1.0633823966279327e38, f64::INFINITY, 1.2760588759535192e38, 2.722258935367508e39, 2.1121432853022313e39, 1.0889035741470031e40, 3.2667107224410092e40, 1.0633823966279327e38, 1.0633823966279327e38, 1.3823971156163125e38, 3.828176627860558e38, f64::INFINITY, 1.3026434358692176e38, 3.402823669209385e38, 1.361129467683754e39, f64::INFINITY, 2.0416942015256308e39, 6.80564733841877e38, 1.5419044751105024e38, 4.0833884030512616e39, 2.5521177519070385e38, 1.1484529883581673e39, 1.7014118346046923e38, 1.4887353552791058e38, 1.361129467683754e39, 6.380294379767596e38, 4.253529586511731e38, f64::INFINITY, 4.519375185668714e38, 3.402823669209385e38, f64::INFINITY, 1.3823971156163125e38, 3.2667107224410092e40, 3.48449143727041e41, 2.9774707105582116e38, 7.443676776395529e38, 3.190147189883798e38, 2.5521177519070385e38, 1.9055812547572554e40, 3.4028236692093846e39, 1.0633823966279327e38, 6.80564733841877e38, 1.7014118346046923e38, 1.2760588759535192e38, f64::INFINITY, 1.4879045877817402e38, 1.595073594941899e38, 8.166776806102523e40, ]; let common_values = &[ (f64::INFINITY, 100224), (1.2760588759535192e38, 74870), (1.7014118346046923e38, 56023), (3.402823669209385e38, 42298), (2.5521177519070385e38, 37662), (6.80564733841877e38, 31926), (5.104235503814077e38, 28139), (1.0633823966279327e38, 25142), (1.4887353552791058e38, 25038), (1.361129467683754e39, 23671), (1.0208471007628154e39, 21048), (2.722258935367508e39, 17641), (2.0416942015256308e39, 15983), (5.444517870735016e39, 13496), (2.1267647932558654e38, 12408), (2.9774707105582116e38, 12336), (4.0833884030512616e39, 11938), (1.169720636290726e38, 11049), (1.595073594941899e38, 10950), (1.3823971156163125e38, 10907), ]; let sample_median = (5.84860318145363e38, None); let sample_moment_stats = MomentStats { mean: NiceFloat(f64::NAN), standard_deviation: NiceFloat(f64::NAN), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; special_random_primitive_float_inclusive_range_helper::( 1.0e38, f64::INFINITY, 129, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f64, a = -f64::MIN_POSITIVE_SUBNORMAL, b = f64::MIN_POSITIVE_SUBNORMAL, mean abs of exponent // = 1075, mean precision = 2, mean zero P = 1/10 let values = &[ 5.0e-324, 5.0e-324, 5.0e-324, -0.0, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, 5.0e-324, 5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, 0.0, -5.0e-324, -5.0e-324, -5.0e-324, -0.0, 5.0e-324, -5.0e-324, -5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, -5.0e-324, 5.0e-324, -5.0e-324, 5.0e-324, 5.0e-324, -0.0, -5.0e-324, -5.0e-324, 0.0, 5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, 5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, 5.0e-324, -5.0e-324, 5.0e-324, -5.0e-324, 5.0e-324, 0.0, -5.0e-324, 5.0e-324, 5.0e-324, ]; let common_values = &[(5.0e-324, 450531), (-5.0e-324, 449245), (-0.0, 50351), (0.0, 49873)]; let sample_median = (0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(5.0e-324), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; special_random_primitive_float_inclusive_range_helper::( -f64::MIN_POSITIVE_SUBNORMAL, f64::MIN_POSITIVE_SUBNORMAL, 1075, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f64, a = -0.0, b = f64::MIN_POSITIVE_SUBNORMAL, mean abs of exponent = 1075, mean precision = // 2, mean zero P = 1/10 let values = &[ 5.0e-324, 5.0e-324, 5.0e-324, -0.0, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 0.0, 5.0e-324, 5.0e-324, 5.0e-324, -0.0, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, -0.0, 5.0e-324, 5.0e-324, 0.0, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 0.0, 5.0e-324, 5.0e-324, 5.0e-324, ]; let common_values = &[(5.0e-324, 899776), (-0.0, 50351), (0.0, 49873)]; let sample_median = (5.0e-324, None); let sample_moment_stats = MomentStats { mean: NiceFloat(5.0e-324), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; special_random_primitive_float_inclusive_range_helper::( -0.0, f64::MIN_POSITIVE_SUBNORMAL, 1075, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f64, a = 0.0, b = 0.0, mean abs of exponent = 1075, mean precision = 2, mean zero P = 1/10 let values = &[0.0; 50]; let common_values = &[(0.0, 1000000)]; let sample_median = (0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(0.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; special_random_primitive_float_inclusive_range_helper::( 0.0, 0.0, 1075, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // -f64::MIN_POSITIVE_SUBNORMAL, b = -f64::MIN_POSITIVE_SUBNORMAL, mean abs of exponent = 1075, // mean precision = 2, mean zero P = 1/10 let values = &[-5.0e-324; 50]; let common_values = &[(-5.0e-324, 1000000)]; let sample_median = (-5.0e-324, None); let sample_moment_stats = MomentStats { mean: NiceFloat(-5.0e-324), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; special_random_primitive_float_inclusive_range_helper::( -f64::MIN_POSITIVE_SUBNORMAL, -f64::MIN_POSITIVE_SUBNORMAL, 1075, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f64, a = -f64::MIN_POSITIVE_SUBNORMAL, b = 0.0, mean abs of exponent = 1075, mean precision = // 2, mean zero P = 1/10 let values = &[ -5.0e-324, -5.0e-324, -5.0e-324, -0.0, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, 0.0, -5.0e-324, -5.0e-324, -5.0e-324, -0.0, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -0.0, -5.0e-324, -5.0e-324, 0.0, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, 0.0, -5.0e-324, -5.0e-324, -5.0e-324, ]; let common_values = &[(-5.0e-324, 899776), (-0.0, 50351), (0.0, 49873)]; let sample_median = (-5.0e-324, None); let sample_moment_stats = MomentStats { mean: NiceFloat(-5.0e-324), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; special_random_primitive_float_inclusive_range_helper::( -f64::MIN_POSITIVE_SUBNORMAL, 0.0, 1075, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f64, a = -Infinity, b = Infinity, mean abs of exponent = 1, mean precision = 2, mean zero P = // 1/10 let values = &[ 12.0, 1.5, 0.75, -0.0, -12.0, -1.5, -0.75, -4.0, 4.0, 2.0, -2.0, -1.2041015625, -2.0, f64::NEGATIVE_INFINITY, -0.75, -0.75, -3.0, 0.0, 1.2041015625, -40.0, -0.6875, 2.0, 0.75, 0.75, -1.3125, 3.0, -2.0, 40.0, 0.6875, -0.0, -0.5, -1.5, f64::NEGATIVE_INFINITY, 1.3125, -0.125, -1.125, -0.046875, 2.0, -1.5, -1.9375, -1.0, 0.5, -0.75, 1.5, -1.0, 0.125, f64::INFINITY, -1.875, 1.125, 0.046875, ]; let common_values = &[ (1.0, 49883), (-1.0, 49740), (1.5, 33699), (-1.5, 33608), (f64::NEGATIVE_INFINITY, 25322), (0.5, 25188), (-0.0, 25144), (-0.5, 25120), (f64::INFINITY, 24924), (0.0, 24834), (2.0, 24765), (-2.0, 24711), (3.0, 16988), (-3.0, 16939), (0.75, 16654), (-0.75, 16610), (4.0, 12510), (0.25, 12465), (-4.0, 12461), (-0.25, 12430), ]; let sample_median = (0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(f64::NAN), standard_deviation: NiceFloat(f64::NAN), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; special_random_primitive_float_inclusive_range_helper::( f64::NEGATIVE_INFINITY, f64::INFINITY, 1, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f64, a = -0.0, b = -0.0, mean abs of exponent = 1, mean precision = 2, mean zero P = 1/10 let values = &[-0.0; 50]; let common_values = &[(-0.0, 1000000)]; let sample_median = (-0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(0.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; special_random_primitive_float_inclusive_range_helper::( -0.0, -0.0, 1, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); } fn special_random_primitive_float_inclusive_range_fail_helper() { assert_panic!(special_random_primitive_float_inclusive_range::( EXAMPLE_SEED, T::ONE, T::ZERO, 1, 1, 2, 1, 1, 10 )); assert_panic!(special_random_primitive_float_inclusive_range::( EXAMPLE_SEED, T::ONE, T::NAN, 1, 1, 2, 1, 1, 10 )); assert_panic!(special_random_primitive_float_inclusive_range::( EXAMPLE_SEED, T::ONE, T::TWO, 0, 1, 2, 1, 1, 10 )); assert_panic!(special_random_primitive_float_inclusive_range::( EXAMPLE_SEED, T::ONE, T::TWO, 1, 0, 2, 1, 1, 10 )); assert_panic!(special_random_primitive_float_inclusive_range::( EXAMPLE_SEED, T::from(100.0), T::from(101.0), 6, 1, 2, 1, 1, 10 )); assert_panic!(special_random_primitive_float_inclusive_range::( EXAMPLE_SEED, T::ONE, T::TWO, 1, 1, 1, 2, 1, 10 )); assert_panic!(special_random_primitive_float_inclusive_range::( EXAMPLE_SEED, T::ONE, T::TWO, 1, 1, 1, 0, 1, 10 )); assert_panic!(special_random_primitive_float_inclusive_range::( EXAMPLE_SEED, T::ONE, T::TWO, 1, 1, 2, 1, 2, 1 )); assert_panic!(special_random_primitive_float_inclusive_range::( EXAMPLE_SEED, T::ONE, T::TWO, 1, 1, 2, 1, 1, 0 )); } #[test] fn special_random_primitive_float_inclusive_range_fail() { apply_fn_to_primitive_floats!(special_random_primitive_float_inclusive_range_fail_helper); } malachite-base-0.4.16/tests/num/random/special_random_primitive_float_range.rs000064400000000000000000001571001046102023000257570ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::traits::NegativeInfinity; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::special_random_primitive_float_range; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::num::random::special_random_primitive_floats_helper_helper; use malachite_base::test_util::stats::moments::{CheckedToF64, MomentStats}; use std::panic::catch_unwind; fn special_random_primitive_float_range_helper( a: T, b: T, mean_exponent_numerator: u64, mean_exponent_denominator: u64, mean_precision_numerator: u64, mean_precision_denominator: u64, mean_zero_p_numerator: u64, mean_zero_p_denominator: u64, expected_values: &[T], expected_common_values: &[(T, usize)], expected_median: (T, Option), expected_moment_stats: MomentStats, ) { special_random_primitive_floats_helper_helper( special_random_primitive_float_range::( EXAMPLE_SEED, a, b, mean_exponent_numerator, mean_exponent_denominator, mean_precision_numerator, mean_precision_denominator, mean_zero_p_numerator, mean_zero_p_denominator, ), expected_values, expected_common_values, expected_median, expected_moment_stats, ); } #[test] fn test_special_random_primitive_float_range() { // f32, a = 1.0, b = 2.0, mean abs of exponent = 1, mean precision = 2, mean zero P = 1/10 let values = &[ 1.0, 1.28125, 1.609375, 1.0, 1.5, 1.0, 1.0, 1.0, 1.5, 1.5, 1.71875, 1.0, 1.0, 1.0, 1.9375, 1.9375, 1.9375, 1.0, 1.25, 1.375, 1.0, 1.0, 1.3125, 1.0, 1.25, 1.25, 1.75, 1.0, 1.5, 1.75, 1.0, 1.5, 1.484375, 1.65625, 1.0, 1.0, 1.75, 1.5234375, 1.75, 1.0, 1.5, 1.25, 1.515625, 1.0, 1.5, 1.0, 1.0, 1.4140625, 1.0, 1.875, ]; let common_values = &[ (1.0, 333222), (1.5, 222154), (1.75, 74130), (1.25, 74019), (1.375, 25091), (1.875, 24869), (1.625, 24805), (1.125, 24731), (1.4375, 8353), (1.8125, 8307), (1.5625, 8208), (1.6875, 8156), (1.0625, 8145), (1.3125, 8117), (1.1875, 8108), (1.9375, 8080), (1.03125, 2799), (1.96875, 2798), (1.15625, 2785), (1.28125, 2779), ]; let sample_median = (1.3359375, None); let sample_moment_stats = MomentStats { mean: NiceFloat(1.3333245906621964), standard_deviation: NiceFloat(0.29800120914228473), skewness: NiceFloat(0.27868047434467813), excess_kurtosis: NiceFloat(-1.2068148586621514), }; special_random_primitive_float_range_helper::( 1.0, 2.0, 1, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f32, a = 1.0, b = 2.0, mean abs of exponent = 10, mean precision = 10, mean zero P = 1/100 let values = &[ 1.4101562, 1.90625, 1.0, 1.953125, 1.875, 1.75, 1.46875, 1.3115959, 1.46875, 1.25, 1.0, 1.5, 1.0, 1.5625, 1.5, 1.5117188, 1.1158447, 1.2253418, 1.1882324, 1.5, 1.1991673, 1.75, 1.15625, 1.2519531, 1.0668945, 1.6660919, 1.0096436, 1.2796631, 1.875, 1.6987305, 1.8608398, 1.3996582, 1.5, 1.1125488, 1.419461, 1.25, 1.0681152, 1.75, 1.1171875, 1.4804688, 1.7055664, 1.3237305, 1.0, 1.0, 1.84375, 1.5, 1.125, 1.3097513, 1.0, 1.375, ]; let common_values = &[ (1.0, 100845), (1.5, 91973), (1.75, 42129), (1.25, 41726), (1.125, 19270), (1.625, 19149), (1.875, 19012), (1.375, 18836), (1.8125, 8852), (1.1875, 8822), (1.3125, 8722), (1.0625, 8692), (1.4375, 8630), (1.6875, 8623), (1.9375, 8620), (1.5625, 8431), (1.71875, 4047), (1.09375, 3974), (1.40625, 3949), (1.90625, 3941), ]; let sample_median = (1.4912109, None); let sample_moment_stats = MomentStats { mean: NiceFloat(1.449574181673412), standard_deviation: NiceFloat(0.29612085814559613), skewness: NiceFloat(0.029341331332504897), excess_kurtosis: NiceFloat(-1.1487737412063284), }; special_random_primitive_float_range_helper::( 1.0, 2.0, 10, 1, 10, 1, 1, 100, values, common_values, sample_median, sample_moment_stats, ); // f32, a = -0.1, b = 0.1, mean abs of exponent = 5, mean precision = 2, mean zero P = 1/10 let values = &[ 0.09375, 0.01171875, 0.01171875, -0.0, -0.09375, -0.01171875, -0.01171875, -0.03125, 0.03125, 0.0625, -0.0625, -0.07525635, -0.0625, 0.0, -0.09375, -0.09375, -0.09375, -0.0, 0.07525635, -0.078125, -0.05078125, 0.0625, 0.09375, 0.09375, -0.024414062, 0.09375, -0.001953125, 0.078125, 0.05078125, -0.0, -0.0625, -0.09375, 0.0, 0.024414062, -0.03125, -0.0043945312, -0.09375, 0.001953125, -0.09375, -0.003540039, -0.03125, 0.0625, -0.046875, 0.09375, -0.0625, 0.03125, 0.0, -0.0146484375, 0.0043945312, 0.09375, ]; let common_values = &[ (0.0625, 74962), (-0.0625, 74736), (-0.0, 50351), (0.09375, 50309), (-0.09375, 50178), (0.0, 49873), (0.03125, 37782), (-0.03125, 37678), (0.078125, 33219), (-0.078125, 33138), (0.046875, 25130), (-0.046875, 25053), (0.015625, 18743), (-0.015625, 18692), (0.0234375, 12593), (-0.0234375, 12549), (0.0703125, 11091), (0.0859375, 11088), (-0.0859375, 11060), (-0.0703125, 11055), ]; let sample_median = (0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(0.0000674789649248169), standard_deviation: NiceFloat(0.05672019953597066), skewness: NiceFloat(-0.001702872258409426), excess_kurtosis: NiceFloat(-1.109977309372344), }; special_random_primitive_float_range_helper::( -0.1, 0.1, 5, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f32, a = -0.1, b = 0.1, mean abs of exponent = 10, mean precision = 10, mean zero P = 1/100 let values = &[ 0.0041503906, 0.0625, 0.00042547443, -0.0041503906, -0.0625, -0.00042547443, -0.0027618408, 0.0027618408, 0.09375, -0.09375, -0.083244324, -0.076171875, -0.00023269653, -0.00043609738, -0.0029296875, 0.083244324, -0.011459351, -0.05419922, 0.076171875, 0.00023269653, 0.00043609738, -0.000006198883, 0.0029296875, -0.0008621216, 0.011459351, 0.05419922, -0.00035095215, -0.0625, 0.000006198883, -0.0008010864, -0.00030517578, -0.00008274312, 0.0008621216, -0.0029296875, -0.04892564, -0.013671875, 0.00035095215, -0.0009398293, 0.0625, -0.07344723, 0.0008010864, -0.01953125, 0.00030517578, 0.00008274312, 0.0029296875, 0.04892564, -0.006134033, -0.0070343018, -0.005493164, -0.0000029057264, ]; let common_values = &[ (0.0625, 7060), (-0.0625, 7045), (0.09375, 6481), (-0.09375, 6468), (0.03125, 6186), (-0.03125, 6171), (0.078125, 5831), (-0.078125, 5813), (0.046875, 5527), (-0.046875, 5516), (0.015625, 5112), (-0.015625, 5103), (-0.0, 5098), (0.0, 4891), (0.0234375, 4821), (-0.0234375, 4810), (0.0078125, 4681), (-0.0078125, 4678), (0.01171875, 4123), (-0.01171875, 4120), ]; let sample_median = (0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(0.000022248151599295377), standard_deviation: NiceFloat(0.035382441406785786), skewness: NiceFloat(0.0002929225243710825), excess_kurtosis: NiceFloat(1.5823949638933827), }; special_random_primitive_float_range_helper::( -0.1, 0.1, 10, 1, 10, 1, 1, 100, values, common_values, sample_median, sample_moment_stats, ); // f32, a = e, b = π, mean abs of exponent = 3, mean precision = 2, mean zero P = 1/10 let values = &[ 3.0, 2.859375, 3.0234375, 3.0, 2.75, 3.0, 3.0, 3.0, 2.75, 2.75, 3.078125, 3.0, 3.0, 3.0, 2.84375, 2.84375, 2.96875, 3.0, 3.125, 2.8125, 3.0, 3.0, 3.03125, 3.0, 3.125, 3.125, 2.875, 3.0, 2.75, 2.875, 3.0, 2.75, 2.9140625, 2.734375, 3.0, 3.0, 3.125, 2.9257812, 3.125, 3.0, 2.75, 3.125, 2.9921875, 3.0, 2.75, 3.0, 3.0, 3.0195312, 3.0, 2.8125, ]; let common_values = &[ (3.0, 333251), (2.75, 222162), (3.125, 74149), (2.875, 74011), (3.0625, 33262), (2.8125, 33146), (2.9375, 33097), (2.90625, 9548), (2.78125, 9377), (2.71875, 9327), (3.03125, 9327), (3.09375, 9323), (2.84375, 9315), (2.96875, 9265), (2.859375, 3186), (3.015625, 3185), (2.796875, 3180), (3.046875, 3160), (3.140625, 3157), (2.765625, 3152), ]; let sample_median = (3.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(2.923236772231216), standard_deviation: NiceFloat(0.12616339323242115), skewness: NiceFloat(-0.17689588042510748), excess_kurtosis: NiceFloat(-1.2738593390011854), }; special_random_primitive_float_range_helper::( core::f32::consts::E, core::f32::consts::PI, 3, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f32, a = e, b = π, mean abs of exponent = 10, mean precision = 10, mean zero P = 1/100 let values = &[ 2.9238281, 2.953125, 3.0, 2.8671875, 2.8125, 3.125, 3.015625, 2.8462658, 3.140625, 2.875, 3.0, 2.75, 3.0, 2.71875, 2.75, 3.0214844, 2.970642, 3.0179443, 2.968872, 2.75, 2.9763536, 2.875, 2.890625, 2.8388672, 2.7814941, 3.087654, 3.1065063, 2.817566, 2.8125, 2.7746582, 2.746338, 3.0207214, 2.75, 2.9852295, 3.0, 2.9980469, 3.006958, 2.875, 2.8632812, 2.9277344, 3.088623, 2.8376465, 3.0, 3.0, 3.0117188, 2.75, 2.8125, 3.0, 3.0, 3.140625, ]; let common_values = &[ (3.0, 103073), (2.75, 94168), (2.875, 43152), (3.125, 42886), (3.0625, 26213), (2.8125, 25982), (2.9375, 25799), (2.90625, 10203), (2.71875, 10186), (2.84375, 10149), (3.09375, 10141), (3.03125, 10134), (2.78125, 10085), (2.96875, 10085), (3.046875, 4666), (2.734375, 4649), (2.765625, 4649), (3.109375, 4629), (2.859375, 4606), (3.140625, 4590), ]; let sample_median = (2.9375, None); let sample_moment_stats = MomentStats { mean: NiceFloat(2.925577550306893), standard_deviation: NiceFloat(0.12565616542944752), skewness: NiceFloat(-0.016691773531483878), excess_kurtosis: NiceFloat(-1.2405888218124512), }; special_random_primitive_float_range_helper::( core::f32::consts::E, core::f32::consts::PI, 10, 1, 10, 1, 1, 100, values, common_values, sample_median, sample_moment_stats, ); // f32, a = 100.0, b = 101.0, mean abs of exponent = 7, mean precision = 2, mean zero P = 1/10 let values = &[ 100.0, 100.28125, 100.609375, 100.0, 100.5, 100.0, 100.0, 100.0, 100.5, 100.5, 100.71875, 100.0, 100.0, 100.0, 100.9375, 100.9375, 100.9375, 100.0, 100.25, 100.375, 100.0, 100.0, 100.3125, 100.0, 100.25, 100.25, 100.75, 100.0, 100.5, 100.75, 100.0, 100.5, 100.484375, 100.65625, 100.0, 100.0, 100.75, 100.52344, 100.75, 100.0, 100.5, 100.25, 100.515625, 100.0, 100.5, 100.0, 100.0, 100.41406, 100.0, 100.875, ]; let common_values = &[ (100.0, 333428), (100.5, 222283), (100.25, 74406), (100.75, 73829), (100.375, 25079), (100.625, 25046), (100.875, 24767), (100.125, 24656), (100.3125, 8323), (100.8125, 8256), (100.4375, 8240), (100.1875, 8213), (100.9375, 8177), (100.5625, 8174), (100.0625, 8080), (100.6875, 8059), (100.34375, 2831), (100.90625, 2811), (100.84375, 2797), (100.03125, 2781), ]; let sample_median = (100.33276, None); let sample_moment_stats = MomentStats { mean: NiceFloat(100.3331636999286), standard_deviation: NiceFloat(0.29794394613548436), skewness: NiceFloat(0.27963401436978874), excess_kurtosis: NiceFloat(-1.2056484413996), }; special_random_primitive_float_range_helper::( 100.0, 101.0, 7, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f32, a = 100.0, b = 101.0, mean abs of exponent = 10, mean precision = 10, mean zero P = // 1/100 let values = &[ 100.41016, 100.90625, 100.0, 100.953125, 100.875, 100.75, 100.46875, 100.0, 100.59375, 100.25, 100.0, 100.5, 100.0, 100.5625, 100.5, 100.24609, 100.3822, 100.41431, 100.40991, 100.5, 100.5, 100.25, 100.46875, 100.009766, 100.78467, 100.64989, 100.06262, 100.12927, 100.125, 100.833496, 100.01904, 100.0, 100.5, 100.11841, 100.6875, 100.75, 100.849365, 100.25, 100.44531, 100.58984, 100.3999, 100.13916, 100.0, 100.0, 100.382324, 100.5, 100.875, 100.3125, 100.0, 100.70117, ]; let common_values = &[ (100.0, 110530), (100.5, 100839), (100.75, 45914), (100.25, 45828), (100.625, 20971), (100.875, 20919), (100.125, 20849), (100.375, 20809), (100.8125, 9612), (100.3125, 9504), (100.9375, 9489), (100.1875, 9482), (100.0625, 9475), (100.6875, 9471), (100.4375, 9432), (100.5625, 9376), (100.40625, 4413), (100.59375, 4409), (100.03125, 4369), (100.21875, 4315), ]; let sample_median = (100.48999, None); let sample_moment_stats = MomentStats { mean: NiceFloat(100.44491497797223), standard_deviation: NiceFloat(0.29627860462288247), skewness: NiceFloat(0.0334721390871067), excess_kurtosis: NiceFloat(-1.1467496174419634), }; special_random_primitive_float_range_helper::( 100.0, 101.0, 10, 1, 10, 1, 1, 100, values, common_values, sample_median, sample_moment_stats, ); // f32, a = 1.0e38, b = Infinity, mean abs of exponent = 129, mean precision = 2, mean zero P = // 1/10 let values = &[ 1.7014118e38, 2.179934e38, 2.7382097e38, 1.2760589e38, 1.4887354e38, 1.2760589e38, 1.2760589e38, 1.2760589e38, 1.4887354e38, 1.0633824e38, 1.5020276e38, 1.7014118e38, 1.7014118e38, 1.7014118e38, 1.80775e38, 3.2964854e38, 3.2964854e38, 1.2760589e38, 1.1697206e38, 2.3394413e38, 1.2760589e38, 1.7014118e38, 1.4089817e38, 1.2760589e38, 2.1267648e38, 1.1697206e38, 1.1697206e38, 1.7014118e38, 2.5521178e38, 2.1267648e38, 1.7014118e38, 1.0633824e38, 2.2596876e38, 1.4754431e38, 1.2760589e38, 1.7014118e38, 2.1267648e38, 3.0705167e38, 2.9774707e38, 1.2760589e38, 1.0633824e38, 2.1267648e38, 1.0168594e38, 1.7014118e38, 2.5521178e38, 1.2760589e38, 1.2760589e38, 1.4654739e38, 1.7014118e38, 1.9140883e38, ]; let common_values = &[ (1.2760589e38, 190486), (1.7014118e38, 142730), (2.5521178e38, 95012), (1.4887354e38, 63724), (1.0633824e38, 63427), (2.1267648e38, 31749), (2.9774707e38, 31613), (1.3823971e38, 28489), (1.1697206e38, 28187), (1.5950736e38, 28108), (1.9140883e38, 10758), (3.1901472e38, 10750), (2.3394413e38, 10610), (2.7647942e38, 10493), (1.329228e38, 8248), (1.1165515e38, 8201), (1.5419045e38, 8177), (1.0102133e38, 8147), (1.4355662e38, 8096), (1.6482427e38, 8021), ]; let sample_median = (1.5286122e38, None); let sample_moment_stats = MomentStats { mean: NiceFloat(1.7213254069804385e38), standard_deviation: NiceFloat(5.915470456567596e37), skewness: NiceFloat(1.0016210709928859), excess_kurtosis: NiceFloat(-0.11636872848929292), }; special_random_primitive_float_range_helper::( 1.0e38, f32::INFINITY, 129, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f32, a = -f32::MIN_POSITIVE_SUBNORMAL, b = 3.0e-45, mean abs of exponent = 150, mean // precision = 2, mean zero P = 1/10 let values = &[ 1.0e-45, 1.0e-45, 1.0e-45, -0.0, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, 1.0e-45, 1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, 0.0, -1.0e-45, -1.0e-45, -1.0e-45, -0.0, 1.0e-45, -1.0e-45, -1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, -1.0e-45, 1.0e-45, -1.0e-45, 1.0e-45, 1.0e-45, -0.0, -1.0e-45, -1.0e-45, 0.0, 1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, 1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, 1.0e-45, -1.0e-45, 1.0e-45, -1.0e-45, 1.0e-45, 0.0, -1.0e-45, 1.0e-45, 1.0e-45, ]; let common_values = &[(1.0e-45, 450531), (-1.0e-45, 449245), (-0.0, 50351), (0.0, 49873)]; let sample_median = (0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(1.8020698251216835e-48), standard_deviation: NiceFloat(1.3292224464360085e-45), skewness: NiceFloat(-0.0025604536978191587), excess_kurtosis: NiceFloat(-1.8886053342505447), }; special_random_primitive_float_range_helper::( -f32::MIN_POSITIVE_SUBNORMAL, 3.0e-45, 150, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f32, a = -0.0, b = 3.0e-45, mean abs of exponent = 150, mean precision = 2, mean zero P = // 1/10 let values = &[ 1.0e-45, 1.0e-45, 1.0e-45, -0.0, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 0.0, 1.0e-45, 1.0e-45, 1.0e-45, -0.0, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, -0.0, 1.0e-45, 1.0e-45, 0.0, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 1.0e-45, 0.0, 1.0e-45, 1.0e-45, 1.0e-45, ]; let common_values = &[(1.0e-45, 899776), (-0.0, 50351), (0.0, 49873)]; let sample_median = (1.0e-45, None); let sample_moment_stats = MomentStats { mean: NiceFloat(1.2608547270363571e-45), standard_deviation: NiceFloat(4.2080794564999146e-46), skewness: NiceFloat(-2.662524701673921), excess_kurtosis: NiceFloat(5.089037787023615), }; special_random_primitive_float_range_helper::( -0.0, 3.0e-45, 150, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f32, a = 0.0, b = f32::MIN_POSITIVE_SUBNORMAL, mean abs of exponent = 150, mean precision = // 2, mean zero P = 1/10 let values = &[0.0; 50]; let common_values = &[(0.0, 1000000)]; let sample_median = (0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(0.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; special_random_primitive_float_range_helper::( 0.0, f32::MIN_POSITIVE_SUBNORMAL, 150, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // -f32::MIN_POSITIVE_SUBNORMAL, b = -0.0, mean abs of exponent = 150, mean precision = 2, mean // zero P = 1/10 let values = &[-1.0e-45; 50]; let common_values = &[(-1.0e-45, 1000000)]; let sample_median = (-1.0e-45, None); let sample_moment_stats = MomentStats { mean: NiceFloat(-1.401298464324817e-45), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; special_random_primitive_float_range_helper::( -f32::MIN_POSITIVE_SUBNORMAL, -0.0, 150, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f32, a = -f32::MIN_POSITIVE_SUBNORMAL, b = f32::MIN_POSITIVE_SUBNORMAL, mean abs of exponent // = 150, mean precision = 2, mean zero P = 1/10 let values = &[ -1.0e-45, -1.0e-45, -1.0e-45, -0.0, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, 0.0, -1.0e-45, -1.0e-45, -1.0e-45, -0.0, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -0.0, -1.0e-45, -1.0e-45, 0.0, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, -1.0e-45, 0.0, -1.0e-45, -1.0e-45, -1.0e-45, ]; let common_values = &[(-1.0e-45, 899776), (-0.0, 50351), (0.0, 49873)]; let sample_median = (-1.0e-45, None); let sample_moment_stats = MomentStats { mean: NiceFloat(-1.2608547270363571e-45), standard_deviation: NiceFloat(4.2080794564999146e-46), skewness: NiceFloat(2.662524701673921), excess_kurtosis: NiceFloat(5.089037787023615), }; special_random_primitive_float_range_helper::( -f32::MIN_POSITIVE_SUBNORMAL, f32::MIN_POSITIVE_SUBNORMAL, 150, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f32, a = -Infinity, b = Infinity, mean abs of exponent = 1, mean precision = 2, mean zero P = // 1/10 let values = &[ 12.0, 1.5, 0.75, 0.0, -12.0, -1.5, -0.75, -4.0, 4.0, 2.0, -2.0, -1.2041016, -2.0, f32::NEGATIVE_INFINITY, -0.75, -0.75, -3.0, 0.0, 1.2041016, -40.0, -0.6875, 2.0, 0.75, 0.75, -1.3125, 3.0, -2.0, 40.0, 0.6875, f32::NEGATIVE_INFINITY, -0.5, -1.5, -0.0, 1.3125, -0.125, -1.125, -0.046875, 2.0, -1.5, -1.9375, -1.0, 0.5, -0.75, 1.5, -1.0, 0.125, 0.0, -1.875, 1.125, 0.046875, ]; let common_values = &[ (1.0, 49888), (-1.0, 49745), (1.5, 33700), (f32::NEGATIVE_INFINITY, 33640), (-1.5, 33609), (0.0, 33393), (-0.0, 33191), (0.5, 25189), (-0.5, 25121), (2.0, 24770), (-2.0, 24716), (3.0, 16990), (-3.0, 16941), (0.75, 16655), (-0.75, 16611), (4.0, 12510), (0.25, 12465), (-4.0, 12461), (-0.25, 12430), (1.75, 11179), ]; let sample_median = (-0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(f64::NAN), standard_deviation: NiceFloat(f64::NAN), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; special_random_primitive_float_range_helper::( f32::NEGATIVE_INFINITY, f32::INFINITY, 1, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f32, a = -0.0, b = 0.0, mean abs of exponent = 1, mean precision = 2, mean zero P = 1/10 let values = &[-0.0; 50]; let common_values = &[(-0.0, 1000000)]; let sample_median = (-0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(0.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; special_random_primitive_float_range_helper::( -0.0, 0.0, 1, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f64, a = 1.0, b = 2.0, mean abs of exponent = 1, mean precision = 2, mean zero P = 1/10 let values = &[ 1.0, 1.28125, 1.609375, 1.0, 1.5, 1.0, 1.0, 1.0, 1.5, 1.5, 1.71875, 1.0, 1.0, 1.0, 1.9375, 1.9375, 1.9375, 1.0, 1.25, 1.375, 1.0, 1.0, 1.3125, 1.0, 1.25, 1.25, 1.75, 1.0, 1.5, 1.75, 1.0, 1.5, 1.484375, 1.65625, 1.0, 1.0, 1.75, 1.5234375, 1.75, 1.0, 1.5, 1.25, 1.515625, 1.0, 1.5, 1.0, 1.0, 1.4140625, 1.0, 1.875, ]; let common_values = &[ (1.0, 333198), (1.5, 222142), (1.25, 74116), (1.75, 74020), (1.625, 24916), (1.375, 24899), (1.875, 24889), (1.125, 24789), (1.8125, 8258), (1.0625, 8253), (1.9375, 8239), (1.5625, 8179), (1.6875, 8158), (1.1875, 8148), (1.4375, 8140), (1.3125, 8094), (1.40625, 2826), (1.84375, 2825), (1.34375, 2802), (1.78125, 2781), ]; let sample_median = (1.3359375, None); let sample_moment_stats = MomentStats { mean: NiceFloat(1.3334110677410675), standard_deviation: NiceFloat(0.29815058562815744), skewness: NiceFloat(0.27918114410601663), excess_kurtosis: NiceFloat(-1.206767297925903), }; special_random_primitive_float_range_helper::( 1.0, 2.0, 1, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f64, a = 1.0, b = 2.0, mean abs of exponent = 10, mean precision = 10, mean zero P = 1/100 let values = &[ 1.41015625, 1.90625, 1.0, 1.953125, 1.875, 1.75, 1.46875, 1.3115959167480469, 1.46875, 1.25, 1.0, 1.5, 1.0, 1.5625, 1.5, 1.51171875, 1.1158447265625, 1.225341796875, 1.188232421875, 1.5, 1.199167251586914, 1.75, 1.15625, 1.251953125, 1.06689453125, 1.6660919189453125, 1.0096435546875, 1.2796630859375, 1.875, 1.69873046875, 1.86083984375, 1.3819717407022836, 1.5, 1.802490234375, 1.909928560256958, 1.2957243919372559, 1.401123046875, 1.75, 1.3671875, 1.95703125, 1.14501953125, 1.59130859375, 1.0, 1.0, 1.825472442433238, 1.5, 1.375, 1.7292792797088623, 1.0, 1.852405808866024, ]; let common_values = &[ (1.0, 90973), (1.5, 83219), (1.75, 38074), (1.25, 37805), (1.875, 17372), (1.375, 17334), (1.625, 17115), (1.125, 17095), (1.3125, 7927), (1.6875, 7879), (1.4375, 7873), (1.5625, 7861), (1.9375, 7859), (1.8125, 7831), (1.1875, 7812), (1.0625, 7625), (1.84375, 3620), (1.34375, 3611), (1.28125, 3607), (1.15625, 3558), ]; let sample_median = (1.4921875, None); let sample_moment_stats = MomentStats { mean: NiceFloat(1.4546223996766015), standard_deviation: NiceFloat(0.29563414647088554), skewness: NiceFloat(0.02445210407687687), excess_kurtosis: NiceFloat(-1.1474911308258557), }; special_random_primitive_float_range_helper::( 1.0, 2.0, 10, 1, 10, 1, 1, 100, values, common_values, sample_median, sample_moment_stats, ); // f64, a = -0.1, b = 0.1, mean abs of exponent = 5, mean precision = 2, mean zero P = 1/10 let values = &[ 0.09375, 0.01171875, 0.01171875, -0.0, -0.09375, -0.01171875, -0.01171875, -0.03125, 0.03125, 0.0625, -0.0625, -0.07525634765625, -0.0625, 0.0, -0.09375, -0.09375, -0.09375, -0.0, 0.07525634765625, -0.078125, -0.05078125, 0.0625, 0.09375, 0.09375, -0.0244140625, 0.09375, -0.001953125, 0.078125, 0.05078125, -0.0, -0.0625, -0.09375, 0.0, 0.0244140625, -0.03125, -0.00439453125, -0.09375, 0.001953125, -0.09375, -0.0035400390625, -0.03125, 0.0625, -0.046875, 0.09375, -0.0625, 0.03125, 0.0, -0.0146484375, 0.00439453125, 0.09375, ]; let common_values = &[ (0.0625, 74957), (-0.0625, 74731), (-0.0, 50351), (0.09375, 50307), (-0.09375, 50176), (0.0, 49873), (0.03125, 37778), (-0.03125, 37674), (0.078125, 33218), (-0.078125, 33137), (0.046875, 25128), (-0.046875, 25051), (0.015625, 18742), (-0.015625, 18691), (0.0234375, 12592), (-0.0234375, 12548), (0.0859375, 11149), (-0.0859375, 11121), (0.0703125, 11027), (-0.0703125, 10991), ]; let sample_median = (0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(0.00006747896492481727), standard_deviation: NiceFloat(0.05672798899804289), skewness: NiceFloat(-0.001703150825150012), excess_kurtosis: NiceFloat(-1.1100263487007116), }; special_random_primitive_float_range_helper::( -0.1, 0.1, 5, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f64, a = -0.1, b = 0.1, mean abs of exponent = 10, mean precision = 10, mean zero P = 1/100 let values = &[ 0.005245480002486147, 0.0625, 0.00037892110412940383, -0.005245480002486147, -0.0625, -0.00037892110412940383, -0.0025482177734375, 0.0025482177734375, 0.08385447226464748, -0.08385447226464748, -0.07456207275390625, -0.076171875, -0.000156402587890625, -0.0004252493381500244, -0.0029296875, 0.07456207275390625, -0.012820055672818853, -0.05615234375, 0.076171875, 0.000156402587890625, 0.0004252493381500244, -6.198883056640625e-6, 0.0029296875, -0.00057220458984375, 0.012820055672818853, 0.05615234375, -0.0003814697265625, -0.0625, 6.198883056640625e-6, -0.00092315673828125, -0.00030517578125, -0.00007461127825081348, 0.00057220458984375, -0.0029296875, -0.05444455146789551, -0.009765625, 0.0003814697265625, -0.0007852371782064438, 0.0625, -0.07266771433324948, 0.00092315673828125, -0.02317537716589868, 0.00030517578125, 0.00007461127825081348, 0.0029296875, 0.05444455146789551, -0.007110595703125, -0.00537109375, -0.0072021484375, -2.2798776626586914e-6, ]; let common_values = &[ (0.0625, 6407), (-0.0625, 6393), (0.09375, 5870), (-0.09375, 5858), (0.03125, 5626), (-0.03125, 5611), (0.078125, 5277), (-0.078125, 5260), (-0.0, 5098), (0.046875, 4988), (-0.046875, 4978), (0.0, 4891), (0.015625, 4680), (-0.015625, 4672), (0.0234375, 4384), (-0.0234375, 4374), (0.0078125, 4263), (-0.0078125, 4260), (0.01171875, 3729), (-0.01171875, 3726), ]; let sample_median = (0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(0.000022298181036079024), standard_deviation: NiceFloat(0.035440202565071834), skewness: NiceFloat(0.00030138197742575316), excess_kurtosis: NiceFloat(1.5712669731678002), }; special_random_primitive_float_range_helper::( -0.1, 0.1, 10, 1, 10, 1, 1, 100, values, common_values, sample_median, sample_moment_stats, ); // f64, a = e, b = π, mean abs of exponent = 3, mean precision = 2, mean zero P = 1/10 let values = &[ 3.0, 2.859375, 3.0234375, 3.0, 2.75, 3.0, 3.0, 3.0, 2.75, 2.75, 3.078125, 3.0, 3.0, 3.0, 2.84375, 2.84375, 2.96875, 3.0, 3.125, 2.8125, 3.0, 3.0, 3.03125, 3.0, 3.125, 3.125, 2.875, 3.0, 2.75, 2.875, 3.0, 2.75, 2.9140625, 2.734375, 3.0, 3.0, 3.125, 2.92578125, 3.125, 3.0, 2.75, 3.125, 2.9921875, 3.0, 2.75, 3.0, 3.0, 3.01953125, 3.0, 2.8125, ]; let common_values = &[ (3.0, 333198), (2.75, 222142), (3.125, 74385), (2.875, 73751), (2.9375, 33356), (2.8125, 33246), (3.0625, 32891), (3.03125, 9479), (2.71875, 9381), (2.84375, 9352), (2.90625, 9344), (2.78125, 9342), (2.96875, 9313), (3.09375, 9258), (2.765625, 3221), (2.921875, 3214), (3.015625, 3204), (3.046875, 3175), (2.859375, 3165), (2.734375, 3163), ]; let sample_median = (3.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(2.9232526079986494), standard_deviation: NiceFloat(0.1262248827883599), skewness: NiceFloat(-0.17691898540367232), excess_kurtosis: NiceFloat(-1.2742881322265622), }; special_random_primitive_float_range_helper::( core::f64::consts::E, core::f64::consts::PI, 3, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f64, a = e, b = π, mean abs of exponent = 10, mean precision = 10, mean zero P = 1/100 let values = &[ 2.923828125, 2.953125, 3.0, 2.8671875, 2.8125, 3.125, 3.015625, 2.8462657928466797, 3.140625, 2.875, 3.0, 2.75, 3.0, 2.71875, 2.75, 3.021484375, 2.97064208984375, 3.0179443359375, 2.9688720703125, 2.75, 2.97635555267334, 2.875, 2.890625, 2.8388671875, 2.781494140625, 3.0876541137695312, 3.10650634765625, 2.81756591796875, 2.8125, 2.774658203125, 2.746337890625, 3.086890615457378, 2.75, 2.7857666015625, 2.9739707708358765, 2.7529093623161316, 2.7723388671875, 3.125, 2.94140625, 2.916015625, 2.776611328125, 2.823486328125, 3.0, 3.0, 3.135541538707912, 2.75, 3.0625, 2.734408974647522, 3.0, 2.789327871054411, ]; let common_values = &[ (3.0, 91105), (2.75, 83336), (2.875, 38014), (3.125, 37964), (3.0625, 23196), (2.9375, 22929), (2.8125, 22922), (3.09375, 9177), (2.78125, 9003), (2.84375, 8943), (2.90625, 8936), (2.71875, 8920), (3.03125, 8913), (2.96875, 8854), (2.765625, 4212), (2.859375, 4171), (2.953125, 4126), (2.890625, 4119), (3.015625, 4090), (2.984375, 4082), ]; let sample_median = (2.9375, None); let sample_moment_stats = MomentStats { mean: NiceFloat(2.9261256924208183), standard_deviation: NiceFloat(0.12519730680807895), skewness: NiceFloat(-0.016892719700380622), excess_kurtosis: NiceFloat(-1.2338524787684633), }; special_random_primitive_float_range_helper::( core::f64::consts::E, core::f64::consts::PI, 10, 1, 10, 1, 1, 100, values, common_values, sample_median, sample_moment_stats, ); // f64, a = 100.0, b = 101.0, mean abs of exponent = 7, mean precision = 2, mean zero P = 1/10 let values = &[ 100.0, 100.28125, 100.609375, 100.0, 100.5, 100.0, 100.0, 100.0, 100.5, 100.5, 100.71875, 100.0, 100.0, 100.0, 100.9375, 100.9375, 100.9375, 100.0, 100.25, 100.375, 100.0, 100.0, 100.3125, 100.0, 100.25, 100.25, 100.75, 100.0, 100.5, 100.75, 100.0, 100.5, 100.484375, 100.65625, 100.0, 100.0, 100.75, 100.5234375, 100.75, 100.0, 100.5, 100.25, 100.515625, 100.0, 100.5, 100.0, 100.0, 100.4140625, 100.0, 100.875, ]; let common_values = &[ (100.0, 333198), (100.5, 222142), (100.25, 74116), (100.75, 74020), (100.625, 24916), (100.375, 24899), (100.875, 24889), (100.125, 24789), (100.8125, 8258), (100.0625, 8253), (100.9375, 8239), (100.5625, 8179), (100.6875, 8158), (100.1875, 8148), (100.4375, 8140), (100.3125, 8094), (100.40625, 2826), (100.84375, 2825), (100.34375, 2802), (100.78125, 2781), ]; let sample_median = (100.3359375, None); let sample_moment_stats = MomentStats { mean: NiceFloat(100.33341106774094), standard_deviation: NiceFloat(0.29815058562814944), skewness: NiceFloat(0.27918114410604106), excess_kurtosis: NiceFloat(-1.2067672979256399), }; special_random_primitive_float_range_helper::( 100.0, 101.0, 7, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f64, a = 100.0, b = 101.0, mean abs of exponent = 10, mean precision = 10, mean zero P = // 1/100 let values = &[ 100.41015625, 100.90625, 100.0, 100.953125, 100.875, 100.75, 100.46875, 100.31159591674805, 100.46875, 100.25, 100.0, 100.5, 100.0, 100.5625, 100.5, 100.51171875, 100.1158447265625, 100.225341796875, 100.188232421875, 100.5, 100.19916725158691, 100.75, 100.15625, 100.251953125, 100.06689453125, 100.66609191894531, 100.0096435546875, 100.2796630859375, 100.875, 100.69873046875, 100.86083984375, 100.38197174070228, 100.5, 100.802490234375, 100.90992856025696, 100.83274569362402, 100.740478515625, 100.25, 100.9140625, 100.32421875, 100.45556640625, 100.36865234375, 100.0, 100.0, 100.09102300740778, 100.5, 100.125, 100.27702021598816, 100.0, 100.45081884413958, ]; let common_values = &[ (100.0, 91410), (100.5, 83666), (100.25, 38155), (100.75, 38107), (100.625, 17631), (100.125, 17378), (100.375, 17229), (100.875, 17035), (100.6875, 7968), (100.1875, 7924), (100.5625, 7918), (100.3125, 7917), (100.4375, 7914), (100.8125, 7806), (100.0625, 7786), (100.9375, 7756), (100.40625, 3664), (100.59375, 3645), (100.71875, 3629), (100.09375, 3596), ]; let sample_median = (100.4921875, None); let sample_moment_stats = MomentStats { mean: NiceFloat(100.45411484815686), standard_deviation: NiceFloat(0.2957014655624591), skewness: NiceFloat(0.026064278269824867), excess_kurtosis: NiceFloat(-1.1480623934899934), }; special_random_primitive_float_range_helper::( 100.0, 101.0, 10, 1, 10, 1, 1, 100, values, common_values, sample_median, sample_moment_stats, ); // f64, a = 1.0e38, b = Infinity, mean abs of exponent = 129, mean precision = 2, mean zero P = // 1/10 let values = &[ 1.78405961588245e44, 2.2322523270013563e41, 7.009816758571332e40, 2.1778071482940062e40, 1.4887353552791058e38, 5.575186299632656e42, 1.2760588759535192e38, 3.402823669209385e38, 8.166776806102523e39, 2.0416942015256308e39, 6.424531087467318e41, 1.7014118346046923e38, 2.722258935367508e39, 2.722258935367508e39, 5.274376687274546e39, 3.2964854295465914e38, 2.4457795122442452e38, 1.361129467683754e39, 2.3819765684465692e39, 1.914088313930279e38, 1.2760588759535192e38, 6.80564733841877e38, 1.089966956543631e38, 3.402823669209385e38, 2.9774707105582116e38, 5.954941421116423e38, 1.169720636290726e38, 1.7014118346046923e38, 1.6333553612205046e40, 2.9774707105582116e38, 2.722258935367508e39, 2.0416942015256308e39, 3.9557825154559096e39, 8.336917989562992e39, 5.444517870735016e39, 4.3556142965880123e40, 1.9055812547572554e40, 1.026164012745955e39, 3.4028236692093846e39, 1.2760588759535192e38, 1.3066842889764037e41, 4.7639531368931385e39, 1.2295358961010472e38, 1.7014118346046923e38, 1.6725558898897967e43, 1.2760588759535192e38, 1.2760588759535192e38, 1.6098350440189294e44, 1.7014118346046923e38, 3.743106036130323e39, ]; let common_values = &[ (1.2760588759535192e38, 83417), (1.7014118346046923e38, 62258), (3.402823669209385e38, 46943), (2.5521177519070385e38, 41660), (6.80564733841877e38, 35196), (5.104235503814077e38, 31368), (1.4887353552791058e38, 27818), (1.0633823966279327e38, 27639), (1.361129467683754e39, 26292), (1.0208471007628154e39, 23299), (2.722258935367508e39, 19745), (2.0416942015256308e39, 17625), (5.444517870735016e39, 14949), (2.9774707105582116e38, 13963), (2.1267647932558654e38, 13727), (4.0833884030512616e39, 13082), (1.169720636290726e38, 12430), (1.3823971156163125e38, 12379), (1.595073594941899e38, 12359), (1.0889035741470031e40, 11070), ]; let sample_median = (4.253529586511731e38, None); let sample_moment_stats = MomentStats { mean: NiceFloat(5.5180886046975516e45), standard_deviation: NiceFloat(1.9464007021815662e48), skewness: NiceFloat(500.41964668581875), excess_kurtosis: NiceFloat(285116.05539365485), }; special_random_primitive_float_range_helper::( 1.0e38, f64::INFINITY, 129, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f64, a = -f64::MIN_POSITIVE_SUBNORMAL, b = 1.0e-323, mean abs of exponent = 1075, mean // precision = 2, mean zero P = 1/10 let values = &[ 5.0e-324, 5.0e-324, 5.0e-324, -0.0, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, 5.0e-324, 5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, 0.0, -5.0e-324, -5.0e-324, -5.0e-324, -0.0, 5.0e-324, -5.0e-324, -5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, -5.0e-324, 5.0e-324, -5.0e-324, 5.0e-324, 5.0e-324, -0.0, -5.0e-324, -5.0e-324, 0.0, 5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, 5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, 5.0e-324, -5.0e-324, 5.0e-324, -5.0e-324, 5.0e-324, 0.0, -5.0e-324, 5.0e-324, 5.0e-324, ]; let common_values = &[(5.0e-324, 450531), (-5.0e-324, 449245), (-0.0, 50351), (0.0, 49873)]; let sample_median = (0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(5.0e-324), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; special_random_primitive_float_range_helper::( -f64::MIN_POSITIVE_SUBNORMAL, 1.0e-323, 1075, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f64, a = -0.0, b = 1.0e-323, mean abs of exponent = 1075, mean precision = 2, mean zero P = // 1/10 let values = &[ 5.0e-324, 5.0e-324, 5.0e-324, -0.0, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 0.0, 5.0e-324, 5.0e-324, 5.0e-324, -0.0, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, -0.0, 5.0e-324, 5.0e-324, 0.0, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 5.0e-324, 0.0, 5.0e-324, 5.0e-324, 5.0e-324, ]; let common_values = &[(5.0e-324, 899776), (-0.0, 50351), (0.0, 49873)]; let sample_median = (5.0e-324, None); let sample_moment_stats = MomentStats { mean: NiceFloat(5.0e-324), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; special_random_primitive_float_range_helper::( -0.0, 1.0e-323, 1075, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f64, a = 0.0, b = f64::MIN_POSITIVE_SUBNORMAL, mean abs of exponent = 1075, mean precision = // 2, mean zero P = 1/10 let values = &[0.0; 50]; let common_values = &[(0.0, 1000000)]; let sample_median = (0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(0.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; special_random_primitive_float_range_helper::( 0.0, f64::MIN_POSITIVE_SUBNORMAL, 1075, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // -f64::MIN_POSITIVE_SUBNORMAL, b = -0.0, mean abs of exponent = 1075, mean precision = 2, mean // zero P = 1/10 let values = &[-5.0e-324; 50]; let common_values = &[(-5.0e-324, 1000000)]; let sample_median = (-5.0e-324, None); let sample_moment_stats = MomentStats { mean: NiceFloat(-5.0e-324), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; special_random_primitive_float_range_helper::( -f64::MIN_POSITIVE_SUBNORMAL, -0.0, 1075, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f64, a = -f64::MIN_POSITIVE_SUBNORMAL, b = f64::MIN_POSITIVE_SUBNORMAL, mean abs of exponent // = 1075, mean precision = 2, mean zero P = 1/10 let values = &[ -5.0e-324, -5.0e-324, -5.0e-324, -0.0, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, 0.0, -5.0e-324, -5.0e-324, -5.0e-324, -0.0, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -0.0, -5.0e-324, -5.0e-324, 0.0, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, -5.0e-324, 0.0, -5.0e-324, -5.0e-324, -5.0e-324, ]; let common_values = &[(-5.0e-324, 899776), (-0.0, 50351), (0.0, 49873)]; let sample_median = (-5.0e-324, None); let sample_moment_stats = MomentStats { mean: NiceFloat(-5.0e-324), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; special_random_primitive_float_range_helper::( -f64::MIN_POSITIVE_SUBNORMAL, f64::MIN_POSITIVE_SUBNORMAL, 1075, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f64, a = -Infinity, b = Infinity, mean abs of exponent = 1, mean precision = 2, mean zero P = // 1/10 let values = &[ 12.0, 1.5, 0.75, 0.0, -12.0, -1.5, -0.75, -4.0, 4.0, 2.0, -2.0, -1.2041015625, -2.0, f64::NEGATIVE_INFINITY, -0.75, -0.75, -3.0, 0.0, 1.2041015625, -40.0, -0.6875, 2.0, 0.75, 0.75, -1.3125, 3.0, -2.0, 40.0, 0.6875, f64::NEGATIVE_INFINITY, -0.5, -1.5, -0.0, 1.3125, -0.125, -1.125, -0.046875, 2.0, -1.5, -1.9375, -1.0, 0.5, -0.75, 1.5, -1.0, 0.125, 0.0, -1.875, 1.125, 0.046875, ]; let common_values = &[ (1.0, 49883), (-1.0, 49740), (1.5, 33699), (f64::NEGATIVE_INFINITY, 33640), (-1.5, 33608), (0.0, 33393), (-0.0, 33191), (0.5, 25188), (-0.5, 25120), (2.0, 24765), (-2.0, 24711), (3.0, 16988), (-3.0, 16939), (0.75, 16654), (-0.75, 16610), (4.0, 12510), (0.25, 12465), (-4.0, 12461), (-0.25, 12430), (1.75, 11176), ]; let sample_median = (-0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(f64::NAN), standard_deviation: NiceFloat(f64::NAN), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; special_random_primitive_float_range_helper::( f64::NEGATIVE_INFINITY, f64::INFINITY, 1, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); // f64, a = -0.0, b = 0.0, mean abs of exponent = 1, mean precision = 2, mean zero P = 1/10 let values = &[-0.0; 50]; let common_values = &[(-0.0, 1000000)]; let sample_median = (-0.0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(0.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; special_random_primitive_float_range_helper::( -0.0, 0.0, 1, 1, 2, 1, 1, 10, values, common_values, sample_median, sample_moment_stats, ); } fn special_random_primitive_float_range_fail_helper() { assert_panic!(special_random_primitive_float_range::( EXAMPLE_SEED, T::ONE, T::ZERO, 1, 1, 2, 1, 1, 10 )); assert_panic!(special_random_primitive_float_range::( EXAMPLE_SEED, T::ONE, T::ONE, 1, 1, 2, 1, 1, 10 )); assert_panic!(special_random_primitive_float_range::( EXAMPLE_SEED, T::ONE, T::NAN, 1, 1, 2, 1, 1, 10 )); assert_panic!(special_random_primitive_float_range::( EXAMPLE_SEED, T::ONE, T::TWO, 0, 1, 2, 1, 1, 10 )); assert_panic!(special_random_primitive_float_range::( EXAMPLE_SEED, T::ONE, T::TWO, 1, 0, 2, 1, 1, 10 )); assert_panic!(special_random_primitive_float_range::( EXAMPLE_SEED, T::from(100.0), T::from(101.0), 6, 1, 2, 1, 1, 10 )); assert_panic!(special_random_primitive_float_range::( EXAMPLE_SEED, T::ONE, T::TWO, 1, 1, 1, 2, 1, 10 )); assert_panic!(special_random_primitive_float_range::( EXAMPLE_SEED, T::ONE, T::TWO, 1, 1, 1, 0, 1, 10 )); assert_panic!(special_random_primitive_float_range::( EXAMPLE_SEED, T::ONE, T::TWO, 1, 1, 2, 1, 2, 1 )); assert_panic!(special_random_primitive_float_range::( EXAMPLE_SEED, T::ONE, T::TWO, 1, 1, 2, 1, 1, 0 )); } #[test] fn special_random_primitive_float_range_fail() { apply_fn_to_primitive_floats!(special_random_primitive_float_range_fail_helper); } malachite-base-0.4.16/tests/num/random/special_random_primitive_floats.rs000064400000000000000000000320121046102023000247600ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::traits::NegativeInfinity; use malachite_base::num::random::special_random_primitive_floats; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::num::random::special_random_primitive_floats_helper_helper; use malachite_base::test_util::stats::moments::{CheckedToF64, MomentStats, NAN_MOMENT_STATS}; use std::panic::catch_unwind; fn special_random_primitive_floats_helper( mean_exponent_numerator: u64, mean_exponent_denominator: u64, mean_precision_numerator: u64, mean_precision_denominator: u64, mean_special_p_numerator: u64, mean_special_p_denominator: u64, expected_values: &[T], expected_common_values: &[(T, usize)], expected_median: (T, Option), expected_moment_stats: MomentStats, ) { special_random_primitive_floats_helper_helper( special_random_primitive_floats::( EXAMPLE_SEED, mean_exponent_numerator, mean_exponent_denominator, mean_precision_numerator, mean_precision_denominator, mean_special_p_numerator, mean_special_p_denominator, ), expected_values, expected_common_values, expected_median, expected_moment_stats, ); } #[test] fn test_special_random_primitive_floats() { // f32, mean abs of exponent = 1/64, mean precision = 65/64, mean special P = 1/4 let values = &[ f32::INFINITY, 1.0, 1.0, f32::INFINITY, 1.0, -1.0, f32::INFINITY, -1.0, f32::INFINITY, 0.0, -1.0, f32::INFINITY, -1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 0.5, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 0.0, -1.5, f32::NEGATIVE_INFINITY, 0.0, -1.0, 1.0, -1.0, -1.0, -1.0, -0.0, 1.0, -1.0, -0.5, -1.0, f32::INFINITY, f32::NEGATIVE_INFINITY, f32::INFINITY, 1.0, ]; let common_values = &[ (1.0, 358244), (-1.0, 357926), (f32::INFINITY, 50304), (f32::NEGATIVE_INFINITY, 50127), (-0.0, 49984), (f32::NAN, 49926), (0.0, 49868), (2.0, 5538), (1.5, 5500), (0.5, 5497), (-1.5, 5454), (-2.0, 5379), (-0.5, 5357), (0.75, 102), (3.0, 98), (-4.0, 95), (-0.25, 91), (-0.75, 87), (-3.0, 86), (0.25, 79), ]; let sample_median = (f32::NAN, None); special_random_primitive_floats_helper::( 1, 64, 65, 64, 1, 4, values, common_values, sample_median, NAN_MOMENT_STATS, ); // f32, mean abs of exponent = 1, mean precision = 2, mean special P = 1/10 let values = &[ 1.0, 1.25, 3.0, f32::INFINITY, -1.0, -1.0, -2.0, -3.5, 1.0, 2.0, -1.5, -2.5, -2.0, f32::INFINITY, -6.5, -1.0, -1.0, f32::INFINITY, 3.0, -0.21875, -1.0, 0.25, 1.5, 5.25, -4.0, 7.0, -0.5, 0.1875, 1.25, f32::INFINITY, -0.1875, -7.5, 0.0, 0.75, -7.0, -6.0, -3.0, 0.234375, -2.0, -0.875, -0.75, 6.0, -24.0, 24.0, -2.0, 1.5, f32::INFINITY, -1.25, 14.0, 5.0, ]; let common_values = &[ (1.0, 74789), (-1.0, 74702), (1.5, 38119), (-0.5, 37713), (2.0, 37640), (-1.5, 37613), (-2.0, 37333), (0.5, 37027), (f32::NEGATIVE_INFINITY, 20096), (0.0, 20064), (f32::INFINITY, 20042), (-0.0, 20022), (f32::NAN, 20000), (0.75, 19050), (4.0, 18892), (0.25, 18875), (-3.0, 18866), (3.0, 18821), (-0.75, 18725), (-4.0, 18663), ]; let sample_median = (f32::NAN, None); special_random_primitive_floats_helper::( 1, 1, 2, 1, 1, 10, values, common_values, sample_median, NAN_MOMENT_STATS, ); // f32, mean abs of exponent = 10, mean precision = 10, mean special P = 1/100 let values = &[ 0.65625, 0.0000014255784, 0.013183594, -0.8125, -74240.0, -0.0078125, -0.03060913, 3.331552, 4.75, -0.000038146973, -0.3125, -27136.0, -59392.0, -1.75, -41.1875, 0.30940247, -0.0009765625, -1536.0, 0.2109375, 0.0014648438, 2.1129381e-8, -0.037109375, 5242880.0, -0.21386719, 134.21094, 4.184082, -1561370.0, -2.1420419e-7, 0.38085938, -0.007003784, -37748736.0, -6448.0, 28.25, -6.703125, -4.483364, -3.1757812, 0.000003915804, -0.020751953, 0.00011110306, -0.000053405256, 0.00019985437, -35.40625, 0.005859375, 0.0078125, 28.25, 30.0, -0.20776367, -144.0, -0.109375, -6144.0, ]; let common_values = &[ (1.0, 2559), (-1.0, 2528), (0.5, 2362), (-2.0, 2312), (-1.5, 2306), (2.0, 2304), (1.5, 2275), (-0.5, 2243), (-3.0, 2204), (-4.0, 2163), (-0.25, 2129), (0.75, 2103), (3.0, 2081), (0.25, 2070), (f32::INFINITY, 2053), (-0.75, 2047), (4.0, 2038), (0.0, 2034), (f32::NEGATIVE_INFINITY, 1982), (-0.0, 1961), ]; let sample_median = (f32::NAN, None); special_random_primitive_floats_helper::( 10, 1, 10, 1, 1, 100, values, common_values, sample_median, NAN_MOMENT_STATS, ); // f64, mean abs of exponent = 1/64, mean precision = 65/64, mean special P = 1/4 let values = &[ f64::INFINITY, 1.0, 1.0, f64::INFINITY, 1.0, -1.0, f64::INFINITY, -1.0, f64::INFINITY, 0.0, -1.0, f64::INFINITY, -1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 0.5, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 0.0, -1.5, f64::NEGATIVE_INFINITY, 0.0, -1.0, 1.0, -1.0, -1.0, -1.0, -0.0, 1.0, -1.0, -0.5, -1.0, f64::INFINITY, f64::NEGATIVE_INFINITY, f64::INFINITY, 1.0, ]; let common_values = &[ (1.0, 358244), (-1.0, 357926), (f64::INFINITY, 50304), (f64::NEGATIVE_INFINITY, 50127), (-0.0, 49984), (f64::NAN, 49926), (0.0, 49868), (2.0, 5538), (1.5, 5500), (0.5, 5497), (-1.5, 5454), (-2.0, 5379), (-0.5, 5357), (0.75, 102), (3.0, 98), (-4.0, 95), (-0.25, 91), (-0.75, 87), (-3.0, 86), (0.25, 79), ]; let sample_median = (f64::NAN, None); special_random_primitive_floats_helper::( 1, 64, 65, 64, 1, 4, values, common_values, sample_median, NAN_MOMENT_STATS, ); // f64, mean abs of exponent = 1, mean precision = 2, mean special P = 1/10 let values = &[ 1.0, 1.25, 3.0, f64::INFINITY, -1.0, -1.0, -2.0, -3.5, 1.0, 2.0, -1.5, -2.5, -2.0, f64::INFINITY, -6.5, -1.0, -1.0, f64::INFINITY, 3.0, -0.21875, -1.0, 0.25, 1.5, 5.25, -4.0, 7.0, -0.5, 0.1875, 1.25, f64::INFINITY, -0.1875, -7.5, 0.0, 0.75, -7.0, -6.0, -3.0, 0.234375, -2.0, -0.875, -0.75, 6.0, -24.0, 24.0, -2.0, 1.5, f64::INFINITY, -1.25, 14.0, 5.0, ]; let common_values = &[ (1.0, 74789), (-1.0, 74702), (1.5, 38119), (-0.5, 37713), (2.0, 37640), (-1.5, 37613), (-2.0, 37333), (0.5, 37027), (f64::NEGATIVE_INFINITY, 20096), (0.0, 20064), (f64::INFINITY, 20042), (-0.0, 20022), (f64::NAN, 20000), (0.75, 19050), (4.0, 18892), (0.25, 18875), (-3.0, 18866), (3.0, 18821), (-0.75, 18725), (-4.0, 18663), ]; let sample_median = (f64::NAN, None); special_random_primitive_floats_helper::( 1, 1, 2, 1, 1, 10, values, common_values, sample_median, NAN_MOMENT_STATS, ); // f64, mean abs of exponent = 10, mean precision = 10, mean special P = 1/100 let values = &[ 0.7709910366684198, 1.2504315236583352e-6, 0.00830078125, -0.8125, -85504.0, -0.0078125, -0.018890380859375, 2.5721821784973145, 5.75, -0.00003814697265625, -0.4375, -24064.0, -43008.0, -1.75, -54.6875, 0.4641265869140625, -0.0014760522753931582, -1536.0, 0.1484375, 0.00146484375, 1.9383151084184647e-8, -0.060546875, 7340032.0, -0.1982421875, 203.0546875, 4.57177734375, -1555162.0, -2.0675361156463623e-7, 0.279296875, -0.0045928955078125, -46137344.0, -5712.0, 17.75, -5.265625, -7.966220855712891, -2.99609375, 5.397188942879438e-6, -0.017333984375, 0.00011491775512695312, -0.00005845972555107437, 0.00020831823348999023, -46.78125, 0.005859375, 0.0078125, 27.25, 30.0, -0.175537109375, -208.0, -0.109375, -6144.0, ]; let common_values = &[ (1.0, 2396), (-1.0, 2336), (-2.0, 2200), (-1.5, 2169), (0.5, 2116), (2.0, 2108), (-0.5, 2101), (1.5, 2085), (f64::INFINITY, 2053), (0.0, 2034), (-3.0, 2000), (4.0, 1993), (f64::NEGATIVE_INFINITY, 1982), (3.0, 1969), (-0.0, 1961), (f64::NAN, 1959), (-0.25, 1955), (0.75, 1946), (0.25, 1917), (-4.0, 1882), ]; let sample_median = (f64::NAN, None); special_random_primitive_floats_helper::( 10, 1, 10, 1, 1, 100, values, common_values, sample_median, NAN_MOMENT_STATS, ); } fn special_random_primitive_floats_fail_helper() { assert_panic!(special_random_primitive_floats::( EXAMPLE_SEED, 0, 1, 10, 1, 1, 10 )); assert_panic!(special_random_primitive_floats::( EXAMPLE_SEED, 1, 0, 10, 1, 1, 10 )); assert_panic!(special_random_primitive_floats::( EXAMPLE_SEED, 10, 1, 1, 1, 1, 10 )); assert_panic!(special_random_primitive_floats::( EXAMPLE_SEED, 10, 1, 1, 0, 1, 10 )); assert_panic!(special_random_primitive_floats::( EXAMPLE_SEED, 10, 1, 10, 1, 1, 0 )); assert_panic!(special_random_primitive_floats::( EXAMPLE_SEED, 10, 1, 10, 1, 2, 1 )); } #[test] fn special_random_primitive_floats_fail() { apply_fn_to_primitive_floats!(special_random_primitive_floats_fail_helper); } malachite-base-0.4.16/tests/num/random/striped/get_striped_bool_vec.rs000064400000000000000000000026141046102023000242000ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::random::striped::{get_striped_bool_vec, StripedBitSource}; use malachite_base::random::EXAMPLE_SEED; pub(crate) fn bool_slice_to_string(bs: &[bool]) -> String { bs.iter().map(|&b| if b { '1' } else { '0' }).collect() } fn get_striped_bool_vec_helper(m_numerator: u64, m_denominator: u64, len: u64, out: &str) { let mut bit_source = StripedBitSource::new(EXAMPLE_SEED, m_numerator, m_denominator); let bits = bool_slice_to_string(&get_striped_bool_vec(&mut bit_source, len)); assert_eq!(bits, out); } #[test] fn test_get_striped_bool_vec() { get_striped_bool_vec_helper(2, 1, 0, ""); get_striped_bool_vec_helper( 2, 1, 50, "00110011000110101010010110100100000110000111010111", ); get_striped_bool_vec_helper( 10, 1, 50, "00011111111111000000011111111111111000000000001111", ); get_striped_bool_vec_helper( 11, 10, 50, "01010101010101101000111001010101010101111010101010", ); } malachite-base-0.4.16/tests/num/random/striped/get_striped_unsigned_vec.rs000064400000000000000000000053571046102023000250700ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::random::striped::{get_striped_unsigned_vec, StripedBitSource}; use malachite_base::random::EXAMPLE_SEED; use malachite_base::strings::ToBinaryString; fn get_striped_unsigned_vec_helper( m_numerator: u64, m_denominator: u64, len: u64, out: &[&str], ) { let mut bit_source = StripedBitSource::new(EXAMPLE_SEED, m_numerator, m_denominator); let xs = get_striped_unsigned_vec::(&mut bit_source, len) .iter() .map(T::to_binary_string) .collect_vec(); assert_eq!(xs, out); } #[test] fn test_get_striped_unsigned_vec() { get_striped_unsigned_vec_helper::(2, 1, 0, &[]); get_striped_unsigned_vec_helper::( 2, 1, 100, &[ "11001100", "1011000", "10100101", "100101", "11000", "10101110", "100111", "11000000", "10010001", "11000", "11000100", "10001011", "1001", ], ); get_striped_unsigned_vec_helper::( 10, 1, 100, &[ "11111000", "111111", "11100000", "11111111", "111", "11000000", "11111111", "0", "0", "11111000", "11111111", "11111111", "11", ], ); get_striped_unsigned_vec_helper::( 11, 10, 100, &[ "10101010", "1101010", "1110001", "10101010", "11101010", "1010101", "1010101", "10101011", "1010101", "1010101", "1010101", "1101101", "1101", ], ); get_striped_unsigned_vec_helper::( 2, 1, 130, &[ "1100000000100111101011100001100000100101101001010101100011001100", "1100110010001011010100110100110001011110001000001100010010001", "10", ], ); get_striped_unsigned_vec_helper::( 10, 1, 130, &[ "11111111110000000000011111111111111000000011111111111000", "1100000111111111111111000000001111111111111111111111100000000000", "11", ], ); get_striped_unsigned_vec_helper::( 11, 10, 130, &[ "1010101101010101010101011110101010101010011100010110101010101010", "101101010101011010110101001110101101101010101010101010101010101", "1", ], ); } malachite-base-0.4.16/tests/num/random/striped/striped_bit_source.rs000064400000000000000000000060561046102023000237130ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::random::striped::StripedBitSource; use malachite_base::random::EXAMPLE_SEED; const BIT_STRING_LENGTH: usize = 80; fn generate_string(bit_source: &mut StripedBitSource) -> String { let mut string = String::with_capacity(BIT_STRING_LENGTH); for bit in bit_source.take(BIT_STRING_LENGTH) { if bit { string.push('1'); } else { string.push('0'); } } string } fn striped_bit_source_helper(m_numerator: u64, m_denominator: u64, bit_string: &str) { let mut bit_source = StripedBitSource::new(EXAMPLE_SEED, m_numerator, m_denominator); assert_eq!(generate_string(&mut bit_source), bit_string); } #[test] pub fn test_striped_bit_source() { striped_bit_source_helper( 4, 1, "00000001011001100000000111100000000011111111110000111011000000000000111111111111", ); striped_bit_source_helper( 10, 1, "00011111111111000000011111111111111000000000001111111111000000000000000000011111", ); striped_bit_source_helper( 1000000, 1, "00000000000000000000000000000000000000000000000000000000000000000000000000000000", ); striped_bit_source_helper( 2, 1, "00110011000110101010010110100100000110000111010111100100000000111000100100011000", ); striped_bit_source_helper( 5, 4, "01010010110101001100101101011010101010001010101011010010101010010001101000010000", ); striped_bit_source_helper( 11, 10, "01010101010101101000111001010101010101111010101010101010110101011010101010101010", ); } #[test] #[should_panic] fn new_fail_1() { StripedBitSource::new(EXAMPLE_SEED, 1, 0); } #[test] #[should_panic] fn new_fail_2() { StripedBitSource::new(EXAMPLE_SEED, 1, 1); } #[test] #[should_panic] fn new_fail_3() { StripedBitSource::new(EXAMPLE_SEED, 2, 3); } #[test] pub fn test_end_block() { let mut bit_source = StripedBitSource::new(EXAMPLE_SEED, 1000000, 1); let mut strings = Vec::with_capacity(5); for _ in 0..5 { strings.push(generate_string(&mut bit_source)); bit_source.end_block(); } assert_eq!( strings, &[ "00000000000000000000000000000000000000000000000000000000000000000000000000000000", "00000000000000000000000000000000000000000000000000000000000000000000000000000000", "00000000000000000000000000000000000000000000000000000000000000000000000000000000", "11111111111111111111111111111111111111111111111111111111111111111111111111111111", "00000000000000000000000000000000000000000000000000000000000000000000000000000000" ] ); } malachite-base-0.4.16/tests/num/random/striped/striped_random_bool_vecs.rs000064400000000000000000000231311046102023000250610ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::random::striped::get_striped_bool_vec::bool_slice_to_string; use itertools::Itertools; use malachite_base::num::random::striped::striped_random_bool_vecs; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; fn striped_random_bool_vecs_helper( mean_stripe_numerator: u64, mean_stripe_denominator: u64, mean_length_numerator: u64, mean_length_denominator: u64, expected_values: &[&str], expected_common_values: &[(&str, usize)], expected_median: (&str, Option<&str>), ) { let xs = striped_random_bool_vecs( EXAMPLE_SEED, mean_stripe_numerator, mean_stripe_denominator, mean_length_numerator, mean_length_denominator, ); let values = xs .clone() .take(20) .map(|bs| bool_slice_to_string(&bs)) .collect_vec(); let common_values = common_values_map_debug(1000000, 10, xs.clone()) .into_iter() .map(|(bs, freq)| (bool_slice_to_string(&bs), freq)) .collect_vec(); let (median_lo, median_hi) = median(xs.take(1000000)); let median_lo = bool_slice_to_string(&median_lo); let median_hi = median_hi.map(|bs| bool_slice_to_string(&bs)); assert_eq!( ( values.iter().map(String::as_str).collect_vec().as_slice(), common_values .iter() .map(|(s, f)| (s.as_str(), *f)) .collect_vec() .as_slice(), (median_lo.as_str(), median_hi.as_deref()) ), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_striped_random_bool_vecs() { striped_random_bool_vecs_helper( 2, 1, 4, 1, &[ "", "00110011000110", "0001", "0110", "0", "", "00111", "10", "0100", "", "111010", "", "", "01111101000", "11001100", "", "100", "", "01011", "000111111", ], &[ ("", 199913), ("1", 80247), ("0", 79926), ("10", 32241), ("00", 32110), ("11", 31988), ("01", 31834), ("001", 12991), ("111", 12989), ("010", 12807), ], ("0100011111011", None), ); striped_random_bool_vecs_helper( 10, 1, 4, 1, &[ "", "00000000000000", "0000", "0001", "0", "", "00011", "11", "0000", "", "111111", "", "", "01111111100", "11111000", "", "111", "", "00000", "000111111", ], &[ ("", 199913), ("1", 80247), ("0", 79926), ("11", 57775), ("00", 57583), ("000", 41616), ("111", 41544), ("0000", 29747), ("1111", 29589), ("11111", 21524), ], ("00000001111", None), ); striped_random_bool_vecs_helper( 11, 10, 4, 1, &[ "", "01011010101010", "0110", "0101", "0", "", "01101", "10", "0101", "", "100101", "", "", "01101011010", "10101010", "", "101", "", "01010", "010101001", ], &[ ("", 199913), ("1", 80247), ("0", 79926), ("10", 58377), ("01", 58287), ("010", 42404), ("101", 42353), ("1010", 30704), ("0101", 30613), ("10101", 22466), ], ("010101", None), ); striped_random_bool_vecs_helper( 2, 1, 10, 1, &[ "0011001100011000100110001011", "000101000001011110", "0011001101000011111", "000", "011011101100", "1", "00111100000001010011001111101", "11110", "01", "10110001011", "111100001101100101000100011011", "01010", "0111", "00110101", "11111011001", "0011", "110111111", "000101101", "0110111011110110011001000", "1", ], &[ ("", 90709), ("0", 41449), ("1", 41338), ("00", 18773), ("10", 18748), ("11", 18731), ("01", 18531), ("001", 8685), ("111", 8639), ("010", 8624), ], ("011011101010", None), ); striped_random_bool_vecs_helper( 10, 1, 10, 1, &[ "0000000000000000000111000000", "000000111111110000", "0001111111111100000", "000", "000000000000", "1", "00000000000001111111111111111", "11111", "00", "10000001111", "111111111101111111111111000000", "00000", "0000", "00000000", "11000011111", "0001", "111111111", "000000000", "0000000001100111111111111", "1", ], &[ ("", 90709), ("0", 41449), ("1", 41338), ("00", 33629), ("11", 33603), ("111", 27832), ("000", 27669), ("1111", 22666), ("0000", 22522), ("11111", 18708), ], ( "00111111111110000000000011111000000001", Some("001111111111100000000000111110011111"), ), ); striped_random_bool_vecs_helper( 11, 10, 10, 1, &[ "0101101010101011010100101010", "011010110101101010", "0101010101010101011", "010", "010110101010", "1", "01010101001101011010101010101", "10101", "01", "10101010101", "101101010110101001010101001010", "01010", "0101", "01010101", "10101101010", "0101", "101011010", "010010101", "0101010101010101010101011", "1", ], &[ ("", 90709), ("0", 41449), ("1", 41338), ("10", 34030), ("01", 33878), ("010", 28388), ("101", 28324), ("1010", 23483), ("0101", 23162), ("10101", 19518), ], ("01011010", None), ); striped_random_bool_vecs_helper( 2, 1, 1, 4, &["", "", "0", "0", "00", "", "", "", "", "", "", "", "01", "0", "", "11", "", "", "", ""], &[ ("", 800023), ("1", 80189), ("0", 79739), ("00", 8218), ("01", 8023), ("11", 7972), ("10", 7920), ("001", 819), ("110", 812), ("101", 810), ], ("", None), ); striped_random_bool_vecs_helper( 10, 1, 1, 4, &["", "", "0", "0", "00", "", "", "", "", "", "", "", "00", "0", "", "11", "", "", "", ""], &[ ("", 800023), ("1", 80189), ("0", 79739), ("00", 14590), ("11", 14351), ("000", 2591), ("111", 2530), ("01", 1651), ("10", 1541), ("1111", 460), ], ("", None), ); striped_random_bool_vecs_helper( 11, 10, 1, 4, &["", "", "0", "0", "01", "", "", "", "", "", "", "", "01", "0", "", "10", "", "", "", ""], &[ ("", 800023), ("1", 80189), ("0", 79739), ("01", 14758), ("10", 14493), ("101", 2640), ("010", 2614), ("00", 1483), ("11", 1399), ("0101", 467), ], ("", None), ); } #[test] #[should_panic] fn striped_random_bool_vecs_fail_1() { striped_random_bool_vecs(EXAMPLE_SEED, 1, 0, 4, 1); } #[test] #[should_panic] fn striped_random_bool_vecs_fail_2() { striped_random_bool_vecs(EXAMPLE_SEED, 2, 3, 4, 1); } #[test] #[should_panic] fn striped_random_bool_vecs_fail_3() { striped_random_bool_vecs(EXAMPLE_SEED, 4, 1, 0, 1); } #[test] #[should_panic] fn striped_random_bool_vecs_fail_4() { striped_random_bool_vecs(EXAMPLE_SEED, 4, 1, 1, 0); } #[test] #[should_panic] fn striped_random_bool_vecs_fail_5() { striped_random_bool_vecs(EXAMPLE_SEED, 4, 1, u64::MAX, u64::MAX - 1); } malachite-base-0.4.16/tests/num/random/striped/striped_random_bool_vecs_from_length_iterator.rs000064400000000000000000000165471046102023000313730ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::random::striped::get_striped_bool_vec::bool_slice_to_string; use itertools::Itertools; use malachite_base::num::random::geometric::geometric_random_unsigneds; use malachite_base::num::random::striped::striped_random_bool_vecs_from_length_iterator; use malachite_base::random::{Seed, EXAMPLE_SEED}; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; use malachite_base::vecs::random_values_from_vec; use std::iter::repeat; fn striped_random_bool_vecs_from_length_iterator_helper>( lengths_gen: &dyn Fn(Seed) -> I, mean_stripe_numerator: u64, mean_stripe_denominator: u64, expected_values: &[&str], expected_common_values: &[(&str, usize)], expected_median: (&str, Option<&str>), ) { let xs = striped_random_bool_vecs_from_length_iterator( EXAMPLE_SEED, lengths_gen, mean_stripe_numerator, mean_stripe_denominator, ); let values = xs .clone() .take(20) .map(|bs| bool_slice_to_string(&bs)) .collect_vec(); let common_values = common_values_map_debug(1000000, 10, xs.clone()) .into_iter() .map(|(bs, freq)| (bool_slice_to_string(&bs), freq)) .collect_vec(); let (median_lo, median_hi) = median(xs.take(1000000)); let median_lo = bool_slice_to_string(&median_lo); let median_hi = median_hi.map(|bs| bool_slice_to_string(&bs)); assert_eq!( ( values.iter().map(String::as_str).collect_vec().as_slice(), common_values .iter() .map(|(s, f)| (s.as_str(), *f)) .collect_vec() .as_slice(), (median_lo.as_str(), median_hi.as_deref()) ), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_striped_random_bool_vecs_from_length_iterator() { striped_random_bool_vecs_from_length_iterator_helper( &|seed| random_values_from_vec(seed, vec![0, 2, 4]), 2, 1, &[ "00", "0110", "00", "0110", "0001", "11", "", "01", "", "1110", "0110", "11", "1000", "01", "0100", "0001", "1010", "", "0000", "", ], &[ ("", 333820), ("00", 83428), ("10", 83346), ("11", 83184), ("01", 83167), ("0010", 20955), ("0001", 20940), ("1110", 20921), ("1011", 20912), ("0011", 20870), ], ("0011", None), ); striped_random_bool_vecs_from_length_iterator_helper( &|seed| random_values_from_vec(seed, vec![0, 2, 4]), 10, 1, &[ "00", "0000", "00", "0000", "0000", "11", "", "00", "", "1111", "0001", "11", "1100", "00", "0000", "0000", "1110", "", "0000", "", ], &[ ("", 333820), ("11", 149822), ("00", 149788), ("0000", 121534), ("1111", 121330), ("01", 16807), ("10", 16708), ("0011", 13644), ("1110", 13490), ("0001", 13454), ], ("0000", None), ); striped_random_bool_vecs_from_length_iterator_helper( &|seed| random_values_from_vec(seed, vec![0, 2, 4]), 11, 10, &[ "01", "0100", "01", "0101", "0101", "10", "", "01", "", "1001", "0101", "10", "1101", "01", "0101", "0110", "1010", "", "0010", "", ], &[ ("", 333820), ("01", 151459), ("10", 151370), ("0101", 125515), ("1010", 124901), ("11", 15160), ("00", 15136), ("0010", 12625), ("1011", 12598), ("1001", 12494), ], ("01", None), ); striped_random_bool_vecs_from_length_iterator_helper( &|seed| geometric_random_unsigneds::(seed, 2, 1).map(|x| x << 1), 2, 1, &[ "001100110001", "00", "0111011001110100", "00", "0010100000101111001100110100", "", "1110000000", "01101110", "10", "", "001110000111", "1111", "", "", "11", "010100", "", "01", "", "00", ], &[ ("", 333981), ("11", 56301), ("01", 55922), ("00", 55472), ("10", 55087), ("0101", 9537), ("0100", 9341), ("0010", 9326), ("1011", 9314), ("0001", 9297), ], ("00111111100101", Some("0011111110010100")), ); striped_random_bool_vecs_from_length_iterator_helper( &|seed| geometric_random_unsigneds::(seed, 2, 1).map(|x| x << 1), 10, 1, &[ "000000000000", "00", "0000000111000000", "00", "0000011111111000000111111111", "", "1110000000", "00000000", "11", "", "000000000000", "1111", "", "", "11", "011111", "", "00", "", "00", ], &[ ("", 333981), ("00", 100383), ("11", 100353), ("1111", 53920), ("0000", 53883), ("000000", 29226), ("111111", 29014), ("00000000", 15928), ("11111111", 15670), ("10", 11035), ], ("000000", None), ); striped_random_bool_vecs_from_length_iterator_helper( &|seed| geometric_random_unsigneds::(seed, 2, 1).map(|x| x << 1), 11, 10, &[ "010110101010", "01", "0100101011010101", "01", "0010100101001010101010101010", "", "1010101101", "01011010", "10", "", "010101010101", "1100", "", "", "10", "010110", "", "01", "", "01", ], &[ ("", 333981), ("10", 101326), ("01", 101218), ("0101", 55895), ("1010", 55433), ("101010", 30661), ("010101", 30567), ("01010101", 17148), ("10101010", 16775), ("00", 10176), ], ("0101", None), ); } #[test] #[should_panic] fn striped_random_bool_vecs_from_length_iterator_fail_1() { striped_random_bool_vecs_from_length_iterator(EXAMPLE_SEED, &|_| repeat(1), 1, 0); } #[test] #[should_panic] fn striped_random_bool_vecs_from_length_iterator_fail_2() { striped_random_bool_vecs_from_length_iterator(EXAMPLE_SEED, &|_| repeat(1), 2, 3); } malachite-base-0.4.16/tests/num/random/striped/striped_random_bool_vecs_length_inclusive_range.rs000064400000000000000000000125021046102023000316570ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::random::striped::get_striped_bool_vec::bool_slice_to_string; use itertools::Itertools; use malachite_base::num::random::striped::striped_random_bool_vecs_length_inclusive_range; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; fn striped_random_bool_vecs_length_inclusive_range_helper( a: u64, b: u64, mean_stripe_numerator: u64, mean_stripe_denominator: u64, expected_values: &[&str], expected_common_values: &[(&str, usize)], expected_median: (&str, Option<&str>), ) { let xs = striped_random_bool_vecs_length_inclusive_range( EXAMPLE_SEED, a, b, mean_stripe_numerator, mean_stripe_denominator, ); let values = xs .clone() .take(20) .map(|bs| bool_slice_to_string(&bs)) .collect_vec(); let common_values = common_values_map_debug(1000000, 10, xs.clone()) .into_iter() .map(|(bs, freq)| (bool_slice_to_string(&bs), freq)) .collect_vec(); let (median_lo, median_hi) = median(xs.take(1000000)); let median_lo = bool_slice_to_string(&median_lo); let median_hi = median_hi.map(|bs| bool_slice_to_string(&bs)); assert_eq!( ( values.iter().map(String::as_str).collect_vec().as_slice(), common_values .iter() .map(|(s, f)| (s.as_str(), *f)) .collect_vec() .as_slice(), (median_lo.as_str(), median_hi.as_deref()) ), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_striped_random_bool_vecs_length_inclusive_range() { striped_random_bool_vecs_length_inclusive_range_helper( 3, 9, 2, 1, &[ "00110011", "01110011", "00100110", "00010111", "001010000", "110", "0100", "1110011", "011001011", "111000", "111110010", "0001001", "00011110", "00000", "1110101", "0011001", "11111", "01000010", "01001110", "10111", ], &[ ("001", 18041), ("110", 18008), ("111", 17919), ("100", 17906), ("011", 17905), ("000", 17819), ("010", 17792), ("101", 17782), ("0111", 9023), ("1011", 9023), ], ("100", None), ); striped_random_bool_vecs_length_inclusive_range_helper( 3, 9, 10, 1, &[ "00000000", "00000000", "00000111", "01111111", "000001111", "111", "0001", "1111110", "000000000", "111000", "111111111", "0000000", "00000000", "00000", "1110000", "0000000", "11111", "00000000", "01111110", "11111", ], &[ ("000", 58009), ("111", 57974), ("1111", 52110), ("0000", 51905), ("00000", 47047), ("11111", 46660), ("111111", 42411), ("000000", 41880), ("0000000", 38018), ("1111111", 37708), ], ("100", None), ); striped_random_bool_vecs_length_inclusive_range_helper( 3, 9, 11, 10, &[ "01011010", "01010101", "00101011", "01010101", "001010010", "101", "0010", "1010101", "010101010", "101010", "100101011", "0101010", "01010101", "01001", "1101011", "0101010", "10101", "01010101", "01010101", "10101", ], &[ ("010", 59241), ("101", 59092), ("1010", 53578), ("0101", 53360), ("01010", 48685), ("10101", 48527), ("010101", 44471), ("101010", 44350), ("0101010", 40536), ("1010101", 40115), ], ("100", None), ); } #[test] #[should_panic] fn striped_random_bool_vecs_length_inclusive_range_fail_1() { striped_random_bool_vecs_length_inclusive_range(EXAMPLE_SEED, 3, 10, 1, 0); } #[test] #[should_panic] fn striped_random_bool_vecs_length_inclusive_range_fail_2() { striped_random_bool_vecs_length_inclusive_range(EXAMPLE_SEED, 3, 10, 2, 3); } #[test] #[should_panic] fn striped_random_bool_vecs_length_inclusive_range_fail_3() { striped_random_bool_vecs_length_inclusive_range(EXAMPLE_SEED, 2, 1, 4, 1); } malachite-base-0.4.16/tests/num/random/striped/striped_random_bool_vecs_length_range.rs000064400000000000000000000123031046102023000275750ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::random::striped::get_striped_bool_vec::bool_slice_to_string; use itertools::Itertools; use malachite_base::num::random::striped::striped_random_bool_vecs_length_range; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; fn striped_random_bool_vecs_length_range_helper( a: u64, b: u64, mean_stripe_numerator: u64, mean_stripe_denominator: u64, expected_values: &[&str], expected_common_values: &[(&str, usize)], expected_median: (&str, Option<&str>), ) { let xs = striped_random_bool_vecs_length_range( EXAMPLE_SEED, a, b, mean_stripe_numerator, mean_stripe_denominator, ); let values = xs .clone() .take(20) .map(|bs| bool_slice_to_string(&bs)) .collect_vec(); let common_values = common_values_map_debug(1000000, 10, xs.clone()) .into_iter() .map(|(bs, freq)| (bool_slice_to_string(&bs), freq)) .collect_vec(); let (median_lo, median_hi) = median(xs.take(1000000)); let median_lo = bool_slice_to_string(&median_lo); let median_hi = median_hi.map(|bs| bool_slice_to_string(&bs)); assert_eq!( ( values.iter().map(String::as_str).collect_vec().as_slice(), common_values .iter() .map(|(s, f)| (s.as_str(), *f)) .collect_vec() .as_slice(), (median_lo.as_str(), median_hi.as_deref()) ), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_striped_random_bool_vecs_length_range() { striped_random_bool_vecs_length_range_helper( 3, 10, 2, 1, &[ "00110011", "01110011", "00100110", "00010111", "001010000", "110", "0100", "1110011", "011001011", "111000", "111110010", "0001001", "00011110", "00000", "1110101", "0011001", "11111", "01000010", "01001110", "10111", ], &[ ("001", 18041), ("110", 18008), ("111", 17919), ("100", 17906), ("011", 17905), ("000", 17819), ("010", 17792), ("101", 17782), ("0111", 9023), ("1011", 9023), ], ("100", None), ); striped_random_bool_vecs_length_range_helper( 3, 10, 10, 1, &[ "00000000", "00000000", "00000111", "01111111", "000001111", "111", "0001", "1111110", "000000000", "111000", "111111111", "0000000", "00000000", "00000", "1110000", "0000000", "11111", "00000000", "01111110", "11111", ], &[ ("000", 58009), ("111", 57974), ("1111", 52110), ("0000", 51905), ("00000", 47047), ("11111", 46660), ("111111", 42411), ("000000", 41880), ("0000000", 38018), ("1111111", 37708), ], ("100", None), ); striped_random_bool_vecs_length_range_helper( 3, 10, 11, 10, &[ "01011010", "01010101", "00101011", "01010101", "001010010", "101", "0010", "1010101", "010101010", "101010", "100101011", "0101010", "01010101", "01001", "1101011", "0101010", "10101", "01010101", "01010101", "10101", ], &[ ("010", 59241), ("101", 59092), ("1010", 53578), ("0101", 53360), ("01010", 48685), ("10101", 48527), ("010101", 44471), ("101010", 44350), ("0101010", 40536), ("1010101", 40115), ], ("100", None), ); } #[test] #[should_panic] fn striped_random_bool_vecs_length_range_fail_1() { striped_random_bool_vecs_length_range(EXAMPLE_SEED, 3, 10, 1, 0); } #[test] #[should_panic] fn striped_random_bool_vecs_length_range_fail_2() { striped_random_bool_vecs_length_range(EXAMPLE_SEED, 3, 10, 2, 3); } #[test] #[should_panic] fn striped_random_bool_vecs_length_range_fail_3() { striped_random_bool_vecs_length_range(EXAMPLE_SEED, 1, 1, 4, 1); } malachite-base-0.4.16/tests/num/random/striped/striped_random_bool_vecs_min_length.rs000064400000000000000000000203761046102023000272750ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::random::striped::get_striped_bool_vec::bool_slice_to_string; use itertools::Itertools; use malachite_base::num::random::striped::striped_random_bool_vecs_min_length; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; fn striped_random_bool_vecs_min_length_helper( min_length: u64, mean_stripe_numerator: u64, mean_stripe_denominator: u64, mean_length_numerator: u64, mean_length_denominator: u64, expected_values: &[&str], expected_common_values: &[(&str, usize)], expected_median: (&str, Option<&str>), ) { let xs = striped_random_bool_vecs_min_length( EXAMPLE_SEED, min_length, mean_stripe_numerator, mean_stripe_denominator, mean_length_numerator, mean_length_denominator, ); let values = xs .clone() .take(20) .map(|bs| bool_slice_to_string(&bs)) .collect_vec(); let common_values = common_values_map_debug(1000000, 10, xs.clone()) .into_iter() .map(|(bs, freq)| (bool_slice_to_string(&bs), freq)) .collect_vec(); let (median_lo, median_hi) = median(xs.take(1000000)); let median_lo = bool_slice_to_string(&median_lo); let median_hi = median_hi.map(|bs| bool_slice_to_string(&bs)); assert_eq!( ( values.iter().map(String::as_str).collect_vec().as_slice(), common_values .iter() .map(|(s, f)| (s.as_str(), *f)) .collect_vec() .as_slice(), (median_lo.as_str(), median_hi.as_deref()) ), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_striped_random_bool_vecs_min_length() { striped_random_bool_vecs_min_length_helper( 0, 2, 1, 4, 1, &[ "", "00110011000110", "0001", "0110", "0", "", "00111", "10", "0100", "", "111010", "", "", "01111101000", "11001100", "", "100", "", "01011", "000111111", ], &[ ("", 199913), ("1", 80247), ("0", 79926), ("10", 32241), ("00", 32110), ("11", 31988), ("01", 31834), ("001", 12991), ("111", 12989), ("010", 12807), ], ("0100011111011", None), ); striped_random_bool_vecs_min_length_helper( 3, 10, 1, 4, 1, &[ "0000", "00000", "00000", "00000", "0000", "10001", "000", "111", "0000", "111", "110", "000", "0000", "0001111", "111", "01111", "111", "00000011", "0000", "1111", ], &[ ("000", 202463), ("111", 202257), ("0000", 91181), ("1111", 91085), ("00000", 41060), ("11111", 41041), ("100", 22693), ("110", 22484), ("001", 22434), ("011", 22270), ], ("100", None), ); striped_random_bool_vecs_min_length_helper( 0, 11, 10, 4, 1, &[ "", "01011010101010", "0110", "0101", "0", "", "01101", "10", "0101", "", "100101", "", "", "01101011010", "10101010", "", "101", "", "01010", "010101001", ], &[ ("", 199913), ("1", 80247), ("0", 79926), ("10", 58377), ("01", 58287), ("010", 42404), ("101", 42353), ("1010", 30704), ("0101", 30613), ("10101", 22466), ], ("010101", None), ); striped_random_bool_vecs_min_length_helper( 3, 2, 1, 10, 1, &[ "00110011", "01110011101100111010000101", "011111010000", "01100110010", "0111", "110", "000000011", "101110", "011000111100000", "111", "101011001100", "0000", "010", "000010100111010000011", "1110010011010111", "010", "11100100", "010", "010111100101", "10000010011001110111111110100", ], &[ ("011", 15722), ("101", 15676), ("110", 15638), ("100", 15613), ("010", 15610), ("111", 15603), ("000", 15516), ("001", 15471), ("0110", 7099), ("1010", 6906), ], ("100", None), ); striped_random_bool_vecs_min_length_helper( 0, 10, 1, 10, 1, &[ "0000000000000000000111000000", "000000111111110000", "0001111111111100000", "000", "000000000000", "1", "00000000000001111111111111111", "11111", "00", "10000001111", "111111111101111111111111000000", "00000", "0000", "00000000", "11000011111", "0001", "111111111", "000000000", "0000000001100111111111111", "1", ], &[ ("", 90709), ("0", 41449), ("1", 41338), ("00", 33629), ("11", 33603), ("111", 27832), ("000", 27669), ("1111", 22666), ("0000", 22522), ("11111", 18708), ], ( "00111111111110000000000011111000000001", Some("001111111111100000000000111110011111"), ), ); striped_random_bool_vecs_min_length_helper( 3, 11, 10, 10, 1, &[ "01011010", "01010101101010010101011010", "011010110101", "01010101010", "0101", "101", "010110101", "100101", "010101010101001", "110", "101001010101", "0101", "010", "010101010101010101101", "1010110101001010", "010", "10110101", "010", "010101010101", "10101001010101010100101011010", ], &[ ("101", 51809), ("010", 51385), ("0101", 41252), ("1010", 40909), ("01010", 33103), ("10101", 32685), ("101010", 25995), ("010101", 25896), ("0101010", 20699), ("1010101", 20622), ], ("100", None), ); } #[test] #[should_panic] fn striped_random_bool_vecs_min_length_fail_1() { striped_random_bool_vecs_min_length(EXAMPLE_SEED, 3, 1, 0, 4, 1); } #[test] #[should_panic] fn striped_random_bool_vecs_min_length_fail_2() { striped_random_bool_vecs_min_length(EXAMPLE_SEED, 3, 2, 3, 4, 1); } #[test] #[should_panic] fn striped_random_bool_vecs_min_length_fail_3() { striped_random_bool_vecs_min_length(EXAMPLE_SEED, 3, 4, 1, 3, 1); } #[test] #[should_panic] fn striped_random_bool_vecs_min_length_fail_4() { striped_random_bool_vecs_min_length(EXAMPLE_SEED, 1, 4, 1, 1, 0); } #[test] #[should_panic] fn striped_random_bool_vecs_min_length_fail_5() { striped_random_bool_vecs_min_length(EXAMPLE_SEED, 0, 4, 1, u64::MAX, u64::MAX - 1); } malachite-base-0.4.16/tests/num/random/striped/striped_random_fixed_length_bool_vecs.rs000064400000000000000000000073331046102023000276070ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::num::random::striped::get_striped_bool_vec::bool_slice_to_string; use itertools::Itertools; use malachite_base::num::random::striped::striped_random_fixed_length_bool_vecs; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; fn striped_random_fixed_length_bool_vecs_helper( len: u64, mean_stripe_numerator: u64, mean_stripe_denominator: u64, expected_values: &[&str], expected_common_values: &[(&str, usize)], expected_median: (&str, Option<&str>), ) { let xs = striped_random_fixed_length_bool_vecs( EXAMPLE_SEED, len, mean_stripe_numerator, mean_stripe_denominator, ); let values = xs .clone() .take(20) .map(|bs| bool_slice_to_string(&bs)) .collect_vec(); let common_values = common_values_map_debug(1000000, 10, xs.clone()) .into_iter() .map(|(bs, freq)| (bool_slice_to_string(&bs), freq)) .collect_vec(); let (median_lo, median_hi) = median(xs.take(1000000)); let median_lo = bool_slice_to_string(&median_lo); let median_hi = median_hi.map(|bs| bool_slice_to_string(&bs)); assert_eq!( ( values.iter().map(String::as_str).collect_vec().as_slice(), common_values .iter() .map(|(s, f)| (s.as_str(), *f)) .collect_vec() .as_slice(), (median_lo.as_str(), median_hi.as_deref()) ), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_striped_random_fixed_length_bool_vecs() { striped_random_fixed_length_bool_vecs_helper(0, 10, 1, &[""; 20], &[("", 1000000)], ("", None)); striped_random_fixed_length_bool_vecs_helper( 1, 10, 1, &[ "0", "0", "0", "0", "0", "1", "0", "1", "0", "1", "1", "0", "0", "0", "1", "0", "1", "0", "0", "1", ], &[("1", 500079), ("0", 499921)], ("1", None), ); striped_random_fixed_length_bool_vecs_helper( 2, 10, 1, &[ "00", "00", "00", "00", "00", "11", "00", "11", "00", "11", "11", "00", "00", "00", "11", "00", "11", "00", "01", "11", ], &[("11", 449989), ("00", 449537), ("01", 50384), ("10", 50090)], ("10", None), ); striped_random_fixed_length_bool_vecs_helper( 5, 10, 1, &[ "00000", "00000", "00000", "00000", "00011", "11000", "00000", "11111", "01111", "11111", "10000", "00011", "00000", "00000", "11000", "00000", "11111", "00000", "00000", "11111", ], &[ ("11111", 328176), ("00000", 327532), ("00001", 36685), ("10000", 36616), ("00111", 36602), ("01111", 36495), ("11110", 36487), ("11000", 36446), ("00011", 36354), ("11100", 36250), ], ("10000", None), ); } #[test] #[should_panic] fn striped_random_fixed_length_bool_vecs_fail_1() { striped_random_fixed_length_bool_vecs(EXAMPLE_SEED, 5, 1, 0); } #[test] #[should_panic] fn striped_random_fixed_length_bool_vecs_fail_2() { striped_random_fixed_length_bool_vecs(EXAMPLE_SEED, 5, 2, 3); } malachite-base-0.4.16/tests/num/random/striped/striped_random_fixed_length_unsigned_vecs.rs000064400000000000000000000176001046102023000304660ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::random::striped::striped_random_fixed_length_unsigned_vecs; use malachite_base::random::EXAMPLE_SEED; use malachite_base::strings::ToBinaryString; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; fn striped_random_fixed_length_unsigned_vecs_helper( len: u64, mean_stripe_numerator: u64, mean_stripe_denominator: u64, expected_values: &[&[&str]], expected_common_values: &[(&[&str], usize)], expected_median: (&[&str], Option<&[&str]>), ) { let xss = striped_random_fixed_length_unsigned_vecs::( EXAMPLE_SEED, len, mean_stripe_numerator, mean_stripe_denominator, ); let values = xss .clone() .take(20) .map(|xs| { xs.into_iter() .map(|x: T| x.to_binary_string()) .collect_vec() }) .collect_vec(); let common_values = common_values_map_debug(1000000, 10, xss.clone()) .into_iter() .map(|(xs, freq)| { ( xs.into_iter() .map(|x: T| x.to_binary_string()) .collect_vec(), freq, ) }) .collect_vec(); let (median_lo, median_hi) = median(xss.take(1000000)); let median_lo = median_lo .into_iter() .map(|x: T| x.to_binary_string()) .collect_vec(); let median_hi = median_hi.map(|xs| { xs.into_iter() .map(|x: T| x.to_binary_string()) .collect_vec() }); let values = values .iter() .map(|xs| xs.iter().map(String::as_str).collect_vec()) .collect_vec(); let common_values = common_values .iter() .map(|(xs, freq)| (xs.iter().map(String::as_str).collect_vec(), *freq)) .collect_vec(); let median_lo = median_lo.iter().map(String::as_str).collect_vec(); let median_hi = median_hi .as_ref() .map(|xs| xs.iter().map(String::as_str).collect_vec()); assert_eq!( ( values.iter().map(Vec::as_slice).collect_vec().as_slice(), common_values .iter() .map(|(xs, f)| (xs.as_slice(), *f)) .collect_vec() .as_slice(), (median_lo.as_slice(), median_hi.as_deref()) ), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_striped_random_fixed_length_unsigned_vecs() { striped_random_fixed_length_unsigned_vecs_helper::( 0, 10, 1, &[&[][..]; 20], &[(&[], 1000000)], (&[], None), ); striped_random_fixed_length_unsigned_vecs_helper::( 1, 10, 1, &[ &["0"], &["0"], &["11100000"], &["11111110"], &["11100000"], &["111111"], &["11100000"], &["11111111"], &["11111100"], &["11111111"], &["11111111"], &["0"], &["11110000"], &["0"], &["11111111"], &["11110000"], &["111"], &["0"], &["100"], &["11111111"], ], &[ (&["0"], 238932), (&["11111111"], 238695), (&["11100000"], 26922), (&["1111111"], 26791), (&["11000000"], 26775), (&["11"], 26754), (&["111"], 26726), (&["11110000"], 26662), (&["11111"], 26607), (&["1111"], 26594), ], (&["1111111"], None), ); striped_random_fixed_length_unsigned_vecs_helper::( 2, 10, 1, &[ &["0", "0"], &["1110000", "0"], &["11111000", "111"], &["11111100", "11111"], &["0", "0"], &["11111111", "11111"], &["0", "0"], &["1111", "11111100"], &["0", "1"], &["1111111", "0"], &["11111111", "11111"], &["11111100", "1"], &["0", "0"], &["110000", "11111111"], &["11111", "0"], &["0", "0"], &["11111111", "11111111"], &["0", "0"], &["1000", "0"], &["11111111", "11111111"], ], &[ (&["0", "0"], 103184), (&["11111111", "11111111"], 102963), (&["0", "11111111"], 11776), (&["11111000", "11111111"], 11585), (&["0", "11111110"], 11579), (&["11111110", "11111111"], 11542), (&["11000000", "11111111"], 11499), (&["1111", "0"], 11487), (&["11111111", "1111111"], 11483), (&["11111111", "1"], 11459), ], (&["1111111", "11111111"], None), ); striped_random_fixed_length_unsigned_vecs_helper::( 5, 10, 1, &[ &["0", "0", "111000", "0", "11111110"], &["11111100", "0", "11111000", "11111111", "11111111"], &["0", "11111100", "11111111", "1111111", "11100000"], &["0", "1000", "0", "11111110", "11111111"], &["10000000", "111", "11111100", "11111111", "11111111"], &["11001111", "0", "11110000", "11111111", "11111111"], &["0", "0", "0", "0", "10000000"], &["1", "0", "0", "11100000", "11111111"], &["0", "0", "0", "0", "11111100"], &["1110111", "0", "11110000", "1110", "11010000"], &["1111101", "11111111", "11111111", "11111111", "111111"], &["0", "1111", "100000", "11111111", "11"], &["10000000", "11111111", "11101111", "11111111", "11111111"], &["11111100", "111111", "0", "0", "1111"], &["11111111", "1", "11111111", "11111111", "11111"], &["0", "11100000", "11111111", "1", "1100"], &["11111111", "1110111", "0", "11111100", "1"], &["11111110", "111", "0", "0", "0"], &["11110000", "11", "10000000", "11111111", "11000011"], &["1", "10000000", "11111111", "11111111", "111"], ], &[ (&["0", "0", "0", "0", "0"], 8118), ( &["11111111", "11111111", "11111111", "11111111", "11111111"], 8057, ), (&["0", "11000000", "11111111", "11111111", "11111111"], 972), (&["11111111", "11111111", "11111111", "111", "0"], 961), (&["11111111", "11111111", "11111111", "11111", "0"], 955), ( &["11111100", "11111111", "11111111", "11111111", "11111111"], 948, ), (&["0", "0", "0", "0", "11111110"], 947), (&["0", "0", "10000000", "11111111", "11111111"], 946), (&["11111111", "1111", "0", "0", "0"], 944), (&["0", "0", "0", "11111111", "11111111"], 944), ], ( &["1111111", "11111111", "11111111", "10000001", "11111100"], Some(&["1111111", "11111111", "11111111", "10000001", "11111111"]), ), ); } #[test] #[should_panic] fn striped_random_fixed_length_unsigned_vecs_fail_1() { striped_random_fixed_length_unsigned_vecs::(EXAMPLE_SEED, 5, 1, 0); } #[test] #[should_panic] fn striped_random_fixed_length_unsigned_vecs_fail_2() { striped_random_fixed_length_unsigned_vecs::(EXAMPLE_SEED, 5, 2, 3); } malachite-base-0.4.16/tests/num/random/striped/striped_random_natural_signeds.rs000064400000000000000000000335441046102023000263010ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::striped::striped_random_natural_signeds; use malachite_base::random::EXAMPLE_SEED; use malachite_base::strings::ToBinaryString; use malachite_base::test_util::stats::common_values_map::common_values_map; use malachite_base::test_util::stats::median; use malachite_base::test_util::stats::moments::{moment_stats, CheckedToF64, MomentStats}; use std::panic::catch_unwind; fn striped_random_natural_signeds_helper( m_numerator: u64, m_denominator: u64, expected_values: &[&str], expected_common_values: &[(&str, usize)], expected_sample_median: (T, Option), expected_sample_moment_stats: MomentStats, ) { let xs = striped_random_natural_signeds::(EXAMPLE_SEED, m_numerator, m_denominator); let actual_values = xs .clone() .map(|x| x.to_binary_string()) .take(20) .collect_vec(); let actual_common_values = common_values_map(1000000, 10, xs.clone()) .iter() .map(|(x, frequency)| (x.to_binary_string(), *frequency)) .collect_vec(); let actual_sample_median = median(xs.clone().take(1000000)); let actual_sample_moment_stats = moment_stats(xs.take(1000000)); assert_eq!( ( actual_values, actual_common_values, actual_sample_median, actual_sample_moment_stats ), ( expected_values .iter() .map(ToString::to_string) .collect_vec(), expected_common_values .iter() .map(|(x, frequency)| (x.to_string(), *frequency)) .collect_vec(), expected_sample_median, expected_sample_moment_stats ) ); } #[test] fn test_striped_random_natural_signeds() { // i8, m = 4 let values = &[ "0", "101100", "110000", "1111100", "1111", "1111110", "0", "111", "11101", "1100000", "1111111", "1100000", "0", "10", "1000011", "111111", "1", "0", "1111", "1", ]; let common_values = &[ ("0", 89042), ("1111111", 88624), ("11111", 29871), ("1111000", 29848), ("1000000", 29802), ("1111110", 29796), ("1100000", 29664), ("1110000", 29649), ("111", 29644), ("111111", 29621), ]; let sample_median = (64, None); let sample_moment_stats = MomentStats { mean: NiceFloat(63.526448000001764), standard_deviation: NiceFloat(47.66137677522695), skewness: NiceFloat(-0.0011056592983105758), excess_kurtosis: NiceFloat(-1.5649370173869874), }; striped_random_natural_signeds_helper::( 4, 1, values, common_values, sample_median, sample_moment_stats, ); // i8, m = 2 let values = &[ "11001", "11100", "101010", "1001011", "101101", "1111100", "111100", "10100", "1101", "1111111", "1100011", "1101101", "1100", "100", "1100001", "100011", "110100", "110101", "110100", "10011", ]; let common_values = &[ ("11010", 8131), ("1111", 8059), ("1010101", 8004), ("1001101", 7998), ("11011", 7993), ("1110111", 7978), ("1010100", 7959), ("111", 7958), ("1011010", 7953), ("1100011", 7947), ]; let sample_median = (64, None); let sample_moment_stats = MomentStats { mean: NiceFloat(63.555225000001755), standard_deviation: NiceFloat(36.938359582441294), skewness: NiceFloat(-0.0007106807748730345), excess_kurtosis: NiceFloat(-1.2008391146615376), }; striped_random_natural_signeds_helper::( 2, 1, values, common_values, sample_median, sample_moment_stats, ); // i8, m = 5/4 let values = &[ "101001", "100101", "100110", "1101001", "101101", "1010101", "111010", "101010", "10110", "1010101", "1001000", "1001011", "1000", "11100", "1111010", "101101", "110101", "101010", "100101", "100010", ]; let common_values = &[ ("101010", 131212), ("1010101", 131202), ("1001010", 33119), ("1011010", 33073), ("10101", 32947), ("100101", 32868), ("1010010", 32851), ("101011", 32817), ("101001", 32765), ("110101", 32761), ]; let sample_median = (65, None); let sample_moment_stats = MomentStats { mean: NiceFloat(63.51375499999882), standard_deviation: NiceFloat(27.10334306669828), skewness: NiceFloat(-0.0017292127163026868), excess_kurtosis: NiceFloat(-1.1007498380278757), }; striped_random_natural_signeds_helper::( 5, 4, values, common_values, sample_median, sample_moment_stats, ); // i64, m = 32 let values = &[ "11111111111111111111111111111", "111111111111111111111111111111111111111111111111111111111", "1111111111111111111111111111", "111111111111111111111111110000000000000000000000000000000000000", "111111111111111111111111111111111111111111111111111111111", "111111111000000000000000000000000000000000000001100000000111111", "11111111111111100000", "11111111111111111", "111111111111", "111111111111111111111111111111111111111111111111111100000000000", "111111111111100000000000000000000000000000000000000000000000000", "111111111000000000000000000000000000000000000000000000000000000", "1111111111111111111111111111100000000000000", "1000000011111111111111111111", "111111000000000000000111111111111111111111111111111111111111111", "0", "11111111111100000000000000000000000000000000000000", "111111111111111111111110000000000000000001111111", "1111111111111111111111111111111111111111111111111111111111111", "1111111", ]; let common_values = &[ ( "111111111111111111111111111111111111111111111111111111111111111", 69948, ), ("0", 69809), ( "111111111111111111111111111111111111111111111111111111111111000", 2383, ), ( "11111111111111111111111111111111111111111111111111111111111", 2362, ), ("11111111111111111111111", 2334), ( "111111111111111100000000000000000000000000000000000000000000000", 2334, ), ( "100000000000000000000000000000000000000000000000000000000000000", 2328, ), ( "111111111111111111111111111111100000000000000000000000000000000", 2327, ), ("111111111", 2320), ("11", 2318), ]; let sample_median = (4611686018427387904, None); let sample_moment_stats = MomentStats { mean: NiceFloat(4.614976015729421e18), standard_deviation: NiceFloat(4.4270184647985137e18), skewness: NiceFloat(-0.0014267894129673844), excess_kurtosis: NiceFloat(-1.9430528242638783), }; striped_random_natural_signeds_helper::( 32, 1, values, common_values, sample_median, sample_moment_stats, ); // i64, m = 2 let values = &[ "1100110001101010100101101001000001100001110101111001000000001", "111011011100111110111000010111001101001101010010111011001100", "11110000010100111000110001101100111001001010101110001000100000", "110010001100111101011100111111100001001110001100001001000000011", "1100110011001011000001001111001010100010110100011010010001", "111000101110010000110100101010100100111001100100001101010011011", "10000011110001100010001010101101101100100000010011101111010", "1110110110110011010011011010000111001101110110010001101011110", "11010010000001101100111000010011100101110010101101001100110000", "110000010001000110001011100111001101110010001111000110001111001", "100011101111011001001101101011100000110001110100111011011011111", "111101111100000110000001010001001101011110011110110100010110010", "1010001010011101001011011111100101110000001010101000111100001", "11110011011100110101011110010001110100010111001010000100011101", "110001001100111101011111000100111101011110111101110011010100111", "1111011101101101011111011010011011001011010001101011100101", "11111101110101010010000100011110100110100000110100101000110111", "10101011010100000101011100111011000001101010001000101111111010", "110000111110001111000001110011101110100001101011111010100110", "1101010111111111000111001111000111110001111110100101000001111", ]; let common_values = &[ ("10101000110110101100110011001101011011101", 1), ("1110100010100111110111100000011111000010100", 1), ("10011111100110010100000010001100001001111011", 1), ("10111110110011101010110111100010100101101100", 1), ("110101001100100110010011010000011100100111011", 1), ("1001000111011010110011001111101001111101110011", 1), ("1010101100111011110111011011011100011101010101", 1), ("1100110000110110000100011110000110101010110010", 1), ("1100110011000110101101111111111110111011101001", 1), ("1101011001000111111110011010000001001001000110", 1), ]; let sample_median = (4616064909372870741, Some(4616067528870766644)); let sample_moment_stats = MomentStats { mean: NiceFloat(4.614689648935556e18), standard_deviation: NiceFloat(2.6622250799886193e18), skewness: NiceFloat(-0.0006757801147527129), excess_kurtosis: NiceFloat(-1.199752325803772), }; striped_random_natural_signeds_helper::( 2, 1, values, common_values, sample_median, sample_moment_stats, ); // i64, m = 33/32 let values = &[ "10101010101010101010101101010101010101010101010101010101010101", "10101010101010100010101010010101101010101010101011010101011010", "10101010010101011010101010101010101101010101010101010101010101", "101010101010101010101101010101010101010101010101010101010101010", "10101010101010101010101011010101010101001010010101001010101010", "101010101010101010101010101010101010100101010010101010110101010", "10101010101010101010101010101010101010101010101010110101010101", "10101010101010101010010101010101010101010101010101010101010101", "10101010010101010101010101010101010101010101010101010101010101", "101010101100101010101010101010101010101010101010101010010101010", "101010101010101010101010101010101011001010101010101101010101010", "101101010101010011010101010101010101010101010101010101010101010", "10101001010101010101011010101010101010101010101010101010101010", "10101010101010101011010010010110101010101010101010101010101010", "101010101010101010110101010101010101010101010010101010101010101", "10101010101010101010101010101010101010101010101010101010101010", "10101010101010101010101010101010101010101010101011010101010101", "10101010101010101010101010101010101010101101010101010101010101", "10101010101010101011011010100101010101001010101010101010101010", "10101010101010101010101010101011010101010101010101010101010101", ]; let common_values = &[ ( "101010101010101010101010101010101010101010101010101010101010101", 74299, ), ( "10101010101010101010101010101010101010101010101010101010101010", 74072, ), ( "101010101010101010101010010101010101010101010101010101010101010", 2429, ), ( "101010101010101010101010101010101010101010101010101010101011010", 2419, ), ( "101010101011010101010101010101010101010101010101010101010101010", 2419, ), ( "101010101010101010101001010101010101010101010101010101010101010", 2411, ), ( "101010101010101010101010101010101010101010101010010101010101010", 2393, ), ( "101010101001010101010101010101010101010101010101010101010101010", 2390, ), ( "10101010101010101010101010101001010101010101010101010101010101", 2389, ), ( "10101010101010101010101010101010101010101010101010101010100101", 2389, ), ]; let sample_median = (5281221163029801642, Some(5281221163029804373)); let sample_moment_stats = MomentStats { mean: NiceFloat(4.613154278246113e18), standard_deviation: NiceFloat(1.599140542162029e18), skewness: NiceFloat(-0.0019511120341977268), excess_kurtosis: NiceFloat(-1.7372862317601716), }; striped_random_natural_signeds_helper::( 33, 32, values, common_values, sample_median, sample_moment_stats, ); } fn striped_random_natural_signeds_fail_helper() { assert_panic!(striped_random_natural_signeds::(EXAMPLE_SEED, 1, 0)); assert_panic!(striped_random_natural_signeds::(EXAMPLE_SEED, 2, 3)); } #[test] fn striped_random_natural_signeds_fail() { apply_fn_to_signeds!(striped_random_natural_signeds_fail_helper); } malachite-base-0.4.16/tests/num/random/striped/striped_random_negative_signeds.rs000064400000000000000000000370261046102023000264340ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::striped::striped_random_negative_signeds; use malachite_base::random::EXAMPLE_SEED; use malachite_base::strings::ToBinaryString; use malachite_base::test_util::stats::common_values_map::common_values_map; use malachite_base::test_util::stats::median; use malachite_base::test_util::stats::moments::{moment_stats, CheckedToF64, MomentStats}; use std::panic::catch_unwind; fn striped_random_negative_signeds_helper( m_numerator: u64, m_denominator: u64, expected_values: &[&str], expected_common_values: &[(&str, usize)], expected_sample_median: (T, Option), expected_sample_moment_stats: MomentStats, ) { let xs = striped_random_negative_signeds::(EXAMPLE_SEED, m_numerator, m_denominator); let actual_values = xs .clone() .map(|x| x.to_binary_string()) .take(20) .collect_vec(); let actual_common_values = common_values_map(1000000, 10, xs.clone()) .iter() .map(|(x, frequency)| (x.to_binary_string(), *frequency)) .collect_vec(); let actual_sample_median = median(xs.clone().take(1000000)); let actual_sample_moment_stats = moment_stats(xs.take(1000000)); assert_eq!( ( actual_values, actual_common_values, actual_sample_median, actual_sample_moment_stats ), ( expected_values .iter() .map(ToString::to_string) .collect_vec(), expected_common_values .iter() .map(|(x, frequency)| (x.to_string(), *frequency)) .collect_vec(), expected_sample_median, expected_sample_moment_stats ) ); } #[test] fn test_striped_random_negative_signeds() { // i8, m = 4 let values = &[ "10000000", "10101100", "10110000", "11111100", "10001111", "11111110", "10000000", "10000111", "10011101", "11100000", "11111111", "11100000", "10000000", "10000010", "11000011", "10111111", "10000001", "10000000", "10001111", "10000001", ]; let common_values = &[ ("10000000", 89042), ("11111111", 88624), ("10011111", 29871), ("11111000", 29848), ("11000000", 29802), ("11111110", 29796), ("11100000", 29664), ("11110000", 29649), ("10000111", 29644), ("10111111", 29621), ]; let sample_median = (-64, None); let sample_moment_stats = MomentStats { mean: NiceFloat(-64.47355199999896), standard_deviation: NiceFloat(47.66137677522698), skewness: NiceFloat(-0.0011056592983105659), excess_kurtosis: NiceFloat(-1.5649370173869896), }; striped_random_negative_signeds_helper::( 4, 1, values, common_values, sample_median, sample_moment_stats, ); // i8, m = 2 let values = &[ "10011001", "10011100", "10101010", "11001011", "10101101", "11111100", "10111100", "10010100", "10001101", "11111111", "11100011", "11101101", "10001100", "10000100", "11100001", "10100011", "10110100", "10110101", "10110100", "10010011", ]; let common_values = &[ ("10011010", 8131), ("10001111", 8059), ("11010101", 8004), ("11001101", 7998), ("10011011", 7993), ("11110111", 7978), ("11010100", 7959), ("10000111", 7958), ("11011010", 7953), ("11100011", 7947), ]; let sample_median = (-64, None); let sample_moment_stats = MomentStats { mean: NiceFloat(-64.44477500000217), standard_deviation: NiceFloat(36.93835958244133), skewness: NiceFloat(-0.0007106807748731826), excess_kurtosis: NiceFloat(-1.2008391146615451), }; striped_random_negative_signeds_helper::( 2, 1, values, common_values, sample_median, sample_moment_stats, ); // i8, m = 5/4 let values = &[ "10101001", "10100101", "10100110", "11101001", "10101101", "11010101", "10111010", "10101010", "10010110", "11010101", "11001000", "11001011", "10001000", "10011100", "11111010", "10101101", "10110101", "10101010", "10100101", "10100010", ]; let common_values = &[ ("10101010", 131212), ("11010101", 131202), ("11001010", 33119), ("11011010", 33073), ("10010101", 32947), ("10100101", 32868), ("11010010", 32851), ("10101011", 32817), ("10101001", 32765), ("10110101", 32761), ]; let sample_median = (-63, None); let sample_moment_stats = MomentStats { mean: NiceFloat(-64.48624499999755), standard_deviation: NiceFloat(27.103343066698287), skewness: NiceFloat(-0.0017292127163029483), excess_kurtosis: NiceFloat(-1.1007498380278833), }; striped_random_negative_signeds_helper::( 5, 4, values, common_values, sample_median, sample_moment_stats, ); // i64, m = 32 let values = &[ "1000000000000000000000000000000000011111111111111111111111111111", "1000000111111111111111111111111111111111111111111111111111111111", "1000000000000000000000000000000000001111111111111111111111111111", "1111111111111111111111111110000000000000000000000000000000000000", "1000000111111111111111111111111111111111111111111111111111111111", "1111111111000000000000000000000000000000000000001100000000111111", "1000000000000000000000000000000000000000000011111111111111100000", "1000000000000000000000000000000000000000000000011111111111111111", "1000000000000000000000000000000000000000000000000000111111111111", "1111111111111111111111111111111111111111111111111111100000000000", "1111111111111100000000000000000000000000000000000000000000000000", "1111111111000000000000000000000000000000000000000000000000000000", "1000000000000000000001111111111111111111111111111100000000000000", "1000000000000000000000000000000000001000000011111111111111111111", "1111111000000000000000111111111111111111111111111111111111111111", "1000000000000000000000000000000000000000000000000000000000000000", "1000000000000011111111111100000000000000000000000000000000000000", "1000000000000000111111111111111111111110000000000000000001111111", "1001111111111111111111111111111111111111111111111111111111111111", "1000000000000000000000000000000000000000000000000000000001111111", ]; let common_values = &[ ( "1111111111111111111111111111111111111111111111111111111111111111", 69948, ), ( "1000000000000000000000000000000000000000000000000000000000000000", 69809, ), ( "1111111111111111111111111111111111111111111111111111111111111000", 2383, ), ( "1000011111111111111111111111111111111111111111111111111111111111", 2362, ), ( "1111111111111111100000000000000000000000000000000000000000000000", 2334, ), ( "1000000000000000000000000000000000000000011111111111111111111111", 2334, ), ( "1100000000000000000000000000000000000000000000000000000000000000", 2328, ), ( "1111111111111111111111111111111100000000000000000000000000000000", 2327, ), ( "1000000000000000000000000000000000000000000000000000000111111111", 2320, ), ( "1000000000000000000000000000000000000000000000000000000000000011", 2318, ), ]; let sample_median = (-4611686018427387904, None); let sample_moment_stats = MomentStats { mean: NiceFloat(-4.608396021125303e18), standard_deviation: NiceFloat(4.4270184647985106e18), skewness: NiceFloat(-0.0014267894129673469), excess_kurtosis: NiceFloat(-1.9430528242638716), }; striped_random_negative_signeds_helper::( 32, 1, values, common_values, sample_median, sample_moment_stats, ); // i64, m = 2 let values = &[ "1001100110001101010100101101001000001100001110101111001000000001", "1000111011011100111110111000010111001101001101010010111011001100", "1011110000010100111000110001101100111001001010101110001000100000", "1110010001100111101011100111111100001001110001100001001000000011", "1000001100110011001011000001001111001010100010110100011010010001", "1111000101110010000110100101010100100111001100100001101010011011", "1000010000011110001100010001010101101101100100000010011101111010", "1001110110110110011010011011010000111001101110110010001101011110", "1011010010000001101100111000010011100101110010101101001100110000", "1110000010001000110001011100111001101110010001111000110001111001", "1100011101111011001001101101011100000110001110100111011011011111", "1111101111100000110000001010001001101011110011110110100010110010", "1001010001010011101001011011111100101110000001010101000111100001", "1011110011011100110101011110010001110100010111001010000100011101", "1110001001100111101011111000100111101011110111101110011010100111", "1000001111011101101101011111011010011011001011010001101011100101", "1011111101110101010010000100011110100110100000110100101000110111", "1010101011010100000101011100111011000001101010001000101111111010", "1000110000111110001111000001110011101110100001101011111010100110", "1001101010111111111000111001111000111110001111110100101000001111", ]; let common_values = &[ ( "1111111111111111111101100100101101000010000101001100011100001011", 1, ), ( "1111111111111111111101010010001100000001111011100011001110010101", 1, ), ( "1111111111111111111101000101011100111011001010001100011011001010", 1, ), ( "1111111111111111111100101001000100000101110101000111010111100101", 1, ), ( "1111111111111111111100000101111010110010101111000000001111000010", 1, ), ( "1111111111111111111010001000001010110110111101111011110111000001", 1, ), ( "1111111111111111110111101001011000111000100110110000000111010011", 1, ), ( "1111111111111111110110001001110101000111010110110110001100010111", 1, ), ( "1111111111111111110101100100101011001110101010101111101001011101", 1, ), ( "1111111111111111101110111110101110101010000001001011010001101111", 1, ), ]; let sample_median = (-4607307127481905067, Some(-4607304507984009164)); let sample_moment_stats = MomentStats { mean: NiceFloat(-4.6086823879191747e18), standard_deviation: NiceFloat(2.66222507998862e18), skewness: NiceFloat(-0.0006757801147528804), excess_kurtosis: NiceFloat(-1.1997523258037708), }; striped_random_negative_signeds_helper::( 2, 1, values, common_values, sample_median, sample_moment_stats, ); // i64, m = 33/32 let values = &[ "1010101010101010101010101101010101010101010101010101010101010101", "1010101010101010100010101010010101101010101010101011010101011010", "1010101010010101011010101010101010101101010101010101010101010101", "1101010101010101010101101010101010101010101010101010101010101010", "1010101010101010101010101011010101010101001010010101001010101010", "1101010101010101010101010101010101010100101010010101010110101010", "1010101010101010101010101010101010101010101010101010110101010101", "1010101010101010101010010101010101010101010101010101010101010101", "1010101010010101010101010101010101010101010101010101010101010101", "1101010101100101010101010101010101010101010101010101010010101010", "1101010101010101010101010101010101011001010101010101101010101010", "1101101010101010011010101010101010101010101010101010101010101010", "1010101001010101010101011010101010101010101010101010101010101010", "1010101010101010101011010010010110101010101010101010101010101010", "1101010101010101010110101010101010101010101010010101010101010101", "1010101010101010101010101010101010101010101010101010101010101010", "1010101010101010101010101010101010101010101010101011010101010101", "1010101010101010101010101010101010101010101101010101010101010101", "1010101010101010101011011010100101010101001010101010101010101010", "1010101010101010101010101010101011010101010101010101010101010101", ]; let common_values = &[ ( "1101010101010101010101010101010101010101010101010101010101010101", 74299, ), ( "1010101010101010101010101010101010101010101010101010101010101010", 74072, ), ( "1101010101010101010101010010101010101010101010101010101010101010", 2429, ), ( "1101010101011010101010101010101010101010101010101010101010101010", 2419, ), ( "1101010101010101010101010101010101010101010101010101010101011010", 2419, ), ( "1101010101010101010101001010101010101010101010101010101010101010", 2411, ), ( "1101010101010101010101010101010101010101010101010010101010101010", 2393, ), ( "1101010101001010101010101010101010101010101010101010101010101010", 2390, ), ( "1010101010101010101010101010101010101010101010101010101010100101", 2389, ), ( "1010101010101010101010101010101001010101010101010101010101010101", 2389, ), ]; let sample_median = (-3942150873824974166, Some(-3942150873824971435)); let sample_moment_stats = MomentStats { mean: NiceFloat(-4.610217758608903e18), standard_deviation: NiceFloat(1.5991405421620288e18), skewness: NiceFloat(-0.0019511120341977582), excess_kurtosis: NiceFloat(-1.7372862317601778), }; striped_random_negative_signeds_helper::( 33, 32, values, common_values, sample_median, sample_moment_stats, ); } fn striped_random_negative_signeds_fail_helper() { assert_panic!(striped_random_negative_signeds::(EXAMPLE_SEED, 1, 0)); assert_panic!(striped_random_negative_signeds::(EXAMPLE_SEED, 2, 3)); } #[test] fn striped_random_negative_signeds_fail() { apply_fn_to_signeds!(striped_random_negative_signeds_fail_helper); } malachite-base-0.4.16/tests/num/random/striped/striped_random_nonzero_signeds.rs000064400000000000000000000353111046102023000263170ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::striped::striped_random_nonzero_signeds; use malachite_base::random::EXAMPLE_SEED; use malachite_base::strings::ToBinaryString; use malachite_base::test_util::stats::common_values_map::common_values_map; use malachite_base::test_util::stats::median; use malachite_base::test_util::stats::moments::{moment_stats, CheckedToF64, MomentStats}; use std::panic::catch_unwind; fn striped_random_nonzero_signeds_helper( m_numerator: u64, m_denominator: u64, expected_values: &[&str], expected_common_values: &[(&str, usize)], expected_sample_median: (T, Option), expected_sample_moment_stats: MomentStats, ) { let xs = striped_random_nonzero_signeds::(EXAMPLE_SEED, m_numerator, m_denominator); let actual_values = xs .clone() .map(|x| x.to_binary_string()) .take(20) .collect_vec(); let actual_common_values = common_values_map(1000000, 10, xs.clone()) .iter() .map(|(x, frequency)| (x.to_binary_string(), *frequency)) .collect_vec(); let actual_sample_median = median(xs.clone().take(1000000)); let actual_sample_moment_stats = moment_stats(xs.take(1000000)); assert_eq!( ( actual_values, actual_common_values, actual_sample_median, actual_sample_moment_stats ), ( expected_values .iter() .map(ToString::to_string) .collect_vec(), expected_common_values .iter() .map(|(x, frequency)| (x.to_string(), *frequency)) .collect_vec(), expected_sample_median, expected_sample_moment_stats ) ); } #[test] fn test_striped_random_nonzero_signeds() { // i8, m = 4 let values = &[ "1100001", "1000000", "1100000", "10000111", "1111", "10000001", "1111000", "100011", "111101", "11111100", "11111111", "11100001", "1", "101111", "10111000", "111111", "1101100", "1111110", "111100", "1", ]; let common_values = &[ ("1111111", 46633), ("11111111", 46592), ("10000000", 46404), ("11000000", 15765), ("11111100", 15719), ("10011111", 15717), ("111111", 15661), ("1111100", 15658), ("11111", 15657), ("1111", 15644), ]; let sample_median = (-1, None); let sample_moment_stats = MomentStats { mean: NiceFloat(-0.47311899999999013), standard_deviation: NiceFloat(81.62164912267556), skewness: NiceFloat(0.0008208424524866476), excess_kurtosis: NiceFloat(-1.1132122689325452), }; striped_random_nonzero_signeds_helper::( 4, 1, values, common_values, sample_median, sample_moment_stats, ); // i8, m = 2 let values = &[ "1110111", "1000010", "1010011", "10011100", "10110", "10000100", "1100001", "100110", "11101", "11100110", "11100000", "11111010", "11011", "101100", "10101011", "10110", "1011110", "1110101", "10001", "10100", ]; let common_values = &[ ("11010110", 4078), ("1100000", 4059), ("1100100", 4058), ("11000100", 4050), ("11100100", 4049), ("11101011", 4048), ("10011000", 4048), ("11111110", 4044), ("1010111", 4040), ("11110100", 4039), ]; let sample_median = (-1, None); let sample_moment_stats = MomentStats { mean: NiceFloat(-0.5178119999999826), standard_deviation: NiceFloat(74.01861596576973), skewness: NiceFloat(0.000735155416319748), excess_kurtosis: NiceFloat(-1.2058601704389202), }; striped_random_nonzero_signeds_helper::( 2, 1, values, common_values, sample_median, sample_moment_stats, ); // i8, m = 5/4 let values = &[ "1010100", "1001010", "1101101", "10010101", "110101", "10101010", "1000010", "101001", "110110", "11011101", "11011001", "11110101", "1010", "10101", "10110101", "111010", "1101001", "1101010", "100110", "101001", ]; let common_values = &[ ("11010101", 66214), ("10101010", 65618), ("1010101", 65486), ("101010", 65185), ("10100101", 16584), ("11010010", 16518), ("1011010", 16486), ("1101010", 16481), ("110101", 16475), ("10010101", 16471), ]; let sample_median = (-5, None); let sample_moment_stats = MomentStats { mean: NiceFloat(-0.5124420000000011), standard_deviation: NiceFloat(69.49222913654884), skewness: NiceFloat(0.0016761512574253166), excess_kurtosis: NiceFloat(-1.4630127076308237), }; striped_random_nonzero_signeds_helper::( 5, 4, values, common_values, sample_median, sample_moment_stats, ); // i64, m = 32 let values = &[ "111000000000000000000000000000001111111111111111111111111111111", "111111111111111111111111111111111111111111111111111111111111111", "111111111111111111111111111111111100000000000000000000000000011", "1000000000000000011111111111111111111111111111111111111111111111", "111111111111111111111111111111100000000000000000000000000", "1000000000000000000000000000000001111111000000000000000000011111", "111111111111111111111000000000000000000011111111111111111111111", "111111111111111000000000010000001111111111", "1000000000000000", "1111111111001111111111111111111111111111111111111111111110000000", "1111111111111111111111111111111111111111111111111111111111111111", "1100000000000000000000000000000000000000000000000000000000000000", "11111111111111111111111111111000000000000000001111111", "111111111111111111111111111111111111111111111111111111", "1000000000000001111111100000011111111111111111111111111111000000", "111111111111111111000", "111111110000001000000000000000000000000000000000000000000000000", "111111111111111111111111111111111111111100000000000001111111111", "111111111111111111111111111111111111111", "1111111111111111111111111111111111111111111", ]; let common_values = &[ ( "1111111111111111111111111111111111111111111111111111111111111111", 36249, ), ( "1000000000000000000000000000000000000000000000000000000000000000", 35940, ), ( "111111111111111111111111111111111111111111111111111111111111111", 35831, ), ( "111111111111111111111111111111111111111111111111111000000000000", 1244, ), ( "1000000000000000000000000000000000000000111111111111111111111111", 1243, ), ( "111111111111111111100000000000000000000000000000000000000000000", 1236, ), ( "1000000000000000000000000000000000000001111111111111111111111111", 1231, ), ( "111111111111111111111110000000000000000000000000000000000000000", 1229, ), ( "1000000000000000000000000000000111111111111111111111111111111111", 1228, ), ( "1111111111111111111111111111111111000000000000000000000000000000", 1226, ), ]; let sample_median = (-1, None); let sample_moment_stats = MomentStats { mean: NiceFloat(4290456766772419.0), standard_deviation: NiceFloat(6.503574909103916e18), skewness: NiceFloat(-0.0008033470716056729), excess_kurtosis: NiceFloat(-1.0564362595467798), }; striped_random_nonzero_signeds_helper::( 32, 1, values, common_values, sample_median, sample_moment_stats, ); // i64, m = 2 let values = &[ "111011100001010110001110001011000010001111010011001110110011001", "111111110100110110100110101000101101000011101011011100101000100", "110111111101001101101001110111101010101111111011100100000100111", "1000110000101001011011100011110101111000101110000001001010011110", "1111111001111100000101110010111000110111101100000010010000110", "1011101011101000100100010110110000010100100110010000101111101011", "110111111011000111010100010011001001010111010010000110110001011", "1110111111011000100010000110111111011111000110110100101011011", "11001110010100010000000011111011101000011001110000011101001011", "1111111000011000100101100000001111001100100011111000000011001110", "1101011111111010011011100100011000000100001100111000011000011010", "1101101001110110010110110101111101111010001011011100001000011111", "1101110000100110011011100110000000011010100111111110001010", "1011001000101100011000110011000001110001101010111010010000100", "1000111011101001000111101001100000111100100111100111001010111100", "11101000100000101100011100101110111000100010100001001101110000", "110100010100010101000011000111011101000100100100011111010000011", "100000011111110101100111000100100111101101110010011101110110001", "10100101100000110010110100110100011010011101101100010", "10111110011011000011000011001010101000101001100001001000000110", ]; let common_values = &[ ("1000001000001111111111101100101100110101100101", 1), ("1101011110010101110000100010110110000010001101", 1), ("1101111000110100001101000000011011000101001001", 1), ("1111000011101100001000100110000111101110100011", 1), ("10011000001111100110100111011000010001100001111", 1), ( "1111111111111111101111101000011101000100001010110001100101110110", 1, ), ( "1111111111111111101011111111000001110100011010010001100100101000", 1, ), ("11010000001000101001101001110011011011010000011", 1), ("11101111110000011100000111100110000000001011010", 1), ("100011011110110010100010110100001001100100001000", 1), ]; let sample_median = (-8123231271792388, Some(-8096687505746509)); let sample_moment_stats = MomentStats { mean: NiceFloat(91581052023966.92), standard_deviation: NiceFloat(5.31973124263762e18), skewness: NiceFloat(0.0012453230455855707), excess_kurtosis: NiceFloat(-1.1981323295909574), }; striped_random_nonzero_signeds_helper::( 2, 1, values, common_values, sample_median, sample_moment_stats, ); // i64, m = 33/32 let values = &[ "101010100101010101010101010101010101010101010101010101010101010", "101010101010101010101010101010110101010101010101010101010101010", "101010100101010101010101010101010101010101010101010101010101010", "1010101010010101010101010101010101010101010101010101010101010110", "11010101010101010101010101010101010101010101010101010101011010", "1010101010101010101010101011010100101010101010101010100101010101", "101010110101010101010101010101010101010101010101010101010101010", "10101010101010101010101001010101010101010101010101010101010101", "10101010101010101010101010101010101010101010101001101010101010", "1101010101010101010101010101010101010011010101101010101010101010", "1101010101010101011010101010101010101010101010101010101010101010", "1101010101010101010101010101010101010101010101010101010101010101", "10101010101010101010101010101010101010101010101010101010101010", "10101010101010101010101010101010101010101010101010101010101010", "1010101010101010101010101010101010101010101010101011010101010101", "10100101010101010101010101010101010101010101010101010101010101", "101001010101010101010101010101010101010101010101010101010101101", "101010101010101010111010101010110101010101010101010101010101010", "10101010101101010101010101010101010101010101010101010101010101", "10101010101010101010101101010010101010110101010101101010101010", ]; let common_values = &[ ( "101010101010101010101010101010101010101010101010101010101010101", 37342, ), ( "10101010101010101010101010101010101010101010101010101010101010", 37241, ), ( "1101010101010101010101010101010101010101010101010101010101010101", 37189, ), ( "1010101010101010101010101010101010101010101010101010101010101010", 37109, ), ( "1010101010101010101010101010101010101001010101010101010101010101", 1241, ), ( "1101010101010101010101010101010101010110101010101010101010101010", 1239, ), ( "10101010101010101010101010101010101010101010101010101010100101", 1235, ), ( "1010101010101010101010101010101010101011010101010101010101010101", 1233, ), ( "1101011010101010101010101010101010101010101010101010101010101010", 1231, ), ( "1101010101010101010101010101010101010101010101010101010101010010", 1227, ), ]; let sample_median = (-1489184412743849302, Some(-1489184412721829206)); let sample_moment_stats = MomentStats { mean: NiceFloat(-2366723010422570.0), standard_deviation: NiceFloat(4.878981868385203e18), skewness: NiceFloat(0.0014056588570288651), excess_kurtosis: NiceFloat(-1.6132504884076841), }; striped_random_nonzero_signeds_helper::( 33, 32, values, common_values, sample_median, sample_moment_stats, ); } fn striped_random_nonzero_signeds_fail_helper() { assert_panic!(striped_random_nonzero_signeds::(EXAMPLE_SEED, 1, 0)); assert_panic!(striped_random_nonzero_signeds::(EXAMPLE_SEED, 2, 3)); } #[test] fn striped_random_nonzero_signeds_fail() { apply_fn_to_signeds!(striped_random_nonzero_signeds_fail_helper); } malachite-base-0.4.16/tests/num/random/striped/striped_random_positive_signeds.rs000064400000000000000000000341261046102023000264720ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::striped::striped_random_positive_signeds; use malachite_base::random::EXAMPLE_SEED; use malachite_base::strings::ToBinaryString; use malachite_base::test_util::stats::common_values_map::common_values_map; use malachite_base::test_util::stats::median; use malachite_base::test_util::stats::moments::{moment_stats, CheckedToF64, MomentStats}; use std::panic::catch_unwind; fn striped_random_positive_signeds_helper( m_numerator: u64, m_denominator: u64, expected_values: &[&str], expected_common_values: &[(&str, usize)], expected_sample_median: (T, Option), expected_sample_moment_stats: MomentStats, ) { let xs = striped_random_positive_signeds::(EXAMPLE_SEED, m_numerator, m_denominator); let actual_values = xs .clone() .map(|x| x.to_binary_string()) .take(20) .collect_vec(); let actual_common_values = common_values_map(1000000, 10, xs.clone()) .iter() .map(|(x, frequency)| (x.to_binary_string(), *frequency)) .collect_vec(); let actual_sample_median = median(xs.clone().take(1000000)); let actual_sample_moment_stats = moment_stats(xs.take(1000000)); assert_eq!( ( actual_values, actual_common_values, actual_sample_median, actual_sample_moment_stats ), ( expected_values .iter() .map(ToString::to_string) .collect_vec(), expected_common_values .iter() .map(|(x, frequency)| (x.to_string(), *frequency)) .collect_vec(), expected_sample_median, expected_sample_moment_stats ) ); } #[test] fn test_striped_random_positive_signeds() { // i8, m = 4 let values = &[ "101100", "110000", "1111100", "1111", "1111110", "111", "11101", "1100000", "1111111", "1100000", "10", "1000011", "111111", "1", "1111", "1", "1111111", "1111111", "111111", "101", ]; let common_values = &[ ("1111111", 97287), ("1111000", 32824), ("11111", 32718), ("1111110", 32708), ("1000000", 32633), ("1100000", 32625), ("111111", 32619), ("1110000", 32582), ("1111", 32563), ("111", 32542), ]; let sample_median = (67, None); let sample_moment_stats = MomentStats { mean: NiceFloat(69.74119900000126), standard_deviation: NiceFloat(45.39301881973154), skewness: NiceFloat(-0.14669679109094702), excess_kurtosis: NiceFloat(-1.4928149640100892), }; striped_random_positive_signeds_helper::( 4, 1, values, common_values, sample_median, sample_moment_stats, ); // i8, m = 2 let values = &[ "11001", "11100", "101010", "1001011", "101101", "1111100", "111100", "10100", "1101", "1111111", "1100011", "1101101", "1100", "100", "1100001", "100011", "110100", "110101", "110100", "10011", ]; let common_values = &[ ("11010", 8196), ("1111", 8123), ("1001101", 8065), ("11011", 8056), ("1010101", 8053), ("1110111", 8043), ("1010100", 8019), ("111", 8015), ("101100", 8003), ("1111010", 8002), ]; let sample_median = (64, None); let sample_moment_stats = MomentStats { mean: NiceFloat(64.04460499999882), standard_deviation: NiceFloat(36.65530083091763), skewness: NiceFloat(-0.0005788615669167611), excess_kurtosis: NiceFloat(-1.2009597413001147), }; striped_random_positive_signeds_helper::( 2, 1, values, common_values, sample_median, sample_moment_stats, ); // i8, m = 5/4 let values = &[ "101001", "100101", "100110", "1101001", "101101", "1010101", "111010", "101010", "10110", "1010101", "1001000", "1001011", "1000", "11100", "1111010", "101101", "110101", "101010", "100101", "100010", ]; let common_values = &[ ("101010", 131218), ("1010101", 131204), ("1001010", 33121), ("1011010", 33074), ("10101", 32947), ("100101", 32868), ("1010010", 32851), ("101011", 32817), ("101001", 32765), ("110101", 32762), ]; let sample_median = (65, None); let sample_moment_stats = MomentStats { mean: NiceFloat(63.51510099999881), standard_deviation: NiceFloat(27.102051665528496), skewness: NiceFloat(-0.0016063884661944201), excess_kurtosis: NiceFloat(-1.1009870884906956), }; striped_random_positive_signeds_helper::( 5, 4, values, common_values, sample_median, sample_moment_stats, ); // i64, m = 32 let values = &[ "11111111111111111111111111111", "111111111111111111111111111111111111111111111111111111111", "1111111111111111111111111111", "111111111111111111111111110000000000000000000000000000000000000", "111111111111111111111111111111111111111111111111111111111", "111111111000000000000000000000000000000000000001100000000111111", "11111111111111100000", "11111111111111111", "111111111111", "111111111111111111111111111111111111111111111111111100000000000", "111111111111100000000000000000000000000000000000000000000000000", "111111111000000000000000000000000000000000000000000000000000000", "1111111111111111111111111111100000000000000", "1000000011111111111111111111", "111111000000000000000111111111111111111111111111111111111111111", "11111111111100000000000000000000000000000000000000", "111111111111111111111110000000000000000001111111", "1111111111111111111111111111111111111111111111111111111111111", "1111111", "111111111111111111100000000000000000000000000000000000000000000", ]; let common_values = &[ ( "111111111111111111111111111111111111111111111111111111111111111", 75198, ), ( "111111111111111111111111111111111111111111111111111111111111000", 2569, ), ( "11111111111111111111111111111111111111111111111111111111111", 2529, ), ( "111111111111111100000000000000000000000000000000000000000000000", 2513, ), ("11111111111111111111111", 2507), ("111111111", 2503), ( "100000000000000000000000000000000000000000000000000000000000000", 2502, ), ( "111111111111111110000000000000000000000000000000000000000000000", 2501, ), ("111111111111111111111111111", 2500), ( "111111111110000000000000000000000000000000000000000000000000000", 2491, ), ]; let sample_median = (8070450532250024960, Some(8070450532250024967)); let sample_moment_stats = MomentStats { mean: NiceFloat(4.959974637374284e18), standard_deviation: NiceFloat(4.3991106930140626e18), skewness: NiceFloat(-0.15099815742030892), excess_kurtosis: NiceFloat(-1.9150786144831098), }; striped_random_positive_signeds_helper::( 32, 1, values, common_values, sample_median, sample_moment_stats, ); // i64, m = 2 let values = &[ "1100110001101010100101101001000001100001110101111001000000001", "111011011100111110111000010111001101001101010010111011001100", "11110000010100111000110001101100111001001010101110001000100000", "110010001100111101011100111111100001001110001100001001000000011", "1100110011001011000001001111001010100010110100011010010001", "111000101110010000110100101010100100111001100100001101010011011", "10000011110001100010001010101101101100100000010011101111010", "1110110110110011010011011010000111001101110110010001101011110", "11010010000001101100111000010011100101110010101101001100110000", "110000010001000110001011100111001101110010001111000110001111001", "100011101111011001001101101011100000110001110100111011011011111", "111101111100000110000001010001001101011110011110110100010110010", "1010001010011101001011011111100101110000001010101000111100001", "11110011011100110101011110010001110100010111001010000100011101", "110001001100111101011111000100111101011110111101110011010100111", "1111011101101101011111011010011011001011010001101011100101", "11111101110101010010000100011110100110100000110100101000110111", "10101011010100000101011100111011000001101010001000101111111010", "110000111110001111000001110011101110100001101011111010100110", "1101010111111111000111001111000111110001111110100101000001111", ]; let common_values = &[ ("10101000110110101100110011001101011011101", 1), ("1110100010100111110111100000011111000010100", 1), ("10011111100110010100000010001100001001111011", 1), ("10111110110011101010110111100010100101101100", 1), ("110101001100100110010011010000011100100111011", 1), ("1001000111011010110011001111101001111101110011", 1), ("1010101100111011110111011011011100011101010101", 1), ("1100110000110110000100011110000110101010110010", 1), ("1100110011000110101101111111111110111011101001", 1), ("1101011001000111111110011010000001001001000110", 1), ]; let sample_median = (4616064909372870741, Some(4616067528870766644)); let sample_moment_stats = MomentStats { mean: NiceFloat(4.614689648935556e18), standard_deviation: NiceFloat(2.6622250799886193e18), skewness: NiceFloat(-0.0006757801147527129), excess_kurtosis: NiceFloat(-1.199752325803772), }; striped_random_positive_signeds_helper::( 2, 1, values, common_values, sample_median, sample_moment_stats, ); // i64, m = 33/32 let values = &[ "10101010101010101010101101010101010101010101010101010101010101", "10101010101010100010101010010101101010101010101011010101011010", "10101010010101011010101010101010101101010101010101010101010101", "101010101010101010101101010101010101010101010101010101010101010", "10101010101010101010101011010101010101001010010101001010101010", "101010101010101010101010101010101010100101010010101010110101010", "10101010101010101010101010101010101010101010101010110101010101", "10101010101010101010010101010101010101010101010101010101010101", "10101010010101010101010101010101010101010101010101010101010101", "101010101100101010101010101010101010101010101010101010010101010", "101010101010101010101010101010101011001010101010101101010101010", "101101010101010011010101010101010101010101010101010101010101010", "10101001010101010101011010101010101010101010101010101010101010", "10101010101010101011010010010110101010101010101010101010101010", "101010101010101010110101010101010101010101010010101010101010101", "10101010101010101010101010101010101010101010101010101010101010", "10101010101010101010101010101010101010101010101011010101010101", "10101010101010101010101010101010101010101101010101010101010101", "10101010101010101011011010100101010101001010101010101010101010", "10101010101010101010101010101011010101010101010101010101010101", ]; let common_values = &[ ( "101010101010101010101010101010101010101010101010101010101010101", 74299, ), ( "10101010101010101010101010101010101010101010101010101010101010", 74072, ), ( "101010101010101010101010010101010101010101010101010101010101010", 2429, ), ( "101010101010101010101010101010101010101010101010101010101011010", 2419, ), ( "101010101011010101010101010101010101010101010101010101010101010", 2419, ), ( "101010101010101010101001010101010101010101010101010101010101010", 2411, ), ( "101010101010101010101010101010101010101010101010010101010101010", 2393, ), ( "101010101001010101010101010101010101010101010101010101010101010", 2390, ), ( "10101010101010101010101010101001010101010101010101010101010101", 2389, ), ( "10101010101010101010101010101010101010101010101010101010100101", 2389, ), ]; let sample_median = (5281221163029801642, Some(5281221163029804373)); let sample_moment_stats = MomentStats { mean: NiceFloat(4.613154278246113e18), standard_deviation: NiceFloat(1.599140542162029e18), skewness: NiceFloat(-0.0019511120341977268), excess_kurtosis: NiceFloat(-1.7372862317601716), }; striped_random_positive_signeds_helper::( 33, 32, values, common_values, sample_median, sample_moment_stats, ); } fn striped_random_positive_signeds_fail_helper() { assert_panic!(striped_random_positive_signeds::(EXAMPLE_SEED, 1, 0)); assert_panic!(striped_random_positive_signeds::(EXAMPLE_SEED, 2, 3)); } #[test] fn striped_random_positive_signeds_fail() { apply_fn_to_signeds!(striped_random_positive_signeds_fail_helper); } malachite-base-0.4.16/tests/num/random/striped/striped_random_positive_unsigneds.rs000064400000000000000000000343571046102023000270430ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::striped::striped_random_positive_unsigneds; use malachite_base::random::EXAMPLE_SEED; use malachite_base::strings::ToBinaryString; use malachite_base::test_util::stats::common_values_map::common_values_map; use malachite_base::test_util::stats::median; use malachite_base::test_util::stats::moments::{moment_stats, CheckedToF64, MomentStats}; use std::panic::catch_unwind; fn striped_random_positive_unsigneds_helper( m_numerator: u64, m_denominator: u64, expected_values: &[&str], expected_common_values: &[(&str, usize)], expected_sample_median: (T, Option), expected_sample_moment_stats: MomentStats, ) { let xs = striped_random_positive_unsigneds::(EXAMPLE_SEED, m_numerator, m_denominator); let actual_values = xs .clone() .map(|x| x.to_binary_string()) .take(20) .collect_vec(); let actual_common_values = common_values_map(1000000, 10, xs.clone()) .iter() .map(|(x, frequency)| (x.to_binary_string(), *frequency)) .collect_vec(); let actual_sample_median = median(xs.clone().take(1000000)); let actual_sample_moment_stats = moment_stats(xs.take(1000000)); assert_eq!( ( actual_values, actual_common_values, actual_sample_median, actual_sample_moment_stats ), ( expected_values .iter() .map(ToString::to_string) .collect_vec(), expected_common_values .iter() .map(|(x, frequency)| (x.to_string(), *frequency)) .collect_vec(), expected_sample_median, expected_sample_moment_stats ) ); } #[test] fn test_striped_random_positive_unsigneds() { // u8, m = 4 let values = &[ "1", "1001100", "1111111", "11000011", "10000000", "1111", "1110110", "11111000", "11111111", "11111101", "1111001", "11110000", "11", "1111111", "1", "11010011", "10000111", "111", "1111001", "10110000", ]; let common_values = &[ ("11111111", 71334), ("11110000", 24018), ("11100000", 24001), ("11111", 23981), ("11111110", 23965), ("111111", 23924), ("11111100", 23919), ("1111", 23888), ("11", 23829), ("111", 23815), ]; let sample_median = (131, None); let sample_moment_stats = MomentStats { mean: NiceFloat(136.63338500000273), standard_deviation: NiceFloat(92.21339578256648), skewness: NiceFloat(-0.10902316932402645), excess_kurtosis: NiceFloat(-1.5167077828673536), }; striped_random_positive_unsigneds_helper::( 4, 1, values, common_values, sample_median, sample_moment_stats, ); // u8, m = 2 let values = &[ "110011", "1110010", "1010110", "10110100", "1000001", "11000011", "101000", "110111", "11", "11000100", "10111001", "11111011", "111101", "1110011", "10100110", "1010010", "1110110", "110011", "11111", "1010011", ]; let common_values = &[ ("1000100", 4120), ("10100100", 4099), ("11100100", 4077), ("10100010", 4054), ("11011010", 4054), ("1010100", 4051), ("10010010", 4044), ("10001011", 4041), ("11100011", 4032), ("10110", 4028), ]; let sample_median = (128, None); let sample_moment_stats = MomentStats { mean: NiceFloat(128.1168509999991), standard_deviation: NiceFloat(73.48547444875528), skewness: NiceFloat(-0.0006394544560910719), excess_kurtosis: NiceFloat(-1.1968013589588233), }; striped_random_positive_unsigneds_helper::( 2, 1, values, common_values, sample_median, sample_moment_stats, ); // u8, m = 5/4 let values = &[ "1010010", "1101010", "110010", "10010100", "1010101", "10111010", "1010100", "1011010", "1010110", "10001101", "10000100", "11100011", "1010", "1001011", "10101010", "1010110", "1010001", "1010100", "1010101", "1010101", ]; let common_values = &[ ("1010101", 105176), ("10101010", 104735), ("10101101", 26535), ("11010101", 26470), ("1010010", 26421), ("101010", 26383), ("1001010", 26310), ("10010101", 26290), ("10110101", 26230), ("10101001", 26220), ]; let sample_median = (130, None); let sample_moment_stats = MomentStats { mean: NiceFloat(127.53545100000133), standard_deviation: NiceFloat(54.22647275765827), skewness: NiceFloat(-0.0014575581250140023), excess_kurtosis: NiceFloat(-1.1009413456646224), }; striped_random_positive_unsigneds_helper::( 5, 4, values, common_values, sample_median, sample_moment_stats, ); // u64, m = 32 let values = &[ "111111111111111111111111111111", "11111111111111111111111111111111111111111111111111111111111", "1111111111111111111111111111111", "1111111111111111111111100000000000000000000000000000000000000000", "11111111111111111111111111111111111111111111111111111111111111", "1111000000000000000000000000000000000000001100000000111111111111", "111111111111111000000000000", "1111111111111111111111111", "111111111111111111111", "1111111111111111111111111111111111111111111000000000000000000000", "1110000000000000000000000000000000000000000000000000000000000111", "1111111111111111111111111111111111111111111111111111111111111111", "11111111111111111111111111111000000000000000000000000000", "100000001111111111111111111111111000000000", "1111111000000000000000000000000000000000000000000000000000000000", "1111", "1111111111111111111111111111111111111111111111111111000", "1111111111111111110000000011111111111111111", "111111111111111111111111100", "1111111111111111111111111111111111111111111111111111111111111111", ]; let common_values = &[ ( "1111111111111111111111111111111111111111111111111111111111111111", 72952, ), ("111111111111111111111111111111", 2474), ( "1111111111111111111111111110000000000000000000000000000000000000", 2456, ), ("111111111", 2437), ("11111111111111111111111111111111111", 2417), ( "1111111111111111111111111111111111111111111111100000000000000000", 2414, ), ( "1111111000000000000000000000000000000000000000000000000000000000", 2410, ), ("111111111111111111111111111111111111", 2408), ("111111111111111111111111111111111111111111111111111", 2404), ( "1111111111111111111111111111111111111111111111111111111111111100", 2399, ), ]; let sample_median = (16140901064496103427, Some(16140901064496103487)); let sample_moment_stats = MomentStats { mean: NiceFloat(9.903368730390014e18), standard_deviation: NiceFloat(8.801310214580938e18), skewness: NiceFloat(-0.14740544458518143), excess_kurtosis: NiceFloat(-1.916675806061043), }; striped_random_positive_unsigneds_helper::( 32, 1, values, common_values, sample_median, sample_moment_stats, ); // u64, m = 2 let values = &[ "11001100011010101001011010010000011000011101011110010000000011", "11101101110011111011100001011100110100110101001011101100110011", "1111101011000111001110010011000110110101010001110111011111100", "1011100110000101000110000000111101100011100111101101111111000000", "110011001100101100000100111100101010001011010001101001000111000", "1010001101111001011010101011011000110011011110010101100100000100", "111100011000100010101011011011001000000100111011110100111011", "100100110010110010010111100011001000100110111001010000100101101", "1101100111000010011100101110010101101001100110000011111011", "1101110011101000110001100100011011100001110011100001101110001000", "1101100100110110101110000011000111010011101101101111111101111100", "1111001111110101110110010100001100001001011101001101101011101011", "111010010110111111001011100000010101010001111000010000110010001", "11010101111001000111010001011100101000010001110110001001100111", "1101011111000100111101011110111101110011010100111111100001000100", "100101000001001011001001101001011100101000110101111110111010101", "110111101110000101100101111100101101011100100010101011010100000", "101011100111011000001101010001000101111111010001100001111100011", "1111100011000100010111100101000001010110011001010100000000011", "11100111100011111000111111010010100000111110101001010111011001", ]; let common_values = &[ ("11011011101110000001110101101011110010111101", 1), ("111100000110100100110100100001100010110000010", 1), ("1011110101111010110111100110111101111101111011", 1), ("1110100010111110000100101010110100101101110111", 1), ("10111011110000001110101010110111111001011011100", 1), ("11000001010110011001100110101011001100000111111", 1), ("100100100011101001001000001010010111100010110100", 1), ("100110100101010111001000010010100111110111010110", 1), ("110110101100010110011100011100110111001111000000", 1), ("111001100010011111010011111010110100101110001000", 1), ]; let sample_median = (9232300347074497346, Some(9232359143244030439)); let sample_moment_stats = MomentStats { mean: NiceFloat(9.22650235650532e18), standard_deviation: NiceFloat(5.325785817923598e18), skewness: NiceFloat(-0.0012562071401776408), excess_kurtosis: NiceFloat(-1.1996143045434082), }; striped_random_positive_unsigneds_helper::( 2, 1, values, common_values, sample_median, sample_moment_stats, ); // u64, m = 33/32 let values = &[ "101010101010101010101011010101010101010101010101010101010101010", "101010101010101110101010110101001010101010101010010101010010101", "101010010101011010101010101010101101010101010101010101010101010", "1010101010101010100101010101010101010101010101010101010101010101", "101010101010101010101101010101010100101001010100101010101010101", "1010101010101010101010101010101011010101101010101001010101010101", "101010101010101010101010101010101010101010101101010101010101010", "101010101010110101010101010101010101010101010101010101010101010", "10101010101010101010101010101010101010101010101010101010101011", "1001010101010101010101010101010101010101010100101010101010101010", "1010101010101010101010101100101010101010110101010101010010101010", "1010011010101010101010101010101010101010101010101010101010010101", "101010101001010101010101010101010101010101010101010101010101010", "101010010110110100101010101010101010101010101010101010101010101", "1010110101010101010101010101010010101010101010101010101010101010", "101010101010101010101010101010101010101010101010101010101010101", "101010101010101010101010101010101101010101010101010101010101010", "101010101010101010101010010101010101010101010101010101010101010", "110110101001010101010010101010101010101010101010101010101010101", "101010101010010101010101010101010101010101010101010101010101010", ]; let common_values = &[ ( "101010101010101010101010101010101010101010101010101010101010101", 72208, ), ( "1010101010101010101010101010101010101010101010101010101010101010", 71633, ), ( "1010101010101010101010101010101010101010101010101010101010101001", 2387, ), ( "101010101010101010101010101010101010110101010101010101010101010", 2371, ), ( "101010101010101010101001010101010101010101010101010101010101010", 2350, ), ( "1010101010101010101010101010101010101010101010101010101010100101", 2343, ), ( "1010101010101010101010101010101001010101010101010101010101010101", 2321, ), ( "101010101010101010101010101010101010101001010101010101010101010", 2317, ), ( "1010101010101010101010101010101010101010100101010101010101010101", 2316, ), ( "1010101010101010101101010101010101010101010101010101010101010101", 2314, ), ]; let sample_median = (10184128240689698133, Some(10184139957360479594)); let sample_moment_stats = MomentStats { mean: NiceFloat(9.22742898450889e18), standard_deviation: NiceFloat(3.1984799302251884e18), skewness: NiceFloat(-0.0008313832988426654), excess_kurtosis: NiceFloat(-1.7364190763714287), }; striped_random_positive_unsigneds_helper::( 33, 32, values, common_values, sample_median, sample_moment_stats, ); } fn striped_random_positive_unsigneds_fail_helper() { assert_panic!(striped_random_positive_unsigneds::(EXAMPLE_SEED, 1, 0)); assert_panic!(striped_random_positive_unsigneds::(EXAMPLE_SEED, 2, 3)); } #[test] fn striped_random_positive_unsigneds_fail() { apply_fn_to_unsigneds!(striped_random_positive_unsigneds_fail_helper); } malachite-base-0.4.16/tests/num/random/striped/striped_random_signed_inclusive_range.rs000064400000000000000000000164511046102023000276230ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::WrappingFrom; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::striped::striped_random_signed_inclusive_range; use malachite_base::random::EXAMPLE_SEED; use malachite_base::strings::ToBinaryString; use malachite_base::test_util::stats::common_values_map::common_values_map; use malachite_base::test_util::stats::median; use malachite_base::test_util::stats::moments::{moment_stats, CheckedToF64, MomentStats}; use std::panic::catch_unwind; fn striped_random_signed_inclusive_range_helper< U: PrimitiveUnsigned + WrappingFrom, S: CheckedToF64 + PrimitiveSigned + WrappingFrom, >( a: S, b: S, m_numerator: u64, m_denominator: u64, expected_values: &[&str], expected_common_values: &[(&str, usize)], expected_sample_median: (S, Option), expected_sample_moment_stats: MomentStats, ) { let xs = striped_random_signed_inclusive_range::( EXAMPLE_SEED, a, b, m_numerator, m_denominator, ); let actual_values = xs .clone() .map(|x| x.to_binary_string()) .take(20) .collect_vec(); let actual_common_values = common_values_map(1000000, 10, xs.clone()) .iter() .map(|(x, frequency)| (x.to_binary_string(), *frequency)) .collect_vec(); let actual_sample_median = median(xs.clone().take(1000000)); let actual_sample_moment_stats = moment_stats(xs.take(1000000)); assert_eq!( ( actual_values, actual_common_values, actual_sample_median, actual_sample_moment_stats ), ( expected_values .iter() .map(ToString::to_string) .collect_vec(), expected_common_values .iter() .map(|(x, frequency)| (x.to_string(), *frequency)) .collect_vec(), expected_sample_median, expected_sample_moment_stats ) ); } #[test] fn test_striped_random_signed_inclusive_range() { // i16, 50, 200, m = 4 let values = &[ "110010", "11000000", "10100110", "110111", "111111", "11001000", "1111000", "111111", "110010", "1111111", "111110", "11000001", "111101", "110111", "11001000", "110011", "111111", "11000011", "11000000", "11000000", ]; let common_values = &[ ("11001000", 187162), ("11000000", 79165), ("111111", 78685), ("110010", 70343), ("110011", 70101), ("110111", 26718), ("111100", 26467), ("111110", 26443), ("111000", 26309), ("11000001", 26222), ]; let sample_median = (128, None); let sample_moment_stats = MomentStats { mean: NiceFloat(126.78841600000145), standard_deviation: NiceFloat(62.97286483710745), skewness: NiceFloat(-0.01241704115437865), excess_kurtosis: NiceFloat(-1.7551228249647437), }; striped_random_signed_inclusive_range_helper::( 50, 200, 4, 1, values, common_values, sample_median, sample_moment_stats, ); // i16, -200, -50, m = 4 let values = &[ "1111111111001110", "1111111101000000", "1111111101011010", "1111111111001001", "1111111111000001", "1111111100111000", "1111111110001000", "1111111111000001", "1111111111001110", "1111111110000001", "1111111111000010", "1111111100111111", "1111111111000011", "1111111111001001", "1111111100111000", "1111111111001101", "1111111111000001", "1111111100111101", "1111111101000000", "1111111101000000", ]; let common_values = &[ ("1111111100111000", 187162), ("1111111101000000", 79165), ("1111111111000001", 78685), ("1111111111001110", 70343), ("1111111111001101", 70101), ("1111111111001001", 26718), ("1111111111000100", 26467), ("1111111111000010", 26443), ("1111111111001000", 26309), ("1111111100111111", 26222), ]; let sample_median = (-128, None); let sample_moment_stats = MomentStats { mean: NiceFloat(-126.78841600000145), standard_deviation: NiceFloat(62.97286483710745), skewness: NiceFloat(0.01241704115437865), excess_kurtosis: NiceFloat(-1.7551228249647437), }; striped_random_signed_inclusive_range_helper::( -200, -50, 4, 1, values, common_values, sample_median, sample_moment_stats, ); // i16, -50, 200, m = 4 let values = &[ "1111111111001110", "1111111111001111", "11000111", "11111", "1111111111111111", "11000011", "1000000", "11000001", "1111111", "11000011", "11000100", "1111111111111111", "11001000", "1111111111010010", "1111111111110100", "1111111111011111", "1111111111111111", "1111111111001111", "1111111111111111", "1111111111010000", ]; let common_values = &[ ("1111111111001110", 93920), ("11001000", 93547), ("1111111111111111", 79262), ("1111111111010000", 70793), ("11000000", 39521), ("0", 33351), ("1111111111001111", 23264), ("1111111111111001", 19879), ("1111111111100000", 19842), ("1111111111110001", 19780), ]; let sample_median = (-1, None); let sample_moment_stats = MomentStats { mean: NiceFloat(42.632988000001404), standard_deviation: NiceFloat(91.45288785939469), skewness: NiceFloat(0.7466366203634324), excess_kurtosis: NiceFloat(-1.0394231672402725), }; striped_random_signed_inclusive_range_helper::( -50, 200, 4, 1, values, common_values, sample_median, sample_moment_stats, ); } fn striped_random_signed_inclusive_range_fail_helper< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >() { assert_panic!(striped_random_signed_inclusive_range::( EXAMPLE_SEED, S::TWO, S::ONE, 5, 1, )); assert_panic!(striped_random_signed_inclusive_range::( EXAMPLE_SEED, S::NEGATIVE_ONE, S::from(-2i8), 5, 1, )); assert_panic!(striped_random_signed_inclusive_range::( EXAMPLE_SEED, S::ONE, S::TWO, 1, 1, )); } #[test] fn striped_random_signed_inclusive_range_fail() { apply_fn_to_unsigned_signed_pairs!(striped_random_signed_inclusive_range_fail_helper); } malachite-base-0.4.16/tests/num/random/striped/striped_random_signed_range.rs000064400000000000000000000161721046102023000255420ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::WrappingFrom; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::striped::striped_random_signed_range; use malachite_base::random::EXAMPLE_SEED; use malachite_base::strings::ToBinaryString; use malachite_base::test_util::stats::common_values_map::common_values_map; use malachite_base::test_util::stats::median; use malachite_base::test_util::stats::moments::{moment_stats, CheckedToF64, MomentStats}; use std::panic::catch_unwind; fn striped_random_signed_range_helper< U: PrimitiveUnsigned + WrappingFrom, S: CheckedToF64 + PrimitiveSigned + WrappingFrom, >( a: S, b: S, m_numerator: u64, m_denominator: u64, expected_values: &[&str], expected_common_values: &[(&str, usize)], expected_sample_median: (S, Option), expected_sample_moment_stats: MomentStats, ) { let xs = striped_random_signed_range::(EXAMPLE_SEED, a, b, m_numerator, m_denominator); let actual_values = xs .clone() .map(|x| x.to_binary_string()) .take(20) .collect_vec(); let actual_common_values = common_values_map(1000000, 10, xs.clone()) .iter() .map(|(x, frequency)| (x.to_binary_string(), *frequency)) .collect_vec(); let actual_sample_median = median(xs.clone().take(1000000)); let actual_sample_moment_stats = moment_stats(xs.take(1000000)); assert_eq!( ( actual_values, actual_common_values, actual_sample_median, actual_sample_moment_stats ), ( expected_values .iter() .map(ToString::to_string) .collect_vec(), expected_common_values .iter() .map(|(x, frequency)| (x.to_string(), *frequency)) .collect_vec(), expected_sample_median, expected_sample_moment_stats ) ); } #[test] fn test_striped_random_signed_range() { // i16, 50, 201, m = 4 let values = &[ "110010", "11000000", "10100110", "110111", "111111", "11001000", "1111000", "111111", "110010", "1111111", "111110", "11000001", "111101", "110111", "11001000", "110011", "111111", "11000011", "11000000", "11000000", ]; let common_values = &[ ("11001000", 187162), ("11000000", 79165), ("111111", 78685), ("110010", 70343), ("110011", 70101), ("110111", 26718), ("111100", 26467), ("111110", 26443), ("111000", 26309), ("11000001", 26222), ]; let sample_median = (128, None); let sample_moment_stats = MomentStats { mean: NiceFloat(126.78841600000145), standard_deviation: NiceFloat(62.97286483710745), skewness: NiceFloat(-0.01241704115437865), excess_kurtosis: NiceFloat(-1.7551228249647437), }; striped_random_signed_range_helper::( 50, 201, 4, 1, values, common_values, sample_median, sample_moment_stats, ); // i16, -200, -49, m = 4 let values = &[ "1111111111001110", "1111111101000000", "1111111101011010", "1111111111001001", "1111111111000001", "1111111100111000", "1111111110001000", "1111111111000001", "1111111111001110", "1111111110000001", "1111111111000010", "1111111100111111", "1111111111000011", "1111111111001001", "1111111100111000", "1111111111001101", "1111111111000001", "1111111100111101", "1111111101000000", "1111111101000000", ]; let common_values = &[ ("1111111100111000", 187162), ("1111111101000000", 79165), ("1111111111000001", 78685), ("1111111111001110", 70343), ("1111111111001101", 70101), ("1111111111001001", 26718), ("1111111111000100", 26467), ("1111111111000010", 26443), ("1111111111001000", 26309), ("1111111100111111", 26222), ]; let sample_median = (-128, None); let sample_moment_stats = MomentStats { mean: NiceFloat(-126.78841600000145), standard_deviation: NiceFloat(62.97286483710745), skewness: NiceFloat(0.01241704115437865), excess_kurtosis: NiceFloat(-1.7551228249647437), }; striped_random_signed_range_helper::( -200, -49, 4, 1, values, common_values, sample_median, sample_moment_stats, ); // i16, -50, 201, m = 4 let values = &[ "1111111111001110", "1111111111001111", "11000111", "11111", "1111111111111111", "11000011", "1000000", "11000001", "1111111", "11000011", "11000100", "1111111111111111", "11001000", "1111111111010010", "1111111111110100", "1111111111011111", "1111111111111111", "1111111111001111", "1111111111111111", "1111111111010000", ]; let common_values = &[ ("1111111111001110", 93920), ("11001000", 93547), ("1111111111111111", 79262), ("1111111111010000", 70793), ("11000000", 39521), ("0", 33351), ("1111111111001111", 23264), ("1111111111111001", 19879), ("1111111111100000", 19842), ("1111111111110001", 19780), ]; let sample_median = (-1, None); let sample_moment_stats = MomentStats { mean: NiceFloat(42.632988000001404), standard_deviation: NiceFloat(91.45288785939469), skewness: NiceFloat(0.7466366203634324), excess_kurtosis: NiceFloat(-1.0394231672402725), }; striped_random_signed_range_helper::( -50, 201, 4, 1, values, common_values, sample_median, sample_moment_stats, ); } fn striped_random_signed_range_fail_helper< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >() { assert_panic!(striped_random_signed_range::( EXAMPLE_SEED, S::TWO, S::TWO, 5, 1, )); assert_panic!(striped_random_signed_range::( EXAMPLE_SEED, S::NEGATIVE_ONE, S::NEGATIVE_ONE, 5, 1, )); assert_panic!(striped_random_signed_range::( EXAMPLE_SEED, S::ONE, S::TWO, 1, 1, )); } #[test] fn striped_random_signed_range_fail() { apply_fn_to_unsigned_signed_pairs!(striped_random_signed_range_fail_helper); } malachite-base-0.4.16/tests/num/random/striped/striped_random_signeds.rs000064400000000000000000000347531046102023000245560ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::striped::striped_random_signeds; use malachite_base::random::EXAMPLE_SEED; use malachite_base::strings::ToBinaryString; use malachite_base::test_util::stats::common_values_map::common_values_map; use malachite_base::test_util::stats::median; use malachite_base::test_util::stats::moments::{moment_stats, CheckedToF64, MomentStats}; use std::panic::catch_unwind; fn striped_random_signeds_helper( m_numerator: u64, m_denominator: u64, expected_values: &[&str], expected_common_values: &[(&str, usize)], expected_sample_median: (T, Option), expected_sample_moment_stats: MomentStats, ) { let xs = striped_random_signeds::(EXAMPLE_SEED, m_numerator, m_denominator); let actual_values = xs .clone() .map(|x| x.to_binary_string()) .take(20) .collect_vec(); let actual_common_values = common_values_map(1000000, 10, xs.clone()) .iter() .map(|(x, frequency)| (x.to_binary_string(), *frequency)) .collect_vec(); let actual_sample_median = median(xs.clone().take(1000000)); let actual_sample_moment_stats = moment_stats(xs.take(1000000)); assert_eq!( ( actual_values, actual_common_values, actual_sample_median, actual_sample_moment_stats ), ( expected_values .iter() .map(ToString::to_string) .collect_vec(), expected_common_values .iter() .map(|(x, frequency)| (x.to_string(), *frequency)) .collect_vec(), expected_sample_median, expected_sample_moment_stats ) ); } #[test] fn test_striped_random_signeds() { // i8, m = 4 let values = &[ "1100001", "1000000", "1100000", "10000111", "1111", "10000001", "1111000", "100011", "111101", "11111100", "11111111", "11100001", "1", "101111", "10111000", "111111", "1101100", "1111110", "111100", "1", ]; let common_values = &[ ("11111111", 44563), ("1111111", 44533), ("0", 44507), ("10000000", 44366), ("11000000", 15052), ("10011111", 15027), ("111111", 15014), ("11111100", 15003), ("1111100", 14976), ("1111", 14944), ]; let sample_median = (-1, None); let sample_moment_stats = MomentStats { mean: NiceFloat(-0.4694119999999954), standard_deviation: NiceFloat(79.79176643677252), skewness: NiceFloat(0.00030165230376920274), excess_kurtosis: NiceFloat(-1.0255715724465873), }; striped_random_signeds_helper::( 4, 1, values, common_values, sample_median, sample_moment_stats, ); // i8, m = 2 let values = &[ "1110111", "1000010", "1010011", "10011100", "10110", "10000100", "1100001", "100110", "11101", "11100110", "11100000", "11111010", "11011", "101100", "10101011", "10110", "1011110", "1110101", "10001", "10100", ]; let common_values = &[ ("11010110", 4062), ("1100000", 4043), ("1100100", 4038), ("11100100", 4031), ("11000100", 4030), ("11111110", 4027), ("111110", 4027), ("11110100", 4027), ("10011000", 4026), ("1010111", 4025), ]; let sample_median = (-1, None); let sample_moment_stats = MomentStats { mean: NiceFloat(-0.5196209999999974), standard_deviation: NiceFloat(73.87620855668304), skewness: NiceFloat(0.0007310111483160227), excess_kurtosis: NiceFloat(-1.1989696073332987), }; striped_random_signeds_helper::( 2, 1, values, common_values, sample_median, sample_moment_stats, ); // i8, m = 5/4 let values = &[ "1010100", "1001010", "1101101", "10010101", "110101", "10101010", "1000010", "101001", "110110", "11011101", "11011001", "11110101", "1010", "10101", "10110101", "111010", "1101001", "1101010", "100110", "101001", ]; let common_values = &[ ("11010101", 66213), ("10101010", 65616), ("1010101", 65484), ("101010", 65183), ("10100101", 16584), ("11010010", 16518), ("1011010", 16486), ("1101010", 16481), ("110101", 16475), ("10010101", 16471), ]; let sample_median = (-5, None); let sample_moment_stats = MomentStats { mean: NiceFloat(-0.512405000000015), standard_deviation: NiceFloat(69.49166061626981), skewness: NiceFloat(0.0016729618125163213), excess_kurtosis: NiceFloat(-1.4629834926857006), }; striped_random_signeds_helper::( 5, 4, values, common_values, sample_median, sample_moment_stats, ); // i64, m = 32 let values = &[ "111000000000000000000000000000001111111111111111111111111111111", "111111111111111111111111111111111111111111111111111111111111111", "111111111111111111111111111111111100000000000000000000000000011", "1000000000000000011111111111111111111111111111111111111111111111", "111111111111111111111111111111100000000000000000000000000", "1000000000000000000000000000000001111111000000000000000000011111", "111111111111111111111000000000000000000011111111111111111111111", "111111111111111000000000010000001111111111", "1000000000000000", "1111111111001111111111111111111111111111111111111111111110000000", "1111111111111111111111111111111111111111111111111111111111111111", "1100000000000000000000000000000000000000000000000000000000000000", "11111111111111111111111111111000000000000000001111111", "111111111111111111111111111111111111111111111111111111", "1000000000000001111111100000011111111111111111111111111111000000", "111111111111111111000", "111111110000001000000000000000000000000000000000000000000000000", "111111111111111111111111111111111111111100000000000001111111111", "111111111111111111111111111111111111111", "1111111111111111111111111111111111111111111", ]; let common_values = &[ ( "1111111111111111111111111111111111111111111111111111111111111111", 35069, ), ( "1000000000000000000000000000000000000000000000000000000000000000", 34751, ), ("0", 34639), ( "111111111111111111111111111111111111111111111111111111111111111", 34560, ), ( "111111111111111111111111111111111111111111111111111000000000000", 1200, ), ( "111111111111111111100000000000000000000000000000000000000000000", 1194, ), ( "1000000000000000000000000000000000000000111111111111111111111111", 1192, ), ( "111111111111111111111110000000000000000000000000000000000000000", 1188, ), ( "1000000000000000000000000000000000000000000000000000000000000111", 1188, ), ( "1000000000000000000000000000000111111111111111111111111111111111", 1187, ), ]; let sample_median = (-1, None); let sample_moment_stats = MomentStats { mean: NiceFloat(1478194767948927.5), standard_deviation: NiceFloat(6.390112936152263e18), skewness: NiceFloat(-0.00034103406624165104), excess_kurtosis: NiceFloat(-0.9868005073632049), }; striped_random_signeds_helper::( 32, 1, values, common_values, sample_median, sample_moment_stats, ); // i64, m = 2 let values = &[ "111011100001010110001110001011000010001111010011001110110011001", "111111110100110110100110101000101101000011101011011100101000100", "110111111101001101101001110111101010101111111011100100000100111", "1000110000101001011011100011110101111000101110000001001010011110", "1111111001111100000101110010111000110111101100000010010000110", "1011101011101000100100010110110000010100100110010000101111101011", "110111111011000111010100010011001001010111010010000110110001011", "1110111111011000100010000110111111011111000110110100101011011", "11001110010100010000000011111011101000011001110000011101001011", "1111111000011000100101100000001111001100100011111000000011001110", "1101011111111010011011100100011000000100001100111000011000011010", "1101101001110110010110110101111101111010001011011100001000011111", "1101110000100110011011100110000000011010100111111110001010", "1011001000101100011000110011000001110001101010111010010000100", "1000111011101001000111101001100000111100100111100111001010111100", "11101000100000101100011100101110111000100010100001001101110000", "110100010100010101000011000111011101000100100100011111010000011", "100000011111110101100111000100100111101101110010011101110110001", "10100101100000110010110100110100011010011101101100010", "10111110011011000011000011001010101000101001100001001000000110", ]; let common_values = &[ ("1000001000001111111111101100101100110101100101", 1), ("1101011110010101110000100010110110000010001101", 1), ("1101111000110100001101000000011011000101001001", 1), ("1111000011101100001000100110000111101110100011", 1), ("10011000001111100110100111011000010001100001111", 1), ( "1111111111111111101111101000011101000100001010110001100101110110", 1, ), ( "1111111111111111101011111111000001110100011010010001100100101000", 1, ), ("11010000001000101001101001110011011011010000011", 1), ("11101111110000011100000111100110000000001011010", 1), ("100011011110110010100010110100001001100100001000", 1), ]; let sample_median = (-8123231271792388, Some(-8096687505746509)); let sample_moment_stats = MomentStats { mean: NiceFloat(91581052023966.92), standard_deviation: NiceFloat(5.31973124263762e18), skewness: NiceFloat(0.0012453230455855707), excess_kurtosis: NiceFloat(-1.1981323295909574), }; striped_random_signeds_helper::( 2, 1, values, common_values, sample_median, sample_moment_stats, ); // i64, m = 33/32 let values = &[ "101010100101010101010101010101010101010101010101010101010101010", "101010101010101010101010101010110101010101010101010101010101010", "101010100101010101010101010101010101010101010101010101010101010", "1010101010010101010101010101010101010101010101010101010101010110", "11010101010101010101010101010101010101010101010101010101011010", "1010101010101010101010101011010100101010101010101010100101010101", "101010110101010101010101010101010101010101010101010101010101010", "10101010101010101010101001010101010101010101010101010101010101", "10101010101010101010101010101010101010101010101001101010101010", "1101010101010101010101010101010101010011010101101010101010101010", "1101010101010101011010101010101010101010101010101010101010101010", "1101010101010101010101010101010101010101010101010101010101010101", "10101010101010101010101010101010101010101010101010101010101010", "10101010101010101010101010101010101010101010101010101010101010", "1010101010101010101010101010101010101010101010101011010101010101", "10100101010101010101010101010101010101010101010101010101010101", "101001010101010101010101010101010101010101010101010101010101101", "101010101010101010111010101010110101010101010101010101010101010", "10101010101101010101010101010101010101010101010101010101010101", "10101010101010101010101101010010101010110101010101101010101010", ]; let common_values = &[ ( "101010101010101010101010101010101010101010101010101010101010101", 37342, ), ( "10101010101010101010101010101010101010101010101010101010101010", 37241, ), ( "1101010101010101010101010101010101010101010101010101010101010101", 37189, ), ( "1010101010101010101010101010101010101010101010101010101010101010", 37109, ), ( "1010101010101010101010101010101010101001010101010101010101010101", 1241, ), ( "1101010101010101010101010101010101010110101010101010101010101010", 1239, ), ( "10101010101010101010101010101010101010101010101010101010100101", 1235, ), ( "1010101010101010101010101010101010101011010101010101010101010101", 1233, ), ( "1101011010101010101010101010101010101010101010101010101010101010", 1231, ), ( "1101010101010101010101010101010101010101010101010101010101010010", 1227, ), ]; let sample_median = (-1489184412743849302, Some(-1489184412721829206)); let sample_moment_stats = MomentStats { mean: NiceFloat(-2366723010422570.0), standard_deviation: NiceFloat(4.878981868385203e18), skewness: NiceFloat(0.0014056588570288651), excess_kurtosis: NiceFloat(-1.6132504884076841), }; striped_random_signeds_helper::( 33, 32, values, common_values, sample_median, sample_moment_stats, ); } fn striped_random_signeds_fail_helper() { assert_panic!(striped_random_signeds::(EXAMPLE_SEED, 1, 0)); assert_panic!(striped_random_signeds::(EXAMPLE_SEED, 2, 3)); } #[test] fn striped_random_signeds_fail() { apply_fn_to_signeds!(striped_random_signeds_fail_helper); } malachite-base-0.4.16/tests/num/random/striped/striped_random_unsigned_bit_chunks.rs000064400000000000000000000243161046102023000271410ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::striped::striped_random_unsigned_bit_chunks; use malachite_base::random::EXAMPLE_SEED; use malachite_base::strings::ToBinaryString; use malachite_base::test_util::stats::common_values_map::common_values_map; use malachite_base::test_util::stats::median; use malachite_base::test_util::stats::moments::{moment_stats, CheckedToF64, MomentStats}; use std::panic::catch_unwind; fn striped_random_unsigned_bit_chunks_helper( chunk_size: u64, m_numerator: u64, m_denominator: u64, expected_values: &[&str], expected_common_values: &[(&str, usize)], expected_sample_median: (T, Option), expected_sample_moment_stats: MomentStats, ) { let xs = striped_random_unsigned_bit_chunks::( EXAMPLE_SEED, chunk_size, m_numerator, m_denominator, ); let actual_values = xs .clone() .map(|x| x.to_binary_string()) .take(20) .collect_vec(); let actual_common_values = common_values_map(1000000, 10, xs.clone()) .iter() .map(|(x, frequency)| (x.to_binary_string(), *frequency)) .collect_vec(); let actual_sample_median = median(xs.clone().take(1000000)); let actual_sample_moment_stats = moment_stats(xs.take(1000000)); assert_eq!( ( actual_values, actual_common_values, actual_sample_median, actual_sample_moment_stats ), ( expected_values .iter() .map(ToString::to_string) .collect_vec(), expected_common_values .iter() .map(|(x, frequency)| (x.to_string(), *frequency)) .collect_vec(), expected_sample_median, expected_sample_moment_stats ) ); } #[test] fn test_striped_random_unsigned_bit_chunks() { // u8, chunk_size = 0, m = 4 let values = &["0"; 20]; let common_values = &[("0", 1000000)]; let sample_median = (0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(0.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; striped_random_unsigned_bit_chunks_helper::( 0, 4, 1, values, common_values, sample_median, sample_moment_stats, ); // u8, chunk_size = 3, m = 4 let values = &[ "0", "0", "0", "101", "11", "100", "11", "11", "0", "111", "111", "100", "0", "11", "111", "0", "0", "1", "0", "0", ]; let common_values = &[ ("111", 281415), ("0", 280832), ("110", 94370), ("11", 93804), ("100", 93374), ("1", 93351), ("10", 31559), ("101", 31295), ]; let sample_median = (4, None); let sample_moment_stats = MomentStats { mean: NiceFloat(3.5039770000000354), standard_deviation: NiceFloat(2.8721055747415143), skewness: NiceFloat(-0.0024668908296986798), excess_kurtosis: NiceFloat(-1.6474519863189017), }; striped_random_unsigned_bit_chunks_helper::( 3, 4, 1, values, common_values, sample_median, sample_moment_stats, ); // chunk_size = 1, u8, m = 2 let values = &[ "0", "0", "0", "1", "0", "1", "0", "0", "0", "1", "1", "1", "0", "0", "1", "0", "0", "0", "0", "0", ]; let common_values = &[("1", 500454), ("0", 499546)]; let sample_median = (1, None); let sample_moment_stats = MomentStats { mean: NiceFloat(0.500454000000004), standard_deviation: NiceFloat(0.5000000438840368), skewness: NiceFloat(-0.0018160007486136712), excess_kurtosis: NiceFloat(-1.9999967021412284), }; striped_random_unsigned_bit_chunks_helper::( 1, 2, 1, values, common_values, sample_median, sample_moment_stats, ); // chunk_size = 6, u8, m = 5/4 let values = &[ "10100", "10110", "10100", "100110", "10010", "101101", "10101", "10001", "10101", "101001", "101101", "101010", "11011", "1101", "100001", "11110", "111", "101", "10110", "10010", ]; let common_values = &[ ("101010", 164180), ("10101", 164004), ("101011", 41169), ("101101", 41127), ("10010", 41114), ("100101", 40919), ("1010", 40893), ("110101", 40851), ("10110", 40844), ("101001", 40812), ]; let sample_median = (32, None); let sample_moment_stats = MomentStats { mean: NiceFloat(31.51096499999948), standard_deviation: NiceFloat(13.555827954398234), skewness: NiceFloat(-0.0016679039370573313), excess_kurtosis: NiceFloat(-1.0970963271830174), }; striped_random_unsigned_bit_chunks_helper::( 6, 5, 4, values, common_values, sample_median, sample_moment_stats, ); // chunk_size = 45, u64, m = 32 let values = &[ "11111111111", "111111111111111111111", "0", "111111111111111111111111111000000000000000000", "111111111", "111111111111111111111111111111111100000000000", "0", "1111111111111111111111111111111111", "1100000000111111111111111111111111111111", "111111111111111111100000000000000011111111111", "111111111111111111111111111111111111111100000", "111111111111111111111111111111111111111111111", "11111111111111111111111111", "1111111", "111111111111111110000000000000000000000000000", "11111111111111", "0", "11111111111111111111111111111", "11111111111111111111111111111111111111111111", "1000000011111111111111111111111110000000", ]; let common_values = &[ ("0", 123843), ("111111111111111111111111111111111111111111111", 123659), ("111111111111111100000000000000000000000000000", 4110), ("111111110000000000000000000000000000000000000", 4093), ("111111111111111111111111111111111", 4092), ("1111111111111111111111111111111111", 4081), ("11111111111111111111111111111111111111", 4078), ("1111111", 4072), ("111111111111111111111000000000000000000000000", 4057), ("111111111111111111111111111111111111111110000", 4051), ]; let sample_median = (17592186044416, None); let sample_moment_stats = MomentStats { mean: NiceFloat(17607908125347.086), standard_deviation: NiceFloat(16886338134364.322), skewness: NiceFloat(-0.0018748788166730555), excess_kurtosis: NiceFloat(-1.9429442153094645), }; striped_random_unsigned_bit_chunks_helper::( 45, 32, 1, values, common_values, sample_median, sample_moment_stats, ); // chunk_size = 4, u64, m = 2 let values = &[ "11", "110", "11", "1100", "101", "1010", "110", "100", "101", "1101", "1111", "1100", "111", "11", "1101", "100", "1", "10", "0", "0", ]; let common_values = &[ ("1110", 62873), ("1010", 62820), ("1000", 62739), ("100", 62694), ("1001", 62689), ("110", 62619), ("1011", 62601), ("11", 62507), ("1100", 62467), ("101", 62457), ]; let sample_median = (8, None); let sample_moment_stats = MomentStats { mean: NiceFloat(7.5009610000000775), standard_deviation: NiceFloat(4.606733799393635), skewness: NiceFloat(-0.0007329768450960305), excess_kurtosis: NiceFloat(-1.20818908668768), }; striped_random_unsigned_bit_chunks_helper::( 4, 2, 1, values, common_values, sample_median, sample_moment_stats, ); // chunk_size = 10, u64, m = 33/32 let values = &[ "101010101", "101010101", "101011010", "1010101010", "101010101", "1010101010", "101010101", "101010101", "101010001", "1010101001", "1010110101", "1010101010", "101101010", "101101010", "1010101101", "101011010", "101010101", "101010010", "101010101", "101010101", ]; let common_values = &[ ("1010101010", 379066), ("101010101", 378152), ("1010110101", 12071), ("101011010", 12069), ("101001010", 12042), ("1011010101", 11977), ("101010110", 11960), ("1001010101", 11941), ("1010010101", 11934), ("100101010", 11903), ]; let sample_median = (565, None); let sample_moment_stats = MomentStats { mean: NiceFloat(511.639053000003), standard_deviation: NiceFloat(177.48758065877436), skewness: NiceFloat(-0.0017256448985827214), excess_kurtosis: NiceFloat(-1.734924505103183), }; striped_random_unsigned_bit_chunks_helper::( 10, 33, 32, values, common_values, sample_median, sample_moment_stats, ); } fn striped_random_unsigned_bit_chunks_fail_helper() { assert_panic!(striped_random_unsigned_bit_chunks::( EXAMPLE_SEED, 4, 1, 0 )); assert_panic!(striped_random_unsigned_bit_chunks::( EXAMPLE_SEED, 4, 2, 3 )); assert_panic!(striped_random_unsigned_bit_chunks::( EXAMPLE_SEED, 200, 4, 1 )); } #[test] fn striped_random_unsigned_bit_chunks_fail() { apply_fn_to_unsigneds!(striped_random_unsigned_bit_chunks_fail_helper); } malachite-base-0.4.16/tests/num/random/striped/striped_random_unsigned_inclusive_range.rs000064400000000000000000000151711046102023000301640ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::striped::striped_random_unsigned_inclusive_range; use malachite_base::random::EXAMPLE_SEED; use malachite_base::strings::ToBinaryString; use malachite_base::test_util::stats::common_values_map::common_values_map; use malachite_base::test_util::stats::median; use malachite_base::test_util::stats::moments::{moment_stats, CheckedToF64, MomentStats}; use std::panic::catch_unwind; fn striped_random_unsigned_inclusive_range_helper( a: T, b: T, m_numerator: u64, m_denominator: u64, expected_values: &[&str], expected_common_values: &[(&str, usize)], expected_sample_median: (T, Option), expected_sample_moment_stats: MomentStats, ) { let xs = striped_random_unsigned_inclusive_range::( EXAMPLE_SEED, a, b, m_numerator, m_denominator, ); let actual_values = xs .clone() .map(|x| x.to_binary_string()) .take(20) .collect_vec(); let actual_common_values = common_values_map(1000000, 10, xs.clone()) .iter() .map(|(x, frequency)| (x.to_binary_string(), *frequency)) .collect_vec(); let actual_sample_median = median(xs.clone().take(1000000)); let actual_sample_moment_stats = moment_stats(xs.take(1000000)); assert_eq!( ( actual_values, actual_common_values, actual_sample_median, actual_sample_moment_stats ), ( expected_values .iter() .map(ToString::to_string) .collect_vec(), expected_common_values .iter() .map(|(x, frequency)| (x.to_string(), *frequency)) .collect_vec(), expected_sample_median, expected_sample_moment_stats ) ); } #[test] fn test_striped_random_unsigned_inclusive_range() { // u8, 5, 5, m = 4 let values = &["101"; 20]; let common_values = &[("101", 1000000)]; let sample_median = (5, None); let sample_moment_stats = MomentStats { mean: NiceFloat(5.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; striped_random_unsigned_inclusive_range_helper::( 5, 5, 4, 1, values, common_values, sample_median, sample_moment_stats, ); // u8, 0, 7, m = 4 let values = &[ "0", "0", "0", "101", "11", "100", "11", "11", "0", "111", "111", "100", "0", "11", "111", "0", "0", "1", "0", "0", ]; let common_values = &[ ("111", 281415), ("0", 280832), ("110", 94370), ("11", 93804), ("100", 93374), ("1", 93351), ("10", 31559), ("101", 31295), ]; let sample_median = (4, None); let sample_moment_stats = MomentStats { mean: NiceFloat(3.5039770000000354), standard_deviation: NiceFloat(2.8721055747415143), skewness: NiceFloat(-0.0024668908296986798), excess_kurtosis: NiceFloat(-1.6474519863189017), }; striped_random_unsigned_inclusive_range_helper::( 0, 7, 4, 1, values, common_values, sample_median, sample_moment_stats, ); // u8, 1, 6, m = 4 let values = &[ "1", "1", "1", "110", "1", "110", "10", "11", "11", "100", "100", "110", "1", "1", "110", "1", "1", "11", "1", "1", ]; let common_values = &[ ("110", 375034), ("1", 374765), ("100", 93832), ("11", 93634), ("101", 31588), ("10", 31147), ]; let sample_median = (4, None); let sample_moment_stats = MomentStats { mean: NiceFloat(3.5014329999999694), standard_deviation: NiceFloat(2.207774177939804), skewness: NiceFloat(-0.0014160236801414635), excess_kurtosis: NiceFloat(-1.753353488243057), }; striped_random_unsigned_inclusive_range_helper::( 1, 6, 4, 1, values, common_values, sample_median, sample_moment_stats, ); // u16, 10000, 20000, m = 4 let values = &[ "10011100011111", "11010011001111", "10011100011100", "100111000011111", "11111100000000", "10011100111100", "10011110110000", "100000000000111", "11111111111111", "10101111001111", "100111000000000", "11000000000111", "11111111000000", "100000000001111", "100000000101100", "100011110000000", "100100011110010", "100011000000111", "100110111111111", "11111111110100", ]; let common_values = &[ ("100111000100000", 70337), ("100111000000000", 16785), ("10011111111111", 12552), ("10011100010000", 11029), ("10011100011111", 11017), ("100000000000000", 10528), ("11111111111111", 8012), ("100111000000111", 5466), ("100111000000001", 5462), ("100111000001111", 5448), ]; let sample_median = (16383, None); let sample_moment_stats = MomentStats { mean: NiceFloat(15546.241523000184), standard_deviation: NiceFloat(3460.441923849274), skewness: NiceFloat(-0.39481033379336405), excess_kurtosis: NiceFloat(-1.1600583805474893), }; striped_random_unsigned_inclusive_range_helper::( 10000, 20000, 4, 1, values, common_values, sample_median, sample_moment_stats, ); } fn striped_random_unsigned_inclusive_range_fail_helper() { assert_panic!(striped_random_unsigned_inclusive_range::( EXAMPLE_SEED, T::TWO, T::ONE, 5, 1, )); assert_panic!(striped_random_unsigned_inclusive_range::( EXAMPLE_SEED, T::ONE, T::TWO, 1, 1, )); } #[test] fn striped_random_unsigned_inclusive_range_fail() { apply_fn_to_unsigneds!(striped_random_unsigned_inclusive_range_fail_helper); } malachite-base-0.4.16/tests/num/random/striped/striped_random_unsigned_range.rs000064400000000000000000000147101046102023000261010ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::striped::striped_random_unsigned_range; use malachite_base::random::EXAMPLE_SEED; use malachite_base::strings::ToBinaryString; use malachite_base::test_util::stats::common_values_map::common_values_map; use malachite_base::test_util::stats::median; use malachite_base::test_util::stats::moments::{moment_stats, CheckedToF64, MomentStats}; use std::panic::catch_unwind; fn striped_random_unsigned_range_helper( a: T, b: T, m_numerator: u64, m_denominator: u64, expected_values: &[&str], expected_common_values: &[(&str, usize)], expected_sample_median: (T, Option), expected_sample_moment_stats: MomentStats, ) { let xs = striped_random_unsigned_range::(EXAMPLE_SEED, a, b, m_numerator, m_denominator); let actual_values = xs .clone() .map(|x| x.to_binary_string()) .take(20) .collect_vec(); let actual_common_values = common_values_map(1000000, 10, xs.clone()) .iter() .map(|(x, frequency)| (x.to_binary_string(), *frequency)) .collect_vec(); let actual_sample_median = median(xs.clone().take(1000000)); let actual_sample_moment_stats = moment_stats(xs.take(1000000)); assert_eq!( ( actual_values, actual_common_values, actual_sample_median, actual_sample_moment_stats ), ( expected_values .iter() .map(ToString::to_string) .collect_vec(), expected_common_values .iter() .map(|(x, frequency)| (x.to_string(), *frequency)) .collect_vec(), expected_sample_median, expected_sample_moment_stats ) ); } #[test] fn test_striped_random_unsigned_range() { // u8, 5, 6, m = 4 let values = &["101"; 20]; let common_values = &[("101", 1000000)]; let sample_median = (5, None); let sample_moment_stats = MomentStats { mean: NiceFloat(5.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; striped_random_unsigned_range_helper::( 5, 6, 4, 1, values, common_values, sample_median, sample_moment_stats, ); // u8, 0, 8, m = 4 let values = &[ "0", "0", "0", "101", "11", "100", "11", "11", "0", "111", "111", "100", "0", "11", "111", "0", "0", "1", "0", "0", ]; let common_values = &[ ("111", 281415), ("0", 280832), ("110", 94370), ("11", 93804), ("100", 93374), ("1", 93351), ("10", 31559), ("101", 31295), ]; let sample_median = (4, None); let sample_moment_stats = MomentStats { mean: NiceFloat(3.5039770000000354), standard_deviation: NiceFloat(2.8721055747415143), skewness: NiceFloat(-0.0024668908296986798), excess_kurtosis: NiceFloat(-1.6474519863189017), }; striped_random_unsigned_range_helper::( 0, 8, 4, 1, values, common_values, sample_median, sample_moment_stats, ); // u8, 1, 7, m = 4 let values = &[ "1", "1", "1", "110", "1", "110", "10", "11", "11", "100", "100", "110", "1", "1", "110", "1", "1", "11", "1", "1", ]; let common_values = &[ ("110", 375034), ("1", 374765), ("100", 93832), ("11", 93634), ("101", 31588), ("10", 31147), ]; let sample_median = (4, None); let sample_moment_stats = MomentStats { mean: NiceFloat(3.5014329999999694), standard_deviation: NiceFloat(2.207774177939804), skewness: NiceFloat(-0.0014160236801414635), excess_kurtosis: NiceFloat(-1.753353488243057), }; striped_random_unsigned_range_helper::( 1, 7, 4, 1, values, common_values, sample_median, sample_moment_stats, ); // u16, 10000, 20001, m = 4 let values = &[ "10011100011111", "11010011001111", "10011100011100", "100111000011111", "11111100000000", "10011100111100", "10011110110000", "100000000000111", "11111111111111", "10101111001111", "100111000000000", "11000000000111", "11111111000000", "100000000001111", "100000000101100", "100011110000000", "100100011110010", "100011000000111", "100110111111111", "11111111110100", ]; let common_values = &[ ("100111000100000", 70337), ("100111000000000", 16785), ("10011111111111", 12552), ("10011100010000", 11029), ("10011100011111", 11017), ("100000000000000", 10528), ("11111111111111", 8012), ("100111000000111", 5466), ("100111000000001", 5462), ("100111000001111", 5448), ]; let sample_median = (16383, None); let sample_moment_stats = MomentStats { mean: NiceFloat(15546.241523000184), standard_deviation: NiceFloat(3460.441923849274), skewness: NiceFloat(-0.39481033379336405), excess_kurtosis: NiceFloat(-1.1600583805474893), }; striped_random_unsigned_range_helper::( 10000, 20001, 4, 1, values, common_values, sample_median, sample_moment_stats, ); } fn striped_random_unsigned_range_fail_helper() { assert_panic!(striped_random_unsigned_range::( EXAMPLE_SEED, T::TWO, T::TWO, 5, 1, )); assert_panic!(striped_random_unsigned_range::( EXAMPLE_SEED, T::ONE, T::TWO, 1, 1, )); } #[test] fn striped_random_unsigned_range_fail() { apply_fn_to_unsigneds!(striped_random_unsigned_range_fail_helper); } malachite-base-0.4.16/tests/num/random/striped/striped_random_unsigned_vecs.rs000064400000000000000000000220621046102023000257440ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::random::striped::striped_random_unsigned_vecs; use malachite_base::random::EXAMPLE_SEED; use malachite_base::strings::ToBinaryString; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; fn striped_random_unsigned_vecs_helper( mean_stripe_numerator: u64, mean_stripe_denominator: u64, mean_length_numerator: u64, mean_length_denominator: u64, expected_values: &[&[&str]], expected_common_values: &[(&[&str], usize)], expected_median: (&[&str], Option<&[&str]>), ) { let xss = striped_random_unsigned_vecs::( EXAMPLE_SEED, mean_stripe_numerator, mean_stripe_denominator, mean_length_numerator, mean_length_denominator, ); let values = xss .clone() .take(20) .map(|xs| { xs.into_iter() .map(|x: T| x.to_binary_string()) .collect_vec() }) .collect_vec(); let common_values = common_values_map_debug(1000000, 10, xss.clone()) .into_iter() .map(|(xs, freq)| { ( xs.into_iter() .map(|x: T| x.to_binary_string()) .collect_vec(), freq, ) }) .collect_vec(); let (median_lo, median_hi) = median(xss.take(1000000)); let median_lo = median_lo .into_iter() .map(|x: T| x.to_binary_string()) .collect_vec(); let median_hi = median_hi.map(|xs| { xs.into_iter() .map(|x: T| x.to_binary_string()) .collect_vec() }); let values = values .iter() .map(|xs| xs.iter().map(String::as_str).collect_vec()) .collect_vec(); let common_values = common_values .iter() .map(|(xs, freq)| (xs.iter().map(String::as_str).collect_vec(), *freq)) .collect_vec(); let median_lo = median_lo.iter().map(String::as_str).collect_vec(); let median_hi = median_hi .as_ref() .map(|xs| xs.iter().map(String::as_str).collect_vec()); assert_eq!( ( values.iter().map(Vec::as_slice).collect_vec().as_slice(), common_values .iter() .map(|(xs, f)| (xs.as_slice(), *f)) .collect_vec() .as_slice(), (median_lo.as_slice(), median_hi.as_deref()) ), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_striped_random_unsigned_vecs() { striped_random_unsigned_vecs_helper::( 2, 1, 4, 1, &[ &[], &[ "11001100", "11000", "11001", "10111101", "10111110", "110000", "11010011", "11", "1110110", "11100011", "1", "1100101", "10111110", "11010111", ], &["101110", "1111000", "10110010", "11101110"], &["10110110", "11000010", "11111010", "1100110"], &["1000"], &[], &["10100000", "100101", "1000010", "1100110", "11000111"], &["111", "11100001"], &["1010110", "10101110", "10111000", "10111101"], &[], &["101011", "10", "1110101", "1110001", "11101111", "10001001"], &[], &[], &[ "10000100", "11110101", "11011100", "10011111", "10001000", "11001111", "1111000", "11010111", "1101001", "111110", "1100100", ], &[ "10101", "11011001", "10100000", "10100001", "1101100", "1101111", "10100011", "11110101", ], &[], &["10111111", "100111", "1111110"], &[], &["11000", "11110010", "11111", "1110011", "11110011"], &[ "10001110", "10011", "1100101", "111100", "10110111", "1101110", "100001", "10000000", "10101100", ], ], &[ (&[], 199913), (&["11010010"], 689), (&["11"], 688), (&["11110111"], 681), (&["10000110"], 673), (&["110010"], 672), (&["11101111"], 671), (&["1000100"], 670), (&["1111101"], 670), (&["11110010"], 670), ], (&["1100000"], None), ); striped_random_unsigned_vecs_helper::( 10, 1, 4, 1, &[ &[], &[ "0", "0", "111000", "0", "11111110", "10000001", "11111111", "11", "0", "0", "0", "11111111", "11111111", "11111", ], &["11110000", "11111111", "11111101", "1111111"], &["0", "0", "11100000", "1"], &["11111110"], &[], &["0", "0", "10011000", "11111111", "111"], &["11111111", "11111111"], &["0", "0", "0", "0"], &[], &["11111111", "11111110", "11111111", "11111111", "11111", "0"], &[], &[], &[ "0", "0", "0", "0", "11111100", "111011", "0", "1111000", "111", "1101000", "11011111", ], &[ "11111111", "11111111", "11111111", "11111", "11000000", "11", "11001000", "11111111", ], &[], &["1", "11100000", "11111111"], &[], &["1000", "0", "0", "11111111", "1111"], &["0", "10000000", "111", "10000000", "111111", "0", "0", "11111000", "11111111"], ], &[ (&[], 199913), (&["0"], 38129), (&["11111111"], 38051), (&["0", "0"], 13204), (&["11111111", "11111111"], 13153), (&["0", "0", "0"], 4662), (&["11111111", "11111111", "11111111"], 4549), (&["1"], 4369), (&["11111100"], 4338), (&["11111"], 4311), ], (&["11100", "11111110", "111111", "0"], None), ); striped_random_unsigned_vecs_helper::( 11, 10, 4, 1, &[ &[], &[ "1011010", "11010101", "1001010", "10110101", "11010110", "10101010", "10101010", "1101010", "10100101", "10101010", "10011010", "1010010", "1010101", "1010101", ], &["10101010", "1010110", "101011", "1010101"], &["1010100", "1010101", "1010101", "10101010"], &["1101010"], &[], &["1001010", "1010101", "1010101", "1010101", "1001001"], &["10101011", "10101010"], &["10101010", "10101101", "10101010", "1011010"], &[], &["10101011", "10101010", "10101010", "11010", "11010", "1010111"], &[], &[], &[ "10101010", "1001011", "11010101", "1010010", "1010101", "10101010", "101010", "1010101", "10101001", "1101010", "1010101", ], &[ "1010101", "1010101", "1010101", "10110101", "10100100", "10110100", "10101010", "10101010", ], &[], &["1010101", "10100101", "10101010"], &[], &["10101010", "1010100", "1101010", "10100101", "1001010"], &[ "10101100", "10101010", "10101010", "10010101", "10101010", "10101101", "10101010", "1001010", "1010101", ], ], &[ (&[], 199913), (&["1010101"], 41088), (&["10101010"], 40900), (&["1010101", "1010101"], 15274), (&["10101010", "10101010"], 15212), (&["10101010", "10101010", "10101010"], 5901), (&["1010101", "1010101", "1010101"], 5641), (&["10101001"], 4206), (&["10100101"], 4201), (&["10101101"], 4181), ], (&["1010101", "10110101"], None), ); } #[test] #[should_panic] fn striped_random_unsigned_vecs_fail_1() { striped_random_unsigned_vecs::(EXAMPLE_SEED, 1, 0, 4, 1); } #[test] #[should_panic] fn striped_random_unsigned_vecs_fail_2() { striped_random_unsigned_vecs::(EXAMPLE_SEED, 2, 3, 4, 1); } #[test] #[should_panic] fn striped_random_unsigned_vecs_fail_3() { striped_random_unsigned_vecs::(EXAMPLE_SEED, 4, 1, 0, 1); } #[test] #[should_panic] fn striped_random_unsigned_vecs_fail_4() { striped_random_unsigned_vecs::(EXAMPLE_SEED, 4, 1, 1, 0); } #[test] #[should_panic] fn striped_random_unsigned_vecs_fail_5() { striped_random_unsigned_vecs::(EXAMPLE_SEED, 4, 1, u64::MAX, u64::MAX - 1); } malachite-base-0.4.16/tests/num/random/striped/striped_random_unsigned_vecs_from_length_iterator.rs000064400000000000000000000371731046102023000322520ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::random::geometric::geometric_random_unsigneds; use malachite_base::num::random::striped::striped_random_unsigned_vecs_from_length_iterator; use malachite_base::random::{Seed, EXAMPLE_SEED}; use malachite_base::strings::ToBinaryString; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; use malachite_base::vecs::random_values_from_vec; use std::iter::repeat; fn striped_random_unsigned_vecs_from_length_iterator_helper< T: PrimitiveUnsigned, I: Clone + Iterator, >( lengths_gen: &dyn Fn(Seed) -> I, mean_stripe_numerator: u64, mean_stripe_denominator: u64, expected_values: &[&[&str]], expected_common_values: &[(&[&str], usize)], expected_median: (&[&str], Option<&[&str]>), ) { let xss = striped_random_unsigned_vecs_from_length_iterator::( EXAMPLE_SEED, lengths_gen, mean_stripe_numerator, mean_stripe_denominator, ); let values = xss .clone() .take(20) .map(|xs| { xs.into_iter() .map(|x: T| x.to_binary_string()) .collect_vec() }) .collect_vec(); let common_values = common_values_map_debug(1000000, 10, xss.clone()) .into_iter() .map(|(xs, freq)| { ( xs.into_iter() .map(|x: T| x.to_binary_string()) .collect_vec(), freq, ) }) .collect_vec(); let (median_lo, median_hi) = median(xss.take(1000000)); let median_lo = median_lo .into_iter() .map(|x: T| x.to_binary_string()) .collect_vec(); let median_hi = median_hi.map(|xs| { xs.into_iter() .map(|x: T| x.to_binary_string()) .collect_vec() }); let values = values .iter() .map(|xs| xs.iter().map(String::as_str).collect_vec()) .collect_vec(); let common_values = common_values .iter() .map(|(xs, freq)| (xs.iter().map(String::as_str).collect_vec(), *freq)) .collect_vec(); let median_lo = median_lo.iter().map(String::as_str).collect_vec(); let median_hi = median_hi .as_ref() .map(|xs| xs.iter().map(String::as_str).collect_vec()); assert_eq!( ( values.iter().map(Vec::as_slice).collect_vec().as_slice(), common_values .iter() .map(|(xs, f)| (xs.as_slice(), *f)) .collect_vec() .as_slice(), (median_lo.as_slice(), median_hi.as_deref()) ), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_striped_random_unsigned_vecs_from_length_iterator() { striped_random_unsigned_vecs_from_length_iterator_helper::( &|seed| random_values_from_vec(seed, vec![0, 2, 4]), 2, 1, &[ &["11001100", "11000"], &["110010", "1111010", "1111101", "1100001"], &["1001100", "1111"], &["10110000", "11011", "1111", "101000"], &["11100110", "1111011", "10001101", "111110"], &["100111", "11101011"], &[], &["1100010", "101011"], &[], &["10100111", "100000", "1110011", "11111111"], &["1011010", "100010", "1100100", "1110110"], &["10000111", "11101111"], &["1100011", "11100101", "10001010", "11011011"], &["1001000", "11011101"], &["10100000", "101110", "11101110", "111101"], &["1100010", "1001111", "1100001", "100"], &["100111", "11100010", "110011", "11011110"], &[], &["10100", "11001011", "11100000", "1001101"], &[], ], &[ (&[], 333820), (&["11110010", "1100111"], 17), (&["10010101", "101"], 16), (&["11010100", "1100001"], 16), (&["1111101", "11100000"], 16), (&["11111111", "1111000"], 16), (&["101100", "110101"], 15), (&["1010111", "1010000"], 15), (&["10101", "1111110"], 15), (&["11110111", "10000"], 15), ], ( &["111111", "11110001", "11111010", "10100110"], Some(&["111111", "11110010"]), ), ); striped_random_unsigned_vecs_from_length_iterator_helper::( &|seed| random_values_from_vec(seed, vec![0, 2, 4]), 10, 1, &[ &["0", "0"], &["1110000", "0", "11111100", "11"], &["11111110", "1111"], &["0", "0", "0", "11111000"], &["0", "0", "1111110", "0"], &["11011111", "11111111"], &[], &["11110000", "11111111"], &[], &["11111111", "11000011", "11111", "0"], &["0", "10000000", "11111001", "1111111"], &["11111111", "11111111"], &["11111111", "11111111", "11111111", "11111111"], &["0", "10000"], &["0", "0", "0", "11111100"], &["0", "0", "0", "0"], &["11111111", "0", "11110001", "11111111"], &[], &["10111100", "11", "10110100", "11101111"], &[], ], &[ (&[], 333820), (&["11111111", "11111111"], 34254), (&["0", "0"], 34215), (&["11111111", "11111111", "11111111", "11111111"], 6413), (&["0", "0", "0", "0"], 6336), (&["11111111", "11111"], 3951), (&["111111", "0"], 3891), (&["11111110", "11111111"], 3890), (&["11111111", "0"], 3889), (&["11111111", "1111"], 3878), ], (&["1", "0", "11111110", "11111111"], None), ); striped_random_unsigned_vecs_from_length_iterator_helper::( &|seed| random_values_from_vec(seed, vec![0, 2, 4]), 11, 10, &[ &["1011010", "11010101"], &["1101010", "10010101", "1010010", "10101010"], &["10101010", "10101010"], &["11010100", "10101010", "101010", "1101011"], &["10101010", "10101010", "10101010", "1001010"], &["10110101", "1010010"], &[], &["1001010", "1010101"], &[], &["1010101", "10110101", "10101010", "1010110"], &["1010100", "1010101", "1010101", "10010101"], &["1001001", "1010101"], &["1010101", "100101", "1010101", "1010101"], &["10110100", "10101010"], &["10101010", "10101010", "10111100", "11100"], &["10101010", "10001010", "1010110", "10100101"], &["10101011", "1101010", "1010101", "10110101"], &[], &["10101010", "1010100", "10110101", "10101010"], &[], ], &[ (&[], 333820), (&["1010101", "1010101"], 39945), (&["10101010", "10101010"], 39772), (&["1010101", "1010101", "1010101", "1010101"], 8708), (&["10101010", "10101010", "10101010", "10101010"], 8700), (&["1010010", "1010101"], 4100), (&["1010101", "10110101"], 4090), (&["1010101", "11010101"], 4089), (&["1010101", "10101101"], 4080), (&["1010110", "1010101"], 4060), ], (&["1010101", "1010101", "1010101", "10110101"], None), ); striped_random_unsigned_vecs_from_length_iterator_helper::( &|seed| geometric_random_unsigneds::(seed, 2, 1).map(|x| x << 1), 2, 1, &[ &[ "11001100", "11000", "11001", "10111101", "10111110", "110000", "11010011", "11", "1110110", "11100011", "1", "1100101", ], &["1111100", "10101111"], &[ "1011100", "11110000", "1100100", "11011101", "1001001", "111101", "101", "10011001", "11111011", "10010111", "1110110", "1101111", "100110", "1110", "11011111", "1100011", ], &["11001010", "10101"], &[ "1101110", "1101111", "1000101", "10100000", "101110", "11101110", "111101", "10110001", "10100111", "110000", "10", "1110110", "111", "1110011", "10001000", "1100010", "11001", "10111100", "10101001", "11001000", "110", "1101", "1100101", "1111011", "11011", "10101101", "11111111", "10011110", ], &[], &[ "11110001", "1100011", "11001000", "1111111", "11001100", "11001101", "11100011", "11011000", "110101", "10000111", ], &[ "11011100", "10111010", "10000101", "0", "10110010", "10010010", "10111000", "10010100", ], &["11010001", "1111000"], &[], &[ "1010100", "10101110", "1000001", "1001011", "1011100", "10110100", "11001000", "1101", "10010101", "10111011", "1111000", "1011", ], &["1010011", "111001", "10101111", "1100101"], &[], &[], &["10010001", "11010001"], &["10111110", "11101111", "11101011", "10010", "1101101", "1010110"], &[], &["100110", "10001010"], &[], &["1101100", "11000"], ], &[ (&[], 333981), (&["1", "10011100"], 13), (&["11111011", "110100"], 13), (&["110000", "10110111"], 13), (&["1100110", "10011000"], 13), (&["11101100", "11011100"], 13), (&["1", "100101"], 12), (&["100010", "101100"], 12), (&["1010", "11000011"], 12), (&["1100101", "1001101"], 12), ], (&["111111", "10101111"], None), ); striped_random_unsigned_vecs_from_length_iterator_helper::( &|seed| geometric_random_unsigneds::(seed, 2, 1).map(|x| x << 1), 10, 1, &[ &[ "0", "0", "111000", "0", "11111110", "10000001", "11111111", "11", "0", "0", "0", "11111111", ], &["0", "11000000"], &[ "11100000", "11111111", "11111011", "11111111", "0", "0", "11100000", "1", "11111111", "11111111", "11111111", "11001", "0", "11111110", "11111111", "11111111", ], &["0", "0"], &[ "0", "0", "100000", "0", "0", "0", "11111100", "11111111", "11111111", "11111111", "11111111", "111111", "1000000", "11111100", "1111111", "10001000", "1111111", "1001", "10", "0", "0", "0", "11111111", "11100001", "10111111", "1", "11111000", "1111111", ], &[], &[ "11111111", "11011111", "11111111", "11111111", "11", "11000000", "11111111", "11111111", "11110000", "11111111", ], &["11111110", "0", "0", "11100000", "11111111", "1111", "0", "11111111"], &["11110011", "11111111"], &[], &[ "10001000", "11111111", "11", "11111110", "0", "11111100", "11111111", "11111111", "11111111", "11", "11111111", "11111", ], &["11111111", "1100001", "0", "11100000"], &[], &[], &["11111111", "11111111"], &["11111000", "1111111", "0", "10000000", "111", "1111"], &[], &["0", "0"], &[], &["0", "0"], ], &[ (&[], 333981), (&["0", "0"], 22998), (&["11111111", "11111111"], 22759), (&["11111111", "11111111", "11111111", "11111111"], 2851), (&["0", "0", "0", "0"], 2788), (&["11111111", "111111"], 2626), (&["1111", "0"], 2620), (&["111", "0"], 2615), (&["111111", "0"], 2608), (&["11111000", "11111111"], 2608), ], ( &["1", "0", "11111000", "1", "1111100", "0", "0", "100000"], Some(&["1", "0", "11111000", "1", "10000000", "11111111", "11111111", "11111111"]), ), ); striped_random_unsigned_vecs_from_length_iterator_helper::( &|seed| geometric_random_unsigneds::(seed, 2, 1).map(|x| x << 1), 11, 10, &[ &[ "1011010", "11010101", "1001010", "10110101", "11010110", "10101010", "10101010", "1101010", "10100101", "10101010", "10011010", "1010010", ], &["10101010", "10101010"], &[ "10101010", "1010010", "10101001", "1010101", "10101011", "10101010", "10101010", "1010101", "10110101", "1010010", "1010101", "1010101", "1010101", "10010010", "10101010", "10101010", ], &["1001010", "10101010"], &[ "10101010", "10010110", "10101010", "10101010", "10101010", "10111100", "11100", "1010101", "1000101", "10101011", "11010010", "10101010", "1011010", "1010101", "10101101", "1101010", "1010101", "10101001", "10101010", "10101010", "10101010", "10101010", "100101", "10100101", "1010101", "1010101", "1010101", "10010101", ], &[], &[ "1010101", "1010101", "10101101", "1010110", "1101010", "11010101", "10100110", "10101010", "10101010", "11010100", ], &[ "10101010", "10110110", "10101010", "101010", "1010101", "1010101", "10101010", "10101010", ], &["10010101", "10101010"], &[], &[ "10101010", "1001010", "1010101", "1011101", "10010101", "10101010", "10101010", "10101010", "10101010", "10110101", "10010100", "1010101", ], &["1010101", "1010101", "1010101", "1010101"], &[], &[], &["1010101", "1001010"], &["1001010", "10101101", "11010010", "10101010", "1101010", "1010101"], &[], &["10000100", "10101010"], &[], &["10101010", "101010"], ], &[ (&[], 333981), (&["10101010", "10101010"], 26752), (&["1010101", "1010101"], 26461), (&["10101010", "10101010", "10101010", "10101010"], 3857), (&["1010101", "1010101", "1010101", "1010101"], 3852), (&["10101010", "1010010"], 2802), (&["1010110", "1010101"], 2776), (&["1010101", "10100101"], 2768), (&["1010101", "10010101"], 2739), (&["10101011", "10101010"], 2730), ], (&["1010101", "1010101", "10010101", "10101010"], None), ); } #[test] #[should_panic] fn striped_random_unsigned_vecs_from_length_iterator_fail_1() { striped_random_unsigned_vecs_from_length_iterator::(EXAMPLE_SEED, &|_| repeat(1), 1, 0); } #[test] #[should_panic] fn striped_random_unsigned_vecs_from_length_iterator_fail_2() { striped_random_unsigned_vecs_from_length_iterator::(EXAMPLE_SEED, &|_| repeat(1), 2, 3); } ././@LongLink00006440000000000000000000000146000000000000007774Lustar malachite-base-0.4.16/tests/num/random/striped/striped_random_unsigned_vecs_length_inclusive_range.rsmalachite-base-0.4.16/tests/num/random/striped/striped_random_unsigned_vecs_length_inclusive_range.r000064400000000000000000000232731046102023000323640ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::random::striped::striped_random_unsigned_vecs_length_inclusive_range; use malachite_base::random::EXAMPLE_SEED; use malachite_base::strings::ToBinaryString; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; fn striped_random_unsigned_vecs_length_inclusive_range_helper( a: u64, b: u64, mean_stripe_numerator: u64, mean_stripe_denominator: u64, expected_values: &[&[&str]], expected_common_values: &[(&[&str], usize)], expected_median: (&[&str], Option<&[&str]>), ) { let xss = striped_random_unsigned_vecs_length_inclusive_range::( EXAMPLE_SEED, a, b, mean_stripe_numerator, mean_stripe_denominator, ); let values = xss .clone() .take(20) .map(|xs| { xs.into_iter() .map(|x: T| x.to_binary_string()) .collect_vec() }) .collect_vec(); let common_values = common_values_map_debug(1000000, 10, xss.clone()) .into_iter() .map(|(xs, freq)| { ( xs.into_iter() .map(|x: T| x.to_binary_string()) .collect_vec(), freq, ) }) .collect_vec(); let (median_lo, median_hi) = median(xss.take(1000000)); let median_lo = median_lo .into_iter() .map(|x: T| x.to_binary_string()) .collect_vec(); let median_hi = median_hi.map(|xs| { xs.into_iter() .map(|x: T| x.to_binary_string()) .collect_vec() }); let values = values .iter() .map(|xs| xs.iter().map(String::as_str).collect_vec()) .collect_vec(); let common_values = common_values .iter() .map(|(xs, freq)| (xs.iter().map(String::as_str).collect_vec(), *freq)) .collect_vec(); let median_lo = median_lo.iter().map(String::as_str).collect_vec(); let median_hi = median_hi .as_ref() .map(|xs| xs.iter().map(String::as_str).collect_vec()); assert_eq!( ( values.iter().map(Vec::as_slice).collect_vec().as_slice(), common_values .iter() .map(|(xs, f)| (xs.as_slice(), *f)) .collect_vec() .as_slice(), (median_lo.as_slice(), median_hi.as_deref()) ), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_striped_random_unsigned_vecs_length_inclusive_range() { striped_random_unsigned_vecs_length_inclusive_range_helper::( 3, 5, 2, 1, &[ &["11001100", "11000", "11001", "10111101"], &["10000010", "10011110", "1011001", "11111000", "10011"], &["1110010", "11111000", "1101011", "110"], &["1000010", "10111001", "11100000", "11001001", "10111010"], &["11011000", "1010", "11101011", "10011011", "10001"], &["10111111", "10110100", "1111011", "110011"], &["11100010", "11110000", "111101"], &["1010011", "10100011", "10001110", "10000100"], &["1010110", "100", "11101010"], &["11000101", "10111101", "100111", "11110110", "10100"], &["1110011", "1111111", "100010", "111110", "11100011"], &["1000100", "10110001", "1100", "11011110"], &["1010110", "110111", "11111001", "11110010", "10011010"], &["11110110", "110110", "1011010", "11111111"], &["1111011", "11100010", "11000111", "10010000", "11111111"], &["11001110", "11001000", "1110000", "10011100", "101000"], &["111001", "10001100", "10100", "11101001", "11111101"], &["10010000", "10010101", "11000100"], &["10110100", "1110110", "111001", "10101100", "1000110"], &["1101", "1011010", "11100010"], ], &[ (&["1001110", "1011", "11000"], 3), (&["1011010", "10011", "100010"], 3), (&["1100010", "101000", "1000010"], 3), (&["1110111", "101000", "100101"], 3), (&["10110", "1100010", "10011111"], 3), (&["11001", "1011", "10110011"], 3), (&["11001", "1110010", "1000101"], 3), (&["101001", "101000", "1110000"], 3), (&["1100101", "1111001", "11100"], 3), (&["10010000", "1110110", "1011111"], 3), ], ( &["1111111", "11110100", "1010100", "1100"], Some(&["1111111", "11110100", "1100001"]), ), ); striped_random_unsigned_vecs_length_inclusive_range_helper::( 3, 5, 10, 1, &[ &["0", "0", "111000", "0"], &["11111100", "11", "11111111", "111", "0"], &["0", "0", "11111100", "11111111"], &["0", "111111", "0", "1000", "0"], &["11111100", "11111111", "1111111", "11111000", "11"], &["11111111", "11111111", "11001111", "0"], &["11100000", "11111111", "11111111"], &["11111111", "11111111", "11111111", "11111111"], &["0", "10", "0"], &["11111111", "1111111", "0", "0", "0"], &["11111111", "11111111", "1111", "10000", "11111111"], &["11000000", "111011", "1000000", "11111011"], &["10", "0", "0", "0", "11111111"], &["111100", "10000000", "11111100", "1111"], &["11111111", "1", "1000000", "0", "0"], &["11110000", "11111111", "0", "0", "111100"], &["11111111", "111", "11111100", "11111111", "1111111"], &["0", "10000000", "11111111"], &["11110000", "10011111", "11111111", "11011111", "1"], &["11111", "11110000", "111"], ], &[ (&["0", "0", "0"], 14915), (&["11111111", "11111111", "11111111"], 14783), (&["0", "0", "0", "0"], 6456), (&["11111111", "11111111", "11111111", "11111111"], 6260), (&["0", "0", "0", "0", "0"], 2738), ( &["11111111", "11111111", "11111111", "11111111", "11111111"], 2722, ), (&["11111111", "111111", "0"], 1721), (&["11111111", "11111111", "1111"], 1717), (&["0", "0", "10000000"], 1708), (&["11110000", "11111111", "11111111"], 1707), ], (&["10000000", "0", "0"], None), ); striped_random_unsigned_vecs_length_inclusive_range_helper::( 3, 5, 11, 10, &[ &["1011010", "11010101", "1001010", "10110101"], &["1010010", "10101010", "10101010", "101010", "10110101"], &["10101010", "1101010", "1001010", "1010101"], &["10101010", "10101010", "1011010", "10101101", "1010100"], &["1010010", "1010101", "1010101", "10101001", "101010"], &["10010101", "10101010", "10101010", "10101010"], &["11011010", "1010110", "1010101"], &["1010101", "1011011", "1010101", "10110101"], &["1010110", "1010101", "1010101"], &["10010101", "10010111", "10100011", "10101010", "1101000"], &["1010101", "1001011", "1010101", "10101001", "10101010"], &["1010110", "10110101", "10101010", "1010100"], &["10101010", "10101010", "10101010", "10101010", "100101"], &["1001010", "10101011", "10101010", "10101010"], &["1010101", "10101010", "10101010", "1011010", "10101101"], &["1010110", "10101010", "1100100", "1010101", "1010101"], &["10100101", "1010110", "100101", "1010101", "1010101"], &["1010110", "1010101", "10101101"], &["10101010", "10101010", "1010100", "1010101", "11010101"], &["1010101", "10101", "1010101"], ], &[ (&["10101010", "10101010", "10101010"], 18583), (&["1010101", "1010101", "1010101"], 18554), (&["1010101", "1010101", "1010101", "1010101"], 8801), (&["10101010", "10101010", "10101010", "10101010"], 8734), ( &["1010101", "1010101", "1010101", "1010101", "1010101"], 4002, ), ( &["10101010", "10101010", "10101010", "10101010", "10101010"], 3983, ), (&["1101010", "1010101", "1010101"], 1971), (&["10110101", "10101010", "10101010"], 1953), (&["1010101", "10101101", "10101010"], 1936), (&["1010101", "10110101", "10101010"], 1934), ], ( &["10000101", "101010", "10101010"], Some(&["10000101", "1001010", "1001001", "100101"]), ), ); } #[test] #[should_panic] fn striped_random_unsigned_vecs_length_inclusive_range_fail_1() { striped_random_unsigned_vecs_length_inclusive_range::(EXAMPLE_SEED, 3, 10, 1, 0); } #[test] #[should_panic] fn striped_random_unsigned_vecs_length_inclusive_range_fail_2() { striped_random_unsigned_vecs_length_inclusive_range::(EXAMPLE_SEED, 3, 10, 2, 3); } #[test] #[should_panic] fn striped_random_unsigned_vecs_length_inclusive_range_fail_3() { striped_random_unsigned_vecs_length_inclusive_range::(EXAMPLE_SEED, 2, 1, 4, 1); } malachite-base-0.4.16/tests/num/random/striped/striped_random_unsigned_vecs_length_range.rs000064400000000000000000000230711046102023000304620ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::random::striped::striped_random_unsigned_vecs_length_range; use malachite_base::random::EXAMPLE_SEED; use malachite_base::strings::ToBinaryString; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; fn striped_random_unsigned_vecs_length_range_helper( a: u64, b: u64, mean_stripe_numerator: u64, mean_stripe_denominator: u64, expected_values: &[&[&str]], expected_common_values: &[(&[&str], usize)], expected_median: (&[&str], Option<&[&str]>), ) { let xss = striped_random_unsigned_vecs_length_range::( EXAMPLE_SEED, a, b, mean_stripe_numerator, mean_stripe_denominator, ); let values = xss .clone() .take(20) .map(|xs| { xs.into_iter() .map(|x: T| x.to_binary_string()) .collect_vec() }) .collect_vec(); let common_values = common_values_map_debug(1000000, 10, xss.clone()) .into_iter() .map(|(xs, freq)| { ( xs.into_iter() .map(|x: T| x.to_binary_string()) .collect_vec(), freq, ) }) .collect_vec(); let (median_lo, median_hi) = median(xss.take(1000000)); let median_lo = median_lo .into_iter() .map(|x: T| x.to_binary_string()) .collect_vec(); let median_hi = median_hi.map(|xs| { xs.into_iter() .map(|x: T| x.to_binary_string()) .collect_vec() }); let values = values .iter() .map(|xs| xs.iter().map(String::as_str).collect_vec()) .collect_vec(); let common_values = common_values .iter() .map(|(xs, freq)| (xs.iter().map(String::as_str).collect_vec(), *freq)) .collect_vec(); let median_lo = median_lo.iter().map(String::as_str).collect_vec(); let median_hi = median_hi .as_ref() .map(|xs| xs.iter().map(String::as_str).collect_vec()); assert_eq!( ( values.iter().map(Vec::as_slice).collect_vec().as_slice(), common_values .iter() .map(|(xs, f)| (xs.as_slice(), *f)) .collect_vec() .as_slice(), (median_lo.as_slice(), median_hi.as_deref()) ), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_striped_random_unsigned_vecs_length_range() { striped_random_unsigned_vecs_length_range_helper::( 3, 6, 2, 1, &[ &["11001100", "11000", "11001", "10111101"], &["10000010", "10011110", "1011001", "11111000", "10011"], &["1110010", "11111000", "1101011", "110"], &["1000010", "10111001", "11100000", "11001001", "10111010"], &["11011000", "1010", "11101011", "10011011", "10001"], &["10111111", "10110100", "1111011", "110011"], &["11100010", "11110000", "111101"], &["1010011", "10100011", "10001110", "10000100"], &["1010110", "100", "11101010"], &["11000101", "10111101", "100111", "11110110", "10100"], &["1110011", "1111111", "100010", "111110", "11100011"], &["1000100", "10110001", "1100", "11011110"], &["1010110", "110111", "11111001", "11110010", "10011010"], &["11110110", "110110", "1011010", "11111111"], &["1111011", "11100010", "11000111", "10010000", "11111111"], &["11001110", "11001000", "1110000", "10011100", "101000"], &["111001", "10001100", "10100", "11101001", "11111101"], &["10010000", "10010101", "11000100"], &["10110100", "1110110", "111001", "10101100", "1000110"], &["1101", "1011010", "11100010"], ], &[ (&["1001110", "1011", "11000"], 3), (&["1011010", "10011", "100010"], 3), (&["1100010", "101000", "1000010"], 3), (&["1110111", "101000", "100101"], 3), (&["10110", "1100010", "10011111"], 3), (&["11001", "1011", "10110011"], 3), (&["11001", "1110010", "1000101"], 3), (&["101001", "101000", "1110000"], 3), (&["1100101", "1111001", "11100"], 3), (&["10010000", "1110110", "1011111"], 3), ], ( &["1111111", "11110100", "1010100", "1100"], Some(&["1111111", "11110100", "1100001"]), ), ); striped_random_unsigned_vecs_length_range_helper::( 3, 6, 10, 1, &[ &["0", "0", "111000", "0"], &["11111100", "11", "11111111", "111", "0"], &["0", "0", "11111100", "11111111"], &["0", "111111", "0", "1000", "0"], &["11111100", "11111111", "1111111", "11111000", "11"], &["11111111", "11111111", "11001111", "0"], &["11100000", "11111111", "11111111"], &["11111111", "11111111", "11111111", "11111111"], &["0", "10", "0"], &["11111111", "1111111", "0", "0", "0"], &["11111111", "11111111", "1111", "10000", "11111111"], &["11000000", "111011", "1000000", "11111011"], &["10", "0", "0", "0", "11111111"], &["111100", "10000000", "11111100", "1111"], &["11111111", "1", "1000000", "0", "0"], &["11110000", "11111111", "0", "0", "111100"], &["11111111", "111", "11111100", "11111111", "1111111"], &["0", "10000000", "11111111"], &["11110000", "10011111", "11111111", "11011111", "1"], &["11111", "11110000", "111"], ], &[ (&["0", "0", "0"], 14915), (&["11111111", "11111111", "11111111"], 14783), (&["0", "0", "0", "0"], 6456), (&["11111111", "11111111", "11111111", "11111111"], 6260), (&["0", "0", "0", "0", "0"], 2738), ( &["11111111", "11111111", "11111111", "11111111", "11111111"], 2722, ), (&["11111111", "111111", "0"], 1721), (&["11111111", "11111111", "1111"], 1717), (&["0", "0", "10000000"], 1708), (&["11110000", "11111111", "11111111"], 1707), ], (&["10000000", "0", "0"], None), ); striped_random_unsigned_vecs_length_range_helper::( 3, 6, 11, 10, &[ &["1011010", "11010101", "1001010", "10110101"], &["1010010", "10101010", "10101010", "101010", "10110101"], &["10101010", "1101010", "1001010", "1010101"], &["10101010", "10101010", "1011010", "10101101", "1010100"], &["1010010", "1010101", "1010101", "10101001", "101010"], &["10010101", "10101010", "10101010", "10101010"], &["11011010", "1010110", "1010101"], &["1010101", "1011011", "1010101", "10110101"], &["1010110", "1010101", "1010101"], &["10010101", "10010111", "10100011", "10101010", "1101000"], &["1010101", "1001011", "1010101", "10101001", "10101010"], &["1010110", "10110101", "10101010", "1010100"], &["10101010", "10101010", "10101010", "10101010", "100101"], &["1001010", "10101011", "10101010", "10101010"], &["1010101", "10101010", "10101010", "1011010", "10101101"], &["1010110", "10101010", "1100100", "1010101", "1010101"], &["10100101", "1010110", "100101", "1010101", "1010101"], &["1010110", "1010101", "10101101"], &["10101010", "10101010", "1010100", "1010101", "11010101"], &["1010101", "10101", "1010101"], ], &[ (&["10101010", "10101010", "10101010"], 18583), (&["1010101", "1010101", "1010101"], 18554), (&["1010101", "1010101", "1010101", "1010101"], 8801), (&["10101010", "10101010", "10101010", "10101010"], 8734), ( &["1010101", "1010101", "1010101", "1010101", "1010101"], 4002, ), ( &["10101010", "10101010", "10101010", "10101010", "10101010"], 3983, ), (&["1101010", "1010101", "1010101"], 1971), (&["10110101", "10101010", "10101010"], 1953), (&["1010101", "10101101", "10101010"], 1936), (&["1010101", "10110101", "10101010"], 1934), ], ( &["10000101", "101010", "10101010"], Some(&["10000101", "1001010", "1001001", "100101"]), ), ); } #[test] #[should_panic] fn striped_random_unsigned_vecs_length_range_fail_1() { striped_random_unsigned_vecs_length_range::(EXAMPLE_SEED, 3, 10, 1, 0); } #[test] #[should_panic] fn striped_random_unsigned_vecs_length_range_fail_2() { striped_random_unsigned_vecs_length_range::(EXAMPLE_SEED, 3, 10, 2, 3); } #[test] #[should_panic] fn striped_random_unsigned_vecs_length_range_fail_3() { striped_random_unsigned_vecs_length_range::(EXAMPLE_SEED, 1, 1, 4, 1); } malachite-base-0.4.16/tests/num/random/striped/striped_random_unsigned_vecs_min_length.rs000064400000000000000000000366771046102023000301710ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::random::striped::striped_random_unsigned_vecs_min_length; use malachite_base::random::EXAMPLE_SEED; use malachite_base::strings::ToBinaryString; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; fn striped_random_unsigned_vecs_min_length_helper( min_length: u64, mean_stripe_numerator: u64, mean_stripe_denominator: u64, mean_length_numerator: u64, mean_length_denominator: u64, expected_values: &[&[&str]], expected_common_values: &[(&[&str], usize)], expected_median: (&[&str], Option<&[&str]>), ) { let xss = striped_random_unsigned_vecs_min_length::( EXAMPLE_SEED, min_length, mean_stripe_numerator, mean_stripe_denominator, mean_length_numerator, mean_length_denominator, ); let values = xss .clone() .take(20) .map(|xs| { xs.into_iter() .map(|x: T| x.to_binary_string()) .collect_vec() }) .collect_vec(); let common_values = common_values_map_debug(1000000, 10, xss.clone()) .into_iter() .map(|(xs, freq)| { ( xs.into_iter() .map(|x: T| x.to_binary_string()) .collect_vec(), freq, ) }) .collect_vec(); let (median_lo, median_hi) = median(xss.take(1000000)); let median_lo = median_lo .into_iter() .map(|x: T| x.to_binary_string()) .collect_vec(); let median_hi = median_hi.map(|xs| { xs.into_iter() .map(|x: T| x.to_binary_string()) .collect_vec() }); let values = values .iter() .map(|xs| xs.iter().map(String::as_str).collect_vec()) .collect_vec(); let common_values = common_values .iter() .map(|(xs, freq)| (xs.iter().map(String::as_str).collect_vec(), *freq)) .collect_vec(); let median_lo = median_lo.iter().map(String::as_str).collect_vec(); let median_hi = median_hi .as_ref() .map(|xs| xs.iter().map(String::as_str).collect_vec()); assert_eq!( ( values.iter().map(Vec::as_slice).collect_vec().as_slice(), common_values .iter() .map(|(xs, f)| (xs.as_slice(), *f)) .collect_vec() .as_slice(), (median_lo.as_slice(), median_hi.as_deref()) ), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_striped_random_unsigned_vecs() { striped_random_unsigned_vecs_min_length_helper::( 0, 2, 1, 4, 1, &[ &[], &[ "11001100", "11000", "11001", "10111101", "10111110", "110000", "11010011", "11", "1110110", "11100011", "1", "1100101", "10111110", "11010111", ], &["101110", "1111000", "10110010", "11101110"], &["10110110", "11000010", "11111010", "1100110"], &["1000"], &[], &["10100000", "100101", "1000010", "1100110", "11000111"], &["111", "11100001"], &["1010110", "10101110", "10111000", "10111101"], &[], &["101011", "10", "1110101", "1110001", "11101111", "10001001"], &[], &[], &[ "10000100", "11110101", "11011100", "10011111", "10001000", "11001111", "1111000", "11010111", "1101001", "111110", "1100100", ], &[ "10101", "11011001", "10100000", "10100001", "1101100", "1101111", "10100011", "11110101", ], &[], &["10111111", "100111", "1111110"], &[], &["11000", "11110010", "11111", "1110011", "11110011"], &[ "10001110", "10011", "1100101", "111100", "10110111", "1101110", "100001", "10000000", "10101100", ], ], &[ (&[], 199913), (&["11010010"], 689), (&["11"], 688), (&["11110111"], 681), (&["10000110"], 673), (&["110010"], 672), (&["11101111"], 671), (&["1000100"], 670), (&["1111101"], 670), (&["11110010"], 670), ], (&["1100000"], None), ); striped_random_unsigned_vecs_min_length_helper::( 3, 2, 1, 4, 1, &[ &["11001100", "11000", "11001", "10111101"], &["10000010", "10011110", "1011001", "11111000", "10011"], &["1110010", "11111000", "1101011", "110", "10100001"], &["1000110", "11111", "110110", "1000101", "1101100"], &["1010", "11101011", "10011011", "10001"], &["10111111", "10110100", "1111011", "110011", "1110001"], &["11110000", "111101", "1010110"], &["10100011", "10001110", "10000100"], &["1010110", "100", "11101010", "11100010"], &["10111101", "100111", "11110110"], &["101001", "10001100", "10000000"], &["1000100", "1111100", "11000110"], &["10001000", "1100010", "11001", "10111100"], &["10101100", "1101110", "11110010", "11100101", "110101", "1001", "11001001"], &["1001011", "1", "10000100"], &["11000100", "10001111", "100001", "11111111", "110001"], &["10010001", "11100001", "111000"], &[ "10100010", "10001100", "11100111", "11010110", "101101", "100", "10010000", "10010101", ], &["1110110", "10110100", "1110110", "111001"], &["10100111", "1110010", "1101", "1011010"], ], &[ (&["111100", "11", "1111"], 3), (&["10000111", "100011", "110"], 3), (&["10101011", "1001101", "1"], 3), (&["10011", "1111000", "111"], 3), (&["10", "10111", "11111000"], 3), (&["11010000", "1001010", "11"], 3), (&["101", "1001110", "1110111"], 3), (&["101", "1001111", "10111101"], 3), (&["111000", "1010011", "1010"], 3), (&["111011", "0", "1110101"], 3), ], ( &["1111111", "11011110", "10110011"], Some(&["1111111", "11011110", "10111100"]), ), ); striped_random_unsigned_vecs_min_length_helper::( 0, 10, 1, 4, 1, &[ &[], &[ "0", "0", "111000", "0", "11111110", "10000001", "11111111", "11", "0", "0", "0", "11111111", "11111111", "11111", ], &["11110000", "11111111", "11111101", "1111111"], &["0", "0", "11100000", "1"], &["11111110"], &[], &["0", "0", "10011000", "11111111", "111"], &["11111111", "11111111"], &["0", "0", "0", "0"], &[], &["11111111", "11111110", "11111111", "11111111", "11111", "0"], &[], &[], &[ "0", "0", "0", "0", "11111100", "111011", "0", "1111000", "111", "1101000", "11011111", ], &[ "11111111", "11111111", "11111111", "11111", "11000000", "11", "11001000", "11111111", ], &[], &["1", "11100000", "11111111"], &[], &["1000", "0", "0", "11111111", "1111"], &["0", "10000000", "111", "10000000", "111111", "0", "0", "11111000", "11111111"], ], &[ (&[], 199913), (&["0"], 38129), (&["11111111"], 38051), (&["0", "0"], 13204), (&["11111111", "11111111"], 13153), (&["0", "0", "0"], 4662), (&["11111111", "11111111", "11111111"], 4549), (&["1"], 4369), (&["11111100"], 4338), (&["11111"], 4311), ], (&["11100", "11111110", "111111", "0"], None), ); striped_random_unsigned_vecs_min_length_helper::( 3, 10, 1, 4, 1, &[ &["0", "0", "111000", "0"], &["11111100", "11", "11111111", "111", "0"], &["0", "0", "11111100", "11111111", "1111111"], &["11000000", "11111111", "11110111", "11111111", "1"], &["0", "10000000", "111", "11111100"], &["11111111", "11111111", "11001111", "0", "11110000"], &["0", "0", "0"], &["11111111", "11111111", "11111111"], &["0", "10", "0", "0"], &["1111111", "0", "0"], &["11111111", "11111111", "11111111"], &["11100000", "11011111", "1"], &["10000000", "1110111", "10000000", "11110110"], &["100", "0", "0", "0", "11111110", "11000011", "1111111"], &["11111001", "11111", "0"], &["11111100", "1111111", "11111111", "11111111", "1111"], &["11111111", "1", "0"], &["11110000", "0", "11110000", "111", "0", "0", "11111111", "1111111"], &["0", "11110000", "10011111", "11111111"], &["10111111", "11", "11100000", "1111"], ], &[ (&["0", "0", "0"], 22115), (&["11111111", "11111111", "11111111"], 21981), (&["0", "0", "0", "0"], 4887), (&["11111111", "11111111", "11111111", "11111111"], 4789), (&["0", "11000000", "11111111"], 2545), (&["11110000", "11111111", "11111111"], 2537), (&["11111111", "11111111", "1111"], 2536), (&["1111111", "0", "0"], 2524), (&["11111111", "111111", "0"], 2524), (&["10000000", "11111111", "11111111"], 2524), ], ( &["10000000", "0", "0", "0", "100", "0", "0", "11111000", "11111111"], Some(&["10000000", "0", "0", "0", "100", "11111110", "11111111", "11111", "11100000"]), ), ); striped_random_unsigned_vecs_min_length_helper::( 0, 11, 10, 4, 1, &[ &[], &[ "1011010", "11010101", "1001010", "10110101", "11010110", "10101010", "10101010", "1101010", "10100101", "10101010", "10011010", "1010010", "1010101", "1010101", ], &["10101010", "1010110", "101011", "1010101"], &["1010100", "1010101", "1010101", "10101010"], &["1101010"], &[], &["1001010", "1010101", "1010101", "1010101", "1001001"], &["10101011", "10101010"], &["10101010", "10101101", "10101010", "1011010"], &[], &["10101011", "10101010", "10101010", "11010", "11010", "1010111"], &[], &[], &[ "10101010", "1001011", "11010101", "1010010", "1010101", "10101010", "101010", "1010101", "10101001", "1101010", "1010101", ], &[ "1010101", "1010101", "1010101", "10110101", "10100100", "10110100", "10101010", "10101010", ], &[], &["1010101", "10100101", "10101010"], &[], &["10101010", "1010100", "1101010", "10100101", "1001010"], &[ "10101100", "10101010", "10101010", "10010101", "10101010", "10101101", "10101010", "1001010", "1010101", ], ], &[ (&[], 199913), (&["1010101"], 41088), (&["10101010"], 40900), (&["1010101", "1010101"], 15274), (&["10101010", "10101010"], 15212), (&["10101010", "10101010", "10101010"], 5901), (&["1010101", "1010101", "1010101"], 5641), (&["10101001"], 4206), (&["10100101"], 4201), (&["10101101"], 4181), ], (&["1010101", "10110101"], None), ); striped_random_unsigned_vecs_min_length_helper::( 3, 11, 10, 4, 1, &[ &["1011010", "11010101", "1001010", "10110101"], &["1010010", "10101010", "10101010", "101010", "10110101"], &["10101010", "1101010", "1001010", "1010101", "1010101"], &["10101010", "1011010", "10101101", "1010100", "10101001"], &["10101010", "10101010", "1010110", "11010101"], &["10010101", "10101010", "10101010", "10101010", "10010010"], &["1010110", "1010101", "1010101"], &["1011011", "1010101", "10110101"], &["1010110", "1010101", "1010101", "110101"], &["10010111", "10100011", "10101010"], &["11010001", "10101010", "10110100"], &["10101010", "1010010", "1010101"], &["1010010", "10010101", "10101010", "1010110"], &["10101010", "10101010", "10101010", "10101010", "10110100", "10110101", "1010100"], &["1010101", "1010101", "1010101"], &["1010100", "1010101", "10110101", "1011010", "10101001"], &["10101011", "110110", "1010101"], &[ "10101010", "1001010", "10101101", "1001010", "10101010", "10101010", "1010110", "1010101", ], &["1011010", "1010101", "1010101", "10101011"], &["1010101", "1010101", "10101010", "11101010"], ], &[ (&["10101010", "10101010", "10101010"], 27990), (&["1010101", "1010101", "1010101"], 27615), (&["10101010", "10101010", "10101010", "10101010"], 6458), (&["1010101", "1010101", "1010101", "1010101"], 6439), (&["10101010", "1011010", "1010101"], 2932), (&["10101010", "10101010", "101010"], 2904), (&["10100101", "10101010", "10101010"], 2904), (&["10110101", "10101010", "10101010"], 2878), (&["1010101", "1010101", "10010101"], 2877), (&["10101010", "10101010", "1001010"], 2864), ], ( &["10001001", "10101010", "11010100", "1010010", "1010101"], Some(&["10001001", "10101010", "11010110", "10101010", "10101010"]), ), ); } #[test] #[should_panic] fn striped_random_unsigned_vecs_min_length_fail_1() { striped_random_unsigned_vecs_min_length::(EXAMPLE_SEED, 3, 1, 0, 4, 1); } #[test] #[should_panic] fn striped_random_unsigned_vecs_min_length_fail_2() { striped_random_unsigned_vecs_min_length::(EXAMPLE_SEED, 3, 2, 3, 4, 1); } #[test] #[should_panic] fn striped_random_unsigned_vecs_min_length_fail_3() { striped_random_unsigned_vecs_min_length::(EXAMPLE_SEED, 3, 4, 1, 3, 1); } #[test] #[should_panic] fn striped_random_unsigned_vecs_min_length_fail_4() { striped_random_unsigned_vecs_min_length::(EXAMPLE_SEED, 1, 4, 1, 1, 0); } #[test] #[should_panic] fn striped_random_unsigned_vecs_min_length_fail_5() { striped_random_unsigned_vecs_min_length::(EXAMPLE_SEED, 0, 4, 1, u64::MAX, u64::MAX - 1); } malachite-base-0.4.16/tests/num/random/striped/striped_random_unsigneds.rs000064400000000000000000000336561046102023000251220ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::striped::striped_random_unsigneds; use malachite_base::random::EXAMPLE_SEED; use malachite_base::strings::ToBinaryString; use malachite_base::test_util::stats::common_values_map::common_values_map; use malachite_base::test_util::stats::median; use malachite_base::test_util::stats::moments::{moment_stats, CheckedToF64, MomentStats}; use std::panic::catch_unwind; fn striped_random_unsigneds_helper( m_numerator: u64, m_denominator: u64, expected_values: &[&str], expected_common_values: &[(&str, usize)], expected_sample_median: (T, Option), expected_sample_moment_stats: MomentStats, ) { let xs = striped_random_unsigneds::(EXAMPLE_SEED, m_numerator, m_denominator); let actual_values = xs .clone() .map(|x| x.to_binary_string()) .take(20) .collect_vec(); let actual_common_values = common_values_map(1000000, 10, xs.clone()) .iter() .map(|(x, frequency)| (x.to_binary_string(), *frequency)) .collect_vec(); let actual_sample_median = median(xs.clone().take(1000000)); let actual_sample_moment_stats = moment_stats(xs.take(1000000)); assert_eq!( ( actual_values, actual_common_values, actual_sample_median, actual_sample_moment_stats ), ( expected_values .iter() .map(ToString::to_string) .collect_vec(), expected_common_values .iter() .map(|(x, frequency)| (x.to_string(), *frequency)) .collect_vec(), expected_sample_median, expected_sample_moment_stats ) ); } #[test] fn test_striped_random_unsigneds() { // u8, m = 4 let values = &[ "1", "1001100", "1111111", "11000011", "0", "10000000", "1111", "1110110", "0", "11111000", "11111111", "11111101", "1111001", "0", "11110000", "11", "0", "1111111", "1", "0", ]; let common_values = &[ ("0", 66602), ("11111111", 66546), ("11100000", 22466), ("11110000", 22460), ("11111", 22373), ("111111", 22356), ("11111100", 22356), ("11111110", 22352), ("1111", 22281), ("11000000", 22273), ]; let sample_median = (128, None); let sample_moment_stats = MomentStats { mean: NiceFloat(127.56886100000068), standard_deviation: NiceFloat(95.37976309187316), skewness: NiceFloat(-0.0013289716890443589), excess_kurtosis: NiceFloat(-1.5650405989826497), }; striped_random_unsigneds_helper::( 4, 1, values, common_values, sample_median, sample_moment_stats, ); // u8, m = 2 let values = &[ "110011", "1110010", "1010110", "10110100", "1000001", "11000011", "101000", "110111", "11", "11000100", "10111001", "11111011", "111101", "1110011", "10100110", "1010010", "1110110", "110011", "11111", "1010011", ]; let common_values = &[ ("1000100", 4102), ("10100100", 4091), ("11100100", 4062), ("10100010", 4038), ("11011010", 4037), ("1010100", 4028), ("10001011", 4028), ("10010010", 4024), ("11100011", 4019), ("1101011", 4010), ]; let sample_median = (128, None); let sample_moment_stats = MomentStats { mean: NiceFloat(127.61267700000472), standard_deviation: NiceFloat(73.77702717610372), skewness: NiceFloat(-0.0007666301824401424), excess_kurtosis: NiceFloat(-1.196710018532242), }; striped_random_unsigneds_helper::( 2, 1, values, common_values, sample_median, sample_moment_stats, ); // u8, m = 5/4 let values = &[ "1010010", "1101010", "110010", "10010100", "1010101", "10111010", "1010100", "1011010", "1010110", "10001101", "10000100", "11100011", "1010", "1001011", "10101010", "1010110", "1010001", "1010100", "1010101", "1010101", ]; let common_values = &[ ("1010101", 105174), ("10101010", 104734), ("10101101", 26535), ("11010101", 26470), ("1010010", 26420), ("101010", 26383), ("1001010", 26310), ("10010101", 26290), ("10110101", 26229), ("10101001", 26220), ]; let sample_median = (130, None); let sample_moment_stats = MomentStats { mean: NiceFloat(127.53448699999743), standard_deviation: NiceFloat(54.22754686756281), skewness: NiceFloat(-0.0015080269385326522), excess_kurtosis: NiceFloat(-1.1008502131352262), }; striped_random_unsigneds_helper::( 5, 4, values, common_values, sample_median, sample_moment_stats, ); // u64, m = 32 let values = &[ "111111111111111111111111111111", "11111111111111111111111111111111111111111111111111111111111", "1111111111111111111111111111111", "1111111111111111111111100000000000000000000000000000000000000000", "11111111111111111111111111111111111111111111111111111111111111", "1111000000000000000000000000000000000000001100000000111111111111", "111111111111111000000000000", "1111111111111111111111111", "111111111111111111111", "1111111111111111111111111111111111111111111000000000000000000000", "1110000000000000000000000000000000000000000000000000000000000111", "1111111111111111111111111111111111111111111111111111111111111111", "11111111111111111111111111111000000000000000000000000000", "100000001111111111111111111111111000000000", "1111111000000000000000000000000000000000000000000000000000000000", "1111", "1111111111111111111111111111111111111111111111111111000", "1111111111111111110000000011111111111111111", "0", "111111111111111111111111100", ]; let common_values = &[ ( "1111111111111111111111111111111111111111111111111111111111111111", 68034, ), ("0", 67854), ("111111111111111111111111111111", 2299), ( "1111111111111111111111111110000000000000000000000000000000000000", 2298, ), ("111111111", 2270), ("111111111111111111111111111111111111", 2255), ("111111111111", 2254), ( "1111111111111111111111111111111111111111111111100000000000000000", 2245, ), ( "1111111111111110000000000000000000000000000000000000000000000000", 2240, ), ( "1111111111111111111111111111111111111111111111111111111111000000", 2237, ), ]; let sample_median = (9223372036854775808, None); let sample_moment_stats = MomentStats { mean: NiceFloat(9.232321508867713e18), standard_deviation: NiceFloat(8.854393011414399e18), skewness: NiceFloat(-0.00195547778002319), excess_kurtosis: NiceFloat(-1.9432719051653975), }; striped_random_unsigneds_helper::( 32, 1, values, common_values, sample_median, sample_moment_stats, ); // u64, m = 2 let values = &[ "11001100011010101001011010010000011000011101011110010000000011", "11101101110011111011100001011100110100110101001011101100110011", "1111101011000111001110010011000110110101010001110111011111100", "1011100110000101000110000000111101100011100111101101111111000000", "110011001100101100000100111100101010001011010001101001000111000", "1010001101111001011010101011011000110011011110010101100100000100", "111100011000100010101011011011001000000100111011110100111011", "100100110010110010010111100011001000100110111001010000100101101", "1101100111000010011100101110010101101001100110000011111011", "1101110011101000110001100100011011100001110011100001101110001000", "1101100100110110101110000011000111010011101101101111111101111100", "1111001111110101110110010100001100001001011101001101101011101011", "111010010110111111001011100000010101010001111000010000110010001", "11010101111001000111010001011100101000010001110110001001100111", "1101011111000100111101011110111101110011010100111111100001000100", "100101000001001011001001101001011100101000110101111110111010101", "110111101110000101100101111100101101011100100010101011010100000", "101011100111011000001101010001000101111111010001100001111100011", "1111100011000100010111100101000001010110011001010100000000011", "11100111100011111000111111010010100000111110101001010111011001", ]; let common_values = &[ ("11011011101110000001110101101011110010111101", 1), ("111100000110100100110100100001100010110000010", 1), ("1011110101111010110111100110111101111101111011", 1), ("1110100010111110000100101010110100101101110111", 1), ("10111011110000001110101010110111111001011011100", 1), ("11000001010110011001100110101011001100000111111", 1), ("100100100011101001001000001010010111100010110100", 1), ("100110100101010111001000010010100111110111010110", 1), ("110110101100010110011100011100110111001111000000", 1), ("111001100010011111010011111010110100101110001000", 1), ]; let sample_median = (9232300347074497346, Some(9232359143244030439)); let sample_moment_stats = MomentStats { mean: NiceFloat(9.22650235650532e18), standard_deviation: NiceFloat(5.325785817923598e18), skewness: NiceFloat(-0.0012562071401776408), excess_kurtosis: NiceFloat(-1.1996143045434082), }; striped_random_unsigneds_helper::( 2, 1, values, common_values, sample_median, sample_moment_stats, ); // u64, m = 33/32 let values = &[ "101010101010101010101011010101010101010101010101010101010101010", "101010101010101110101010110101001010101010101010010101010010101", "101010010101011010101010101010101101010101010101010101010101010", "1010101010101010100101010101010101010101010101010101010101010101", "101010101010101010101101010101010100101001010100101010101010101", "1010101010101010101010101010101011010101101010101001010101010101", "101010101010101010101010101010101010101010101101010101010101010", "101010101010110101010101010101010101010101010101010101010101010", "10101010101010101010101010101010101010101010101010101010101011", "1001010101010101010101010101010101010101010100101010101010101010", "1010101010101010101010101100101010101010110101010101010010101010", "1010011010101010101010101010101010101010101010101010101010010101", "101010101001010101010101010101010101010101010101010101010101010", "101010010110110100101010101010101010101010101010101010101010101", "1010110101010101010101010101010010101010101010101010101010101010", "101010101010101010101010101010101010101010101010101010101010101", "101010101010101010101010101010101101010101010101010101010101010", "101010101010101010101010010101010101010101010101010101010101010", "110110101001010101010010101010101010101010101010101010101010101", "101010101010010101010101010101010101010101010101010101010101010", ]; let common_values = &[ ( "101010101010101010101010101010101010101010101010101010101010101", 72208, ), ( "1010101010101010101010101010101010101010101010101010101010101010", 71633, ), ( "1010101010101010101010101010101010101010101010101010101010101001", 2387, ), ( "101010101010101010101010101010101010110101010101010101010101010", 2371, ), ( "101010101010101010101001010101010101010101010101010101010101010", 2350, ), ( "1010101010101010101010101010101010101010101010101010101010100101", 2343, ), ( "1010101010101010101010101010101001010101010101010101010101010101", 2321, ), ( "101010101010101010101010101010101010101001010101010101010101010", 2317, ), ( "1010101010101010101010101010101010101010100101010101010101010101", 2316, ), ( "1010101010101010101101010101010101010101010101010101010101010101", 2314, ), ]; let sample_median = (10184128240689698133, Some(10184139957360479594)); let sample_moment_stats = MomentStats { mean: NiceFloat(9.22742898450889e18), standard_deviation: NiceFloat(3.1984799302251884e18), skewness: NiceFloat(-0.0008313832988426654), excess_kurtosis: NiceFloat(-1.7364190763714287), }; striped_random_unsigneds_helper::( 33, 32, values, common_values, sample_median, sample_moment_stats, ); } fn striped_random_unsigneds_fail_helper() { assert_panic!(striped_random_unsigneds::(EXAMPLE_SEED, 1, 0)); assert_panic!(striped_random_unsigneds::(EXAMPLE_SEED, 2, 3)); } #[test] fn striped_random_unsigneds_fail() { apply_fn_to_unsigneds!(striped_random_unsigneds_fail_helper); } malachite-base-0.4.16/tests/num/random/variable_range_generator/next_bit_chunk.rs000064400000000000000000000041021046102023000263520ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::random::VariableRangeGenerator; use malachite_base::random::EXAMPLE_SEED; use std::panic::catch_unwind; fn next_bit_chunk_helper(chunk_size: u64, expected_values: &[T]) { let mut range_generator = VariableRangeGenerator::new(EXAMPLE_SEED); let mut xs = Vec::with_capacity(20); for _ in 0..20 { xs.push(range_generator.next_bit_chunk::(chunk_size)); } assert_eq!(xs, expected_values); } #[test] fn test_next_bit_chunk() { next_bit_chunk_helper::( 1, &[1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0], ); next_bit_chunk_helper::( 2, &[1, 0, 3, 1, 3, 3, 2, 3, 1, 1, 0, 1, 0, 3, 2, 1, 0, 1, 2, 3], ); next_bit_chunk_helper::( 3, &[1, 6, 5, 7, 6, 3, 1, 2, 4, 5, 1, 2, 6, 5, 4, 6, 0, 5, 6, 0], ); next_bit_chunk_helper::( 7, &[113, 94, 23, 98, 70, 92, 52, 84, 33, 47, 1, 113, 54, 10, 47, 17, 89, 92, 119, 66], ); next_bit_chunk_helper::( 8, &[ 113, 239, 69, 108, 228, 210, 168, 161, 87, 32, 110, 83, 188, 34, 89, 238, 93, 200, 149, 115, ], ); } fn next_bit_chunk_fail_helper() { assert_panic!({ let mut range_generator = VariableRangeGenerator::new(EXAMPLE_SEED); range_generator.next_bit_chunk::(0) }); assert_panic!({ let mut range_generator = VariableRangeGenerator::new(EXAMPLE_SEED); range_generator.next_bit_chunk::(T::WIDTH + 1) }); } #[test] fn next_bit_chunk_fail() { apply_fn_to_unsigneds!(next_bit_chunk_fail_helper); } malachite-base-0.4.16/tests/num/random/variable_range_generator/next_bool.rs000064400000000000000000000027261046102023000253510ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::random::VariableRangeGenerator; use malachite_base::random::EXAMPLE_SEED; #[test] fn test_next_bool() { let mut range_generator = VariableRangeGenerator::new(EXAMPLE_SEED); let mut xs = Vec::with_capacity(100); for _ in 0..100 { xs.push(range_generator.next_bool()); } assert_eq!( xs, &[ true, false, true, false, true, true, true, true, true, false, true, false, false, true, false, false, false, true, true, false, false, true, true, true, false, false, true, false, false, false, false, true, true, false, true, false, true, false, true, true, true, true, true, false, false, false, true, true, false, false, false, true, false, true, true, false, true, false, true, false, true, false, false, true, true, false, true, false, true, false, true, false, true, true, false, false, false, false, true, true, false, true, true, false, false, true, true, true, true, false, true, true, true, false, true, false, true, false, true, true ] ); } malachite-base-0.4.16/tests/num/random/variable_range_generator/next_in_inclusive_range.rs000064400000000000000000000035341046102023000302570ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::random::VariableRangeGenerator; use malachite_base::random::EXAMPLE_SEED; use std::panic::catch_unwind; fn next_in_inclusive_range_helper(a: T, b: T, expected_values: &[T]) { let mut range_generator = VariableRangeGenerator::new(EXAMPLE_SEED); let mut xs = Vec::with_capacity(20); for _ in 0..20 { xs.push(range_generator.next_in_inclusive_range(a, b)); } assert_eq!(xs, expected_values); } #[test] fn test_next_in_inclusive_range() { next_in_inclusive_range_helper::(5, 5, &[5; 20]); next_in_inclusive_range_helper::( 1, 6, &[2, 6, 4, 2, 3, 5, 6, 2, 3, 6, 5, 1, 6, 1, 3, 6, 3, 1, 5, 1], ); next_in_inclusive_range_helper::( 10, 19, &[11, 17, 15, 14, 16, 14, 12, 18, 11, 17, 15, 10, 12, 16, 13, 15, 12, 12, 19, 15], ); next_in_inclusive_range_helper::( 0, u8::MAX, &[ 113, 239, 69, 108, 228, 210, 168, 161, 87, 32, 110, 83, 188, 34, 89, 238, 93, 200, 149, 115, ], ); } fn next_in_inclusive_range_fail_helper() { assert_panic!({ let mut range_generator = VariableRangeGenerator::new(EXAMPLE_SEED); range_generator.next_in_inclusive_range(T::TWO, T::ONE); }); } #[test] fn next_in_inclusive_range_fail() { apply_fn_to_unsigneds!(next_in_inclusive_range_fail_helper); } malachite-base-0.4.16/tests/num/random/variable_range_generator/next_in_range.rs000064400000000000000000000033561046102023000262000ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::random::VariableRangeGenerator; use malachite_base::random::EXAMPLE_SEED; use std::panic::catch_unwind; fn next_in_range_helper(a: T, b: T, expected_values: &[T]) { let mut range_generator = VariableRangeGenerator::new(EXAMPLE_SEED); let mut xs = Vec::with_capacity(20); for _ in 0..20 { xs.push(range_generator.next_in_range(a, b)); } assert_eq!(xs, expected_values); } #[test] fn test_next_in_range() { next_in_range_helper::(5, 6, &[5; 20]); next_in_range_helper::( 1, 7, &[2, 6, 4, 2, 3, 5, 6, 2, 3, 6, 5, 1, 6, 1, 3, 6, 3, 1, 5, 1], ); next_in_range_helper::( 10, 20, &[11, 17, 15, 14, 16, 14, 12, 18, 11, 17, 15, 10, 12, 16, 13, 15, 12, 12, 19, 15], ); next_in_range_helper::( 0, u8::MAX, &[ 113, 239, 69, 108, 228, 210, 168, 161, 87, 32, 110, 83, 188, 34, 89, 238, 93, 200, 149, 115, ], ); } fn next_in_range_fail_helper() { assert_panic!({ let mut range_generator = VariableRangeGenerator::new(EXAMPLE_SEED); range_generator.next_in_range(T::TWO, T::TWO); }); } #[test] fn next_in_range_fail() { apply_fn_to_unsigneds!(next_in_range_fail_helper); } malachite-base-0.4.16/tests/num/random/variable_range_generator/next_less_than.rs000064400000000000000000000033531046102023000263730ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::random::VariableRangeGenerator; use malachite_base::random::EXAMPLE_SEED; use std::panic::catch_unwind; fn next_less_than_helper(limit: T, expected_values: &[T]) { let mut range_generator = VariableRangeGenerator::new(EXAMPLE_SEED); let mut xs = Vec::with_capacity(20); for _ in 0..20 { xs.push(range_generator.next_less_than(limit)); } assert_eq!(xs, expected_values); } #[test] fn test_next_less_than() { next_less_than_helper::(1, &[0; 20]); next_less_than_helper::( 2, &[1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0], ); next_less_than_helper::( 3, &[1, 0, 1, 2, 1, 1, 0, 1, 0, 2, 1, 0, 1, 2, 2, 0, 1, 0, 2, 2], ); next_less_than_helper::( 4, &[1, 0, 3, 1, 3, 3, 2, 3, 1, 1, 0, 1, 0, 3, 2, 1, 0, 1, 2, 3], ); next_less_than_helper::( 10, &[1, 7, 5, 4, 6, 4, 2, 8, 1, 7, 5, 0, 2, 6, 3, 5, 2, 2, 9, 5], ); } fn next_less_than_fail_helper() { assert_panic!({ let mut range_generator = VariableRangeGenerator::new(EXAMPLE_SEED); range_generator.next_less_than(T::ZERO); }); } #[test] fn next_less_than_fail() { apply_fn_to_unsigneds!(next_less_than_fail_helper); } malachite-base-0.4.16/tests/options/exhaustive/exhaustive_options.rs000064400000000000000000000021151046102023000241020ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::nevers::Never; use malachite_base::options::exhaustive::exhaustive_options; use std::fmt::Debug; fn exhaustive_options_helper(xs: &[T], out: &[Option]) { assert_eq!( exhaustive_options(xs.iter().cloned()) .collect_vec() .as_slice(), out ); } #[test] fn test_exhaustive_options() { exhaustive_options_helper::(&[], &[None]); exhaustive_options_helper(&[5], &[None, Some(5)]); exhaustive_options_helper(&[1, 2, 3], &[None, Some(1), Some(2), Some(3)]); exhaustive_options_helper( &[Some(2), None, Some(5)], &[None, Some(Some(2)), Some(None), Some(Some(5))], ); } malachite-base-0.4.16/tests/options/exhaustive/exhaustive_somes.rs000064400000000000000000000020471046102023000235410ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::nevers::Never; use malachite_base::options::exhaustive::exhaustive_somes; use std::fmt::Debug; fn exhaustive_somes_helper(xs: &[T], out: &[Option]) { assert_eq!( exhaustive_somes(xs.iter().cloned()) .collect_vec() .as_slice(), out ); } #[test] fn test_exhaustive_somes() { exhaustive_somes_helper::(&[], &[]); exhaustive_somes_helper(&[5], &[Some(5)]); exhaustive_somes_helper(&[1, 2, 3], &[Some(1), Some(2), Some(3)]); exhaustive_somes_helper( &[Some(2), None, Some(5)], &[Some(Some(2)), Some(None), Some(Some(5))], ); } malachite-base-0.4.16/tests/options/option_from_str.rs000064400000000000000000000035621046102023000212070ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::nevers::Never; use malachite_base::options::{option_from_str, option_from_str_custom}; use malachite_base::orderings::ordering_from_str; use std::cmp::Ordering::*; use std::fmt::Debug; use std::str::FromStr; #[allow(clippy::needless_pass_by_value)] fn option_from_str_helper(s: &str, out: Option>) { assert_eq!(option_from_str(s), out); } #[test] fn test_option_from_str() { option_from_str_helper::("Some(false)", Some(Some(false))); option_from_str_helper::("Some(5)", Some(Some(5))); option_from_str_helper::("None", Some(None)); option_from_str_helper::("Some(hi)", None); option_from_str_helper::("abc", None); } #[allow(clippy::needless_pass_by_value)] fn option_from_str_custom_helper( f: &dyn Fn(&str) -> Option, s: &str, out: Option>, ) { assert_eq!(option_from_str_custom(f, s), out); } #[test] fn test_option_from_str_custom() { option_from_str_custom_helper(&ordering_from_str, "Some(Less)", Some(Some(Less))); option_from_str_custom_helper( &option_from_str, "Some(Some(false))", Some(Some(Some(false))), ); option_from_str_custom_helper(&option_from_str::, "Some(None)", Some(Some(None))); option_from_str_custom_helper(&option_from_str::, "None", Some(None)); option_from_str_custom_helper(&ordering_from_str, "Some(hi)", None); option_from_str_custom_helper(&ordering_from_str, "abc", None); } malachite-base-0.4.16/tests/options/random/random_options.rs000064400000000000000000000121621046102023000222730ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use core::hash::Hash; use itertools::Itertools; use malachite_base::num::random::random_primitive_ints; use malachite_base::options::random::random_options; use malachite_base::random::{Seed, EXAMPLE_SEED}; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; use std::fmt::Debug; fn random_options_helper( p_none_numerator: u64, p_none_denominator: u64, xs_gen: &dyn Fn(Seed) -> I, expected_values: &[Option], expected_common_values: &[(Option, usize)], expected_median: (Option, Option>), ) where I::Item: Clone + Debug + Eq + Hash + Ord, { let xs = random_options(EXAMPLE_SEED, p_none_numerator, p_none_denominator, xs_gen); let values = xs.clone().take(20).collect_vec(); let common_values = common_values_map_debug(1000000, 10, xs.clone()); let median = median(xs.take(1000000)); assert_eq!( (values.as_slice(), common_values.as_slice(), median), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_random_options() { // p = 1/2 random_options_helper( 1, 2, &random_primitive_ints::, &[ Some(85), Some(11), Some(136), None, Some(200), None, Some(235), Some(134), Some(203), None, None, None, Some(223), Some(38), None, Some(235), Some(217), Some(177), Some(162), Some(32), ], &[ (None, 500454), (Some(81), 2076), (Some(208), 2066), (Some(35), 2065), (Some(211), 2045), (Some(112), 2042), (Some(143), 2039), (Some(162), 2037), (Some(170), 2036), (Some(58), 2035), ], (None, None), ); // p = 50/51 random_options_helper( 50, 51, &random_primitive_ints::, &[None; 20], &[ (None, 980283), (Some(18), 102), (Some(25), 99), (Some(237), 98), (Some(116), 97), (Some(226), 97), (Some(23), 95), (Some(185), 95), (Some(30), 94), (Some(73), 94), ], (None, None), ); // p = 1/51 random_options_helper( 1, 51, &random_primitive_ints::, &[ Some(85), Some(11), Some(136), Some(200), Some(235), Some(134), Some(203), Some(223), Some(38), Some(235), Some(217), Some(177), Some(162), Some(32), Some(166), Some(234), Some(30), Some(218), Some(90), Some(106), ], &[ (None, 19543), (Some(58), 4030), (Some(81), 4001), (Some(194), 3981), (Some(66), 3973), (Some(64), 3969), (Some(143), 3965), (Some(4), 3964), (Some(196), 3952), (Some(208), 3941), ], (Some(125), None), ); // p = 1/11 random_options_helper( 1, 11, &|seed| random_options(seed, 1, 11, &random_primitive_ints::), &[ Some(Some(229)), Some(Some(58)), Some(Some(126)), Some(Some(192)), Some(Some(140)), Some(Some(235)), Some(Some(50)), Some(Some(162)), Some(Some(5)), Some(Some(14)), Some(Some(107)), Some(Some(218)), Some(Some(96)), Some(Some(86)), Some(Some(51)), None, Some(Some(240)), Some(Some(186)), Some(Some(180)), Some(Some(152)), ], &[ (None, 90592), (Some(None), 83007), (Some(Some(186)), 3385), (Some(Some(193)), 3377), (Some(Some(83)), 3366), (Some(Some(55)), 3365), (Some(Some(245)), 3362), (Some(Some(148)), 3354), (Some(Some(143)), 3345), (Some(Some(136)), 3341), ], (Some(Some(101)), None), ); } #[test] #[should_panic] fn random_options_fail_1() { random_options(EXAMPLE_SEED, 1, 0, &random_primitive_ints::); } #[test] #[should_panic] fn random_options_fail_2() { random_options(EXAMPLE_SEED, 2, 1, &random_primitive_ints::); } malachite-base-0.4.16/tests/options/random/random_somes.rs000064400000000000000000000065231046102023000217320ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use core::hash::Hash; use itertools::Itertools; use malachite_base::num::random::random_primitive_ints; use malachite_base::options::random::random_somes; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; use std::fmt::Debug; fn random_somes_helper( xs: I, expected_values: &[Option], expected_common_values: &[(Option, usize)], expected_median: (Option, Option>), ) where I::Item: Clone + Debug + Eq + Hash + Ord, { let xs = random_somes(xs); let values = xs.clone().take(20).collect_vec(); let common_values = common_values_map_debug(1000000, 10, xs.clone()); let median = median(xs.take(1000000)); assert_eq!( (values.as_slice(), common_values.as_slice(), median), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_random_somes() { random_somes_helper( random_primitive_ints::(EXAMPLE_SEED), &[ Some(113), Some(239), Some(69), Some(108), Some(228), Some(210), Some(168), Some(161), Some(87), Some(32), Some(110), Some(83), Some(188), Some(34), Some(89), Some(238), Some(93), Some(200), Some(149), Some(115), ], &[ (Some(214), 4097), (Some(86), 4078), (Some(166), 4049), (Some(22), 4048), (Some(126), 4047), (Some(55), 4040), (Some(93), 4037), (Some(191), 4036), (Some(36), 4035), (Some(42), 4032), ], (Some(127), None), ); random_somes_helper( random_somes(random_primitive_ints::(EXAMPLE_SEED)), &[ Some(Some(113)), Some(Some(239)), Some(Some(69)), Some(Some(108)), Some(Some(228)), Some(Some(210)), Some(Some(168)), Some(Some(161)), Some(Some(87)), Some(Some(32)), Some(Some(110)), Some(Some(83)), Some(Some(188)), Some(Some(34)), Some(Some(89)), Some(Some(238)), Some(Some(93)), Some(Some(200)), Some(Some(149)), Some(Some(115)), ], &[ (Some(Some(214)), 4097), (Some(Some(86)), 4078), (Some(Some(166)), 4049), (Some(Some(22)), 4048), (Some(Some(126)), 4047), (Some(Some(55)), 4040), (Some(Some(93)), 4037), (Some(Some(191)), 4036), (Some(Some(36)), 4035), (Some(Some(42)), 4032), ], (Some(Some(127)), None), ); } malachite-base-0.4.16/tests/orderings/exhaustive.rs000064400000000000000000000014501046102023000204440ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::orderings::exhaustive::{exhaustive_orderings, orderings_increasing}; use std::cmp::Ordering::*; #[test] fn test_orderings_increasing() { assert_eq!( orderings_increasing().collect_vec(), &[Less, Equal, Greater] ); } #[test] fn test_exhaustive_orderings() { assert_eq!( exhaustive_orderings().collect_vec(), &[Equal, Less, Greater] ); } malachite-base-0.4.16/tests/orderings/ordering_from_str.rs000064400000000000000000000013351046102023000220050ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::orderings::ordering_from_str; use std::cmp::Ordering::*; #[test] fn test_from_str() { let test = |s, out| { assert_eq!(ordering_from_str(s), out); }; test("Equal", Some(Equal)); test("Less", Some(Less)); test("Greater", Some(Greater)); test("", None); test("abc", None); test("Lesser", None); } malachite-base-0.4.16/tests/orderings/random.rs000064400000000000000000000024521046102023000175420ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::orderings::random::random_orderings; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; use std::cmp::Ordering::*; #[test] fn test_random_orderings() { let xs = random_orderings(EXAMPLE_SEED); let values = xs.clone().take(20).collect_vec(); let common_values = common_values_map_debug(1000000, 10, xs.clone()); let median = median(xs.take(1000000)); assert_eq!( (values.as_slice(), common_values.as_slice(), median), ( &[ Less, Equal, Less, Greater, Less, Less, Equal, Less, Equal, Greater, Less, Equal, Less, Greater, Greater, Equal, Less, Equal, Greater, Greater ][..], &[(Less, 333784), (Greater, 333516), (Equal, 332700)][..], (Equal, None) ) ); } malachite-base-0.4.16/tests/random/fork.rs000064400000000000000000000021141046102023000165020ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::random::{Seed, EXAMPLE_SEED}; #[test] fn test_fork() { assert_eq!( EXAMPLE_SEED.fork("first"), Seed::from_bytes([ 0x20, 0x18, 0x1, 0x3d, 0x96, 0x4d, 0x3e, 0x98, 0x10, 0x9d, 0x35, 0x75, 0x22, 0x89, 0xf7, 0xe9, 0xbe, 0x2f, 0x9c, 0x15, 0x95, 0x42, 0x1a, 0x79, 0x52, 0xf, 0x56, 0x9a, 0x7b, 0x8c, 0xd9, 0x34 ]) ); assert_eq!( EXAMPLE_SEED.fork("second"), Seed::from_bytes([ 0xe0, 0x36, 0x88, 0x58, 0x6d, 0x67, 0x33, 0xea, 0xf2, 0x1c, 0x88, 0xf9, 0xe3, 0xbd, 0x52, 0xc0, 0xe5, 0xad, 0x61, 0x81, 0x21, 0xd8, 0x2f, 0x8e, 0xcd, 0xf, 0x89, 0x9d, 0x32, 0xc5, 0x35, 0x83 ]) ); } malachite-base-0.4.16/tests/random/from_bytes.rs000064400000000000000000000010521046102023000177120ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::random::Seed; use malachite_base::random::EXAMPLE_SEED; #[test] fn test_from_bytes() { assert_eq!(Seed::from_bytes(EXAMPLE_SEED.bytes), EXAMPLE_SEED); } malachite-base-0.4.16/tests/random/get_rng.rs000064400000000000000000000014351046102023000171730ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::random::EXAMPLE_SEED; use rand_chacha::rand_core::RngCore; #[test] fn test_get_rng() { let mut bytes = [0; 32]; EXAMPLE_SEED.get_rng().fill_bytes(&mut bytes); assert_eq!( bytes, [ 113, 239, 69, 108, 228, 210, 168, 161, 87, 32, 110, 83, 188, 34, 89, 238, 93, 200, 149, 115, 189, 149, 217, 201, 117, 146, 31, 72, 151, 169, 174, 33 ] ); } malachite-base-0.4.16/tests/random/next.rs000064400000000000000000000013151046102023000165210ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::random::{Seed, EXAMPLE_SEED}; #[test] fn test_next() { assert_eq!( EXAMPLE_SEED.next(), Seed::from_bytes([ 113, 239, 69, 108, 228, 210, 168, 161, 87, 32, 110, 83, 188, 34, 89, 238, 93, 200, 149, 115, 189, 149, 217, 201, 117, 146, 31, 72, 151, 169, 174, 33 ]) ); } malachite-base-0.4.16/tests/rational_sequences/access/get.rs000064400000000000000000000043201046102023000221660ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::rational_sequences::RationalSequence; use malachite_base::test_util::generators::{ unsigned_rational_sequence_unsigned_pair_gen_var_1, unsigned_rational_sequence_unsigned_pair_gen_var_2, }; #[test] pub fn test_get() { fn test(non_repeating: &[u8], repeating: &[u8], index: usize, out: Option<&u8>) { let xs = RationalSequence::from_slices(non_repeating, repeating); assert_eq!(xs.get(index), out); } test(&[], &[], 0, None); test(&[1, 2, 3], &[], 0, Some(&1)); test(&[1, 2, 3], &[], 1, Some(&2)); test(&[1, 2, 3], &[], 2, Some(&3)); test(&[1, 2, 3], &[], 3, None); test(&[1, 2, 3], &[4], 3, Some(&4)); test(&[1, 2, 3], &[4], 100, Some(&4)); } #[test] pub fn test_index() { fn test(non_repeating: &[u8], repeating: &[u8], index: usize, out: u8) { let xs = RationalSequence::from_slices(non_repeating, repeating); assert_eq!(xs[index], out); } test(&[1, 2, 3], &[], 0, 1); test(&[1, 2, 3], &[], 1, 2); test(&[1, 2, 3], &[], 2, 3); test(&[1, 2, 3], &[4], 3, 4); test(&[1, 2, 3], &[4], 100, 4); } #[allow(clippy::unnecessary_operation)] #[test] #[should_panic] fn index_fail_1() { RationalSequence::::from_vec(vec![])[0]; } #[allow(clippy::unnecessary_operation)] #[test] #[should_panic] fn index_fail_2() { RationalSequence::from_vec(vec![1, 2, 3])[3]; } #[test] fn get_properties() { unsigned_rational_sequence_unsigned_pair_gen_var_1::().test_properties( |(xs, index)| { assert_eq!(xs.get(index), xs.iter().nth(index)); }, ); } #[test] fn index_properties() { unsigned_rational_sequence_unsigned_pair_gen_var_2::().test_properties(|(xs, index)| { let x = xs[index]; assert_eq!(xs.iter().nth(index).unwrap(), &x); assert_eq!(xs.get(index), Some(&x)); }); } malachite-base-0.4.16/tests/rational_sequences/access/mutate.rs000064400000000000000000000042651046102023000227160ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::rational_sequences::RationalSequence; use malachite_base::test_util::generators::large_type_gen_var_22; #[test] pub fn test_mutate() { fn test( non_repeating: &[u8], repeating: &[u8], index: usize, new_value: u8, out: u8, non_repeating_out: &[u8], repeating_out: &[u8], ) { let mut xs = RationalSequence::from_slices(non_repeating, repeating); assert_eq!( xs.mutate(index, |x| { *x = new_value; out }), out ); assert_eq!( xs, RationalSequence::from_slices(non_repeating_out, repeating_out) ); } test(&[1, 2, 3], &[], 0, 5, 6, &[5, 2, 3], &[]); test(&[1, 2, 3], &[], 1, 5, 6, &[1, 5, 3], &[]); test(&[1, 2, 3], &[], 2, 5, 6, &[1, 2, 5], &[]); test( &[1, 2, 3], &[4, 5, 6], 3, 100, 6, &[1, 2, 3, 100], &[5, 6, 4], ); test( &[1, 2, 3], &[4, 5, 6], 10, 100, 6, &[1, 2, 3, 4, 5, 6, 4, 5, 6, 4, 100], &[6, 4, 5], ); } #[test] #[should_panic] fn mutate_fail_1() { RationalSequence::::from_vec(vec![]).mutate(0, |_| {}); } #[test] #[should_panic] fn mutate_fail_2() { RationalSequence::from_vec(vec![1, 2, 3]).mutate(3, |_| {}); } #[test] fn mutate_properties() { large_type_gen_var_22::().test_properties(|(mut xs, index, y, z)| { let xs_old = xs.clone(); let x_old = xs[index]; assert_eq!( xs.mutate(index, |x| { *x = y; z }), z ); assert_eq!(xs[index], y); xs.mutate(index, |x| { *x = x_old; }); assert_eq!(xs, xs_old); }); } malachite-base-0.4.16/tests/rational_sequences/basic/component_len.rs000064400000000000000000000022201046102023000240640ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::rational_sequences::RationalSequence; use malachite_base::test_util::generators::{unsigned_rational_sequence_gen, unsigned_vec_gen}; #[test] pub fn test_component_len() { fn test(non_repeating: &[u8], repeating: &[u8], out: usize) { let xs = RationalSequence::from_slices(non_repeating, repeating); assert_eq!(xs.component_len(), out); } test(&[], &[], 0); test(&[1, 2, 3], &[], 3); test(&[], &[1, 2, 3], 3); test(&[1, 2, 3], &[4, 5, 6], 6); } #[test] fn component_len_properties() { unsigned_rational_sequence_gen::().test_properties(|xs| { xs.component_len(); }); unsigned_vec_gen::().test_properties(|xs| { assert_eq!(RationalSequence::from_slice(&xs).component_len(), xs.len()); }); } malachite-base-0.4.16/tests/rational_sequences/basic/is_empty.rs000064400000000000000000000021551046102023000230640ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::rational_sequences::RationalSequence; use malachite_base::test_util::generators::unsigned_rational_sequence_gen; #[test] pub fn test_is_empty() { fn test(non_repeating: &[u8], repeating: &[u8], out: bool) { let xs = RationalSequence::from_slices(non_repeating, repeating); assert_eq!(xs.is_empty(), out); } test(&[], &[], true); test(&[1, 2, 3], &[], false); test(&[], &[1, 2, 3], false); test(&[1, 2, 3], &[4, 5, 6], false); } #[test] fn is_empty_properties() { unsigned_rational_sequence_gen::().test_properties(|xs| { let empty = xs.is_empty(); assert_eq!(empty, xs == RationalSequence::from_vec(vec![])); assert_eq!(empty, xs.component_len() == 0); }); } malachite-base-0.4.16/tests/rational_sequences/basic/is_finite.rs000064400000000000000000000022461046102023000232050ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::rational_sequences::RationalSequence; use malachite_base::test_util::generators::{unsigned_rational_sequence_gen, unsigned_vec_gen}; #[test] pub fn test_is_finite() { fn test(non_repeating: &[u8], repeating: &[u8], out: bool) { let xs = RationalSequence::from_slices(non_repeating, repeating); assert_eq!(xs.is_finite(), out); } test(&[], &[], true); test(&[1, 2, 3], &[], true); test(&[], &[1, 2, 3], false); test(&[1, 2, 3], &[4, 5, 6], false); } #[test] fn is_finite_properties() { unsigned_rational_sequence_gen::().test_properties(|xs| { assert_eq!(xs.is_finite(), xs.slices_ref().1.is_empty()); }); unsigned_vec_gen::().test_properties(|xs| { assert!(RationalSequence::from_slice(&xs).is_finite()); }); } malachite-base-0.4.16/tests/rational_sequences/basic/iter.rs000064400000000000000000000035551046102023000222030ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::iterators::{count_is_at_least, prefix_to_string}; use malachite_base::rational_sequences::RationalSequence; use malachite_base::test_util::generators::{unsigned_rational_sequence_gen, unsigned_vec_gen}; #[test] pub fn test_iter() { fn test(non_repeating: &[u8], repeating: &[u8], out: &str) { let xs = RationalSequence::from_slices(non_repeating, repeating); assert_eq!(prefix_to_string(xs.iter(), 10), out); } test(&[], &[], "[]"); test(&[1, 2, 3], &[], "[1, 2, 3]"); test(&[], &[1, 2, 3], "[1, 2, 3, 1, 2, 3, 1, 2, 3, 1, ...]"); test( &[1, 2, 3], &[4, 5, 6], "[1, 2, 3, 4, 5, 6, 4, 5, 6, 4, ...]", ); } #[test] fn iter_properties() { unsigned_rational_sequence_gen::().test_properties(|xs| { let mut it = xs.iter(); if let Some(len) = xs.len() { assert_eq!(it.count(), len); } else { assert!(count_is_at_least(&mut it, 20)); } let non_rep_len = xs.slices_ref().0.len(); let rep_len = xs.slices_ref().1.len(); assert!(Iterator::eq( xs.iter().take(non_rep_len), xs.slices_ref().0.iter() )); assert!(Iterator::eq( xs.iter().skip(non_rep_len).take(rep_len), xs.slices_ref().1.iter() )); }); unsigned_vec_gen::().test_properties(|xs| { assert!(Iterator::eq( xs.iter(), RationalSequence::from_slice(&xs).iter() )); }); } malachite-base-0.4.16/tests/rational_sequences/basic/len.rs000064400000000000000000000022441046102023000220100ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::rational_sequences::RationalSequence; use malachite_base::test_util::generators::{unsigned_rational_sequence_gen, unsigned_vec_gen}; #[test] pub fn test_len() { fn test(non_repeating: &[u8], repeating: &[u8], out: Option) { let xs = RationalSequence::from_slices(non_repeating, repeating); assert_eq!(xs.len(), out); } test(&[], &[], Some(0)); test(&[1, 2, 3], &[], Some(3)); test(&[], &[1, 2, 3], None); test(&[1, 2, 3], &[4, 5, 6], None); } #[test] fn len_properties() { unsigned_rational_sequence_gen::().test_properties(|xs| { assert_eq!(xs.len().is_some(), xs.is_finite()); }); unsigned_vec_gen::().test_properties(|xs| { assert_eq!(RationalSequence::from_slice(&xs).len(), Some(xs.len())); }); } malachite-base-0.4.16/tests/rational_sequences/comparison/cmp.rs000064400000000000000000000034011046102023000230760ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::rational_sequences::RationalSequence; use malachite_base::test_util::generators::{ unsigned_rational_sequence_gen, unsigned_rational_sequence_pair_gen, unsigned_rational_sequence_triple_gen, }; use std::cmp::Ordering::*; #[test] fn test_cmp() { let xs = &[ RationalSequence::from_vec(vec![]), RationalSequence::from_vec(vec![1, 2, 3]), RationalSequence::from_vecs(vec![], vec![1, 2, 3]), RationalSequence::from_vecs(vec![1, 2, 3], vec![4, 5, 6]), RationalSequence::from_vec(vec![1, 2, 4]), ]; for (i, x) in xs.iter().enumerate() { for (j, y) in xs.iter().enumerate() { assert_eq!(i.cmp(&j), x.clone().cmp(&y.clone())); } } } #[test] fn cmp_properties() { unsigned_rational_sequence_pair_gen::().test_properties(|(xs, ys)| { let ord = xs.cmp(&ys); assert_eq!(ys.cmp(&xs).reverse(), ord); assert_eq!(xs == ys, xs.cmp(&ys) == Equal); }); let empty = RationalSequence::from_vec(vec![]); unsigned_rational_sequence_gen::().test_properties(|xs| { assert_eq!(xs.cmp(&xs), Equal); assert!(xs >= empty); }); unsigned_rational_sequence_triple_gen::().test_properties(|(xs, ys, zs)| { if xs < ys && ys < zs { assert!(xs < zs); } else if xs > ys && ys > zs { assert!(xs > zs); } }); } malachite-base-0.4.16/tests/rational_sequences/comparison/eq.rs000064400000000000000000000026611046102023000227330ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::rational_sequences::RationalSequence; use malachite_base::test_util::generators::{ unsigned_rational_sequence_gen, unsigned_rational_sequence_pair_gen, unsigned_rational_sequence_triple_gen, }; #[test] fn test_eq() { let xs = &[ RationalSequence::from_vec(vec![]), RationalSequence::from_vec(vec![1, 2, 3]), RationalSequence::from_vecs(vec![], vec![1, 2, 3]), RationalSequence::from_vecs(vec![1, 2, 3], vec![4, 5, 6]), ]; for (i, x) in xs.iter().enumerate() { for (j, y) in xs.iter().enumerate() { assert_eq!(i == j, x.clone() == y.clone()); } } } #[test] fn eq_properties() { unsigned_rational_sequence_pair_gen::().test_properties(|(xs, ys)| { assert_eq!(xs == ys, ys == xs); }); unsigned_rational_sequence_gen::().test_properties(|xs| { assert_eq!(xs, xs); }); unsigned_rational_sequence_triple_gen::().test_properties(|(xs, ys, zs)| { if xs == ys && ys == zs { assert_eq!(xs, zs); } }); } malachite-base-0.4.16/tests/rational_sequences/comparison/hash.rs000064400000000000000000000012141046102023000232420ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::generators::unsigned_rational_sequence_gen; use malachite_base::test_util::hash::hash; #[test] fn hash_properties() { unsigned_rational_sequence_gen::().test_properties(|xs| { assert_eq!(hash(&xs), hash(&xs.clone())); }); } malachite-base-0.4.16/tests/rational_sequences/conversion/clone.rs000064400000000000000000000034221046102023000234350ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::rational_sequences::RationalSequence; use malachite_base::test_util::generators::{ unsigned_rational_sequence_gen, unsigned_rational_sequence_pair_gen, }; #[test] #[allow(clippy::redundant_clone)] fn test_clone() { let test = |nr: &[u8], r: &[u8]| { let xs = RationalSequence::from_slices(nr, r); let xs_clone = xs.clone(); assert!(xs.is_valid()); assert_eq!(xs_clone, xs); }; test(&[], &[]); test(&[1, 2, 3], &[]); test(&[], &[1, 2, 3]); test(&[1, 2, 3], &[4, 5, 5]); } #[test] fn test_clone_from() { let test = |nr_1: &[u8], r_1: &[u8], nr_2: &[u8], r_2: &[u8]| { let mut x = RationalSequence::from_slices(nr_1, r_1); let y = RationalSequence::from_slices(nr_2, r_2); x.clone_from(&y); assert!(x.is_valid()); assert_eq!(x, y); }; test(&[], &[], &[1, 2, 3], &[4, 5, 6]); test(&[], &[1, 2, 3], &[1, 2, 3], &[]); } #[allow(clippy::redundant_clone)] #[test] fn clone_and_clone_from_properties() { unsigned_rational_sequence_gen::().test_properties(|xs| { let mut_xs = xs.clone(); assert!(mut_xs.is_valid()); assert_eq!(mut_xs, xs); }); unsigned_rational_sequence_pair_gen::().test_properties(|(xs, ys)| { let mut mut_xs = xs.clone(); mut_xs.clone_from(&ys); assert!(mut_xs.is_valid()); assert_eq!(mut_xs, ys); }); } malachite-base-0.4.16/tests/rational_sequences/conversion/from_vec.rs000064400000000000000000000023401046102023000241330ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::rational_sequences::RationalSequence; use malachite_base::strings::ToDebugString; use malachite_base::test_util::generators::unsigned_vec_gen; #[test] pub fn test_from_vec_and_from_slice() { fn test(non_repeating: &[u8], out: &str) { assert_eq!(RationalSequence::from_slice(non_repeating).to_string(), out); assert_eq!( RationalSequence::from_vec(non_repeating.to_vec()).to_string(), out ); } test(&[], "[]"); test(&[1, 2, 3], "[1, 2, 3]"); } #[test] fn from_vec_and_from_slice_properties() { unsigned_vec_gen::().test_properties(|xs| { let rs = RationalSequence::from_slice(&xs); assert!(rs.is_valid()); assert_eq!(rs.to_string(), xs.to_debug_string()); assert!(rs.is_finite()); assert_eq!(RationalSequence::from_vec(xs), rs); }); } malachite-base-0.4.16/tests/rational_sequences/conversion/from_vecs.rs000064400000000000000000000031761046102023000243260ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::rational_sequences::{rational_sequence_is_reduced, RationalSequence}; use malachite_base::test_util::generators::unsigned_vec_pair_gen; #[test] pub fn test_from_vecs_and_from_slices() { fn test(non_repeating: &[u8], repeating: &[u8], out: &str) { assert_eq!( RationalSequence::from_slices(non_repeating, repeating).to_string(), out ); assert_eq!( RationalSequence::from_vecs(non_repeating.to_vec(), repeating.to_vec()).to_string(), out ); } test(&[], &[], "[]"); test(&[1, 2, 3], &[], "[1, 2, 3]"); test(&[], &[1, 2, 3], "[[1, 2, 3]]"); test(&[1, 2, 3], &[4, 5, 6], "[1, 2, 3, [4, 5, 6]]"); test(&[1, 2], &[3, 4, 3, 4], "[1, 2, [3, 4]]"); test(&[1, 2, 3], &[4, 3, 4, 3], "[1, 2, [3, 4]]"); test(&[1, 2, 3, 4], &[3, 4, 3, 4], "[1, 2, [3, 4]]"); } #[test] fn from_vec_and_from_slice_properties() { unsigned_vec_pair_gen::().test_properties(|(xs, ys)| { let rs = RationalSequence::from_slices(&xs, &ys); assert!(rs.is_valid()); assert_eq!(RationalSequence::from_vecs(xs.clone(), ys.clone()), rs); if rational_sequence_is_reduced(&xs, &ys) { assert_eq!(rs.into_vecs(), (xs, ys)); } }); } malachite-base-0.4.16/tests/rational_sequences/conversion/to_vecs.rs000064400000000000000000000032771046102023000240070ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::rational_sequences::RationalSequence; use malachite_base::test_util::generators::unsigned_rational_sequence_gen; #[test] pub fn test_to_vecs_into_vecs_and_slices_ref() { fn test(non_repeating: &[u8], repeating: &[u8], o_xs: &[u8], o_ys: &[u8]) { let xs = RationalSequence::from_slices(non_repeating, repeating); let (out_xs, out_ys) = xs.to_vecs(); assert_eq!(out_xs, o_xs); assert_eq!(out_ys, o_ys); let (out_xs, out_ys) = xs.clone().into_vecs(); assert_eq!(out_xs, o_xs); assert_eq!(out_ys, o_ys); let (out_xs, out_ys) = xs.slices_ref(); assert_eq!(out_xs, o_xs); assert_eq!(out_ys, o_ys); } test(&[], &[], &[], &[]); test(&[1, 2, 3], &[], &[1, 2, 3], &[]); test(&[], &[1, 2, 3], &[], &[1, 2, 3]); test(&[1, 2, 3], &[4, 5, 6], &[1, 2, 3], &[4, 5, 6]); } #[test] fn to_vecs_into_vecs_and_slices_ref_properties() { unsigned_rational_sequence_gen::().test_properties(|rxs| { let (xs, ys) = rxs.to_vecs(); let (xs_alt, ys_alt) = rxs.clone().into_vecs(); assert_eq!(xs_alt, xs); assert_eq!(ys_alt, ys); let (xs_alt, ys_alt) = rxs.slices_ref(); assert_eq!(xs_alt, xs); assert_eq!(ys_alt, ys); assert_eq!(RationalSequence::from_vecs(xs, ys), rxs); }); } malachite-base-0.4.16/tests/rational_sequences/exhaustive.rs000064400000000000000000000061671046102023000223460ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::nevers::nevers; use malachite_base::num::exhaustive::exhaustive_unsigneds; use malachite_base::rational_sequences::exhaustive::exhaustive_rational_sequences; use malachite_base::strings::ToDebugString; use malachite_base::tuples::exhaustive::exhaustive_units; use std::fmt::{Display, Formatter, Result}; #[derive(Clone, Eq, PartialEq)] struct Unit(()); impl Display for Unit { fn fmt(&self, f: &mut Formatter) -> Result { f.write_str("()") } } #[test] fn test_exhaustive_rational_sequences() { assert_eq!( exhaustive_rational_sequences(nevers()) .collect_vec() .to_debug_string(), "[[]]" ); assert_eq!( exhaustive_rational_sequences(exhaustive_units().map(Unit)) .take(20) .collect_vec() .to_debug_string(), "[[], [[()]], [()], [(), ()], [(), (), (), ()], [(), (), ()], [(), (), (), (), ()], \ [(), (), (), (), (), ()], [(), (), (), (), (), (), (), (), ()], \ [(), (), (), (), (), (), ()], [(), (), (), (), (), (), (), ()], \ [(), (), (), (), (), (), (), (), (), ()], \ [(), (), (), (), (), (), (), (), (), (), (), ()], \ [(), (), (), (), (), (), (), (), (), (), ()], \ [(), (), (), (), (), (), (), (), (), (), (), (), ()], \ [(), (), (), (), (), (), (), (), (), (), (), (), (), ()], \ [(), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), ()], \ [(), (), (), (), (), (), (), (), (), (), (), (), (), (), ()], \ [(), (), (), (), (), (), (), (), (), (), (), (), (), (), (), ()], \ [(), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), ()]]" ); assert_eq!( exhaustive_rational_sequences(exhaustive_bools()) .take(20) .collect_vec() .to_debug_string(), "[[], [[false]], [false], [[true]], [false, [true]], [true], [true, [false]], \ [false, false, false], [false, false, false, [true]], [[false, false, true]], \ [false, [false, false, true]], [[false, true]], [false, [false, true]], \ [false, false, false, [false, false, true]], [false, false, false, [false, true]], \ [false, false], [false, false, true], [false, false, true, [false]], \ [false, false, [true]], [false, true]]" ); assert_eq!( exhaustive_rational_sequences(exhaustive_unsigneds::()) .take(20) .collect_vec() .to_debug_string(), "[[], [[0]], [0], [[1]], [0, [1]], [1], [1, [0]], [0, 0, 0], [0, 0, 0, [1]], [[2]], \ [0, [2]], [[3]], [0, [3]], [1, [2]], [0, 0, 0, [2]], [1, [3]], [0, 0, 0, [3]], [2], \ [2, [0]], [0, 0]]" ); } malachite-base-0.4.16/tests/rational_sequences/random.rs000064400000000000000000000064461046102023000214410ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::num::random::random_primitive_ints; use malachite_base::random::EXAMPLE_SEED; use malachite_base::rational_sequences::random::random_rational_sequences; use malachite_base::rational_sequences::RationalSequence; use malachite_base::test_util::stats::common_values_map::common_values_map; use malachite_base::test_util::stats::median; #[test] fn test_random_rational_sequences() { let xs = random_rational_sequences(EXAMPLE_SEED, &random_primitive_ints::, 4, 1); let values = xs .clone() .map(|x| RationalSequence::to_string(&x)) .take(20) .collect_vec(); let values = values.iter().map(String::as_str).collect_vec(); let common_values = common_values_map(1000000, 10, xs.clone()) .into_iter() .map(|(x, freq)| (x.to_string(), freq)) .collect_vec(); let common_values = common_values .iter() .map(|(x, freq)| (x.as_str(), *freq)) .collect_vec(); let (median_lo, median_hi) = median(xs.take(1000000)); let (median_lo, median_hi) = ( median_lo.to_string(), median_hi.map(|x| RationalSequence::to_string(&x)), ); let actual_median = (median_lo.as_str(), median_hi.as_deref()); assert_eq!( (values.as_slice(), common_values.as_slice(), actual_median), ( &[ "[[85, 11, 136, 200, 235, 134, 203, 223, 38, 235, 217, 177, 162, 32]]", "[166, 234, 30, 218, [90, 106, 9, 216]]", "[204]", "[151, 213, 97, 253, 78, [91, 39]]", "[191, 175, 170, 232]", "[233, 2, 35, 22, 217, 198]", "[[114, 17, 32, 173, 114, 65, 121, 222, 173, 25, 144]]", "[148, 79, 115, 52, 73, 69, 137, 91]", "[153, 178, 112]", "[34, 95, 106, 167, 197, [130, 168, 122, 207, 172, 177, 86, 150, 221]]", "[218, [101]]", "[115, 74, 9, 123, 109, 52, 201]", "[159, 247, 250, 48, 133, 235, 196, 40, [97]]", "[104, 68, 190, [216, 7, 216, 157, 43, 43, 112]]", "[]", "[217, 24, 11, 103, 211, [84, 135]]", "[[55, 29, 206, 89, 65, 191, 51, 9, 79]]", "[[148, 34]]", "[22, 22, 62, 3, 114, 118, 20, 47, 194, 50, 32, [120, 176, 166, 23]]", "[204, 248, 177, 238, 237, 222, 154, 113, [225, 65]]" ][..], &[ ("[]", 39885), ("[[243]]", 157), ("[68]", 154), ("[1]", 153), ("[120]", 153), ("[71]", 152), ("[[40]]", 152), ("[[158]]", 151), ("[[169]]", 151), ("[[183]]", 151) ][..], ( "[122, 194, 41, 122, [232]]", Some("[[122, 194, 89, 228, 124, 219]]") ) ) ); } malachite-base-0.4.16/tests/rational_sequences/to_string.rs000064400000000000000000000027171046102023000221660ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::rational_sequences::RationalSequence; use malachite_base::strings::string_is_subset; use malachite_base::strings::ToDebugString; use malachite_base::test_util::generators::{unsigned_rational_sequence_gen, unsigned_vec_gen}; #[test] pub fn test_to_string() { fn test(non_repeating: &[u8], repeating: &[u8], out: &str) { let xs = RationalSequence::from_slices(non_repeating, repeating); assert_eq!(xs.to_string(), out); assert_eq!(xs.to_debug_string(), out); } test(&[], &[], "[]"); test(&[1, 2, 3], &[], "[1, 2, 3]"); test(&[], &[1, 2, 3], "[[1, 2, 3]]"); test(&[1, 2, 3], &[4, 5, 6], "[1, 2, 3, [4, 5, 6]]"); } #[test] fn to_string_properties() { unsigned_rational_sequence_gen::().test_properties(|xs| { let s = xs.to_string(); assert_eq!(xs.to_debug_string(), s); assert!(string_is_subset(&s, " ,0123456789[]")); }); unsigned_vec_gen::().test_properties(|xs| { assert_eq!( RationalSequence::from_slice(&xs).to_string(), xs.to_debug_string() ); }); } malachite-base-0.4.16/tests/rounding_modes/clone.rs000064400000000000000000000024051046102023000204000ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::rounding_modes::RoundingMode::{self, *}; use malachite_base::test_util::generators::{rounding_mode_gen, rounding_mode_pair_gen}; #[test] #[allow(clippy::clone_on_copy)] fn test_clone() { let test = |rm: RoundingMode| { let cloned = rm.clone(); assert_eq!(cloned, rm); }; test(Down); test(Up); test(Floor); test(Ceiling); test(Nearest); test(Exact); } #[test] fn test_clone_from() { let test = |mut x: RoundingMode, y: RoundingMode| { x.clone_from(&y); assert_eq!(x, y); }; test(Exact, Floor); test(Up, Ceiling); } #[test] fn clone_and_clone_from_properties() { rounding_mode_gen().test_properties(|rm| { assert_eq!(rm.clone(), rm); }); rounding_mode_pair_gen().test_properties(|(x, y)| { let mut mut_x = x; mut_x.clone_from(&y); assert_eq!(mut_x, y); }); } malachite-base-0.4.16/tests/rounding_modes/cmp.rs000064400000000000000000000022771046102023000200660ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::rounding_modes::RoundingMode; use malachite_base::test_util::common::test_cmp_helper; use malachite_base::test_util::generators::{ rounding_mode_gen, rounding_mode_pair_gen, rounding_mode_triple_gen, }; use std::cmp::Ordering::*; #[test] fn test_cmp() { test_cmp_helper::(&["Down", "Up", "Floor", "Ceiling", "Nearest", "Exact"]); } #[test] fn cmp_properties() { rounding_mode_pair_gen().test_properties(|(x, y)| { let ord = x.cmp(&y); assert_eq!(y.cmp(&x).reverse(), ord); }); rounding_mode_gen().test_properties(|x| { assert_eq!(x.cmp(&x), Equal); }); rounding_mode_triple_gen().test_properties(|(x, y, z)| { if x < y && y < z { assert!(x < z); } else if x > y && y > z { assert!(x > z); } }); } malachite-base-0.4.16/tests/rounding_modes/eq.rs000064400000000000000000000021151046102023000177030ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::rounding_modes::RoundingMode; use malachite_base::test_util::common::test_eq_helper; use malachite_base::test_util::generators::{ rounding_mode_gen, rounding_mode_pair_gen, rounding_mode_triple_gen, }; #[test] fn test_eq() { test_eq_helper::(&["Down", "Up", "Floor", "Ceiling", "Nearest", "Exact"]); } #[test] #[allow(clippy::eq_op)] fn eq_properties() { rounding_mode_pair_gen().test_properties(|(x, y)| { assert_eq!(x == y, y == x); }); rounding_mode_gen().test_properties(|rm| { assert_eq!(rm, rm); }); rounding_mode_triple_gen().test_properties(|(x, y, z)| { if x == y && x == z { assert_eq!(x, z); } }); } malachite-base-0.4.16/tests/rounding_modes/exhaustive.rs000064400000000000000000000013011046102023000214570ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::rounding_modes::exhaustive::exhaustive_rounding_modes; use malachite_base::rounding_modes::RoundingMode::*; #[test] fn test_exhaustive_rounding_modes() { assert_eq!( exhaustive_rounding_modes().collect_vec(), &[Down, Up, Floor, Ceiling, Nearest, Exact] ); } malachite-base-0.4.16/tests/rounding_modes/from_str.rs000064400000000000000000000027701046102023000211400ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::rounding_modes::RoundingMode::{self, *}; use malachite_base::test_util::generators::common::GenConfig; use malachite_base::test_util::generators::{string_gen, string_gen_var_2}; use std::str::FromStr; #[test] fn test_from_str() { let test = |s, out| { assert_eq!(RoundingMode::from_str(s), out); }; test("Down", Ok(Down)); test("Up", Ok(Up)); test("Floor", Ok(Floor)); test("Ceiling", Ok(Ceiling)); test("Nearest", Ok(Nearest)); test("Exact", Ok(Exact)); test("", Err("".to_string())); test("abc", Err("abc".to_string())); test("Uptown", Err("Uptown".to_string())); } #[allow(clippy::needless_pass_by_value)] fn from_str_helper(s: String) { let result = RoundingMode::from_str(&s); if let Ok(result) = result { assert_eq!(result.to_string(), s); } } #[test] fn from_str_properties() { let mut config = GenConfig::new(); config.insert("mean_length_n", 128); config.insert("mean_length_d", 1); string_gen().test_properties_with_config(&config, from_str_helper); string_gen_var_2().test_properties_with_config(&config, from_str_helper); } malachite-base-0.4.16/tests/rounding_modes/hash.rs000064400000000000000000000011541046102023000202230ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::test_util::generators::rounding_mode_gen; use malachite_base::test_util::hash::hash; #[test] fn hash_properties() { rounding_mode_gen().test_properties(|rm| { assert_eq!(hash(&rm), hash(&rm.clone())); }); } malachite-base-0.4.16/tests/rounding_modes/neg.rs000064400000000000000000000020611046102023000200470ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::NegAssign; use malachite_base::rounding_modes::RoundingMode::{self, *}; use malachite_base::test_util::generators::rounding_mode_gen; #[test] fn test_neg() { let test = |mut rm: RoundingMode, out| { assert_eq!(-rm, out); rm.neg_assign(); assert_eq!(rm, out); }; test(Down, Down); test(Up, Up); test(Floor, Ceiling); test(Ceiling, Floor); test(Nearest, Nearest); test(Exact, Exact); } #[test] fn neg_properties() { rounding_mode_gen().test_properties(|rm| { assert_eq!(-(-rm), rm); let mut rm_alt = rm; rm_alt.neg_assign(); assert_eq!(rm_alt, -rm); }); } malachite-base-0.4.16/tests/rounding_modes/random.rs000064400000000000000000000025471046102023000205670ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::random::EXAMPLE_SEED; use malachite_base::rounding_modes::random::random_rounding_modes; use malachite_base::rounding_modes::RoundingMode::*; use malachite_base::test_util::stats::common_values_map::common_values_map; #[test] fn test_random_rounding_modes() { let xs = random_rounding_modes(EXAMPLE_SEED); let values = xs.clone().take(20).collect_vec(); let common_values = common_values_map(1000000, 10, xs.clone()); assert_eq!( (values.as_slice(), common_values.as_slice()), ( &[ Up, Exact, Ceiling, Up, Floor, Nearest, Exact, Up, Floor, Exact, Nearest, Down, Exact, Down, Floor, Exact, Floor, Down, Nearest, Down ][..], &[ (Ceiling, 167408), (Down, 167104), (Nearest, 166935), (Exact, 166549), (Floor, 166068), (Up, 165936) ][..] ) ); } malachite-base-0.4.16/tests/rounding_modes/size.rs000064400000000000000000000010131046102023000202440ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::rounding_modes::RoundingMode; use std::mem::size_of; #[test] fn test_size() { assert_eq!(size_of::(), 1); } malachite-base-0.4.16/tests/rounding_modes/to_string.rs000064400000000000000000000022051046102023000213060ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::rounding_modes::RoundingMode::{self, *}; use malachite_base::strings::string_is_subset; use malachite_base::test_util::generators::rounding_mode_gen; use malachite_base::test_util::rounding_modes::ROUNDING_MODE_CHARS; use std::str::FromStr; #[test] fn test_to_string() { let test = |rm: RoundingMode, out| { assert_eq!(rm.to_string(), out); }; test(Down, "Down"); test(Up, "Up"); test(Floor, "Floor"); test(Ceiling, "Ceiling"); test(Nearest, "Nearest"); test(Exact, "Exact"); } #[test] fn to_string_properties() { rounding_mode_gen().test_properties(|rm| { let s = rm.to_string(); assert_eq!(RoundingMode::from_str(&s), Ok(rm)); assert!(string_is_subset(&s, ROUNDING_MODE_CHARS)); }); } malachite-base-0.4.16/tests/sets/exhaustive/exhaustive_b_tree_sets.rs000064400000000000000000000067161046102023000242030ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::sets::exhaustive::exhaustive_b_tree_sets; use malachite_base::test_util::sets::exhaustive::{ exhaustive_b_tree_sets_helper_helper, exhaustive_b_tree_sets_small_helper_helper, }; use malachite_base::tuples::exhaustive::exhaustive_units; use std::collections::BTreeSet; use std::fmt::Debug; fn exhaustive_b_tree_sets_helper(xs: I, out: &[BTreeSet]) where I::Item: Clone + Debug + Ord, { exhaustive_b_tree_sets_helper_helper(exhaustive_b_tree_sets(xs), out); } fn exhaustive_b_tree_sets_small_helper( xs: I, out_len: usize, out: &[BTreeSet], ) where I::Item: Clone + Debug + Ord, { exhaustive_b_tree_sets_small_helper_helper(exhaustive_b_tree_sets(xs), out_len, out); } #[test] fn test_exhaustive_b_tree_sets() { exhaustive_b_tree_sets_small_helper(nevers(), 1, &[btreeset! {}]); exhaustive_b_tree_sets_small_helper(exhaustive_units(), 2, &[btreeset! {}, btreeset! {()}]); exhaustive_b_tree_sets_small_helper( exhaustive_bools(), 4, &[btreeset! {}, btreeset! {false}, btreeset! {true}, btreeset! {false, true}], ); exhaustive_b_tree_sets_small_helper( 1..=6, 64, &[ btreeset! {}, btreeset! {1}, btreeset! {2}, btreeset! {1, 2}, btreeset! {3}, btreeset! {1, 3}, btreeset! {2, 3}, btreeset! {1, 2, 3}, btreeset! {4}, btreeset! {1, 4}, btreeset! {2, 4}, btreeset! {1, 2, 4}, btreeset! {3, 4}, btreeset! {1, 3, 4}, btreeset! {2, 3, 4}, btreeset! {1, 2, 3, 4}, btreeset! {5}, btreeset! {1, 5}, btreeset! {2, 5}, btreeset! {1, 2, 5}, ], ); exhaustive_b_tree_sets_small_helper( 'a'..='c', 8, &[ btreeset! {}, btreeset! {'a'}, btreeset! {'b'}, btreeset! {'a', 'b'}, btreeset! {'c'}, btreeset! {'a', 'c'}, btreeset! {'b', 'c'}, btreeset! {'a', 'b', 'c'}, ], ); exhaustive_b_tree_sets_helper( exhaustive_ascii_chars(), &[ btreeset! {}, btreeset! {'a'}, btreeset! {'b'}, btreeset! {'a', 'b'}, btreeset! {'c'}, btreeset! {'a', 'c'}, btreeset! {'b', 'c'}, btreeset! {'a', 'b', 'c'}, btreeset! {'d'}, btreeset! {'a', 'd'}, btreeset! {'b', 'd'}, btreeset! {'a', 'b', 'd'}, btreeset! {'c', 'd'}, btreeset! {'a', 'c', 'd'}, btreeset! {'b', 'c', 'd'}, btreeset! {'a', 'b', 'c', 'd'}, btreeset! {'e'}, btreeset! {'a', 'e'}, btreeset! {'b', 'e'}, btreeset! {'a', 'b', 'e'}, ], ); } malachite-base-0.4.16/tests/sets/exhaustive/exhaustive_b_tree_sets_fixed_length.rs000064400000000000000000000202251046102023000267120ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::num::exhaustive::exhaustive_unsigneds; use malachite_base::sets::exhaustive::exhaustive_b_tree_sets_fixed_length; use malachite_base::test_util::sets::exhaustive::{ exhaustive_b_tree_sets_helper_helper, exhaustive_b_tree_sets_small_helper_helper, }; use malachite_base::tuples::exhaustive::exhaustive_units; use malachite_base::vecs::exhaustive::exhaustive_ordered_unique_vecs_fixed_length; use std::collections::BTreeSet; use std::fmt::Debug; fn exhaustive_b_tree_sets_fixed_length_helper( len: u64, xs: I, out: &[BTreeSet], ) where I::Item: Clone + Debug + Ord, { exhaustive_b_tree_sets_helper_helper(exhaustive_b_tree_sets_fixed_length(len, xs), out); } fn exhaustive_b_tree_sets_fixed_length_small_helper( len: u64, xs: I, out_len: usize, out: &[BTreeSet], ) where I::Item: Clone + Debug + Ord, { exhaustive_b_tree_sets_small_helper_helper( exhaustive_b_tree_sets_fixed_length(len, xs), out_len, out, ); } #[test] fn test_exhaustive_b_tree_sets_fixed_length() { // This demonstrates that 0 ^ 0 == 1: exhaustive_b_tree_sets_fixed_length_small_helper(0, nevers(), 1, &[btreeset! {}]); exhaustive_b_tree_sets_fixed_length_small_helper(1, nevers(), 0, &[]); exhaustive_b_tree_sets_fixed_length_small_helper(2, nevers(), 0, &[]); exhaustive_b_tree_sets_fixed_length_small_helper(5, nevers(), 0, &[]); exhaustive_b_tree_sets_fixed_length_small_helper(1, exhaustive_units(), 1, &[btreeset! {()}]); exhaustive_b_tree_sets_fixed_length_small_helper(2, exhaustive_units(), 0, &[]); exhaustive_b_tree_sets_fixed_length_small_helper(5, exhaustive_units(), 0, &[]); exhaustive_b_tree_sets_fixed_length_small_helper( 0, exhaustive_unsigneds::(), 1, &[btreeset! {}], ); exhaustive_b_tree_sets_fixed_length_small_helper( 1, exhaustive_unsigneds::(), 256, &[ btreeset! {0}, btreeset! {1}, btreeset! {2}, btreeset! {3}, btreeset! {4}, btreeset! {5}, btreeset! {6}, btreeset! {7}, btreeset! {8}, btreeset! {9}, btreeset! {10}, btreeset! {11}, btreeset! {12}, btreeset! {13}, btreeset! {14}, btreeset! {15}, btreeset! {16}, btreeset! {17}, btreeset! {18}, btreeset! {19}, ], ); exhaustive_b_tree_sets_fixed_length_helper( 1, exhaustive_unsigneds::(), &[ btreeset! {0}, btreeset! {1}, btreeset! {2}, btreeset! {3}, btreeset! {4}, btreeset! {5}, btreeset! {6}, btreeset! {7}, btreeset! {8}, btreeset! {9}, btreeset! {10}, btreeset! {11}, btreeset! {12}, btreeset! {13}, btreeset! {14}, btreeset! {15}, btreeset! {16}, btreeset! {17}, btreeset! {18}, btreeset! {19}, ], ); exhaustive_b_tree_sets_fixed_length_small_helper( 2, exhaustive_unsigneds::(), 32640, &[ btreeset! {0, 1}, btreeset! {0, 2}, btreeset! {1, 2}, btreeset! {0, 3}, btreeset! {1, 3}, btreeset! {2, 3}, btreeset! {0, 4}, btreeset! {1, 4}, btreeset! {2, 4}, btreeset! {3, 4}, btreeset! {0, 5}, btreeset! {1, 5}, btreeset! {2, 5}, btreeset! {3, 5}, btreeset! {4, 5}, btreeset! {0, 6}, btreeset! {1, 6}, btreeset! {2, 6}, btreeset! {3, 6}, btreeset! {4, 6}, ], ); exhaustive_b_tree_sets_fixed_length_helper( 3, exhaustive_unsigneds::(), &[ btreeset! {0, 1, 2}, btreeset! {0, 1, 3}, btreeset! {0, 2, 3}, btreeset! {1, 2, 3}, btreeset! {0, 1, 4}, btreeset! {0, 2, 4}, btreeset! {1, 2, 4}, btreeset! {0, 3, 4}, btreeset! {1, 3, 4}, btreeset! {2, 3, 4}, btreeset! {0, 1, 5}, btreeset! {0, 2, 5}, btreeset! {1, 2, 5}, btreeset! {0, 3, 5}, btreeset! {1, 3, 5}, btreeset! {2, 3, 5}, btreeset! {0, 4, 5}, btreeset! {1, 4, 5}, btreeset! {2, 4, 5}, btreeset! {3, 4, 5}, ], ); exhaustive_b_tree_sets_fixed_length_small_helper( 2, exhaustive_ascii_chars(), 8128, &[ btreeset! {'a', 'b'}, btreeset! {'a', 'c'}, btreeset! {'b', 'c'}, btreeset! {'a', 'd'}, btreeset! {'b', 'd'}, btreeset! {'c', 'd'}, btreeset! {'a', 'e'}, btreeset! {'b', 'e'}, btreeset! {'c', 'e'}, btreeset! {'d', 'e'}, btreeset! {'a', 'f'}, btreeset! {'b', 'f'}, btreeset! {'c', 'f'}, btreeset! {'d', 'f'}, btreeset! {'e', 'f'}, btreeset! {'a', 'g'}, btreeset! {'b', 'g'}, btreeset! {'c', 'g'}, btreeset! {'d', 'g'}, btreeset! {'e', 'g'}, ], ); exhaustive_b_tree_sets_fixed_length_small_helper( 1, exhaustive_bools(), 2, &[btreeset! {false}, btreeset! {true}], ); exhaustive_b_tree_sets_fixed_length_small_helper( 2, exhaustive_bools(), 1, &[btreeset! {false, true}], ); exhaustive_b_tree_sets_fixed_length_small_helper(4, exhaustive_bools(), 0, &[]); exhaustive_b_tree_sets_fixed_length_small_helper( 4, 1..=6, 15, &[ btreeset! {1, 2, 3, 4}, btreeset! {1, 2, 3, 5}, btreeset! {1, 2, 4, 5}, btreeset! {1, 3, 4, 5}, btreeset! {2, 3, 4, 5}, btreeset! {1, 2, 3, 6}, btreeset! {1, 2, 4, 6}, btreeset! {1, 3, 4, 6}, btreeset! {2, 3, 4, 6}, btreeset! {1, 2, 5, 6}, btreeset! {1, 3, 5, 6}, btreeset! {2, 3, 5, 6}, btreeset! {1, 4, 5, 6}, btreeset! {2, 4, 5, 6}, btreeset! {3, 4, 5, 6}, ], ); exhaustive_b_tree_sets_fixed_length_helper( 2, exhaustive_ordered_unique_vecs_fixed_length(2, exhaustive_unsigneds::()), &[ btreeset! {vec![0, 1], vec![0, 2]}, btreeset! {vec![0, 1], vec![1, 2]}, btreeset! {vec![0, 2], vec![1, 2]}, btreeset! {vec![0, 1], vec![0, 3]}, btreeset! {vec![0, 2], vec![0, 3]}, btreeset! {vec![1, 2], vec![0, 3]}, btreeset! {vec![0, 1], vec![1, 3]}, btreeset! {vec![0, 2], vec![1, 3]}, btreeset! {vec![1, 2], vec![1, 3]}, btreeset! {vec![0, 3], vec![1, 3]}, btreeset! {vec![0, 1], vec![2, 3]}, btreeset! {vec![0, 2], vec![2, 3]}, btreeset! {vec![1, 2], vec![2, 3]}, btreeset! {vec![0, 3], vec![2, 3]}, btreeset! {vec![1, 3], vec![2, 3]}, btreeset! {vec![0, 1], vec![0, 4]}, btreeset! {vec![0, 2], vec![0, 4]}, btreeset! {vec![1, 2], vec![0, 4]}, btreeset! {vec![0, 3], vec![0, 4]}, btreeset! {vec![1, 3], vec![0, 4]}, ], ); } malachite-base-0.4.16/tests/sets/exhaustive/exhaustive_b_tree_sets_length_inclusive_range.rs000064400000000000000000000042301046102023000307660ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::nevers::nevers; use malachite_base::sets::exhaustive::exhaustive_b_tree_sets_length_inclusive_range; use malachite_base::test_util::sets::exhaustive::exhaustive_b_tree_sets_small_helper_helper; use malachite_base::tuples::exhaustive::exhaustive_units; use std::collections::BTreeSet; use std::fmt::Debug; fn exhaustive_b_tree_sets_length_inclusive_range_small_helper( a: u64, b: u64, xs: I, out_len: usize, out: &[BTreeSet], ) where I::Item: Clone + Debug + Ord, { exhaustive_b_tree_sets_small_helper_helper( exhaustive_b_tree_sets_length_inclusive_range(a, b, xs), out_len, out, ); } #[test] fn test_exhaustive_b_tree_sets_length_inclusive_range() { exhaustive_b_tree_sets_length_inclusive_range_small_helper(0, 4, nevers(), 1, &[btreeset! {}]); exhaustive_b_tree_sets_length_inclusive_range_small_helper(6, 9, nevers(), 0, &[]); exhaustive_b_tree_sets_length_inclusive_range_small_helper( 0, 4, exhaustive_units(), 2, &[btreeset! {}, btreeset! {()}], ); exhaustive_b_tree_sets_length_inclusive_range_small_helper(1, 0, exhaustive_bools(), 0, &[]); exhaustive_b_tree_sets_length_inclusive_range_small_helper( 0, 1, exhaustive_bools(), 3, &[btreeset! {}, btreeset! {false}, btreeset! {true}], ); exhaustive_b_tree_sets_length_inclusive_range_small_helper( 2, 3, exhaustive_bools(), 1, &[btreeset! {false, true}], ); exhaustive_b_tree_sets_length_inclusive_range_small_helper( 1, 1, 'a'..='c', 3, &[btreeset! {'a'}, btreeset! {'b'}, btreeset! {'c'}], ); } malachite-base-0.4.16/tests/sets/exhaustive/exhaustive_b_tree_sets_length_range.rs000064400000000000000000000042031046102023000267050ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::nevers::nevers; use malachite_base::sets::exhaustive::exhaustive_b_tree_sets_length_range; use malachite_base::test_util::sets::exhaustive::exhaustive_b_tree_sets_small_helper_helper; use malachite_base::tuples::exhaustive::exhaustive_units; use std::collections::BTreeSet; use std::fmt::Debug; fn exhaustive_b_tree_sets_length_range_small_helper( a: u64, b: u64, xs: I, out_len: usize, out: &[BTreeSet], ) where I::Item: Clone + Debug + Ord, { exhaustive_b_tree_sets_small_helper_helper( exhaustive_b_tree_sets_length_range(a, b, xs), out_len, out, ); } #[test] fn test_exhaustive_b_tree_sets_length_range() { exhaustive_b_tree_sets_length_range_small_helper(0, 5, nevers(), 1, &[btreeset! {}]); exhaustive_b_tree_sets_length_range_small_helper(6, 10, nevers(), 0, &[]); exhaustive_b_tree_sets_length_range_small_helper( 0, 5, exhaustive_units(), 2, &[btreeset! {}, btreeset! {()}], ); exhaustive_b_tree_sets_length_range_small_helper(1, 0, exhaustive_bools(), 0, &[]); exhaustive_b_tree_sets_length_range_small_helper(1, 1, exhaustive_bools(), 0, &[]); exhaustive_b_tree_sets_length_range_small_helper( 0, 2, exhaustive_bools(), 3, &[btreeset! {}, btreeset! {false}, btreeset! {true}], ); exhaustive_b_tree_sets_length_range_small_helper( 2, 4, exhaustive_bools(), 1, &[btreeset! {false, true}], ); exhaustive_b_tree_sets_length_range_small_helper( 1, 2, 'a'..='c', 3, &[btreeset! {'a'}, btreeset! {'b'}, btreeset! {'c'}], ); } malachite-base-0.4.16/tests/sets/exhaustive/exhaustive_b_tree_sets_min_length.rs000064400000000000000000000111131046102023000263720ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::sets::exhaustive::exhaustive_b_tree_sets_min_length; use malachite_base::test_util::sets::exhaustive::{ exhaustive_b_tree_sets_helper_helper, exhaustive_b_tree_sets_small_helper_helper, }; use malachite_base::tuples::exhaustive::exhaustive_units; use std::collections::BTreeSet; use std::fmt::Debug; fn exhaustive_b_tree_sets_min_length_helper( min_length: u64, xs: I, out: &[BTreeSet], ) where I::Item: Clone + Debug + Ord, { exhaustive_b_tree_sets_helper_helper(exhaustive_b_tree_sets_min_length(min_length, xs), out); } fn exhaustive_b_tree_sets_min_length_small_helper( min_length: u64, xs: I, out_len: usize, out: &[BTreeSet], ) where I::Item: Clone + Debug + Ord, { exhaustive_b_tree_sets_small_helper_helper( exhaustive_b_tree_sets_min_length(min_length, xs), out_len, out, ); } #[test] fn test_exhaustive_b_tree_sets_min_length() { exhaustive_b_tree_sets_min_length_small_helper(0, nevers(), 1, &[btreeset! {}]); exhaustive_b_tree_sets_min_length_small_helper(4, nevers(), 0, &[]); exhaustive_b_tree_sets_min_length_small_helper( 0, exhaustive_units(), 2, &[btreeset! {}, btreeset! {()}], ); exhaustive_b_tree_sets_min_length_small_helper(5, exhaustive_units(), 0, &[]); exhaustive_b_tree_sets_min_length_small_helper( 0, exhaustive_bools(), 4, &[btreeset! {}, btreeset! {false}, btreeset! {true}, btreeset! {false, true}], ); exhaustive_b_tree_sets_min_length_small_helper( 1, exhaustive_bools(), 3, &[btreeset! {false}, btreeset! {true}, btreeset! {false, true}], ); exhaustive_b_tree_sets_min_length_small_helper( 0, 'a'..='c', 8, &[ btreeset! {}, btreeset! {'a'}, btreeset! {'b'}, btreeset! {'a', 'b'}, btreeset! {'c'}, btreeset! {'a', 'c'}, btreeset! {'b', 'c'}, btreeset! {'a', 'b', 'c'}, ], ); exhaustive_b_tree_sets_min_length_small_helper( 2, 'a'..='c', 4, &[ btreeset! {'a', 'b'}, btreeset! {'a', 'c'}, btreeset! {'b', 'c'}, btreeset! {'a', 'b', 'c'}, ], ); exhaustive_b_tree_sets_min_length_helper( 0, exhaustive_ascii_chars(), &[ btreeset! {}, btreeset! {'a'}, btreeset! {'b'}, btreeset! {'a', 'b'}, btreeset! {'c'}, btreeset! {'a', 'c'}, btreeset! {'b', 'c'}, btreeset! {'a', 'b', 'c'}, btreeset! {'d'}, btreeset! {'a', 'd'}, btreeset! {'b', 'd'}, btreeset! {'a', 'b', 'd'}, btreeset! {'c', 'd'}, btreeset! {'a', 'c', 'd'}, btreeset! {'b', 'c', 'd'}, btreeset! {'a', 'b', 'c', 'd'}, btreeset! {'e'}, btreeset! {'a', 'e'}, btreeset! {'b', 'e'}, btreeset! {'a', 'b', 'e'}, ], ); exhaustive_b_tree_sets_min_length_helper( 3, exhaustive_ascii_chars(), &[ btreeset! {'a', 'b', 'c'}, btreeset! {'a', 'b', 'd'}, btreeset! {'a', 'c', 'd'}, btreeset! {'b', 'c', 'd'}, btreeset! {'a', 'b', 'c', 'd'}, btreeset! {'a', 'b', 'e'}, btreeset! {'a', 'c', 'e'}, btreeset! {'b', 'c', 'e'}, btreeset! {'a', 'b', 'c', 'e'}, btreeset! {'a', 'd', 'e'}, btreeset! {'b', 'd', 'e'}, btreeset! {'a', 'b', 'd', 'e'}, btreeset! {'c', 'd', 'e'}, btreeset! {'a', 'c', 'd', 'e'}, btreeset! {'b', 'c', 'd', 'e'}, btreeset! {'a', 'b', 'c', 'd', 'e'}, btreeset! {'a', 'b', 'f'}, btreeset! {'a', 'c', 'f'}, btreeset! {'b', 'c', 'f'}, btreeset! {'a', 'b', 'c', 'f'}, ], ); } malachite-base-0.4.16/tests/sets/exhaustive/exhaustive_hash_sets.rs000064400000000000000000000066251046102023000236650ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::sets::exhaustive::exhaustive_hash_sets; use malachite_base::test_util::sets::exhaustive::{ exhaustive_hash_sets_helper_helper, exhaustive_hash_sets_small_helper_helper, }; use malachite_base::tuples::exhaustive::exhaustive_units; use std::collections::HashSet; use std::fmt::Debug; use std::hash::Hash; fn exhaustive_hash_sets_helper(xs: I, out: &[HashSet]) where I::Item: Clone + Debug + Eq + Hash, { exhaustive_hash_sets_helper_helper(exhaustive_hash_sets(xs), out); } fn exhaustive_hash_sets_small_helper( xs: I, out_len: usize, out: &[HashSet], ) where I::Item: Clone + Debug + Eq + Hash, { exhaustive_hash_sets_small_helper_helper(exhaustive_hash_sets(xs), out_len, out); } #[test] fn test_exhaustive_hash_sets() { exhaustive_hash_sets_small_helper(nevers(), 1, &[hashset! {}]); exhaustive_hash_sets_small_helper(exhaustive_units(), 2, &[hashset! {}, hashset! {()}]); exhaustive_hash_sets_small_helper( exhaustive_bools(), 4, &[hashset! {}, hashset! {false}, hashset! {true}, hashset! {false, true}], ); exhaustive_hash_sets_small_helper( 1..=6, 64, &[ hashset! {}, hashset! {1}, hashset! {2}, hashset! {1, 2}, hashset! {3}, hashset! {1, 3}, hashset! {2, 3}, hashset! {1, 2, 3}, hashset! {4}, hashset! {1, 4}, hashset! {2, 4}, hashset! {1, 2, 4}, hashset! {3, 4}, hashset! {1, 3, 4}, hashset! {2, 3, 4}, hashset! {1, 2, 3, 4}, hashset! {5}, hashset! {1, 5}, hashset! {2, 5}, hashset! {1, 2, 5}, ], ); exhaustive_hash_sets_small_helper( 'a'..='c', 8, &[ hashset! {}, hashset! {'a'}, hashset! {'b'}, hashset! {'a', 'b'}, hashset! {'c'}, hashset! {'a', 'c'}, hashset! {'b', 'c'}, hashset! {'a', 'b', 'c'}, ], ); exhaustive_hash_sets_helper( exhaustive_ascii_chars(), &[ hashset! {}, hashset! {'a'}, hashset! {'b'}, hashset! {'a', 'b'}, hashset! {'c'}, hashset! {'a', 'c'}, hashset! {'b', 'c'}, hashset! {'a', 'b', 'c'}, hashset! {'d'}, hashset! {'a', 'd'}, hashset! {'b', 'd'}, hashset! {'a', 'b', 'd'}, hashset! {'c', 'd'}, hashset! {'a', 'c', 'd'}, hashset! {'b', 'c', 'd'}, hashset! {'a', 'b', 'c', 'd'}, hashset! {'e'}, hashset! {'a', 'e'}, hashset! {'b', 'e'}, hashset! {'a', 'b', 'e'}, ], ); } malachite-base-0.4.16/tests/sets/exhaustive/exhaustive_hash_sets_fixed_length.rs000064400000000000000000000177561046102023000264140ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::num::exhaustive::exhaustive_unsigneds; use malachite_base::sets::exhaustive::exhaustive_hash_sets_fixed_length; use malachite_base::test_util::sets::exhaustive::{ exhaustive_hash_sets_helper_helper, exhaustive_hash_sets_small_helper_helper, }; use malachite_base::tuples::exhaustive::exhaustive_units; use malachite_base::vecs::exhaustive::exhaustive_ordered_unique_vecs_fixed_length; use std::collections::HashSet; use std::fmt::Debug; use std::hash::Hash; fn exhaustive_hash_sets_fixed_length_helper( len: u64, xs: I, out: &[HashSet], ) where I::Item: Clone + Debug + Eq + Hash, { exhaustive_hash_sets_helper_helper(exhaustive_hash_sets_fixed_length(len, xs), out); } fn exhaustive_hash_sets_fixed_length_small_helper( len: u64, xs: I, out_len: usize, out: &[HashSet], ) where I::Item: Clone + Debug + Eq + Hash, { exhaustive_hash_sets_small_helper_helper( exhaustive_hash_sets_fixed_length(len, xs), out_len, out, ); } #[test] fn test_exhaustive_hash_sets_fixed_length() { // This demonstrates that 0 ^ 0 == 1: exhaustive_hash_sets_fixed_length_small_helper(0, nevers(), 1, &[hashset! {}]); exhaustive_hash_sets_fixed_length_small_helper(1, nevers(), 0, &[]); exhaustive_hash_sets_fixed_length_small_helper(2, nevers(), 0, &[]); exhaustive_hash_sets_fixed_length_small_helper(5, nevers(), 0, &[]); exhaustive_hash_sets_fixed_length_small_helper(1, exhaustive_units(), 1, &[hashset! {()}]); exhaustive_hash_sets_fixed_length_small_helper(2, exhaustive_units(), 0, &[]); exhaustive_hash_sets_fixed_length_small_helper(5, exhaustive_units(), 0, &[]); exhaustive_hash_sets_fixed_length_small_helper( 0, exhaustive_unsigneds::(), 1, &[hashset! {}], ); exhaustive_hash_sets_fixed_length_small_helper( 1, exhaustive_unsigneds::(), 256, &[ hashset! {0}, hashset! {1}, hashset! {2}, hashset! {3}, hashset! {4}, hashset! {5}, hashset! {6}, hashset! {7}, hashset! {8}, hashset! {9}, hashset! {10}, hashset! {11}, hashset! {12}, hashset! {13}, hashset! {14}, hashset! {15}, hashset! {16}, hashset! {17}, hashset! {18}, hashset! {19}, ], ); exhaustive_hash_sets_fixed_length_helper( 1, exhaustive_unsigneds::(), &[ hashset! {0}, hashset! {1}, hashset! {2}, hashset! {3}, hashset! {4}, hashset! {5}, hashset! {6}, hashset! {7}, hashset! {8}, hashset! {9}, hashset! {10}, hashset! {11}, hashset! {12}, hashset! {13}, hashset! {14}, hashset! {15}, hashset! {16}, hashset! {17}, hashset! {18}, hashset! {19}, ], ); exhaustive_hash_sets_fixed_length_small_helper( 2, exhaustive_unsigneds::(), 32640, &[ hashset! {0, 1}, hashset! {0, 2}, hashset! {1, 2}, hashset! {0, 3}, hashset! {1, 3}, hashset! {2, 3}, hashset! {0, 4}, hashset! {1, 4}, hashset! {2, 4}, hashset! {3, 4}, hashset! {0, 5}, hashset! {1, 5}, hashset! {2, 5}, hashset! {3, 5}, hashset! {4, 5}, hashset! {0, 6}, hashset! {1, 6}, hashset! {2, 6}, hashset! {3, 6}, hashset! {4, 6}, ], ); exhaustive_hash_sets_fixed_length_helper( 3, exhaustive_unsigneds::(), &[ hashset! {0, 1, 2}, hashset! {0, 1, 3}, hashset! {0, 2, 3}, hashset! {1, 2, 3}, hashset! {0, 1, 4}, hashset! {0, 2, 4}, hashset! {1, 2, 4}, hashset! {0, 3, 4}, hashset! {1, 3, 4}, hashset! {2, 3, 4}, hashset! {0, 1, 5}, hashset! {0, 2, 5}, hashset! {1, 2, 5}, hashset! {0, 3, 5}, hashset! {1, 3, 5}, hashset! {2, 3, 5}, hashset! {0, 4, 5}, hashset! {1, 4, 5}, hashset! {2, 4, 5}, hashset! {3, 4, 5}, ], ); exhaustive_hash_sets_fixed_length_small_helper( 2, exhaustive_ascii_chars(), 8128, &[ hashset! {'a', 'b'}, hashset! {'a', 'c'}, hashset! {'b', 'c'}, hashset! {'a', 'd'}, hashset! {'b', 'd'}, hashset! {'c', 'd'}, hashset! {'a', 'e'}, hashset! {'b', 'e'}, hashset! {'c', 'e'}, hashset! {'d', 'e'}, hashset! {'a', 'f'}, hashset! {'b', 'f'}, hashset! {'c', 'f'}, hashset! {'d', 'f'}, hashset! {'e', 'f'}, hashset! {'a', 'g'}, hashset! {'b', 'g'}, hashset! {'c', 'g'}, hashset! {'d', 'g'}, hashset! {'e', 'g'}, ], ); exhaustive_hash_sets_fixed_length_small_helper( 1, exhaustive_bools(), 2, &[hashset! {false}, hashset! {true}], ); exhaustive_hash_sets_fixed_length_small_helper( 2, exhaustive_bools(), 1, &[hashset! {false, true}], ); exhaustive_hash_sets_fixed_length_small_helper(4, exhaustive_bools(), 0, &[]); exhaustive_hash_sets_fixed_length_small_helper( 4, 1..=6, 15, &[ hashset! {1, 2, 3, 4}, hashset! {1, 2, 3, 5}, hashset! {1, 2, 4, 5}, hashset! {1, 3, 4, 5}, hashset! {2, 3, 4, 5}, hashset! {1, 2, 3, 6}, hashset! {1, 2, 4, 6}, hashset! {1, 3, 4, 6}, hashset! {2, 3, 4, 6}, hashset! {1, 2, 5, 6}, hashset! {1, 3, 5, 6}, hashset! {2, 3, 5, 6}, hashset! {1, 4, 5, 6}, hashset! {2, 4, 5, 6}, hashset! {3, 4, 5, 6}, ], ); exhaustive_hash_sets_fixed_length_helper( 2, exhaustive_ordered_unique_vecs_fixed_length(2, exhaustive_unsigneds::()), &[ hashset! {vec![0, 1], vec![0, 2]}, hashset! {vec![0, 1], vec![1, 2]}, hashset! {vec![0, 2], vec![1, 2]}, hashset! {vec![0, 1], vec![0, 3]}, hashset! {vec![0, 2], vec![0, 3]}, hashset! {vec![1, 2], vec![0, 3]}, hashset! {vec![0, 1], vec![1, 3]}, hashset! {vec![0, 2], vec![1, 3]}, hashset! {vec![1, 2], vec![1, 3]}, hashset! {vec![0, 3], vec![1, 3]}, hashset! {vec![0, 1], vec![2, 3]}, hashset! {vec![0, 2], vec![2, 3]}, hashset! {vec![1, 2], vec![2, 3]}, hashset! {vec![0, 3], vec![2, 3]}, hashset! {vec![1, 3], vec![2, 3]}, hashset! {vec![0, 1], vec![0, 4]}, hashset! {vec![0, 2], vec![0, 4]}, hashset! {vec![1, 2], vec![0, 4]}, hashset! {vec![0, 3], vec![0, 4]}, hashset! {vec![1, 3], vec![0, 4]}, ], ); } malachite-base-0.4.16/tests/sets/exhaustive/exhaustive_hash_sets_length_inclusive_range.rs000064400000000000000000000042151046102023000304540ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::nevers::nevers; use malachite_base::sets::exhaustive::exhaustive_hash_sets_length_inclusive_range; use malachite_base::test_util::sets::exhaustive::exhaustive_hash_sets_small_helper_helper; use malachite_base::tuples::exhaustive::exhaustive_units; use std::collections::HashSet; use std::fmt::Debug; use std::hash::Hash; fn exhaustive_hash_sets_length_inclusive_range_small_helper( a: u64, b: u64, xs: I, out_len: usize, out: &[HashSet], ) where I::Item: Clone + Debug + Eq + Hash, { exhaustive_hash_sets_small_helper_helper( exhaustive_hash_sets_length_inclusive_range(a, b, xs), out_len, out, ); } #[test] fn test_exhaustive_hash_sets_length_inclusive_range() { exhaustive_hash_sets_length_inclusive_range_small_helper(0, 4, nevers(), 1, &[hashset! {}]); exhaustive_hash_sets_length_inclusive_range_small_helper(6, 9, nevers(), 0, &[]); exhaustive_hash_sets_length_inclusive_range_small_helper( 0, 4, exhaustive_units(), 2, &[hashset! {}, hashset! {()}], ); exhaustive_hash_sets_length_inclusive_range_small_helper(1, 0, exhaustive_bools(), 0, &[]); exhaustive_hash_sets_length_inclusive_range_small_helper( 0, 1, exhaustive_bools(), 3, &[hashset! {}, hashset! {false}, hashset! {true}], ); exhaustive_hash_sets_length_inclusive_range_small_helper( 2, 3, exhaustive_bools(), 1, &[hashset! {false, true}], ); exhaustive_hash_sets_length_inclusive_range_small_helper( 1, 1, 'a'..='c', 3, &[hashset! {'a'}, hashset! {'b'}, hashset! {'c'}], ); } malachite-base-0.4.16/tests/sets/exhaustive/exhaustive_hash_sets_length_range.rs000064400000000000000000000041661046102023000264000ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::nevers::nevers; use malachite_base::sets::exhaustive::exhaustive_hash_sets_length_range; use malachite_base::test_util::sets::exhaustive::exhaustive_hash_sets_small_helper_helper; use malachite_base::tuples::exhaustive::exhaustive_units; use std::collections::HashSet; use std::fmt::Debug; use std::hash::Hash; fn exhaustive_hash_sets_length_range_small_helper( a: u64, b: u64, xs: I, out_len: usize, out: &[HashSet], ) where I::Item: Clone + Debug + Eq + Hash, { exhaustive_hash_sets_small_helper_helper( exhaustive_hash_sets_length_range(a, b, xs), out_len, out, ); } #[test] fn test_exhaustive_hash_sets_length_range() { exhaustive_hash_sets_length_range_small_helper(0, 5, nevers(), 1, &[hashset! {}]); exhaustive_hash_sets_length_range_small_helper(6, 10, nevers(), 0, &[]); exhaustive_hash_sets_length_range_small_helper( 0, 5, exhaustive_units(), 2, &[hashset! {}, hashset! {()}], ); exhaustive_hash_sets_length_range_small_helper(1, 0, exhaustive_bools(), 0, &[]); exhaustive_hash_sets_length_range_small_helper(1, 1, exhaustive_bools(), 0, &[]); exhaustive_hash_sets_length_range_small_helper( 0, 2, exhaustive_bools(), 3, &[hashset! {}, hashset! {false}, hashset! {true}], ); exhaustive_hash_sets_length_range_small_helper( 2, 4, exhaustive_bools(), 1, &[hashset! {false, true}], ); exhaustive_hash_sets_length_range_small_helper( 1, 2, 'a'..='c', 3, &[hashset! {'a'}, hashset! {'b'}, hashset! {'c'}], ); } malachite-base-0.4.16/tests/sets/exhaustive/exhaustive_hash_sets_min_length.rs000064400000000000000000000107101046102023000260570ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::sets::exhaustive::exhaustive_hash_sets_min_length; use malachite_base::test_util::sets::exhaustive::{ exhaustive_hash_sets_helper_helper, exhaustive_hash_sets_small_helper_helper, }; use malachite_base::tuples::exhaustive::exhaustive_units; use std::collections::HashSet; use std::fmt::Debug; use std::hash::Hash; fn exhaustive_hash_sets_min_length_helper( min_length: u64, xs: I, out: &[HashSet], ) where I::Item: Clone + Debug + Eq + Hash, { exhaustive_hash_sets_helper_helper(exhaustive_hash_sets_min_length(min_length, xs), out); } fn exhaustive_hash_sets_min_length_small_helper( min_length: u64, xs: I, out_len: usize, out: &[HashSet], ) where I::Item: Clone + Debug + Eq + Hash, { exhaustive_hash_sets_small_helper_helper( exhaustive_hash_sets_min_length(min_length, xs), out_len, out, ); } #[test] fn test_exhaustive_hash_sets_min_length() { exhaustive_hash_sets_min_length_small_helper(0, nevers(), 1, &[hashset! {}]); exhaustive_hash_sets_min_length_small_helper(4, nevers(), 0, &[]); exhaustive_hash_sets_min_length_small_helper( 0, exhaustive_units(), 2, &[hashset! {}, hashset! {()}], ); exhaustive_hash_sets_min_length_small_helper(5, exhaustive_units(), 0, &[]); exhaustive_hash_sets_min_length_small_helper( 0, exhaustive_bools(), 4, &[hashset! {}, hashset! {false}, hashset! {true}, hashset! {false, true}], ); exhaustive_hash_sets_min_length_small_helper( 1, exhaustive_bools(), 3, &[hashset! {false}, hashset! {true}, hashset! {false, true}], ); exhaustive_hash_sets_min_length_small_helper( 0, 'a'..='c', 8, &[ hashset! {}, hashset! {'a'}, hashset! {'b'}, hashset! {'a', 'b'}, hashset! {'c'}, hashset! {'a', 'c'}, hashset! {'b', 'c'}, hashset! {'a', 'b', 'c'}, ], ); exhaustive_hash_sets_min_length_small_helper( 2, 'a'..='c', 4, &[hashset! {'a', 'b'}, hashset! {'a', 'c'}, hashset! {'b', 'c'}, hashset! {'a', 'b', 'c'}], ); exhaustive_hash_sets_min_length_helper( 0, exhaustive_ascii_chars(), &[ hashset! {}, hashset! {'a'}, hashset! {'b'}, hashset! {'a', 'b'}, hashset! {'c'}, hashset! {'a', 'c'}, hashset! {'b', 'c'}, hashset! {'a', 'b', 'c'}, hashset! {'d'}, hashset! {'a', 'd'}, hashset! {'b', 'd'}, hashset! {'a', 'b', 'd'}, hashset! {'c', 'd'}, hashset! {'a', 'c', 'd'}, hashset! {'b', 'c', 'd'}, hashset! {'a', 'b', 'c', 'd'}, hashset! {'e'}, hashset! {'a', 'e'}, hashset! {'b', 'e'}, hashset! {'a', 'b', 'e'}, ], ); exhaustive_hash_sets_min_length_helper( 3, exhaustive_ascii_chars(), &[ hashset! {'a', 'b', 'c'}, hashset! {'a', 'b', 'd'}, hashset! {'a', 'c', 'd'}, hashset! {'b', 'c', 'd'}, hashset! {'a', 'b', 'c', 'd'}, hashset! {'a', 'b', 'e'}, hashset! {'a', 'c', 'e'}, hashset! {'b', 'c', 'e'}, hashset! {'a', 'b', 'c', 'e'}, hashset! {'a', 'd', 'e'}, hashset! {'b', 'd', 'e'}, hashset! {'a', 'b', 'd', 'e'}, hashset! {'c', 'd', 'e'}, hashset! {'a', 'c', 'd', 'e'}, hashset! {'b', 'c', 'd', 'e'}, hashset! {'a', 'b', 'c', 'd', 'e'}, hashset! {'a', 'b', 'f'}, hashset! {'a', 'c', 'f'}, hashset! {'b', 'c', 'f'}, hashset! {'a', 'b', 'c', 'f'}, ], ); } malachite-base-0.4.16/tests/sets/exhaustive/lex_b_tree_sets.rs000064400000000000000000000105461046102023000226020ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::sets::exhaustive::lex_b_tree_sets; use malachite_base::test_util::sets::exhaustive::{ exhaustive_b_tree_sets_helper_helper, exhaustive_b_tree_sets_small_helper_helper, }; use malachite_base::tuples::exhaustive::exhaustive_units; use std::collections::BTreeSet; use std::fmt::Debug; fn lex_b_tree_sets_helper(xs: I, out: &[BTreeSet]) where I::Item: Clone + Debug + Eq + Ord, { exhaustive_b_tree_sets_helper_helper(lex_b_tree_sets(xs), out); } fn lex_b_tree_sets_small_helper( xs: I, out_len: usize, out: &[BTreeSet], ) where I::Item: Clone + Debug + Eq + Ord, { exhaustive_b_tree_sets_small_helper_helper(lex_b_tree_sets(xs), out_len, out); } #[test] fn test_lex_b_tree_sets() { lex_b_tree_sets_small_helper(nevers(), 1, &[btreeset! {}]); lex_b_tree_sets_small_helper(exhaustive_units(), 2, &[btreeset! {}, btreeset! {()}]); lex_b_tree_sets_small_helper( exhaustive_bools(), 4, &[btreeset! {}, btreeset! {false}, btreeset! {false, true}, btreeset! {true}], ); lex_b_tree_sets_small_helper( 1..=6, 64, &[ btreeset! {}, btreeset! {1}, btreeset! {1, 2}, btreeset! {1, 2, 3}, btreeset! {1, 2, 3, 4}, btreeset! {1, 2, 3, 4, 5}, btreeset! {1, 2, 3, 4, 5, 6}, btreeset! {1, 2, 3, 4, 6}, btreeset! {1, 2, 3, 5}, btreeset! {1, 2, 3, 5, 6}, btreeset! {1, 2, 3, 6}, btreeset! {1, 2, 4}, btreeset! {1, 2, 4, 5}, btreeset! {1, 2, 4, 5, 6}, btreeset! {1, 2, 4, 6}, btreeset! {1, 2, 5}, btreeset! {1, 2, 5, 6}, btreeset! {1, 2, 6}, btreeset! {1, 3}, btreeset! {1, 3, 4}, ], ); lex_b_tree_sets_small_helper( 'a'..='c', 8, &[ btreeset! {}, btreeset! {'a'}, btreeset! {'a', 'b'}, btreeset! {'a', 'b', 'c'}, btreeset! {'a', 'c'}, btreeset! {'b'}, btreeset! {'b', 'c'}, btreeset! {'c'}, ], ); lex_b_tree_sets_helper( exhaustive_ascii_chars(), &[ btreeset! {}, btreeset! {'a'}, btreeset! {'a', 'b'}, btreeset! {'a', 'b', 'c'}, btreeset! {'a', 'b', 'c', 'd'}, btreeset! {'a', 'b', 'c', 'd', 'e'}, btreeset! {'a', 'b', 'c', 'd', 'e', 'f'}, btreeset! {'a', 'b', 'c', 'd', 'e', 'f', 'g'}, btreeset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'}, btreeset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'}, btreeset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'}, btreeset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'}, btreeset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l'}, btreeset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm'}, btreeset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n'}, btreeset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o'}, btreeset! { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p' }, btreeset! { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q' }, btreeset! { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', }, btreeset! { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', }, ], ); } malachite-base-0.4.16/tests/sets/exhaustive/lex_b_tree_sets_fixed_length.rs000064400000000000000000000175361046102023000253300ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::num::exhaustive::exhaustive_unsigneds; use malachite_base::sets::exhaustive::lex_b_tree_sets_fixed_length; use malachite_base::test_util::sets::exhaustive::{ exhaustive_b_tree_sets_helper_helper, exhaustive_b_tree_sets_small_helper_helper, }; use malachite_base::tuples::exhaustive::exhaustive_units; use malachite_base::vecs::exhaustive::lex_ordered_unique_vecs_fixed_length; use std::collections::BTreeSet; use std::fmt::Debug; fn lex_b_tree_sets_fixed_length_helper(len: u64, xs: I, out: &[BTreeSet]) where I::Item: Clone + Debug + Eq + Ord, { exhaustive_b_tree_sets_helper_helper(lex_b_tree_sets_fixed_length(len, xs), out); } fn lex_b_tree_sets_fixed_length_small_helper( len: u64, xs: I, out_len: usize, out: &[BTreeSet], ) where I::Item: Clone + Debug + Eq + Ord, { exhaustive_b_tree_sets_small_helper_helper(lex_b_tree_sets_fixed_length(len, xs), out_len, out); } #[test] fn test_lex_b_tree_sets_fixed_length() { lex_b_tree_sets_fixed_length_small_helper(0, nevers(), 1, &[btreeset! {}]); lex_b_tree_sets_fixed_length_small_helper(1, nevers(), 0, &[]); lex_b_tree_sets_fixed_length_small_helper(2, nevers(), 0, &[]); lex_b_tree_sets_fixed_length_small_helper(5, nevers(), 0, &[]); lex_b_tree_sets_fixed_length_small_helper(1, exhaustive_units(), 1, &[btreeset! {()}]); lex_b_tree_sets_fixed_length_small_helper(2, exhaustive_units(), 0, &[]); lex_b_tree_sets_fixed_length_small_helper(5, exhaustive_units(), 0, &[]); lex_b_tree_sets_fixed_length_small_helper(0, exhaustive_unsigneds::(), 1, &[btreeset! {}]); lex_b_tree_sets_fixed_length_small_helper( 1, exhaustive_unsigneds::(), 256, &[ btreeset! {0}, btreeset! {1}, btreeset! {2}, btreeset! {3}, btreeset! {4}, btreeset! {5}, btreeset! {6}, btreeset! {7}, btreeset! {8}, btreeset! {9}, btreeset! {10}, btreeset! {11}, btreeset! {12}, btreeset! {13}, btreeset! {14}, btreeset! {15}, btreeset! {16}, btreeset! {17}, btreeset! {18}, btreeset! {19}, ], ); lex_b_tree_sets_fixed_length_helper( 1, exhaustive_unsigneds::(), &[ btreeset! {0}, btreeset! {1}, btreeset! {2}, btreeset! {3}, btreeset! {4}, btreeset! {5}, btreeset! {6}, btreeset! {7}, btreeset! {8}, btreeset! {9}, btreeset! {10}, btreeset! {11}, btreeset! {12}, btreeset! {13}, btreeset! {14}, btreeset! {15}, btreeset! {16}, btreeset! {17}, btreeset! {18}, btreeset! {19}, ], ); lex_b_tree_sets_fixed_length_small_helper( 2, exhaustive_unsigneds::(), 32640, &[ btreeset! {0, 1}, btreeset! {0, 2}, btreeset! {0, 3}, btreeset! {0, 4}, btreeset! {0, 5}, btreeset! {0, 6}, btreeset! {0, 7}, btreeset! {0, 8}, btreeset! {0, 9}, btreeset! {0, 10}, btreeset! {0, 11}, btreeset! {0, 12}, btreeset! {0, 13}, btreeset! {0, 14}, btreeset! {0, 15}, btreeset! {0, 16}, btreeset! {0, 17}, btreeset! {0, 18}, btreeset! {0, 19}, btreeset! {0, 20}, ], ); lex_b_tree_sets_fixed_length_helper( 3, exhaustive_unsigneds::(), &[ btreeset! {0, 1, 2}, btreeset! {0, 1, 3}, btreeset! {0, 1, 4}, btreeset! {0, 1, 5}, btreeset! {0, 1, 6}, btreeset! {0, 1, 7}, btreeset! {0, 1, 8}, btreeset! {0, 1, 9}, btreeset! {0, 1, 10}, btreeset! {0, 1, 11}, btreeset! {0, 1, 12}, btreeset! {0, 1, 13}, btreeset! {0, 1, 14}, btreeset! {0, 1, 15}, btreeset! {0, 1, 16}, btreeset! {0, 1, 17}, btreeset! {0, 1, 18}, btreeset! {0, 1, 19}, btreeset! {0, 1, 20}, btreeset! {0, 1, 21}, ], ); lex_b_tree_sets_fixed_length_small_helper( 2, exhaustive_ascii_chars(), 8128, &[ btreeset! {'a', 'b'}, btreeset! {'a', 'c'}, btreeset! {'a', 'd'}, btreeset! {'a', 'e'}, btreeset! {'a', 'f'}, btreeset! {'a', 'g'}, btreeset! {'a', 'h'}, btreeset! {'a', 'i'}, btreeset! {'a', 'j'}, btreeset! {'a', 'k'}, btreeset! {'a', 'l'}, btreeset! {'a', 'm'}, btreeset! {'a', 'n'}, btreeset! {'a', 'o'}, btreeset! {'a', 'p'}, btreeset! {'a', 'q'}, btreeset! {'a', 'r'}, btreeset! {'a', 's'}, btreeset! {'a', 't'}, btreeset! {'a', 'u'}, ], ); lex_b_tree_sets_fixed_length_small_helper( 1, exhaustive_bools(), 2, &[btreeset! {false}, btreeset! {true}], ); lex_b_tree_sets_fixed_length_small_helper(2, exhaustive_bools(), 1, &[btreeset! {false, true}]); lex_b_tree_sets_fixed_length_small_helper(4, exhaustive_bools(), 0, &[]); lex_b_tree_sets_fixed_length_small_helper( 4, 1..=6, 15, &[ btreeset! {1, 2, 3, 4}, btreeset! {1, 2, 3, 5}, btreeset! {1, 2, 3, 6}, btreeset! {1, 2, 4, 5}, btreeset! {1, 2, 4, 6}, btreeset! {1, 2, 5, 6}, btreeset! {1, 3, 4, 5}, btreeset! {1, 3, 4, 6}, btreeset! {1, 3, 5, 6}, btreeset! {1, 4, 5, 6}, btreeset! {2, 3, 4, 5}, btreeset! {2, 3, 4, 6}, btreeset! {2, 3, 5, 6}, btreeset! {2, 4, 5, 6}, btreeset! {3, 4, 5, 6}, ], ); lex_b_tree_sets_fixed_length_helper( 2, lex_ordered_unique_vecs_fixed_length(2, exhaustive_unsigneds::()), &[ btreeset! {vec![0, 1], vec![0, 2]}, btreeset! {vec![0, 1], vec![0, 3]}, btreeset! {vec![0, 1], vec![0, 4]}, btreeset! {vec![0, 1], vec![0, 5]}, btreeset! {vec![0, 1], vec![0, 6]}, btreeset! {vec![0, 1], vec![0, 7]}, btreeset! {vec![0, 1], vec![0, 8]}, btreeset! {vec![0, 1], vec![0, 9]}, btreeset! {vec![0, 1], vec![0, 10]}, btreeset! {vec![0, 1], vec![0, 11]}, btreeset! {vec![0, 1], vec![0, 12]}, btreeset! {vec![0, 1], vec![0, 13]}, btreeset! {vec![0, 1], vec![0, 14]}, btreeset! {vec![0, 1], vec![0, 15]}, btreeset! {vec![0, 1], vec![0, 16]}, btreeset! {vec![0, 1], vec![0, 17]}, btreeset! {vec![0, 1], vec![0, 18]}, btreeset! {vec![0, 1], vec![0, 19]}, btreeset! {vec![0, 1], vec![0, 20]}, btreeset! {vec![0, 1], vec![0, 21]}, ], ); } malachite-base-0.4.16/tests/sets/exhaustive/lex_b_tree_sets_length_inclusive_range.rs000064400000000000000000000041201046102023000273670ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::nevers::nevers; use malachite_base::sets::exhaustive::lex_b_tree_sets_length_inclusive_range; use malachite_base::test_util::sets::exhaustive::exhaustive_b_tree_sets_small_helper_helper; use malachite_base::tuples::exhaustive::exhaustive_units; use std::collections::BTreeSet; use std::fmt::Debug; fn lex_b_tree_sets_length_inclusive_range_small_helper( a: u64, b: u64, xs: I, out_len: usize, out: &[BTreeSet], ) where I::Item: Clone + Debug + Eq + Ord, { exhaustive_b_tree_sets_small_helper_helper( lex_b_tree_sets_length_inclusive_range(a, b, xs), out_len, out, ); } #[test] fn test_lex_b_tree_sets_length_inclusive_range() { lex_b_tree_sets_length_inclusive_range_small_helper(0, 4, nevers(), 1, &[btreeset! {}]); lex_b_tree_sets_length_inclusive_range_small_helper(6, 9, nevers(), 0, &[]); lex_b_tree_sets_length_inclusive_range_small_helper( 0, 4, exhaustive_units(), 2, &[btreeset! {}, btreeset! {()}], ); lex_b_tree_sets_length_inclusive_range_small_helper(1, 0, exhaustive_bools(), 0, &[]); lex_b_tree_sets_length_inclusive_range_small_helper( 0, 1, exhaustive_bools(), 3, &[btreeset! {}, btreeset! {false}, btreeset! {true}], ); lex_b_tree_sets_length_inclusive_range_small_helper( 2, 3, exhaustive_bools(), 1, &[btreeset! {false, true}], ); lex_b_tree_sets_length_inclusive_range_small_helper( 1, 1, 'a'..='c', 3, &[btreeset! {'a'}, btreeset! {'b'}, btreeset! {'c'}], ); } malachite-base-0.4.16/tests/sets/exhaustive/lex_b_tree_sets_length_range.rs000064400000000000000000000040641046102023000253150ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::nevers::nevers; use malachite_base::sets::exhaustive::lex_b_tree_sets_length_range; use malachite_base::test_util::sets::exhaustive::exhaustive_b_tree_sets_small_helper_helper; use malachite_base::tuples::exhaustive::exhaustive_units; use std::collections::BTreeSet; use std::fmt::Debug; fn lex_b_tree_sets_length_range_small_helper( a: u64, b: u64, xs: I, out_len: usize, out: &[BTreeSet], ) where I::Item: Clone + Debug + Eq + Ord, { exhaustive_b_tree_sets_small_helper_helper( lex_b_tree_sets_length_range(a, b, xs), out_len, out, ); } #[test] fn test_lex_b_tree_sets_length_range() { lex_b_tree_sets_length_range_small_helper(0, 5, nevers(), 1, &[btreeset! {}]); lex_b_tree_sets_length_range_small_helper(6, 10, nevers(), 0, &[]); lex_b_tree_sets_length_range_small_helper( 0, 5, exhaustive_units(), 2, &[btreeset! {}, btreeset! {()}], ); lex_b_tree_sets_length_range_small_helper(1, 0, exhaustive_bools(), 0, &[]); lex_b_tree_sets_length_range_small_helper(1, 1, exhaustive_bools(), 0, &[]); lex_b_tree_sets_length_range_small_helper( 0, 2, exhaustive_bools(), 3, &[btreeset! {}, btreeset! {false}, btreeset! {true}], ); lex_b_tree_sets_length_range_small_helper( 2, 4, exhaustive_bools(), 1, &[btreeset! {false, true}], ); lex_b_tree_sets_length_range_small_helper( 1, 2, 'a'..='c', 3, &[btreeset! {'a'}, btreeset! {'b'}, btreeset! {'c'}], ); } malachite-base-0.4.16/tests/sets/exhaustive/lex_b_tree_sets_min_length.rs000064400000000000000000000150421046102023000250020ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::sets::exhaustive::lex_b_tree_sets_min_length; use malachite_base::test_util::sets::exhaustive::{ exhaustive_b_tree_sets_helper_helper, exhaustive_b_tree_sets_small_helper_helper, }; use malachite_base::tuples::exhaustive::exhaustive_units; use std::collections::BTreeSet; use std::fmt::Debug; fn lex_b_tree_sets_min_length_helper( min_length: u64, xs: I, out: &[BTreeSet], ) where I::Item: Clone + Debug + Eq + Ord, { exhaustive_b_tree_sets_helper_helper(lex_b_tree_sets_min_length(min_length, xs), out); } fn lex_b_tree_sets_min_length_small_helper( min_length: u64, xs: I, out_len: usize, out: &[BTreeSet], ) where I::Item: Clone + Debug + Eq + Ord, { exhaustive_b_tree_sets_small_helper_helper( lex_b_tree_sets_min_length(min_length, xs), out_len, out, ); } #[test] fn test_lex_b_tree_sets_min_length() { lex_b_tree_sets_min_length_small_helper(0, nevers(), 1, &[btreeset! {}]); lex_b_tree_sets_min_length_small_helper(4, nevers(), 0, &[]); lex_b_tree_sets_min_length_small_helper( 0, exhaustive_units(), 2, &[btreeset! {}, btreeset! {()}], ); lex_b_tree_sets_min_length_small_helper(5, exhaustive_units(), 0, &[]); lex_b_tree_sets_min_length_small_helper( 0, exhaustive_bools(), 4, &[btreeset! {}, btreeset! {false}, btreeset! {false, true}, btreeset! {true}], ); lex_b_tree_sets_min_length_small_helper( 1, exhaustive_bools(), 3, &[btreeset! {false}, btreeset! {false, true}, btreeset! {true}], ); lex_b_tree_sets_min_length_small_helper( 0, 'a'..='c', 8, &[ btreeset! {}, btreeset! {'a'}, btreeset! {'a', 'b'}, btreeset! {'a', 'b', 'c'}, btreeset! {'a', 'c'}, btreeset! {'b'}, btreeset! {'b', 'c'}, btreeset! {'c'}, ], ); lex_b_tree_sets_min_length_small_helper( 2, 'a'..='c', 4, &[ btreeset! {'a', 'b'}, btreeset! {'a', 'b', 'c'}, btreeset! {'a', 'c'}, btreeset! {'b', 'c'}, ], ); lex_b_tree_sets_min_length_helper( 0, exhaustive_ascii_chars(), &[ btreeset! {}, btreeset! {'a'}, btreeset! {'a', 'b'}, btreeset! {'a', 'b', 'c'}, btreeset! {'a', 'b', 'c', 'd'}, btreeset! {'a', 'b', 'c', 'd', 'e'}, btreeset! {'a', 'b', 'c', 'd', 'e', 'f'}, btreeset! {'a', 'b', 'c', 'd', 'e', 'f', 'g'}, btreeset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'}, btreeset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'}, btreeset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'}, btreeset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'}, btreeset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l'}, btreeset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm'}, btreeset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n'}, btreeset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o'}, btreeset! { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p' }, btreeset! { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q' }, btreeset! { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', }, btreeset! { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', }, ], ); lex_b_tree_sets_min_length_helper( 3, exhaustive_ascii_chars(), &[ btreeset! {'a', 'b', 'c'}, btreeset! {'a', 'b', 'c', 'd'}, btreeset! {'a', 'b', 'c', 'd', 'e'}, btreeset! {'a', 'b', 'c', 'd', 'e', 'f'}, btreeset! {'a', 'b', 'c', 'd', 'e', 'f', 'g'}, btreeset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'}, btreeset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'}, btreeset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'}, btreeset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'}, btreeset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l'}, btreeset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm'}, btreeset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n'}, btreeset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o'}, btreeset! { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p' }, btreeset! { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q' }, btreeset! { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', }, btreeset! { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', }, btreeset! { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', }, btreeset! { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', }, btreeset! { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', }, ], ); } malachite-base-0.4.16/tests/sets/exhaustive/lex_hash_sets.rs000064400000000000000000000104241046102023000222600ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::sets::exhaustive::lex_hash_sets; use malachite_base::test_util::sets::exhaustive::{ exhaustive_hash_sets_helper_helper, exhaustive_hash_sets_small_helper_helper, }; use malachite_base::tuples::exhaustive::exhaustive_units; use std::collections::HashSet; use std::fmt::Debug; use std::hash::Hash; fn lex_hash_sets_helper(xs: I, out: &[HashSet]) where I::Item: Clone + Debug + Eq + Hash, { exhaustive_hash_sets_helper_helper(lex_hash_sets(xs), out); } fn lex_hash_sets_small_helper(xs: I, out_len: usize, out: &[HashSet]) where I::Item: Clone + Debug + Eq + Hash, { exhaustive_hash_sets_small_helper_helper(lex_hash_sets(xs), out_len, out); } #[test] fn test_lex_hash_sets() { lex_hash_sets_small_helper(nevers(), 1, &[hashset! {}]); lex_hash_sets_small_helper(exhaustive_units(), 2, &[hashset! {}, hashset! {()}]); lex_hash_sets_small_helper( exhaustive_bools(), 4, &[hashset! {}, hashset! {false}, hashset! {false, true}, hashset! {true}], ); lex_hash_sets_small_helper( 1..=6, 64, &[ hashset! {}, hashset! {1}, hashset! {1, 2}, hashset! {1, 2, 3}, hashset! {1, 2, 3, 4}, hashset! {1, 2, 3, 4, 5}, hashset! {1, 2, 3, 4, 5, 6}, hashset! {1, 2, 3, 4, 6}, hashset! {1, 2, 3, 5}, hashset! {1, 2, 3, 5, 6}, hashset! {1, 2, 3, 6}, hashset! {1, 2, 4}, hashset! {1, 2, 4, 5}, hashset! {1, 2, 4, 5, 6}, hashset! {1, 2, 4, 6}, hashset! {1, 2, 5}, hashset! {1, 2, 5, 6}, hashset! {1, 2, 6}, hashset! {1, 3}, hashset! {1, 3, 4}, ], ); lex_hash_sets_small_helper( 'a'..='c', 8, &[ hashset! {}, hashset! {'a'}, hashset! {'a', 'b'}, hashset! {'a', 'b', 'c'}, hashset! {'a', 'c'}, hashset! {'b'}, hashset! {'b', 'c'}, hashset! {'c'}, ], ); lex_hash_sets_helper( exhaustive_ascii_chars(), &[ hashset! {}, hashset! {'a'}, hashset! {'a', 'b'}, hashset! {'a', 'b', 'c'}, hashset! {'a', 'b', 'c', 'd'}, hashset! {'a', 'b', 'c', 'd', 'e'}, hashset! {'a', 'b', 'c', 'd', 'e', 'f'}, hashset! {'a', 'b', 'c', 'd', 'e', 'f', 'g'}, hashset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'}, hashset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'}, hashset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'}, hashset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'}, hashset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l'}, hashset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm'}, hashset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n'}, hashset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o'}, hashset! { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p' }, hashset! { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q' }, hashset! { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', }, hashset! { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', }, ], ); } malachite-base-0.4.16/tests/sets/exhaustive/lex_hash_sets_fixed_length.rs000064400000000000000000000172551046102023000250110ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::num::exhaustive::exhaustive_unsigneds; use malachite_base::sets::exhaustive::lex_hash_sets_fixed_length; use malachite_base::test_util::sets::exhaustive::{ exhaustive_hash_sets_helper_helper, exhaustive_hash_sets_small_helper_helper, }; use malachite_base::tuples::exhaustive::exhaustive_units; use malachite_base::vecs::exhaustive::lex_ordered_unique_vecs_fixed_length; use std::collections::HashSet; use std::fmt::Debug; use std::hash::Hash; fn lex_hash_sets_fixed_length_helper(len: u64, xs: I, out: &[HashSet]) where I::Item: Clone + Debug + Eq + Hash, { exhaustive_hash_sets_helper_helper(lex_hash_sets_fixed_length(len, xs), out); } fn lex_hash_sets_fixed_length_small_helper( len: u64, xs: I, out_len: usize, out: &[HashSet], ) where I::Item: Clone + Debug + Eq + Hash, { exhaustive_hash_sets_small_helper_helper(lex_hash_sets_fixed_length(len, xs), out_len, out); } #[test] fn test_lex_hash_sets_fixed_length() { lex_hash_sets_fixed_length_small_helper(0, nevers(), 1, &[hashset! {}]); lex_hash_sets_fixed_length_small_helper(1, nevers(), 0, &[]); lex_hash_sets_fixed_length_small_helper(2, nevers(), 0, &[]); lex_hash_sets_fixed_length_small_helper(5, nevers(), 0, &[]); lex_hash_sets_fixed_length_small_helper(1, exhaustive_units(), 1, &[hashset! {()}]); lex_hash_sets_fixed_length_small_helper(2, exhaustive_units(), 0, &[]); lex_hash_sets_fixed_length_small_helper(5, exhaustive_units(), 0, &[]); lex_hash_sets_fixed_length_small_helper(0, exhaustive_unsigneds::(), 1, &[hashset! {}]); lex_hash_sets_fixed_length_small_helper( 1, exhaustive_unsigneds::(), 256, &[ hashset! {0}, hashset! {1}, hashset! {2}, hashset! {3}, hashset! {4}, hashset! {5}, hashset! {6}, hashset! {7}, hashset! {8}, hashset! {9}, hashset! {10}, hashset! {11}, hashset! {12}, hashset! {13}, hashset! {14}, hashset! {15}, hashset! {16}, hashset! {17}, hashset! {18}, hashset! {19}, ], ); lex_hash_sets_fixed_length_helper( 1, exhaustive_unsigneds::(), &[ hashset! {0}, hashset! {1}, hashset! {2}, hashset! {3}, hashset! {4}, hashset! {5}, hashset! {6}, hashset! {7}, hashset! {8}, hashset! {9}, hashset! {10}, hashset! {11}, hashset! {12}, hashset! {13}, hashset! {14}, hashset! {15}, hashset! {16}, hashset! {17}, hashset! {18}, hashset! {19}, ], ); lex_hash_sets_fixed_length_small_helper( 2, exhaustive_unsigneds::(), 32640, &[ hashset! {0, 1}, hashset! {0, 2}, hashset! {0, 3}, hashset! {0, 4}, hashset! {0, 5}, hashset! {0, 6}, hashset! {0, 7}, hashset! {0, 8}, hashset! {0, 9}, hashset! {0, 10}, hashset! {0, 11}, hashset! {0, 12}, hashset! {0, 13}, hashset! {0, 14}, hashset! {0, 15}, hashset! {0, 16}, hashset! {0, 17}, hashset! {0, 18}, hashset! {0, 19}, hashset! {0, 20}, ], ); lex_hash_sets_fixed_length_helper( 3, exhaustive_unsigneds::(), &[ hashset! {0, 1, 2}, hashset! {0, 1, 3}, hashset! {0, 1, 4}, hashset! {0, 1, 5}, hashset! {0, 1, 6}, hashset! {0, 1, 7}, hashset! {0, 1, 8}, hashset! {0, 1, 9}, hashset! {0, 1, 10}, hashset! {0, 1, 11}, hashset! {0, 1, 12}, hashset! {0, 1, 13}, hashset! {0, 1, 14}, hashset! {0, 1, 15}, hashset! {0, 1, 16}, hashset! {0, 1, 17}, hashset! {0, 1, 18}, hashset! {0, 1, 19}, hashset! {0, 1, 20}, hashset! {0, 1, 21}, ], ); lex_hash_sets_fixed_length_small_helper( 2, exhaustive_ascii_chars(), 8128, &[ hashset! {'a', 'b'}, hashset! {'a', 'c'}, hashset! {'a', 'd'}, hashset! {'a', 'e'}, hashset! {'a', 'f'}, hashset! {'a', 'g'}, hashset! {'a', 'h'}, hashset! {'a', 'i'}, hashset! {'a', 'j'}, hashset! {'a', 'k'}, hashset! {'a', 'l'}, hashset! {'a', 'm'}, hashset! {'a', 'n'}, hashset! {'a', 'o'}, hashset! {'a', 'p'}, hashset! {'a', 'q'}, hashset! {'a', 'r'}, hashset! {'a', 's'}, hashset! {'a', 't'}, hashset! {'a', 'u'}, ], ); lex_hash_sets_fixed_length_small_helper( 1, exhaustive_bools(), 2, &[hashset! {false}, hashset! {true}], ); lex_hash_sets_fixed_length_small_helper(2, exhaustive_bools(), 1, &[hashset! {false, true}]); lex_hash_sets_fixed_length_small_helper(4, exhaustive_bools(), 0, &[]); lex_hash_sets_fixed_length_small_helper( 4, 1..=6, 15, &[ hashset! {1, 2, 3, 4}, hashset! {1, 2, 3, 5}, hashset! {1, 2, 3, 6}, hashset! {1, 2, 4, 5}, hashset! {1, 2, 4, 6}, hashset! {1, 2, 5, 6}, hashset! {1, 3, 4, 5}, hashset! {1, 3, 4, 6}, hashset! {1, 3, 5, 6}, hashset! {1, 4, 5, 6}, hashset! {2, 3, 4, 5}, hashset! {2, 3, 4, 6}, hashset! {2, 3, 5, 6}, hashset! {2, 4, 5, 6}, hashset! {3, 4, 5, 6}, ], ); lex_hash_sets_fixed_length_helper( 2, lex_ordered_unique_vecs_fixed_length(2, exhaustive_unsigneds::()), &[ hashset! {vec![0, 1], vec![0, 2]}, hashset! {vec![0, 1], vec![0, 3]}, hashset! {vec![0, 1], vec![0, 4]}, hashset! {vec![0, 1], vec![0, 5]}, hashset! {vec![0, 1], vec![0, 6]}, hashset! {vec![0, 1], vec![0, 7]}, hashset! {vec![0, 1], vec![0, 8]}, hashset! {vec![0, 1], vec![0, 9]}, hashset! {vec![0, 1], vec![0, 10]}, hashset! {vec![0, 1], vec![0, 11]}, hashset! {vec![0, 1], vec![0, 12]}, hashset! {vec![0, 1], vec![0, 13]}, hashset! {vec![0, 1], vec![0, 14]}, hashset! {vec![0, 1], vec![0, 15]}, hashset! {vec![0, 1], vec![0, 16]}, hashset! {vec![0, 1], vec![0, 17]}, hashset! {vec![0, 1], vec![0, 18]}, hashset! {vec![0, 1], vec![0, 19]}, hashset! {vec![0, 1], vec![0, 20]}, hashset! {vec![0, 1], vec![0, 21]}, ], ); } malachite-base-0.4.16/tests/sets/exhaustive/lex_hash_sets_length_inclusive_range.rs000064400000000000000000000041001046102023000270500ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::nevers::nevers; use malachite_base::sets::exhaustive::lex_hash_sets_length_inclusive_range; use malachite_base::test_util::sets::exhaustive::exhaustive_hash_sets_small_helper_helper; use malachite_base::tuples::exhaustive::exhaustive_units; use std::collections::HashSet; use std::fmt::Debug; use std::hash::Hash; fn lex_hash_sets_length_inclusive_range_small_helper( a: u64, b: u64, xs: I, out_len: usize, out: &[HashSet], ) where I::Item: Clone + Debug + Eq + Hash, { exhaustive_hash_sets_small_helper_helper( lex_hash_sets_length_inclusive_range(a, b, xs), out_len, out, ); } #[test] fn test_lex_hash_sets_length_inclusive_range() { lex_hash_sets_length_inclusive_range_small_helper(0, 4, nevers(), 1, &[hashset! {}]); lex_hash_sets_length_inclusive_range_small_helper(6, 9, nevers(), 0, &[]); lex_hash_sets_length_inclusive_range_small_helper( 0, 4, exhaustive_units(), 2, &[hashset! {}, hashset! {()}], ); lex_hash_sets_length_inclusive_range_small_helper(1, 0, exhaustive_bools(), 0, &[]); lex_hash_sets_length_inclusive_range_small_helper( 0, 1, exhaustive_bools(), 3, &[hashset! {}, hashset! {false}, hashset! {true}], ); lex_hash_sets_length_inclusive_range_small_helper( 2, 3, exhaustive_bools(), 1, &[hashset! {false, true}], ); lex_hash_sets_length_inclusive_range_small_helper( 1, 1, 'a'..='c', 3, &[hashset! {'a'}, hashset! {'b'}, hashset! {'c'}], ); } malachite-base-0.4.16/tests/sets/exhaustive/lex_hash_sets_length_range.rs000064400000000000000000000037241046102023000250020ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::nevers::nevers; use malachite_base::sets::exhaustive::lex_hash_sets_length_range; use malachite_base::test_util::sets::exhaustive::exhaustive_hash_sets_small_helper_helper; use malachite_base::tuples::exhaustive::exhaustive_units; use std::collections::HashSet; use std::fmt::Debug; use std::hash::Hash; fn lex_hash_sets_length_range_small_helper( a: u64, b: u64, xs: I, out_len: usize, out: &[HashSet], ) where I::Item: Clone + Debug + Eq + Hash, { exhaustive_hash_sets_small_helper_helper(lex_hash_sets_length_range(a, b, xs), out_len, out); } #[test] fn test_lex_hash_sets_length_range() { lex_hash_sets_length_range_small_helper(0, 5, nevers(), 1, &[hashset! {}]); lex_hash_sets_length_range_small_helper(6, 10, nevers(), 0, &[]); lex_hash_sets_length_range_small_helper( 0, 5, exhaustive_units(), 2, &[hashset! {}, hashset! {()}], ); lex_hash_sets_length_range_small_helper(1, 0, exhaustive_bools(), 0, &[]); lex_hash_sets_length_range_small_helper(1, 1, exhaustive_bools(), 0, &[]); lex_hash_sets_length_range_small_helper( 0, 2, exhaustive_bools(), 3, &[hashset! {}, hashset! {false}, hashset! {true}], ); lex_hash_sets_length_range_small_helper(2, 4, exhaustive_bools(), 1, &[hashset! {false, true}]); lex_hash_sets_length_range_small_helper( 1, 2, 'a'..='c', 3, &[hashset! {'a'}, hashset! {'b'}, hashset! {'c'}], ); } malachite-base-0.4.16/tests/sets/exhaustive/lex_hash_sets_min_length.rs000064400000000000000000000145561046102023000244760ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::sets::exhaustive::lex_hash_sets_min_length; use malachite_base::test_util::sets::exhaustive::{ exhaustive_hash_sets_helper_helper, exhaustive_hash_sets_small_helper_helper, }; use malachite_base::tuples::exhaustive::exhaustive_units; use std::collections::HashSet; use std::fmt::Debug; use std::hash::Hash; fn lex_hash_sets_min_length_helper( min_length: u64, xs: I, out: &[HashSet], ) where I::Item: Clone + Debug + Eq + Hash, { exhaustive_hash_sets_helper_helper(lex_hash_sets_min_length(min_length, xs), out); } fn lex_hash_sets_min_length_small_helper( min_length: u64, xs: I, out_len: usize, out: &[HashSet], ) where I::Item: Clone + Debug + Eq + Hash, { exhaustive_hash_sets_small_helper_helper( lex_hash_sets_min_length(min_length, xs), out_len, out, ); } #[test] fn test_lex_hash_sets_min_length() { lex_hash_sets_min_length_small_helper(0, nevers(), 1, &[hashset! {}]); lex_hash_sets_min_length_small_helper(4, nevers(), 0, &[]); lex_hash_sets_min_length_small_helper(0, exhaustive_units(), 2, &[hashset! {}, hashset! {()}]); lex_hash_sets_min_length_small_helper(5, exhaustive_units(), 0, &[]); lex_hash_sets_min_length_small_helper( 0, exhaustive_bools(), 4, &[hashset! {}, hashset! {false}, hashset! {false, true}, hashset! {true}], ); lex_hash_sets_min_length_small_helper( 1, exhaustive_bools(), 3, &[hashset! {false}, hashset! {false, true}, hashset! {true}], ); lex_hash_sets_min_length_small_helper( 0, 'a'..='c', 8, &[ hashset! {}, hashset! {'a'}, hashset! {'a', 'b'}, hashset! {'a', 'b', 'c'}, hashset! {'a', 'c'}, hashset! {'b'}, hashset! {'b', 'c'}, hashset! {'c'}, ], ); lex_hash_sets_min_length_small_helper( 2, 'a'..='c', 4, &[hashset! {'a', 'b'}, hashset! {'a', 'b', 'c'}, hashset! {'a', 'c'}, hashset! {'b', 'c'}], ); lex_hash_sets_min_length_helper( 0, exhaustive_ascii_chars(), &[ hashset! {}, hashset! {'a'}, hashset! {'a', 'b'}, hashset! {'a', 'b', 'c'}, hashset! {'a', 'b', 'c', 'd'}, hashset! {'a', 'b', 'c', 'd', 'e'}, hashset! {'a', 'b', 'c', 'd', 'e', 'f'}, hashset! {'a', 'b', 'c', 'd', 'e', 'f', 'g'}, hashset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'}, hashset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'}, hashset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'}, hashset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'}, hashset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l'}, hashset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm'}, hashset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n'}, hashset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o'}, hashset! { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p' }, hashset! { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q' }, hashset! { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', }, hashset! { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', }, ], ); lex_hash_sets_min_length_helper( 3, exhaustive_ascii_chars(), &[ hashset! {'a', 'b', 'c'}, hashset! {'a', 'b', 'c', 'd'}, hashset! {'a', 'b', 'c', 'd', 'e'}, hashset! {'a', 'b', 'c', 'd', 'e', 'f'}, hashset! {'a', 'b', 'c', 'd', 'e', 'f', 'g'}, hashset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'}, hashset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'}, hashset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'}, hashset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'}, hashset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l'}, hashset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm'}, hashset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n'}, hashset! {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o'}, hashset! { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p' }, hashset! { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q' }, hashset! { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', }, hashset! { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', }, hashset! { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', }, hashset! { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', }, hashset! { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', }, ], ); } malachite-base-0.4.16/tests/sets/exhaustive/shortlex_b_tree_sets.rs000064400000000000000000000064771046102023000236720ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::sets::exhaustive::shortlex_b_tree_sets; use malachite_base::test_util::sets::exhaustive::{ exhaustive_b_tree_sets_helper_helper, exhaustive_b_tree_sets_small_helper_helper, }; use malachite_base::tuples::exhaustive::exhaustive_units; use std::collections::BTreeSet; use std::fmt::Debug; fn shortlex_b_tree_sets_helper(xs: I, out: &[BTreeSet]) where I::Item: Clone + Debug + Eq + Ord, { exhaustive_b_tree_sets_helper_helper(shortlex_b_tree_sets(xs), out); } fn shortlex_b_tree_sets_small_helper( xs: I, out_len: usize, out: &[BTreeSet], ) where I::Item: Clone + Debug + Eq + Ord, { exhaustive_b_tree_sets_small_helper_helper(shortlex_b_tree_sets(xs), out_len, out); } #[test] fn test_shortlex_b_tree_sets() { shortlex_b_tree_sets_small_helper(nevers(), 1, &[btreeset! {}]); shortlex_b_tree_sets_small_helper(exhaustive_units(), 2, &[btreeset! {}, btreeset! {()}]); shortlex_b_tree_sets_small_helper( exhaustive_bools(), 4, &[btreeset! {}, btreeset! {false}, btreeset! {true}, btreeset! {false, true}], ); shortlex_b_tree_sets_small_helper( 1..=6, 64, &[ btreeset! {}, btreeset! {1}, btreeset! {2}, btreeset! {3}, btreeset! {4}, btreeset! {5}, btreeset! {6}, btreeset! {1, 2}, btreeset! {1, 3}, btreeset! {1, 4}, btreeset! {1, 5}, btreeset! {1, 6}, btreeset! {2, 3}, btreeset! {2, 4}, btreeset! {2, 5}, btreeset! {2, 6}, btreeset! {3, 4}, btreeset! {3, 5}, btreeset! {3, 6}, btreeset! {4, 5}, ], ); shortlex_b_tree_sets_small_helper( 'a'..='c', 8, &[ btreeset! {}, btreeset! {'a'}, btreeset! {'b'}, btreeset! {'c'}, btreeset! {'a', 'b'}, btreeset! {'a', 'c'}, btreeset! {'b', 'c'}, btreeset! {'a', 'b', 'c'}, ], ); shortlex_b_tree_sets_helper( exhaustive_ascii_chars(), &[ btreeset! {}, btreeset! {'a'}, btreeset! {'b'}, btreeset! {'c'}, btreeset! {'d'}, btreeset! {'e'}, btreeset! {'f'}, btreeset! {'g'}, btreeset! {'h'}, btreeset! {'i'}, btreeset! {'j'}, btreeset! {'k'}, btreeset! {'l'}, btreeset! {'m'}, btreeset! {'n'}, btreeset! {'o'}, btreeset! {'p'}, btreeset! {'q'}, btreeset! {'r'}, btreeset! {'s'}, ], ); } malachite-base-0.4.16/tests/sets/exhaustive/shortlex_b_tree_sets_length_inclusive_range.rs000064400000000000000000000042071046102023000304550ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::nevers::nevers; use malachite_base::sets::exhaustive::shortlex_b_tree_sets_length_inclusive_range; use malachite_base::test_util::sets::exhaustive::exhaustive_b_tree_sets_small_helper_helper; use malachite_base::tuples::exhaustive::exhaustive_units; use std::collections::BTreeSet; use std::fmt::Debug; fn shortlex_b_tree_sets_length_inclusive_range_small_helper( a: u64, b: u64, xs: I, out_len: usize, out: &[BTreeSet], ) where I::Item: Clone + Debug + Eq + Ord, { exhaustive_b_tree_sets_small_helper_helper( shortlex_b_tree_sets_length_inclusive_range(a, b, xs), out_len, out, ); } #[test] fn test_shortlex_b_tree_sets_length_inclusive_range() { shortlex_b_tree_sets_length_inclusive_range_small_helper(0, 4, nevers(), 1, &[btreeset! {}]); shortlex_b_tree_sets_length_inclusive_range_small_helper(6, 9, nevers(), 0, &[]); shortlex_b_tree_sets_length_inclusive_range_small_helper( 0, 5, exhaustive_units(), 2, &[btreeset! {}, btreeset! {()}], ); shortlex_b_tree_sets_length_inclusive_range_small_helper(1, 0, exhaustive_bools(), 0, &[]); shortlex_b_tree_sets_length_inclusive_range_small_helper( 0, 1, exhaustive_bools(), 3, &[btreeset! {}, btreeset! {false}, btreeset! {true}], ); shortlex_b_tree_sets_length_inclusive_range_small_helper( 2, 3, exhaustive_bools(), 1, &[btreeset! {false, true}], ); shortlex_b_tree_sets_length_inclusive_range_small_helper( 1, 1, 'a'..='c', 3, &[btreeset! {'a'}, btreeset! {'b'}, btreeset! {'c'}], ); } malachite-base-0.4.16/tests/sets/exhaustive/shortlex_b_tree_sets_length_range.rs000064400000000000000000000041601046102023000263720ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::nevers::nevers; use malachite_base::sets::exhaustive::shortlex_b_tree_sets_length_range; use malachite_base::test_util::sets::exhaustive::exhaustive_b_tree_sets_small_helper_helper; use malachite_base::tuples::exhaustive::exhaustive_units; use std::collections::BTreeSet; use std::fmt::Debug; fn shortlex_b_tree_sets_length_range_small_helper( a: u64, b: u64, xs: I, out_len: usize, out: &[BTreeSet], ) where I::Item: Clone + Debug + Eq + Ord, { exhaustive_b_tree_sets_small_helper_helper( shortlex_b_tree_sets_length_range(a, b, xs), out_len, out, ); } #[test] fn test_shortlex_b_tree_sets_length_range() { shortlex_b_tree_sets_length_range_small_helper(0, 5, nevers(), 1, &[btreeset! {}]); shortlex_b_tree_sets_length_range_small_helper(6, 10, nevers(), 0, &[]); shortlex_b_tree_sets_length_range_small_helper( 0, 5, exhaustive_units(), 2, &[btreeset! {}, btreeset! {()}], ); shortlex_b_tree_sets_length_range_small_helper(1, 0, exhaustive_bools(), 0, &[]); shortlex_b_tree_sets_length_range_small_helper(1, 1, exhaustive_bools(), 0, &[]); shortlex_b_tree_sets_length_range_small_helper( 0, 2, exhaustive_bools(), 3, &[btreeset! {}, btreeset! {false}, btreeset! {true}], ); shortlex_b_tree_sets_length_range_small_helper( 2, 4, exhaustive_bools(), 1, &[btreeset! {false, true}], ); shortlex_b_tree_sets_length_range_small_helper( 1, 2, 'a'..='c', 3, &[btreeset! {'a'}, btreeset! {'b'}, btreeset! {'c'}], ); } malachite-base-0.4.16/tests/sets/exhaustive/shortlex_b_tree_sets_min_length.rs000064400000000000000000000106441046102023000260650ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::sets::exhaustive::shortlex_b_tree_sets_min_length; use malachite_base::test_util::sets::exhaustive::{ exhaustive_b_tree_sets_helper_helper, exhaustive_b_tree_sets_small_helper_helper, }; use malachite_base::tuples::exhaustive::exhaustive_units; use std::collections::BTreeSet; use std::fmt::Debug; fn shortlex_b_tree_sets_min_length_helper( min_length: u64, xs: I, out: &[BTreeSet], ) where I::Item: Clone + Debug + Eq + Ord, { exhaustive_b_tree_sets_helper_helper(shortlex_b_tree_sets_min_length(min_length, xs), out); } fn shortlex_b_tree_sets_min_length_small_helper( min_length: u64, xs: I, out_len: usize, out: &[BTreeSet], ) where I::Item: Clone + Debug + Eq + Ord, { exhaustive_b_tree_sets_small_helper_helper( shortlex_b_tree_sets_min_length(min_length, xs), out_len, out, ); } #[test] fn test_shortlex_b_tree_sets_min_length() { shortlex_b_tree_sets_min_length_small_helper(0, nevers(), 1, &[btreeset! {}]); shortlex_b_tree_sets_min_length_small_helper(4, nevers(), 0, &[]); shortlex_b_tree_sets_min_length_small_helper( 0, exhaustive_units(), 2, &[btreeset! {}, btreeset! {()}], ); shortlex_b_tree_sets_min_length_small_helper(5, exhaustive_units(), 0, &[]); shortlex_b_tree_sets_min_length_small_helper( 0, exhaustive_bools(), 4, &[btreeset! {}, btreeset! {false}, btreeset! {true}, btreeset! {false, true}], ); shortlex_b_tree_sets_min_length_small_helper( 1, exhaustive_bools(), 3, &[btreeset! {false}, btreeset! {true}, btreeset! {false, true}], ); shortlex_b_tree_sets_min_length_small_helper( 0, 'a'..='c', 8, &[ btreeset! {}, btreeset! {'a'}, btreeset! {'b'}, btreeset! {'c'}, btreeset! {'a', 'b'}, btreeset! {'a', 'c'}, btreeset! {'b', 'c'}, btreeset! {'a', 'b', 'c'}, ], ); shortlex_b_tree_sets_min_length_small_helper( 2, 'a'..='c', 4, &[ btreeset! {'a', 'b'}, btreeset! {'a', 'c'}, btreeset! {'b', 'c'}, btreeset! {'a', 'b', 'c'}, ], ); shortlex_b_tree_sets_min_length_helper( 0, exhaustive_ascii_chars(), &[ btreeset! {}, btreeset! {'a'}, btreeset! {'b'}, btreeset! {'c'}, btreeset! {'d'}, btreeset! {'e'}, btreeset! {'f'}, btreeset! {'g'}, btreeset! {'h'}, btreeset! {'i'}, btreeset! {'j'}, btreeset! {'k'}, btreeset! {'l'}, btreeset! {'m'}, btreeset! {'n'}, btreeset! {'o'}, btreeset! {'p'}, btreeset! {'q'}, btreeset! {'r'}, btreeset! {'s'}, ], ); shortlex_b_tree_sets_min_length_helper( 3, exhaustive_ascii_chars(), &[ btreeset! {'a', 'b', 'c'}, btreeset! {'a', 'b', 'd'}, btreeset! {'a', 'b', 'e'}, btreeset! {'a', 'b', 'f'}, btreeset! {'a', 'b', 'g'}, btreeset! {'a', 'b', 'h'}, btreeset! {'a', 'b', 'i'}, btreeset! {'a', 'b', 'j'}, btreeset! {'a', 'b', 'k'}, btreeset! {'a', 'b', 'l'}, btreeset! {'a', 'b', 'm'}, btreeset! {'a', 'b', 'n'}, btreeset! {'a', 'b', 'o'}, btreeset! {'a', 'b', 'p'}, btreeset! {'a', 'b', 'q'}, btreeset! {'a', 'b', 'r'}, btreeset! {'a', 'b', 's'}, btreeset! {'a', 'b', 't'}, btreeset! {'a', 'b', 'u'}, btreeset! {'a', 'b', 'v'}, ], ); } malachite-base-0.4.16/tests/sets/exhaustive/shortlex_hash_sets.rs000064400000000000000000000064051046102023000233440ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::sets::exhaustive::shortlex_hash_sets; use malachite_base::test_util::sets::exhaustive::{ exhaustive_hash_sets_helper_helper, exhaustive_hash_sets_small_helper_helper, }; use malachite_base::tuples::exhaustive::exhaustive_units; use std::collections::HashSet; use std::fmt::Debug; use std::hash::Hash; fn shortlex_hash_sets_helper(xs: I, out: &[HashSet]) where I::Item: Clone + Debug + Eq + Hash, { exhaustive_hash_sets_helper_helper(shortlex_hash_sets(xs).take(20), out); } fn shortlex_hash_sets_small_helper( xs: I, out_len: usize, out: &[HashSet], ) where I::Item: Clone + Debug + Eq + Hash, { exhaustive_hash_sets_small_helper_helper(shortlex_hash_sets(xs), out_len, out); } #[test] fn test_shortlex_hash_sets() { shortlex_hash_sets_small_helper(nevers(), 1, &[hashset! {}]); shortlex_hash_sets_small_helper(exhaustive_units(), 2, &[hashset! {}, hashset! {()}]); shortlex_hash_sets_small_helper( exhaustive_bools(), 4, &[hashset! {}, hashset! {false}, hashset! {true}, hashset! {false, true}], ); shortlex_hash_sets_small_helper( 1..=6, 64, &[ hashset! {}, hashset! {1}, hashset! {2}, hashset! {3}, hashset! {4}, hashset! {5}, hashset! {6}, hashset! {1, 2}, hashset! {1, 3}, hashset! {1, 4}, hashset! {1, 5}, hashset! {1, 6}, hashset! {2, 3}, hashset! {2, 4}, hashset! {2, 5}, hashset! {2, 6}, hashset! {3, 4}, hashset! {3, 5}, hashset! {3, 6}, hashset! {4, 5}, ], ); shortlex_hash_sets_small_helper( 'a'..='c', 8, &[ hashset! {}, hashset! {'a'}, hashset! {'b'}, hashset! {'c'}, hashset! {'a', 'b'}, hashset! {'a', 'c'}, hashset! {'b', 'c'}, hashset! {'a', 'b', 'c'}, ], ); shortlex_hash_sets_helper( exhaustive_ascii_chars(), &[ hashset! {}, hashset! {'a'}, hashset! {'b'}, hashset! {'c'}, hashset! {'d'}, hashset! {'e'}, hashset! {'f'}, hashset! {'g'}, hashset! {'h'}, hashset! {'i'}, hashset! {'j'}, hashset! {'k'}, hashset! {'l'}, hashset! {'m'}, hashset! {'n'}, hashset! {'o'}, hashset! {'p'}, hashset! {'q'}, hashset! {'r'}, hashset! {'s'}, ], ); } malachite-base-0.4.16/tests/sets/exhaustive/shortlex_hash_sets_length_inclusive_range.rs000064400000000000000000000041671046102023000301450ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::nevers::nevers; use malachite_base::sets::exhaustive::shortlex_hash_sets_length_inclusive_range; use malachite_base::test_util::sets::exhaustive::exhaustive_hash_sets_small_helper_helper; use malachite_base::tuples::exhaustive::exhaustive_units; use std::collections::HashSet; use std::fmt::Debug; use std::hash::Hash; fn shortlex_hash_sets_length_inclusive_range_small_helper( a: u64, b: u64, xs: I, out_len: usize, out: &[HashSet], ) where I::Item: Clone + Debug + Eq + Hash, { exhaustive_hash_sets_small_helper_helper( shortlex_hash_sets_length_inclusive_range(a, b, xs), out_len, out, ); } #[test] fn test_shortlex_hash_sets_length_inclusive_range() { shortlex_hash_sets_length_inclusive_range_small_helper(0, 4, nevers(), 1, &[hashset! {}]); shortlex_hash_sets_length_inclusive_range_small_helper(6, 9, nevers(), 0, &[]); shortlex_hash_sets_length_inclusive_range_small_helper( 0, 4, exhaustive_units(), 2, &[hashset! {}, hashset! {()}], ); shortlex_hash_sets_length_inclusive_range_small_helper(1, 0, exhaustive_bools(), 0, &[]); shortlex_hash_sets_length_inclusive_range_small_helper( 0, 1, exhaustive_bools(), 3, &[hashset! {}, hashset! {false}, hashset! {true}], ); shortlex_hash_sets_length_inclusive_range_small_helper( 2, 3, exhaustive_bools(), 1, &[hashset! {false, true}], ); shortlex_hash_sets_length_inclusive_range_small_helper( 1, 1, 'a'..='c', 3, &[hashset! {'a'}, hashset! {'b'}, hashset! {'c'}], ); } malachite-base-0.4.16/tests/sets/exhaustive/shortlex_hash_sets_length_range.rs000064400000000000000000000041361046102023000260600ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::nevers::nevers; use malachite_base::sets::exhaustive::shortlex_hash_sets_length_range; use malachite_base::test_util::sets::exhaustive::exhaustive_hash_sets_small_helper_helper; use malachite_base::tuples::exhaustive::exhaustive_units; use std::collections::HashSet; use std::fmt::Debug; use std::hash::Hash; fn shortlex_hash_sets_length_range_small_helper( a: u64, b: u64, xs: I, out_len: usize, out: &[HashSet], ) where I::Item: Clone + Debug + Eq + Hash, { exhaustive_hash_sets_small_helper_helper( shortlex_hash_sets_length_range(a, b, xs), out_len, out, ); } #[test] fn test_shortlex_hash_sets_length_range() { shortlex_hash_sets_length_range_small_helper(0, 5, nevers(), 1, &[hashset! {}]); shortlex_hash_sets_length_range_small_helper(6, 10, nevers(), 0, &[]); shortlex_hash_sets_length_range_small_helper( 0, 5, exhaustive_units(), 2, &[hashset! {}, hashset! {()}], ); shortlex_hash_sets_length_range_small_helper(1, 0, exhaustive_bools(), 0, &[]); shortlex_hash_sets_length_range_small_helper(1, 1, exhaustive_bools(), 0, &[]); shortlex_hash_sets_length_range_small_helper( 0, 2, exhaustive_bools(), 3, &[hashset! {}, hashset! {false}, hashset! {true}], ); shortlex_hash_sets_length_range_small_helper( 2, 4, exhaustive_bools(), 1, &[hashset! {false, true}], ); shortlex_hash_sets_length_range_small_helper( 1, 2, 'a'..='c', 3, &[hashset! {'a'}, hashset! {'b'}, hashset! {'c'}], ); } malachite-base-0.4.16/tests/sets/exhaustive/shortlex_hash_sets_min_length.rs000064400000000000000000000104271046102023000255470ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::sets::exhaustive::shortlex_hash_sets_min_length; use malachite_base::test_util::sets::exhaustive::{ exhaustive_hash_sets_helper_helper, exhaustive_hash_sets_small_helper_helper, }; use malachite_base::tuples::exhaustive::exhaustive_units; use std::collections::HashSet; use std::fmt::Debug; use std::hash::Hash; fn shortlex_hash_sets_min_length_helper( min_length: u64, xs: I, out: &[HashSet], ) where I::Item: Clone + Debug + Eq + Hash, { exhaustive_hash_sets_helper_helper(shortlex_hash_sets_min_length(min_length, xs), out); } fn shortlex_hash_sets_min_length_small_helper( min_length: u64, xs: I, out_len: usize, out: &[HashSet], ) where I::Item: Clone + Debug + Eq + Hash, { exhaustive_hash_sets_small_helper_helper( shortlex_hash_sets_min_length(min_length, xs), out_len, out, ); } #[test] fn test_shortlex_hash_sets_min_length() { shortlex_hash_sets_min_length_small_helper(0, nevers(), 1, &[hashset! {}]); shortlex_hash_sets_min_length_small_helper(4, nevers(), 0, &[]); shortlex_hash_sets_min_length_small_helper( 0, exhaustive_units(), 2, &[hashset! {}, hashset! {()}], ); shortlex_hash_sets_min_length_small_helper(5, exhaustive_units(), 0, &[]); shortlex_hash_sets_min_length_small_helper( 0, exhaustive_bools(), 4, &[hashset! {}, hashset! {false}, hashset! {true}, hashset! {false, true}], ); shortlex_hash_sets_min_length_small_helper( 1, exhaustive_bools(), 3, &[hashset! {false}, hashset! {true}, hashset! {false, true}], ); shortlex_hash_sets_min_length_small_helper( 0, 'a'..='c', 8, &[ hashset! {}, hashset! {'a'}, hashset! {'b'}, hashset! {'c'}, hashset! {'a', 'b'}, hashset! {'a', 'c'}, hashset! {'b', 'c'}, hashset! {'a', 'b', 'c'}, ], ); shortlex_hash_sets_min_length_small_helper( 2, 'a'..='c', 4, &[hashset! {'a', 'b'}, hashset! {'a', 'c'}, hashset! {'b', 'c'}, hashset! {'a', 'b', 'c'}], ); shortlex_hash_sets_min_length_helper( 0, exhaustive_ascii_chars(), &[ hashset! {}, hashset! {'a'}, hashset! {'b'}, hashset! {'c'}, hashset! {'d'}, hashset! {'e'}, hashset! {'f'}, hashset! {'g'}, hashset! {'h'}, hashset! {'i'}, hashset! {'j'}, hashset! {'k'}, hashset! {'l'}, hashset! {'m'}, hashset! {'n'}, hashset! {'o'}, hashset! {'p'}, hashset! {'q'}, hashset! {'r'}, hashset! {'s'}, ], ); shortlex_hash_sets_min_length_helper( 3, exhaustive_ascii_chars(), &[ hashset! {'a', 'b', 'c'}, hashset! {'a', 'b', 'd'}, hashset! {'a', 'b', 'e'}, hashset! {'a', 'b', 'f'}, hashset! {'a', 'b', 'g'}, hashset! {'a', 'b', 'h'}, hashset! {'a', 'b', 'i'}, hashset! {'a', 'b', 'j'}, hashset! {'a', 'b', 'k'}, hashset! {'a', 'b', 'l'}, hashset! {'a', 'b', 'm'}, hashset! {'a', 'b', 'n'}, hashset! {'a', 'b', 'o'}, hashset! {'a', 'b', 'p'}, hashset! {'a', 'b', 'q'}, hashset! {'a', 'b', 'r'}, hashset! {'a', 'b', 's'}, hashset! {'a', 'b', 't'}, hashset! {'a', 'b', 'u'}, hashset! {'a', 'b', 'v'}, ], ); } malachite-base-0.4.16/tests/sets/random/random_b_tree_sets.rs000064400000000000000000000175651046102023000223750ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use core::hash::Hash; use itertools::Itertools; use malachite_base::chars::exhaustive::exhaustive_chars; use malachite_base::chars::random::graphic_weighted_random_char_inclusive_range; use malachite_base::num::random::geometric::geometric_random_unsigneds; use malachite_base::num::random::random_primitive_ints; use malachite_base::random::{Seed, EXAMPLE_SEED}; use malachite_base::sets::random::random_b_tree_sets; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; use std::collections::BTreeSet; use std::fmt::Debug; fn random_b_tree_sets_helper>( xs_gen: &dyn Fn(Seed) -> I, mean_length_numerator: u64, mean_length_denominator: u64, expected_values: &[BTreeSet], expected_common_values: &[(BTreeSet, usize)], expected_median: (BTreeSet, Option>), ) { let xs = random_b_tree_sets( EXAMPLE_SEED, xs_gen, mean_length_numerator, mean_length_denominator, ); let values = xs.clone().take(20).collect_vec(); let common_values = common_values_map_debug(1000000, 10, xs.clone()); let median = median(xs.take(1000000)); assert_eq!( (values.as_slice(), common_values.as_slice(), median), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_random_b_tree_sets() { random_b_tree_sets_helper( &random_primitive_ints::, 4, 1, &[ btreeset! {}, btreeset! {11, 32, 38, 85, 134, 136, 162, 166, 177, 200, 203, 217, 223, 235}, btreeset! {30, 90, 218, 234}, btreeset! {9, 106, 204, 216}, btreeset! {151}, btreeset! {}, btreeset! {78, 91, 97, 213, 253}, btreeset! {39, 191}, btreeset! {170, 175, 232, 233}, btreeset! {}, btreeset! {2, 22, 35, 114, 198, 217}, btreeset! {}, btreeset! {}, btreeset! {17, 25, 32, 65, 79, 114, 121, 144, 148, 173, 222}, btreeset! {52, 69, 73, 91, 115, 137, 153, 178}, btreeset! {}, btreeset! {34, 95, 112}, btreeset! {}, btreeset! {106, 130, 167, 168, 197}, btreeset! {86, 101, 122, 150, 172, 177, 207, 218, 221}, ], &[ (btreeset! {}, 199913), (btreeset! {7}, 705), (btreeset! {25}, 689), (btreeset! {184}, 681), (btreeset! {213}, 681), (btreeset! {255}, 676), (btreeset! {215}, 675), (btreeset! {54}, 673), (btreeset! {122}, 672), (btreeset! {207}, 672), ], ( btreeset! {27, 31, 211, 238}, Some(btreeset! {27, 31, 247, 251}), ), ); random_b_tree_sets_helper( &|seed| geometric_random_unsigneds::(seed, 32, 1), 4, 1, &[ btreeset! {}, btreeset! {1, 9, 12, 14, 16, 17, 19, 21, 41, 42, 68, 79, 124, 141}, btreeset! {0, 1, 10, 99}, btreeset! {2, 12, 36, 77}, btreeset! {1}, btreeset! {}, btreeset! {1, 5, 9, 19, 103}, btreeset! {6, 7}, btreeset! {15, 18, 51, 159}, btreeset! {}, btreeset! {2, 26, 40, 52, 64, 75}, btreeset! {}, btreeset! {}, btreeset! {3, 4, 5, 7, 30, 31, 34, 43, 49, 51, 67}, btreeset! {1, 14, 16, 24, 29, 41, 47, 52}, btreeset! {}, btreeset! {11, 13, 62}, btreeset! {}, btreeset! {3, 14, 42, 47, 109}, btreeset! {5, 13, 16, 25, 37, 41, 42, 86, 96}, ], &[ (btreeset! {}, 199913), (btreeset! {0}, 4861), (btreeset! {1}, 4593), (btreeset! {2}, 4498), (btreeset! {3}, 4405), (btreeset! {4}, 4330), (btreeset! {5}, 4078), (btreeset! {6}, 4050), (btreeset! {7}, 3858), (btreeset! {8}, 3848), ], ( btreeset! {3, 9, 14, 22, 36, 56, 107}, Some(btreeset! {3, 9, 14, 22, 42, 54, 73, 150}), ), ); random_b_tree_sets_helper( &random_primitive_ints::, 1, 4, &[ btreeset! {}, btreeset! {}, btreeset! {85}, btreeset! {11}, btreeset! {136, 200}, btreeset! {}, btreeset! {}, btreeset! {}, btreeset! {}, btreeset! {}, btreeset! {}, btreeset! {}, btreeset! {134, 235}, btreeset! {203}, btreeset! {}, btreeset! {38, 223}, btreeset! {}, btreeset! {}, btreeset! {}, btreeset! {}, ], &[ (btreeset! {}, 800023), (btreeset! {162}, 692), (btreeset! {235}, 690), (btreeset! {90}, 688), (btreeset! {65}, 687), (btreeset! {249}, 686), (btreeset! {175}, 684), (btreeset! {108}, 683), (btreeset! {211}, 682), (btreeset! {237}, 680), ], (btreeset! {}, None), ); random_b_tree_sets_helper( &|seed| { graphic_weighted_random_char_inclusive_range( seed, 'a', exhaustive_chars().nth(200).unwrap(), 1, 1, ) }, 4, 1, &[ btreeset! {}, btreeset! {'g', 'q', '³', '»', 'À', 'Á', 'Ã', 'È', 'á', 'â', 'ì', 'ñ', 'Ā', 'ą'}, btreeset! {'ª', '´', 'Ã', 'ä'}, btreeset! {'½', 'Á', 'Ï', 'ý'}, btreeset! {'j'}, btreeset! {}, btreeset! {'u', '½', 'Â', 'Ñ', 'ï'}, btreeset! {'x', 'õ'}, btreeset! {'¡', 'Â', 'ù', 'Ċ'}, btreeset! {}, btreeset! {'b', 'r', 's', '¬', 'Â', 'Ñ'}, btreeset! {}, btreeset! {}, btreeset! {'j', 'n', 't', '¬', 'º', '¿', 'Á', 'Ø', 'Þ', 'ô', 'ü'}, btreeset! {'b', 'k', '±', 'Î', 'Ü', 'æ', 'è', 'ā'}, btreeset! {}, btreeset! {'«', '¹', 'Î'}, btreeset! {}, btreeset! {'~', '¯', '´', 'Ý', 'â'}, btreeset! {'g', '¼', 'Ç', 'Î', 'Ü', 'Þ', 'æ', 'é', 'ö'}, ], &[ (btreeset! {}, 199913), (btreeset! {'Ó'}, 1270), (btreeset! {'Â'}, 1249), (btreeset! {'§'}, 1244), (btreeset! {'¿'}, 1243), (btreeset! {'õ'}, 1241), (btreeset! {'ĉ'}, 1234), (btreeset! {'¤'}, 1232), (btreeset! {'¼'}, 1232), (btreeset! {'Ì'}, 1229), ], ( btreeset! {'o', 'v', '¢', '±', 'Ä', 'Ć'}, Some(btreeset! {'o', 'v', '¢', '³', 'ã'}), ), ); } #[test] #[should_panic] fn random_b_tree_sets_fail_1() { random_b_tree_sets(EXAMPLE_SEED, &random_primitive_ints::, 0, 1); } #[test] #[should_panic] fn random_b_tree_sets_fail_2() { random_b_tree_sets(EXAMPLE_SEED, &random_primitive_ints::, 1, 0); } #[test] #[should_panic] fn random_b_tree_sets_fail_3() { random_b_tree_sets( EXAMPLE_SEED, &random_primitive_ints::, u64::MAX, u64::MAX - 1, ); } malachite-base-0.4.16/tests/sets/random/random_b_tree_sets_fixed_length.rs000064400000000000000000000143101046102023000250760ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use core::hash::Hash; use itertools::{repeat_n, Itertools}; use malachite_base::bools::random::random_bools; use malachite_base::num::random::random_primitive_ints; use malachite_base::random::EXAMPLE_SEED; use malachite_base::sets::random::random_b_tree_sets_fixed_length; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; use std::collections::BTreeSet; use std::fmt::Debug; fn random_b_tree_sets_fixed_length_helper( len: u64, xs: I, expected_values: &[BTreeSet], expected_common_values: &[(BTreeSet, usize)], expected_median: (BTreeSet, Option>), ) where I::Item: Clone + Debug + Eq + Hash + Ord, { let xs = random_b_tree_sets_fixed_length(len, xs); let values = xs.clone().take(20).collect_vec(); let common_values = common_values_map_debug(1000000, 10, xs.clone()); let median = median(xs.take(1000000)); assert_eq!( (values.as_slice(), common_values.as_slice(), median), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_random_b_tree_sets_fixed_length() { random_b_tree_sets_fixed_length_helper( 0, random_primitive_ints::(EXAMPLE_SEED), &repeat_n(btreeset! {}, 20).collect_vec(), &[(btreeset! {}, 1000000)], (btreeset! {}, None), ); random_b_tree_sets_fixed_length_helper( 1, random_bools(EXAMPLE_SEED), &[ btreeset! {true}, btreeset! {false}, btreeset! {false}, btreeset! {false}, btreeset! {true}, btreeset! {true}, btreeset! {true}, btreeset! {false}, btreeset! {true}, btreeset! {true}, btreeset! {true}, btreeset! {true}, btreeset! {false}, btreeset! {true}, btreeset! {true}, btreeset! {true}, btreeset! {true}, btreeset! {false}, btreeset! {true}, btreeset! {false}, ], &[(btreeset! {true}, 500473), (btreeset! {false}, 499527)], (btreeset! {true}, None), ); random_b_tree_sets_fixed_length_helper( 3, random_primitive_ints::(EXAMPLE_SEED), &[ btreeset! {69, 113, 239}, btreeset! {108, 210, 228}, btreeset! {87, 161, 168}, btreeset! {32, 83, 110}, btreeset! {34, 89, 188}, btreeset! {93, 200, 238}, btreeset! {115, 149, 189}, btreeset! {149, 201, 217}, btreeset! {31, 117, 146}, btreeset! {72, 151, 169}, btreeset! {7, 33, 174}, btreeset! {38, 81, 144}, btreeset! {72, 113, 127}, btreeset! {107, 128, 233}, btreeset! {12, 46, 119}, btreeset! {18, 164, 243}, btreeset! {59, 114, 174}, btreeset! {39, 174, 247}, btreeset! {104, 160, 184}, btreeset! {37, 100, 252}, ], &[ (btreeset! {57, 142, 207}, 7), (btreeset! {32, 68, 169}, 6), (btreeset! {36, 70, 195}, 6), (btreeset! {125, 168, 194}, 6), (btreeset! {0, 97, 205}, 5), (btreeset! {2, 33, 227}, 5), (btreeset! {5, 46, 239}, 5), (btreeset! {9, 68, 189}, 5), (btreeset! {9, 78, 240}, 5), (btreeset! {1, 110, 203}, 5), ], (btreeset! {52, 133, 241}, Some(btreeset! {52, 133, 242})), ); random_b_tree_sets_fixed_length_helper( 2, random_b_tree_sets_fixed_length(2, random_primitive_ints::(EXAMPLE_SEED)), &[ btreeset! {btreeset!{69, 108}, btreeset!{113, 239}}, btreeset! {btreeset!{161, 168}, btreeset!{210, 228}}, btreeset! {btreeset!{32, 87}, btreeset!{83, 110}}, btreeset! {btreeset!{34, 188}, btreeset!{89, 238}}, btreeset! {btreeset!{93, 200}, btreeset!{115, 149}}, btreeset! {btreeset!{149, 189}, btreeset!{201, 217}}, btreeset! {btreeset!{31, 72}, btreeset!{117, 146}}, btreeset! {btreeset!{33, 174}, btreeset!{151, 169}}, btreeset! {btreeset!{7, 38}, btreeset!{81, 144}}, btreeset! {btreeset!{72, 127}, btreeset!{113, 128}}, btreeset! {btreeset!{46, 119}, btreeset!{107, 233}}, btreeset! {btreeset!{12, 18}, btreeset!{164, 243}}, btreeset! {btreeset!{59, 247}, btreeset!{114, 174}}, btreeset! {btreeset!{39, 174}, btreeset!{160, 184}}, btreeset! {btreeset!{37, 104}, btreeset!{100, 252}}, btreeset! {btreeset!{69, 107}, btreeset!{122, 228}}, btreeset! {btreeset!{142, 179}, btreeset!{242, 248}}, btreeset! {btreeset!{61, 189}, btreeset!{233, 239}}, btreeset! {btreeset!{7, 192}, btreeset!{85, 235}}, btreeset! {btreeset!{90, 200}, btreeset!{178, 185}}, ], &[ (btreeset! {btreeset!{0, 78}, btreeset!{34, 52}}, 2), (btreeset! {btreeset!{1, 58}, btreeset!{6, 112}}, 2), (btreeset! {btreeset!{1, 63}, btreeset!{8, 154}}, 2), (btreeset! {btreeset!{1, 97}, btreeset!{7, 250}}, 2), (btreeset! {btreeset!{2, 33}, btreeset!{40, 81}}, 2), (btreeset! {btreeset!{3, 160}, btreeset!{7, 29}}, 2), (btreeset! {btreeset!{3, 32}, btreeset!{12, 60}}, 2), (btreeset! {btreeset!{6, 130}, btreeset!{7, 20}}, 2), (btreeset! {btreeset!{6, 68}, btreeset!{7, 126}}, 2), (btreeset! {btreeset!{6, 77}, btreeset!{36, 54}}, 2), ], ( btreeset! {btreeset!{40, 193}, btreeset!{94, 142}}, Some(btreeset! {btreeset!{40, 193}, btreeset!{97, 243}}), ), ); } malachite-base-0.4.16/tests/sets/random/random_b_tree_sets_from_length_iterator.rs000064400000000000000000000104731046102023000266610ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use core::hash::Hash; use itertools::Itertools; use malachite_base::bools::random::random_bools; use malachite_base::num::random::geometric::geometric_random_unsigneds; use malachite_base::num::random::random_primitive_ints; use malachite_base::random::{Seed, EXAMPLE_SEED}; use malachite_base::sets::random::random_b_tree_sets_from_length_iterator; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; use malachite_base::vecs::random_values_from_vec; use std::collections::BTreeSet; use std::fmt::Debug; fn random_b_tree_sets_from_length_iterator_helper< T: Clone + Debug + Eq + Hash + Ord, I: Clone + Iterator, J: Clone + Iterator, >( lengths_gen: &dyn Fn(Seed) -> I, xs_gen: &dyn Fn(Seed) -> J, expected_values: &[BTreeSet], expected_common_values: &[(BTreeSet, usize)], expected_median: (BTreeSet, Option>), ) { let xs = random_b_tree_sets_from_length_iterator(EXAMPLE_SEED, lengths_gen, xs_gen); let values = xs.clone().take(20).collect_vec(); let common_values = common_values_map_debug(1000000, 10, xs.clone()); let median = median(xs.take(1000000)); assert_eq!( (values.as_slice(), common_values.as_slice(), median), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_random_b_tree_sets_from_length_iterator() { random_b_tree_sets_from_length_iterator_helper( &|seed| random_values_from_vec(seed, vec![0, 2]), &random_bools, &[ btreeset! {false, true}, btreeset! {}, btreeset! {false, true}, btreeset! {false, true}, btreeset! {}, btreeset! {false, true}, btreeset! {false, true}, btreeset! {}, btreeset! {false, true}, btreeset! {false, true}, btreeset! {}, btreeset! {false, true}, btreeset! {}, btreeset! {false, true}, btreeset! {false, true}, btreeset! {}, btreeset! {}, btreeset! {}, btreeset! {false, true}, btreeset! {}, ], &[(btreeset! {false, true}, 500363), (btreeset! {}, 499637)], (btreeset! {false, true}, None), ); random_b_tree_sets_from_length_iterator_helper( &|seed| geometric_random_unsigneds::(seed, 2, 1).map(|x| x << 1), &random_primitive_ints::, &[ btreeset! {11, 38, 85, 134, 136, 162, 177, 200, 203, 217, 223, 235}, btreeset! {32, 166}, btreeset! {9, 30, 39, 78, 90, 91, 97, 106, 151, 191, 204, 213, 216, 218, 234, 253}, btreeset! {170, 175}, btreeset! { 2, 17, 22, 25, 32, 34, 35, 52, 65, 69, 73, 79, 91, 112, 114, 115, 121, 137, 144, 148, 153, 173, 178, 198, 217, 222, 232, 233, }, btreeset! {}, btreeset! {95, 106, 122, 130, 167, 168, 172, 177, 197, 207}, btreeset! {9, 74, 86, 101, 115, 150, 218, 221}, btreeset! {109, 123}, btreeset! {}, btreeset! {40, 48, 52, 97, 104, 133, 159, 196, 201, 235, 247, 250}, btreeset! {7, 68, 190, 216}, btreeset! {}, btreeset! {}, btreeset! {157, 216}, btreeset! {11, 24, 43, 103, 112, 217}, btreeset! {}, btreeset! {84, 211}, btreeset! {}, btreeset! {55, 135}, ], &[ (btreeset! {}, 333981), (btreeset! {33, 163}, 22), (btreeset! {76, 233}, 19), (btreeset! {5, 42}, 18), (btreeset! {76, 79}, 18), (btreeset! {32, 134}, 18), (btreeset! {69, 234}, 18), (btreeset! {74, 164}, 18), (btreeset! {86, 192}, 18), (btreeset! {99, 145}, 18), ], (btreeset! {12, 190}, None), ); } malachite-base-0.4.16/tests/sets/random/random_b_tree_sets_length_inclusive_range.rs000064400000000000000000000134121046102023000271560ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use core::hash::Hash; use itertools::Itertools; use malachite_base::chars::random::random_char_inclusive_range; use malachite_base::num::random::geometric::geometric_random_unsigneds; use malachite_base::num::random::random_primitive_ints; use malachite_base::random::{Seed, EXAMPLE_SEED}; use malachite_base::sets::random::random_b_tree_sets_length_inclusive_range; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; use std::collections::BTreeSet; use std::fmt::Debug; fn random_b_tree_sets_length_inclusive_range_helper< T: Clone + Debug + Eq + Hash + Ord, I: Clone + Iterator, >( a: u64, b: u64, xs_gen: &dyn Fn(Seed) -> I, expected_values: &[BTreeSet], expected_common_values: &[(BTreeSet, usize)], expected_median: (BTreeSet, Option>), ) { let xs = random_b_tree_sets_length_inclusive_range(EXAMPLE_SEED, a, b, xs_gen); let values = xs.clone().take(20).collect_vec(); let common_values = common_values_map_debug(1000000, 10, xs.clone()); let median = median(xs.take(1000000)); assert_eq!( (values.as_slice(), common_values.as_slice(), median), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_random_b_tree_sets_length_inclusive_range() { random_b_tree_sets_length_inclusive_range_helper( 2, 3, &random_primitive_ints::, &[ btreeset! {11, 85, 136}, btreeset! {200, 235}, btreeset! {134, 203, 223}, btreeset! {38, 217, 235}, btreeset! {162, 177}, btreeset! {32, 166, 234}, btreeset! {30, 90, 218}, btreeset! {9, 106}, btreeset! {151, 204, 216}, btreeset! {97, 213, 253}, btreeset! {78, 91}, btreeset! {39, 175, 191}, btreeset! {170, 232}, btreeset! {2, 35, 233}, btreeset! {22, 198, 217}, btreeset! {17, 114}, btreeset! {32, 173}, btreeset! {65, 114}, btreeset! {121, 173, 222}, btreeset! {25, 144}, ], &[ (btreeset! {106, 108}, 34), (btreeset! {224, 237}, 34), (btreeset! {51, 132}, 32), (btreeset! {82, 117}, 32), (btreeset! {72, 108}, 31), (btreeset! {142, 194}, 31), (btreeset! {0, 34}, 30), (btreeset! {12, 208}, 30), (btreeset! {15, 141}, 30), (btreeset! {30, 248}, 30), ], (btreeset! {62, 131, 203}, Some(btreeset! {62, 131, 205})), ); random_b_tree_sets_length_inclusive_range_helper( 2, 3, &|seed| geometric_random_unsigneds::(seed, 2, 1), &[ btreeset! {0, 1, 5}, btreeset! {1, 4}, btreeset! {2, 4, 6}, btreeset! {0, 1, 2}, btreeset! {9, 13}, btreeset! {0, 2, 7}, btreeset! {4, 6, 7}, btreeset! {0, 6}, btreeset! {0, 1, 3}, btreeset! {1, 2, 5}, btreeset! {0, 1}, btreeset! {0, 1, 4}, btreeset! {0, 2}, btreeset! {0, 2, 12}, btreeset! {1, 2, 3}, btreeset! {3, 9}, btreeset! {0, 1}, btreeset! {1, 2}, btreeset! {0, 1, 11}, btreeset! {1, 6}, ], &[ (btreeset! {0, 1}, 103032), (btreeset! {0, 1, 2}, 84142), (btreeset! {0, 2}, 66185), (btreeset! {0, 1, 3}, 52638), (btreeset! {0, 3}, 42990), (btreeset! {1, 2}, 40380), (btreeset! {0, 1, 4}, 33815), (btreeset! {0, 2, 3}, 31257), (btreeset! {0, 4}, 28088), (btreeset! {1, 3}, 26214), ], (btreeset! {0, 3}, None), ); random_b_tree_sets_length_inclusive_range_helper( 2, 3, &|seed| random_char_inclusive_range(seed, 'a', 'z'), &[ btreeset! {'c', 'q', 'v'}, btreeset! {'e', 'i'}, btreeset! {'g', 'p', 's'}, btreeset! {'m', 'n', 't'}, btreeset! {'o', 'z'}, btreeset! {'f', 'k', 'm'}, btreeset! {'q', 'u', 'y'}, btreeset! {'k', 'x'}, btreeset! {'h', 'n', 'u'}, btreeset! {'a', 'j', 'n'}, btreeset! {'w', 'z'}, btreeset! {'b', 'l', 'w'}, btreeset! {'l', 'u'}, btreeset! {'e', 'l', 'n'}, btreeset! {'k', 'u', 'v'}, btreeset! {'c', 'h'}, btreeset! {'i', 'y'}, btreeset! {'m', 'r'}, btreeset! {'m', 's', 'y'}, btreeset! {'e', 'l'}, ], &[ (btreeset! {'l', 'x'}, 1640), (btreeset! {'o', 't'}, 1636), (btreeset! {'b', 'p'}, 1630), (btreeset! {'m', 'v'}, 1623), (btreeset! {'h', 'u'}, 1621), (btreeset! {'a', 'x'}, 1614), (btreeset! {'d', 'f'}, 1613), (btreeset! {'e', 'r'}, 1613), (btreeset! {'o', 'p'}, 1612), (btreeset! {'c', 'i'}, 1611), ], (btreeset! {'g', 'j'}, None), ); } #[test] #[should_panic] fn random_b_tree_sets_length_inclusive_range_fail() { random_b_tree_sets_length_inclusive_range(EXAMPLE_SEED, 2, 1, &random_primitive_ints::); } malachite-base-0.4.16/tests/sets/random/random_b_tree_sets_length_range.rs000064400000000000000000000132601046102023000250760ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use core::hash::Hash; use itertools::Itertools; use malachite_base::chars::random::random_char_inclusive_range; use malachite_base::num::random::geometric::geometric_random_unsigneds; use malachite_base::num::random::random_primitive_ints; use malachite_base::random::{Seed, EXAMPLE_SEED}; use malachite_base::sets::random::random_b_tree_sets_length_range; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; use std::collections::BTreeSet; use std::fmt::Debug; fn random_b_tree_sets_length_range_helper< T: Clone + Debug + Eq + Hash + Ord, I: Clone + Iterator, >( a: u64, b: u64, xs_gen: &dyn Fn(Seed) -> I, expected_values: &[BTreeSet], expected_common_values: &[(BTreeSet, usize)], expected_median: (BTreeSet, Option>), ) { let xs = random_b_tree_sets_length_range(EXAMPLE_SEED, a, b, xs_gen); let values = xs.clone().take(20).collect_vec(); let common_values = common_values_map_debug(1000000, 10, xs.clone()); let median = median(xs.take(1000000)); assert_eq!( (values.as_slice(), common_values.as_slice(), median), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_random_b_tree_sets_length_range() { random_b_tree_sets_length_range_helper( 2, 4, &random_primitive_ints::, &[ btreeset! {11, 85, 136}, btreeset! {200, 235}, btreeset! {134, 203, 223}, btreeset! {38, 217, 235}, btreeset! {162, 177}, btreeset! {32, 166, 234}, btreeset! {30, 90, 218}, btreeset! {9, 106}, btreeset! {151, 204, 216}, btreeset! {97, 213, 253}, btreeset! {78, 91}, btreeset! {39, 175, 191}, btreeset! {170, 232}, btreeset! {2, 35, 233}, btreeset! {22, 198, 217}, btreeset! {17, 114}, btreeset! {32, 173}, btreeset! {65, 114}, btreeset! {121, 173, 222}, btreeset! {25, 144}, ], &[ (btreeset! {106, 108}, 34), (btreeset! {224, 237}, 34), (btreeset! {51, 132}, 32), (btreeset! {82, 117}, 32), (btreeset! {72, 108}, 31), (btreeset! {142, 194}, 31), (btreeset! {0, 34}, 30), (btreeset! {12, 208}, 30), (btreeset! {15, 141}, 30), (btreeset! {30, 248}, 30), ], (btreeset! {62, 131, 203}, Some(btreeset! {62, 131, 205})), ); random_b_tree_sets_length_range_helper( 2, 4, &|seed| geometric_random_unsigneds::(seed, 2, 1), &[ btreeset! {0, 1, 5}, btreeset! {1, 4}, btreeset! {2, 4, 6}, btreeset! {0, 1, 2}, btreeset! {9, 13}, btreeset! {0, 2, 7}, btreeset! {4, 6, 7}, btreeset! {0, 6}, btreeset! {0, 1, 3}, btreeset! {1, 2, 5}, btreeset! {0, 1}, btreeset! {0, 1, 4}, btreeset! {0, 2}, btreeset! {0, 2, 12}, btreeset! {1, 2, 3}, btreeset! {3, 9}, btreeset! {0, 1}, btreeset! {1, 2}, btreeset! {0, 1, 11}, btreeset! {1, 6}, ], &[ (btreeset! {0, 1}, 103032), (btreeset! {0, 1, 2}, 84142), (btreeset! {0, 2}, 66185), (btreeset! {0, 1, 3}, 52638), (btreeset! {0, 3}, 42990), (btreeset! {1, 2}, 40380), (btreeset! {0, 1, 4}, 33815), (btreeset! {0, 2, 3}, 31257), (btreeset! {0, 4}, 28088), (btreeset! {1, 3}, 26214), ], (btreeset! {0, 3}, None), ); random_b_tree_sets_length_range_helper( 2, 4, &|seed| random_char_inclusive_range(seed, 'a', 'z'), &[ btreeset! {'c', 'q', 'v'}, btreeset! {'e', 'i'}, btreeset! {'g', 'p', 's'}, btreeset! {'m', 'n', 't'}, btreeset! {'o', 'z'}, btreeset! {'f', 'k', 'm'}, btreeset! {'q', 'u', 'y'}, btreeset! {'k', 'x'}, btreeset! {'h', 'n', 'u'}, btreeset! {'a', 'j', 'n'}, btreeset! {'w', 'z'}, btreeset! {'b', 'l', 'w'}, btreeset! {'l', 'u'}, btreeset! {'e', 'l', 'n'}, btreeset! {'k', 'u', 'v'}, btreeset! {'c', 'h'}, btreeset! {'i', 'y'}, btreeset! {'m', 'r'}, btreeset! {'m', 's', 'y'}, btreeset! {'e', 'l'}, ], &[ (btreeset! {'l', 'x'}, 1640), (btreeset! {'o', 't'}, 1636), (btreeset! {'b', 'p'}, 1630), (btreeset! {'m', 'v'}, 1623), (btreeset! {'h', 'u'}, 1621), (btreeset! {'a', 'x'}, 1614), (btreeset! {'d', 'f'}, 1613), (btreeset! {'e', 'r'}, 1613), (btreeset! {'o', 'p'}, 1612), (btreeset! {'c', 'i'}, 1611), ], (btreeset! {'g', 'j'}, None), ); } #[test] #[should_panic] fn random_b_tree_sets_length_range_fail() { random_b_tree_sets_length_range(EXAMPLE_SEED, 2, 2, &random_primitive_ints::); } malachite-base-0.4.16/tests/sets/random/random_b_tree_sets_min_length.rs000064400000000000000000000363351046102023000245750ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use core::hash::Hash; use itertools::Itertools; use malachite_base::chars::exhaustive::exhaustive_chars; use malachite_base::chars::random::graphic_weighted_random_char_inclusive_range; use malachite_base::num::random::geometric::geometric_random_unsigneds; use malachite_base::num::random::random_primitive_ints; use malachite_base::random::{Seed, EXAMPLE_SEED}; use malachite_base::sets::random::random_b_tree_sets_min_length; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; use std::collections::BTreeSet; use std::fmt::Debug; fn random_b_tree_sets_min_length_helper< T: Clone + Debug + Eq + Hash + Ord, I: Clone + Iterator, >( min_length: u64, xs_gen: &dyn Fn(Seed) -> I, mean_length_numerator: u64, mean_length_denominator: u64, expected_values: &[BTreeSet], expected_common_values: &[(BTreeSet, usize)], expected_median: (BTreeSet, Option>), ) { let xs = random_b_tree_sets_min_length( EXAMPLE_SEED, min_length, xs_gen, mean_length_numerator, mean_length_denominator, ); let values = xs.clone().take(20).collect_vec(); let common_values = common_values_map_debug(1000000, 10, xs.clone()); let median = median(xs.take(1000000)); assert_eq!( (values.as_slice(), common_values.as_slice(), median), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_random_b_tree_sets_min_length() { random_b_tree_sets_min_length_helper( 0, &random_primitive_ints::, 4, 1, &[ btreeset! {}, btreeset! {11, 32, 38, 85, 134, 136, 162, 166, 177, 200, 203, 217, 223, 235}, btreeset! {30, 90, 218, 234}, btreeset! {9, 106, 204, 216}, btreeset! {151}, btreeset! {}, btreeset! {78, 91, 97, 213, 253}, btreeset! {39, 191}, btreeset! {170, 175, 232, 233}, btreeset! {}, btreeset! {2, 22, 35, 114, 198, 217}, btreeset! {}, btreeset! {}, btreeset! {17, 25, 32, 65, 79, 114, 121, 144, 148, 173, 222}, btreeset! {52, 69, 73, 91, 115, 137, 153, 178}, btreeset! {}, btreeset! {34, 95, 112}, btreeset! {}, btreeset! {106, 130, 167, 168, 197}, btreeset! {86, 101, 122, 150, 172, 177, 207, 218, 221}, ], &[ (btreeset! {}, 199913), (btreeset! {7}, 705), (btreeset! {25}, 689), (btreeset! {184}, 681), (btreeset! {213}, 681), (btreeset! {255}, 676), (btreeset! {215}, 675), (btreeset! {54}, 673), (btreeset! {122}, 672), (btreeset! {207}, 672), ], ( btreeset! {27, 31, 211, 238}, Some(btreeset! {27, 31, 247, 251}), ), ); random_b_tree_sets_min_length_helper( 3, &random_primitive_ints::, 7, 1, &[ btreeset! {11, 85, 136}, btreeset! { 9, 30, 32, 38, 90, 106, 134, 162, 166, 177, 200, 203, 217, 218, 223, 234, 235 }, btreeset! {78, 97, 151, 204, 213, 216, 253}, btreeset! {39, 91, 170, 175, 191, 232, 233}, btreeset! {2, 22, 35, 217}, btreeset! {17, 114, 198}, btreeset! {25, 32, 65, 114, 121, 144, 173, 222}, btreeset! {52, 73, 79, 115, 148}, btreeset! {34, 69, 91, 112, 137, 153, 178}, btreeset! {95, 106, 167}, btreeset! {86, 122, 130, 150, 168, 172, 177, 197, 207}, btreeset! {101, 218, 221}, btreeset! {9, 74, 115}, btreeset! {40, 48, 52, 97, 104, 109, 123, 133, 159, 196, 201, 235, 247, 250}, btreeset! {7, 11, 24, 43, 68, 103, 112, 157, 190, 216, 217}, btreeset! {84, 135, 211}, btreeset! {29, 55, 65, 89, 191, 206}, btreeset! {9, 51, 79}, btreeset! {3, 20, 22, 34, 62, 114, 118, 148}, btreeset! {23, 32, 47, 50, 120, 166, 176, 177, 194, 204, 238, 248}, ], &[ (btreeset! {5, 128, 142}, 4), (btreeset! {137, 145, 160}, 4), (btreeset! {2, 4, 52}, 3), (btreeset! {1, 5, 192}, 3), (btreeset! {12, 41, 58}, 3), (btreeset! {2, 95, 171}, 3), (btreeset! {20, 86, 94}, 3), (btreeset! {21, 43, 50}, 3), (btreeset! {3, 81, 122}, 3), (btreeset! {31, 54, 79}, 3), ], ( btreeset! {26, 138, 167}, Some(btreeset! {26, 138, 167, 173, 211}), ), ); random_b_tree_sets_min_length_helper( 0, &|seed| geometric_random_unsigneds::(seed, 32, 1), 4, 1, &[ btreeset! {}, btreeset! {1, 9, 12, 14, 16, 17, 19, 21, 41, 42, 68, 79, 124, 141}, btreeset! {0, 1, 10, 99}, btreeset! {2, 12, 36, 77}, btreeset! {1}, btreeset! {}, btreeset! {1, 5, 9, 19, 103}, btreeset! {6, 7}, btreeset! {15, 18, 51, 159}, btreeset! {}, btreeset! {2, 26, 40, 52, 64, 75}, btreeset! {}, btreeset! {}, btreeset! {3, 4, 5, 7, 30, 31, 34, 43, 49, 51, 67}, btreeset! {1, 14, 16, 24, 29, 41, 47, 52}, btreeset! {}, btreeset! {11, 13, 62}, btreeset! {}, btreeset! {3, 14, 42, 47, 109}, btreeset! {5, 13, 16, 25, 37, 41, 42, 86, 96}, ], &[ (btreeset! {}, 199913), (btreeset! {0}, 4861), (btreeset! {1}, 4593), (btreeset! {2}, 4498), (btreeset! {3}, 4405), (btreeset! {4}, 4330), (btreeset! {5}, 4078), (btreeset! {6}, 4050), (btreeset! {7}, 3858), (btreeset! {8}, 3848), ], ( btreeset! {3, 9, 14, 22, 36, 56, 107}, Some(btreeset! {3, 9, 14, 22, 42, 54, 73, 150}), ), ); random_b_tree_sets_min_length_helper( 3, &|seed| geometric_random_unsigneds::(seed, 32, 1), 7, 1, &[ btreeset! {1, 14, 42}, btreeset! {0, 1, 9, 10, 12, 16, 17, 19, 21, 36, 41, 68, 77, 79, 99, 124, 141}, btreeset! {1, 2, 5, 9, 12, 19, 103}, btreeset! {6, 7, 15, 18, 51, 52, 159}, btreeset! {2, 40, 64, 75}, btreeset! {26, 34, 67}, btreeset! {4, 5, 7, 30, 31, 43, 49, 51}, btreeset! {3, 14, 16, 24, 47}, btreeset! {1, 11, 13, 29, 41, 52, 62}, btreeset! {3, 47, 109}, btreeset! {13, 14, 16, 25, 37, 41, 42, 86, 96}, btreeset! {5, 20, 42}, btreeset! {2, 74, 82}, btreeset! {3, 6, 7, 11, 17, 20, 36, 45, 56, 66, 76, 80, 89, 127}, btreeset! {1, 6, 10, 13, 19, 23, 25, 32, 41, 43, 97}, btreeset! {7, 41, 134}, btreeset! {9, 10, 25, 26, 47, 105}, btreeset! {68, 94, 109}, btreeset! {1, 3, 9, 13, 28, 43, 44, 84}, btreeset! {0, 4, 5, 6, 7, 13, 31, 32, 37, 42, 50, 75}, ], &[ (btreeset! {0, 2, 5}, 42), (btreeset! {0, 1, 8}, 39), (btreeset! {0, 3, 4}, 38), (btreeset! {1, 3, 9}, 38), (btreeset! {0, 1, 7}, 35), (btreeset! {0, 2, 8}, 34), (btreeset! {1, 2, 12}, 34), (btreeset! {0, 1, 2}, 33), (btreeset! {1, 2, 3}, 33), (btreeset! {1, 3, 4}, 33), ], ( btreeset! {3, 8, 14, 19, 25, 36, 52, 64, 71}, Some(btreeset! {3, 8, 14, 19, 25, 38, 58, 61}), ), ); random_b_tree_sets_min_length_helper( 0, &random_primitive_ints::, 1, 4, &[ btreeset! {}, btreeset! {}, btreeset! {85}, btreeset! {11}, btreeset! {136, 200}, btreeset! {}, btreeset! {}, btreeset! {}, btreeset! {}, btreeset! {}, btreeset! {}, btreeset! {}, btreeset! {134, 235}, btreeset! {203}, btreeset! {}, btreeset! {38, 223}, btreeset! {}, btreeset! {}, btreeset! {}, btreeset! {}, ], &[ (btreeset! {}, 800023), (btreeset! {162}, 692), (btreeset! {235}, 690), (btreeset! {90}, 688), (btreeset! {65}, 687), (btreeset! {249}, 686), (btreeset! {175}, 684), (btreeset! {108}, 683), (btreeset! {211}, 682), (btreeset! {237}, 680), ], (btreeset! {}, None), ); random_b_tree_sets_min_length_helper( 3, &random_primitive_ints::, 13, 4, &[ btreeset! {11, 85, 136}, btreeset! {134, 200, 235}, btreeset! {38, 203, 223, 235}, btreeset! {32, 162, 177, 217}, btreeset! {30, 90, 166, 218, 234}, btreeset! {9, 106, 216}, btreeset! {151, 204, 213}, btreeset! {78, 97, 253}, btreeset! {39, 91, 191}, btreeset! {170, 175, 232}, btreeset! {2, 35, 233}, btreeset! {22, 198, 217}, btreeset! {17, 32, 65, 114, 173}, btreeset! {25, 121, 173, 222}, btreeset! {79, 144, 148}, btreeset! {52, 69, 73, 115, 137}, btreeset! {91, 153, 178}, btreeset! {34, 95, 112}, btreeset! {106, 167, 197}, btreeset! {122, 130, 168}, ], &[ (btreeset! {10, 87, 204}, 6), (btreeset! {15, 40, 115}, 6), (btreeset! {108, 193, 199}, 6), (btreeset! {1, 22, 70}, 5), (btreeset! {1, 8, 212}, 5), (btreeset! {2, 40, 169}, 5), (btreeset! {2, 58, 211}, 5), (btreeset! {3, 29, 186}, 5), (btreeset! {3, 97, 112}, 5), (btreeset! {11, 66, 140}, 5), ], (btreeset! {49, 78, 193}, Some(btreeset! {49, 78, 193, 215})), ); random_b_tree_sets_min_length_helper( 0, &|seed| { graphic_weighted_random_char_inclusive_range( seed, 'a', exhaustive_chars().nth(200).unwrap(), 1, 1, ) }, 4, 1, &[ btreeset! {}, btreeset! {'g', 'q', '³', '»', 'À', 'Á', 'Ã', 'È', 'á', 'â', 'ì', 'ñ', 'Ā', 'ą'}, btreeset! {'ª', '´', 'Ã', 'ä'}, btreeset! {'½', 'Á', 'Ï', 'ý'}, btreeset! {'j'}, btreeset! {}, btreeset! {'u', '½', 'Â', 'Ñ', 'ï'}, btreeset! {'x', 'õ'}, btreeset! {'¡', 'Â', 'ù', 'Ċ'}, btreeset! {}, btreeset! {'b', 'r', 's', '¬', 'Â', 'Ñ'}, btreeset! {}, btreeset! {}, btreeset! {'j', 'n', 't', '¬', 'º', '¿', 'Á', 'Ø', 'Þ', 'ô', 'ü'}, btreeset! {'b', 'k', '±', 'Î', 'Ü', 'æ', 'è', 'ā'}, btreeset! {}, btreeset! {'«', '¹', 'Î'}, btreeset! {}, btreeset! {'~', '¯', '´', 'Ý', 'â'}, btreeset! {'g', '¼', 'Ç', 'Î', 'Ü', 'Þ', 'æ', 'é', 'ö'}, ], &[ (btreeset! {}, 199913), (btreeset! {'Ó'}, 1270), (btreeset! {'Â'}, 1249), (btreeset! {'§'}, 1244), (btreeset! {'¿'}, 1243), (btreeset! {'õ'}, 1241), (btreeset! {'ĉ'}, 1234), (btreeset! {'¤'}, 1232), (btreeset! {'¼'}, 1232), (btreeset! {'Ì'}, 1229), ], ( btreeset! {'o', 'v', '¢', '±', 'Ä', 'Ć'}, Some(btreeset! {'o', 'v', '¢', '³', 'ã'}), ), ); random_b_tree_sets_min_length_helper( 3, &|seed| { graphic_weighted_random_char_inclusive_range( seed, 'a', exhaustive_chars().nth(200).unwrap(), 1, 1, ) }, 7, 1, &[ btreeset! {'g', 'q', 'á'}, btreeset! { 'g', 'ª', '³', '´', '»', '½', 'À', 'Á', 'Ã', 'È', 'Ï', 'â', 'ä', 'ì', 'ñ', 'Ā', 'ą', }, btreeset! {'j', 'u', '½', 'Â', 'Ñ', 'ï', 'ý'}, btreeset! {'x', '¡', '¬', 'Â', 'õ', 'ù', 'Ċ'}, btreeset! {'b', 's', '¬', 'Ñ'}, btreeset! {'n', 'r', 'Â'}, btreeset! {'t', '¬', 'º', '¿', 'Ø', 'Þ', 'ô', 'ü'}, btreeset! {'j', 'k', '±', 'Á', 'è'}, btreeset! {'b', '«', '¹', 'Î', 'Ü', 'æ', 'ā'}, btreeset! {'~', '´', 'Î'}, btreeset! {'g', '¯', 'Î', 'Ý', 'Þ', 'â', 'æ', 'é', 'ö'}, btreeset! {'¼', 'Ç', 'Ü'}, btreeset! {'¡', '§', 'Ì'}, btreeset! {'d', 'm', 'z', '{', '¨', '®', '±', '¼', 'Ë', 'Ü', 'ê', 'ì', 'ý', 'þ'}, btreeset! {'x', 'ª', '½', 'À', 'Õ', 'ì', 'ï', 'û', 'ă', 'Ą', 'ċ'}, btreeset! {'¢', '«', 'Ć'}, btreeset! {'{', '¢', '½', 'È', 'ä', 'ÿ'}, btreeset! {'Ë', 'Õ', 'ê'}, btreeset! {'p', '¨', '°', 'º', 'Å', 'Ó', '×', 'ü'}, btreeset! {'d', 'k', 'o', 'v', '¥', '±', 'Ä', 'È', 'Ê', 'ß', 'æ', 'Ć'}, ], &[ (btreeset! {'m', 'u', 'w'}, 6), (btreeset! {'b', 'n', 'Ã'}, 6), (btreeset! {'g', '®', 'Ý'}, 6), (btreeset! {'x', 'Ä', 'î'}, 6), (btreeset! {'º', 'Ú', '÷'}, 6), (btreeset! {'a', 'w', 'ø'}, 5), (btreeset! {'c', 'e', 'Þ'}, 5), (btreeset! {'d', 't', 'Ã'}, 5), (btreeset! {'m', 'r', 'È'}, 5), (btreeset! {'w', '{', '³'}, 5), ], ( btreeset! {'o', 's', '×', 'Ý', 'Þ', 'ß', 'î', 'ù'}, Some(btreeset! {'o', 's', '×', 'à', 'ã', 'ò', 'ċ'}), ), ); } #[test] #[should_panic] fn random_b_tree_sets_min_length_fail_1() { random_b_tree_sets_min_length(EXAMPLE_SEED, 3, &random_primitive_ints::, 3, 1); } #[test] #[should_panic] fn random_b_tree_sets_min_length_fail_2() { random_b_tree_sets_min_length(EXAMPLE_SEED, 1, &random_primitive_ints::, 1, 0); } #[test] #[should_panic] fn random_b_tree_sets_min_length_fail_3() { random_b_tree_sets_min_length( EXAMPLE_SEED, 0, &random_primitive_ints::, u64::MAX, u64::MAX - 1, ); } malachite-base-0.4.16/tests/sets/random/random_hash_sets.rs000064400000000000000000000126411046102023000220460ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use core::hash::Hash; use itertools::Itertools; use malachite_base::chars::exhaustive::exhaustive_chars; use malachite_base::chars::random::graphic_weighted_random_char_inclusive_range; use malachite_base::num::random::geometric::geometric_random_unsigneds; use malachite_base::num::random::random_primitive_ints; use malachite_base::random::{Seed, EXAMPLE_SEED}; use malachite_base::sets::random::random_hash_sets; use std::collections::HashSet; use std::fmt::Debug; fn random_hash_sets_helper>( xs_gen: &dyn Fn(Seed) -> I, mean_length_numerator: u64, mean_length_denominator: u64, expected_values: &[HashSet], ) { let xs = random_hash_sets( EXAMPLE_SEED, xs_gen, mean_length_numerator, mean_length_denominator, ); let values = xs.take(20).collect_vec(); assert_eq!(values.as_slice(), expected_values); } #[test] fn test_random_hash_sets() { random_hash_sets_helper( &random_primitive_ints::, 4, 1, &[ hashset! {}, hashset! {11, 32, 38, 85, 134, 136, 162, 166, 177, 200, 203, 217, 223, 235}, hashset! {30, 90, 218, 234}, hashset! {9, 106, 204, 216}, hashset! {151}, hashset! {}, hashset! {78, 91, 97, 213, 253}, hashset! {39, 191}, hashset! {170, 175, 232, 233}, hashset! {}, hashset! {2, 22, 35, 114, 198, 217}, hashset! {}, hashset! {}, hashset! {17, 25, 32, 65, 79, 114, 121, 144, 148, 173, 222}, hashset! {52, 69, 73, 91, 115, 137, 153, 178}, hashset! {}, hashset! {34, 95, 112}, hashset! {}, hashset! {106, 130, 167, 168, 197}, hashset! {86, 101, 122, 150, 172, 177, 207, 218, 221}, ], ); random_hash_sets_helper( &|seed| geometric_random_unsigneds::(seed, 32, 1), 4, 1, &[ hashset! {}, hashset! {1, 9, 12, 14, 16, 17, 19, 21, 41, 42, 68, 79, 124, 141}, hashset! {0, 1, 10, 99}, hashset! {2, 12, 36, 77}, hashset! {1}, hashset! {}, hashset! {1, 5, 9, 19, 103}, hashset! {6, 7}, hashset! {15, 18, 51, 159}, hashset! {}, hashset! {2, 26, 40, 52, 64, 75}, hashset! {}, hashset! {}, hashset! {3, 4, 5, 7, 30, 31, 34, 43, 49, 51, 67}, hashset! {1, 14, 16, 24, 29, 41, 47, 52}, hashset! {}, hashset! {11, 13, 62}, hashset! {}, hashset! {3, 14, 42, 47, 109}, hashset! {5, 13, 16, 25, 37, 41, 42, 86, 96}, ], ); random_hash_sets_helper( &random_primitive_ints::, 1, 4, &[ hashset! {}, hashset! {}, hashset! {85}, hashset! {11}, hashset! {136, 200}, hashset! {}, hashset! {}, hashset! {}, hashset! {}, hashset! {}, hashset! {}, hashset! {}, hashset! {134, 235}, hashset! {203}, hashset! {}, hashset! {38, 223}, hashset! {}, hashset! {}, hashset! {}, hashset! {}, ], ); random_hash_sets_helper( &|seed| { graphic_weighted_random_char_inclusive_range( seed, 'a', exhaustive_chars().nth(200).unwrap(), 1, 1, ) }, 4, 1, &[ hashset! {}, hashset! {'g', 'q', '³', '»', 'À', 'Á', 'Ã', 'È', 'á', 'â', 'ì', 'ñ', 'Ā', 'ą'}, hashset! {'ª', '´', 'Ã', 'ä'}, hashset! {'½', 'Á', 'Ï', 'ý'}, hashset! {'j'}, hashset! {}, hashset! {'u', '½', 'Â', 'Ñ', 'ï'}, hashset! {'x', 'õ'}, hashset! {'¡', 'Â', 'ù', 'Ċ'}, hashset! {}, hashset! {'b', 'r', 's', '¬', 'Â', 'Ñ'}, hashset! {}, hashset! {}, hashset! {'j', 'n', 't', '¬', 'º', '¿', 'Á', 'Ø', 'Þ', 'ô', 'ü'}, hashset! {'b', 'k', '±', 'Î', 'Ü', 'æ', 'è', 'ā'}, hashset! {}, hashset! {'«', '¹', 'Î'}, hashset! {}, hashset! {'~', '¯', '´', 'Ý', 'â'}, hashset! {'g', '¼', 'Ç', 'Î', 'Ü', 'Þ', 'æ', 'é', 'ö'}, ], ); } #[test] #[should_panic] fn random_hash_sets_fail_1() { random_hash_sets(EXAMPLE_SEED, &random_primitive_ints::, 0, 1); } #[test] #[should_panic] fn random_hash_sets_fail_2() { random_hash_sets(EXAMPLE_SEED, &random_primitive_ints::, 1, 0); } #[test] #[should_panic] fn random_hash_sets_fail_3() { random_hash_sets( EXAMPLE_SEED, &random_primitive_ints::, u64::MAX, u64::MAX - 1, ); } malachite-base-0.4.16/tests/sets/random/random_hash_sets_fixed_length.rs000064400000000000000000000100521046102023000245600ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::{repeat_n, Itertools}; use malachite_base::bools::random::random_bools; use malachite_base::num::random::random_primitive_ints; use malachite_base::random::EXAMPLE_SEED; use malachite_base::sets::random::random_hash_sets_fixed_length; use malachite_base::vecs::random::random_ordered_unique_vecs_fixed_length; use std::collections::HashSet; use std::fmt::Debug; use std::hash::Hash; fn random_hash_sets_fixed_length_helper( len: u64, xs: I, expected_values: &[HashSet], ) where I::Item: Debug + Eq + Hash, { let xs = random_hash_sets_fixed_length(len, xs); let values = xs.take(20).collect_vec(); assert_eq!(values.as_slice(), expected_values); } #[test] fn test_random_hash_sets_fixed_length() { random_hash_sets_fixed_length_helper( 0, random_primitive_ints::(EXAMPLE_SEED), &repeat_n(hashset! {}, 20).collect_vec(), ); random_hash_sets_fixed_length_helper( 1, random_bools(EXAMPLE_SEED), &[ hashset! {true}, hashset! {false}, hashset! {false}, hashset! {false}, hashset! {true}, hashset! {true}, hashset! {true}, hashset! {false}, hashset! {true}, hashset! {true}, hashset! {true}, hashset! {true}, hashset! {false}, hashset! {true}, hashset! {true}, hashset! {true}, hashset! {true}, hashset! {false}, hashset! {true}, hashset! {false}, ], ); random_hash_sets_fixed_length_helper( 3, random_primitive_ints::(EXAMPLE_SEED), &[ hashset! {69, 113, 239}, hashset! {108, 210, 228}, hashset! {87, 161, 168}, hashset! {32, 83, 110}, hashset! {34, 89, 188}, hashset! {93, 200, 238}, hashset! {115, 149, 189}, hashset! {149, 201, 217}, hashset! {31, 117, 146}, hashset! {72, 151, 169}, hashset! {7, 33, 174}, hashset! {38, 81, 144}, hashset! {72, 113, 127}, hashset! {107, 128, 233}, hashset! {12, 46, 119}, hashset! {18, 164, 243}, hashset! {59, 114, 174}, hashset! {39, 174, 247}, hashset! {104, 160, 184}, hashset! {37, 100, 252}, ], ); random_hash_sets_fixed_length_helper( 2, random_ordered_unique_vecs_fixed_length(2, random_primitive_ints::(EXAMPLE_SEED)), &[ hashset! {vec![69, 108], vec![113, 239]}, hashset! {vec![161, 168], vec![210, 228]}, hashset! {vec![32, 87], vec![83, 110]}, hashset! {vec![34, 188], vec![89, 238]}, hashset! {vec![93, 200], vec![115, 149]}, hashset! {vec![149, 189], vec![201, 217]}, hashset! {vec![31, 72], vec![117, 146]}, hashset! {vec![33, 174], vec![151, 169]}, hashset! {vec![7, 38], vec![81, 144]}, hashset! {vec![72, 127], vec![113, 128]}, hashset! {vec![46, 119], vec![107, 233]}, hashset! {vec![12, 18], vec![164, 243]}, hashset! {vec![59, 247], vec![114, 174]}, hashset! {vec![39, 174], vec![160, 184]}, hashset! {vec![37, 104], vec![100, 252]}, hashset! {vec![69, 107], vec![122, 228]}, hashset! {vec![142, 179], vec![242, 248]}, hashset! {vec![61, 189], vec![233, 239]}, hashset! {vec![7, 192], vec![85, 235]}, hashset! {vec![90, 200], vec![178, 185]}, ], ); } malachite-base-0.4.16/tests/sets/random/random_hash_sets_from_length_iterator.rs000064400000000000000000000064041046102023000263430ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::bools::random::random_bools; use malachite_base::num::random::geometric::geometric_random_unsigneds; use malachite_base::num::random::random_primitive_ints; use malachite_base::random::{Seed, EXAMPLE_SEED}; use malachite_base::sets::random::random_hash_sets_from_length_iterator; use malachite_base::vecs::random_values_from_vec; use std::collections::HashSet; use std::fmt::Debug; use std::hash::Hash; fn random_hash_sets_from_length_iterator_helper< T: Clone + Debug + Eq + Hash, I: Clone + Iterator, J: Clone + Iterator, >( lengths_gen: &dyn Fn(Seed) -> I, xs_gen: &dyn Fn(Seed) -> J, expected_values: &[HashSet], ) { let xs = random_hash_sets_from_length_iterator(EXAMPLE_SEED, lengths_gen, xs_gen); let values = xs.take(20).collect_vec(); assert_eq!(values.as_slice(), expected_values); } #[test] fn test_random_hash_sets_from_length_iterator() { random_hash_sets_from_length_iterator_helper( &|seed| random_values_from_vec(seed, vec![0, 2]), &random_bools, &[ hashset! {false, true}, hashset! {}, hashset! {false, true}, hashset! {false, true}, hashset! {}, hashset! {false, true}, hashset! {false, true}, hashset! {}, hashset! {false, true}, hashset! {false, true}, hashset! {}, hashset! {false, true}, hashset! {}, hashset! {false, true}, hashset! {false, true}, hashset! {}, hashset! {}, hashset! {}, hashset! {false, true}, hashset! {}, ], ); random_hash_sets_from_length_iterator_helper( &|seed| geometric_random_unsigneds::(seed, 2, 1).map(|x| x << 1), &random_primitive_ints::, &[ hashset! {11, 38, 85, 134, 136, 162, 177, 200, 203, 217, 223, 235}, hashset! {32, 166}, hashset! {9, 30, 39, 78, 90, 91, 97, 106, 151, 191, 204, 213, 216, 218, 234, 253}, hashset! {170, 175}, hashset! { 2, 17, 22, 25, 32, 34, 35, 52, 65, 69, 73, 79, 91, 112, 114, 115, 121, 137, 144, 148, 153, 173, 178, 198, 217, 222, 232, 233, }, hashset! {}, hashset! {95, 106, 122, 130, 167, 168, 172, 177, 197, 207}, hashset! {9, 74, 86, 101, 115, 150, 218, 221}, hashset! {109, 123}, hashset! {}, hashset! {40, 48, 52, 97, 104, 133, 159, 196, 201, 235, 247, 250}, hashset! {7, 68, 190, 216}, hashset! {}, hashset! {}, hashset! {157, 216}, hashset! {11, 24, 43, 103, 112, 217}, hashset! {}, hashset! {84, 211}, hashset! {}, hashset! {55, 135}, ], ); } malachite-base-0.4.16/tests/sets/random/random_hash_sets_length_inclusive_range.rs000064400000000000000000000075361046102023000266530ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use core::hash::Hash; use itertools::Itertools; use malachite_base::chars::random::random_char_inclusive_range; use malachite_base::num::random::geometric::geometric_random_unsigneds; use malachite_base::num::random::random_primitive_ints; use malachite_base::random::{Seed, EXAMPLE_SEED}; use malachite_base::sets::random::random_hash_sets_length_inclusive_range; use std::collections::HashSet; use std::fmt::Debug; fn random_hash_sets_length_inclusive_range_helper< T: Clone + Debug + Eq + Hash + Ord, I: Clone + Iterator, >( a: u64, b: u64, xs_gen: &dyn Fn(Seed) -> I, expected_values: &[HashSet], ) { let xs = random_hash_sets_length_inclusive_range(EXAMPLE_SEED, a, b, xs_gen); let values = xs.take(20).collect_vec(); assert_eq!(values.as_slice(), expected_values); } #[test] fn test_random_hash_sets_length_inclusive_range() { random_hash_sets_length_inclusive_range_helper( 2, 3, &random_primitive_ints::, &[ hashset! {11, 85, 136}, hashset! {200, 235}, hashset! {134, 203, 223}, hashset! {38, 217, 235}, hashset! {162, 177}, hashset! {32, 166, 234}, hashset! {30, 90, 218}, hashset! {9, 106}, hashset! {151, 204, 216}, hashset! {97, 213, 253}, hashset! {78, 91}, hashset! {39, 175, 191}, hashset! {170, 232}, hashset! {2, 35, 233}, hashset! {22, 198, 217}, hashset! {17, 114}, hashset! {32, 173}, hashset! {65, 114}, hashset! {121, 173, 222}, hashset! {25, 144}, ], ); random_hash_sets_length_inclusive_range_helper( 2, 3, &|seed| geometric_random_unsigneds::(seed, 2, 1), &[ hashset! {0, 1, 5}, hashset! {1, 4}, hashset! {2, 4, 6}, hashset! {0, 1, 2}, hashset! {9, 13}, hashset! {0, 2, 7}, hashset! {4, 6, 7}, hashset! {0, 6}, hashset! {0, 1, 3}, hashset! {1, 2, 5}, hashset! {0, 1}, hashset! {0, 1, 4}, hashset! {0, 2}, hashset! {0, 2, 12}, hashset! {1, 2, 3}, hashset! {3, 9}, hashset! {0, 1}, hashset! {1, 2}, hashset! {0, 1, 11}, hashset! {1, 6}, ], ); random_hash_sets_length_inclusive_range_helper( 2, 3, &|seed| random_char_inclusive_range(seed, 'a', 'z'), &[ hashset! {'c', 'q', 'v'}, hashset! {'e', 'i'}, hashset! {'g', 'p', 's'}, hashset! {'m', 'n', 't'}, hashset! {'o', 'z'}, hashset! {'f', 'k', 'm'}, hashset! {'q', 'u', 'y'}, hashset! {'k', 'x'}, hashset! {'h', 'n', 'u'}, hashset! {'a', 'j', 'n'}, hashset! {'w', 'z'}, hashset! {'b', 'l', 'w'}, hashset! {'l', 'u'}, hashset! {'e', 'l', 'n'}, hashset! {'k', 'u', 'v'}, hashset! {'c', 'h'}, hashset! {'i', 'y'}, hashset! {'m', 'r'}, hashset! {'m', 's', 'y'}, hashset! {'e', 'l'}, ], ); } #[test] #[should_panic] fn random_hash_sets_length_inclusive_range_fail() { random_hash_sets_length_inclusive_range(EXAMPLE_SEED, 2, 1, &random_primitive_ints::); } malachite-base-0.4.16/tests/sets/random/random_hash_sets_length_range.rs000064400000000000000000000074041046102023000245640ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use core::hash::Hash; use itertools::Itertools; use malachite_base::chars::random::random_char_inclusive_range; use malachite_base::num::random::geometric::geometric_random_unsigneds; use malachite_base::num::random::random_primitive_ints; use malachite_base::random::{Seed, EXAMPLE_SEED}; use malachite_base::sets::random::random_hash_sets_length_range; use std::collections::HashSet; use std::fmt::Debug; fn random_hash_sets_length_range_helper< T: Clone + Debug + Eq + Hash + Ord, I: Clone + Iterator, >( a: u64, b: u64, xs_gen: &dyn Fn(Seed) -> I, expected_values: &[HashSet], ) { let xs = random_hash_sets_length_range(EXAMPLE_SEED, a, b, xs_gen); let values = xs.take(20).collect_vec(); assert_eq!(values.as_slice(), expected_values); } #[test] fn test_random_hash_sets_length_range() { random_hash_sets_length_range_helper( 2, 4, &random_primitive_ints::, &[ hashset! {11, 85, 136}, hashset! {200, 235}, hashset! {134, 203, 223}, hashset! {38, 217, 235}, hashset! {162, 177}, hashset! {32, 166, 234}, hashset! {30, 90, 218}, hashset! {9, 106}, hashset! {151, 204, 216}, hashset! {97, 213, 253}, hashset! {78, 91}, hashset! {39, 175, 191}, hashset! {170, 232}, hashset! {2, 35, 233}, hashset! {22, 198, 217}, hashset! {17, 114}, hashset! {32, 173}, hashset! {65, 114}, hashset! {121, 173, 222}, hashset! {25, 144}, ], ); random_hash_sets_length_range_helper( 2, 4, &|seed| geometric_random_unsigneds::(seed, 2, 1), &[ hashset! {0, 1, 5}, hashset! {1, 4}, hashset! {2, 4, 6}, hashset! {0, 1, 2}, hashset! {9, 13}, hashset! {0, 2, 7}, hashset! {4, 6, 7}, hashset! {0, 6}, hashset! {0, 1, 3}, hashset! {1, 2, 5}, hashset! {0, 1}, hashset! {0, 1, 4}, hashset! {0, 2}, hashset! {0, 2, 12}, hashset! {1, 2, 3}, hashset! {3, 9}, hashset! {0, 1}, hashset! {1, 2}, hashset! {0, 1, 11}, hashset! {1, 6}, ], ); random_hash_sets_length_range_helper( 2, 4, &|seed| random_char_inclusive_range(seed, 'a', 'z'), &[ hashset! {'c', 'q', 'v'}, hashset! {'e', 'i'}, hashset! {'g', 'p', 's'}, hashset! {'m', 'n', 't'}, hashset! {'o', 'z'}, hashset! {'f', 'k', 'm'}, hashset! {'q', 'u', 'y'}, hashset! {'k', 'x'}, hashset! {'h', 'n', 'u'}, hashset! {'a', 'j', 'n'}, hashset! {'w', 'z'}, hashset! {'b', 'l', 'w'}, hashset! {'l', 'u'}, hashset! {'e', 'l', 'n'}, hashset! {'k', 'u', 'v'}, hashset! {'c', 'h'}, hashset! {'i', 'y'}, hashset! {'m', 'r'}, hashset! {'m', 's', 'y'}, hashset! {'e', 'l'}, ], ); } #[test] #[should_panic] fn random_hash_sets_length_range_fail() { random_hash_sets_length_range(EXAMPLE_SEED, 2, 2, &random_primitive_ints::); } malachite-base-0.4.16/tests/sets/random/random_hash_sets_min_length.rs000064400000000000000000000247601046102023000242570ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use core::hash::Hash; use itertools::Itertools; use malachite_base::chars::exhaustive::exhaustive_chars; use malachite_base::chars::random::graphic_weighted_random_char_inclusive_range; use malachite_base::num::random::geometric::geometric_random_unsigneds; use malachite_base::num::random::random_primitive_ints; use malachite_base::random::{Seed, EXAMPLE_SEED}; use malachite_base::sets::random::random_hash_sets_min_length; use std::collections::HashSet; use std::fmt::Debug; fn random_hash_sets_min_length_helper< T: Clone + Debug + Eq + Hash + Ord, I: Clone + Iterator, >( min_length: u64, xs_gen: &dyn Fn(Seed) -> I, mean_length_numerator: u64, mean_length_denominator: u64, expected_values: &[HashSet], ) { let xs = random_hash_sets_min_length( EXAMPLE_SEED, min_length, xs_gen, mean_length_numerator, mean_length_denominator, ); let values = xs.take(20).collect_vec(); assert_eq!(values.as_slice(), expected_values); } #[test] fn test_random_hash_sets_min_length() { random_hash_sets_min_length_helper( 0, &random_primitive_ints::, 4, 1, &[ hashset! {}, hashset! {11, 32, 38, 85, 134, 136, 162, 166, 177, 200, 203, 217, 223, 235}, hashset! {30, 90, 218, 234}, hashset! {9, 106, 204, 216}, hashset! {151}, hashset! {}, hashset! {78, 91, 97, 213, 253}, hashset! {39, 191}, hashset! {170, 175, 232, 233}, hashset! {}, hashset! {2, 22, 35, 114, 198, 217}, hashset! {}, hashset! {}, hashset! {17, 25, 32, 65, 79, 114, 121, 144, 148, 173, 222}, hashset! {52, 69, 73, 91, 115, 137, 153, 178}, hashset! {}, hashset! {34, 95, 112}, hashset! {}, hashset! {106, 130, 167, 168, 197}, hashset! {86, 101, 122, 150, 172, 177, 207, 218, 221}, ], ); random_hash_sets_min_length_helper( 3, &random_primitive_ints::, 7, 1, &[ hashset! {11, 85, 136}, hashset! { 9, 30, 32, 38, 90, 106, 134, 162, 166, 177, 200, 203, 217, 218, 223, 234, 235 }, hashset! {78, 97, 151, 204, 213, 216, 253}, hashset! {39, 91, 170, 175, 191, 232, 233}, hashset! {2, 22, 35, 217}, hashset! {17, 114, 198}, hashset! {25, 32, 65, 114, 121, 144, 173, 222}, hashset! {52, 73, 79, 115, 148}, hashset! {34, 69, 91, 112, 137, 153, 178}, hashset! {95, 106, 167}, hashset! {86, 122, 130, 150, 168, 172, 177, 197, 207}, hashset! {101, 218, 221}, hashset! {9, 74, 115}, hashset! {40, 48, 52, 97, 104, 109, 123, 133, 159, 196, 201, 235, 247, 250}, hashset! {7, 11, 24, 43, 68, 103, 112, 157, 190, 216, 217}, hashset! {84, 135, 211}, hashset! {29, 55, 65, 89, 191, 206}, hashset! {9, 51, 79}, hashset! {3, 20, 22, 34, 62, 114, 118, 148}, hashset! {23, 32, 47, 50, 120, 166, 176, 177, 194, 204, 238, 248}, ], ); random_hash_sets_min_length_helper( 0, &|seed| geometric_random_unsigneds::(seed, 32, 1), 4, 1, &[ hashset! {}, hashset! {1, 9, 12, 14, 16, 17, 19, 21, 41, 42, 68, 79, 124, 141}, hashset! {0, 1, 10, 99}, hashset! {2, 12, 36, 77}, hashset! {1}, hashset! {}, hashset! {1, 5, 9, 19, 103}, hashset! {6, 7}, hashset! {15, 18, 51, 159}, hashset! {}, hashset! {2, 26, 40, 52, 64, 75}, hashset! {}, hashset! {}, hashset! {3, 4, 5, 7, 30, 31, 34, 43, 49, 51, 67}, hashset! {1, 14, 16, 24, 29, 41, 47, 52}, hashset! {}, hashset! {11, 13, 62}, hashset! {}, hashset! {3, 14, 42, 47, 109}, hashset! {5, 13, 16, 25, 37, 41, 42, 86, 96}, ], ); random_hash_sets_min_length_helper( 3, &|seed| geometric_random_unsigneds::(seed, 32, 1), 7, 1, &[ hashset! {1, 14, 42}, hashset! {0, 1, 9, 10, 12, 16, 17, 19, 21, 36, 41, 68, 77, 79, 99, 124, 141}, hashset! {1, 2, 5, 9, 12, 19, 103}, hashset! {6, 7, 15, 18, 51, 52, 159}, hashset! {2, 40, 64, 75}, hashset! {26, 34, 67}, hashset! {4, 5, 7, 30, 31, 43, 49, 51}, hashset! {3, 14, 16, 24, 47}, hashset! {1, 11, 13, 29, 41, 52, 62}, hashset! {3, 47, 109}, hashset! {13, 14, 16, 25, 37, 41, 42, 86, 96}, hashset! {5, 20, 42}, hashset! {2, 74, 82}, hashset! {3, 6, 7, 11, 17, 20, 36, 45, 56, 66, 76, 80, 89, 127}, hashset! {1, 6, 10, 13, 19, 23, 25, 32, 41, 43, 97}, hashset! {7, 41, 134}, hashset! {9, 10, 25, 26, 47, 105}, hashset! {68, 94, 109}, hashset! {1, 3, 9, 13, 28, 43, 44, 84}, hashset! {0, 4, 5, 6, 7, 13, 31, 32, 37, 42, 50, 75}, ], ); random_hash_sets_min_length_helper( 0, &random_primitive_ints::, 1, 4, &[ hashset! {}, hashset! {}, hashset! {85}, hashset! {11}, hashset! {136, 200}, hashset! {}, hashset! {}, hashset! {}, hashset! {}, hashset! {}, hashset! {}, hashset! {}, hashset! {134, 235}, hashset! {203}, hashset! {}, hashset! {38, 223}, hashset! {}, hashset! {}, hashset! {}, hashset! {}, ], ); random_hash_sets_min_length_helper( 3, &random_primitive_ints::, 13, 4, &[ hashset! {11, 85, 136}, hashset! {134, 200, 235}, hashset! {38, 203, 223, 235}, hashset! {32, 162, 177, 217}, hashset! {30, 90, 166, 218, 234}, hashset! {9, 106, 216}, hashset! {151, 204, 213}, hashset! {78, 97, 253}, hashset! {39, 91, 191}, hashset! {170, 175, 232}, hashset! {2, 35, 233}, hashset! {22, 198, 217}, hashset! {17, 32, 65, 114, 173}, hashset! {25, 121, 173, 222}, hashset! {79, 144, 148}, hashset! {52, 69, 73, 115, 137}, hashset! {91, 153, 178}, hashset! {34, 95, 112}, hashset! {106, 167, 197}, hashset! {122, 130, 168}, ], ); random_hash_sets_min_length_helper( 0, &|seed| { graphic_weighted_random_char_inclusive_range( seed, 'a', exhaustive_chars().nth(200).unwrap(), 1, 1, ) }, 4, 1, &[ hashset! {}, hashset! {'g', 'q', '³', '»', 'À', 'Á', 'Ã', 'È', 'á', 'â', 'ì', 'ñ', 'Ā', 'ą'}, hashset! {'ª', '´', 'Ã', 'ä'}, hashset! {'½', 'Á', 'Ï', 'ý'}, hashset! {'j'}, hashset! {}, hashset! {'u', '½', 'Â', 'Ñ', 'ï'}, hashset! {'x', 'õ'}, hashset! {'¡', 'Â', 'ù', 'Ċ'}, hashset! {}, hashset! {'b', 'r', 's', '¬', 'Â', 'Ñ'}, hashset! {}, hashset! {}, hashset! {'j', 'n', 't', '¬', 'º', '¿', 'Á', 'Ø', 'Þ', 'ô', 'ü'}, hashset! {'b', 'k', '±', 'Î', 'Ü', 'æ', 'è', 'ā'}, hashset! {}, hashset! {'«', '¹', 'Î'}, hashset! {}, hashset! {'~', '¯', '´', 'Ý', 'â'}, hashset! {'g', '¼', 'Ç', 'Î', 'Ü', 'Þ', 'æ', 'é', 'ö'}, ], ); random_hash_sets_min_length_helper( 3, &|seed| { graphic_weighted_random_char_inclusive_range( seed, 'a', exhaustive_chars().nth(200).unwrap(), 1, 1, ) }, 7, 1, &[ hashset! {'g', 'q', 'á'}, hashset! { 'g', 'ª', '³', '´', '»', '½', 'À', 'Á', 'Ã', 'È', 'Ï', 'â', 'ä', 'ì', 'ñ', 'Ā', 'ą', }, hashset! {'j', 'u', '½', 'Â', 'Ñ', 'ï', 'ý'}, hashset! {'x', '¡', '¬', 'Â', 'õ', 'ù', 'Ċ'}, hashset! {'b', 's', '¬', 'Ñ'}, hashset! {'n', 'r', 'Â'}, hashset! {'t', '¬', 'º', '¿', 'Ø', 'Þ', 'ô', 'ü'}, hashset! {'j', 'k', '±', 'Á', 'è'}, hashset! {'b', '«', '¹', 'Î', 'Ü', 'æ', 'ā'}, hashset! {'~', '´', 'Î'}, hashset! {'g', '¯', 'Î', 'Ý', 'Þ', 'â', 'æ', 'é', 'ö'}, hashset! {'¼', 'Ç', 'Ü'}, hashset! {'¡', '§', 'Ì'}, hashset! {'d', 'm', 'z', '{', '¨', '®', '±', '¼', 'Ë', 'Ü', 'ê', 'ì', 'ý', 'þ'}, hashset! {'x', 'ª', '½', 'À', 'Õ', 'ì', 'ï', 'û', 'ă', 'Ą', 'ċ'}, hashset! {'¢', '«', 'Ć'}, hashset! {'{', '¢', '½', 'È', 'ä', 'ÿ'}, hashset! {'Ë', 'Õ', 'ê'}, hashset! {'p', '¨', '°', 'º', 'Å', 'Ó', '×', 'ü'}, hashset! {'d', 'k', 'o', 'v', '¥', '±', 'Ä', 'È', 'Ê', 'ß', 'æ', 'Ć'}, ], ); } #[test] #[should_panic] fn random_hash_sets_min_length_fail_1() { random_hash_sets_min_length(EXAMPLE_SEED, 3, &random_primitive_ints::, 3, 1); } #[test] #[should_panic] fn random_hash_sets_min_length_fail_2() { random_hash_sets_min_length(EXAMPLE_SEED, 1, &random_primitive_ints::, 1, 0); } #[test] #[should_panic] fn random_hash_sets_min_length_fail_3() { random_hash_sets_min_length( EXAMPLE_SEED, 0, &random_primitive_ints::, u64::MAX, u64::MAX - 1, ); } malachite-base-0.4.16/tests/slices/exhaustive_slice_permutations.rs000064400000000000000000000062701046102023000237300ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::num::arithmetic::traits::Factorial; use malachite_base::num::conversion::traits::WrappingFrom; use malachite_base::slices::exhaustive_slice_permutations; fn exhaustive_slice_permutations_helper(cs: &str, out: &[&str]) { let cs = cs.chars().collect_vec(); let css: Vec = exhaustive_slice_permutations(&cs) .map(|ds| ds.into_iter().copied().collect()) .collect(); assert_eq!(css.len(), usize::factorial(u64::wrapping_from(cs.len()))); assert_eq!(css.iter().map(String::as_str).collect_vec().as_slice(), out); } #[test] fn test_exhaustive_slice_permutations() { exhaustive_slice_permutations_helper("", &[""]); exhaustive_slice_permutations_helper("1", &["1"]); exhaustive_slice_permutations_helper("12", &["12", "21"]); exhaustive_slice_permutations_helper("123", &["123", "132", "213", "231", "312", "321"]); exhaustive_slice_permutations_helper( "1234", &[ "1234", "1243", "1324", "1342", "1423", "1432", "2134", "2143", "2314", "2341", "2413", "2431", "3124", "3142", "3214", "3241", "3412", "3421", "4123", "4132", "4213", "4231", "4312", "4321", ], ); exhaustive_slice_permutations_helper( "12345", &[ "12345", "12354", "12435", "12453", "12534", "12543", "13245", "13254", "13425", "13452", "13524", "13542", "14235", "14253", "14325", "14352", "14523", "14532", "15234", "15243", "15324", "15342", "15423", "15432", "21345", "21354", "21435", "21453", "21534", "21543", "23145", "23154", "23415", "23451", "23514", "23541", "24135", "24153", "24315", "24351", "24513", "24531", "25134", "25143", "25314", "25341", "25413", "25431", "31245", "31254", "31425", "31452", "31524", "31542", "32145", "32154", "32415", "32451", "32514", "32541", "34125", "34152", "34215", "34251", "34512", "34521", "35124", "35142", "35214", "35241", "35412", "35421", "41235", "41253", "41325", "41352", "41523", "41532", "42135", "42153", "42315", "42351", "42513", "42531", "43125", "43152", "43215", "43251", "43512", "43521", "45123", "45132", "45213", "45231", "45312", "45321", "51234", "51243", "51324", "51342", "51423", "51432", "52134", "52143", "52314", "52341", "52413", "52431", "53124", "53142", "53214", "53241", "53412", "53421", "54123", "54132", "54213", "54231", "54312", "54321", ], ); exhaustive_slice_permutations_helper( "abcd", &[ "abcd", "abdc", "acbd", "acdb", "adbc", "adcb", "bacd", "badc", "bcad", "bcda", "bdac", "bdca", "cabd", "cadb", "cbad", "cbda", "cdab", "cdba", "dabc", "dacb", "dbac", "dbca", "dcab", "dcba", ], ); } malachite-base-0.4.16/tests/slices/min_repeating_len.rs000064400000000000000000000034461046102023000212330ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::DivisibleBy; use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::slices::min_repeating_len; use malachite_base::test_util::generators::common::GenConfig; use malachite_base::test_util::generators::{unsigned_gen, unsigned_vec_gen_var_4}; #[test] fn test_min_repeating_len() { let test = |xs: &[u32], out| { assert_eq!(min_repeating_len(xs), out); }; test(&[1, 2, 1, 2, 1, 2], 2); test(&[1, 2, 1, 2, 1, 3], 6); test(&[5, 5, 5], 1); test(&[100], 1); } #[test] #[should_panic] fn min_repeating_len_fail() { min_repeating_len::(&[]); } #[test] fn min_repeating_len_properties() { let mut config = GenConfig::new(); config.insert("mean_length_n", 32); config.insert("mean_length_d", 1); config.insert("mean_stripe_n", 16 << u8::LOG_WIDTH); config.insert("mean_stripe_d", 1); unsigned_vec_gen_var_4::().test_properties_with_config(&config, |xs| { let len = xs.len(); let repeating_len = min_repeating_len(&xs); assert_ne!(repeating_len, 0); assert!(len.divisible_by(repeating_len)); let rep = &xs[..repeating_len]; assert_eq!(min_repeating_len(rep), repeating_len); assert!(Iterator::eq(rep.iter().cycle().take(len), xs.iter())); }); unsigned_gen::().test_properties_with_config(&config, |x| { assert_eq!(min_repeating_len(&[x]), 1); }); } malachite-base-0.4.16/tests/slices/random_slice_permutations.rs000064400000000000000000000077651046102023000230350ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::random::EXAMPLE_SEED; use malachite_base::slices::random_slice_permutations; use malachite_base::test_util::stats::common_values_map::common_values_map; use malachite_base::test_util::stats::median; fn random_slice_permutations_helper( cs: &str, expected_values: &[&str], expected_common_values: &[(&str, usize)], expected_median: (&str, Option<&str>), ) { let cs = cs.chars().collect_vec(); let ss = random_slice_permutations(EXAMPLE_SEED, &cs).map(|ds| ds.into_iter().copied().collect()); let values = ss.clone().take(20).collect_vec(); let common_values = common_values_map(1000000, 10, ss.clone()); let (median_lo, median_hi) = median(ss.take(1000000)); assert_eq!( ( values.iter().map(String::as_str).collect_vec().as_slice(), common_values .iter() .map(|(s, f)| (s.as_str(), *f)) .collect_vec() .as_slice(), (median_lo.as_str(), median_hi.as_deref()) ), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_random_slice_permutations() { random_slice_permutations_helper("", &[""; 20], &[("", 1000000)], ("", None)); random_slice_permutations_helper("a", &["a"; 20], &[("a", 1000000)], ("a", None)); random_slice_permutations_helper( "ab", &[ "ab", "ba", "ba", "ba", "ba", "ba", "ba", "ab", "ab", "ab", "ab", "ab", "ba", "ba", "ab", "ba", "ba", "ba", "ab", "ba", ], &[("ab", 500433), ("ba", 499567)], ("ab", None), ); random_slice_permutations_helper( "abc", &[ "acb", "bac", "bca", "bac", "bca", "acb", "acb", "cab", "acb", "bca", "cab", "bac", "abc", "acb", "cab", "cba", "bac", "bac", "cab", "cba", ], &[ ("acb", 167689), ("cba", 167200), ("cab", 166428), ("bca", 166332), ("bac", 166279), ("abc", 166072), ], ("bac", None), ); random_slice_permutations_helper( "abcd", &[ "cadb", "cbad", "cadb", "badc", "acdb", "cbad", "dabc", "dbca", "cdba", "cdab", "bacd", "cabd", "adbc", "cdab", "dcab", "abcd", "abcd", "dacb", "bcad", "adcb", ], &[ ("dabc", 41997), ("dbac", 41989), ("dcab", 41951), ("acbd", 41923), ("cdba", 41816), ("bcad", 41795), ("bdca", 41760), ("dacb", 41738), ("dbca", 41735), ("bdac", 41723), ], ("cabd", None), ); random_slice_permutations_helper( "abcdefghij", &[ "acjbhfdgie", "cbijehgfda", "fjageibdhc", "abcjefgdih", "gicjbfehda", "ahdjfciebg", "hfcdgeaibj", "gacdhjibfe", "cabejhdigf", "bicfdjhage", "jfhcgdbeai", "bifcedghja", "ifahdgebjc", "aefgicjhbd", "ebafcjhdgi", "eihjdcabgf", "ehiajdcfgb", "cgehadjibf", "hfcabdgije", "fjhiedgbac", ], &[ ("hieafgbdjc", 6), ("agdcihfjeb", 5), ("aigjfdehcb", 5), ("aijdhcefgb", 5), ("aijgcdbehf", 5), ("badjcigfhe", 5), ("bfhadgcjie", 5), ("bgjfdcheia", 5), ("bhfigadjec", 5), ("bjigahdfec", 5), ], ("fabdjchgie", Some("fabdjchieg")), ); } malachite-base-0.4.16/tests/slices/random_values_from_slice.rs000064400000000000000000000042521046102023000226110ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::nevers::Never; use malachite_base::random::EXAMPLE_SEED; use malachite_base::slices::random_values_from_slice; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; #[test] fn test_random_values_from_slice() { let test = |slice: &[u32], values: &[u32], common_values: &[(u32, usize)], actual_median: (u32, Option)| { let xs = random_values_from_slice(EXAMPLE_SEED, slice).cloned(); let expected_values = xs.clone().take(20).collect_vec(); let expected_common_values = common_values_map_debug(1000000, 10, xs.clone()); let expected_median = median(xs.take(1000000)); assert_eq!( ( expected_values.as_slice(), expected_common_values.as_slice(), expected_median ), (values, common_values, actual_median) ); }; test(&[5], &[5; 20], &[(5, 1000000)], (5, None)); test( &[0, 1], &[1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0], &[(1, 500473), (0, 499527)], (1, None), ); test( &[1, 1, 1, 10], &[ 1, 1, 10, 1, 10, 10, 1, 10, 1, 1, 1, 1, 1, 10, 1, 1, 1, 1, 1, 10, ], &[(1, 749985), (10, 250015)], (1, None), ); test( &[2, 3, 5, 7, 11], &[ 3, 7, 3, 5, 11, 3, 5, 11, 2, 2, 5, 5, 2, 11, 2, 11, 5, 11, 5, 3, ], &[ (2, 200420), (7, 200369), (11, 200347), (5, 199589), (3, 199275), ], (5, None), ); } #[test] #[should_panic] fn random_values_from_slice_fail() { random_values_from_slice::(EXAMPLE_SEED, &[]); } malachite-base-0.4.16/tests/slices/slice_leading_zeros.rs000064400000000000000000000031131046102023000215470ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::slices::{slice_leading_zeros, slice_test_zero, slice_trailing_zeros}; use malachite_base::test_util::generators::common::GenConfig; use malachite_base::test_util::generators::unsigned_vec_gen; #[test] fn test_slice_leading_zeros() { let test = |xs: &[u32], out| { assert_eq!(slice_leading_zeros(xs), out); }; test(&[], 0); test(&[0], 1); test(&[0, 0, 0], 3); test(&[123], 0); test(&[123, 0], 0); test(&[0, 123, 0, 0, 0], 1); test(&[1, 2, 3], 0); test(&[0, 0, 0, 1, 2, 3], 3); } #[test] fn slice_leading_zeros_properties() { let mut config = GenConfig::new(); config.insert("mean_length_n", 32); config.insert("mean_length_d", 1); config.insert("mean_stripe_n", 16 << u8::LOG_WIDTH); config.insert("mean_stripe_d", 1); unsigned_vec_gen::().test_properties_with_config(&config, |xs| { let leading_zeros = slice_leading_zeros(&xs); assert!(leading_zeros <= xs.len()); assert_eq!(leading_zeros == xs.len(), slice_test_zero(&xs)); let mut new_xs = xs; new_xs.reverse(); assert_eq!(slice_trailing_zeros(&new_xs), leading_zeros); }); } malachite-base-0.4.16/tests/slices/slice_move_left.rs000064400000000000000000000051771046102023000207160ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::slices::slice_move_left; use malachite_base::test_util::generators::common::GenConfig; use malachite_base::test_util::generators::{ unsigned_vec_gen, unsigned_vec_unsigned_pair_gen_var_1, }; use malachite_base::test_util::slices::slice_move_left_naive; #[test] fn test_slice_move_left() { let test = |xs_in: &[u32], amount, xs_out: &[u32]| { let mut xs = xs_in.to_vec(); slice_move_left(&mut xs, amount); assert_eq!(xs, xs_out); let mut xs = xs_in.to_vec(); slice_move_left_naive::(&mut xs, amount); assert_eq!(xs, xs_out); }; test(&[], 0, &[]); test(&[1], 0, &[1]); test(&[1], 1, &[1]); test(&[1, 2, 3], 0, &[1, 2, 3]); test(&[1, 2, 3], 1, &[2, 3, 3]); test(&[1, 2, 3], 2, &[3, 2, 3]); test(&[1, 2, 3], 3, &[1, 2, 3]); test(&[1, 2, 3, 4, 5, 6], 2, &[3, 4, 5, 6, 5, 6]); } #[test] #[should_panic] fn slice_move_left_fail_1() { let xs = &mut []; slice_move_left::(xs, 1); } #[test] #[should_panic] fn slice_move_left_fail_2() { let xs = &mut [1, 2, 3]; slice_move_left::(xs, 4); } #[test] fn slice_move_left_properties() { let mut config = GenConfig::new(); config.insert("mean_length_n", 32); config.insert("mean_length_d", 1); config.insert("mean_stripe_n", 16 << u8::LOG_WIDTH); config.insert("mean_stripe_d", 1); unsigned_vec_unsigned_pair_gen_var_1::().test_properties_with_config( &config, |(mut xs, amount)| { let old_xs = xs.clone(); slice_move_left(&mut xs, amount); let boundary = old_xs.len() - amount; let (xs_lo, xs_hi) = xs.split_at(boundary); assert_eq!(xs_lo, &old_xs[amount..]); assert_eq!(xs_hi, &old_xs[boundary..]); let mut xs_alt = old_xs; slice_move_left_naive(&mut xs_alt, amount); assert_eq!(xs_alt, xs); }, ); unsigned_vec_gen::().test_properties_with_config(&config, |mut xs| { let old_xs = xs.clone(); slice_move_left(&mut xs, 0); assert_eq!(xs, old_xs); let mut xs = old_xs.clone(); slice_move_left(&mut xs, old_xs.len()); assert_eq!(xs, old_xs); }); } malachite-base-0.4.16/tests/slices/slice_set_zero.rs000064400000000000000000000027141046102023000205620ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::slices::{slice_set_zero, slice_test_zero}; use malachite_base::test_util::generators::common::GenConfig; use malachite_base::test_util::generators::unsigned_vec_gen; #[test] fn test_slice_set_zero() { let test = |xs: &[u32], out: &[u32]| { let mut mut_xs = xs.to_vec(); slice_set_zero(&mut mut_xs); assert_eq!(mut_xs, out); }; test(&[], &[]); test(&[0], &[0]); test(&[0, 0, 0], &[0, 0, 0]); test(&[123], &[0]); test(&[123, 0], &[0, 0]); test(&[0, 123, 0, 0, 0], &[0, 0, 0, 0, 0]); } #[test] fn slice_set_zero_properties() { let mut config = GenConfig::new(); config.insert("mean_length_n", 32); config.insert("mean_length_d", 1); config.insert("mean_stripe_n", 16 << u8::LOG_WIDTH); config.insert("mean_stripe_d", 1); unsigned_vec_gen::().test_properties_with_config(&config, |mut xs| { let old_xs = xs.clone(); slice_set_zero(&mut xs); assert_eq!(old_xs.len(), xs.len()); assert!(slice_test_zero(&xs)); }); } malachite-base-0.4.16/tests/slices/slice_test_zero.rs000064400000000000000000000026071046102023000207470ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::slices::{slice_set_zero, slice_test_zero}; use malachite_base::test_util::generators::common::GenConfig; use malachite_base::test_util::generators::unsigned_vec_gen; #[test] fn test_slice_test_zero() { let test = |xs: &[u32], out| { assert_eq!(slice_test_zero(xs), out); }; test(&[], true); test(&[0], true); test(&[0, 0, 0], true); test(&[123], false); test(&[123, 0], false); test(&[0, 123, 0, 0, 0], false); } #[test] fn slice_test_zero_properties() { let mut config = GenConfig::new(); config.insert("mean_length_n", 32); config.insert("mean_length_d", 1); config.insert("mean_stripe_n", 16 << u8::LOG_WIDTH); config.insert("mean_stripe_d", 1); unsigned_vec_gen::().test_properties_with_config(&config, |xs| { let xs_are_zero = slice_test_zero(&xs); let mut new_xs = xs.clone(); slice_set_zero(&mut new_xs); assert_eq!(xs == new_xs, xs_are_zero); }); } malachite-base-0.4.16/tests/slices/slice_trailing_zeros.rs000064400000000000000000000031221046102023000217550ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::slices::{slice_leading_zeros, slice_test_zero, slice_trailing_zeros}; use malachite_base::test_util::generators::common::GenConfig; use malachite_base::test_util::generators::unsigned_vec_gen; #[test] fn test_slice_trailing_zeros() { let test = |xs: &[u32], out| { assert_eq!(slice_trailing_zeros(xs), out); }; test(&[], 0); test(&[0], 1); test(&[0, 0, 0], 3); test(&[123], 0); test(&[123, 0], 1); test(&[0, 123, 0, 0, 0], 3); test(&[1, 2, 3], 0); test(&[1, 2, 3, 0, 0, 0], 3); } #[test] fn slice_trailing_zeros_properties() { let mut config = GenConfig::new(); config.insert("mean_length_n", 32); config.insert("mean_length_d", 1); config.insert("mean_stripe_n", 16 << u8::LOG_WIDTH); config.insert("mean_stripe_d", 1); unsigned_vec_gen::().test_properties_with_config(&config, |xs| { let trailing_zeros = slice_trailing_zeros(&xs); assert!(trailing_zeros <= xs.len()); assert_eq!(trailing_zeros == xs.len(), slice_test_zero(&xs)); let mut new_xs = xs; new_xs.reverse(); assert_eq!(slice_leading_zeros(&new_xs), trailing_zeros); }); } malachite-base-0.4.16/tests/slices/split_into_chunks.rs000064400000000000000000000145031046102023000213070ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::slices::slice_set_zero; use malachite_base::test_util::generators::common::GenConfig; use malachite_base::test_util::generators::unsigned_vec_unsigned_unsigned_triple_gen_var_2; #[test] fn test_split_into_chunks() { let xs = &[0, 1, 2, 3, 4, 5, 6, 7]; split_into_chunks!(xs, 3, [xs_1, xs_2], xs_3); assert_eq!(xs_1, &[0, 1, 2]); assert_eq!(xs_2, &[3, 4, 5]); assert_eq!(xs_3, &[6, 7]); split_into_chunks!(xs, 3, [xs_1], xs_2); assert_eq!(xs_1, &[0, 1, 2]); assert_eq!(xs_2, &[3, 4, 5, 6, 7]); split_into_chunks!(xs, 1, [xs_1, xs_2], xs_3); assert_eq!(xs_1, &[0]); assert_eq!(xs_2, &[1]); assert_eq!(xs_3, &[2, 3, 4, 5, 6, 7]); split_into_chunks!(xs, 0, [xs_1, xs_2], xs_3); assert_eq!(xs_1, &[]); assert_eq!(xs_2, &[]); assert_eq!(xs_3, &[0, 1, 2, 3, 4, 5, 6, 7]); split_into_chunks!(xs, 5, [], xs_1); assert_eq!(xs_1, &[0, 1, 2, 3, 4, 5, 6, 7]); } #[test] #[should_panic] fn split_into_chunks_fail() { let xs = &[0, 1, 2, 3, 4, 5, 6, 7]; split_into_chunks!(xs, 5, [_xs_1, _xs_2], _xs_3); } #[test] fn test_split_into_chunks_mut() { let xs = &mut [0, 1, 2, 3, 4, 5, 6, 7]; split_into_chunks_mut!(xs, 3, [xs_1, xs_2], xs_3); assert_eq!(xs_1, &[0, 1, 2]); assert_eq!(xs_2, &[3, 4, 5]); assert_eq!(xs_3, &[6, 7]); split_into_chunks_mut!(xs, 3, [xs_1], xs_2); assert_eq!(xs_1, &[0, 1, 2]); assert_eq!(xs_2, &[3, 4, 5, 6, 7]); split_into_chunks_mut!(xs, 1, [xs_1, xs_2], xs_3); assert_eq!(xs_1, &[0]); assert_eq!(xs_2, &[1]); assert_eq!(xs_3, &[2, 3, 4, 5, 6, 7]); split_into_chunks_mut!(xs, 0, [xs_1, xs_2], xs_3); assert_eq!(xs_1, &[]); assert_eq!(xs_2, &[]); assert_eq!(xs_3, &[0, 1, 2, 3, 4, 5, 6, 7]); split_into_chunks_mut!(xs, 5, [], xs_1); assert_eq!(xs_1, &[0, 1, 2, 3, 4, 5, 6, 7]); split_into_chunks_mut!(xs, 3, [_xs_1, xs_2], _xs_3); slice_set_zero(xs_2); assert_eq!(xs, &[0, 1, 2, 0, 0, 0, 6, 7]); } #[test] #[should_panic] fn split_into_chunks_mut_fail() { let xs = &mut [0, 1, 2, 3, 4, 5, 6, 7]; split_into_chunks_mut!(xs, 5, [_xs_1, _xs_2], _xs_3); } macro_rules! split_into_chunks_helper { ($xs: expr, $len: expr, $n: expr, [$($xs_i: ident),*], $xs_last: ident) => {{ split_into_chunks!($xs, $len, [$($xs_i),*], $xs_last); $( assert_eq!($xs_i.len(), $len); )* assert_eq!($xs_last.len(), $xs.len() - ($n - 1) * $len); let mut xs_alt = Vec::with_capacity($xs.len()); $( xs_alt.extend($xs_i.iter().cloned()); )* xs_alt.extend($xs_last.iter().cloned()); assert_eq!(xs_alt, $xs); }} } #[test] fn split_into_chunks_properties() { let mut config = GenConfig::new(); config.insert("small_unsigned_mean_n", 8); config.insert("small_unsigned_mean_d", 1); config.insert("mean_stripe_n", u8::WIDTH << 1); config.insert("mean_stripe_d", 1); unsigned_vec_unsigned_unsigned_triple_gen_var_2::().test_properties_with_config( &config, |(xs, len, n)| match n { 0 => split_into_chunks_helper!(xs, len, 1, [], xs_1), 1 => split_into_chunks_helper!(xs, len, 2, [xs_1], xs_2), 2 => split_into_chunks_helper!(xs, len, 3, [xs_1, xs_2], xs_3), 3 => { split_into_chunks_helper!(xs, len, 4, [xs_1, xs_2, xs_3], xs_4); } 4 => { split_into_chunks_helper!(xs, len, 5, [xs_1, xs_2, xs_3, xs_4], xs_5); } 5 => split_into_chunks_helper!(xs, len, 6, [xs_1, xs_2, xs_3, xs_4, xs_5], xs_6), 6 => split_into_chunks_helper!(xs, len, 7, [xs_1, xs_2, xs_3, xs_4, xs_5, xs_6], xs_7), 7 => split_into_chunks_helper!( xs, len, 8, [xs_1, xs_2, xs_3, xs_4, xs_5, xs_6, xs_7], xs_8 ), _ => {} }, ); } macro_rules! split_into_chunks_mut_helper { ($xs: expr, $len: expr, $n: expr, [$($xs_i: ident),*], $xs_last: ident) => {{ let xs_len = $xs.len(); split_into_chunks_mut!($xs, $len, [$($xs_i),*], $xs_last); $( assert_eq!($xs_i.len(), $len); )* assert_eq!($xs_last.len(), xs_len - ($n - 1) * $len); let mut xs_alt = Vec::with_capacity(xs_len); $( xs_alt.extend($xs_i.iter().cloned()); )* xs_alt.extend($xs_last.iter().cloned()); assert_eq!(xs_alt, $xs); }} } #[test] fn split_into_chunks_mut_properties() { let mut config = GenConfig::new(); config.insert("small_unsigned_mean_n", 8); config.insert("small_unsigned_mean_d", 1); config.insert("mean_stripe_n", u8::WIDTH << 1); config.insert("mean_stripe_d", 1); unsigned_vec_unsigned_unsigned_triple_gen_var_2::().test_properties_with_config( &config, |(mut xs, len, n)| match n { 0 => split_into_chunks_mut_helper!(xs, len, 1, [], xs_1), 1 => split_into_chunks_mut_helper!(xs, len, 2, [xs_1], xs_2), 2 => split_into_chunks_mut_helper!(xs, len, 3, [xs_1, xs_2], xs_3), 3 => { split_into_chunks_mut_helper!(xs, len, 4, [xs_1, xs_2, xs_3], xs_4); } 4 => { split_into_chunks_mut_helper!(xs, len, 5, [xs_1, xs_2, xs_3, xs_4], xs_5); } 5 => split_into_chunks_mut_helper!(xs, len, 6, [xs_1, xs_2, xs_3, xs_4, xs_5], xs_6), 6 => { split_into_chunks_mut_helper!( xs, len, 7, [xs_1, xs_2, xs_3, xs_4, xs_5, xs_6], xs_7 ); } 7 => split_into_chunks_mut_helper!( xs, len, 8, [xs_1, xs_2, xs_3, xs_4, xs_5, xs_6, xs_7], xs_8 ), _ => {} }, ); } malachite-base-0.4.16/tests/strings/exhaustive/exhaustive_fixed_length_strings.rs000064400000000000000000000040621046102023000266210ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::strings::exhaustive::exhaustive_fixed_length_strings; fn exhaustive_fixed_length_strings_helper(len: u64, out: &[&str]) { let css = exhaustive_fixed_length_strings(len).take(20).collect_vec(); assert_eq!(css.iter().map(String::as_str).collect_vec().as_slice(), out); } #[test] fn test_exhaustive_fixed_length_strings() { exhaustive_fixed_length_strings_helper(0, &[""]); exhaustive_fixed_length_strings_helper( 1, &[ "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", ], ); exhaustive_fixed_length_strings_helper( 2, &[ "aa", "ab", "ba", "bb", "ac", "ad", "bc", "bd", "ca", "cb", "da", "db", "cc", "cd", "dc", "dd", "ae", "af", "be", "bf", ], ); exhaustive_fixed_length_strings_helper( 3, &[ "aaa", "aab", "aba", "abb", "baa", "bab", "bba", "bbb", "aac", "aad", "abc", "abd", "bac", "bad", "bbc", "bbd", "aca", "acb", "ada", "adb", ], ); exhaustive_fixed_length_strings_helper( 10, &[ "aaaaaaaaaa", "aaaaaaaaab", "aaaaaaaaba", "aaaaaaaabb", "aaaaaaabaa", "aaaaaaabab", "aaaaaaabba", "aaaaaaabbb", "aaaaaabaaa", "aaaaaabaab", "aaaaaababa", "aaaaaababb", "aaaaaabbaa", "aaaaaabbab", "aaaaaabbba", "aaaaaabbbb", "aaaaabaaaa", "aaaaabaaab", "aaaaabaaba", "aaaaabaabb", ], ); } malachite-base-0.4.16/tests/strings/exhaustive/exhaustive_fixed_length_strings_using_chars.rs000064400000000000000000000076411046102023000312140ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::strings::exhaustive::exhaustive_fixed_length_strings_using_chars; use std::iter::{empty, once}; fn exhaustive_fixed_length_strings_using_chars_helper>( len: u64, cs: I, out: &[&str], ) { let css = exhaustive_fixed_length_strings_using_chars(len, cs) .take(20) .collect_vec(); assert_eq!(css.iter().map(String::as_str).collect_vec().as_slice(), out); } #[test] fn test_exhaustive_fixed_length_strings_using_chars() { exhaustive_fixed_length_strings_using_chars_helper(0, empty(), &[""]); exhaustive_fixed_length_strings_using_chars_helper(1, empty(), &[]); exhaustive_fixed_length_strings_using_chars_helper(0, once('q'), &[""]); exhaustive_fixed_length_strings_using_chars_helper(1, once('q'), &["q"]); exhaustive_fixed_length_strings_using_chars_helper(2, once('q'), &["qq"]); exhaustive_fixed_length_strings_using_chars_helper(3, once('q'), &["qqq"]); exhaustive_fixed_length_strings_using_chars_helper(10, once('q'), &["qqqqqqqqqq"]); exhaustive_fixed_length_strings_using_chars_helper(0, ['x', 'y'].iter().copied(), &[""]); exhaustive_fixed_length_strings_using_chars_helper(1, ['x', 'y'].iter().copied(), &["x", "y"]); exhaustive_fixed_length_strings_using_chars_helper( 2, ['x', 'y'].iter().copied(), &["xx", "xy", "yx", "yy"], ); exhaustive_fixed_length_strings_using_chars_helper( 3, ['x', 'y'].iter().copied(), &["xxx", "xxy", "xyx", "xyy", "yxx", "yxy", "yyx", "yyy"], ); exhaustive_fixed_length_strings_using_chars_helper( 10, ['x', 'y'].iter().copied(), &[ "xxxxxxxxxx", "xxxxxxxxxy", "xxxxxxxxyx", "xxxxxxxxyy", "xxxxxxxyxx", "xxxxxxxyxy", "xxxxxxxyyx", "xxxxxxxyyy", "xxxxxxyxxx", "xxxxxxyxxy", "xxxxxxyxyx", "xxxxxxyxyy", "xxxxxxyyxx", "xxxxxxyyxy", "xxxxxxyyyx", "xxxxxxyyyy", "xxxxxyxxxx", "xxxxxyxxxy", "xxxxxyxxyx", "xxxxxyxxyy", ], ); exhaustive_fixed_length_strings_using_chars_helper(0, ['c', 'a', 't'].iter().copied(), &[""]); exhaustive_fixed_length_strings_using_chars_helper( 1, ['c', 'a', 't'].iter().copied(), &["c", "a", "t"], ); exhaustive_fixed_length_strings_using_chars_helper( 2, ['c', 'a', 't'].iter().copied(), &["cc", "ca", "ac", "aa", "ct", "at", "tc", "ta", "tt"], ); exhaustive_fixed_length_strings_using_chars_helper( 3, ['c', 'a', 't'].iter().copied(), &[ "ccc", "cca", "cac", "caa", "acc", "aca", "aac", "aaa", "cct", "cat", "act", "aat", "ctc", "cta", "atc", "ata", "ctt", "att", "tcc", "tca", ], ); exhaustive_fixed_length_strings_using_chars_helper( 10, ['c', 'a', 't'].iter().copied(), &[ "cccccccccc", "ccccccccca", "ccccccccac", "ccccccccaa", "cccccccacc", "cccccccaca", "cccccccaac", "cccccccaaa", "ccccccaccc", "ccccccacca", "ccccccacac", "ccccccacaa", "ccccccaacc", "ccccccaaca", "ccccccaaac", "ccccccaaaa", "cccccacccc", "cccccaccca", "cccccaccac", "cccccaccaa", ], ); } malachite-base-0.4.16/tests/strings/exhaustive/exhaustive_strings.rs000064400000000000000000000014531046102023000241020ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::strings::exhaustive::exhaustive_strings; #[test] fn test_exhaustive_strings() { let ss = exhaustive_strings().take(20).collect_vec(); assert_eq!( ss.iter().map(String::as_str).collect_vec().as_slice(), &[ "", "a", "b", "aaa", "c", "aa", "d", "aaaa", "e", "ab", "f", "aab", "g", "ba", "h", "aaaaa", "i", "bb", "j", "aba" ], ); } malachite-base-0.4.16/tests/strings/exhaustive/exhaustive_strings_using_chars.rs000064400000000000000000000043551046102023000264730ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::strings::exhaustive::exhaustive_strings_using_chars; use std::iter::{empty, once}; fn exhaustive_strings_using_chars_helper>(cs: I, out: &[&str]) { let ss = exhaustive_strings_using_chars(cs).take(20).collect_vec(); assert_eq!(ss.iter().map(String::as_str).collect_vec().as_slice(), out); } #[test] fn test_exhaustive_strings_using_chars() { exhaustive_strings_using_chars_helper(empty(), &[""]); exhaustive_strings_using_chars_helper( once('a'), &[ "", "a", "aa", "aaaa", "aaa", "aaaaa", "aaaaaa", "aaaaaaaaa", "aaaaaaa", "aaaaaaaa", "aaaaaaaaaa", "aaaaaaaaaaaa", "aaaaaaaaaaa", "aaaaaaaaaaaaa", "aaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaa", ], ); exhaustive_strings_using_chars_helper( "ab".chars(), &[ "", "a", "b", "aaa", "aa", "aab", "ab", "aaaaa", "ba", "aba", "bb", "aaaa", "abb", "aaab", "baa", "aaaaaaa", "bab", "aaba", "bba", "aaaab", ], ); exhaustive_strings_using_chars_helper( "xyz".chars(), &[ "", "x", "y", "xxx", "z", "xx", "xy", "xxxxx", "yx", "xxy", "yy", "xxxx", "xz", "xyx", "yz", "xxxxxx", "zx", "xyy", "zy", "xxxy", ], ); exhaustive_strings_using_chars_helper( exhaustive_ascii_chars(), &[ "", "a", "b", "aaa", "c", "aa", "d", "aaaa", "e", "ab", "f", "aab", "g", "ba", "h", "aaaaa", "i", "bb", "j", "aba", ], ); } malachite-base-0.4.16/tests/strings/exhaustive/lex_fixed_length_strings.rs000064400000000000000000000037631046102023000252330ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::strings::exhaustive::lex_fixed_length_strings; fn lex_fixed_length_strings_helper(len: u64, out: &[&str]) { let css = lex_fixed_length_strings(len).take(20).collect_vec(); assert_eq!(css.iter().map(String::as_str).collect_vec().as_slice(), out); } #[test] fn test_lex_fixed_length_strings() { lex_fixed_length_strings_helper(0, &[""]); lex_fixed_length_strings_helper( 1, &[ "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", ], ); lex_fixed_length_strings_helper( 2, &[ "aa", "ab", "ac", "ad", "ae", "af", "ag", "ah", "ai", "aj", "ak", "al", "am", "an", "ao", "ap", "aq", "ar", "as", "at", ], ); lex_fixed_length_strings_helper( 3, &[ "aaa", "aab", "aac", "aad", "aae", "aaf", "aag", "aah", "aai", "aaj", "aak", "aal", "aam", "aan", "aao", "aap", "aaq", "aar", "aas", "aat", ], ); lex_fixed_length_strings_helper( 10, &[ "aaaaaaaaaa", "aaaaaaaaab", "aaaaaaaaac", "aaaaaaaaad", "aaaaaaaaae", "aaaaaaaaaf", "aaaaaaaaag", "aaaaaaaaah", "aaaaaaaaai", "aaaaaaaaaj", "aaaaaaaaak", "aaaaaaaaal", "aaaaaaaaam", "aaaaaaaaan", "aaaaaaaaao", "aaaaaaaaap", "aaaaaaaaaq", "aaaaaaaaar", "aaaaaaaaas", "aaaaaaaaat", ], ); } malachite-base-0.4.16/tests/strings/exhaustive/lex_fixed_length_strings_using_chars.rs000064400000000000000000000074161046102023000276170ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::strings::exhaustive::lex_fixed_length_strings_using_chars; use std::iter::{empty, once}; fn lex_fixed_length_strings_using_chars_helper>( len: u64, cs: I, out: &[&str], ) { let css = lex_fixed_length_strings_using_chars(len, cs) .take(20) .collect_vec(); assert_eq!(css.iter().map(String::as_str).collect_vec().as_slice(), out); } #[test] fn test_lex_fixed_length_strings_using_chars() { lex_fixed_length_strings_using_chars_helper(0, empty(), &[""]); lex_fixed_length_strings_using_chars_helper(1, empty(), &[]); lex_fixed_length_strings_using_chars_helper(0, once('q'), &[""]); lex_fixed_length_strings_using_chars_helper(1, once('q'), &["q"]); lex_fixed_length_strings_using_chars_helper(2, once('q'), &["qq"]); lex_fixed_length_strings_using_chars_helper(3, once('q'), &["qqq"]); lex_fixed_length_strings_using_chars_helper(10, once('q'), &["qqqqqqqqqq"]); lex_fixed_length_strings_using_chars_helper(0, ['x', 'y'].iter().copied(), &[""]); lex_fixed_length_strings_using_chars_helper(1, ['x', 'y'].iter().copied(), &["x", "y"]); lex_fixed_length_strings_using_chars_helper( 2, ['x', 'y'].iter().copied(), &["xx", "xy", "yx", "yy"], ); lex_fixed_length_strings_using_chars_helper( 3, ['x', 'y'].iter().copied(), &["xxx", "xxy", "xyx", "xyy", "yxx", "yxy", "yyx", "yyy"], ); lex_fixed_length_strings_using_chars_helper( 10, ['x', 'y'].iter().copied(), &[ "xxxxxxxxxx", "xxxxxxxxxy", "xxxxxxxxyx", "xxxxxxxxyy", "xxxxxxxyxx", "xxxxxxxyxy", "xxxxxxxyyx", "xxxxxxxyyy", "xxxxxxyxxx", "xxxxxxyxxy", "xxxxxxyxyx", "xxxxxxyxyy", "xxxxxxyyxx", "xxxxxxyyxy", "xxxxxxyyyx", "xxxxxxyyyy", "xxxxxyxxxx", "xxxxxyxxxy", "xxxxxyxxyx", "xxxxxyxxyy", ], ); lex_fixed_length_strings_using_chars_helper(0, ['c', 'a', 't'].iter().copied(), &[""]); lex_fixed_length_strings_using_chars_helper( 1, ['c', 'a', 't'].iter().copied(), &["c", "a", "t"], ); lex_fixed_length_strings_using_chars_helper( 2, ['c', 'a', 't'].iter().copied(), &["cc", "ca", "ct", "ac", "aa", "at", "tc", "ta", "tt"], ); lex_fixed_length_strings_using_chars_helper( 3, ['c', 'a', 't'].iter().copied(), &[ "ccc", "cca", "cct", "cac", "caa", "cat", "ctc", "cta", "ctt", "acc", "aca", "act", "aac", "aaa", "aat", "atc", "ata", "att", "tcc", "tca", ], ); lex_fixed_length_strings_using_chars_helper( 10, ['c', 'a', 't'].iter().copied(), &[ "cccccccccc", "ccccccccca", "ccccccccct", "ccccccccac", "ccccccccaa", "ccccccccat", "cccccccctc", "ccccccccta", "cccccccctt", "cccccccacc", "cccccccaca", "cccccccact", "cccccccaac", "cccccccaaa", "cccccccaat", "cccccccatc", "cccccccata", "cccccccatt", "ccccccctcc", "ccccccctca", ], ); } malachite-base-0.4.16/tests/strings/exhaustive/shortlex_strings.rs000064400000000000000000000014241046102023000235630ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::strings::exhaustive::shortlex_strings; #[test] fn test_shortlex_strings() { let ss = shortlex_strings().take(20).collect_vec(); assert_eq!( ss.iter().map(String::as_str).collect_vec().as_slice(), &[ "", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", ] ); } malachite-base-0.4.16/tests/strings/exhaustive/shortlex_strings_using_chars.rs000064400000000000000000000042741046102023000261560ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::strings::exhaustive::shortlex_strings_using_chars; use std::iter::{empty, once}; fn shortlex_strings_using_chars_helper>(cs: I, out: &[&str]) { let ss = shortlex_strings_using_chars(cs).take(20).collect_vec(); assert_eq!(ss.iter().map(String::as_str).collect_vec().as_slice(), out); } #[test] fn test_shortlex_strings_using_chars() { shortlex_strings_using_chars_helper(empty(), &[""]); shortlex_strings_using_chars_helper( once('a'), &[ "", "a", "aa", "aaa", "aaaa", "aaaaa", "aaaaaa", "aaaaaaa", "aaaaaaaa", "aaaaaaaaa", "aaaaaaaaaa", "aaaaaaaaaaa", "aaaaaaaaaaaa", "aaaaaaaaaaaaa", "aaaaaaaaaaaaaa", "aaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaa", ], ); shortlex_strings_using_chars_helper( "ab".chars(), &[ "", "a", "b", "aa", "ab", "ba", "bb", "aaa", "aab", "aba", "abb", "baa", "bab", "bba", "bbb", "aaaa", "aaab", "aaba", "aabb", "abaa", ], ); shortlex_strings_using_chars_helper( "xyz".chars(), &[ "", "x", "y", "z", "xx", "xy", "xz", "yx", "yy", "yz", "zx", "zy", "zz", "xxx", "xxy", "xxz", "xyx", "xyy", "xyz", "xzx", ], ); shortlex_strings_using_chars_helper( exhaustive_ascii_chars(), &[ "", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", ], ); } malachite-base-0.4.16/tests/strings/random/random_fixed_length_strings.rs000064400000000000000000000204711046102023000250110ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::random::EXAMPLE_SEED; use malachite_base::strings::random::random_fixed_length_strings; use malachite_base::test_util::stats::common_values_map::common_values_map; use malachite_base::test_util::stats::median; fn random_fixed_length_strings_helper( len: u64, expected_values: &[&str], expected_common_values: &[(&str, usize)], expected_median: (&str, Option<&str>), ) { let ss = random_fixed_length_strings(EXAMPLE_SEED, len); let values = ss.clone().take(20).collect_vec(); let common_values = common_values_map(1000000, 10, ss.clone()); let (median_lo, median_hi) = median(ss.take(1000000)); assert_eq!( ( values.iter().map(String::as_str).collect_vec().as_slice(), common_values .iter() .map(|(s, f)| (s.as_str(), *f)) .collect_vec() .as_slice(), (median_lo.as_str(), median_hi.as_deref()) ), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_random_fixed_length_strings() { random_fixed_length_strings_helper(0, &[""; 20], &[("", 1000000)], ("", None)); random_fixed_length_strings_helper( 1, &[ "\u{5f771}", "\u{87234}", "\u{bcd36}", "\u{9e195}", "\u{5da07}", "\u{36553}", "\u{45028}", "\u{1cdfd}", "\u{d8530}", "\u{c7f2e}", "\u{ba4bc}", "\u{ff677}", "\u{a12e2}", "\u{d775c}", "\u{f827b}", "\u{bdf7a}", "簅", "\u{15aca}", "\u{4e5e2}", "\u{bb286}", ], &[ ("\u{1e21d}", 8), ("\u{bd934}", 8), ("\u{dc941}", 8), ("䄡", 7), ("霜", 7), ("\u{ee5a}", 7), ("𐊩", 7), ("\u{163a4}", 7), ("\u{1e7ff}", 7), ("𣡝", 7), ], ("\u{88629}", Some("\u{8862a}")), ); random_fixed_length_strings_helper( 2, &[ "\u{5f771}\u{87234}", "\u{bcd36}\u{9e195}", "\u{5da07}\u{36553}", "\u{45028}\u{1cdfd}", "\u{d8530}\u{c7f2e}", "\u{ba4bc}\u{ff677}", "\u{a12e2}\u{d775c}", "\u{f827b}\u{bdf7a}", "簅\u{15aca}", "\u{4e5e2}\u{bb286}", "\u{18eeb}\u{bac4f}", "\u{5b55a}\u{65709}", "\u{b2626}\u{31a93}", "\u{8757b}\u{b3524}", "\u{fcc17}\u{32c01}", "\u{aada8}\u{57e7c}", "\u{eb738}栨", "\u{51a21}\u{ef6af}", "\u{b9caa}\u{d5099}", "\u{e397f}\u{32518}", ], &[ ("\u{6}욵", 1), ("\u{19}此", 1), ("\u{1c}훶", 1), ("+쳭", 1), (">\u{f454}", 1), ("B韧", 1), ("¦×", 1), ("Ϊǔ", 1), ("ӚĐ", 1), ("ۥä", 1), ], ("\u{882fd}\u{b44d9}", Some("\u{882fe}\u{6d6a7}")), ); random_fixed_length_strings_helper( 3, &[ "\u{5f771}\u{87234}\u{bcd36}", "\u{9e195}\u{5da07}\u{36553}", "\u{45028}\u{1cdfd}\u{d8530}", "\u{c7f2e}\u{ba4bc}\u{ff677}", "\u{a12e2}\u{d775c}\u{f827b}", "\u{bdf7a}簅\u{15aca}", "\u{4e5e2}\u{bb286}\u{18eeb}", "\u{bac4f}\u{5b55a}\u{65709}", "\u{b2626}\u{31a93}\u{8757b}", "\u{b3524}\u{fcc17}\u{32c01}", "\u{aada8}\u{57e7c}\u{eb738}", "栨\u{51a21}\u{ef6af}", "\u{b9caa}\u{d5099}\u{e397f}", "\u{32518}\u{6952d}\u{93ad5}", "\u{65c6e}\u{dc7bd}\u{aec4c}", "\u{dd524}\u{c0bc1}\u{795d0}", "\u{dbb9d}\u{a50fb}紐", "\u{4effe}\u{794af}\u{1b5a0}", "\u{56be3}\u{78fc9}\u{5870a}", "\u{106f48}\u{dfffa}\u{3cc01}", ], &[ ("\u{19}此\u{2f2bd}", 1), ("(\u{6c2b8}\u{f70}", 1), ("+쳭\u{93ded}", 1), (",\u{e5cc2}\u{ea33}", 1), ("6\u{a341e}엕", 1), (">\u{f454}\u{5e168}", 1), ("G\u{47b77}䊹", 1), ("K\u{58609}\u{e08e}", 1), ("O┑\u{37d86}", 1), ("R\u{f41e}\u{41c45}", 1), ], ( "\u{884b7}\u{6ad70}\u{3d86d}", Some("\u{884b8}\u{10f66a}\u{da539}"), ), ); random_fixed_length_strings_helper( 10, &[ "\u{5f771}\u{87234}\u{bcd36}\u{9e195}\u{5da07}\u{36553}\u{45028}\u{1cdfd}\u{d8530}\ \u{c7f2e}", "\u{ba4bc}\u{ff677}\u{a12e2}\u{d775c}\u{f827b}\u{bdf7a}簅\u{15aca}\u{4e5e2}\u{bb286}", "\u{18eeb}\u{bac4f}\u{5b55a}\u{65709}\u{b2626}\u{31a93}\u{8757b}\u{b3524}\u{fcc17}\ \u{32c01}", "\u{aada8}\u{57e7c}\u{eb738}栨\u{51a21}\u{ef6af}\u{b9caa}\u{d5099}\u{e397f}\u{32518}", "\u{6952d}\u{93ad5}\u{65c6e}\u{dc7bd}\u{aec4c}\u{dd524}\u{c0bc1}\u{795d0}\u{dbb9d}\ \u{a50fb}", "紐\u{4effe}\u{794af}\u{1b5a0}\u{56be3}\u{78fc9}\u{5870a}\u{106f48}\u{dfffa}\u{3cc01}", "\u{91290}\u{4628e}\u{bee71}\u{70e90}\u{b48bb}\u{3a445}\u{10a645}𬆠\u{e59de}\u{61b5a}", "\u{f4783}\u{c5ab2}幔\u{fdb07}\u{abccb}\u{ba750}\u{88d5a}\u{a706e}\u{969a2}\u{1089e3}", "\u{102189}\u{5f066}\u{10ea66}\u{435bb}\u{bcbd6}\u{4bc59}𱆞\u{f50a0}\u{47bc1}\u{5fd98}", "\u{91a7a}\u{100a8d}\u{e0017}\u{9db06}\u{1ab04}\u{780f6}ㅚ\u{5fc0a}\u{fb714}\u{c62cd}", "\u{b22dc}\u{10364e}\u{ee477}\u{f0983}\u{b5c36}\u{41f7b}\u{bdf28}\u{b27f7}\u{94dc8}\ \u{73381}", "\u{34609}\u{52911}\u{e56bf}\u{100af4}\u{396ff}\u{1051a8}𬅑\u{815dc}\u{fd1e7}\u{e6e9c}", "攠\u{eceaa}\u{10029d}\u{5e236}\u{d963b}\u{bbb1a}\u{108b67}\u{e5bc3}\u{97108}𢔱", "\u{9f166}\u{dedb4}\u{52752}\u{45bf5}\u{86d73}\u{ff2fd}쫵\u{78f74}\u{93bc0}\u{c308f}", "\u{e8b6}\u{89619}\u{1cdf9}\u{b9c86}\u{9f375}\u{c2487}\u{e1c3e}\u{f6e29}\u{79cc5}𬑎", "\u{9a803}\u{bf22e}\u{7e88e}\u{c50e8}\u{58c32}\u{79248}𰥦\u{b238b}\u{104b92}\u{8cc78}", "\u{eecc5}𢇡\u{e1fb6}\u{625ab}\u{a1988}䮨\u{bbaa5}\u{143be}\u{a12d4}\u{1028e1}", "\u{1c105}\u{9493f}\u{efa70}\u{13487}紋\u{b1948}\u{89052}\u{8c3cb}\u{b82d2}\u{729c3}", "\u{10c5ba}\u{dec07}𰢫\u{d277f}\u{3e5dc}\u{52431}\u{4867e}\u{75774}𪲨\u{b865a}", "\u{105191}\u{93891}\u{c4975}\u{c2f58}\u{d387c}\u{157dd}\u{77a83}\u{d6eec}\u{b2581}\ \u{9bb09}", ], &[ ("崕浆\u{3da8f}뽑\u{d3fa5}\u{3139e}X\u{48918}\u{108376}♟", 1), ("馑霸\u{fdd49}\u{d2b16}튞ଓ儳輋韨\u{be78f}", 1), ("𨟿\u{a025e}\u{4d531}席ےᥒ\"𤭉\u{b30a9}\u{988d4}", 1), ( "\u{c6771}\u{c979e}᳇\u{f4e2}能Ŷ\u{474f6}\u{f872}窚\u{6ad4b}", 1, ), ("+쳭\u{93ded}\u{84fa9}㱆\u{b3aac}곖𦸌\u{593c4}\u{57c2f}", 1), ( "w\u{6bb08}\u{e8b68}\u{f961c}\u{c362e}\u{2e6b}\u{95326}\u{7ff5b}受\u{f715}", 1, ), ( "ȵ\u{48470}\u{104dcc}扞×ⴞ\u{1ebce}\u{1065e4}\u{34780}\u{46560}", 1, ), ("ɿ\u{13f25}\u{bb3ca}垾\u{7f077}酓\u{3f2d3}\u{86f0b}壪床", 1), ( "ӯ\u{83676}\u{d50cb}ꧏ\u{f9dcd}\u{d1466}\u{1de8e}\u{13bb5}搜\u{592}", 1, ), ( "\u{5cb}\u{cc480}ⶺǠ\u{95c2c}\u{6d588}㬪𪮊\u{147b9}\u{d7fa9}", 1, ), ], ( "\u{880b8}\u{7ba91}\u{615f9}𝟂\u{1a34d}\u{4bb86}\u{363e3}\u{f113b}\u{fada1}\u{88aa9}", Some("\u{880b8}\u{9f3aa}\u{d7dab}𪿾\u{100550}\u{fd341}𬐿鄓𬫦\u{e718}"), ), ); } malachite-base-0.4.16/tests/strings/random/random_fixed_length_strings_using_chars.rs000064400000000000000000000211021046102023000273660ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::chars::random::{random_ascii_chars, random_char_inclusive_range}; use malachite_base::random::EXAMPLE_SEED; use malachite_base::strings::random::random_fixed_length_strings_using_chars; use malachite_base::test_util::stats::common_values_map::common_values_map; use malachite_base::test_util::stats::median; use std::iter::repeat; fn random_fixed_length_strings_using_chars_helper>( len: u64, cs: I, expected_values: &[&str], expected_common_values: &[(&str, usize)], expected_median: (&str, Option<&str>), ) { let ss = random_fixed_length_strings_using_chars(len, cs); let values = ss.clone().take(20).collect_vec(); let common_values = common_values_map(1000000, 10, ss.clone()); let (median_lo, median_hi) = median(ss.take(1000000)); assert_eq!( ( values.iter().map(String::as_str).collect_vec().as_slice(), common_values .iter() .map(|(s, f)| (s.as_str(), *f)) .collect_vec() .as_slice(), (median_lo.as_str(), median_hi.as_deref()) ), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_random_fixed_length_strings_using_chars() { random_fixed_length_strings_using_chars_helper( 0, repeat('a'), &[""; 20], &[("", 1000000)], ("", None), ); random_fixed_length_strings_using_chars_helper( 1, repeat('a'), &["a"; 20], &[("a", 1000000)], ("a", None), ); random_fixed_length_strings_using_chars_helper( 2, repeat('a'), &["aa"; 20], &[("aa", 1000000)], ("aa", None), ); random_fixed_length_strings_using_chars_helper( 3, repeat('a'), &["aaa"; 20], &[("aaa", 1000000)], ("aaa", None), ); random_fixed_length_strings_using_chars_helper( 10, repeat('a'), &["aaaaaaaaaa"; 20], &[("aaaaaaaaaa", 1000000)], ("aaaaaaaaaa", None), ); random_fixed_length_strings_using_chars_helper( 1, random_char_inclusive_range(EXAMPLE_SEED, 'a', 'c'), &[ "b", "a", "b", "c", "b", "b", "a", "b", "a", "c", "b", "a", "b", "c", "c", "a", "b", "a", "c", "c", ], &[("b", 333784), ("c", 333516), ("a", 332700)], ("b", None), ); random_fixed_length_strings_using_chars_helper( 2, random_char_inclusive_range(EXAMPLE_SEED, 'a', 'c'), &[ "ba", "bc", "bb", "ab", "ac", "ba", "bc", "ca", "ba", "cc", "cb", "ac", "cb", "bb", "aa", "ca", "cc", "ba", "bb", "ac", ], &[ ("cb", 111755), ("aa", 111436), ("cc", 111255), ("bb", 111161), ("ab", 111154), ("ba", 111089), ("ca", 110836), ("bc", 110731), ("ac", 110583), ], ("bb", None), ); random_fixed_length_strings_using_chars_helper( 3, random_char_inclusive_range(EXAMPLE_SEED, 'a', 'c'), &[ "bab", "cbb", "aba", "cba", "bcc", "aba", "ccc", "bac", "cbb", "baa", "cac", "cba", "bba", "cca", "cab", "cbb", "ccb", "bba", "cab", "bbc", ], &[ ("bab", 37526), ("ccb", 37346), ("acb", 37337), ("bca", 37271), ("cbb", 37251), ("bba", 37211), ("aab", 37170), ("caa", 37142), ("bbb", 37096), ("abc", 37095), ], ("bbb", None), ); random_fixed_length_strings_using_chars_helper( 10, random_char_inclusive_range(EXAMPLE_SEED, 'a', 'c'), &[ "babcbbabac", "babccabacc", "cbaccbbbaa", "caccbabbac", "cacabcbbcc", "bbbacabbbc", "abbcbbbcbc", "bbcabbbcab", "cbaacabbbc", "bccccccbac", "abaacbcaba", "bbaabcacab", "bbabaaacbc", "cccbccabba", "aacabaabcc", "acabccccab", "bcacccaacc", "accaccbbbc", "aabcbaabcc", "cbccbbbabc", ], &[ ("caacabbbba", 38), ("cbaaacbaab", 37), ("bcacbbabca", 36), ("bcbacaabba", 36), ("aabaaccbaa", 35), ("abcbccaaab", 35), ("bcbcbbbbba", 35), ("aabccaaaca", 34), ("abacaaabba", 34), ("baccbabbcb", 34), ], ("bbbbbbbacc", None), ); random_fixed_length_strings_using_chars_helper( 1, random_ascii_chars(EXAMPLE_SEED), &[ "q", "^", "\u{17}", "b", "F", "\\", "4", "T", "!", "/", "\u{1}", "q", "6", "\n", "/", "\u{11}", "Y", "\\", "w", "B", ], &[ ("\u{2}", 8077), ("y", 8039), ("0", 8015), ("q", 7966), ("\u{8}", 7937), ("M", 7933), ("2", 7928), ("[", 7927), ("R", 7925), ("f", 7924), ], ("?", None), ); random_fixed_length_strings_using_chars_helper( 2, random_ascii_chars(EXAMPLE_SEED), &[ "q^", "\u{17}b", "F\\", "4T", "!/", "\u{1}q", "6\n", "/\u{11}", "Y\\", "wB", "\\r", "\\^", "\u{15}3", "\'.", "\'r", "\u{7}$", "\u{17}S", ":\r", "r@", "I(", ], &[ ("c5", 91), ("\u{1c} ", 90), ("GN", 90), ("a2", 90), ("\u{13}%", 89), ("o\u{14}", 89), ("(u", 88), ("X2", 88), ("\u{10}e", 87), ("\u{1e}f", 87), ], ("@\u{2}", None), ); random_fixed_length_strings_using_chars_helper( 3, random_ascii_chars(EXAMPLE_SEED), &[ "q^\u{17}", "bF\\", "4T!", "/\u{1}q", "6\n/", "\u{11}Y\\", "wB\\", "r\\^", "\u{15}3\'", ".\'r", "\u{7}$\u{17}", "S:\r", "r@I", "(\u{10}\u{11}", "}\u{b}\u{7}", "0z5", ".n1", "\u{10}At", "<9.", "w\\?", ], &[ ("$7\u{5}", 7), ("*\u{1c}\u{1e}", 7), ("\u{e}sb", 6), ("\u{10}+g", 6), ("\u{13}`\u{14}", 6), ("\u{13}oF", 6), ("\u{15}[[", 6), ("\u{1c}Ve", 6), ("\u{1e}<7", 6), ("\"*K", 6), ], ("?}^", None), ); random_fixed_length_strings_using_chars_helper( 10, random_ascii_chars(EXAMPLE_SEED), &[ "q^\u{17}bF\\4T!/", "\u{1}q6\n/\u{11}Y\\wB", "\\r\\^\u{15}3\'.\'r", "\u{7}$\u{17}S:\rr@I(", "\u{10}\u{11}}\u{b}\u{7}0z5.n", "1\u{10}At<9.w\\?", "b\u{15}(\\hJ\u{10}cO\\", "^5Edc\u{1f}kq{t", "=z./\u{5}x\u{1}dZr", "J%\u{5}`=VU_\u{7f}b", ";\u{13}\u{6}U.k\r\u{6}PB", "k]$p\u{1a}+FOH.", "\r,a\u{1}=DZZ\u{16}\u{18}", "cY\t\u{1e}\u{19}&<,\u{13}%", "\u{c}{Z!$Z,\u{17}\u{8}?", "\u{3}\u{4}]\u{1}H\u{c}(K*|", "l\u{15}8^:\u{e}\u{7f}D(P", "\u{1}XEk!$\u{14}/];", "E9d\u{e})|v\u{e}W*", ").\u{19}\u{11}5\u{7f}b8\u{18}:", ], &[ ("\u{0}\u{0}\u{1})\u{19}\\\u{10};bj", 1), ("\u{0}\u{0}\u{3}\u{7};sV\u{e}2}", 1), ("\u{0}\u{0}\u{5}\tmrh\u{1f}{E", 1), ("\u{0}\u{0}\n\n\u{2}\"\u{13}ftF", 1), ("\u{0}\u{0}\r+I^a\u{6}>R", 1), ("\u{0}\u{0}\ry#hUV8+", 1), ("\u{0}\u{0}\u{e}\"^\u{6},+\u{10}[", 1), ("\u{0}\u{0}\u{11}J\u{0}\u{11}5kiy", 1), ("\u{0}\u{0}\u{12}\u{4}txo}{7", 1), ("\u{0}\u{0}\u{13}Gb;}ex|", 1), ], ( "@\u{b}\u{c}t\u{11}\u{b}\u{e}NV&", Some("@\u{b}\u{e}FN+o}X\u{4}"), ), ); } malachite-base-0.4.16/tests/strings/random/random_strings.rs000064400000000000000000000161271046102023000222740ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::random::EXAMPLE_SEED; use malachite_base::strings::random::random_strings; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; fn random_strings_helper( mean_length_numerator: u64, mean_length_denominator: u64, expected_values: &[&str], expected_common_values: &[(&str, usize)], expected_median: (&str, Option<&str>), ) { let ss = random_strings(EXAMPLE_SEED, mean_length_numerator, mean_length_denominator); let values = ss.clone().take(20).collect_vec(); let common_values = common_values_map_debug(1000000, 10, ss.clone()); let (median_lo, median_hi) = median(ss.take(1000000)); assert_eq!( ( values.iter().map(String::as_str).collect_vec().as_slice(), common_values .iter() .map(|(s, f)| (s.as_str(), *f)) .collect_vec() .as_slice(), (median_lo.as_str(), median_hi.as_deref()) ), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_random_strings() { random_strings_helper( 4, 1, &[ "", "\u{81355}\u{a331d}\u{b707b}\u{1354b}\u{b16ac}𣙘\u{67377}\u{4aaa4}\u{a6d6e}\u{45616}\ \u{7725f}\u{41e2d}\u{d6b59}\u{de165}", "\u{c2d29}\u{695af}\u{98fd7}\u{10ca51}", "\u{bec46}\u{c0bec}\u{cb677}\u{71318}", "\u{755e1}", "", "𫮜\u{a2f84}柂\u{f5560}\u{6737b}", "\u{8442e}\u{a6883}", "\u{49cf2}\u{32d2b}\u{1e6e5}\u{1084bd}", "", "\u{85172}\u{103bd2}\u{bffa3}\u{c792c}\u{4c421}\u{905ef}", "", "", "\u{c0f92}匥\u{105164}𦤃\u{8ebb2}\u{9e650}\u{399cd}\u{51328}\u{61706}\u{1096f6}\ \u{d9e03}", "\u{ac5ce}\u{db625}\u{f1185}\u{f170e}\u{b7772}\u{dfa6f}\u{f65d0}\u{10c939}", "", "\u{3e110}𪐛\u{84380}", "", "\u{46189}\u{5832d}ꌍ𫁜\u{1083cd}", "\u{102636}\u{c0f80}\u{cacb1}\u{89486}\u{1ad3c}𖢸\u{b7896}\u{3dadc}\u{82b15}", ], &[ ("", 199913), ("姑", 4), ("\u{36097}", 4), ("\u{3d772}", 4), ("\u{40698}", 4), ("\u{6e63c}", 4), ("\u{7d354}", 4), ("\u{8465e}", 4), ("\u{9090b}", 4), ("\u{929c5}", 4), ], ( "\u{667cc}\u{850e8}\u{42572}𪩋\u{637c9}\u{ef6f1}", Some("\u{667cc}\u{a3e1a}\u{bead8}𢰏\u{d2d0b}"), ), ); random_strings_helper( 10, 1, &[ "\u{81355}\u{a331d}\u{b707b}\u{1354b}\u{b16ac}𣙘\u{67377}\u{4aaa4}\u{a6d6e}\u{45616}\ \u{7725f}\u{41e2d}\u{d6b59}\u{de165}\u{c2d29}\u{695af}\u{98fd7}\u{10ca51}\u{bec46}\ \u{c0bec}\u{cb677}\u{71318}\u{755e1}𫮜\u{a2f84}柂\u{f5560}\u{6737b}", "\u{8442e}\u{a6883}\u{49cf2}\u{32d2b}\u{1e6e5}\u{1084bd}\u{85172}\u{103bd2}\u{bffa3}\ \u{c792c}\u{4c421}\u{905ef}\u{c0f92}匥\u{105164}𦤃\u{8ebb2}\u{9e650}", "\u{399cd}\u{51328}\u{61706}\u{1096f6}\u{d9e03}\u{ac5ce}\u{db625}\u{f1185}\u{f170e}\ \u{b7772}\u{dfa6f}\u{f65d0}\u{10c939}\u{3e110}𪐛\u{84380}\u{46189}\u{5832d}ꌍ", "𫁜\u{1083cd}\u{102636}", "\u{c0f80}\u{cacb1}\u{89486}\u{1ad3c}𖢸\u{b7896}\u{3dadc}\u{82b15}\u{e01b7}\u{53091}\ \u{eafa3}\u{e6a8c}", "\u{af3e0}", "\u{56c4c}\u{b06f5}\u{76039}\u{49cbf}\u{103396}\u{99695}\u{fb2c5}\u{1269b}\u{d63a8}\ \u{7b2ad}\u{62abc}\u{426cf}\u{917bd}\u{3ef1e}\u{900a7}𤧏\u{1079f9}\u{41860}\u{9861d}\ \u{cbfd1}\u{48859}\u{5826c}\u{b5d68}\u{9d637}\u{10039d}\u{8e8d5}𡩔\u{50c19}\u{b9d8e}", "\u{f97c0}\u{5e025}\u{71838}\u{bdfd5}\u{d2042}", "\u{bdb07}\u{54a51}", "𞠮\u{f718c}轜\u{511f8}\u{d45cc}\u{cdcb6}\u{51127}\u{62ef1}𗛜\u{5a889}\u{4f824}", "\u{e4fc5}𛂮\u{67155}\u{990bb}\u{54368}\u{1ec21}\u{155e9}\u{cda02}𥵯\u{ac392}\u{41517}\ \u{6d7f1}\u{101067}\u{127d7}\u{76266}\u{e4c58}\u{ba16f}\u{50d46}\u{69b8a}\u{b8556}\ \u{e2a57}\u{c71bb}\u{b2276}\u{db65b}\u{72eba}\u{9ce32}𨚕쬽\u{b14b4}\u{721f3}", "\u{e92d0}\u{79265}\u{3413c}\u{8a37b}\u{3b281}", "\u{1038bc}\u{105572}\u{60004}\u{2f067}", "\u{8d937}\u{a77ba}\u{5cdfa}\u{d281b}\u{4fad0}\u{926dd}탘\u{589d1}", "\u{4c96e}\u{31c01}\u{d7b70}\u{3b41a}\u{fa158}\u{37ba2}\u{f7772}\u{51268}\u{a5a58}\ \u{6dac7}\u{13515}", "\u{94c1f}\u{72cc7}\u{4e95e}\u{ce473}", "\u{10125f}\u{e1343}\u{ff236}\u{883de}凴\u{6274f}\u{ada6c}\u{b0b8b}\u{7f144}", "𠛾\u{72db9}\u{a49b2}𓅹\u{7fe45}\u{fb3c5}\u{86a5e}\u{b91ae}\u{7ef4b}", "\u{4e11e}\u{48ae3}\u{8e62a}\u{6a125}\u{692a6}\u{d811f}\u{1a0d4}\u{70978}\u{1b985}\ \u{d83b6}\u{82dff}\u{41a7f}\u{94b31}깥\u{87f4b}\u{aa0ce}\u{f6b18}⠋\u{ded9c}𬟺\u{10df0a}\ \u{b9982}\u{adaaa}𠰮\u{10db78}", "\u{1c15b}", ], &[ ("", 90709), ("瞁", 4), ("\u{7cb3d}", 4), ("\u{844e7}", 4), ("摄", 3), ("覨", 3), ("霮", 3), ("鬻", 3), ("뀳", 3), ("𥛋", 3), ], ( "\u{7abb9}⼥\u{8df6b}\u{6f616}\u{7661d}\u{68c62}", Some( "\u{7abb9}\u{6e013}\u{10c6dc}\u{5be7a}\u{99103}\u{f9c20}\u{108e71}\u{12917}\ \u{9f018}𥱗", ), ), ); random_strings_helper( 1, 4, &[ "", "", "\u{81355}", "\u{a331d}", "\u{b707b}\u{1354b}", "", "", "", "", "", "", "", "\u{b16ac}𣙘", "\u{67377}", "", "\u{4aaa4}\u{a6d6e}", "", "", "", "", ], &[ ("", 800023), ("\u{4a9ab}", 5), ("悧", 4), ("𦹝", 4), ("𱩖", 4), ("\u{1b9f0}", 4), ("\u{56b1b}", 4), ("\u{61e16}", 4), ("\u{8a520}", 4), ("\u{959f7}", 4), ], ("", None), ); } #[test] #[should_panic] fn random_strings_fail_1() { random_strings(EXAMPLE_SEED, 0, 1); } #[test] #[should_panic] fn random_strings_fail_2() { random_strings(EXAMPLE_SEED, 1, 0); } #[test] #[should_panic] fn random_strings_fail_3() { random_strings(EXAMPLE_SEED, u64::MAX, u64::MAX - 1); } malachite-base-0.4.16/tests/strings/random/random_strings_using_chars.rs000064400000000000000000000125171046102023000246600ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::chars::random::{random_ascii_chars, random_char_inclusive_range}; use malachite_base::random::{Seed, EXAMPLE_SEED}; use malachite_base::strings::random::random_strings_using_chars; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; use std::iter::repeat; fn random_strings_using_chars_helper>( cs_gen: &dyn Fn(Seed) -> I, mean_length_numerator: u64, mean_length_denominator: u64, expected_values: &[&str], expected_common_values: &[(&str, usize)], expected_median: (&str, Option<&str>), ) { let ss = random_strings_using_chars( EXAMPLE_SEED, cs_gen, mean_length_numerator, mean_length_denominator, ); let values = ss.clone().take(20).collect_vec(); let common_values = common_values_map_debug(1000000, 10, ss.clone()); let (median_lo, median_hi) = median(ss.take(1000000)); assert_eq!( ( values.iter().map(String::as_str).collect_vec().as_slice(), common_values .iter() .map(|(s, f)| (s.as_str(), *f)) .collect_vec() .as_slice(), (median_lo.as_str(), median_hi.as_deref()) ), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_random_strings_using_chars() { random_strings_using_chars_helper( &|_| repeat('a'), 4, 1, &[ "", "aaaaaaaaaaaaaa", "aaaa", "aaaa", "a", "", "aaaaa", "aa", "aaaa", "", "aaaaaa", "", "", "aaaaaaaaaaa", "aaaaaaaa", "", "aaa", "", "aaaaa", "aaaaaaaaa", ], &[ ("", 199913), ("a", 160173), ("aa", 128173), ("aaa", 102460), ("aaaa", 81463), ("aaaaa", 65695), ("aaaaaa", 52495), ("aaaaaaa", 41943), ("aaaaaaaa", 33396), ("aaaaaaaaa", 27035), ], ("aaa", None), ); random_strings_using_chars_helper( &|seed| random_char_inclusive_range(seed, 'a', 'c'), 4, 1, &[ "", "bbbbcaaacacaca", "cccb", "acca", "b", "", "cbcac", "cb", "cbba", "", "ccacca", "", "", "acacbcccccc", "baccbccb", "", "bcc", "", "cbbca", "aacbaabbc", ], &[ ("", 199913), ("c", 53448), ("a", 53374), ("b", 53351), ("ab", 14396), ("aa", 14370), ("cb", 14345), ("cc", 14252), ("ba", 14240), ("ac", 14237), ], ("b", None), ); random_strings_using_chars_helper( &random_ascii_chars, 4, 1, &[ "", "U\u{16} D<]ae_M,O\u{1d}V", "(\u{10}&U", "{P-K", "Z", "", "\u{4}X\u{19}_,", "\u{1d},", "?\'[N", "", "|}*\u{15}zt", "", "", "\u{2}FXHmX\\\u{8} ZJ", "\u{b}\u{14}OwV\u{19} R", "", "|4\u{e}", "", "M$E\u{12}n", "J)\u{16}\u{1c}\u{11}_T\u{1d}-", ], &[ ("", 199913), ("\u{c}", 1334), ("~", 1322), ("R", 1318), ("o", 1312), ("=", 1310), ("\u{1d}", 1310), ("}", 1308), ("\u{10}", 1306), ("\u{1e}", 1306), ], ("/x\u{b}", Some("/x\u{f}")), ); random_strings_using_chars_helper( &random_ascii_chars, 1, 4, &[ "", "", "U", "\u{16}", " D", "", "", "", "", "", "", "", "<]", "a", "", "e_", "", "", "", "", ], &[ ("", 800023), ("<", 1334), ("$", 1329), ("\u{b}", 1319), ("%", 1313), ("v", 1309), ("A", 1308), ("\u{1a}", 1308), ("d", 1307), ("B", 1306), ], ("", None), ); } #[test] #[should_panic] fn random_strings_using_chars_fail_1() { random_strings_using_chars(EXAMPLE_SEED, &random_ascii_chars, 0, 1); } #[test] #[should_panic] fn random_strings_using_chars_fail_2() { random_strings_using_chars(EXAMPLE_SEED, &random_ascii_chars, 1, 0); } #[test] #[should_panic] fn random_strings_using_chars_fail_3() { random_strings_using_chars(EXAMPLE_SEED, &random_ascii_chars, u64::MAX, u64::MAX - 1); } malachite-base-0.4.16/tests/strings/string_is_subset.rs000064400000000000000000000032751046102023000213510ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::strings::{string_is_subset, string_sort, string_unique}; use malachite_base::test_util::generators::common::GenConfig; use malachite_base::test_util::generators::string_pair_gen; #[test] fn test_string_is_subset() { let test = |s, t, out| { assert_eq!(string_is_subset(s, t), out); }; test("", "Hello, world!", true); test("o, well", "Hello, world!", true); test("MMM", "Mississippi", true); test("Hello, World!", "Hello, world!", false); test("j", "Mississippi", false); test( "abcdefghijklmnopqrstuvwxyz", "A quick brown fox jumps over the lazy dog", true, ); } #[test] fn string_is_subset_properties() { let mut config = GenConfig::new(); config.insert("mean_length_n", 128); config.insert("mean_length_d", 1); string_pair_gen().test_properties_with_config(&config, |(s, t)| { let is_subset = string_is_subset(&s, &t); assert_eq!( string_is_subset(&string_sort(&s), &string_sort(&t)), is_subset ); assert_eq!( string_is_subset(&string_unique(&s), &string_unique(&t)), is_subset ); assert_eq!( is_subset && string_is_subset(&t, &s), string_sort(&string_unique(&s)) == string_sort(&string_unique(&t)) ); }); } malachite-base-0.4.16/tests/strings/string_sort.rs000064400000000000000000000027761046102023000203450ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::iterators::comparison::is_weakly_ascending; use malachite_base::strings::{string_is_subset, string_sort, string_unique}; use malachite_base::test_util::generators::common::GenConfig; use malachite_base::test_util::generators::string_gen; #[test] fn test_string_sort() { let test = |s, out| { assert_eq!(string_sort(s), out); }; test("", ""); test("x", "x"); test("Hello, world!", " !,Hdellloorw"); test("Mississippi", "Miiiippssss"); test( "A quick brown fox jumps over the lazy dog", " Aabcdeefghijklmnoooopqrrstuuvwxyz", ); } #[test] fn string_sort_properties() { let mut config = GenConfig::new(); config.insert("mean_length_n", 128); config.insert("mean_length_d", 1); string_gen().test_properties_with_config(&config, |s| { let t = string_sort(&s); assert!(is_weakly_ascending(t.chars())); assert_eq!(s.len(), t.len()); assert_eq!(string_sort(&t), t); assert_eq!(string_unique(&t), string_sort(&string_unique(&s))); assert!(string_is_subset(&s, &t)); assert!(string_is_subset(&t, &s)); }); } malachite-base-0.4.16/tests/strings/string_unique.rs000064400000000000000000000026271046102023000206570ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::iterators::is_unique; use malachite_base::strings::{string_is_subset, string_unique}; use malachite_base::test_util::generators::common::GenConfig; use malachite_base::test_util::generators::string_gen; #[test] fn test_string_unique() { let test = |s, out| { assert_eq!(string_unique(s), out); }; test("", ""); test("x", "x"); test("xxxxxxxxx", "x"); test("Hello, world!", "Helo, wrd!"); test("Mississippi", "Misp"); test( "A quick brown fox jumps over the lazy dog", "A quickbrownfxjmpsvethlazydg", ); } #[test] fn string_unique_properties() { let mut config = GenConfig::new(); config.insert("mean_length_n", 128); config.insert("mean_length_d", 1); string_gen().test_properties_with_config(&config, |s| { let t = string_unique(&s); assert!(is_unique(t.chars())); assert!(t.len() <= s.len()); assert_eq!(string_unique(&t), t); assert!(string_is_subset(&s, &t)); assert!(string_is_subset(&t, &s)); }); } malachite-base-0.4.16/tests/strings/strings_from_char_vecs.rs000064400000000000000000000023771046102023000225160ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::strings::strings_from_char_vecs; use std::iter::repeat; fn strings_from_char_vecs_helper>>(css: I, out: &[&str]) { let css = strings_from_char_vecs(css).take(20).collect_vec(); assert_eq!(css.iter().map(String::as_str).collect_vec().as_slice(), out); } #[test] fn test_strings_from_char_vecs() { strings_from_char_vecs_helper([].iter().cloned(), &[]); strings_from_char_vecs_helper([vec!['a']].iter().cloned(), &["a"]); strings_from_char_vecs_helper( [vec!['a', 'b'], vec!['c', 'd']].iter().cloned(), &["ab", "cd"], ); strings_from_char_vecs_helper( repeat(vec!['c', 'a', 't']), &[ "cat", "cat", "cat", "cat", "cat", "cat", "cat", "cat", "cat", "cat", "cat", "cat", "cat", "cat", "cat", "cat", "cat", "cat", "cat", "cat", ], ); } malachite-base-0.4.16/tests/strings/to_binary_string.rs000064400000000000000000000011471046102023000213330ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::strings::ToBinaryString; #[test] pub fn test_to_binary_string() { assert_eq!(5u32.to_binary_string(), "101"); assert_eq!( (-5i32).to_binary_string(), "11111111111111111111111111111011" ); } malachite-base-0.4.16/tests/strings/to_debug_string.rs000064400000000000000000000014001046102023000211250ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::strings::ToDebugString; #[test] pub fn test_to_debug_string() { let empty: &[Option] = &[]; assert_eq!(empty.to_debug_string(), "[]"); assert_eq!([1, 2, 3].to_debug_string(), "[1, 2, 3]"); assert_eq!( [vec![2, 3], vec![], vec![4]].to_debug_string(), "[[2, 3], [], [4]]" ); assert_eq!(Some(5).to_debug_string(), "Some(5)"); } malachite-base-0.4.16/tests/strings/to_lower_hex_string.rs000064400000000000000000000011061046102023000220360ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::strings::ToLowerHexString; #[test] pub fn test_to_lower_hex_string() { assert_eq!(50u32.to_lower_hex_string(), "32"); assert_eq!((-100i32).to_lower_hex_string(), "ffffff9c"); } malachite-base-0.4.16/tests/strings/to_octal_string.rs000064400000000000000000000010721046102023000211460ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::strings::ToOctalString; #[test] pub fn test_to_octal_string() { assert_eq!(50u32.to_octal_string(), "62"); assert_eq!((-100i32).to_octal_string(), "37777777634"); } malachite-base-0.4.16/tests/strings/to_upper_hex_string.rs000064400000000000000000000011061046102023000220410ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::strings::ToUpperHexString; #[test] pub fn test_to_upper_hex_string() { assert_eq!(50u32.to_upper_hex_string(), "32"); assert_eq!((-100i32).to_upper_hex_string(), "FFFFFF9C"); } malachite-base-0.4.16/tests/tuples/exhaustive/exhaustive_custom_tuples.rs000064400000000000000000000303531046102023000251430ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::extra_variadic::{ exhaustive_triples_from_single, exhaustive_triples_xxy, exhaustive_triples_xxy_custom_output, exhaustive_triples_xyx, exhaustive_triples_xyx_custom_output, }; use crate::get_sample_output_types; use itertools::Itertools; use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::nevers::nevers; use malachite_base::num::exhaustive::exhaustive_unsigneds; use malachite_base::orderings::exhaustive::exhaustive_orderings; use malachite_base::tuples::exhaustive::exhaustive_pairs; use std::cmp::Ordering::*; use std::fmt::Debug; use std::iter::once; #[allow(clippy::needless_pass_by_value)] fn exhaustive_triples_xxy_helper< X: Clone + Debug + Eq, I: Clone + Iterator, Y: Clone + Debug + Eq, J: Clone + Iterator, >( xs: I, ys: J, out_len: usize, out: &[(X, X, Y)], ) { let ts = exhaustive_triples_xxy(xs.clone(), ys.clone()); assert_eq!(ts.clone().take(20).collect_vec(), out); assert_eq!(ts.count(), out_len); let output_types = get_sample_output_types(3); let ts = exhaustive_triples_xxy_custom_output( xs.clone(), ys.clone(), output_types[0][0], output_types[0][1], output_types[0][2], ); let ts_prefix = ts.clone().take(20).collect_vec(); assert_eq!(ts_prefix.as_slice(), out); assert_eq!(ts.count(), out_len); for alt_output_types in &output_types[1..] { let ts = exhaustive_triples_xxy_custom_output( xs.clone(), ys.clone(), alt_output_types[0], alt_output_types[1], alt_output_types[2], ); ts.clone().take(20).for_each(drop); assert_eq!(ts.count(), out_len); } } #[test] fn test_exhaustive_triples_xxy() { exhaustive_triples_xxy_helper(nevers(), nevers(), 0, &[]); exhaustive_triples_xxy_helper(nevers(), 0..4, 0, &[]); exhaustive_triples_xxy_helper(once('a'), once(1), 1, &[('a', 'a', 1)]); exhaustive_triples_xxy_helper( once('a'), 0..4, 4, &[('a', 'a', 0), ('a', 'a', 1), ('a', 'a', 2), ('a', 'a', 3)], ); exhaustive_triples_xxy_helper( exhaustive_unsigneds::(), 'a'..'e', 1 << 18, &[ (0, 0, 'a'), (0, 0, 'b'), (0, 1, 'a'), (0, 1, 'b'), (1, 0, 'a'), (1, 0, 'b'), (1, 1, 'a'), (1, 1, 'b'), (0, 0, 'c'), (0, 0, 'd'), (0, 1, 'c'), (0, 1, 'd'), (1, 0, 'c'), (1, 0, 'd'), (1, 1, 'c'), (1, 1, 'd'), (0, 2, 'a'), (0, 2, 'b'), (0, 3, 'a'), (0, 3, 'b'), ], ); exhaustive_triples_xxy_helper( exhaustive_bools(), 0..4, 16, &[ (false, false, 0), (false, false, 1), (false, true, 0), (false, true, 1), (true, false, 0), (true, false, 1), (true, true, 0), (true, true, 1), (false, false, 2), (false, false, 3), (false, true, 2), (false, true, 3), (true, false, 2), (true, false, 3), (true, true, 2), (true, true, 3), ], ); exhaustive_triples_xxy_helper( 'a'..'f', 0..3, 75, &[ ('a', 'a', 0), ('a', 'a', 1), ('a', 'b', 0), ('a', 'b', 1), ('b', 'a', 0), ('b', 'a', 1), ('b', 'b', 0), ('b', 'b', 1), ('a', 'a', 2), ('a', 'b', 2), ('b', 'a', 2), ('b', 'b', 2), ('a', 'c', 0), ('a', 'c', 1), ('a', 'd', 0), ('a', 'd', 1), ('b', 'c', 0), ('b', 'c', 1), ('b', 'd', 0), ('b', 'd', 1), ], ); exhaustive_triples_xxy_helper( ['a', 'b', 'c'].iter().copied(), exhaustive_orderings(), 27, &[ ('a', 'a', Equal), ('a', 'a', Less), ('a', 'b', Equal), ('a', 'b', Less), ('b', 'a', Equal), ('b', 'a', Less), ('b', 'b', Equal), ('b', 'b', Less), ('a', 'a', Greater), ('a', 'b', Greater), ('b', 'a', Greater), ('b', 'b', Greater), ('a', 'c', Equal), ('a', 'c', Less), ('b', 'c', Equal), ('b', 'c', Less), ('a', 'c', Greater), ('b', 'c', Greater), ('c', 'a', Equal), ('c', 'a', Less), ], ); exhaustive_triples_xxy_helper( exhaustive_pairs(exhaustive_orderings(), exhaustive_bools()), exhaustive_triples_from_single([Less, Greater].iter().copied()), 288, &[ ((Equal, false), (Equal, false), (Less, Less, Less)), ((Equal, false), (Equal, false), (Less, Less, Greater)), ((Equal, false), (Equal, true), (Less, Less, Less)), ((Equal, false), (Equal, true), (Less, Less, Greater)), ((Equal, true), (Equal, false), (Less, Less, Less)), ((Equal, true), (Equal, false), (Less, Less, Greater)), ((Equal, true), (Equal, true), (Less, Less, Less)), ((Equal, true), (Equal, true), (Less, Less, Greater)), ((Equal, false), (Equal, false), (Less, Greater, Less)), ((Equal, false), (Equal, false), (Less, Greater, Greater)), ((Equal, false), (Equal, true), (Less, Greater, Less)), ((Equal, false), (Equal, true), (Less, Greater, Greater)), ((Equal, true), (Equal, false), (Less, Greater, Less)), ((Equal, true), (Equal, false), (Less, Greater, Greater)), ((Equal, true), (Equal, true), (Less, Greater, Less)), ((Equal, true), (Equal, true), (Less, Greater, Greater)), ((Equal, false), (Less, false), (Less, Less, Less)), ((Equal, false), (Less, false), (Less, Less, Greater)), ((Equal, false), (Less, true), (Less, Less, Less)), ((Equal, false), (Less, true), (Less, Less, Greater)), ], ); } #[allow(clippy::needless_pass_by_value)] fn exhaustive_triples_xyx_helper< X: Clone + Debug + Eq, I: Clone + Iterator, Y: Clone + Debug + Eq, J: Clone + Iterator, >( xs: I, ys: J, out_len: usize, out: &[(X, Y, X)], ) { let ts = exhaustive_triples_xyx(xs.clone(), ys.clone()); assert_eq!(ts.clone().take(20).collect_vec(), out); assert_eq!(ts.count(), out_len); let output_types = get_sample_output_types(3); let ts = exhaustive_triples_xyx_custom_output( xs.clone(), ys.clone(), output_types[0][0], output_types[0][1], output_types[0][2], ); let ts_prefix = ts.clone().take(20).collect_vec(); assert_eq!(ts_prefix.as_slice(), out); assert_eq!(ts.count(), out_len); for alt_output_types in &output_types[1..] { let ts = exhaustive_triples_xyx_custom_output( xs.clone(), ys.clone(), alt_output_types[0], alt_output_types[1], alt_output_types[2], ); ts.clone().take(20).for_each(drop); assert_eq!(ts.count(), out_len); } } #[test] fn test_exhaustive_triples_xyx() { exhaustive_triples_xyx_helper(nevers(), nevers(), 0, &[]); exhaustive_triples_xyx_helper(nevers(), 0..4, 0, &[]); exhaustive_triples_xyx_helper(once('a'), once(1), 1, &[('a', 1, 'a')]); exhaustive_triples_xyx_helper( once('a'), 0..4, 4, &[('a', 0, 'a'), ('a', 1, 'a'), ('a', 2, 'a'), ('a', 3, 'a')], ); exhaustive_triples_xyx_helper( exhaustive_unsigneds::(), 'a'..'e', 1 << 18, &[ (0, 'a', 0), (0, 'a', 1), (0, 'b', 0), (0, 'b', 1), (1, 'a', 0), (1, 'a', 1), (1, 'b', 0), (1, 'b', 1), (0, 'a', 2), (0, 'a', 3), (0, 'b', 2), (0, 'b', 3), (1, 'a', 2), (1, 'a', 3), (1, 'b', 2), (1, 'b', 3), (0, 'c', 0), (0, 'c', 1), (0, 'd', 0), (0, 'd', 1), ], ); exhaustive_triples_xyx_helper( exhaustive_bools(), 0..4, 16, &[ (false, 0, false), (false, 0, true), (false, 1, false), (false, 1, true), (true, 0, false), (true, 0, true), (true, 1, false), (true, 1, true), (false, 2, false), (false, 2, true), (false, 3, false), (false, 3, true), (true, 2, false), (true, 2, true), (true, 3, false), (true, 3, true), ], ); exhaustive_triples_xyx_helper( 'a'..'f', 0..3, 75, &[ ('a', 0, 'a'), ('a', 0, 'b'), ('a', 1, 'a'), ('a', 1, 'b'), ('b', 0, 'a'), ('b', 0, 'b'), ('b', 1, 'a'), ('b', 1, 'b'), ('a', 0, 'c'), ('a', 0, 'd'), ('a', 1, 'c'), ('a', 1, 'd'), ('b', 0, 'c'), ('b', 0, 'd'), ('b', 1, 'c'), ('b', 1, 'd'), ('a', 2, 'a'), ('a', 2, 'b'), ('b', 2, 'a'), ('b', 2, 'b'), ], ); exhaustive_triples_xyx_helper( ['a', 'b', 'c'].iter().copied(), exhaustive_orderings(), 27, &[ ('a', Equal, 'a'), ('a', Equal, 'b'), ('a', Less, 'a'), ('a', Less, 'b'), ('b', Equal, 'a'), ('b', Equal, 'b'), ('b', Less, 'a'), ('b', Less, 'b'), ('a', Equal, 'c'), ('a', Less, 'c'), ('b', Equal, 'c'), ('b', Less, 'c'), ('a', Greater, 'a'), ('a', Greater, 'b'), ('b', Greater, 'a'), ('b', Greater, 'b'), ('a', Greater, 'c'), ('b', Greater, 'c'), ('c', Equal, 'a'), ('c', Equal, 'b'), ], ); exhaustive_triples_xyx_helper( exhaustive_pairs(exhaustive_orderings(), exhaustive_bools()), exhaustive_triples_from_single([Less, Greater].iter().copied()), 288, &[ ((Equal, false), (Less, Less, Less), (Equal, false)), ((Equal, false), (Less, Less, Less), (Equal, true)), ((Equal, false), (Less, Less, Greater), (Equal, false)), ((Equal, false), (Less, Less, Greater), (Equal, true)), ((Equal, true), (Less, Less, Less), (Equal, false)), ((Equal, true), (Less, Less, Less), (Equal, true)), ((Equal, true), (Less, Less, Greater), (Equal, false)), ((Equal, true), (Less, Less, Greater), (Equal, true)), ((Equal, false), (Less, Less, Less), (Less, false)), ((Equal, false), (Less, Less, Less), (Less, true)), ((Equal, false), (Less, Less, Greater), (Less, false)), ((Equal, false), (Less, Less, Greater), (Less, true)), ((Equal, true), (Less, Less, Less), (Less, false)), ((Equal, true), (Less, Less, Less), (Less, true)), ((Equal, true), (Less, Less, Greater), (Less, false)), ((Equal, true), (Less, Less, Greater), (Less, true)), ((Equal, false), (Less, Greater, Less), (Equal, false)), ((Equal, false), (Less, Greater, Less), (Equal, true)), ((Equal, false), (Less, Greater, Greater), (Equal, false)), ((Equal, false), (Less, Greater, Greater), (Equal, true)), ], ); } malachite-base-0.4.16/tests/tuples/exhaustive/exhaustive_dependent_pairs.rs000064400000000000000000000333761046102023000254110ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use core::hash::Hash; use itertools::{chain, Itertools}; use malachite_base::iterators::bit_distributor::BitDistributorOutputType; use malachite_base::num::exhaustive::exhaustive_positive_primitive_ints; use malachite_base::num::iterators::{bit_distributor_sequence, ruler_sequence}; use malachite_base::tuples::exhaustive::{ exhaustive_dependent_pairs, exhaustive_dependent_pairs_stop_after_empty_ys, ExhaustiveDependentPairsYsGenerator, }; use std::collections::HashMap; use std::fmt::Debug; use std::iter::{once, repeat, Cloned}; use std::slice::Iter; #[derive(Clone, Debug)] struct ExhaustiveGeneratorFromMap { map: HashMap, } impl ExhaustiveDependentPairsYsGenerator>> for ExhaustiveGeneratorFromMap { #[inline] fn get_ys(&self, x: &X) -> Cloned> { self.map[x].iter().cloned() } } fn exhaustive_dependent_pairs_finite_ys_helper( xs: I, map: HashMap, out_ruler: &[(I::Item, Y)], out_normal_normal: &[(I::Item, Y)], out_tiny_normal: &[(I::Item, Y)], ) where I::Item: Clone + Debug + Eq + Hash, Y: Clone + Debug + Eq, { let xss_ruler = exhaustive_dependent_pairs( ruler_sequence(), xs.clone(), ExhaustiveGeneratorFromMap { map: map.clone() }, ) .take(20) .collect_vec(); assert_eq!(xss_ruler.as_slice(), out_ruler); let xss_normal_normal = exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(1), ), xs.clone(), ExhaustiveGeneratorFromMap { map: map.clone() }, ) .take(20) .collect_vec(); assert_eq!(xss_normal_normal.as_slice(), out_normal_normal); let xss_tiny_normal = exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), xs, ExhaustiveGeneratorFromMap { map }, ) .take(20) .collect_vec(); assert_eq!(xss_tiny_normal.as_slice(), out_tiny_normal); } #[test] fn test_exhaustive_dependent_pairs() { exhaustive_dependent_pairs_finite_ys_helper( [1, 2, 3].iter().copied(), hashmap! { 1 => &[100, 101, 102][..], 2 => &[200, 201, 202][..], 3 => &[300, 301, 302][..] }, &[(1, 100), (2, 200), (1, 101), (3, 300), (1, 102), (2, 201), (2, 202), (3, 301), (3, 302)], &[(1, 100), (2, 200), (1, 101), (2, 201), (3, 300), (1, 102), (3, 301), (3, 302), (2, 202)], &[(1, 100), (2, 200), (3, 300), (1, 101), (1, 102), (2, 201), (3, 301), (3, 302), (2, 202)], ); exhaustive_dependent_pairs_finite_ys_helper( ["cat", "dog", "mouse", "dog", "cat"].iter().copied(), hashmap! { "cat" => &[2, 3, 4][..], "dog" => &[20][..], "mouse" => &[30, 40][..] }, &[ ("cat", 2), ("dog", 20), ("cat", 3), ("mouse", 30), ("cat", 4), ("mouse", 40), ("dog", 20), ("cat", 2), ("cat", 3), ("cat", 4), ], &[ ("cat", 2), ("dog", 20), ("cat", 3), ("mouse", 30), ("dog", 20), ("cat", 2), ("cat", 3), ("cat", 4), ("mouse", 40), ("cat", 4), ], &[ ("cat", 2), ("dog", 20), ("mouse", 30), ("dog", 20), ("cat", 3), ("mouse", 40), ("cat", 2), ("cat", 4), ("cat", 3), ("cat", 4), ], ); exhaustive_dependent_pairs_finite_ys_helper( [1, 2, 3, 2, 3, 2, 2].iter().copied(), hashmap! { 1 => &[100, 101, 102][..], 2 => &[][..], 3 => &[300, 301, 302][..] }, &[(1, 100), (3, 300), (1, 101), (3, 300), (1, 102), (3, 301), (3, 302), (3, 301), (3, 302)], &[(1, 100), (3, 300), (1, 101), (3, 301), (3, 300), (1, 102), (3, 301), (3, 302), (3, 302)], &[(1, 100), (3, 300), (3, 300), (1, 101), (1, 102), (3, 301), (3, 301), (3, 302), (3, 302)], ); exhaustive_dependent_pairs_finite_ys_helper( [].iter().copied(), hashmap! { 1 => &[100, 101, 102][..], 2 => &[][..], 3 => &[300, 301, 302][..] }, &[], &[], &[], ); exhaustive_dependent_pairs_finite_ys_helper( [2, 2, 2, 2, 2].iter().copied(), hashmap! { 1 => &[100, 101, 102][..], 2 => &[][..], 3 => &[300, 301, 302][..] }, &[], &[], &[], ); } fn exhaustive_dependent_pairs_finite_ys_stop_after_empty_ys_helper( xs: I, map: HashMap, out_ruler: &[(I::Item, Y)], out_normal_normal: &[(I::Item, Y)], out_tiny_normal: &[(I::Item, Y)], ) where I::Item: Clone + Debug + Eq + Hash, Y: Clone + Debug + Eq, { let xss_ruler = exhaustive_dependent_pairs_stop_after_empty_ys( ruler_sequence(), xs.clone(), ExhaustiveGeneratorFromMap { map: map.clone() }, ) .take(20) .collect_vec(); assert_eq!(xss_ruler.as_slice(), out_ruler); let xss_normal_normal = exhaustive_dependent_pairs_stop_after_empty_ys( bit_distributor_sequence( BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(1), ), xs.clone(), ExhaustiveGeneratorFromMap { map: map.clone() }, ) .take(20) .collect_vec(); assert_eq!(xss_normal_normal.as_slice(), out_normal_normal); let xss_tiny_normal = exhaustive_dependent_pairs_stop_after_empty_ys( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), xs, ExhaustiveGeneratorFromMap { map }, ) .take(20) .collect_vec(); assert_eq!(xss_tiny_normal.as_slice(), out_tiny_normal); } #[test] fn test_exhaustive_dependent_pairs_stop_after_empty_ys() { exhaustive_dependent_pairs_finite_ys_stop_after_empty_ys_helper( [1, 2, 3].iter().copied(), hashmap! { 1 => &[100, 101, 102][..], 2 => &[200, 201, 202][..], 3 => &[300, 301, 302][..] }, &[(1, 100), (2, 200), (1, 101), (3, 300), (1, 102), (2, 201), (2, 202), (3, 301), (3, 302)], &[(1, 100), (2, 200), (1, 101), (2, 201), (3, 300), (1, 102), (3, 301), (3, 302), (2, 202)], &[(1, 100), (2, 200), (3, 300), (1, 101), (1, 102), (2, 201), (3, 301), (3, 302), (2, 202)], ); exhaustive_dependent_pairs_finite_ys_stop_after_empty_ys_helper( ["cat", "dog", "mouse", "dog", "cat"].iter().copied(), hashmap! { "cat" => &[2, 3, 4][..], "dog" => &[20][..], "mouse" => &[30, 40][..] }, &[ ("cat", 2), ("dog", 20), ("cat", 3), ("mouse", 30), ("cat", 4), ("mouse", 40), ("dog", 20), ("cat", 2), ("cat", 3), ("cat", 4), ], &[ ("cat", 2), ("dog", 20), ("cat", 3), ("mouse", 30), ("dog", 20), ("cat", 2), ("cat", 3), ("cat", 4), ("mouse", 40), ("cat", 4), ], &[ ("cat", 2), ("dog", 20), ("mouse", 30), ("dog", 20), ("cat", 3), ("mouse", 40), ("cat", 2), ("cat", 4), ("cat", 3), ("cat", 4), ], ); // Notice difference from `exhaustive_dependent_pairs` exhaustive_dependent_pairs_finite_ys_stop_after_empty_ys_helper( [1, 2, 3, 2, 3, 2, 2].iter().copied(), hashmap! { 1 => &[100, 101, 102][..], 2 => &[][..], 3 => &[300, 301, 302][..] }, &[(1, 100)], &[(1, 100)], &[(1, 100)], ); exhaustive_dependent_pairs_finite_ys_stop_after_empty_ys_helper( [].iter().copied(), hashmap! { 1 => &[100, 101, 102][..], 2 => &[][..], 3 => &[300, 301, 302][..] }, &[], &[], &[], ); exhaustive_dependent_pairs_finite_ys_stop_after_empty_ys_helper( [2, 2, 2, 2, 2].iter().copied(), hashmap! { 1 => &[100, 101, 102][..], 2 => &[][..], 3 => &[300, 301, 302][..] }, &[], &[], &[], ); // With `exhaustive_dependent_pairs` this would hang exhaustive_dependent_pairs_finite_ys_stop_after_empty_ys_helper( chain(once(3), repeat(2)), hashmap! { 1 => &[100, 101, 102][..], 2 => &[][..], 3 => &[300, 301, 302][..] }, &[(3, 300)], &[(3, 300)], &[(3, 300)], ); } #[derive(Clone, Debug)] struct MultiplesGeneratorHelper { u: u64, step: u64, } impl Iterator for MultiplesGeneratorHelper { type Item = u64; fn next(&mut self) -> Option { let next = self.u; self.u += self.step; Some(next) } } #[derive(Clone, Debug)] struct MultiplesGenerator {} impl ExhaustiveDependentPairsYsGenerator for MultiplesGenerator { #[inline] fn get_ys(&self, x: &u64) -> MultiplesGeneratorHelper { MultiplesGeneratorHelper { u: *x, step: *x } } } #[test] fn test_exhaustive_dependent_pairs_infinite() { let xs = exhaustive_positive_primitive_ints::(); let xss_ruler = exhaustive_dependent_pairs(ruler_sequence(), xs.clone(), MultiplesGenerator {}) .take(50) .collect_vec(); assert_eq!( xss_ruler.as_slice(), &[ (1, 1), (2, 2), (1, 2), (3, 3), (1, 3), (2, 4), (1, 4), (4, 4), (1, 5), (2, 6), (1, 6), (3, 6), (1, 7), (2, 8), (1, 8), (5, 5), (1, 9), (2, 10), (1, 10), (3, 9), (1, 11), (2, 12), (1, 12), (4, 8), (1, 13), (2, 14), (1, 14), (3, 12), (1, 15), (2, 16), (1, 16), (6, 6), (1, 17), (2, 18), (1, 18), (3, 15), (1, 19), (2, 20), (1, 20), (4, 12), (1, 21), (2, 22), (1, 22), (3, 18), (1, 23), (2, 24), (1, 24), (5, 10), (1, 25), (2, 26) ] ); let xss_normal_normal = exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::normal(1), BitDistributorOutputType::normal(1), ), xs.clone(), MultiplesGenerator {}, ) .take(50) .collect_vec(); assert_eq!( xss_normal_normal.as_slice(), &[ (1, 1), (2, 2), (1, 2), (2, 4), (3, 3), (4, 4), (3, 6), (4, 8), (1, 3), (2, 6), (1, 4), (2, 8), (3, 9), (4, 12), (3, 12), (4, 16), (5, 5), (6, 6), (5, 10), (6, 12), (7, 7), (8, 8), (7, 14), (8, 16), (5, 15), (6, 18), (5, 20), (6, 24), (7, 21), (8, 24), (7, 28), (8, 32), (1, 5), (2, 10), (1, 6), (2, 12), (3, 15), (4, 20), (3, 18), (4, 24), (1, 7), (2, 14), (1, 8), (2, 16), (3, 21), (4, 28), (3, 24), (4, 32), (5, 25), (6, 30) ] ); let xss_tiny_normal = exhaustive_dependent_pairs( bit_distributor_sequence( BitDistributorOutputType::tiny(), BitDistributorOutputType::normal(1), ), xs, MultiplesGenerator {}, ) .take(50) .collect_vec(); assert_eq!( xss_tiny_normal.as_slice(), &[ (1, 1), (2, 2), (3, 3), (4, 4), (1, 2), (2, 4), (3, 6), (4, 8), (5, 5), (6, 6), (7, 7), (8, 8), (5, 10), (6, 12), (7, 14), (8, 16), (1, 3), (2, 6), (3, 9), (4, 12), (1, 4), (2, 8), (3, 12), (4, 16), (5, 15), (6, 18), (7, 21), (8, 24), (5, 20), (6, 24), (7, 28), (8, 32), (1, 5), (2, 10), (3, 15), (4, 20), (1, 6), (2, 12), (3, 18), (4, 24), (5, 25), (6, 30), (7, 35), (8, 40), (5, 30), (6, 36), (7, 42), (8, 48), (1, 7), (2, 14) ] ); } malachite-base-0.4.16/tests/tuples/exhaustive/exhaustive_ordered_unique_tuples.rs000064400000000000000000000115741046102023000266470ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::extra_variadic::{ exhaustive_ordered_unique_quadruples, exhaustive_ordered_unique_quintuples, exhaustive_ordered_unique_triples, }; use itertools::Itertools; use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::num::exhaustive::exhaustive_unsigneds; use malachite_base::tuples::exhaustive::{exhaustive_ordered_unique_pairs, exhaustive_units}; use std::fmt::Debug; macro_rules! helpers { ($t: ty, $ts: ident, $ts_helper: ident, $ts_small_helper: ident) => { fn $ts_helper(xs: I, out: &[$t]) where I::Item: Clone + Debug + Eq, { let ts = $ts(xs).take(20).collect_vec(); assert_eq!(ts.as_slice(), out); } fn $ts_small_helper(xs: I, out_len: usize, out: &[$t]) where I::Item: Clone + Debug + Eq, { let ts = $ts(xs); let ts_prefix = ts.clone().take(20).collect_vec(); assert_eq!(ts_prefix.as_slice(), out); assert_eq!(ts.count(), out_len); } }; } helpers!( (I::Item, I::Item), exhaustive_ordered_unique_pairs, _exhaustive_ordered_unique_pairs_helper, exhaustive_ordered_unique_pairs_small_helper ); helpers!( (I::Item, I::Item, I::Item), exhaustive_ordered_unique_triples, exhaustive_ordered_unique_triples_helper, _exhaustive_ordered_unique_triples_small_helper ); helpers!( (I::Item, I::Item, I::Item, I::Item), exhaustive_ordered_unique_quadruples, _exhaustive_ordered_unique_quadruples_helper, exhaustive_ordered_unique_quadruples_small_helper ); helpers!( (I::Item, I::Item, I::Item, I::Item, I::Item), exhaustive_ordered_unique_quintuples, _exhaustive_ordered_unique_quintuples_helper, exhaustive_ordered_unique_quintuples_small_helper ); #[test] fn test_exhaustive_ordered_unique_tuples() { exhaustive_ordered_unique_pairs_small_helper(nevers(), 0, &[]); exhaustive_ordered_unique_quintuples_small_helper(nevers(), 0, &[]); exhaustive_ordered_unique_pairs_small_helper(exhaustive_units(), 0, &[]); exhaustive_ordered_unique_quintuples_small_helper(exhaustive_units(), 0, &[]); exhaustive_ordered_unique_pairs_small_helper( exhaustive_unsigneds::(), 32640, &[ (0, 1), (0, 2), (1, 2), (0, 3), (1, 3), (2, 3), (0, 4), (1, 4), (2, 4), (3, 4), (0, 5), (1, 5), (2, 5), (3, 5), (4, 5), (0, 6), (1, 6), (2, 6), (3, 6), (4, 6), ], ); exhaustive_ordered_unique_triples_helper( exhaustive_unsigneds::(), &[ (0, 1, 2), (0, 1, 3), (0, 2, 3), (1, 2, 3), (0, 1, 4), (0, 2, 4), (1, 2, 4), (0, 3, 4), (1, 3, 4), (2, 3, 4), (0, 1, 5), (0, 2, 5), (1, 2, 5), (0, 3, 5), (1, 3, 5), (2, 3, 5), (0, 4, 5), (1, 4, 5), (2, 4, 5), (3, 4, 5), ], ); exhaustive_ordered_unique_pairs_small_helper( exhaustive_ascii_chars(), 8128, &[ ('a', 'b'), ('a', 'c'), ('b', 'c'), ('a', 'd'), ('b', 'd'), ('c', 'd'), ('a', 'e'), ('b', 'e'), ('c', 'e'), ('d', 'e'), ('a', 'f'), ('b', 'f'), ('c', 'f'), ('d', 'f'), ('e', 'f'), ('a', 'g'), ('b', 'g'), ('c', 'g'), ('d', 'g'), ('e', 'g'), ], ); exhaustive_ordered_unique_pairs_small_helper(exhaustive_bools(), 1, &[(false, true)]); exhaustive_ordered_unique_quadruples_small_helper( 1..=6, 15, &[ (1, 2, 3, 4), (1, 2, 3, 5), (1, 2, 4, 5), (1, 3, 4, 5), (2, 3, 4, 5), (1, 2, 3, 6), (1, 2, 4, 6), (1, 3, 4, 6), (2, 3, 4, 6), (1, 2, 5, 6), (1, 3, 5, 6), (2, 3, 5, 6), (1, 4, 5, 6), (2, 4, 5, 6), (3, 4, 5, 6), ], ); } malachite-base-0.4.16/tests/tuples/exhaustive/exhaustive_tuples_1_input.rs000064400000000000000000000124041046102023000252050ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::extra_variadic::exhaustive_triples_1_input; use crate::get_sample_output_types; use itertools::Itertools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::num::exhaustive::{exhaustive_positive_primitive_ints, exhaustive_unsigneds}; use malachite_base::tuples::exhaustive::exhaustive_pairs_1_input; use std::fmt::Debug; fn exhaustive_pairs_1_input_helper>( xs: &I, out_len: Option, out: &[(T, T)], ) where T: Clone + Debug + Eq, { let output_types = get_sample_output_types(2); let ps = exhaustive_pairs_1_input(xs.clone(), output_types[0][0], output_types[0][1]); assert_eq!(ps.clone().take(20).collect_vec(), out); if let Some(out_len) = out_len { assert_eq!(ps.count(), out_len); } for alt_output_types in &output_types[1..] { let ps = exhaustive_pairs_1_input(xs.clone(), alt_output_types[0], alt_output_types[1]); ps.clone().take(20).for_each(drop); if let Some(out_len) = out_len { assert_eq!(ps.count(), out_len); } } } #[test] fn test_exhaustive_pairs_1_input() { exhaustive_pairs_1_input_helper(&nevers(), Some(0), &[]); exhaustive_pairs_1_input_helper( &exhaustive_unsigneds::(), Some(1 << 16), &[ (0, 0), (0, 1), (1, 0), (1, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 0), (2, 1), (3, 0), (3, 1), (2, 2), (2, 3), (3, 2), (3, 3), (0, 4), (0, 5), (1, 4), (1, 5), ], ); exhaustive_pairs_1_input_helper( &exhaustive_positive_primitive_ints::(), None, &[ (1, 1), (1, 2), (2, 1), (2, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 1), (3, 2), (4, 1), (4, 2), (3, 3), (3, 4), (4, 3), (4, 4), (1, 5), (1, 6), (2, 5), (2, 6), ], ); exhaustive_pairs_1_input_helper( &['x', 'y', 'z'].iter().copied(), Some(9), &[ ('x', 'x'), ('x', 'y'), ('y', 'x'), ('y', 'y'), ('x', 'z'), ('y', 'z'), ('z', 'x'), ('z', 'y'), ('z', 'z'), ], ); } fn exhaustive_triples_1_input_helper>( xs: &I, out_len: Option, out: &[(T, T, T)], ) where T: Clone + Debug + Eq, { let output_types = get_sample_output_types(3); let ps = exhaustive_triples_1_input( xs.clone(), output_types[0][0], output_types[0][1], output_types[0][2], ); assert_eq!(ps.clone().take(20).collect_vec(), out); if let Some(out_len) = out_len { assert_eq!(ps.count(), out_len); } for alt_output_types in &output_types[1..] { let ps = exhaustive_triples_1_input( xs.clone(), alt_output_types[0], alt_output_types[1], alt_output_types[2], ); ps.clone().take(20).for_each(drop); if let Some(out_len) = out_len { assert_eq!(ps.count(), out_len); } } } #[test] fn test_exhaustive_triples_1_input() { exhaustive_triples_1_input_helper( &['x', 'y', 'z'].iter().copied(), Some(27), &[ ('x', 'x', 'x'), ('x', 'x', 'y'), ('x', 'y', 'x'), ('x', 'y', 'y'), ('y', 'x', 'x'), ('y', 'x', 'y'), ('y', 'y', 'x'), ('y', 'y', 'y'), ('x', 'x', 'z'), ('x', 'y', 'z'), ('y', 'x', 'z'), ('y', 'y', 'z'), ('x', 'z', 'x'), ('x', 'z', 'y'), ('y', 'z', 'x'), ('y', 'z', 'y'), ('x', 'z', 'z'), ('y', 'z', 'z'), ('z', 'x', 'x'), ('z', 'x', 'y'), ], ); exhaustive_triples_1_input_helper( &exhaustive_ascii_chars(), None, &[ ('a', 'a', 'a'), ('a', 'a', 'b'), ('a', 'b', 'a'), ('a', 'b', 'b'), ('b', 'a', 'a'), ('b', 'a', 'b'), ('b', 'b', 'a'), ('b', 'b', 'b'), ('a', 'a', 'c'), ('a', 'a', 'd'), ('a', 'b', 'c'), ('a', 'b', 'd'), ('b', 'a', 'c'), ('b', 'a', 'd'), ('b', 'b', 'c'), ('b', 'b', 'd'), ('a', 'c', 'a'), ('a', 'c', 'b'), ('a', 'd', 'a'), ('a', 'd', 'b'), ], ); } malachite-base-0.4.16/tests/tuples/exhaustive/exhaustive_tuples_custom_output.rs000064400000000000000000000236361046102023000265710ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::extra_variadic::exhaustive_triples_from_single; use crate::get_sample_output_types; use itertools::Itertools; use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::nevers::nevers; use malachite_base::num::exhaustive::exhaustive_unsigneds; use malachite_base::options::exhaustive::exhaustive_somes; use malachite_base::orderings::exhaustive::exhaustive_orderings; use malachite_base::tuples::exhaustive::{ exhaustive_pairs, exhaustive_pairs_custom_output, exhaustive_pairs_from_single, exhaustive_triples, exhaustive_triples_custom_output, }; use std::cmp::Ordering::*; use std::fmt::Debug; use std::iter::once; #[allow(clippy::needless_pass_by_value)] fn exhaustive_pairs_helper< X: Clone + Debug + Eq, I: Clone + Iterator, Y: Clone + Debug + Eq, J: Clone + Iterator, >( xs: I, ys: J, out_len: usize, out: &[(X, Y)], ) { let ps = exhaustive_pairs(xs.clone(), ys.clone()); assert_eq!(ps.clone().take(20).collect_vec(), out); assert_eq!(ps.count(), out_len); let output_types = get_sample_output_types(2); let ps = exhaustive_pairs_custom_output( xs.clone(), ys.clone(), output_types[0][0], output_types[0][1], ); assert_eq!(ps.clone().take(20).collect_vec(), out); assert_eq!(ps.count(), out_len); for alt_output_types in &output_types[1..] { let ps = exhaustive_pairs_custom_output( xs.clone(), ys.clone(), alt_output_types[0], alt_output_types[1], ); ps.clone().take(20).for_each(drop); assert_eq!(ps.count(), out_len); } } #[test] fn test_exhaustive_pairs_and_exhaustive_pairs_custom_output() { exhaustive_pairs_helper(nevers(), nevers(), 0, &[]); exhaustive_pairs_helper(nevers(), 0..4, 0, &[]); exhaustive_pairs_helper(once('a'), once(1), 1, &[('a', 1)]); exhaustive_pairs_helper( once('a'), 0..4, 4, &[('a', 0), ('a', 1), ('a', 2), ('a', 3)], ); exhaustive_pairs_helper( exhaustive_unsigneds::(), 'a'..'e', 1024, &[ (0, 'a'), (0, 'b'), (1, 'a'), (1, 'b'), (0, 'c'), (0, 'd'), (1, 'c'), (1, 'd'), (2, 'a'), (2, 'b'), (3, 'a'), (3, 'b'), (2, 'c'), (2, 'd'), (3, 'c'), (3, 'd'), (4, 'a'), (4, 'b'), (5, 'a'), (5, 'b'), ], ); exhaustive_pairs_helper( exhaustive_bools(), 0..4, 8, &[ (false, 0), (false, 1), (true, 0), (true, 1), (false, 2), (false, 3), (true, 2), (true, 3), ], ); exhaustive_pairs_helper( 'a'..'f', 0..3, 15, &[ ('a', 0), ('a', 1), ('b', 0), ('b', 1), ('a', 2), ('b', 2), ('c', 0), ('c', 1), ('d', 0), ('d', 1), ('c', 2), ('d', 2), ('e', 0), ('e', 1), ('e', 2), ], ); exhaustive_pairs_helper( ['a', 'b', 'c'].iter().copied(), exhaustive_orderings(), 9, &[ ('a', Equal), ('a', Less), ('b', Equal), ('b', Less), ('a', Greater), ('b', Greater), ('c', Equal), ('c', Less), ('c', Greater), ], ); exhaustive_pairs_helper( exhaustive_pairs(exhaustive_orderings(), exhaustive_bools()), exhaustive_triples_from_single([Less, Greater].iter().copied()), 48, &[ ((Equal, false), (Less, Less, Less)), ((Equal, false), (Less, Less, Greater)), ((Equal, true), (Less, Less, Less)), ((Equal, true), (Less, Less, Greater)), ((Equal, false), (Less, Greater, Less)), ((Equal, false), (Less, Greater, Greater)), ((Equal, true), (Less, Greater, Less)), ((Equal, true), (Less, Greater, Greater)), ((Less, false), (Less, Less, Less)), ((Less, false), (Less, Less, Greater)), ((Less, true), (Less, Less, Less)), ((Less, true), (Less, Less, Greater)), ((Less, false), (Less, Greater, Less)), ((Less, false), (Less, Greater, Greater)), ((Less, true), (Less, Greater, Less)), ((Less, true), (Less, Greater, Greater)), ((Equal, false), (Greater, Less, Less)), ((Equal, false), (Greater, Less, Greater)), ((Equal, true), (Greater, Less, Less)), ((Equal, true), (Greater, Less, Greater)), ], ); } #[allow(clippy::needless_pass_by_value)] fn exhaustive_triples_helper< X: Clone + Debug + Eq, I: Clone + Iterator, Y: Clone + Debug + Eq, J: Clone + Iterator, Z: Clone + Debug + Eq, K: Clone + Iterator, >( xs: I, ys: J, zs: K, out_len: usize, out: &[(X, Y, Z)], ) { let ts = exhaustive_triples(xs.clone(), ys.clone(), zs.clone()); assert_eq!(ts.clone().take(20).collect_vec(), out); assert_eq!(ts.count(), out_len); let output_types = get_sample_output_types(3); let ts = exhaustive_triples_custom_output( xs.clone(), ys.clone(), zs.clone(), output_types[0][0], output_types[0][1], output_types[0][2], ); assert_eq!(ts.clone().take(20).collect_vec(), out); assert_eq!(ts.count(), out_len); for alt_output_types in &output_types[1..] { let ts = exhaustive_triples_custom_output( xs.clone(), ys.clone(), zs.clone(), alt_output_types[0], alt_output_types[1], alt_output_types[2], ); ts.clone().take(20).for_each(drop); assert_eq!(ts.count(), out_len); } } #[test] fn test_exhaustive_triples_and_exhaustive_triples_custom_output() { exhaustive_triples_helper(nevers(), nevers(), nevers(), 0, &[]); exhaustive_triples_helper(nevers(), 0..4, 'a'..'f', 0, &[]); exhaustive_triples_helper(once('a'), once(false), once(5), 1, &[('a', false, 5)]); exhaustive_triples_helper( once('a'), once(false), 0..4, 4, &[('a', false, 0), ('a', false, 1), ('a', false, 2), ('a', false, 3)], ); exhaustive_triples_helper( exhaustive_unsigneds::(), exhaustive_pairs_from_single(exhaustive_bools()), 'a'..'e', 4096, &[ (0, (false, false), 'a'), (0, (false, false), 'b'), (0, (false, true), 'a'), (0, (false, true), 'b'), (1, (false, false), 'a'), (1, (false, false), 'b'), (1, (false, true), 'a'), (1, (false, true), 'b'), (0, (false, false), 'c'), (0, (false, false), 'd'), (0, (false, true), 'c'), (0, (false, true), 'd'), (1, (false, false), 'c'), (1, (false, false), 'd'), (1, (false, true), 'c'), (1, (false, true), 'd'), (0, (true, false), 'a'), (0, (true, false), 'b'), (0, (true, true), 'a'), (0, (true, true), 'b'), ], ); exhaustive_triples_helper( exhaustive_bools(), 0..3, 'a'..'d', 18, &[ (false, 0, 'a'), (false, 0, 'b'), (false, 1, 'a'), (false, 1, 'b'), (true, 0, 'a'), (true, 0, 'b'), (true, 1, 'a'), (true, 1, 'b'), (false, 0, 'c'), (false, 1, 'c'), (true, 0, 'c'), (true, 1, 'c'), (false, 2, 'a'), (false, 2, 'b'), (true, 2, 'a'), (true, 2, 'b'), (false, 2, 'c'), (true, 2, 'c'), ], ); exhaustive_triples_helper( 0..11, exhaustive_somes(0..12), 'a'..'n', 1716, &[ (0, Some(0), 'a'), (0, Some(0), 'b'), (0, Some(1), 'a'), (0, Some(1), 'b'), (1, Some(0), 'a'), (1, Some(0), 'b'), (1, Some(1), 'a'), (1, Some(1), 'b'), (0, Some(0), 'c'), (0, Some(0), 'd'), (0, Some(1), 'c'), (0, Some(1), 'd'), (1, Some(0), 'c'), (1, Some(0), 'd'), (1, Some(1), 'c'), (1, Some(1), 'd'), (0, Some(2), 'a'), (0, Some(2), 'b'), (0, Some(3), 'a'), (0, Some(3), 'b'), ], ); exhaustive_triples_helper( ['a', 'b', 'c'].iter().copied(), ["xx", "yy", "zz"].iter().copied(), 0..3, 27, &[ ('a', "xx", 0), ('a', "xx", 1), ('a', "yy", 0), ('a', "yy", 1), ('b', "xx", 0), ('b', "xx", 1), ('b', "yy", 0), ('b', "yy", 1), ('a', "xx", 2), ('a', "yy", 2), ('b', "xx", 2), ('b', "yy", 2), ('a', "zz", 0), ('a', "zz", 1), ('b', "zz", 0), ('b', "zz", 1), ('a', "zz", 2), ('b', "zz", 2), ('c', "xx", 0), ('c', "xx", 1), ], ); } malachite-base-0.4.16/tests/tuples/exhaustive/exhaustive_tuples_from_single.rs000064400000000000000000000207331046102023000261360ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::extra_variadic::{ exhaustive_octuples_from_single, exhaustive_quadruples_from_single, exhaustive_quintuples_from_single, exhaustive_triples_from_single, }; use itertools::Itertools; use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::num::exhaustive::exhaustive_unsigneds; use malachite_base::tuples::exhaustive::{exhaustive_pairs_from_single, exhaustive_units}; use std::fmt::Debug; macro_rules! helpers { ($t: ty, $ts: ident, $ts_helper: ident, $ts_small_helper: ident) => { fn $ts_helper(xs: I, out: &[$t]) where I::Item: Clone + Debug + Eq, { let ts = $ts(xs).take(20).collect_vec(); assert_eq!(ts.as_slice(), out); } fn $ts_small_helper(xs: I, out_len: usize, out: &[$t]) where I::Item: Clone + Debug + Eq, { let ts = $ts(xs); let ts_prefix = ts.clone().take(20).collect_vec(); assert_eq!(ts_prefix.as_slice(), out); assert_eq!(ts.count(), out_len); } }; } helpers!( (I::Item, I::Item), exhaustive_pairs_from_single, exhaustive_pairs_from_single_helper, exhaustive_pairs_from_single_small_helper ); helpers!( (I::Item, I::Item, I::Item), exhaustive_triples_from_single, exhaustive_triples_from_single_helper, _exhaustive_triples_from_single_small_helper ); helpers!( (I::Item, I::Item, I::Item, I::Item), exhaustive_quadruples_from_single, _exhaustive_quadruples_from_single_helper, exhaustive_quadruples_from_single_small_helper ); helpers!( (I::Item, I::Item, I::Item, I::Item, I::Item), exhaustive_quintuples_from_single, _exhaustive_quintuples_from_single_helper, exhaustive_quintuples_from_single_small_helper ); helpers!( ( I::Item, I::Item, I::Item, I::Item, I::Item, I::Item, I::Item, I::Item ), exhaustive_octuples_from_single, _exhaustive_octuples_from_single_helper, exhaustive_octuples_from_single_small_helper ); #[test] fn test_exhaustive_tuples_from_single() { exhaustive_pairs_from_single_small_helper(nevers(), 0, &[]); exhaustive_quintuples_from_single_small_helper(nevers(), 0, &[]); exhaustive_pairs_from_single_small_helper(exhaustive_units(), 1, &[((), ())]); exhaustive_quintuples_from_single_small_helper(exhaustive_units(), 1, &[((), (), (), (), ())]); exhaustive_pairs_from_single_helper( exhaustive_unsigneds::(), &[ (0, 0), (0, 1), (1, 0), (1, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 0), (2, 1), (3, 0), (3, 1), (2, 2), (2, 3), (3, 2), (3, 3), (0, 4), (0, 5), (1, 4), (1, 5), ], ); exhaustive_triples_from_single_helper( exhaustive_unsigneds::(), &[ (0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1), (1, 0, 0), (1, 0, 1), (1, 1, 0), (1, 1, 1), (0, 0, 2), (0, 0, 3), (0, 1, 2), (0, 1, 3), (1, 0, 2), (1, 0, 3), (1, 1, 2), (1, 1, 3), (0, 2, 0), (0, 2, 1), (0, 3, 0), (0, 3, 1), ], ); exhaustive_pairs_from_single_small_helper( exhaustive_ascii_chars(), 0x4000, &[ ('a', 'a'), ('a', 'b'), ('b', 'a'), ('b', 'b'), ('a', 'c'), ('a', 'd'), ('b', 'c'), ('b', 'd'), ('c', 'a'), ('c', 'b'), ('d', 'a'), ('d', 'b'), ('c', 'c'), ('c', 'd'), ('d', 'c'), ('d', 'd'), ('a', 'e'), ('a', 'f'), ('b', 'e'), ('b', 'f'), ], ); exhaustive_pairs_from_single_small_helper( exhaustive_bools(), 4, &[(false, false), (false, true), (true, false), (true, true)], ); exhaustive_quadruples_from_single_small_helper( exhaustive_bools(), 16, &[ (false, false, false, false), (false, false, false, true), (false, false, true, false), (false, false, true, true), (false, true, false, false), (false, true, false, true), (false, true, true, false), (false, true, true, true), (true, false, false, false), (true, false, false, true), (true, false, true, false), (true, false, true, true), (true, true, false, false), (true, true, false, true), (true, true, true, false), (true, true, true, true), ], ); exhaustive_octuples_from_single_small_helper( exhaustive_bools(), 256, &[ (false, false, false, false, false, false, false, false), (false, false, false, false, false, false, false, true), (false, false, false, false, false, false, true, false), (false, false, false, false, false, false, true, true), (false, false, false, false, false, true, false, false), (false, false, false, false, false, true, false, true), (false, false, false, false, false, true, true, false), (false, false, false, false, false, true, true, true), (false, false, false, false, true, false, false, false), (false, false, false, false, true, false, false, true), (false, false, false, false, true, false, true, false), (false, false, false, false, true, false, true, true), (false, false, false, false, true, true, false, false), (false, false, false, false, true, true, false, true), (false, false, false, false, true, true, true, false), (false, false, false, false, true, true, true, true), (false, false, false, true, false, false, false, false), (false, false, false, true, false, false, false, true), (false, false, false, true, false, false, true, false), (false, false, false, true, false, false, true, true), ], ); exhaustive_octuples_from_single_small_helper( 0..3, 6561, &[ (0, 0, 0, 0, 0, 0, 0, 0), (0, 0, 0, 0, 0, 0, 0, 1), (0, 0, 0, 0, 0, 0, 1, 0), (0, 0, 0, 0, 0, 0, 1, 1), (0, 0, 0, 0, 0, 1, 0, 0), (0, 0, 0, 0, 0, 1, 0, 1), (0, 0, 0, 0, 0, 1, 1, 0), (0, 0, 0, 0, 0, 1, 1, 1), (0, 0, 0, 0, 1, 0, 0, 0), (0, 0, 0, 0, 1, 0, 0, 1), (0, 0, 0, 0, 1, 0, 1, 0), (0, 0, 0, 0, 1, 0, 1, 1), (0, 0, 0, 0, 1, 1, 0, 0), (0, 0, 0, 0, 1, 1, 0, 1), (0, 0, 0, 0, 1, 1, 1, 0), (0, 0, 0, 0, 1, 1, 1, 1), (0, 0, 0, 1, 0, 0, 0, 0), (0, 0, 0, 1, 0, 0, 0, 1), (0, 0, 0, 1, 0, 0, 1, 0), (0, 0, 0, 1, 0, 0, 1, 1), ], ); exhaustive_pairs_from_single_helper( exhaustive_pairs_from_single(exhaustive_unsigneds::()), &[ ((0, 0), (0, 0)), ((0, 0), (0, 1)), ((0, 1), (0, 0)), ((0, 1), (0, 1)), ((0, 0), (1, 0)), ((0, 0), (1, 1)), ((0, 1), (1, 0)), ((0, 1), (1, 1)), ((1, 0), (0, 0)), ((1, 0), (0, 1)), ((1, 1), (0, 0)), ((1, 1), (0, 1)), ((1, 0), (1, 0)), ((1, 0), (1, 1)), ((1, 1), (1, 0)), ((1, 1), (1, 1)), ((0, 0), (0, 2)), ((0, 0), (0, 3)), ((0, 1), (0, 2)), ((0, 1), (0, 3)), ], ); } malachite-base-0.4.16/tests/tuples/exhaustive/exhaustive_unique_tuples.rs000064400000000000000000000114731046102023000251410ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::extra_variadic::{ exhaustive_unique_quadruples, exhaustive_unique_quintuples, exhaustive_unique_triples, }; use itertools::Itertools; use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::num::exhaustive::exhaustive_unsigneds; use malachite_base::tuples::exhaustive::{exhaustive_unique_pairs, exhaustive_units}; use std::fmt::Debug; macro_rules! helpers { ($t: ty, $ts: ident, $ts_helper: ident, $ts_small_helper: ident) => { fn $ts_helper(xs: I, out: &[$t]) where I::Item: Clone + Debug + Eq, { let ts = $ts(xs).take(20).collect_vec(); assert_eq!(ts.as_slice(), out); } fn $ts_small_helper(xs: I, out_len: usize, out: &[$t]) where I::Item: Clone + Debug + Eq, { let ts = $ts(xs); let ts_prefix = ts.clone().take(20).collect_vec(); assert_eq!(ts_prefix.as_slice(), out); assert_eq!(ts.count(), out_len); } }; } helpers!( (I::Item, I::Item), exhaustive_unique_pairs, _exhaustive_unique_pairs_helper, exhaustive_unique_pairs_small_helper ); helpers!( (I::Item, I::Item, I::Item), exhaustive_unique_triples, exhaustive_unique_triples_helper, _exhaustive_unique_triples_small_helper ); helpers!( (I::Item, I::Item, I::Item, I::Item), exhaustive_unique_quadruples, _exhaustive_unique_quadruples_helper, exhaustive_unique_quadruples_small_helper ); helpers!( (I::Item, I::Item, I::Item, I::Item, I::Item), exhaustive_unique_quintuples, _exhaustive_unique_quintuples_helper, exhaustive_unique_quintuples_small_helper ); #[test] fn test_exhaustive_unique_tuples() { exhaustive_unique_pairs_small_helper(nevers(), 0, &[]); exhaustive_unique_quintuples_small_helper(nevers(), 0, &[]); exhaustive_unique_pairs_small_helper(exhaustive_units(), 0, &[]); exhaustive_unique_quintuples_small_helper(exhaustive_units(), 0, &[]); exhaustive_unique_pairs_small_helper( exhaustive_unsigneds::(), 65280, &[ (0, 1), (1, 0), (0, 2), (2, 0), (1, 2), (2, 1), (0, 3), (3, 0), (1, 3), (3, 1), (2, 3), (3, 2), (0, 4), (4, 0), (1, 4), (4, 1), (2, 4), (4, 2), (3, 4), (4, 3), ], ); exhaustive_unique_triples_helper( exhaustive_unsigneds::(), &[ (0, 1, 2), (0, 1, 3), (0, 2, 1), (0, 2, 3), (1, 0, 2), (0, 3, 1), (1, 2, 0), (1, 2, 3), (2, 0, 1), (1, 0, 3), (2, 1, 0), (0, 3, 2), (1, 3, 0), (2, 0, 3), (3, 0, 1), (0, 2, 4), (3, 1, 0), (2, 3, 0), (3, 0, 2), (0, 1, 4), ], ); exhaustive_unique_pairs_small_helper( exhaustive_ascii_chars(), 16256, &[ ('a', 'b'), ('b', 'a'), ('a', 'c'), ('c', 'a'), ('b', 'c'), ('c', 'b'), ('a', 'd'), ('d', 'a'), ('b', 'd'), ('d', 'b'), ('c', 'd'), ('d', 'c'), ('a', 'e'), ('e', 'a'), ('b', 'e'), ('e', 'b'), ('c', 'e'), ('e', 'c'), ('d', 'e'), ('e', 'd'), ], ); exhaustive_unique_pairs_small_helper(exhaustive_bools(), 2, &[(false, true), (true, false)]); exhaustive_unique_quadruples_small_helper( 1..=6, 360, &[ (1, 2, 3, 4), (1, 2, 3, 5), (1, 2, 4, 3), (1, 2, 4, 5), (1, 3, 2, 4), (1, 2, 5, 3), (1, 3, 4, 2), (1, 3, 4, 5), (1, 4, 2, 3), (1, 3, 2, 5), (1, 4, 3, 2), (1, 2, 5, 4), (2, 1, 3, 4), (1, 3, 5, 2), (2, 1, 4, 3), (2, 3, 4, 5), (2, 3, 1, 4), (1, 5, 2, 3), (2, 3, 4, 1), (1, 4, 2, 5), ], ); } malachite-base-0.4.16/tests/tuples/exhaustive/exhaustive_units.rs000064400000000000000000000010551046102023000233740ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::tuples::exhaustive::exhaustive_units; #[test] fn test_exhaustive_units() { assert_eq!(exhaustive_units().collect_vec(), &[()]); } malachite-base-0.4.16/tests/tuples/exhaustive/lex_custom_tuples.rs000064400000000000000000000250341046102023000235460ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::extra_variadic::{lex_triples_from_single, lex_triples_xxy, lex_triples_xyx}; use itertools::Itertools; use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::nevers::nevers; use malachite_base::num::exhaustive::exhaustive_unsigneds; use malachite_base::orderings::exhaustive::exhaustive_orderings; use malachite_base::tuples::exhaustive::lex_pairs; use std::cmp::Ordering::*; use std::fmt::Debug; use std::iter::once; fn lex_triples_xxy_helper< X: Clone + Debug + Eq, I: Clone + Iterator, Y: Clone + Debug + Eq, J: Clone + Iterator, >( xs: I, ys: J, out_len: usize, out: &[(X, X, Y)], ) { let ts = lex_triples_xxy(xs, ys); let ts_prefix = ts.clone().take(20).collect_vec(); assert_eq!(ts_prefix.as_slice(), out); assert_eq!(ts.count(), out_len); } #[test] fn test_lex_triples_xxy() { lex_triples_xxy_helper(nevers(), nevers(), 0, &[]); lex_triples_xxy_helper(nevers(), 0..4, 0, &[]); lex_triples_xxy_helper(once('a'), once(1), 1, &[('a', 'a', 1)]); lex_triples_xxy_helper( once('a'), 0..4, 4, &[('a', 'a', 0), ('a', 'a', 1), ('a', 'a', 2), ('a', 'a', 3)], ); lex_triples_xxy_helper( exhaustive_unsigneds::(), 'a'..'e', 1 << 18, &[ (0, 0, 'a'), (0, 0, 'b'), (0, 0, 'c'), (0, 0, 'd'), (0, 1, 'a'), (0, 1, 'b'), (0, 1, 'c'), (0, 1, 'd'), (0, 2, 'a'), (0, 2, 'b'), (0, 2, 'c'), (0, 2, 'd'), (0, 3, 'a'), (0, 3, 'b'), (0, 3, 'c'), (0, 3, 'd'), (0, 4, 'a'), (0, 4, 'b'), (0, 4, 'c'), (0, 4, 'd'), ], ); lex_triples_xxy_helper( exhaustive_bools(), 0..4, 16, &[ (false, false, 0), (false, false, 1), (false, false, 2), (false, false, 3), (false, true, 0), (false, true, 1), (false, true, 2), (false, true, 3), (true, false, 0), (true, false, 1), (true, false, 2), (true, false, 3), (true, true, 0), (true, true, 1), (true, true, 2), (true, true, 3), ], ); lex_triples_xxy_helper( 'a'..'f', 0..3, 75, &[ ('a', 'a', 0), ('a', 'a', 1), ('a', 'a', 2), ('a', 'b', 0), ('a', 'b', 1), ('a', 'b', 2), ('a', 'c', 0), ('a', 'c', 1), ('a', 'c', 2), ('a', 'd', 0), ('a', 'd', 1), ('a', 'd', 2), ('a', 'e', 0), ('a', 'e', 1), ('a', 'e', 2), ('b', 'a', 0), ('b', 'a', 1), ('b', 'a', 2), ('b', 'b', 0), ('b', 'b', 1), ], ); lex_triples_xxy_helper( ['a', 'b', 'c'].iter().copied(), exhaustive_orderings(), 27, &[ ('a', 'a', Equal), ('a', 'a', Less), ('a', 'a', Greater), ('a', 'b', Equal), ('a', 'b', Less), ('a', 'b', Greater), ('a', 'c', Equal), ('a', 'c', Less), ('a', 'c', Greater), ('b', 'a', Equal), ('b', 'a', Less), ('b', 'a', Greater), ('b', 'b', Equal), ('b', 'b', Less), ('b', 'b', Greater), ('b', 'c', Equal), ('b', 'c', Less), ('b', 'c', Greater), ('c', 'a', Equal), ('c', 'a', Less), ], ); lex_triples_xxy_helper( lex_pairs(exhaustive_orderings(), exhaustive_bools()), lex_triples_from_single([Less, Greater].iter().copied()), 288, &[ ((Equal, false), (Equal, false), (Less, Less, Less)), ((Equal, false), (Equal, false), (Less, Less, Greater)), ((Equal, false), (Equal, false), (Less, Greater, Less)), ((Equal, false), (Equal, false), (Less, Greater, Greater)), ((Equal, false), (Equal, false), (Greater, Less, Less)), ((Equal, false), (Equal, false), (Greater, Less, Greater)), ((Equal, false), (Equal, false), (Greater, Greater, Less)), ((Equal, false), (Equal, false), (Greater, Greater, Greater)), ((Equal, false), (Equal, true), (Less, Less, Less)), ((Equal, false), (Equal, true), (Less, Less, Greater)), ((Equal, false), (Equal, true), (Less, Greater, Less)), ((Equal, false), (Equal, true), (Less, Greater, Greater)), ((Equal, false), (Equal, true), (Greater, Less, Less)), ((Equal, false), (Equal, true), (Greater, Less, Greater)), ((Equal, false), (Equal, true), (Greater, Greater, Less)), ((Equal, false), (Equal, true), (Greater, Greater, Greater)), ((Equal, false), (Less, false), (Less, Less, Less)), ((Equal, false), (Less, false), (Less, Less, Greater)), ((Equal, false), (Less, false), (Less, Greater, Less)), ((Equal, false), (Less, false), (Less, Greater, Greater)), ], ); } fn lex_triples_xyx_helper< X: Clone + Debug + Eq, I: Clone + Iterator, Y: Clone + Debug + Eq, J: Clone + Iterator, >( xs: I, ys: J, out_len: usize, out: &[(X, Y, X)], ) { let ts = lex_triples_xyx(xs, ys); let ts_prefix = ts.clone().take(20).collect_vec(); assert_eq!(ts_prefix.as_slice(), out); assert_eq!(ts.count(), out_len); } #[test] fn test_lex_triples_xyx() { lex_triples_xyx_helper(nevers(), nevers(), 0, &[]); lex_triples_xyx_helper(nevers(), 0..4, 0, &[]); lex_triples_xyx_helper(once('a'), once(1), 1, &[('a', 1, 'a')]); lex_triples_xyx_helper( once('a'), 0..4, 4, &[('a', 0, 'a'), ('a', 1, 'a'), ('a', 2, 'a'), ('a', 3, 'a')], ); lex_triples_xyx_helper( exhaustive_unsigneds::(), 'a'..'e', 1 << 18, &[ (0, 'a', 0), (0, 'a', 1), (0, 'a', 2), (0, 'a', 3), (0, 'a', 4), (0, 'a', 5), (0, 'a', 6), (0, 'a', 7), (0, 'a', 8), (0, 'a', 9), (0, 'a', 10), (0, 'a', 11), (0, 'a', 12), (0, 'a', 13), (0, 'a', 14), (0, 'a', 15), (0, 'a', 16), (0, 'a', 17), (0, 'a', 18), (0, 'a', 19), ], ); lex_triples_xyx_helper( exhaustive_bools(), 0..4, 16, &[ (false, 0, false), (false, 0, true), (false, 1, false), (false, 1, true), (false, 2, false), (false, 2, true), (false, 3, false), (false, 3, true), (true, 0, false), (true, 0, true), (true, 1, false), (true, 1, true), (true, 2, false), (true, 2, true), (true, 3, false), (true, 3, true), ], ); lex_triples_xyx_helper( 'a'..'f', 0..3, 75, &[ ('a', 0, 'a'), ('a', 0, 'b'), ('a', 0, 'c'), ('a', 0, 'd'), ('a', 0, 'e'), ('a', 1, 'a'), ('a', 1, 'b'), ('a', 1, 'c'), ('a', 1, 'd'), ('a', 1, 'e'), ('a', 2, 'a'), ('a', 2, 'b'), ('a', 2, 'c'), ('a', 2, 'd'), ('a', 2, 'e'), ('b', 0, 'a'), ('b', 0, 'b'), ('b', 0, 'c'), ('b', 0, 'd'), ('b', 0, 'e'), ], ); lex_triples_xyx_helper( ['a', 'b', 'c'].iter().copied(), exhaustive_orderings(), 27, &[ ('a', Equal, 'a'), ('a', Equal, 'b'), ('a', Equal, 'c'), ('a', Less, 'a'), ('a', Less, 'b'), ('a', Less, 'c'), ('a', Greater, 'a'), ('a', Greater, 'b'), ('a', Greater, 'c'), ('b', Equal, 'a'), ('b', Equal, 'b'), ('b', Equal, 'c'), ('b', Less, 'a'), ('b', Less, 'b'), ('b', Less, 'c'), ('b', Greater, 'a'), ('b', Greater, 'b'), ('b', Greater, 'c'), ('c', Equal, 'a'), ('c', Equal, 'b'), ], ); lex_triples_xyx_helper( lex_pairs(exhaustive_orderings(), exhaustive_bools()), lex_triples_from_single([Less, Greater].iter().copied()), 288, &[ ((Equal, false), (Less, Less, Less), (Equal, false)), ((Equal, false), (Less, Less, Less), (Equal, true)), ((Equal, false), (Less, Less, Less), (Less, false)), ((Equal, false), (Less, Less, Less), (Less, true)), ((Equal, false), (Less, Less, Less), (Greater, false)), ((Equal, false), (Less, Less, Less), (Greater, true)), ((Equal, false), (Less, Less, Greater), (Equal, false)), ((Equal, false), (Less, Less, Greater), (Equal, true)), ((Equal, false), (Less, Less, Greater), (Less, false)), ((Equal, false), (Less, Less, Greater), (Less, true)), ((Equal, false), (Less, Less, Greater), (Greater, false)), ((Equal, false), (Less, Less, Greater), (Greater, true)), ((Equal, false), (Less, Greater, Less), (Equal, false)), ((Equal, false), (Less, Greater, Less), (Equal, true)), ((Equal, false), (Less, Greater, Less), (Less, false)), ((Equal, false), (Less, Greater, Less), (Less, true)), ((Equal, false), (Less, Greater, Less), (Greater, false)), ((Equal, false), (Less, Greater, Less), (Greater, true)), ((Equal, false), (Less, Greater, Greater), (Equal, false)), ((Equal, false), (Less, Greater, Greater), (Equal, true)), ], ); } malachite-base-0.4.16/tests/tuples/exhaustive/lex_dependent_pairs.rs000064400000000000000000000120211046102023000237740ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use core::hash::Hash; use itertools::{chain, Itertools}; use malachite_base::tuples::exhaustive::{ lex_dependent_pairs, lex_dependent_pairs_stop_after_empty_ys, ExhaustiveDependentPairsYsGenerator, }; use std::collections::HashMap; use std::fmt::Debug; use std::iter::{once, repeat, Cloned}; use std::slice::Iter; #[derive(Clone, Debug)] struct DPGeneratorFromMap { map: HashMap, } impl ExhaustiveDependentPairsYsGenerator>> for DPGeneratorFromMap { #[inline] fn get_ys(&self, x: &X) -> Cloned> { self.map[x].iter().cloned() } } fn lex_dependent_pairs_helper( xs: I, map: HashMap, out: &[(I::Item, Y)], ) where I::Item: Clone + Debug + Eq + Hash, Y: Clone + Debug + Eq, { let xss = lex_dependent_pairs(xs, DPGeneratorFromMap { map }) .take(20) .collect_vec(); assert_eq!(xss.as_slice(), out); } #[test] fn test_lex_dependent_pairs() { lex_dependent_pairs_helper( [1, 2, 3].iter().copied(), hashmap! { 1 => &[100, 101, 102][..], 2 => &[200, 201, 202][..], 3 => &[300, 301, 302][..] }, &[(1, 100), (1, 101), (1, 102), (2, 200), (2, 201), (2, 202), (3, 300), (3, 301), (3, 302)], ); lex_dependent_pairs_helper( ["cat", "dog", "mouse", "dog", "cat"].iter().copied(), hashmap! { "cat" => &[2, 3, 4][..], "dog" => &[20][..], "mouse" => &[30, 40][..] }, &[ ("cat", 2), ("cat", 3), ("cat", 4), ("dog", 20), ("mouse", 30), ("mouse", 40), ("dog", 20), ("cat", 2), ("cat", 3), ("cat", 4), ], ); lex_dependent_pairs_helper( [1, 2, 3, 2, 3, 2, 2].iter().copied(), hashmap! { 1 => &[100, 101, 102][..], 2 => &[][..], 3 => &[300, 301, 302][..] }, &[(1, 100), (1, 101), (1, 102), (3, 300), (3, 301), (3, 302), (3, 300), (3, 301), (3, 302)], ); lex_dependent_pairs_helper( [].iter().copied(), hashmap! { 1 => &[100, 101, 102][..], 2 => &[][..], 3 => &[300, 301, 302][..] }, &[], ); lex_dependent_pairs_helper( [2, 2, 2, 2, 2].iter().copied(), hashmap! { 1 => &[100, 101, 102][..], 2 => &[][..], 3 => &[300, 301, 302][..] }, &[], ); } fn lex_dependent_pairs_stop_after_empty_ys_helper( xs: I, map: HashMap, out: &[(I::Item, Y)], ) where I::Item: Clone + Debug + Eq + Hash, Y: Clone + Debug + Eq, { let xss = lex_dependent_pairs_stop_after_empty_ys(xs, DPGeneratorFromMap { map }) .take(20) .collect_vec(); assert_eq!(xss.as_slice(), out); } #[test] fn test_lex_dependent_pairs_stop_after_empty_ys() { lex_dependent_pairs_stop_after_empty_ys_helper( [1, 2, 3].iter().copied(), hashmap! { 1 => &[100, 101, 102][..], 2 => &[200, 201, 202][..], 3 => &[300, 301, 302][..] }, &[(1, 100), (1, 101), (1, 102), (2, 200), (2, 201), (2, 202), (3, 300), (3, 301), (3, 302)], ); lex_dependent_pairs_stop_after_empty_ys_helper( ["cat", "dog", "mouse", "dog", "cat"].iter().copied(), hashmap! { "cat" => &[2, 3, 4][..], "dog" => &[20][..], "mouse" => &[30, 40][..] }, &[ ("cat", 2), ("cat", 3), ("cat", 4), ("dog", 20), ("mouse", 30), ("mouse", 40), ("dog", 20), ("cat", 2), ("cat", 3), ("cat", 4), ], ); // Notice difference from `lex_dependent_pairs` lex_dependent_pairs_stop_after_empty_ys_helper( [1, 2, 3, 2, 3, 2, 2].iter().copied(), hashmap! { 1 => &[100, 101, 102][..], 2 => &[][..], 3 => &[300, 301, 302][..] }, &[(1, 100), (1, 101), (1, 102)], ); lex_dependent_pairs_stop_after_empty_ys_helper( [].iter().copied(), hashmap! { 1 => &[100, 101, 102][..], 2 => &[][..], 3 => &[300, 301, 302][..] }, &[], ); lex_dependent_pairs_stop_after_empty_ys_helper( [2, 2, 2, 2, 2].iter().copied(), hashmap! { 1 => &[100, 101, 102][..], 2 => &[][..], 3 => &[300, 301, 302][..] }, &[], ); // With `lex_dependent_pairs` this would hang lex_dependent_pairs_stop_after_empty_ys_helper( chain(once(3), repeat(2)), hashmap! { 1 => &[100, 101, 102][..], 2 => &[][..], 3 => &[300, 301, 302][..] }, &[(3, 300), (3, 301), (3, 302)], ); } malachite-base-0.4.16/tests/tuples/exhaustive/lex_ordered_unique_tuples.rs000064400000000000000000000113311046102023000252410ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::extra_variadic::{ lex_ordered_unique_quadruples, lex_ordered_unique_quintuples, lex_ordered_unique_triples, }; use itertools::Itertools; use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::num::exhaustive::exhaustive_unsigneds; use malachite_base::tuples::exhaustive::{exhaustive_units, lex_ordered_unique_pairs}; use std::fmt::Debug; macro_rules! helpers { ($t: ty, $ts: ident, $ts_helper: ident, $ts_small_helper: ident) => { fn $ts_helper(xs: I, out: &[$t]) where I::Item: Clone + Debug + Eq, { let ts = $ts(xs).take(20).collect_vec(); assert_eq!(ts.as_slice(), out); } fn $ts_small_helper(xs: I, out_len: usize, out: &[$t]) where I::Item: Clone + Debug + Eq, { let ts = $ts(xs); let ts_prefix = ts.clone().take(20).collect_vec(); assert_eq!(ts_prefix.as_slice(), out); assert_eq!(ts.count(), out_len); } }; } helpers!( (I::Item, I::Item), lex_ordered_unique_pairs, _lex_ordered_unique_pairs_helper, lex_ordered_unique_pairs_small_helper ); helpers!( (I::Item, I::Item, I::Item), lex_ordered_unique_triples, lex_ordered_unique_triples_helper, _lex_ordered_unique_triples_small_helper ); helpers!( (I::Item, I::Item, I::Item, I::Item), lex_ordered_unique_quadruples, _lex_ordered_unique_quadruples_helper, lex_ordered_unique_quadruples_small_helper ); helpers!( (I::Item, I::Item, I::Item, I::Item, I::Item), lex_ordered_unique_quintuples, _lex_ordered_unique_quintuples_helper, lex_ordered_unique_quintuples_small_helper ); #[test] fn test_lex_ordered_unique_tuples() { lex_ordered_unique_pairs_small_helper(nevers(), 0, &[]); lex_ordered_unique_quintuples_small_helper(nevers(), 0, &[]); lex_ordered_unique_pairs_small_helper(exhaustive_units(), 0, &[]); lex_ordered_unique_quintuples_small_helper(exhaustive_units(), 0, &[]); lex_ordered_unique_pairs_small_helper( exhaustive_unsigneds::(), 32640, &[ (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7), (0, 8), (0, 9), (0, 10), (0, 11), (0, 12), (0, 13), (0, 14), (0, 15), (0, 16), (0, 17), (0, 18), (0, 19), (0, 20), ], ); lex_ordered_unique_triples_helper( exhaustive_unsigneds::(), &[ (0, 1, 2), (0, 1, 3), (0, 1, 4), (0, 1, 5), (0, 1, 6), (0, 1, 7), (0, 1, 8), (0, 1, 9), (0, 1, 10), (0, 1, 11), (0, 1, 12), (0, 1, 13), (0, 1, 14), (0, 1, 15), (0, 1, 16), (0, 1, 17), (0, 1, 18), (0, 1, 19), (0, 1, 20), (0, 1, 21), ], ); lex_ordered_unique_pairs_small_helper( exhaustive_ascii_chars(), 8128, &[ ('a', 'b'), ('a', 'c'), ('a', 'd'), ('a', 'e'), ('a', 'f'), ('a', 'g'), ('a', 'h'), ('a', 'i'), ('a', 'j'), ('a', 'k'), ('a', 'l'), ('a', 'm'), ('a', 'n'), ('a', 'o'), ('a', 'p'), ('a', 'q'), ('a', 'r'), ('a', 's'), ('a', 't'), ('a', 'u'), ], ); lex_ordered_unique_pairs_small_helper(exhaustive_bools(), 1, &[(false, true)]); lex_ordered_unique_quadruples_small_helper( 1..=6, 15, &[ (1, 2, 3, 4), (1, 2, 3, 5), (1, 2, 3, 6), (1, 2, 4, 5), (1, 2, 4, 6), (1, 2, 5, 6), (1, 3, 4, 5), (1, 3, 4, 6), (1, 3, 5, 6), (1, 4, 5, 6), (2, 3, 4, 5), (2, 3, 4, 6), (2, 3, 5, 6), (2, 4, 5, 6), (3, 4, 5, 6), ], ); } malachite-base-0.4.16/tests/tuples/exhaustive/lex_tuples.rs000064400000000000000000000203321046102023000221500ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::extra_variadic::{lex_triples, lex_triples_from_single}; use itertools::Itertools; use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::nevers::nevers; use malachite_base::num::exhaustive::exhaustive_unsigneds; use malachite_base::options::exhaustive::exhaustive_somes; use malachite_base::orderings::exhaustive::exhaustive_orderings; use malachite_base::tuples::exhaustive::{lex_pairs, lex_pairs_from_single}; use std::cmp::Ordering::*; use std::fmt::Debug; use std::iter::once; fn lex_pairs_helper< X: Clone + Debug + Eq, I: Clone + Iterator, Y: Clone + Debug + Eq, J: Clone + Iterator, >( xs: I, ys: J, out_len: usize, out: &[(X, Y)], ) { let ps = lex_pairs(xs, ys); let ps_prefix = ps.clone().take(20).collect_vec(); assert_eq!(ps_prefix.as_slice(), out); assert_eq!(ps.count(), out_len); } #[test] fn test_lex_pairs() { lex_pairs_helper(nevers(), nevers(), 0, &[]); lex_pairs_helper(nevers(), 0..4, 0, &[]); lex_pairs_helper(once('a'), once(1), 1, &[('a', 1)]); lex_pairs_helper( once('a'), 0..4, 4, &[('a', 0), ('a', 1), ('a', 2), ('a', 3)], ); lex_pairs_helper( exhaustive_unsigneds::(), 'a'..'e', 1024, &[ (0, 'a'), (0, 'b'), (0, 'c'), (0, 'd'), (1, 'a'), (1, 'b'), (1, 'c'), (1, 'd'), (2, 'a'), (2, 'b'), (2, 'c'), (2, 'd'), (3, 'a'), (3, 'b'), (3, 'c'), (3, 'd'), (4, 'a'), (4, 'b'), (4, 'c'), (4, 'd'), ], ); lex_pairs_helper( exhaustive_bools(), 0..4, 8, &[ (false, 0), (false, 1), (false, 2), (false, 3), (true, 0), (true, 1), (true, 2), (true, 3), ], ); lex_pairs_helper( 'a'..'f', 0..3, 15, &[ ('a', 0), ('a', 1), ('a', 2), ('b', 0), ('b', 1), ('b', 2), ('c', 0), ('c', 1), ('c', 2), ('d', 0), ('d', 1), ('d', 2), ('e', 0), ('e', 1), ('e', 2), ], ); lex_pairs_helper( ['a', 'b', 'c'].iter().copied(), exhaustive_orderings(), 9, &[ ('a', Equal), ('a', Less), ('a', Greater), ('b', Equal), ('b', Less), ('b', Greater), ('c', Equal), ('c', Less), ('c', Greater), ], ); lex_pairs_helper( lex_pairs(exhaustive_orderings(), exhaustive_bools()), lex_triples_from_single([Less, Greater].iter().copied()), 48, &[ ((Equal, false), (Less, Less, Less)), ((Equal, false), (Less, Less, Greater)), ((Equal, false), (Less, Greater, Less)), ((Equal, false), (Less, Greater, Greater)), ((Equal, false), (Greater, Less, Less)), ((Equal, false), (Greater, Less, Greater)), ((Equal, false), (Greater, Greater, Less)), ((Equal, false), (Greater, Greater, Greater)), ((Equal, true), (Less, Less, Less)), ((Equal, true), (Less, Less, Greater)), ((Equal, true), (Less, Greater, Less)), ((Equal, true), (Less, Greater, Greater)), ((Equal, true), (Greater, Less, Less)), ((Equal, true), (Greater, Less, Greater)), ((Equal, true), (Greater, Greater, Less)), ((Equal, true), (Greater, Greater, Greater)), ((Less, false), (Less, Less, Less)), ((Less, false), (Less, Less, Greater)), ((Less, false), (Less, Greater, Less)), ((Less, false), (Less, Greater, Greater)), ], ); } fn lex_triples_helper< X: Clone + Debug + Eq, I: Clone + Iterator, Y: Clone + Debug + Eq, J: Clone + Iterator, Z: Clone + Debug + Eq, K: Clone + Iterator, >( xs: I, ys: J, zs: K, out_len: usize, out: &[(X, Y, Z)], ) { let ts = lex_triples(xs, ys, zs); let ts_prefix = ts.clone().take(20).collect_vec(); assert_eq!(ts_prefix.as_slice(), out); assert_eq!(ts.count(), out_len); } #[test] fn test_lex_triples() { lex_triples_helper(nevers(), nevers(), nevers(), 0, &[]); lex_triples_helper(nevers(), 0..4, 'a'..'f', 0, &[]); lex_triples_helper(once('a'), once(false), once(5), 1, &[('a', false, 5)]); lex_triples_helper( once('a'), once(false), 0..4, 4, &[('a', false, 0), ('a', false, 1), ('a', false, 2), ('a', false, 3)], ); lex_triples_helper( exhaustive_unsigneds::(), lex_pairs_from_single(exhaustive_bools()), 'a'..'e', 4096, &[ (0, (false, false), 'a'), (0, (false, false), 'b'), (0, (false, false), 'c'), (0, (false, false), 'd'), (0, (false, true), 'a'), (0, (false, true), 'b'), (0, (false, true), 'c'), (0, (false, true), 'd'), (0, (true, false), 'a'), (0, (true, false), 'b'), (0, (true, false), 'c'), (0, (true, false), 'd'), (0, (true, true), 'a'), (0, (true, true), 'b'), (0, (true, true), 'c'), (0, (true, true), 'd'), (1, (false, false), 'a'), (1, (false, false), 'b'), (1, (false, false), 'c'), (1, (false, false), 'd'), ], ); lex_triples_helper( exhaustive_bools(), 0..3, 'a'..'d', 18, &[ (false, 0, 'a'), (false, 0, 'b'), (false, 0, 'c'), (false, 1, 'a'), (false, 1, 'b'), (false, 1, 'c'), (false, 2, 'a'), (false, 2, 'b'), (false, 2, 'c'), (true, 0, 'a'), (true, 0, 'b'), (true, 0, 'c'), (true, 1, 'a'), (true, 1, 'b'), (true, 1, 'c'), (true, 2, 'a'), (true, 2, 'b'), (true, 2, 'c'), ], ); lex_triples_helper( 0..11, exhaustive_somes(0..12), 'a'..'n', 1716, &[ (0, Some(0), 'a'), (0, Some(0), 'b'), (0, Some(0), 'c'), (0, Some(0), 'd'), (0, Some(0), 'e'), (0, Some(0), 'f'), (0, Some(0), 'g'), (0, Some(0), 'h'), (0, Some(0), 'i'), (0, Some(0), 'j'), (0, Some(0), 'k'), (0, Some(0), 'l'), (0, Some(0), 'm'), (0, Some(1), 'a'), (0, Some(1), 'b'), (0, Some(1), 'c'), (0, Some(1), 'd'), (0, Some(1), 'e'), (0, Some(1), 'f'), (0, Some(1), 'g'), ], ); lex_triples_helper( ['a', 'b', 'c'].iter().copied(), ["xx", "yy", "zz"].iter().copied(), 0..3, 27, &[ ('a', "xx", 0), ('a', "xx", 1), ('a', "xx", 2), ('a', "yy", 0), ('a', "yy", 1), ('a', "yy", 2), ('a', "zz", 0), ('a', "zz", 1), ('a', "zz", 2), ('b', "xx", 0), ('b', "xx", 1), ('b', "xx", 2), ('b', "yy", 0), ('b', "yy", 1), ('b', "yy", 2), ('b', "zz", 0), ('b', "zz", 1), ('b', "zz", 2), ('c', "xx", 0), ('c', "xx", 1), ], ); } malachite-base-0.4.16/tests/tuples/exhaustive/lex_tuples_from_single.rs000064400000000000000000000204131046102023000245340ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::extra_variadic::{ lex_octuples_from_single, lex_quadruples_from_single, lex_quintuples_from_single, lex_triples_from_single, }; use itertools::Itertools; use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::num::exhaustive::exhaustive_unsigneds; use malachite_base::tuples::exhaustive::{exhaustive_units, lex_pairs_from_single}; use std::fmt::Debug; macro_rules! helpers { ($t: ty, $ts: ident, $ts_helper: ident, $ts_small_helper: ident) => { fn $ts_helper(xs: I, out: &[$t]) where I::Item: Clone + Debug + Eq, { let ts = $ts(xs).take(20).collect_vec(); assert_eq!(ts.as_slice(), out); } fn $ts_small_helper(xs: I, out_len: usize, out: &[$t]) where I::Item: Clone + Debug + Eq, { let ts = $ts(xs); let ts_prefix = ts.clone().take(20).collect_vec(); assert_eq!(ts_prefix.as_slice(), out); assert_eq!(ts.count(), out_len); } }; } helpers!( (I::Item, I::Item), lex_pairs_from_single, lex_pairs_from_single_helper, lex_pairs_from_single_small_helper ); helpers!( (I::Item, I::Item, I::Item), lex_triples_from_single, lex_triples_from_single_helper, _lex_triples_from_single_small_helper ); helpers!( (I::Item, I::Item, I::Item, I::Item), lex_quadruples_from_single, _lex_quadruples_from_single_helper, lex_quadruples_from_single_small_helper ); helpers!( (I::Item, I::Item, I::Item, I::Item, I::Item), lex_quintuples_from_single, _lex_quintuples_from_single_helper, lex_quintuples_from_single_small_helper ); helpers!( ( I::Item, I::Item, I::Item, I::Item, I::Item, I::Item, I::Item, I::Item ), lex_octuples_from_single, _lex_octuples_from_single_helper, lex_octuples_from_single_small_helper ); #[test] fn test_lex_tuples_from_single() { lex_pairs_from_single_small_helper(nevers(), 0, &[]); lex_quintuples_from_single_small_helper(nevers(), 0, &[]); lex_pairs_from_single_small_helper(exhaustive_units(), 1, &[((), ())]); lex_quintuples_from_single_small_helper(exhaustive_units(), 1, &[((), (), (), (), ())]); lex_pairs_from_single_helper( exhaustive_unsigneds::(), &[ (0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7), (0, 8), (0, 9), (0, 10), (0, 11), (0, 12), (0, 13), (0, 14), (0, 15), (0, 16), (0, 17), (0, 18), (0, 19), ], ); lex_triples_from_single_helper( exhaustive_unsigneds::(), &[ (0, 0, 0), (0, 0, 1), (0, 0, 2), (0, 0, 3), (0, 0, 4), (0, 0, 5), (0, 0, 6), (0, 0, 7), (0, 0, 8), (0, 0, 9), (0, 0, 10), (0, 0, 11), (0, 0, 12), (0, 0, 13), (0, 0, 14), (0, 0, 15), (0, 0, 16), (0, 0, 17), (0, 0, 18), (0, 0, 19), ], ); lex_pairs_from_single_small_helper( exhaustive_ascii_chars(), 0x4000, &[ ('a', 'a'), ('a', 'b'), ('a', 'c'), ('a', 'd'), ('a', 'e'), ('a', 'f'), ('a', 'g'), ('a', 'h'), ('a', 'i'), ('a', 'j'), ('a', 'k'), ('a', 'l'), ('a', 'm'), ('a', 'n'), ('a', 'o'), ('a', 'p'), ('a', 'q'), ('a', 'r'), ('a', 's'), ('a', 't'), ], ); lex_pairs_from_single_small_helper( exhaustive_bools(), 4, &[(false, false), (false, true), (true, false), (true, true)], ); lex_quadruples_from_single_small_helper( exhaustive_bools(), 16, &[ (false, false, false, false), (false, false, false, true), (false, false, true, false), (false, false, true, true), (false, true, false, false), (false, true, false, true), (false, true, true, false), (false, true, true, true), (true, false, false, false), (true, false, false, true), (true, false, true, false), (true, false, true, true), (true, true, false, false), (true, true, false, true), (true, true, true, false), (true, true, true, true), ], ); lex_octuples_from_single_small_helper( exhaustive_bools(), 256, &[ (false, false, false, false, false, false, false, false), (false, false, false, false, false, false, false, true), (false, false, false, false, false, false, true, false), (false, false, false, false, false, false, true, true), (false, false, false, false, false, true, false, false), (false, false, false, false, false, true, false, true), (false, false, false, false, false, true, true, false), (false, false, false, false, false, true, true, true), (false, false, false, false, true, false, false, false), (false, false, false, false, true, false, false, true), (false, false, false, false, true, false, true, false), (false, false, false, false, true, false, true, true), (false, false, false, false, true, true, false, false), (false, false, false, false, true, true, false, true), (false, false, false, false, true, true, true, false), (false, false, false, false, true, true, true, true), (false, false, false, true, false, false, false, false), (false, false, false, true, false, false, false, true), (false, false, false, true, false, false, true, false), (false, false, false, true, false, false, true, true), ], ); lex_octuples_from_single_small_helper( 0..3, 6561, &[ (0, 0, 0, 0, 0, 0, 0, 0), (0, 0, 0, 0, 0, 0, 0, 1), (0, 0, 0, 0, 0, 0, 0, 2), (0, 0, 0, 0, 0, 0, 1, 0), (0, 0, 0, 0, 0, 0, 1, 1), (0, 0, 0, 0, 0, 0, 1, 2), (0, 0, 0, 0, 0, 0, 2, 0), (0, 0, 0, 0, 0, 0, 2, 1), (0, 0, 0, 0, 0, 0, 2, 2), (0, 0, 0, 0, 0, 1, 0, 0), (0, 0, 0, 0, 0, 1, 0, 1), (0, 0, 0, 0, 0, 1, 0, 2), (0, 0, 0, 0, 0, 1, 1, 0), (0, 0, 0, 0, 0, 1, 1, 1), (0, 0, 0, 0, 0, 1, 1, 2), (0, 0, 0, 0, 0, 1, 2, 0), (0, 0, 0, 0, 0, 1, 2, 1), (0, 0, 0, 0, 0, 1, 2, 2), (0, 0, 0, 0, 0, 2, 0, 0), (0, 0, 0, 0, 0, 2, 0, 1), ], ); lex_pairs_from_single_helper( lex_pairs_from_single(exhaustive_unsigneds::()), &[ ((0, 0), (0, 0)), ((0, 0), (0, 1)), ((0, 0), (0, 2)), ((0, 0), (0, 3)), ((0, 0), (0, 4)), ((0, 0), (0, 5)), ((0, 0), (0, 6)), ((0, 0), (0, 7)), ((0, 0), (0, 8)), ((0, 0), (0, 9)), ((0, 0), (0, 10)), ((0, 0), (0, 11)), ((0, 0), (0, 12)), ((0, 0), (0, 13)), ((0, 0), (0, 14)), ((0, 0), (0, 15)), ((0, 0), (0, 16)), ((0, 0), (0, 17)), ((0, 0), (0, 18)), ((0, 0), (0, 19)), ], ); } malachite-base-0.4.16/tests/tuples/exhaustive/lex_unique_tuples.rs000064400000000000000000000112251046102023000235370ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::extra_variadic::{lex_unique_quadruples, lex_unique_quintuples, lex_unique_triples}; use itertools::Itertools; use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::num::exhaustive::exhaustive_unsigneds; use malachite_base::tuples::exhaustive::{exhaustive_units, lex_unique_pairs}; use std::fmt::Debug; macro_rules! helpers { ($t: ty, $ts: ident, $ts_helper: ident, $ts_small_helper: ident) => { fn $ts_helper(xs: I, out: &[$t]) where I::Item: Clone + Debug + Eq, { let ts = $ts(xs).take(20).collect_vec(); assert_eq!(ts.as_slice(), out); } fn $ts_small_helper(xs: I, out_len: usize, out: &[$t]) where I::Item: Clone + Debug + Eq, { let ts = $ts(xs); let ts_prefix = ts.clone().take(20).collect_vec(); assert_eq!(ts_prefix.as_slice(), out); assert_eq!(ts.count(), out_len); } }; } helpers!( (I::Item, I::Item), lex_unique_pairs, _lex_unique_pairs_helper, lex_unique_pairs_small_helper ); helpers!( (I::Item, I::Item, I::Item), lex_unique_triples, lex_unique_triples_helper, _lex_unique_triples_small_helper ); helpers!( (I::Item, I::Item, I::Item, I::Item), lex_unique_quadruples, _lex_unique_quadruples_helper, lex_unique_quadruples_small_helper ); helpers!( (I::Item, I::Item, I::Item, I::Item, I::Item), lex_unique_quintuples, _lex_unique_quintuples_helper, lex_unique_quintuples_small_helper ); #[test] fn test_lex_unique_tuples() { lex_unique_pairs_small_helper(nevers(), 0, &[]); lex_unique_quintuples_small_helper(nevers(), 0, &[]); lex_unique_pairs_small_helper(exhaustive_units(), 0, &[]); lex_unique_quintuples_small_helper(exhaustive_units(), 0, &[]); lex_unique_pairs_small_helper( exhaustive_unsigneds::(), 65280, &[ (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7), (0, 8), (0, 9), (0, 10), (0, 11), (0, 12), (0, 13), (0, 14), (0, 15), (0, 16), (0, 17), (0, 18), (0, 19), (0, 20), ], ); lex_unique_triples_helper( exhaustive_unsigneds::(), &[ (0, 1, 2), (0, 1, 3), (0, 1, 4), (0, 1, 5), (0, 1, 6), (0, 1, 7), (0, 1, 8), (0, 1, 9), (0, 1, 10), (0, 1, 11), (0, 1, 12), (0, 1, 13), (0, 1, 14), (0, 1, 15), (0, 1, 16), (0, 1, 17), (0, 1, 18), (0, 1, 19), (0, 1, 20), (0, 1, 21), ], ); lex_unique_pairs_small_helper( exhaustive_ascii_chars(), 16256, &[ ('a', 'b'), ('a', 'c'), ('a', 'd'), ('a', 'e'), ('a', 'f'), ('a', 'g'), ('a', 'h'), ('a', 'i'), ('a', 'j'), ('a', 'k'), ('a', 'l'), ('a', 'm'), ('a', 'n'), ('a', 'o'), ('a', 'p'), ('a', 'q'), ('a', 'r'), ('a', 's'), ('a', 't'), ('a', 'u'), ], ); lex_unique_pairs_small_helper(exhaustive_bools(), 2, &[(false, true), (true, false)]); lex_unique_quadruples_small_helper( 1..=6, 360, &[ (1, 2, 3, 4), (1, 2, 3, 5), (1, 2, 3, 6), (1, 2, 4, 3), (1, 2, 4, 5), (1, 2, 4, 6), (1, 2, 5, 3), (1, 2, 5, 4), (1, 2, 5, 6), (1, 2, 6, 3), (1, 2, 6, 4), (1, 2, 6, 5), (1, 3, 2, 4), (1, 3, 2, 5), (1, 3, 2, 6), (1, 3, 4, 2), (1, 3, 4, 5), (1, 3, 4, 6), (1, 3, 5, 2), (1, 3, 5, 4), ], ); } malachite-base-0.4.16/tests/tuples/random/random_custom_tuples.rs000064400000000000000000000207431046102023000233330ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::extra_variadic::{random_triples_from_single, random_triples_xxy, random_triples_xyx}; use core::hash::Hash; use itertools::Itertools; use malachite_base::bools::random::random_bools; use malachite_base::num::random::random_primitive_ints; use malachite_base::random::{Seed, EXAMPLE_SEED}; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; use malachite_base::tuples::random::random_pairs_from_single; use std::fmt::Debug; #[allow(clippy::type_complexity)] fn random_triples_xxy_helper< X: Clone + Debug + Eq + Hash + Ord, I: Clone + Iterator, Y: Clone + Debug + Eq + Hash + Ord, J: Clone + Iterator, >( xs_gen: &dyn Fn(Seed) -> I, ys_gen: &dyn Fn(Seed) -> J, expected_values: &[(X, X, Y)], expected_common_values: &[((X, X, Y), usize)], expected_median: ((X, X, Y), Option<(X, X, Y)>), ) { let xs = random_triples_xxy(EXAMPLE_SEED, xs_gen, ys_gen); let values = xs.clone().take(20).collect_vec(); let common_values = common_values_map_debug(1000000, 10, xs.clone()); let median = median(xs.take(1000000)); assert_eq!( (values.as_slice(), common_values.as_slice(), median), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_random_triples_xxy() { random_triples_xxy_helper( &random_primitive_ints::, &random_bools, &[ (85, 11, false), (136, 200, true), (235, 134, false), (203, 223, false), (38, 235, false), (217, 177, true), (162, 32, true), (166, 234, false), (30, 218, false), (90, 106, false), (9, 216, false), (204, 151, true), (213, 97, false), (253, 78, true), (91, 39, false), (191, 175, true), (170, 232, false), (233, 2, true), (35, 22, true), (217, 198, false), ], &[ ((87, 70, false), 23), ((36, 187, false), 23), ((228, 249, false), 22), ((130, 73, true), 20), ((67, 187, true), 20), ((89, 216, true), 20), ((132, 195, true), 20), ((145, 23, false), 20), ((24, 126, false), 20), ((146, 106, false), 20), ], ((127, 197, true), None), ); random_triples_xxy_helper( &|seed| random_pairs_from_single(random_primitive_ints::(seed)), &|seed| random_triples_from_single(random_primitive_ints::(seed)), &[ ((85, 11), (136, 200), (98, -88, -58)), ((235, 134), (203, 223), (40, 20, -4)), ((38, 235), (217, 177), (47, 87, -124)), ((162, 32), (166, 234), (72, 77, 63)), ((30, 218), (90, 106), (91, 108, 127)), ((9, 216), (204, 151), (53, -115, 84)), ((213, 97), (253, 78), (18, 10, 112)), ((91, 39), (191, 175), (-102, 104, 53)), ((170, 232), (233, 2), (75, -18, -107)), ((35, 22), (217, 198), (-66, 51, -109)), ((114, 17), (32, 173), (100, 114, -116)), ((114, 65), (121, 222), (2, 63, -67)), ((173, 25), (144, 148), (-34, 67, 119)), ((79, 115), (52, 73), (0, -33, 5)), ((69, 137), (91, 153), (-20, -24, 50)), ((178, 112), (34, 95), (44, -15, 21)), ((106, 167), (197, 130), (22, 94, 27)), ((168, 122), (207, 172), (-128, -36, 25)), ((177, 86), (150, 221), (-5, -13, 50)), ((218, 101), (115, 74), (-119, -21, 46)), ], &[ (((8, 24), (5, 3), (0, 54, 59)), 1), (((8, 72), (11, 57), (6, 5, 9)), 1), (((80, 9), (9, 5), (84, 9, 10)), 1), (((86, 2), (49, 4), (2, 0, 27)), 1), (((0, 2), (92, 5), (-49, 31, 7)), 1), (((1, 15), (12, 5), (51, 5, 47)), 1), (((1, 25), (3, 66), (70, 65, 7)), 1), (((1, 72), (2, 1), (8, 49, -10)), 1), (((1, 82), (6, 26), (86, 3, 70)), 1), (((1, 85), (14, 92), (3, 5, 53)), 1), ], ( ((128, 20), (243, 155), (-90, 7, -77)), Some(((128, 21), (19, 63), (52, 113, -21))), ), ); } #[allow(clippy::type_complexity)] fn random_triples_xyx_helper< X: Clone + Debug + Eq + Hash + Ord, I: Clone + Iterator, Y: Clone + Debug + Eq + Hash + Ord, J: Clone + Iterator, >( xs_gen: &dyn Fn(Seed) -> I, ys_gen: &dyn Fn(Seed) -> J, expected_values: &[(X, Y, X)], expected_common_values: &[((X, Y, X), usize)], expected_median: ((X, Y, X), Option<(X, Y, X)>), ) { let xs = random_triples_xyx(EXAMPLE_SEED, xs_gen, ys_gen); let values = xs.clone().take(20).collect_vec(); let common_values = common_values_map_debug(1000000, 10, xs.clone()); let median = median(xs.take(1000000)); assert_eq!( (values.as_slice(), common_values.as_slice(), median), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_random_triples_xyx() { random_triples_xyx_helper( &random_primitive_ints::, &random_bools, &[ (85, false, 11), (136, true, 200), (235, false, 134), (203, false, 223), (38, false, 235), (217, true, 177), (162, true, 32), (166, false, 234), (30, false, 218), (90, false, 106), (9, false, 216), (204, true, 151), (213, false, 97), (253, true, 78), (91, false, 39), (191, true, 175), (170, false, 232), (233, true, 2), (35, true, 22), (217, false, 198), ], &[ ((87, false, 70), 23), ((36, false, 187), 23), ((228, false, 249), 22), ((130, true, 73), 20), ((67, true, 187), 20), ((89, true, 216), 20), ((132, true, 195), 20), ((145, false, 23), 20), ((24, false, 126), 20), ((146, false, 106), 20), ], ((127, true, 141), None), ); random_triples_xyx_helper( &|seed| random_pairs_from_single(random_primitive_ints::(seed)), &|seed| random_triples_from_single(random_primitive_ints::(seed)), &[ ((85, 11), (98, -88, -58), (136, 200)), ((235, 134), (40, 20, -4), (203, 223)), ((38, 235), (47, 87, -124), (217, 177)), ((162, 32), (72, 77, 63), (166, 234)), ((30, 218), (91, 108, 127), (90, 106)), ((9, 216), (53, -115, 84), (204, 151)), ((213, 97), (18, 10, 112), (253, 78)), ((91, 39), (-102, 104, 53), (191, 175)), ((170, 232), (75, -18, -107), (233, 2)), ((35, 22), (-66, 51, -109), (217, 198)), ((114, 17), (100, 114, -116), (32, 173)), ((114, 65), (2, 63, -67), (121, 222)), ((173, 25), (-34, 67, 119), (144, 148)), ((79, 115), (0, -33, 5), (52, 73)), ((69, 137), (-20, -24, 50), (91, 153)), ((178, 112), (44, -15, 21), (34, 95)), ((106, 167), (22, 94, 27), (197, 130)), ((168, 122), (-128, -36, 25), (207, 172)), ((177, 86), (-5, -13, 50), (150, 221)), ((218, 101), (-119, -21, 46), (115, 74)), ], &[ (((8, 24), (0, 54, 59), (5, 3)), 1), (((8, 72), (6, 5, 9), (11, 57)), 1), (((80, 9), (84, 9, 10), (9, 5)), 1), (((86, 2), (2, 0, 27), (49, 4)), 1), (((0, 2), (-49, 31, 7), (92, 5)), 1), (((1, 15), (51, 5, 47), (12, 5)), 1), (((1, 25), (70, 65, 7), (3, 66)), 1), (((1, 72), (8, 49, -10), (2, 1)), 1), (((1, 82), (86, 3, 70), (6, 26)), 1), (((1, 85), (3, 5, 53), (14, 92)), 1), ], ( ((128, 20), (118, 50, 18), (55, 110)), Some(((128, 21), (-107, 66, -82), (216, 142))), ), ); } malachite-base-0.4.16/tests/tuples/random/random_ordered_unique_tuples.rs000064400000000000000000000112041046102023000250230ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::extra_variadic::random_ordered_unique_triples; use core::hash::Hash; use itertools::Itertools; use malachite_base::num::random::random_primitive_ints; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; use malachite_base::tuples::random::random_ordered_unique_pairs; use std::fmt::Debug; #[allow(clippy::type_complexity)] fn random_ordered_unique_pairs_helper( xs: I, expected_values: &[(I::Item, I::Item)], expected_common_values: &[((I::Item, I::Item), usize)], expected_median: ((I::Item, I::Item), Option<(I::Item, I::Item)>), ) where I::Item: Clone + Debug + Eq + Hash + Ord, { let xs = random_ordered_unique_pairs(xs); let values = xs.clone().take(20).collect_vec(); let common_values = common_values_map_debug(1000000, 10, xs.clone()); let median = median(xs.take(1000000)); assert_eq!( (values.as_slice(), common_values.as_slice(), median), (expected_values, expected_common_values, expected_median) ); } #[allow(clippy::type_complexity)] fn random_ordered_unique_triples_helper( xs: I, expected_values: &[(I::Item, I::Item, I::Item)], expected_common_values: &[((I::Item, I::Item, I::Item), usize)], expected_median: ( (I::Item, I::Item, I::Item), Option<(I::Item, I::Item, I::Item)>, ), ) where I::Item: Clone + Debug + Eq + Hash + Ord, { let xs = random_ordered_unique_triples(xs); let values = xs.clone().take(20).collect_vec(); let common_values = common_values_map_debug(1000000, 10, xs.clone()); let median = median(xs.take(1000000)); assert_eq!( (values.as_slice(), common_values.as_slice(), median), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_random_ordered_unique_tuples() { random_ordered_unique_triples_helper( random_primitive_ints::(EXAMPLE_SEED), &[ (69, 113, 239), (108, 210, 228), (87, 161, 168), (32, 83, 110), (34, 89, 188), (93, 200, 238), (115, 149, 189), (149, 201, 217), (31, 117, 146), (72, 151, 169), (7, 33, 174), (38, 81, 144), (72, 113, 127), (107, 128, 233), (12, 46, 119), (18, 164, 243), (59, 114, 174), (39, 174, 247), (104, 160, 184), (37, 100, 252), ], &[ ((57, 142, 207), 7), ((32, 68, 169), 6), ((36, 70, 195), 6), ((125, 168, 194), 6), ((0, 97, 205), 5), ((2, 33, 227), 5), ((5, 46, 239), 5), ((9, 68, 189), 5), ((9, 78, 240), 5), ((1, 110, 203), 5), ], ((52, 133, 241), Some((52, 133, 242))), ); random_ordered_unique_pairs_helper( random_ordered_unique_pairs(random_primitive_ints::(EXAMPLE_SEED)), &[ ((69, 108), (113, 239)), ((161, 168), (210, 228)), ((32, 87), (83, 110)), ((34, 188), (89, 238)), ((93, 200), (115, 149)), ((149, 189), (201, 217)), ((31, 72), (117, 146)), ((33, 174), (151, 169)), ((7, 38), (81, 144)), ((72, 127), (113, 128)), ((46, 119), (107, 233)), ((12, 18), (164, 243)), ((59, 247), (114, 174)), ((39, 174), (160, 184)), ((37, 104), (100, 252)), ((69, 107), (122, 228)), ((142, 179), (242, 248)), ((61, 189), (233, 239)), ((7, 192), (85, 235)), ((90, 200), (178, 185)), ], &[ (((0, 78), (34, 52)), 2), (((1, 58), (6, 112)), 2), (((1, 63), (8, 154)), 2), (((1, 97), (7, 250)), 2), (((2, 33), (40, 81)), 2), (((3, 160), (7, 29)), 2), (((3, 32), (12, 60)), 2), (((6, 130), (7, 20)), 2), (((6, 68), (7, 126)), 2), (((6, 77), (36, 54)), 2), ], (((40, 193), (94, 142)), Some(((40, 193), (97, 243)))), ); } malachite-base-0.4.16/tests/tuples/random/random_tuples.rs000064400000000000000000000206301046102023000217340ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::extra_variadic::{random_triples, random_triples_from_single}; use core::hash::Hash; use itertools::Itertools; use malachite_base::bools::random::random_bools; use malachite_base::chars::random::random_ascii_chars; use malachite_base::num::random::geometric::geometric_random_signeds; use malachite_base::num::random::random_primitive_ints; use malachite_base::random::{Seed, EXAMPLE_SEED}; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; use malachite_base::tuples::random::{random_pairs, random_pairs_from_single}; use malachite_base::tuples::singletons; use std::fmt::Debug; fn random_pairs_helper< X: Clone + Debug + Eq + Hash + Ord, I: Clone + Iterator, Y: Clone + Debug + Eq + Hash + Ord, J: Clone + Iterator, >( xs_gen: &dyn Fn(Seed) -> I, ys_gen: &dyn Fn(Seed) -> J, expected_values: &[(X, Y)], expected_common_values: &[((X, Y), usize)], expected_median: ((X, Y), Option<(X, Y)>), ) { let xs = random_pairs(EXAMPLE_SEED, xs_gen, ys_gen); let values = xs.clone().take(20).collect_vec(); let common_values = common_values_map_debug(1000000, 10, xs.clone()); let median = median(xs.take(1000000)); assert_eq!( (values.as_slice(), common_values.as_slice(), median), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_random_pairs() { random_pairs_helper( &random_primitive_ints::, &random_bools, &[ (85, false), (11, true), (136, false), (200, false), (235, false), (134, true), (203, true), (223, false), (38, false), (235, false), (217, false), (177, true), (162, false), (32, true), (166, false), (234, true), (30, false), (218, true), (90, true), (106, false), ], &[ ((81, true), 2077), ((58, false), 2074), ((220, false), 2064), ((14, false), 2053), ((194, true), 2050), ((66, false), 2050), ((71, true), 2049), ((208, false), 2043), ((7, true), 2041), ((64, true), 2038), ], ((127, true), None), ); random_pairs_helper( &|seed| random_pairs_from_single(random_primitive_ints::(seed)), &|seed| random_triples_from_single(random_primitive_ints::(seed)), &[ ((85, 11), (98, -88, -58)), ((136, 200), (40, 20, -4)), ((235, 134), (47, 87, -124)), ((203, 223), (72, 77, 63)), ((38, 235), (91, 108, 127)), ((217, 177), (53, -115, 84)), ((162, 32), (18, 10, 112)), ((166, 234), (-102, 104, 53)), ((30, 218), (75, -18, -107)), ((90, 106), (-66, 51, -109)), ((9, 216), (100, 114, -116)), ((204, 151), (2, 63, -67)), ((213, 97), (-34, 67, 119)), ((253, 78), (0, -33, 5)), ((91, 39), (-20, -24, 50)), ((191, 175), (44, -15, 21)), ((170, 232), (22, 94, 27)), ((233, 2), (-128, -36, 25)), ((35, 22), (-5, -13, 50)), ((217, 198), (-119, -21, 46)), ], &[ (((0, 5), (6, 7, 42)), 1), (((8, 8), (18, 5, 6)), 1), (((9, 1), (5, 3, 23)), 1), (((0, 0), (97, 7, 73)), 1), (((0, 2), (12, 20, 6)), 1), (((0, 99), (20, 8, 6)), 1), (((1, 81), (3, 21, 3)), 1), (((1, 83), (-6, 8, 8)), 1), (((1, 9), (-37, 9, 7)), 1), (((1, 9), (4, 95, 15)), 1), ], ( ((127, 197), (-18, 55, -20)), Some(((127, 197), (-8, -68, 49))), ), ); } #[allow(clippy::type_complexity)] fn random_triples_helper< X: Clone + Debug + Eq + Hash + Ord, I: Clone + Iterator, Y: Clone + Debug + Eq + Hash + Ord, J: Clone + Iterator, Z: Clone + Debug + Eq + Hash + Ord, K: Clone + Iterator, >( xs_gen: &dyn Fn(Seed) -> I, ys_gen: &dyn Fn(Seed) -> J, zs_gen: &dyn Fn(Seed) -> K, expected_values: &[(X, Y, Z)], expected_common_values: &[((X, Y, Z), usize)], expected_median: ((X, Y, Z), Option<(X, Y, Z)>), ) { let xs = random_triples(EXAMPLE_SEED, xs_gen, ys_gen, zs_gen); let values = xs.clone().take(20).collect_vec(); let common_values = common_values_map_debug(1000000, 10, xs.clone()); let median = median(xs.take(1000000)); assert_eq!( (values.as_slice(), common_values.as_slice(), median), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_random_triples() { random_triples_helper( &random_primitive_ints::, &random_ascii_chars, &|seed| geometric_random_signeds::(seed, 10, 1), &[ (85, 'b', 0), (11, 'P', -6), (136, '\u{1a}', -6), (200, 'F', 8), (235, 'B', 0), (134, '\u{2}', -3), (203, '\u{7f}', -17), (223, '\u{17}', 2), (38, 'W', 0), (235, '\u{8}', 2), (217, '\"', 9), (177, 'j', -6), (162, 't', 20), (32, 'g', -20), (166, '\u{16}', 43), (234, '6', 9), (30, '\u{7f}', -7), (218, 'j', -16), (90, '4', -29), (106, '$', -2), ], &[ ((54, '*', -1), 9), ((252, '\u{c}', 0), 9), ((253, '\u{6}', 0), 9), ((4, '~', 0), 8), ((51, '1', 1), 8), ((131, '!', 1), 8), ((138, 'i', 1), 8), ((185, 'q', 1), 8), ((58, '?', -2), 8), ((225, 'k', -4), 8), ], ((127, 'x', -2), None), ); random_triples_helper( &|seed| singletons(random_bools(seed)), &|seed| random_pairs_from_single(random_primitive_ints::(seed)), &|seed| random_triples_from_single(random_ascii_chars(seed)), &[ ((true,), (98, 168), ('(', '\u{15}', 'h')), ((false,), (198, 40), ('\u{7f}', '%', '\u{7f}')), ((true,), (20, 252), ('\u{13}', '\u{2}', '+')), ((false,), (47, 87), ('\u{1b}', 'v', '\r')), ((true,), (132, 72), ('\u{1b}', '\u{15}', 'I')), ((false,), (77, 63), ('$', '\u{1a}', '}')), ((true,), (91, 108), ('(', '\u{e}', '1')), ((false,), (127, 53), ('$', '/', 'O')), ((true,), (141, 84), ('\u{1f}', 'Z', '>')), ((true,), (18, 10), ('}', '\u{13}', '\\')), ((false,), (112, 154), ('\u{1a}', '\u{14}', 't')), ((true,), (104, 53), (' ', '`', '\u{2}')), ((false,), (75, 238), ('\u{17}', 'a', '8')), ((false,), (149, 190), ('H', ']', '*')), ((false,), (51, 147), ('i', '2', '}')), ((false,), (100, 114), ('\u{3}', '\u{f}', '\u{7f}')), ((false,), (140, 2), ('\u{f}', 'Y', 'D')), ((false,), (63, 189), ('m', '\\', '8')), ((false,), (222, 67), ('M', '\u{7}', '8')), ((true,), (119, 0), ('\u{13}', '.', '\"')), ], &[ (((true,), (57, 9), ('R', '}', 'Q')), 2), (((true,), (233, 229), ('t', '\u{b}', 'Q')), 2), (((false,), (236, 203), ('b', '\u{e}', '\u{e}')), 2), (((true,), (0, 0), ('{', '{', '4')), 1), (((true,), (0, 2), ('-', 'S', '{')), 1), (((true,), (0, 2), ('N', 'E', '-')), 1), (((true,), (0, 2), ('O', '3', 'S')), 1), (((true,), (0, 3), ('"', '/', 'P')), 1), (((true,), (0, 3), (';', 'M', 'W')), 1), (((true,), (0, 3), ('i', ']', 'P')), 1), ], ( ((false,), (255, 175), ('g', '\u{1e}', '4')), Some(((false,), (255, 176), ('\u{10}', 's', '\''))), ), ); } malachite-base-0.4.16/tests/tuples/random/random_tuples_from_single.rs000064400000000000000000000111751046102023000243240ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::extra_variadic::random_triples_from_single; use core::hash::Hash; use itertools::Itertools; use malachite_base::num::random::random_primitive_ints; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; use malachite_base::tuples::random::random_pairs_from_single; use std::fmt::Debug; #[allow(clippy::type_complexity)] fn random_pairs_from_single_helper( xs: I, expected_values: &[(I::Item, I::Item)], expected_common_values: &[((I::Item, I::Item), usize)], expected_median: ((I::Item, I::Item), Option<(I::Item, I::Item)>), ) where I::Item: Clone + Debug + Eq + Hash + Ord, { let xs = random_pairs_from_single(xs); let values = xs.clone().take(20).collect_vec(); let common_values = common_values_map_debug(1000000, 10, xs.clone()); let median = median(xs.take(1000000)); assert_eq!( (values.as_slice(), common_values.as_slice(), median), (expected_values, expected_common_values, expected_median) ); } #[allow(clippy::type_complexity)] fn random_triples_from_single_helper( xs: I, expected_values: &[(I::Item, I::Item, I::Item)], expected_common_values: &[((I::Item, I::Item, I::Item), usize)], expected_median: ( (I::Item, I::Item, I::Item), Option<(I::Item, I::Item, I::Item)>, ), ) where I::Item: Clone + Debug + Eq + Hash + Ord, { let xs = random_triples_from_single(xs); let values = xs.clone().take(20).collect_vec(); let common_values = common_values_map_debug(1000000, 10, xs.clone()); let median = median(xs.take(1000000)); assert_eq!( (values.as_slice(), common_values.as_slice(), median), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_random_tuples_from_single() { random_triples_from_single_helper( random_primitive_ints::(EXAMPLE_SEED), &[ (113, 239, 69), (108, 228, 210), (168, 161, 87), (32, 110, 83), (188, 34, 89), (238, 93, 200), (149, 115, 189), (149, 217, 201), (117, 146, 31), (72, 151, 169), (174, 33, 7), (38, 81, 144), (72, 127, 113), (128, 233, 107), (46, 119, 12), (18, 164, 243), (114, 174, 59), (247, 39, 174), (160, 184, 104), (37, 100, 252), ], &[ ((222, 60, 79), 4), ((26, 110, 13), 4), ((41, 254, 55), 4), ((109, 134, 76), 4), ((165, 174, 73), 4), ((236, 57, 174), 4), ((73, 168, 192), 4), ((89, 197, 244), 4), ((91, 170, 115), 4), ((142, 168, 231), 4), ], ((127, 253, 76), Some((127, 253, 86))), ); random_pairs_from_single_helper( random_pairs_from_single(random_primitive_ints::(EXAMPLE_SEED)), &[ ((113, 239), (69, 108)), ((228, 210), (168, 161)), ((87, 32), (110, 83)), ((188, 34), (89, 238)), ((93, 200), (149, 115)), ((189, 149), (217, 201)), ((117, 146), (31, 72)), ((151, 169), (174, 33)), ((7, 38), (81, 144)), ((72, 127), (113, 128)), ((233, 107), (46, 119)), ((12, 18), (164, 243)), ((114, 174), (59, 247)), ((39, 174), (160, 184)), ((104, 37), (100, 252)), ((228, 122), (107, 69)), ((242, 248), (179, 142)), ((239, 233), (61, 189)), ((235, 85), (192, 7)), ((200, 90), (185, 178)), ], &[ (((28, 96), (0, 11)), 2), (((2, 43), (64, 233)), 2), (((20, 33), (14, 10)), 2), (((223, 84), (7, 22)), 2), (((43, 33), (131, 6)), 2), (((6, 233), (45, 89)), 2), (((65, 26), (6, 146)), 2), (((71, 80), (68, 88)), 2), (((9, 85), (186, 55)), 2), (((96, 254), (9, 37)), 2), ], (((127, 243), (125, 130)), Some(((127, 243), (134, 100)))), ); } malachite-base-0.4.16/tests/tuples/random/random_unique_tuples.rs000064400000000000000000000111061046102023000233200ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::extra_variadic::random_unique_triples; use core::hash::Hash; use itertools::Itertools; use malachite_base::num::random::random_primitive_ints; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; use malachite_base::tuples::random::random_unique_pairs; use std::fmt::Debug; #[allow(clippy::type_complexity)] fn random_unique_pairs_helper( xs: I, expected_values: &[(I::Item, I::Item)], expected_common_values: &[((I::Item, I::Item), usize)], expected_median: ((I::Item, I::Item), Option<(I::Item, I::Item)>), ) where I::Item: Clone + Debug + Eq + Hash + Ord, { let xs = random_unique_pairs(xs); let values = xs.clone().take(20).collect_vec(); let common_values = common_values_map_debug(1000000, 10, xs.clone()); let median = median(xs.take(1000000)); assert_eq!( (values.as_slice(), common_values.as_slice(), median), (expected_values, expected_common_values, expected_median) ); } #[allow(clippy::type_complexity)] fn random_unique_triples_helper( xs: I, expected_values: &[(I::Item, I::Item, I::Item)], expected_common_values: &[((I::Item, I::Item, I::Item), usize)], expected_median: ( (I::Item, I::Item, I::Item), Option<(I::Item, I::Item, I::Item)>, ), ) where I::Item: Clone + Debug + Eq + Hash + Ord, { let xs = random_unique_triples(xs); let values = xs.clone().take(20).collect_vec(); let common_values = common_values_map_debug(1000000, 10, xs.clone()); let median = median(xs.take(1000000)); assert_eq!( (values.as_slice(), common_values.as_slice(), median), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_random_unique_tuples() { random_unique_triples_helper( random_primitive_ints::(EXAMPLE_SEED), &[ (113, 239, 69), (108, 228, 210), (168, 161, 87), (32, 110, 83), (188, 34, 89), (238, 93, 200), (149, 115, 189), (149, 217, 201), (117, 146, 31), (72, 151, 169), (174, 33, 7), (38, 81, 144), (72, 127, 113), (128, 233, 107), (46, 119, 12), (18, 164, 243), (114, 174, 59), (247, 39, 174), (160, 184, 104), (37, 100, 252), ], &[ ((205, 0, 97), 4), ((102, 18, 19), 4), ((105, 70, 13), 4), ((22, 45, 192), 4), ((87, 100, 26), 4), ((15, 107, 109), 4), ((134, 245, 157), 4), ((138, 164, 179), 4), ((219, 253, 196), 4), ((237, 197, 239), 4), ], ((128, 16, 107), Some((128, 16, 116))), ); random_unique_pairs_helper( random_unique_pairs(random_primitive_ints::(EXAMPLE_SEED)), &[ ((113, 239), (69, 108)), ((228, 210), (168, 161)), ((87, 32), (110, 83)), ((188, 34), (89, 238)), ((93, 200), (149, 115)), ((189, 149), (217, 201)), ((117, 146), (31, 72)), ((151, 169), (174, 33)), ((7, 38), (81, 144)), ((72, 127), (113, 128)), ((233, 107), (46, 119)), ((12, 18), (164, 243)), ((114, 174), (59, 247)), ((39, 174), (160, 184)), ((104, 37), (100, 252)), ((228, 122), (107, 69)), ((242, 248), (179, 142)), ((239, 233), (61, 189)), ((235, 85), (192, 7)), ((200, 90), (185, 178)), ], &[ (((60, 12), (3, 32)), 2), (((0, 80), (88, 210)), 2), (((1, 3), (216, 183)), 2), (((159, 0), (69, 30)), 2), (((199, 6), (95, 79)), 2), (((2, 98), (221, 19)), 2), (((212, 65), (99, 2)), 2), (((3, 14), (61, 170)), 2), (((41, 155), (3, 72)), 2), (((47, 85), (69, 66)), 2), ], (((128, 41), (252, 44)), Some(((128, 42), (8, 241)))), ); } malachite-base-0.4.16/tests/tuples/random/random_units.rs000064400000000000000000000010521046102023000215570ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::tuples::random::random_units; #[test] fn test_random_units() { assert_eq!(random_units().take(20).collect_vec(), &[(); 20]); } malachite-base-0.4.16/tests/tuples/singletons.rs000064400000000000000000000015751046102023000177740ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::nevers::Never; use malachite_base::tuples::singletons; use std::fmt::Debug; fn singletons_helper(xs: &[T], out: &[(T,)]) { assert_eq!(singletons(xs.iter().cloned()).collect_vec().as_slice(), out); } #[test] fn test_singletons() { singletons_helper::(&[], &[]); singletons_helper(&[5], &[(5,)]); singletons_helper(&[1, 2, 3], &[(1,), (2,), (3,)]); singletons_helper(&[(2,), (1,), (5,)], &[((2,),), ((1,),), ((5,),)]); } malachite-base-0.4.16/tests/unions/clone.rs000064400000000000000000000021461046102023000167010ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::unions::Union2; #[allow(clippy::redundant_clone)] #[test] fn test_clone() { let test = |u: Union2, u32>| { let cloned = u.clone(); assert_eq!(cloned, u); }; test(Union2::A(vec![])); test(Union2::A(vec!['a', 'b', 'c'])); test(Union2::B(5)); } #[test] fn test_clone_from() { let test = |mut u: Union2, u32>, v: Union2, u32>| { u.clone_from(&v); assert_eq!(u, v); }; test(Union2::A(vec!['a', 'b', 'c']), Union2::A(vec![])); test(Union2::A(vec![]), Union2::A(vec!['a', 'b', 'c'])); test(Union2::B(5), Union2::B(6)); test(Union2::A(vec!['a', 'b', 'c']), Union2::B(6)); test(Union2::B(6), Union2::A(vec!['a', 'b', 'c'])); } malachite-base-0.4.16/tests/unions/debug.rs000064400000000000000000000013251046102023000166650ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::strings::ToDebugString; use malachite_base::unions::Union2; #[test] fn test_to_debug() { let test = |u: Union2, u32>, out| { assert_eq!(u.to_debug_string(), out); }; test(Union2::A(vec![]), "A([])"); test(Union2::A(vec!['a', 'b', 'c']), "A(['a', 'b', 'c'])"); test(Union2::B(5), "B(5)"); } malachite-base-0.4.16/tests/unions/display.rs000064400000000000000000000012101046102023000172350ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::extra_variadic::Union3; #[test] fn test_to_string() { let test = |u: Union3, out| { assert_eq!(u.to_string(), out); }; test(Union3::A('a'), "A(a)"); test(Union3::B(5), "B(5)"); test(Union3::C(false), "C(false)"); } malachite-base-0.4.16/tests/unions/eq.rs000064400000000000000000000011441046102023000162030ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::extra_variadic::Union3; use malachite_base::test_util::common::test_eq_helper; #[test] fn test_eq() { test_eq_helper::>(&[ "B(8)", "A(d)", "C(true)", "B(5)", "C(false)", "A(a)", ]); } malachite-base-0.4.16/tests/unions/exhaustive/exhaustive_unions.rs000064400000000000000000000141251046102023000235460ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::extra_variadic::exhaustive_union3s; use crate::extra_variadic::Union3; use itertools::Itertools; use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::nevers::nevers; use malachite_base::num::exhaustive::exhaustive_unsigneds; use malachite_base::options::exhaustive::exhaustive_somes; use malachite_base::orderings::exhaustive::exhaustive_orderings; use malachite_base::unions::exhaustive::exhaustive_union2s; use malachite_base::unions::Union2; use std::cmp::Ordering::*; use std::fmt::Debug; use std::iter::once; fn exhaustive_union2s_helper< X: Clone + Debug + Eq, I: Clone + Iterator, Y: Clone + Debug + Eq, J: Clone + Iterator, >( xs: I, ys: J, out_len: usize, out: &[Union2], ) { let us = exhaustive_union2s(xs, ys); let us_prefix = us.clone().take(20).collect_vec(); assert_eq!(us_prefix.as_slice(), out); assert_eq!(us.count(), out_len); } #[test] fn test_exhaustive_union2s() { exhaustive_union2s_helper(nevers(), nevers(), 0, &[]); exhaustive_union2s_helper( nevers(), 0..4, 4, &[Union2::B(0), Union2::B(1), Union2::B(2), Union2::B(3)], ); exhaustive_union2s_helper(once('a'), once(1), 2, &[Union2::A('a'), Union2::B(1)]); exhaustive_union2s_helper( once('a'), 0..4, 5, &[Union2::A('a'), Union2::B(0), Union2::B(1), Union2::B(2), Union2::B(3)], ); exhaustive_union2s_helper( 'a'..'e', exhaustive_unsigneds::(), 260, &[ Union2::A('a'), Union2::B(0), Union2::A('b'), Union2::B(1), Union2::A('c'), Union2::B(2), Union2::A('d'), Union2::B(3), Union2::B(4), Union2::B(5), Union2::B(6), Union2::B(7), Union2::B(8), Union2::B(9), Union2::B(10), Union2::B(11), Union2::B(12), Union2::B(13), Union2::B(14), Union2::B(15), ], ); exhaustive_union2s_helper( exhaustive_bools(), 0..4, 6, &[ Union2::A(false), Union2::B(0), Union2::A(true), Union2::B(1), Union2::B(2), Union2::B(3), ], ); exhaustive_union2s_helper( 'a'..'f', 0..3, 8, &[ Union2::A('a'), Union2::B(0), Union2::A('b'), Union2::B(1), Union2::A('c'), Union2::B(2), Union2::A('d'), Union2::A('e'), ], ); exhaustive_union2s_helper( ['a', 'b', 'c'].iter().copied(), exhaustive_orderings(), 6, &[ Union2::A('a'), Union2::B(Equal), Union2::A('b'), Union2::B(Less), Union2::A('c'), Union2::B(Greater), ], ); } fn exhaustive_union3s_helper< X: Clone + Debug + Eq, I: Clone + Iterator, Y: Clone + Debug + Eq, J: Clone + Iterator, Z: Clone + Debug + Eq, K: Clone + Iterator, >( xs: I, ys: J, zs: K, out_len: usize, out: &[Union3], ) { let ts = exhaustive_union3s(xs, ys, zs); let ts_prefix = ts.clone().take(20).collect_vec(); assert_eq!(ts_prefix.as_slice(), out); assert_eq!(ts.count(), out_len); } #[test] fn test_exhaustive_union3s() { exhaustive_union3s_helper(nevers(), nevers(), nevers(), 0, &[]); exhaustive_union3s_helper( nevers(), 0..4, 'a'..'f', 9, &[ Union3::B(0), Union3::C('a'), Union3::B(1), Union3::C('b'), Union3::B(2), Union3::C('c'), Union3::B(3), Union3::C('d'), Union3::C('e'), ], ); exhaustive_union3s_helper( once('a'), once(false), once(5), 3, &[Union3::A('a'), Union3::B(false), Union3::C(5)], ); exhaustive_union3s_helper( once('a'), once(false), 0..4, 6, &[Union3::A('a'), Union3::B(false), Union3::C(0), Union3::C(1), Union3::C(2), Union3::C(3)], ); exhaustive_union3s_helper( exhaustive_bools(), 0..3, 'a'..'d', 8, &[ Union3::A(false), Union3::B(0), Union3::C('a'), Union3::A(true), Union3::B(1), Union3::C('b'), Union3::B(2), Union3::C('c'), ], ); exhaustive_union3s_helper( 0..11, exhaustive_somes(0..12), 'a'..'n', 36, &[ Union3::A(0), Union3::B(Some(0)), Union3::C('a'), Union3::A(1), Union3::B(Some(1)), Union3::C('b'), Union3::A(2), Union3::B(Some(2)), Union3::C('c'), Union3::A(3), Union3::B(Some(3)), Union3::C('d'), Union3::A(4), Union3::B(Some(4)), Union3::C('e'), Union3::A(5), Union3::B(Some(5)), Union3::C('f'), Union3::A(6), Union3::B(Some(6)), ], ); exhaustive_union3s_helper( ['a', 'b', 'c'].iter().copied(), ["xx", "yy", "zz"].iter().copied(), 0..3, 9, &[ Union3::A('a'), Union3::B("xx"), Union3::C(0), Union3::A('b'), Union3::B("yy"), Union3::C(1), Union3::A('c'), Union3::B("zz"), Union3::C(2), ], ); } malachite-base-0.4.16/tests/unions/exhaustive/lex_unions.rs000064400000000000000000000136651046102023000221610ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::extra_variadic::lex_union3s; use crate::extra_variadic::Union3; use itertools::Itertools; use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::nevers::nevers; use malachite_base::num::exhaustive::exhaustive_unsigneds; use malachite_base::options::exhaustive::exhaustive_somes; use malachite_base::orderings::exhaustive::exhaustive_orderings; use malachite_base::unions::exhaustive::lex_union2s; use malachite_base::unions::Union2; use std::cmp::Ordering::*; use std::fmt::Debug; use std::iter::once; fn lex_union2s_helper< X: Clone + Debug + Eq, I: Clone + Iterator, Y: Clone + Debug + Eq, J: Clone + Iterator, >( xs: I, ys: J, out_len: usize, out: &[Union2], ) { let us = lex_union2s(xs, ys); let us_prefix = us.clone().take(20).collect_vec(); assert_eq!(us_prefix.as_slice(), out); assert_eq!(us.count(), out_len); } #[test] fn test_lex_union2s() { lex_union2s_helper(nevers(), nevers(), 0, &[]); lex_union2s_helper( nevers(), 0..4, 4, &[Union2::B(0), Union2::B(1), Union2::B(2), Union2::B(3)], ); lex_union2s_helper(once('a'), once(1), 2, &[Union2::A('a'), Union2::B(1)]); lex_union2s_helper( once('a'), 0..4, 5, &[Union2::A('a'), Union2::B(0), Union2::B(1), Union2::B(2), Union2::B(3)], ); lex_union2s_helper( 'a'..'e', exhaustive_unsigneds::(), 260, &[ Union2::A('a'), Union2::A('b'), Union2::A('c'), Union2::A('d'), Union2::B(0), Union2::B(1), Union2::B(2), Union2::B(3), Union2::B(4), Union2::B(5), Union2::B(6), Union2::B(7), Union2::B(8), Union2::B(9), Union2::B(10), Union2::B(11), Union2::B(12), Union2::B(13), Union2::B(14), Union2::B(15), ], ); lex_union2s_helper( exhaustive_bools(), 0..4, 6, &[ Union2::A(false), Union2::A(true), Union2::B(0), Union2::B(1), Union2::B(2), Union2::B(3), ], ); lex_union2s_helper( 'a'..'f', 0..3, 8, &[ Union2::A('a'), Union2::A('b'), Union2::A('c'), Union2::A('d'), Union2::A('e'), Union2::B(0), Union2::B(1), Union2::B(2), ], ); lex_union2s_helper( ['a', 'b', 'c'].iter().copied(), exhaustive_orderings(), 6, &[ Union2::A('a'), Union2::A('b'), Union2::A('c'), Union2::B(Equal), Union2::B(Less), Union2::B(Greater), ], ); } fn lex_union3s_helper< X: Clone + Debug + Eq, I: Clone + Iterator, Y: Clone + Debug + Eq, J: Clone + Iterator, Z: Clone + Debug + Eq, K: Clone + Iterator, >( xs: I, ys: J, zs: K, out_len: usize, out: &[Union3], ) { let ts = lex_union3s(xs, ys, zs); let ts_prefix = ts.clone().take(20).collect_vec(); assert_eq!(ts_prefix.as_slice(), out); assert_eq!(ts.count(), out_len); } #[test] fn test_lex_union3s() { lex_union3s_helper(nevers(), nevers(), nevers(), 0, &[]); lex_union3s_helper( nevers(), 0..4, 'a'..'f', 9, &[ Union3::B(0), Union3::B(1), Union3::B(2), Union3::B(3), Union3::C('a'), Union3::C('b'), Union3::C('c'), Union3::C('d'), Union3::C('e'), ], ); lex_union3s_helper( once('a'), once(false), once(5), 3, &[Union3::A('a'), Union3::B(false), Union3::C(5)], ); lex_union3s_helper( once('a'), once(false), 0..4, 6, &[Union3::A('a'), Union3::B(false), Union3::C(0), Union3::C(1), Union3::C(2), Union3::C(3)], ); lex_union3s_helper( exhaustive_bools(), 0..3, 'a'..'d', 8, &[ Union3::A(false), Union3::A(true), Union3::B(0), Union3::B(1), Union3::B(2), Union3::C('a'), Union3::C('b'), Union3::C('c'), ], ); lex_union3s_helper( 0..11, exhaustive_somes(0..12), 'a'..'n', 36, &[ Union3::A(0), Union3::A(1), Union3::A(2), Union3::A(3), Union3::A(4), Union3::A(5), Union3::A(6), Union3::A(7), Union3::A(8), Union3::A(9), Union3::A(10), Union3::B(Some(0)), Union3::B(Some(1)), Union3::B(Some(2)), Union3::B(Some(3)), Union3::B(Some(4)), Union3::B(Some(5)), Union3::B(Some(6)), Union3::B(Some(7)), Union3::B(Some(8)), ], ); lex_union3s_helper( ['a', 'b', 'c'].iter().copied(), ["xx", "yy", "zz"].iter().copied(), 0..3, 9, &[ Union3::A('a'), Union3::A('b'), Union3::A('c'), Union3::B("xx"), Union3::B("yy"), Union3::B("zz"), Union3::C(0), Union3::C(1), Union3::C(2), ], ); } malachite-base-0.4.16/tests/unions/from_str.rs000064400000000000000000000031431046102023000174320ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::extra_variadic::Union3; use malachite_base::unions::UnionFromStrError; use std::result::Result; use std::str::FromStr; #[test] fn test_from_str() { let test = |s, out| { assert_eq!(Union3::from_str(s), out); }; test("A(a)", Ok(Union3::A('a'))); test("B(5)", Ok(Union3::B(5))); test("C(false)", Ok(Union3::C(false))); test("", Err(UnionFromStrError::Generic(String::new()))); test("xyz", Err(UnionFromStrError::Generic("xyz".to_string()))); test("D(a)", Err(UnionFromStrError::Generic("D(a)".to_string()))); test("A(a", Err(UnionFromStrError::Generic("A(a".to_string()))); let result: Result, _> = Union3::from_str("A(ab)"); if let Err(UnionFromStrError::Specific(Union3::A(_e))) = result { } else { panic!("wrong error variant") } let result: Result, _> = Union3::from_str("B(-1)"); if let Err(UnionFromStrError::Specific(Union3::B(_e))) = result { } else { panic!("wrong error variant") } let result: Result, _> = Union3::from_str("C(tralse)"); if let Err(UnionFromStrError::Specific(Union3::C(_e))) = result { } else { panic!("wrong error variant") } } malachite-base-0.4.16/tests/unions/ord.rs000064400000000000000000000011471046102023000163650ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::extra_variadic::Union3; use malachite_base::test_util::common::test_cmp_helper; #[test] fn test_cmp() { test_cmp_helper::>(&[ "A(a)", "A(d)", "B(5)", "B(8)", "C(false)", "C(true)", ]); } malachite-base-0.4.16/tests/unions/random/random_unions.rs000064400000000000000000000174041046102023000217370ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::extra_variadic::random_union3s; use crate::extra_variadic::Union3; use core::hash::Hash; use itertools::Itertools; use malachite_base::bools::random::random_bools; use malachite_base::chars::random::random_char_inclusive_range; use malachite_base::num::random::geometric::geometric_random_unsigneds; use malachite_base::num::random::random_unsigned_inclusive_range; use malachite_base::orderings::random::random_orderings; use malachite_base::random::{Seed, EXAMPLE_SEED}; use malachite_base::strings::random::random_strings_using_chars; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; use malachite_base::unions::random::random_union2s; use malachite_base::unions::Union2; use std::cmp::Ordering::*; use std::fmt::Debug; fn random_union2s_helper< X: Clone + Debug + Eq + Hash + Ord, I: Clone + Iterator, Y: Clone + Debug + Eq + Hash + Ord, J: Clone + Iterator, >( xs_gen: &dyn Fn(Seed) -> I, ys_gen: &dyn Fn(Seed) -> J, expected_values: &[Union2], expected_common_values: &[(Union2, usize)], expected_median: (Union2, Option>), ) { let us = random_union2s(EXAMPLE_SEED, xs_gen, ys_gen); let values = us.clone().take(20).collect_vec(); let common_values = common_values_map_debug(1000000, 10, us.clone()); let median = median(us.take(1000000)); assert_eq!( (values.as_slice(), common_values.as_slice(), median), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_random_union2s() { random_union2s_helper( &|seed| random_char_inclusive_range(seed, 'a', 'z'), &|seed| random_unsigned_inclusive_range::(seed, 1, 10), &[ Union2::A('v'), Union2::B(3), Union2::A('c'), Union2::A('q'), Union2::A('i'), Union2::A('e'), Union2::A('p'), Union2::A('g'), Union2::A('s'), Union2::B(7), Union2::A('n'), Union2::A('t'), Union2::B(9), Union2::A('m'), Union2::A('z'), Union2::B(7), Union2::B(9), Union2::A('o'), Union2::A('m'), Union2::B(3), ], &[ (Union2::B(5), 50535), (Union2::B(4), 50190), (Union2::B(10), 50183), (Union2::B(3), 50068), (Union2::B(9), 50064), (Union2::B(6), 50002), (Union2::B(2), 49882), (Union2::B(1), 49807), (Union2::B(7), 49533), (Union2::B(8), 49495), ], (Union2::A('z'), None), ); random_union2s_helper( &random_bools, &|seed| geometric_random_unsigneds::(seed, 4, 1), &[ Union2::A(true), Union2::B(6), Union2::A(false), Union2::A(true), Union2::A(false), Union2::A(true), Union2::A(false), Union2::A(true), Union2::A(false), Union2::B(0), Union2::A(true), Union2::A(true), Union2::B(2), Union2::A(false), Union2::A(true), Union2::B(2), Union2::B(2), Union2::A(false), Union2::A(false), Union2::B(8), ], &[ (Union2::A(false), 250462), (Union2::A(true), 249779), (Union2::B(0), 100190), (Union2::B(1), 79510), (Union2::B(2), 63929), (Union2::B(3), 51260), (Union2::B(4), 41099), (Union2::B(5), 32494), (Union2::B(6), 26037), (Union2::B(7), 21139), ], (Union2::A(true), None), ); } #[allow(clippy::type_complexity)] fn random_union3s_helper< X: Clone + Debug + Eq + Hash + Ord, I: Clone + Iterator, Y: Clone + Debug + Eq + Hash + Ord, J: Clone + Iterator, Z: Clone + Debug + Eq + Hash + Ord, K: Clone + Iterator, >( xs_gen: &dyn Fn(Seed) -> I, ys_gen: &dyn Fn(Seed) -> J, zs_gen: &dyn Fn(Seed) -> K, expected_values: &[Union3], expected_common_values: &[(Union3, usize)], expected_median: (Union3, Option>), ) { let us = random_union3s(EXAMPLE_SEED, xs_gen, ys_gen, zs_gen); let values = us.clone().take(20).collect_vec(); let common_values = common_values_map_debug(1000000, 10, us.clone()); let median = median(us.take(1000000)); assert_eq!( (values.as_slice(), common_values.as_slice(), median), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_random_union3s() { random_union3s_helper( &|seed| random_char_inclusive_range(seed, 'a', 'z'), &|seed| random_unsigned_inclusive_range::(seed, 1, 10), &random_orderings, &[ Union3::C(Equal), Union3::A('v'), Union3::A('c'), Union3::A('q'), Union3::C(Greater), Union3::A('i'), Union3::B(3), Union3::C(Greater), Union3::B(7), Union3::C(Greater), Union3::C(Greater), Union3::C(Greater), Union3::B(9), Union3::C(Equal), Union3::A('e'), Union3::A('p'), Union3::A('g'), Union3::A('s'), Union3::C(Equal), Union3::A('n'), ], &[ (Union3::C(Less), 111378), (Union3::C(Greater), 111191), (Union3::C(Equal), 110903), (Union3::B(5), 33724), (Union3::B(10), 33503), (Union3::B(4), 33375), (Union3::B(9), 33348), (Union3::B(2), 33347), (Union3::B(6), 33288), (Union3::B(7), 33283), ], (Union3::B(5), None), ); random_union3s_helper( &random_bools, &|seed| geometric_random_unsigneds::(seed, 4, 1), &|seed| { random_strings_using_chars( seed, &|seed_2| random_char_inclusive_range(seed_2, 'a', 'z'), 4, 1, ) }, &[ Union3::C("qvfm".to_string()), Union3::A(true), Union3::A(false), Union3::A(true), Union3::C("kt".to_string()), Union3::A(false), Union3::B(6), Union3::C("auqoox".to_string()), Union3::B(0), Union3::C("ak".to_string()), Union3::C("".to_string()), Union3::C("dz".to_string()), Union3::B(2), Union3::C("ebaq".to_string()), Union3::A(true), Union3::A(false), Union3::A(true), Union3::A(false), Union3::C("gvqmloscuftfzjrn".to_string()), Union3::A(true), ], &[ (Union3::A(false), 166833), (Union3::A(true), 166495), (Union3::B(0), 66610), (Union3::C("".to_string()), 66483), (Union3::B(1), 53004), (Union3::B(2), 42754), (Union3::B(3), 34312), (Union3::B(4), 27360), (Union3::B(5), 21599), (Union3::B(6), 17332), ], (Union3::B(3), None), ); } malachite-base-0.4.16/tests/unions/unwrap.rs000064400000000000000000000011661046102023000171160ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::extra_variadic::Union3; #[test] fn test_unwrap() { let test = |u: Union3, out| { assert_eq!(u.unwrap(), out); }; test(Union3::A('a'), 'a'); test(Union3::B('b'), 'b'); test(Union3::C('c'), 'c'); } malachite-base-0.4.16/tests/vecs/exhaustive/exhaustive_combined_k_compositions.rs000064400000000000000000000057501046102023000265640ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::vecs::exhaustive::exhaustive_combined_k_compositions; fn exhaustive_combined_k_compositions_helper( n_min: usize, n_max: usize, k: usize, out: &[&[usize]], ) { let xss = exhaustive_combined_k_compositions(n_min, n_max, k).collect_vec(); assert_eq!(xss.iter().map(Vec::as_slice).collect_vec().as_slice(), out); } #[test] fn test_exhaustive_combined_k_compositions() { exhaustive_combined_k_compositions_helper( 3, 5, 3, &[ &[1, 1, 1], &[1, 1, 2], &[1, 2, 1], &[2, 1, 1], &[1, 1, 3], &[1, 2, 2], &[1, 3, 1], &[2, 1, 2], &[2, 2, 1], &[3, 1, 1], ], ); exhaustive_combined_k_compositions_helper( 6, 8, 5, &[ &[1, 1, 1, 1, 2], &[1, 1, 1, 1, 3], &[1, 1, 1, 2, 1], &[1, 1, 1, 1, 4], &[1, 1, 2, 1, 1], &[1, 1, 1, 2, 2], &[1, 2, 1, 1, 1], &[2, 1, 1, 1, 1], &[1, 1, 1, 3, 1], &[1, 1, 1, 2, 3], &[1, 1, 2, 1, 2], &[1, 1, 2, 2, 1], &[1, 1, 3, 1, 1], &[1, 1, 1, 3, 2], &[1, 2, 1, 1, 2], &[1, 2, 1, 2, 1], &[1, 2, 2, 1, 1], &[1, 1, 1, 4, 1], &[1, 3, 1, 1, 1], &[2, 1, 1, 1, 2], &[2, 1, 1, 2, 1], &[1, 1, 2, 1, 3], &[2, 1, 2, 1, 1], &[1, 1, 2, 2, 2], &[2, 2, 1, 1, 1], &[1, 1, 2, 3, 1], &[3, 1, 1, 1, 1], &[1, 1, 3, 1, 2], &[1, 1, 3, 2, 1], &[1, 1, 4, 1, 1], &[1, 2, 1, 1, 3], &[1, 2, 1, 2, 2], &[1, 2, 1, 3, 1], &[1, 2, 2, 1, 2], &[1, 2, 2, 2, 1], &[1, 2, 3, 1, 1], &[1, 3, 1, 1, 2], &[1, 3, 1, 2, 1], &[1, 3, 2, 1, 1], &[1, 4, 1, 1, 1], &[2, 1, 1, 1, 3], &[2, 1, 1, 2, 2], &[2, 1, 1, 3, 1], &[2, 1, 2, 1, 2], &[2, 1, 2, 2, 1], &[2, 1, 3, 1, 1], &[2, 2, 1, 1, 2], &[2, 2, 1, 2, 1], &[2, 2, 2, 1, 1], &[2, 3, 1, 1, 1], &[3, 1, 1, 1, 2], &[3, 1, 1, 2, 1], &[3, 1, 2, 1, 1], &[3, 2, 1, 1, 1], &[4, 1, 1, 1, 1], ], ); } #[test] #[should_panic] fn exhaustive_combined_k_compositions_fail() { exhaustive_combined_k_compositions(2, 1, 3); } malachite-base-0.4.16/tests/vecs/exhaustive/exhaustive_ordered_unique_vecs.rs000064400000000000000000000056101046102023000257110ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::test_util::vecs::exhaustive::{ exhaustive_vecs_helper_helper, exhaustive_vecs_small_helper_helper, }; use malachite_base::tuples::exhaustive::exhaustive_units; use malachite_base::vecs::exhaustive::exhaustive_ordered_unique_vecs; use std::fmt::Debug; fn exhaustive_ordered_unique_vecs_helper(xs: I, out: &[&[I::Item]]) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_helper_helper(exhaustive_ordered_unique_vecs(xs), out); } fn exhaustive_ordered_unique_vecs_small_helper( xs: I, out_len: usize, out: &[&[I::Item]], ) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_small_helper_helper(exhaustive_ordered_unique_vecs(xs), out_len, out); } #[test] fn test_exhaustive_ordered_unique_vecs() { exhaustive_ordered_unique_vecs_small_helper(nevers(), 1, &[&[]]); exhaustive_ordered_unique_vecs_small_helper(exhaustive_units(), 2, &[&[], &[()]]); exhaustive_ordered_unique_vecs_small_helper( exhaustive_bools(), 4, &[&[], &[false], &[true], &[false, true]], ); exhaustive_ordered_unique_vecs_small_helper( 1..=6, 64, &[ &[], &[1], &[2], &[1, 2], &[3], &[1, 3], &[2, 3], &[1, 2, 3], &[4], &[1, 4], &[2, 4], &[1, 2, 4], &[3, 4], &[1, 3, 4], &[2, 3, 4], &[1, 2, 3, 4], &[5], &[1, 5], &[2, 5], &[1, 2, 5], ], ); exhaustive_ordered_unique_vecs_small_helper( 'a'..='c', 8, &[&[], &['a'], &['b'], &['a', 'b'], &['c'], &['a', 'c'], &['b', 'c'], &['a', 'b', 'c']], ); exhaustive_ordered_unique_vecs_helper( exhaustive_ascii_chars(), &[ &[], &['a'], &['b'], &['a', 'b'], &['c'], &['a', 'c'], &['b', 'c'], &['a', 'b', 'c'], &['d'], &['a', 'd'], &['b', 'd'], &['a', 'b', 'd'], &['c', 'd'], &['a', 'c', 'd'], &['b', 'c', 'd'], &['a', 'b', 'c', 'd'], &['e'], &['a', 'e'], &['b', 'e'], &['a', 'b', 'e'], ], ); } malachite-base-0.4.16/tests/vecs/exhaustive/exhaustive_ordered_unique_vecs_fixed_length.rs000064400000000000000000000156711046102023000304410ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::num::exhaustive::exhaustive_unsigneds; use malachite_base::test_util::vecs::exhaustive::{ exhaustive_vecs_helper_helper, exhaustive_vecs_small_helper_helper, }; use malachite_base::tuples::exhaustive::exhaustive_units; use malachite_base::vecs::exhaustive::exhaustive_ordered_unique_vecs_fixed_length; use std::fmt::Debug; fn exhaustive_ordered_unique_vecs_fixed_length_helper( len: u64, xs: I, out: &[&[I::Item]], ) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_helper_helper(exhaustive_ordered_unique_vecs_fixed_length(len, xs), out); } fn exhaustive_ordered_unique_vecs_fixed_length_small_helper( len: u64, xs: I, out_len: usize, out: &[&[I::Item]], ) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_small_helper_helper( exhaustive_ordered_unique_vecs_fixed_length(len, xs), out_len, out, ); } #[test] fn test_exhaustive_ordered_unique_vecs_fixed_length() { // This demonstrates that 0 ^ 0 == 1: exhaustive_ordered_unique_vecs_fixed_length_small_helper(0, nevers(), 1, &[&[]]); exhaustive_ordered_unique_vecs_fixed_length_small_helper(1, nevers(), 0, &[]); exhaustive_ordered_unique_vecs_fixed_length_small_helper(2, nevers(), 0, &[]); exhaustive_ordered_unique_vecs_fixed_length_small_helper(5, nevers(), 0, &[]); exhaustive_ordered_unique_vecs_fixed_length_small_helper(1, exhaustive_units(), 1, &[&[()]]); exhaustive_ordered_unique_vecs_fixed_length_small_helper(2, exhaustive_units(), 0, &[]); exhaustive_ordered_unique_vecs_fixed_length_small_helper(5, exhaustive_units(), 0, &[]); exhaustive_ordered_unique_vecs_fixed_length_small_helper( 0, exhaustive_unsigneds::(), 1, &[&[]], ); exhaustive_ordered_unique_vecs_fixed_length_small_helper( 1, exhaustive_unsigneds::(), 256, &[ &[0], &[1], &[2], &[3], &[4], &[5], &[6], &[7], &[8], &[9], &[10], &[11], &[12], &[13], &[14], &[15], &[16], &[17], &[18], &[19], ], ); exhaustive_ordered_unique_vecs_fixed_length_helper( 1, exhaustive_unsigneds::(), &[ &[0], &[1], &[2], &[3], &[4], &[5], &[6], &[7], &[8], &[9], &[10], &[11], &[12], &[13], &[14], &[15], &[16], &[17], &[18], &[19], ], ); exhaustive_ordered_unique_vecs_fixed_length_small_helper( 2, exhaustive_unsigneds::(), 32640, &[ &[0, 1], &[0, 2], &[1, 2], &[0, 3], &[1, 3], &[2, 3], &[0, 4], &[1, 4], &[2, 4], &[3, 4], &[0, 5], &[1, 5], &[2, 5], &[3, 5], &[4, 5], &[0, 6], &[1, 6], &[2, 6], &[3, 6], &[4, 6], ], ); exhaustive_ordered_unique_vecs_fixed_length_helper( 3, exhaustive_unsigneds::(), &[ &[0, 1, 2], &[0, 1, 3], &[0, 2, 3], &[1, 2, 3], &[0, 1, 4], &[0, 2, 4], &[1, 2, 4], &[0, 3, 4], &[1, 3, 4], &[2, 3, 4], &[0, 1, 5], &[0, 2, 5], &[1, 2, 5], &[0, 3, 5], &[1, 3, 5], &[2, 3, 5], &[0, 4, 5], &[1, 4, 5], &[2, 4, 5], &[3, 4, 5], ], ); exhaustive_ordered_unique_vecs_fixed_length_small_helper( 2, exhaustive_ascii_chars(), 8128, &[ &['a', 'b'], &['a', 'c'], &['b', 'c'], &['a', 'd'], &['b', 'd'], &['c', 'd'], &['a', 'e'], &['b', 'e'], &['c', 'e'], &['d', 'e'], &['a', 'f'], &['b', 'f'], &['c', 'f'], &['d', 'f'], &['e', 'f'], &['a', 'g'], &['b', 'g'], &['c', 'g'], &['d', 'g'], &['e', 'g'], ], ); exhaustive_ordered_unique_vecs_fixed_length_small_helper( 1, exhaustive_bools(), 2, &[&[false], &[true]], ); exhaustive_ordered_unique_vecs_fixed_length_small_helper( 2, exhaustive_bools(), 1, &[&[false, true]], ); exhaustive_ordered_unique_vecs_fixed_length_small_helper(4, exhaustive_bools(), 0, &[]); exhaustive_ordered_unique_vecs_fixed_length_small_helper( 4, 1..=6, 15, &[ &[1, 2, 3, 4], &[1, 2, 3, 5], &[1, 2, 4, 5], &[1, 3, 4, 5], &[2, 3, 4, 5], &[1, 2, 3, 6], &[1, 2, 4, 6], &[1, 3, 4, 6], &[2, 3, 4, 6], &[1, 2, 5, 6], &[1, 3, 5, 6], &[2, 3, 5, 6], &[1, 4, 5, 6], &[2, 4, 5, 6], &[3, 4, 5, 6], ], ); exhaustive_ordered_unique_vecs_fixed_length_helper( 2, exhaustive_ordered_unique_vecs_fixed_length(2, exhaustive_unsigneds::()), &[ &[vec![0, 1], vec![0, 2]], &[vec![0, 1], vec![1, 2]], &[vec![0, 2], vec![1, 2]], &[vec![0, 1], vec![0, 3]], &[vec![0, 2], vec![0, 3]], &[vec![1, 2], vec![0, 3]], &[vec![0, 1], vec![1, 3]], &[vec![0, 2], vec![1, 3]], &[vec![1, 2], vec![1, 3]], &[vec![0, 3], vec![1, 3]], &[vec![0, 1], vec![2, 3]], &[vec![0, 2], vec![2, 3]], &[vec![1, 2], vec![2, 3]], &[vec![0, 3], vec![2, 3]], &[vec![1, 3], vec![2, 3]], &[vec![0, 1], vec![0, 4]], &[vec![0, 2], vec![0, 4]], &[vec![1, 2], vec![0, 4]], &[vec![0, 3], vec![0, 4]], &[vec![1, 3], vec![0, 4]], ], ); } malachite-base-0.4.16/tests/vecs/exhaustive/exhaustive_ordered_unique_vecs_length_inclusive_range.rs000064400000000000000000000042171046102023000325110ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::nevers::nevers; use malachite_base::test_util::vecs::exhaustive::exhaustive_vecs_small_helper_helper; use malachite_base::tuples::exhaustive::exhaustive_units; use malachite_base::vecs::exhaustive::exhaustive_ordered_unique_vecs_length_inclusive_range; use std::fmt::Debug; fn exhaustive_ordered_unique_vecs_length_inclusive_range_small_helper( a: u64, b: u64, xs: I, out_len: usize, out: &[&[I::Item]], ) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_small_helper_helper( exhaustive_ordered_unique_vecs_length_inclusive_range(a, b, xs), out_len, out, ); } #[test] fn test_exhaustive_ordered_unique_vecs_length_inclusive_range() { exhaustive_ordered_unique_vecs_length_inclusive_range_small_helper(0, 4, nevers(), 1, &[&[]]); exhaustive_ordered_unique_vecs_length_inclusive_range_small_helper(6, 9, nevers(), 0, &[]); exhaustive_ordered_unique_vecs_length_inclusive_range_small_helper( 0, 4, exhaustive_units(), 2, &[&[], &[()]], ); exhaustive_ordered_unique_vecs_length_inclusive_range_small_helper( 1, 0, exhaustive_bools(), 0, &[], ); exhaustive_ordered_unique_vecs_length_inclusive_range_small_helper( 0, 1, exhaustive_bools(), 3, &[&[], &[false], &[true]], ); exhaustive_ordered_unique_vecs_length_inclusive_range_small_helper( 2, 3, exhaustive_bools(), 1, &[&[false, true]], ); exhaustive_ordered_unique_vecs_length_inclusive_range_small_helper( 1, 1, 'a'..='c', 3, &[&['a'], &['b'], &['c']], ); } malachite-base-0.4.16/tests/vecs/exhaustive/exhaustive_ordered_unique_vecs_length_range.rs000064400000000000000000000041231046102023000304240ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::nevers::nevers; use malachite_base::test_util::vecs::exhaustive::exhaustive_vecs_small_helper_helper; use malachite_base::tuples::exhaustive::exhaustive_units; use malachite_base::vecs::exhaustive::exhaustive_ordered_unique_vecs_length_range; use std::fmt::Debug; fn exhaustive_ordered_unique_vecs_length_range_small_helper( a: u64, b: u64, xs: I, out_len: usize, out: &[&[I::Item]], ) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_small_helper_helper( exhaustive_ordered_unique_vecs_length_range(a, b, xs), out_len, out, ); } #[test] fn test_exhaustive_ordered_unique_vecs_length_range() { exhaustive_ordered_unique_vecs_length_range_small_helper(0, 5, nevers(), 1, &[&[]]); exhaustive_ordered_unique_vecs_length_range_small_helper(6, 10, nevers(), 0, &[]); exhaustive_ordered_unique_vecs_length_range_small_helper( 0, 5, exhaustive_units(), 2, &[&[], &[()]], ); exhaustive_ordered_unique_vecs_length_range_small_helper(1, 0, exhaustive_bools(), 0, &[]); exhaustive_ordered_unique_vecs_length_range_small_helper(1, 1, exhaustive_bools(), 0, &[]); exhaustive_ordered_unique_vecs_length_range_small_helper( 0, 2, exhaustive_bools(), 3, &[&[], &[false], &[true]], ); exhaustive_ordered_unique_vecs_length_range_small_helper( 2, 4, exhaustive_bools(), 1, &[&[false, true]], ); exhaustive_ordered_unique_vecs_length_range_small_helper( 1, 2, 'a'..='c', 3, &[&['a'], &['b'], &['c']], ); } malachite-base-0.4.16/tests/vecs/exhaustive/exhaustive_ordered_unique_vecs_min_length.rs000064400000000000000000000076331046102023000301240ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::test_util::vecs::exhaustive::{ exhaustive_vecs_helper_helper, exhaustive_vecs_small_helper_helper, }; use malachite_base::tuples::exhaustive::exhaustive_units; use malachite_base::vecs::exhaustive::exhaustive_ordered_unique_vecs_min_length; use std::fmt::Debug; fn exhaustive_ordered_unique_vecs_min_length_helper( min_length: u64, xs: I, out: &[&[I::Item]], ) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_helper_helper( exhaustive_ordered_unique_vecs_min_length(min_length, xs), out, ); } fn exhaustive_ordered_unique_vecs_min_length_small_helper( min_length: u64, xs: I, out_len: usize, out: &[&[I::Item]], ) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_small_helper_helper( exhaustive_ordered_unique_vecs_min_length(min_length, xs), out_len, out, ); } #[test] fn test_exhaustive_ordered_unique_vecs_min_length() { exhaustive_ordered_unique_vecs_min_length_small_helper(0, nevers(), 1, &[&[]]); exhaustive_ordered_unique_vecs_min_length_small_helper(4, nevers(), 0, &[]); exhaustive_ordered_unique_vecs_min_length_small_helper(0, exhaustive_units(), 2, &[&[], &[()]]); exhaustive_ordered_unique_vecs_min_length_small_helper(5, exhaustive_units(), 0, &[]); exhaustive_ordered_unique_vecs_min_length_small_helper( 0, exhaustive_bools(), 4, &[&[], &[false], &[true], &[false, true]], ); exhaustive_ordered_unique_vecs_min_length_small_helper( 1, exhaustive_bools(), 3, &[&[false], &[true], &[false, true]], ); exhaustive_ordered_unique_vecs_min_length_small_helper( 0, 'a'..='c', 8, &[&[], &['a'], &['b'], &['a', 'b'], &['c'], &['a', 'c'], &['b', 'c'], &['a', 'b', 'c']], ); exhaustive_ordered_unique_vecs_min_length_small_helper( 2, 'a'..='c', 4, &[&['a', 'b'], &['a', 'c'], &['b', 'c'], &['a', 'b', 'c']], ); exhaustive_ordered_unique_vecs_min_length_helper( 0, exhaustive_ascii_chars(), &[ &[], &['a'], &['b'], &['a', 'b'], &['c'], &['a', 'c'], &['b', 'c'], &['a', 'b', 'c'], &['d'], &['a', 'd'], &['b', 'd'], &['a', 'b', 'd'], &['c', 'd'], &['a', 'c', 'd'], &['b', 'c', 'd'], &['a', 'b', 'c', 'd'], &['e'], &['a', 'e'], &['b', 'e'], &['a', 'b', 'e'], ], ); exhaustive_ordered_unique_vecs_min_length_helper( 3, exhaustive_ascii_chars(), &[ &['a', 'b', 'c'], &['a', 'b', 'd'], &['a', 'c', 'd'], &['b', 'c', 'd'], &['a', 'b', 'c', 'd'], &['a', 'b', 'e'], &['a', 'c', 'e'], &['b', 'c', 'e'], &['a', 'b', 'c', 'e'], &['a', 'd', 'e'], &['b', 'd', 'e'], &['a', 'b', 'd', 'e'], &['c', 'd', 'e'], &['a', 'c', 'd', 'e'], &['b', 'c', 'd', 'e'], &['a', 'b', 'c', 'd', 'e'], &['a', 'b', 'f'], &['a', 'c', 'f'], &['b', 'c', 'f'], &['a', 'b', 'c', 'f'], ], ); } malachite-base-0.4.16/tests/vecs/exhaustive/exhaustive_unique_vecs.rs000064400000000000000000000061771046102023000242160ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::test_util::vecs::exhaustive::{ exhaustive_vecs_helper_helper, exhaustive_vecs_small_helper_helper, }; use malachite_base::tuples::exhaustive::exhaustive_units; use malachite_base::vecs::exhaustive::exhaustive_unique_vecs; use std::fmt::Debug; fn exhaustive_unique_vecs_helper(xs: I, out: &[&[I::Item]]) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_helper_helper(exhaustive_unique_vecs(xs), out); } fn exhaustive_unique_vecs_small_helper( xs: I, out_len: usize, out: &[&[I::Item]], ) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_small_helper_helper(exhaustive_unique_vecs(xs), out_len, out); } #[test] fn test_exhaustive_unique_vecs() { exhaustive_unique_vecs_small_helper(nevers(), 1, &[&[]]); exhaustive_unique_vecs_small_helper(exhaustive_units(), 2, &[&[], &[()]]); exhaustive_unique_vecs_small_helper( exhaustive_bools(), 5, &[&[], &[false], &[true], &[false, true], &[true, false]], ); exhaustive_unique_vecs_small_helper( 1..=6, 1957, &[ &[], &[1], &[2], &[3], &[1, 2], &[1, 3], &[2, 1], &[1, 2, 3], &[3, 1], &[2, 3], &[3, 2], &[4], &[1, 3, 2], &[1, 4], &[2, 1, 3], &[3, 4], &[2, 3, 1], &[4, 1], &[3, 1, 2], &[2, 4], ], ); exhaustive_unique_vecs_small_helper( 'a'..='c', 16, &[ &[], &['a'], &['b'], &['c'], &['a', 'b'], &['a', 'c'], &['b', 'a'], &['a', 'b', 'c'], &['c', 'a'], &['b', 'c'], &['c', 'b'], &['a', 'c', 'b'], &['b', 'a', 'c'], &['b', 'c', 'a'], &['c', 'a', 'b'], &['c', 'b', 'a'], ], ); exhaustive_unique_vecs_helper( exhaustive_ascii_chars(), &[ &[], &['a'], &['b'], &['c'], &['a', 'b'], &['a', 'c'], &['b', 'a'], &['a', 'b', 'c'], &['c', 'a'], &['b', 'c'], &['c', 'b'], &['d'], &['a', 'c', 'b'], &['a', 'd'], &['b', 'a', 'c'], &['c', 'd'], &['b', 'c', 'a'], &['d', 'a'], &['c', 'a', 'b'], &['b', 'd'], ], ); } malachite-base-0.4.16/tests/vecs/exhaustive/exhaustive_unique_vecs_fixed_length.rs000064400000000000000000000154651046102023000267360ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::num::exhaustive::exhaustive_unsigneds; use malachite_base::test_util::vecs::exhaustive::{ exhaustive_vecs_helper_helper, exhaustive_vecs_small_helper_helper, }; use malachite_base::tuples::exhaustive::exhaustive_units; use malachite_base::vecs::exhaustive::exhaustive_unique_vecs_fixed_length; use std::fmt::Debug; fn exhaustive_unique_vecs_fixed_length_helper(len: u64, xs: I, out: &[&[I::Item]]) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_helper_helper(exhaustive_unique_vecs_fixed_length(len, xs), out); } fn exhaustive_unique_vecs_fixed_length_small_helper( len: u64, xs: I, out_len: usize, out: &[&[I::Item]], ) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_small_helper_helper(exhaustive_unique_vecs_fixed_length(len, xs), out_len, out); } #[test] fn test_exhaustive_unique_vecs_fixed_length() { // This demonstrates that 0 ^ 0 == 1: exhaustive_unique_vecs_fixed_length_small_helper(0, nevers(), 1, &[&[]]); exhaustive_unique_vecs_fixed_length_small_helper(1, nevers(), 0, &[]); exhaustive_unique_vecs_fixed_length_small_helper(2, nevers(), 0, &[]); exhaustive_unique_vecs_fixed_length_small_helper(5, nevers(), 0, &[]); exhaustive_unique_vecs_fixed_length_small_helper(1, exhaustive_units(), 1, &[&[()]]); exhaustive_unique_vecs_fixed_length_small_helper(2, exhaustive_units(), 0, &[]); exhaustive_unique_vecs_fixed_length_small_helper(5, exhaustive_units(), 0, &[]); exhaustive_unique_vecs_fixed_length_small_helper(0, exhaustive_unsigneds::(), 1, &[&[]]); exhaustive_unique_vecs_fixed_length_small_helper( 1, exhaustive_unsigneds::(), 256, &[ &[0], &[1], &[2], &[3], &[4], &[5], &[6], &[7], &[8], &[9], &[10], &[11], &[12], &[13], &[14], &[15], &[16], &[17], &[18], &[19], ], ); exhaustive_unique_vecs_fixed_length_helper( 1, exhaustive_unsigneds::(), &[ &[0], &[1], &[2], &[3], &[4], &[5], &[6], &[7], &[8], &[9], &[10], &[11], &[12], &[13], &[14], &[15], &[16], &[17], &[18], &[19], ], ); exhaustive_unique_vecs_fixed_length_small_helper( 2, exhaustive_unsigneds::(), 65280, &[ &[0, 1], &[1, 0], &[0, 2], &[2, 0], &[1, 2], &[2, 1], &[0, 3], &[3, 0], &[1, 3], &[3, 1], &[2, 3], &[3, 2], &[0, 4], &[4, 0], &[1, 4], &[4, 1], &[2, 4], &[4, 2], &[3, 4], &[4, 3], ], ); exhaustive_unique_vecs_fixed_length_helper( 3, exhaustive_unsigneds::(), &[ &[0, 1, 2], &[0, 1, 3], &[0, 2, 1], &[0, 2, 3], &[1, 0, 2], &[0, 3, 1], &[1, 2, 0], &[1, 2, 3], &[2, 0, 1], &[1, 0, 3], &[2, 1, 0], &[0, 3, 2], &[1, 3, 0], &[2, 0, 3], &[3, 0, 1], &[0, 2, 4], &[3, 1, 0], &[2, 3, 0], &[3, 0, 2], &[0, 1, 4], ], ); exhaustive_unique_vecs_fixed_length_small_helper( 2, exhaustive_ascii_chars(), 16256, &[ &['a', 'b'], &['b', 'a'], &['a', 'c'], &['c', 'a'], &['b', 'c'], &['c', 'b'], &['a', 'd'], &['d', 'a'], &['b', 'd'], &['d', 'b'], &['c', 'd'], &['d', 'c'], &['a', 'e'], &['e', 'a'], &['b', 'e'], &['e', 'b'], &['c', 'e'], &['e', 'c'], &['d', 'e'], &['e', 'd'], ], ); exhaustive_unique_vecs_fixed_length_small_helper( 1, exhaustive_bools(), 2, &[&[false], &[true]], ); exhaustive_unique_vecs_fixed_length_small_helper( 2, exhaustive_bools(), 2, &[&[false, true], &[true, false]], ); exhaustive_unique_vecs_fixed_length_small_helper(4, exhaustive_bools(), 0, &[]); exhaustive_unique_vecs_fixed_length_small_helper( 4, 1..=6, 360, &[ &[1, 2, 3, 4], &[1, 2, 3, 5], &[1, 2, 4, 3], &[1, 2, 4, 5], &[1, 3, 2, 4], &[1, 2, 5, 3], &[1, 3, 4, 2], &[1, 3, 4, 5], &[1, 4, 2, 3], &[1, 3, 2, 5], &[1, 4, 3, 2], &[1, 2, 5, 4], &[2, 1, 3, 4], &[1, 3, 5, 2], &[2, 1, 4, 3], &[2, 3, 4, 5], &[2, 3, 1, 4], &[1, 5, 2, 3], &[2, 3, 4, 1], &[1, 4, 2, 5], ], ); exhaustive_unique_vecs_fixed_length_helper( 2, exhaustive_unique_vecs_fixed_length(2, exhaustive_unsigneds::()), &[ &[vec![0, 1], vec![1, 0]], &[vec![1, 0], vec![0, 1]], &[vec![0, 1], vec![0, 2]], &[vec![0, 2], vec![0, 1]], &[vec![1, 0], vec![0, 2]], &[vec![0, 2], vec![1, 0]], &[vec![0, 1], vec![2, 0]], &[vec![2, 0], vec![0, 1]], &[vec![1, 0], vec![2, 0]], &[vec![2, 0], vec![1, 0]], &[vec![0, 2], vec![2, 0]], &[vec![2, 0], vec![0, 2]], &[vec![0, 1], vec![1, 2]], &[vec![1, 2], vec![0, 1]], &[vec![1, 0], vec![1, 2]], &[vec![1, 2], vec![1, 0]], &[vec![0, 2], vec![1, 2]], &[vec![1, 2], vec![0, 2]], &[vec![2, 0], vec![1, 2]], &[vec![1, 2], vec![2, 0]], ], ); } malachite-base-0.4.16/tests/vecs/exhaustive/exhaustive_unique_vecs_length_inclusive_range.rs000064400000000000000000000040301046102023000307760ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::nevers::nevers; use malachite_base::test_util::vecs::exhaustive::exhaustive_vecs_small_helper_helper; use malachite_base::tuples::exhaustive::exhaustive_units; use malachite_base::vecs::exhaustive::exhaustive_unique_vecs_length_inclusive_range; use std::fmt::Debug; fn exhaustive_unique_vecs_length_inclusive_range_small_helper( a: u64, b: u64, xs: I, out_len: usize, out: &[&[I::Item]], ) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_small_helper_helper( exhaustive_unique_vecs_length_inclusive_range(a, b, xs), out_len, out, ); } #[test] fn test_exhaustive_unique_vecs_length_inclusive_range() { exhaustive_unique_vecs_length_inclusive_range_small_helper(0, 4, nevers(), 1, &[&[]]); exhaustive_unique_vecs_length_inclusive_range_small_helper(6, 9, nevers(), 0, &[]); exhaustive_unique_vecs_length_inclusive_range_small_helper( 0, 4, exhaustive_units(), 2, &[&[], &[()]], ); exhaustive_unique_vecs_length_inclusive_range_small_helper(1, 0, exhaustive_bools(), 0, &[]); exhaustive_unique_vecs_length_inclusive_range_small_helper( 0, 1, exhaustive_bools(), 3, &[&[], &[false], &[true]], ); exhaustive_unique_vecs_length_inclusive_range_small_helper( 2, 3, exhaustive_bools(), 2, &[&[false, true], &[true, false]], ); exhaustive_unique_vecs_length_inclusive_range_small_helper( 1, 1, 'a'..='c', 3, &[&['a'], &['b'], &['c']], ); } malachite-base-0.4.16/tests/vecs/exhaustive/exhaustive_unique_vecs_length_range.rs000064400000000000000000000036451046102023000267300ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::nevers::nevers; use malachite_base::test_util::vecs::exhaustive::exhaustive_vecs_small_helper_helper; use malachite_base::tuples::exhaustive::exhaustive_units; use malachite_base::vecs::exhaustive::exhaustive_unique_vecs_length_range; use std::fmt::Debug; fn exhaustive_unique_vecs_length_range_small_helper( a: u64, b: u64, xs: I, out_len: usize, out: &[&[I::Item]], ) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_small_helper_helper( exhaustive_unique_vecs_length_range(a, b, xs), out_len, out, ); } #[test] fn test_exhaustive_unique_vecs_length_range() { exhaustive_unique_vecs_length_range_small_helper(0, 5, nevers(), 1, &[&[]]); exhaustive_unique_vecs_length_range_small_helper(6, 10, nevers(), 0, &[]); exhaustive_unique_vecs_length_range_small_helper(0, 5, exhaustive_units(), 2, &[&[], &[()]]); exhaustive_unique_vecs_length_range_small_helper(1, 0, exhaustive_bools(), 0, &[]); exhaustive_unique_vecs_length_range_small_helper(1, 1, exhaustive_bools(), 0, &[]); exhaustive_unique_vecs_length_range_small_helper( 0, 2, exhaustive_bools(), 3, &[&[], &[false], &[true]], ); exhaustive_unique_vecs_length_range_small_helper( 2, 4, exhaustive_bools(), 2, &[&[false, true], &[true, false]], ); exhaustive_unique_vecs_length_range_small_helper(1, 2, 'a'..='c', 3, &[&['a'], &['b'], &['c']]); } malachite-base-0.4.16/tests/vecs/exhaustive/exhaustive_unique_vecs_min_length.rs000064400000000000000000000105461046102023000264150ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::test_util::vecs::exhaustive::{ exhaustive_vecs_helper_helper, exhaustive_vecs_small_helper_helper, }; use malachite_base::tuples::exhaustive::exhaustive_units; use malachite_base::vecs::exhaustive::exhaustive_unique_vecs_min_length; use std::fmt::Debug; fn exhaustive_unique_vecs_min_length_helper( min_length: u64, xs: I, out: &[&[I::Item]], ) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_helper_helper(exhaustive_unique_vecs_min_length(min_length, xs), out); } fn exhaustive_unique_vecs_min_length_small_helper( min_length: u64, xs: I, out_len: usize, out: &[&[I::Item]], ) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_small_helper_helper( exhaustive_unique_vecs_min_length(min_length, xs), out_len, out, ); } #[test] fn test_exhaustive_unique_vecs_min_length() { exhaustive_unique_vecs_min_length_small_helper(0, nevers(), 1, &[&[]]); exhaustive_unique_vecs_min_length_small_helper(4, nevers(), 0, &[]); exhaustive_unique_vecs_min_length_small_helper(0, exhaustive_units(), 2, &[&[], &[()]]); exhaustive_unique_vecs_min_length_small_helper(5, exhaustive_units(), 0, &[]); exhaustive_unique_vecs_min_length_small_helper( 0, exhaustive_bools(), 5, &[&[], &[false], &[true], &[false, true], &[true, false]], ); exhaustive_unique_vecs_min_length_small_helper( 1, exhaustive_bools(), 4, &[&[false], &[true], &[false, true], &[true, false]], ); exhaustive_unique_vecs_min_length_small_helper( 0, 'a'..='c', 16, &[ &[], &['a'], &['b'], &['c'], &['a', 'b'], &['a', 'c'], &['b', 'a'], &['a', 'b', 'c'], &['c', 'a'], &['b', 'c'], &['c', 'b'], &['a', 'c', 'b'], &['b', 'a', 'c'], &['b', 'c', 'a'], &['c', 'a', 'b'], &['c', 'b', 'a'], ], ); exhaustive_unique_vecs_min_length_small_helper( 2, 'a'..='c', 12, &[ &['a', 'b'], &['a', 'c'], &['b', 'a'], &['b', 'c'], &['c', 'a'], &['c', 'b'], &['a', 'b', 'c'], &['a', 'c', 'b'], &['b', 'a', 'c'], &['b', 'c', 'a'], &['c', 'a', 'b'], &['c', 'b', 'a'], ], ); exhaustive_unique_vecs_min_length_helper( 0, exhaustive_ascii_chars(), &[ &[], &['a'], &['b'], &['c'], &['a', 'b'], &['a', 'c'], &['b', 'a'], &['a', 'b', 'c'], &['c', 'a'], &['b', 'c'], &['c', 'b'], &['d'], &['a', 'c', 'b'], &['a', 'd'], &['b', 'a', 'c'], &['c', 'd'], &['b', 'c', 'a'], &['d', 'a'], &['c', 'a', 'b'], &['b', 'd'], ], ); exhaustive_unique_vecs_min_length_helper( 3, exhaustive_ascii_chars(), &[ &['a', 'b', 'c'], &['a', 'b', 'd'], &['a', 'c', 'b'], &['a', 'c', 'd'], &['b', 'a', 'c'], &['a', 'd', 'b'], &['b', 'c', 'a'], &['b', 'c', 'd'], &['c', 'a', 'b'], &['b', 'a', 'd'], &['c', 'b', 'a'], &['a', 'd', 'c'], &['b', 'd', 'a'], &['c', 'a', 'd'], &['d', 'a', 'b'], &['a', 'b', 'e'], &['d', 'b', 'a'], &['c', 'd', 'a'], &['d', 'a', 'c'], &['a', 'b', 'c', 'd'], ], ); } malachite-base-0.4.16/tests/vecs/exhaustive/exhaustive_vecs.rs000064400000000000000000000111511046102023000226140ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::num::exhaustive::exhaustive_unsigneds; use malachite_base::test_util::vecs::exhaustive::exhaustive_vecs_helper_helper; use malachite_base::tuples::exhaustive::exhaustive_units; use malachite_base::vecs::exhaustive::exhaustive_vecs; use std::fmt::Debug; fn exhaustive_vecs_helper(xs: I, out: &[&[I::Item]]) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_helper_helper(exhaustive_vecs(xs), out); } #[test] fn test_exhaustive_vecs() { exhaustive_vecs_helper(nevers(), &[&[]]); exhaustive_vecs_helper( exhaustive_units(), &[ &[], &[()], &[(), ()], &[(), (), (), ()], &[(), (), ()], &[(), (), (), (), ()], &[(), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), ()], ], ); exhaustive_vecs_helper( exhaustive_bools(), &[ &[], &[false], &[true], &[false, false, false], &[false, false], &[false, false, true], &[false, true], &[false, false, false, false, false], &[true, false], &[false, true, false], &[true, true], &[false, false, false, false], &[false, true, true], &[false, false, false, true], &[true, false, false], &[false, false, false, false, false, false, false], &[true, false, true], &[false, false, true, false], &[true, true, false], &[false, false, false, false, true], ], ); exhaustive_vecs_helper( 'a'..='c', &[ &[], &['a'], &['b'], &['a', 'a', 'a'], &['c'], &['a', 'a'], &['a', 'b'], &['a', 'a', 'a', 'a', 'a'], &['b', 'a'], &['a', 'a', 'b'], &['b', 'b'], &['a', 'a', 'a', 'a'], &['a', 'c'], &['a', 'b', 'a'], &['b', 'c'], &['a', 'a', 'a', 'a', 'a', 'a'], &['c', 'a'], &['a', 'b', 'b'], &['c', 'b'], &['a', 'a', 'a', 'b'], ], ); exhaustive_vecs_helper( exhaustive_ascii_chars(), &[ &[], &['a'], &['b'], &['a', 'a', 'a'], &['c'], &['a', 'a'], &['d'], &['a', 'a', 'a', 'a'], &['e'], &['a', 'b'], &['f'], &['a', 'a', 'b'], &['g'], &['b', 'a'], &['h'], &['a', 'a', 'a', 'a', 'a'], &['i'], &['b', 'b'], &['j'], &['a', 'b', 'a'], ], ); exhaustive_vecs_helper( exhaustive_unsigneds::(), &[ &[], &[0], &[1], &[0, 0, 0], &[2], &[0, 0], &[3], &[0, 0, 0, 0], &[4], &[0, 1], &[5], &[0, 0, 1], &[6], &[1, 0], &[7], &[0, 0, 0, 0, 0], &[8], &[1, 1], &[9], &[0, 1, 0], ], ); } malachite-base-0.4.16/tests/vecs/exhaustive/exhaustive_vecs_fixed_length_from_single.rs000064400000000000000000000235411046102023000277260ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::num::exhaustive::exhaustive_unsigneds; use malachite_base::test_util::vecs::exhaustive::{ exhaustive_vecs_helper_helper, exhaustive_vecs_small_helper_helper, }; use malachite_base::tuples::exhaustive::exhaustive_units; use malachite_base::vecs::exhaustive::exhaustive_vecs_fixed_length_from_single; use std::fmt::Debug; fn exhaustive_vecs_fixed_length_from_single_helper(len: u64, xs: I, out: &[&[I::Item]]) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_helper_helper(exhaustive_vecs_fixed_length_from_single(len, xs), out); } fn exhaustive_vecs_fixed_length_from_single_small_helper( len: u64, xs: I, out_len: usize, out: &[&[I::Item]], ) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_small_helper_helper( exhaustive_vecs_fixed_length_from_single(len, xs), out_len, out, ); } #[test] fn test_exhaustive_vecs_fixed_length_from_single() { // This demonstrates that 0 ^ 0 == 1: exhaustive_vecs_fixed_length_from_single_small_helper(0, nevers(), 1, &[&[]]); exhaustive_vecs_fixed_length_from_single_small_helper(1, nevers(), 0, &[]); exhaustive_vecs_fixed_length_from_single_small_helper(2, nevers(), 0, &[]); exhaustive_vecs_fixed_length_from_single_small_helper(5, nevers(), 0, &[]); exhaustive_vecs_fixed_length_from_single_small_helper(1, exhaustive_units(), 1, &[&[()]]); exhaustive_vecs_fixed_length_from_single_small_helper(2, exhaustive_units(), 1, &[&[(), ()]]); exhaustive_vecs_fixed_length_from_single_small_helper(5, exhaustive_units(), 1, &[&[(); 5]]); exhaustive_vecs_fixed_length_from_single_small_helper( 0, exhaustive_unsigneds::(), 1, &[&[]], ); exhaustive_vecs_fixed_length_from_single_small_helper( 1, exhaustive_unsigneds::(), 256, &[ &[0], &[1], &[2], &[3], &[4], &[5], &[6], &[7], &[8], &[9], &[10], &[11], &[12], &[13], &[14], &[15], &[16], &[17], &[18], &[19], ], ); exhaustive_vecs_fixed_length_from_single_helper( 1, exhaustive_unsigneds::(), &[ &[0], &[1], &[2], &[3], &[4], &[5], &[6], &[7], &[8], &[9], &[10], &[11], &[12], &[13], &[14], &[15], &[16], &[17], &[18], &[19], ], ); exhaustive_vecs_fixed_length_from_single_small_helper( 2, exhaustive_unsigneds::(), 0x10000, &[ &[0, 0], &[0, 1], &[1, 0], &[1, 1], &[0, 2], &[0, 3], &[1, 2], &[1, 3], &[2, 0], &[2, 1], &[3, 0], &[3, 1], &[2, 2], &[2, 3], &[3, 2], &[3, 3], &[0, 4], &[0, 5], &[1, 4], &[1, 5], ], ); exhaustive_vecs_fixed_length_from_single_helper( 3, exhaustive_unsigneds::(), &[ &[0, 0, 0], &[0, 0, 1], &[0, 1, 0], &[0, 1, 1], &[1, 0, 0], &[1, 0, 1], &[1, 1, 0], &[1, 1, 1], &[0, 0, 2], &[0, 0, 3], &[0, 1, 2], &[0, 1, 3], &[1, 0, 2], &[1, 0, 3], &[1, 1, 2], &[1, 1, 3], &[0, 2, 0], &[0, 2, 1], &[0, 3, 0], &[0, 3, 1], ], ); exhaustive_vecs_fixed_length_from_single_small_helper( 2, exhaustive_ascii_chars(), 0x4000, &[ &['a', 'a'], &['a', 'b'], &['b', 'a'], &['b', 'b'], &['a', 'c'], &['a', 'd'], &['b', 'c'], &['b', 'd'], &['c', 'a'], &['c', 'b'], &['d', 'a'], &['d', 'b'], &['c', 'c'], &['c', 'd'], &['d', 'c'], &['d', 'd'], &['a', 'e'], &['a', 'f'], &['b', 'e'], &['b', 'f'], ], ); exhaustive_vecs_fixed_length_from_single_small_helper( 1, exhaustive_bools(), 2, &[&[false], &[true]], ); exhaustive_vecs_fixed_length_from_single_small_helper( 2, exhaustive_bools(), 4, &[&[false, false], &[false, true], &[true, false], &[true, true]], ); exhaustive_vecs_fixed_length_from_single_small_helper( 4, exhaustive_bools(), 16, &[ &[false, false, false, false], &[false, false, false, true], &[false, false, true, false], &[false, false, true, true], &[false, true, false, false], &[false, true, false, true], &[false, true, true, false], &[false, true, true, true], &[true, false, false, false], &[true, false, false, true], &[true, false, true, false], &[true, false, true, true], &[true, true, false, false], &[true, true, false, true], &[true, true, true, false], &[true, true, true, true], ], ); exhaustive_vecs_fixed_length_from_single_small_helper( 10, exhaustive_bools(), 1024, &[ &[false, false, false, false, false, false, false, false, false, false], &[false, false, false, false, false, false, false, false, false, true], &[false, false, false, false, false, false, false, false, true, false], &[false, false, false, false, false, false, false, false, true, true], &[false, false, false, false, false, false, false, true, false, false], &[false, false, false, false, false, false, false, true, false, true], &[false, false, false, false, false, false, false, true, true, false], &[false, false, false, false, false, false, false, true, true, true], &[false, false, false, false, false, false, true, false, false, false], &[false, false, false, false, false, false, true, false, false, true], &[false, false, false, false, false, false, true, false, true, false], &[false, false, false, false, false, false, true, false, true, true], &[false, false, false, false, false, false, true, true, false, false], &[false, false, false, false, false, false, true, true, false, true], &[false, false, false, false, false, false, true, true, true, false], &[false, false, false, false, false, false, true, true, true, true], &[false, false, false, false, false, true, false, false, false, false], &[false, false, false, false, false, true, false, false, false, true], &[false, false, false, false, false, true, false, false, true, false], &[false, false, false, false, false, true, false, false, true, true], ], ); exhaustive_vecs_fixed_length_from_single_small_helper( 10, 0..3, 59049, &[ &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], &[0, 0, 0, 0, 0, 0, 0, 0, 0, 1], &[0, 0, 0, 0, 0, 0, 0, 0, 1, 0], &[0, 0, 0, 0, 0, 0, 0, 0, 1, 1], &[0, 0, 0, 0, 0, 0, 0, 1, 0, 0], &[0, 0, 0, 0, 0, 0, 0, 1, 0, 1], &[0, 0, 0, 0, 0, 0, 0, 1, 1, 0], &[0, 0, 0, 0, 0, 0, 0, 1, 1, 1], &[0, 0, 0, 0, 0, 0, 1, 0, 0, 0], &[0, 0, 0, 0, 0, 0, 1, 0, 0, 1], &[0, 0, 0, 0, 0, 0, 1, 0, 1, 0], &[0, 0, 0, 0, 0, 0, 1, 0, 1, 1], &[0, 0, 0, 0, 0, 0, 1, 1, 0, 0], &[0, 0, 0, 0, 0, 0, 1, 1, 0, 1], &[0, 0, 0, 0, 0, 0, 1, 1, 1, 0], &[0, 0, 0, 0, 0, 0, 1, 1, 1, 1], &[0, 0, 0, 0, 0, 1, 0, 0, 0, 0], &[0, 0, 0, 0, 0, 1, 0, 0, 0, 1], &[0, 0, 0, 0, 0, 1, 0, 0, 1, 0], &[0, 0, 0, 0, 0, 1, 0, 0, 1, 1], ], ); exhaustive_vecs_fixed_length_from_single_helper( 2, exhaustive_vecs_fixed_length_from_single(2, exhaustive_unsigneds::()), &[ &[vec![0, 0], vec![0, 0]], &[vec![0, 0], vec![0, 1]], &[vec![0, 1], vec![0, 0]], &[vec![0, 1], vec![0, 1]], &[vec![0, 0], vec![1, 0]], &[vec![0, 0], vec![1, 1]], &[vec![0, 1], vec![1, 0]], &[vec![0, 1], vec![1, 1]], &[vec![1, 0], vec![0, 0]], &[vec![1, 0], vec![0, 1]], &[vec![1, 1], vec![0, 0]], &[vec![1, 1], vec![0, 1]], &[vec![1, 0], vec![1, 0]], &[vec![1, 0], vec![1, 1]], &[vec![1, 1], vec![1, 0]], &[vec![1, 1], vec![1, 1]], &[vec![0, 0], vec![0, 2]], &[vec![0, 0], vec![0, 3]], &[vec![0, 1], vec![0, 2]], &[vec![0, 1], vec![0, 3]], ], ); } malachite-base-0.4.16/tests/vecs/exhaustive/exhaustive_vecs_fixed_length_m_inputs.rs000064400000000000000000000243351046102023000272620ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::get_sample_output_types; use itertools::Itertools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::iterators::bit_distributor::BitDistributorOutputType; use malachite_base::nevers::nevers; use malachite_base::num::exhaustive::{exhaustive_positive_primitive_ints, exhaustive_unsigneds}; use malachite_base::vecs::exhaustive::{ exhaustive_vecs_fixed_length_1_input, exhaustive_vecs_fixed_length_2_inputs, }; use std::fmt::Debug; use std::iter::empty; fn exhaustive_vecs_fixed_length_1_input_helper>( xs: &I, len: usize, out_len: Option, out: &[&[T]], ) where T: Clone + Debug + Eq, { let output_types = get_sample_output_types(len); let xss = exhaustive_vecs_fixed_length_1_input(xs.clone(), &output_types[0]); let xss_prefix = xss.clone().take(20).collect_vec(); assert_eq!( xss_prefix .iter() .map(Vec::as_slice) .collect_vec() .as_slice(), out ); if let Some(out_len) = out_len { assert_eq!(xss.count(), out_len); } for alt_output_types in &output_types[1..] { let xss = exhaustive_vecs_fixed_length_1_input(xs.clone(), alt_output_types); xss.clone().take(20).for_each(drop); if let Some(out_len) = out_len { assert_eq!(xss.count(), out_len); } } } #[test] fn test_exhaustive_vecs_fixed_length_1_input() { exhaustive_vecs_fixed_length_1_input_helper(&nevers(), 2, Some(0), &[]); exhaustive_vecs_fixed_length_1_input_helper( &exhaustive_unsigneds::(), 2, Some(1 << 16), &[ &[0, 0], &[0, 1], &[1, 0], &[1, 1], &[0, 2], &[0, 3], &[1, 2], &[1, 3], &[2, 0], &[2, 1], &[3, 0], &[3, 1], &[2, 2], &[2, 3], &[3, 2], &[3, 3], &[0, 4], &[0, 5], &[1, 4], &[1, 5], ], ); exhaustive_vecs_fixed_length_1_input_helper( &exhaustive_positive_primitive_ints::(), 2, None, &[ &[1, 1], &[1, 2], &[2, 1], &[2, 2], &[1, 3], &[1, 4], &[2, 3], &[2, 4], &[3, 1], &[3, 2], &[4, 1], &[4, 2], &[3, 3], &[3, 4], &[4, 3], &[4, 4], &[1, 5], &[1, 6], &[2, 5], &[2, 6], ], ); exhaustive_vecs_fixed_length_1_input_helper( &['x', 'y', 'z'].iter().copied(), 2, Some(9), &[ &['x', 'x'], &['x', 'y'], &['y', 'x'], &['y', 'y'], &['x', 'z'], &['y', 'z'], &['z', 'x'], &['z', 'y'], &['z', 'z'], ], ); exhaustive_vecs_fixed_length_1_input_helper( &['x', 'y', 'z'].iter().copied(), 3, Some(27), &[ &['x', 'x', 'x'], &['x', 'x', 'y'], &['x', 'y', 'x'], &['x', 'y', 'y'], &['y', 'x', 'x'], &['y', 'x', 'y'], &['y', 'y', 'x'], &['y', 'y', 'y'], &['x', 'x', 'z'], &['x', 'y', 'z'], &['y', 'x', 'z'], &['y', 'y', 'z'], &['x', 'z', 'x'], &['x', 'z', 'y'], &['y', 'z', 'x'], &['y', 'z', 'y'], &['x', 'z', 'z'], &['y', 'z', 'z'], &['z', 'x', 'x'], &['z', 'x', 'y'], ], ); exhaustive_vecs_fixed_length_1_input_helper( &exhaustive_ascii_chars(), 3, None, &[ &['a', 'a', 'a'], &['a', 'a', 'b'], &['a', 'b', 'a'], &['a', 'b', 'b'], &['b', 'a', 'a'], &['b', 'a', 'b'], &['b', 'b', 'a'], &['b', 'b', 'b'], &['a', 'a', 'c'], &['a', 'a', 'd'], &['a', 'b', 'c'], &['a', 'b', 'd'], &['b', 'a', 'c'], &['b', 'a', 'd'], &['b', 'b', 'c'], &['b', 'b', 'd'], &['a', 'c', 'a'], &['a', 'c', 'b'], &['a', 'd', 'a'], &['a', 'd', 'b'], ], ); } fn exhaustive_vecs_fixed_length_2_inputs_helper< T, I: Clone + Iterator, J: Clone + Iterator, >( xs: &I, ys: &J, len: usize, input_indices: &[usize], out_len: Option, out: &[&[T]], ) where T: Clone + Debug + Eq, { let output_types = get_sample_output_types(len); let output_configs: Vec<(BitDistributorOutputType, usize)> = output_types[0] .iter() .copied() .zip(input_indices.iter().copied()) .collect(); let xss = exhaustive_vecs_fixed_length_2_inputs(xs.clone(), ys.clone(), &output_configs); let xss_prefix = xss.clone().take(20).collect_vec(); assert_eq!( xss_prefix .iter() .map(Vec::as_slice) .collect_vec() .as_slice(), out ); if let Some(out_len) = out_len { assert_eq!(xss.count(), out_len); } for alt_output_types in &output_types[1..] { let output_configs: Vec<(BitDistributorOutputType, usize)> = alt_output_types .iter() .copied() .zip(input_indices.iter().copied()) .collect(); let xss = exhaustive_vecs_fixed_length_2_inputs(xs.clone(), ys.clone(), &output_configs); xss.clone().take(20).for_each(drop); if let Some(out_len) = out_len { assert_eq!(xss.count(), out_len); } } } #[test] fn test_exhaustive_vecs_fixed_length_2_inputs() { exhaustive_vecs_fixed_length_2_inputs_helper(&nevers(), &nevers(), 2, &[0, 1], Some(0), &[]); exhaustive_vecs_fixed_length_2_inputs_helper( &empty(), &exhaustive_unsigneds::(), 2, &[0, 1], Some(0), &[], ); exhaustive_vecs_fixed_length_2_inputs_helper( &exhaustive_unsigneds::(), &exhaustive_positive_primitive_ints::(), 2, &[0, 1], None, &[ &[0, 1], &[0, 2], &[1, 1], &[1, 2], &[0, 3], &[0, 4], &[1, 3], &[1, 4], &[2, 1], &[2, 2], &[3, 1], &[3, 2], &[2, 3], &[2, 4], &[3, 3], &[3, 4], &[0, 5], &[0, 6], &[1, 5], &[1, 6], ], ); exhaustive_vecs_fixed_length_2_inputs_helper( &exhaustive_ascii_chars(), &['x', 'y', 'z'].iter().copied(), 2, &[0, 1], Some(384), &[ &['a', 'x'], &['a', 'y'], &['b', 'x'], &['b', 'y'], &['a', 'z'], &['b', 'z'], &['c', 'x'], &['c', 'y'], &['d', 'x'], &['d', 'y'], &['c', 'z'], &['d', 'z'], &['e', 'x'], &['e', 'y'], &['f', 'x'], &['f', 'y'], &['e', 'z'], &['f', 'z'], &['g', 'x'], &['g', 'y'], ], ); exhaustive_vecs_fixed_length_2_inputs_helper( &exhaustive_ascii_chars(), &['x', 'y', 'z'].iter().copied(), 3, &[0, 1, 1], Some(1152), &[ &['a', 'x', 'x'], &['a', 'x', 'y'], &['a', 'y', 'x'], &['a', 'y', 'y'], &['b', 'x', 'x'], &['b', 'x', 'y'], &['b', 'y', 'x'], &['b', 'y', 'y'], &['a', 'x', 'z'], &['a', 'y', 'z'], &['b', 'x', 'z'], &['b', 'y', 'z'], &['a', 'z', 'x'], &['a', 'z', 'y'], &['b', 'z', 'x'], &['b', 'z', 'y'], &['a', 'z', 'z'], &['b', 'z', 'z'], &['c', 'x', 'x'], &['c', 'x', 'y'], ], ); exhaustive_vecs_fixed_length_2_inputs_helper( &exhaustive_ascii_chars(), &['x', 'y', 'z'].iter().copied(), 3, &[0, 1, 0], Some(49152), &[ &['a', 'x', 'a'], &['a', 'x', 'b'], &['a', 'y', 'a'], &['a', 'y', 'b'], &['b', 'x', 'a'], &['b', 'x', 'b'], &['b', 'y', 'a'], &['b', 'y', 'b'], &['a', 'x', 'c'], &['a', 'x', 'd'], &['a', 'y', 'c'], &['a', 'y', 'd'], &['b', 'x', 'c'], &['b', 'x', 'd'], &['b', 'y', 'c'], &['b', 'y', 'd'], &['a', 'z', 'a'], &['a', 'z', 'b'], &['b', 'z', 'a'], &['b', 'z', 'b'], ], ); } #[test] #[should_panic] fn exhaustive_vecs_fixed_length_2_inputs_fail_1() { exhaustive_vecs_fixed_length_2_inputs(0..2, 0..3, &[]); } #[test] #[should_panic] fn exhaustive_vecs_fixed_length_2_inputs_fail_2() { exhaustive_vecs_fixed_length_2_inputs(0..2, 0..3, &[(BitDistributorOutputType::normal(1), 0)]); } #[test] #[should_panic] fn exhaustive_vecs_fixed_length_2_inputs_fail_3() { exhaustive_vecs_fixed_length_2_inputs(0..2, 0..3, &[(BitDistributorOutputType::normal(1), 1)]); } #[test] #[should_panic] fn exhaustive_vecs_fixed_length_2_inputs_fail_4() { exhaustive_vecs_fixed_length_2_inputs( 0..2, 0..3, &[ (BitDistributorOutputType::normal(1), 0), (BitDistributorOutputType::normal(1), 1), (BitDistributorOutputType::normal(1), 2), ], ); } malachite-base-0.4.16/tests/vecs/exhaustive/exhaustive_vecs_from_length_iterator.rs000064400000000000000000000120651046102023000271160ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::nevers::nevers; use malachite_base::num::exhaustive::exhaustive_unsigneds; use malachite_base::test_util::vecs::exhaustive::exhaustive_vecs_helper_helper; use malachite_base::vecs::exhaustive::exhaustive_vecs_from_length_iterator; use std::fmt::Debug; use std::iter::empty; fn exhaustive_vecs_from_element_iterator_helper, J: Clone + Iterator>( lengths: I, xs: J, out: &[&[J::Item]], ) where J::Item: Clone + Debug + Eq, { exhaustive_vecs_helper_helper(exhaustive_vecs_from_length_iterator(lengths, xs), out); } #[test] fn test_exhaustive_vecs_from_element_iterator() { exhaustive_vecs_from_element_iterator_helper(empty(), exhaustive_bools(), &[]); exhaustive_vecs_from_element_iterator_helper( [2, 1, 2].iter().copied(), exhaustive_bools(), &[ &[false, false], &[false], &[false, true], &[false, false], &[true, false], &[true], &[true, true], &[false, true], &[true, false], &[true, true], ], ); exhaustive_vecs_from_element_iterator_helper( exhaustive_unsigneds::().map(|u| u << 1), exhaustive_bools(), &[ &[], &[false, false], &[false, true], &[false, false, false, false, false, false], &[true, false], &[false, false, false, false], &[true, true], &[false, false, false, false, false, false, false, false], &[false, false, false, true], &[false, false, false, false, false, true], &[false, false, true, false], &[false, false, false, false, false, false, false, true], &[false, false, true, true], &[false, false, false, false, true, false], &[false, true, false, false], &[false, false, false, false, false, false, false, false, false, false, false, false], &[false, true, false, true], &[false, false, false, false, true, true], &[false, true, true, false], &[false, false, false, false, false, false, true, false], ], ); exhaustive_vecs_from_element_iterator_helper( [2, 1, 0, 2].iter().copied(), exhaustive_bools(), &[ &[false, false], &[false], &[false, true], &[], &[true, false], &[true], &[true, true], &[false, false], &[false, true], &[true, false], &[true, true], ], ); exhaustive_vecs_from_element_iterator_helper(empty(), exhaustive_unsigneds::(), &[]); exhaustive_vecs_from_element_iterator_helper( [2, 1, 2].iter().copied(), exhaustive_unsigneds::(), &[ &[0, 0], &[0], &[0, 1], &[0, 0], &[1, 0], &[1], &[1, 1], &[0, 2], &[0, 3], &[2], &[1, 2], &[0, 1], &[1, 3], &[3], &[2, 0], &[4], &[2, 1], &[5], &[3, 0], &[1, 0], ], ); exhaustive_vecs_from_element_iterator_helper( exhaustive_unsigneds::().map(|u| u << 1), exhaustive_unsigneds::(), &[ &[], &[0, 0], &[0, 1], &[0, 0, 0, 0, 0, 0], &[1, 0], &[0, 0, 0, 0], &[1, 1], &[0, 0, 0, 0, 0, 0, 0, 0], &[0, 2], &[0, 0, 0, 1], &[0, 3], &[0, 0, 0, 0, 0, 1], &[1, 2], &[0, 0, 1, 0], &[1, 3], &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], &[2, 0], &[0, 0, 1, 1], &[2, 1], &[0, 0, 0, 0, 1, 0], ], ); exhaustive_vecs_from_element_iterator_helper( [2, 1, 0, 2].iter().copied(), exhaustive_unsigneds::(), &[ &[0, 0], &[0], &[0, 1], &[], &[1, 0], &[1], &[1, 1], &[0, 0], &[0, 2], &[2], &[0, 3], &[0, 1], &[1, 2], &[3], &[1, 3], &[4], &[2, 0], &[5], &[2, 1], &[1, 0], ], ); // Stops after first empty ys exhaustive_vecs_from_element_iterator_helper( [0, 0, 1, 0].iter().copied(), nevers(), &[&[], &[]], ); } malachite-base-0.4.16/tests/vecs/exhaustive/exhaustive_vecs_length_inclusive_range.rs000064400000000000000000000105051046102023000274140ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::nevers::nevers; use malachite_base::num::exhaustive::exhaustive_unsigneds; use malachite_base::test_util::vecs::exhaustive::{ exhaustive_vecs_helper_helper, exhaustive_vecs_small_helper_helper, }; use malachite_base::tuples::exhaustive::exhaustive_units; use malachite_base::vecs::exhaustive::exhaustive_vecs_length_inclusive_range; use std::fmt::Debug; fn exhaustive_vecs_length_inclusive_range_helper( a: u64, b: u64, xs: I, out: &[&[I::Item]], ) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_helper_helper(exhaustive_vecs_length_inclusive_range(a, b, xs), out); } fn exhaustive_vecs_length_inclusive_range_small_helper( a: u64, b: u64, xs: I, out_len: usize, out: &[&[I::Item]], ) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_small_helper_helper( exhaustive_vecs_length_inclusive_range(a, b, xs), out_len, out, ); } #[test] fn test_exhaustive_vecs_length_inclusive_range() { exhaustive_vecs_length_inclusive_range_small_helper(0, 4, nevers(), 1, &[&[]]); exhaustive_vecs_length_inclusive_range_small_helper(6, 9, nevers(), 0, &[]); exhaustive_vecs_length_inclusive_range_small_helper(5, 3, exhaustive_bools(), 0, &[]); exhaustive_vecs_length_inclusive_range_small_helper( 0, 4, exhaustive_units(), 5, &[&[], &[()], &[(), ()], &[(), (), (), ()], &[(), (), ()]], ); exhaustive_vecs_length_inclusive_range_small_helper( 1, 1, exhaustive_bools(), 2, &[&[false], &[true]], ); exhaustive_vecs_length_inclusive_range_small_helper( 0, 2, exhaustive_bools(), 7, &[&[], &[false], &[true], &[false, false], &[false, true], &[true, false], &[true, true]], ); exhaustive_vecs_length_inclusive_range_small_helper( 2, 3, exhaustive_bools(), 12, &[ &[false, false], &[false, false, false], &[false, true], &[true, false], &[true, true], &[false, false, true], &[false, true, false], &[false, true, true], &[true, false, false], &[true, false, true], &[true, true, false], &[true, true, true], ], ); exhaustive_vecs_length_inclusive_range_small_helper( 5, 7, 'a'..='c', 3159, &[ &['a', 'a', 'a', 'a', 'a'], &['a', 'a', 'a', 'a', 'a', 'a'], &['a', 'a', 'a', 'a', 'b'], &['a', 'a', 'a', 'a', 'a', 'a', 'a'], &['a', 'a', 'a', 'b', 'a'], &['a', 'a', 'a', 'a', 'a', 'b'], &['a', 'a', 'a', 'b', 'b'], &['a', 'a', 'b', 'a', 'a'], &['a', 'a', 'b', 'a', 'b'], &['a', 'a', 'a', 'a', 'b', 'a'], &['a', 'a', 'b', 'b', 'a'], &['a', 'a', 'a', 'a', 'a', 'a', 'b'], &['a', 'a', 'b', 'b', 'b'], &['a', 'a', 'a', 'a', 'b', 'b'], &['a', 'b', 'a', 'a', 'a'], &['a', 'a', 'a', 'b', 'a', 'a'], &['a', 'b', 'a', 'a', 'b'], &['a', 'a', 'a', 'b', 'a', 'b'], &['a', 'b', 'a', 'b', 'a'], &['a', 'a', 'a', 'a', 'a', 'b', 'a'], ], ); exhaustive_vecs_length_inclusive_range_helper( 2, 3, exhaustive_unsigneds::(), &[ &[0, 0], &[0, 0, 0], &[0, 1], &[1, 0], &[1, 1], &[0, 0, 1], &[0, 2], &[0, 1, 0], &[0, 3], &[0, 1, 1], &[1, 2], &[1, 3], &[2, 0], &[1, 0, 0], &[2, 1], &[3, 0], &[3, 1], &[1, 0, 1], &[2, 2], &[2, 3], ], ); } malachite-base-0.4.16/tests/vecs/exhaustive/exhaustive_vecs_length_n.rs000064400000000000000000000230501046102023000244730ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::extra_variadic::exhaustive_vecs_length_3; use malachite_base::nevers::nevers; use malachite_base::num::exhaustive::exhaustive_unsigneds; use malachite_base::orderings::exhaustive::exhaustive_orderings; use malachite_base::test_util::vecs::exhaustive::{ exhaustive_vecs_helper_helper, exhaustive_vecs_small_helper_helper, }; use malachite_base::vecs::exhaustive::{ exhaustive_vecs_fixed_length_from_single, exhaustive_vecs_length_2, }; use std::cmp::Ordering::*; use std::fmt::Debug; use std::iter::{empty, once}; fn exhaustive_vecs_length_2_helper, J: Iterator>( xs: I, ys: J, out: &[&[T]], ) where T: Clone + Debug + Eq, { exhaustive_vecs_helper_helper(exhaustive_vecs_length_2(xs, ys), out); } fn exhaustive_vecs_length_2_finite_helper< T, I: Clone + Iterator, J: Clone + Iterator, >( xs: I, ys: J, out_len: usize, out: &[&[T]], ) where T: Clone + Debug + Eq, { exhaustive_vecs_small_helper_helper(exhaustive_vecs_length_2(xs, ys), out_len, out); } #[test] fn test_exhaustive_vecs_length_2() { exhaustive_vecs_length_2_finite_helper(nevers(), nevers(), 0, &[]); exhaustive_vecs_length_2_finite_helper(empty(), 0..4, 0, &[]); exhaustive_vecs_length_2_finite_helper(once(0), once(1), 1, &[&[0, 1]]); exhaustive_vecs_length_2_finite_helper(once(0), 0..4, 4, &[&[0, 0], &[0, 1], &[0, 2], &[0, 3]]); exhaustive_vecs_length_2_finite_helper( exhaustive_unsigneds::(), 0..4, 1024, &[ &[0, 0], &[0, 1], &[1, 0], &[1, 1], &[0, 2], &[0, 3], &[1, 2], &[1, 3], &[2, 0], &[2, 1], &[3, 0], &[3, 1], &[2, 2], &[2, 3], &[3, 2], &[3, 3], &[4, 0], &[4, 1], &[5, 0], &[5, 1], ], ); exhaustive_vecs_length_2_helper( exhaustive_unsigneds::(), 0..4, &[ &[0, 0], &[0, 1], &[1, 0], &[1, 1], &[0, 2], &[0, 3], &[1, 2], &[1, 3], &[2, 0], &[2, 1], &[3, 0], &[3, 1], &[2, 2], &[2, 3], &[3, 2], &[3, 3], &[4, 0], &[4, 1], &[5, 0], &[5, 1], ], ); exhaustive_vecs_length_2_finite_helper( 0..2, 0..4, 8, &[&[0, 0], &[0, 1], &[1, 0], &[1, 1], &[0, 2], &[0, 3], &[1, 2], &[1, 3]], ); exhaustive_vecs_length_2_finite_helper( 0..5, 0..3, 15, &[ &[0, 0], &[0, 1], &[1, 0], &[1, 1], &[0, 2], &[1, 2], &[2, 0], &[2, 1], &[3, 0], &[3, 1], &[2, 2], &[3, 2], &[4, 0], &[4, 1], &[4, 2], ], ); exhaustive_vecs_length_2_finite_helper( ['a', 'b', 'c'].iter().copied(), ['x', 'y', 'z'].iter().copied(), 9, &[ &['a', 'x'], &['a', 'y'], &['b', 'x'], &['b', 'y'], &['a', 'z'], &['b', 'z'], &['c', 'x'], &['c', 'y'], &['c', 'z'], ], ); exhaustive_vecs_length_2_finite_helper( exhaustive_vecs_length_2(exhaustive_orderings(), [Less, Greater].iter().copied()), exhaustive_vecs_fixed_length_from_single(3, [Less, Greater].iter().copied()), 48, &[ &[vec![Equal, Less], vec![Less, Less, Less]], &[vec![Equal, Less], vec![Less, Less, Greater]], &[vec![Equal, Greater], vec![Less, Less, Less]], &[vec![Equal, Greater], vec![Less, Less, Greater]], &[vec![Equal, Less], vec![Less, Greater, Less]], &[vec![Equal, Less], vec![Less, Greater, Greater]], &[vec![Equal, Greater], vec![Less, Greater, Less]], &[vec![Equal, Greater], vec![Less, Greater, Greater]], &[vec![Less, Less], vec![Less, Less, Less]], &[vec![Less, Less], vec![Less, Less, Greater]], &[vec![Less, Greater], vec![Less, Less, Less]], &[vec![Less, Greater], vec![Less, Less, Greater]], &[vec![Less, Less], vec![Less, Greater, Less]], &[vec![Less, Less], vec![Less, Greater, Greater]], &[vec![Less, Greater], vec![Less, Greater, Less]], &[vec![Less, Greater], vec![Less, Greater, Greater]], &[vec![Equal, Less], vec![Greater, Less, Less]], &[vec![Equal, Less], vec![Greater, Less, Greater]], &[vec![Equal, Greater], vec![Greater, Less, Less]], &[vec![Equal, Greater], vec![Greater, Less, Greater]], ], ); } fn exhaustive_vecs_length_3_helper< T, I: Iterator, J: Iterator, K: Iterator, >( xs: I, ys: J, zs: K, out: &[&[T]], ) where T: Clone + Debug + Eq, { exhaustive_vecs_helper_helper(exhaustive_vecs_length_3(xs, ys, zs), out); } fn exhaustive_vecs_length_3_finite_helper< T, I: Clone + Iterator, J: Clone + Iterator, K: Clone + Iterator, >( xs: I, ys: J, zs: K, out_len: usize, out: &[&[T]], ) where T: Clone + Debug + Eq, { exhaustive_vecs_small_helper_helper(exhaustive_vecs_length_3(xs, ys, zs), out_len, out); } #[test] fn test_exhaustive_vecs_length_3() { exhaustive_vecs_length_3_finite_helper(nevers(), nevers(), nevers(), 0, &[]); exhaustive_vecs_length_3_finite_helper(empty(), 0..4, 0..5, 0, &[]); exhaustive_vecs_length_3_finite_helper(once(0), once(1), once(5), 1, &[&[0, 1, 5]]); exhaustive_vecs_length_3_finite_helper( once(0), once(3), 0..4, 4, &[&[0, 3, 0], &[0, 3, 1], &[0, 3, 2], &[0, 3, 3]], ); exhaustive_vecs_length_3_finite_helper( exhaustive_unsigneds::(), 0..4, 0..4, 4096, &[ &[0, 0, 0], &[0, 0, 1], &[0, 1, 0], &[0, 1, 1], &[1, 0, 0], &[1, 0, 1], &[1, 1, 0], &[1, 1, 1], &[0, 0, 2], &[0, 0, 3], &[0, 1, 2], &[0, 1, 3], &[1, 0, 2], &[1, 0, 3], &[1, 1, 2], &[1, 1, 3], &[0, 2, 0], &[0, 2, 1], &[0, 3, 0], &[0, 3, 1], ], ); exhaustive_vecs_length_3_helper( exhaustive_unsigneds::(), 0..4, 0..4, &[ &[0, 0, 0], &[0, 0, 1], &[0, 1, 0], &[0, 1, 1], &[1, 0, 0], &[1, 0, 1], &[1, 1, 0], &[1, 1, 1], &[0, 0, 2], &[0, 0, 3], &[0, 1, 2], &[0, 1, 3], &[1, 0, 2], &[1, 0, 3], &[1, 1, 2], &[1, 1, 3], &[0, 2, 0], &[0, 2, 1], &[0, 3, 0], &[0, 3, 1], ], ); exhaustive_vecs_length_3_finite_helper( 0..2, 0..3, 0..3, 18, &[ &[0, 0, 0], &[0, 0, 1], &[0, 1, 0], &[0, 1, 1], &[1, 0, 0], &[1, 0, 1], &[1, 1, 0], &[1, 1, 1], &[0, 0, 2], &[0, 1, 2], &[1, 0, 2], &[1, 1, 2], &[0, 2, 0], &[0, 2, 1], &[1, 2, 0], &[1, 2, 1], &[0, 2, 2], &[1, 2, 2], ], ); exhaustive_vecs_length_3_finite_helper( 0..11, 0..12, 0..13, 1716, &[ &[0, 0, 0], &[0, 0, 1], &[0, 1, 0], &[0, 1, 1], &[1, 0, 0], &[1, 0, 1], &[1, 1, 0], &[1, 1, 1], &[0, 0, 2], &[0, 0, 3], &[0, 1, 2], &[0, 1, 3], &[1, 0, 2], &[1, 0, 3], &[1, 1, 2], &[1, 1, 3], &[0, 2, 0], &[0, 2, 1], &[0, 3, 0], &[0, 3, 1], ], ); exhaustive_vecs_length_3_finite_helper( ['a', 'b', 'c'].iter().copied(), ['x', 'y', 'z'].iter().copied(), ['0', '1', '2'].iter().copied(), 27, &[ &['a', 'x', '0'], &['a', 'x', '1'], &['a', 'y', '0'], &['a', 'y', '1'], &['b', 'x', '0'], &['b', 'x', '1'], &['b', 'y', '0'], &['b', 'y', '1'], &['a', 'x', '2'], &['a', 'y', '2'], &['b', 'x', '2'], &['b', 'y', '2'], &['a', 'z', '0'], &['a', 'z', '1'], &['b', 'z', '0'], &['b', 'z', '1'], &['a', 'z', '2'], &['b', 'z', '2'], &['c', 'x', '0'], &['c', 'x', '1'], ], ); } malachite-base-0.4.16/tests/vecs/exhaustive/exhaustive_vecs_length_range.rs000064400000000000000000000101211046102023000253250ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::nevers::nevers; use malachite_base::num::exhaustive::exhaustive_unsigneds; use malachite_base::test_util::vecs::exhaustive::{ exhaustive_vecs_helper_helper, exhaustive_vecs_small_helper_helper, }; use malachite_base::tuples::exhaustive::exhaustive_units; use malachite_base::vecs::exhaustive::exhaustive_vecs_length_range; use std::fmt::Debug; fn exhaustive_vecs_length_range_helper( a: u64, b: u64, xs: I, out: &[&[I::Item]], ) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_helper_helper(exhaustive_vecs_length_range(a, b, xs), out); } fn exhaustive_vecs_length_range_small_helper( a: u64, b: u64, xs: I, out_len: usize, out: &[&[I::Item]], ) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_small_helper_helper(exhaustive_vecs_length_range(a, b, xs), out_len, out); } #[test] fn test_exhaustive_vecs_length_range() { exhaustive_vecs_length_range_small_helper(0, 5, nevers(), 1, &[&[]]); exhaustive_vecs_length_range_small_helper(6, 10, nevers(), 0, &[]); exhaustive_vecs_length_range_small_helper( 0, 5, exhaustive_units(), 5, &[&[], &[()], &[(), ()], &[(), (), (), ()], &[(), (), ()]], ); exhaustive_vecs_length_range_small_helper(1, 1, exhaustive_bools(), 0, &[]); exhaustive_vecs_length_range_small_helper(5, 3, exhaustive_bools(), 0, &[]); exhaustive_vecs_length_range_small_helper( 0, 3, exhaustive_bools(), 7, &[&[], &[false], &[true], &[false, false], &[false, true], &[true, false], &[true, true]], ); exhaustive_vecs_length_range_small_helper( 2, 4, exhaustive_bools(), 12, &[ &[false, false], &[false, false, false], &[false, true], &[true, false], &[true, true], &[false, false, true], &[false, true, false], &[false, true, true], &[true, false, false], &[true, false, true], &[true, true, false], &[true, true, true], ], ); exhaustive_vecs_length_range_small_helper( 5, 8, 'a'..='c', 3159, &[ &['a', 'a', 'a', 'a', 'a'], &['a', 'a', 'a', 'a', 'a', 'a'], &['a', 'a', 'a', 'a', 'b'], &['a', 'a', 'a', 'a', 'a', 'a', 'a'], &['a', 'a', 'a', 'b', 'a'], &['a', 'a', 'a', 'a', 'a', 'b'], &['a', 'a', 'a', 'b', 'b'], &['a', 'a', 'b', 'a', 'a'], &['a', 'a', 'b', 'a', 'b'], &['a', 'a', 'a', 'a', 'b', 'a'], &['a', 'a', 'b', 'b', 'a'], &['a', 'a', 'a', 'a', 'a', 'a', 'b'], &['a', 'a', 'b', 'b', 'b'], &['a', 'a', 'a', 'a', 'b', 'b'], &['a', 'b', 'a', 'a', 'a'], &['a', 'a', 'a', 'b', 'a', 'a'], &['a', 'b', 'a', 'a', 'b'], &['a', 'a', 'a', 'b', 'a', 'b'], &['a', 'b', 'a', 'b', 'a'], &['a', 'a', 'a', 'a', 'a', 'b', 'a'], ], ); exhaustive_vecs_length_range_helper( 2, 4, exhaustive_unsigneds::(), &[ &[0, 0], &[0, 0, 0], &[0, 1], &[1, 0], &[1, 1], &[0, 0, 1], &[0, 2], &[0, 1, 0], &[0, 3], &[0, 1, 1], &[1, 2], &[1, 3], &[2, 0], &[1, 0, 0], &[2, 1], &[3, 0], &[3, 1], &[1, 0, 1], &[2, 2], &[2, 3], ], ); } malachite-base-0.4.16/tests/vecs/exhaustive/exhaustive_vecs_min_length.rs000064400000000000000000000252241046102023000250260ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::num::exhaustive::exhaustive_unsigneds; use malachite_base::test_util::vecs::exhaustive::exhaustive_vecs_helper_helper; use malachite_base::tuples::exhaustive::exhaustive_units; use malachite_base::vecs::exhaustive::exhaustive_vecs_min_length; use std::fmt::Debug; fn exhaustive_vecs_min_length_helper( min_length: u64, xs: I, out: &[&[I::Item]], ) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_helper_helper(exhaustive_vecs_min_length(min_length, xs), out); } #[test] fn test_exhaustive_vecs_min_length() { exhaustive_vecs_min_length_helper(0, nevers(), &[&[]]); exhaustive_vecs_min_length_helper(4, nevers(), &[]); exhaustive_vecs_min_length_helper( 0, exhaustive_units(), &[ &[], &[()], &[(), ()], &[(), (), (), ()], &[(), (), ()], &[(), (), (), (), ()], &[(), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), ()], ], ); exhaustive_vecs_min_length_helper( 5, exhaustive_units(), &[ &[(), (), (), (), ()], &[(), (), (), (), (), ()], &[(), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), ()], &[ (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), ], &[(), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), ()], &[ (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), ], &[ (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), ], ], ); exhaustive_vecs_min_length_helper( 0, exhaustive_bools(), &[ &[], &[false], &[true], &[false, false, false], &[false, false], &[false, false, true], &[false, true], &[false, false, false, false, false], &[true, false], &[false, true, false], &[true, true], &[false, false, false, false], &[false, true, true], &[false, false, false, true], &[true, false, false], &[false, false, false, false, false, false, false], &[true, false, true], &[false, false, true, false], &[true, true, false], &[false, false, false, false, true], ], ); exhaustive_vecs_min_length_helper( 3, exhaustive_bools(), &[ &[false, false, false], &[false, false, false, false], &[false, false, true], &[false, false, false, false, false], &[false, true, false], &[false, false, false, true], &[false, true, true], &[false, false, false, false, false, false], &[true, false, false], &[false, false, true, false], &[true, false, true], &[false, false, false, false, true], &[true, true, false], &[false, false, true, true], &[true, true, true], &[false, false, false, false, false, false, false], &[false, true, false, false], &[false, false, false, true, false], &[false, true, false, true], &[false, false, false, false, false, true], ], ); exhaustive_vecs_min_length_helper( 0, 'a'..='c', &[ &[], &['a'], &['b'], &['a', 'a', 'a'], &['c'], &['a', 'a'], &['a', 'b'], &['a', 'a', 'a', 'a', 'a'], &['b', 'a'], &['a', 'a', 'b'], &['b', 'b'], &['a', 'a', 'a', 'a'], &['a', 'c'], &['a', 'b', 'a'], &['b', 'c'], &['a', 'a', 'a', 'a', 'a', 'a'], &['c', 'a'], &['a', 'b', 'b'], &['c', 'b'], &['a', 'a', 'a', 'b'], ], ); exhaustive_vecs_min_length_helper( 3, 'a'..='c', &[ &['a', 'a', 'a'], &['a', 'a', 'a', 'a'], &['a', 'a', 'b'], &['a', 'a', 'a', 'a', 'a'], &['a', 'b', 'a'], &['a', 'a', 'a', 'b'], &['a', 'b', 'b'], &['a', 'a', 'a', 'a', 'a', 'a'], &['b', 'a', 'a'], &['a', 'a', 'b', 'a'], &['b', 'a', 'b'], &['a', 'a', 'a', 'a', 'b'], &['b', 'b', 'a'], &['a', 'a', 'b', 'b'], &['b', 'b', 'b'], &['a', 'a', 'a', 'a', 'a', 'a', 'a'], &['a', 'a', 'c'], &['a', 'b', 'a', 'a'], &['a', 'b', 'c'], &['a', 'a', 'a', 'b', 'a'], ], ); exhaustive_vecs_min_length_helper( 0, exhaustive_ascii_chars(), &[ &[], &['a'], &['b'], &['a', 'a', 'a'], &['c'], &['a', 'a'], &['d'], &['a', 'a', 'a', 'a'], &['e'], &['a', 'b'], &['f'], &['a', 'a', 'b'], &['g'], &['b', 'a'], &['h'], &['a', 'a', 'a', 'a', 'a'], &['i'], &['b', 'b'], &['j'], &['a', 'b', 'a'], ], ); exhaustive_vecs_min_length_helper( 3, exhaustive_ascii_chars(), &[ &['a', 'a', 'a'], &['a', 'a', 'a', 'a'], &['a', 'a', 'b'], &['a', 'a', 'a', 'a', 'a'], &['a', 'b', 'a'], &['a', 'a', 'a', 'b'], &['a', 'b', 'b'], &['a', 'a', 'a', 'a', 'a', 'a'], &['b', 'a', 'a'], &['a', 'a', 'b', 'a'], &['b', 'a', 'b'], &['a', 'a', 'a', 'a', 'b'], &['b', 'b', 'a'], &['a', 'a', 'b', 'b'], &['b', 'b', 'b'], &['a', 'a', 'a', 'a', 'a', 'a', 'a'], &['a', 'a', 'c'], &['a', 'b', 'a', 'a'], &['a', 'a', 'd'], &['a', 'a', 'a', 'b', 'a'], ], ); exhaustive_vecs_min_length_helper( 0, exhaustive_unsigneds::(), &[ &[], &[0], &[1], &[0, 0, 0], &[2], &[0, 0], &[3], &[0, 0, 0, 0], &[4], &[0, 1], &[5], &[0, 0, 1], &[6], &[1, 0], &[7], &[0, 0, 0, 0, 0], &[8], &[1, 1], &[9], &[0, 1, 0], ], ); exhaustive_vecs_min_length_helper( 3, exhaustive_unsigneds::(), &[ &[0, 0, 0], &[0, 0, 0, 0], &[0, 0, 1], &[0, 0, 0, 0, 0], &[0, 1, 0], &[0, 0, 0, 1], &[0, 1, 1], &[0, 0, 0, 0, 0, 0], &[1, 0, 0], &[0, 0, 1, 0], &[1, 0, 1], &[0, 0, 0, 0, 1], &[1, 1, 0], &[0, 0, 1, 1], &[1, 1, 1], &[0, 0, 0, 0, 0, 0, 0], &[0, 0, 2], &[0, 1, 0, 0], &[0, 0, 3], &[0, 0, 0, 1, 0], ], ); } malachite-base-0.4.16/tests/vecs/exhaustive/lex_k_compositions.rs000064400000000000000000000126001046102023000233170ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::vecs::exhaustive::lex_k_compositions; fn lex_k_compositions_helper(n: usize, k: usize, out: &[&[usize]]) { let xss = lex_k_compositions(n, k).collect_vec(); assert_eq!(xss.iter().map(Vec::as_slice).collect_vec().as_slice(), out); } #[test] fn test_lex_k_compositions() { lex_k_compositions_helper(0, 0, &[&[]]); lex_k_compositions_helper(0, 1, &[]); lex_k_compositions_helper(1, 0, &[]); lex_k_compositions_helper(1, 1, &[&[1]]); lex_k_compositions_helper(1, 2, &[]); lex_k_compositions_helper(2, 0, &[]); lex_k_compositions_helper(2, 1, &[&[2]]); lex_k_compositions_helper(2, 2, &[&[1, 1]]); lex_k_compositions_helper(2, 3, &[]); lex_k_compositions_helper(5, 0, &[]); lex_k_compositions_helper(5, 1, &[&[5]]); lex_k_compositions_helper(5, 2, &[&[1, 4], &[2, 3], &[3, 2], &[4, 1]]); lex_k_compositions_helper( 5, 3, &[&[1, 1, 3], &[1, 2, 2], &[1, 3, 1], &[2, 1, 2], &[2, 2, 1], &[3, 1, 1]], ); lex_k_compositions_helper( 5, 4, &[&[1, 1, 1, 2], &[1, 1, 2, 1], &[1, 2, 1, 1], &[2, 1, 1, 1]], ); lex_k_compositions_helper(5, 5, &[&[1, 1, 1, 1, 1]]); lex_k_compositions_helper(5, 6, &[]); lex_k_compositions_helper( 10, 5, &[ &[1, 1, 1, 1, 6], &[1, 1, 1, 2, 5], &[1, 1, 1, 3, 4], &[1, 1, 1, 4, 3], &[1, 1, 1, 5, 2], &[1, 1, 1, 6, 1], &[1, 1, 2, 1, 5], &[1, 1, 2, 2, 4], &[1, 1, 2, 3, 3], &[1, 1, 2, 4, 2], &[1, 1, 2, 5, 1], &[1, 1, 3, 1, 4], &[1, 1, 3, 2, 3], &[1, 1, 3, 3, 2], &[1, 1, 3, 4, 1], &[1, 1, 4, 1, 3], &[1, 1, 4, 2, 2], &[1, 1, 4, 3, 1], &[1, 1, 5, 1, 2], &[1, 1, 5, 2, 1], &[1, 1, 6, 1, 1], &[1, 2, 1, 1, 5], &[1, 2, 1, 2, 4], &[1, 2, 1, 3, 3], &[1, 2, 1, 4, 2], &[1, 2, 1, 5, 1], &[1, 2, 2, 1, 4], &[1, 2, 2, 2, 3], &[1, 2, 2, 3, 2], &[1, 2, 2, 4, 1], &[1, 2, 3, 1, 3], &[1, 2, 3, 2, 2], &[1, 2, 3, 3, 1], &[1, 2, 4, 1, 2], &[1, 2, 4, 2, 1], &[1, 2, 5, 1, 1], &[1, 3, 1, 1, 4], &[1, 3, 1, 2, 3], &[1, 3, 1, 3, 2], &[1, 3, 1, 4, 1], &[1, 3, 2, 1, 3], &[1, 3, 2, 2, 2], &[1, 3, 2, 3, 1], &[1, 3, 3, 1, 2], &[1, 3, 3, 2, 1], &[1, 3, 4, 1, 1], &[1, 4, 1, 1, 3], &[1, 4, 1, 2, 2], &[1, 4, 1, 3, 1], &[1, 4, 2, 1, 2], &[1, 4, 2, 2, 1], &[1, 4, 3, 1, 1], &[1, 5, 1, 1, 2], &[1, 5, 1, 2, 1], &[1, 5, 2, 1, 1], &[1, 6, 1, 1, 1], &[2, 1, 1, 1, 5], &[2, 1, 1, 2, 4], &[2, 1, 1, 3, 3], &[2, 1, 1, 4, 2], &[2, 1, 1, 5, 1], &[2, 1, 2, 1, 4], &[2, 1, 2, 2, 3], &[2, 1, 2, 3, 2], &[2, 1, 2, 4, 1], &[2, 1, 3, 1, 3], &[2, 1, 3, 2, 2], &[2, 1, 3, 3, 1], &[2, 1, 4, 1, 2], &[2, 1, 4, 2, 1], &[2, 1, 5, 1, 1], &[2, 2, 1, 1, 4], &[2, 2, 1, 2, 3], &[2, 2, 1, 3, 2], &[2, 2, 1, 4, 1], &[2, 2, 2, 1, 3], &[2, 2, 2, 2, 2], &[2, 2, 2, 3, 1], &[2, 2, 3, 1, 2], &[2, 2, 3, 2, 1], &[2, 2, 4, 1, 1], &[2, 3, 1, 1, 3], &[2, 3, 1, 2, 2], &[2, 3, 1, 3, 1], &[2, 3, 2, 1, 2], &[2, 3, 2, 2, 1], &[2, 3, 3, 1, 1], &[2, 4, 1, 1, 2], &[2, 4, 1, 2, 1], &[2, 4, 2, 1, 1], &[2, 5, 1, 1, 1], &[3, 1, 1, 1, 4], &[3, 1, 1, 2, 3], &[3, 1, 1, 3, 2], &[3, 1, 1, 4, 1], &[3, 1, 2, 1, 3], &[3, 1, 2, 2, 2], &[3, 1, 2, 3, 1], &[3, 1, 3, 1, 2], &[3, 1, 3, 2, 1], &[3, 1, 4, 1, 1], &[3, 2, 1, 1, 3], &[3, 2, 1, 2, 2], &[3, 2, 1, 3, 1], &[3, 2, 2, 1, 2], &[3, 2, 2, 2, 1], &[3, 2, 3, 1, 1], &[3, 3, 1, 1, 2], &[3, 3, 1, 2, 1], &[3, 3, 2, 1, 1], &[3, 4, 1, 1, 1], &[4, 1, 1, 1, 3], &[4, 1, 1, 2, 2], &[4, 1, 1, 3, 1], &[4, 1, 2, 1, 2], &[4, 1, 2, 2, 1], &[4, 1, 3, 1, 1], &[4, 2, 1, 1, 2], &[4, 2, 1, 2, 1], &[4, 2, 2, 1, 1], &[4, 3, 1, 1, 1], &[5, 1, 1, 1, 2], &[5, 1, 1, 2, 1], &[5, 1, 2, 1, 1], &[5, 2, 1, 1, 1], &[6, 1, 1, 1, 1], ], ); } malachite-base-0.4.16/tests/vecs/exhaustive/lex_ordered_unique_vecs.rs000064400000000000000000000073321046102023000243170ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::test_util::vecs::exhaustive::{ exhaustive_vecs_helper_helper, exhaustive_vecs_small_helper_helper, }; use malachite_base::tuples::exhaustive::exhaustive_units; use malachite_base::vecs::exhaustive::lex_ordered_unique_vecs; use std::fmt::Debug; fn lex_ordered_unique_vecs_helper(xs: I, out: &[&[I::Item]]) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_helper_helper(lex_ordered_unique_vecs(xs), out); } fn lex_ordered_unique_vecs_small_helper( xs: I, out_len: usize, out: &[&[I::Item]], ) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_small_helper_helper(lex_ordered_unique_vecs(xs), out_len, out); } #[test] fn test_lex_ordered_unique_vecs() { lex_ordered_unique_vecs_small_helper(nevers(), 1, &[&[]]); lex_ordered_unique_vecs_small_helper(exhaustive_units(), 2, &[&[], &[()]]); lex_ordered_unique_vecs_small_helper( exhaustive_bools(), 4, &[&[], &[false], &[false, true], &[true]], ); lex_ordered_unique_vecs_small_helper( 1..=6, 64, &[ &[], &[1], &[1, 2], &[1, 2, 3], &[1, 2, 3, 4], &[1, 2, 3, 4, 5], &[1, 2, 3, 4, 5, 6], &[1, 2, 3, 4, 6], &[1, 2, 3, 5], &[1, 2, 3, 5, 6], &[1, 2, 3, 6], &[1, 2, 4], &[1, 2, 4, 5], &[1, 2, 4, 5, 6], &[1, 2, 4, 6], &[1, 2, 5], &[1, 2, 5, 6], &[1, 2, 6], &[1, 3], &[1, 3, 4], ], ); lex_ordered_unique_vecs_small_helper( 'a'..='c', 8, &[&[], &['a'], &['a', 'b'], &['a', 'b', 'c'], &['a', 'c'], &['b'], &['b', 'c'], &['c']], ); lex_ordered_unique_vecs_helper( exhaustive_ascii_chars(), &[ &[], &['a'], &['a', 'b'], &['a', 'b', 'c'], &['a', 'b', 'c', 'd'], &['a', 'b', 'c', 'd', 'e'], &['a', 'b', 'c', 'd', 'e', 'f'], &['a', 'b', 'c', 'd', 'e', 'f', 'g'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q'], &[ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', ], &[ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', ], ], ); } malachite-base-0.4.16/tests/vecs/exhaustive/lex_ordered_unique_vecs_fixed_length.rs000064400000000000000000000153201046102023000270330ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::num::exhaustive::exhaustive_unsigneds; use malachite_base::test_util::vecs::exhaustive::{ exhaustive_vecs_helper_helper, exhaustive_vecs_small_helper_helper, }; use malachite_base::tuples::exhaustive::exhaustive_units; use malachite_base::vecs::exhaustive::lex_ordered_unique_vecs_fixed_length; use std::fmt::Debug; fn lex_ordered_unique_vecs_fixed_length_helper(len: u64, xs: I, out: &[&[I::Item]]) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_helper_helper(lex_ordered_unique_vecs_fixed_length(len, xs), out); } fn lex_ordered_unique_vecs_fixed_length_small_helper( len: u64, xs: I, out_len: usize, out: &[&[I::Item]], ) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_small_helper_helper( lex_ordered_unique_vecs_fixed_length(len, xs), out_len, out, ); } #[test] fn test_lex_ordered_unique_vecs_fixed_length() { // This demonstrates that 0 ^ 0 == 1: lex_ordered_unique_vecs_fixed_length_small_helper(0, nevers(), 1, &[&[]]); lex_ordered_unique_vecs_fixed_length_small_helper(1, nevers(), 0, &[]); lex_ordered_unique_vecs_fixed_length_small_helper(2, nevers(), 0, &[]); lex_ordered_unique_vecs_fixed_length_small_helper(5, nevers(), 0, &[]); lex_ordered_unique_vecs_fixed_length_small_helper(1, exhaustive_units(), 1, &[&[()]]); lex_ordered_unique_vecs_fixed_length_small_helper(2, exhaustive_units(), 0, &[]); lex_ordered_unique_vecs_fixed_length_small_helper(5, exhaustive_units(), 0, &[]); lex_ordered_unique_vecs_fixed_length_small_helper(0, exhaustive_unsigneds::(), 1, &[&[]]); lex_ordered_unique_vecs_fixed_length_small_helper( 1, exhaustive_unsigneds::(), 256, &[ &[0], &[1], &[2], &[3], &[4], &[5], &[6], &[7], &[8], &[9], &[10], &[11], &[12], &[13], &[14], &[15], &[16], &[17], &[18], &[19], ], ); lex_ordered_unique_vecs_fixed_length_helper( 1, exhaustive_unsigneds::(), &[ &[0], &[1], &[2], &[3], &[4], &[5], &[6], &[7], &[8], &[9], &[10], &[11], &[12], &[13], &[14], &[15], &[16], &[17], &[18], &[19], ], ); lex_ordered_unique_vecs_fixed_length_small_helper( 2, exhaustive_unsigneds::(), 32640, &[ &[0, 1], &[0, 2], &[0, 3], &[0, 4], &[0, 5], &[0, 6], &[0, 7], &[0, 8], &[0, 9], &[0, 10], &[0, 11], &[0, 12], &[0, 13], &[0, 14], &[0, 15], &[0, 16], &[0, 17], &[0, 18], &[0, 19], &[0, 20], ], ); lex_ordered_unique_vecs_fixed_length_helper( 3, exhaustive_unsigneds::(), &[ &[0, 1, 2], &[0, 1, 3], &[0, 1, 4], &[0, 1, 5], &[0, 1, 6], &[0, 1, 7], &[0, 1, 8], &[0, 1, 9], &[0, 1, 10], &[0, 1, 11], &[0, 1, 12], &[0, 1, 13], &[0, 1, 14], &[0, 1, 15], &[0, 1, 16], &[0, 1, 17], &[0, 1, 18], &[0, 1, 19], &[0, 1, 20], &[0, 1, 21], ], ); lex_ordered_unique_vecs_fixed_length_small_helper( 2, exhaustive_ascii_chars(), 8128, &[ &['a', 'b'], &['a', 'c'], &['a', 'd'], &['a', 'e'], &['a', 'f'], &['a', 'g'], &['a', 'h'], &['a', 'i'], &['a', 'j'], &['a', 'k'], &['a', 'l'], &['a', 'm'], &['a', 'n'], &['a', 'o'], &['a', 'p'], &['a', 'q'], &['a', 'r'], &['a', 's'], &['a', 't'], &['a', 'u'], ], ); lex_ordered_unique_vecs_fixed_length_small_helper( 1, exhaustive_bools(), 2, &[&[false], &[true]], ); lex_ordered_unique_vecs_fixed_length_small_helper(2, exhaustive_bools(), 1, &[&[false, true]]); lex_ordered_unique_vecs_fixed_length_small_helper(4, exhaustive_bools(), 0, &[]); lex_ordered_unique_vecs_fixed_length_small_helper( 4, 1..=6, 15, &[ &[1, 2, 3, 4], &[1, 2, 3, 5], &[1, 2, 3, 6], &[1, 2, 4, 5], &[1, 2, 4, 6], &[1, 2, 5, 6], &[1, 3, 4, 5], &[1, 3, 4, 6], &[1, 3, 5, 6], &[1, 4, 5, 6], &[2, 3, 4, 5], &[2, 3, 4, 6], &[2, 3, 5, 6], &[2, 4, 5, 6], &[3, 4, 5, 6], ], ); lex_ordered_unique_vecs_fixed_length_helper( 2, lex_ordered_unique_vecs_fixed_length(2, exhaustive_unsigneds::()), &[ &[vec![0, 1], vec![0, 2]], &[vec![0, 1], vec![0, 3]], &[vec![0, 1], vec![0, 4]], &[vec![0, 1], vec![0, 5]], &[vec![0, 1], vec![0, 6]], &[vec![0, 1], vec![0, 7]], &[vec![0, 1], vec![0, 8]], &[vec![0, 1], vec![0, 9]], &[vec![0, 1], vec![0, 10]], &[vec![0, 1], vec![0, 11]], &[vec![0, 1], vec![0, 12]], &[vec![0, 1], vec![0, 13]], &[vec![0, 1], vec![0, 14]], &[vec![0, 1], vec![0, 15]], &[vec![0, 1], vec![0, 16]], &[vec![0, 1], vec![0, 17]], &[vec![0, 1], vec![0, 18]], &[vec![0, 1], vec![0, 19]], &[vec![0, 1], vec![0, 20]], &[vec![0, 1], vec![0, 21]], ], ); } malachite-base-0.4.16/tests/vecs/exhaustive/lex_ordered_unique_vecs_length_inclusive_range.rs000064400000000000000000000040231046102023000311070ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::nevers::nevers; use malachite_base::test_util::vecs::exhaustive::exhaustive_vecs_small_helper_helper; use malachite_base::tuples::exhaustive::exhaustive_units; use malachite_base::vecs::exhaustive::lex_ordered_unique_vecs_length_inclusive_range; use std::fmt::Debug; fn lex_ordered_unique_vecs_length_inclusive_range_small_helper( a: u64, b: u64, xs: I, out_len: usize, out: &[&[I::Item]], ) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_small_helper_helper( lex_ordered_unique_vecs_length_inclusive_range(a, b, xs), out_len, out, ); } #[test] fn test_lex_ordered_unique_vecs_length_inclusive_range() { lex_ordered_unique_vecs_length_inclusive_range_small_helper(0, 4, nevers(), 1, &[&[]]); lex_ordered_unique_vecs_length_inclusive_range_small_helper(6, 9, nevers(), 0, &[]); lex_ordered_unique_vecs_length_inclusive_range_small_helper( 0, 4, exhaustive_units(), 2, &[&[], &[()]], ); lex_ordered_unique_vecs_length_inclusive_range_small_helper(1, 0, exhaustive_bools(), 0, &[]); lex_ordered_unique_vecs_length_inclusive_range_small_helper( 0, 1, exhaustive_bools(), 3, &[&[], &[false], &[true]], ); lex_ordered_unique_vecs_length_inclusive_range_small_helper( 2, 3, exhaustive_bools(), 1, &[&[false, true]], ); lex_ordered_unique_vecs_length_inclusive_range_small_helper( 1, 1, 'a'..='c', 3, &[&['a'], &['b'], &['c']], ); } malachite-base-0.4.16/tests/vecs/exhaustive/lex_ordered_unique_vecs_length_range.rs000064400000000000000000000037201046102023000270310ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::nevers::nevers; use malachite_base::test_util::vecs::exhaustive::exhaustive_vecs_small_helper_helper; use malachite_base::tuples::exhaustive::exhaustive_units; use malachite_base::vecs::exhaustive::lex_ordered_unique_vecs_length_range; use std::fmt::Debug; fn lex_ordered_unique_vecs_length_range_small_helper( a: u64, b: u64, xs: I, out_len: usize, out: &[&[I::Item]], ) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_small_helper_helper( lex_ordered_unique_vecs_length_range(a, b, xs), out_len, out, ); } #[test] fn test_lex_ordered_unique_vecs_length_range() { lex_ordered_unique_vecs_length_range_small_helper(0, 5, nevers(), 1, &[&[]]); lex_ordered_unique_vecs_length_range_small_helper(6, 10, nevers(), 0, &[]); lex_ordered_unique_vecs_length_range_small_helper(0, 5, exhaustive_units(), 2, &[&[], &[()]]); lex_ordered_unique_vecs_length_range_small_helper(1, 0, exhaustive_bools(), 0, &[]); lex_ordered_unique_vecs_length_range_small_helper(1, 1, exhaustive_bools(), 0, &[]); lex_ordered_unique_vecs_length_range_small_helper( 0, 2, exhaustive_bools(), 3, &[&[], &[false], &[true]], ); lex_ordered_unique_vecs_length_range_small_helper( 2, 4, exhaustive_bools(), 1, &[&[false, true]], ); lex_ordered_unique_vecs_length_range_small_helper( 1, 2, 'a'..='c', 3, &[&['a'], &['b'], &['c']], ); } malachite-base-0.4.16/tests/vecs/exhaustive/lex_ordered_unique_vecs_min_length.rs000064400000000000000000000133311046102023000265170ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::test_util::vecs::exhaustive::{ exhaustive_vecs_helper_helper, exhaustive_vecs_small_helper_helper, }; use malachite_base::tuples::exhaustive::exhaustive_units; use malachite_base::vecs::exhaustive::lex_ordered_unique_vecs_min_length; use std::fmt::Debug; fn lex_ordered_unique_vecs_min_length_helper( min_length: u64, xs: I, out: &[&[I::Item]], ) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_helper_helper(lex_ordered_unique_vecs_min_length(min_length, xs), out); } fn lex_ordered_unique_vecs_min_length_small_helper( min_length: u64, xs: I, out_len: usize, out: &[&[I::Item]], ) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_small_helper_helper( lex_ordered_unique_vecs_min_length(min_length, xs), out_len, out, ); } #[test] fn test_lex_ordered_unique_vecs_min_length() { lex_ordered_unique_vecs_min_length_small_helper(0, nevers(), 1, &[&[]]); lex_ordered_unique_vecs_min_length_small_helper(4, nevers(), 0, &[]); lex_ordered_unique_vecs_min_length_small_helper(0, exhaustive_units(), 2, &[&[], &[()]]); lex_ordered_unique_vecs_min_length_small_helper(5, exhaustive_units(), 0, &[]); lex_ordered_unique_vecs_min_length_small_helper( 0, exhaustive_bools(), 4, &[&[], &[false], &[false, true], &[true]], ); lex_ordered_unique_vecs_min_length_small_helper( 1, exhaustive_bools(), 3, &[&[false], &[false, true], &[true]], ); lex_ordered_unique_vecs_min_length_small_helper( 0, 'a'..='c', 8, &[&[], &['a'], &['a', 'b'], &['a', 'b', 'c'], &['a', 'c'], &['b'], &['b', 'c'], &['c']], ); lex_ordered_unique_vecs_min_length_small_helper( 2, 'a'..='c', 4, &[&['a', 'b'], &['a', 'b', 'c'], &['a', 'c'], &['b', 'c']], ); lex_ordered_unique_vecs_min_length_helper( 0, exhaustive_ascii_chars(), &[ &[], &['a'], &['a', 'b'], &['a', 'b', 'c'], &['a', 'b', 'c', 'd'], &['a', 'b', 'c', 'd', 'e'], &['a', 'b', 'c', 'd', 'e', 'f'], &['a', 'b', 'c', 'd', 'e', 'f', 'g'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q'], &[ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', ], &[ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', ], ], ); lex_ordered_unique_vecs_min_length_helper( 3, exhaustive_ascii_chars(), &[ &['a', 'b', 'c'], &['a', 'b', 'c', 'd'], &['a', 'b', 'c', 'd', 'e'], &['a', 'b', 'c', 'd', 'e', 'f'], &['a', 'b', 'c', 'd', 'e', 'f', 'g'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q'], &[ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', ], &[ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', ], &[ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', ], &[ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', ], &[ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', ], ], ); } malachite-base-0.4.16/tests/vecs/exhaustive/lex_unique_vecs.rs000064400000000000000000000077751046102023000226260ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::test_util::vecs::exhaustive::{ exhaustive_vecs_helper_helper, exhaustive_vecs_small_helper_helper, }; use malachite_base::tuples::exhaustive::exhaustive_units; use malachite_base::vecs::exhaustive::lex_unique_vecs; use std::fmt::Debug; fn lex_unique_vecs_helper(xs: I, out: &[&[I::Item]]) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_helper_helper(lex_unique_vecs(xs), out); } fn lex_unique_vecs_small_helper(xs: I, out_len: usize, out: &[&[I::Item]]) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_small_helper_helper(lex_unique_vecs(xs), out_len, out); } #[test] fn test_lex_unique_vecs() { lex_unique_vecs_small_helper(nevers(), 1, &[&[]]); lex_unique_vecs_small_helper(exhaustive_units(), 2, &[&[], &[()]]); lex_unique_vecs_small_helper( exhaustive_bools(), 5, &[&[], &[false], &[false, true], &[true], &[true, false]], ); lex_unique_vecs_small_helper( 1..=6, 1957, &[ &[], &[1], &[1, 2], &[1, 2, 3], &[1, 2, 3, 4], &[1, 2, 3, 4, 5], &[1, 2, 3, 4, 5, 6], &[1, 2, 3, 4, 6], &[1, 2, 3, 4, 6, 5], &[1, 2, 3, 5], &[1, 2, 3, 5, 4], &[1, 2, 3, 5, 4, 6], &[1, 2, 3, 5, 6], &[1, 2, 3, 5, 6, 4], &[1, 2, 3, 6], &[1, 2, 3, 6, 4], &[1, 2, 3, 6, 4, 5], &[1, 2, 3, 6, 5], &[1, 2, 3, 6, 5, 4], &[1, 2, 4], ], ); lex_unique_vecs_small_helper( 'a'..='c', 16, &[ &[], &['a'], &['a', 'b'], &['a', 'b', 'c'], &['a', 'c'], &['a', 'c', 'b'], &['b'], &['b', 'a'], &['b', 'a', 'c'], &['b', 'c'], &['b', 'c', 'a'], &['c'], &['c', 'a'], &['c', 'a', 'b'], &['c', 'b'], &['c', 'b', 'a'], ], ); lex_unique_vecs_helper( exhaustive_ascii_chars(), &[ &[], &['a'], &['a', 'b'], &['a', 'b', 'c'], &['a', 'b', 'c', 'd'], &['a', 'b', 'c', 'd', 'e'], &['a', 'b', 'c', 'd', 'e', 'f'], &['a', 'b', 'c', 'd', 'e', 'f', 'g'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q'], &[ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', ], &[ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', ], ], ); } malachite-base-0.4.16/tests/vecs/exhaustive/lex_unique_vecs_fixed_length.rs000064400000000000000000000152021046102023000253260ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::num::exhaustive::exhaustive_unsigneds; use malachite_base::test_util::vecs::exhaustive::{ exhaustive_vecs_helper_helper, exhaustive_vecs_small_helper_helper, }; use malachite_base::tuples::exhaustive::exhaustive_units; use malachite_base::vecs::exhaustive::lex_unique_vecs_fixed_length; use std::fmt::Debug; fn lex_unique_vecs_fixed_length_helper(len: u64, xs: I, out: &[&[I::Item]]) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_helper_helper(lex_unique_vecs_fixed_length(len, xs), out); } fn lex_unique_vecs_fixed_length_small_helper( len: u64, xs: I, out_len: usize, out: &[&[I::Item]], ) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_small_helper_helper(lex_unique_vecs_fixed_length(len, xs), out_len, out); } #[test] fn test_lex_unique_vecs_fixed_length() { // This demonstrates that 0 ^ 0 == 1: lex_unique_vecs_fixed_length_small_helper(0, nevers(), 1, &[&[]]); lex_unique_vecs_fixed_length_small_helper(1, nevers(), 0, &[]); lex_unique_vecs_fixed_length_small_helper(2, nevers(), 0, &[]); lex_unique_vecs_fixed_length_small_helper(5, nevers(), 0, &[]); lex_unique_vecs_fixed_length_small_helper(1, exhaustive_units(), 1, &[&[()]]); lex_unique_vecs_fixed_length_small_helper(2, exhaustive_units(), 0, &[]); lex_unique_vecs_fixed_length_small_helper(5, exhaustive_units(), 0, &[]); lex_unique_vecs_fixed_length_small_helper(0, exhaustive_unsigneds::(), 1, &[&[]]); lex_unique_vecs_fixed_length_small_helper( 1, exhaustive_unsigneds::(), 256, &[ &[0], &[1], &[2], &[3], &[4], &[5], &[6], &[7], &[8], &[9], &[10], &[11], &[12], &[13], &[14], &[15], &[16], &[17], &[18], &[19], ], ); lex_unique_vecs_fixed_length_helper( 1, exhaustive_unsigneds::(), &[ &[0], &[1], &[2], &[3], &[4], &[5], &[6], &[7], &[8], &[9], &[10], &[11], &[12], &[13], &[14], &[15], &[16], &[17], &[18], &[19], ], ); lex_unique_vecs_fixed_length_small_helper( 2, exhaustive_unsigneds::(), 65280, &[ &[0, 1], &[0, 2], &[0, 3], &[0, 4], &[0, 5], &[0, 6], &[0, 7], &[0, 8], &[0, 9], &[0, 10], &[0, 11], &[0, 12], &[0, 13], &[0, 14], &[0, 15], &[0, 16], &[0, 17], &[0, 18], &[0, 19], &[0, 20], ], ); lex_unique_vecs_fixed_length_helper( 3, exhaustive_unsigneds::(), &[ &[0, 1, 2], &[0, 1, 3], &[0, 1, 4], &[0, 1, 5], &[0, 1, 6], &[0, 1, 7], &[0, 1, 8], &[0, 1, 9], &[0, 1, 10], &[0, 1, 11], &[0, 1, 12], &[0, 1, 13], &[0, 1, 14], &[0, 1, 15], &[0, 1, 16], &[0, 1, 17], &[0, 1, 18], &[0, 1, 19], &[0, 1, 20], &[0, 1, 21], ], ); lex_unique_vecs_fixed_length_small_helper( 2, exhaustive_ascii_chars(), 16256, &[ &['a', 'b'], &['a', 'c'], &['a', 'd'], &['a', 'e'], &['a', 'f'], &['a', 'g'], &['a', 'h'], &['a', 'i'], &['a', 'j'], &['a', 'k'], &['a', 'l'], &['a', 'm'], &['a', 'n'], &['a', 'o'], &['a', 'p'], &['a', 'q'], &['a', 'r'], &['a', 's'], &['a', 't'], &['a', 'u'], ], ); lex_unique_vecs_fixed_length_small_helper(1, exhaustive_bools(), 2, &[&[false], &[true]]); lex_unique_vecs_fixed_length_small_helper( 2, exhaustive_bools(), 2, &[&[false, true], &[true, false]], ); lex_unique_vecs_fixed_length_small_helper(4, exhaustive_bools(), 0, &[]); lex_unique_vecs_fixed_length_small_helper( 4, 1..=6, 360, &[ &[1, 2, 3, 4], &[1, 2, 3, 5], &[1, 2, 3, 6], &[1, 2, 4, 3], &[1, 2, 4, 5], &[1, 2, 4, 6], &[1, 2, 5, 3], &[1, 2, 5, 4], &[1, 2, 5, 6], &[1, 2, 6, 3], &[1, 2, 6, 4], &[1, 2, 6, 5], &[1, 3, 2, 4], &[1, 3, 2, 5], &[1, 3, 2, 6], &[1, 3, 4, 2], &[1, 3, 4, 5], &[1, 3, 4, 6], &[1, 3, 5, 2], &[1, 3, 5, 4], ], ); lex_unique_vecs_fixed_length_helper( 2, lex_unique_vecs_fixed_length(2, exhaustive_unsigneds::()), &[ &[vec![0, 1], vec![0, 2]], &[vec![0, 1], vec![0, 3]], &[vec![0, 1], vec![0, 4]], &[vec![0, 1], vec![0, 5]], &[vec![0, 1], vec![0, 6]], &[vec![0, 1], vec![0, 7]], &[vec![0, 1], vec![0, 8]], &[vec![0, 1], vec![0, 9]], &[vec![0, 1], vec![0, 10]], &[vec![0, 1], vec![0, 11]], &[vec![0, 1], vec![0, 12]], &[vec![0, 1], vec![0, 13]], &[vec![0, 1], vec![0, 14]], &[vec![0, 1], vec![0, 15]], &[vec![0, 1], vec![0, 16]], &[vec![0, 1], vec![0, 17]], &[vec![0, 1], vec![0, 18]], &[vec![0, 1], vec![0, 19]], &[vec![0, 1], vec![0, 20]], &[vec![0, 1], vec![0, 21]], ], ); } malachite-base-0.4.16/tests/vecs/exhaustive/lex_unique_vecs_length_inclusive_range.rs000064400000000000000000000036341046102023000274120ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::nevers::nevers; use malachite_base::test_util::vecs::exhaustive::exhaustive_vecs_small_helper_helper; use malachite_base::tuples::exhaustive::exhaustive_units; use malachite_base::vecs::exhaustive::lex_unique_vecs_length_inclusive_range; use std::fmt::Debug; fn lex_unique_vecs_length_inclusive_range_small_helper( a: u64, b: u64, xs: I, out_len: usize, out: &[&[I::Item]], ) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_small_helper_helper( lex_unique_vecs_length_inclusive_range(a, b, xs), out_len, out, ); } #[test] fn test_lex_unique_vecs_length_inclusive_range() { lex_unique_vecs_length_inclusive_range_small_helper(0, 4, nevers(), 1, &[&[]]); lex_unique_vecs_length_inclusive_range_small_helper(6, 9, nevers(), 0, &[]); lex_unique_vecs_length_inclusive_range_small_helper(0, 4, exhaustive_units(), 2, &[&[], &[()]]); lex_unique_vecs_length_inclusive_range_small_helper(1, 0, exhaustive_bools(), 0, &[]); lex_unique_vecs_length_inclusive_range_small_helper( 0, 1, exhaustive_bools(), 3, &[&[], &[false], &[true]], ); lex_unique_vecs_length_inclusive_range_small_helper( 2, 3, exhaustive_bools(), 2, &[&[false, true], &[true, false]], ); lex_unique_vecs_length_inclusive_range_small_helper( 1, 1, 'a'..='c', 3, &[&['a'], &['b'], &['c']], ); } malachite-base-0.4.16/tests/vecs/exhaustive/lex_unique_vecs_length_range.rs000064400000000000000000000034621046102023000253300ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::nevers::nevers; use malachite_base::test_util::vecs::exhaustive::exhaustive_vecs_small_helper_helper; use malachite_base::tuples::exhaustive::exhaustive_units; use malachite_base::vecs::exhaustive::lex_unique_vecs_length_range; use std::fmt::Debug; fn lex_unique_vecs_length_range_small_helper( a: u64, b: u64, xs: I, out_len: usize, out: &[&[I::Item]], ) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_small_helper_helper(lex_unique_vecs_length_range(a, b, xs), out_len, out); } #[test] fn test_lex_unique_vecs_length_range() { lex_unique_vecs_length_range_small_helper(0, 5, nevers(), 1, &[&[]]); lex_unique_vecs_length_range_small_helper(6, 10, nevers(), 0, &[]); lex_unique_vecs_length_range_small_helper(0, 5, exhaustive_units(), 2, &[&[], &[()]]); lex_unique_vecs_length_range_small_helper(1, 0, exhaustive_bools(), 0, &[]); lex_unique_vecs_length_range_small_helper(1, 1, exhaustive_bools(), 0, &[]); lex_unique_vecs_length_range_small_helper( 0, 2, exhaustive_bools(), 3, &[&[], &[false], &[true]], ); lex_unique_vecs_length_range_small_helper( 2, 4, exhaustive_bools(), 2, &[&[false, true], &[true, false]], ); lex_unique_vecs_length_range_small_helper(1, 2, 'a'..='c', 3, &[&['a'], &['b'], &['c']]); } malachite-base-0.4.16/tests/vecs/exhaustive/lex_unique_vecs_min_length.rs000064400000000000000000000143041046102023000250140ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::test_util::vecs::exhaustive::{ exhaustive_vecs_helper_helper, exhaustive_vecs_small_helper_helper, }; use malachite_base::tuples::exhaustive::exhaustive_units; use malachite_base::vecs::exhaustive::lex_unique_vecs_min_length; use std::fmt::Debug; fn lex_unique_vecs_min_length_helper( min_length: u64, xs: I, out: &[&[I::Item]], ) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_helper_helper(lex_unique_vecs_min_length(min_length, xs), out); } fn lex_unique_vecs_min_length_small_helper( min_length: u64, xs: I, out_len: usize, out: &[&[I::Item]], ) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_small_helper_helper(lex_unique_vecs_min_length(min_length, xs), out_len, out); } #[test] fn test_lex_unique_vecs_min_length() { lex_unique_vecs_min_length_small_helper(0, nevers(), 1, &[&[]]); lex_unique_vecs_min_length_small_helper(4, nevers(), 0, &[]); lex_unique_vecs_min_length_small_helper(0, exhaustive_units(), 2, &[&[], &[()]]); lex_unique_vecs_min_length_small_helper(5, exhaustive_units(), 0, &[]); lex_unique_vecs_min_length_small_helper( 0, exhaustive_bools(), 5, &[&[], &[false], &[false, true], &[true], &[true, false]], ); lex_unique_vecs_min_length_small_helper( 1, exhaustive_bools(), 4, &[&[false], &[false, true], &[true], &[true, false]], ); lex_unique_vecs_min_length_small_helper( 0, 'a'..='c', 16, &[ &[], &['a'], &['a', 'b'], &['a', 'b', 'c'], &['a', 'c'], &['a', 'c', 'b'], &['b'], &['b', 'a'], &['b', 'a', 'c'], &['b', 'c'], &['b', 'c', 'a'], &['c'], &['c', 'a'], &['c', 'a', 'b'], &['c', 'b'], &['c', 'b', 'a'], ], ); lex_unique_vecs_min_length_small_helper( 2, 'a'..='c', 12, &[ &['a', 'b'], &['a', 'b', 'c'], &['a', 'c'], &['a', 'c', 'b'], &['b', 'a'], &['b', 'a', 'c'], &['b', 'c'], &['b', 'c', 'a'], &['c', 'a'], &['c', 'a', 'b'], &['c', 'b'], &['c', 'b', 'a'], ], ); lex_unique_vecs_min_length_helper( 0, exhaustive_ascii_chars(), &[ &[], &['a'], &['a', 'b'], &['a', 'b', 'c'], &['a', 'b', 'c', 'd'], &['a', 'b', 'c', 'd', 'e'], &['a', 'b', 'c', 'd', 'e', 'f'], &['a', 'b', 'c', 'd', 'e', 'f', 'g'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q'], &[ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', ], &[ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', ], ], ); lex_unique_vecs_min_length_helper( 3, exhaustive_ascii_chars(), &[ &['a', 'b', 'c'], &['a', 'b', 'c', 'd'], &['a', 'b', 'c', 'd', 'e'], &['a', 'b', 'c', 'd', 'e', 'f'], &['a', 'b', 'c', 'd', 'e', 'f', 'g'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p'], &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q'], &[ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', ], &[ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', ], &[ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', ], &[ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', ], &[ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', ], ], ); } malachite-base-0.4.16/tests/vecs/exhaustive/lex_vecs_fixed_length_from_single.rs000064400000000000000000000231341046102023000263270ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::num::exhaustive::exhaustive_unsigneds; use malachite_base::test_util::vecs::exhaustive::{ exhaustive_vecs_helper_helper, exhaustive_vecs_small_helper_helper, }; use malachite_base::tuples::exhaustive::exhaustive_units; use malachite_base::vecs::exhaustive::lex_vecs_fixed_length_from_single; use std::fmt::Debug; fn lex_vecs_fixed_length_from_single_helper(len: u64, xs: I, out: &[&[I::Item]]) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_helper_helper(lex_vecs_fixed_length_from_single(len, xs), out); } fn lex_vecs_fixed_length_from_single_small_helper( len: u64, xs: I, out_len: usize, out: &[&[I::Item]], ) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_small_helper_helper(lex_vecs_fixed_length_from_single(len, xs), out_len, out); } #[test] fn test_lex_vecs_fixed_length_from_single() { // This demonstrates that 0 ^ 0 == 1: lex_vecs_fixed_length_from_single_small_helper(0, nevers(), 1, &[&[]]); lex_vecs_fixed_length_from_single_small_helper(1, nevers(), 0, &[]); lex_vecs_fixed_length_from_single_small_helper(2, nevers(), 0, &[]); lex_vecs_fixed_length_from_single_small_helper(5, nevers(), 0, &[]); lex_vecs_fixed_length_from_single_small_helper(1, exhaustive_units(), 1, &[&[()]]); lex_vecs_fixed_length_from_single_small_helper(2, exhaustive_units(), 1, &[&[(), ()]]); lex_vecs_fixed_length_from_single_small_helper(5, exhaustive_units(), 1, &[&[(); 5]]); lex_vecs_fixed_length_from_single_small_helper(0, exhaustive_unsigneds::(), 1, &[&[]]); lex_vecs_fixed_length_from_single_small_helper( 1, exhaustive_unsigneds::(), 256, &[ &[0], &[1], &[2], &[3], &[4], &[5], &[6], &[7], &[8], &[9], &[10], &[11], &[12], &[13], &[14], &[15], &[16], &[17], &[18], &[19], ], ); lex_vecs_fixed_length_from_single_helper( 1, exhaustive_unsigneds::(), &[ &[0], &[1], &[2], &[3], &[4], &[5], &[6], &[7], &[8], &[9], &[10], &[11], &[12], &[13], &[14], &[15], &[16], &[17], &[18], &[19], ], ); lex_vecs_fixed_length_from_single_small_helper( 2, exhaustive_unsigneds::(), 0x10000, &[ &[0, 0], &[0, 1], &[0, 2], &[0, 3], &[0, 4], &[0, 5], &[0, 6], &[0, 7], &[0, 8], &[0, 9], &[0, 10], &[0, 11], &[0, 12], &[0, 13], &[0, 14], &[0, 15], &[0, 16], &[0, 17], &[0, 18], &[0, 19], ], ); lex_vecs_fixed_length_from_single_helper( 3, exhaustive_unsigneds::(), &[ &[0, 0, 0], &[0, 0, 1], &[0, 0, 2], &[0, 0, 3], &[0, 0, 4], &[0, 0, 5], &[0, 0, 6], &[0, 0, 7], &[0, 0, 8], &[0, 0, 9], &[0, 0, 10], &[0, 0, 11], &[0, 0, 12], &[0, 0, 13], &[0, 0, 14], &[0, 0, 15], &[0, 0, 16], &[0, 0, 17], &[0, 0, 18], &[0, 0, 19], ], ); lex_vecs_fixed_length_from_single_small_helper( 2, exhaustive_ascii_chars(), 0x4000, &[ &['a', 'a'], &['a', 'b'], &['a', 'c'], &['a', 'd'], &['a', 'e'], &['a', 'f'], &['a', 'g'], &['a', 'h'], &['a', 'i'], &['a', 'j'], &['a', 'k'], &['a', 'l'], &['a', 'm'], &['a', 'n'], &['a', 'o'], &['a', 'p'], &['a', 'q'], &['a', 'r'], &['a', 's'], &['a', 't'], ], ); lex_vecs_fixed_length_from_single_small_helper(1, exhaustive_bools(), 2, &[&[false], &[true]]); lex_vecs_fixed_length_from_single_small_helper( 2, exhaustive_bools(), 4, &[&[false, false], &[false, true], &[true, false], &[true, true]], ); lex_vecs_fixed_length_from_single_small_helper( 4, exhaustive_bools(), 16, &[ &[false, false, false, false], &[false, false, false, true], &[false, false, true, false], &[false, false, true, true], &[false, true, false, false], &[false, true, false, true], &[false, true, true, false], &[false, true, true, true], &[true, false, false, false], &[true, false, false, true], &[true, false, true, false], &[true, false, true, true], &[true, true, false, false], &[true, true, false, true], &[true, true, true, false], &[true, true, true, true], ], ); lex_vecs_fixed_length_from_single_small_helper( 10, exhaustive_bools(), 1024, &[ &[false, false, false, false, false, false, false, false, false, false], &[false, false, false, false, false, false, false, false, false, true], &[false, false, false, false, false, false, false, false, true, false], &[false, false, false, false, false, false, false, false, true, true], &[false, false, false, false, false, false, false, true, false, false], &[false, false, false, false, false, false, false, true, false, true], &[false, false, false, false, false, false, false, true, true, false], &[false, false, false, false, false, false, false, true, true, true], &[false, false, false, false, false, false, true, false, false, false], &[false, false, false, false, false, false, true, false, false, true], &[false, false, false, false, false, false, true, false, true, false], &[false, false, false, false, false, false, true, false, true, true], &[false, false, false, false, false, false, true, true, false, false], &[false, false, false, false, false, false, true, true, false, true], &[false, false, false, false, false, false, true, true, true, false], &[false, false, false, false, false, false, true, true, true, true], &[false, false, false, false, false, true, false, false, false, false], &[false, false, false, false, false, true, false, false, false, true], &[false, false, false, false, false, true, false, false, true, false], &[false, false, false, false, false, true, false, false, true, true], ], ); lex_vecs_fixed_length_from_single_small_helper( 10, 0..3, 59049, &[ &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], &[0, 0, 0, 0, 0, 0, 0, 0, 0, 1], &[0, 0, 0, 0, 0, 0, 0, 0, 0, 2], &[0, 0, 0, 0, 0, 0, 0, 0, 1, 0], &[0, 0, 0, 0, 0, 0, 0, 0, 1, 1], &[0, 0, 0, 0, 0, 0, 0, 0, 1, 2], &[0, 0, 0, 0, 0, 0, 0, 0, 2, 0], &[0, 0, 0, 0, 0, 0, 0, 0, 2, 1], &[0, 0, 0, 0, 0, 0, 0, 0, 2, 2], &[0, 0, 0, 0, 0, 0, 0, 1, 0, 0], &[0, 0, 0, 0, 0, 0, 0, 1, 0, 1], &[0, 0, 0, 0, 0, 0, 0, 1, 0, 2], &[0, 0, 0, 0, 0, 0, 0, 1, 1, 0], &[0, 0, 0, 0, 0, 0, 0, 1, 1, 1], &[0, 0, 0, 0, 0, 0, 0, 1, 1, 2], &[0, 0, 0, 0, 0, 0, 0, 1, 2, 0], &[0, 0, 0, 0, 0, 0, 0, 1, 2, 1], &[0, 0, 0, 0, 0, 0, 0, 1, 2, 2], &[0, 0, 0, 0, 0, 0, 0, 2, 0, 0], &[0, 0, 0, 0, 0, 0, 0, 2, 0, 1], ], ); lex_vecs_fixed_length_from_single_helper( 2, lex_vecs_fixed_length_from_single(2, exhaustive_unsigneds::()), &[ &[vec![0, 0], vec![0, 0]], &[vec![0, 0], vec![0, 1]], &[vec![0, 0], vec![0, 2]], &[vec![0, 0], vec![0, 3]], &[vec![0, 0], vec![0, 4]], &[vec![0, 0], vec![0, 5]], &[vec![0, 0], vec![0, 6]], &[vec![0, 0], vec![0, 7]], &[vec![0, 0], vec![0, 8]], &[vec![0, 0], vec![0, 9]], &[vec![0, 0], vec![0, 10]], &[vec![0, 0], vec![0, 11]], &[vec![0, 0], vec![0, 12]], &[vec![0, 0], vec![0, 13]], &[vec![0, 0], vec![0, 14]], &[vec![0, 0], vec![0, 15]], &[vec![0, 0], vec![0, 16]], &[vec![0, 0], vec![0, 17]], &[vec![0, 0], vec![0, 18]], &[vec![0, 0], vec![0, 19]], ], ); } malachite-base-0.4.16/tests/vecs/exhaustive/lex_vecs_fixed_length_m_inputs.rs000064400000000000000000000116751046102023000256700ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::num::exhaustive::{exhaustive_positive_primitive_ints, exhaustive_unsigneds}; use malachite_base::vecs::exhaustive::lex_vecs_fixed_length_2_inputs; use std::fmt::Debug; use std::iter::empty; fn lex_vecs_fixed_length_2_inputs_helper< T: Clone + Debug + Eq, I: Clone + Iterator, J: Clone + Iterator, >( xs: &I, ys: &J, output_to_input_map: &[usize], out_len: Option, out: &[&[T]], ) { let xss = lex_vecs_fixed_length_2_inputs(xs.clone(), ys.clone(), output_to_input_map); let xss_prefix = xss.clone().take(20).collect_vec(); assert_eq!( xss_prefix .iter() .map(Vec::as_slice) .collect_vec() .as_slice(), out ); if let Some(out_len) = out_len { assert_eq!(xss.count(), out_len); } } #[test] fn test_lex_vecs_fixed_length_2_inputs() { lex_vecs_fixed_length_2_inputs_helper(&nevers(), &nevers(), &[0, 1], Some(0), &[]); lex_vecs_fixed_length_2_inputs_helper( &empty(), &exhaustive_unsigneds::(), &[0, 1], Some(0), &[], ); lex_vecs_fixed_length_2_inputs_helper( &exhaustive_unsigneds::(), &exhaustive_positive_primitive_ints::(), &[0, 1], None, &[ &[0, 1], &[0, 2], &[0, 3], &[0, 4], &[0, 5], &[0, 6], &[0, 7], &[0, 8], &[0, 9], &[0, 10], &[0, 11], &[0, 12], &[0, 13], &[0, 14], &[0, 15], &[0, 16], &[0, 17], &[0, 18], &[0, 19], &[0, 20], ], ); lex_vecs_fixed_length_2_inputs_helper( &exhaustive_ascii_chars(), &['x', 'y', 'z'].iter().copied(), &[0, 1], Some(384), &[ &['a', 'x'], &['a', 'y'], &['a', 'z'], &['b', 'x'], &['b', 'y'], &['b', 'z'], &['c', 'x'], &['c', 'y'], &['c', 'z'], &['d', 'x'], &['d', 'y'], &['d', 'z'], &['e', 'x'], &['e', 'y'], &['e', 'z'], &['f', 'x'], &['f', 'y'], &['f', 'z'], &['g', 'x'], &['g', 'y'], ], ); lex_vecs_fixed_length_2_inputs_helper( &exhaustive_ascii_chars(), &['x', 'y', 'z'].iter().copied(), &[0, 1, 1], Some(1152), &[ &['a', 'x', 'x'], &['a', 'x', 'y'], &['a', 'x', 'z'], &['a', 'y', 'x'], &['a', 'y', 'y'], &['a', 'y', 'z'], &['a', 'z', 'x'], &['a', 'z', 'y'], &['a', 'z', 'z'], &['b', 'x', 'x'], &['b', 'x', 'y'], &['b', 'x', 'z'], &['b', 'y', 'x'], &['b', 'y', 'y'], &['b', 'y', 'z'], &['b', 'z', 'x'], &['b', 'z', 'y'], &['b', 'z', 'z'], &['c', 'x', 'x'], &['c', 'x', 'y'], ], ); lex_vecs_fixed_length_2_inputs_helper( &exhaustive_ascii_chars(), &['x', 'y', 'z'].iter().copied(), &[0, 1, 0], Some(49152), &[ &['a', 'x', 'a'], &['a', 'x', 'b'], &['a', 'x', 'c'], &['a', 'x', 'd'], &['a', 'x', 'e'], &['a', 'x', 'f'], &['a', 'x', 'g'], &['a', 'x', 'h'], &['a', 'x', 'i'], &['a', 'x', 'j'], &['a', 'x', 'k'], &['a', 'x', 'l'], &['a', 'x', 'm'], &['a', 'x', 'n'], &['a', 'x', 'o'], &['a', 'x', 'p'], &['a', 'x', 'q'], &['a', 'x', 'r'], &['a', 'x', 's'], &['a', 'x', 't'], ], ); } #[test] #[should_panic] fn lex_vecs_fixed_length_2_inputs_fail_1() { lex_vecs_fixed_length_2_inputs(0..2, 0..3, &[]); } #[test] #[should_panic] fn lex_vecs_fixed_length_2_inputs_fail_2() { lex_vecs_fixed_length_2_inputs(0..2, 0..3, &[0]); } #[test] #[should_panic] fn lex_vecs_fixed_length_2_inputs_fail_3() { lex_vecs_fixed_length_2_inputs(0..2, 0..3, &[1]); } #[test] #[should_panic] fn lex_vecs_fixed_length_2_inputs_fail_4() { lex_vecs_fixed_length_2_inputs(0..2, 0..3, &[0, 1, 2]); } malachite-base-0.4.16/tests/vecs/exhaustive/lex_vecs_length_n.rs000064400000000000000000000225011046102023000230760ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::extra_variadic::lex_vecs_length_3; use malachite_base::nevers::nevers; use malachite_base::num::exhaustive::exhaustive_unsigneds; use malachite_base::orderings::exhaustive::exhaustive_orderings; use malachite_base::test_util::vecs::exhaustive::{ exhaustive_vecs_helper_helper, exhaustive_vecs_small_helper_helper, }; use malachite_base::vecs::exhaustive::{ exhaustive_vecs_fixed_length_from_single, lex_vecs_length_2, }; use std::cmp::Ordering::*; use std::fmt::Debug; use std::iter::{empty, once}; fn lex_vecs_length_2_helper, J: Iterator>( xs: I, ys: J, out: &[&[T]], ) { exhaustive_vecs_helper_helper(lex_vecs_length_2(xs, ys), out); } fn lex_vecs_length_2_finite_helper< T: Clone + Debug + Eq, I: Clone + Iterator, J: Clone + Iterator, >( xs: I, ys: J, out_len: usize, out: &[&[T]], ) { exhaustive_vecs_small_helper_helper(lex_vecs_length_2(xs, ys), out_len, out); } #[test] fn test_lex_vecs_length_2() { lex_vecs_length_2_finite_helper(nevers(), nevers(), 0, &[]); lex_vecs_length_2_finite_helper(empty(), 0..4, 0, &[]); lex_vecs_length_2_finite_helper(once(0), once(1), 1, &[&[0, 1]]); lex_vecs_length_2_finite_helper(once(0), 0..4, 4, &[&[0, 0], &[0, 1], &[0, 2], &[0, 3]]); lex_vecs_length_2_finite_helper( exhaustive_unsigneds::(), 0..4, 1024, &[ &[0, 0], &[0, 1], &[0, 2], &[0, 3], &[1, 0], &[1, 1], &[1, 2], &[1, 3], &[2, 0], &[2, 1], &[2, 2], &[2, 3], &[3, 0], &[3, 1], &[3, 2], &[3, 3], &[4, 0], &[4, 1], &[4, 2], &[4, 3], ], ); lex_vecs_length_2_helper( exhaustive_unsigneds::(), 0..4, &[ &[0, 0], &[0, 1], &[0, 2], &[0, 3], &[1, 0], &[1, 1], &[1, 2], &[1, 3], &[2, 0], &[2, 1], &[2, 2], &[2, 3], &[3, 0], &[3, 1], &[3, 2], &[3, 3], &[4, 0], &[4, 1], &[4, 2], &[4, 3], ], ); lex_vecs_length_2_finite_helper( 0..2, 0..4, 8, &[&[0, 0], &[0, 1], &[0, 2], &[0, 3], &[1, 0], &[1, 1], &[1, 2], &[1, 3]], ); lex_vecs_length_2_finite_helper( 0..5, 0..3, 15, &[ &[0, 0], &[0, 1], &[0, 2], &[1, 0], &[1, 1], &[1, 2], &[2, 0], &[2, 1], &[2, 2], &[3, 0], &[3, 1], &[3, 2], &[4, 0], &[4, 1], &[4, 2], ], ); lex_vecs_length_2_finite_helper( ['a', 'b', 'c'].iter().copied(), ['x', 'y', 'z'].iter().copied(), 9, &[ &['a', 'x'], &['a', 'y'], &['a', 'z'], &['b', 'x'], &['b', 'y'], &['b', 'z'], &['c', 'x'], &['c', 'y'], &['c', 'z'], ], ); lex_vecs_length_2_finite_helper( lex_vecs_length_2(exhaustive_orderings(), [Less, Greater].iter().copied()), exhaustive_vecs_fixed_length_from_single(3, [Less, Greater].iter().copied()), 48, &[ &[vec![Equal, Less], vec![Less, Less, Less]], &[vec![Equal, Less], vec![Less, Less, Greater]], &[vec![Equal, Less], vec![Less, Greater, Less]], &[vec![Equal, Less], vec![Less, Greater, Greater]], &[vec![Equal, Less], vec![Greater, Less, Less]], &[vec![Equal, Less], vec![Greater, Less, Greater]], &[vec![Equal, Less], vec![Greater, Greater, Less]], &[vec![Equal, Less], vec![Greater, Greater, Greater]], &[vec![Equal, Greater], vec![Less, Less, Less]], &[vec![Equal, Greater], vec![Less, Less, Greater]], &[vec![Equal, Greater], vec![Less, Greater, Less]], &[vec![Equal, Greater], vec![Less, Greater, Greater]], &[vec![Equal, Greater], vec![Greater, Less, Less]], &[vec![Equal, Greater], vec![Greater, Less, Greater]], &[vec![Equal, Greater], vec![Greater, Greater, Less]], &[vec![Equal, Greater], vec![Greater, Greater, Greater]], &[vec![Less, Less], vec![Less, Less, Less]], &[vec![Less, Less], vec![Less, Less, Greater]], &[vec![Less, Less], vec![Less, Greater, Less]], &[vec![Less, Less], vec![Less, Greater, Greater]], ], ); } fn lex_vecs_length_3_helper< T, I: Iterator, J: Iterator, K: Iterator, >( xs: I, ys: J, zs: K, out: &[&[T]], ) where T: Clone + Debug + Eq, { exhaustive_vecs_helper_helper(lex_vecs_length_3(xs, ys, zs), out); } fn lex_vecs_length_3_finite_helper< T, I: Clone + Iterator, J: Clone + Iterator, K: Clone + Iterator, >( xs: I, ys: J, zs: K, out_len: usize, out: &[&[T]], ) where T: Clone + Debug + Eq, { exhaustive_vecs_small_helper_helper(lex_vecs_length_3(xs, ys, zs), out_len, out); } #[test] fn test_lex_vecs_length_3() { lex_vecs_length_3_finite_helper(nevers(), nevers(), nevers(), 0, &[]); lex_vecs_length_3_finite_helper(empty(), 0..4, 0..5, 0, &[]); lex_vecs_length_3_finite_helper(once(0), once(1), once(5), 1, &[&[0, 1, 5]]); lex_vecs_length_3_finite_helper( once(0), once(3), 0..4, 4, &[&[0, 3, 0], &[0, 3, 1], &[0, 3, 2], &[0, 3, 3]], ); lex_vecs_length_3_finite_helper( exhaustive_unsigneds::(), 0..4, 0..4, 4096, &[ &[0, 0, 0], &[0, 0, 1], &[0, 0, 2], &[0, 0, 3], &[0, 1, 0], &[0, 1, 1], &[0, 1, 2], &[0, 1, 3], &[0, 2, 0], &[0, 2, 1], &[0, 2, 2], &[0, 2, 3], &[0, 3, 0], &[0, 3, 1], &[0, 3, 2], &[0, 3, 3], &[1, 0, 0], &[1, 0, 1], &[1, 0, 2], &[1, 0, 3], ], ); lex_vecs_length_3_helper( exhaustive_unsigneds::(), 0..4, 0..4, &[ &[0, 0, 0], &[0, 0, 1], &[0, 0, 2], &[0, 0, 3], &[0, 1, 0], &[0, 1, 1], &[0, 1, 2], &[0, 1, 3], &[0, 2, 0], &[0, 2, 1], &[0, 2, 2], &[0, 2, 3], &[0, 3, 0], &[0, 3, 1], &[0, 3, 2], &[0, 3, 3], &[1, 0, 0], &[1, 0, 1], &[1, 0, 2], &[1, 0, 3], ], ); lex_vecs_length_3_finite_helper( 0..2, 0..3, 0..3, 18, &[ &[0, 0, 0], &[0, 0, 1], &[0, 0, 2], &[0, 1, 0], &[0, 1, 1], &[0, 1, 2], &[0, 2, 0], &[0, 2, 1], &[0, 2, 2], &[1, 0, 0], &[1, 0, 1], &[1, 0, 2], &[1, 1, 0], &[1, 1, 1], &[1, 1, 2], &[1, 2, 0], &[1, 2, 1], &[1, 2, 2], ], ); lex_vecs_length_3_finite_helper( 0..11, 0..12, 0..13, 1716, &[ &[0, 0, 0], &[0, 0, 1], &[0, 0, 2], &[0, 0, 3], &[0, 0, 4], &[0, 0, 5], &[0, 0, 6], &[0, 0, 7], &[0, 0, 8], &[0, 0, 9], &[0, 0, 10], &[0, 0, 11], &[0, 0, 12], &[0, 1, 0], &[0, 1, 1], &[0, 1, 2], &[0, 1, 3], &[0, 1, 4], &[0, 1, 5], &[0, 1, 6], ], ); lex_vecs_length_3_finite_helper( ['a', 'b', 'c'].iter().copied(), ['x', 'y', 'z'].iter().copied(), ['0', '1', '2'].iter().copied(), 27, &[ &['a', 'x', '0'], &['a', 'x', '1'], &['a', 'x', '2'], &['a', 'y', '0'], &['a', 'y', '1'], &['a', 'y', '2'], &['a', 'z', '0'], &['a', 'z', '1'], &['a', 'z', '2'], &['b', 'x', '0'], &['b', 'x', '1'], &['b', 'x', '2'], &['b', 'y', '0'], &['b', 'y', '1'], &['b', 'y', '2'], &['b', 'z', '0'], &['b', 'z', '1'], &['b', 'z', '2'], &['c', 'x', '0'], &['c', 'x', '1'], ], ); } malachite-base-0.4.16/tests/vecs/exhaustive/next_bit_pattern.rs000064400000000000000000000154761046102023000227760ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::repeat_n; use malachite_base::num::arithmetic::traits::BinomialCoefficient; use malachite_base::vecs::exhaustive::next_bit_pattern; fn pattern_to_string(pattern: &[bool]) -> String { let mut s = String::with_capacity(pattern.len()); for &b in pattern.iter().rev() { s.push(if b { '1' } else { '0' }); } s } fn next_bit_pattern_helper( width: usize, min_bits: usize, max_bits: usize, expected_patterns: &[&'static str], ) { assert!(min_bits <= max_bits); assert_ne!(max_bits, 0); assert!(width >= min_bits); let mut pattern: Vec = repeat_n(false, width).collect(); for b in &mut pattern[..min_bits] { *b = true; } let mut bit_count = min_bits; let mut patterns = Vec::new(); while pattern.len() == width { assert_eq!(pattern.iter().filter(|&&b| b).count(), bit_count); assert!(bit_count >= min_bits); assert!(bit_count <= max_bits); patterns.push(pattern_to_string(&pattern)); next_bit_pattern(&mut pattern, &mut bit_count, min_bits, max_bits); } assert_eq!( patterns.len(), (min_bits..=max_bits) .map(|b| usize::binomial_coefficient(width, b)) .sum() ); assert_eq!(patterns, expected_patterns); } #[test] fn test_next_bit_pattern() { next_bit_pattern_helper(5, 1, 1, &["00001", "00010", "00100", "01000", "10000"]); next_bit_pattern_helper( 5, 2, 2, &["00011", "00101", "00110", "01001", "01010", "01100", "10001", "10010", "10100", "11000"], ); next_bit_pattern_helper( 5, 3, 3, &["00111", "01011", "01101", "01110", "10011", "10101", "10110", "11001", "11010", "11100"], ); next_bit_pattern_helper(5, 4, 4, &["01111", "10111", "11011", "11101", "11110"]); next_bit_pattern_helper(5, 5, 5, &["11111"]); next_bit_pattern_helper( 5, 0, 1, &["00000", "00001", "00010", "00100", "01000", "10000"], ); next_bit_pattern_helper( 5, 1, 2, &[ "00001", "00010", "00011", "00100", "00101", "00110", "01000", "01001", "01010", "01100", "10000", "10001", "10010", "10100", "11000", ], ); next_bit_pattern_helper( 5, 2, 3, &[ "00011", "00101", "00110", "00111", "01001", "01010", "01011", "01100", "01101", "01110", "10001", "10010", "10011", "10100", "10101", "10110", "11000", "11001", "11010", "11100", ], ); next_bit_pattern_helper( 5, 3, 4, &[ "00111", "01011", "01101", "01110", "01111", "10011", "10101", "10110", "10111", "11001", "11010", "11011", "11100", "11101", "11110", ], ); next_bit_pattern_helper( 5, 4, 5, &["01111", "10111", "11011", "11101", "11110", "11111"], ); next_bit_pattern_helper( 5, 0, 2, &[ "00000", "00001", "00010", "00011", "00100", "00101", "00110", "01000", "01001", "01010", "01100", "10000", "10001", "10010", "10100", "11000", ], ); next_bit_pattern_helper( 5, 1, 3, &[ "00001", "00010", "00011", "00100", "00101", "00110", "00111", "01000", "01001", "01010", "01011", "01100", "01101", "01110", "10000", "10001", "10010", "10011", "10100", "10101", "10110", "11000", "11001", "11010", "11100", ], ); next_bit_pattern_helper( 5, 2, 4, &[ "00011", "00101", "00110", "00111", "01001", "01010", "01011", "01100", "01101", "01110", "01111", "10001", "10010", "10011", "10100", "10101", "10110", "10111", "11000", "11001", "11010", "11011", "11100", "11101", "11110", ], ); next_bit_pattern_helper( 5, 3, 5, &[ "00111", "01011", "01101", "01110", "01111", "10011", "10101", "10110", "10111", "11001", "11010", "11011", "11100", "11101", "11110", "11111", ], ); next_bit_pattern_helper( 5, 0, 3, &[ "00000", "00001", "00010", "00011", "00100", "00101", "00110", "00111", "01000", "01001", "01010", "01011", "01100", "01101", "01110", "10000", "10001", "10010", "10011", "10100", "10101", "10110", "11000", "11001", "11010", "11100", ], ); next_bit_pattern_helper( 5, 1, 4, &[ "00001", "00010", "00011", "00100", "00101", "00110", "00111", "01000", "01001", "01010", "01011", "01100", "01101", "01110", "01111", "10000", "10001", "10010", "10011", "10100", "10101", "10110", "10111", "11000", "11001", "11010", "11011", "11100", "11101", "11110", ], ); next_bit_pattern_helper( 5, 2, 5, &[ "00011", "00101", "00110", "00111", "01001", "01010", "01011", "01100", "01101", "01110", "01111", "10001", "10010", "10011", "10100", "10101", "10110", "10111", "11000", "11001", "11010", "11011", "11100", "11101", "11110", "11111", ], ); next_bit_pattern_helper( 5, 0, 4, &[ "00000", "00001", "00010", "00011", "00100", "00101", "00110", "00111", "01000", "01001", "01010", "01011", "01100", "01101", "01110", "01111", "10000", "10001", "10010", "10011", "10100", "10101", "10110", "10111", "11000", "11001", "11010", "11011", "11100", "11101", "11110", ], ); next_bit_pattern_helper( 5, 1, 5, &[ "00001", "00010", "00011", "00100", "00101", "00110", "00111", "01000", "01001", "01010", "01011", "01100", "01101", "01110", "01111", "10000", "10001", "10010", "10011", "10100", "10101", "10110", "10111", "11000", "11001", "11010", "11011", "11100", "11101", "11110", "11111", ], ); next_bit_pattern_helper( 5, 0, 5, &[ "00000", "00001", "00010", "00011", "00100", "00101", "00110", "00111", "01000", "01001", "01010", "01011", "01100", "01101", "01110", "01111", "10000", "10001", "10010", "10011", "10100", "10101", "10110", "10111", "11000", "11001", "11010", "11011", "11100", "11101", "11110", "11111", ], ); } malachite-base-0.4.16/tests/vecs/exhaustive/shortlex_ordered_unique_vecs.rs000064400000000000000000000053571046102023000254040ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::test_util::vecs::exhaustive::{ exhaustive_vecs_helper_helper, exhaustive_vecs_small_helper_helper, }; use malachite_base::tuples::exhaustive::exhaustive_units; use malachite_base::vecs::exhaustive::shortlex_ordered_unique_vecs; use std::fmt::Debug; fn shortlex_ordered_unique_vecs_helper(xs: I, out: &[&[I::Item]]) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_helper_helper(shortlex_ordered_unique_vecs(xs), out); } fn shortlex_ordered_unique_vecs_small_helper( xs: I, out_len: usize, out: &[&[I::Item]], ) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_small_helper_helper(shortlex_ordered_unique_vecs(xs), out_len, out); } #[test] fn test_shortlex_ordered_unique_vecs() { shortlex_ordered_unique_vecs_small_helper(nevers(), 1, &[&[]]); shortlex_ordered_unique_vecs_small_helper(exhaustive_units(), 2, &[&[], &[()]]); shortlex_ordered_unique_vecs_small_helper( exhaustive_bools(), 4, &[&[], &[false], &[true], &[false, true]], ); shortlex_ordered_unique_vecs_small_helper( 1..=6, 64, &[ &[], &[1], &[2], &[3], &[4], &[5], &[6], &[1, 2], &[1, 3], &[1, 4], &[1, 5], &[1, 6], &[2, 3], &[2, 4], &[2, 5], &[2, 6], &[3, 4], &[3, 5], &[3, 6], &[4, 5], ], ); shortlex_ordered_unique_vecs_small_helper( 'a'..='c', 8, &[&[], &['a'], &['b'], &['c'], &['a', 'b'], &['a', 'c'], &['b', 'c'], &['a', 'b', 'c']], ); shortlex_ordered_unique_vecs_helper( exhaustive_ascii_chars(), &[ &[], &['a'], &['b'], &['c'], &['d'], &['e'], &['f'], &['g'], &['h'], &['i'], &['j'], &['k'], &['l'], &['m'], &['n'], &['o'], &['p'], &['q'], &['r'], &['s'], ], ); } malachite-base-0.4.16/tests/vecs/exhaustive/shortlex_ordered_unique_vecs_length_inclusive_range.rs000064400000000000000000000041711046102023000321730ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::nevers::nevers; use malachite_base::test_util::vecs::exhaustive::exhaustive_vecs_small_helper_helper; use malachite_base::tuples::exhaustive::exhaustive_units; use malachite_base::vecs::exhaustive::shortlex_ordered_unique_vecs_length_inclusive_range; use std::fmt::Debug; fn shortlex_ordered_unique_vecs_length_inclusive_range_small_helper( a: u64, b: u64, xs: I, out_len: usize, out: &[&[I::Item]], ) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_small_helper_helper( shortlex_ordered_unique_vecs_length_inclusive_range(a, b, xs), out_len, out, ); } #[test] fn test_shortlex_ordered_unique_vecs_length_inclusive_range() { shortlex_ordered_unique_vecs_length_inclusive_range_small_helper(0, 4, nevers(), 1, &[&[]]); shortlex_ordered_unique_vecs_length_inclusive_range_small_helper(6, 9, nevers(), 0, &[]); shortlex_ordered_unique_vecs_length_inclusive_range_small_helper( 0, 4, exhaustive_units(), 2, &[&[], &[()]], ); shortlex_ordered_unique_vecs_length_inclusive_range_small_helper( 1, 0, exhaustive_bools(), 0, &[], ); shortlex_ordered_unique_vecs_length_inclusive_range_small_helper( 0, 1, exhaustive_bools(), 3, &[&[], &[false], &[true]], ); shortlex_ordered_unique_vecs_length_inclusive_range_small_helper( 2, 3, exhaustive_bools(), 1, &[&[false, true]], ); shortlex_ordered_unique_vecs_length_inclusive_range_small_helper( 1, 1, 'a'..='c', 3, &[&['a'], &['b'], &['c']], ); } malachite-base-0.4.16/tests/vecs/exhaustive/shortlex_ordered_unique_vecs_length_range.rs000064400000000000000000000040731046102023000301130ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::nevers::nevers; use malachite_base::test_util::vecs::exhaustive::exhaustive_vecs_small_helper_helper; use malachite_base::tuples::exhaustive::exhaustive_units; use malachite_base::vecs::exhaustive::shortlex_ordered_unique_vecs_length_range; use std::fmt::Debug; fn shortlex_ordered_unique_vecs_length_range_small_helper( a: u64, b: u64, xs: I, out_len: usize, out: &[&[I::Item]], ) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_small_helper_helper( shortlex_ordered_unique_vecs_length_range(a, b, xs), out_len, out, ); } #[test] fn test_shortlex_ordered_unique_vecs_length_range() { shortlex_ordered_unique_vecs_length_range_small_helper(0, 5, nevers(), 1, &[&[]]); shortlex_ordered_unique_vecs_length_range_small_helper(6, 10, nevers(), 0, &[]); shortlex_ordered_unique_vecs_length_range_small_helper( 0, 5, exhaustive_units(), 2, &[&[], &[()]], ); shortlex_ordered_unique_vecs_length_range_small_helper(1, 0, exhaustive_bools(), 0, &[]); shortlex_ordered_unique_vecs_length_range_small_helper(1, 1, exhaustive_bools(), 0, &[]); shortlex_ordered_unique_vecs_length_range_small_helper( 0, 2, exhaustive_bools(), 3, &[&[], &[false], &[true]], ); shortlex_ordered_unique_vecs_length_range_small_helper( 2, 4, exhaustive_bools(), 1, &[&[false, true]], ); shortlex_ordered_unique_vecs_length_range_small_helper( 1, 2, 'a'..='c', 3, &[&['a'], &['b'], &['c']], ); } malachite-base-0.4.16/tests/vecs/exhaustive/shortlex_ordered_unique_vecs_min_length.rs000064400000000000000000000073231046102023000276030ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::test_util::vecs::exhaustive::{ exhaustive_vecs_helper_helper, exhaustive_vecs_small_helper_helper, }; use malachite_base::tuples::exhaustive::exhaustive_units; use malachite_base::vecs::exhaustive::shortlex_ordered_unique_vecs_min_length; use std::fmt::Debug; fn shortlex_ordered_unique_vecs_min_length_helper( min_length: u64, xs: I, out: &[&[I::Item]], ) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_helper_helper(shortlex_ordered_unique_vecs_min_length(min_length, xs), out); } fn shortlex_ordered_unique_vecs_min_length_small_helper( min_length: u64, xs: I, out_len: usize, out: &[&[I::Item]], ) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_small_helper_helper( shortlex_ordered_unique_vecs_min_length(min_length, xs), out_len, out, ); } #[test] fn test_shortlex_ordered_unique_vecs_min_length() { shortlex_ordered_unique_vecs_min_length_small_helper(0, nevers(), 1, &[&[]]); shortlex_ordered_unique_vecs_min_length_small_helper(4, nevers(), 0, &[]); shortlex_ordered_unique_vecs_min_length_small_helper(0, exhaustive_units(), 2, &[&[], &[()]]); shortlex_ordered_unique_vecs_min_length_small_helper(5, exhaustive_units(), 0, &[]); shortlex_ordered_unique_vecs_min_length_small_helper( 0, exhaustive_bools(), 4, &[&[], &[false], &[true], &[false, true]], ); shortlex_ordered_unique_vecs_min_length_small_helper( 1, exhaustive_bools(), 3, &[&[false], &[true], &[false, true]], ); shortlex_ordered_unique_vecs_min_length_small_helper( 0, 'a'..='c', 8, &[&[], &['a'], &['b'], &['c'], &['a', 'b'], &['a', 'c'], &['b', 'c'], &['a', 'b', 'c']], ); shortlex_ordered_unique_vecs_min_length_small_helper( 2, 'a'..='c', 4, &[&['a', 'b'], &['a', 'c'], &['b', 'c'], &['a', 'b', 'c']], ); shortlex_ordered_unique_vecs_min_length_helper( 0, exhaustive_ascii_chars(), &[ &[], &['a'], &['b'], &['c'], &['d'], &['e'], &['f'], &['g'], &['h'], &['i'], &['j'], &['k'], &['l'], &['m'], &['n'], &['o'], &['p'], &['q'], &['r'], &['s'], ], ); shortlex_ordered_unique_vecs_min_length_helper( 3, exhaustive_ascii_chars(), &[ &['a', 'b', 'c'], &['a', 'b', 'd'], &['a', 'b', 'e'], &['a', 'b', 'f'], &['a', 'b', 'g'], &['a', 'b', 'h'], &['a', 'b', 'i'], &['a', 'b', 'j'], &['a', 'b', 'k'], &['a', 'b', 'l'], &['a', 'b', 'm'], &['a', 'b', 'n'], &['a', 'b', 'o'], &['a', 'b', 'p'], &['a', 'b', 'q'], &['a', 'b', 'r'], &['a', 'b', 's'], &['a', 'b', 't'], &['a', 'b', 'u'], &['a', 'b', 'v'], ], ); } malachite-base-0.4.16/tests/vecs/exhaustive/shortlex_unique_vecs.rs000064400000000000000000000057371046102023000237020ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::test_util::vecs::exhaustive::{ exhaustive_vecs_helper_helper, exhaustive_vecs_small_helper_helper, }; use malachite_base::tuples::exhaustive::exhaustive_units; use malachite_base::vecs::exhaustive::shortlex_unique_vecs; use std::fmt::Debug; fn shortlex_unique_vecs_helper(xs: I, out: &[&[I::Item]]) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_helper_helper(shortlex_unique_vecs(xs), out); } fn shortlex_unique_vecs_small_helper(xs: I, out_len: usize, out: &[&[I::Item]]) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_small_helper_helper(shortlex_unique_vecs(xs), out_len, out); } #[test] fn test_shortlex_unique_vecs() { shortlex_unique_vecs_small_helper(nevers(), 1, &[&[]]); shortlex_unique_vecs_small_helper(exhaustive_units(), 2, &[&[], &[()]]); shortlex_unique_vecs_small_helper( exhaustive_bools(), 5, &[&[], &[false], &[true], &[false, true], &[true, false]], ); shortlex_unique_vecs_small_helper( 1..=6, 1957, &[ &[], &[1], &[2], &[3], &[4], &[5], &[6], &[1, 2], &[1, 3], &[1, 4], &[1, 5], &[1, 6], &[2, 1], &[2, 3], &[2, 4], &[2, 5], &[2, 6], &[3, 1], &[3, 2], &[3, 4], ], ); shortlex_unique_vecs_small_helper( 'a'..='c', 16, &[ &[], &['a'], &['b'], &['c'], &['a', 'b'], &['a', 'c'], &['b', 'a'], &['b', 'c'], &['c', 'a'], &['c', 'b'], &['a', 'b', 'c'], &['a', 'c', 'b'], &['b', 'a', 'c'], &['b', 'c', 'a'], &['c', 'a', 'b'], &['c', 'b', 'a'], ], ); shortlex_unique_vecs_helper( exhaustive_ascii_chars(), &[ &[], &['a'], &['b'], &['c'], &['d'], &['e'], &['f'], &['g'], &['h'], &['i'], &['j'], &['k'], &['l'], &['m'], &['n'], &['o'], &['p'], &['q'], &['r'], &['s'], ], ); } malachite-base-0.4.16/tests/vecs/exhaustive/shortlex_unique_vecs_length_inclusive_range.rs000064400000000000000000000040021046102023000304600ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::nevers::nevers; use malachite_base::test_util::vecs::exhaustive::exhaustive_vecs_small_helper_helper; use malachite_base::tuples::exhaustive::exhaustive_units; use malachite_base::vecs::exhaustive::shortlex_unique_vecs_length_inclusive_range; use std::fmt::Debug; fn shortlex_unique_vecs_length_inclusive_range_small_helper( a: u64, b: u64, xs: I, out_len: usize, out: &[&[I::Item]], ) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_small_helper_helper( shortlex_unique_vecs_length_inclusive_range(a, b, xs), out_len, out, ); } #[test] fn test_shortlex_unique_vecs_length_inclusive_range() { shortlex_unique_vecs_length_inclusive_range_small_helper(0, 4, nevers(), 1, &[&[]]); shortlex_unique_vecs_length_inclusive_range_small_helper(6, 9, nevers(), 0, &[]); shortlex_unique_vecs_length_inclusive_range_small_helper( 0, 4, exhaustive_units(), 2, &[&[], &[()]], ); shortlex_unique_vecs_length_inclusive_range_small_helper(1, 0, exhaustive_bools(), 0, &[]); shortlex_unique_vecs_length_inclusive_range_small_helper( 0, 1, exhaustive_bools(), 3, &[&[], &[false], &[true]], ); shortlex_unique_vecs_length_inclusive_range_small_helper( 2, 3, exhaustive_bools(), 2, &[&[false, true], &[true, false]], ); shortlex_unique_vecs_length_inclusive_range_small_helper( 1, 1, 'a'..='c', 3, &[&['a'], &['b'], &['c']], ); } malachite-base-0.4.16/tests/vecs/exhaustive/shortlex_unique_vecs_length_range.rs000064400000000000000000000035561046102023000264140ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::nevers::nevers; use malachite_base::test_util::vecs::exhaustive::exhaustive_vecs_small_helper_helper; use malachite_base::tuples::exhaustive::exhaustive_units; use malachite_base::vecs::exhaustive::shortlex_unique_vecs_length_range; use std::fmt::Debug; fn shortlex_unique_vecs_length_range_small_helper( a: u64, b: u64, xs: I, out_len: usize, out: &[&[I::Item]], ) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_small_helper_helper(shortlex_unique_vecs_length_range(a, b, xs), out_len, out); } #[test] fn test_shortlex_unique_vecs_length_range() { shortlex_unique_vecs_length_range_small_helper(0, 5, nevers(), 1, &[&[]]); shortlex_unique_vecs_length_range_small_helper(6, 10, nevers(), 0, &[]); shortlex_unique_vecs_length_range_small_helper(0, 5, exhaustive_units(), 2, &[&[], &[()]]); shortlex_unique_vecs_length_range_small_helper(1, 0, exhaustive_bools(), 0, &[]); shortlex_unique_vecs_length_range_small_helper(1, 1, exhaustive_bools(), 0, &[]); shortlex_unique_vecs_length_range_small_helper( 0, 2, exhaustive_bools(), 3, &[&[], &[false], &[true]], ); shortlex_unique_vecs_length_range_small_helper( 2, 4, exhaustive_bools(), 2, &[&[false, true], &[true, false]], ); shortlex_unique_vecs_length_range_small_helper(1, 2, 'a'..='c', 3, &[&['a'], &['b'], &['c']]); } malachite-base-0.4.16/tests/vecs/exhaustive/shortlex_unique_vecs_min_length.rs000064400000000000000000000103351046102023000260740ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::test_util::vecs::exhaustive::{ exhaustive_vecs_helper_helper, exhaustive_vecs_small_helper_helper, }; use malachite_base::tuples::exhaustive::exhaustive_units; use malachite_base::vecs::exhaustive::shortlex_unique_vecs_min_length; use std::fmt::Debug; fn shortlex_unique_vecs_min_length_helper( min_length: u64, xs: I, out: &[&[I::Item]], ) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_helper_helper(shortlex_unique_vecs_min_length(min_length, xs), out); } fn shortlex_unique_vecs_min_length_small_helper( min_length: u64, xs: I, out_len: usize, out: &[&[I::Item]], ) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_small_helper_helper( shortlex_unique_vecs_min_length(min_length, xs), out_len, out, ); } #[test] fn test_shortlex_unique_vecs_min_length() { shortlex_unique_vecs_min_length_small_helper(0, nevers(), 1, &[&[]]); shortlex_unique_vecs_min_length_small_helper(4, nevers(), 0, &[]); shortlex_unique_vecs_min_length_small_helper(0, exhaustive_units(), 2, &[&[], &[()]]); shortlex_unique_vecs_min_length_small_helper(5, exhaustive_units(), 0, &[]); shortlex_unique_vecs_min_length_small_helper( 0, exhaustive_bools(), 5, &[&[], &[false], &[true], &[false, true], &[true, false]], ); shortlex_unique_vecs_min_length_small_helper( 1, exhaustive_bools(), 4, &[&[false], &[true], &[false, true], &[true, false]], ); shortlex_unique_vecs_min_length_small_helper( 0, 'a'..='c', 16, &[ &[], &['a'], &['b'], &['c'], &['a', 'b'], &['a', 'c'], &['b', 'a'], &['b', 'c'], &['c', 'a'], &['c', 'b'], &['a', 'b', 'c'], &['a', 'c', 'b'], &['b', 'a', 'c'], &['b', 'c', 'a'], &['c', 'a', 'b'], &['c', 'b', 'a'], ], ); shortlex_unique_vecs_min_length_small_helper( 2, 'a'..='c', 12, &[ &['a', 'b'], &['a', 'c'], &['b', 'a'], &['b', 'c'], &['c', 'a'], &['c', 'b'], &['a', 'b', 'c'], &['a', 'c', 'b'], &['b', 'a', 'c'], &['b', 'c', 'a'], &['c', 'a', 'b'], &['c', 'b', 'a'], ], ); shortlex_unique_vecs_min_length_helper( 0, exhaustive_ascii_chars(), &[ &[], &['a'], &['b'], &['c'], &['d'], &['e'], &['f'], &['g'], &['h'], &['i'], &['j'], &['k'], &['l'], &['m'], &['n'], &['o'], &['p'], &['q'], &['r'], &['s'], ], ); shortlex_unique_vecs_min_length_helper( 3, exhaustive_ascii_chars(), &[ &['a', 'b', 'c'], &['a', 'b', 'd'], &['a', 'b', 'e'], &['a', 'b', 'f'], &['a', 'b', 'g'], &['a', 'b', 'h'], &['a', 'b', 'i'], &['a', 'b', 'j'], &['a', 'b', 'k'], &['a', 'b', 'l'], &['a', 'b', 'm'], &['a', 'b', 'n'], &['a', 'b', 'o'], &['a', 'b', 'p'], &['a', 'b', 'q'], &['a', 'b', 'r'], &['a', 'b', 's'], &['a', 'b', 't'], &['a', 'b', 'u'], &['a', 'b', 'v'], ], ); } malachite-base-0.4.16/tests/vecs/exhaustive/shortlex_vecs.rs000064400000000000000000000071761046102023000223130ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::test_util::vecs::exhaustive::exhaustive_vecs_helper_helper; use malachite_base::tuples::exhaustive::exhaustive_units; use malachite_base::vecs::exhaustive::shortlex_vecs; use std::fmt::Debug; fn shortlex_vecs_helper(xs: I, out: &[&[I::Item]]) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_helper_helper(shortlex_vecs(xs), out); } #[test] fn test_shortlex_vecs() { shortlex_vecs_helper(nevers(), &[&[]]); shortlex_vecs_helper( exhaustive_units(), &[ &[], &[()], &[(), ()], &[(), (), ()], &[(), (), (), ()], &[(), (), (), (), ()], &[(), (), (), (), (), ()], &[(), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), (), (), (), (), ()], &[(); 16], &[(); 17], &[(); 18], &[(); 19], ], ); shortlex_vecs_helper( exhaustive_bools(), &[ &[], &[false], &[true], &[false, false], &[false, true], &[true, false], &[true, true], &[false, false, false], &[false, false, true], &[false, true, false], &[false, true, true], &[true, false, false], &[true, false, true], &[true, true, false], &[true, true, true], &[false, false, false, false], &[false, false, false, true], &[false, false, true, false], &[false, false, true, true], &[false, true, false, false], ], ); shortlex_vecs_helper( 'a'..='c', &[ &[], &['a'], &['b'], &['c'], &['a', 'a'], &['a', 'b'], &['a', 'c'], &['b', 'a'], &['b', 'b'], &['b', 'c'], &['c', 'a'], &['c', 'b'], &['c', 'c'], &['a', 'a', 'a'], &['a', 'a', 'b'], &['a', 'a', 'c'], &['a', 'b', 'a'], &['a', 'b', 'b'], &['a', 'b', 'c'], &['a', 'c', 'a'], ], ); shortlex_vecs_helper( exhaustive_ascii_chars(), &[ &[], &['a'], &['b'], &['c'], &['d'], &['e'], &['f'], &['g'], &['h'], &['i'], &['j'], &['k'], &['l'], &['m'], &['n'], &['o'], &['p'], &['q'], &['r'], &['s'], ], ); } malachite-base-0.4.16/tests/vecs/exhaustive/shortlex_vecs_from_length_iterator.rs000064400000000000000000000057141046102023000266040ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::nevers::nevers; use malachite_base::num::exhaustive::exhaustive_unsigneds; use malachite_base::test_util::vecs::exhaustive::exhaustive_vecs_helper_helper; use malachite_base::vecs::exhaustive::shortlex_vecs_from_length_iterator; use std::fmt::Debug; use std::iter::empty; fn shortlex_vecs_from_element_iterator_helper, J: Clone + Iterator>( lengths: I, xs: J, out: &[&[J::Item]], ) where J::Item: Clone + Debug + Eq, { exhaustive_vecs_helper_helper(shortlex_vecs_from_length_iterator(lengths, xs), out); } #[test] fn test_shortlex_vecs_from_element_iterator() { shortlex_vecs_from_element_iterator_helper(empty(), exhaustive_bools(), &[]); shortlex_vecs_from_element_iterator_helper( [2, 1, 2].iter().copied(), exhaustive_bools(), &[ &[false, false], &[false, true], &[true, false], &[true, true], &[false], &[true], &[false, false], &[false, true], &[true, false], &[true, true], ], ); shortlex_vecs_from_element_iterator_helper( exhaustive_unsigneds::().map(|u| u << 1), exhaustive_bools(), &[ &[], &[false, false], &[false, true], &[true, false], &[true, true], &[false, false, false, false], &[false, false, false, true], &[false, false, true, false], &[false, false, true, true], &[false, true, false, false], &[false, true, false, true], &[false, true, true, false], &[false, true, true, true], &[true, false, false, false], &[true, false, false, true], &[true, false, true, false], &[true, false, true, true], &[true, true, false, false], &[true, true, false, true], &[true, true, true, false], ], ); shortlex_vecs_from_element_iterator_helper( [2, 1, 0, 2].iter().copied(), exhaustive_bools(), &[ &[false, false], &[false, true], &[true, false], &[true, true], &[false], &[true], &[], &[false, false], &[false, true], &[true, false], &[true, true], ], ); // Stops after first empty ys shortlex_vecs_from_element_iterator_helper([0, 0, 1, 0].iter().copied(), nevers(), &[&[], &[]]); } malachite-base-0.4.16/tests/vecs/exhaustive/shortlex_vecs_length_inclusive_range.rs000064400000000000000000000065011046102023000271000ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::nevers::nevers; use malachite_base::test_util::vecs::exhaustive::exhaustive_vecs_small_helper_helper; use malachite_base::tuples::exhaustive::exhaustive_units; use malachite_base::vecs::exhaustive::shortlex_vecs_length_inclusive_range; use std::fmt::Debug; fn shortlex_vecs_length_inclusive_range_small_helper( a: u64, b: u64, xs: I, out_len: usize, out: &[&[I::Item]], ) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_small_helper_helper( shortlex_vecs_length_inclusive_range(a, b, xs), out_len, out, ); } #[test] fn test_shortlex_vecs_length_inclusive_range() { shortlex_vecs_length_inclusive_range_small_helper(0, 4, nevers(), 1, &[&[]]); shortlex_vecs_length_inclusive_range_small_helper(6, 9, nevers(), 0, &[]); shortlex_vecs_length_inclusive_range_small_helper(5, 3, exhaustive_bools(), 0, &[]); shortlex_vecs_length_inclusive_range_small_helper( 0, 4, exhaustive_units(), 5, &[&[], &[()], &[(), ()], &[(), (), ()], &[(), (), (), ()]], ); shortlex_vecs_length_inclusive_range_small_helper( 1, 1, exhaustive_bools(), 2, &[&[false], &[true]], ); shortlex_vecs_length_inclusive_range_small_helper( 0, 2, exhaustive_bools(), 7, &[&[], &[false], &[true], &[false, false], &[false, true], &[true, false], &[true, true]], ); shortlex_vecs_length_inclusive_range_small_helper( 2, 3, exhaustive_bools(), 12, &[ &[false, false], &[false, true], &[true, false], &[true, true], &[false, false, false], &[false, false, true], &[false, true, false], &[false, true, true], &[true, false, false], &[true, false, true], &[true, true, false], &[true, true, true], ], ); shortlex_vecs_length_inclusive_range_small_helper( 5, 7, 'a'..='c', 3159, &[ &['a', 'a', 'a', 'a', 'a'], &['a', 'a', 'a', 'a', 'b'], &['a', 'a', 'a', 'a', 'c'], &['a', 'a', 'a', 'b', 'a'], &['a', 'a', 'a', 'b', 'b'], &['a', 'a', 'a', 'b', 'c'], &['a', 'a', 'a', 'c', 'a'], &['a', 'a', 'a', 'c', 'b'], &['a', 'a', 'a', 'c', 'c'], &['a', 'a', 'b', 'a', 'a'], &['a', 'a', 'b', 'a', 'b'], &['a', 'a', 'b', 'a', 'c'], &['a', 'a', 'b', 'b', 'a'], &['a', 'a', 'b', 'b', 'b'], &['a', 'a', 'b', 'b', 'c'], &['a', 'a', 'b', 'c', 'a'], &['a', 'a', 'b', 'c', 'b'], &['a', 'a', 'b', 'c', 'c'], &['a', 'a', 'c', 'a', 'a'], &['a', 'a', 'c', 'a', 'b'], ], ); } malachite-base-0.4.16/tests/vecs/exhaustive/shortlex_vecs_length_range.rs000064400000000000000000000061531046102023000250220ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::nevers::nevers; use malachite_base::test_util::vecs::exhaustive::exhaustive_vecs_small_helper_helper; use malachite_base::tuples::exhaustive::exhaustive_units; use malachite_base::vecs::exhaustive::shortlex_vecs_length_range; use std::fmt::Debug; fn shortlex_vecs_length_range_small_helper( a: u64, b: u64, xs: I, out_len: usize, out: &[&[I::Item]], ) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_small_helper_helper(shortlex_vecs_length_range(a, b, xs), out_len, out); } #[test] fn test_shortlex_vecs_length_range() { shortlex_vecs_length_range_small_helper(0, 5, nevers(), 1, &[&[]]); shortlex_vecs_length_range_small_helper(6, 10, nevers(), 0, &[]); shortlex_vecs_length_range_small_helper( 0, 5, exhaustive_units(), 5, &[&[], &[()], &[(), ()], &[(), (), ()], &[(), (), (), ()]], ); shortlex_vecs_length_range_small_helper(1, 1, exhaustive_bools(), 0, &[]); shortlex_vecs_length_range_small_helper(5, 3, exhaustive_bools(), 0, &[]); shortlex_vecs_length_range_small_helper( 0, 3, exhaustive_bools(), 7, &[&[], &[false], &[true], &[false, false], &[false, true], &[true, false], &[true, true]], ); shortlex_vecs_length_range_small_helper( 2, 4, exhaustive_bools(), 12, &[ &[false, false], &[false, true], &[true, false], &[true, true], &[false, false, false], &[false, false, true], &[false, true, false], &[false, true, true], &[true, false, false], &[true, false, true], &[true, true, false], &[true, true, true], ], ); shortlex_vecs_length_range_small_helper( 5, 8, 'a'..='c', 3159, &[ &['a', 'a', 'a', 'a', 'a'], &['a', 'a', 'a', 'a', 'b'], &['a', 'a', 'a', 'a', 'c'], &['a', 'a', 'a', 'b', 'a'], &['a', 'a', 'a', 'b', 'b'], &['a', 'a', 'a', 'b', 'c'], &['a', 'a', 'a', 'c', 'a'], &['a', 'a', 'a', 'c', 'b'], &['a', 'a', 'a', 'c', 'c'], &['a', 'a', 'b', 'a', 'a'], &['a', 'a', 'b', 'a', 'b'], &['a', 'a', 'b', 'a', 'c'], &['a', 'a', 'b', 'b', 'a'], &['a', 'a', 'b', 'b', 'b'], &['a', 'a', 'b', 'b', 'c'], &['a', 'a', 'b', 'c', 'a'], &['a', 'a', 'b', 'c', 'b'], &['a', 'a', 'b', 'c', 'c'], &['a', 'a', 'c', 'a', 'a'], &['a', 'a', 'c', 'a', 'b'], ], ); } malachite-base-0.4.16/tests/vecs/exhaustive/shortlex_vecs_min_length.rs000064400000000000000000000157451046102023000245200ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::bools::exhaustive::exhaustive_bools; use malachite_base::chars::exhaustive::exhaustive_ascii_chars; use malachite_base::nevers::nevers; use malachite_base::test_util::vecs::exhaustive::exhaustive_vecs_helper_helper; use malachite_base::tuples::exhaustive::exhaustive_units; use malachite_base::vecs::exhaustive::shortlex_vecs_min_length; use std::fmt::Debug; fn shortlex_vecs_min_length_helper(min_length: u64, xs: I, out: &[&[I::Item]]) where I::Item: Clone + Debug + Eq, { exhaustive_vecs_helper_helper(shortlex_vecs_min_length(min_length, xs), out); } #[test] fn test_shortlex_vecs_min_length() { shortlex_vecs_min_length_helper(0, nevers(), &[&[]]); shortlex_vecs_min_length_helper(4, nevers(), &[]); shortlex_vecs_min_length_helper( 0, exhaustive_units(), &[ &[], &[()], &[(), ()], &[(), (), ()], &[(), (), (), ()], &[(), (), (), (), ()], &[(), (), (), (), (), ()], &[(), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), (), (), (), (), ()], &[(); 16], &[(); 17], &[(); 18], &[(); 19], ], ); shortlex_vecs_min_length_helper( 5, exhaustive_units(), &[ &[(), (), (), (), ()], &[(), (), (), (), (), ()], &[(), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), (), (), (), (), ()], &[(); 16], &[(); 17], &[(); 18], &[(); 19], &[(); 20], &[(); 21], &[(); 22], &[(); 23], &[(); 24], ], ); shortlex_vecs_min_length_helper( 0, exhaustive_bools(), &[ &[], &[false], &[true], &[false, false], &[false, true], &[true, false], &[true, true], &[false, false, false], &[false, false, true], &[false, true, false], &[false, true, true], &[true, false, false], &[true, false, true], &[true, true, false], &[true, true, true], &[false, false, false, false], &[false, false, false, true], &[false, false, true, false], &[false, false, true, true], &[false, true, false, false], ], ); shortlex_vecs_min_length_helper( 3, exhaustive_bools(), &[ &[false, false, false], &[false, false, true], &[false, true, false], &[false, true, true], &[true, false, false], &[true, false, true], &[true, true, false], &[true, true, true], &[false, false, false, false], &[false, false, false, true], &[false, false, true, false], &[false, false, true, true], &[false, true, false, false], &[false, true, false, true], &[false, true, true, false], &[false, true, true, true], &[true, false, false, false], &[true, false, false, true], &[true, false, true, false], &[true, false, true, true], ], ); shortlex_vecs_min_length_helper( 0, 'a'..='c', &[ &[], &['a'], &['b'], &['c'], &['a', 'a'], &['a', 'b'], &['a', 'c'], &['b', 'a'], &['b', 'b'], &['b', 'c'], &['c', 'a'], &['c', 'b'], &['c', 'c'], &['a', 'a', 'a'], &['a', 'a', 'b'], &['a', 'a', 'c'], &['a', 'b', 'a'], &['a', 'b', 'b'], &['a', 'b', 'c'], &['a', 'c', 'a'], ], ); shortlex_vecs_min_length_helper( 3, 'a'..='c', &[ &['a', 'a', 'a'], &['a', 'a', 'b'], &['a', 'a', 'c'], &['a', 'b', 'a'], &['a', 'b', 'b'], &['a', 'b', 'c'], &['a', 'c', 'a'], &['a', 'c', 'b'], &['a', 'c', 'c'], &['b', 'a', 'a'], &['b', 'a', 'b'], &['b', 'a', 'c'], &['b', 'b', 'a'], &['b', 'b', 'b'], &['b', 'b', 'c'], &['b', 'c', 'a'], &['b', 'c', 'b'], &['b', 'c', 'c'], &['c', 'a', 'a'], &['c', 'a', 'b'], ], ); shortlex_vecs_min_length_helper( 0, exhaustive_ascii_chars(), &[ &[], &['a'], &['b'], &['c'], &['d'], &['e'], &['f'], &['g'], &['h'], &['i'], &['j'], &['k'], &['l'], &['m'], &['n'], &['o'], &['p'], &['q'], &['r'], &['s'], ], ); shortlex_vecs_min_length_helper( 3, exhaustive_ascii_chars(), &[ &['a', 'a', 'a'], &['a', 'a', 'b'], &['a', 'a', 'c'], &['a', 'a', 'd'], &['a', 'a', 'e'], &['a', 'a', 'f'], &['a', 'a', 'g'], &['a', 'a', 'h'], &['a', 'a', 'i'], &['a', 'a', 'j'], &['a', 'a', 'k'], &['a', 'a', 'l'], &['a', 'a', 'm'], &['a', 'a', 'n'], &['a', 'a', 'o'], &['a', 'a', 'p'], &['a', 'a', 'q'], &['a', 'a', 'r'], &['a', 'a', 's'], &['a', 'a', 't'], ], ); } malachite-base-0.4.16/tests/vecs/exhaustive_vec_permutations.rs000064400000000000000000000057301046102023000230640ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::vecs::exhaustive_vec_permutations; fn exhaustive_vec_permutations_helper(cs: &str, out: &[&str]) { let cs = cs.chars().collect_vec(); let css: Vec = exhaustive_vec_permutations(cs) .map(|ds| ds.into_iter().collect()) .collect(); assert_eq!(css.iter().map(String::as_str).collect_vec().as_slice(), out); } #[test] fn test_exhaustive_vec_permutations() { exhaustive_vec_permutations_helper("", &[""]); exhaustive_vec_permutations_helper("1", &["1"]); exhaustive_vec_permutations_helper("12", &["12", "21"]); exhaustive_vec_permutations_helper("123", &["123", "132", "213", "231", "312", "321"]); exhaustive_vec_permutations_helper( "1234", &[ "1234", "1243", "1324", "1342", "1423", "1432", "2134", "2143", "2314", "2341", "2413", "2431", "3124", "3142", "3214", "3241", "3412", "3421", "4123", "4132", "4213", "4231", "4312", "4321", ], ); exhaustive_vec_permutations_helper( "12345", &[ "12345", "12354", "12435", "12453", "12534", "12543", "13245", "13254", "13425", "13452", "13524", "13542", "14235", "14253", "14325", "14352", "14523", "14532", "15234", "15243", "15324", "15342", "15423", "15432", "21345", "21354", "21435", "21453", "21534", "21543", "23145", "23154", "23415", "23451", "23514", "23541", "24135", "24153", "24315", "24351", "24513", "24531", "25134", "25143", "25314", "25341", "25413", "25431", "31245", "31254", "31425", "31452", "31524", "31542", "32145", "32154", "32415", "32451", "32514", "32541", "34125", "34152", "34215", "34251", "34512", "34521", "35124", "35142", "35214", "35241", "35412", "35421", "41235", "41253", "41325", "41352", "41523", "41532", "42135", "42153", "42315", "42351", "42513", "42531", "43125", "43152", "43215", "43251", "43512", "43521", "45123", "45132", "45213", "45231", "45312", "45321", "51234", "51243", "51324", "51342", "51423", "51432", "52134", "52143", "52314", "52341", "52413", "52431", "53124", "53142", "53214", "53241", "53412", "53421", "54123", "54132", "54213", "54231", "54312", "54321", ], ); exhaustive_vec_permutations_helper( "abcd", &[ "abcd", "abdc", "acbd", "acdb", "adbc", "adcb", "bacd", "badc", "bcad", "bcda", "bdac", "bdca", "cabd", "cadb", "cbad", "cbda", "cdab", "cdba", "dabc", "dacb", "dbac", "dbca", "dcab", "dcba", ], ); } malachite-base-0.4.16/tests/vecs/random/random_ordered_unique_vecs.rs000064400000000000000000000150211046102023000240740ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use core::hash::Hash; use malachite_base::chars::exhaustive::exhaustive_chars; use malachite_base::chars::random::graphic_weighted_random_char_inclusive_range; use malachite_base::num::random::geometric::geometric_random_unsigneds; use malachite_base::num::random::random_primitive_ints; use malachite_base::random::{Seed, EXAMPLE_SEED}; use malachite_base::test_util::vecs::random::random_vecs_helper_helper; use malachite_base::vecs::random::random_ordered_unique_vecs; use std::fmt::Debug; fn random_ordered_unique_vecs_helper< T: Clone + Debug + Eq + Hash + Ord, I: Clone + Iterator, >( xs_gen: &dyn Fn(Seed) -> I, mean_length_numerator: u64, mean_length_denominator: u64, expected_values: &[&[T]], expected_common_values: &[(&[T], usize)], expected_median: (&[T], Option<&[T]>), ) { random_vecs_helper_helper( random_ordered_unique_vecs( EXAMPLE_SEED, xs_gen, mean_length_numerator, mean_length_denominator, ), expected_values, expected_common_values, expected_median, ); } #[test] fn test_random_ordered_unique_vecs() { random_ordered_unique_vecs_helper( &random_primitive_ints::, 4, 1, &[ &[][..], &[11, 32, 38, 85, 134, 136, 162, 166, 177, 200, 203, 217, 223, 235], &[30, 90, 218, 234], &[9, 106, 204, 216], &[151], &[], &[78, 91, 97, 213, 253], &[39, 191], &[170, 175, 232, 233], &[], &[2, 22, 35, 114, 198, 217], &[], &[], &[17, 25, 32, 65, 79, 114, 121, 144, 148, 173, 222], &[52, 69, 73, 91, 115, 137, 153, 178], &[], &[34, 95, 112], &[], &[106, 130, 167, 168, 197], &[86, 101, 122, 150, 172, 177, 207, 218, 221], ], &[ (&[], 199913), (&[7], 705), (&[25], 689), (&[184], 681), (&[213], 681), (&[255], 676), (&[215], 675), (&[54], 673), (&[122], 672), (&[207], 672), ], (&[27, 31, 211, 238], Some(&[27, 31, 247, 251])), ); random_ordered_unique_vecs_helper( &|seed| geometric_random_unsigneds::(seed, 32, 1), 4, 1, &[ &[], &[1, 9, 12, 14, 16, 17, 19, 21, 41, 42, 68, 79, 124, 141], &[0, 1, 10, 99], &[2, 12, 36, 77], &[1], &[], &[1, 5, 9, 19, 103], &[6, 7], &[15, 18, 51, 159], &[], &[2, 26, 40, 52, 64, 75], &[], &[], &[3, 4, 5, 7, 30, 31, 34, 43, 49, 51, 67], &[1, 14, 16, 24, 29, 41, 47, 52], &[], &[11, 13, 62], &[], &[3, 14, 42, 47, 109], &[5, 13, 16, 25, 37, 41, 42, 86, 96], ], &[ (&[], 199913), (&[0], 4861), (&[1], 4593), (&[2], 4498), (&[3], 4405), (&[4], 4330), (&[5], 4078), (&[6], 4050), (&[7], 3858), (&[8], 3848), ], ( &[3, 9, 14, 22, 36, 56, 107], Some(&[3, 9, 14, 22, 42, 54, 73, 150]), ), ); random_ordered_unique_vecs_helper( &random_primitive_ints::, 1, 4, &[ &[], &[], &[85], &[11], &[136, 200], &[], &[], &[], &[], &[], &[], &[], &[134, 235], &[203], &[], &[38, 223], &[], &[], &[], &[], ], &[ (&[], 800023), (&[162], 692), (&[235], 690), (&[90], 688), (&[65], 687), (&[249], 686), (&[175], 684), (&[108], 683), (&[211], 682), (&[237], 680), ], (&[], None), ); random_ordered_unique_vecs_helper( &|seed| { graphic_weighted_random_char_inclusive_range( seed, 'a', exhaustive_chars().nth(200).unwrap(), 1, 1, ) }, 4, 1, &[ &[], &['g', 'q', '³', '»', 'À', 'Á', 'Ã', 'È', 'á', 'â', 'ì', 'ñ', 'Ā', 'ą'], &['ª', '´', 'Ã', 'ä'], &['½', 'Á', 'Ï', 'ý'], &['j'], &[], &['u', '½', 'Â', 'Ñ', 'ï'], &['x', 'õ'], &['¡', 'Â', 'ù', 'Ċ'], &[], &['b', 'r', 's', '¬', 'Â', 'Ñ'], &[], &[], &['j', 'n', 't', '¬', 'º', '¿', 'Á', 'Ø', 'Þ', 'ô', 'ü'], &['b', 'k', '±', 'Î', 'Ü', 'æ', 'è', 'ā'], &[], &['«', '¹', 'Î'], &[], &['~', '¯', '´', 'Ý', 'â'], &['g', '¼', 'Ç', 'Î', 'Ü', 'Þ', 'æ', 'é', 'ö'], ], &[ (&[], 199913), (&['Ó'], 1270), (&['Â'], 1249), (&['§'], 1244), (&['¿'], 1243), (&['õ'], 1241), (&['ĉ'], 1234), (&['¤'], 1232), (&['¼'], 1232), (&['Ì'], 1229), ], ( &['o', 'v', '¢', '±', 'Ä', 'Ć'], Some(&['o', 'v', '¢', '³', 'ã']), ), ); } #[test] #[should_panic] fn random_ordered_unique_vecs_fail_1() { random_ordered_unique_vecs(EXAMPLE_SEED, &random_primitive_ints::, 0, 1); } #[test] #[should_panic] fn random_ordered_unique_vecs_fail_2() { random_ordered_unique_vecs(EXAMPLE_SEED, &random_primitive_ints::, 1, 0); } #[test] #[should_panic] fn random_ordered_unique_vecs_fail_3() { random_ordered_unique_vecs( EXAMPLE_SEED, &random_primitive_ints::, u64::MAX, u64::MAX - 1, ); } malachite-base-0.4.16/tests/vecs/random/random_ordered_unique_vecs_fixed_length.rs000064400000000000000000000115611046102023000266210ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use core::hash::Hash; use itertools::{repeat_n, Itertools}; use malachite_base::bools::random::random_bools; use malachite_base::num::random::random_primitive_ints; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::vecs::random::random_vecs_helper_helper; use malachite_base::vecs::random::random_ordered_unique_vecs_fixed_length; use std::fmt::Debug; fn random_ordered_unique_vecs_fixed_length_helper( len: u64, xs: I, expected_values: &[&[I::Item]], expected_common_values: &[(&[I::Item], usize)], expected_median: (&[I::Item], Option<&[I::Item]>), ) where I::Item: Clone + Debug + Eq + Hash + Ord, { random_vecs_helper_helper( random_ordered_unique_vecs_fixed_length(len, xs), expected_values, expected_common_values, expected_median, ); } #[test] fn test_random_ordered_unique_vecs_fixed_length() { random_ordered_unique_vecs_fixed_length_helper( 0, random_primitive_ints::(EXAMPLE_SEED), repeat_n(&[][..], 20).collect_vec().as_slice(), &[(&[], 1000000)], (&[], None), ); random_ordered_unique_vecs_fixed_length_helper( 1, random_bools(EXAMPLE_SEED), &[ &[true], &[false], &[false], &[false], &[true], &[true], &[true], &[false], &[true], &[true], &[true], &[true], &[false], &[true], &[true], &[true], &[true], &[false], &[true], &[false], ], &[(&[true], 500473), (&[false], 499527)], (&[true], None), ); random_ordered_unique_vecs_fixed_length_helper( 3, random_primitive_ints::(EXAMPLE_SEED), &[ &[69, 113, 239], &[108, 210, 228], &[87, 161, 168], &[32, 83, 110], &[34, 89, 188], &[93, 200, 238], &[115, 149, 189], &[149, 201, 217], &[31, 117, 146], &[72, 151, 169], &[7, 33, 174], &[38, 81, 144], &[72, 113, 127], &[107, 128, 233], &[12, 46, 119], &[18, 164, 243], &[59, 114, 174], &[39, 174, 247], &[104, 160, 184], &[37, 100, 252], ], &[ (&[57, 142, 207], 7), (&[32, 68, 169], 6), (&[36, 70, 195], 6), (&[125, 168, 194], 6), (&[0, 97, 205], 5), (&[2, 33, 227], 5), (&[5, 46, 239], 5), (&[9, 68, 189], 5), (&[9, 78, 240], 5), (&[1, 110, 203], 5), ], (&[52, 133, 241], Some(&[52, 133, 242])), ); random_ordered_unique_vecs_fixed_length_helper( 2, random_ordered_unique_vecs_fixed_length(2, random_primitive_ints::(EXAMPLE_SEED)), &[ &[vec![69, 108], vec![113, 239]], &[vec![161, 168], vec![210, 228]], &[vec![32, 87], vec![83, 110]], &[vec![34, 188], vec![89, 238]], &[vec![93, 200], vec![115, 149]], &[vec![149, 189], vec![201, 217]], &[vec![31, 72], vec![117, 146]], &[vec![33, 174], vec![151, 169]], &[vec![7, 38], vec![81, 144]], &[vec![72, 127], vec![113, 128]], &[vec![46, 119], vec![107, 233]], &[vec![12, 18], vec![164, 243]], &[vec![59, 247], vec![114, 174]], &[vec![39, 174], vec![160, 184]], &[vec![37, 104], vec![100, 252]], &[vec![69, 107], vec![122, 228]], &[vec![142, 179], vec![242, 248]], &[vec![61, 189], vec![233, 239]], &[vec![7, 192], vec![85, 235]], &[vec![90, 200], vec![178, 185]], ], &[ (&[vec![0, 78], vec![34, 52]], 2), (&[vec![1, 58], vec![6, 112]], 2), (&[vec![1, 63], vec![8, 154]], 2), (&[vec![1, 97], vec![7, 250]], 2), (&[vec![2, 33], vec![40, 81]], 2), (&[vec![3, 160], vec![7, 29]], 2), (&[vec![3, 32], vec![12, 60]], 2), (&[vec![6, 130], vec![7, 20]], 2), (&[vec![6, 68], vec![7, 126]], 2), (&[vec![6, 77], vec![36, 54]], 2), ], ( &[vec![40, 193], vec![94, 142]], Some(&[vec![40, 193], vec![97, 243]]), ), ); } malachite-base-0.4.16/tests/vecs/random/random_ordered_unique_vecs_from_length_iterator.rs000064400000000000000000000070501046102023000303740ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use core::hash::Hash; use malachite_base::bools::random::random_bools; use malachite_base::num::random::geometric::geometric_random_unsigneds; use malachite_base::num::random::random_primitive_ints; use malachite_base::random::{Seed, EXAMPLE_SEED}; use malachite_base::test_util::vecs::random::random_vecs_helper_helper; use malachite_base::vecs::random::random_ordered_unique_vecs_from_length_iterator; use malachite_base::vecs::random_values_from_vec; use std::fmt::Debug; fn random_ordered_unique_vecs_from_length_iterator_helper< T: Clone + Debug + Eq + Hash + Ord, I: Clone + Iterator, J: Clone + Iterator, >( lengths_gen: &dyn Fn(Seed) -> I, xs_gen: &dyn Fn(Seed) -> J, expected_values: &[&[T]], expected_common_values: &[(&[T], usize)], expected_median: (&[T], Option<&[T]>), ) { random_vecs_helper_helper( random_ordered_unique_vecs_from_length_iterator(EXAMPLE_SEED, lengths_gen, xs_gen), expected_values, expected_common_values, expected_median, ); } #[test] fn test_random_ordered_unique_vecs_from_length_iterator() { random_ordered_unique_vecs_from_length_iterator_helper( &|seed| random_values_from_vec(seed, vec![0, 2]), &random_bools, &[ &[false, true], &[], &[false, true], &[false, true], &[], &[false, true], &[false, true], &[], &[false, true], &[false, true], &[], &[false, true], &[], &[false, true], &[false, true], &[], &[], &[], &[false, true], &[], ], &[(&[false, true], 500363), (&[], 499637)], (&[false, true], None), ); random_ordered_unique_vecs_from_length_iterator_helper( &|seed| geometric_random_unsigneds::(seed, 2, 1).map(|x| x << 1), &random_primitive_ints::, &[ &[11, 38, 85, 134, 136, 162, 177, 200, 203, 217, 223, 235], &[32, 166], &[9, 30, 39, 78, 90, 91, 97, 106, 151, 191, 204, 213, 216, 218, 234, 253], &[170, 175], &[ 2, 17, 22, 25, 32, 34, 35, 52, 65, 69, 73, 79, 91, 112, 114, 115, 121, 137, 144, 148, 153, 173, 178, 198, 217, 222, 232, 233, ], &[], &[95, 106, 122, 130, 167, 168, 172, 177, 197, 207], &[9, 74, 86, 101, 115, 150, 218, 221], &[109, 123], &[], &[40, 48, 52, 97, 104, 133, 159, 196, 201, 235, 247, 250], &[7, 68, 190, 216], &[], &[], &[157, 216], &[11, 24, 43, 103, 112, 217], &[], &[84, 211], &[], &[55, 135], ], &[ (&[], 333981), (&[33, 163], 22), (&[76, 233], 19), (&[5, 42], 18), (&[76, 79], 18), (&[32, 134], 18), (&[69, 234], 18), (&[74, 164], 18), (&[86, 192], 18), (&[99, 145], 18), ], (&[12, 190], None), ); } malachite-base-0.4.16/tests/vecs/random/random_ordered_unique_vecs_length_inclusive_range.rs000064400000000000000000000113161046102023000306750ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use core::hash::Hash; use malachite_base::chars::random::random_char_inclusive_range; use malachite_base::num::random::geometric::geometric_random_unsigneds; use malachite_base::num::random::random_primitive_ints; use malachite_base::random::{Seed, EXAMPLE_SEED}; use malachite_base::test_util::vecs::random::random_vecs_helper_helper; use malachite_base::vecs::random::random_ordered_unique_vecs_length_inclusive_range; use std::fmt::Debug; fn random_ordered_unique_vecs_length_inclusive_range_helper< T: Clone + Debug + Eq + Hash + Ord, I: Clone + Iterator, >( a: u64, b: u64, xs_gen: &dyn Fn(Seed) -> I, expected_values: &[&[T]], expected_common_values: &[(&[T], usize)], expected_median: (&[T], Option<&[T]>), ) { random_vecs_helper_helper( random_ordered_unique_vecs_length_inclusive_range(EXAMPLE_SEED, a, b, xs_gen), expected_values, expected_common_values, expected_median, ); } #[test] fn test_random_ordered_unique_vecs_length_inclusive_range() { random_ordered_unique_vecs_length_inclusive_range_helper( 2, 3, &random_primitive_ints::, &[ &[11, 85, 136], &[200, 235], &[134, 203, 223], &[38, 217, 235], &[162, 177], &[32, 166, 234], &[30, 90, 218], &[9, 106], &[151, 204, 216], &[97, 213, 253], &[78, 91], &[39, 175, 191], &[170, 232], &[2, 35, 233], &[22, 198, 217], &[17, 114], &[32, 173], &[65, 114], &[121, 173, 222], &[25, 144], ], &[ (&[106, 108], 34), (&[224, 237], 34), (&[51, 132], 32), (&[82, 117], 32), (&[72, 108], 31), (&[142, 194], 31), (&[0, 34], 30), (&[12, 208], 30), (&[15, 141], 30), (&[30, 248], 30), ], (&[62, 131, 203], Some(&[62, 131, 205])), ); random_ordered_unique_vecs_length_inclusive_range_helper( 2, 3, &|seed| geometric_random_unsigneds::(seed, 2, 1), &[ &[0, 1, 5], &[1, 4], &[2, 4, 6], &[0, 1, 2], &[9, 13], &[0, 2, 7], &[4, 6, 7], &[0, 6], &[0, 1, 3], &[1, 2, 5], &[0, 1], &[0, 1, 4], &[0, 2], &[0, 2, 12], &[1, 2, 3], &[3, 9], &[0, 1], &[1, 2], &[0, 1, 11], &[1, 6], ], &[ (&[0, 1], 103032), (&[0, 1, 2], 84142), (&[0, 2], 66185), (&[0, 1, 3], 52638), (&[0, 3], 42990), (&[1, 2], 40380), (&[0, 1, 4], 33815), (&[0, 2, 3], 31257), (&[0, 4], 28088), (&[1, 3], 26214), ], (&[0, 3], None), ); random_ordered_unique_vecs_length_inclusive_range_helper( 2, 3, &|seed| random_char_inclusive_range(seed, 'a', 'z'), &[ &['c', 'q', 'v'], &['e', 'i'], &['g', 'p', 's'], &['m', 'n', 't'], &['o', 'z'], &['f', 'k', 'm'], &['q', 'u', 'y'], &['k', 'x'], &['h', 'n', 'u'], &['a', 'j', 'n'], &['w', 'z'], &['b', 'l', 'w'], &['l', 'u'], &['e', 'l', 'n'], &['k', 'u', 'v'], &['c', 'h'], &['i', 'y'], &['m', 'r'], &['m', 's', 'y'], &['e', 'l'], ], &[ (&['l', 'x'], 1640), (&['o', 't'], 1636), (&['b', 'p'], 1630), (&['m', 'v'], 1623), (&['h', 'u'], 1621), (&['a', 'x'], 1614), (&['d', 'f'], 1613), (&['e', 'r'], 1613), (&['o', 'p'], 1612), (&['c', 'i'], 1611), ], (&['g', 'j'], None), ); } #[test] #[should_panic] fn random_ordered_unique_vecs_length_inclusive_range_fail() { random_ordered_unique_vecs_length_inclusive_range( EXAMPLE_SEED, 2, 1, &random_primitive_ints::, ); } malachite-base-0.4.16/tests/vecs/random/random_ordered_unique_vecs_length_range.rs000064400000000000000000000111151046102023000266110ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use core::hash::Hash; use malachite_base::chars::random::random_char_inclusive_range; use malachite_base::num::random::geometric::geometric_random_unsigneds; use malachite_base::num::random::random_primitive_ints; use malachite_base::random::{Seed, EXAMPLE_SEED}; use malachite_base::test_util::vecs::random::random_vecs_helper_helper; use malachite_base::vecs::random::random_ordered_unique_vecs_length_range; use std::fmt::Debug; fn random_ordered_unique_vecs_length_range_helper< T: Clone + Debug + Eq + Hash + Ord, I: Clone + Iterator, >( a: u64, b: u64, xs_gen: &dyn Fn(Seed) -> I, expected_values: &[&[T]], expected_common_values: &[(&[T], usize)], expected_median: (&[T], Option<&[T]>), ) { random_vecs_helper_helper( random_ordered_unique_vecs_length_range(EXAMPLE_SEED, a, b, xs_gen), expected_values, expected_common_values, expected_median, ); } #[test] fn test_random_ordered_unique_vecs_length_range() { random_ordered_unique_vecs_length_range_helper( 2, 4, &random_primitive_ints::, &[ &[11, 85, 136], &[200, 235], &[134, 203, 223], &[38, 217, 235], &[162, 177], &[32, 166, 234], &[30, 90, 218], &[9, 106], &[151, 204, 216], &[97, 213, 253], &[78, 91], &[39, 175, 191], &[170, 232], &[2, 35, 233], &[22, 198, 217], &[17, 114], &[32, 173], &[65, 114], &[121, 173, 222], &[25, 144], ], &[ (&[106, 108], 34), (&[224, 237], 34), (&[51, 132], 32), (&[82, 117], 32), (&[72, 108], 31), (&[142, 194], 31), (&[0, 34], 30), (&[12, 208], 30), (&[15, 141], 30), (&[30, 248], 30), ], (&[62, 131, 203], Some(&[62, 131, 205])), ); random_ordered_unique_vecs_length_range_helper( 2, 4, &|seed| geometric_random_unsigneds::(seed, 2, 1), &[ &[0, 1, 5], &[1, 4], &[2, 4, 6], &[0, 1, 2], &[9, 13], &[0, 2, 7], &[4, 6, 7], &[0, 6], &[0, 1, 3], &[1, 2, 5], &[0, 1], &[0, 1, 4], &[0, 2], &[0, 2, 12], &[1, 2, 3], &[3, 9], &[0, 1], &[1, 2], &[0, 1, 11], &[1, 6], ], &[ (&[0, 1], 103032), (&[0, 1, 2], 84142), (&[0, 2], 66185), (&[0, 1, 3], 52638), (&[0, 3], 42990), (&[1, 2], 40380), (&[0, 1, 4], 33815), (&[0, 2, 3], 31257), (&[0, 4], 28088), (&[1, 3], 26214), ], (&[0, 3], None), ); random_ordered_unique_vecs_length_range_helper( 2, 4, &|seed| random_char_inclusive_range(seed, 'a', 'z'), &[ &['c', 'q', 'v'], &['e', 'i'], &['g', 'p', 's'], &['m', 'n', 't'], &['o', 'z'], &['f', 'k', 'm'], &['q', 'u', 'y'], &['k', 'x'], &['h', 'n', 'u'], &['a', 'j', 'n'], &['w', 'z'], &['b', 'l', 'w'], &['l', 'u'], &['e', 'l', 'n'], &['k', 'u', 'v'], &['c', 'h'], &['i', 'y'], &['m', 'r'], &['m', 's', 'y'], &['e', 'l'], ], &[ (&['l', 'x'], 1640), (&['o', 't'], 1636), (&['b', 'p'], 1630), (&['m', 'v'], 1623), (&['h', 'u'], 1621), (&['a', 'x'], 1614), (&['d', 'f'], 1613), (&['e', 'r'], 1613), (&['o', 'p'], 1612), (&['c', 'i'], 1611), ], (&['g', 'j'], None), ); } #[test] #[should_panic] fn random_ordered_unique_vecs_length_range_fail() { random_ordered_unique_vecs_length_range(EXAMPLE_SEED, 2, 2, &random_primitive_ints::); } malachite-base-0.4.16/tests/vecs/random/random_ordered_unique_vecs_min_length.rs000064400000000000000000000312621046102023000263050ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use core::hash::Hash; use malachite_base::chars::exhaustive::exhaustive_chars; use malachite_base::chars::random::graphic_weighted_random_char_inclusive_range; use malachite_base::num::random::geometric::geometric_random_unsigneds; use malachite_base::num::random::random_primitive_ints; use malachite_base::random::{Seed, EXAMPLE_SEED}; use malachite_base::test_util::vecs::random::random_vecs_helper_helper; use malachite_base::vecs::random::random_ordered_unique_vecs_min_length; use std::fmt::Debug; fn random_ordered_unique_vecs_min_length_helper< T: Clone + Debug + Eq + Hash + Ord, I: Clone + Iterator, >( min_length: u64, xs_gen: &dyn Fn(Seed) -> I, mean_length_numerator: u64, mean_length_denominator: u64, expected_values: &[&[T]], expected_common_values: &[(&[T], usize)], expected_median: (&[T], Option<&[T]>), ) { random_vecs_helper_helper( random_ordered_unique_vecs_min_length( EXAMPLE_SEED, min_length, xs_gen, mean_length_numerator, mean_length_denominator, ), expected_values, expected_common_values, expected_median, ); } #[test] fn test_random_ordered_unique_vecs_min_length() { random_ordered_unique_vecs_min_length_helper( 0, &random_primitive_ints::, 4, 1, &[ &[], &[11, 32, 38, 85, 134, 136, 162, 166, 177, 200, 203, 217, 223, 235], &[30, 90, 218, 234], &[9, 106, 204, 216], &[151], &[], &[78, 91, 97, 213, 253], &[39, 191], &[170, 175, 232, 233], &[], &[2, 22, 35, 114, 198, 217], &[], &[], &[17, 25, 32, 65, 79, 114, 121, 144, 148, 173, 222], &[52, 69, 73, 91, 115, 137, 153, 178], &[], &[34, 95, 112], &[], &[106, 130, 167, 168, 197], &[86, 101, 122, 150, 172, 177, 207, 218, 221], ], &[ (&[], 199913), (&[7], 705), (&[25], 689), (&[184], 681), (&[213], 681), (&[255], 676), (&[215], 675), (&[54], 673), (&[122], 672), (&[207], 672), ], (&[27, 31, 211, 238], Some(&[27, 31, 247, 251])), ); random_ordered_unique_vecs_min_length_helper( 3, &random_primitive_ints::, 7, 1, &[ &[11, 85, 136], &[9, 30, 32, 38, 90, 106, 134, 162, 166, 177, 200, 203, 217, 218, 223, 234, 235], &[78, 97, 151, 204, 213, 216, 253], &[39, 91, 170, 175, 191, 232, 233], &[2, 22, 35, 217], &[17, 114, 198], &[25, 32, 65, 114, 121, 144, 173, 222], &[52, 73, 79, 115, 148], &[34, 69, 91, 112, 137, 153, 178], &[95, 106, 167], &[86, 122, 130, 150, 168, 172, 177, 197, 207], &[101, 218, 221], &[9, 74, 115], &[40, 48, 52, 97, 104, 109, 123, 133, 159, 196, 201, 235, 247, 250], &[7, 11, 24, 43, 68, 103, 112, 157, 190, 216, 217], &[84, 135, 211], &[29, 55, 65, 89, 191, 206], &[9, 51, 79], &[3, 20, 22, 34, 62, 114, 118, 148], &[23, 32, 47, 50, 120, 166, 176, 177, 194, 204, 238, 248], ], &[ (&[5, 128, 142], 4), (&[137, 145, 160], 4), (&[2, 4, 52], 3), (&[1, 5, 192], 3), (&[12, 41, 58], 3), (&[2, 95, 171], 3), (&[20, 86, 94], 3), (&[21, 43, 50], 3), (&[3, 81, 122], 3), (&[31, 54, 79], 3), ], (&[26, 138, 167], Some(&[26, 138, 167, 173, 211])), ); random_ordered_unique_vecs_min_length_helper( 0, &|seed| geometric_random_unsigneds::(seed, 32, 1), 4, 1, &[ &[], &[1, 9, 12, 14, 16, 17, 19, 21, 41, 42, 68, 79, 124, 141], &[0, 1, 10, 99], &[2, 12, 36, 77], &[1], &[], &[1, 5, 9, 19, 103], &[6, 7], &[15, 18, 51, 159], &[], &[2, 26, 40, 52, 64, 75], &[], &[], &[3, 4, 5, 7, 30, 31, 34, 43, 49, 51, 67], &[1, 14, 16, 24, 29, 41, 47, 52], &[], &[11, 13, 62], &[], &[3, 14, 42, 47, 109], &[5, 13, 16, 25, 37, 41, 42, 86, 96], ], &[ (&[], 199913), (&[0], 4861), (&[1], 4593), (&[2], 4498), (&[3], 4405), (&[4], 4330), (&[5], 4078), (&[6], 4050), (&[7], 3858), (&[8], 3848), ], ( &[3, 9, 14, 22, 36, 56, 107], Some(&[3, 9, 14, 22, 42, 54, 73, 150]), ), ); random_ordered_unique_vecs_min_length_helper( 3, &|seed| geometric_random_unsigneds::(seed, 32, 1), 7, 1, &[ &[1, 14, 42], &[0, 1, 9, 10, 12, 16, 17, 19, 21, 36, 41, 68, 77, 79, 99, 124, 141], &[1, 2, 5, 9, 12, 19, 103], &[6, 7, 15, 18, 51, 52, 159], &[2, 40, 64, 75], &[26, 34, 67], &[4, 5, 7, 30, 31, 43, 49, 51], &[3, 14, 16, 24, 47], &[1, 11, 13, 29, 41, 52, 62], &[3, 47, 109], &[13, 14, 16, 25, 37, 41, 42, 86, 96], &[5, 20, 42], &[2, 74, 82], &[3, 6, 7, 11, 17, 20, 36, 45, 56, 66, 76, 80, 89, 127], &[1, 6, 10, 13, 19, 23, 25, 32, 41, 43, 97], &[7, 41, 134], &[9, 10, 25, 26, 47, 105], &[68, 94, 109], &[1, 3, 9, 13, 28, 43, 44, 84], &[0, 4, 5, 6, 7, 13, 31, 32, 37, 42, 50, 75], ], &[ (&[0, 2, 5], 42), (&[0, 1, 8], 39), (&[0, 3, 4], 38), (&[1, 3, 9], 38), (&[0, 1, 7], 35), (&[0, 2, 8], 34), (&[1, 2, 12], 34), (&[0, 1, 2], 33), (&[1, 2, 3], 33), (&[1, 3, 4], 33), ], ( &[3, 8, 14, 19, 25, 36, 52, 64, 71], Some(&[3, 8, 14, 19, 25, 38, 58, 61]), ), ); random_ordered_unique_vecs_min_length_helper( 0, &random_primitive_ints::, 1, 4, &[ &[], &[], &[85], &[11], &[136, 200], &[], &[], &[], &[], &[], &[], &[], &[134, 235], &[203], &[], &[38, 223], &[], &[], &[], &[], ], &[ (&[], 800023), (&[162], 692), (&[235], 690), (&[90], 688), (&[65], 687), (&[249], 686), (&[175], 684), (&[108], 683), (&[211], 682), (&[237], 680), ], (&[], None), ); random_ordered_unique_vecs_min_length_helper( 3, &random_primitive_ints::, 13, 4, &[ &[11, 85, 136], &[134, 200, 235], &[38, 203, 223, 235], &[32, 162, 177, 217], &[30, 90, 166, 218, 234], &[9, 106, 216], &[151, 204, 213], &[78, 97, 253], &[39, 91, 191], &[170, 175, 232], &[2, 35, 233], &[22, 198, 217], &[17, 32, 65, 114, 173], &[25, 121, 173, 222], &[79, 144, 148], &[52, 69, 73, 115, 137], &[91, 153, 178], &[34, 95, 112], &[106, 167, 197], &[122, 130, 168], ], &[ (&[10, 87, 204], 6), (&[15, 40, 115], 6), (&[108, 193, 199], 6), (&[1, 22, 70], 5), (&[1, 8, 212], 5), (&[2, 40, 169], 5), (&[2, 58, 211], 5), (&[3, 29, 186], 5), (&[3, 97, 112], 5), (&[11, 66, 140], 5), ], (&[49, 78, 193], Some(&[49, 78, 193, 215])), ); random_ordered_unique_vecs_min_length_helper( 0, &|seed| { graphic_weighted_random_char_inclusive_range( seed, 'a', exhaustive_chars().nth(200).unwrap(), 1, 1, ) }, 4, 1, &[ &[], &['g', 'q', '³', '»', 'À', 'Á', 'Ã', 'È', 'á', 'â', 'ì', 'ñ', 'Ā', 'ą'], &['ª', '´', 'Ã', 'ä'], &['½', 'Á', 'Ï', 'ý'], &['j'], &[], &['u', '½', 'Â', 'Ñ', 'ï'], &['x', 'õ'], &['¡', 'Â', 'ù', 'Ċ'], &[], &['b', 'r', 's', '¬', 'Â', 'Ñ'], &[], &[], &['j', 'n', 't', '¬', 'º', '¿', 'Á', 'Ø', 'Þ', 'ô', 'ü'], &['b', 'k', '±', 'Î', 'Ü', 'æ', 'è', 'ā'], &[], &['«', '¹', 'Î'], &[], &['~', '¯', '´', 'Ý', 'â'], &['g', '¼', 'Ç', 'Î', 'Ü', 'Þ', 'æ', 'é', 'ö'], ], &[ (&[][..], 199913), (&['Ó'], 1270), (&['Â'], 1249), (&['§'], 1244), (&['¿'], 1243), (&['õ'], 1241), (&['ĉ'], 1234), (&['¤'], 1232), (&['¼'], 1232), (&['Ì'], 1229), ], ( &['o', 'v', '¢', '±', 'Ä', 'Ć'], Some(&['o', 'v', '¢', '³', 'ã']), ), ); random_ordered_unique_vecs_min_length_helper( 3, &|seed| { graphic_weighted_random_char_inclusive_range( seed, 'a', exhaustive_chars().nth(200).unwrap(), 1, 1, ) }, 7, 1, &[ &['g', 'q', 'á'], &['g', 'ª', '³', '´', '»', '½', 'À', 'Á', 'Ã', 'È', 'Ï', 'â', 'ä', 'ì', 'ñ', 'Ā', 'ą'], &['j', 'u', '½', 'Â', 'Ñ', 'ï', 'ý'], &['x', '¡', '¬', 'Â', 'õ', 'ù', 'Ċ'], &['b', 's', '¬', 'Ñ'], &['n', 'r', 'Â'], &['t', '¬', 'º', '¿', 'Ø', 'Þ', 'ô', 'ü'], &['j', 'k', '±', 'Á', 'è'], &['b', '«', '¹', 'Î', 'Ü', 'æ', 'ā'], &['~', '´', 'Î'], &['g', '¯', 'Î', 'Ý', 'Þ', 'â', 'æ', 'é', 'ö'], &['¼', 'Ç', 'Ü'], &['¡', '§', 'Ì'], &['d', 'm', 'z', '{', '¨', '®', '±', '¼', 'Ë', 'Ü', 'ê', 'ì', 'ý', 'þ'], &['x', 'ª', '½', 'À', 'Õ', 'ì', 'ï', 'û', 'ă', 'Ą', 'ċ'], &['¢', '«', 'Ć'], &['{', '¢', '½', 'È', 'ä', 'ÿ'], &['Ë', 'Õ', 'ê'], &['p', '¨', '°', 'º', 'Å', 'Ó', '×', 'ü'], &['d', 'k', 'o', 'v', '¥', '±', 'Ä', 'È', 'Ê', 'ß', 'æ', 'Ć'], ], &[ (&['m', 'u', 'w'], 6), (&['b', 'n', 'Ã'], 6), (&['g', '®', 'Ý'], 6), (&['x', 'Ä', 'î'], 6), (&['º', 'Ú', '÷'], 6), (&['a', 'w', 'ø'], 5), (&['c', 'e', 'Þ'], 5), (&['d', 't', 'Ã'], 5), (&['m', 'r', 'È'], 5), (&['w', '{', '³'], 5), ], ( &['o', 's', '×', 'Ý', 'Þ', 'ß', 'î', 'ù'], Some(&['o', 's', '×', 'à', 'ã', 'ò', 'ċ']), ), ); } #[test] #[should_panic] fn random_ordered_unique_vecs_min_length_fail_1() { random_ordered_unique_vecs_min_length(EXAMPLE_SEED, 3, &random_primitive_ints::, 3, 1); } #[test] #[should_panic] fn random_ordered_unique_vecs_min_length_fail_2() { random_ordered_unique_vecs_min_length(EXAMPLE_SEED, 1, &random_primitive_ints::, 1, 0); } #[test] #[should_panic] fn random_ordered_unique_vecs_min_length_fail_3() { random_ordered_unique_vecs_min_length( EXAMPLE_SEED, 0, &random_primitive_ints::, u64::MAX, u64::MAX - 1, ); } malachite-base-0.4.16/tests/vecs/random/random_unique_vecs.rs000064400000000000000000000145061046102023000223770ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use core::hash::Hash; use malachite_base::chars::exhaustive::exhaustive_chars; use malachite_base::chars::random::graphic_weighted_random_char_inclusive_range; use malachite_base::num::random::geometric::geometric_random_unsigneds; use malachite_base::num::random::random_primitive_ints; use malachite_base::random::{Seed, EXAMPLE_SEED}; use malachite_base::test_util::vecs::random::random_vecs_helper_helper; use malachite_base::vecs::random::random_unique_vecs; use std::fmt::Debug; fn random_unique_vecs_helper>( xs_gen: &dyn Fn(Seed) -> I, mean_length_numerator: u64, mean_length_denominator: u64, expected_values: &[&[T]], expected_common_values: &[(&[T], usize)], expected_median: (&[T], Option<&[T]>), ) { random_vecs_helper_helper( random_unique_vecs( EXAMPLE_SEED, xs_gen, mean_length_numerator, mean_length_denominator, ), expected_values, expected_common_values, expected_median, ); } #[test] fn test_random_unique_vecs() { random_unique_vecs_helper( &random_primitive_ints::, 4, 1, &[ &[], &[85, 11, 136, 200, 235, 134, 203, 223, 38, 217, 177, 162, 32, 166], &[234, 30, 218, 90], &[106, 9, 216, 204], &[151], &[], &[213, 97, 253, 78, 91], &[39, 191], &[175, 170, 232, 233], &[], &[2, 35, 22, 217, 198, 114], &[], &[], &[17, 32, 173, 114, 65, 121, 222, 25, 144, 148, 79], &[115, 52, 73, 69, 137, 91, 153, 178], &[], &[112, 34, 95], &[], &[106, 167, 197, 130, 168], &[122, 207, 172, 177, 86, 150, 221, 218, 101], ], &[ (&[], 199913), (&[7], 705), (&[25], 689), (&[184], 681), (&[213], 681), (&[255], 676), (&[215], 675), (&[54], 673), (&[122], 672), (&[207], 672), ], (&[96], None), ); random_unique_vecs_helper( &|seed| geometric_random_unsigneds::(seed, 32, 1), 4, 1, &[ &[], &[1, 14, 42, 12, 141, 19, 9, 68, 16, 79, 21, 17, 41, 124], &[10, 1, 99, 0], &[77, 36, 2, 12], &[1], &[], &[103, 9, 19, 1, 5], &[7, 6], &[51, 159, 15, 18], &[], &[52, 75, 40, 64, 2, 26], &[], &[], &[67, 34, 51, 30, 31, 49, 43, 7, 5, 4, 3], &[14, 47, 24, 16, 52, 29, 1, 41], &[], &[13, 11, 62], &[], &[47, 3, 109, 42, 14], &[37, 86, 25, 96, 41, 13, 16, 42, 5], ], &[ (&[], 199913), (&[0], 4861), (&[1], 4593), (&[2], 4498), (&[3], 4405), (&[4], 4330), (&[5], 4078), (&[6], 4050), (&[7], 3858), (&[8], 3848), ], (&[15, 3], None), ); random_unique_vecs_helper( &random_primitive_ints::, 1, 4, &[ &[], &[], &[85], &[11], &[136, 200], &[], &[], &[], &[], &[], &[], &[], &[235, 134], &[203], &[], &[223, 38], &[], &[], &[], &[], ], &[ (&[][..], 800023), (&[162], 692), (&[235], 690), (&[90], 688), (&[65], 687), (&[249], 686), (&[175], 684), (&[108], 683), (&[211], 682), (&[237], 680), ], (&[], None), ); random_unique_vecs_helper( &|seed| { graphic_weighted_random_char_inclusive_range( seed, 'a', exhaustive_chars().nth(200).unwrap(), 1, 1, ) }, 4, 1, &[ &[], &['q', 'á', 'g', 'Á', 'À', 'È', '»', 'ì', '³', 'ą', 'â', 'Ã', 'ñ', 'Ā'], &['Ã', 'ª', 'ä', '´'], &['½', 'Á', 'Ï', 'ý'], &['j'], &[], &['ï', 'Ñ', 'u', 'Â', '½'], &['õ', 'x'], &['Â', 'ù', '¡', 'Ċ'], &[], &['¬', 'b', 'Ñ', 's', 'Â', 'r'], &[], &[], &['n', '¿', 'Þ', 'ô', 'Ø', 'º', 'ü', 't', '¬', 'j', 'Á'], &['±', 'è', 'k', 'æ', 'b', 'Î', 'ā', 'Ü'], &[], &['¹', '«', 'Î'], &[], &['~', '´', 'Ý', 'â', '¯'], &['é', 'æ', 'Þ', 'ö', 'g', 'Î', 'Ç', 'Ü', '¼'], ], &[ (&[], 199913), (&['Ó'], 1270), (&['Â'], 1249), (&['§'], 1244), (&['¿'], 1243), (&['õ'], 1241), (&['ĉ'], 1234), (&['¤'], 1232), (&['¼'], 1232), (&['Ì'], 1229), ], ( &['¶', 'Ă', 'ą', '®', 'Á', 'í', '¬', '¾', '¸', 'Ã', '}', 'ù', 'ý', '½', 'a'], Some(&['¶', 'Ă', 'ć']), ), ); } #[test] #[should_panic] fn random_unique_vecs_fail_1() { random_unique_vecs(EXAMPLE_SEED, &random_primitive_ints::, 0, 1); } #[test] #[should_panic] fn random_unique_vecs_fail_2() { random_unique_vecs(EXAMPLE_SEED, &random_primitive_ints::, 1, 0); } #[test] #[should_panic] fn random_unique_vecs_fail_3() { random_unique_vecs( EXAMPLE_SEED, &random_primitive_ints::, u64::MAX, u64::MAX - 1, ); } malachite-base-0.4.16/tests/vecs/random/random_unique_vecs_fixed_length.rs000064400000000000000000000114731046102023000251170ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use core::hash::Hash; use itertools::{repeat_n, Itertools}; use malachite_base::bools::random::random_bools; use malachite_base::num::random::random_primitive_ints; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::vecs::random::random_vecs_helper_helper; use malachite_base::vecs::random::random_unique_vecs_fixed_length; use std::fmt::Debug; fn random_unique_vecs_fixed_length_helper( len: u64, xs: I, expected_values: &[&[I::Item]], expected_common_values: &[(&[I::Item], usize)], expected_median: (&[I::Item], Option<&[I::Item]>), ) where I::Item: Clone + Debug + Eq + Hash + Ord, { random_vecs_helper_helper( random_unique_vecs_fixed_length(len, xs), expected_values, expected_common_values, expected_median, ); } #[test] fn test_random_unique_vecs_fixed_length() { random_unique_vecs_fixed_length_helper( 0, random_primitive_ints::(EXAMPLE_SEED), repeat_n(&[][..], 20).collect_vec().as_slice(), &[(&[], 1000000)], (&[], None), ); random_unique_vecs_fixed_length_helper( 1, random_bools(EXAMPLE_SEED), &[ &[true], &[false], &[false], &[false], &[true], &[true], &[true], &[false], &[true], &[true], &[true], &[true], &[false], &[true], &[true], &[true], &[true], &[false], &[true], &[false], ], &[(&[true], 500473), (&[false], 499527)], (&[true], None), ); random_unique_vecs_fixed_length_helper( 3, random_primitive_ints::(EXAMPLE_SEED), &[ &[113, 239, 69], &[108, 228, 210], &[168, 161, 87], &[32, 110, 83], &[188, 34, 89], &[238, 93, 200], &[149, 115, 189], &[149, 217, 201], &[117, 146, 31], &[72, 151, 169], &[174, 33, 7], &[38, 81, 144], &[72, 127, 113], &[128, 233, 107], &[46, 119, 12], &[18, 164, 243], &[114, 174, 59], &[247, 39, 174], &[160, 184, 104], &[37, 100, 252], ], &[ (&[205, 0, 97], 4), (&[102, 18, 19], 4), (&[105, 70, 13], 4), (&[22, 45, 192], 4), (&[87, 100, 26], 4), (&[15, 107, 109], 4), (&[134, 245, 157], 4), (&[138, 164, 179], 4), (&[219, 253, 196], 4), (&[237, 197, 239], 4), ], (&[128, 16, 107], Some(&[128, 16, 116])), ); random_unique_vecs_fixed_length_helper( 2, random_unique_vecs_fixed_length(2, random_primitive_ints::(EXAMPLE_SEED)), &[ &[vec![113, 239], vec![69, 108]], &[vec![228, 210], vec![168, 161]], &[vec![87, 32], vec![110, 83]], &[vec![188, 34], vec![89, 238]], &[vec![93, 200], vec![149, 115]], &[vec![189, 149], vec![217, 201]], &[vec![117, 146], vec![31, 72]], &[vec![151, 169], vec![174, 33]], &[vec![7, 38], vec![81, 144]], &[vec![72, 127], vec![113, 128]], &[vec![233, 107], vec![46, 119]], &[vec![12, 18], vec![164, 243]], &[vec![114, 174], vec![59, 247]], &[vec![39, 174], vec![160, 184]], &[vec![104, 37], vec![100, 252]], &[vec![228, 122], vec![107, 69]], &[vec![242, 248], vec![179, 142]], &[vec![239, 233], vec![61, 189]], &[vec![235, 85], vec![192, 7]], &[vec![200, 90], vec![185, 178]], ], &[ (&[vec![60, 12], vec![3, 32]], 2), (&[vec![0, 80], vec![88, 210]], 2), (&[vec![1, 3], vec![216, 183]], 2), (&[vec![159, 0], vec![69, 30]], 2), (&[vec![199, 6], vec![95, 79]], 2), (&[vec![2, 98], vec![221, 19]], 2), (&[vec![212, 65], vec![99, 2]], 2), (&[vec![3, 14], vec![61, 170]], 2), (&[vec![41, 155], vec![3, 72]], 2), (&[vec![47, 85], vec![69, 66]], 2), ], ( &[vec![128, 41], vec![252, 44]], Some(&[vec![128, 42], vec![8, 241]]), ), ); } malachite-base-0.4.16/tests/vecs/random/random_unique_vecs_from_length_iterator.rs000064400000000000000000000070721046102023000266740ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use core::hash::Hash; use malachite_base::bools::random::random_bools; use malachite_base::num::random::geometric::geometric_random_unsigneds; use malachite_base::num::random::random_primitive_ints; use malachite_base::random::{Seed, EXAMPLE_SEED}; use malachite_base::test_util::vecs::random::random_vecs_helper_helper; use malachite_base::vecs::random::random_unique_vecs_from_length_iterator; use malachite_base::vecs::random_values_from_vec; use std::fmt::Debug; fn random_unique_vecs_from_length_iterator_helper< T: Clone + Debug + Eq + Hash + Ord, I: Clone + Iterator, J: Clone + Iterator, >( lengths_gen: &dyn Fn(Seed) -> I, xs_gen: &dyn Fn(Seed) -> J, expected_values: &[&[T]], expected_common_values: &[(&[T], usize)], expected_median: (&[T], Option<&[T]>), ) { random_vecs_helper_helper( random_unique_vecs_from_length_iterator(EXAMPLE_SEED, lengths_gen, xs_gen), expected_values, expected_common_values, expected_median, ); } #[test] fn test_random_unique_vecs_from_length_iterator() { random_unique_vecs_from_length_iterator_helper( &|seed| random_values_from_vec(seed, vec![0, 2]), &random_bools, &[ &[true, false], &[], &[true, false], &[true, false], &[], &[true, false], &[true, false], &[], &[true, false], &[false, true], &[], &[false, true], &[], &[false, true], &[false, true], &[], &[], &[], &[true, false], &[], ], &[(&[], 499637), (&[false, true], 250413), (&[true, false], 249950)], (&[false, true], None), ); random_unique_vecs_from_length_iterator_helper( &|seed| geometric_random_unsigneds::(seed, 2, 1).map(|x| x << 1), &random_primitive_ints::, &[ &[85, 11, 136, 200, 235, 134, 203, 223, 38, 217, 177, 162], &[32, 166], &[234, 30, 218, 90, 106, 9, 216, 204, 151, 213, 97, 253, 78, 91, 39, 191], &[175, 170], &[ 232, 233, 2, 35, 22, 217, 198, 114, 17, 32, 173, 65, 121, 222, 25, 144, 148, 79, 115, 52, 73, 69, 137, 91, 153, 178, 112, 34, ], &[], &[95, 106, 167, 197, 130, 168, 122, 207, 172, 177], &[86, 150, 221, 218, 101, 115, 74, 9], &[123, 109], &[], &[52, 201, 159, 247, 250, 48, 133, 235, 196, 40, 97, 104], &[68, 190, 216, 7], &[], &[], &[216, 157], &[43, 112, 217, 24, 11, 103], &[], &[211, 84], &[], &[135, 55], ], &[ (&[], 333981), (&[79, 76], 14), (&[234, 129], 14), (&[119, 62], 13), (&[33, 163], 13), (&[5, 42], 12), (&[28, 91], 12), (&[55, 25], 12), (&[152, 55], 12), (&[224, 77], 12), ], (&[63, 197, 169, 69, 240, 201], Some(&[63, 197, 181, 249])), ); } malachite-base-0.4.16/tests/vecs/random/random_unique_vecs_length_inclusive_range.rs000064400000000000000000000110731046102023000271710ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use core::hash::Hash; use malachite_base::chars::random::random_char_inclusive_range; use malachite_base::num::random::geometric::geometric_random_unsigneds; use malachite_base::num::random::random_primitive_ints; use malachite_base::random::{Seed, EXAMPLE_SEED}; use malachite_base::test_util::vecs::random::random_vecs_helper_helper; use malachite_base::vecs::random::random_unique_vecs_length_inclusive_range; use std::fmt::Debug; fn random_unique_vecs_length_inclusive_range_helper< T: Clone + Debug + Eq + Hash + Ord, I: Clone + Iterator, >( a: u64, b: u64, xs_gen: &dyn Fn(Seed) -> I, expected_values: &[&[T]], expected_common_values: &[(&[T], usize)], expected_median: (&[T], Option<&[T]>), ) { random_vecs_helper_helper( random_unique_vecs_length_inclusive_range(EXAMPLE_SEED, a, b, xs_gen), expected_values, expected_common_values, expected_median, ); } #[test] fn test_random_unique_vecs_length_inclusive_range() { random_unique_vecs_length_inclusive_range_helper( 2, 3, &random_primitive_ints::, &[ &[85, 11, 136], &[200, 235], &[134, 203, 223], &[38, 235, 217], &[177, 162], &[32, 166, 234], &[30, 218, 90], &[106, 9], &[216, 204, 151], &[213, 97, 253], &[78, 91], &[39, 191, 175], &[170, 232], &[233, 2, 35], &[22, 217, 198], &[114, 17], &[32, 173], &[114, 65], &[121, 222, 173], &[25, 144], ], &[ (&[149, 194], 23), (&[237, 224], 23), (&[109, 76], 21), (&[187, 29], 21), (&[96, 105], 21), (&[233, 132], 21), (&[25, 96], 20), (&[92, 85], 20), (&[108, 72], 20), (&[128, 48], 20), ], (&[127, 247], None), ); random_unique_vecs_length_inclusive_range_helper( 2, 3, &|seed| geometric_random_unsigneds::(seed, 2, 1), &[ &[5, 0, 1], &[1, 4], &[2, 4, 6], &[2, 0, 1], &[9, 13], &[0, 2, 7], &[4, 6, 7], &[6, 0], &[0, 1, 3], &[5, 1, 2], &[1, 0], &[0, 1, 4], &[2, 0], &[12, 0, 2], &[3, 1, 2], &[3, 9], &[1, 0], &[2, 1], &[11, 1, 0], &[1, 6], ], &[ (&[0, 1], 55434), (&[1, 0], 47598), (&[0, 2], 37211), (&[2, 0], 28974), (&[0, 3], 24737), (&[1, 2], 21227), (&[2, 1], 19153), (&[0, 1, 2], 18604), (&[3, 0], 18253), (&[0, 4], 16195), ], (&[1, 4], None), ); random_unique_vecs_length_inclusive_range_helper( 2, 3, &|seed| random_char_inclusive_range(seed, 'a', 'z'), &[ &['v', 'c', 'q'], &['i', 'e'], &['p', 'g', 's'], &['n', 't', 'm'], &['z', 'o'], &['m', 'f', 'k'], &['q', 'y', 'u'], &['k', 'x'], &['h', 'u', 'n'], &['n', 'j', 'a'], &['w', 'z'], &['l', 'w', 'b'], &['l', 'u'], &['n', 'e', 'l'], &['v', 'k', 'u'], &['h', 'c'], &['y', 'i'], &['m', 'r'], &['m', 'y', 's'], &['l', 'e'], ], &[ (&['i', 'p'], 855), (&['o', 't'], 845), (&['c', 'i'], 842), (&['h', 'u'], 841), (&['x', 'l'], 841), (&['a', 'o'], 833), (&['g', 'h'], 833), (&['z', 'n'], 832), (&['j', 'n'], 831), (&['l', 'c'], 829), ], (&['m', 'z', 'l'], None), ); } #[test] #[should_panic] fn random_unique_vecs_length_inclusive_range_fail() { random_unique_vecs_length_inclusive_range(EXAMPLE_SEED, 2, 1, &random_primitive_ints::); } malachite-base-0.4.16/tests/vecs/random/random_unique_vecs_length_range.rs000064400000000000000000000107411046102023000251110ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use core::hash::Hash; use malachite_base::chars::random::random_char_inclusive_range; use malachite_base::num::random::geometric::geometric_random_unsigneds; use malachite_base::num::random::random_primitive_ints; use malachite_base::random::{Seed, EXAMPLE_SEED}; use malachite_base::test_util::vecs::random::random_vecs_helper_helper; use malachite_base::vecs::random::random_unique_vecs_length_range; use std::fmt::Debug; fn random_unique_vecs_length_range_helper< T: Clone + Debug + Eq + Hash + Ord, I: Clone + Iterator, >( a: u64, b: u64, xs_gen: &dyn Fn(Seed) -> I, expected_values: &[&[T]], expected_common_values: &[(&[T], usize)], expected_median: (&[T], Option<&[T]>), ) { random_vecs_helper_helper( random_unique_vecs_length_range(EXAMPLE_SEED, a, b, xs_gen), expected_values, expected_common_values, expected_median, ); } #[test] fn test_random_unique_vecs_length_range() { random_unique_vecs_length_range_helper( 2, 4, &random_primitive_ints::, &[ &[85, 11, 136], &[200, 235], &[134, 203, 223], &[38, 235, 217], &[177, 162], &[32, 166, 234], &[30, 218, 90], &[106, 9], &[216, 204, 151], &[213, 97, 253], &[78, 91], &[39, 191, 175], &[170, 232], &[233, 2, 35], &[22, 217, 198], &[114, 17], &[32, 173], &[114, 65], &[121, 222, 173], &[25, 144], ], &[ (&[149, 194], 23), (&[237, 224], 23), (&[109, 76], 21), (&[187, 29], 21), (&[96, 105], 21), (&[233, 132], 21), (&[25, 96], 20), (&[92, 85], 20), (&[108, 72], 20), (&[128, 48], 20), ], (&[127, 247], None), ); random_unique_vecs_length_range_helper( 2, 4, &|seed| geometric_random_unsigneds::(seed, 2, 1), &[ &[5, 0, 1], &[1, 4], &[2, 4, 6], &[2, 0, 1], &[9, 13], &[0, 2, 7], &[4, 6, 7], &[6, 0], &[0, 1, 3], &[5, 1, 2], &[1, 0], &[0, 1, 4], &[2, 0], &[12, 0, 2], &[3, 1, 2], &[3, 9], &[1, 0], &[2, 1], &[11, 1, 0], &[1, 6], ], &[ (&[0, 1], 55434), (&[1, 0], 47598), (&[0, 2], 37211), (&[2, 0], 28974), (&[0, 3], 24737), (&[1, 2], 21227), (&[2, 1], 19153), (&[0, 1, 2], 18604), (&[3, 0], 18253), (&[0, 4], 16195), ], (&[1, 4], None), ); random_unique_vecs_length_range_helper( 2, 4, &|seed| random_char_inclusive_range(seed, 'a', 'z'), &[ &['v', 'c', 'q'], &['i', 'e'], &['p', 'g', 's'], &['n', 't', 'm'], &['z', 'o'], &['m', 'f', 'k'], &['q', 'y', 'u'], &['k', 'x'], &['h', 'u', 'n'], &['n', 'j', 'a'], &['w', 'z'], &['l', 'w', 'b'], &['l', 'u'], &['n', 'e', 'l'], &['v', 'k', 'u'], &['h', 'c'], &['y', 'i'], &['m', 'r'], &['m', 'y', 's'], &['l', 'e'], ], &[ (&['i', 'p'], 855), (&['o', 't'], 845), (&['c', 'i'], 842), (&['h', 'u'], 841), (&['x', 'l'], 841), (&['a', 'o'], 833), (&['g', 'h'], 833), (&['z', 'n'], 832), (&['j', 'n'], 831), (&['l', 'c'], 829), ], (&['m', 'z', 'l'], None), ); } #[test] #[should_panic] fn random_unique_vecs_length_range_fail() { random_unique_vecs_length_range(EXAMPLE_SEED, 2, 2, &random_primitive_ints::); } malachite-base-0.4.16/tests/vecs/random/random_unique_vecs_min_length.rs000064400000000000000000000307231046102023000246020ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use core::hash::Hash; use malachite_base::chars::exhaustive::exhaustive_chars; use malachite_base::chars::random::graphic_weighted_random_char_inclusive_range; use malachite_base::num::random::geometric::geometric_random_unsigneds; use malachite_base::num::random::random_primitive_ints; use malachite_base::random::{Seed, EXAMPLE_SEED}; use malachite_base::test_util::vecs::random::random_vecs_helper_helper; use malachite_base::vecs::random::random_unique_vecs_min_length; use std::fmt::Debug; fn random_unique_vecs_min_length_helper< T: Clone + Debug + Eq + Hash + Ord, I: Clone + Iterator, >( min_length: u64, xs_gen: &dyn Fn(Seed) -> I, mean_length_numerator: u64, mean_length_denominator: u64, expected_values: &[&[T]], expected_common_values: &[(&[T], usize)], expected_median: (&[T], Option<&[T]>), ) { random_vecs_helper_helper( random_unique_vecs_min_length( EXAMPLE_SEED, min_length, xs_gen, mean_length_numerator, mean_length_denominator, ), expected_values, expected_common_values, expected_median, ); } #[test] fn test_random_unique_vecs_min_length() { random_unique_vecs_min_length_helper( 0, &random_primitive_ints::, 4, 1, &[ &[], &[85, 11, 136, 200, 235, 134, 203, 223, 38, 217, 177, 162, 32, 166], &[234, 30, 218, 90], &[106, 9, 216, 204], &[151], &[], &[213, 97, 253, 78, 91], &[39, 191], &[175, 170, 232, 233], &[], &[2, 35, 22, 217, 198, 114], &[], &[], &[17, 32, 173, 114, 65, 121, 222, 25, 144, 148, 79], &[115, 52, 73, 69, 137, 91, 153, 178], &[], &[112, 34, 95], &[], &[106, 167, 197, 130, 168], &[122, 207, 172, 177, 86, 150, 221, 218, 101], ], &[ (&[], 199913), (&[7], 705), (&[25], 689), (&[184], 681), (&[213], 681), (&[255], 676), (&[215], 675), (&[54], 673), (&[122], 672), (&[207], 672), ], (&[96], None), ); random_unique_vecs_min_length_helper( 3, &random_primitive_ints::, 7, 1, &[ &[85, 11, 136], &[200, 235, 134, 203, 223, 38, 217, 177, 162, 32, 166, 234, 30, 218, 90, 106, 9], &[216, 204, 151, 213, 97, 253, 78], &[91, 39, 191, 175, 170, 232, 233], &[2, 35, 22, 217], &[198, 114, 17], &[32, 173, 114, 65, 121, 222, 25, 144], &[148, 79, 115, 52, 73], &[69, 137, 91, 153, 178, 112, 34], &[95, 106, 167], &[197, 130, 168, 122, 207, 172, 177, 86, 150], &[221, 218, 101], &[115, 74, 9], &[123, 109, 52, 201, 159, 247, 250, 48, 133, 235, 196, 40, 97, 104], &[68, 190, 216, 7, 157, 43, 112, 217, 24, 11, 103], &[211, 84, 135], &[55, 29, 206, 89, 65, 191], &[51, 9, 79], &[148, 34, 22, 62, 3, 114, 118, 20], &[47, 194, 50, 32, 120, 176, 166, 23, 204, 248, 177, 238], ], &[ (&[8, 94, 244], 3), (&[233, 14, 180], 3), (&[46, 247, 166], 3), (&[84, 118, 223], 3), (&[4, 52, 2], 2), (&[80, 2, 0], 2), (&[1, 116, 5], 2), (&[1, 5, 192], 2), (&[1, 96, 39], 2), (&[20, 10, 9], 2), ], ( &[127, 218, 55, 167, 163, 19, 99, 71, 32, 117, 72, 38, 27, 29], Some(&[127, 218, 69, 59, 30, 91]), ), ); random_unique_vecs_min_length_helper( 0, &|seed| geometric_random_unsigneds::(seed, 32, 1), 4, 1, &[ &[], &[1, 14, 42, 12, 141, 19, 9, 68, 16, 79, 21, 17, 41, 124], &[10, 1, 99, 0], &[77, 36, 2, 12], &[1], &[], &[103, 9, 19, 1, 5], &[7, 6], &[51, 159, 15, 18], &[], &[52, 75, 40, 64, 2, 26], &[], &[], &[67, 34, 51, 30, 31, 49, 43, 7, 5, 4, 3], &[14, 47, 24, 16, 52, 29, 1, 41], &[], &[13, 11, 62], &[], &[47, 3, 109, 42, 14], &[37, 86, 25, 96, 41, 13, 16, 42, 5], ], &[ (&[], 199913), (&[0], 4861), (&[1], 4593), (&[2], 4498), (&[3], 4405), (&[4], 4330), (&[5], 4078), (&[6], 4050), (&[7], 3858), (&[8], 3848), ], (&[15, 3], None), ); random_unique_vecs_min_length_helper( 3, &|seed| geometric_random_unsigneds::(seed, 32, 1), 7, 1, &[ &[1, 14, 42], &[12, 141, 19, 9, 68, 16, 79, 21, 17, 41, 124, 10, 1, 99, 0, 77, 36], &[2, 12, 1, 103, 9, 19, 5], &[7, 6, 51, 159, 15, 18, 52], &[75, 40, 64, 2], &[26, 67, 34], &[51, 30, 31, 49, 43, 7, 5, 4], &[3, 14, 47, 24, 16], &[52, 29, 1, 41, 13, 11, 62], &[47, 3, 109], &[42, 14, 37, 86, 25, 96, 41, 13, 16], &[42, 5, 20], &[2, 82, 74], &[7, 76, 11, 17, 127, 36, 20, 56, 89, 45, 6, 80, 3, 66], &[23, 43, 1, 25, 6, 41, 19, 97, 10, 13, 32], &[41, 7, 134], &[47, 105, 26, 10, 9, 25], &[94, 68, 109], &[1, 9, 84, 3, 43, 44, 28, 13], &[13, 5, 0, 31, 50, 75, 32, 4, 7, 37, 42, 6], ], &[ (&[0, 1, 7], 13), (&[0, 2, 8], 12), (&[6, 2, 8], 12), (&[0, 2, 5], 11), (&[2, 7, 3], 11), (&[9, 3, 1], 11), (&[0, 9, 2], 10), (&[1, 8, 7], 10), (&[3, 5, 1], 10), (&[5, 0, 2], 10), ], (&[22, 28, 18, 89, 4, 52, 51], Some(&[22, 28, 19])), ); random_unique_vecs_min_length_helper( 0, &random_primitive_ints::, 1, 4, &[ &[], &[], &[85], &[11], &[136, 200], &[], &[], &[], &[], &[], &[], &[], &[235, 134], &[203], &[], &[223, 38], &[], &[], &[], &[], ], &[ (&[], 800023), (&[162], 692), (&[235], 690), (&[90], 688), (&[65], 687), (&[249], 686), (&[175], 684), (&[108], 683), (&[211], 682), (&[237], 680), ], (&[], None), ); random_unique_vecs_min_length_helper( 3, &random_primitive_ints::, 13, 4, &[ &[85, 11, 136], &[200, 235, 134], &[203, 223, 38, 235], &[217, 177, 162, 32], &[166, 234, 30, 218, 90], &[106, 9, 216], &[204, 151, 213], &[97, 253, 78], &[91, 39, 191], &[175, 170, 232], &[233, 2, 35], &[22, 217, 198], &[114, 17, 32, 173, 65], &[121, 222, 173, 25], &[144, 148, 79], &[115, 52, 73, 69, 137], &[91, 153, 178], &[112, 34, 95], &[106, 167, 197], &[130, 168, 122], ], &[ (&[8, 57, 90], 4), (&[185, 30, 26], 4), (&[106, 20, 234], 4), (&[152, 245, 81], 4), (&[108, 192, 235], 4), (&[75, 2, 5], 3), (&[0, 106, 9], 3), (&[2, 91, 90], 3), (&[212, 1, 8], 3), (&[49, 5, 75], 3), ], (&[128, 38, 40], Some(&[128, 38, 42])), ); random_unique_vecs_min_length_helper( 0, &|seed| { graphic_weighted_random_char_inclusive_range( seed, 'a', exhaustive_chars().nth(200).unwrap(), 1, 1, ) }, 4, 1, &[ &[], &['q', 'á', 'g', 'Á', 'À', 'È', '»', 'ì', '³', 'ą', 'â', 'Ã', 'ñ', 'Ā'], &['Ã', 'ª', 'ä', '´'], &['½', 'Á', 'Ï', 'ý'], &['j'], &[], &['ï', 'Ñ', 'u', 'Â', '½'], &['õ', 'x'], &['Â', 'ù', '¡', 'Ċ'], &[], &['¬', 'b', 'Ñ', 's', 'Â', 'r'], &[], &[], &['n', '¿', 'Þ', 'ô', 'Ø', 'º', 'ü', 't', '¬', 'j', 'Á'], &['±', 'è', 'k', 'æ', 'b', 'Î', 'ā', 'Ü'], &[], &['¹', '«', 'Î'], &[], &['~', '´', 'Ý', 'â', '¯'], &['é', 'æ', 'Þ', 'ö', 'g', 'Î', 'Ç', 'Ü', '¼'], ], &[ (&[], 199913), (&['Ó'], 1270), (&['Â'], 1249), (&['§'], 1244), (&['¿'], 1243), (&['õ'], 1241), (&['ĉ'], 1234), (&['¤'], 1232), (&['¼'], 1232), (&['Ì'], 1229), ], ( &['¶', 'Ă', 'ą', '®', 'Á', 'í', '¬', '¾', '¸', 'Ã', '}', 'ù', 'ý', '½', 'a'], Some(&['¶', 'Ă', 'ć']), ), ); random_unique_vecs_min_length_helper( 3, &|seed| { graphic_weighted_random_char_inclusive_range( seed, 'a', exhaustive_chars().nth(200).unwrap(), 1, 1, ) }, 7, 1, &[ &['q', 'á', 'g'], &['Á', 'À', 'È', '»', 'ì', '³', 'ą', 'â', 'g', 'Ã', 'ñ', 'Ā', 'ª', 'ä', '´', '½', 'Ï'], &['ý', 'j', 'ï', 'Ñ', 'u', 'Â', '½'], &['õ', 'x', 'Â', 'ù', '¡', 'Ċ', '¬'], &['b', 'Ñ', '¬', 's'], &['Â', 'r', 'n'], &['¿', 'Þ', 'ô', 'Ø', 'º', 'ü', 't', '¬'], &['j', 'Á', '±', 'è', 'k'], &['æ', 'b', 'Î', 'ā', 'Ü', '¹', '«'], &['Î', '~', '´'], &['Ý', 'â', '¯', 'é', 'æ', 'Þ', 'ö', 'g', 'Î'], &['Ç', 'Ü', '¼'], &['¡', '§', 'Ì'], &['±', 'd', 'ê', 'm', '®', 'ì', '¨', 'ý', 'þ', 'Ë', '{', 'Ü', 'z', '¼'], &['ï', 'ă', 'Ą', 'û', 'ª', 'ċ', 'x', 'À', 'ì', 'Õ', '½'], &['¢', '«', 'Ć'], &['{', 'È', 'ÿ', '½', '¢', 'ä'], &['Ë', 'Õ', 'ê'], &['º', 'ü', '×', '¨', 'Å', 'p', '°', 'Ó'], &['d', 'Ê', 'æ', 'ß', 'v', 'Ć', 'k', 'Ä', '±', 'È', '¥', 'o'], ], &[ (&['a', 'Ã', '¤'], 4), (&['Ā', 'Ì', 'k'], 4), (&['w', 'm', 'u'], 3), (&['a', 'k', 'Ä'], 3), (&['b', 'Ã', 'n'], 3), (&['c', '|', 'Æ'], 3), (&['d', 'm', 'ï'], 3), (&['d', 'z', '¢'], 3), (&['d', '¯', 't'], 3), (&['f', 'g', '¹'], 3), ], ( &['Ç', 'Ĉ', 's', 'ò', 'c', '¿', 'Å', 'Ô', 'Æ'], Some(&['Ç', 'Ĉ', 'v', '³', 'ò']), ), ); } #[test] #[should_panic] fn random_unique_vecs_min_length_fail_1() { random_unique_vecs_min_length(EXAMPLE_SEED, 3, &random_primitive_ints::, 3, 1); } #[test] #[should_panic] fn random_unique_vecs_min_length_fail_2() { random_unique_vecs_min_length(EXAMPLE_SEED, 1, &random_primitive_ints::, 1, 0); } #[test] #[should_panic] fn random_unique_vecs_min_length_fail_3() { random_unique_vecs_min_length( EXAMPLE_SEED, 0, &random_primitive_ints::, u64::MAX, u64::MAX - 1, ); } malachite-base-0.4.16/tests/vecs/random/random_vecs.rs000064400000000000000000000157211046102023000210110ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use core::hash::Hash; use malachite_base::chars::random::random_char_inclusive_range; use malachite_base::num::random::geometric::geometric_random_unsigneds; use malachite_base::num::random::random_primitive_ints; use malachite_base::random::{Seed, EXAMPLE_SEED}; use malachite_base::test_util::vecs::random::random_vecs_helper_helper; use malachite_base::tuples::random::random_units; use malachite_base::vecs::random::random_vecs; use std::fmt::Debug; fn random_vecs_helper>( xs_gen: &dyn Fn(Seed) -> I, mean_length_numerator: u64, mean_length_denominator: u64, expected_values: &[&[T]], expected_common_values: &[(&[T], usize)], expected_median: (&[T], Option<&[T]>), ) { random_vecs_helper_helper( random_vecs( EXAMPLE_SEED, xs_gen, mean_length_numerator, mean_length_denominator, ), expected_values, expected_common_values, expected_median, ); } #[test] fn test_random_vecs() { random_vecs_helper( &|_| random_units(), 4, 1, &[ &[], &[(), (), (), (), (), (), (), (), (), (), (), (), (), ()], &[(), (), (), ()], &[(), (), (), ()], &[()], &[], &[(), (), (), (), ()], &[(), ()], &[(), (), (), ()], &[], &[(), (), (), (), (), ()], &[], &[], &[(), (), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), ()], &[], &[(), (), ()], &[], &[(), (), (), (), ()], &[(), (), (), (), (), (), (), (), ()], ], &[ (&[], 199913), (&[()], 160173), (&[(), ()], 128173), (&[(), (), ()], 102460), (&[(), (), (), ()], 81463), (&[(), (), (), (), ()], 65695), (&[(), (), (), (), (), ()], 52495), (&[(), (), (), (), (), (), ()], 41943), (&[(), (), (), (), (), (), (), ()], 33396), (&[(), (), (), (), (), (), (), (), ()], 27035), ], (&[(), (), ()], None), ); random_vecs_helper( &random_primitive_ints::, 4, 1, &[ &[], &[85, 11, 136, 200, 235, 134, 203, 223, 38, 235, 217, 177, 162, 32], &[166, 234, 30, 218], &[90, 106, 9, 216], &[204], &[], &[151, 213, 97, 253, 78], &[91, 39], &[191, 175, 170, 232], &[], &[233, 2, 35, 22, 217, 198], &[], &[], &[114, 17, 32, 173, 114, 65, 121, 222, 173, 25, 144], &[148, 79, 115, 52, 73, 69, 137, 91], &[], &[153, 178, 112], &[], &[34, 95, 106, 167, 197], &[130, 168, 122, 207, 172, 177, 86, 150, 221], ], &[ (&[], 199913), (&[146], 693), (&[26], 692), (&[185], 688), (&[58], 683), (&[196], 683), (&[81], 678), (&[229], 675), (&[192], 673), (&[233], 673), ], (&[96], None), ); random_vecs_helper( &|seed| geometric_random_unsigneds::(seed, 2, 1), 4, 1, &[ &[], &[5, 0, 0, 1, 1, 1, 4, 2, 4, 6, 2, 2, 0, 1], &[9, 13, 0, 0], &[2, 0, 7, 4], &[6], &[], &[7, 6, 0, 0, 0], &[1, 3], &[5, 1, 2, 1], &[], &[0, 0, 1, 4, 2, 0], &[], &[], &[12, 0, 0, 2, 3, 1, 1, 1, 2, 3, 3], &[9, 1, 0, 2, 1, 11, 1, 0], &[], &[1, 6, 0], &[], &[3, 18, 3, 3, 0], &[5, 1, 2, 5, 0, 0, 2, 3, 1], ], &[ (&[], 199913), (&[0], 53462), (&[1], 35352), (&[2], 23512), (&[3], 16118), (&[0, 0], 14371), (&[4], 10594), (&[0, 1], 9566), (&[1, 0], 9409), (&[5], 7157), ], (&[1], None), ); random_vecs_helper( &random_primitive_ints::, 1, 4, &[ &[], &[], &[85], &[11], &[136, 200], &[], &[], &[], &[], &[], &[], &[], &[235, 134], &[203], &[], &[223, 38], &[], &[], &[], &[], ], &[ (&[], 800023), (&[8], 704), (&[162], 691), (&[81], 690), (&[211], 690), (&[108], 688), (&[235], 688), (&[35], 687), (&[65], 682), (&[208], 679), ], (&[], None), ); random_vecs_helper( &|seed| random_char_inclusive_range(seed, 'a', 'z'), 4, 1, &[ &[], &['v', 'c', 'q', 'i', 'e', 'p', 'g', 's', 'n', 't', 'm', 'z', 'o', 'm'], &['f', 'k', 'q', 'y'], &['u', 'k', 'x', 'h'], &['u'], &[], &['n', 'n', 'j', 'n', 'j'], &['a', 'w'], &['z', 'l', 'w', 'b'], &[], &['l', 'u', 'n', 'e', 'l', 'v'], &[], &[], &['k', 'u', 'h', 'c', 'y', 'i', 'm', 'r', 'm', 'y', 's'], &['l', 'e', 'a', 's', 'w', 'k', 'o', 'b'], &[], &['k', 'w', 'g'], &[], &['d', 'q', 'e', 'f', 'u'], &['z', 'r', 'g', 'j', 'k', 'r', 's', 'y', 'n'], ], &[ (&[], 199913), (&['o'], 6313), (&['y'], 6262), (&['q'], 6261), (&['j'], 6245), (&['p'], 6244), (&['g'], 6219), (&['x'], 6215), (&['e'], 6200), (&['t'], 6188), ], (&['j', 's', 'z'], None), ); } #[test] #[should_panic] fn random_vecs_fail_1() { random_vecs(EXAMPLE_SEED, &random_primitive_ints::, 0, 1); } #[test] #[should_panic] fn random_vecs_fail_2() { random_vecs(EXAMPLE_SEED, &random_primitive_ints::, 1, 0); } #[test] #[should_panic] fn random_vecs_fail_3() { random_vecs( EXAMPLE_SEED, &random_primitive_ints::, u64::MAX, u64::MAX - 1, ); } malachite-base-0.4.16/tests/vecs/random/random_vecs_fixed_length.rs000064400000000000000000000203721046102023000235270ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use crate::extra_variadic::random_vecs_length_3; use core::hash::Hash; use malachite_base::chars::random::random_char_inclusive_range; use malachite_base::num::random::{random_primitive_ints, random_unsigned_range}; use malachite_base::random::{Seed, EXAMPLE_SEED}; use malachite_base::test_util::vecs::random::random_vecs_helper_helper; use malachite_base::vecs::random::{random_vecs_fixed_length_from_single, random_vecs_length_2}; use std::fmt::Debug; fn random_vecs_length_2_helper< T: Clone + Debug + Eq + Hash + Ord, I: Clone + Iterator, J: Clone + Iterator, >( xs_gen: &dyn Fn(Seed) -> I, ys_gen: &dyn Fn(Seed) -> J, expected_values: &[&[T]], expected_common_values: &[(&[T], usize)], expected_median: (&[T], Option<&[T]>), ) { random_vecs_helper_helper( random_vecs_length_2(EXAMPLE_SEED, xs_gen, ys_gen), expected_values, expected_common_values, expected_median, ); } #[test] fn test_random_vecs_length_2() { random_vecs_length_2_helper( &random_primitive_ints::, &|seed| random_unsigned_range(seed, 0, 10), &[ &[85, 2], &[11, 6], &[136, 8], &[200, 6], &[235, 8], &[134, 2], &[203, 4], &[223, 1], &[38, 2], &[235, 7], &[217, 5], &[177, 4], &[162, 8], &[32, 8], &[166, 4], &[234, 4], &[30, 3], &[218, 5], &[90, 6], &[106, 7], ], &[ (&[196, 6], 466), (&[162, 5], 457), (&[132, 5], 455), (&[200, 2], 455), (&[61, 3], 454), (&[117, 5], 453), (&[28, 0], 446), (&[148, 5], 446), (&[194, 9], 446), (&[44, 3], 444), ], (&[127, 9], None), ); random_vecs_length_2_helper( &|seed| random_vecs_fixed_length_from_single(2, random_primitive_ints::(seed)), &|seed| random_vecs_fixed_length_from_single(3, random_primitive_ints::(seed)), &[ &[vec![85, 11], vec![98, 168, 198]], &[vec![136, 200], vec![40, 20, 252]], &[vec![235, 134], vec![47, 87, 132]], &[vec![203, 223], vec![72, 77, 63]], &[vec![38, 235], vec![91, 108, 127]], &[vec![217, 177], vec![53, 141, 84]], &[vec![162, 32], vec![18, 10, 112]], &[vec![166, 234], vec![154, 104, 53]], &[vec![30, 218], vec![75, 238, 149]], &[vec![90, 106], vec![190, 51, 147]], &[vec![9, 216], vec![100, 114, 140]], &[vec![204, 151], vec![2, 63, 189]], &[vec![213, 97], vec![222, 67, 119]], &[vec![253, 78], vec![0, 223, 5]], &[vec![91, 39], vec![236, 232, 50]], &[vec![191, 175], vec![44, 241, 21]], &[vec![170, 232], vec![22, 94, 27]], &[vec![233, 2], vec![128, 220, 25]], &[vec![35, 22], vec![251, 243, 50]], &[vec![217, 198], vec![137, 235, 46]], ], &[ (&[vec![0, 5], vec![6, 7, 42]], 1), (&[vec![8, 8], vec![18, 5, 6]], 1), (&[vec![9, 1], vec![5, 3, 23]], 1), (&[vec![0, 0], vec![97, 7, 73]], 1), (&[vec![0, 2], vec![12, 20, 6]], 1), (&[vec![0, 99], vec![20, 8, 6]], 1), (&[vec![1, 81], vec![3, 21, 3]], 1), (&[vec![1, 9], vec![219, 9, 7]], 1), (&[vec![1, 9], vec![4, 95, 15]], 1), (&[vec![15, 2], vec![56, 0, 8]], 1), ], ( &[vec![127, 197], vec![162, 123, 217]], Some(&[vec![127, 197], vec![163, 170, 161]]), ), ); } fn random_vecs_length_3_helper< T: Clone + Debug + Eq + Hash + Ord, I: Clone + Iterator, J: Clone + Iterator, K: Clone + Iterator, >( xs_gen: &dyn Fn(Seed) -> I, ys_gen: &dyn Fn(Seed) -> J, zs_gen: &dyn Fn(Seed) -> K, expected_values: &[&[T]], expected_common_values: &[(&[T], usize)], expected_median: (&[T], Option<&[T]>), ) { random_vecs_helper_helper( random_vecs_length_3(EXAMPLE_SEED, xs_gen, ys_gen, zs_gen), expected_values, expected_common_values, expected_median, ); } #[test] fn test_random_vecs_length_3() { random_vecs_length_3_helper( &|seed| random_char_inclusive_range(seed, 'a', 'c'), &|seed| random_char_inclusive_range(seed, 'd', 'f'), &|seed| random_char_inclusive_range(seed, 'g', 'i'), &[ &['b', 'f', 'g'], &['b', 'd', 'i'], &['b', 'f', 'i'], &['b', 'e', 'i'], &['c', 'd', 'i'], &['a', 'f', 'i'], &['a', 'f', 'g'], &['a', 'f', 'g'], &['c', 'f', 'i'], &['a', 'e', 'i'], &['c', 'd', 'h'], &['a', 'd', 'h'], &['c', 'f', 'i'], &['a', 'f', 'i'], &['c', 'd', 'g'], &['c', 'd', 'h'], &['c', 'e', 'g'], &['b', 'e', 'h'], &['a', 'd', 'g'], &['c', 'd', 'g'], ], &[ (&['b', 'f', 'i'], 37416), (&['a', 'f', 'g'], 37345), (&['c', 'd', 'i'], 37278), (&['b', 'f', 'g'], 37274), (&['a', 'd', 'h'], 37207), (&['b', 'f', 'h'], 37188), (&['b', 'd', 'i'], 37153), (&['b', 'e', 'g'], 37117), (&['a', 'd', 'g'], 37092), (&['c', 'f', 'g'], 37068), ], (&['b', 'e', 'h'], None), ); random_vecs_length_3_helper( &|seed| random_vecs_fixed_length_from_single(1, random_primitive_ints::(seed)), &|seed| random_vecs_fixed_length_from_single(2, random_primitive_ints::(seed)), &|seed| random_vecs_fixed_length_from_single(3, random_primitive_ints::(seed)), &[ &[vec![85], vec![98, 168], vec![168, 10, 250]], &[vec![11], vec![198, 40], vec![95, 250, 79]], &[vec![136], vec![20, 252], vec![4, 171, 141]], &[vec![200], vec![47, 87], vec![189, 177, 169]], &[vec![235], vec![132, 72], vec![36, 73, 154]], &[vec![134], vec![77, 63], vec![62, 202, 17]], &[vec![203], vec![91, 108], vec![35, 189, 158]], &[vec![223], vec![127, 53], vec![31, 173, 175]], &[vec![38], vec![141, 84], vec![63, 225, 106]], &[vec![235], vec![18, 10], vec![40, 116, 16]], &[vec![217], vec![112, 154], vec![88, 112, 9]], &[vec![177], vec![104, 53], vec![227, 144, 93]], &[vec![162], vec![75, 238], vec![85, 90, 214]], &[vec![32], vec![149, 190], vec![31, 60, 254]], &[vec![166], vec![51, 147], vec![143, 44, 177]], &[vec![234], vec![100, 114], vec![205, 197, 53]], &[vec![30], vec![140, 2], vec![15, 184, 137]], &[vec![218], vec![63, 189], vec![75, 116, 140]], &[vec![90], vec![222, 67], vec![19, 119, 60]], &[vec![106], vec![119, 0], vec![219, 21, 164]], ], &[ (&[vec![0], vec![47, 4], vec![31, 6, 1]], 1), (&[vec![0], vec![5, 12], vec![9, 6, 54]], 1), (&[vec![6], vec![99, 35], vec![3, 2, 3]], 1), (&[vec![7], vec![7, 56], vec![6, 3, 76]], 1), (&[vec![7], vec![9, 5], vec![148, 1, 1]], 1), (&[vec![9], vec![61, 7], vec![9, 60, 8]], 1), (&[vec![0], vec![0, 55], vec![1, 12, 83]], 1), (&[vec![0], vec![1, 57], vec![60, 4, 55]], 1), (&[vec![0], vec![1, 8], vec![235, 0, 27]], 1), (&[vec![0], vec![73, 15], vec![0, 2, 11]], 1), ], ( &[vec![127], vec![241, 129], vec![232, 173, 11]], Some(&[vec![127], vec![241, 149], vec![219, 172, 49]]), ), ); } malachite-base-0.4.16/tests/vecs/random/random_vecs_fixed_length_from_single.rs000064400000000000000000000115551046102023000261160ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use core::hash::Hash; use itertools::{repeat_n, Itertools}; use malachite_base::bools::random::random_bools; use malachite_base::num::random::random_primitive_ints; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::vecs::random::random_vecs_helper_helper; use malachite_base::vecs::random::random_vecs_fixed_length_from_single; use std::fmt::Debug; fn random_vecs_fixed_length_from_single_helper( len: u64, xs: I, expected_values: &[&[I::Item]], expected_common_values: &[(&[I::Item], usize)], expected_median: (&[I::Item], Option<&[I::Item]>), ) where I::Item: Clone + Debug + Eq + Hash + Ord, { random_vecs_helper_helper( random_vecs_fixed_length_from_single(len, xs), expected_values, expected_common_values, expected_median, ); } #[test] fn test_random_vecs_fixed_length_from_single() { random_vecs_fixed_length_from_single_helper( 0, random_primitive_ints::(EXAMPLE_SEED), repeat_n(&[][..], 20).collect_vec().as_slice(), &[(&[], 1000000)], (&[], None), ); random_vecs_fixed_length_from_single_helper( 1, random_bools(EXAMPLE_SEED), &[ &[true], &[false], &[false], &[false], &[true], &[true], &[true], &[false], &[true], &[true], &[true], &[true], &[false], &[true], &[true], &[true], &[true], &[false], &[true], &[false], ], &[(&[true], 500473), (&[false], 499527)], (&[true], None), ); random_vecs_fixed_length_from_single_helper( 3, random_primitive_ints::(EXAMPLE_SEED), &[ &[113, 239, 69], &[108, 228, 210], &[168, 161, 87], &[32, 110, 83], &[188, 34, 89], &[238, 93, 200], &[149, 115, 189], &[149, 217, 201], &[117, 146, 31], &[72, 151, 169], &[174, 33, 7], &[38, 81, 144], &[72, 127, 113], &[128, 233, 107], &[46, 119, 12], &[18, 164, 243], &[114, 174, 59], &[247, 39, 174], &[160, 184, 104], &[37, 100, 252], ], &[ (&[222, 60, 79], 4), (&[26, 110, 13], 4), (&[41, 254, 55], 4), (&[109, 134, 76], 4), (&[165, 174, 73], 4), (&[236, 57, 174], 4), (&[73, 168, 192], 4), (&[89, 197, 244], 4), (&[91, 170, 115], 4), (&[142, 168, 231], 4), ], (&[127, 253, 76], Some(&[127, 253, 86])), ); random_vecs_fixed_length_from_single_helper( 2, random_vecs_fixed_length_from_single(2, random_primitive_ints::(EXAMPLE_SEED)), &[ &[vec![113, 239], vec![69, 108]], &[vec![228, 210], vec![168, 161]], &[vec![87, 32], vec![110, 83]], &[vec![188, 34], vec![89, 238]], &[vec![93, 200], vec![149, 115]], &[vec![189, 149], vec![217, 201]], &[vec![117, 146], vec![31, 72]], &[vec![151, 169], vec![174, 33]], &[vec![7, 38], vec![81, 144]], &[vec![72, 127], vec![113, 128]], &[vec![233, 107], vec![46, 119]], &[vec![12, 18], vec![164, 243]], &[vec![114, 174], vec![59, 247]], &[vec![39, 174], vec![160, 184]], &[vec![104, 37], vec![100, 252]], &[vec![228, 122], vec![107, 69]], &[vec![242, 248], vec![179, 142]], &[vec![239, 233], vec![61, 189]], &[vec![235, 85], vec![192, 7]], &[vec![200, 90], vec![185, 178]], ], &[ (&[vec![28, 96], vec![0, 11]], 2), (&[vec![2, 43], vec![64, 233]], 2), (&[vec![20, 33], vec![14, 10]], 2), (&[vec![223, 84], vec![7, 22]], 2), (&[vec![43, 33], vec![131, 6]], 2), (&[vec![6, 233], vec![45, 89]], 2), (&[vec![65, 26], vec![6, 146]], 2), (&[vec![71, 80], vec![68, 88]], 2), (&[vec![9, 85], vec![186, 55]], 2), (&[vec![96, 254], vec![9, 37]], 2), ], ( &[vec![127, 243], vec![125, 130]], Some(&[vec![127, 243], vec![134, 100]]), ), ); } malachite-base-0.4.16/tests/vecs/random/random_vecs_fixed_length_m_inputs.rs000064400000000000000000000134751046102023000254530ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use core::hash::Hash; use malachite_base::num::random::{random_primitive_ints, random_unsigned_range}; use malachite_base::random::{Seed, EXAMPLE_SEED}; use malachite_base::test_util::vecs::random::random_vecs_helper_helper; use malachite_base::vecs::random::{ random_vecs_fixed_length_2_inputs, random_vecs_fixed_length_from_single, }; use std::fmt::Debug; fn random_vecs_fixed_length_2_inputs_helper< T: Clone + Debug + Eq + Hash + Ord, I: Clone + Iterator, J: Clone + Iterator, >( xs_gen: &dyn Fn(Seed) -> I, ys_gen: &dyn Fn(Seed) -> J, output_to_input_map: &[usize], expected_values: &[&[T]], expected_common_values: &[(&[T], usize)], expected_median: (&[T], Option<&[T]>), ) { random_vecs_helper_helper( random_vecs_fixed_length_2_inputs(EXAMPLE_SEED, xs_gen, ys_gen, output_to_input_map), expected_values, expected_common_values, expected_median, ); } #[test] fn test_random_vecs_fixed_length_2_inputs() { random_vecs_fixed_length_2_inputs_helper( &random_primitive_ints::, &|seed| random_unsigned_range(seed, 0, 10), &[0, 0, 1], &[ &[85, 11, 2], &[136, 200, 6], &[235, 134, 8], &[203, 223, 6], &[38, 235, 8], &[217, 177, 2], &[162, 32, 4], &[166, 234, 1], &[30, 218, 2], &[90, 106, 7], &[9, 216, 5], &[204, 151, 4], &[213, 97, 8], &[253, 78, 8], &[91, 39, 4], &[191, 175, 4], &[170, 232, 3], &[233, 2, 5], &[35, 22, 6], &[217, 198, 7], ], &[ (&[156, 162, 3], 11), (&[248, 1, 7], 10), (&[178, 121, 1], 10), (&[36, 97, 6], 9), (&[46, 27, 2], 9), (&[64, 75, 6], 9), (&[135, 80, 5], 9), (&[215, 11, 3], 9), (&[39, 178, 7], 9), (&[75, 164, 6], 9), ], (&[127, 197, 7], None), ); random_vecs_fixed_length_2_inputs_helper( &|seed| random_vecs_fixed_length_from_single(2, random_primitive_ints::(seed)), &|seed| random_vecs_fixed_length_from_single(3, random_primitive_ints::(seed)), &[0, 1, 0], &[ &[vec![85, 11], vec![98, 168, 198], vec![136, 200]], &[vec![235, 134], vec![40, 20, 252], vec![203, 223]], &[vec![38, 235], vec![47, 87, 132], vec![217, 177]], &[vec![162, 32], vec![72, 77, 63], vec![166, 234]], &[vec![30, 218], vec![91, 108, 127], vec![90, 106]], &[vec![9, 216], vec![53, 141, 84], vec![204, 151]], &[vec![213, 97], vec![18, 10, 112], vec![253, 78]], &[vec![91, 39], vec![154, 104, 53], vec![191, 175]], &[vec![170, 232], vec![75, 238, 149], vec![233, 2]], &[vec![35, 22], vec![190, 51, 147], vec![217, 198]], &[vec![114, 17], vec![100, 114, 140], vec![32, 173]], &[vec![114, 65], vec![2, 63, 189], vec![121, 222]], &[vec![173, 25], vec![222, 67, 119], vec![144, 148]], &[vec![79, 115], vec![0, 223, 5], vec![52, 73]], &[vec![69, 137], vec![236, 232, 50], vec![91, 153]], &[vec![178, 112], vec![44, 241, 21], vec![34, 95]], &[vec![106, 167], vec![22, 94, 27], vec![197, 130]], &[vec![168, 122], vec![128, 220, 25], vec![207, 172]], &[vec![177, 86], vec![251, 243, 50], vec![150, 221]], &[vec![218, 101], vec![137, 235, 46], vec![115, 74]], ], &[ (&[vec![8, 24], vec![0, 54, 59], vec![5, 3]], 1), (&[vec![8, 72], vec![6, 5, 9], vec![11, 57]], 1), (&[vec![80, 9], vec![84, 9, 10], vec![9, 5]], 1), (&[vec![86, 2], vec![2, 0, 27], vec![49, 4]], 1), (&[vec![0, 2], vec![207, 31, 7], vec![92, 5]], 1), (&[vec![1, 15], vec![51, 5, 47], vec![12, 5]], 1), (&[vec![1, 25], vec![70, 65, 7], vec![3, 66]], 1), (&[vec![1, 72], vec![8, 49, 246], vec![2, 1]], 1), (&[vec![1, 82], vec![86, 3, 70], vec![6, 26]], 1), (&[vec![1, 85], vec![3, 5, 53], vec![14, 92]], 1), ], ( &[vec![128, 20], vec![252, 3, 74], vec![108, 132]], Some(&[vec![128, 21], vec![6, 87, 236], vec![223, 197]]), ), ); } #[test] #[should_panic] fn random_vecs_fixed_length_2_inputs_fail_1() { random_vecs_fixed_length_2_inputs( EXAMPLE_SEED, &|seed| random_unsigned_range::(seed, 0, 10), &|seed| random_unsigned_range(seed, 0, 5), &[], ); } #[test] #[should_panic] fn random_vecs_fixed_length_2_inputs_fail_2() { random_vecs_fixed_length_2_inputs( EXAMPLE_SEED, &|seed| random_unsigned_range::(seed, 0, 10), &|seed| random_unsigned_range(seed, 0, 5), &[0], ); } #[test] #[should_panic] fn random_vecs_fixed_length_2_inputs_fail_3() { random_vecs_fixed_length_2_inputs( EXAMPLE_SEED, &|seed| random_unsigned_range::(seed, 0, 10), &|seed| random_unsigned_range(seed, 0, 5), &[1], ); } #[test] #[should_panic] fn random_vecs_fixed_length_2_inputs_fail_4() { random_vecs_fixed_length_2_inputs( EXAMPLE_SEED, &|seed| random_unsigned_range::(seed, 0, 10), &|seed| random_unsigned_range(seed, 0, 5), &[0, 1, 2], ); } malachite-base-0.4.16/tests/vecs/random/random_vecs_from_length_iterator.rs000064400000000000000000000100531046102023000252770ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use core::hash::Hash; use malachite_base::bools::random::random_bools; use malachite_base::num::random::geometric::geometric_random_unsigneds; use malachite_base::num::random::random_primitive_ints; use malachite_base::random::{Seed, EXAMPLE_SEED}; use malachite_base::test_util::vecs::random::random_vecs_helper_helper; use malachite_base::vecs::random::random_vecs_from_length_iterator; use malachite_base::vecs::random_values_from_vec; use std::fmt::Debug; fn random_vecs_from_length_iterator_helper< T: Clone + Debug + Eq + Hash + Ord, I: Clone + Iterator, J: Clone + Iterator, >( lengths_gen: &dyn Fn(Seed) -> I, xs_gen: &dyn Fn(Seed) -> J, expected_values: &[&[T]], expected_common_values: &[(&[T], usize)], expected_median: (&[T], Option<&[T]>), ) { random_vecs_helper_helper( random_vecs_from_length_iterator(EXAMPLE_SEED, lengths_gen, xs_gen), expected_values, expected_common_values, expected_median, ); } #[test] fn test_random_vecs_from_length_iterator() { random_vecs_from_length_iterator_helper( &|seed| random_values_from_vec(seed, vec![0, 2, 4]), &random_bools, &[ &[true, false], &[true, false, true, false], &[true, false], &[true, true, false, true], &[false, false, false, false], &[false, false], &[], &[false, true], &[], &[false, false, false, true], &[false, false, false, true], &[false, false], &[true, true, true, true], &[false, true], &[false, true, true, true], &[false, true, true, false], &[false, false, false, true], &[], &[true, true, false, true], &[], ], &[ (&[], 333820), (&[true, false], 83553), (&[false, false], 83348), (&[false, true], 83319), (&[true, true], 82905), (&[true, true, true, false], 21126), (&[false, false, false, true], 20940), (&[false, false, true, false], 20931), (&[true, true, false, true], 20925), (&[true, false, false, false], 20899), ], (&[false, false, true, true], None), ); random_vecs_from_length_iterator_helper( &|seed| geometric_random_unsigneds::(seed, 2, 1).map(|x| x << 1), &random_primitive_ints::, &[ &[85, 11, 136, 200, 235, 134, 203, 223, 38, 235, 217, 177], &[162, 32], &[166, 234, 30, 218, 90, 106, 9, 216, 204, 151, 213, 97, 253, 78, 91, 39], &[191, 175], &[ 170, 232, 233, 2, 35, 22, 217, 198, 114, 17, 32, 173, 114, 65, 121, 222, 173, 25, 144, 148, 79, 115, 52, 73, 69, 137, 91, 153, ], &[], &[178, 112, 34, 95, 106, 167, 197, 130, 168, 122], &[207, 172, 177, 86, 150, 221, 218, 101], &[115, 74], &[], &[9, 123, 109, 52, 201, 159, 247, 250, 48, 133, 235, 196], &[40, 97, 104, 68], &[], &[], &[190, 216], &[7, 216, 157, 43, 43, 112], &[], &[217, 24], &[], &[11, 103], ], &[ (&[], 333981), (&[198, 47], 13), (&[203, 121], 13), (&[77, 29], 12), (&[97, 58], 12), (&[174, 43], 12), (&[80, 107], 12), (&[100, 118], 12), (&[176, 218], 12), (&[203, 110], 12), ], (&[63, 135], None), ); } malachite-base-0.4.16/tests/vecs/random/random_vecs_length_inclusive_range.rs000064400000000000000000000124151046102023000256040ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use core::hash::Hash; use malachite_base::chars::random::random_char_inclusive_range; use malachite_base::num::random::geometric::geometric_random_unsigneds; use malachite_base::num::random::random_primitive_ints; use malachite_base::random::{Seed, EXAMPLE_SEED}; use malachite_base::test_util::vecs::random::random_vecs_helper_helper; use malachite_base::tuples::random::random_units; use malachite_base::vecs::random::random_vecs_length_inclusive_range; use std::fmt::Debug; fn random_vecs_length_inclusive_range_helper< T: Clone + Debug + Eq + Hash + Ord, I: Clone + Iterator, >( a: u64, b: u64, xs_gen: &dyn Fn(Seed) -> I, expected_values: &[&[T]], expected_common_values: &[(&[T], usize)], expected_median: (&[T], Option<&[T]>), ) { random_vecs_helper_helper( random_vecs_length_inclusive_range(EXAMPLE_SEED, a, b, xs_gen), expected_values, expected_common_values, expected_median, ); } #[test] fn test_random_vecs_length_inclusive_range() { random_vecs_length_inclusive_range_helper( 2, 3, &|_| random_units(), &[ &[(), (), ()], &[(), ()], &[(), (), ()], &[(), (), ()], &[(), ()], &[(), (), ()], &[(), (), ()], &[(), ()], &[(), (), ()], &[(), (), ()], &[(), ()], &[(), (), ()], &[(), ()], &[(), (), ()], &[(), (), ()], &[(), ()], &[(), ()], &[(), ()], &[(), (), ()], &[(), ()], ], &[(&[(), (), ()], 500363), (&[(), ()], 499637)], (&[(), (), ()], None), ); random_vecs_length_inclusive_range_helper( 2, 3, &random_primitive_ints::, &[ &[85, 11, 136], &[200, 235], &[134, 203, 223], &[38, 235, 217], &[177, 162], &[32, 166, 234], &[30, 218, 90], &[106, 9], &[216, 204, 151], &[213, 97, 253], &[78, 91], &[39, 191, 175], &[170, 232], &[233, 2, 35], &[22, 217, 198], &[114, 17], &[32, 173], &[114, 65], &[121, 222, 173], &[25, 144], ], &[ (&[234, 192], 23), (&[0, 40], 19), (&[68, 88], 19), (&[188, 21], 19), (&[215, 22], 19), (&[221, 92], 19), (&[255, 26], 19), (&[34, 253], 19), (&[61, 159], 19), (&[155, 140], 19), ], (&[128, 5, 208], Some(&[128, 5, 239])), ); random_vecs_length_inclusive_range_helper( 2, 3, &|seed| geometric_random_unsigneds::(seed, 2, 1), &[ &[5, 0, 0], &[1, 1], &[1, 4, 2], &[4, 6, 2], &[2, 0], &[1, 9, 13], &[0, 0, 2], &[0, 7], &[4, 6, 7], &[6, 0, 0], &[0, 1], &[3, 5, 1], &[2, 1], &[0, 0, 1], &[4, 2, 0], &[12, 0], &[0, 2], &[3, 1], &[1, 1, 2], &[3, 3], ], &[ (&[0, 0], 55357), (&[0, 1], 37179), (&[1, 0], 37106), (&[0, 2], 24784), (&[2, 0], 24772), (&[1, 1], 24686), (&[0, 0, 0], 18703), (&[3, 0], 16656), (&[2, 1], 16622), (&[1, 2], 16275), ], (&[1, 3], None), ); random_vecs_length_inclusive_range_helper( 2, 3, &|seed| random_char_inclusive_range(seed, 'a', 'z'), &[ &['v', 'c', 'q'], &['i', 'e'], &['p', 'g', 's'], &['n', 't', 'm'], &['z', 'o'], &['m', 'f', 'k'], &['q', 'y', 'u'], &['k', 'x'], &['h', 'u', 'n'], &['n', 'j', 'n'], &['j', 'a'], &['w', 'z', 'l'], &['w', 'b'], &['l', 'u', 'n'], &['e', 'l', 'v'], &['k', 'u'], &['h', 'c'], &['y', 'i'], &['m', 'r', 'm'], &['y', 's'], ], &[ (&['w', 'o'], 822), (&['f', 's'], 814), (&['w', 'u'], 810), (&['g', 'c'], 806), (&['w', 'f'], 806), (&['m', 'z'], 805), (&['q', 'k'], 805), (&['i', 'b'], 802), (&['u', 'k'], 800), (&['h', 'p'], 798), ], (&['m', 'z', 'w'], None), ); } #[test] #[should_panic] fn random_vecs_length_inclusive_range_fail() { random_vecs_length_inclusive_range(EXAMPLE_SEED, 2, 1, &random_primitive_ints::); } malachite-base-0.4.16/tests/vecs/random/random_vecs_length_range.rs000064400000000000000000000122511046102023000235210ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use core::hash::Hash; use malachite_base::chars::random::random_char_inclusive_range; use malachite_base::num::random::geometric::geometric_random_unsigneds; use malachite_base::num::random::random_primitive_ints; use malachite_base::random::{Seed, EXAMPLE_SEED}; use malachite_base::test_util::vecs::random::random_vecs_helper_helper; use malachite_base::tuples::random::random_units; use malachite_base::vecs::random::random_vecs_length_range; use std::fmt::Debug; fn random_vecs_length_range_helper< T: Clone + Debug + Eq + Hash + Ord, I: Clone + Iterator, >( a: u64, b: u64, xs_gen: &dyn Fn(Seed) -> I, expected_values: &[&[T]], expected_common_values: &[(&[T], usize)], expected_median: (&[T], Option<&[T]>), ) { random_vecs_helper_helper( random_vecs_length_range(EXAMPLE_SEED, a, b, xs_gen), expected_values, expected_common_values, expected_median, ); } #[test] fn test_random_vecs_length_range() { random_vecs_length_range_helper( 2, 4, &|_| random_units(), &[ &[(), (), ()], &[(), ()], &[(), (), ()], &[(), (), ()], &[(), ()], &[(), (), ()], &[(), (), ()], &[(), ()], &[(), (), ()], &[(), (), ()], &[(), ()], &[(), (), ()], &[(), ()], &[(), (), ()], &[(), (), ()], &[(), ()], &[(), ()], &[(), ()], &[(), (), ()], &[(), ()], ], &[(&[(), (), ()], 500363), (&[(), ()], 499637)], (&[(), (), ()], None), ); random_vecs_length_range_helper( 2, 4, &random_primitive_ints::, &[ &[85, 11, 136], &[200, 235], &[134, 203, 223], &[38, 235, 217], &[177, 162], &[32, 166, 234], &[30, 218, 90], &[106, 9], &[216, 204, 151], &[213, 97, 253], &[78, 91], &[39, 191, 175], &[170, 232], &[233, 2, 35], &[22, 217, 198], &[114, 17], &[32, 173], &[114, 65], &[121, 222, 173], &[25, 144], ], &[ (&[234, 192], 23), (&[0, 40], 19), (&[68, 88], 19), (&[188, 21], 19), (&[215, 22], 19), (&[221, 92], 19), (&[255, 26], 19), (&[34, 253], 19), (&[61, 159], 19), (&[155, 140], 19), ], (&[128, 5, 208], Some(&[128, 5, 239])), ); random_vecs_length_range_helper( 2, 4, &|seed| geometric_random_unsigneds::(seed, 2, 1), &[ &[5, 0, 0], &[1, 1], &[1, 4, 2], &[4, 6, 2], &[2, 0], &[1, 9, 13], &[0, 0, 2], &[0, 7], &[4, 6, 7], &[6, 0, 0], &[0, 1], &[3, 5, 1], &[2, 1], &[0, 0, 1], &[4, 2, 0], &[12, 0], &[0, 2], &[3, 1], &[1, 1, 2], &[3, 3], ], &[ (&[0, 0], 55357), (&[0, 1], 37179), (&[1, 0], 37106), (&[0, 2], 24784), (&[2, 0], 24772), (&[1, 1], 24686), (&[0, 0, 0], 18703), (&[3, 0], 16656), (&[2, 1], 16622), (&[1, 2], 16275), ], (&[1, 3], None), ); random_vecs_length_range_helper( 2, 4, &|seed| random_char_inclusive_range(seed, 'a', 'z'), &[ &['v', 'c', 'q'], &['i', 'e'], &['p', 'g', 's'], &['n', 't', 'm'], &['z', 'o'], &['m', 'f', 'k'], &['q', 'y', 'u'], &['k', 'x'], &['h', 'u', 'n'], &['n', 'j', 'n'], &['j', 'a'], &['w', 'z', 'l'], &['w', 'b'], &['l', 'u', 'n'], &['e', 'l', 'v'], &['k', 'u'], &['h', 'c'], &['y', 'i'], &['m', 'r', 'm'], &['y', 's'], ], &[ (&['w', 'o'], 822), (&['f', 's'], 814), (&['w', 'u'], 810), (&['g', 'c'], 806), (&['w', 'f'], 806), (&['m', 'z'], 805), (&['q', 'k'], 805), (&['i', 'b'], 802), (&['u', 'k'], 800), (&['h', 'p'], 798), ], (&['m', 'z', 'w'], None), ); } #[test] #[should_panic] fn random_vecs_length_range_fail() { random_vecs_length_range(EXAMPLE_SEED, 2, 2, &random_primitive_ints::); } malachite-base-0.4.16/tests/vecs/random/random_vecs_min_length.rs000064400000000000000000000343501046102023000232140ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use core::hash::Hash; use malachite_base::chars::random::random_char_inclusive_range; use malachite_base::num::random::geometric::geometric_random_unsigneds; use malachite_base::num::random::random_primitive_ints; use malachite_base::random::{Seed, EXAMPLE_SEED}; use malachite_base::test_util::vecs::random::random_vecs_helper_helper; use malachite_base::tuples::random::random_units; use malachite_base::vecs::random::random_vecs_min_length; use std::fmt::Debug; fn random_vecs_min_length_helper< T: Clone + Debug + Eq + Hash + Ord, I: Clone + Iterator, >( min_length: u64, xs_gen: &dyn Fn(Seed) -> I, mean_length_numerator: u64, mean_length_denominator: u64, expected_values: &[&[T]], expected_common_values: &[(&[T], usize)], expected_median: (&[T], Option<&[T]>), ) { random_vecs_helper_helper( random_vecs_min_length( EXAMPLE_SEED, min_length, xs_gen, mean_length_numerator, mean_length_denominator, ), expected_values, expected_common_values, expected_median, ); } #[test] fn test_random_vecs_min_length() { random_vecs_min_length_helper( 0, &|_| random_units(), 4, 1, &[ &[], &[(), (), (), (), (), (), (), (), (), (), (), (), (), ()], &[(), (), (), ()], &[(), (), (), ()], &[()], &[], &[(), (), (), (), ()], &[(), ()], &[(), (), (), ()], &[], &[(), (), (), (), (), ()], &[], &[], &[(), (), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), ()], &[], &[(), (), ()], &[], &[(), (), (), (), ()], &[(), (), (), (), (), (), (), (), ()], ], &[ (&[], 199913), (&[()], 160173), (&[(), ()], 128173), (&[(), (), ()], 102460), (&[(), (), (), ()], 81463), (&[(), (), (), (), ()], 65695), (&[(), (), (), (), (), ()], 52495), (&[(), (), (), (), (), (), ()], 41943), (&[(), (), (), (), (), (), (), ()], 33396), (&[(), (), (), (), (), (), (), (), ()], 27035), ], (&[(), (), ()], None), ); random_vecs_min_length_helper( 3, &|_| random_units(), 7, 1, &[ &[(), (), ()], &[(), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), ()], &[(), (), (), (), (), (), ()], &[(), (), (), ()], &[(), (), ()], &[(), (), (), (), (), (), (), ()], &[(), (), (), (), ()], &[(), (), (), (), (), (), ()], &[(), (), ()], &[(), (), (), (), (), (), (), (), ()], &[(), (), ()], &[(), (), ()], &[(), (), (), (), (), (), (), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), ()], &[(), (), ()], &[(), (), (), (), (), ()], &[(), (), ()], &[(), (), (), (), (), (), (), ()], &[(), (), (), (), (), (), (), (), (), (), (), ()], ], &[ (&[(), (), ()], 199913), (&[(), (), (), ()], 160173), (&[(), (), (), (), ()], 128173), (&[(), (), (), (), (), ()], 102460), (&[(), (), (), (), (), (), ()], 81463), (&[(), (), (), (), (), (), (), ()], 65695), (&[(), (), (), (), (), (), (), (), ()], 52495), (&[(), (), (), (), (), (), (), (), (), ()], 41943), (&[(), (), (), (), (), (), (), (), (), (), ()], 33396), (&[(), (), (), (), (), (), (), (), (), (), (), ()], 27035), ], (&[(), (), (), (), (), ()], None), ); random_vecs_min_length_helper( 0, &random_primitive_ints::, 4, 1, &[ &[], &[85, 11, 136, 200, 235, 134, 203, 223, 38, 235, 217, 177, 162, 32], &[166, 234, 30, 218], &[90, 106, 9, 216], &[204], &[], &[151, 213, 97, 253, 78], &[91, 39], &[191, 175, 170, 232], &[], &[233, 2, 35, 22, 217, 198], &[], &[], &[114, 17, 32, 173, 114, 65, 121, 222, 173, 25, 144], &[148, 79, 115, 52, 73, 69, 137, 91], &[], &[153, 178, 112], &[], &[34, 95, 106, 167, 197], &[130, 168, 122, 207, 172, 177, 86, 150, 221], ], &[ (&[], 199913), (&[146], 693), (&[26], 692), (&[185], 688), (&[58], 683), (&[196], 683), (&[81], 678), (&[229], 675), (&[192], 673), (&[233], 673), ], (&[96], None), ); random_vecs_min_length_helper( 3, &random_primitive_ints::, 7, 1, &[ &[85, 11, 136], &[200, 235, 134, 203, 223, 38, 235, 217, 177, 162, 32, 166, 234, 30, 218, 90, 106], &[9, 216, 204, 151, 213, 97, 253], &[78, 91, 39, 191, 175, 170, 232], &[233, 2, 35, 22], &[217, 198, 114], &[17, 32, 173, 114, 65, 121, 222, 173], &[25, 144, 148, 79, 115], &[52, 73, 69, 137, 91, 153, 178], &[112, 34, 95], &[106, 167, 197, 130, 168, 122, 207, 172, 177], &[86, 150, 221], &[218, 101, 115], &[74, 9, 123, 109, 52, 201, 159, 247, 250, 48, 133, 235, 196, 40], &[97, 104, 68, 190, 216, 7, 216, 157, 43, 43, 112], &[217, 24, 11], &[103, 211, 84, 135, 55, 29], &[206, 89, 65], &[191, 51, 9, 79, 148, 34, 22, 22], &[62, 3, 114, 118, 20, 47, 194, 50, 32, 120, 176, 166], ], &[ (&[65, 71, 68], 3), (&[34, 39, 234], 3), (&[207, 218, 62], 3), (&[89, 175, 228], 3), (&[198, 166, 242], 3), (&[2, 94, 4], 2), (&[3, 91, 9], 2), (&[6, 3, 61], 2), (&[0, 18, 20], 2), (&[1, 48, 93], 2), ], (&[128, 11, 100, 4, 101, 167, 125], Some(&[128, 11, 104])), ); random_vecs_min_length_helper( 0, &|seed| geometric_random_unsigneds::(seed, 2, 1), 4, 1, &[ &[], &[5, 0, 0, 1, 1, 1, 4, 2, 4, 6, 2, 2, 0, 1], &[9, 13, 0, 0], &[2, 0, 7, 4], &[6], &[], &[7, 6, 0, 0, 0], &[1, 3], &[5, 1, 2, 1], &[], &[0, 0, 1, 4, 2, 0], &[], &[], &[12, 0, 0, 2, 3, 1, 1, 1, 2, 3, 3], &[9, 1, 0, 2, 1, 11, 1, 0], &[], &[1, 6, 0], &[], &[3, 18, 3, 3, 0], &[5, 1, 2, 5, 0, 0, 2, 3, 1], ], &[ (&[], 199913), (&[0], 53462), (&[1], 35352), (&[2], 23512), (&[3], 16118), (&[0, 0], 14371), (&[4], 10594), (&[0, 1], 9566), (&[1, 0], 9409), (&[5], 7157), ], (&[1], None), ); random_vecs_min_length_helper( 3, &|seed| geometric_random_unsigneds::(seed, 2, 1), 7, 1, &[ &[5, 0, 0], &[1, 1, 1, 4, 2, 4, 6, 2, 2, 0, 1, 9, 13, 0, 0, 2, 0], &[7, 4, 6, 7, 6, 0, 0], &[0, 1, 3, 5, 1, 2, 1], &[0, 0, 1, 4], &[2, 0, 12], &[0, 0, 2, 3, 1, 1, 1, 2], &[3, 3, 9, 1, 0], &[2, 1, 11, 1, 0, 1, 6], &[0, 3, 18], &[3, 3, 0, 5, 1, 2, 5, 0, 0], &[2, 3, 1], &[0, 2, 1], &[2, 3, 1, 3, 3, 0, 0, 7, 2, 0, 0, 4, 2, 1], &[0, 3, 1, 4, 2, 2, 1, 5, 0, 2, 0], &[2, 0, 0], &[1, 4, 1, 3, 3, 1], &[0, 0, 0], &[1, 4, 2, 1, 1, 0, 1, 0], &[0, 0, 1, 0, 2, 0, 7, 0, 0, 0, 2, 12], ], &[ (&[0, 0, 0], 7500), (&[1, 0, 0], 5048), (&[0, 0, 1], 4956), (&[0, 1, 0], 4876), (&[0, 0, 2], 3336), (&[0, 2, 0], 3320), (&[1, 1, 0], 3305), (&[2, 0, 0], 3303), (&[0, 1, 1], 3242), (&[1, 0, 1], 3239), ], ( &[1, 3, 1, 1, 4, 0, 2, 3], Some(&[1, 3, 1, 1, 4, 0, 4, 0, 0]), ), ); random_vecs_min_length_helper( 0, &random_primitive_ints::, 1, 4, &[ &[], &[], &[85], &[11], &[136, 200], &[], &[], &[], &[], &[], &[], &[], &[235, 134], &[203], &[], &[223, 38], &[], &[], &[], &[], ], &[ (&[], 800023), (&[8], 704), (&[162], 691), (&[81], 690), (&[211], 690), (&[108], 688), (&[235], 688), (&[35], 687), (&[65], 682), (&[208], 679), ], (&[], None), ); random_vecs_min_length_helper( 3, &random_primitive_ints::, 13, 4, &[ &[85, 11, 136], &[200, 235, 134], &[203, 223, 38, 235], &[217, 177, 162, 32], &[166, 234, 30, 218, 90], &[106, 9, 216], &[204, 151, 213], &[97, 253, 78], &[91, 39, 191], &[175, 170, 232], &[233, 2, 35], &[22, 217, 198], &[114, 17, 32, 173, 114], &[65, 121, 222, 173], &[25, 144, 148], &[79, 115, 52, 73, 69], &[137, 91, 153], &[178, 112, 34], &[95, 106, 167], &[197, 130, 168], ], &[ (&[34, 248, 94], 4), (&[155, 89, 108], 4), (&[232, 167, 146], 4), (&[255, 244, 186], 4), (&[0, 70, 96], 3), (&[18, 1, 93], 3), (&[30, 0, 90], 3), (&[50, 3, 37], 3), (&[82, 1, 99], 3), (&[9, 42, 49], 3), ], (&[127, 228, 182], Some(&[127, 228, 193])), ); random_vecs_min_length_helper( 0, &|seed| random_char_inclusive_range(seed, 'a', 'z'), 4, 1, &[ &[], &['v', 'c', 'q', 'i', 'e', 'p', 'g', 's', 'n', 't', 'm', 'z', 'o', 'm'], &['f', 'k', 'q', 'y'], &['u', 'k', 'x', 'h'], &['u'], &[], &['n', 'n', 'j', 'n', 'j'], &['a', 'w'], &['z', 'l', 'w', 'b'], &[], &['l', 'u', 'n', 'e', 'l', 'v'], &[], &[], &['k', 'u', 'h', 'c', 'y', 'i', 'm', 'r', 'm', 'y', 's'], &['l', 'e', 'a', 's', 'w', 'k', 'o', 'b'], &[], &['k', 'w', 'g'], &[], &['d', 'q', 'e', 'f', 'u'], &['z', 'r', 'g', 'j', 'k', 'r', 's', 'y', 'n'], ], &[ (&[], 199913), (&['o'], 6313), (&['y'], 6262), (&['q'], 6261), (&['j'], 6245), (&['p'], 6244), (&['g'], 6219), (&['x'], 6215), (&['e'], 6200), (&['t'], 6188), ], (&['j', 's', 'z'], None), ); random_vecs_min_length_helper( 3, &|seed| random_char_inclusive_range(seed, 'a', 'z'), 7, 1, &[ &['v', 'c', 'q'], &['i', 'e', 'p', 'g', 's', 'n', 't', 'm', 'z', 'o', 'm', 'f', 'k', 'q', 'y', 'u', 'k'], &['x', 'h', 'u', 'n', 'n', 'j', 'n'], &['j', 'a', 'w', 'z', 'l', 'w', 'b'], &['l', 'u', 'n', 'e'], &['l', 'v', 'k'], &['u', 'h', 'c', 'y', 'i', 'm', 'r', 'm'], &['y', 's', 'l', 'e', 'a'], &['s', 'w', 'k', 'o', 'b', 'k', 'w'], &['g', 'd', 'q'], &['e', 'f', 'u', 'z', 'r', 'g', 'j', 'k', 'r'], &['s', 'y', 'n'], &['f', 't', 's'], &['f', 'e', 's', 'p', 'j', 'n', 'h', 'n', 'r', 'f', 'i', 'u', 'k', 'p'], &['p', 'g', 'l', 'd', 'l', 'l', 'z', 's', 'w', 'w', 'l'], &['w', 'z', 'j'], &['j', 'j', 'y', 'g', 'e', 'z'], &['v', 'p', 'y'], &['u', 'q', 'l', 'h', 'r', 'r', 's', 'q'], &['b', 'n', 'e', 's', 'p', 'r', 'd', 'a', 'k', 'w', 'c', 'y'], ], &[ (&['b', 'c', 'j'], 25), (&['e', 'k', 'd'], 25), (&['a', 'x', 'n'], 24), (&['b', 'e', 'z'], 24), (&['c', 'c', 'b'], 24), (&['d', 'g', 'h'], 24), (&['g', 'l', 'i'], 24), (&['i', 'w', 'n'], 24), (&['j', 'd', 'w'], 24), (&['m', 'y', 'a'], 24), ], ( &['m', 'z', 'z', 'r', 'e', 'r'], Some(&['m', 'z', 'z', 'r', 'g', 'i']), ), ); } #[test] #[should_panic] fn random_vecs_min_length_fail_1() { random_vecs_min_length(EXAMPLE_SEED, 3, &random_primitive_ints::, 3, 1); } #[test] #[should_panic] fn random_vecs_min_length_fail_2() { random_vecs_min_length(EXAMPLE_SEED, 1, &random_primitive_ints::, 1, 0); } #[test] #[should_panic] fn random_vecs_min_length_fail_3() { random_vecs_min_length( EXAMPLE_SEED, 0, &random_primitive_ints::, u64::MAX, u64::MAX - 1, ); } malachite-base-0.4.16/tests/vecs/random_values_from_vec.rs000064400000000000000000000041071046102023000217440ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::nevers::Never; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::common_values_map::common_values_map_debug; use malachite_base::test_util::stats::median; use malachite_base::vecs::random_values_from_vec; #[test] fn test_random_values_from_vec() { let test = |vec: Vec, values: &[u32], common_values: &[(u32, usize)], actual_median: (u32, Option)| { let xs = random_values_from_vec(EXAMPLE_SEED, vec); let expected_values = xs.clone().take(20).collect_vec(); let expected_common_values = common_values_map_debug(1000000, 10, xs.clone()); let expected_median = median(xs.take(1000000)); assert_eq!( ( expected_values.as_slice(), expected_common_values.as_slice(), expected_median ), (values, common_values, actual_median) ); }; test(vec![5], &[5; 20], &[(5, 1000000)], (5, None)); test( vec![0, 1], &[1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0], &[(1, 500473), (0, 499527)], (1, None), ); test( vec![1, 1, 1, 10], &[1, 1, 10, 1, 10, 10, 1, 10, 1, 1, 1, 1, 1, 10, 1, 1, 1, 1, 1, 10], &[(1, 749985), (10, 250015)], (1, None), ); test( vec![2, 3, 5, 7, 11], &[3, 7, 3, 5, 11, 3, 5, 11, 2, 2, 5, 5, 2, 11, 2, 11, 5, 11, 5, 3], &[(2, 200420), (7, 200369), (11, 200347), (5, 199589), (3, 199275)], (5, None), ); } #[test] #[should_panic] fn random_values_from_vec_fail() { random_values_from_vec::(EXAMPLE_SEED, vec![]); } malachite-base-0.4.16/tests/vecs/random_vec_permutations.rs000064400000000000000000000077051046102023000221630ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::random::EXAMPLE_SEED; use malachite_base::test_util::stats::common_values_map::common_values_map; use malachite_base::test_util::stats::median; use malachite_base::vecs::random_vec_permutations; fn random_vec_permutations_helper( cs: &str, expected_values: &[&str], expected_common_values: &[(&str, usize)], expected_median: (&str, Option<&str>), ) { let ss = random_vec_permutations(EXAMPLE_SEED, cs.chars().collect_vec()) .map(|ds| ds.into_iter().collect()); let values = ss.clone().take(20).collect_vec(); let common_values = common_values_map(1000000, 10, ss.clone()); let (median_lo, median_hi) = median(ss.take(1000000)); assert_eq!( ( values.iter().map(String::as_str).collect_vec().as_slice(), common_values .iter() .map(|(s, f)| (s.as_str(), *f)) .collect_vec() .as_slice(), (median_lo.as_str(), median_hi.as_deref()) ), (expected_values, expected_common_values, expected_median) ); } #[test] fn test_random_vec_permutations() { random_vec_permutations_helper("", &[""; 20], &[("", 1000000)], ("", None)); random_vec_permutations_helper("a", &["a"; 20], &[("a", 1000000)], ("a", None)); random_vec_permutations_helper( "ab", &[ "ab", "ba", "ba", "ba", "ba", "ba", "ba", "ab", "ab", "ab", "ab", "ab", "ba", "ba", "ab", "ba", "ba", "ba", "ab", "ba", ], &[("ab", 500433), ("ba", 499567)], ("ab", None), ); random_vec_permutations_helper( "abc", &[ "acb", "bac", "bca", "bac", "bca", "acb", "acb", "cab", "acb", "bca", "cab", "bac", "abc", "acb", "cab", "cba", "bac", "bac", "cab", "cba", ], &[ ("acb", 167689), ("cba", 167200), ("cab", 166428), ("bca", 166332), ("bac", 166279), ("abc", 166072), ], ("bac", None), ); random_vec_permutations_helper( "abcd", &[ "cadb", "cbad", "cadb", "badc", "acdb", "cbad", "dabc", "dbca", "cdba", "cdab", "bacd", "cabd", "adbc", "cdab", "dcab", "abcd", "abcd", "dacb", "bcad", "adcb", ], &[ ("dabc", 41997), ("dbac", 41989), ("dcab", 41951), ("acbd", 41923), ("cdba", 41816), ("bcad", 41795), ("bdca", 41760), ("dacb", 41738), ("dbca", 41735), ("bdac", 41723), ], ("cabd", None), ); random_vec_permutations_helper( "abcdefghij", &[ "acjbhfdgie", "cbijehgfda", "fjageibdhc", "abcjefgdih", "gicjbfehda", "ahdjfciebg", "hfcdgeaibj", "gacdhjibfe", "cabejhdigf", "bicfdjhage", "jfhcgdbeai", "bifcedghja", "ifahdgebjc", "aefgicjhbd", "ebafcjhdgi", "eihjdcabgf", "ehiajdcfgb", "cgehadjibf", "hfcabdgije", "fjhiedgbac", ], &[ ("hieafgbdjc", 6), ("agdcihfjeb", 5), ("aigjfdehcb", 5), ("aijdhcefgb", 5), ("aijgcdbehf", 5), ("badjcigfhe", 5), ("bfhadgcjie", 5), ("bgjfdcheia", 5), ("bhfigadjec", 5), ("bjigahdfec", 5), ], ("fabdjchgie", Some("fabdjchieg")), ); } malachite-base-0.4.16/tests/vecs/vec_delete_left.rs000064400000000000000000000043651046102023000203440ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::test_util::generators::common::GenConfig; use malachite_base::test_util::generators::{ unsigned_vec_gen, unsigned_vec_unsigned_pair_gen_var_1, }; use malachite_base::vecs::vec_delete_left; #[test] fn test_vec_delete_left() { let test = |xs: &[u32], delete_size: usize, out: &[u32]| { let mut mut_xs = xs.to_vec(); vec_delete_left(&mut mut_xs, delete_size); assert_eq!(mut_xs, out); }; test(&[], 0, &[]); test(&[1, 2, 3, 4, 5], 0, &[1, 2, 3, 4, 5]); test(&[1, 2, 3, 4, 5], 3, &[4, 5]); test(&[1, 2, 3, 4, 5], 5, &[]); } #[test] #[should_panic] fn vec_delete_left_fail_1() { let mut xs: Vec = Vec::new(); vec_delete_left(&mut xs, 1); } #[test] #[should_panic] fn vec_delete_left_fail_2() { let mut xs: Vec = vec![1, 2, 3]; vec_delete_left(&mut xs, 4); } #[test] fn vec_delete_left_properties() { let mut config = GenConfig::new(); config.insert("mean_length_n", 32); config.insert("mean_length_d", 1); config.insert("mean_stripe_n", 16 << u8::LOG_WIDTH); config.insert("mean_stripe_d", 1); unsigned_vec_unsigned_pair_gen_var_1::().test_properties_with_config( &config, |(mut xs, amount)| { let old_xs = xs.clone(); vec_delete_left(&mut xs, amount); assert_eq!(xs == old_xs, amount == 0); assert_eq!(xs.is_empty(), amount == old_xs.len()); assert_eq!(xs.len(), old_xs.len() - amount); assert_eq!(&old_xs[amount..], xs); }, ); unsigned_vec_gen::().test_properties_with_config(&config, |mut xs| { let old_xs = xs.clone(); vec_delete_left(&mut xs, old_xs.len()); assert!(xs.is_empty()); let mut xs = old_xs.clone(); vec_delete_left(&mut xs, 0); assert_eq!(xs, old_xs); }); } malachite-base-0.4.16/tests/vecs/vec_from_str.rs000064400000000000000000000060711046102023000177170ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::nevers::Never; use malachite_base::options::option_from_str; use malachite_base::orderings::ordering_from_str; use malachite_base::vecs::{vec_from_str, vec_from_str_custom}; use std::cmp::Ordering::*; use std::fmt::Debug; use std::str::FromStr; #[allow(clippy::needless_pass_by_value)] fn vec_from_str_helper(s: &str, out: Option>) { assert_eq!(vec_from_str(s), out); } #[test] fn test_vec_from_str() { vec_from_str_helper::("[]", Some(vec![])); vec_from_str_helper::("[5]", Some(vec![5])); vec_from_str_helper::("[5, 6, 7]", Some(vec![5, 6, 7])); vec_from_str_helper::("[false, false, true]", Some(vec![false, false, true])); vec_from_str_helper::("[a, b]", Some(vec!["a".to_string(), "b".to_string()])); vec_from_str_helper::("[a, b]", Some(vec!["a".to_string(), " b".to_string()])); vec_from_str_helper::("[a , b]", Some(vec!["a ".to_string(), "b".to_string()])); vec_from_str_helper::("[a,, b]", Some(vec!["a,".to_string(), "b".to_string()])); vec_from_str_helper::("[a ,,b]", Some(vec!["a ,,b".to_string()])); vec_from_str_helper::("[a,b]", Some(vec!["a,b".to_string()])); vec_from_str_helper::("[", None); vec_from_str_helper::("", None); vec_from_str_helper::("abc", None); vec_from_str_helper::("[false, false, true", None); vec_from_str_helper::("[false, false, true]", None); vec_from_str_helper::("[false, false, true,]", None); vec_from_str_helper::("[false, false, true] ", None); vec_from_str_helper::("[false, false, true ]", None); vec_from_str_helper::("[false, false, rue]", None); } #[allow(clippy::needless_pass_by_value)] fn vec_from_str_custom_helper( f: &dyn Fn(&str) -> Option, s: &str, out: Option>, ) { assert_eq!(vec_from_str_custom(f, s), out); } #[test] fn test_vec_from_str_custom() { vec_from_str_custom_helper( &ordering_from_str, "[Less, Greater]", Some(vec![Less, Greater]), ); vec_from_str_custom_helper( &option_from_str, "[Some(false), None]", Some(vec![Some(false), None]), ); vec_from_str_custom_helper( &vec_from_str, "[[], [3], [2, 5]]", Some(vec![vec![], vec![3], vec![2, 5]]), ); vec_from_str_custom_helper(&option_from_str::, "[Some(fals), None]", None); vec_from_str_custom_helper(&vec_from_str::, "[[], [3], [2, 5,]]", None); vec_from_str_custom_helper(&vec_from_str::, "[[], 3, [2, 5]]", None); vec_from_str_custom_helper(&vec_from_str::, "[[], [3], [true]]", None); } malachite-base-0.4.16/tests/vecs/vec_pad_left.rs000064400000000000000000000050371046102023000176430ustar 00000000000000// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::test_util::generators::common::GenConfig; use malachite_base::test_util::generators::{ unsigned_pair_gen_var_2, unsigned_vec_unsigned_pair_gen, unsigned_vec_unsigned_unsigned_triple_gen_var_1, }; use malachite_base::vecs::{vec_delete_left, vec_pad_left}; #[test] fn test_vec_pad_left() { let test = |xs: &[u32], pad_size: usize, pad_value: u32, out: &[u32]| { let mut mut_xs = xs.to_vec(); vec_pad_left(&mut mut_xs, pad_size, pad_value); assert_eq!(mut_xs, out); }; test(&[], 3, 6, &[6, 6, 6]); test(&[1, 2, 3], 0, 10, &[1, 2, 3]); test(&[1, 2, 3], 5, 10, &[10, 10, 10, 10, 10, 1, 2, 3]); } #[test] fn vec_pad_left_properties() { let mut config = GenConfig::new(); config.insert("mean_length_n", 32); config.insert("mean_length_d", 1); config.insert("mean_stripe_n", 16 << u8::LOG_WIDTH); config.insert("mean_stripe_d", 1); config.insert("small_unsigned_length_n", 32); config.insert("small_unsigned_length_d", 1); unsigned_vec_unsigned_unsigned_triple_gen_var_1::().test_properties_with_config( &config, |(mut xs, pad_size, pad_value)| { let old_xs = xs.clone(); vec_pad_left(&mut xs, pad_size, pad_value); assert_eq!(xs == old_xs, pad_size == 0); assert_eq!(xs.len(), old_xs.len() + pad_size); assert!(xs[..pad_size].iter().all(|&x| x == pad_value)); assert_eq!(&xs[pad_size..], old_xs); vec_delete_left(&mut xs, pad_size); assert_eq!(xs, old_xs); }, ); unsigned_vec_unsigned_pair_gen::().test_properties_with_config( &config, |(mut xs, pad_value)| { let old_xs = xs.clone(); vec_pad_left(&mut xs, 0, pad_value); assert_eq!(xs, old_xs); }, ); unsigned_pair_gen_var_2::().test_properties_with_config( &config, |(pad_value, pad_size)| { let mut xs = Vec::new(); vec_pad_left(&mut xs, pad_size, pad_value); assert_eq!(xs, vec![pad_value; pad_size]); }, ); }