From bd4c1c520bc2ed4abe285eaf5aafc289e931d44c Mon Sep 17 00:00:00 2001 From: Philipp Rehner Date: Wed, 12 Aug 2026 13:20:48 +0200 Subject: [PATCH] Update num-dual dependency to 0.15 --- CHANGELOG.md | 4 +++ Cargo.toml | 4 +-- README.md | 2 +- src/ad.rs | 89 ++++++++++++++++++++++++---------------------------- src/lib.rs | 2 +- src/ops.rs | 6 ++-- 6 files changed, 53 insertions(+), 54 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 979ca81..71c08ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.15.0] - 2026-08-12 +### Packaging +- Updated `num-dual` dependency to 0.15. + ## [0.14.1] - 2026-07-24 ### Added - Added `into_dimensionality` and `into_dyn` for quantities of arrays. [#119](https://github.com/itt-ustutt/quantity/pull/119) diff --git a/Cargo.toml b/Cargo.toml index 5b0f580..89921e9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "quantity" -version = "0.14.1" +version = "0.15.0" authors = [ "Philipp Rehner ", "Gernot Bauer ", @@ -33,7 +33,7 @@ nalgebra = { version = "0.35", optional = true } approx = { version = "0.5", optional = true } pyo3 = { version = "0.29", optional = true } numpy = { version = "0.29", optional = true } -num-dual = { version = "0.14", optional = true } +num-dual = { version = "0.15", optional = true } [dev-dependencies] approx = "0.5" diff --git a/README.md b/README.md index 3a53652..7981eba 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Add this to your `Cargo.toml`: ``` [dependencies] -quantity = "0.14" +quantity = "0.15" ``` ## Examples diff --git a/src/ad.rs b/src/ad.rs index 6a3920f..16517b3 100644 --- a/src/ad.rs +++ b/src/ad.rs @@ -6,7 +6,7 @@ use num_dual::{ }; use std::ops::Sub; -impl, U> DualStruct for Quantity { +impl DualStruct for Quantity { type Real = Quantity; type Inner = Quantity; @@ -19,21 +19,21 @@ impl, U> DualStruct for Quantity { } } -pub fn zeroth_derivative, UX, UY>(g: G, x: Quantity) -> Quantity +pub fn zeroth_derivative(g: G, x: Quantity) -> Quantity where - G: Fn(Quantity, UX>) -> Quantity, UY>, + G: Fn(Quantity, UX>) -> Quantity, UY>, UY: Sub, { let r = num_dual::zeroth_derivative(|x| g(Quantity::new(x)).0, x.0); Quantity::new(r) } -pub fn first_derivative, UX, UY>( +pub fn first_derivative( g: G, x: Quantity, ) -> (Quantity, Quantity>) where - G: Fn(Quantity, UX>) -> Quantity, UY>, + G: Fn(Quantity, UX>) -> Quantity, UY>, UY: Sub, { let r = num_dual::first_derivative(|x| g(Quantity::new(x)).0, x.0); @@ -41,13 +41,13 @@ where } #[expect(clippy::type_complexity)] -pub fn gradient, UX, UY, N: Dim>( +pub fn gradient( g: G, x: &Quantity, UX>, ) -> (Quantity, Quantity, Diff>) where DefaultAllocator: Allocator, - G: Fn(Quantity, N>, UX>) -> Quantity, UY>, + G: Fn(Quantity, N>, UX>) -> Quantity, UY>, UY: Sub, { let r = num_dual::gradient(|x| g(Quantity::new(x)).0, &x.0); @@ -55,13 +55,13 @@ where } #[expect(clippy::type_complexity)] -pub fn gradient_copy + Copy, UX, UY, N: Gradients>( +pub fn gradient_copy( g: G, x: &Quantity, UX>, ) -> (Quantity, Quantity, Diff>) where DefaultAllocator: Allocator, - G: Fn(Quantity, N>, UX>) -> Quantity, UY>, + G: Fn(Quantity, N>, UX>) -> Quantity, UY>, UY: Sub, { let r = N::gradient(|x, _: &()| g(Quantity::new(x)).0, &x.0, &()); @@ -69,7 +69,7 @@ where } #[expect(clippy::type_complexity)] -pub fn jacobian, UX, UY, M: Dim, N: Dim>( +pub fn jacobian( g: G, x: &Quantity, UX>, ) -> ( @@ -78,9 +78,7 @@ pub fn jacobian, UX, UY, M: Dim, N: Dim>( ) where DefaultAllocator: Allocator + Allocator + Allocator + Allocator, - G: Fn( - Quantity, N>, UX>, - ) -> Quantity, M>, UY>, + G: Fn(Quantity, N>, UX>) -> Quantity, M>, UY>, UY: Sub, { let r = num_dual::jacobian(|x| g(Quantity::new(x)).0, &x.0); @@ -88,7 +86,7 @@ where } #[expect(clippy::type_complexity)] -pub fn jacobian_copy + Copy, UX, UY, N: Gradients>( +pub fn jacobian_copy( g: G, x: &Quantity, UX>, ) -> ( @@ -97,7 +95,7 @@ pub fn jacobian_copy + Copy, UX, UY, N: Gradients>( ) where DefaultAllocator: Allocator + Allocator + Allocator + Allocator, - G: Fn(Quantity, N>, UX>) -> Quantity, N>, UY>, + G: Fn(Quantity, N>, UX>) -> Quantity, N>, UY>, UY: Sub, { let r = N::jacobian(|x, _: &()| g(Quantity::new(x)).0, &x.0, &()); @@ -105,7 +103,7 @@ where } #[expect(clippy::type_complexity)] -pub fn second_derivative, UX, UY>( +pub fn second_derivative( g: G, x: Quantity, ) -> ( @@ -114,7 +112,7 @@ pub fn second_derivative, UX, UY>( Quantity, UX>>, ) where - G: Fn(Quantity, UX>) -> Quantity, UY>, + G: Fn(Quantity, UX>) -> Quantity, UY>, UY: Sub, Diff: Sub, { @@ -123,7 +121,7 @@ where } #[expect(clippy::type_complexity)] -pub fn hessian, UX, UY, N: Dim>( +pub fn hessian( g: G, x: &Quantity, UX>, ) -> ( @@ -133,7 +131,7 @@ pub fn hessian, UX, UY, N: Dim>( ) where DefaultAllocator: Allocator + Allocator + Allocator, - G: Fn(Quantity, N>, UX>) -> Quantity, UY>, + G: Fn(Quantity, N>, UX>) -> Quantity, UY>, UY: Sub, Diff: Sub, { @@ -142,7 +140,7 @@ where } #[expect(clippy::type_complexity)] -pub fn hessian_copy + Copy, UX, UY, N: Gradients>( +pub fn hessian_copy( g: G, x: &Quantity, UX>, ) -> ( @@ -152,7 +150,7 @@ pub fn hessian_copy + Copy, UX, UY, N: Gradients>( ) where DefaultAllocator: Allocator + Allocator, - G: Fn(Quantity, N>, UX>) -> Quantity, UY>, + G: Fn(Quantity, N>, UX>) -> Quantity, UY>, UY: Sub, Diff: Sub, { @@ -161,7 +159,7 @@ where } #[expect(clippy::type_complexity)] -pub fn second_partial_derivative, UX, UY, UZ>( +pub fn second_partial_derivative( g: G, (x, y): (Quantity, Quantity), ) -> ( @@ -171,12 +169,7 @@ pub fn second_partial_derivative, UX, UY, UZ>( Quantity, UY>>, ) where - G: Fn( - ( - Quantity, UX>, - Quantity, UY>, - ), - ) -> Quantity, UZ>, + G: Fn((Quantity, UX>, Quantity, UY>)) -> Quantity, UZ>, UZ: Sub, UZ: Sub, Diff: Sub, @@ -194,7 +187,7 @@ where } #[expect(clippy::type_complexity)] -pub fn partial_hessian, UX, UY, UZ, M: Dim, N: Dim>( +pub fn partial_hessian( g: G, (x, y): (&Quantity, UX>, &Quantity, UY>), ) -> ( @@ -206,10 +199,10 @@ pub fn partial_hessian, UX, UY, UZ, M: Dim, N: Dim>( where G: Fn( ( - Quantity, M>, UX>, - Quantity, N>, UY>, + Quantity, M>, UX>, + Quantity, N>, UY>, ), - ) -> Quantity, UZ>, + ) -> Quantity, UZ>, DefaultAllocator: Allocator + Allocator + Allocator + Allocator, UZ: Sub, UZ: Sub, @@ -228,7 +221,7 @@ where } #[expect(clippy::type_complexity)] -pub fn partial_hessian_copy + Copy, UX, UY, UZ, N: Gradients>( +pub fn partial_hessian_copy( g: G, (x, y): (&Quantity, UX>, Quantity), ) -> ( @@ -240,10 +233,10 @@ pub fn partial_hessian_copy + Copy, UX, UY, UZ, N: Gradients> where G: Fn( ( - Quantity, N>, UX>, - Quantity, UY>, + Quantity, N>, UX>, + Quantity, UY>, ), - ) -> Quantity, UZ>, + ) -> Quantity, UZ>, DefaultAllocator: Allocator, UZ: Sub, UZ: Sub, @@ -264,7 +257,7 @@ where } #[expect(clippy::type_complexity)] -pub fn third_derivative, UX, UY>( +pub fn third_derivative( g: G, x: Quantity, ) -> ( @@ -274,7 +267,7 @@ pub fn third_derivative, UX, UY>( Quantity, UX>, UX>>, ) where - G: Fn(Quantity, UX>) -> Quantity, UY>, + G: Fn(Quantity, UX>) -> Quantity, UY>, UY: Sub, Diff: Sub, Diff, UX>: Sub, @@ -289,7 +282,7 @@ where } #[expect(clippy::type_complexity)] -pub fn third_partial_derivative, UX, UY, UZ, U>( +pub fn third_partial_derivative( g: G, (x, y, z): (Quantity, Quantity, Quantity), ) -> ( @@ -305,11 +298,11 @@ pub fn third_partial_derivative, UX, UY, UZ, U>( where G: Fn( ( - Quantity, UX>, - Quantity, UY>, - Quantity, UZ>, + Quantity, UX>, + Quantity, UY>, + Quantity, UZ>, ), - ) -> Quantity, UY>, + ) -> Quantity, UY>, U: Sub, U: Sub, U: Sub, @@ -343,10 +336,10 @@ mod test_num_dual { use num_dual::{Dual64, ImplicitDerivative, ImplicitFunction}; struct AreaImplicit; - impl ImplicitFunction for AreaImplicit { + impl ImplicitFunction for AreaImplicit { type Parameters = Area; type Variable = D; - fn residual + Copy>(x: D, &area: &Area) -> D { + fn residual(x: D, &area: &Area) -> D { let l = Length::new(x); (area - l * l).convert_into(area) } @@ -361,18 +354,18 @@ mod test_num_dual { assert_eq!(x, a.0.sqrt()) } - fn volume + Copy>(x: Length) -> Volume { + fn volume(x: Length) -> Volume { x * x * x } - fn distance, N: Dim>(x: Length>) -> Length + fn distance(x: Length>) -> Length where DefaultAllocator: Allocator, { x.dot(&x).sqrt() } - fn volume2 + Copy>((x, h): (Length, Length)) -> Volume { + fn volume2((x, h): (Length, Length)) -> Volume { x * x * h } diff --git a/src/lib.rs b/src/lib.rs index 5fd6e5b..ac7d8fc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -699,7 +699,7 @@ impl Angle { } #[cfg(feature = "num-dual")] -impl> Angle { +impl Angle { angle_methods!(T); } diff --git a/src/ops.rs b/src/ops.rs index f247f0b..b3379d0 100644 --- a/src/ops.rs +++ b/src/ops.rs @@ -9,6 +9,8 @@ use nalgebra::{DefaultAllocator, Dim, OMatrix}; use ndarray::{Array, ArrayBase, Data, DataMut, DataOwned, Dimension}; #[cfg(feature = "num-dual")] use num_dual::DualNum; +#[cfg(feature = "num-dual")] +use num_traits::FromPrimitive; use num_traits::{Inv, Signed}; use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; @@ -430,7 +432,7 @@ impl Quantity { } #[cfg(feature = "num-dual")] -impl, U> Quantity { +impl Quantity { /// Calculate the integer power of self. /// /// # Example @@ -492,7 +494,7 @@ impl, U> Quantity { where U: Div>, { - Quantity::new(self.0.powf(1.0 / R as f64)) + Quantity::new(self.0.powf(D::Primitive::from_f64(1.0 / R as f64).unwrap())) } }