Skip to content

Commit

Permalink
update documentation (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
maksym-arutyunyan authored Jun 16, 2022
1 parent 93a33a8 commit 181566e
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 119 deletions.
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
[package]
name = "big_o"
description = "Infers asymptotic computational complexity."
version = "0.1.0"
edition = "2021"
authors = ["Maksym Arutyunyan"]
repository = "https://github.com/maksym-arutyunyan/big_o"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

Expand Down
64 changes: 7 additions & 57 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,63 +7,13 @@ Infers asymptotic computational complexity.
## Examples

```rs
// f(x) = offset
let data = vec![(1., 11.), (2., 11.), (3., 11.), (4., 11.)];
let (best, _all) = big_o::infer_complexity(data).unwrap();
assert_eq!(best.name, big_o::Name::Constant);
assert_eq!(best.notation, "O(1)");
assert_approx_eq::assert_approx_eq!(best.params.gain.unwrap(), 0.0, 1e-6);
assert_approx_eq::assert_approx_eq!(best.params.offset.unwrap(), 11.0, 1e-6);
// f(x) = gain * x ^ 2 + offset
let data = vec![(1., 1.), (2., 4.), (3., 9.), (4., 16.)];

// f(x) = gain * log(x) + offset
let data = vec![(10., 1.), (100., 2.), (1_000., 3.), (10_000., 4.)];
let (best, _all) = big_o::infer_complexity(data).unwrap();
assert_eq!(best.name, big_o::Name::Logarithmic);
assert_eq!(best.notation, "O(log n)");
let (best, _all) = big_o::infer_complexity(data).unwrap();

// f(x) = gain * x + offset
let data = vec![(1., 17.), (2., 27.), (3., 37.), (4., 47.)];
let (best, _all) = big_o::infer_complexity(data).unwrap();
assert_eq!(best.name, big_o::Name::Linear);
assert_eq!(best.notation, "O(n)");
assert_approx_eq::assert_approx_eq!(best.params.gain.unwrap(), 10.0, 1e-6);
assert_approx_eq::assert_approx_eq!(best.params.offset.unwrap(), 7.0, 1e-6);

// f(x) = gain * x * log(x) + offset
let data = vec![(10., 10.), (100., 200.), (1_000., 3_000.), (10_000., 40_000.)];
let (best, _all) = big_o::infer_complexity(data).unwrap();
assert_eq!(best.name, big_o::Name::Linearithmic);
assert_eq!(best.notation, "O(n log n)");

// f(x) = gain * x ^ 2 + offset
let data = vec![(1., 1.), (2., 4.), (3., 9.), (4., 16.)];
let (best, _all) = big_o::infer_complexity(data).unwrap();
assert_eq!(best.name, big_o::Name::Quadratic);
assert_eq!(best.notation, "O(n^2)");
assert_approx_eq::assert_approx_eq!(best.params.gain.unwrap(), 1.0, 1e-6);
assert_approx_eq::assert_approx_eq!(best.params.offset.unwrap(), 0.0, 1e-6);

// f(x) = gain * x ^ 3 + offset
let data = vec![(1., 1.), (2., 8.), (3., 27.), (4., 64.)];
let (best, _all) = big_o::infer_complexity(data).unwrap();
assert_eq!(best.name, big_o::Name::Cubic);
assert_eq!(best.notation, "O(n^3)");
assert_approx_eq::assert_approx_eq!(best.params.gain.unwrap(), 1.0, 1e-6);
assert_approx_eq::assert_approx_eq!(best.params.offset.unwrap(), 0.0, 1e-6);

// f(x) = gain * x ^ power
let data = vec![(1., 1.), (2., 16.), (3., 81.), (4., 256.)];
let (best, _all) = big_o::infer_complexity(data).unwrap();
assert_eq!(best.name, big_o::Name::Polynomial);
assert_eq!(best.notation, "O(n^m)");
assert_approx_eq::assert_approx_eq!(best.params.gain.unwrap(), 1.0, 1e-6);
assert_approx_eq::assert_approx_eq!(best.params.power.unwrap(), 4.0, 1e-6);

// f(x) = gain * base ^ x
let data = vec![(1., 2.), (2., 4.), (3., 8.), (4., 16.)];
let (best, _all) = big_o::infer_complexity(data).unwrap();
assert_eq!(best.name, big_o::Name::Exponential);
assert_eq!(best.notation, "O(c^n)");
assert_approx_eq::assert_approx_eq!(best.params.gain.unwrap(), 1.0, 1e-6);
assert_approx_eq::assert_approx_eq!(best.params.base.unwrap(), 2.0, 1e-6);
assert_eq!(best.name, big_o::Name::Quadratic);
assert_eq!(best.notation, "O(n^2)");
assert_approx_eq::assert_approx_eq!(best.params.gain.unwrap(), 1.0, 1e-6);
assert_approx_eq::assert_approx_eq!(best.params.offset.unwrap(), 0.0, 1e-6);
```
12 changes: 9 additions & 3 deletions src/complexity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,22 @@ use crate::name;
use crate::name::Name;
use crate::params::Params;

/// A structure to describe asymptotic computational complexity
#[derive(Clone, Debug)]
pub struct Complexity {
/// Human-readable name
pub name: Name,

/// Big O notation
pub notation: &'static str,

/// Approximation function parameters
pub params: Params,
}

impl Complexity {
/// Returns a calculated function f(x), given coefficients (a, b).
fn get_function(&self) -> Result<Box<dyn Fn(f64) -> f64>, &'static str> {
/// Returns a calculated approximation function `f(x)`
pub fn get_function(&self) -> Result<Box<dyn Fn(f64) -> f64>, &'static str> {
let p = &self.params;
if let (Some(a), Some(b)) = match self.name {
Name::Polynomial => (p.gain, p.power),
Expand All @@ -35,7 +41,7 @@ impl Complexity {
}
}

/// Computes values of f(x) given x.
/// Computes values of `f(x)` given `x`
pub fn compute_f(&self, x: Vec<f64>) -> Result<Vec<f64>, &'static str> {
let f = self.get_function()?;
let y = x.into_iter().map(f).collect();
Expand Down
62 changes: 9 additions & 53 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
//! Infers asymptotic computational complexity.
//!
//! `big_o` helps to estimate computational complexity of algorithms by inspecting measurement data
//! (eg. execution time, memory consumption, etc). Users are expected to provide measurement data,
//! `big_o` will try to fit a set of complexity models and return the best fit.
mod complexity;
mod linalg;
mod name;
Expand All @@ -10,67 +16,17 @@ pub use crate::params::Params;

/// Infers complexity of given data points, returns the best and all the fitted complexities.
///
/// # Examples
/// # Example
/// ```
/// // f(x) = offset
/// let data = vec![(1., 11.), (2., 11.), (3., 11.), (4., 11.)];
/// let (best, _all) = big_o::infer_complexity(data).unwrap();
/// assert_eq!(best.name, big_o::Name::Constant);
/// assert_eq!(best.notation, "O(1)");
/// assert_approx_eq::assert_approx_eq!(best.params.gain.unwrap(), 0.0, 1e-6);
/// assert_approx_eq::assert_approx_eq!(best.params.offset.unwrap(), 11.0, 1e-6);
///
/// // f(x) = gain * log(x) + offset
/// let data = vec![(10., 1.), (100., 2.), (1_000., 3.), (10_000., 4.)];
/// let (best, _all) = big_o::infer_complexity(data).unwrap();
/// assert_eq!(best.name, big_o::Name::Logarithmic);
/// assert_eq!(best.notation, "O(log n)");
///
/// // f(x) = gain * x + offset
/// let data = vec![(1., 17.), (2., 27.), (3., 37.), (4., 47.)];
/// let (best, _all) = big_o::infer_complexity(data).unwrap();
/// assert_eq!(best.name, big_o::Name::Linear);
/// assert_eq!(best.notation, "O(n)");
/// assert_approx_eq::assert_approx_eq!(best.params.gain.unwrap(), 10.0, 1e-6);
/// assert_approx_eq::assert_approx_eq!(best.params.offset.unwrap(), 7.0, 1e-6);
///
/// // f(x) = gain * x * log(x) + offset
/// let data = vec![(10., 10.), (100., 200.), (1_000., 3_000.), (10_000., 40_000.)];
/// let (best, _all) = big_o::infer_complexity(data).unwrap();
/// assert_eq!(best.name, big_o::Name::Linearithmic);
/// assert_eq!(best.notation, "O(n log n)");
///
/// // f(x) = gain * x ^ 2 + offset
/// let data = vec![(1., 1.), (2., 4.), (3., 9.), (4., 16.)];
///
/// let (best, _all) = big_o::infer_complexity(data).unwrap();
///
/// assert_eq!(best.name, big_o::Name::Quadratic);
/// assert_eq!(best.notation, "O(n^2)");
/// assert_approx_eq::assert_approx_eq!(best.params.gain.unwrap(), 1.0, 1e-6);
/// assert_approx_eq::assert_approx_eq!(best.params.offset.unwrap(), 0.0, 1e-6);
///
/// // f(x) = gain * x ^ 3 + offset
/// let data = vec![(1., 1.), (2., 8.), (3., 27.), (4., 64.)];
/// let (best, _all) = big_o::infer_complexity(data).unwrap();
/// assert_eq!(best.name, big_o::Name::Cubic);
/// assert_eq!(best.notation, "O(n^3)");
/// assert_approx_eq::assert_approx_eq!(best.params.gain.unwrap(), 1.0, 1e-6);
/// assert_approx_eq::assert_approx_eq!(best.params.offset.unwrap(), 0.0, 1e-6);
///
/// // f(x) = gain * x ^ power
/// let data = vec![(1., 1.), (2., 16.), (3., 81.), (4., 256.)];
/// let (best, _all) = big_o::infer_complexity(data).unwrap();
/// assert_eq!(best.name, big_o::Name::Polynomial);
/// assert_eq!(best.notation, "O(n^m)");
/// assert_approx_eq::assert_approx_eq!(best.params.gain.unwrap(), 1.0, 1e-6);
/// assert_approx_eq::assert_approx_eq!(best.params.power.unwrap(), 4.0, 1e-6);
///
/// // f(x) = gain * base ^ x
/// let data = vec![(1., 2.), (2., 4.), (3., 8.), (4., 16.)];
/// let (best, _all) = big_o::infer_complexity(data).unwrap();
/// assert_eq!(best.name, big_o::Name::Exponential);
/// assert_eq!(best.notation, "O(c^n)");
/// assert_approx_eq::assert_approx_eq!(best.params.gain.unwrap(), 1.0, 1e-6);
/// assert_approx_eq::assert_approx_eq!(best.params.base.unwrap(), 2.0, 1e-6);
/// ```
pub fn infer_complexity(
data: Vec<(f64, f64)>,
Expand Down
13 changes: 7 additions & 6 deletions src/params.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
/// A structure to hold function parameters:
/// A structure to hold function parameters
///
/// Function examples:
/// - `f(x) = gain * x + offset`
/// - `f(x) = gain * x ^ power`
/// - `f(x) = gain * base ^ x`
///
/// # Example
/// ```
/// let p = big_o::Params::new().gain(2.0).offset(3.0).build();
/// let params = big_o::Params::new().gain(2.0).offset(3.0).build();
///
/// assert_eq!(p.gain, Some(2.0));
/// assert_eq!(p.offset, Some(3.0));
/// assert_eq!(p.power, None);
/// assert_eq!(params.gain, Some(2.0));
/// assert_eq!(params.offset, Some(3.0));
/// assert_eq!(params.power, None);
/// ```
#[derive(Clone, Debug)]
pub struct Params {
Expand All @@ -21,7 +22,7 @@ pub struct Params {
pub base: Option<f64>,
}

/// Params builder.
/// Params builder
impl Params {
pub fn new() -> Self {
Self {
Expand Down

0 comments on commit 181566e

Please sign in to comment.