diff --git a/docs/api/linear/algebra.md b/docs/api/linear/algebra.md index de4e834..b97066e 100644 --- a/docs/api/linear/algebra.md +++ b/docs/api/linear/algebra.md @@ -1,16 +1,17 @@ # Algebra -Ah, yes, algebra, my favorite subject. This chapter exists in the `linear` category and provides tools for solving linear equations, systems of linear equations, and quadratic equations. +The algebra chapter provides essential tools for solving linear and quadratic equations. This module is fundamental for mathematical computations involving equations with one or two variables, and quadratic problems. ```c++ #include ``` -## Classes +## Overview -The algebra module contains two main classes: -- **`LinearAlgebra`** - Solves linear equations and systems of linear equations -- **`QuadraticEquation`** - Solves quadratic equations using the quadratic formula +Algebra is the mathematics of solving equations. This module helps you answer questions like: +- "What value of x makes this equation true?" +- "Where do these two lines intersect?" +- "What are the roots of this quadratic equation?" --- @@ -18,151 +19,357 @@ The algebra module contains two main classes: Provides methods for solving linear equations in one or two variables. -### Features +### Single Variable Linear Equations -#### Single Variable Linear Equations -- `solve_1v(double a, double b) → std::optional` - Solves ax + b = 0 for x - - Returns `std::nullopt` if no solution exists (when a = 0 and b ≠ 0) +```c++ +static std::optional solve_1v(double a, double b); +``` -#### System of Two Linear Equations -- `solve_2v(double a1, double b1, double c1, double a2, double b2, double c2) → std::optional>` - Solves the system: - ``` - a1·x + b1·y = c1 - a2·x + b2·y = c2 - ``` - - Returns `std::pair` containing (x, y) if a unique solution exists - - Returns `std::nullopt` if the system has no solution or infinitely many solutions +Solves equations of the form ax + b = 0 for x. -### Example Usage +**Formula:** x = -b/a (when a ≠ 0) +**Examples:** ```c++ -#include -#include +// Solve: 2x + 6 = 0 +auto result = imeth::LinearAlgebra::solve_1v(2, 6); +if (result.has_value()) { + std::cout << "x = " << result.value() << "\n"; // x = -3 +} -int main() { - // Solve: 2x + 6 = 0 - auto result = imeth::LinearAlgebra::solve_1v(2, 6); - if (result.has_value()) { - std::cout << "x = " << result.value() << "\n"; // x = -3 - } +// Solve: 5x - 15 = 0 +auto x = imeth::LinearAlgebra::solve_1v(5, -15); // x = 3 - // Solve system: - // 2x + 3y = 8 - // x - y = 1 - auto system = imeth::LinearAlgebra::solve_2v(2, 3, 8, 1, -1, 1); - if (system.has_value()) { - auto [x, y] = system.value(); - std::cout << "x = " << x << ", y = " << y << "\n"; // x = 2.2, y = 1.2 - } +// No solution case: 0x + 5 = 0 +auto no_solution = imeth::LinearAlgebra::solve_1v(0, 5); +if (!no_solution.has_value()) { + std::cout << "No solution exists\n"; +} +``` - return 0; +**Real-world:** +- Simple cost equations: "If total cost = 2x + 6, when is cost zero?" +- Distance problems: "At what time does position equal zero?" +- Break-even analysis + +**Returns:** `std::optional` containing the solution, or `std::nullopt` if no solution exists (when a = 0 and b ≠ 0) + +--- + +### System of Two Linear Equations + +```c++ +static std::optional> solve_2v( + double a1, double b1, double c1, + double a2, double b2, double c2 +); +``` + +Solves systems of two linear equations with two variables: +``` +a1·x + b1·y = c1 +a2·x + b2·y = c2 +``` + +**Examples:** +```c++ +// Solve system: +// 2x + 3y = 8 +// x - y = 1 +auto system = imeth::LinearAlgebra::solve_2v(2, 3, 8, 1, -1, 1); +if (system.has_value()) { + auto [x, y] = system.value(); + std::cout << "x = " << x << ", y = " << y << "\n"; // x = 2.2, y = 1.2 +} + +// Solve system: +// 3x + 2y = 7 +// 2x + y = 4 +auto result = imeth::LinearAlgebra::solve_2v(3, 2, 7, 2, 1, 4); // x = 1, y = 2 + +// Parallel lines (no solution) +// x + y = 1 +// x + y = 2 +auto parallel = imeth::LinearAlgebra::solve_2v(1, 1, 1, 1, 1, 2); +if (!parallel.has_value()) { + std::cout << "No solution (parallel lines)\n"; +} + +// Infinite solutions (same line) +// 2x + 4y = 6 +// x + 2y = 3 +auto infinite = imeth::LinearAlgebra::solve_2v(2, 4, 6, 1, 2, 3); +if (!infinite.has_value()) { + std::cout << "Infinite solutions (same line)\n"; } ``` +**Real-world:** +- Finding intersection points of two lines +- Supply and demand equilibrium +- Mixture problems (two unknowns) +- Resource allocation with constraints + +**Returns:** `std::optional>` containing (x, y) if a unique solution exists, or `std::nullopt` if the system has no solution or infinitely many solutions + --- ## QuadraticEquation Solves quadratic equations of the form ax² + bx + c = 0 using the quadratic formula. -### Features +### Solution Type -#### Solution Type ```c++ using Solution = std::variant>; ``` -The `Solution` type can represent three possible outcomes: +The `Solution` type represents three possible outcomes: - `std::monostate` - No real solutions (complex roots, discriminant < 0) - `double` - One solution / repeated root (discriminant = 0) -- `std::pair` - Two distinct real solutions (discriminant > 0), where first ≤ second +- `std::pair` - Two distinct real solutions (discriminant > 0), ordered ascending -#### Solving Quadratic Equations -- `solve(double a, double b, double c) → Solution` - Solves ax² + bx + c = 0 - - Uses the quadratic formula: x = (-b ± √(b² - 4ac)) / 2a - - Handles degenerate cases (when a = 0, reduces to linear equation) - - Returns solutions in ascending order when two solutions exist +--- -### Example Usage +### Solving Quadratic Equations ```c++ -#include -#include -#include +static Solution solve(double a, double b, double c); +``` -int main() { - // Solve: x² - 5x + 6 = 0 - // Factors as: (x - 2)(x - 3) = 0 - auto result = imeth::QuadraticEquation::solve(1, -5, 6); - - if (std::holds_alternative>(result)) { - auto [x1, x2] = std::get>(result); - std::cout << "Two solutions: x1 = " << x1 << ", x2 = " << x2 << "\n"; - // Output: x1 = 2, x2 = 3 - } - else if (std::holds_alternative(result)) { - double x = std::get(result); - std::cout << "One solution: x = " << x << "\n"; - } - else { - std::cout << "No real solutions (complex roots)\n"; - } +Solves equations of the form ax² + bx + c = 0. - return 0; +**Formula:** x = (-b ± √(b² - 4ac)) / 2a + +**Discriminant:** Δ = b² - 4ac +- Δ > 0: Two distinct real roots +- Δ = 0: One repeated root +- Δ < 0: Two complex conjugate roots (no real solutions) + +**Examples:** + +#### Two Distinct Solutions +```c++ +// Solve: x² - 5x + 6 = 0 +// Factors as: (x - 2)(x - 3) = 0 +auto result = imeth::QuadraticEquation::solve(1, -5, 6); + +if (std::holds_alternative>(result)) { + auto [x1, x2] = std::get>(result); + std::cout << "Two solutions: x1 = " << x1 << ", x2 = " << x2 << "\n"; + // Output: x1 = 2, x2 = 3 } -``` -### More Examples +// Solve: x² - 7x + 10 = 0 +auto roots = imeth::QuadraticEquation::solve(1, -7, 10); // x1 = 2, x2 = 5 +// Solve: 2x² + 5x - 3 = 0 +auto result2 = imeth::QuadraticEquation::solve(2, 5, -3); // x1 = -3, x2 = 0.5 +``` + +#### One Repeated Root ```c++ -// Repeated root (discriminant = 0) -// Solve: x² - 4x + 4 = 0 → (x - 2)² = 0 +// Solve: x² - 4x + 4 = 0 +// Factors as: (x - 2)² = 0 auto repeated = imeth::QuadraticEquation::solve(1, -4, 4); + if (std::holds_alternative(repeated)) { double x = std::get(repeated); std::cout << "Repeated root: x = " << x << "\n"; // x = 2 } -// No real solutions (discriminant < 0) +// Solve: x² + 6x + 9 = 0 → (x + 3)² = 0 +auto root = imeth::QuadraticEquation::solve(1, 6, 9); // x = -3 +``` + +#### No Real Solutions +```c++ // Solve: x² + x + 1 = 0 auto no_real = imeth::QuadraticEquation::solve(1, 1, 1); + if (std::holds_alternative(no_real)) { - std::cout << "No real solutions\n"; + std::cout << "No real solutions (complex roots)\n"; } -// Negative leading coefficient -// Solve: -x² + 4x - 3 = 0 → x² - 4x + 3 = 0 +// Solve: x² + 4x + 5 = 0 +auto complex = imeth::QuadraticEquation::solve(1, 4, 5); // No real roots +``` + +#### Negative Leading Coefficient +```c++ +// Solve: -x² + 4x - 3 = 0 +// Equivalent to: x² - 4x + 3 = 0 auto negative_a = imeth::QuadraticEquation::solve(-1, 4, -3); + if (std::holds_alternative>(negative_a)) { auto [x1, x2] = std::get>(negative_a); std::cout << "x1 = " << x1 << ", x2 = " << x2 << "\n"; // x1 = 1, x2 = 3 } +``` -// Working with LinearAlgebra and QuadraticEquation together -// Check if a value is a solution +#### Degenerate Case (Linear Equation) +```c++ +// When a = 0, equation becomes linear: bx + c = 0 +// Solve: 0x² + 3x - 6 = 0 → 3x - 6 = 0 +auto linear = imeth::QuadraticEquation::solve(0, 3, -6); // x = 2 +``` + +--- + +### Verification and Usage + +```c++ +// Verify a solution auto solutions = imeth::QuadraticEquation::solve(1, -3, 2); if (std::holds_alternative>(solutions)) { auto [x1, x2] = std::get>(solutions); + // Verify: x² - 3x + 2 = 0 when x = x1 double check = x1 * x1 - 3 * x1 + 2; std::cout << "Verification: " << check << "\n"; // ≈ 0 + + // Check second root + double check2 = x2 * x2 - 3 * x2 + 2; + std::cout << "Verification: " << check2 << "\n"; // ≈ 0 +} + +// Pattern matching all solution types +auto result = imeth::QuadraticEquation::solve(2, -4, 2); +if (std::holds_alternative>(result)) { + auto [x1, x2] = std::get>(result); + std::cout << "Two solutions: " << x1 << ", " << x2 << "\n"; +} +else if (std::holds_alternative(result)) { + double x = std::get(result); + std::cout << "One solution: " << x << "\n"; +} +else { + std::cout << "No real solutions\n"; +} +``` + +**Real-world:** +- Projectile motion (height vs. time) +- Area and optimization problems +- Physics problems (acceleration, velocity) +- Economics (profit maximization) +- Engineering (beam deflection, circuit analysis) + +**Returns:** +- `std::monostate` if no real solutions exist +- `double` if one repeated root exists +- `std::pair` if two distinct solutions exist (ordered ascending) + +--- + +## Complete Example + +```c++ +#include +#include +#include + +int main() { + using namespace imeth; + + // Single variable linear equation + std::cout << "=== Linear Equation (1 variable) ===\n"; + auto linear1 = LinearAlgebra::solve_1v(2, 6); + if (linear1.has_value()) { + std::cout << "2x + 6 = 0, x = " << linear1.value() << "\n"; // x = -3 + } + + // System of linear equations + std::cout << "\n=== System of Linear Equations ===\n"; + auto system = LinearAlgebra::solve_2v(2, 3, 8, 1, -1, 1); + if (system.has_value()) { + auto [x, y] = system.value(); + std::cout << "System solution: x = " << x << ", y = " << y << "\n"; + } + + // Quadratic with two solutions + std::cout << "\n=== Quadratic Equations ===\n"; + auto quad1 = QuadraticEquation::solve(1, -5, 6); + if (std::holds_alternative>(quad1)) { + auto [x1, x2] = std::get>(quad1); + std::cout << "x² - 5x + 6 = 0: x1 = " << x1 << ", x2 = " << x2 << "\n"; + } + + // Quadratic with repeated root + auto quad2 = QuadraticEquation::solve(1, -4, 4); + if (std::holds_alternative(quad2)) { + double x = std::get(quad2); + std::cout << "x² - 4x + 4 = 0: x = " << x << " (repeated)\n"; + } + + // Quadratic with no real solutions + auto quad3 = QuadraticEquation::solve(1, 1, 1); + if (std::holds_alternative(quad3)) { + std::cout << "x² + x + 1 = 0: No real solutions\n"; + } + + // Real-world problem: Projectile motion + std::cout << "\n=== Projectile Motion Example ===\n"; + // Height equation: h(t) = -4.9t² + 20t + 2 + // Find when projectile hits ground (h = 0) + auto time = QuadraticEquation::solve(-4.9, 20, 2); + if (std::holds_alternative>(time)) { + auto [t1, t2] = std::get>(time); + std::cout << "Projectile hits ground at t = " << t2 << " seconds\n"; + } + + return 0; } ``` +--- + +## Tips + +- **Linear vs Quadratic**: Linear equations have at most one solution; quadratic equations can have 0, 1, or 2 real solutions +- **Check for nullopt**: Always verify `has_value()` before accessing `std::optional` results +- **Discriminant**: For quadratics, check discriminant (b² - 4ac) to predict number of solutions before solving +- **Solution Order**: When two solutions exist, they're always returned in ascending order (smaller first) +- **Degenerate Cases**: Handle edge cases where a = 0 (linear instead of quadratic) +- **Verification**: Test solutions by substituting back into original equation + +--- + +## Quick Reference + +| Problem Type | Function | Example Use Case | +|-------------|----------|------------------| +| Linear (1 var) | `LinearAlgebra::solve_1v(a, b)` | Cost equations, simple physics | +| Linear system | `LinearAlgebra::solve_2v(...)` | Line intersections, supply/demand | +| Quadratic | `QuadraticEquation::solve(a, b, c)` | Projectile motion, area problems | + +| Discriminant | Result Type | Meaning | +|--------------|-------------|---------| +| Δ > 0 | `std::pair` | Two distinct real roots | +| Δ = 0 | `double` | One repeated root | +| Δ < 0 | `std::monostate` | No real roots (complex) | + +--- + ## Mathematical Background ### Linear Equations (1 variable) -- Form: ax + b = 0 -- Solution: x = -b/a (when a ≠ 0) +- **Form:** ax + b = 0 +- **Solution:** x = -b/a (when a ≠ 0) +- **No solution when:** a = 0 and b ≠ 0 ### System of Linear Equations (2 variables) -- Uses elimination or substitution methods -- Determines if system has unique solution, no solution, or infinite solutions +- **Form:** Two equations with two unknowns +- **Methods:** Elimination, substitution, matrix methods +- **Unique solution when:** Lines intersect at one point +- **No solution when:** Lines are parallel +- **Infinite solutions when:** Lines coincide (same line) ### Quadratic Equations -- Form: ax² + bx + c = 0 -- Discriminant: Δ = b² - 4ac +- **Form:** ax² + bx + c = 0 +- **Quadratic Formula:** x = (-b ± √Δ) / 2a +- **Discriminant:** Δ = b² - 4ac - Δ > 0: Two distinct real roots - - Δ = 0: One repeated root - - Δ < 0: Two complex conjugate roots (no real solutions) -- Quadratic formula: x = (-b ± √Δ) / 2a + - Δ = 0: One repeated root (perfect square) + - Δ < 0: Two complex conjugate roots +- **Factored Form:** a(x - r₁)(x - r₂) = 0, where r₁ and r₂ are roots \ No newline at end of file diff --git a/docs/api/linear/matrix.md b/docs/api/linear/matrix.md index b36ccac..0106db7 100644 --- a/docs/api/linear/matrix.md +++ b/docs/api/linear/matrix.md @@ -1,245 +1,638 @@ # Matrix -I genuinely don't know what matrix or vector is (besides them being a dynamic alternative for arrays in C++). I mean, what do you expect from a 9th grader? -But, here the chapter `matrix.hpp`, exists... +The matrix chapter provides classes and methods for linear algebra operations, including matrix manipulation, vector operations, and solving systems of linear equations. ```c++ #include ``` -## Classes +## Overview + +Matrices are rectangular grids of numbers that represent: +- Systems of equations with multiple unknowns +- Transformations (rotations, scaling) in graphics and physics +- Data tables and organized information +- Network connections (adjacency matrices) + +This module helps you solve problems like: +- "I have 3 equations with 3 unknowns - what are the solutions?" +- "How do I rotate a 3D object in space?" +- "What's the result of applying multiple transformations?" + +--- + +## Classes Overview The matrix module contains three main classes: -- **Matrix** - Represents a 2D matrix and provides matrix operations -- **Vector** - Represents a mathematical vector (1D array of numbers) -- **Solver** - Provides methods for solving systems of linear equations +- **Matrix** - 2D matrix with mathematical operations +- **Vector** - 1D array of numbers +- **Solver** - Methods for solving systems of linear equations --- -## Matrix +## Matrix Class -A 2D array of numbers that supports mathematical operations like addition, multiplication, and transposition. +A rectangular array of numbers arranged in rows and columns. ### Constructors -- `Matrix(size_t rows, size_t cols)` - Creates a matrix with specified dimensions (initialized to zero) -- `Matrix(std::initializer_list> data)` - Creates a matrix from a list of rows +```c++ +Matrix(size_t rows, size_t cols); +Matrix(std::initializer_list> data); +``` + +**Examples:** +```c++ +// Create 3×4 zero matrix +imeth::Matrix A(3, 4); + +// Create matrix with values +imeth::Matrix B = { + {1, 2, 3}, + {4, 5, 6} +}; + +// Single-row matrix +imeth::Matrix row = {{1, 2, 3, 4}}; + +// Single-column matrix +imeth::Matrix col = {{1}, {2}, {3}, {4}}; +``` + +--- ### Element Access -- `operator()(size_t r, size_t c) → double&` - Accesses element at row r, column c (modifiable) -- `operator()(size_t r, size_t c) const → double` - Accesses element at row r, column c (read-only) +```c++ +double& operator()(size_t r, size_t c); +double operator()(size_t r, size_t c) const; +``` + +Access or modify elements at row r, column c (0-indexed). + +**Examples:** +```c++ +imeth::Matrix M = { + {1, 2, 3}, + {4, 5, 6}, + {7, 8, 9} +}; + +double val = M(0, 0); // 1 (top-left) +M(1, 1) = 20; // Modify center + +// Loop through elements +for (size_t i = 0; i < M.rows(); ++i) { + for (size_t j = 0; j < M.cols(); ++j) { + std::cout << M(i, j) << " "; + } +} + +// Set diagonal to 1 +for (size_t i = 0; i < std::min(M.rows(), M.cols()); ++i) { + M(i, i) = 1.0; +} +``` + +**Real-world:** Image processing, data analysis, game transformations + +--- ### Properties -- `rows() const → size_t` - Returns the number of rows -- `cols() const → size_t` - Returns the number of columns +```c++ +size_t rows() const; +size_t cols() const; +``` -### Static Methods +**Examples:** +```c++ +imeth::Matrix A(3, 4); +size_t r = A.rows(); // 3 +size_t c = A.cols(); // 4 -- `identity(size_t n) → Matrix` - Creates an n×n identity matrix (1s on diagonal, 0s elsewhere) +// Check if square +bool is_square = (A.rows() == A.cols()); -### Operations +// Validate operations +bool can_multiply = (A.cols() == B.rows()); +``` -- `transpose() const → Matrix` - Returns the transpose (rows ↔ columns) -- `operator*(const Matrix& rhs) const → Matrix` - Matrix multiplication -- `operator+(const Matrix& rhs) const → Matrix` - Matrix addition -- `operator-(const Matrix& rhs) const → Matrix` - Matrix subtraction +--- -### Example Usage +### Identity Matrix ```c++ -#include -#include +static Matrix identity(size_t n); +``` -int main() { - // Create a 2×3 matrix - imeth::Matrix A = { - {1, 2, 3}, - {4, 5, 6} - }; +Creates n×n identity matrix with 1s on diagonal, 0s elsewhere. - std::cout << "Matrix A is " << A.rows() << "×" << A.cols() << "\n"; +**Examples:** +```c++ +imeth::Matrix I3 = imeth::Matrix::identity(3); +// [[1, 0, 0], +// [0, 1, 0], +// [0, 0, 1]] + +// Identity property: I × A = A × I = A +imeth::Matrix A = {{2, 3}, {4, 5}}; +imeth::Matrix I2 = imeth::Matrix::identity(2); +imeth::Matrix result = I2 * A; // equals A +``` - // Access elements - std::cout << "A(0,0) = " << A(0, 0) << "\n"; // 1 - std::cout << "A(1,2) = " << A(1, 2) << "\n"; // 6 +**Real-world:** Default transformations, checking matrix inverses, initialization - // Modify element - A(0, 0) = 10; +--- - // Transpose - imeth::Matrix A_T = A.transpose(); - std::cout << "Transpose is " << A_T.rows() << "×" << A_T.cols() << "\n"; // 3×2 +### Transpose - // Create identity matrix - imeth::Matrix I = imeth::Matrix::identity(3); - // I = [[1, 0, 0], - // [0, 1, 0], - // [0, 0, 1]] +```c++ +Matrix transpose() const; +``` - return 0; -} +Returns matrix with rows and columns swapped. + +**Formula:** A^T[i][j] = A[j][i] + +**Examples:** +```c++ +imeth::Matrix A = { + {1, 2, 3}, + {4, 5, 6} +}; // 2×3 + +imeth::Matrix A_T = A.transpose(); +// [[1, 4], +// [2, 5], +// [3, 6]] (3×2) + +// Column vector to row vector +imeth::Matrix col = {{1}, {2}, {3}}; +imeth::Matrix row = col.transpose(); // {{1, 2, 3}} + +// Double transpose returns original +imeth::Matrix original = A.transpose().transpose(); // equals A +``` + +**Properties:** +- (A^T)^T = A +- (A + B)^T = A^T + B^T +- (AB)^T = B^T A^T + +**Real-world:** Converting vector formats, matrix calculus, covariance matrices + +--- + +### Addition + +```c++ +Matrix operator+(const Matrix& rhs) const; ``` -### More Examples +Element-wise addition. Matrices must have same dimensions. +**Examples:** ```c++ -// Matrix addition imeth::Matrix A = {{1, 2}, {3, 4}}; imeth::Matrix B = {{5, 6}, {7, 8}}; -imeth::Matrix C = A + B; // {{6, 8}, {10, 12}} -// Matrix multiplication -imeth::Matrix D = {{1, 2}, {3, 4}}; -imeth::Matrix E = {{2, 0}, {1, 2}}; -imeth::Matrix F = D * E; // {{4, 4}, {10, 8}} +imeth::Matrix C = A + B; +// [[6, 8], +// [10, 12]] + +// Add identity to diagonal +imeth::Matrix I = imeth::Matrix::identity(2); +imeth::Matrix result = A + I; +// [[2, 2], +// [3, 5]] -// Matrix subtraction -imeth::Matrix G = B - A; // {{4, 4}, {4, 4}} +// Chain additions +imeth::Matrix total = A + B + C; ``` +**Properties:** Commutative, associative, A + 0 = A + +**Real-world:** Image blending, summing force matrices, aggregating data + --- -## Vector +### Subtraction + +```c++ +Matrix operator-(const Matrix& rhs) const; +``` + +Element-wise subtraction. Matrices must have same dimensions. + +**Examples:** +```c++ +imeth::Matrix A = {{5, 6}, {7, 8}}; +imeth::Matrix B = {{1, 2}, {3, 4}}; -A 1D array of numbers (essentially a column vector in mathematical terms). +imeth::Matrix C = A - B; +// [[4, 4], +// [4, 4]] + +// Calculate change +imeth::Matrix original = {{10, 20}, {30, 40}}; +imeth::Matrix modified = {{12, 18}, {32, 38}}; +imeth::Matrix change = modified - original; + +// Subtract from itself +imeth::Matrix zero = A - A; // All zeros +``` + +**Real-world:** Frame differences in video, error calculation, change detection + +--- + +### Multiplication + +```c++ +Matrix operator*(const Matrix& rhs) const; +``` + +Matrix multiplication using dot product of rows and columns. + +**Rule:** A.cols() must equal B.rows() for A × B + +**Formula:** C[i][j] = Σ(A[i][k] × B[k][j]) + +**Examples:** +```c++ +imeth::Matrix A = {{1, 2}, {3, 4}}; +imeth::Matrix B = {{5, 6}, {7, 8}}; + +imeth::Matrix C = A * B; +// C[0][0] = 1×5 + 2×7 = 19 +// C[0][1] = 1×6 + 2×8 = 22 +// [[19, 22], +// [43, 50]] + +// Multiply 2×3 and 3×2 → 2×2 +imeth::Matrix D = {{1, 2, 3}, {4, 5, 6}}; +imeth::Matrix E = {{7, 8}, {9, 10}, {11, 12}}; +imeth::Matrix F = D * E; // [[58, 64], [139, 154]] + +// Identity property +imeth::Matrix I = imeth::Matrix::identity(2); +imeth::Matrix unchanged = A * I; // equals A + +// Matrix powers +imeth::Matrix A_squared = A * A; +``` + +**Properties:** +- NOT commutative: A × B ≠ B × A +- Associative: (AB)C = A(BC) +- Distributive: A(B + C) = AB + AC +- Dimension rule: (m×n) × (n×p) = (m×p) + +**Real-world:** 3D graphics transformations, neural networks, coordinate systems + +--- + +## Vector Class + +One-dimensional array of numbers. ### Constructors -- `Vector(size_t n)` - Creates a vector of size n (initialized to zero) -- `Vector(std::initializer_list data)` - Creates a vector from a list of values +```c++ +Vector(size_t n); +Vector(std::initializer_list data); +``` -### Element Access +**Examples:** +```c++ +// Size 5, initialized to zero +imeth::Vector v1(5); -- `operator[](size_t i) → double&` - Accesses element at index i (modifiable) -- `operator[](size_t i) const → double` - Accesses element at index i (read-only) +// With initial values +imeth::Vector v2 = {1.0, 2.0, 3.0, 4.0}; -### Properties +// 3D position vector +imeth::Vector position = {10.5, 20.3, 15.7}; + +// Unit vectors +imeth::Vector x_axis = {1, 0, 0}; +imeth::Vector y_axis = {0, 1, 0}; +imeth::Vector z_axis = {0, 0, 1}; +``` -- `size() const → size_t` - Returns the number of elements +**Real-world:** Coordinates, velocities, feature vectors, data samples -### Example Usage +--- + +### Element Access ```c++ -#include -#include +double& operator[](size_t i); +double operator[](size_t i) const; +``` -int main() { - // Create a vector - imeth::Vector v = {1.0, 2.0, 3.0, 4.0}; +Access element at index i (0-indexed). - std::cout << "Vector size: " << v.size() << "\n"; // 4 +**Examples:** +```c++ +imeth::Vector v = {10, 20, 30, 40, 50}; - // Access elements - std::cout << "v[0] = " << v[0] << "\n"; // 1.0 - std::cout << "v[2] = " << v[2] << "\n"; // 3.0 +double first = v[0]; // 10 +v[2] = 300; // Modify - // Modify element - v[1] = 5.0; +// Iterate +for (size_t i = 0; i < v.size(); ++i) { + v[i] *= 2; // Double each element +} - // Create empty vector and fill it - imeth::Vector u(5); - for (size_t i = 0; i < u.size(); ++i) { - u[i] = i * 2.0; - } +// Find maximum +double max_val = v[0]; +for (size_t i = 1; i < v.size(); ++i) { + if (v[i] > max_val) max_val = v[i]; +} - return 0; +// Compute sum +double sum = 0; +for (size_t i = 0; i < v.size(); ++i) { + sum += v[i]; } ``` --- -## Solver +### Properties -Provides numerical methods for solving systems of linear equations Ax = b, where A is a matrix, x is the unknown vector, and b is the result vector. +```c++ +size_t size() const; +``` -### Methods +Returns number of elements. -- `gaussian_elimination(const Matrix& A, const Vector& b) → Vector` - Solves Ax = b using Gaussian elimination with back substitution -- `gauss_jordan(const Matrix& A, const Vector& b) → Vector` - Solves Ax = b using Gauss-Jordan elimination (reduced row echelon form) -- `lu_decomposition(const Matrix& A, const Vector& b) → Vector` - Solves Ax = b using LU decomposition (factors A = LU) +**Examples:** +```c++ +imeth::Vector v = {1, 2, 3, 4, 5}; +size_t len = v.size(); // 5 -### Example Usage +// Validate operations +bool can_add = (a.size() == b.size()); -```c++ -#include -#include +// Check matrix compatibility +bool compatible = (M.cols() == v.size()); +``` -int main() { - // Solve the system: - // 2x + 3y = 8 - // x - y = 1 +--- - imeth::Matrix A = { - {2, 3}, - {1, -1} - }; +## Solver Class - imeth::Vector b = {8, 1}; +Solves systems of linear equations: **Ax = b** - // Method 1: Gaussian elimination - imeth::Vector x1 = imeth::Solver::gaussian_elimination(A, b); - std::cout << "Solution (Gaussian): x = " << x1[0] << ", y = " << x1[1] << "\n"; +Where: +- **A** is n×n coefficient matrix +- **x** is unknown vector +- **b** is result vector - // Method 2: Gauss-Jordan - imeth::Vector x2 = imeth::Solver::gauss_jordan(A, b); - std::cout << "Solution (Gauss-Jordan): x = " << x2[0] << ", y = " << x2[1] << "\n"; +--- - // Method 3: LU decomposition - imeth::Vector x3 = imeth::Solver::lu_decomposition(A, b); - std::cout << "Solution (LU): x = " << x3[0] << ", y = " << x3[1] << "\n"; +### Gaussian Elimination - return 0; -} +```c++ +static Vector gaussian_elimination(const Matrix& A, const Vector& b); ``` -### More Examples +Forward elimination + back substitution. +**Examples:** ```c++ -// Solve a 3×3 system: -// x + 2y + z = 6 -// 2x + y + z = 6 -// x + y + 2z = 7 +// Solve: 2x + 3y = 8 +// x - y = 1 -imeth::Matrix A = { +imeth::Matrix A = {{2, 3}, {1, -1}}; +imeth::Vector b = {8, 1}; + +imeth::Vector sol = imeth::Solver::gaussian_elimination(A, b); +// x = 2.2, y = 1.2 + +// 3×3 system +imeth::Matrix A3 = { {1, 2, 1}, {2, 1, 1}, {1, 1, 2} }; +imeth::Vector b3 = {6, 6, 7}; +imeth::Vector sol3 = imeth::Solver::gaussian_elimination(A3, b3); +``` + +**Best for:** General purpose, single solve + +**Real-world:** Circuit analysis, structural engineering, economics + +**Complexity:** O(n³) + +--- + +### Gauss-Jordan Elimination + +```c++ +static Vector gauss_jordan(const Matrix& A, const Vector& b); +``` + +Reduces to identity matrix (no back substitution needed). + +**Examples:** +```c++ +imeth::Matrix A = {{2, 3}, {1, -1}}; +imeth::Vector b = {8, 1}; + +imeth::Vector sol = imeth::Solver::gauss_jordan(A, b); +// x = 2.2, y = 1.2 + +// 4×4 system +imeth::Matrix A4 = { + {4, 1, 0, 0}, + {1, 4, 1, 0}, + {0, 1, 4, 1}, + {0, 0, 1, 4} +}; +imeth::Vector b4 = {5, 6, 6, 5}; +imeth::Vector sol4 = imeth::Solver::gauss_jordan(A4, b4); +``` + +**Best for:** Finding inverses, multiple systems + +**Real-world:** Linear programming, regression analysis + +**Complexity:** O(n³) + +--- + +### LU Decomposition + +```c++ +static Vector lu_decomposition(const Matrix& A, const Vector& b); +``` + +Factors A = LU, then solves Ly = b and Ux = y. + +**Examples:** +```c++ +imeth::Matrix A = {{2, 3}, {1, -1}}; +imeth::Vector b = {8, 1}; + +imeth::Vector sol = imeth::Solver::lu_decomposition(A, b); +// x = 2.2, y = 1.2 -imeth::Vector b = {6, 6, 7}; +// Multiple solves with same A (efficient!) +imeth::Vector b1 = {8, 1}; +imeth::Vector b2 = {10, 2}; +imeth::Vector b3 = {5, 0}; + +imeth::Vector sol1 = imeth::Solver::lu_decomposition(A, b1); +imeth::Vector sol2 = imeth::Solver::lu_decomposition(A, b2); +imeth::Vector sol3 = imeth::Solver::lu_decomposition(A, b3); +``` -imeth::Vector solution = imeth::Solver::gaussian_elimination(A, b); +**Best for:** Multiple solves with same coefficient matrix -std::cout << "x = " << solution[0] << "\n"; // x = 1 -std::cout << "y = " << solution[1] << "\n"; // y = 2 -std::cout << "z = " << solution[2] << "\n"; // z = 2 +**Real-world:** Simulations, finite element analysis, control systems + +**Complexity:** O(n³) factorization + O(n²) per solve + +--- -// Verify solution: A * x = b -for (size_t i = 0; i < A.rows(); ++i) { - double result = 0; - for (size_t j = 0; j < A.cols(); ++j) { - result += A(i, j) * solution[j]; +## Solver Comparison + +| Method | Best Use | Complexity | Advantage | +|--------|----------|------------|-----------| +| **Gaussian** | Single solve | O(n³) | Simple, reliable | +| **Gauss-Jordan** | Need inverse | O(n³) | No back substitution | +| **LU** | Multiple solves | O(n³) + O(kn²) | Efficient for k solves | + +--- + +## Complete Examples + +### Traffic Flow Analysis + +```c++ +#include +#include + +int main() { + // Conservation law: flow in = flow out + // x1 + x2 = 100 + // x2 + x3 = 150 + // x3 + x4 = 80 + // x4 + x1 = 130 + + imeth::Matrix A = { + {1, 1, 0, 0}, + {0, 1, 1, 0}, + {0, 0, 1, 1}, + {1, 0, 0, 1} + }; + + imeth::Vector b = {100, 150, 80, 130}; + imeth::Vector flow = imeth::Solver::gaussian_elimination(A, b); + + std::cout << "Road flows (vehicles/hour):\n"; + for (size_t i = 0; i < flow.size(); ++i) { + std::cout << "Road " << i+1 << ": " << flow[i] << "\n"; } - std::cout << "Row " << i << " check: " << result << " = " << b[i] << "\n"; + + return 0; } ``` -## Mathematical Background +--- -**Matrix** - A rectangular array of numbers arranged in rows and columns. Matrices are used to represent linear transformations and systems of equations. +### 3D Rotation -**Vector** - A one-dimensional array of numbers. In this context, it represents either the coefficients on the right side of equations (vector b) or the solution values (vector x). +```c++ +#include +#include -**System of Linear Equations** - Multiple equations like: +int main() { + // Rotate point (1,0,0) by 90° around Z-axis + double angle = M_PI / 2; + + imeth::Matrix rotation = { + {std::cos(angle), -std::sin(angle), 0}, + {std::sin(angle), std::cos(angle), 0}, + {0, 0, 1} + }; + + imeth::Matrix point = {{1}, {0}, {0}}; + imeth::Matrix rotated = rotation * point; + + std::cout << "Rotated: (" << rotated(0,0) << ", " + << rotated(1,0) << ", " << rotated(2,0) << ")\n"; + // Result: (0, 1, 0) + + return 0; +} ``` -a₁₁x₁ + a₁₂x₂ + ... = b₁ -a₂₁x₁ + a₂₂x₂ + ... = b₂ -... + +--- + +### Portfolio Optimization + +```c++ +#include + +int main() { + // Allocate $10,000 across 3 investments + imeth::Matrix constraints = { + {1, 1, 1}, // Total = $10,000 + {0.05, 0.08, 0.12}, // Expected return 8% + {1, -2, 1} // Risk balance + }; + + imeth::Vector targets = {10000, 800, 0}; + imeth::Vector allocation = imeth::Solver::gauss_jordan(constraints, targets); + + std::cout << "Allocation:\n"; + for (size_t i = 0; i < allocation.size(); ++i) { + std::cout << "Investment " << i+1 << ": $" << allocation[i] << "\n"; + } + + return 0; +} ``` -**Solving Methods:** -- **Gaussian Elimination** - Transforms the system to upper triangular form, then uses back substitution -- **Gauss-Jordan** - Reduces the matrix to reduced row echelon form (identity matrix) -- **LU Decomposition** - Factors matrix A into lower (L) and upper (U) triangular matrices +--- + +## Tips + +- **Dimension compatibility**: Check before operations (A.cols() == B.rows() for multiplication) +- **Zero-based indexing**: Valid indices for 3×3 matrix are (0,0) to (2,2) +- **Order matters**: A × B ≠ B × A for matrix multiplication +- **Choose solver wisely**: Gaussian for one solve, LU for multiple solves +- **Verify solutions**: Substitute back into original equations +- **Identity baseline**: Use I as starting point for transformations + +--- + +## Quick Reference + +| Operation | Syntax | Requirement | +|-----------|--------|-------------| +| Create matrix | `Matrix A(m, n)` or `{{...}}` | - | +| Access element | `A(i, j)` | 0 ≤ i < rows, 0 ≤ j < cols | +| Add/Subtract | `A + B`, `A - B` | Same dimensions | +| Multiply | `A * B` | A.cols() == B.rows() | +| Transpose | `A.transpose()` | - | +| Identity | `Matrix::identity(n)` | Square n×n | +| Solve system | `Solver::gaussian_elimination(A, b)` | Square matrix A | + +**Properties:** +- Addition: Commutative, associative +- Multiplication: Associative, NOT commutative +- Transpose: (A^T)^T = A, (AB)^T = B^T A^T +- Identity: I × A = A × I = A + +**Complexity:** +- Element access: O(1) +- Add/Subtract: O(mn) +- Multiply: O(mnp) for (m×n) × (n×p) +- Solve: O(n³) \ No newline at end of file diff --git a/docs/api/operation/arithmetic.md b/docs/api/operation/arithmetic.md index b467308..9529d59 100644 --- a/docs/api/operation/arithmetic.md +++ b/docs/api/operation/arithmetic.md @@ -6,72 +6,804 @@ The arithmetic chapter is the first chapter from the `operation` category. It pr #include ``` -## Features - -### Basic Operations -- `add(double a, double b) → double` - Standard addition -- `subtract(double a, double b) → double` - Standard subtraction -- `multiply(double a, double b) → double` - Standard multiplication -- `divide(double a, double b) → double` - Standard division - -### Power and Roots -- `power(double base, int exponent) → double` - Raises base to an integer exponent -- `squareRoot(double n) → double` - Computes √n -- `cubeRoot(double n) → double` - Computes ∛n - -### Absolute Value and Sign -- `absolute(double n) → double` - Returns |n| -- `sign(double n) → int` - Returns -1 for negative, 0 for zero, 1 for positive - -### Remainders and Divisibility -- `remainder(int a, int b) → int` - Integer remainder of a ÷ b -- `isDivisible(int a, int b) → bool` - Checks if a is divisible by b - -### Percentages -- `percentOf(double percent, double total) → double` - Calculates percent% of total -- `whatPercent(double part, double total) → double` - Finds what percent part is of total -- `percentIncrease(double original, double newValue) → double` - Calculates percentage increase -- `percentDecrease(double original, double newValue) → double` - Calculates percentage decrease - -### Averages and Statistics -- `average(const std::vector& numbers) → double` - Mean of a vector of numbers -- `sum(const std::vector& numbers) → double` - Total sum -- `minimum(const std::vector& numbers) → double` - Minimum value -- `maximum(const std::vector& numbers) → double` - Maximum value -- `range(const std::vector& numbers) → double` - Difference between max and min -- `median(std::vector numbers) → double` - Middle value (sorts the data) - -### Fractions -- `addFractions(double num1, double den1, double num2, double den2) → double` - Adds two fractions -- `subtractFractions(double num1, double den1, double num2, double den2) → double` - Subtracts fractions -- `multiplyFractions(double num1, double den1, double num2, double den2) → double` - Multiplies fractions -- `divideFractions(double num1, double den1, double num2, double den2) → double` - Divides fractions - -### Rounding -- `roundToNearest(double n) → double` - Rounds to nearest integer -- `roundUp(double n) → double` - Ceiling function -- `roundDown(double n) → double` - Floor function -- `roundToDecimalPlaces(double n, int places) → double` - Rounds to specified decimal places - -### Number Properties -- `isEven(int n) → bool` - Checks if even -- `isOdd(int n) → bool` - Checks if odd -- `isPrime(int n) → bool` - Tests for primality -- `greatestCommonDivisor(int a, int b) → int` - GCD of two integers -- `leastCommonMultiple(int a, int b) → int` - LCM of two integers - -### Geometry -- `distance2D(double x1, double y1, double x2, double y2) → double` - Euclidean distance between two points -- `pythagorean(double a, double b) → double` - Calculates hypotenuse using Pythagorean theorem - -### Conversions -- `celsiusToFahrenheit(double celsius) → double` - Temperature conversion C → F -- `fahrenheitToCelsius(double fahrenheit) → double` - Temperature conversion F → C - -### Finance -- `simpleInterest(double principal, double rate, double time) → double` - Calculates simple interest - -## Example Usage +## Overview + +Arithmetic is the foundation of mathematics. This module helps you answer questions like: +- "What's the average of these test scores?" +- "Is this number prime?" +- "How much is 15% of $200?" +- "What's the distance between two points?" + +--- + +## Basic Operations + +### Addition + +```c++ +double add(double a, double b); +``` + +Standard addition of two numbers. + +**Examples:** +```c++ +add(5.0, 3.0); // 8.0 +add(-10.5, 7.2); // -3.3 +add(100, 250); // 350.0 +``` + +**Real-world:** Calculating totals, summing prices, combining quantities. + +--- + +### Subtraction + +```c++ +double subtract(double a, double b); +``` + +Standard subtraction - computes a - b. + +**Examples:** +```c++ +subtract(10.0, 3.0); // 7.0 +subtract(5.5, 8.2); // -2.7 +subtract(100, 45); // 55.0 +``` + +**Real-world:** Finding differences, calculating change, determining deficits. + +--- + +### Multiplication + +```c++ +double multiply(double a, double b); +``` + +Standard multiplication of two numbers. + +**Examples:** +```c++ +multiply(5.0, 3.0); // 15.0 +multiply(-4.0, 2.5); // -10.0 +multiply(12, 0.5); // 6.0 +``` + +**Real-world:** Scaling quantities, calculating areas, price × quantity. + +--- + +### Division + +```c++ +double divide(double a, double b); +``` + +Standard division - computes a ÷ b. + +**Examples:** +```c++ +divide(10.0, 2.0); // 5.0 +divide(7.0, 2.0); // 3.5 +divide(100, 3); // 33.333... +``` + +**Real-world:** Splitting bills, calculating rates, finding averages. + +**Note:** Division by zero will cause an error. + +--- + +## Power and Roots + +### Power + +```c++ +double power(double base, int exponent); +``` + +Raises base to an integer exponent. + +**Examples:** +```c++ +power(2, 3); // 8.0 (2³) +power(5, 2); // 25.0 (5²) +power(10, 0); // 1.0 (anything⁰ = 1) +power(2, -2); // 0.25 (2⁻² = 1/4) +``` + +**Real-world:** Compound interest, exponential growth, area/volume calculations. + +--- + +### Square Root + +```c++ +double squareRoot(double n); +``` + +Computes the square root (√n). + +**Examples:** +```c++ +squareRoot(9); // 3.0 +squareRoot(25); // 5.0 +squareRoot(2); // 1.414... +squareRoot(100); // 10.0 +``` + +**Real-world:** Pythagorean theorem, standard deviation, geometric calculations. + +--- + +### Cube Root + +```c++ +double cubeRoot(double n); +``` + +Computes the cube root (∛n). + +**Examples:** +```c++ +cubeRoot(8); // 2.0 +cubeRoot(27); // 3.0 +cubeRoot(-8); // -2.0 (cube root of negative is negative) +cubeRoot(1000); // 10.0 +``` + +**Real-world:** Volume calculations, finding side length from volume. + +--- + +## Absolute Value and Sign + +### Absolute Value + +```c++ +double absolute(double n); +``` + +Returns the absolute value |n| (always positive or zero). + +**Examples:** +```c++ +absolute(5.0); // 5.0 +absolute(-5.0); // 5.0 +absolute(0); // 0.0 +absolute(-3.14); // 3.14 +``` + +**Real-world:** Distance calculations, magnitude, error measurements. + +--- + +### Sign + +```c++ +int sign(double n); +``` + +Returns the sign of a number: +- Returns -1 for negative numbers +- Returns 0 for zero +- Returns 1 for positive numbers + +**Examples:** +```c++ +sign(42.5); // 1 +sign(-17.3); // -1 +sign(0.0); // 0 +sign(-0.001); // -1 +``` + +**Real-world:** Direction indicators, profit/loss status, trend analysis. + +--- + +## Remainders and Divisibility + +### Remainder + +```c++ +int remainder(int a, int b); +``` + +Integer remainder of a ÷ b (modulo operation). + +**Examples:** +```c++ +remainder(10, 3); // 1 (10 = 3×3 + 1) +remainder(17, 5); // 2 (17 = 5×3 + 2) +remainder(20, 4); // 0 (evenly divisible) +remainder(7, 10); // 7 (dividend smaller than divisor) +``` + +**Real-world:** Clock arithmetic, cyclic patterns, checking divisibility. + +--- + +### Is Divisible + +```c++ +bool isDivisible(int a, int b); +``` + +Checks if a is evenly divisible by b (remainder is 0). + +**Examples:** +```c++ +isDivisible(10, 2); // true +isDivisible(15, 3); // true +isDivisible(17, 5); // false +isDivisible(100, 25); // true +``` + +**Real-world:** Checking if items can be evenly distributed, validating constraints. + +--- + +## Percentages + +### Percent Of + +```c++ +double percentOf(double percent, double total); +``` + +Calculates what percent% of total equals. + +**Formula:** result = (percent / 100) × total + +**Examples:** +```c++ +percentOf(20, 100); // 20.0 (20% of 100) +percentOf(15, 200); // 30.0 (15% of 200) +percentOf(50, 80); // 40.0 (50% of 80) +percentOf(8.5, 150); // 12.75 (8.5% of 150) +``` + +**Real-world:** Calculating tips, discounts, tax amounts, commissions. + +--- + +### What Percent + +```c++ +double whatPercent(double part, double total); +``` + +Finds what percent the part is of the total. + +**Formula:** result = (part / total) × 100 + +**Examples:** +```c++ +whatPercent(25, 100); // 25.0 (25 is 25% of 100) +whatPercent(30, 150); // 20.0 (30 is 20% of 150) +whatPercent(45, 90); // 50.0 (45 is 50% of 90) +whatPercent(7, 35); // 20.0 (7 is 20% of 35) +``` + +**Real-world:** Grade percentages, completion rates, market share analysis. + +--- + +### Percent Increase + +```c++ +double percentIncrease(double original, double newValue); +``` + +Calculates the percentage increase from original to newValue. + +**Formula:** ((newValue - original) / original) × 100 + +**Examples:** +```c++ +percentIncrease(50, 75); // 50.0 (increased by 50%) +percentIncrease(100, 150); // 50.0 (increased by 50%) +percentIncrease(80, 100); // 25.0 (increased by 25%) +percentIncrease(200, 250); // 25.0 (increased by 25%) +``` + +**Real-world:** Price increases, population growth, salary raises, profit margins. + +--- + +### Percent Decrease + +```c++ +double percentDecrease(double original, double newValue); +``` + +Calculates the percentage decrease from original to newValue. + +**Formula:** ((original - newValue) / original) × 100 + +**Examples:** +```c++ +percentDecrease(100, 75); // 25.0 (decreased by 25%) +percentDecrease(200, 150); // 25.0 (decreased by 25%) +percentDecrease(80, 60); // 25.0 (decreased by 25%) +percentDecrease(50, 25); // 50.0 (decreased by 50%) +``` + +**Real-world:** Discounts, price reductions, depreciation, weight loss tracking. + +--- + +## Averages and Statistics + +### Average (Mean) + +```c++ +double average(const std::vector& numbers); +``` + +Calculates the arithmetic mean (average) of a set of numbers. + +**Formula:** sum of all numbers ÷ count of numbers + +**Examples:** +```c++ +std::vector grades = {85, 90, 78, 92, 88}; +average(grades); // 86.6 + +std::vector temps = {72.5, 68.0, 75.2, 71.8}; +average(temps); // 71.875 +``` + +**Real-world:** Grade point average, average temperature, mean income. + +--- + +### Sum + +```c++ +double sum(const std::vector& numbers); +``` + +Calculates the total sum of all numbers in the vector. + +**Examples:** +```c++ +std::vector prices = {10.5, 25.0, 8.75, 15.25}; +sum(prices); // 59.5 + +std::vector scores = {100, 85, 90, 95}; +sum(scores); // 370.0 +``` + +**Real-world:** Total sales, combined scores, aggregate values. + +--- + +### Minimum + +```c++ +double minimum(const std::vector& numbers); +``` + +Finds the smallest value in the vector. + +**Examples:** +```c++ +std::vector temps = {72.5, 68.0, 75.2, 71.8}; +minimum(temps); // 68.0 + +std::vector prices = {19.99, 15.50, 22.00, 12.99}; +minimum(prices); // 12.99 +``` + +**Real-world:** Lowest price, minimum temperature, worst score. + +--- + +### Maximum + +```c++ +double maximum(const std::vector& numbers); +``` + +Finds the largest value in the vector. + +**Examples:** +```c++ +std::vector temps = {72.5, 68.0, 75.2, 71.8}; +maximum(temps); // 75.2 + +std::vector scores = {85, 92, 78, 95, 88}; +maximum(scores); // 95.0 +``` + +**Real-world:** Highest score, peak temperature, maximum capacity. + +--- + +### Range + +```c++ +double range(const std::vector& numbers); +``` + +Calculates the difference between the maximum and minimum values. + +**Formula:** max - min + +**Examples:** +```c++ +std::vector temps = {68.0, 72.5, 75.2, 71.8}; +range(temps); // 7.2 (75.2 - 68.0) + +std::vector ages = {25, 35, 42, 28, 31}; +range(ages); // 17.0 (42 - 25) +``` + +**Real-world:** Temperature variation, price spread, age distribution. + +--- + +### Median + +```c++ +double median(std::vector numbers); +``` + +Finds the middle value when numbers are sorted. If there's an even count, returns the average of the two middle values. + +**Note:** This function sorts the input vector. + +**Examples:** +```c++ +std::vector odd = {3, 1, 4, 1, 5}; +median(odd); // 3.0 (middle of 1,1,3,4,5) + +std::vector even = {10, 20, 30, 40}; +median(even); // 25.0 (average of 20 and 30) +``` + +**Real-world:** Median income (resistant to outliers), middle test score. + +--- + +## Fractions + +### Add Fractions + +```c++ +double addFractions(double num1, double den1, double num2, double den2); +``` + +Adds two fractions: (num1/den1) + (num2/den2). + +**Examples:** +```c++ +addFractions(1, 2, 1, 3); // 0.8333... (1/2 + 1/3 = 5/6) +addFractions(2, 5, 3, 10); // 0.7 (2/5 + 3/10 = 7/10) +addFractions(1, 4, 1, 4); // 0.5 (1/4 + 1/4 = 1/2) +``` + +**Real-world:** Recipe measurements, combining partial amounts. + +--- + +### Subtract Fractions + +```c++ +double subtractFractions(double num1, double den1, double num2, double den2); +``` + +Subtracts two fractions: (num1/den1) - (num2/den2). + +**Examples:** +```c++ +subtractFractions(3, 4, 1, 2); // 0.25 (3/4 - 1/2 = 1/4) +subtractFractions(5, 6, 1, 3); // 0.5 (5/6 - 1/3 = 1/2) +``` + +**Real-world:** Measuring remaining quantities, calculating differences. + +--- + +### Multiply Fractions + +```c++ +double multiplyFractions(double num1, double den1, double num2, double den2); +``` + +Multiplies two fractions: (num1/den1) × (num2/den2). + +**Examples:** +```c++ +multiplyFractions(2, 3, 3, 4); // 0.5 (2/3 × 3/4 = 1/2) +multiplyFractions(1, 2, 1, 2); // 0.25 (1/2 × 1/2 = 1/4) +``` + +**Real-world:** Scaling recipes, calculating portions. + +--- + +### Divide Fractions + +```c++ +double divideFractions(double num1, double den1, double num2, double den2); +``` + +Divides two fractions: (num1/den1) ÷ (num2/den2). + +**Examples:** +```c++ +divideFractions(1, 2, 1, 4); // 2.0 (1/2 ÷ 1/4 = 2) +divideFractions(3, 4, 3, 8); // 2.0 (3/4 ÷ 3/8 = 2) +``` + +**Real-world:** Dividing quantities, portion distribution. + +--- + +## Rounding + +### Round to Nearest + +```c++ +double roundToNearest(double n); +``` + +Rounds to the nearest integer. Values at .5 round up. + +**Examples:** +```c++ +roundToNearest(3.2); // 3.0 +roundToNearest(3.7); // 4.0 +roundToNearest(3.5); // 4.0 +roundToNearest(-2.5); // -2.0 or -3.0 (implementation dependent) +``` + +**Real-world:** Rounding prices, counting items, simplifying measurements. + +--- + +### Round Up (Ceiling) + +```c++ +double roundUp(double n); +``` + +Rounds up to the next integer (ceiling function). + +**Examples:** +```c++ +roundUp(3.1); // 4.0 +roundUp(3.9); // 4.0 +roundUp(3.0); // 3.0 +roundUp(-2.1); // -2.0 +``` + +**Real-world:** Calculating packages needed, minimum capacity, buffer allocation. + +--- + +### Round Down (Floor) + +```c++ +double roundDown(double n); +``` + +Rounds down to the previous integer (floor function). + +**Examples:** +```c++ +roundDown(3.1); // 3.0 +roundDown(3.9); // 3.0 +roundDown(3.0); // 3.0 +roundDown(-2.1); // -3.0 +``` + +**Real-world:** Complete sets, whole units available, truncating values. + +--- + +### Round to Decimal Places + +```c++ +double roundToDecimalPlaces(double n, int places); +``` + +Rounds to a specified number of decimal places. + +**Examples:** +```c++ +roundToDecimalPlaces(3.14159, 2); // 3.14 +roundToDecimalPlaces(2.5678, 1); // 2.6 +roundToDecimalPlaces(100.567, 0); // 101.0 +roundToDecimalPlaces(1.2345, 3); // 1.235 +``` + +**Real-world:** Currency (2 decimal places), precision measurements, display formatting. + +--- + +## Number Properties + +### Is Even + +```c++ +bool isEven(int n); +``` + +Checks if a number is even (divisible by 2). + +**Examples:** +```c++ +isEven(4); // true +isEven(7); // false +isEven(0); // true +isEven(-6); // true +``` + +**Real-world:** Pairing items, determining patterns, scheduling rotations. + +--- + +### Is Odd + +```c++ +bool isOdd(int n); +``` + +Checks if a number is odd (not divisible by 2). + +**Examples:** +```c++ +isOdd(5); // true +isOdd(8); // false +isOdd(1); // true +isOdd(-3); // true +``` + +**Real-world:** Alternating patterns, parity checks, game logic. + +--- + +### Is Prime + +```c++ +bool isPrime(int n); +``` + +Tests whether a number is prime (only divisible by 1 and itself). + +**Examples:** +```c++ +isPrime(2); // true (smallest prime) +isPrime(17); // true +isPrime(20); // false (divisible by 2, 4, 5, 10) +isPrime(1); // false (1 is not prime by definition) +isPrime(29); // true +``` + +**Real-world:** Cryptography, hash functions, mathematical research. + +--- + +### Greatest Common Divisor (GCD) + +```c++ +int greatestCommonDivisor(int a, int b); +``` + +Finds the largest number that divides both a and b evenly. + +**Examples:** +```c++ +greatestCommonDivisor(48, 18); // 6 +greatestCommonDivisor(100, 50); // 50 +greatestCommonDivisor(17, 19); // 1 (coprime numbers) +greatestCommonDivisor(24, 36); // 12 +``` + +**Real-world:** Simplifying fractions, tile arrangements, gear ratios. + +--- + +### Least Common Multiple (LCM) + +```c++ +int leastCommonMultiple(int a, int b); +``` + +Finds the smallest positive number that is a multiple of both a and b. + +**Examples:** +```c++ +leastCommonMultiple(4, 6); // 12 +leastCommonMultiple(3, 5); // 15 +leastCommonMultiple(12, 18); // 36 +leastCommonMultiple(7, 14); // 14 +``` + +**Real-world:** Scheduling cycles, pattern repetition, synchronization problems. + +--- + +## Geometry + +### Distance 2D + +```c++ +double distance2D(double x1, double y1, double x2, double y2); +``` + +Calculates the Euclidean distance between two points in 2D space. + +**Formula:** √[(x₂-x₁)² + (y₂-y₁)²] + +**Examples:** +```c++ +distance2D(0, 0, 3, 4); // 5.0 +distance2D(1, 1, 4, 5); // 5.0 +distance2D(-2, -3, 1, 1); // 5.0 +distance2D(0, 0, 1, 1); // 1.414... (√2) +``` + +**Real-world:** GPS distance, game coordinates, mapping applications. + +--- + +### Pythagorean Theorem + +```c++ +double pythagorean(double a, double b); +``` + +Calculates the hypotenuse of a right triangle given the two legs. + +**Formula:** c = √(a² + b²) + +**Examples:** +```c++ +pythagorean(3, 4); // 5.0 (3-4-5 triangle) +pythagorean(5, 12); // 13.0 (5-12-13 triangle) +pythagorean(1, 1); // 1.414... (√2) +pythagorean(6, 8); // 10.0 +``` + +**Real-world:** Construction, navigation, diagonal measurements. + +## Finance + +### Simple Interest + +```c++ +double simpleInterest(double principal, double rate, double time); +``` + +Calculates simple interest on a principal amount. + +**Formula:** I = P × r × t + +**Parameters:** +- principal: Initial amount +- rate: Interest rate (as decimal, e.g., 0.05 for 5%) +- time: Time period (usually in years) + +**Examples:** +```c++ +simpleInterest(1000, 0.05, 2); // 100.0 ($1000 at 5% for 2 years) +simpleInterest(5000, 0.03, 1); // 150.0 ($5000 at 3% for 1 year) +simpleInterest(10000, 0.04, 3); // 1200.0 ($10000 at 4% for 3 years) +``` + +**Real-world:** Loan interest, savings accounts, investment returns. + +--- + +## Complete Examples + +### Example 1: Simple Calculator ```c++ #include @@ -109,27 +841,166 @@ int main() { } ``` -## More Examples +--- + +### Example 2: Statistical Analysis + +```c++ +#include +#include +#include + +int main() { + std::vector grades = {85.5, 92.0, 78.5, 95.0, 88.0}; + + std::cout << "Grade Statistics\n"; + std::cout << "================\n"; + std::cout << "Average: " << imeth::Arithmetic::average(grades) << "\n"; + std::cout << "Median: " << imeth::Arithmetic::median(grades) << "\n"; + std::cout << "Minimum: " << imeth::Arithmetic::minimum(grades) << "\n"; + std::cout << "Maximum: " << imeth::Arithmetic::maximum(grades) << "\n"; + std::cout << "Range: " << imeth::Arithmetic::range(grades) << "\n"; + + return 0; +} +``` + +--- + +### Example 3: Number Theory + +```c++ +#include +#include + +int main() { + int a = 48, b = 18; + + std::cout << "Number Theory for " << a << " and " << b << "\n"; + std::cout << "GCD: " << imeth::Arithmetic::greatestCommonDivisor(a, b) << "\n"; + std::cout << "LCM: " << imeth::Arithmetic::leastCommonMultiple(a, b) << "\n"; + + std::cout << "\nPrime numbers from 1 to 20:\n"; + for (int i = 1; i <= 20; i++) { + if (imeth::Arithmetic::isPrime(i)) { + std::cout << i << " "; + } + } + std::cout << "\n"; + + return 0; +} +``` + +--- + +### Example 4: Percentage Calculations ```c++ -// Statistical calculations -std::vector grades = {85.5, 92.0, 78.5, 95.0, 88.0}; -double avg = imeth::Arithmetic::average(grades); // 87.8 -double med = imeth::Arithmetic::median(grades); // 88.0 -double minGrade = imeth::Arithmetic::minimum(grades); // 78.5 +#include +#include -// Number theory -int gcd = imeth::Arithmetic::greatestCommonDivisor(48, 18); // 6 -bool prime = imeth::Arithmetic::isPrime(17); // true +int main() { + double originalPrice = 100.0; + double salePrice = 75.0; -// Percentage calculations -double discount = imeth::Arithmetic::percentOf(20, 100.0); // 20.0 -double increase = imeth::Arithmetic::percentIncrease(50, 75); // 50.0 + double discount = imeth::Arithmetic::percentOf(20, originalPrice); + double decrease = imeth::Arithmetic::percentDecrease(originalPrice, salePrice); -// Geometry -double dist = imeth::Arithmetic::distance2D(0, 0, 3, 4); // 5.0 -double hyp = imeth::Arithmetic::pythagorean(3, 4); // 5.0 + std::cout << "Original Price: $" << originalPrice << "\n"; + std::cout << "20% discount: $" << discount << "\n"; + std::cout << "Sale Price: $" << salePrice << "\n"; + std::cout << "Percent saved: " << decrease << "%\n"; -// Temperature conversion -double fahrenheit = imeth::Arithmetic::celsiusToFahrenheit(25); // 77.0 + return 0; +} +``` + +--- + +### Example 5: Geometry Calculations + +```c++ +#include +#include + +int main() { + // Calculate distance between two cities (coordinates) + double city1_x = 0, city1_y = 0; + double city2_x = 3, city2_y = 4; + + double distance = imeth::Arithmetic::distance2D(city1_x, city1_y, + city2_x, city2_y); + + std::cout << "Distance between cities: " << distance << " km\n"; + + // Calculate diagonal of a rectangle + double width = 6, height = 8; + double diagonal = imeth::Arithmetic::pythagorean(width, height); + + std::cout << "Rectangle diagonal: " << diagonal << "\n"; + + return 0; +} +``` + +--- + +## Tips + +- **Division by Zero**: Always check for zero before dividing +- **Integer vs Double**: Use appropriate types for your calculations +- **Rounding**: Choose the right rounding method for your use case +- **Prime Testing**: Large numbers may take longer to test +- **Floating Point**: Be aware of floating-point precision limitations +- **Vector Operations**: Ensure vectors are not empty before statistical calculations + +--- + +## Quick Reference + +| Operation Type | Function | Use Case | +|---------------|----------|----------| +| Basic math | `add`, `subtract`, `multiply`, `divide` | Calculations | +| Powers | `power`, `squareRoot`, `cubeRoot` | Exponents, roots | +| Statistics | `average`, `median`, `sum` | Data analysis | +| Percentages | `percentOf`, `whatPercent` | Discounts, rates | +| Rounding | `roundToNearest`, `roundUp`, `roundDown` | Display, precision | +| Number theory | `isPrime`, `greatestCommonDivisor` | Math problems | +| Geometry | `distance2D`, `pythagorean` | Coordinates, triangles | +| Temperature | `celsiusToFahrenheit` | Conversions | +| Finance | `simpleInterest` | Loans, investments | + +--- + +## Common Use Cases + +### Shopping Calculations +```c++ +double price = 50.0; +double taxRate = 0.08; // 8% tax +double tax = imeth::Arithmetic::percentOf(taxRate * 100, price); +double total = imeth::Arithmetic::add(price, tax); +``` + +### Grade Calculator +```c++ +std::vector scores = {85, 90, 78, 92}; +double avg = imeth::Arithmetic::average(scores); +double rounded = imeth::Arithmetic::roundToNearest(avg); +``` + +### Distance Calculation +```c++ +double dist = imeth::Arithmetic::distance2D(x1, y1, x2, y2); +double roundedDist = imeth::Arithmetic::roundToDecimalPlaces(dist, 2); +``` + +### Fraction Simplification +```c++ +int num = 48, den = 18; +int gcd = imeth::Arithmetic::greatestCommonDivisor(num, den); +int simplifiedNum = num / gcd; // 8 +int simplifiedDen = den / gcd; // 3 +// Result: 48/18 = 8/3 ``` diff --git a/docs/api/operation/logarithm.md b/docs/api/operation/logarithm.md index 285515b..bbdb90e 100644 --- a/docs/api/operation/logarithm.md +++ b/docs/api/operation/logarithm.md @@ -1,108 +1,954 @@ # Logarithm -Logarithm is the second chapter that can be found from the `operation` category. It provides methods and functions to operate logarithmic operations, including common logarithms, natural logarithms, exponential equation solving, and base conversions. +Logarithm is the second chapter from the `operation` category. It provides methods and functions for logarithmic operations, including common logarithms, natural logarithms, exponential equation solving, and base conversions. Logarithms are the inverse of exponential functions and are essential for solving problems involving exponential growth, decay, and scale transformations. ```c++ #include ``` -## Features +## Overview -### Logarithm Functions -- `log(double base, double value) → std::optional` - Computes log_base(value) with arbitrary base -- `ln(double value) → std::optional` - Natural logarithm (base e) -- `log10(double value) → std::optional` - Common logarithm (base 10) -- `log2(double value) → std::optional` - Binary logarithm (base 2) +Logarithms answer the question: "To what power must we raise a base to get a certain value?" This module helps you solve problems like: +- "2 raised to what power equals 8?" (Answer: 3, because 2³ = 8) +- "How many times must I double something to reach 1000?" +- "What's the pH of this solution?" (uses log₁₀) +- "How many bits do I need to represent this number?" (uses log₂) -### Exponential Equations -- `solve_exponential(double base, double value) → std::optional` - Solves base^x = value for x +--- -### Base Conversion -- `change_base(double value, double old_base, double new_base) → std::optional` - Converts logarithm from one base to another using the change of base formula +## Return Value Convention -## Return Values +**IMPORTANT:** All logarithm functions return `std::optional` for safe error handling. -All methods return `std::optional`: -- Contains a value if the operation is valid -- Returns `std::nullopt` if: - - `value ≤ 0` (logarithm undefined for non-positive numbers) - - `base ≤ 0` (invalid base) - - `base = 1` (division by zero in change of base formula) +```c++ +auto result = imeth::Logarithm::log(2, 8); +if (result.has_value()) { + std::cout << "Result: " << result.value() << "\n"; +} else { + std::cout << "Invalid input\n"; +} +``` + +Functions return `std::nullopt` when: +- `value ≤ 0` (logarithm undefined for non-positive numbers) +- `base ≤ 0` (invalid base) +- `base = 1` (would cause division by zero) + +--- + +## Logarithm Functions + +### General Logarithm + +```c++ +std::optional log(double base, double value); +``` + +Computes log_base(value) - the power to which base must be raised to get value. + +**Formula:** If base^x = value, then log_base(value) = x + +**Examples:** +```c++ +auto result1 = imeth::Logarithm::log(2, 8); +// result1.value() = 3.0 (because 2³ = 8) + +auto result2 = imeth::Logarithm::log(10, 100); +// result2.value() = 2.0 (because 10² = 100) + +auto result3 = imeth::Logarithm::log(5, 125); +// result3.value() = 3.0 (because 5³ = 125) + +auto result4 = imeth::Logarithm::log(3, 27); +// result4.value() = 3.0 (because 3³ = 27) + +// Invalid cases +auto invalid1 = imeth::Logarithm::log(2, -5); +// invalid1.has_value() = false (negative value) + +auto invalid2 = imeth::Logarithm::log(1, 10); +// invalid2.has_value() = false (base cannot be 1) + +auto invalid3 = imeth::Logarithm::log(-2, 8); +// invalid3.has_value() = false (negative base) +``` + +**Real-world applications:** +- Database indexing complexity analysis +- Algorithm time complexity calculations +- Custom scale conversions +- Financial compound interest calculations + +--- + +### Natural Logarithm (ln) + +```c++ +std::optional ln(double value); +``` + +Computes the natural logarithm (base e ≈ 2.71828) - the most fundamental logarithm in mathematics. + +**Formula:** ln(value) = log_e(value) + +**Examples:** +```c++ +auto result1 = imeth::Logarithm::ln(2.718281828); +// result1.value() ≈ 1.0 (ln(e) = 1) + +auto result2 = imeth::Logarithm::ln(1); +// result2.value() = 0.0 (ln(1) = 0, because e⁰ = 1) + +auto result3 = imeth::Logarithm::ln(7.389056); +// result3.value() ≈ 2.0 (ln(e²) = 2) + +auto result4 = imeth::Logarithm::ln(20.085537); +// result4.value() ≈ 3.0 (ln(e³) = 3) + +auto result5 = imeth::Logarithm::ln(0.367879); +// result5.value() ≈ -1.0 (ln(e⁻¹) = -1) + +// Invalid case +auto invalid = imeth::Logarithm::ln(0); +// invalid.has_value() = false (ln(0) is undefined) +``` + +**Real-world applications:** +- Continuous compound interest: A = Pe^(rt), solve for t using ln +- Population growth models: P(t) = P₀e^(kt) +- Radioactive decay calculations +- Information theory and entropy +- Normal distribution calculations in statistics +- Chemical reaction rates (Arrhenius equation) +- Machine learning loss functions + +**Why natural logarithm?** +The natural logarithm has unique mathematical properties: +- Derivative of ln(x) is 1/x (simplest) +- Integral of 1/x is ln(x) +- Area under curve 1/x from 1 to e equals 1 + +--- + +### Common Logarithm (log₁₀) + +```c++ +std::optional log10(double value); +``` + +Computes the common logarithm (base 10) - widely used in science and engineering. + +**Formula:** log₁₀(value) = log_10(value) + +**Examples:** +```c++ +auto result1 = imeth::Logarithm::log10(10); +// result1.value() = 1.0 (10¹ = 10) + +auto result2 = imeth::Logarithm::log10(100); +// result2.value() = 2.0 (10² = 100) + +auto result3 = imeth::Logarithm::log10(1000); +// result3.value() = 3.0 (10³ = 1000) + +auto result4 = imeth::Logarithm::log10(1); +// result4.value() = 0.0 (10⁰ = 1) + +auto result5 = imeth::Logarithm::log10(0.01); +// result5.value() = -2.0 (10⁻² = 0.01) + +auto result6 = imeth::Logarithm::log10(50); +// result6.value() ≈ 1.699 (10^1.699 ≈ 50) +``` + +**Real-world applications:** +- **pH calculations**: pH = -log₁₀[H⁺] concentration + - pH 7 (neutral): [H⁺] = 10⁻⁷ + - pH 3 (acidic): [H⁺] = 10⁻³ +- **Decibel scale**: dB = 10·log₁₀(P/P₀) + - Sound intensity measurements + - Signal strength in telecommunications +- **Richter scale**: Earthquake magnitude +- **Star magnitude**: Brightness of celestial objects +- **Scientific notation**: Counting orders of magnitude +- **Slide rule calculations**: Historical computing + +**Why base 10?** +Base 10 is intuitive for humans because: +- We use decimal number system +- Easy to count orders of magnitude +- Powers of 10 are easy to visualize + +--- + +### Binary Logarithm (log₂) + +```c++ +std::optional log2(double value); +``` + +Computes the binary logarithm (base 2) - fundamental in computer science. + +**Formula:** log₂(value) = log_2(value) + +**Examples:** +```c++ +auto result1 = imeth::Logarithm::log2(2); +// result1.value() = 1.0 (2¹ = 2) + +auto result2 = imeth::Logarithm::log2(8); +// result2.value() = 3.0 (2³ = 8) + +auto result3 = imeth::Logarithm::log2(16); +// result3.value() = 4.0 (2⁴ = 16) + +auto result4 = imeth::Logarithm::log2(1024); +// result4.value() = 10.0 (2¹⁰ = 1024) + +auto result5 = imeth::Logarithm::log2(1); +// result5.value() = 0.0 (2⁰ = 1) + +auto result6 = imeth::Logarithm::log2(0.5); +// result6.value() = -1.0 (2⁻¹ = 0.5) + +auto result7 = imeth::Logarithm::log2(32); +// result7.value() = 5.0 (2⁵ = 32) +``` + +**Real-world applications:** +- **Bit calculations**: How many bits to represent n values? + - 256 values = log₂(256) = 8 bits + - 1024 values = log₂(1024) = 10 bits +- **Algorithm complexity**: Binary search is O(log₂(n)) +- **Tree depth**: Binary tree with n nodes has depth ≈ log₂(n) +- **Information theory**: Entropy and information content +- **Audio processing**: Octaves in music (frequency doubling) +- **Image compression**: JPEG, PNG compression ratios +- **Network protocols**: Packet size calculations +- **Memory addressing**: Address space calculations + +**Why base 2?** +Base 2 is natural for computers because: +- Binary system (0 and 1) +- Powers of 2 in memory (KB, MB, GB) +- Bit-level operations + +--- + +## Exponential Equations + +### Solve Exponential + +```c++ +std::optional solve_exponential(double base, double value); +``` + +Solves the exponential equation: base^x = value for x. + +This is equivalent to computing log_base(value), but the function name makes the intent clearer when solving equations. + +**Formula:** If base^x = value, then x = log_base(value) + +**Examples:** +```c++ +// Solve: 2^x = 8 +auto x1 = imeth::Logarithm::solve_exponential(2, 8); +// x1.value() = 3.0 (because 2³ = 8) + +// Solve: 2^x = 32 +auto x2 = imeth::Logarithm::solve_exponential(2, 32); +// x2.value() = 5.0 (because 2⁵ = 32) + +// Solve: 10^x = 1000 +auto x3 = imeth::Logarithm::solve_exponential(10, 1000); +// x3.value() = 3.0 (because 10³ = 1000) + +// Solve: 3^x = 81 +auto x4 = imeth::Logarithm::solve_exponential(3, 81); +// x4.value() = 4.0 (because 3⁴ = 81) + +// Solve: 5^x = 125 +auto x5 = imeth::Logarithm::solve_exponential(5, 125); +// x5.value() = 3.0 (because 5³ = 125) + +// Solve: 2^x = 1 +auto x6 = imeth::Logarithm::solve_exponential(2, 1); +// x6.value() = 0.0 (because 2⁰ = 1) + +// Solve: e^x = 20 +auto x7 = imeth::Logarithm::solve_exponential(2.718281828, 20); +// x7.value() ≈ 2.996 (because e^2.996 ≈ 20) +``` + +**Real-world applications:** +- **Compound interest**: How long until money doubles? + - Solve: (1.05)^t = 2 → t = log₁.₀₅(2) ≈ 14.2 years at 5% interest +- **Population growth**: When will population reach target? + - Solve: P₀(1.02)^t = 2P₀ → t = log₁.₀₂(2) ≈ 35 years at 2% growth +- **Radioactive decay**: How long for half-life? + - Solve: (0.5)^t = 0.25 → t = 2 half-lives +- **Moore's Law**: When will transistor count reach target? +- **Pandemic modeling**: Infection doubling time +- **Battery discharge**: Time to reach certain voltage +- **Chemical reactions**: Time to completion + +--- + +## Base Conversion + +### Change Base + +```c++ +std::optional change_base(double value, double old_base, double new_base); +``` + +Converts a logarithm from one base to another using the change of base formula. + +**Formula:** log_new(value) = log_old(value) / log_old(new_base) + +Or equivalently: log_b(x) = log_a(x) / log_a(b) + +**Examples:** +```c++ +// Convert log₂(8) to base 10 +auto result1 = imeth::Logarithm::change_base(8, 2, 10); +// result1.value() ≈ 0.903 (log₁₀(8)) + +// Convert log₁₀(100) to base 2 +auto result2 = imeth::Logarithm::change_base(100, 10, 2); +// result2.value() ≈ 6.644 (log₂(100)) + +// Convert log₅(25) to base 3 +auto result3 = imeth::Logarithm::change_base(25, 5, 3); +// result3.value() ≈ 2.930 (log₃(25)) + +// Convert ln(e²) to base 10 +auto result4 = imeth::Logarithm::change_base(7.389, 2.718281828, 10); +// result4.value() ≈ 0.869 (log₁₀(e²)) + +// Verify: log₂(8) = 3, converting to base 10 +auto verify = imeth::Logarithm::change_base(8, 2, 10); +// First compute: log₁₀(8) ≈ 0.903 +// Verify: log₂(8) = log₁₀(8) / log₁₀(2) = 0.903 / 0.301 ≈ 3.0 +``` + +**Real-world applications:** +- **Calculator conversions**: Most calculators only have ln and log₁₀ + - To compute log₂(100): Use log₁₀(100) / log₁₀(2) +- **Algorithm analysis**: Converting between different complexity bases +- **Information theory**: Converting between different entropy bases +- **Scientific calculations**: Adapting formulas to available tools +- **Database queries**: Converting between different logarithmic scales + +**Why change base?** +- Your calculator might only have certain bases (usually 10 and e) +- Different fields prefer different bases +- Mathematical proofs often use natural logarithm +- Computer science uses base 2 +- General science uses base 10 + +--- + +## Mathematical Properties + +The logarithm functions implement standard mathematical properties: + +### Product Rule +**log(xy) = log(x) + log(y)** + +```c++ +// Instead of log(100 × 1000) +auto direct = imeth::Logarithm::log10(100000); // 5.0 + +// Can compute as log(100) + log(1000) +auto log_100 = imeth::Logarithm::log10(100); // 2.0 +auto log_1000 = imeth::Logarithm::log10(1000); // 3.0 +// Sum: 2.0 + 3.0 = 5.0 +``` + +**Real-world:** Multiplying very large numbers (astronomy, particle physics) + +--- + +### Quotient Rule +**log(x/y) = log(x) - log(y)** -## Example Usage +```c++ +// Instead of log(1000 / 10) +auto direct = imeth::Logarithm::log10(100); // 2.0 + +// Can compute as log(1000) - log(10) +auto log_1000 = imeth::Logarithm::log10(1000); // 3.0 +auto log_10 = imeth::Logarithm::log10(10); // 1.0 +// Difference: 3.0 - 1.0 = 2.0 +``` + +**Real-world:** Simplifying division problems, slide rule calculations + +--- + +### Power Rule +**log(x^n) = n · log(x)** + +```c++ +// Instead of log(2^10) +auto direct = imeth::Logarithm::log2(1024); // 10.0 + +// Can compute as 10 × log(2) +auto log_2 = imeth::Logarithm::log2(2); // 1.0 +// Product: 10 × 1.0 = 10.0 +``` + +**Real-world:** Exponential growth calculations, compound interest + +--- + +### Change of Base Formula +**log_b(x) = log_a(x) / log_a(b)** + +```c++ +// Compute log₂(8) using base 10 +auto log_8 = imeth::Logarithm::log10(8); // 0.903 +auto log_2 = imeth::Logarithm::log10(2); // 0.301 +// Division: 0.903 / 0.301 ≈ 3.0 + +// Or use the built-in function +auto result = imeth::Logarithm::change_base(8, 2, 10); // 0.903 +``` + +**Real-world:** When your calculator doesn't have the base you need + +--- + +### Identity Properties +```c++ +// log_b(b) = 1 +auto log_e_e = imeth::Logarithm::ln(2.718281828); // 1.0 +auto log_10_10 = imeth::Logarithm::log10(10); // 1.0 +auto log_2_2 = imeth::Logarithm::log2(2); // 1.0 + +// log_b(1) = 0 (for any base) +auto log_10_1 = imeth::Logarithm::log10(1); // 0.0 +auto ln_1 = imeth::Logarithm::ln(1); // 0.0 +auto log_2_1 = imeth::Logarithm::log2(1); // 0.0 + +// log_b(b^x) = x +auto result = imeth::Logarithm::log2(8); // 3.0 (because 2³ = 8) + +// b^(log_b(x)) = x +// If log₂(8) = 3, then 2³ = 8 +``` + +--- + +## Complete Examples + +### Example 1: Compound Interest Calculator ```c++ #include #include +#include int main() { - // Basic logarithms - auto result = imeth::Logarithm::log(2, 8); - if (result.has_value()) { - std::cout << "log_2(8) = " << result.value() << "\n"; // 3.0 + double principal = 1000.0; // Initial amount + double rate = 0.05; // 5% annual interest + double target = 2000.0; // Want to double money + + // Solve: principal × (1 + rate)^t = target + // (1.05)^t = 2 + // t = log₁.₀₅(2) + + double growth_factor = 1.0 + rate; + double multiplier = target / principal; + + auto years = imeth::Logarithm::solve_exponential(growth_factor, multiplier); + + if (years.has_value()) { + std::cout << std::fixed << std::setprecision(2); + std::cout << "To turn $" << principal << " into $" << target + << " at " << (rate * 100) << "% interest:\n"; + std::cout << "Time needed: " << years.value() << " years\n"; } - // Natural logarithm - auto ln_result = imeth::Logarithm::ln(2.718281828); - if (ln_result.has_value()) { - std::cout << "ln(e) ≈ " << ln_result.value() << "\n"; // ≈ 1.0 + return 0; +} +// Output: Time needed: 14.21 years +``` + +--- + +### Example 2: pH Calculator (Chemistry) + +```c++ +#include +#include +#include + +int main() { + // pH = -log₁₀[H⁺] + double hydrogen_concentration = 0.001; // mol/L + + auto log_h = imeth::Logarithm::log10(hydrogen_concentration); + + if (log_h.has_value()) { + double pH = -log_h.value(); + + std::cout << std::fixed << std::setprecision(2); + std::cout << "[H⁺] = " << hydrogen_concentration << " mol/L\n"; + std::cout << "pH = " << pH << "\n"; + + if (pH < 7) { + std::cout << "Solution is acidic\n"; + } else if (pH > 7) { + std::cout << "Solution is basic\n"; + } else { + std::cout << "Solution is neutral\n"; + } } - // Common logarithm - auto log10_result = imeth::Logarithm::log10(1000); - if (log10_result.has_value()) { - std::cout << "log_10(1000) = " << log10_result.value() << "\n"; // 3.0 + return 0; +} +// Output: pH = 3.00, Solution is acidic +``` + +--- + +### Example 3: Bit Calculations (Computer Science) + +```c++ +#include +#include +#include + +int main() { + int num_values = 1000; + + // How many bits needed to represent 1000 different values? + auto bits_needed = imeth::Logarithm::log2(num_values); + + if (bits_needed.has_value()) { + int bits = static_cast(std::ceil(bits_needed.value())); + int max_values = static_cast(std::pow(2, bits)); + + std::cout << "To represent " << num_values << " values:\n"; + std::cout << "Bits needed (exact): " << bits_needed.value() << "\n"; + std::cout << "Bits needed (rounded): " << bits << " bits\n"; + std::cout << "Max values with " << bits << " bits: " + << max_values << "\n"; } - // Binary logarithm - auto log2_result = imeth::Logarithm::log2(16); - if (log2_result.has_value()) { - std::cout << "log_2(16) = " << log2_result.value() << "\n"; // 4.0 + return 0; +} +// Output: Bits needed: 10 bits (can represent up to 1024 values) +``` + +### Example 4: Algorithm Complexity Analysis + +```c++ +#include +#include +#include + +int main() { + std::vector data_sizes = {100, 1000, 10000, 100000, 1000000}; + + std::cout << std::setw(12) << "Data Size" + << std::setw(15) << "Linear O(n)" + << std::setw(20) << "Logarithmic O(log n)" + << std::setw(20) << "Linearithmic O(n log n)\n"; + std::cout << std::string(67, '-') << "\n"; + + for (int n : data_sizes) { + auto log_n = imeth::Logarithm::log2(n); + + if (log_n.has_value()) { + std::cout << std::setw(12) << n + << std::setw(15) << n + << std::setw(20) << std::fixed << std::setprecision(2) + << log_n.value() + << std::setw(20) << (n * log_n.value()) << "\n"; + } } return 0; } +// Shows how logarithmic algorithms scale much better than linear ``` -## More Examples +--- + +### Example 8: Base Conversion for Calculator ```c++ -// Solving exponential equations -// Solve: 2^x = 32 -auto x = imeth::Logarithm::solve_exponential(2, 32); -if (x.has_value()) { - std::cout << "x = " << x.value() << "\n"; // 5.0 +#include +#include +#include + +int main() { + // Most calculators only have ln and log₁₀ + // To compute log₃(27), use change of base + + double value = 27; + double desired_base = 3; + + // Method 1: Using change_base + auto result1 = imeth::Logarithm::change_base(value, desired_base, 10); + + // Method 2: Manual calculation + auto log10_val = imeth::Logarithm::log10(value); + auto log10_base = imeth::Logarithm::log10(desired_base); + + if (log10_val.has_value() && log10_base.has_value()) { + double result2 = log10_val.value() / log10_base.value(); + + std::cout << std::fixed << std::setprecision(6); + std::cout << "Computing log₃(27):\n"; + std::cout << "Using change_base: " << result1.value() << "\n"; + std::cout << "Manual calculation: " << result2 << "\n"; + std::cout << "Verification: 3³ = " << std::pow(3, result2) << "\n"; + } + + return 0; } +// Output: log₃(27) = 3.0 (because 3³ = 27) +``` -// Solve: 10^x = 1000 -auto x2 = imeth::Logarithm::solve_exponential(10, 1000); -if (x2.has_value()) { - std::cout << "x = " << x2.value() << "\n"; // 3.0 +--- + +## Error Handling Best Practices + +Always check if the result has a value before using it: + +```c++ +// Good practice +auto result = imeth::Logarithm::log(2, 8); +if (result.has_value()) { + std::cout << "Result: " << result.value() << "\n"; +} else { + std::cerr << "Error: Invalid input for logarithm\n"; } -// Change of base -// Convert log_2(8) to base 10 -auto converted = imeth::Logarithm::change_base(8, 2, 10); -if (converted.has_value()) { - std::cout << "log_10(8) = " << converted.value() << "\n"; // ≈ 0.903 +// Alternative with default value +auto result = imeth::Logarithm::log(2, 8); +double value = result.value_or(0.0); // Returns 0.0 if invalid + +// Compact check +if (auto result = imeth::Logarithm::log(2, 8)) { + std::cout << "Result: " << *result << "\n"; } +``` + +**Common error scenarios:** +```c++ +// Negative value +auto err1 = imeth::Logarithm::log10(-5); // nullopt + +// Zero value +auto err2 = imeth::Logarithm::ln(0); // nullopt + +// Invalid base (≤ 0) +auto err3 = imeth::Logarithm::log(-2, 8); // nullopt + +// Base = 1 (undefined) +auto err4 = imeth::Logarithm::log(1, 10); // nullopt +``` + +--- + +## Tips + +- **Choose the right base**: Use ln for calculus, log₁₀ for science/engineering, log₂ for computer science +- **Always validate input**: Check for negative numbers and zero before computation +- **Use std::optional properly**: Always check `has_value()` before accessing the result +- **Understand the domain**: Logarithms only work for positive numbers +- **Performance consideration**: `ln` is typically fastest, other bases use conversion +- **Precision**: Results are accurate to double precision (~15 decimal places) +- **Avoid unnecessary conversions**: Use the specific function (ln, log10, log2) instead of converting from log() -// Error handling -auto invalid = imeth::Logarithm::log(2, -5); -if (!invalid.has_value()) { - std::cout << "Cannot compute logarithm of negative number\n"; +--- + +## Common Pitfalls + +### 1. Forgetting to Check std::optional + +```c++ +// ❌ WRONG - May crash if result is nullopt +auto result = imeth::Logarithm::log(2, -8); +std::cout << result.value() << "\n"; // CRASH! + +// ✅ CORRECT +auto result = imeth::Logarithm::log(2, -8); +if (result.has_value()) { + std::cout << result.value() << "\n"; +} else { + std::cerr << "Invalid input\n"; } +``` -auto invalid_base = imeth::Logarithm::log(1, 10); -if (!invalid_base.has_value()) { - std::cout << "Base cannot be 1\n"; +### 2. Using Wrong Base + +```c++ +// ❌ WRONG - Using natural log for pH calculation +auto pH = -imeth::Logarithm::ln(0.001); // Wrong! pH uses base 10 + +// ✅ CORRECT +auto log_h = imeth::Logarithm::log10(0.001); +if (log_h.has_value()) { + double pH = -log_h.value(); // pH = 3.0 } ``` -## Mathematical Properties +### 3. Confusion Between log() and solve_exponential() -The logarithm functions implement standard mathematical properties: -- **Product rule**: log(xy) = log(x) + log(y) -- **Quotient rule**: log(x/y) = log(x) - log(y) -- **Power rule**: log(x^n) = n·log(x) -- **Change of base**: log_b(x) = log_a(x) / log_a(b) +```c++ +// Both compute the same thing but have different semantic meaning: + +// When you think: "log₂(8) = ?" +auto result1 = imeth::Logarithm::log(2, 8); // 3.0 + +// When you think: "2^x = 8, solve for x" +auto result2 = imeth::Logarithm::solve_exponential(2, 8); // 3.0 + +// Use the one that matches your mental model! +``` + +### 4. Base 1 Error + +```c++ +// ❌ WRONG - Base cannot be 1 +auto result = imeth::Logarithm::log(1, 100); // nullopt! +// log₁(x) is undefined because 1^n = 1 for all n + +// ✅ CORRECT - Use a valid base +auto result = imeth::Logarithm::log(10, 100); // 2.0 +``` + +### 5. Negative or Zero Input + +```c++ +// ❌ WRONG - Logarithm undefined for non-positive numbers +auto result1 = imeth::Logarithm::log10(0); // nullopt +auto result2 = imeth::Logarithm::ln(-5); // nullopt + +// ✅ CORRECT - Ensure positive input +double value = -5; +if (value > 0) { + auto result = imeth::Logarithm::ln(value); +} +``` + +--- + +## Performance Characteristics + +### Time Complexity +All logarithm operations: **O(1)** - constant time + +The functions use optimized math library implementations: +- `ln()`: Direct call to `std::log()` +- `log10()`: Direct call to `std::log10()` +- `log2()`: Direct call to `std::log2()` +- `log()`: Uses change of base formula: `ln(value) / ln(base)` +- `solve_exponential()`: Alias for `log()` +- `change_base()`: Uses formula: `log_old(value) / log_old(new_base)` + +### Space Complexity +**O(1)** - constant space (only stores the result) + +### Relative Performance +``` +Fastest: ln() ≈ 1.0x (baseline) +Fast: log10() ≈ 1.1x +Fast: log2() ≈ 1.1x +Moderate: log() ≈ 1.5x (requires division) +Moderate: change_base()≈ 2.0x (requires two logarithms) +``` + +**Performance tip**: If you need many logarithms with the same base, consider converting once: +```c++ +// Slow: Computing log₃ many times +for (double val : values) { + auto result = imeth::Logarithm::log(3, val); + // Uses log(val) / log(3) each time +} + +// Faster: Precompute the denominator +auto log_3 = imeth::Logarithm::ln(3); +if (log_3.has_value()) { + double ln_3 = log_3.value(); + for (double val : values) { + auto ln_val = imeth::Logarithm::ln(val); + if (ln_val.has_value()) { + double result = ln_val.value() / ln_3; + // More efficient! + } + } +} +``` + +--- + +## Mathematical Background + +### What is a Logarithm? + +A logarithm answers the question: **"What exponent do I need?"** + +Given: **base^? = value** +Answer: **? = log_base(value)** + +**Visual understanding:** +``` +Exponential: 2¹ = 2, 2² = 4, 2³ = 8, 2⁴ = 16 +Logarithm: log₂(2) = 1, log₂(4) = 2, log₂(8) = 3, log₂(16) = 4 +``` + +The logarithm is the **inverse operation** of exponentiation: +- Exponentiation: base^x = value +- Logarithm: x = log_base(value) + +### Why Are Logarithms Useful? + +1. **Turn multiplication into addition** + - log(a × b) = log(a) + log(b) + - Makes complex calculations simpler + +2. **Turn division into subtraction** + - log(a / b) = log(a) - log(b) + +3. **Turn exponentiation into multiplication** + - log(a^n) = n × log(a) + +4. **Handle very large numbers** + - log₁₀(1,000,000,000) = 9 (much easier to work with) + +5. **Solve exponential equations** + - If 2^x = 100, then x = log₂(100) ≈ 6.64 + +### The Three Important Bases + +**Base e (Natural Logarithm - ln)** +- **e ≈ 2.71828...** +- Used in: calculus, continuous growth, physics +- Special property: derivative of e^x is e^x +- Most fundamental in mathematics + +**Base 10 (Common Logarithm - log₁₀)** +- Matches our decimal number system +- Used in: chemistry (pH), physics (decibels), seismology (Richter scale) +- Easy to understand orders of magnitude + +**Base 2 (Binary Logarithm - log₂)** +- Matches binary computer system +- Used in: computer science, information theory, algorithm analysis +- Answers: "How many bits?" or "How many times do I halve/double?" + +--- + +## Relationship to Other Operations + +### Logarithm ↔ Exponentiation +```c++ +// These are inverses of each other +double x = 3.0; +double base = 2.0; + +// Exponentiation: 2^3 = 8 +double value = imeth::Arithmethic::power(base, x); // 8.0 + +// Logarithm: log₂(8) = 3 +auto result = imeth::Logarithm::log(base, value); // 3.0 +``` + +### Logarithm ↔ Root +```c++ +// √x is the same as x^(1/2) +// Which means: log(√x) = log(x^(1/2)) = (1/2) × log(x) + +double x = 16.0; + +// Square root +double sqrt_x = std::sqrt(x); // 4.0 + +// Using logarithm +auto log_x = imeth::Logarithm::log2(x); // 4.0 +if (log_x.has_value()) { + double half_log = log_x.value() / 2.0; // 2.0 + // 2^2 = 4, which is √16 +} +``` + +--- + +## Integration with Other Modules + +### With Exponential Operations +```c++ +#include +#include + +// Compound interest: A = P × e^(rt) +// To find time t when A is known: t = ln(A/P) / r + +double principal = 1000.0; +double amount = 2000.0; +double rate = 0.05; + +double ratio = amount / principal; +auto ln_ratio = imeth::Logarithm::ln(ratio); + +if (ln_ratio.has_value()) { + double time = ln_ratio.value() / rate; + std::cout << "Time to double: " << time << " years\n"; +} +``` + +### With Trigonometry (Advanced) +```c++ +// Logarithms can solve exponential trigonometric equations +// Example: e^x = 1 + sin(x), solve numerically using logarithms +``` + +### With Statistics +```c++ +// Log-normal distribution +// Log transformation for skewed data +auto log_data = imeth::Logarithm::ln(data_point); +``` + +--- + +## Frequently Asked Questions + +**Q: Why does my calculator show "Math Error" for log(-5)?** +A: Logarithms are only defined for positive numbers. This library returns `std::nullopt` for invalid inputs instead of crashing. + +**Q: What's the difference between ln, log, and log₁₀?** +A: +- `ln` = natural logarithm (base e ≈ 2.718) +- `log10` = common logarithm (base 10) +- `log` = general logarithm (any base you specify) + +**Q: Why do I need logarithms if I have exponentiation?** +A: Logarithms solve the inverse problem. If you know 2^x = 100 and need to find x, you use logarithms: x = log₂(100). + +**Q: Can I compute logarithm of zero?** +A: No, log(0) approaches negative infinity but is undefined. The function returns `std::nullopt`. + +**Q: Why is log₁(anything) undefined?** +A: Because 1^x = 1 for all x. There's no unique answer to "1 to what power equals 5?" + +**Q: How accurate are these functions?** +A: Accurate to double precision (~15-17 significant decimal digits). + +**Q: Which is faster: ln(), log10(), or log()?** +A: `ln()` and `log10()` are slightly faster because they're direct library calls. `log()` requires an additional division. + +**Q: Can I use this for complex numbers?** +A: No, this library only supports real numbers (double). Complex logarithms require a different implementation. + +**Q: What's the relationship between log₂ and bits?** +A: log₂(n) tells you how many bits are needed to represent n different values (rounded up). + +---