Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Quantity-Aware access parts of quantity with complex storage type #454

Open
mkalte666 opened this issue Jan 17, 2024 · 2 comments
Open

Quantity-Aware access parts of quantity with complex storage type #454

mkalte666 opened this issue Jan 17, 2024 · 2 comments

Comments

@mkalte666
Copy link

mkalte666 commented Jan 17, 2024

It can be interesting (or needed) to access only the real or imaginary part of a complex quantity.

Currently, i have solved this for my codebase like this, but it would be nice to have this available in uom directly as well. For all i know, its already there; im known to miss the most obvious functions out there :D

/// Helper trait to grab real or complex parts of Quantities
pub trait ComplexAccess {
    type VT;
    type AT;
    /// Get the real part of Self
    fn real(&self) -> Self::VT;

    /// Get the imaginary part of Self
    fn imag(&self) -> Self::VT;

    /// Get the norm of Self
    fn norm(&self) -> Self::VT;

    /// Get the argument of Self
    fn arg(&self) -> Self::AT;
}

use uom::{storage_type_complex32, storage_type_complex64};

storage_types! {
    pub types: Complex;

    impl<D> crate::ComplexAccess for uom::si::Quantity<D,uom::si::SI<V>,V>
    where
        D: uom::si::Dimension + ?Sized,
    {
        type VT = uom::si::Quantity<D,uom::si::SI<VV>,VV>;
        type AT = uom::si::angle::Angle<uom::si::SI::<VV>,VV>;
        fn real(&self) -> Self::VT {
            Self::VT {
                dimension: self.dimension,
                units: std::marker::PhantomData::default(),
                value: self.value.re
            }
        }

        fn imag(&self) -> Self::VT {
            Self::VT {
                dimension: self.dimension,
                units: std::marker::PhantomData::default(),
                value: self.value.im
            }
        }

        fn norm(&self) -> Self::VT
        {
            Self::VT {
                dimension: self.dimension,
                units: std::marker::PhantomData::default(),
                value: self.value.norm()
            }
        }

        fn arg(&self) -> Self::AT
        {
           Self::AT::new::<uom::si::angle::radian>(self.value.arg())
        }
    }
}

Example usage would be somthing like this:

let z = si::complex64::ElectricalResistance::new::<ohm>(Complex64::new(123.0,321.0));
let im : si::f64::ElectricalResistance = z.real(); 
assert_eq!(im.get::<ohm>(), 321.0);
// do something with re; i.e compute a capacitance or whatever else 
@iliekturtles
Copy link
Owner

I don't think the trait is necessary. Similar to how how methods for other underlying types are implemented, we would just need to add methods for Complex to return the re/im fields.

e.g. is_nan for floating point types:

uom/src/system.rs

Lines 759 to 780 in 85b665e

// Explicitly definte floating point methods for float and complex storage types.
// `Complex<T>` doesn't implement `Float`/`FloatCore`, but it does implement these methods
// when the underlying type, `T`, implements `FloatCore`.
mod float {
storage_types! {
types: Float, Complex;
use super::super::*;
impl<D, U> Quantity<D, U, V>
where
D: Dimension + ?Sized,
U: Units<V> + ?Sized,
{
/// Returns `true` if this value is `NAN` and `false` otherwise.
#[cfg_attr(feature = "cargo-clippy", allow(clippy::wrong_self_convention))]
#[must_use = "method returns a new number and does not mutate the original value"]
#[inline(always)]
pub fn is_nan(self) -> bool
{
self.value.is_nan()
}

@mkalte666
Copy link
Author

mkalte666 commented Jan 19, 2024

oh sorry I should have clarified this; im using the trait because I don't wanna keep track of(rather, don't have the time for) more patching right now. Basically a quick and dirty way to get this to work for me right now without much thought^^

A solution like you described would be much preferable :D

Maybe I can get to that as well later, but right now I'm quite busy in way to may ways ;_;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants