use crate::symbolic::core::Expr;
use crate::symbolic::simplify_dag::simplify;
#[must_use]
pub fn arg(z: &Expr) -> Expr {
Expr::new_apply(Expr::Variable("Arg".to_string()), z.clone())
}
#[must_use]
pub fn abs(z: &Expr) -> Expr {
Expr::new_abs(z.clone())
}
#[must_use]
pub fn general_log(
z: &Expr,
k: &Expr,
) -> Expr {
let pi = Expr::Pi;
let i = Expr::new_complex(Expr::Constant(0.0), Expr::Constant(1.0));
let term_2_pi_k = Expr::new_mul(Expr::Constant(2.0), Expr::new_mul(pi, k.clone()));
let full_arg = Expr::new_add(arg(z), term_2_pi_k);
let result = Expr::new_add(Expr::new_log(abs(z)), Expr::new_mul(i, full_arg));
simplify(&result)
}
#[must_use]
pub fn general_sqrt(
z: &Expr,
k: &Expr,
) -> Expr {
let pi = Expr::Pi;
let i = Expr::new_complex(Expr::Constant(0.0), Expr::Constant(1.0));
let magnitude_sqrt = Expr::new_sqrt(abs(z));
let angle = Expr::new_div(
Expr::new_add(
arg(z),
Expr::new_mul(Expr::Constant(2.0), Expr::new_mul(pi, k.clone())),
),
Expr::Constant(2.0),
);
let result = Expr::new_mul(magnitude_sqrt, Expr::new_exp(Expr::new_mul(i, angle)));
simplify(&result)
}
#[must_use]
pub fn general_power(
z: &Expr,
w: &Expr,
k: &Expr,
) -> Expr {
let log_z = general_log(z, k);
simplify(&Expr::new_exp(Expr::new_mul(w.clone(), log_z)))
}
#[must_use]
pub fn general_nth_root(
z: &Expr,
n: &Expr,
k: &Expr,
) -> Expr {
let pi = Expr::Pi;
let i = Expr::new_complex(Expr::Constant(0.0), Expr::Constant(1.0));
let magnitude_root = Expr::new_pow(abs(z), Expr::new_div(Expr::Constant(1.0), n.clone()));
let angle = Expr::new_div(
Expr::new_add(
arg(z),
Expr::new_mul(Expr::Constant(2.0), Expr::new_mul(pi, k.clone())),
),
n.clone(),
);
let result = Expr::new_mul(magnitude_root, Expr::new_exp(Expr::new_mul(i, angle)));
simplify(&result)
}
#[must_use]
pub fn general_arcsin(
z: &Expr,
k: &Expr,
) -> Expr {
let pi = Expr::Pi;
let principal_arcsin = Expr::new_arcsin(z.clone());
let term1 = Expr::new_mul(k.clone(), pi);
let term2 = Expr::new_mul(
Expr::new_pow(Expr::Constant(-1.0), k.clone()),
principal_arcsin,
);
simplify(&Expr::new_add(term1, term2))
}
#[must_use]
pub fn general_arccos(
z: &Expr,
k: &Expr,
s: &Expr,
) -> Expr {
let pi = Expr::Pi;
let principal_arccos = Expr::new_arccos(z.clone());
let term1 = Expr::new_mul(Expr::Constant(2.0), Expr::new_mul(k.clone(), pi));
let term2 = Expr::new_mul(s.clone(), principal_arccos);
simplify(&Expr::new_add(term1, term2))
}
#[must_use]
pub fn general_arctan(
z: &Expr,
k: &Expr,
) -> Expr {
let pi = Expr::Pi;
let principal_arctan = Expr::new_arctan(z.clone());
let term1 = Expr::new_mul(k.clone(), pi);
simplify(&Expr::new_add(term1, principal_arctan))
}
#[must_use]
pub fn general_arcsinh(
z: &Expr,
k: &Expr,
) -> Expr {
let z_squared = Expr::new_pow(z.clone(), Expr::Constant(2.0));
let inner = Expr::new_add(z_squared, Expr::Constant(1.0));
let sqrt_part = general_sqrt(&inner, &Expr::Constant(0.0)); let arg = Expr::new_add(z.clone(), sqrt_part);
general_log(&arg, k)
}
#[must_use]
pub fn general_arccosh(
z: &Expr,
k: &Expr,
) -> Expr {
let z_squared = Expr::new_pow(z.clone(), Expr::Constant(2.0));
let inner = Expr::new_sub(z_squared, Expr::Constant(1.0));
let sqrt_part = general_sqrt(&inner, &Expr::Constant(0.0)); let arg = Expr::new_add(z.clone(), sqrt_part);
general_log(&arg, k)
}
#[must_use]
pub fn general_arctanh(
z: &Expr,
k: &Expr,
) -> Expr {
let numerator = Expr::new_add(Expr::Constant(1.0), z.clone());
let denominator = Expr::new_sub(Expr::Constant(1.0), z.clone());
let ratio = Expr::new_div(numerator, denominator);
let log_part = general_log(&ratio, k);
simplify(&Expr::new_mul(Expr::Constant(0.5), log_part))
}