use crate::error::SymEngineResult;
use crate::expr::{ExprLang, Expression};
use egg::RecExpr;
pub fn sin(x: &Expression) -> Expression {
apply_unary(x, ExprLang::Sin)
}
pub fn cos(x: &Expression) -> Expression {
apply_unary(x, ExprLang::Cos)
}
pub fn tan(x: &Expression) -> Expression {
apply_unary(x, ExprLang::Tan)
}
pub fn exp(x: &Expression) -> Expression {
apply_unary(x, ExprLang::Exp)
}
pub fn log(x: &Expression) -> Expression {
apply_unary(x, ExprLang::Log)
}
pub fn log_base(x: &Expression, base: &Expression) -> Expression {
log(x) / log(base)
}
pub fn sqrt(x: &Expression) -> Expression {
apply_unary(x, ExprLang::Sqrt)
}
pub fn abs(x: &Expression) -> Expression {
apply_unary(x, ExprLang::Abs)
}
pub fn asin(x: &Expression) -> Expression {
apply_unary(x, ExprLang::Asin)
}
pub fn acos(x: &Expression) -> Expression {
apply_unary(x, ExprLang::Acos)
}
pub fn atan(x: &Expression) -> Expression {
apply_unary(x, ExprLang::Atan)
}
pub fn sinh(x: &Expression) -> Expression {
apply_unary(x, ExprLang::Sinh)
}
pub fn cosh(x: &Expression) -> Expression {
apply_unary(x, ExprLang::Cosh)
}
pub fn tanh(x: &Expression) -> Expression {
apply_unary(x, ExprLang::Tanh)
}
fn apply_unary<F>(x: &Expression, make_node: F) -> Expression
where
F: FnOnce([egg::Id; 1]) -> ExprLang,
{
let mut expr = x.as_rec_expr().clone();
let id = egg::Id::from(expr.as_ref().len() - 1);
expr.add(make_node([id]));
Expression::from_rec_expr(expr)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_trig_functions() {
let x = Expression::symbol("x");
let sin_x = sin(&x);
let cos_x = cos(&x);
let tan_x = tan(&x);
assert!(!sin_x.is_symbol());
assert!(!cos_x.is_symbol());
assert!(!tan_x.is_symbol());
}
#[test]
fn test_exp_log() {
let x = Expression::symbol("x");
let exp_x = exp(&x);
let log_x = log(&x);
assert!(!exp_x.is_symbol());
assert!(!log_x.is_symbol());
}
}