diff --git a/Cargo.lock b/Cargo.lock
index 3c31d49bd..1b0e454f4 100755
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4,21 +4,21 @@ version = 4
[[package]]
name = "ahash"
-version = "0.8.11"
+version = "0.8.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
+checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75"
dependencies = [
"cfg-if",
"once_cell",
"version_check",
- "zerocopy 0.7.35",
+ "zerocopy",
]
[[package]]
name = "aho-corasick"
-version = "1.1.3"
+version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
+checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
dependencies = [
"memchr",
]
@@ -31,9 +31,9 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
[[package]]
name = "anyhow"
-version = "1.0.100"
+version = "1.0.102"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61"
+checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
[[package]]
name = "approx"
@@ -56,7 +56,7 @@ dependencies = [
"paste",
"rand 0.9.2",
"rand_xoshiro",
- "thiserror 2.0.17",
+ "thiserror 2.0.18",
"web-time",
]
@@ -72,7 +72,7 @@ dependencies = [
"num-integer",
"num-traits",
"rand 0.9.2",
- "thiserror 2.0.17",
+ "thiserror 2.0.18",
]
[[package]]
@@ -87,15 +87,15 @@ dependencies = [
[[package]]
name = "autocfg"
-version = "1.4.0"
+version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
+checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
[[package]]
name = "bitflags"
-version = "2.9.0"
+version = "2.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
+checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af"
[[package]]
name = "block-buffer"
@@ -108,28 +108,28 @@ dependencies = [
[[package]]
name = "bumpalo"
-version = "3.17.0"
+version = "3.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf"
+checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb"
[[package]]
name = "bytemuck"
-version = "1.23.2"
+version = "1.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3995eaeebcdf32f91f980d360f78732ddc061097ab4e39991ae7a6ace9194677"
+checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec"
dependencies = [
"bytemuck_derive",
]
[[package]]
name = "bytemuck_derive"
-version = "1.10.1"
+version = "1.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4f154e572231cb6ba2bd1176980827e3d5dc04cc183a75dea38109fbdd672d29"
+checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.106",
+ "syn 2.0.117",
]
[[package]]
@@ -147,9 +147,9 @@ dependencies = [
"ahash",
"cached_proc_macro",
"cached_proc_macro_types",
- "hashbrown",
+ "hashbrown 0.15.5",
"once_cell",
- "thiserror 2.0.17",
+ "thiserror 2.0.18",
"web-time",
]
@@ -162,7 +162,7 @@ dependencies = [
"darling",
"proc-macro2",
"quote",
- "syn 2.0.106",
+ "syn 2.0.117",
]
[[package]]
@@ -173,18 +173,19 @@ checksum = "ade8366b8bd5ba243f0a58f036cc0ca8a2f069cff1a2351ef1cac6b083e16fc0"
[[package]]
name = "cc"
-version = "1.2.23"
+version = "1.2.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5f4ac86a9e5bc1e2b3449ab9d7d3a6a405e3d1bb28d7b9be8614f55846ae3766"
+checksum = "aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2"
dependencies = [
+ "find-msvc-tools",
"shlex",
]
[[package]]
name = "cfg-if"
-version = "1.0.0"
+version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "cpufeatures"
@@ -253,15 +254,15 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
[[package]]
name = "crunchy"
-version = "0.2.3"
+version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929"
+checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
[[package]]
name = "crypto-common"
-version = "0.1.6"
+version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
+checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a"
dependencies = [
"generic-array",
"typenum",
@@ -269,21 +270,21 @@ dependencies = [
[[package]]
name = "csv"
-version = "1.3.1"
+version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "acdc4883a9c96732e4733212c01447ebd805833b7275a73ca3ee080fd77afdaf"
+checksum = "52cd9d68cf7efc6ddfaaee42e7288d3a99d613d4b50f76ce9827ae0c6e14f938"
dependencies = [
"csv-core",
"itoa",
"ryu",
- "serde",
+ "serde_core",
]
[[package]]
name = "csv-core"
-version = "0.1.12"
+version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7d02f3b0da4c6504f86e9cd789d8dbafab48c2321be74e9987593de5a894d93d"
+checksum = "704a3c26996a80471189265814dbc2c257598b96b8a7feae2d31ace646bb9782"
dependencies = [
"memchr",
]
@@ -309,7 +310,7 @@ dependencies = [
"proc-macro2",
"quote",
"strsim",
- "syn 2.0.106",
+ "syn 2.0.117",
]
[[package]]
@@ -320,7 +321,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead"
dependencies = [
"darling_core",
"quote",
- "syn 2.0.106",
+ "syn 2.0.117",
]
[[package]]
@@ -331,9 +332,9 @@ checksum = "930c7171c8df9fb1782bdf9b918ed9ed2d33d1d22300abb754f9085bc48bf8e8"
[[package]]
name = "deranged"
-version = "0.4.1"
+version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28cfac68e08048ae1883171632c2aef3ebc555621ae56fbccce1cbf22dd7f058"
+checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c"
dependencies = [
"powerfmt",
]
@@ -351,7 +352,7 @@ dependencies = [
"num-traits",
"petgraph",
"serde",
- "thiserror 2.0.17",
+ "thiserror 2.0.18",
]
[[package]]
@@ -366,13 +367,20 @@ dependencies = [
[[package]]
name = "dyn-stack"
-version = "0.13.0"
+version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "490bd48eb68fffcfed519b4edbfd82c69cbe741d175b84f0e0cbe8c57cbe0bdd"
+checksum = "1c4713e43e2886ba72b8271aa66c93d722116acf7a75555cce11dcde84388fe8"
dependencies = [
"bytemuck",
+ "dyn-stack-macros",
]
+[[package]]
+name = "dyn-stack-macros"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e1d926b4d407d372f141f93bb444696142c29d32962ccbd3531117cf3aa0bfa9"
+
[[package]]
name = "either"
version = "1.15.0"
@@ -388,7 +396,7 @@ dependencies = [
"heck",
"proc-macro2",
"quote",
- "syn 2.0.106",
+ "syn 2.0.117",
]
[[package]]
@@ -417,7 +425,7 @@ checksum = "3bf679796c0322556351f287a51b49e48f7c4986e727b5dd78c972d30e2e16cc"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.106",
+ "syn 2.0.117",
]
[[package]]
@@ -428,7 +436,7 @@ checksum = "44f23cf4b44bfce11a86ace86f8a73ffdec849c9fd00a386a53d278bd9e81fb3"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.106",
+ "syn 2.0.117",
]
[[package]]
@@ -439,25 +447,31 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
name = "extendr-api"
-version = "0.7.1"
+version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "67505d96c7faa49d20e749dba7ba2447db52c40a788fd88cc2b6bef02c02277a"
+checksum = "ea54977c6e37236839ffcbc20b5dcea58aa32ae43fbef54a81e1011dc6b19061"
dependencies = [
+ "extendr-ffi",
"extendr-macros",
- "libR-sys",
"once_cell",
"paste",
]
+[[package]]
+name = "extendr-ffi"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c76777174a82bdb3e66872f580687d3d0143eed1df9b9cd72b321b9596a23ca7"
+
[[package]]
name = "extendr-macros"
-version = "0.7.1"
+version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "81b58838056f294411d0b2c35ac1a2b24c507d6828b75f2c1e74f00ee9b99267"
+checksum = "661cc4ae29de9c4dafe16cfcbda1dbb9f31bd2568f96ebad232cc1f9bcc8b04d"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.106",
+ "syn 2.0.117",
]
[[package]]
@@ -507,7 +521,7 @@ checksum = "2cc4b8cd876795d3b19ddfd59b03faa303c0b8adb9af6e188e81fc647c485bb9"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.106",
+ "syn 2.0.117",
]
[[package]]
@@ -528,6 +542,12 @@ dependencies = [
"reborrow",
]
+[[package]]
+name = "find-msvc-tools"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
+
[[package]]
name = "fixedbitset"
version = "0.5.7"
@@ -673,16 +693,17 @@ checksum = "5881e4c3c2433fe4905bb19cfd2b5d49d4248274862b68c27c33d9ba4e13f9ec"
[[package]]
name = "generator"
-version = "0.8.5"
+version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d18470a76cb7f8ff746cf1f7470914f900252ec36bbc40b569d74b1258446827"
+checksum = "52f04ae4152da20c76fe800fa48659201d5cf627c5149ca0b707b69d7eef6cf9"
dependencies = [
"cc",
"cfg-if",
"libc",
"log",
"rustversion",
- "windows",
+ "windows-link",
+ "windows-result",
]
[[package]]
@@ -697,25 +718,25 @@ dependencies = [
[[package]]
name = "getrandom"
-version = "0.2.15"
+version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
+checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
dependencies = [
"cfg-if",
"libc",
- "wasi 0.11.0+wasi-snapshot-preview1",
+ "wasi",
]
[[package]]
name = "getrandom"
-version = "0.3.2"
+version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0"
+checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
dependencies = [
"cfg-if",
"libc",
"r-efi",
- "wasi 0.14.2+wasi-0.2.4",
+ "wasip2",
]
[[package]]
@@ -810,33 +831,40 @@ checksum = "8babf46d4c1c9d92deac9f7be466f76dfc4482b6452fc5024b5e8daf6ffeb3ee"
[[package]]
name = "glam"
-version = "0.30.8"
+version = "0.30.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e12d847aeb25f41be4c0ec9587d624e9cd631bc007a8fd7ce3f5851e064c6460"
+checksum = "19fc433e8437a212d1b6f1e68c7824af3aed907da60afa994e7f542d18d12aa9"
[[package]]
name = "half"
-version = "2.5.0"
+version = "2.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7db2ff139bba50379da6aa0766b52fdcb62cb5b263009b09ed58ba604e14bbd1"
+checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b"
dependencies = [
"bytemuck",
"cfg-if",
"crunchy",
"num-traits",
+ "zerocopy",
]
[[package]]
name = "hashbrown"
-version = "0.15.2"
+version = "0.15.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
+checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
dependencies = [
"allocator-api2",
"equivalent",
"foldhash",
]
+[[package]]
+name = "hashbrown"
+version = "0.16.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
+
[[package]]
name = "heck"
version = "0.5.0"
@@ -845,9 +873,9 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "hermit-abi"
-version = "0.3.9"
+version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
+checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
[[package]]
name = "ident_case"
@@ -857,12 +885,12 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
[[package]]
name = "indexmap"
-version = "2.8.0"
+version = "2.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058"
+checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017"
dependencies = [
"equivalent",
- "hashbrown",
+ "hashbrown 0.16.1",
]
[[package]]
@@ -878,15 +906,15 @@ dependencies = [
[[package]]
name = "itoa"
-version = "1.0.15"
+version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
+checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2"
[[package]]
name = "js-sys"
-version = "0.3.77"
+version = "0.3.91"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f"
+checksum = "b49715b7073f385ba4bc528e5747d02e66cb39c6146efb66b781f131f0fb399c"
dependencies = [
"once_cell",
"wasm-bindgen",
@@ -898,39 +926,33 @@ version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
-[[package]]
-name = "libR-sys"
-version = "0.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "06ac9752bc1e83f5a354a62b9e81bd8db4468b1008e29f262441e7f0e91e6bb3"
-
[[package]]
name = "libc"
-version = "0.2.171"
+version = "0.2.183"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
+checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d"
[[package]]
name = "libloading"
-version = "0.8.6"
+version = "0.8.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34"
+checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55"
dependencies = [
"cfg-if",
- "windows-targets",
+ "windows-link",
]
[[package]]
name = "libm"
-version = "0.2.15"
+version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de"
+checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
[[package]]
name = "log"
-version = "0.4.27"
+version = "0.4.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
+checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
[[package]]
name = "loom"
@@ -956,9 +978,9 @@ dependencies = [
[[package]]
name = "matrixmultiply"
-version = "0.3.9"
+version = "0.3.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9380b911e3e96d10c1f415da0876389aaf1b56759054eeb0de7df940c456ba1a"
+checksum = "a06de3016e9fae57a36fd14dba131fccf49f74b40b7fbdb472f96e361ec71a08"
dependencies = [
"autocfg",
"rawpointer",
@@ -966,9 +988,9 @@ dependencies = [
[[package]]
name = "memchr"
-version = "2.7.4"
+version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
+checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
[[package]]
name = "nalgebra"
@@ -1009,7 +1031,7 @@ dependencies = [
"glam 0.27.0",
"glam 0.28.0",
"glam 0.29.3",
- "glam 0.30.8",
+ "glam 0.30.10",
"matrixmultiply",
"nalgebra-macros",
"num-complex",
@@ -1027,7 +1049,7 @@ checksum = "973e7178a678cfd059ccec50887658d482ce16b0aa9da3888ddeab5cd5eb4889"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.106",
+ "syn 2.0.117",
]
[[package]]
@@ -1145,7 +1167,7 @@ version = "0.50.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
dependencies = [
- "windows-sys 0.59.0",
+ "windows-sys 0.61.2",
]
[[package]]
@@ -1171,9 +1193,9 @@ dependencies = [
[[package]]
name = "num-conv"
-version = "0.1.0"
+version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
+checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050"
[[package]]
name = "num-integer"
@@ -1207,9 +1229,9 @@ dependencies = [
[[package]]
name = "num_cpus"
-version = "1.16.0"
+version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
+checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b"
dependencies = [
"hermit-abi",
"libc",
@@ -1229,20 +1251,19 @@ checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
[[package]]
name = "pest"
-version = "2.8.0"
+version = "2.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "198db74531d58c70a361c42201efde7e2591e976d518caf7662a47dc5720e7b6"
+checksum = "e0848c601009d37dfa3430c4666e147e49cdcf1b92ecd3e63657d8a5f19da662"
dependencies = [
"memchr",
- "thiserror 2.0.17",
"ucd-trie",
]
[[package]]
name = "pest_derive"
-version = "2.8.0"
+version = "2.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d725d9cfd79e87dccc9341a2ef39d1b6f6353d68c4b33c177febbe1a402c97c5"
+checksum = "11f486f1ea21e6c10ed15d5a7c77165d0ee443402f0780849d1768e7d9d6fe77"
dependencies = [
"pest",
"pest_generator",
@@ -1250,24 +1271,23 @@ dependencies = [
[[package]]
name = "pest_generator"
-version = "2.8.0"
+version = "2.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "db7d01726be8ab66ab32f9df467ae8b1148906685bbe75c82d1e65d7f5b3f841"
+checksum = "8040c4647b13b210a963c1ed407c1ff4fdfa01c31d6d2a098218702e6664f94f"
dependencies = [
"pest",
"pest_meta",
"proc-macro2",
"quote",
- "syn 2.0.106",
+ "syn 2.0.117",
]
[[package]]
name = "pest_meta"
-version = "2.8.0"
+version = "2.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f9f832470494906d1fca5329f8ab5791cc60beb230c74815dff541cbd2b5ca0"
+checksum = "89815c69d36021a140146f26659a81d6c2afa33d216d736dd4be5381a7362220"
dependencies = [
- "once_cell",
"pest",
"sha2",
]
@@ -1279,7 +1299,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455"
dependencies = [
"fixedbitset",
- "hashbrown",
+ "hashbrown 0.15.5",
"indexmap",
"serde",
]
@@ -1304,15 +1324,15 @@ dependencies = [
"serde",
"serde_json",
"statrs",
- "thiserror 2.0.17",
+ "thiserror 2.0.18",
"tracing",
]
[[package]]
name = "pin-project-lite"
-version = "0.2.16"
+version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
+checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
[[package]]
name = "pm_rs"
@@ -1351,15 +1371,15 @@ dependencies = [
[[package]]
name = "portable-atomic"
-version = "1.11.0"
+version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e"
+checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49"
[[package]]
name = "portable-atomic-util"
-version = "0.2.4"
+version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507"
+checksum = "7a9db96d7fa8782dd8c15ce32ffe8680bbd1e978a43bf51a34d39483540495f5"
dependencies = [
"portable-atomic",
]
@@ -1376,14 +1396,14 @@ version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
dependencies = [
- "zerocopy 0.8.24",
+ "zerocopy",
]
[[package]]
name = "private-gemm-x86"
-version = "0.1.18"
+version = "0.1.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b8138b380908e85071bdd6b2841a38b0858ef09848b754a15219d0b9ca90928"
+checksum = "0af8c3e5087969c323f667ccb4b789fa0954f5aa650550e38e81cf9108be21b5"
dependencies = [
"crossbeam",
"defer",
@@ -1397,9 +1417,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
-version = "1.0.101"
+version = "1.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de"
+checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
dependencies = [
"unicode-ident",
]
@@ -1433,9 +1453,9 @@ dependencies = [
[[package]]
name = "qd"
-version = "0.7.4"
+version = "0.7.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "73940173cf92cd24f3650f5f388946524026712a6ca170762340acf5fb3fde0f"
+checksum = "ff8bb755b6008c3b41bf8a0866c8dd4e1245a2f011ceaa22a13ee55c538493e2"
dependencies = [
"bytemuck",
"libm",
@@ -1445,18 +1465,18 @@ dependencies = [
[[package]]
name = "quote"
-version = "1.0.40"
+version = "1.0.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
+checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
dependencies = [
"proc-macro2",
]
[[package]]
name = "r-efi"
-version = "5.2.0"
+version = "5.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
+checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
[[package]]
name = "rand"
@@ -1476,7 +1496,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
dependencies = [
"rand_chacha 0.9.0",
- "rand_core 0.9.3",
+ "rand_core 0.9.5",
]
[[package]]
@@ -1496,7 +1516,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
dependencies = [
"ppv-lite86",
- "rand_core 0.9.3",
+ "rand_core 0.9.5",
]
[[package]]
@@ -1505,16 +1525,16 @@ version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
- "getrandom 0.2.15",
+ "getrandom 0.2.17",
]
[[package]]
name = "rand_core"
-version = "0.9.3"
+version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
+checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c"
dependencies = [
- "getrandom 0.3.2",
+ "getrandom 0.3.4",
]
[[package]]
@@ -1543,14 +1563,14 @@ version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f703f4665700daf5512dcca5f43afa6af89f09db47fb56be587f80636bda2d41"
dependencies = [
- "rand_core 0.9.3",
+ "rand_core 0.9.5",
]
[[package]]
name = "raw-cpuid"
-version = "11.5.0"
+version = "11.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c6df7ab838ed27997ba19a4664507e6f82b41fe6e20be42929332156e5e85146"
+checksum = "498cd0dc59d73224351ee52a95fee0f1a617a2eae0e7d9d720cc622c73a54186"
dependencies = [
"bitflags",
]
@@ -1589,9 +1609,9 @@ checksum = "03251193000f4bd3b042892be858ee50e8b3719f2b08e5833ac4353724632430"
[[package]]
name = "regex-automata"
-version = "0.4.9"
+version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
+checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f"
dependencies = [
"aho-corasick",
"memchr",
@@ -1600,21 +1620,21 @@ dependencies = [
[[package]]
name = "regex-syntax"
-version = "0.8.5"
+version = "0.8.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
+checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a"
[[package]]
name = "rustversion"
-version = "1.0.20"
+version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2"
+checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
[[package]]
name = "ryu"
-version = "1.0.20"
+version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
+checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f"
[[package]]
name = "safe_arch"
@@ -1648,41 +1668,52 @@ checksum = "1bc711410fbe7399f390ca1c3b60ad0f53f80e95c5eb935e52268a0e2cd49acc"
[[package]]
name = "serde"
-version = "1.0.219"
+version = "1.0.228"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
+dependencies = [
+ "serde_core",
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_core"
+version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
+checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.219"
+version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
+checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.106",
+ "syn 2.0.117",
]
[[package]]
name = "serde_json"
-version = "1.0.140"
+version = "1.0.149"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
+checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
dependencies = [
"itoa",
"memchr",
- "ryu",
"serde",
+ "serde_core",
+ "zmij",
]
[[package]]
name = "sha2"
-version = "0.10.8"
+version = "0.10.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
+checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
dependencies = [
"cfg-if",
"cpufeatures",
@@ -1706,9 +1737,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "simba"
-version = "0.9.0"
+version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b3a386a501cd104797982c15ae17aafe8b9261315b5d07e3ec803f2ea26be0fa"
+checksum = "c99284beb21666094ba2b75bbceda012e610f5479dfcc2d6e2426f53197ffd95"
dependencies = [
"approx",
"num-complex",
@@ -1719,9 +1750,9 @@ dependencies = [
[[package]]
name = "smallvec"
-version = "1.14.0"
+version = "1.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd"
+checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
[[package]]
name = "sobol_burley"
@@ -1731,9 +1762,9 @@ checksum = "09f37cae1d97c4078377153ede7a26f7813b689ad5c6b76ff45dc52e53afe1d1"
[[package]]
name = "spindle"
-version = "0.2.5"
+version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f794dedb367e82477aa6bbf83ea9bbce9bc074b3caacaa82fc4ba398ec9b701d"
+checksum = "673aaca3d8aa5387a6eba861fbf984af5348d9df5d940c25c6366b19556fdf64"
dependencies = [
"atomic-wait",
"crossbeam",
@@ -1773,9 +1804,9 @@ dependencies = [
[[package]]
name = "syn"
-version = "2.0.106"
+version = "2.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6"
+checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
dependencies = [
"proc-macro2",
"quote",
@@ -1807,11 +1838,11 @@ dependencies = [
[[package]]
name = "thiserror"
-version = "2.0.17"
+version = "2.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8"
+checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
dependencies = [
- "thiserror-impl 2.0.17",
+ "thiserror-impl 2.0.18",
]
[[package]]
@@ -1822,56 +1853,55 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.106",
+ "syn 2.0.117",
]
[[package]]
name = "thiserror-impl"
-version = "2.0.17"
+version = "2.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913"
+checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.106",
+ "syn 2.0.117",
]
[[package]]
name = "thread_local"
-version = "1.1.8"
+version = "1.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"
+checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185"
dependencies = [
"cfg-if",
- "once_cell",
]
[[package]]
name = "time"
-version = "0.3.41"
+version = "0.3.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40"
+checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c"
dependencies = [
"deranged",
"itoa",
"num-conv",
"powerfmt",
- "serde",
+ "serde_core",
"time-core",
"time-macros",
]
[[package]]
name = "time-core"
-version = "0.1.4"
+version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c"
+checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca"
[[package]]
name = "time-macros"
-version = "0.2.22"
+version = "0.2.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49"
+checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215"
dependencies = [
"num-conv",
"time-core",
@@ -1879,9 +1909,9 @@ dependencies = [
[[package]]
name = "tracing"
-version = "0.1.41"
+version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
+checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100"
dependencies = [
"pin-project-lite",
"tracing-attributes",
@@ -1890,20 +1920,20 @@ dependencies = [
[[package]]
name = "tracing-attributes"
-version = "0.1.28"
+version = "0.1.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d"
+checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.106",
+ "syn 2.0.117",
]
[[package]]
name = "tracing-core"
-version = "0.1.33"
+version = "0.1.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c"
+checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a"
dependencies = [
"once_cell",
"valuable",
@@ -1922,9 +1952,9 @@ dependencies = [
[[package]]
name = "tracing-subscriber"
-version = "0.3.20"
+version = "0.3.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5"
+checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e"
dependencies = [
"matchers",
"nu-ansi-term",
@@ -1941,9 +1971,9 @@ dependencies = [
[[package]]
name = "typenum"
-version = "1.18.0"
+version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f"
+checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
[[package]]
name = "ucd-trie"
@@ -1953,9 +1983,9 @@ checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971"
[[package]]
name = "unicode-ident"
-version = "1.0.18"
+version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
+checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
[[package]]
name = "valuable"
@@ -1981,49 +2011,37 @@ dependencies = [
[[package]]
name = "wasi"
-version = "0.11.0+wasi-snapshot-preview1"
+version = "0.11.1+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
[[package]]
-name = "wasi"
-version = "0.14.2+wasi-0.2.4"
+name = "wasip2"
+version = "1.0.2+wasi-0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
+checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5"
dependencies = [
- "wit-bindgen-rt",
+ "wit-bindgen",
]
[[package]]
name = "wasm-bindgen"
-version = "0.2.100"
+version = "0.2.114"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
+checksum = "6532f9a5c1ece3798cb1c2cfdba640b9b3ba884f5db45973a6f442510a87d38e"
dependencies = [
"cfg-if",
"once_cell",
+ "rustversion",
"wasm-bindgen-macro",
-]
-
-[[package]]
-name = "wasm-bindgen-backend"
-version = "0.2.100"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6"
-dependencies = [
- "bumpalo",
- "log",
- "proc-macro2",
- "quote",
- "syn 2.0.106",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
-version = "0.2.100"
+version = "0.2.114"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407"
+checksum = "18a2d50fcf105fb33bb15f00e7a77b772945a2ee45dcf454961fd843e74c18e6"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@@ -2031,22 +2049,22 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
-version = "0.2.100"
+version = "0.2.114"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
+checksum = "03ce4caeaac547cdf713d280eda22a730824dd11e6b8c3ca9e42247b25c631e3"
dependencies = [
+ "bumpalo",
"proc-macro2",
"quote",
- "syn 2.0.106",
- "wasm-bindgen-backend",
+ "syn 2.0.117",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
-version = "0.2.100"
+version = "0.2.114"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d"
+checksum = "75a326b8c223ee17883a4251907455a2431acc2791c98c26279376490c378c16"
dependencies = [
"unicode-ident",
]
@@ -2063,9 +2081,9 @@ dependencies = [
[[package]]
name = "wide"
-version = "0.7.32"
+version = "0.7.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "41b5576b9a81633f3e8df296ce0063042a73507636cbe956c61133dd7034ab22"
+checksum = "0ce5da8ecb62bcd8ec8b7ea19f69a51275e91299be594ea5cc6ef7819e16cd03"
dependencies = [
"bytemuck",
"safe_arch",
@@ -2073,111 +2091,24 @@ dependencies = [
[[package]]
name = "winapi-util"
-version = "0.1.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
-dependencies = [
- "windows-sys 0.59.0",
-]
-
-[[package]]
-name = "windows"
-version = "0.61.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c5ee8f3d025738cb02bad7868bbb5f8a6327501e870bf51f1b455b0a2454a419"
-dependencies = [
- "windows-collections",
- "windows-core",
- "windows-future",
- "windows-link",
- "windows-numerics",
-]
-
-[[package]]
-name = "windows-collections"
-version = "0.2.0"
+version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8"
+checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
dependencies = [
- "windows-core",
-]
-
-[[package]]
-name = "windows-core"
-version = "0.61.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "46ec44dc15085cea82cf9c78f85a9114c463a369786585ad2882d1ff0b0acf40"
-dependencies = [
- "windows-implement",
- "windows-interface",
- "windows-link",
- "windows-result",
- "windows-strings",
-]
-
-[[package]]
-name = "windows-future"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e"
-dependencies = [
- "windows-core",
- "windows-link",
- "windows-threading",
-]
-
-[[package]]
-name = "windows-implement"
-version = "0.60.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.106",
-]
-
-[[package]]
-name = "windows-interface"
-version = "0.59.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.106",
+ "windows-sys 0.61.2",
]
[[package]]
name = "windows-link"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"
-
-[[package]]
-name = "windows-numerics"
-version = "0.2.0"
+version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1"
-dependencies = [
- "windows-core",
- "windows-link",
-]
+checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
[[package]]
name = "windows-result"
-version = "0.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4b895b5356fc36103d0f64dd1e94dfa7ac5633f1c9dd6e80fe9ec4adef69e09d"
-dependencies = [
- "windows-link",
-]
-
-[[package]]
-name = "windows-strings"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2a7ab927b2637c19b3dbe0965e75d8f2d30bdd697a1516191cad2ec4df8fb28a"
+checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5"
dependencies = [
"windows-link",
]
@@ -2188,45 +2119,20 @@ version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
dependencies = [
- "windows_aarch64_gnullvm 0.42.2",
- "windows_aarch64_msvc 0.42.2",
- "windows_i686_gnu 0.42.2",
- "windows_i686_msvc 0.42.2",
- "windows_x86_64_gnu 0.42.2",
- "windows_x86_64_gnullvm 0.42.2",
- "windows_x86_64_msvc 0.42.2",
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc",
]
[[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"
+version = "0.61.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
-dependencies = [
- "windows_aarch64_gnullvm 0.52.6",
- "windows_aarch64_msvc 0.52.6",
- "windows_i686_gnu 0.52.6",
- "windows_i686_gnullvm",
- "windows_i686_msvc 0.52.6",
- "windows_x86_64_gnu 0.52.6",
- "windows_x86_64_gnullvm 0.52.6",
- "windows_x86_64_msvc 0.52.6",
-]
-
-[[package]]
-name = "windows-threading"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6"
+checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
dependencies = [
"windows-link",
]
@@ -2237,78 +2143,36 @@ version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
-[[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.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
-[[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.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
-[[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.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
-[[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.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
-[[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.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
-[[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.42.2"
@@ -2316,56 +2180,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
[[package]]
-name = "windows_x86_64_msvc"
-version = "0.52.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
-
-[[package]]
-name = "wit-bindgen-rt"
-version = "0.39.0"
+name = "wit-bindgen"
+version = "0.51.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
-dependencies = [
- "bitflags",
-]
+checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5"
[[package]]
name = "zerocopy"
-version = "0.7.35"
+version = "0.8.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
+checksum = "a789c6e490b576db9f7e6b6d661bcc9799f7c0ac8352f56ea20193b2681532e5"
dependencies = [
- "zerocopy-derive 0.7.35",
-]
-
-[[package]]
-name = "zerocopy"
-version = "0.8.24"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879"
-dependencies = [
- "zerocopy-derive 0.8.24",
+ "zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
-version = "0.7.35"
+version = "0.8.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
+checksum = "f65c489a7071a749c849713807783f70672b28094011623e200cb86dcb835953"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.106",
+ "syn 2.0.117",
]
[[package]]
-name = "zerocopy-derive"
-version = "0.8.24"
+name = "zmij"
+version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.106",
-]
+checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
diff --git a/R/PMutilities.R b/R/PMutilities.R
index 9fbf7c7fe..82514d7e7 100755
--- a/R/PMutilities.R
+++ b/R/PMutilities.R
@@ -102,7 +102,7 @@ logAxis <- function(side, grid = F, ...) {
}
axis(side, ticksat1, labels = labels, tcl = -0.5, lwd = 0, lwd.ticks = 1, ...)
axis(side, ticksat2, labels = NA, tcl = -0.25, lwd = 0, lwd.ticks = 1, ...)
-
+
if (grid & (side == 1 | side == 3)) abline(v = ticksat2, col = "lightgray", lty = 1)
if (grid & (side == 2 | side == 4)) abline(h = ticksat2, col = "lightgray", lty = 1)
}
@@ -114,7 +114,7 @@ rmnorm <- function(n, mean, sigma) {
sigma1 <- sigma
ev <- eigen(sigma, symmetric = TRUE)
retval <- ev$vectors %*% diag(sqrt(ev$values), length(ev$values)) %*%
- t(ev$vectors)
+ t(ev$vectors)
retval <- matrix(rnorm(n * ncol(sigma)), nrow = n) %*% retval
retval <- sweep(retval, 2, mean, "+")
colnames(retval) <- names(mean)
@@ -122,8 +122,9 @@ rmnorm <- function(n, mean, sigma) {
}
# density function for the multivariate normal distribution, code from mvtnorm package
-dmv_norm <- function(x, mean = rep(0, p), sigma = diag(p), log = FALSE,
-checkSymmetry = TRUE) {
+dmv_norm <- function(
+ x, mean = rep(0, p), sigma = diag(p), log = FALSE,
+ checkSymmetry = TRUE) {
if (is.vector(x)) {
x <- matrix(x, ncol = length(x))
}
@@ -157,443 +158,443 @@ checkSymmetry = TRUE) {
rss <- colSums(tmp^2)
logretval <- -sum(log(diag(dec))) - 0.5 * p * log(2 *
pi) - 0.5 * rss
- }
- names(logretval) <- rownames(x)
- if (log) {
- logretval
- } else {
- exp(logretval)
- }
}
-
- openHTML <- function(x) pander::openFileInOS(x)
-
- # parse NP_RF file only for final cycle information; used for bootstrapping
- # indpts,ab,corden,nvar,nactve,iaddl,icyctot,par
-
-
-
- random_name <- function() {
- n <- 1
- a <- do.call(paste0, replicate(5, sample(LETTERS, n, TRUE), FALSE))
- paste0(a, sprintf("%04d", sample(9999, n, TRUE)), sample(LETTERS, n, TRUE))
- }
-
-
-
-
- # check for numeric id and convert to number if necessary
- checkID <- function(id) {
- id <- gsub("^[[:blank:]]+", "", id)
- id <- gsub("[[:blank:]]+$", "", id)
- idNonNum <- suppressWarnings(any(is.na(as.numeric(id))))
- if (!idNonNum) id <- as.numeric(id)
- return(id)
- }
-
- # extract pattern from strings
- strparse <- function(pattern, x) {
- match <- regexpr(pattern, x, ignore.case = T)
- start <- match[1]
- stop <- match[1] + attr(match, "match.length") - 1
- return(substr(x, start, stop))
- }
-
-
- # parse blocks in new model template
- parseBlocks <- function(model) {
- modelFile <- scan(model, what = "character", sep = "\n", blank.lines.skip = T, quiet = T)
- # remove comment lines
- commLn <- grep("^C ", modelFile)
- if (length(commLn) > 0) modelFile <- modelFile[-commLn]
- if (length(grep("TSTMULT", modelFile)) > 0) {
- return(list(status = 0, model = model))
- }
- # stop, we already have a fortran model file
- blockStart <- grep("#", modelFile)
- blockStop <- c(blockStart[-1] - 1, length(modelFile))
- headers <- tolower(modelFile[blockStart])
- primVar <- blockStart[grep("#pri", headers)]
- covar <- blockStart[grep("#cov", headers)]
- secVar <- blockStart[grep("#sec", headers)]
- bolus <- blockStart[grep("#bol", headers)]
- ini <- blockStart[grep("#ini", headers)]
- f <- blockStart[grep("#f", headers)]
- lag <- blockStart[grep("#lag", headers)]
- diffeq <- blockStart[grep("#dif", headers)]
- eqn <- blockStart[grep("#eqn", headers)]
- output <- blockStart[grep("#out", headers)]
- error <- blockStart[grep("#err", headers)]
- extra <- blockStart[grep("#ext", headers)]
-
- if (length(diffeq) > 0) {
- eqn <- diffeq
- } # change diffeq block to eqn for more general
-
- headerPresent <- which(c(
- length(primVar) > 0, length(covar) > 0, length(secVar) > 0, length(bolus) > 0, length(ini) > 0,
- length(f) > 0, length(lag) > 0, length(eqn) > 0, length(output) > 0, length(error) > 0, length(extra) > 0
- ))
- missing_mandatory <- which(!c(1, 8:10) %in% headerPresent)
- if(length(missing_mandatory)){
- # missing mandatory headers
- missing_headers <- c("#PRI", "#EQN", "#OUT", "#ERR")[missing_mandatory]
- cli::cli_abort(c("x" = "Model file is missing mandatory header{?s}: {missing_headers} "))
- }
-
- headerOrder <- c(primVar, covar, secVar, bolus, ini, f, lag, eqn, output, error, extra)
- blockStart <- blockStart[rank(headerOrder)]
- blockStop <- blockStop[rank(headerOrder)]
-
- # remove headers that have no information
- ok <- mapply(function(x, y) x != y, blockStart, blockStop)
- blockStart <- blockStart[ok]
- blockStop <- blockStop[ok]
- headerPresent <- headerPresent[ok]
-
- # get blocks
- blocks <- list(primVar = NA, covar = NA, secVar = NA, bolus = NA, ini = NA, f = NA, lag = NA, eqn = NA, output = NA, error = NA, extra = NA)
- for (i in 1:length(headerPresent)) {
- temp <- modelFile[(blockStart[i] + 1):blockStop[i]]
- allblank <- grep("^[[:blank:]]+$", temp)
- if (length(allblank) > 0) temp <- temp[-allblank]
- blocks[[headerPresent[i]]] <- tolower(temp)
- }
- emptyHeaders <- which(is.na(blocks))
- if (length(emptyHeaders) > 0) blocks[emptyHeaders] <- ""
- return(blocks)
- } # end parseBlocks
-
- # check all blocks statements for more than maxwidth characters and insert line break if necessary
- chunks <- function(x, maxwidth = 60) {
- for (i in 1:length(x)) {
- for (j in 1:length(x[[i]])) {
- temp <- x[[i]][j]
- if (nchar(temp) > maxwidth) {
- numchunks <- floor(nchar(temp) / maxwidth)
- if (nchar(temp) %% maxwidth > 0) numchunks <- numchunks + 1
- splitchunks <- vector("character", numchunks)
- chunkindex <- c(seq(0, numchunks * maxwidth, maxwidth), nchar(temp))
- for (k in 1:numchunks) {
- splitchunks[k] <- substr(temp, chunkindex[k] + 1, chunkindex[k + 1])
- }
- x[[i]][j] <- paste(splitchunks, collapse = "\n & ")
+ names(logretval) <- rownames(x)
+ if (log) {
+ logretval
+ } else {
+ exp(logretval)
+ }
+}
+
+openHTML <- function(x) pander::openFileInOS(x)
+
+# parse NP_RF file only for final cycle information; used for bootstrapping
+# indpts,ab,corden,nvar,nactve,iaddl,icyctot,par
+
+
+
+random_name <- function() {
+ n <- 1
+ a <- do.call(paste0, replicate(5, sample(LETTERS, n, TRUE), FALSE))
+ paste0(a, sprintf("%04d", sample(9999, n, TRUE)), sample(LETTERS, n, TRUE))
+}
+
+
+
+
+# check for numeric id and convert to number if necessary
+checkID <- function(id) {
+ id <- gsub("^[[:blank:]]+", "", id)
+ id <- gsub("[[:blank:]]+$", "", id)
+ idNonNum <- suppressWarnings(any(is.na(as.numeric(id))))
+ if (!idNonNum) id <- as.numeric(id)
+ return(id)
+}
+
+# extract pattern from strings
+strparse <- function(pattern, x) {
+ match <- regexpr(pattern, x, ignore.case = T)
+ start <- match[1]
+ stop <- match[1] + attr(match, "match.length") - 1
+ return(substr(x, start, stop))
+}
+
+
+# parse blocks in new model template
+parseBlocks <- function(model) {
+ modelFile <- scan(model, what = "character", sep = "\n", blank.lines.skip = T, quiet = T)
+ # remove comment lines
+ commLn <- grep("^C ", modelFile)
+ if (length(commLn) > 0) modelFile <- modelFile[-commLn]
+ if (length(grep("TSTMULT", modelFile)) > 0) {
+ return(list(status = 0, model = model))
+ }
+ # stop, we already have a fortran model file
+ blockStart <- grep("#", modelFile)
+ blockStop <- c(blockStart[-1] - 1, length(modelFile))
+ headers <- tolower(modelFile[blockStart])
+ primVar <- blockStart[grep("#pri", headers)]
+ covar <- blockStart[grep("#cov", headers)]
+ secVar <- blockStart[grep("#sec", headers)]
+ bolus <- blockStart[grep("#bol", headers)]
+ ini <- blockStart[grep("#ini", headers)]
+ f <- blockStart[grep("#f", headers)]
+ lag <- blockStart[grep("#lag", headers)]
+ diffeq <- blockStart[grep("#dif", headers)]
+ eqn <- blockStart[grep("#eqn", headers)]
+ output <- blockStart[grep("#out", headers)]
+ error <- blockStart[grep("#err", headers)]
+ extra <- blockStart[grep("#ext", headers)]
+
+ if (length(diffeq) > 0) {
+ eqn <- diffeq
+ } # change diffeq block to eqn for more general
+
+ headerPresent <- which(c(
+ length(primVar) > 0, length(covar) > 0, length(secVar) > 0, length(bolus) > 0, length(ini) > 0,
+ length(f) > 0, length(lag) > 0, length(eqn) > 0, length(output) > 0, length(error) > 0, length(extra) > 0
+ ))
+ missing_mandatory <- which(!c(1, 8:10) %in% headerPresent)
+ if (length(missing_mandatory)) {
+ # missing mandatory headers
+ missing_headers <- c("#PRI", "#EQN", "#OUT", "#ERR")[missing_mandatory]
+ cli::cli_abort(c("x" = "Model file is missing mandatory header{?s}: {missing_headers} "))
+ }
+
+ headerOrder <- c(primVar, covar, secVar, bolus, ini, f, lag, eqn, output, error, extra)
+ blockStart <- blockStart[rank(headerOrder)]
+ blockStop <- blockStop[rank(headerOrder)]
+
+ # remove headers that have no information
+ ok <- mapply(function(x, y) x != y, blockStart, blockStop)
+ blockStart <- blockStart[ok]
+ blockStop <- blockStop[ok]
+ headerPresent <- headerPresent[ok]
+
+ # get blocks
+ blocks <- list(primVar = NA, covar = NA, secVar = NA, bolus = NA, ini = NA, f = NA, lag = NA, eqn = NA, output = NA, error = NA, extra = NA)
+ for (i in 1:length(headerPresent)) {
+ temp <- modelFile[(blockStart[i] + 1):blockStop[i]]
+ allblank <- grep("^[[:blank:]]+$", temp)
+ if (length(allblank) > 0) temp <- temp[-allblank]
+ blocks[[headerPresent[i]]] <- tolower(temp)
+ }
+ emptyHeaders <- which(is.na(blocks))
+ if (length(emptyHeaders) > 0) blocks[emptyHeaders] <- ""
+ return(blocks)
+} # end parseBlocks
+
+# check all blocks statements for more than maxwidth characters and insert line break if necessary
+chunks <- function(x, maxwidth = 60) {
+ for (i in 1:length(x)) {
+ for (j in 1:length(x[[i]])) {
+ temp <- x[[i]][j]
+ if (nchar(temp) > maxwidth) {
+ numchunks <- floor(nchar(temp) / maxwidth)
+ if (nchar(temp) %% maxwidth > 0) numchunks <- numchunks + 1
+ splitchunks <- vector("character", numchunks)
+ chunkindex <- c(seq(0, numchunks * maxwidth, maxwidth), nchar(temp))
+ for (k in 1:numchunks) {
+ splitchunks[k] <- substr(temp, chunkindex[k] + 1, chunkindex[k + 1])
}
+ x[[i]][j] <- paste(splitchunks, collapse = "\n & ")
}
}
- return(x)
- } # end chunks
-
- # change dX[digit] to XP(digit) and X[digit] to X(digit)
- fortranize <- function(block) {
- block <- purrr::map_chr(block, ~ gsub("dX\\[(\\d+)\\]", "XP\\(\\1\\)", .x, ignore.case = T, perl = T))
- block <- purrr::map_chr(block, ~ gsub("BOLUS\\[\\d+\\]", "", .x, ignore.case = T, perl = T))
- block <- purrr::map_chr(block, ~ gsub("\\[(\\d+)\\]", "\\(\\1\\)", .x, ignore.case = T, perl = T))
- return(block)
- }
-
-
- # convert new model template to model fortran file
- makeModel <- function(model = "model.txt", data = "data.csv", engine, backend = getPMoptions("backend"), write = T, quiet = F) {
- blocks <- parseBlocks(model)
-
- # check for reserved variable names
- reserved <- c(
- "ndim", "t", "x", "xp", "rpar", "ipar", "p", "r", "b", "npl", "numeqt", "ndrug", "nadd", "rateiv", "cv",
- "n", "nd", "ni", "nup", "nuic", "np", "nbcomp", "psym", "fa", "lag", "tin", "tout"
- )
- conflict <- c(match(tolower(blocks$primVar), reserved, nomatch = -99), match(tolower(blocks$secVar), reserved, nomatch = -99), match(tolower(blocks$covar), reserved, nomatch = -99))
- nconflict <- sum(conflict != -99)
- if (nconflict > 0) {
- msg <- paste("\n", paste(paste("'", reserved[conflict[conflict != -99]], "'", sep = ""), collapse = ", "), " ", c("is a", "are")[1 + as.numeric(nconflict > 1)], " reserved ", c("name", "names")[1 + as.numeric(nconflict > 1)], ", regardless of case.\nPlease choose non-reserved parameter/covariate names.\n", sep = "")
- return(list(status = -1, msg = msg))
- }
-
- # check all blocks statements for more than maxwidth characters and insert line break if necessary
- maxwidth <- 60
- blocks <- chunks(x = blocks, maxwidth = maxwidth)
-
- # ensure in fortran format: dX -> XP and [] -> ()
- blocks <- purrr::map(blocks, fortranize)
-
- # primary variable definitions
- npvar <- length(blocks$primVar)
- psym <- vector("character", npvar)
- pvardef <- psym
- if (length(grep(";", blocks$primVar)) > 0) {
- # using ';' as separator
- sep <- ";"
- } else {
- if (length(grep(",", blocks$primVar)) > 0) {
- # using ',' as separator
- sep <- ","
- } else {
- return(list(status = -1, msg = "\nPrimary variables should be defined as 'var,lower_val,upper_val' or 'var,fixed_val'.\n"))
- }
- }
-
- # find out if any are fixed to be positive only for IT2B
- fixedpos <- grep("\\+", blocks$primVar)
- if (length(fixedpos) > 0) blocks$primVar <- gsub("\\+", "", blocks$primVar)
-
- # find out if any are to be fixed (constant)
- fixcon <- grep("!", blocks$primVar)
- nofix <- length(fixcon)
- if (nofix > 0) blocks$primVar <- gsub("!", "", blocks$primVar)
-
-
- # get limits [a,b] on primary variables
- splitprimVar <- strsplit(blocks$primVar, sep)
- a <- as.numeric(unlist(lapply(splitprimVar, function(x) x[2])))
- b <- as.numeric(unlist(lapply(splitprimVar, function(x) x[3])))
-
- # set parameter type: 1 for random, 0 for constant, -1 for random but pos (IT2B only) and 2 for fixed random
- ptype <- c(1, 2)[1 + as.numeric(is.na(b))]
- # if any fixed constant variables are present, set ptype to 0
- if (nofix > 0) ptype[fixcon] <- 0
-
- # npvar is total number of parameters
- # nvar is number of random (estimated) parameters
- # nranfix is number of fixed (but unknown) parameters
- # nofix is number of constant parameters
- nranfix <- sum(as.numeric(is.na(b))) - nofix
- nvar <- npvar - nofix - nranfix
-
- if ((engine$alg == "IT" | engine$alg == "ERR") & length(fixedpos) > 0) ptype[fixedpos] <- -1
-
- if (nofix > 0) {
- valfix <- a[which(ptype == 0)]
+ }
+ return(x)
+} # end chunks
+
+# change dX[digit] to XP(digit) and X[digit] to X(digit)
+fortranize <- function(block) {
+ block <- purrr::map_chr(block, ~ gsub("dX\\[(\\d+)\\]", "XP\\(\\1\\)", .x, ignore.case = T, perl = T))
+ block <- purrr::map_chr(block, ~ gsub("BOLUS\\[\\d+\\]", "", .x, ignore.case = T, perl = T))
+ block <- purrr::map_chr(block, ~ gsub("\\[(\\d+)\\]", "\\(\\1\\)", .x, ignore.case = T, perl = T))
+ return(block)
+}
+
+
+# convert new model template to model fortran file
+makeModel <- function(model = "model.txt", data = "data.csv", engine, backend = getPMoptions("backend"), write = T, quiet = F) {
+ blocks <- parseBlocks(model)
+
+ # check for reserved variable names
+ reserved <- c(
+ "ndim", "t", "x", "xp", "rpar", "ipar", "p", "r", "b", "npl", "numeqt", "ndrug", "nadd", "rateiv", "cv",
+ "n", "nd", "ni", "nup", "nuic", "np", "nbcomp", "psym", "fa", "lag", "tin", "tout"
+ )
+ conflict <- c(match(tolower(blocks$primVar), reserved, nomatch = -99), match(tolower(blocks$secVar), reserved, nomatch = -99), match(tolower(blocks$covar), reserved, nomatch = -99))
+ nconflict <- sum(conflict != -99)
+ if (nconflict > 0) {
+ msg <- paste("\n", paste(paste("'", reserved[conflict[conflict != -99]], "'", sep = ""), collapse = ", "), " ", c("is a", "are")[1 + as.numeric(nconflict > 1)], " reserved ", c("name", "names")[1 + as.numeric(nconflict > 1)], ", regardless of case.\nPlease choose non-reserved parameter/covariate names.\n", sep = "")
+ return(list(status = -1, msg = msg))
+ }
+
+ # check all blocks statements for more than maxwidth characters and insert line break if necessary
+ maxwidth <- 60
+ blocks <- chunks(x = blocks, maxwidth = maxwidth)
+
+ # ensure in fortran format: dX -> XP and [] -> ()
+ blocks <- purrr::map(blocks, fortranize)
+
+ # primary variable definitions
+ npvar <- length(blocks$primVar)
+ psym <- vector("character", npvar)
+ pvardef <- psym
+ if (length(grep(";", blocks$primVar)) > 0) {
+ # using ';' as separator
+ sep <- ";"
+ } else {
+ if (length(grep(",", blocks$primVar)) > 0) {
+ # using ',' as separator
+ sep <- ","
} else {
- valfix <- NA
+ return(list(status = -1, msg = "\nPrimary variables should be defined as 'var,lower_val,upper_val' or 'var,fixed_val'.\n"))
}
-
- if (nranfix > 0) {
- valranfix <- a[which(ptype == 2)]
+ }
+
+ # find out if any are fixed to be positive only for IT2B
+ fixedpos <- grep("\\+", blocks$primVar)
+ if (length(fixedpos) > 0) blocks$primVar <- gsub("\\+", "", blocks$primVar)
+
+ # find out if any are to be fixed (constant)
+ fixcon <- grep("!", blocks$primVar)
+ nofix <- length(fixcon)
+ if (nofix > 0) blocks$primVar <- gsub("!", "", blocks$primVar)
+
+
+ # get limits [a,b] on primary variables
+ splitprimVar <- strsplit(blocks$primVar, sep)
+ a <- as.numeric(unlist(lapply(splitprimVar, function(x) x[2])))
+ b <- as.numeric(unlist(lapply(splitprimVar, function(x) x[3])))
+
+ # set parameter type: 1 for random, 0 for constant, -1 for random but pos (IT2B only) and 2 for fixed random
+ ptype <- c(1, 2)[1 + as.numeric(is.na(b))]
+ # if any fixed constant variables are present, set ptype to 0
+ if (nofix > 0) ptype[fixcon] <- 0
+
+ # npvar is total number of parameters
+ # nvar is number of random (estimated) parameters
+ # nranfix is number of fixed (but unknown) parameters
+ # nofix is number of constant parameters
+ nranfix <- sum(as.numeric(is.na(b))) - nofix
+ nvar <- npvar - nofix - nranfix
+
+ if ((engine$alg == "IT" | engine$alg == "ERR") & length(fixedpos) > 0) ptype[fixedpos] <- -1
+
+ if (nofix > 0) {
+ valfix <- a[which(ptype == 0)]
+ } else {
+ valfix <- NA
+ }
+
+ if (nranfix > 0) {
+ valranfix <- a[which(ptype == 2)]
+ } else {
+ valranfix <- NA
+ }
+
+ ab.df <- data.frame(a = a[which(ptype == 1)], b = b[which(ptype == 1)])
+
+
+ # replace a,b with SIM limits argument if it is present
+ if (engine$alg == "SIM" & !all(is.na(engine$limits))) {
+ if (nrow(engine$limits) == nvar) {
+ # make sure same row number
+ replA <- engine$limits[, 1]
+ replB <- engine$limits[, 2]
+ ab.df$a[!is.na(replA)] <- replA[!is.na(replA)]
+ ab.df$b[!is.na(replB)] <- replB[!is.na(replB)]
} else {
- valranfix <- NA
+ return(list(status = -1, msg = "Your limit block does not have the same number of parameters as the model file.\n"))
}
-
- ab.df <- data.frame(a = a[which(ptype == 1)], b = b[which(ptype == 1)])
-
-
- # replace a,b with SIM limits argument if it is present
- if (engine$alg == "SIM" & !all(is.na(engine$limits))) {
- if (nrow(engine$limits) == nvar) {
- # make sure same row number
- replA <- engine$limits[, 1]
- replB <- engine$limits[, 2]
- ab.df$a[!is.na(replA)] <- replA[!is.na(replA)]
- ab.df$b[!is.na(replB)] <- replB[!is.na(replB)]
- } else {
- return(list(status = -1, msg = "Your limit block does not have the same number of parameters as the model file.\n"))
- }
- }
-
- if (nofix > 0 & any(is.na(valfix))) {
- return(list(status = -1, msg = "One or more variables did not have any boundaries.\n"))
+ }
+
+ if (nofix > 0 & any(is.na(valfix))) {
+ return(list(status = -1, msg = "One or more variables did not have any boundaries.\n"))
+ }
+ if (nranfix > 0 & any(is.na(valranfix))) {
+ return(list(status = -1, msg = "One or more variables did not have any boundaries.\n"))
+ }
+
+ # set grid point index for NPAG if not supplied
+ if (engine$indpts == -99) {
+ indpts <- switch(nvar,
+ 1,
+ 1,
+ 3,
+ 4,
+ 6
+ )
+ if (is.null(indpts)) indpts <- 100 + nvar - 5
+ if (indpts > 108) indpts <- 108
+ } else {
+ indpts <- engine$indpts
+ }
+
+
+ # transform ab
+ if (nrow(ab.df) > 0) {
+ ab <- paste(t(as.matrix(ab.df)))
+ ab <- c(paste(ab[1:(length(ab) - 1)], "t", sep = ""), ab[length(ab)])
+ ab[seq(1, 2 * nvar, 2)] <- sub("t", " ", ab[seq(1, 2 * nvar, 2)])
+ ab[seq(2, 2 * nvar, 2)] <- sub("t", "\n", ab[seq(2, 2 * nvar, 2)])
+ ab <- paste(ab, collapse = "")
+ }
+
+ blocks$primVar <- unlist(lapply(splitprimVar, function(x) x[1]))
+
+ for (i in 1:npvar) {
+ psym[i] <- paste("PSYM(", i, ")='", blocks$primVar[i], "'", sep = "")
+ pvardef[i] <- paste(blocks$primVar[i], "=P(", i, ")", sep = "")
+ }
+
+
+ # covariate definitions
+ if (blocks$covar[1] != "") {
+ ncov <- length(blocks$covar)
+ interpol <- grep("!", blocks$covar)
+ blocks$covar <- gsub("!", "", blocks$covar)
+ covardef <- vector("character", ncov)
+ for (i in 1:ncov) {
+ covardef[i] <- paste(blocks$covar[i], "=CV(", i, ")", sep = "")
}
- if (nranfix > 0 & any(is.na(valranfix))) {
- return(list(status = -1, msg = "One or more variables did not have any boundaries.\n"))
+ if (!identical(1:ncov, which(tolower(engine$covnames) %in% tolower(blocks$covar)))) {
+ return(list(status = -1, msg = "The covariate set in your model file was not in the same order as in your data file.\n"))
}
-
- # set grid point index for NPAG if not supplied
- if (engine$indpts == -99) {
- indpts <- switch(nvar,
- 1,
- 1,
- 3,
- 4,
- 6
- )
- if (is.null(indpts)) indpts <- 100 + nvar - 5
- if (indpts > 108) indpts <- 108
+ } else {
+ covardef <- ""
+ interpol <- grep("!", blocks$covar)
+ }
+ if (engine$ncov > 0) {
+ ctype <- rep(2, engine$ncov)
+ } else {
+ ctype <- -99
+ }
+ # set covariate type based on number of covariates in data file, default is 2, interpolated
+ if (length(interpol) > 0) ctype[interpol] <- 1 # change those in model file with "!" to constant
+
+ # secondary variable definitions
+ svardef <- blocks$secVar
+
+ # get secondary variables and remove continuation lines beginning with "&"
+ secVarNames <- gsub("[[:blank:]]", "", unlist(lapply(strsplit(svardef, "="), function(x) x[1])))
+ secVarNames[is.na(secVarNames)] <- ""
+ oldContLines <- grep("^\\+", secVarNames)
+ if (length(oldContLines > 0)) {
+ return(list(status = -1, msg = "\nThe model file format has changed. Please replace '+' with '&' in all continuation lines.\n"))
+ }
+ contLines <- grep("^&", secVarNames)
+
+ if (length(contLines) > 0) {
+ secVarNames <- secVarNames[-contLines]
+ svardef <- gsub("^&", "", svardef)
+ }
+
+ # take out any extra declarations in eqn to add to declarations in subroutine
+ diffdec <- grep("COMMON|EXTERNAL|DIMENSION", blocks$eqn, ignore.case = T)
+ if (length(diffdec) > 0) {
+ diffstate <- blocks$eqn[diffdec]
+ blocks$eqn <- blocks$eqn[-diffdec]
+ } else {
+ diffstate <- ""
+ }
+
+ # detect N
+ if (blocks$eqn[1] == "" | grepl("^\\{algebraic:", blocks$eqn[1])) {
+ if ("KE" %in% toupper(secVarNames) | "KE" %in% toupper(blocks$primVar)) {
+ N <- -1
} else {
- indpts <- engine$indpts
- }
-
-
- # transform ab
- if (nrow(ab.df) > 0) {
- ab <- paste(t(as.matrix(ab.df)))
- ab <- c(paste(ab[1:(length(ab) - 1)], "t", sep = ""), ab[length(ab)])
- ab[seq(1, 2 * nvar, 2)] <- sub("t", " ", ab[seq(1, 2 * nvar, 2)])
- ab[seq(2, 2 * nvar, 2)] <- sub("t", "\n", ab[seq(2, 2 * nvar, 2)])
- ab <- paste(ab, collapse = "")
+ N <- 0
}
-
- blocks$primVar <- unlist(lapply(splitprimVar, function(x) x[1]))
-
- for (i in 1:npvar) {
- psym[i] <- paste("PSYM(", i, ")='", blocks$primVar[i], "'", sep = "")
- pvardef[i] <- paste(blocks$primVar[i], "=P(", i, ")", sep = "")
+ } else {
+ # get number of equations and verify with data file
+ # find statements with XP(digit) or dX[digit]
+ compLines <- grep("XP\\([[:digit:]]+\\)|dX\\[[[:digit:]]+\\]", blocks$eqn, ignore.case = T)
+ if (length(compLines) == 0) {
+ N <- 0
+ } else {
+ compStatements <- sapply(blocks$eqn[compLines], function(x) strparse("XP\\([[:digit:]]+\\)|dX\\[[[:digit:]]+\\]", x))
+ compNumbers <- sapply(compStatements, function(x) strparse("[[:digit:]]+", x))
+ # get max number
+ N <- max(as.numeric(compNumbers))
}
-
-
- # covariate definitions
- if (blocks$covar[1] != "") {
- ncov <- length(blocks$covar)
- interpol <- grep("!", blocks$covar)
- blocks$covar <- gsub("!", "", blocks$covar)
- covardef <- vector("character", ncov)
- for (i in 1:ncov) {
- covardef[i] <- paste(blocks$covar[i], "=CV(", i, ")", sep = "")
+ }
+
+ # figure out model if N = -1 and if so, assign values to required KA,KE,V,KCP,KPC
+ # in future, use {algebraic: xx} which is in model files now to select correct algebraic model
+ # for now, comment the eqn lines in fortran if present
+ if (length(grep("^\\{algebraic:", blocks$eqn[1])) > 0) {
+ blocks$eqn[1] <- "This model uses algebraic solutions. Differential equations provided here for reference only."
+ blocks$eqn <- purrr::map_chr(blocks$eqn, \(x) paste0("! ", x))
+ }
+
+
+ reqVars <- c("KA", "KE", "KCP", "KPC", "V")
+ matchVars <- match(reqVars, toupper(c(blocks$primVar, secVarNames)))
+ if (N == -1) {
+ if (any(is.na(matchVars))) {
+ missVars <- reqVars[is.na(matchVars)]
+ if ("KE" %in% toupper(missVars)) {
+ return(list(status = -1, msg = "\nYou have specified an algebraic model, which requires a variable named 'KE'\n"))
}
- if (!identical(1:ncov, which(tolower(engine$covnames) %in% tolower(blocks$covar)))) {
- return(list(status = -1, msg = "The covariate set in your model file was not in the same order as in your data file.\n"))
+ if ("V" %in% toupper(missVars)) {
+ return(list(status = -1, msg = "\nYou have specified an algebraic model, which requires a variable named 'V'\n"))
}
+ missVarValues <- paste(missVars, "=0", sep = "")
+ if (length(missVarValues) > 0) svardef <- c(svardef, missVarValues)
+ svardef <- svardef[svardef != ""]
+ # add new secondary variables that won't be estimated
+ secVarNames <- c(secVarNames, missVars)
+ secVarNames <- secVarNames[secVarNames != ""]
} else {
- covardef <- ""
- interpol <- grep("!", blocks$covar)
- }
- if (engine$ncov > 0) {
- ctype <- rep(2, engine$ncov)
- } else {
- ctype <- -99
- }
- # set covariate type based on number of covariates in data file, default is 2, interpolated
- if (length(interpol) > 0) ctype[interpol] <- 1 # change those in model file with "!" to constant
-
- # secondary variable definitions
- svardef <- blocks$secVar
-
- # get secondary variables and remove continuation lines beginning with "&"
- secVarNames <- gsub("[[:blank:]]", "", unlist(lapply(strsplit(svardef, "="), function(x) x[1])))
- secVarNames[is.na(secVarNames)] <- ""
- oldContLines <- grep("^\\+", secVarNames)
- if (length(oldContLines > 0)) {
- return(list(status = -1, msg = "\nThe model file format has changed. Please replace '+' with '&' in all continuation lines.\n"))
+ missVars <- NA
}
- contLines <- grep("^&", secVarNames)
-
- if (length(contLines) > 0) {
- secVarNames <- secVarNames[-contLines]
- svardef <- gsub("^&", "", svardef)
- }
-
- # take out any extra declarations in eqn to add to declarations in subroutine
- diffdec <- grep("COMMON|EXTERNAL|DIMENSION", blocks$eqn, ignore.case = T)
- if (length(diffdec) > 0) {
- diffstate <- blocks$eqn[diffdec]
- blocks$eqn <- blocks$eqn[-diffdec]
- } else {
- diffstate <- ""
- }
-
- # detect N
- if (blocks$eqn[1] == "" | grepl("^\\{algebraic:", blocks$eqn[1])) {
- if ("KE" %in% toupper(secVarNames) | "KE" %in% toupper(blocks$primVar)) {
- N <- -1
- } else {
- N <- 0
- }
+ } else {
+ if (any(is.na(matchVars))) {
+ missVars <- reqVars[is.na(matchVars)]
} else {
- # get number of equations and verify with data file
- # find statements with XP(digit) or dX[digit]
- compLines <- grep("XP\\([[:digit:]]+\\)|dX\\[[[:digit:]]+\\]", blocks$eqn, ignore.case = T)
- if (length(compLines) == 0) {
- N <- 0
- } else {
- compStatements <- sapply(blocks$eqn[compLines], function(x) strparse("XP\\([[:digit:]]+\\)|dX\\[[[:digit:]]+\\]", x))
- compNumbers <- sapply(compStatements, function(x) strparse("[[:digit:]]+", x))
- # get max number
- N <- max(as.numeric(compNumbers))
- }
+ missVars <- NA
}
-
- # figure out model if N = -1 and if so, assign values to required KA,KE,V,KCP,KPC
- # in future, use {algebraic: xx} which is in model files now to select correct algebraic model
- # for now, comment the eqn lines in fortran if present
- if (length(grep("^\\{algebraic:", blocks$eqn[1])) > 0) {
- blocks$eqn[1] <- "This model uses algebraic solutions. Differential equations provided here for reference only."
- blocks$eqn <- purrr::map_chr(blocks$eqn, \(x) paste0("! ", x))
- }
-
-
- reqVars <- c("KA", "KE", "KCP", "KPC", "V")
- matchVars <- match(reqVars, toupper(c(blocks$primVar, secVarNames)))
- if (N == -1) {
- if (any(is.na(matchVars))) {
- missVars <- reqVars[is.na(matchVars)]
- if ("KE" %in% toupper(missVars)) {
- return(list(status = -1, msg = "\nYou have specified an algebraic model, which requires a variable named 'KE'\n"))
- }
- if ("V" %in% toupper(missVars)) {
- return(list(status = -1, msg = "\nYou have specified an algebraic model, which requires a variable named 'V'\n"))
- }
- missVarValues <- paste(missVars, "=0", sep = "")
- if (length(missVarValues) > 0) svardef <- c(svardef, missVarValues)
- svardef <- svardef[svardef != ""]
- # add new secondary variables that won't be estimated
- secVarNames <- c(secVarNames, missVars)
- secVarNames <- secVarNames[secVarNames != ""]
- } else {
- missVars <- NA
- }
- } else {
- if (any(is.na(matchVars))) {
- missVars <- reqVars[is.na(matchVars)]
- } else {
- missVars <- NA
- }
+ }
+
+ # extract bolus inputs and create bolus block, then remove bolus[x] from equations
+ bolus <- purrr::map(blocks$eqn, ~ stringr::str_extract_all(.x, regex("B[\\[\\(]\\d+|BOL[\\[\\(]\\d+|BOLUS[\\[\\(]\\d+", ignore_case = TRUE), simplify = FALSE))
+ blocks$bolus <- purrr::imap(bolus, \(x, idx){
+ if (length(x[[1]]) > 0) {
+ paste0("NBCOMP(", stringr::str_extract(x[[1]], "\\d+$"), ") = ", idx)
}
-
- # extract bolus inputs and create bolus block, then remove bolus[x] from equations
- bolus <- purrr::map(blocks$eqn, ~ stringr::str_extract_all(.x, regex("B[\\[\\(]\\d+|BOL[\\[\\(]\\d+|BOLUS[\\[\\(]\\d+", ignore_case = TRUE), simplify = FALSE))
- blocks$bolus <- purrr::imap(bolus, \(x, idx){
- if (length(x[[1]]) > 0) {
- paste0("NBCOMP(", stringr::str_extract(x[[1]], "\\d+$"), ") = ", idx)
- }
- }) %>% unlist()
- blocks$eqn <- purrr::map(blocks$eqn, \(x) stringr::str_replace_all(x, regex("(\\+*|-*|\\**)\\s*B[\\[\\(]\\d+[\\]\\)]|(\\+*|-*|\\**)\\s*BOL[\\[\\(]\\d+[\\]\\)]|(\\+*|-*|\\**)\\s*BOLUS[\\[\\(]\\d+[\\]\\)]", ignore_case = TRUE), "")) %>%
+ }) %>% unlist()
+ blocks$eqn <- purrr::map(blocks$eqn, \(x) stringr::str_replace_all(x, regex("(\\+*|-*|\\**)\\s*B[\\[\\(]\\d+[\\]\\)]|(\\+*|-*|\\**)\\s*BOL[\\[\\(]\\d+[\\]\\)]|(\\+*|-*|\\**)\\s*BOLUS[\\[\\(]\\d+[\\]\\)]", ignore_case = TRUE), "")) %>%
unlist()
-
- # replace R[x] or R(x) with RATEIV(x)
- blocks$eqn <- purrr::map(blocks$eqn, \(x) stringr::str_replace_all(x, regex("R[\\[\\(](\\d+)[\\]\\)]", ignore_case = TRUE), "RATEIV\\(\\1\\)")) %>%
+
+ # replace R[x] or R(x) with RATEIV(x)
+ blocks$eqn <- purrr::map(blocks$eqn, \(x) stringr::str_replace_all(x, regex("R[\\[\\(](\\d+)[\\]\\)]", ignore_case = TRUE), "RATEIV\\(\\1\\)")) %>%
unlist()
-
- # get number of equations and verify with data file
- # find statements with Y(digit) or Y[digit]
- outputLines <- grep("Y\\([[:digit:]]+\\)|Y\\[[[:digit:]]+\\]", blocks$output, ignore.case = T)
- if (length(outputLines) == 0) {
- return(list(status = -1, msg = "\nYou must have at least one output equation of the form 'Y[1] = ...'\n"))
- }
- # extract numbers
- outputStatements <- sapply(blocks$output[outputLines], function(x) strparse("Y\\([[:digit:]]+\\)|Y\\[[[:digit:]]+\\]", x))
- outputNumbers <- sapply(outputStatements, function(x) strparse("[[:digit:]]", x))
- # get max number
- modelnumeqt <- max(as.numeric(outputNumbers))
- if (modelnumeqt != engine$numeqt) {
- return(list(status = -1, msg = "\nThe number of output equations in the model file\ndoes not match the maximum value of outeq in your datafile.\n"))
- }
-
- # remove leading ampersands from getfa, getix, gettlag if present
- oldContLines <- grep("^\\+", c(blocks$f, blocks$ini, blocks$lag))
- if (length(oldContLines > 0)) {
- return(list(status = -1, msg = "\nThe model file format has changed. Please replace '+' with '&' in all continuation lines.\n"))
- }
- if (length(grep("^&", blocks$f) > 0)) blocks$f <- gsub("^&", "", blocks$f)
- if (length(grep("^&", blocks$ini) > 0)) blocks$ini <- gsub("^&", "", blocks$ini)
- if (length(grep("^&", blocks$lag) > 0)) blocks$lag <- gsub("^&", "", blocks$lag)
-
- # variable declarations for fortran and make sure not >maxwidth characters
- if (secVarNames[1] != "") {
- vardec <- paste("REAL*8 ", paste(blocks$primVar, collapse = ","), ",", paste(secVarNames, collapse = ","), sep = "")
- } else {
- vardec <- paste("REAL*8 ", paste(blocks$primVar, collapse = ","), sep = "")
- }
- if (blocks$covar[1] != "") {
- vardec <- paste(vardec, ",", paste(blocks$covar, collapse = ","), sep = "")
- }
- if (nchar(vardec) > maxwidth) {
- vardec <- paste(unlist(strsplit(vardec, ",")), collapse = ",\n & ")
- }
-
- # error
- blocks$error <- tolower(gsub("[[:space:]]", "", blocks$error))
- # check to make sure coefficient lines are the same number as outputs
- nErrCoeff <- length(blocks$error) - 1
- if (nErrCoeff != modelnumeqt) {
- return(list(status = -1, msg = paste("\nThere ", c("is", "are")[1 + as.numeric(nErrCoeff > 1)], " ",
+
+ # get number of equations and verify with data file
+ # find statements with Y(digit) or Y[digit]
+ outputLines <- grep("Y\\([[:digit:]]+\\)|Y\\[[[:digit:]]+\\]", blocks$output, ignore.case = T)
+ if (length(outputLines) == 0) {
+ return(list(status = -1, msg = "\nYou must have at least one output equation of the form 'Y[1] = ...'\n"))
+ }
+ # extract numbers
+ outputStatements <- sapply(blocks$output[outputLines], function(x) strparse("Y\\([[:digit:]]+\\)|Y\\[[[:digit:]]+\\]", x))
+ outputNumbers <- sapply(outputStatements, function(x) strparse("[[:digit:]]", x))
+ # get max number
+ modelnumeqt <- max(as.numeric(outputNumbers))
+ if (modelnumeqt != engine$numeqt) {
+ return(list(status = -1, msg = "\nThe number of output equations in the model file\ndoes not match the maximum value of outeq in your datafile.\n"))
+ }
+
+ # remove leading ampersands from getfa, getix, gettlag if present
+ oldContLines <- grep("^\\+", c(blocks$f, blocks$ini, blocks$lag))
+ if (length(oldContLines > 0)) {
+ return(list(status = -1, msg = "\nThe model file format has changed. Please replace '+' with '&' in all continuation lines.\n"))
+ }
+ if (length(grep("^&", blocks$f) > 0)) blocks$f <- gsub("^&", "", blocks$f)
+ if (length(grep("^&", blocks$ini) > 0)) blocks$ini <- gsub("^&", "", blocks$ini)
+ if (length(grep("^&", blocks$lag) > 0)) blocks$lag <- gsub("^&", "", blocks$lag)
+
+ # variable declarations for fortran and make sure not >maxwidth characters
+ if (secVarNames[1] != "") {
+ vardec <- paste("REAL*8 ", paste(blocks$primVar, collapse = ","), ",", paste(secVarNames, collapse = ","), sep = "")
+ } else {
+ vardec <- paste("REAL*8 ", paste(blocks$primVar, collapse = ","), sep = "")
+ }
+ if (blocks$covar[1] != "") {
+ vardec <- paste(vardec, ",", paste(blocks$covar, collapse = ","), sep = "")
+ }
+ if (nchar(vardec) > maxwidth) {
+ vardec <- paste(unlist(strsplit(vardec, ",")), collapse = ",\n & ")
+ }
+
+ # error
+ blocks$error <- tolower(gsub("[[:space:]]", "", blocks$error))
+ # check to make sure coefficient lines are the same number as outputs
+ nErrCoeff <- length(blocks$error) - 1
+ if (nErrCoeff != modelnumeqt) {
+ return(list(status = -1, msg = paste("\nThere ", c("is", "are")[1 + as.numeric(nErrCoeff > 1)], " ",
nErrCoeff, c(" line", " lines")[1 + as.numeric(nErrCoeff > 1)],
" of error coefficients in the model file, but ",
modelnumeqt, " output ", c("equation", "equations")[1 + as.numeric(modelnumeqt > 1)],
@@ -619,7 +620,7 @@ checkSymmetry = TRUE) {
fixed <- grep("!", blocks$error[gamlam[1]])
ierr <- unlist(strsplit(blocks$error[gamlam[1]], "="))
ierrtype <- gsub("[[:space:]]", "", tolower(substr(ierr[1], 1, 1)))
-
+
# NPAG error parameters
# IERRMOD
# 1 SD WITH GAMMA(IEQ) FIXED
@@ -632,7 +633,7 @@ checkSymmetry = TRUE) {
# 2 IF ONE SET OF ABOVE Cs USED FOR ALL PATIENTS;
# 1 IF Cs ALREADY IN PATIENT FILES WILL BE USED; IF A
# PATIENT HAS NO C'S, THEN POPULATION C'S WILL BE USED.
-
+
if (engine$alg == "NP") {
if (length(fixed) > 0) {
# gamma is fixed (error for lambda)
@@ -667,7 +668,7 @@ checkSymmetry = TRUE) {
asserr <- paste(gsub("!", "", asserr), collapse = "\n") # clean up asserr
iass <- paste(iass, collapse = " ") # clean up iass
}
-
+
# IT2B error parameters
# IERRMOD
# 1 IF GAMMA(IEQ) IS TO REMAIN 1.0 THROUGHOUT THE ANALYSIS;
@@ -680,7 +681,7 @@ checkSymmetry = TRUE) {
# 2 IF ONE SET OF ABOVE Cs USED FOR ALL PATIENTS;
# 1 IF Cs ALREADY IN PATIENT FILES WILL BE USED; IF A
# PATIENT HAS NO C'S, THEN POPULATION C'S WILL BE USED.
-
+
# IQVAL
# 0 IF OUTPUT EQ. HAS ITS Cs ENTERED BY USER (NOT
# ESTIMATED BY assbigxx.exe) AND IERRTYPE(IEQ) = 1
@@ -688,7 +689,7 @@ checkSymmetry = TRUE) {
# ESTIMATED BY assbigxx.exe) AND IERRTYPE(IEQ) = 0
# 4 IF OUTPUT EQ. HAD ITS Cs ESTIMATED PREVIOUSLY
# BY assbigxx.exe.
-
+
if (engine$alg == "IT") {
if (ierrtype == "l") {
return(list(status = -1, msg = "\nLambda is not currently implemented in IT2B\nPlease correct the error block in your model file.\n"))
@@ -730,11 +731,11 @@ checkSymmetry = TRUE) {
return(list(status = -1, msg = "Please specify a gamma or lambda error model in your\nmodel file error block."))
}
}
-
-
-
-
-
+
+
+
+
+
# write report
if (!quiet) {
cat(paste("\nModel solver mode: ", switch(letters[N + 2],
@@ -777,27 +778,27 @@ checkSymmetry = TRUE) {
cat(paste("\nCovariates used in model file: ", c(paste(blocks$covar, collapse = ", "), "None")[1 + as.numeric(blocks$covar[1] == "")]))
cat(paste("\nSecondary Variables: ", paste(secVarNames, collapse = ", "), sep = ""))
cat(paste("\nModel conditions: ", c("bioavailability term defined, ", "no bioavailability term defined, ")[1 + as.numeric(blocks$f[1] == "")],
- c("initial conditions are not zero, ", "initial conditions are zero, ")[1 + as.numeric(blocks$ini[1] == "")],
- c("lag term defined", "no lag term defined")[1 + as.numeric(blocks$lag[1] == "")],
- sep = ""
- ))
- if (engine$alg != "SIM") cat(paste("\nNumber of cycles to run:", engine$cycles))
- cat("\n\n")
-}
-# end if quiet
-if (getPMoptions("backend") == "rust") {
- model_file <- "main.rs"
-} else {
- model_file <- modelFor
-}
+ c("initial conditions are not zero, ", "initial conditions are zero, ")[1 + as.numeric(blocks$ini[1] == "")],
+ c("lag term defined", "no lag term defined")[1 + as.numeric(blocks$lag[1] == "")],
+ sep = ""
+ ))
+ if (engine$alg != "SIM") cat(paste("\nNumber of cycles to run:", engine$cycles))
+ cat("\n\n")
+ }
+ # end if quiet
+ if (getPMoptions("backend") == "rust") {
+ model_file <- "main.rs"
+ } else {
+ model_file <- modelFor
+ }
-ret_list <- list(
- status = 1, N = N, ptype = ptype, model = model_file,
- ctype = ctype, nvar = nvar, nofix = nofix, nranfix = nranfix,
- valfix = valfix, ab = ab.df, indpts = indpts,
- asserr = asserr, blocks = blocks
-)
-return(ret_list)
+ ret_list <- list(
+ status = 1, N = N, ptype = ptype, model = model_file,
+ ctype = ctype, nvar = nvar, nofix = nofix, nranfix = nranfix,
+ valfix = valfix, ab = ab.df, indpts = indpts,
+ asserr = asserr, blocks = blocks
+ )
+ return(ret_list)
}
# end makeModel function
@@ -816,7 +817,7 @@ endNicely <- function(message, model = -99, data = -99) {
"it2b*.*", "itas*.*", "it_prep*", "it_run*", "itlog.txt", "ITcontrol", "itscript*", "instr.inx",
"assdriv.f", "err_prep*", "err_run*", "ERRcontrol", "errscript*", "errlog.txt"
))
-
+
if (length(cleanUp) > 0) file.remove(cleanUp)
stop(message, call. = F)
}
@@ -836,8 +837,8 @@ var.wt <- function(x, w, na.rm = FALSE) {
# weighted t test
weighted.t.test <- function(x, w, mu, conf.level = 0.95, alternative = "two.sided", na.rm = TRUE) {
if (!missing(conf.level) &
- (length(conf.level) != 1 || !is.finite(conf.level) ||
- conf.level < 0 || conf.level > 1)) {
+ (length(conf.level) != 1 || !is.finite(conf.level) ||
+ conf.level < 0 || conf.level > 1)) {
stop("'conf.level' must be a single number between 0 and 1")
}
# see if x came from PM_op object
@@ -846,29 +847,29 @@ weighted.t.test <- function(x, w, mu, conf.level = 0.95, alternative = "two.side
x <- x$d
mu <- 0
}
-
+
if (na.rm) {
w <- w[i <- !is.na(x)]
x <- x[i]
}
-
+
# to achieve consistent behavior in loops, return NA-structure in case of complete missings
if (sum(is.na(x)) == length(x)) {
return(list(estimate = NA, se = NA, conf.int = NA, statistic = NA, df = NA, p.value = NA))
}
-
+
# if only one value is present: this is the best estimate, no significance test provided
if (sum(!is.na(x)) == 1) {
warning("Warning weighted.t.test: only one value provided; this value is returned without test of significance!", call. = FALSE)
return(list(estimate = x[which(!is.na(x))], se = NA, conf.int = NA, statistic = NA, df = NA, p.value = NA))
}
-
+
x.w <- weighted.mean(x, w, na.rm = na.rm)
var.w <- var.wt(x, w, na.rm = na.rm)
df <- length(x) - 1
t.value <- sqrt(length(x)) * ((x.w - mu) / sqrt(var.w))
se <- sqrt(var.w) / sqrt(length(x))
-
+
if (alternative == "less") {
pval <- pt(t.value, df)
cint <- c(-Inf, x.w + se * qt(conf.level, df))
@@ -880,7 +881,7 @@ weighted.t.test <- function(x, w, mu, conf.level = 0.95, alternative = "two.side
alpha <- 1 - conf.level
cint <- x.w + se * qt(1 - alpha / 2, df) * c(-1, 1)
}
-
+
names(t.value) <- "t"
return(list(estimate = x.w, se = se, conf.int = cint, statistic = t.value, df = df, p.value = pval))
}
@@ -907,13 +908,13 @@ FileExists <- function(filename) {
while (!file.exists(filename)) { # oops, filename doesn't exist
cat(paste0(filename, " does not exist in ", getwd(), ".\n"))
filename <- tryCatch(readline("Enter another filename or 'ESC' to quit: \n"),
- interrupt = function(e) {
- stop("No filename. Function aborted.\n", call. = F)
- }
- )
+ interrupt = function(e) {
+ stop("No filename. Function aborted.\n", call. = F)
+ }
+ )
+ }
}
-}
-return(filename)
+ return(filename)
}
@@ -921,11 +922,11 @@ return(filename)
getOS <- function() {
OS <- switch(Sys.info()[1],
- Darwin = 1,
- Windows = 2,
- Linux = 3
-)
-return(OS)
+ Darwin = 1,
+ Windows = 2,
+ Linux = 3
+ )
+ return(OS)
}
# This might be a solution: https://community.rstudio.com/t/how-to-get-rstudio-ide-to-use-the-correct-terminal-path-in-mac-os-x/131528/3
@@ -997,7 +998,7 @@ getCov <- function(mdata) {
covstart <- NA
covend <- NA
}
-
+
return(list(ncov = ncov, covnames = covnames, covstart = covstart, covend = covend))
}
@@ -1046,11 +1047,11 @@ checkRequiredPackages <- function(pkg, repos = "CRAN", quietly = TRUE) {
} # nope, still didn't install
}
}
-
+
msg <- pkg %>%
- map_chr(managePkgs) %>%
- keep(~ . != "ok")
-
+ map_chr(managePkgs) %>%
+ keep(~ . != "ok")
+
if (length(msg) > 0) {
if (!quietly) {
cat(
@@ -1106,8 +1107,8 @@ obsStatus <- function(data) {
# import recycled text into documentation
template <- function(name) {
insert <- readLines(paste0("man-roxygen/", name, ".R")) %>%
- stringr::str_replace("#' ", "") %>%
- stringr::str_replace("
", " \n")
+ stringr::str_replace("#' ", "") %>%
+ stringr::str_replace("
", " \n")
insert <- c(insert, " \n")
insert <- paste(insert, collapse = " ")
return(insert)
@@ -1120,122 +1121,124 @@ template <- function(name) {
# modified from Hmisc functions
-wtd.table <- function(x, weights = NULL,
- type = c("list", "table"),
- normwt = TRUE,
- na.rm = TRUE) {
- type <- match.arg(type)
- if (!length(weights)) {
- weights <- rep(1, length(x))
- }
- isdate <- lubridate::is.Date(x)
- ax <- attributes(x)
- ax$names <- NULL
- if (is.character(x)) {
- x <- as.factor(x)
- }
- lev <- levels(x)
- x <- unclass(x)
- if (na.rm) {
- s <- !is.na(x + weights)
- x <- x[s, drop = FALSE]
- weights <- weights[s]
- }
- n <- length(x)
- if (normwt) {
- weights <- weights * length(x) / sum(weights)
- }
- i <- order(x)
- x <- x[i]
- weights <- weights[i]
- if (anyDuplicated(x)) {
- weights <- tapply(weights, x, sum)
- if (length(lev)) {
- levused <- lev[sort(unique(x))]
- if ((length(weights) > length(levused)) && any(is.na(weights))) {
- weights <- weights[!is.na(weights)]
- }
- if (length(weights) != length(levused)) {
- stop("program logic error")
- }
- names(weights) <- levused
+wtd.table <- function(
+ x, weights = NULL,
+ type = c("list", "table"),
+ normwt = TRUE,
+ na.rm = TRUE) {
+ type <- match.arg(type)
+ if (!length(weights)) {
+ weights <- rep(1, length(x))
+ }
+ isdate <- lubridate::is.Date(x)
+ ax <- attributes(x)
+ ax$names <- NULL
+ if (is.character(x)) {
+ x <- as.factor(x)
+ }
+ lev <- levels(x)
+ x <- unclass(x)
+ if (na.rm) {
+ s <- !is.na(x + weights)
+ x <- x[s, drop = FALSE]
+ weights <- weights[s]
+ }
+ n <- length(x)
+ if (normwt) {
+ weights <- weights * length(x) / sum(weights)
+ }
+ i <- order(x)
+ x <- x[i]
+ weights <- weights[i]
+ if (anyDuplicated(x)) {
+ weights <- tapply(weights, x, sum)
+ if (length(lev)) {
+ levused <- lev[sort(unique(x))]
+ if ((length(weights) > length(levused)) && any(is.na(weights))) {
+ weights <- weights[!is.na(weights)]
}
- if (!length(names(weights))) {
+ if (length(weights) != length(levused)) {
stop("program logic error")
}
- if (type == "table") {
- return(weights)
- }
- x <- all_is_numeric(names(weights), "vector")
- if (isdate) {
- attributes(x) <- c(attributes(x), ax)
- }
- names(weights) <- NULL
- return(list(x = x, sum.of.weights = weights))
+ names(weights) <- levused
+ }
+ if (!length(names(weights))) {
+ stop("program logic error")
}
- xx <- x
+ if (type == "table") {
+ return(weights)
+ }
+ x <- all_is_numeric(names(weights), "vector")
if (isdate) {
- attributes(xx) <- c(attributes(xx), ax)
+ attributes(x) <- c(attributes(x), ax)
}
- if (type == "list") {
- list(x = if (length(lev)) lev[x] else xx, sum.of.weights = weights)
+ names(weights) <- NULL
+ return(list(x = x, sum.of.weights = weights))
+ }
+ xx <- x
+ if (isdate) {
+ attributes(xx) <- c(attributes(xx), ax)
+ }
+ if (type == "list") {
+ list(x = if (length(lev)) lev[x] else xx, sum.of.weights = weights)
+ } else {
+ names(weights) <- if (length(lev)) {
+ lev[x]
} else {
- names(weights) <- if (length(lev)) {
- lev[x]
- } else {
- xx
- }
- weights
+ xx
}
+ weights
}
-
- wtd.mean <- function(x, weights = NULL, normwt = "ignored", na.rm = TRUE) {
- if (!length(weights)) {
- return(mean(x, na.rm = na.rm))
- }
- if (na.rm) {
- s <- !is.na(x + weights)
- x <- x[s]
- weights <- weights[s]
- }
- sum(weights * x) / sum(weights)
- }
-
-
- wtd.quantile <- function(x, weights = NULL, probs = c(0, 0.25, 0.5, 0.75, 1),
- normwt = TRUE,
- na.rm = TRUE) {
- if (!length(weights)) {
- return(quantile(x, probs = probs, na.rm = na.rm))
- }
-
- if (any(probs < 0 | probs > 1)) {
- cli::cli_abort("Probabilities must be between 0 and 1 inclusive")
- }
- nams <- paste(format(round(probs * 100, if (length(probs) >
+}
+
+wtd.mean <- function(x, weights = NULL, normwt = "ignored", na.rm = TRUE) {
+ if (!length(weights)) {
+ return(mean(x, na.rm = na.rm))
+ }
+ if (na.rm) {
+ s <- !is.na(x + weights)
+ x <- x[s]
+ weights <- weights[s]
+ }
+ sum(weights * x) / sum(weights)
+}
+
+
+wtd.quantile <- function(
+ x, weights = NULL, probs = c(0, 0.25, 0.5, 0.75, 1),
+ normwt = TRUE,
+ na.rm = TRUE) {
+ if (!length(weights)) {
+ return(quantile(x, probs = probs, na.rm = na.rm))
+ }
+
+ if (any(probs < 0 | probs > 1)) {
+ cli::cli_abort("Probabilities must be between 0 and 1 inclusive")
+ }
+ nams <- paste(format(round(probs * 100, if (length(probs) >
1) {
- 2 - log10(diff(range(probs)))
- } else {
- 2
- })), "%", sep = "")
- i <- is.na(weights) | weights == 0
- if (any(i)) {
- x <- x[!i]
- weights <- weights[!i]
- }
-
- w <- wtd.table(x, weights,
- na.rm = na.rm, normwt = normwt,
- type = "list"
- )
- x <- w$x
- wts <- w$sum.of.weights
- n <- sum(wts)
- order <- 1 + (n - 1) * probs
- low <- pmax(floor(order), 1)
- high <- pmin(low + 1, n)
- order <- order %% 1
- allq <- approx(cumsum(wts), x,
+ 2 - log10(diff(range(probs)))
+ } else {
+ 2
+ })), "%", sep = "")
+ i <- is.na(weights) | weights == 0
+ if (any(i)) {
+ x <- x[!i]
+ weights <- weights[!i]
+ }
+
+ w <- wtd.table(x, weights,
+ na.rm = na.rm, normwt = normwt,
+ type = "list"
+ )
+ x <- w$x
+ wts <- w$sum.of.weights
+ n <- sum(wts)
+ order <- 1 + (n - 1) * probs
+ low <- pmax(floor(order), 1)
+ high <- pmin(low + 1, n)
+ order <- order %% 1
+ allq <- approx(cumsum(wts), x,
xout = c(low, high), method = "constant",
f = 1, rule = 2
)$y
@@ -1245,311 +1248,316 @@ wtd.table <- function(x, weights = NULL,
return(quantiles)
}
-wtd.var <- function(x, weights = NULL,
- normwt = TRUE,
- na.rm = TRUE,
- method = c("unbiased", "ML")) {
- if (any(weights == 1)) {
- return(0)
- }
-
- method <- match.arg(method)
- if (!length(weights)) {
- if (na.rm) {
- x <- x[!is.na(x)]
- }
- return(var(x))
- }
+wtd.var <- function(
+ x, weights = NULL,
+ normwt = TRUE,
+ na.rm = TRUE,
+ method = c("unbiased", "ML")) {
+ if (any(weights == 1)) {
+ return(0)
+ }
+
+ method <- match.arg(method)
+ if (!length(weights)) {
if (na.rm) {
- s <- !is.na(x + weights)
- x <- x[s]
- weights <- weights[s]
- }
- if (normwt) {
- weights <- weights * length(x) / sum(weights)
- }
- if (normwt || method == "ML") {
- return(as.numeric(stats::cov.wt(cbind(x), weights, method = method)$cov))
+ x <- x[!is.na(x)]
}
- sw <- sum(weights)
- if (sw <= 1) {
- cli::cli_warn("only one effective observation; variance estimate undefined")
- }
- xbar <- sum(weights * x) / sw
- sum(weights * ((x - xbar)^2)) / (sw - 1)
- }
-
-
-
- # Check if all values numeric ---------------------------------------------
-
- #' @title Check if all values are numeric
- #' @description
- #' `r lifecycle::badge("stable")`
- #' Checks if all values in a vector are numeric.
- #' @details
- #' The function checks if all values in a vector are numeric.
- #' It can be used to check if a vector contains only numeric values.
- #' It can also be used to check if a vector contains any non-numeric values.
- #' @param x A vector to check.
- #' @param what A character string indicating what to return.
- #' Can be "test", "vector", or "nonnum".
- #' The default is "test".
- #' @param extras A character vector of extra values to exclude from the check.
- #' The default is c(".", "NA").
- #' @return A logical value indicating if all values are numeric.
- #' If `what` is "vector", a numeric vector is returned.
- #' If `what` is "nonnum", a character vector of non-numeric values is returned.
- #' If `what` is "test", a logical value is returned.
- #' @export
- #' @examples
- #' \dontrun{
- #' all_is_numeric(c("1", "2", "3"))
- #' all_is_numeric(c("1", "2", "a"))
- #' all_is_numeric(c("1", "2", "3"), what = "vector")
- #' all_is_numeric(c("1", "2", "a"), what = "nonnum")
- #' }
- all_is_numeric <- function(x, what = c("test", "vector", "nonnum"), extras = c(
- ".",
- "NA"
- )) {
- what <- match.arg(what)
- x <- sub("[[:space:]]+$", "", x)
- x <- sub("^[[:space:]]+", "", x)
- xs <- x[!x %in% c("", extras)]
- if (!length(xs) || all(is.na(x))) {
- return(switch(what,
- test = FALSE,
- vector = x,
- nonnum = x[0]
- ))
- }
- isnon <- suppressWarnings(!is.na(xs) & is.na(as.numeric(xs)))
- isnum <- !any(isnon)
- switch(what,
- test = isnum,
- vector = if (isnum) suppressWarnings(as.numeric(x)) else x,
- nonnum = xs[isnon]
- )
+ return(var(x))
}
-
-
-
-
- # Save Flextable ---------------------------------------------------------
-
- #' @title Save a flextable object to a file
- #' @description
- #' `r lifecycle::badge("stable")`
- #' Saves flextable objects to a file based on the `file` attribute
- #' in the object, set when the flextable generator function is called.
- #' Allowable file types are 'docx', 'pptx', 'html', 'png', and 'svg'.
- #' @param x A [flextable::flextable] object.
- #' @return A message indicating the file was saved.
- #' @export
- #' @keywords internal
-
- save_flextable <- function(x) {
- # check if x is a flextable
- if (!inherits(x, "flextable")) {
- cli::cli_abort("{.arg x} must be a flextable object.")
- }
-
- file <- attr(x, "file")
- if (!is.null(file)) {
- # get file extension
- ext <- stringr::str_match(file, "\\.(.*)$")[2]
-
- # save flextable based on file extension
- if (ext %in% c("docx", "doc")) {
- flextable::save_as_docx(x, path = file)
- } else if (ext %in% c("pptx", "ppt")) {
- flextable::save_as_pptx(x, path = file)
- } else if (ext %in% c("html", "htm")) {
- flextable::save_as_html(x, path = file)
- } else if (ext %in% c("png", "svg")) {
- flextable::save_as_image(x, path = file)
- } else {
- cli::cli_abort("File type not recognized. Choose from 'docx', 'pptx', 'html', 'png', or 'svg'.")
- }
-
- cli::cli_inform(paste("The file", file, "was saved to", getwd(), "."))
+ if (na.rm) {
+ s <- !is.na(x + weights)
+ x <- x[s]
+ weights <- weights[s]
+ }
+ if (normwt) {
+ weights <- weights * length(x) / sum(weights)
+ }
+ if (normwt || method == "ML") {
+ return(as.numeric(stats::cov.wt(cbind(x), weights, method = method)$cov))
+ }
+ sw <- sum(weights)
+ if (sw <= 1) {
+ cli::cli_warn("only one effective observation; variance estimate undefined")
+ }
+ xbar <- sum(weights * x) / sw
+ sum(weights * ((x - xbar)^2)) / (sw - 1)
+}
+
+
+
+# Check if all values numeric ---------------------------------------------
+
+#' @title Check if all values are numeric
+#' @description
+#' `r lifecycle::badge("stable")`
+#' Checks if all values in a vector are numeric.
+#' @details
+#' The function checks if all values in a vector are numeric.
+#' It can be used to check if a vector contains only numeric values.
+#' It can also be used to check if a vector contains any non-numeric values.
+#' @param x A vector to check.
+#' @param what A character string indicating what to return.
+#' Can be "test", "vector", or "nonnum".
+#' The default is "test".
+#' @param extras A character vector of extra values to exclude from the check.
+#' The default is c(".", "NA").
+#' @return A logical value indicating if all values are numeric.
+#' If `what` is "vector", a numeric vector is returned.
+#' If `what` is "nonnum", a character vector of non-numeric values is returned.
+#' If `what` is "test", a logical value is returned.
+#' @export
+#' @examples
+#' \dontrun{
+#' all_is_numeric(c("1", "2", "3"))
+#' all_is_numeric(c("1", "2", "a"))
+#' all_is_numeric(c("1", "2", "3"), what = "vector")
+#' all_is_numeric(c("1", "2", "a"), what = "nonnum")
+#' }
+all_is_numeric <- function(x, what = c("test", "vector", "nonnum"), extras = c(
+ ".",
+ "NA"
+ )) {
+ what <- match.arg(what)
+ x <- sub("[[:space:]]+$", "", x)
+ x <- sub("^[[:space:]]+", "", x)
+ xs <- x[!x %in% c("", extras)]
+ if (!length(xs) || all(is.na(x))) {
+ return(switch(what,
+ test = FALSE,
+ vector = x,
+ nonnum = x[0]
+ ))
+ }
+ isnon <- suppressWarnings(!is.na(xs) & is.na(as.numeric(xs)))
+ isnum <- !any(isnon)
+ switch(what,
+ test = isnum,
+ vector = if (isnum) suppressWarnings(as.numeric(x)) else x,
+ nonnum = xs[isnon]
+ )
+}
+
+
+
+
+# Save Flextable ---------------------------------------------------------
+
+#' @title Save a flextable object to a file
+#' @description
+#' `r lifecycle::badge("stable")`
+#' Saves flextable objects to a file based on the `file` attribute
+#' in the object, set when the flextable generator function is called.
+#' Allowable file types are 'docx', 'pptx', 'html', 'png', and 'svg'.
+#' @param x A [flextable::flextable] object.
+#' @return A message indicating the file was saved.
+#' @export
+#' @keywords internal
+
+save_flextable <- function(x) {
+ # check if x is a flextable
+ if (!inherits(x, "flextable")) {
+ cli::cli_abort("{.arg x} must be a flextable object.")
+ }
+
+ file <- attr(x, "file")
+ if (!is.null(file)) {
+ # get file extension
+ ext <- stringr::str_match(file, "\\.(.*)$")[2]
+
+ # save flextable based on file extension
+ if (ext %in% c("docx", "doc")) {
+ flextable::save_as_docx(x, path = file)
+ } else if (ext %in% c("pptx", "ppt")) {
+ flextable::save_as_pptx(x, path = file)
+ } else if (ext %in% c("html", "htm")) {
+ flextable::save_as_html(x, path = file)
+ } else if (ext %in% c("png", "svg")) {
+ flextable::save_as_image(x, path = file)
+ } else {
+ cli::cli_abort("File type not recognized. Choose from 'docx', 'pptx', 'html', 'png', or 'svg'.")
}
-
- return(invisible(x))
- }
-
-
-
- # Ask with warning --------------------------------------------------------
-
- #' @title Ask with warning
- #' @description Get user input in warning situation
- #' @details Combines the [cli::cli_text] function with [readline].
- #' @param text The warning text.
- #' @param prompt The prompt preceding user input. Default is ">>".
- #' @param ... Additional parameters which could be passed to [cli::cli_text].
- #' @return The value of the user response
- #' @export
- #' @keywords internal
- #'
- cli_ask <- function(text, prompt = ">> ", ...) {
- cli::cli_text(text, ...)
- ans <- readline(prompt = prompt)
- return(ans)
- }
-
-
- # Function to Character ---------------------------------------------------
-
- #' @title Convert a function to a character string
- #' @keywords internal
- func_to_char <- function(fun){
- deparse(fun, width.cutoff = 500L) %>%
+
+ cli::cli_inform(paste("The file", file, "was saved to", getwd(), "."))
+ }
+
+ return(invisible(x))
+}
+
+
+
+# Ask with warning --------------------------------------------------------
+
+#' @title Ask with warning
+#' @description Get user input in warning situation
+#' @details Combines the [cli::cli_text] function with [readline].
+#' @param text The warning text.
+#' @param prompt The prompt preceding user input. Default is ">>".
+#' @param ... Additional parameters which could be passed to [cli::cli_text].
+#' @return The value of the user response
+#' @export
+#' @keywords internal
+#'
+cli_ask <- function(text, prompt = ">> ", ...) {
+ cli::cli_text(text, ...)
+ ans <- readline(prompt = prompt)
+ return(ans)
+}
+
+
+# Function to Character ---------------------------------------------------
+
+#' @title Convert a function to a character string
+#' @keywords internal
+func_to_char <- function(fun) {
+ deparse(fun, width.cutoff = 500L) %>%
stringr::str_trim("left") %>%
purrr::discard(\(x) stringr::str_detect(x, "function|\\{|\\}"))
- }
-
-
- # Round to x digits ---------------------------------------------------
-
- #' @title Round to x digits
- #' @description
- #' `r lifecycle::badge("stable")`
- #' Rounds a numeric value to a specified number of digits for display in flextables and plots.
- #' @details Uses [base::format] and [base::round] to round a numeric value to a specified number of digits.
- #' @param x A numeric value to be rounded.
- #' @param digits The number of digits to round to. Default is set using [setPMoptions].
- #' @return A character string representing the rounded value with the specified number of digits.
- #' @export
- #' @keywords internal
-
- round2 <- function(x, digits = getPMoptions("digits")) {
- if (is.null(digits) || !is.numeric(digits)) digits <- 2
- format(round(x, digits), nsmall = digits)
- }
-
-
- # Print data frame in CLI format ------------------------------------------
- #' @title Print data frame in CLI format
- #' @description
- #' `r lifecycle::badge("stable")`
- #' Prints a data frame in a format suitable for the command line interface (CLI).
- #' @details
- #' Uses [dplyr::mutate] to convert all columns to character, rounds numeric values using [round2],
- #' and formats the output using [knitr::kable] for a simple table format.
- #' The function replaces spaces with non-breaking spaces for better alignment in the CLI.
- #' @param df A data frame to be printed.
- #' @return A formatted text output of the data frame.
- #' @export
- #' @keywords internal
- cli_df <- function(df) {
-
- highlight <- attr(df, "highlight") # get columns to highlight minimums from attributes
-
- # Convert all columns to character for uniform formatting
- df_chr <- df %>% mutate(across(where(is.double), ~round2(.x))) %>%
- mutate(across(everything(), ~as.character(.x, stringsAsFactors = FALSE)))
-
-
- if (highlight){ # highlight minimums in requested columns
- # first replace minima with special formatting
- # mins <- df %>% summarize(across(c(-run, -nvar, -converged, -pval, -best), ~round2(min(.x, na.rm = TRUE)))) # get minima for each column
- mins <- df %>% summarize(across(c(-run, -nvar, -converged, -pval, -best), ~ which(.x == min(.x, na.rm = TRUE)))) %>% unlist() # get minima for each column
-
- best <- df %>% summarize(across(best, ~ which(.x == max(.x, na.rm = TRUE)))) %>% unlist() # get best for best column
-
- # create table to get the spacing
- df_tab <- knitr::kable(df_chr, format = "simple")
-
- # rebuild the data frame
- df2 <- map_vec(df_tab, \(x) str_split(x, "(?<=\\s)(?=\\S)"))
- df2 <- as.data.frame(do.call(rbind, df2))
-
- # replace minima with highlighted versions
- # first 2 rows are headers and spacers, so need to add 2 to the mins row index
- for (p in 1:length(mins)){
- df2[mins[p]+2, p+3] <- stringr::str_replace_all(df2[mins[p]+2, p+3], "(\\d+(?:\\.\\d+)?)(\\s+)", "{.red \\1}\\2")
- }
+}
+
- # for(p in 1:length(mins)){
- # df2[, p+3] <- stringr::str_replace_all(df2[, p+3], as.character(mins[p]), paste0("{.strong ", as.character(mins[p]), "}"))
- # }
- # df2$V18 <- stringr::str_replace(df2$V18, as.character(best), paste0("{.red ", as.character(best), "}"))
- df2$V17[best+2] <- stringr::str_replace(df2$V17[best+2], "(\\d+(?:\\.\\d+)?)(\\s+)", "{.red \\1}\\2")
-
- # print header
- header <- df2[1,] %>% stringr::str_replace_all(" ", "\u00A0" ) %>% paste(collapse = "")
- cli::cli_text("{.strong {header}}")
- cli::cli_div(theme = list(span.red = list(color = "red", "font-weight" = "bold")))
-
- # replace ≥2 spaces with non-breaking spaces
- for (i in 2:nrow(df2)) {
- # m <- gregexpr("\\s{2,}", df_tab[i], perl = TRUE)
- # regmatches(df_tab[i], m) <- lapply(regmatches(df_tab[i], m), function(ss) {
- # vapply(ss, function(one) {
- # paste0(rep("\u00A0", nchar(one)), collapse = "")
- # }, character(1))
- # })
- # print each row
- cli::cli_text(paste(df2[i,], collapse = "") %>% stringr::str_replace_all(" ", "\u00A0" ) %>% stringr::str_replace_all("strong\u00A0+", "strong ") %>% stringr::str_replace_all("red\u00A0+", "red "))
- }
- cli::cli_end()
- } else { # no highlighting
-
- # create table
- df_tab <- knitr::kable(df_chr, format = "simple")
-
- # print header
- header <- df_tab[1] %>% stringr::str_replace_all(" ", "\u00A0" )
- cli::cli_text("{.strong {header}}")
+# Round to x digits ---------------------------------------------------
+#' @title Round to x digits
+#' @description
+#' `r lifecycle::badge("stable")`
+#' Rounds a numeric value to a specified number of digits for display in flextables and plots.
+#' @details Uses [base::format] and [base::round] to round a numeric value to a specified number of digits.
+#' @param x A numeric value to be rounded.
+#' @param digits The number of digits to round to. Default is set using [setPMoptions].
+#' @return A character string representing the rounded value with the specified number of digits.
+#' @export
+#' @keywords internal
+
+round2 <- function(x, digits = getPMoptions("digits")) {
+ if (is.null(digits) || !is.numeric(digits)) digits <- 2
+ format(round(x, digits), nsmall = digits)
+}
+
+
+# Print data frame in CLI format ------------------------------------------
+#' @title Print data frame in CLI format
+#' @description
+#' `r lifecycle::badge("stable")`
+#' Prints a data frame in a format suitable for the command line interface (CLI).
+#' @details
+#' Uses [dplyr::mutate] to convert all columns to character, rounds numeric values using [round2],
+#' and formats the output using [knitr::kable] for a simple table format.
+#' The function replaces spaces with non-breaking spaces for better alignment in the CLI.
+#' @param df A data frame to be printed.
+#' @return A formatted text output of the data frame.
+#' @export
+#' @keywords internal
+cli_df <- function(df) {
+ highlight <- attr(df, "highlight") # get columns to highlight minimums from attributes
+
+ # Convert all columns to character for uniform formatting
+ df_chr <- df %>%
+ mutate(across(where(is.double), ~ round2(.x))) %>%
+ mutate(across(everything(), ~ as.character(.x, stringsAsFactors = FALSE)))
+
+
+ if (highlight) { # highlight minimums in requested columns
+ # first replace minima with special formatting
+ # mins <- df %>% summarize(across(c(-run, -nvar, -converged, -pval, -best), ~round2(min(.x, na.rm = TRUE)))) # get minima for each column
+ mins <- df %>%
+ summarize(across(c(-run, -nvar, -converged, -pval, -best), ~ which(.x == min(.x, na.rm = TRUE)))) %>%
+ unlist() # get minima for each column
+
+ best <- df %>%
+ summarize(across(best, ~ which(.x == max(.x, na.rm = TRUE)))) %>%
+ unlist() # get best for best column
+
+ # create table to get the spacing
+ df_tab <- knitr::kable(df_chr, format = "simple")
+
+ # rebuild the data frame
+ df2 <- map_vec(df_tab, \(x) str_split(x, "(?<=\\s)(?=\\S)"))
+ df2 <- as.data.frame(do.call(rbind, df2))
+
+ # replace minima with highlighted versions
+ # first 2 rows are headers and spacers, so need to add 2 to the mins row index
+ for (p in 1:length(mins)) {
+ df2[mins[p] + 2, p + 3] <- stringr::str_replace_all(df2[mins[p] + 2, p + 3], "(\\d+(?:\\.\\d+)?)(\\s+)", "{.red \\1}\\2")
+ }
+
+ # for(p in 1:length(mins)){
+ # df2[, p+3] <- stringr::str_replace_all(df2[, p+3], as.character(mins[p]), paste0("{.strong ", as.character(mins[p]), "}"))
+ # }
+ # df2$V18 <- stringr::str_replace(df2$V18, as.character(best), paste0("{.red ", as.character(best), "}"))
+ df2$V17[best + 2] <- stringr::str_replace(df2$V17[best + 2], "(\\d+(?:\\.\\d+)?)(\\s+)", "{.red \\1}\\2")
+
+ # print header
+ header <- df2[1, ] %>%
+ stringr::str_replace_all(" ", "\u00A0") %>%
+ paste(collapse = "")
+ cli::cli_text("{.strong {header}}")
+ cli::cli_div(theme = list(span.red = list(color = "red", "font-weight" = "bold")))
+
+ # replace ≥2 spaces with non-breaking spaces
+ for (i in 2:nrow(df2)) {
+ # m <- gregexpr("\\s{2,}", df_tab[i], perl = TRUE)
+ # regmatches(df_tab[i], m) <- lapply(regmatches(df_tab[i], m), function(ss) {
+ # vapply(ss, function(one) {
+ # paste0(rep("\u00A0", nchar(one)), collapse = "")
+ # }, character(1))
+ # })
# print each row
- for (i in 2:length(df_tab)) {
- cli::cli_text(df_tab[i] %>% stringr::str_replace_all(" ", "\u00A0" ))
- }
+ cli::cli_text(paste(df2[i, ], collapse = "") %>% stringr::str_replace_all(" ", "\u00A0") %>% stringr::str_replace_all("strong\u00A0+", "strong ") %>% stringr::str_replace_all("red\u00A0+", "red "))
}
-
- }
-
- #' @title Convert correlation matrix to covariance matrix
- #' @description
- #' `r lifecycle::badge("stable")`
- #' Converts a correlation matrix to a covariance matrix using standard deviations.
- #' @details
- #' Uses matrix multiplication to convert a correlation matrix to a covariance matrix.
- #' @param cor A correlation matrix.
- #' @param sd A vector of standard deviations corresponding to the variables in the correlation matrix.
- #' @return A covariance matrix.
- #' @export
- #' @author Michael Neely
- #'
- cor2cov <- function(cor, sd){
- cov_matrix <- diag(sd) %*% cor %*% diag(sd)
- return(cov_matrix)
- }
-
-
- #' @title Check if a matrix is positive definite
- #' @description
- #' `r lifecycle::badge("stable")`
- #' Checks if a matrix is positive definite and attempts to fix it if necessary.
- #' @param mat A covariance matrix to check.
- #' @return A positive definite covariance matrix, 1 if aborting, or -1 if unable to fix
- #' @export
- #' @author Michael Neely
- #' @keywords internal
- pos_def <- function(mat, id, source){
- # check to make sure mat (within 15 sig digits, which is in file) is pos-def and fix if necessary
- posdef <- rlang::try_fetch(eigen(signif(mat, 15)),
+ cli::cli_end()
+ } else { # no highlighting
+
+ # create table
+ df_tab <- knitr::kable(df_chr, format = "simple")
+
+ # print header
+ header <- df_tab[1] %>% stringr::str_replace_all(" ", "\u00A0")
+ cli::cli_text("{.strong {header}}")
+
+ # print each row
+ for (i in 2:length(df_tab)) {
+ cli::cli_text(df_tab[i] %>% stringr::str_replace_all(" ", "\u00A0"))
+ }
+ }
+}
+
+#' @title Convert correlation matrix to covariance matrix
+#' @description
+#' `r lifecycle::badge("stable")`
+#' Converts a correlation matrix to a covariance matrix using standard deviations.
+#' @details
+#' Uses matrix multiplication to convert a correlation matrix to a covariance matrix.
+#' @param cor A correlation matrix.
+#' @param sd A vector of standard deviations corresponding to the variables in the correlation matrix.
+#' @return A covariance matrix.
+#' @export
+#' @author Michael Neely
+#'
+cor2cov <- function(cor, sd) {
+ cov_matrix <- diag(sd) %*% cor %*% diag(sd)
+ return(cov_matrix)
+}
+
+
+#' @title Check if a matrix is positive definite
+#' @description
+#' `r lifecycle::badge("stable")`
+#' Checks if a matrix is positive definite and attempts to fix it if necessary.
+#' @param mat A covariance matrix to check.
+#' @return A positive definite covariance matrix, 1 if aborting, or -1 if unable to fix
+#' @export
+#' @author Michael Neely
+#' @keywords internal
+pos_def <- function(mat, id, source) {
+ # check to make sure mat (within 15 sig digits, which is in file) is pos-def and fix if necessary
+ posdef <- rlang::try_fetch(eigen(signif(mat, 15)),
error = function(e) {
return(list(values = 0))
}
)
ans <- NULL
if (any(posdef$values < 0)) {
-
- mat_names <- dimnames(mat)[[1]] #store for later
+ mat_names <- dimnames(mat)[[1]] # store for later
if (is.null(ans)) {
cli::cli_alert_warning("Warning: your covariance matrix is not positive definite. This is typically due to small population size.\nChoose one of the following:\n1) end simulation\n2) fix covariances\n3) set covariances to 0\n ")
ans <- readline("\n")
@@ -1561,24 +1569,22 @@ wtd.var <- function(x, weights = NULL,
if (ans == 2) {
# eigen decomposition to fix the matrix
for (j in 1:10) { # try up to 10 times
- eps <- 1e-8 # threshold for small eigenvalues
+ eps <- 1e-8 # threshold for small eigenvalues
eig <- eigen(mat)
- eig$values[eig$values < eps] <- eps # threshold small eigenvalues
+ eig$values[eig$values < eps] <- eps # threshold small eigenvalues
mat <- eig$vectors %*% diag(eig$values) %*% t(eig$vectors)
-
-
+
+
posdef <- eigen(signif(mat, 15))
-
+
if (all(posdef$values >= 0)) { # success, break out of loop
break
}
- if(j == 10) browser()
+ if (j == 10) browser()
}
posdef <- eigen(signif(mat, 15)) # last check
if (any(posdef$values < 0)) {
-
return(-1)
-
}
mat <- data.frame(mat)
names(mat) <- mat_names
@@ -1592,7 +1598,7 @@ wtd.var <- function(x, weights = NULL,
mat <- mat2
}
}
-
+
return(mat)
}
@@ -1600,7 +1606,7 @@ wtd.var <- function(x, weights = NULL,
#' @title Modify a list with another list, allowing NULL values
#' @description
#' `r lifecycle::badge("stable")`
-#' Version of [utils::modifyList()] that works with lists which have unnamed elements.
+#' Version of [utils::modifyList()] that works with lists which have unnamed elements.
#' @param x A list to be modified.
#' @param val A list of values to modify `x`.
#' @param keep.null A logical value indicating whether to keep NULL values in `val`.
@@ -1608,34 +1614,36 @@ wtd.var <- function(x, weights = NULL,
#' @return A modified list, as in [utils::modifyList()].
#' @export
#' @keywords internal
-modifyList2 <- function (x, val, keep.null = FALSE)
-{
+modifyList2 <- function(x, val, keep.null = FALSE) {
stopifnot(is.list(x), is.list(val))
names(x) <- tolower(names(x))
names(val) <- tolower(names(val))
xnames <- names(x)
vnames <- names(val)
# handle unnamed lists
- if(is.null(xnames)) xnames <- 1:length(x)
- if(is.null(vnames)) vnames <- 1:length(val)
+ if (is.null(xnames)) xnames <- 1:length(x)
+ if (is.null(vnames)) vnames <- 1:length(val)
# handle unnamed elements
xnames <- ifelse(xnames == "", as.character(seq_along(xnames)), xnames)
vnames <- ifelse(vnames == "", as.character(seq_along(vnames)), vnames)
-
+
vnames <- vnames[nzchar(vnames)]
if (keep.null) {
for (v in vnames) {
- x[v] <- if (v %in% xnames && is.list(x[[v]]) && is.list(val[[v]]))
- list(modifyList(x[[v]], val[[v]], keep.null = keep.null))
- else val[v]
+ x[v] <- if (v %in% xnames && is.list(x[[v]]) && is.list(val[[v]])) {
+ list(modifyList(x[[v]], val[[v]], keep.null = keep.null))
+ } else {
+ val[v]
+ }
}
- }
- else {
+ } else {
for (v in vnames) {
- x[[v]] <- if (v %in% xnames && is.list(x[[v]]) &&
- is.list(val[[v]]))
- modifyList2(x[[v]], val[[v]], keep.null = keep.null)
- else val[[v]]
+ x[[v]] <- if (v %in% xnames && is.list(x[[v]]) &&
+ is.list(val[[v]])) {
+ modifyList2(x[[v]], val[[v]], keep.null = keep.null)
+ } else {
+ val[[v]]
+ }
}
}
x
@@ -1649,6 +1657,6 @@ modifyList2 <- function (x, val, keep.null = FALSE)
#' @return NULL
#' @export
#' @keywords internal
-clear_build <- function(){
+clear_build <- function() {
fs::dir_delete(system.file("template", package = "Pmetrics"))
}
diff --git a/R/mod_lib.R b/R/mod_lib.R
index f625aaed6..d36bca6b0 100755
--- a/R/mod_lib.R
+++ b/R/mod_lib.R
@@ -21,8 +21,9 @@ alt_mod_lib_names <- function(){
# returns model from detected template, 0 if none, and -1 if more than one
get_found_model <- function(fun){
eqns <- as.list(body(fun)[-1])
- found_pri <- map(eqns, \(x) deparse(x) %in% mod_lib_names()) %>% unlist()
- found_alt <- map(eqns, \(x) deparse(x) %in% alt_mod_lib_names()$alt) %>% unlist()
+ expr_to_char <- \(x) paste(deparse(x, width.cutoff = 500L), collapse = "\n")
+ found_pri <- map_lgl(eqns, \(x) expr_to_char(x) %in% mod_lib_names())
+ found_alt <- map_lgl(eqns, \(x) expr_to_char(x) %in% alt_mod_lib_names()$alt)
all_found <- sum(found_pri, found_alt)
if(all_found > 1){
@@ -38,10 +39,10 @@ get_found_model <- function(fun){
}
if (any(found_pri)) { # found a primary model name
- found_model_name <- eqns[[which(found_pri)]] %>% deparse()
+ found_model_name <- expr_to_char(eqns[[which(found_pri)]])
} else { # found an alternative model name
found_model_name <- alt_mod_lib_names() %>%
- filter(alt == eqns[[which(found_alt)]] %>% deparse()) %>%
+ filter(alt == expr_to_char(eqns[[which(found_alt)]])) %>%
pull(primary)
}
diff --git a/R/model_transpiler.R b/R/model_transpiler.R
index c4f78d941..e3aa80e14 100755
--- a/R/model_transpiler.R
+++ b/R/model_transpiler.R
@@ -224,7 +224,7 @@ expr_to_rust <- function(expr, params = NULL, covs = NULL,
tem <- found$name
eqns <- as.list(body(fun)[-1])
if (length(eqns) > 0) {
- eqns_char <- map_chr(eqns, deparse)
+ eqns_char <- map_chr(eqns, \(x) paste(deparse(x, width.cutoff = 500L), collapse = "\n"))
# check for ODE, which should not be present
if (any(stringr::str_detect(eqns_char, regex("dx\\[\\d+\\]", ignore_case = FALSE)))) {
cli::cli_abort(c(
diff --git a/tests/testthat/test-Examples.R b/tests/testthat/test-Examples.R
index e34c4916c..b055e0705 100755
--- a/tests/testthat/test-Examples.R
+++ b/tests/testthat/test-Examples.R
@@ -190,6 +190,44 @@ test_that("Basic model fitting", {
expect_output(exFit$run(intern = T), "The run did not converge before the last cycle.")
})
+test_that("Analytical models allow multi-line secondary conditionals", {
+ mod <- PM_model$new(
+ pri = list(
+ Ka = ab(0.5, 6),
+ Ke = ab(0.1, 1.5),
+ v0 = ab(25, 120)
+ ),
+ cov = list(
+ gender = interp("none"),
+ wt = interp()
+ ),
+ sec = function() {
+ v = v0 * wt
+ if (gender < 1) {
+ v = v0 * 0.8
+ }
+ },
+ eqn = function() {
+ two_comp_bolus
+ },
+ lag = function() {
+ lag[1] = 0
+ },
+ out = function() {
+ y[1] = x[2] / v
+ },
+ err = list(
+ proportional(5, c(0.1, 0.15, 0, 0))
+ ),
+ compile = FALSE
+ )
+
+ expect_s3_class(mod, "PM_model")
+ sec_code <- paste(deparse(mod$arg_list$sec), collapse = "\n")
+ expect_true(grepl("if (gender < 1)", sec_code, fixed = TRUE))
+ expect_true(grepl("v = v0 * wt", sec_code, fixed = TRUE))
+})
+
# test_that("Load model",{
# exRes <- PM_load(1)
# expect_equal(exRes$data$data,PM_data$new(data = "ex.csv", quiet=T)$data, ignore_attr = T)