number_diff/
lib.rs

1//! # Overview
2//! ## Number Diff - An all-purpose tool for calculus
3//!
4//!
5//!
6//! ### Functions
7//! Number Diff is built around a calculus-like function, that is, a function that takes an
8//! f64 as an argument, returning an f64 according to some specific rule. In the current state of
9//! the crate, functions are limited to ƒ: ℝ ⟶ ℝ (have a look at the [supported
10//! functions](#supported-functions) for which functions can be used).  
11//! There are plans to expand to ƒ: ℂ ⟶ ℂ in the not so distant future.
12//!
13//! #### Usage
14//! Functions are represented by the Function struct. The Function struct can be created by either
15//! parsing a string or combining functions using standard operations. A Function
16//! instance can then be used with the call(x) method (or when using the nightly feature, Function
17//! instances can be called directly).
18//!
19//! Check out [some examples](https://github.com/HellFelix/number-diff/tree/main/examples)!
20//!
21//! ## Supported functions
22//! | Function | Parsing Identifier | In-code Function |
23//! |:----------:|:-------------------:|:-----------------:|
24//! | sin      | "sin(_)"            | [sin()](crate::sin) |
25//! | cos       | "cos(_)"            | [cos()](crate::cos) |
26//! | tan       | "tan(_)"            | [tan()](crate::tan) |
27//! | sec       | "sec(_)"            | [sec()](crate::sec) |
28//! | csc       | "csc(_)"            | [csc()](crate::csc) |
29//! | cot       | "cot(_)"            | [cot()](crate::cot) |
30//! | asin      | "asin(_)"            | [asin()](crate::asin) |
31//! | acos      | "acos(_)"            | [acos()](crate::acos) |
32//! | atan      | "atan(_)"            | [atan()](crate::atan) |
33//! | sinh      | "sinh(_)"            | [sinh()](crate::sinh) |
34//! | cosh      | "cosh(_)"            | [cosh()](crate::cosh) |
35//! | tanh      | "tanh(_)"            | [tanh()](crate::tanh) |
36//! | natural log|"ln(_)"            | [ln()](crate::ln) |
37//! | absolute value|"abs(_)"           | [abs()](crate::abs) |
38//! | square root|"sqrt(_)"            | [sqrt()](crate::sqrt) |
39//! | factorial | "_!"              | [factorial()](crate::factorial) |
40//! | addition | "_ + _ "            | [+](core::ops::Add) |
41//! | subtraction| "_ - _"            | [-](core::ops::Sub)  |
42//! | multiplication| "_ * _"       | [*](core::ops::Mul) |
43//! | division   | "_ / _"           | [/](core::ops::Div) |
44//! | contant | "1", "-12", "3.14", etc. | [f64](f64) |
45//! | independent variable | "x"    | [Function::default()](crate::Function::default) |
46//!
47//! Note that "_" in the table above refers to any other function of the ones provided above. Note also that the
48//! operations (+, -, *, /) cannot be applied to each other. Attempting to apply an operation to
49//! another operation will make the parser return a [Parsing Error](crate::Error::ParseError).
50//!
51//! ### Derivatives
52//! All of the [supported functions](#supported-functions) are [smooth functions](https://en.wikipedia.org/wiki/Smoothness) which in turn
53//! means that once initialized, a [Function](crate::Function) is guaranteed to be a smooth function and so are all of its
54//! derivatives.
55//!
56//! Derivatives are calculated analytically. The provided derivative function will always be the
57//! the exact derivative of the original function (although not always in simplest form).
58//!
59//! Note that in its current state, differentiating might in some rare cases return NaN for
60//! certain input values where simplification fails to avoid a division by zero.
61//!
62//! Function instances can be differentiated using the [differentiate()
63//! method](crate::Function::differentiate) or using the [derivative_of()
64//! function](crate::derivative_of).
65//!
66//! ### Integrals
67//! Integration is stable for the most part. With a standard precision of 1000, integration uses
68//! Simpson's rule in order to find an approximate value of the integral.
69//!
70//! For usage examples, check out the [integration documentation](crate::Integrate)!
71//!
72//! Note that while integrating over an interval (including the bounds of integration) inside of which the value of the
73//! specified function is undefined, the resulting value might be [NaN](f64::NAN).
74//!
75//! Also, integrating over an interval (including the bounds of integration) inside of which the value of the
76//! specified function is infinit, the resulting value might be [inf](f64::INFINITY) even though
77//! the integral should converge.
78//!
79//! ### Series Expansions
80//! See [this article](https://en.wikipedia.org/wiki/Series_expansion) for an explanation of series
81//! expansions.
82//!
83//! #### Current stability of series expansions
84//!
85//! | Expansion Technique | Stability | Usage       |
86//! |:-------------------:|:---------:|:-----------:|
87//! | Taylor series       | Stable ✅ | [get_taylor_expansion()](crate::Function::get_taylor_expansion)|
88//! | Maclaurin series    | Stable ✅ | [get_maclaurin_expansion()](crate::Function::get_maclaurin_expansion)|
89//! | Fourier series      | Unimplemented ❌| N/A |
90
91#![cfg_attr(feature = "nightly", feature(unboxed_closures))]
92#![cfg_attr(feature = "nightly", feature(fn_traits))]
93#![cfg_attr(feature = "nightly", feature(tuple_trait))]
94
95mod functions;
96pub use functions::calc::Elementary;
97
98mod utils;
99pub use utils::include::*;
100
101mod simplify;
102
103type Func = Box<dyn Fn(f64) -> f64 + 'static>;
104
105#[derive(Debug)]
106pub enum Error {
107    ParseError(String),
108    SimplifyError(Elementary, String),
109    InternalError(String),
110    ExpansionError(String),
111    InputError(String),
112}