use crate::api::expr::{Ex, Expr, Numeric};
use crate::base::assumptions::Props;
impl Expr<Numeric> {
#[must_use]
pub fn re(&self) -> Ex {
let id = self.inner.write().arena.re(self.raw_id());
self.wrap(id)
}
#[must_use]
pub fn im(&self) -> Ex {
let id = self.inner.write().arena.im(self.raw_id());
self.wrap(id)
}
#[must_use]
pub fn conjugate(&self) -> Ex {
let id = self.inner.write().arena.conjugate(self.raw_id());
self.wrap(id)
}
#[must_use]
pub fn arg(&self) -> Ex {
let id = self.inner.write().arena.arg(self.raw_id());
self.wrap(id)
}
#[must_use]
pub fn as_real_imag(&self) -> (Ex, Ex) {
let (re, im) = self.inner.write().arena.as_real_imag_expr(self.raw_id());
(self.wrap(re), self.wrap(im))
}
#[must_use]
pub fn expand_complex(&self) -> Ex {
let id = {
let mut guard = self.inner.write();
crate::base::complex::expand_complex(&mut guard.arena, self.raw_id())
};
self.wrap(id)
}
#[must_use]
pub fn polar(&self) -> (Ex, Ex) {
(self.abs(), self.arg())
}
#[must_use]
pub fn abs_squared(&self) -> Ex {
let id = {
let mut guard = self.inner.write();
let arena = &mut guard.arena;
let parts = crate::base::complex::decompose(arena, self.raw_id());
if parts.exact {
let two = arena.int(2);
let re2 = arena.pow(parts.re, two);
let im2 = arena.pow(parts.im, two);
arena.add(&[re2, im2])
} else {
let conj = arena.conjugate(self.raw_id());
arena.mul(&[self.raw_id(), conj])
}
};
self.wrap(id)
}
#[must_use]
pub fn is_real_valued(&self) -> Option<bool> {
if let Some(v) = self.query(Props::REAL) {
return Some(v);
}
let mut guard = self.inner.write();
let arena = &mut guard.arena;
let parts = crate::base::complex::decompose(arena, self.raw_id());
if parts.im == arena.zero() {
return Some(true);
}
if parts.exact {
if let Some(r) = arena.as_num(parts.im)
&& !num_traits::Zero::is_zero(r)
{
return Some(false);
}
let im_id = parts.im;
drop(guard);
let im_ex = self.wrap(im_id);
return match im_ex.query(Props::ZERO) {
Some(true) => Some(true),
_ => match im_ex.query(Props::NONZERO) {
Some(true) => Some(false),
_ => None,
},
};
}
None
}
}
impl Expr<Numeric> {
#[must_use]
pub fn si(&self) -> Ex {
let id = self.inner.write().arena.si(self.raw_id());
self.wrap(id)
}
#[must_use]
pub fn ci(&self) -> Ex {
let id = self.inner.write().arena.ci(self.raw_id());
self.wrap(id)
}
#[must_use]
pub fn ei(&self) -> Ex {
let id = self.inner.write().arena.ei(self.raw_id());
self.wrap(id)
}
#[must_use]
pub fn li(&self) -> Ex {
let id = self.inner.write().arena.li(self.raw_id());
self.wrap(id)
}
#[must_use]
pub fn zeta(&self) -> Ex {
let id = self.inner.write().arena.zeta(self.raw_id());
self.wrap(id)
}
#[must_use]
pub fn polygamma(&self, n: &Ex) -> Ex {
let n_id = self.checked_id(n);
let id = self.inner.write().arena.polygamma(n_id, self.raw_id());
self.wrap(id)
}
#[must_use]
pub fn kronecker_delta(&self, other: &Ex) -> Ex {
let other_id = self.checked_id(other);
let id = self
.inner
.write()
.arena
.kronecker_delta(self.raw_id(), other_id);
self.wrap(id)
}
}