1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
//! Crate for math functions
/// Polynomials
pub mod algebra;
/// Contains context
pub mod context;
/// Operations
pub mod operations;
/// Operators
pub mod operators;
mod parser;
mod tests;
use crate::parser::splitter::split;
use crate::parser::{parse, ParsingError};
pub use algebra::matrix::{Matrix, Vec2, Vec3};
use context::Context;
use std::str::FromStr;
/// Representation of a Function
#[derive(Clone, PartialEq, Debug)]
pub(crate) enum Function {
/// X Variable
X,
/// Y Variable
Y,
/// Z Variable
Z,
/// Euler's number
E,
/// Pi
PI,
/// Generic numeric constant
Num(f64),
/// Rational
/// Represent a binary operation between two functions
Binary {
/// Operation between the two functions
operation: Operation,
/// Two operands
terms: (Box<Self>, Box<Self>),
},
/// Represent a special function such as sin, cos... with its argument
Special {
/// Built-in funciton types
kind: FunctionType,
/// Argument of the function (sin(4x), 4x is the argument)
argument: Box<Self>,
},
}
#[derive(Debug, PartialEq)]
/// Representation of a function with 1 variable
pub struct F1D(Function);
#[derive(Debug, PartialEq)]
/// Representation of a function with 2 variables
pub struct F2D(Function);
#[derive(PartialEq, Debug)]
/// Representation of a function with 3 variables
pub struct F3D(Function);
#[derive(Clone, PartialEq, Debug)]
/// Types of special built-in functions
pub(crate) enum FunctionType {
/// Sine
Sin,
/// Cosine
Cos,
/// Tangent
Tan,
/// Cotangent
Cot,
/// Secant
Sec,
/// Cosecant
Csc,
/// Inverse of sine
ASin,
/// Inverse of cosine
ACos,
/// Inverse of tangent
ATan,
/// Hyperbolic sine
Sinh,
/// Hyperbolic cosine
Cosh,
/// Hyperbolic tangent
Tanh,
/// Hyperbolic cotangent
Coth,
/// Hyperbolic secant
Sech,
/// Hyperbolic cosecant
Csch,
/// Inverse of hyperbolic sine
ASinh,
/// Inverse of hyperbolic cosine
ACosh,
/// Inverse of hyperbolic tangent
ATanh,
/// Absolute value
Abs,
/// Natural logarithm
Ln,
}
#[derive(Clone, PartialEq, Debug)]
pub(crate) enum Operation {
Add,
Sub,
Mul,
Div,
Pow,
Comp,
}
impl Operation {
fn priority(&self) -> u8 {
match self {
Operation::Add => 4,
Operation::Sub => 4,
Operation::Mul => 3,
Operation::Div => 3,
Operation::Pow => 2,
Operation::Comp => 1,
}
}
}
/// Function to approximate f64 to the nth decimal place
pub fn approx(num: f64, digits: u32) -> f64 {
let y = 10i32.pow(digits) as f64;
(num * y).round() / y
}
impl FromStr for F1D {
type Err = ParsingError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut s = s.to_string();
s.retain(|c| !c.is_whitespace());
match parse(split(&s)?, &Context::new(), 1) {
Ok(val) => Ok(F1D(val)),
Err(err) => Err(err),
}
}
}
impl FromStr for F2D {
type Err = ParsingError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut s = s.to_string();
s.retain(|c| !c.is_whitespace());
match parse(split(&s)?, &Context::new(), 2) {
Ok(val) => Ok(F2D(val)),
Err(err) => Err(err),
}
}
}
impl FromStr for F3D {
type Err = ParsingError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut s = s.to_string();
s.retain(|c| !c.is_whitespace());
match parse(split(&s)?, &Context::new(), 3) {
Ok(val) => Ok(F3D(val)),
Err(err) => Err(err),
}
}
}