use crate::ast::Ci;
use crate::ast::MathExpression;
use derive_new::new;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::fmt;
use utoipa::ToSchema;
#[derive(
Debug, Ord, PartialOrd, PartialEq, Eq, Clone, Hash, new, Deserialize, Serialize, JsonSchema,
)]
pub struct Derivative {
pub order: u8,
pub var_index: u8,
pub bound_var: Ci,
pub notation: DerivativeNotation,
}
#[derive(
Debug, Ord, PartialOrd, PartialEq, Eq, Clone, Hash, new, Deserialize, Serialize, JsonSchema,
)]
pub enum DerivativeNotation {
LeibnizTotal,
LeibnizPartialStandard,
LeibnizPartialCompact,
Newton,
DNotation,
Lagrange,
}
#[derive(
Debug, Ord, PartialOrd, PartialEq, Eq, Clone, Hash, new, Deserialize, Serialize, JsonSchema,
)]
pub struct Logarithm {
pub notation: LogarithmNotation,
}
#[derive(
Debug, Ord, PartialOrd, PartialEq, Eq, Clone, Hash, new, Deserialize, Serialize, JsonSchema,
)]
pub enum LogarithmNotation {
Ln,
Log,
LogBase(Box<MathExpression>),
}
#[derive(
Debug,
Ord,
PartialOrd,
PartialEq,
Eq,
Clone,
Hash,
new,
Deserialize,
Serialize,
ToSchema,
JsonSchema,
)]
pub struct Summation {
pub lower_bound: Option<Box<MathExpression>>,
pub upper_bound: Option<Box<MathExpression>>,
}
#[derive(
Debug,
Ord,
PartialOrd,
PartialEq,
Eq,
Clone,
Hash,
new,
Deserialize,
Serialize,
ToSchema,
JsonSchema,
)]
pub struct Hat {
pub comp: Box<MathExpression>,
}
#[derive(
Debug,
Ord,
PartialOrd,
PartialEq,
Eq,
Clone,
Hash,
new,
Deserialize,
Serialize,
ToSchema,
JsonSchema,
)]
pub struct Gradient {
pub subscript: Option<Box<MathExpression>>,
}
#[derive(
Debug,
Ord,
PartialOrd,
PartialEq,
Eq,
Clone,
Hash,
new,
Deserialize,
Serialize,
ToSchema,
JsonSchema,
)]
pub struct Int {
pub lower_limit: Option<Box<MathExpression>>,
pub upper_limit: Option<Box<MathExpression>>,
pub integration_variable: Box<MathExpression>,
}
#[derive(
Debug,
Ord,
PartialOrd,
PartialEq,
Eq,
Clone,
Hash,
new,
Deserialize,
Serialize,
ToSchema,
JsonSchema,
)]
pub enum Operator {
Add,
Multiply,
Equals,
Divide,
Subtract,
Sqrt,
Lparen,
Rparen,
Compose,
Factorial,
Exp,
Power,
Gradient(Gradient),
Dot,
Div,
Abs,
Derivative(Derivative),
Sin,
Cos,
Tan,
Sec,
Csc,
Cot,
Arcsin,
Arccos,
Arctan,
Arcsec,
Arccsc,
Arccot,
Mean,
Summation(Summation),
Cross,
Hat(Hat),
Int(Int),
Laplacian,
SurfaceInt,
Comma,
Logarithm(Logarithm),
Min,
Other(String),
}
impl fmt::Display for Operator {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Operator::Add => write!(f, "+"),
Operator::Multiply => write!(f, "*"),
Operator::Equals => write!(f, "="),
Operator::Divide => write!(f, "/"),
Operator::Subtract => write!(f, "-"),
Operator::Sqrt => write!(f, "√"),
Operator::Lparen => write!(f, "("),
Operator::Rparen => write!(f, ")"),
Operator::Compose => write!(f, "."),
Operator::Factorial => write!(f, "!"),
Operator::Derivative(Derivative {
order,
var_index: _,
bound_var,
notation,
}) => match notation {
DerivativeNotation::LeibnizTotal => write!(f, "D({order}, {bound_var})"),
DerivativeNotation::LeibnizPartialStandard => write!(f, "PD({order}, {bound_var})"),
DerivativeNotation::LeibnizPartialCompact => write!(f, "∂_{{{bound_var}}})"),
DerivativeNotation::Newton => write!(f, "D({order}, {bound_var})"),
DerivativeNotation::Lagrange => write!(f, "D({order}, {bound_var})"),
DerivativeNotation::DNotation => write!(f, "D({order}, {bound_var})"),
},
Operator::Exp => write!(f, "exp"),
Operator::Power => write!(f, "^"),
Operator::Other(op) => write!(f, "{op}"),
Operator::Sin => write!(f, "Sin"),
Operator::Cos => write!(f, "Cos"),
Operator::Tan => write!(f, "Tan"),
Operator::Sec => write!(f, "Sec"),
Operator::Csc => write!(f, "Csc"),
Operator::Cot => write!(f, "Cot"),
Operator::Arcsin => write!(f, "Arcsin"),
Operator::Arccos => write!(f, "Arccos"),
Operator::Arctan => write!(f, "Arctan"),
Operator::Arcsec => write!(f, "Arcsec"),
Operator::Arccsc => write!(f, "Arccsc"),
Operator::Arccot => write!(f, "Arccot"),
Operator::Mean => write!(f, "Mean"),
Operator::Gradient(Gradient { subscript }) => match subscript {
Some(sub) => write!(f, "Grad_{sub}"),
None => write!(f, "Grad"),
},
Operator::Dot => write!(f, "⋅"),
Operator::Div => write!(f, "Div"),
Operator::Abs => write!(f, "Abs"),
Operator::Summation(Summation {
lower_bound,
upper_bound,
}) => match (lower_bound, upper_bound) {
(Some(low), Some(up)) => write!(f, "Sum_{{{low}}}^{{{up}}}"),
(Some(low), None) => write!(f, "Sum_{{{low}}}"),
(None, Some(up)) => write!(f, "Sum^{{{up}}}"),
(None, None) => write!(f, "Sum"),
},
Operator::Int(Int {
lower_limit,
upper_limit,
integration_variable,
}) => match (lower_limit, upper_limit) {
(Some(low), Some(up)) => {
write!(f, "Int_{{{low}}}^{{{up}}}({integration_variable})")
}
(Some(low), None) => write!(f, "Int_{{{low}}}({integration_variable})"),
(None, Some(up)) => write!(f, "Int^{{{up}}}(integration_variable)"),
(None, None) => write!(f, "Int"),
},
Operator::Cross => write!(f, "×"),
Operator::Hat(Hat { comp }) => write!(f, "Hat({comp})"),
Operator::Laplacian => write!(f, "Laplacian"),
Operator::SurfaceInt => {
write!(f, "SurfaceInt")
}
Operator::Min => write!(f, "Min"),
Operator::Comma => write!(f, ","),
Operator::Logarithm(Logarithm { notation }) => match notation {
LogarithmNotation::Ln => write!(f, "Ln"),
LogarithmNotation::Log => write!(f, "Log"),
LogarithmNotation::LogBase(x) => write!(f, "Log_{{{x}}}"),
},
}
}
}