From 52240fb57f6510e71654f5506adddf0c58e049ce Mon Sep 17 00:00:00 2001 From: Stefan Ulbrich Date: Wed, 20 Apr 2022 22:59:31 +0200 Subject: [PATCH 1/7] Initial attempt at updating dependencies --- CHANGELOG.md | 3 + Cargo.lock | 364 ++++++++++++++++++++++++++++++++++------------ Cargo.toml | 20 +-- src/lib.rs | 2 +- src/ndarrayext.rs | 18 +-- src/sprsext.rs | 13 +- src/umv/make.rs | 9 +- 7 files changed, 301 insertions(+), 128 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 79067f1..d624ff0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Changelog +## v0.4.0 (2022) +* Update to ndarray 0.15 and sprs 0.11 + ## v0.3.0 (22.03.2020) * Add `Real` pub trait. Trait `Real` is only implemented for `f32` and `f64`, diff --git a/Cargo.lock b/Cargo.lock index 9af3d52..19b4ea0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,225 +1,409 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "alga" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f823d037a7ec6ea2197046bafd4ae150e6bc36f9ca347404f46a46823fa84f2" dependencies = [ - "approx 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libm 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "num-complex 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "approx 0.3.2", + "num-complex 0.2.4", + "num-traits", ] [[package]] name = "almost" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3aa2999eb46af81abb65c2d30d446778d7e613b60bbf4e174a027e80f90a3c14" [[package]] name = "approx" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0e60b75072ecd4168020818c0107f2857bb6c4e64252d8d3983f6263b40a5c3" +dependencies = [ + "num-traits", +] + +[[package]] +name = "approx" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f2a05fd1bd10b2527e20a2cd32d8873d115b8b39fe219ee25f42a8aca6ba278" +dependencies = [ + "num-traits", +] + +[[package]] +name = "approx" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" dependencies = [ - "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits", ] [[package]] name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "crossbeam-channel" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aaa7bd5fb665c6864b5f963dd9097905c54125909c7aa94c9e18507cdbe6c53" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1145cf131a2c6ba0615079ab6a638f7e1973ac9c2634fcbeaaad6114246efe8c" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "lazy_static", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38" +dependencies = [ + "cfg-if", + "lazy_static", +] [[package]] name = "csaps" -version = "0.3.0" +version = "0.4.0" dependencies = [ - "almost 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "approx 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ndarray 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "sprs 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sprs-ldl 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "thiserror 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "almost", + "approx 0.5.1", + "itertools", + "ndarray 0.15.4", + "num-traits", + "sprs 0.11.0", + "sprs-ldl", + "thiserror", ] [[package]] name = "either" -version = "1.5.3" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" [[package]] -name = "itertools" -version = "0.8.2" +name = "hermit-abi" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" dependencies = [ - "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", ] [[package]] name = "itertools" -version = "0.9.0" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" dependencies = [ - "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "either", ] +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.124" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21a41fed9d98f27ab1c6d161da622a4fa35e8a54a8adc24bbf3ddd0ef70b0e50" + [[package]] name = "libm" -version = "0.1.4" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33a33a362ce288760ec6a508b94caaec573ae7d3bbbd91b87aa0bad4456839db" [[package]] name = "matrixmultiply" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "916806ba0031cd542105d916a97c8572e1fa6dd79c9c51e7eb43a09ec2dd84c1" dependencies = [ - "rawpointer 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rawpointer", +] + +[[package]] +name = "matrixmultiply" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "add85d4dd35074e6fedc608f8c8f513a3548619a9024b751949ef0e8e45a4d84" +dependencies = [ + "rawpointer", +] + +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", ] [[package]] name = "ndarray" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c0d5c9540a691d153064dc47a4db2504587a75eae07bf1d73f7a596ebc73c04" dependencies = [ - "approx 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "matrixmultiply 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "num-complex 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "rawpointer 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "matrixmultiply 0.2.4", + "num-complex 0.3.1", + "num-integer", + "num-traits", + "rawpointer", +] + +[[package]] +name = "ndarray" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dec23e6762830658d2b3d385a75aa212af2f67a4586d4442907144f3bb6a1ca8" +dependencies = [ + "approx 0.4.0", + "matrixmultiply 0.3.2", + "num-complex 0.4.0", + "num-integer", + "num-traits", + "rawpointer", ] [[package]] name = "num-complex" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95" dependencies = [ - "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "747d632c0c558b87dbabbe6a82f3b4ae03720d0646ac5b7b4dae89394be5f2c5" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26873667bbbb7c5182d4a37c1add32cdf09f841af72da53318fdb81543c15085" +dependencies = [ + "num-traits", ] [[package]] name = "num-integer" -version = "0.1.42" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" dependencies = [ - "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg", + "num-traits", ] [[package]] name = "num-traits" -version = "0.1.43" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" dependencies = [ - "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg", + "libm", ] [[package]] -name = "num-traits" -version = "0.2.11" +name = "num_cpus" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" dependencies = [ - "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hermit-abi", + "libc", ] [[package]] name = "proc-macro2" -version = "1.0.9" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1" dependencies = [ - "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid", ] [[package]] name = "quote" -version = "1.0.3" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" dependencies = [ - "proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", ] [[package]] name = "rawpointer" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" + +[[package]] +name = "rayon" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd249e82c21598a9a426a4e00dd7adc1d640b22445ec8545feef801d1a74c221" +dependencies = [ + "autocfg", + "crossbeam-deque", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f51245e1e62e1f1629cbfec37b5793bbabcaeb90f30e94d2ba03564687353e4" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "num_cpus", +] + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "smallvec" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" + +[[package]] +name = "sprs" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9fc9999597a9e160f7aae4ab43f395365b396cfd971406ffb4b066679a81ca3" +dependencies = [ + "alga", + "ndarray 0.14.0", + "num-complex 0.2.4", + "num-traits", + "num_cpus", + "rayon", + "smallvec", +] [[package]] name = "sprs" -version = "0.7.1" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea71e48b3eab4c4b153e8e35dcaeac132720809ef68359097b8cb54a18edd70" dependencies = [ - "alga 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", - "ndarray 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num-complex 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", + "alga", + "ndarray 0.15.4", + "num-complex 0.4.0", + "num-traits", + "num_cpus", + "rayon", + "smallvec", ] [[package]] name = "sprs-ldl" -version = "0.5.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a365b7b64559c3b7a498347e93b863bf26cd855f55f5f41be3a63f4bfc81f4f" dependencies = [ - "num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", - "sprs 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits", + "sprs 0.10.0", ] [[package]] name = "syn" -version = "1.0.17" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d" dependencies = [ - "proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote", + "unicode-xid", ] [[package]] name = "thiserror" -version = "1.0.12" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" dependencies = [ - "thiserror-impl 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.12" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" dependencies = [ - "proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote", + "syn", ] [[package]] name = "unicode-xid" -version = "0.2.0" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" - -[metadata] -"checksum alga 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "658f9468113d34781f6ca9d014d174c74b73de870f1e0e3ad32079bbab253b19" -"checksum almost 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3aa2999eb46af81abb65c2d30d446778d7e613b60bbf4e174a027e80f90a3c14" -"checksum approx 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0e60b75072ecd4168020818c0107f2857bb6c4e64252d8d3983f6263b40a5c3" -"checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" -"checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" -"checksum itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484" -"checksum itertools 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" -"checksum libm 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a" -"checksum matrixmultiply 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d4f7ec66360130972f34830bfad9ef05c6610a43938a467bcc9ab9369ab3478f" -"checksum ndarray 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "25b001fc2f5df269365fb77bd8396ce6b1f61c9848f7f088c25e57494bacc57b" -"checksum num-complex 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95" -"checksum num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba" -"checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" -"checksum num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096" -"checksum proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6c09721c6781493a2a492a96b5a5bf19b65917fe6728884e7c44dd0c60ca3435" -"checksum quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f" -"checksum rawpointer 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" -"checksum sprs 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ec63571489873d4506683915840eeb1bb16b3198ee4894cc6f2fe3013d505e56" -"checksum sprs-ldl 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4208c8a54c86b8a49c386b5219840ceb93e5250208d0f48dadab42bd5efe3eb" -"checksum syn 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "0df0eb663f387145cab623dea85b09c2c5b4b0aef44e945d928e682fce71bb03" -"checksum thiserror 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)" = "268c0f167625b8b0cc90a91787b158a372b4edadb31d6e20479dc787309defad" -"checksum thiserror-impl 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a3ecbaa927a1d5a73d14a20af52463fa433c0727d07ef5e208f0546841d2efd" -"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" diff --git a/Cargo.toml b/Cargo.toml index 459ac6b..4979b09 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "csaps" -version = "0.3.0" +version = "0.4.0" authors = ["Eugene Prilepin "] description = "Cubic spline approximation (smoothing)" @@ -13,7 +13,7 @@ documentation = "https://docs.rs/csaps" readme = "README.md" license = "MIT" -edition = "2018" +edition = "2021" [badges] @@ -22,14 +22,14 @@ coveralls = { repository = "espdev/csaps-rs", branch = "master", service = "gith [dependencies] -num-traits = "0.2.11" -ndarray = "0.13.0" -sprs = "0.7.1" -sprs-ldl = "0.5.0" +num-traits = "0.2.14" +ndarray = "0.15.4" +sprs = "0.11.0" +sprs-ldl = "0.9.0" # 0.10.0 not published https://github.com/vbarrielle/sprs/issues/293 almost = "0.2.0" -itertools = "0.9.0" -thiserror = "1.0.12" +itertools = "0.10.3" +thiserror = "1.0.30" [dev-dependencies] -approx = "0.3.2" -ndarray = {version = "0.13", features = ["approx"]} +approx = "0.5.1" +ndarray = {version = "0.15.4", features = ["approx"]} diff --git a/src/lib.rs b/src/lib.rs index 7b9fcc7..421a3be 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -32,7 +32,7 @@ //! Univariate data auto smoothing //! //! ```rust -//! use ndarray::{array, Array1}; +//! use ndarray::prelude::*; //! use csaps::CubicSmoothingSpline; //! //! let x = array![1., 2., 3., 4.]; diff --git a/src/ndarrayext.rs b/src/ndarrayext.rs index 6c25d4d..3f9ae0e 100644 --- a/src/ndarrayext.rs +++ b/src/ndarrayext.rs @@ -1,19 +1,7 @@ -use ndarray::{ - Dimension, - IntoDimension, - Axis, - Slice, - Ix1, - Ix2, - AsArray, - Array, - Array1, - ArrayView, - ArrayView2, - s -}; -use almost; + +// use almost; +use ndarray::{prelude::*, IntoDimension, Slice}; use itertools::Itertools; use crate::{ diff --git a/src/sprsext.rs b/src/sprsext.rs index 890ee50..c5473c3 100644 --- a/src/sprsext.rs +++ b/src/sprsext.rs @@ -1,8 +1,8 @@ use std::iter::FromIterator; -use ndarray::{Array1, Array2, Axis, s}; +use ndarray::{prelude::*}; -use sprs::{TriMat, CsMat, Shape}; +use sprs::{CsMat, TriMat, Shape, IndPtrBase}; use sprs_ldl::LdlNumeric; use crate::Real; @@ -91,7 +91,7 @@ pub fn diagonal(m: &CsMat, k: isize) -> Array1 fn diagonal_csr(k: isize, shape: Shape, - indptr: &[usize], + indptr: IndPtrBase, indices: &[usize], data: &[T]) -> Array1 where @@ -100,7 +100,7 @@ fn diagonal_csr(k: isize, let (rows, cols) = shape; if k <= -(rows as isize) || k >= cols as isize { - panic!(format!("k ({}) exceeds matrix dimensions {:?}", k, shape)); + panic!("k ({}) exceeds matrix dimensions {:?}", k, shape); } let first_row = if k >= 0 { 0 } else { (-k) as usize }; @@ -112,12 +112,11 @@ fn diagonal_csr(k: isize, for i in 0..diag_size { let row = first_row + i; let col = first_col + i; - let row_begin = indptr[row]; - let row_end = indptr[row + 1]; + let row = indptr.outer_inds_sz(row); let mut diag_value = T::zero(); - for j in row_begin..row_end { + for j in row.start..row.end { if indices[j] == col { diag_value += data[j]; } diff --git a/src/umv/make.rs b/src/umv/make.rs index 8db8824..a614978 100644 --- a/src/umv/make.rs +++ b/src/umv/make.rs @@ -1,5 +1,4 @@ -use ndarray::{Dimension, Axis, Array1, Array2, s, stack}; -use sprs::binop::scalar_mul_mat as sprs_mul_s; +use ndarray::{prelude::*, stack}; use crate::{ Real, @@ -96,8 +95,8 @@ impl<'a, T, D> CubicSmoothingSpline<'a, T, D> // Solve linear system Ax = b for the 2nd derivatives let usol = { let a = { - let a1 = sprs_mul_s(&qtwq, s1); - let a2 = sprs_mul_s(&r, smooth); + let a1 = &qtwq * s1; + let a2 = &r * smooth; drop(qtwq); drop(r); @@ -125,7 +124,7 @@ impl<'a, T, D> CubicSmoothingSpline<'a, T, D> let diags_w = (ones(pcount) / weights).insert_axis(Axis(0)); let w = sprsext::diags(diags_w, &[0], (pcount, pcount)); - let wd2 = &sprs_mul_s(&w, s1) * &d2; + let wd2 = &w * &d2; drop(d1); drop(d2); From ef564a28d33d84835d9a90f575e1ef37d577a44d Mon Sep 17 00:00:00 2001 From: Stefan Ulbrich Date: Thu, 21 Apr 2022 21:02:06 +0200 Subject: [PATCH 2/7] Fix sparse matrix dependency --- Cargo.lock | 64 +++++++----------------------------------------------- Cargo.toml | 4 ++-- 2 files changed, 10 insertions(+), 58 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 19b4ea0..1b73f05 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -110,9 +110,9 @@ dependencies = [ "almost", "approx 0.5.1", "itertools", - "ndarray 0.15.4", + "ndarray", "num-traits", - "sprs 0.11.0", + "sprs", "sprs-ldl", "thiserror", ] @@ -159,15 +159,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33a33a362ce288760ec6a508b94caaec573ae7d3bbbd91b87aa0bad4456839db" -[[package]] -name = "matrixmultiply" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "916806ba0031cd542105d916a97c8572e1fa6dd79c9c51e7eb43a09ec2dd84c1" -dependencies = [ - "rawpointer", -] - [[package]] name = "matrixmultiply" version = "0.3.2" @@ -186,19 +177,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "ndarray" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c0d5c9540a691d153064dc47a4db2504587a75eae07bf1d73f7a596ebc73c04" -dependencies = [ - "matrixmultiply 0.2.4", - "num-complex 0.3.1", - "num-integer", - "num-traits", - "rawpointer", -] - [[package]] name = "ndarray" version = "0.15.4" @@ -206,7 +184,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dec23e6762830658d2b3d385a75aa212af2f67a4586d4442907144f3bb6a1ca8" dependencies = [ "approx 0.4.0", - "matrixmultiply 0.3.2", + "matrixmultiply", "num-complex 0.4.0", "num-integer", "num-traits", @@ -223,15 +201,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "num-complex" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "747d632c0c558b87dbabbe6a82f3b4ae03720d0646ac5b7b4dae89394be5f2c5" -dependencies = [ - "num-traits", -] - [[package]] name = "num-complex" version = "0.4.0" @@ -331,29 +300,13 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" -[[package]] -name = "sprs" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9fc9999597a9e160f7aae4ab43f395365b396cfd971406ffb4b066679a81ca3" -dependencies = [ - "alga", - "ndarray 0.14.0", - "num-complex 0.2.4", - "num-traits", - "num_cpus", - "rayon", - "smallvec", -] - [[package]] name = "sprs" version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea71e48b3eab4c4b153e8e35dcaeac132720809ef68359097b8cb54a18edd70" +source = "git+https://github.com/vbarrielle/sprs?rev=3895313#38953136024e1814895b560951f41d0e10c42d16" dependencies = [ "alga", - "ndarray 0.15.4", + "ndarray", "num-complex 0.4.0", "num-traits", "num_cpus", @@ -363,12 +316,11 @@ dependencies = [ [[package]] name = "sprs-ldl" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a365b7b64559c3b7a498347e93b863bf26cd855f55f5f41be3a63f4bfc81f4f" +version = "0.10.0" +source = "git+https://github.com/vbarrielle/sprs?rev=3895313#38953136024e1814895b560951f41d0e10c42d16" dependencies = [ "num-traits", - "sprs 0.10.0", + "sprs", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 4979b09..93a8ef8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,8 +24,8 @@ coveralls = { repository = "espdev/csaps-rs", branch = "master", service = "gith [dependencies] num-traits = "0.2.14" ndarray = "0.15.4" -sprs = "0.11.0" -sprs-ldl = "0.9.0" # 0.10.0 not published https://github.com/vbarrielle/sprs/issues/293 +sprs = {version = "0.11.0", git = "https://github.com/vbarrielle/sprs", rev = "3895313" } +sprs-ldl = {version = "0.10.0", git = "https://github.com/vbarrielle/sprs", rev = "3895313" } # 0.10.0 not published https://github.com/vbarrielle/sprs/issues/293 almost = "0.2.0" itertools = "0.10.3" thiserror = "1.0.30" From fc06f40308f638280141a27dd8be1d7a6a678552 Mon Sep 17 00:00:00 2001 From: Stefan Ulbrich Date: Thu, 21 Apr 2022 22:32:13 +0200 Subject: [PATCH 3/7] Fix errors related ndarray --- Cargo.toml | 2 +- src/umv/evaluate.rs | 19 +++++-------------- src/umv/make.rs | 36 ++++++++++++++++++------------------ 3 files changed, 24 insertions(+), 33 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 93a8ef8..3f55e0f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ documentation = "https://docs.rs/csaps" readme = "README.md" license = "MIT" -edition = "2021" +edition = "2018" [badges] diff --git a/src/umv/evaluate.rs b/src/umv/evaluate.rs index 09eefc9..682df9c 100644 --- a/src/umv/evaluate.rs +++ b/src/umv/evaluate.rs @@ -1,14 +1,5 @@ -use ndarray::{ - Dimension, - Axis, - Array, - Array1, - Array2, - ArrayView1, - ArrayView2, - s, - stack, -}; +use ndarray::{prelude::*, s, concatenate}; + use crate::{ Real, @@ -35,12 +26,12 @@ impl<'a, T> NdSpline<'a, T> xi: ArrayView1<'a, T>) -> Array2 { let edges = { - let mesh = breaks.slice(s![1..-1]); + let mesh = breaks.slice(s![1 as i32..-1]); let one = Array1::::ones((1, )); let left_bound = &one * T::neg_infinity(); let right_bound = &one * T::infinity(); - stack![Axis(0), left_bound, mesh, right_bound] + concatenate![Axis(0), left_bound, mesh, right_bound] }; let mut indices = digitize(&xi, &edges); @@ -68,7 +59,7 @@ impl<'a, T> NdSpline<'a, T> .map(coeffs_by_index) .collect(); - stack(Axis(1), &indexed_coeffs).unwrap() + concatenate(Axis(1), &indexed_coeffs).unwrap() }; // Vectorized computing the spline pieces (polynoms) on the given data sites diff --git a/src/umv/make.rs b/src/umv/make.rs index a614978..d192470 100644 --- a/src/umv/make.rs +++ b/src/umv/make.rs @@ -1,4 +1,4 @@ -use ndarray::{prelude::*, stack}; +use ndarray::{prelude::*, stack, concatenate}; use crate::{ Real, @@ -17,9 +17,9 @@ impl<'a, T, D> CubicSmoothingSpline<'a, T, D> { pub(super) fn make_spline(&mut self) -> Result<()> { let one = T::one(); - let two = T::from(2.0).unwrap(); - let three = T::from(3.0).unwrap(); - let six = T::from(6.0).unwrap(); + let two = T::from::(2.0).unwrap(); + let three = T::from::(3.0).unwrap(); + let six = T::from::(6.0).unwrap(); let breaks = self.x; @@ -41,8 +41,8 @@ impl<'a, T, D> CubicSmoothingSpline<'a, T, D> // The corner case for Nx2 data (2 data points) if pcount == 2 { drop(dx); - let yi = y.slice(s![.., 0]).insert_axis(Axis(1)); - let coeffs = stack![Axis(1), dydx, yi]; + let yi = y.slice(s![.., 0 as usize]).insert_axis(Axis(1)); + let coeffs = concatenate![Axis(1), dydx, yi]; self.smooth = Some(one); self.spline = Some(NdSpline::new(breaks, coeffs)); @@ -56,11 +56,11 @@ impl<'a, T, D> CubicSmoothingSpline<'a, T, D> let qtwq = { let qt = { let odx = ones(pcount - 1) / &dx; - let odx_head = odx.slice(s![..-1]).insert_axis(Axis(0)).into_owned(); - let odx_tail = odx.slice(s![1..]).insert_axis(Axis(0)).into_owned(); + let odx_head = odx.slice(s![..-1 as i32]).insert_axis(Axis(0)).into_owned(); + let odx_tail = odx.slice(s![1 as i32..]).insert_axis(Axis(0)).into_owned(); drop(odx); let odx_body = -(&odx_tail + &odx_head); - let diags_qt = stack![Axis(0), odx_head, odx_body, odx_tail]; + let diags_qt = concatenate![Axis(0), odx_head, odx_body, odx_tail]; sprsext::diags(diags_qt, &[0, 1, 2], (pcount - 2, pcount)) }; @@ -76,10 +76,10 @@ impl<'a, T, D> CubicSmoothingSpline<'a, T, D> }; let r = { - let dx_head = dx.slice(s![..-1]).insert_axis(Axis(0)).into_owned(); - let dx_tail = dx.slice(s![1..]).insert_axis(Axis(0)).into_owned(); + let dx_head = dx.slice(s![..-1 as i32]).insert_axis(Axis(0)).into_owned(); + let dx_tail = dx.slice(s![1 as i32..]).insert_axis(Axis(0)).into_owned(); let dx_body = (&dx_tail + &dx_head) * two; - let diags_r = stack![Axis(0), dx_tail, dx_body, dx_head]; + let diags_r = concatenate![Axis(0), dx_tail, dx_body, dx_head]; sprsext::diags(diags_r, &[-1, 0, 1], (pcount - 2, pcount - 2)) }; @@ -109,11 +109,11 @@ impl<'a, T, D> CubicSmoothingSpline<'a, T, D> sprsext::solve(&a, &b) }; - // Compute and stack spline coefficients + // Compute and concatenatespline coefficients let coeffs = { let vpad = |arr: &Array2| -> Array2 { let pad = Array2::::zeros((1, arr.shape()[1])); - stack(Axis(0), &[pad.view(), arr.view(), pad.view()]).unwrap() + concatenate(Axis(0), &[pad.view(), arr.view(), pad.view()]).unwrap() }; let dx = dx.insert_axis(Axis(1)); @@ -133,17 +133,17 @@ impl<'a, T, D> CubicSmoothingSpline<'a, T, D> }; let c3 = vpad(&(usol * smooth)); - let c3_head = c3.slice(s![..-1, ..]); - let c3_tail = c3.slice(s![1.., ..]); + let c3_head = c3.slice(s![..-1 as i32, ..]); + let c3_tail = c3.slice(s![1 as i32.., ..]); let p1 = diff(&c3, Some(Axis(0))) / &dx; let p2 = &c3_head * three; let p3 = diff(&yi, Some(Axis(0))) / &dx - (&c3_head * two + c3_tail) * dx; - let p4 = yi.slice(s![..-1, ..]); + let p4 = yi.view().slice(s![..-1 as i32, ..]); drop(c3); - stack![Axis(0), p1, p2, p3, p4].t().to_owned() + concatenate(Axis(0), &[p1.view(), p2.view(), p3.view(), p4]).unwrap().t().to_owned() }; self.smooth = Some(smooth); From 3cff5d5642b3a4b53e31b3535040ab939e15458b Mon Sep 17 00:00:00 2001 From: Stefan Ulbrich Date: Fri, 22 Apr 2022 00:37:53 +0200 Subject: [PATCH 4/7] Adapted traits, fixed most of the sprs issues --- src/ndarrayext.rs | 4 ++-- src/ndg.rs | 8 ++++---- src/ndg/evaluate.rs | 4 ++-- src/ndg/make.rs | 2 +- src/ndg/validate.rs | 8 ++++---- src/sprsext.rs | 25 ++++++++++++++++++++----- src/traits.rs | 11 ++++++++--- src/umv.rs | 8 ++++---- src/umv/evaluate.rs | 4 ++-- src/umv/make.rs | 14 +++++++++++--- src/umv/validate.rs | 2 +- src/validate.rs | 4 ++-- 12 files changed, 61 insertions(+), 33 deletions(-) diff --git a/src/ndarrayext.rs b/src/ndarrayext.rs index 3f9ae0e..0391c4e 100644 --- a/src/ndarrayext.rs +++ b/src/ndarrayext.rs @@ -14,7 +14,7 @@ use crate::{ pub fn diff<'a, T: 'a, D, V>(data: V, axis: Option) -> Array where - T: Real, + T: Real, D: Dimension, V: AsArray<'a, T, D> { @@ -127,7 +127,7 @@ pub fn from_2d<'a, T: 'a, D, S, I>(data: I, shape: S, axis: Axis) -> Result(arr: A, bins: B) -> Array1 where - T: Real, + T: Real, A: AsArray<'a, T, Ix1>, B: AsArray<'a, T, Ix1>, { diff --git a/src/ndg.rs b/src/ndg.rs index c87504f..033f778 100644 --- a/src/ndg.rs +++ b/src/ndg.rs @@ -26,7 +26,7 @@ use crate::{Real, Result}; #[derive(Debug)] pub struct NdGridSpline<'a, T, D> where - T: Real, + T: Real, D: Dimension { /// The grid dimensionality @@ -49,7 +49,7 @@ pub struct NdGridSpline<'a, T, D> impl<'a, T, D> NdGridSpline<'a, T, D> where - T: Real, + T: Real, D: Dimension { /// Creates `NdGridSpline` struct from given `breaks` and `coeffs` @@ -134,7 +134,7 @@ impl<'a, T, D> NdGridSpline<'a, T, D> /// pub struct GridCubicSmoothingSpline<'a, T, D> where - T: Real, + T: Real, D: Dimension { /// X data sites (also breaks) @@ -156,7 +156,7 @@ pub struct GridCubicSmoothingSpline<'a, T, D> impl<'a, T, D> GridCubicSmoothingSpline<'a, T, D> where - T: Real, + T: Real, D: Dimension { /// Creates `NdGridCubicSmoothingSpline` struct from the given `X` data sites and `Y` data values diff --git a/src/ndg/evaluate.rs b/src/ndg/evaluate.rs index ba0c920..290f46e 100644 --- a/src/ndg/evaluate.rs +++ b/src/ndg/evaluate.rs @@ -16,7 +16,7 @@ use super::{ impl<'a, T, D> NdGridSpline<'a, T, D> where - T: Real, + T: Real, D: Dimension { /// Implements evaluating the spline on the given mesh of Xi-sites @@ -62,7 +62,7 @@ impl<'a, T, D> NdGridSpline<'a, T, D> impl<'a, T, D> GridCubicSmoothingSpline<'a, T, D> where - T: Real, + T: Real, D: Dimension { pub(super) fn evaluate_spline(&self, xi: &[ArrayView1<'a, T>]) -> Array { diff --git a/src/ndg/make.rs b/src/ndg/make.rs index 3c05c51..3543575 100644 --- a/src/ndg/make.rs +++ b/src/ndg/make.rs @@ -17,7 +17,7 @@ use super::{ impl<'a, T, D> GridCubicSmoothingSpline<'a, T, D> where - T: Real, + T: Real, D: Dimension { pub(super) fn make_spline(&mut self) -> Result<()> { diff --git a/src/ndg/validate.rs b/src/ndg/validate.rs index 9cfacab..6bd5bc0 100644 --- a/src/ndg/validate.rs +++ b/src/ndg/validate.rs @@ -12,7 +12,7 @@ use super::GridCubicSmoothingSpline; impl<'a, T, D> GridCubicSmoothingSpline<'a, T, D> where - T: Real, + T: Real, D: Dimension { pub(super) fn make_validate(&self) -> Result<()> { @@ -53,7 +53,7 @@ impl<'a, T, D> GridCubicSmoothingSpline<'a, T, D> pub(super) fn validate_xy(x: &[ArrayView1<'_, T>], y: ArrayView<'_, T, D>) -> Result<()> where - T: Real, + T: Real, D: Dimension { if x.len() != y.ndim() { @@ -98,7 +98,7 @@ pub(super) fn validate_xy(x: &[ArrayView1<'_, T>], y: ArrayView<'_, T, D>) pub(super) fn validate_weights(x: &[ArrayView1<'_, T>], w: &[Option>]) -> Result<()> where - T: Real + T: Real { let x_len = x.len(); let w_len = w.len(); @@ -134,7 +134,7 @@ pub(super) fn validate_weights(x: &[ArrayView1<'_, T>], w: &[Option(x: &[ArrayView1<'_, T>], smooth: &[Option]) -> Result<()> where - T: Real + T: Real { let x_len = x.len(); let s_len = smooth.len(); diff --git a/src/sprsext.rs b/src/sprsext.rs index c5473c3..d650c59 100644 --- a/src/sprsext.rs +++ b/src/sprsext.rs @@ -2,12 +2,14 @@ use std::iter::FromIterator; use ndarray::{prelude::*}; -use sprs::{CsMat, TriMat, Shape, IndPtrBase}; +use sprs::{CsMat, TriMat, Shape, IndPtrBase, SpIndex, CsMatBase, CsMatI}; use sprs_ldl::LdlNumeric; use crate::Real; + + /// Creates CSR matrix from given diagonals /// /// The created matrix represents diagonal-like sparse matrix (DIA), but in CSR data storage @@ -15,7 +17,7 @@ use crate::Real; /// pub fn diags(diags: Array2, offsets: &[isize], shape: Shape) -> CsMat where - T: Real + T: Real { let (rows, cols) = shape; @@ -77,7 +79,7 @@ pub fn diags(diags: Array2, offsets: &[isize], shape: Shape) -> CsMat /// pub fn diagonal(m: &CsMat, k: isize) -> Array1 where - T: Real + T: Real { let (rows, cols) = m.shape(); @@ -95,7 +97,7 @@ fn diagonal_csr(k: isize, indices: &[usize], data: &[T]) -> Array1 where - T: Real + T: Real { let (rows, cols) = shape; @@ -136,7 +138,7 @@ fn diagonal_csr(k: isize, /// pub fn solve(a: &CsMat, b: &Array2) -> Array2 where - T: Real + T: Real { let mut x = Array2::::zeros(b.raw_dim()); @@ -369,3 +371,16 @@ mod tests { assert_eq!(sprsext::diagonal(&m_csc, k), array![1., 2.]); } } + +// use std::ops::{Mul, Deref}; + +// impl<'a, I, Iptr, IpStorage, IStorage, DStorage, T> Mul for &'a CsMatBase where +// I: 'a + SpIndex, +// Iptr: 'a + SpIndex, +// IpStorage: 'a + Deref, +// IStorage: 'a + Deref, +// DStorage: 'a + Deref, +// T: Real { + +// type Output = CsMatI; +// } \ No newline at end of file diff --git a/src/traits.rs b/src/traits.rs index 6296481..b7a71c1 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -1,5 +1,8 @@ use ndarray::NdFloat; use almost::AlmostEqual; +use sprs::{MulAcc}; + +use std::ops::{Mul, DivAssign}; /// Floating-point element types `f32` and `f64`. @@ -9,7 +12,9 @@ use almost::AlmostEqual; /// checking almost equality. /// /// This trait can only be implemented by `f32` and `f64`. -pub trait Real: NdFloat + AlmostEqual + Default {} +pub trait Real: NdFloat + AlmostEqual + Default + MulAcc + for<'r> DivAssign<&'r T> + Mul {} + +impl Real for f32 {} +impl Real for f64 {} -impl Real for f32 {} -impl Real for f64 {} + \ No newline at end of file diff --git a/src/umv.rs b/src/umv.rs index 51757ac..51c6ee1 100644 --- a/src/umv.rs +++ b/src/umv.rs @@ -26,7 +26,7 @@ use crate::{Real, Result}; /// for the given data sites. /// #[derive(Debug)] -pub struct NdSpline<'a, T: Real> +pub struct NdSpline<'a, T: Real> { /// The spline dimensionality ndim: usize, @@ -47,7 +47,7 @@ pub struct NdSpline<'a, T: Real> impl<'a, T> NdSpline<'a, T> where - T: Real + T: Real { /// Creates `NdSpline` struct from given `breaks` and `coeffs` /// @@ -147,7 +147,7 @@ impl<'a, T> NdSpline<'a, T> /// pub struct CubicSmoothingSpline<'a, T, D> where - T: Real, + T: Real, D: Dimension { /// X data sites (also breaks) @@ -172,7 +172,7 @@ pub struct CubicSmoothingSpline<'a, T, D> impl<'a, T, D> CubicSmoothingSpline<'a, T, D> where - T: Real, + T: Real, D: Dimension { /// Creates `CubicSmoothingSpline` struct from the given `X` data sites and `Y` data values diff --git a/src/umv/evaluate.rs b/src/umv/evaluate.rs index 682df9c..b79332c 100644 --- a/src/umv/evaluate.rs +++ b/src/umv/evaluate.rs @@ -13,7 +13,7 @@ use super::{CubicSmoothingSpline, NdSpline}; impl<'a, T> NdSpline<'a, T> where - T: Real + T: Real { /// Implements evaluating the spline on the given mesh of Xi-sites /// @@ -77,7 +77,7 @@ impl<'a, T> NdSpline<'a, T> impl<'a, T, D> CubicSmoothingSpline<'a, T, D> where - T: Real, + T: Real, D: Dimension { pub(super) fn evaluate_spline(&self, xi: ArrayView1<'a, T>) -> Result> { diff --git a/src/umv/make.rs b/src/umv/make.rs index d192470..733b664 100644 --- a/src/umv/make.rs +++ b/src/umv/make.rs @@ -1,4 +1,6 @@ -use ndarray::{prelude::*, stack, concatenate}; +use ndarray::{prelude::*, concatenate, s}; + + use crate::{ Real, @@ -12,7 +14,7 @@ use super::{NdSpline, CubicSmoothingSpline}; impl<'a, T, D> CubicSmoothingSpline<'a, T, D> where - T: Real, + T: Real, D: Dimension { pub(super) fn make_spline(&mut self) -> Result<()> { @@ -41,7 +43,7 @@ impl<'a, T, D> CubicSmoothingSpline<'a, T, D> // The corner case for Nx2 data (2 data points) if pcount == 2 { drop(dx); - let yi = y.slice(s![.., 0 as usize]).insert_axis(Axis(1)); + let yi = y.slice(s![.., 0 as i32]).insert_axis(Axis(1)); let coeffs = concatenate![Axis(1), dydx, yi]; self.smooth = Some(one); @@ -65,6 +67,7 @@ impl<'a, T, D> CubicSmoothingSpline<'a, T, D> sprsext::diags(diags_qt, &[0, 1, 2], (pcount - 2, pcount)) }; + let diags_sqrw = (ones(pcount) / weights.mapv(T::sqrt)).insert_axis(Axis(0)); let sqrw = sprsext::diags(diags_sqrw, &[0], (pcount, pcount)); let qtw = &qt * &sqrw; @@ -95,6 +98,11 @@ impl<'a, T, D> CubicSmoothingSpline<'a, T, D> // Solve linear system Ax = b for the 2nd derivatives let usol = { let a = { + + + // cannot multiply `&CsMatBase, Vec, Vec>` by `T` + // the trait `Mul` is not implemented for `&CsMatBase, Vec, Vec>` + let a1 = &qtwq * s1; let a2 = &r * smooth; drop(qtwq); diff --git a/src/umv/validate.rs b/src/umv/validate.rs index eab93d2..d67af75 100644 --- a/src/umv/validate.rs +++ b/src/umv/validate.rs @@ -15,7 +15,7 @@ use crate::{ impl<'a, T, D> CubicSmoothingSpline<'a, T, D> where - T: Real, + T: Real, D: Dimension { pub(super) fn make_validate(&self) -> Result<()> { diff --git a/src/validate.rs b/src/validate.rs index b1e08a9..54fa7fa 100644 --- a/src/validate.rs +++ b/src/validate.rs @@ -5,7 +5,7 @@ use crate::{Real, Result, CsapsError::InvalidInputData}; pub(crate) fn validate_data_sites(x: ArrayView1) -> Result<()> where - T: Real + T: Real { for w in x.windows(2) { let e1 = w[0]; @@ -25,7 +25,7 @@ pub(crate) fn validate_data_sites(x: ArrayView1) -> Result<()> pub(crate) fn validate_smooth_value(smooth: T) -> Result<()> where - T: Real + T: Real { if smooth < T::zero() || smooth > T::one() { return Err( From 92a5f575e9b8b198cdd9c49ca3c4e4a66cbac008 Mon Sep 17 00:00:00 2001 From: Stefan Ulbrich Date: Sat, 30 Apr 2022 17:19:25 +0200 Subject: [PATCH 5/7] Update traits to allow for sparse matrix addition --- src/ndg/make.rs | 18 +++++++++++++++--- src/traits.rs | 42 ++++++++++++++++++++++++++++++++++++------ src/umv.rs | 17 ++++++++++++++--- src/umv/make.rs | 21 ++++++++++++++------- 4 files changed, 79 insertions(+), 19 deletions(-) diff --git a/src/ndg/make.rs b/src/ndg/make.rs index 3543575..864be33 100644 --- a/src/ndg/make.rs +++ b/src/ndg/make.rs @@ -1,4 +1,4 @@ -use ndarray::Dimension; +use ndarray::{Dimension, ArrayView1, ArrayView2}; use crate::{ Real, @@ -14,10 +14,13 @@ use super::{ util::permute_axes }; +use std::ops::Add; impl<'a, T, D> GridCubicSmoothingSpline<'a, T, D> where T: Real, + + D: Dimension { pub(super) fn make_spline(&mut self) -> Result<()> { @@ -33,12 +36,21 @@ impl<'a, T, D> GridCubicSmoothingSpline<'a, T, D> let permuted_axes: D = permute_axes(ndim); for ax in (0..ndim).rev() { - let x = breaks[ax].view(); - let y = to_2d_simple(coeffs.view())?; + let x: ArrayView1 = breaks[ax].view(); + let y: ArrayView2 = to_2d_simple(coeffs.view())?; let weights = self.weights[ax].map(|v| v.reborrow()); let s = self.smooth[ax]; + // Cannot explain how this error happens + // + // = note: required because of the requirements on the impl of `for<'r> Add` for `&'r CsMatBase, _, _, _, _, _>` + // = note: 127 redundant requirements hidden + // = note: required because of the requirements on the impl of `for<'r> Add` for `&'r CsMatBase: NdFloat + AlmostEqual + Default + MulAcc + for<'r> DivAssign<&'r T> + Mul {} +pub trait Real: + num_traits::Zero + + NdFloat + + PartialEq + + AlmostEqual + + Clone + + Default + + MulAcc + + for<'r> DivAssign<&'r T> + + Mul +{ +} + impl Real for f32 {} impl Real for f64 {} - \ No newline at end of file +fn test( + a: &CsMatBase, Vec, Vec, usize>, + b: &CsMatBase, Vec, Vec, usize>, +) where + T: Real, + for<'r> &'r T: Add<&'r T, Output = T>, +{ + let c = a + b; +} + +fn test2( + a: &CsMatBase, Vec, Vec, usize>, + b: &CsMatBase, Vec, Vec, usize>, +) { + let c = a + b; +} diff --git a/src/umv.rs b/src/umv.rs index 51c6ee1..b8167ef 100644 --- a/src/umv.rs +++ b/src/umv.rs @@ -13,6 +13,8 @@ use ndarray::{ ArrayView2, }; +use std::ops::Add; + use crate::{Real, Result}; @@ -26,7 +28,11 @@ use crate::{Real, Result}; /// for the given data sites. /// #[derive(Debug)] -pub struct NdSpline<'a, T: Real> +pub struct NdSpline<'a, T> +where + + T: Real, + { /// The spline dimensionality ndim: usize, @@ -46,8 +52,9 @@ pub struct NdSpline<'a, T: Real> impl<'a, T> NdSpline<'a, T> - where - T: Real +where + + T: Real, { /// Creates `NdSpline` struct from given `breaks` and `coeffs` /// @@ -148,6 +155,8 @@ impl<'a, T> NdSpline<'a, T> pub struct CubicSmoothingSpline<'a, T, D> where T: Real, + + D: Dimension { /// X data sites (also breaks) @@ -173,6 +182,8 @@ pub struct CubicSmoothingSpline<'a, T, D> impl<'a, T, D> CubicSmoothingSpline<'a, T, D> where T: Real, + for<'r> &'r T: Add<&'r T, Output = T>, + D: Dimension { /// Creates `CubicSmoothingSpline` struct from the given `X` data sites and `Y` data values diff --git a/src/umv/make.rs b/src/umv/make.rs index 733b664..4edce11 100644 --- a/src/umv/make.rs +++ b/src/umv/make.rs @@ -1,5 +1,6 @@ -use ndarray::{prelude::*, concatenate, s}; +use std::ops::Add; +use ndarray::{prelude::*, concatenate, s}; use crate::{ @@ -14,8 +15,9 @@ use super::{NdSpline, CubicSmoothingSpline}; impl<'a, T, D> CubicSmoothingSpline<'a, T, D> where - T: Real, - D: Dimension + T: Real, + for<'r> &'r T: Add<&'r T, Output = T>, + D: Dimension { pub(super) fn make_spline(&mut self) -> Result<()> { let one = T::one(); @@ -102,13 +104,18 @@ impl<'a, T, D> CubicSmoothingSpline<'a, T, D> // cannot multiply `&CsMatBase, Vec, Vec>` by `T` // the trait `Mul` is not implemented for `&CsMatBase, Vec, Vec>` + + let a1 = qtwq.map(|el| s1 * *el ); + let a2 = r.map(|el| *el * smooth); - let a1 = &qtwq * s1; - let a2 = &r * smooth; + + // let a1 = &qtwq * s1; + // let a2 = &r * smooth; drop(qtwq); drop(r); - &a1 + &a2 + + &a1 + &a2 }; let b = diff(&dydx, Some(Axis(1))).t().to_owned(); @@ -147,7 +154,7 @@ impl<'a, T, D> CubicSmoothingSpline<'a, T, D> let p1 = diff(&c3, Some(Axis(0))) / &dx; let p2 = &c3_head * three; let p3 = diff(&yi, Some(Axis(0))) / &dx - (&c3_head * two + c3_tail) * dx; - let p4 = yi.view().slice(s![..-1 as i32, ..]); + let p4 = yi.slice(s![..-1 as i32, ..]); // was yi.view() drop(c3); From efb693624ae6ff7fe45230ee16ea1b6a09d38541 Mon Sep 17 00:00:00 2001 From: Stefan Ulbrich <6009224+StefanUlbrich@users.noreply.github.com> Date: Tue, 2 Aug 2022 23:25:34 +0200 Subject: [PATCH 6/7] Update dependencies --- Cargo.lock | 17 +++++------------ Cargo.toml | 6 +++--- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1b73f05..d38f3b2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -28,15 +28,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "approx" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f2a05fd1bd10b2527e20a2cd32d8873d115b8b39fe219ee25f42a8aca6ba278" -dependencies = [ - "num-traits", -] - [[package]] name = "approx" version = "0.5.1" @@ -183,7 +174,7 @@ version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dec23e6762830658d2b3d385a75aa212af2f67a4586d4442907144f3bb6a1ca8" dependencies = [ - "approx 0.4.0", + "approx 0.5.1", "matrixmultiply", "num-complex 0.4.0", "num-integer", @@ -303,7 +294,8 @@ checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" [[package]] name = "sprs" version = "0.11.0" -source = "git+https://github.com/vbarrielle/sprs?rev=3895313#38953136024e1814895b560951f41d0e10c42d16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea71e48b3eab4c4b153e8e35dcaeac132720809ef68359097b8cb54a18edd70" dependencies = [ "alga", "ndarray", @@ -317,7 +309,8 @@ dependencies = [ [[package]] name = "sprs-ldl" version = "0.10.0" -source = "git+https://github.com/vbarrielle/sprs?rev=3895313#38953136024e1814895b560951f41d0e10c42d16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc152d7b3747cde0983b91da392c8a5448e8f82260726bf56064f6d475c69e82" dependencies = [ "num-traits", "sprs", diff --git a/Cargo.toml b/Cargo.toml index 3f55e0f..9574e2e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,12 +24,12 @@ coveralls = { repository = "espdev/csaps-rs", branch = "master", service = "gith [dependencies] num-traits = "0.2.14" ndarray = "0.15.4" -sprs = {version = "0.11.0", git = "https://github.com/vbarrielle/sprs", rev = "3895313" } -sprs-ldl = {version = "0.10.0", git = "https://github.com/vbarrielle/sprs", rev = "3895313" } # 0.10.0 not published https://github.com/vbarrielle/sprs/issues/293 +sprs-ldl = "0.10.0" +sprs = "0.11.0" almost = "0.2.0" itertools = "0.10.3" thiserror = "1.0.30" [dev-dependencies] approx = "0.5.1" -ndarray = {version = "0.15.4", features = ["approx"]} +ndarray = {version = "0.15.4", features = ["approx-0_5"]} From ff352bdc0b6ffedf3f353d878c2daae15bf17f2c Mon Sep 17 00:00:00 2001 From: Stefan Ulbrich <6009224+StefanUlbrich@users.noreply.github.com> Date: Wed, 3 Aug 2022 01:34:43 +0200 Subject: [PATCH 7/7] Fix errors with generic float trait. --- src/lib.rs | 25 ++++++++- src/ndarrayext.rs | 8 ++- src/ndg.rs | 4 +- src/ndg/make.rs | 15 +++--- src/sprsext.rs | 4 +- src/traits.rs | 68 +++++++++++++----------- src/umv.rs | 122 +++++++++++++++++++++++--------------------- src/umv/evaluate.rs | 39 ++++++-------- src/umv/make.rs | 16 ++++-- src/umv/validate.rs | 4 +- src/validate.rs | 5 +- tests/umv_make.rs | 25 +++++++-- 12 files changed, 204 insertions(+), 131 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 421a3be..321a76b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -134,6 +134,29 @@ use std::result; pub type Result = result::Result; pub use errors::CsapsError; -pub use traits::Real; +pub use traits::{Real, RealRef}; pub use umv::{NdSpline, CubicSmoothingSpline}; pub use ndg::{NdGridSpline, GridCubicSmoothingSpline}; + + +// #[cfg(test)] +// mod tests { +// use crate::CubicSmoothingSpline; +// use ndarray::prelude::*; + +// #[test] +// fn test_new() { + +// let zeros = Array1::::zeros(1); + +// let x = zeros.view(); +// let zeros = Array2::::zeros((1,1)); +// let y = zeros.view(); + + +// let sp = CubicSmoothingSpline::new(x.view(), y.view()) +// // .with_optional_weights(weights) +// // .with_optional_smooth(s) +// .make(); +// } +// } \ No newline at end of file diff --git a/src/ndarrayext.rs b/src/ndarrayext.rs index 0391c4e..5270f83 100644 --- a/src/ndarrayext.rs +++ b/src/ndarrayext.rs @@ -1,20 +1,22 @@ +use almost::AlmostEqual; // use almost; use ndarray::{prelude::*, IntoDimension, Slice}; use itertools::Itertools; + use crate::{ - Real, Result, CsapsError::{ReshapeFrom2d, ReshapeTo2d}, - util::dim_from_vec + util::dim_from_vec, Real }; pub fn diff<'a, T: 'a, D, V>(data: V, axis: Option) -> Array where T: Real, + // T: Clone + NdFloat, D: Dimension, V: AsArray<'a, T, D> { @@ -128,6 +130,8 @@ pub fn from_2d<'a, T: 'a, D, S, I>(data: I, shape: S, axis: Axis) -> Result(arr: A, bins: B) -> Array1 where T: Real, + // T: Clone + NdFloat + AlmostEqual, + A: AsArray<'a, T, Ix1>, B: AsArray<'a, T, Ix1>, { diff --git a/src/ndg.rs b/src/ndg.rs index 033f778..1c50b8f 100644 --- a/src/ndg.rs +++ b/src/ndg.rs @@ -11,7 +11,7 @@ use ndarray::{ ArrayView1, }; -use crate::{Real, Result}; +use crate::{Real, Result, RealRef}; /// N-d grid spline PP-form representation @@ -157,6 +157,8 @@ pub struct GridCubicSmoothingSpline<'a, T, D> impl<'a, T, D> GridCubicSmoothingSpline<'a, T, D> where T: Real, + for<'r> &'r T: RealRef<&'r T, T>, + D: Dimension { /// Creates `NdGridCubicSmoothingSpline` struct from the given `X` data sites and `Y` data values diff --git a/src/ndg/make.rs b/src/ndg/make.rs index 864be33..cce0b44 100644 --- a/src/ndg/make.rs +++ b/src/ndg/make.rs @@ -1,11 +1,13 @@ -use ndarray::{Dimension, ArrayView1, ArrayView2}; +use ndarray::Dimension; +use ndarray::prelude::*; +use crate::util::dim_from_vec; use crate::{ Real, + RealRef, Result, CubicSmoothingSpline, ndarrayext::to_2d_simple, - util::dim_from_vec, }; use super::{ @@ -14,12 +16,11 @@ use super::{ util::permute_axes }; -use std::ops::Add; impl<'a, T, D> GridCubicSmoothingSpline<'a, T, D> where T: Real, - + for<'r> &'r T: RealRef<&'r T, T>, D: Dimension { @@ -36,8 +37,8 @@ impl<'a, T, D> GridCubicSmoothingSpline<'a, T, D> let permuted_axes: D = permute_axes(ndim); for ax in (0..ndim).rev() { - let x: ArrayView1 = breaks[ax].view(); - let y: ArrayView2 = to_2d_simple(coeffs.view())?; + let x = breaks[ax].view(); + let y = to_2d_simple(coeffs.view())?; let weights = self.weights[ax].map(|v| v.reborrow()); let s = self.smooth[ax]; @@ -51,6 +52,8 @@ impl<'a, T, D> GridCubicSmoothingSpline<'a, T, D> // ::zeros(1).view(); + // let y = Array2::::zeros((1,1)).view(); let sp = CubicSmoothingSpline::new(x, y) .with_optional_weights(weights) .with_optional_smooth(s) diff --git a/src/sprsext.rs b/src/sprsext.rs index d650c59..d4ce126 100644 --- a/src/sprsext.rs +++ b/src/sprsext.rs @@ -2,7 +2,7 @@ use std::iter::FromIterator; use ndarray::{prelude::*}; -use sprs::{CsMat, TriMat, Shape, IndPtrBase, SpIndex, CsMatBase, CsMatI}; +use sprs::{CsMat, TriMat, Shape, IndPtrBase}; use sprs_ldl::LdlNumeric; use crate::Real; @@ -18,6 +18,7 @@ use crate::Real; pub fn diags(diags: Array2, offsets: &[isize], shape: Shape) -> CsMat where T: Real + // T: Clone + NdFloat { let (rows, cols) = shape; @@ -173,6 +174,7 @@ mod tests { use crate::sprsext; + #[test] fn test_diags_1() { /* diff --git a/src/traits.rs b/src/traits.rs index e96a728..3331945 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -2,11 +2,10 @@ use almost::AlmostEqual; use ndarray::NdFloat; use sprs::{CsMatBase, MulAcc}; -use num_traits; -use std::{ - io::Read, - ops::{DivAssign, Mul, Add}, -}; +// use num_traits::{Num, Float}; +use num_traits::{Num, MulAdd, Float}; + +use std::ops::{Add, Mul, AddAssign}; /// Floating-point element types `f32` and `f64`. /// @@ -15,36 +14,47 @@ use std::{ /// checking almost equality. /// /// This trait can only be implemented by `f32` and `f64`. +// pub trait Real: +// num_traits::Zero +// + NdFloat +// + PartialEq +// + AlmostEqual +// + Clone +// + Default +// + MulAcc +// + for<'r> DivAssign<&'r T> +// + Mul +// { +// } pub trait Real: - num_traits::Zero - + NdFloat - + PartialEq - + AlmostEqual - + Clone - + Default - + MulAcc - + for<'r> DivAssign<&'r T> - + Mul + Num + NdFloat + Default + AlmostEqual + Float + + for<'r> std::ops::DivAssign<&'r T> + + MulAdd { } +pub trait RealRef: Add + Mul {} impl Real for f32 {} impl Real for f64 {} -fn test( - a: &CsMatBase, Vec, Vec, usize>, - b: &CsMatBase, Vec, Vec, usize>, -) where - T: Real, - for<'r> &'r T: Add<&'r T, Output = T>, -{ - let c = a + b; -} +impl RealRef<&f32,f32> for &f32 {} +impl RealRef<&f64,f64> for &f64 {} -fn test2( - a: &CsMatBase, Vec, Vec, usize>, - b: &CsMatBase, Vec, Vec, usize>, -) { - let c = a + b; -} +// fn test( +// a: &CsMatBase, Vec, Vec, usize>, +// b: &CsMatBase, Vec, Vec, usize>, +// ) where +// T: Real, +// // for<'r> &'r T: Add<&'r T, Output = T>, +// for<'r> &'r T: RealRef<&'r T, T> +// { +// let c = a + b; +// } + +// fn test2( +// a: &CsMatBase, Vec, Vec, usize>, +// b: &CsMatBase, Vec, Vec, usize>, +// ) { +// let c = a + b; +// } diff --git a/src/umv.rs b/src/umv.rs index b8167ef..cd839a2 100644 --- a/src/umv.rs +++ b/src/umv.rs @@ -1,22 +1,13 @@ -mod validate; -mod make; mod evaluate; +mod make; +mod validate; -use ndarray::{ - Dimension, - Axis, - AsArray, - Array, - Array2, - ArrayView, - ArrayView1, - ArrayView2, -}; - -use std::ops::Add; +use std::ops::{Add, Mul}; -use crate::{Real, Result}; +use ndarray::{Array, Array2, ArrayView, ArrayView1, ArrayView2, AsArray, Axis, Dimension}; +use sprs::MulAcc; +use crate::{Real, RealRef, Result}; /// N-dimensional (univariate/multivariate) spline PP-form representation /// @@ -30,9 +21,7 @@ use crate::{Real, Result}; #[derive(Debug)] pub struct NdSpline<'a, T> where - T: Real, - { /// The spline dimensionality ndim: usize, @@ -50,10 +39,8 @@ where coeffs: Array2, } - impl<'a, T> NdSpline<'a, T> where - T: Real, { /// Creates `NdSpline` struct from given `breaks` and `coeffs` @@ -83,19 +70,29 @@ where } /// Returns the spline dimensionality - pub fn ndim(&self) -> usize { self.ndim } + pub fn ndim(&self) -> usize { + self.ndim + } /// Returns the spline order - pub fn order(&self) -> usize { self.order } + pub fn order(&self) -> usize { + self.order + } /// Returns the number of pieces of the spline - pub fn pieces(&self) -> usize { self.pieces } + pub fn pieces(&self) -> usize { + self.pieces + } /// Returns the view to the breaks array - pub fn breaks(&self) -> ArrayView1<'_, T> { self.breaks.view() } + pub fn breaks(&self) -> ArrayView1<'_, T> { + self.breaks.view() + } /// Returns the view to the spline coefficients array - pub fn coeffs(&self) -> ArrayView2<'_, T> { self.coeffs.view() } + pub fn coeffs(&self) -> ArrayView2<'_, T> { + self.coeffs.view() + } /// Evaluates the spline on the given data sites pub fn evaluate(&self, xi: ArrayView1<'a, T>) -> Array2 { @@ -109,7 +106,6 @@ where } } - /// N-dimensional (univariate/multivariate) smoothing spline calculator/evaluator /// /// The struct represents n-d smoothing cubic spline and allows you to make and evaluate the @@ -153,11 +149,12 @@ where /// ``` /// pub struct CubicSmoothingSpline<'a, T, D> - where - T: Real, - +where + T: Real, + for<'r> &'r T: RealRef<&'r T, T>, - D: Dimension + // for<'r> &'r T: Add<&'r T, Output = T>, // This causes the recursion error + D: Dimension, { /// X data sites (also breaks) x: ArrayView1<'a, T>, @@ -175,16 +172,16 @@ pub struct CubicSmoothingSpline<'a, T, D> smooth: Option, /// `NdSpline` struct with computed spline - spline: Option> + spline: Option>, } - impl<'a, T, D> CubicSmoothingSpline<'a, T, D> - where - T: Real, - for<'r> &'r T: Add<&'r T, Output = T>, +where + T: Real, + for<'r> &'r T: RealRef<&'r T, T>, - D: Dimension + // for<'r> &'r T: Add<&'r T, Output = T>, + D: Dimension, { /// Creates `CubicSmoothingSpline` struct from the given `X` data sites and `Y` data values /// @@ -197,9 +194,9 @@ impl<'a, T, D> CubicSmoothingSpline<'a, T, D> /// equal to 2 and etc. /// pub fn new(x: X, y: Y) -> Self - where - X: AsArray<'a, T>, - Y: AsArray<'a, T, D> + where + X: AsArray<'a, T>, + Y: AsArray<'a, T, D>, { CubicSmoothingSpline { x: x.into(), @@ -252,8 +249,8 @@ impl<'a, T, D> CubicSmoothingSpline<'a, T, D> /// `weights.len()` must be equal to `x.len()` /// pub fn with_weights(mut self, weights: W) -> Self - where - W: AsArray<'a, T> + where + W: AsArray<'a, T>, { self.invalidate(); self.weights = Some(weights.into()); @@ -265,8 +262,8 @@ impl<'a, T, D> CubicSmoothingSpline<'a, T, D> /// `weights.len()` must be equal to `x.len()` /// pub fn with_optional_weights(mut self, weights: Option) -> Self - where - W: AsArray<'a, T> + where + W: AsArray<'a, T>, { self.invalidate(); self.weights = weights.map(|w| w.into()); @@ -294,19 +291,6 @@ impl<'a, T, D> CubicSmoothingSpline<'a, T, D> self } - /// Makes (computes) the spline for given data and parameters - /// - /// # Errors - /// - /// - If the data or parameters are invalid - /// - If reshaping Y data to 2-d view has failed - /// - pub fn make(mut self) -> Result { - self.make_validate()?; - self.make_spline()?; - Ok(self) - } - /// Evaluates the computed spline on the given data sites /// /// # Errors @@ -315,8 +299,8 @@ impl<'a, T, D> CubicSmoothingSpline<'a, T, D> /// - If the spline yet has not been computed /// pub fn evaluate(&self, xi: X) -> Result> - where - X: AsArray<'a, T> + where + X: AsArray<'a, T>, { let xi = xi.into(); self.evaluate_validate(xi)?; @@ -339,4 +323,28 @@ impl<'a, T, D> CubicSmoothingSpline<'a, T, D> fn invalidate(&mut self) { self.spline = None; } + /// Makes (computes) the spline for given data and parameters + /// + /// # Errors + /// + /// - If the data or parameters are invalid + /// - If reshaping Y data to 2-d view has failed + /// + pub fn make(mut self) -> Result { + self.make_validate()?; + self.make_spline()?; + Ok(self) + } } + +// // Moved outside to resolve the recursion error +// impl<'a, T, D> CubicSmoothingSpline<'a, T, D> +// where +// T: Real, +// for<'r> &'r T: Add<&'r T, Output = T>, +// T: MulAcc, +// for<'r> &'r T: Mul<&'r T, Output = T>, + +// D: Dimension, +// { +// } diff --git a/src/umv/evaluate.rs b/src/umv/evaluate.rs index b79332c..293b02c 100644 --- a/src/umv/evaluate.rs +++ b/src/umv/evaluate.rs @@ -1,19 +1,16 @@ -use ndarray::{prelude::*, s, concatenate}; - +use ndarray::{concatenate, prelude::*, s}; use crate::{ - Real, - Result, - ndarrayext::{from_2d, digitize}, - util::dim_from_vec + ndarrayext::{digitize, from_2d}, + util::dim_from_vec, + Real, RealRef, Result, }; use super::{CubicSmoothingSpline, NdSpline}; - impl<'a, T> NdSpline<'a, T> - where - T: Real +where + T: Real, { /// Implements evaluating the spline on the given mesh of Xi-sites /// @@ -23,11 +20,11 @@ impl<'a, T> NdSpline<'a, T> pieces: usize, breaks: ArrayView1<'_, T>, coeffs: ArrayView2<'_, T>, - xi: ArrayView1<'a, T>) -> Array2 - { + xi: ArrayView1<'a, T>, + ) -> Array2 { let edges = { let mesh = breaks.slice(s![1 as i32..-1]); - let one = Array1::::ones((1, )); + let one = Array1::::ones((1,)); let left_bound = &one * T::neg_infinity(); let right_bound = &one * T::infinity(); @@ -48,16 +45,11 @@ impl<'a, T> NdSpline<'a, T> // where N is ndim and M is the size of xi let get_indexed_coeffs = |inds: &Array1| { // Returns Nx1 2-d array of coeffs by given index - let coeffs_by_index = |&index| { - coeffs.slice(s![.., index]).insert_axis(Axis(1)) - }; + let coeffs_by_index = |&index| coeffs.slice(s![.., index]).insert_axis(Axis(1)); // Get the M-sized vector of coeffs values Nx1 arrays // for all dimensions for 1xM indices array - let indexed_coeffs: Vec<_> = inds - .iter() - .map(coeffs_by_index) - .collect(); + let indexed_coeffs: Vec<_> = inds.iter().map(coeffs_by_index).collect(); concatenate(Axis(1), &indexed_coeffs).unwrap() }; @@ -74,11 +66,12 @@ impl<'a, T> NdSpline<'a, T> } } - impl<'a, T, D> CubicSmoothingSpline<'a, T, D> - where - T: Real, - D: Dimension +where + T: Real, + for<'r> &'r T: RealRef<&'r T, T>, + + D: Dimension, { pub(super) fn evaluate_spline(&self, xi: ArrayView1<'a, T>) -> Result> { let axis = self.axis.unwrap(); diff --git a/src/umv/make.rs b/src/umv/make.rs index 4edce11..7822243 100644 --- a/src/umv/make.rs +++ b/src/umv/make.rs @@ -1,13 +1,15 @@ -use std::ops::Add; + +use std::ops::{Add, Mul}; use ndarray::{prelude::*, concatenate, s}; +use sprs::MulAcc; use crate::{ Real, Result, ndarrayext::{diff, to_2d}, - sprsext + sprsext, RealRef }; use super::{NdSpline, CubicSmoothingSpline}; @@ -16,10 +18,16 @@ use super::{NdSpline, CubicSmoothingSpline}; impl<'a, T, D> CubicSmoothingSpline<'a, T, D> where T: Real, - for<'r> &'r T: Add<&'r T, Output = T>, + for<'r> &'r T: RealRef<&'r T, T>, + + // T: MulAcc, + // for<'r> &'r T: Add<&'r T, Output = T>, + // for<'r> &'r T: Mul<&'r T, Output = T>, + D: Dimension { pub(super) fn make_spline(&mut self) -> Result<()> { + // todo!(); let one = T::one(); let two = T::from::(2.0).unwrap(); let three = T::from::(3.0).unwrap(); @@ -115,7 +123,7 @@ impl<'a, T, D> CubicSmoothingSpline<'a, T, D> drop(r); - &a1 + &a2 + &a1 + &a2 // was &a1 + &a2 }; let b = diff(&dydx, Some(Axis(1))).t().to_owned(); diff --git a/src/umv/validate.rs b/src/umv/validate.rs index d67af75..d518a0b 100644 --- a/src/umv/validate.rs +++ b/src/umv/validate.rs @@ -9,13 +9,15 @@ use crate::{ CubicSmoothingSpline, CsapsError::InvalidInputData, Result, - validate::{validate_data_sites, validate_smooth_value}, + validate::{validate_data_sites, validate_smooth_value}, RealRef, }; impl<'a, T, D> CubicSmoothingSpline<'a, T, D> where T: Real, + for<'r> &'r T: RealRef<&'r T, T>, + D: Dimension { pub(super) fn make_validate(&self) -> Result<()> { diff --git a/src/validate.rs b/src/validate.rs index 54fa7fa..da62874 100644 --- a/src/validate.rs +++ b/src/validate.rs @@ -1,4 +1,5 @@ -use ndarray::ArrayView1; +use almost::AlmostEqual; +use ndarray::{ArrayView1, NdFloat}; use crate::{Real, Result, CsapsError::InvalidInputData}; @@ -6,6 +7,7 @@ use crate::{Real, Result, CsapsError::InvalidInputData}; pub(crate) fn validate_data_sites(x: ArrayView1) -> Result<()> where T: Real + // T: AlmostEqual + NdFloat { for w in x.windows(2) { let e1 = w[0]; @@ -26,6 +28,7 @@ pub(crate) fn validate_data_sites(x: ArrayView1) -> Result<()> pub(crate) fn validate_smooth_value(smooth: T) -> Result<()> where T: Real + // T: NdFloat { if smooth < T::zero() || smooth > T::one() { return Err( diff --git a/tests/umv_make.rs b/tests/umv_make.rs index 6889497..cf42e40 100644 --- a/tests/umv_make.rs +++ b/tests/umv_make.rs @@ -1,11 +1,19 @@ +use std::ops::{Add, Mul}; + use ndarray::{array, Array, Array2, Dimension, Array1}; -use csaps::{Real, CubicSmoothingSpline}; +use csaps::{Real, CubicSmoothingSpline, RealRef}; +use sprs::MulAcc; fn test_driver_make_nd_npt(x: Array1, y: Array, order: usize, pieces: usize, coeffs: Array2) where - T: Real, + T: Real, + for<'r> &'r T: RealRef<&'r T, T>, + + // for<'r> &'r T: Add<&'r T, Output = T>, + // T: MulAcc, + // for<'r> &'r T: Mul<&'r T, Output = T>, D: Dimension { let s = CubicSmoothingSpline::new(&x, &y) @@ -22,7 +30,12 @@ fn test_driver_make_nd_npt(x: Array1, y: Array, fn test_driver_make_nd_2pt(x: Array1, y: Array, coeffs: Array2) where - T: Real, + T: Real, + for<'r> &'r T: RealRef<&'r T, T>, + + // for<'r> &'r T: Add<&'r T, Output = T>, + // T: MulAcc, + // for<'r> &'r T: Mul<&'r T, Output = T>, D: Dimension { test_driver_make_nd_npt(x, y, 2, 1, coeffs); @@ -30,8 +43,10 @@ fn test_driver_make_nd_2pt(x: Array1, y: Array, coeffs: Array2 fn test_driver_make_nd_4pt(x: Array1, y: Array, coeffs: Array2) where - T: Real, - D: Dimension + T: Real, + D: Dimension, + for<'r> &'r T: RealRef<&'r T, T>, + { test_driver_make_nd_npt(x, y, 4, 3, coeffs); }