From 6f9cccfebdd40fa91012e424c306398909aaf12f Mon Sep 17 00:00:00 2001 From: Philipp Rehner Date: Sat, 18 Apr 2026 18:29:33 +0200 Subject: [PATCH] Extend methods of `Angle` to dual numbers --- CHANGELOG.md | 2 ++ Cargo.toml | 3 +++ src/lib.rs | 64 +++++++++++++++++++++++++++++++--------------------- 3 files changed, 43 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b3c36cb..889afb4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Added +- Added implementations for trigonometric funtions for `Angle` with `T: DualNum` when the `num-dual` feature is active. [#105](https://github.com/itt-ustutt/quantity/pull/105) ## [0.13.0] - 2026-01-06 ### Changed diff --git a/Cargo.toml b/Cargo.toml index f8dd49e..a519acf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,6 +35,9 @@ pyo3 = { version = "0.27", optional = true } numpy = { version = "0.27", optional = true } num-dual = { version = "0.13", optional = true } +[dev-dependencies] +approx = "0.5" + [features] default = [] ## Use generalized (hyper-)dual numbers from the [num-dual] crate as value of a quantity. diff --git a/src/lib.rs b/src/lib.rs index 78f03ee..a1b2373 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -647,34 +647,46 @@ pub const RADIANS: Angle = Quantity(1.0, PhantomData); /// Angle unit degrees $\\left(1°=\\frac{\\pi}{180}\text{rad}\\right)$ pub const DEGREES: Angle = Quantity(std::f64::consts::PI / 180., PhantomData); -impl Angle { - pub fn sin(self) -> f64 { - self.0.sin() - } - - pub fn cos(self) -> f64 { - self.0.cos() - } - - pub fn tan(self) -> f64 { - self.0.tan() - } - - pub fn asin(x: f64) -> Self { - Quantity(x.asin(), PhantomData) - } - - pub fn acos(x: f64) -> Self { - Quantity(x.acos(), PhantomData) - } +macro_rules! angle_methods { + ($t:ty) => { + pub fn sin(self) -> $t { + self.0.sin() + } + + pub fn cos(self) -> $t { + self.0.cos() + } + + pub fn tan(self) -> $t { + self.0.tan() + } + + pub fn asin(x: $t) -> Self { + Quantity(x.asin(), PhantomData) + } + + pub fn acos(x: $t) -> Self { + Quantity(x.acos(), PhantomData) + } + + pub fn atan(x: $t) -> Self { + Quantity(x.atan(), PhantomData) + } + + pub fn atan2(y: $t, x: $t) -> Self { + Quantity(y.atan2(x), PhantomData) + } + }; +} - pub fn atan(x: f64) -> Self { - Quantity(x.atan(), PhantomData) - } +#[cfg(not(feature = "num-dual"))] +impl Angle { + angle_methods!(f64); +} - pub fn atan2(y: f64, x: f64) -> Self { - Quantity(y.atan2(x), PhantomData) - } +#[cfg(feature = "num-dual")] +impl> Angle { + angle_methods!(T); } impl Dimensionless {