#[macro_export]
macro_rules! measure {
( [$( $val:expr ),+] $(; $aprox:literal)?) => {
{
let value = vec![$($val as f64,)+];
let mut _aprox = true;
$ ( _aprox = $aprox;)?
match Measure::new(vec![$($val as f64,)+], vec![0.0; value.len()], _aprox) {
Ok(measure) => measure,
Err(e) => panic!("{}", e)
}
}
};
( [$( $val:expr),+], $err:literal $(; $aprox:literal)?) => {
{
let value = vec![$($val as f64,)+];
let mut _aprox = true;
$ ( _aprox = $aprox;)?
match Measure::new(vec![$($val as f64,)+], vec![$err as f64; value.len()], _aprox) {
Ok(measure) => measure,
Err(e) => panic!("{}", e)
}
}
};
( [$( $val:expr),+] , [$( $err:expr ),+] $(; $aprox:literal)?) => {
{
let mut _aprox = true;
$ ( _aprox = $aprox;)?
match Measure::new(vec![$($val as f64,)+], vec![$($err as f64,)+], _aprox) {
Ok(measure) => measure,
Err(e) => panic!("{}", e)
}
}
};
( $val:literal , $err:literal $(; $aprox:literal)?) => {
{
let mut _aprox = true;
$ ( _aprox = $aprox;)?
match Measure::new(vec![$val as f64], vec![$err as f64], _aprox) {
Ok(measure) => measure,
Err(e) => panic!("{}", e)
}
}
};
( $( ($val:expr, $err:expr) ),+ $(; $aprox:literal)?) => {
{
let mut _aprox = true;
$ ( _aprox = $aprox;)?
match Measure::new(vec![$($val as f64,)+], vec![$($err as f64,)+], _aprox) {
Ok(measure) => measure,
Err(e) => panic!("{}", e)
}
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! impl_op {
($from:ty, $for:ty) => {
impl Add<$from> for $for {
type Output = Measure;
fn add(self, other: $from) -> Self::Output {
if self.len() == 1 {
return Measure {
value: other
.value
.iter()
.map(|oval| self.value[0] + oval)
.collect(),
error: other
.error
.iter()
.map(|oerr| (self.error[0].powi(2) + oerr.powi(2)).sqrt())
.collect(),
style: Style::PM,
};
}
if other.len() == 1 {
return Measure {
value: self
.value
.iter()
.map(|sval| sval + other.value[0])
.collect(),
error: self
.error
.iter()
.map(|serr| (serr.powi(2) + other.error[0].powi(2)).sqrt())
.collect(),
style: Style::PM,
};
}
assert_eq!(
self.len(),
other.len(),
"Measures lengths must be equals, obtained {} and {}.",
self.len(),
other.len()
);
Measure {
value: self
.value
.iter()
.zip(other.value.iter())
.map(|(sval, oval)| sval + oval)
.collect(),
error: self
.error
.iter()
.zip(other.error.iter())
.map(|(serr, oerr)| (serr.powi(2) + oerr.powi(2)).sqrt())
.collect(),
style: Style::PM,
}
}
}
impl Sub<$from> for $for {
type Output = Measure;
fn sub(self, other: $from) -> Self::Output {
if self.len() == 1 {
return Measure {
value: other
.value
.iter()
.map(|oval| self.value[0] - oval)
.collect(),
error: other
.error
.iter()
.map(|oerr| (self.error[0].powi(2) + oerr.powi(2)).sqrt())
.collect(),
style: Style::PM,
};
}
if other.len() == 1 {
return Measure {
value: self
.value
.iter()
.map(|sval| sval - other.value[0])
.collect(),
error: self
.error
.iter()
.map(|serr| (serr.powi(2) + other.error[0].powi(2)).sqrt())
.collect(),
style: Style::PM,
};
}
assert_eq!(
self.len(),
other.len(),
"Measures lengths must be equals, obtained {} and {}.",
self.len(),
other.len()
);
Measure {
value: self
.value
.iter()
.zip(other.value.iter())
.map(|(sval, oval)| sval - oval)
.collect(),
error: self
.error
.iter()
.zip(other.error.iter())
.map(|(serr, oerr)| (serr.powi(2) + oerr.powi(2)).sqrt())
.collect(),
style: Style::PM,
}
}
}
impl Mul<$from> for $for {
type Output = Measure;
fn mul(self, other: $from) -> Self::Output {
if self.len() == 1 {
return Measure {
value: other
.value
.iter()
.map(|oval| self.value[0] * oval)
.collect(),
error: other
.iter()
.map(|(oval, oerr)| {
((oval * self.error[0]).powi(2) + (oerr * self.value[0]).powi(2))
.sqrt()
})
.collect(),
style: Style::PM,
};
}
if other.len() == 1 {
return Measure {
value: self
.value
.iter()
.map(|sval| sval * other.value[0])
.collect(),
error: self
.iter()
.map(|(sval, serr)| {
((other.value[0] * serr).powi(2) + (sval * other.error[0]).powi(2))
.sqrt()
})
.collect(),
style: Style::PM,
};
}
assert_eq!(
self.len(),
other.len(),
"Measures lengths must be equals, obtained {} and {}.",
self.len(),
other.len()
);
Measure {
value: self
.value
.iter()
.zip(other.value.iter())
.map(|(sval, oval)| sval * oval)
.collect(),
error: self
.iter()
.zip(other.iter())
.map(|((sval, serr), (oval, oerr))| {
((oval * serr).powi(2) + (sval * oerr).powi(2)).sqrt()
})
.collect(),
style: Style::PM,
}
}
}
impl Div<$from> for $for {
type Output = Measure;
fn div(self, other: $from) -> Self::Output {
if self.len() == 1 {
return Measure {
value: other
.value
.iter()
.map(|oval| self.value[0] / oval)
.collect(),
error: other
.iter()
.map(|(oval, oerr)| {
((1.0 / oval * self.error[0]).powi(2)
+ (self.value[0] / oval.powi(2) * oerr.powi(2)))
.sqrt()
})
.collect(),
style: Style::PM,
};
}
if other.len() == 1 {
return Measure {
value: self
.value
.iter()
.map(|sval| sval / other.value[0])
.collect(),
error: self
.iter()
.map(|(sval, serr)| {
((1.0 / other.value[0] * serr).powi(2)
+ (sval / other.value[0].powi(2) * other.error[0].powi(2)))
.sqrt()
})
.collect(),
style: Style::PM,
};
}
assert_eq!(
self.len(),
other.len(),
"Measures lengths must be equals, obtained {} and {}.",
self.len(),
other.len()
);
Measure {
value: self
.value
.iter()
.zip(other.value.iter())
.map(|(sval, oval)| sval / oval)
.collect(),
error: self
.iter()
.zip(other.iter())
.map(|((sval, serr), (oval, oerr))| {
((1.0 / oval * serr).powi(2) + (sval / oval.powi(2) * oerr.powi(2)))
.sqrt()
})
.collect(),
style: Style::PM,
}
}
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! impl_op_number {
($for:ty) => {
impl<T: std::convert::Into<f64>> Add<T> for $for {
type Output = Measure;
fn add(self, num: T) -> Self::Output {
let num = num.into();
Measure {
value: self.value.iter().map(|val| val + num).collect(),
error: self.error.clone(),
style: Style::PM,
}
}
}
impl<T: std::convert::Into<f64>> Sub<T> for $for {
type Output = Measure;
fn sub(self, num: T) -> Self::Output {
let num = num.into();
Measure {
value: self.value.iter().map(|val| val - num).collect(),
error: self.error.clone(),
style: Style::PM,
}
}
}
impl<T: std::convert::Into<f64>> Mul<T> for $for {
type Output = Measure;
fn mul(self, num: T) -> Self::Output {
let num = num.into();
Measure {
value: self.value.iter().map(|val| val * num).collect(),
error: self.error.iter().map(|err| err * num.abs()).collect(),
style: Style::PM,
}
}
}
impl<T: std::convert::Into<f64>> Div<T> for $for {
type Output = Measure;
fn div(self, num: T) -> Self::Output {
let num = num.into();
Measure {
value: self.value.iter().map(|val| val / num).collect(),
error: self.error.iter().map(|err| err / num.abs()).collect(),
style: Style::PM,
}
}
}
};
($from:ty, $for:ty) => {
impl Add<$from> for $for {
type Output = Measure;
fn add(self, measure: $from) -> Self::Output {
Measure {
value: measure
.value
.iter()
.map(|val| val + (self as f64))
.collect(),
error: measure.error.clone(),
style: Style::PM,
}
}
}
impl Sub<$from> for $for {
type Output = Measure;
fn sub(self, measure: $from) -> Self::Output {
Measure {
value: measure
.value
.iter()
.map(|val| val - (self as f64))
.collect(),
error: measure.error.clone(),
style: Style::PM,
}
}
}
impl Mul<$from> for $for {
type Output = Measure;
fn mul(self, measure: $from) -> Self::Output {
Measure {
value: measure
.value
.iter()
.map(|val| val * (self as f64))
.collect(),
error: measure
.error
.iter()
.map(|err| err * (self as f64).abs())
.collect(),
style: Style::PM,
}
}
}
impl Div<$from> for $for {
type Output = Measure;
fn div(self, measure: $from) -> Self::Output {
Measure {
value: measure
.value
.iter()
.map(|val| (self as f64) / val)
.collect(),
error: measure
.iter()
.map(|(val, err)| (self as f64).abs() * err / val.powi(2))
.collect(),
style: Style::PM,
}
}
}
};
}