{"id":13609684,"url":"https://github.com/markrogoyski/math-php","last_synced_at":"2025-05-10T10:30:55.033Z","repository":{"id":48167188,"uuid":"55360541","full_name":"markrogoyski/math-php","owner":"markrogoyski","description":"Powerful modern math library for PHP: Features descriptive statistics and regressions; Continuous and discrete probability distributions; Linear algebra with matrices and vectors, Numerical analysis; special mathematical functions; Algebra","archived":false,"fork":false,"pushed_at":"2025-01-26T21:01:16.000Z","size":5832,"stargazers_count":2366,"open_issues_count":57,"forks_count":243,"subscribers_count":79,"default_branch":"master","last_synced_at":"2025-05-08T00:56:48.324Z","etag":null,"topics":["algebra","combinatorics","distributions","finance","information-theory","linear-algebra","math","mathematics","matrix","number-theory","numerical-analysis","php","php-library","probability","regression","statistics","vector"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/markrogoyski.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2016-04-03T17:57:14.000Z","updated_at":"2025-05-06T09:11:33.000Z","dependencies_parsed_at":"2023-02-19T03:40:31.162Z","dependency_job_id":"603a6d09-49c4-4b51-a0a8-11f4daa4a43f","html_url":"https://github.com/markrogoyski/math-php","commit_stats":{"total_commits":3083,"total_committers":20,"mean_commits":154.15,"dds":"0.27927343496594226","last_synced_commit":"dbc2d1d1dca9081782e7660e23eadb3d3663324e"},"previous_names":[],"tags_count":138,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markrogoyski%2Fmath-php","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markrogoyski%2Fmath-php/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markrogoyski%2Fmath-php/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markrogoyski%2Fmath-php/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/markrogoyski","download_url":"https://codeload.github.com/markrogoyski/math-php/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252978742,"owners_count":21834915,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["algebra","combinatorics","distributions","finance","information-theory","linear-algebra","math","mathematics","matrix","number-theory","numerical-analysis","php","php-library","probability","regression","statistics","vector"],"created_at":"2024-08-01T19:01:37.103Z","updated_at":"2025-05-08T00:56:59.812Z","avatar_url":"https://github.com/markrogoyski.png","language":"PHP","funding_links":[],"categories":["Math, Statistics \u0026 Linear Algebra","Table of Contents","PHP","目录"],"sub_categories":["Recommended core stack","Numbers","数字 Numbers","Globalization"],"readme":"![MathPHP Logo](https://github.com/markrogoyski/math-php/blob/master/docs/image/MathPHPLogo.png?raw=true)\n\n### MathPHP - Powerful Modern Math Library for PHP\n\nThe only library you need to integrate mathematical functions into your applications. It is a self-contained library in pure PHP with no external dependencies.\n\n[![Coverage Status](https://coveralls.io/repos/github/markrogoyski/math-php/badge.svg?branch=master)](https://coveralls.io/github/markrogoyski/math-php?branch=master)\n[![License](https://poser.pugx.org/markrogoyski/math-php/license)](https://packagist.org/packages/markrogoyski/math-php)\n\nFeatures\n--------\n * [Algebra](#algebra)\n * [Arithmetic](#arithmetic)\n * Expression\n   - [Polynomial](#expression---polynomial)\n * [Finance](#finance)\n * Functions\n   - [Map](#functions---map---single-array)\n   - [Special Functions](#functions---special-functions)\n * Information Theory\n   - [Entropy](#information-theory---entropy)\n * Linear Algebra\n   - [Matrix](#linear-algebra---matrix)\n   - [Vector](#linear-algebra---vector)\n * Numbers\n   - [Arbitrary Integer](#number---arbitrary-length-integers)\n   - [Complex](#number---complex-numbers)\n   - [Quaternion](#number---quaternion)\n   - [Rational](#number---rational-numbers)\n * Number Theory\n   - [Integers](#number-theory---integers)\n * Numerical Analysis\n   - [Interpolation](#numerical-analysis---interpolation)\n   - [Numerical Differentiation](#numerical-analysis---numerical-differentiation)\n   - [Numerical Integration](#numerical-analysis---numerical-integration)\n   - [Root Finding](#numerical-analysis---root-finding)\n * Probability\n     - [Combinatorics](#probability---combinatorics)\n     - Distributions\n         * [Continuous](#probability---continuous-distributions)\n         * [Discrete](#probability---discrete-distributions)\n         * [Multivariate](#probability---multivariate-distributions)\n         * [Tables](#probability---distribution-tables)\n * [Sample Data](#sample-data)\n * [Search](#search)\n * Sequences\n     - [Basic](#sequences---basic)\n     - [Advanced](#sequences---advanced)\n     - [NonInteger](#sequences---non-integer)\n * [Set Theory](#set-theory)\n * Statistics\n     - [ANOVA](#statistics---anova)\n     - [Averages](#statistics---averages)\n     - [Circular](#statistics---circular)\n     - [Correlation](#statistics---correlation)\n     - [Descriptive](#statistics---descriptive)\n     - [Distance](#statistics---distance)\n     - [Distributions](#statistics---distributions)\n     - [Divergence](#statistics---divergence)\n     - [Effect Size](#statistics---effect-size)\n     - [Experiments](#statistics---experiments)\n     - [Kernel Density Estimation](#statistics---kernel-density-estimation)\n     - Multivariate\n        * [PCA (Principal Component Analysis)](#statistics---multivariate---principal-component-analysis)\n        * [PLS (Partial Least Squares Regression)](#statistics---multivariate---partial-least-squares-regression)\n     - [Outlier](#statistics---outlier)\n     - [Random Variables](#statistics---random-variables)\n     - [Regressions](#statistics---regressions)\n     - [Significance Testing](#statistics---significance-testing)\n * [Trigonometry](#trigonometry)\n\nSetup\n-----\n\n Add the library to your `composer.json` file in your project:\n\n```javascript\n{\n  \"require\": {\n      \"markrogoyski/math-php\": \"2.*\"\n  }\n}\n```\n\nUse [composer](http://getcomposer.org) to install the library:\n\n```bash\n$ php composer.phar install\n```\n\nComposer will install MathPHP inside your vendor folder. Then you can add the following to your\n.php files to use the library with Autoloading.\n\n```php\nrequire_once __DIR__ . '/vendor/autoload.php';\n```\n\nAlternatively, use composer on the command line to require and install MathPHP:\n\n```\n$ php composer.phar require markrogoyski/math-php:2.*\n```\n\n### Minimum Requirements\n * PHP 7.2\n\n Note: For PHP 7.0 and 7.1, use v1.0 (`markrogoyski/math-php:1.*`)\n\nUsage\n-----\n\n### Algebra\n```php\nuse MathPHP\\Algebra;\n\n// Greatest common divisor (GCD)\n$gcd = Algebra::gcd(8, 12);\n\n// Extended greatest common divisor - gcd(a, b) = a*a' + b*b'\n$gcd = Algebra::extendedGcd(12, 8); // returns array [gcd, a', b']\n\n// Least common multiple (LCM)\n$lcm = Algebra::lcm(5, 2);\n\n// Factors of an integer\n$factors = Algebra::factors(12); // returns [1, 2, 3, 4, 6, 12]\n\n// Linear equation of one variable: ax + b = 0\n[$a, $b] = [2, 4]; // 2x + 4 = 0\n$x       = Algebra::linear($a, $b);\n\n// Quadratic equation: ax² + bx + c = 0\n[$a, $b, $c] = [1, 2, -8]; // x² + 2x - 8\n[$x₁, $x₂]   = Algebra::quadratic($a, $b, $c);\n\n// Discriminant: Δ = b² - 4ac\n[$a, $b, $c] = [2, 3, 4]; // 3² - 4(2)(4)\n$Δ           = Algebra::discriminant($a, $b, $c);\n\n// Cubic equation: z³ + a₂z² + a₁z + a₀ = 0\n[$a₃, $a₂, $a₁, $a₀] = [2, 9, 3, -4]; // 2x³ + 9x² + 3x -4\n[$x₁, $x₂, $x₃]      = Algebra::cubic($a₃, $a₂, $a₁, $a₀);\n\n// Quartic equation: a₄z⁴ + a₃z³ + a₂z² + a₁z + a₀ = 0\n[$a₄, $a₃, $a₂, $a₁, $a₀] = [1, -10, 35, -50, 24]; // z⁴ - 10z³ + 35z² - 50z + 24 = 0\n[$z₁, $z₂, $z₃, $z₄]      = Algebra::quartic($a₄, $a₃, $a₂, $a₁, $a₀);\n```\n\n### Arithmetic\n```php\nuse MathPHP\\Arithmetic;\n\n$√x  = Arithmetic::isqrt(8);     // 2 Integer square root\n$³√x = Arithmetic::cubeRoot(-8); // -2\n$ⁿ√x = Arithmetic::root(81, 4);  // nᵗʰ root (4ᵗʰ): 3\n\n// Sum of digits\n$digit_sum    = Arithmetic::digitSum(99);    // 18\n$digital_root = Arithmetic::digitalRoot(99); // 9\n\n// Equality of numbers within a tolerance\n$x = 0.00000003458;\n$y = 0.00000003455;\n$ε = 0.0000000001;\n$almostEqual = Arithmetic::almostEqual($x, $y, $ε); // true\n\n// Copy sign\n$magnitude = 5;\n$sign      = -3;\n$signed_magnitude = Arithmetic::copySign($magnitude, $sign); // -5\n\n// Modulo (Differs from PHP remainder (%) operator for negative numbers)\n$dividend = 12;\n$divisor  = 5;\n$modulo   = Arithmetic::modulo($dividend, $divisor);  // 2\n$modulo   = Arithmetic::modulo(-$dividend, $divisor); // 3\n```\n\n### Expression - Polynomial\n```php\nuse MathPHP\\Expression\\Polynomial;\n\n// Polynomial x² + 2x + 3\n$coefficients = [1, 2, 3]\n$polynomial   = new Polynomial($coefficients);\n\n// Evaluate for x = 3\n$x = 3;\n$y = $polynomial($x);  // 18: 3² + 2*3 + 3\n\n// Calculus\n$derivative = $polynomial-\u003edifferentiate();  // Polynomial 2x + 2\n$integral   = $polynomial-\u003eintegrate();      // Polynomial ⅓x³ + x² + 3x\n\n// Arithmetic\n$sum        = $polynomial-\u003eadd($polynomial);       // Polynomial 2x² + 4x + 6\n$sum        = $polynomial-\u003eadd(2);                 // Polynomial x² + 2x + 5\n$difference = $polynomial-\u003esubtract($polynomial);  // Polynomial 0\n$difference = $polynomial-\u003esubtract(2);            // Polynomial x² + 2x + 1\n$product    = $polynomial-\u003emultiply($polynomial);  // Polynomial x⁴ + 4x³ + 10x² + 12x + 9\n$product    = $polynomial-\u003emultiply(2);            // Polynomial 2x² + 4x + 6\n$negated    = $polynomial-\u003enegate();               // Polynomial -x² - 2x - 3\n\n// Data\n$degree       = $polynomial-\u003egetDegree();        // 2\n$coefficients = $polynomial-\u003egetCoefficients();  // [1, 2, 3]\n\n// String representation\nprint($polynomial);  // x² + 2x + 3\n\n// Roots\n$polynomial = new Polynomial([1, -3, -4]);\n$roots      = $polynomial-\u003eroots();         // [-1, 4]\n\n// Companion matrix\n$companion = $polynomial-\u003ecompanionMatrix();\n```\n\n### Finance\n```php\nuse MathPHP\\Finance;\n\n// Financial payment for a loan or annuity with compound interest\n$rate          = 0.035 / 12; // 3.5% interest paid at the end of every month\n$periods       = 30 * 12;    // 30-year mortgage\n$present_value = 265000;     // Mortgage note of $265,000.00\n$future_value  = 0;\n$beginning     = false;      // Adjust the payment to the beginning or end of the period\n$pmt           = Finance::pmt($rate, $periods, $present_value, $future_value, $beginning);\n\n// Interest on a financial payment for a loan or annuity with compound interest.\n$period = 1; // First payment period\n$ipmt   = Finance::ipmt($rate, $period, $periods, $present_value, $future_value, $beginning);\n\n// Principle on a financial payment for a loan or annuity with compound interest\n$ppmt = Finance::ppmt($rate, $period, $periods, $present_value, $future_value = 0, $beginning);\n\n// Number of payment periods of an annuity.\n$periods = Finance::periods($rate, $payment, $present_value, $future_value, $beginning);\n\n// Annual Equivalent Rate (AER) of an annual percentage rate (APR)\n$nominal = 0.035; // APR 3.5% interest\n$periods = 12;    // Compounded monthly\n$aer     = Finance::aer($nominal, $periods);\n\n// Annual nominal rate of an annual effective rate (AER)\n$nomial = Finance::nominal($aer, $periods);\n\n// Future value for a loan or annuity with compound interest\n$payment = 1189.97;\n$fv      = Finance::fv($rate, $periods, $payment, $present_value, $beginning)\n\n// Present value for a loan or annuity with compound interest\n$pv = Finance::pv($rate, $periods, $payment, $future_value, $beginning)\n\n// Net present value of cash flows\n$values = [-1000, 100, 200, 300, 400];\n$npv    = Finance::npv($rate, $values);\n\n// Interest rate per period of an annuity\n$beginning = false; // Adjust the payment to the beginning or end of the period\n$rate      = Finance::rate($periods, $payment, $present_value, $future_value, $beginning);\n\n// Internal rate of return\n$values = [-100, 50, 40, 30];\n$irr    = Finance::irr($values); // Rate of return of an initial investment of $100 with returns of $50, $40, and $30\n\n// Modified internal rate of return\n$finance_rate      = 0.05; // 5% financing\n$reinvestment_rate = 0.10; // reinvested at 10%\n$mirr              = Finance::mirr($values, $finance_rate); // rate of return of an initial investment of $100 at 5% financing with returns of $50, $40, and $30 reinvested at 10%\n\n// Discounted payback of an investment\n$values  = [-1000, 100, 200, 300, 400, 500];\n$rate    = 0.1;\n$payback = Finance::payback($values, $rate); // The payback period of an investment with a $1,000 investment and future returns of $100, $200, $300, $400, $500 and a discount rate of 0.10\n\n// Profitability index\n$values              = [-100, 50, 50, 50];\n$profitability_index = Finance::profitabilityIndex($values, $rate); // The profitability index of an initial $100 investment with future returns of $50, $50, $50 with a 10% discount rate\n```\n\n### Functions - Map - Single Array\n```php\nuse MathPHP\\Functions\\Map;\n\n$x = [1, 2, 3, 4];\n\n$sums        = Map\\Single::add($x, 2);      // [3, 4, 5, 6]\n$differences = Map\\Single::subtract($x, 1); // [0, 1, 2, 3]\n$products    = Map\\Single::multiply($x, 5); // [5, 10, 15, 20]\n$quotients   = Map\\Single::divide($x, 2);   // [0.5, 1, 1.5, 2]\n$x²          = Map\\Single::square($x);      // [1, 4, 9, 16]\n$x³          = Map\\Single::cube($x);        // [1, 8, 27, 64]\n$x⁴          = Map\\Single::pow($x, 4);      // [1, 16, 81, 256]\n$√x          = Map\\Single::sqrt($x);        // [1, 1.414, 1.732, 2]\n$∣x∣         = Map\\Single::abs($x);         // [1, 2, 3, 4]\n$maxes       = Map\\Single::max($x, 3);      // [3, 3, 3, 4]\n$mins        = Map\\Single::min($x, 3);      // [1, 2, 3, 3]\n$reciprocals = Map\\Single::reciprocal($x);  // [1, 1/2, 1/3, 1/4]\n```\n\n### Functions - Map - Multiple Arrays\n```php\nuse MathPHP\\Functions\\Map;\n\n$x = [10, 10, 10, 10];\n$y = [1,   2,  5, 10];\n\n// Map function against elements of two or more arrays, item by item (by item ...)\n$sums        = Map\\Multi::add($x, $y);      // [11, 12, 15, 20]\n$differences = Map\\Multi::subtract($x, $y); // [9, 8, 5, 0]\n$products    = Map\\Multi::multiply($x, $y); // [10, 20, 50, 100]\n$quotients   = Map\\Multi::divide($x, $y);   // [10, 5, 2, 1]\n$maxes       = Map\\Multi::max($x, $y);      // [10, 10, 10, 10]\n$mins        = Map\\Multi::mins($x, $y);     // [1, 2, 5, 10]\n\n// All functions work on multiple arrays; not limited to just two\n$x    = [10, 10, 10, 10];\n$y    = [1,   2,  5, 10];\n$z    = [4,   5,  6,  7];\n$sums = Map\\Multi::add($x, $y, $z); // [15, 17, 21, 27]\n```\n\n### Functions - Special Functions\n```php\nuse MathPHP\\Functions\\Special;\n\n// Gamma function Γ(z)\n$z = 4;\n$Γ = Special::gamma($z);\n$Γ = Special::gammaLanczos($z);   // Lanczos approximation\n$Γ = Special::gammaStirling($z);  // Stirling approximation\n$l = Special::logGamma($z);\n$c = Special::logGammaCorr($z);   // Log gamma correction\n\n// Incomplete gamma functions - γ(s,t), Γ(s,x), P(s,x)\n[$x, $s] = [1, 2];\n$γ = Special::lowerIncompleteGamma($x, $s);\n$Γ = Special::upperIncompleteGamma($x, $s);\n$P = Special::regularizedLowerIncompleteGamma($x, $s);\n\n// Beta function\n[$x, $y] = [1, 2];\n$β  = Special::beta($x, $y);\n$lβ = Special::logBeta($x, $y);\n\n// Incomplete beta functions\n[$x, $a, $b] = [0.4, 2, 3];\n$B  = Special::incompleteBeta($x, $a, $b);\n$Iₓ = Special::regularizedIncompleteBeta($x, $a, $b);\n\n// Multivariate beta function\n$αs = [1, 2, 3];\n$β  = Special::multivariateBeta($αs);\n\n// Error function (Gauss error function)\n$error = Special::errorFunction(2);              // same as erf\n$error = Special::erf(2);                        // same as errorFunction\n$error = Special::complementaryErrorFunction(2); // same as erfc\n$error = Special::erfc(2);                       // same as complementaryErrorFunction\n\n// Hypergeometric functions\n$pFq = Special::generalizedHypergeometric($p, $q, $a, $b, $c, $z);\n$₁F₁ = Special::confluentHypergeometric($a, $b, $z);\n$₂F₁ = Special::hypergeometric($a, $b, $c, $z);\n\n// Sign function (also known as signum or sgn)\n$x    = 4;\n$sign = Special::signum($x); // same as sgn\n$sign = Special::sgn($x);    // same as signum\n\n// Logistic function (logistic sigmoid function)\n$x₀ = 2; // x-value of the sigmoid's midpoint\n$L  = 3; // the curve's maximum value\n$k  = 4; // the steepness of the curve\n$x  = 5;\n$logistic = Special::logistic($x₀, $L, $k, $x);\n\n// Sigmoid function\n$t = 2;\n$sigmoid = Special::sigmoid($t);\n\n// Softmax function\n$𝐳    = [1, 2, 3, 4, 1, 2, 3];\n$σ⟮𝐳⟯ⱼ = Special::softmax($𝐳);\n\n// Log of the error term in the Stirling-De Moivre factorial series\n$err = Special::stirlingError($n);\n```\n\n### Information Theory - Entropy\n```php\nuse MathPHP\\InformationTheory\\Entropy;\n\n// Probability distributions\n$p = [0.2, 0.5, 0.3];\n$q = [0.1, 0.4, 0.5];\n\n// Shannon entropy\n$bits  = Entropy::shannonEntropy($p);         // log₂\n$nats  = Entropy::shannonNatEntropy($p);      // ln\n$harts = Entropy::shannonHartleyEntropy($p);  // log₁₀\n\n// Cross entropy\n$H⟮p、q⟯ = Entropy::crossEntropy($p, $q);       // log₂\n\n// Joint entropy\n$P⟮x、y⟯ = [1/2, 1/4, 1/4, 0];\nH⟮x、y⟯ = Entropy::jointEntropy($P⟮x、y⟯);        // log₂\n\n// Rényi entropy\n$α    = 0.5;\n$Hₐ⟮X⟯ = Entropy::renyiEntropy($p, $α);         // log₂\n\n// Perplexity\n$perplexity = Entropy::perplexity($p);         // log₂\n```\n\n### Linear Algebra - Matrix\n```php\nuse MathPHP\\LinearAlgebra\\Matrix;\nuse MathPHP\\LinearAlgebra\\MatrixFactory;\n\n// Create an m × n matrix from an array of arrays\n$matrix = [\n    [1, 2, 3],\n    [4, 5, 6],\n    [7, 8, 9],\n];\n$A = MatrixFactory::create($matrix);\n\n// Basic matrix data\n$array = $A-\u003egetMatrix();  // Original array of arrays\n$rows  = $A-\u003egetM();       // number of rows\n$cols  = $A-\u003egetN();       // number of columns\n\n// Basic matrix element getters (zero-based indexing)\n$row = $A-\u003egetRow(2);\n$col = $A-\u003egetColumn(2);\n$Aᵢⱼ = $A-\u003eget(2, 2);\n$Aᵢⱼ = $A[2][2];\n\n// Row operations\n[$mᵢ, $mⱼ, $k] = [1, 2, 5];\n$R = $A-\u003erowInterchange($mᵢ, $mⱼ);\n$R = $A-\u003erowExclude($mᵢ);             // Exclude row $mᵢ\n$R = $A-\u003erowMultiply($mᵢ, $k);        // Multiply row mᵢ by k\n$R = $A-\u003erowDivide($mᵢ, $k);          // Divide row mᵢ by k\n$R = $A-\u003erowAdd($mᵢ, $mⱼ, $k);        // Add k * row mᵢ to row mⱼ\n$R = $A-\u003erowAddScalar($mᵢ, $k);       // Add k to each item of row mᵢ\n$R = $A-\u003erowAddVector($mᵢ, $V);       // Add Vector V to row mᵢ\n$R = $A-\u003erowSubtract($mᵢ, $mⱼ, $k);   // Subtract k * row mᵢ from row mⱼ\n$R = $A-\u003erowSubtractScalar($mᵢ, $k);  // Subtract k from each item of row mᵢ\n\n// Column operations\n[$nᵢ, $nⱼ, $k] = [1, 2, 5];\n$R = $A-\u003ecolumnInterchange($nᵢ, $nⱼ);\n$R = $A-\u003ecolumnExclude($nᵢ);          // Exclude column $nᵢ\n$R = $A-\u003ecolumnMultiply($nᵢ, $k);     // Multiply column nᵢ by k\n$R = $A-\u003ecolumnAdd($nᵢ, $nⱼ, $k);     // Add k * column nᵢ to column nⱼ\n$R = $A-\u003ecolumnAddVector($nᵢ, $V);    // Add Vector V to column nᵢ\n\n// Matrix augmentations - return a new Matrix\n$⟮A∣B⟯ = $A-\u003eaugment($B);        // Augment on the right - standard augmentation\n$⟮A∣I⟯ = $A-\u003eaugmentIdentity();  // Augment with the identity matrix\n$⟮A∣B⟯ = $A-\u003eaugmentBelow($B);\n$⟮A∣B⟯ = $A-\u003eaugmentAbove($B);\n$⟮B∣A⟯ = $A-\u003eaugmentLeft($B);\n\n// Matrix arithmetic operations - return a new Matrix\n$A＋B = $A-\u003eadd($B);\n$A⊕B  = $A-\u003edirectSum($B);\n$A⊕B  = $A-\u003ekroneckerSum($B);\n$A−B  = $A-\u003esubtract($B);\n$AB   = $A-\u003emultiply($B);\n$２A  = $A-\u003escalarMultiply(2);\n$A／2 = $A-\u003escalarDivide(2);\n$−A   = $A-\u003enegate();\n$A∘B  = $A-\u003ehadamardProduct($B);\n$A⊗B  = $A-\u003ekroneckerProduct($B);\n\n// Matrix operations - return a new Matrix\n$Aᵀ 　 = $A-\u003etranspose();\n$D  　 = $A-\u003ediagonal();\n$A⁻¹   = $A-\u003einverse();\n$Mᵢⱼ   = $A-\u003eminorMatrix($mᵢ, $nⱼ);        // Square matrix with row mᵢ and column nⱼ removed\n$Mk    = $A-\u003eleadingPrincipalMinor($k);    // kᵗʰ-order leading principal minor\n$CM    = $A-\u003ecofactorMatrix();\n$B     = $A-\u003emeanDeviation();              // optional parameter to specify data direction (variables in 'rows' or 'columns')\n$S     = $A-\u003ecovarianceMatrix();           // optional parameter to specify data direction (variables in 'rows' or 'columns')\n$adj⟮A⟯ = $A-\u003eadjugate();\n$Mᵢⱼ   = $A-\u003esubmatrix($mᵢ, $nᵢ, $mⱼ, $nⱼ) // Submatrix of A from row mᵢ, column nᵢ to row mⱼ, column nⱼ\n$H     = $A-\u003ehouseholder();\n\n// Matrix value operations - return a value\n$tr⟮A⟯   = $A-\u003etrace();\n$|A|    = $a-\u003edet();              // Determinant\n$Mᵢⱼ    = $A-\u003eminor($mᵢ, $nⱼ);    // First minor\n$Cᵢⱼ    = $A-\u003ecofactor($mᵢ, $nⱼ);\n$rank⟮A⟯ = $A-\u003erank();\n\n// Matrix vector operations - return a new Vector\n$AB = $A-\u003evectorMultiply($X₁);\n$M  = $A-\u003erowSums();\n$M  = $A-\u003ecolumnSums();\n$M  = $A-\u003erowMeans();\n$M  = $A-\u003ecolumnMeans();\n\n// Matrix norms - return a value\n$‖A‖₁ = $A-\u003eoneNorm();\n$‖A‖F = $A-\u003efrobeniusNorm(); // Hilbert–Schmidt norm\n$‖A‖∞ = $A-\u003einfinityNorm();\n$max   = $A-\u003emaxNorm();\n\n// Matrix reductions\n$ref  = $A-\u003eref();   // Matrix in row echelon form\n$rref = $A-\u003erref();  // Matrix in reduced row echelon form\n\n// Matrix decompositions\n// LU decomposition\n$LU = $A-\u003eluDecomposition();\n$L  = $LU-\u003eL;  // lower triangular matrix\n$U  = $LU-\u003eU;  // upper triangular matrix\n$P  = $LU-P;   // permutation matrix\n\n// QR decomposition\n$QR = $A-\u003eqrDecomposition();\n$Q  = $QR-\u003eQ;  // orthogonal matrix\n$R  = $QR-\u003eR;  // upper triangular matrix\n\n// SVD (Singular Value Decomposition)\n$SVD = $A-\u003esvd();\n$U   = $A-\u003eU;  // m x m orthogonal matrix\n$V   = $A-\u003eV;  // n x n orthogonal matrix\n$S   = $A-\u003eS;  // m x n diagonal matrix of singular values\n$D   = $A-\u003eD;  // Vector of diagonal elements from S\n\n// Crout decomposition\n$LU = $A-\u003ecroutDecomposition();\n$L  = $LU-\u003eL;  // lower triangular matrix\n$U  = $LU-\u003eU;  // normalized upper triangular matrix\n\n// Cholesky decomposition\n$LLᵀ = $A-\u003echoleskyDecomposition();\n$L   = $LLᵀ-\u003eL;   // lower triangular matrix\n$LT  = $LLᵀ-\u003eLT;  // transpose of lower triangular matrix\n\n// Eigenvalues and eigenvectors\n$eigenvalues   = $A-\u003eeigenvalues();   // array of eigenvalues\n$eigenvecetors = $A-\u003eeigenvectors();  // Matrix of eigenvectors\n\n// Solve a linear system of equations: Ax = b\n$b = new Vector(1, 2, 3);\n$x = $A-\u003esolve($b);\n\n// Map a function over each element\n$func = function($x) {\n    return $x * 2;\n};\n$R = $A-\u003emap($func);  // using closure\n$R = $A-\u003emap('abs');  // using callable\n\n// Map a function over each row\n$array = $A-\u003emapRows('array_reverse');  // using callable returns matrix-like array of arrays\n$array = $A-\u003emapRows('array_sum');     // using callable returns array of aggregate calculations\n\n// Walk maps a function to all values without mutation or returning a value\n$A-\u003ewalk($func);\n\n// Matrix comparisons\n$bool = $A-\u003eisEqual($B);\n\n// Matrix properties - return a bool\n$bool = $A-\u003eisSquare();\n$bool = $A-\u003eisSymmetric();\n$bool = $A-\u003eisSkewSymmetric();\n$bool = $A-\u003eisSingular();\n$bool = $A-\u003eisNonsingular();           // Same as isInvertible\n$bool = $A-\u003eisInvertible();            // Same as isNonsingular\n$bool = $A-\u003eisPositiveDefinite();\n$bool = $A-\u003eisPositiveSemidefinite();\n$bool = $A-\u003eisNegativeDefinite();\n$bool = $A-\u003eisNegativeSemidefinite();\n$bool = $A-\u003eisLowerTriangular();\n$bool = $A-\u003eisUpperTriangular();\n$bool = $A-\u003eisTriangular();\n$bool = $A-\u003eisDiagonal();\n$bool = $A-\u003eisRectangularDiagonal();\n$bool = $A-\u003eisUpperBidiagonal();\n$bool = $A-\u003eisLowerBidiagonal();\n$bool = $A-\u003eisBidiagonal();\n$bool = $A-\u003eisTridiagonal();\n$bool = $A-\u003eisUpperHessenberg();\n$bool = $A-\u003eisLowerHessenberg();\n$bool = $A-\u003eisOrthogonal();\n$bool = $A-\u003eisNormal();\n$bool = $A-\u003eisIdempotent();\n$bool = $A-\u003eisNilpotent();\n$bool = $A-\u003eisInvolutory();\n$bool = $A-\u003eisSignature();\n$bool = $A-\u003eisRef();\n$bool = $A-\u003eisRref();\n\n// Other representations of matrix data\n$vectors = $A-\u003easVectors();                 // array of column vectors\n$D       = $A-\u003egetDiagonalElements();       // array of the diagonal elements\n$d       = $A-\u003egetSuperdiagonalElements();  // array of the superdiagonal elements\n$d       = $A-\u003egetSubdiagonalElements();    // array of the subdiagonal elements\n\n// String representation - Print a matrix\nprint($A);\n/*\n [1, 2, 3]\n [2, 3, 4]\n [3, 4, 5]\n */\n\n// PHP Predefined Interfaces\n$json = json_encode($A); // JsonSerializable\n$Aᵢⱼ  = $A[$mᵢ][$nⱼ];    // ArrayAccess\n```\n\n#### Linear Algebra - Matrix Construction (Factory)\n```php\n$matrix = [\n    [1, 2, 3],\n    [4, 5, 6],\n    [7, 8, 9],\n];\n\n// Matrix factory creates most appropriate matrix\n$A = MatrixFactory::create($matrix);\n\n// Matrix factory can create a matrix from an array of column vectors\nuse MathPHP\\LinearAlgebra\\Vector;\n$X₁ = new Vector([1, 4, 7]);\n$X₂ = new Vector([2, 5, 8]);\n$X₃ = new Vector([3, 6, 9]);\n$A  = MatrixFactory::createFromVectors([$X₁, $X₂, $X₃]);\n\n// Create from row or column vector\n$A = MatrixFactory::createFromRowVector([1, 2, 3]);    // 1 × n matrix consisting of a single row of n elements\n$A = MatrixFactory::createFromColumnVector([1, 2, 3]); // m × 1 matrix consisting of a single column of m elements\n\n// Specialized matrices\n[$m, $n, $k, $angle, $size]   = [4, 4, 2, 3.14159, 2];\n$identity_matrix              = MatrixFactory::identity($n);                   // Ones on the main diagonal\n$zero_matrix                  = MatrixFactory::zero($m, $n);                   // All zeros\n$ones_matrix                  = MatrixFactory::one($m, $n);                    // All ones\n$eye_matrix                   = MatrixFactory::eye($m, $n, $k);                // Ones (or other value) on the k-th diagonal\n$exchange_matrix              = MatrixFactory::exchange($n);                   // Ones on the reverse diagonal\n$downshift_permutation_matrix = MatrixFactory::downshiftPermutation($n);       // Permutation matrix that pushes the components of a vector down one notch with wraparound\n$upshift_permutation_matrix   = MatrixFactory::upshiftPermutation($n);         // Permutation matrix that pushes the components of a vector up one notch with wraparound\n$diagonal_matrix              = MatrixFactory::diagonal([1, 2, 3]);            // 3 x 3 diagonal matrix with zeros above and below the diagonal\n$hilbert_matrix               = MatrixFactory::hilbert($n);                    // Square matrix with entries being the unit fractions\n$vandermonde_matrix           = MatrixFactory::vandermonde([1, 2, 3], 4);      // 4 x 3 Vandermonde matrix\n$random_matrix                = MatrixFactory::random($m, $n);                 // m x n matrix of random integers\n$givens_matrix                = MatrixFactory::givens($m, $n, $angle, $size);  // givens rotation matrix\n```\n\n### Linear Algebra - Vector\n```php\nuse MathPHP\\LinearAlgebra\\Vector;\n\n// Vector\n$A = new Vector([1, 2]);\n$B = new Vector([2, 4]);\n\n// Basic vector data\n$array = $A-\u003egetVector();\n$n     = $A-\u003egetN();           // number of elements\n$M     = $A-\u003easColumnMatrix(); // Vector as an nx1 matrix\n$M     = $A-\u003easRowMatrix();    // Vector as a 1xn matrix\n\n// Basic vector elements (zero-based indexing)\n$item = $A-\u003eget(1);\n\n// Vector numeric operations - return a value\n$sum               = $A-\u003esum();\n$│A│               = $A-\u003elength();                            // same as l2Norm\n$max               = $A-\u003emax();\n$min               = $A-\u003emin();\n$A⋅B               = $A-\u003edotProduct($B);                      // same as innerProduct\n$A⋅B               = $A-\u003einnerProduct($B);                    // same as dotProduct\n$A⊥⋅B              = $A-\u003eperpDotProduct($B);\n$radAngle          = $A-\u003eangleBetween($B);                    // angle in radians\n$degAngle          = $A-\u003eangleBetween($B, $inDegrees = true); // angle in degrees\n$taxicabDistance   = $A-\u003el1Distance($B);                      // same as minkowskiDistance($B, 1)\n$euclidDistance    = $A-\u003el2Distance($B);                      // same as minkowskiDistance($B, 2)\n$minkowskiDistance = $A-\u003eminkowskiDistance($B, $p = 2);\n\n// Vector arithmetic operations - return a Vector\n$A＋B  = $A-\u003eadd($B);\n$A−B   = $A-\u003esubtract($B);\n$A×B   = $A-\u003emultiply($B);\n$A／B  = $A-\u003edivide($B);\n$kA    = $A-\u003escalarMultiply($k);\n$A／k  = $A-\u003escalarDivide($k);\n\n// Vector operations - return a Vector or Matrix\n$A⨂B  = $A-\u003eouterProduct($B);  // Same as direct product\n$AB    = $A-\u003edirectProduct($B); // Same as outer product\n$AxB   = $A-\u003ecrossProduct($B);\n$A⨂B   = $A-\u003ekroneckerProduct($B);\n$Â     = $A-\u003enormalize();\n$A⊥    = $A-\u003eperpendicular();\n$projᵇA = $A-\u003eprojection($B);   // projection of A onto B\n$perpᵇA = $A-\u003eperp($B);         // perpendicular of A on B\n\n// Vector norms - return a value\n$l₁norm = $A-\u003el1Norm();\n$l²norm = $A-\u003el2Norm();\n$pnorm  = $A-\u003epNorm();\n$max    = $A-\u003emaxNorm();\n\n// String representation\nprint($A);  // [1, 2]\n\n// PHP standard interfaces\n$n    = count($A);                // Countable\n$json = json_encode($A);          // JsonSerializable\n$Aᵢ   = $A[$i];                   // ArrayAccess\nforeach ($A as $element) { ... }  // Iterator\n```\n\n### Number - Arbitrary Length Integers\n```php\nuse MathPHP\\Number;\nuse MathPHP\\Functions;\n\n// Create arbitrary-length big integers from int or string\n$bigInt = new Number\\ArbitraryInteger('876937869482938749389832');\n\n// Unary functions\n$−bigInt  = $bigInt-\u003enegate();\n$√bigInt  = $bigInt-\u003eisqrt();       // Integer square root\n$│bitInt│ = $bigInt-\u003eabs();         // Absolute value\n$bigInt！  = $bigInt-\u003efact();\n$bool     = $bigInt-\u003eisPositive();\n\n// Binary functions\n$sum              = $bigInt-\u003eadd($bigInt);\n$difference       = $bigInt-\u003esubtract($bigInt);\n$product          = $bigInt-\u003emultiply($bigInt);\n$quotient         = $bigInt-\u003eintdiv($divisor);\n$mod              = $bigInt-\u003emod($divisor);\n[$quotient, $mod] = $bigInt-\u003efullIntdiv($divisor);\n$pow              = $bigInt-\u003epow($exponent);\n$shifted          = $bigInt-\u003eleftShift(2);\n\n// Comparison functions\n$bool = $bigInt-\u003eequals($bigInt);\n$bool = $bigInt-\u003egreaterThan($bigInt);\n$bool = $bigInt-\u003elessThan($bigInt);\n\n// Conversions\n$int    = $bigInt-\u003etoInt();\n$float  = $bigInt-\u003etoFloat();\n$binary = $bigInt-\u003etoBinary();\n$string = (string) $bigInt;\n\n// Functions\n$ackermann    = Functions\\ArbitraryInteger::ackermann($bigInt);\n$randomBigInt = Functions\\ArbitaryInteger::rand($intNumberOfBytes);\n```\n\n### Number - Complex Numbers\n```php\nuse MathPHP\\Number\\Complex;\n\n[$r, $i] = [2, 4];\n$complex = new Complex($r, $i);\n\n// Accessors\n$r = $complex-\u003er;\n$i = $complex-\u003ei;\n\n// Unary functions\n$conjugate = $complex-\u003ecomplexConjugate();\n$│c│       = $complex-\u003eabs();     // absolute value (modulus)\n$arg⟮c⟯     = $complex-\u003earg();     // argument (phase)\n$√c        = $complex-\u003esqrt();    // positive square root\n[$z₁, $z₂] = $complex-\u003eroots();\n$c⁻¹       = $complex-\u003einverse();\n$−c        = $complex-\u003enegate();\n[$r, $θ]   = $complex-\u003epolarForm();\n\n// Binary functions\n$c＋c = $complex-\u003eadd($complex);\n$c−c  = $complex-\u003esubtract($complex);\n$c×c  = $complex-\u003emultiply($complex);\n$c／c = $complex-\u003edivide($complex);\n\n// Other functions\n$bool   = $complex-\u003eequals($complex);\n$string = (string) $complex;\n```\n\n### Number - Quaternion\n```php\nUse MathPHP\\Number\\Quaternion;\n\n$r = 4;\n$i = 1;\n$j = 2;\n$k = 3;\n\n$quaternion = new Quaternion($r, $i, $j, $k);\n\n// Get individual parts\n[$r, $i, $j, $k] = [$quaternion-\u003er, $quaternion-\u003ei, $quaternion-\u003ej, $quaternion-\u003ek];\n\n// Unary functions\n$conjugate    = $quaternion-\u003ecomplexConjugate();\n$│q│          = $quaternion-\u003eabs();  // absolute value (magnitude)\n$quaternion⁻¹ = $quaternion-\u003einverse();\n$−q           = $quaternion-\u003enegate();\n\n// Binary functions\n$q＋q = $quaternion-\u003eadd($quaternion);\n$q−q  = $quaternion-\u003esubtract($quaternion);\n$q×q  = $quaternion-\u003emultiply($quaternion);\n$q／q = $quaternion-\u003edivide($quaternion);\n\n// Other functions\n$bool = $quaternion-\u003eequals($quaternion);\n```\n\n### Number - Rational Numbers\n```php\nuse MathPHP\\Number\\Rational;\n\n$whole       = 0;\n$numerator   = 2;\n$denominator = 3;\n\n$rational = new Rational($whole, $numerator, $denominator);  // ²/₃\n\n// Get individual parts\n$whole       = $rational-\u003egetWholePart();\n$numerator   = $rational-\u003egetNumerator();\n$denominator = $rational-\u003egetDenominator();\n\n// Unary functions\n$│rational│ = $rational-\u003eabs();\n$inverse    = $rational-\u003einverse();\n\n// Binary functions\n$sum            = $rational-\u003eadd($rational);\n$diff           = $rational-\u003esubtract($rational);\n$product        = $rational-\u003emultiply($rational);\n$quotient       = $rational-\u003edivide($rational);\n$exponentiation = $rational-\u003epow(2);\n\n// Other functions\n$bool   = $rational-\u003eequals($rational);\n$float  = $rational-\u003etoFloat();\n$string = (string) $rational;\n```\n\n### Number Theory - Integers\n```php\nuse MathPHP\\NumberTheory\\Integer;\n\n$n = 225;\n\n// Prime numbers\n$bool    = Integer::isPrime($n);\n$factors = Integer::primeFactorization($n);\n\n// Divisor function\n$int  = Integer::numberOfDivisors($n);\n$int  = Integer::sumOfDivisors($n);\n\n// Aliquot sums\n$int  = Integer::aliquotSum($n);        // sum-of-divisors - n\n$bool = Integer::isPerfectNumber($n);   // n = aliquot sum\n$bool = Integer::isDeficientNumber($n); // n \u003e aliquot sum\n$bool = Integer::isAbundantNumber($n);  // n \u003c aliquot sum\n\n// Totients\n$int  = Integer::totient($n);        // Jordan's totient k=1 (Euler's totient)\n$int  = Integer::totient($n, 2);     // Jordan's totient k=2\n$int  = Integer::cototient($n);      // Cototient\n$int  = Integer::reducedTotient($n); // Carmichael's function\n\n// Möbius function\n$int  = Integer::mobius($n);\n\n// Radical/squarefree kernel\n$int  = Integer::radical($n);\n\n// Squarefree\n$bool = Integer::isSquarefree($n);\n\n// Refactorable number\n$bool = Integer::isRefactorableNumber($n);\n\n// Sphenic number\n$bool = Integer::isSphenicNumber($n);\n\n// Perfect powers\n$bool    = Integer::isPerfectPower($n);\n[$m, $k] = Integer::perfectPower($n);\n\n// Coprime\n$bool = Integer::coprime(4, 35);\n\n// Even and odd\n$bool = Integer::isEven($n);\n$bool = Integer::isOdd($n);\n```\n\n### Numerical Analysis - Interpolation\n```php\nuse MathPHP\\NumericalAnalysis\\Interpolation;\n\n// Interpolation is a method of constructing new data points with the range\n// of a discrete set of known data points.\n// Each integration method can take input in two ways:\n//  1) As a set of points (inputs and outputs of a function)\n//  2) As a callback function, and the number of function evaluations to\n//     perform on an interval between a start and end point.\n\n// Input as a set of points\n$points = [[0, 1], [1, 4], [2, 9], [3, 16]];\n\n// Input as a callback function\n$f⟮x⟯ = function ($x) {\n    return $x**2 + 2 * $x + 1;\n};\n[$start, $end, $n] = [0, 3, 4];\n\n// Lagrange Polynomial\n// Returns a function p(x) of x\n$p = Interpolation\\LagrangePolynomial::interpolate($points);                // input as a set of points\n$p = Interpolation\\LagrangePolynomial::interpolate($f⟮x⟯, $start, $end, $n); // input as a callback function\n\n$p(0) // 1\n$p(3) // 16\n\n// Nevilles Method\n// More accurate than Lagrange Polynomial Interpolation given the same input\n// Returns the evaluation of the interpolating polynomial at the $target point\n$target = 2;\n$result = Interpolation\\NevillesMethod::interpolate($target, $points);                // input as a set of points\n$result = Interpolation\\NevillesMethod::interpolate($target, $f⟮x⟯, $start, $end, $n); // input as a callback function\n\n// Newton Polynomial (Forward)\n// Returns a function p(x) of x\n$p = Interpolation\\NewtonPolynomialForward::interpolate($points);                // input as a set of points\n$p = Interpolation\\NewtonPolynomialForward::interpolate($f⟮x⟯, $start, $end, $n); // input as a callback function\n\n$p(0) // 1\n$p(3) // 16\n\n// Natural Cubic Spline\n// Returns a piecewise polynomial p(x)\n$p = Interpolation\\NaturalCubicSpline::interpolate($points);                // input as a set of points\n$p = Interpolation\\NaturalCubicSpline::interpolate($f⟮x⟯, $start, $end, $n); // input as a callback function\n\n$p(0) // 1\n$p(3) // 16\n\n// Clamped Cubic Spline\n// Returns a piecewise polynomial p(x)\n\n// Input as a set of points\n$points = [[0, 1, 0], [1, 4, -1], [2, 9, 4], [3, 16, 0]];\n\n// Input as a callback function\n$f⟮x⟯ = function ($x) {\n    return $x**2 + 2 * $x + 1;\n};\n$f’⟮x⟯ = function ($x) {\n    return 2*$x + 2;\n};\n[$start, $end, $n] = [0, 3, 4];\n\n$p = Interpolation\\ClampedCubicSpline::interpolate($points);                       // input as a set of points\n$p = Interpolation\\ClampedCubicSpline::interpolate($f⟮x⟯, $f’⟮x⟯, $start, $end, $n); // input as a callback function\n\n$p(0); // 1\n$p(3); // 16\n\n// Regular Grid Interpolation\n// Returns a scalar\n\n// Points defining the regular grid\n$xs = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];\n$ys = [10, 11, 12, 13, 14, 15, 16, 17, 18, 19];\n$zs = [110, 111, 112, 113, 114, 115, 116, 117, 118, 119];\n\n// Data on the regular grid in n dimensions\n$data = [];\n$func = function ($x, $y, $z) {\n    return 2 * $x + 3 * $y - $z;\n};\nforeach ($xs as $i =\u003e $x) {\n    foreach ($ys as $j =\u003e $y) {\n        foreach ($zs as $k =\u003e $z) {\n            $data[$i][$j][$k] = $func($x, $y, $z);\n        }\n    }\n}\n\n// Constructing a RegularGridInterpolator\n$rgi = new Interpolation\\RegularGridInterpolator([$xs, $ys, $zs], $data, 'linear');  // 'nearest' method also available\n\n// Interpolating coordinates on the regular grid\n$coordinates   = [2.21, 12.1, 115.9];\n$interpolation = $rgi($coordinates);  // -75.18\n```\n\n### Numerical Analysis - Numerical Differentiation\n```php\nuse MathPHP\\NumericalAnalysis\\NumericalDifferentiation;\n\n// Numerical Differentiation approximates the derivative of a function.\n// Each Differentiation method can take input in two ways:\n//  1) As a set of points (inputs and outputs of a function)\n//  2) As a callback function, and the number of function evaluations to\n//     perform on an interval between a start and end point.\n\n// Input as a callback function\n$f⟮x⟯ = function ($x) {\n    return $x**2 + 2 * $x + 1;\n};\n\n// Three Point Formula\n// Returns an approximation for the derivative of our input at our target\n\n// Input as a set of points\n$points = [[0, 1], [1, 4], [2, 9]];\n\n$target = 0;\n[$start, $end, $n] = [0, 2, 3];\n$derivative = NumericalDifferentiation\\ThreePointFormula::differentiate($target, $points);                // input as a set of points\n$derivative = NumericalDifferentiation\\ThreePointFormula::differentiate($target, $f⟮x⟯, $start, $end, $n); // input as a callback function\n\n// Five Point Formula\n// Returns an approximation for the derivative of our input at our target\n\n// Input as a set of points\n$points = [[0, 1], [1, 4], [2, 9], [3, 16], [4, 25]];\n\n$target = 0;\n[$start, $end, $n] = [0, 4, 5];\n$derivative = NumericalDifferentiation\\FivePointFormula::differentiate($target, $points);                // input as a set of points\n$derivative = NumericalDifferentiation\\FivePointFormula::differentiate($target, $f⟮x⟯, $start, $end, $n); // input as a callback function\n\n// Second Derivative Midpoint Formula\n// Returns an approximation for the second derivative of our input at our target\n\n// Input as a set of points\n$points = [[0, 1], [1, 4], [2, 9];\n\n$target = 1;\n[$start, $end, $n] = [0, 2, 3];\n$derivative = NumericalDifferentiation\\SecondDerivativeMidpointFormula::differentiate($target, $points);                // input as a set of points\n$derivative = NumericalDifferentiation\\SecondDerivativeMidpointFormula::differentiate($target, $f⟮x⟯, $start, $end, $n); // input as a callback function\n```\n\n### Numerical Analysis - Numerical Integration\n```php\nuse MathPHP\\NumericalAnalysis\\NumericalIntegration;\n\n// Numerical integration approximates the definite integral of a function.\n// Each integration method can take input in two ways:\n//  1) As a set of points (inputs and outputs of a function)\n//  2) As a callback function, and the number of function evaluations to\n//     perform on an interval between a start and end point.\n\n// Trapezoidal Rule (closed Newton-Cotes formula)\n$points = [[0, 1], [1, 4], [2, 9], [3, 16]];\n$∫f⟮x⟯dx = NumericalIntegration\\TrapezoidalRule::approximate($points); // input as a set of points\n\n$f⟮x⟯ = function ($x) {\n    return $x**2 + 2 * $x + 1;\n};\n[$start, $end, $n] = [0, 3, 4];\n$∫f⟮x⟯dx = NumericalIntegration\\TrapezoidalRule::approximate($f⟮x⟯, $start, $end, $n); // input as a callback function\n\n// Simpsons Rule (closed Newton-Cotes formula)\n$points = [[0, 1], [1, 4], [2, 9], [3, 16], [4,3]];\n$∫f⟮x⟯dx = NumericalIntegration\\SimpsonsRule::approximate($points); // input as a set of points\n\n$f⟮x⟯ = function ($x) {\n    return $x**2 + 2 * $x + 1;\n};\n[$start, $end, $n] = [0, 3, 5];\n$∫f⟮x⟯dx = NumericalIntegration\\SimpsonsRule::approximate($f⟮x⟯, $start, $end, $n); // input as a callback function\n\n// Simpsons 3/8 Rule (closed Newton-Cotes formula)\n$points = [[0, 1], [1, 4], [2, 9], [3, 16]];\n$∫f⟮x⟯dx = NumericalIntegration\\SimpsonsThreeEighthsRule::approximate($points); // input as a set of points\n\n$f⟮x⟯ = function ($x) {\n    return $x**2 + 2 * $x + 1;\n};\n[$start, $end, $n] = [0, 3, 5];\n$∫f⟮x⟯dx = NumericalIntegration\\SimpsonsThreeEighthsRule::approximate($f⟮x⟯, $start, $end, $n); // input as a callback function\n\n// Booles Rule (closed Newton-Cotes formula)\n$points = [[0, 1], [1, 4], [2, 9], [3, 16], [4, 25]];\n$∫f⟮x⟯dx = NumericalIntegration\\BoolesRule::approximate($points); // input as a set of points\n\n$f⟮x⟯ = function ($x) {\n    return $x**3 + 2 * $x + 1;\n};\n[$start, $end, $n] = [0, 4, 5];\n$∫f⟮x⟯dx = NumericalIntegration\\BoolesRuleRule::approximate($f⟮x⟯, $start, $end, $n); // input as a callback function\n\n// Rectangle Method (open Newton-Cotes formula)\n$points = [[0, 1], [1, 4], [2, 9], [3, 16]];\n$∫f⟮x⟯dx = NumericalIntegration\\RectangleMethod::approximate($points); // input as a set of points\n\n$f⟮x⟯ = function ($x) {\n    return $x**2 + 2 * $x + 1;\n};\n[$start, $end, $n] = [0, 3, 4];\n$∫f⟮x⟯dx = NumericalIntegration\\RectangleMethod::approximate($f⟮x⟯, $start, $end, $n); // input as a callback function\n\n// Midpoint Rule (open Newton-Cotes formula)\n$points = [[0, 1], [1, 4], [2, 9], [3, 16]];\n$∫f⟮x⟯dx = NumericalIntegration\\MidpointRule::approximate($points); // input as a set of points\n\n$f⟮x⟯ = function ($x) {\n    return $x**2 + 2 * $x + 1;\n};\n[$start, $end, $n] = [0, 3, 4];\n$∫f⟮x⟯dx = NumericalIntegration\\MidpointRule::approximate($f⟮x⟯, $start, $end, $n); // input as a callback function\n```\n\n### Numerical Analysis - Root Finding\n```php\nuse MathPHP\\NumericalAnalysis\\RootFinding;\n\n// Root-finding methods solve for a root of a polynomial.\n\n// f(x) = x⁴ + 8x³ -13x² -92x + 96\n$f⟮x⟯ = function($x) {\n    return $x**4 + 8 * $x**3 - 13 * $x**2 - 92 * $x + 96;\n};\n\n// Newton's Method\n$args     = [-4.1];  // Parameters to pass to callback function (initial guess, other parameters)\n$target   = 0;       // Value of f(x) we a trying to solve for\n$tol      = 0.00001; // Tolerance; how close to the actual solution we would like\n$position = 0;       // Which element in the $args array will be changed; also serves as initial guess. Defaults to 0.\n$x        = RootFinding\\NewtonsMethod::solve($f⟮x⟯, $args, $target, $tol, $position); // Solve for x where f(x) = $target\n\n// Secant Method\n$p₀  = -1;      // First initial approximation\n$p₁  = 2;       // Second initial approximation\n$tol = 0.00001; // Tolerance; how close to the actual solution we would like\n$x   = RootFinding\\SecantMethod::solve($f⟮x⟯, $p₀, $p₁, $tol); // Solve for x where f(x) = 0\n\n// Bisection Method\n$a   = 2;       // The start of the interval which contains a root\n$b   = 5;       // The end of the interval which contains a root\n$tol = 0.00001; // Tolerance; how close to the actual solution we would like\n$x   = RootFinding\\BisectionMethod::solve($f⟮x⟯, $a, $b, $tol); // Solve for x where f(x) = 0\n\n// Fixed-Point Iteration\n// f(x) = x⁴ + 8x³ -13x² -92x + 96\n// Rewrite f(x) = 0 as (x⁴ + 8x³ -13x² + 96)/92 = x\n// Thus, g(x) = (x⁴ + 8x³ -13x² + 96)/92\n$g⟮x⟯ = function($x) {\n    return ($x**4 + 8 * $x**3 - 13 * $x**2 + 96)/92;\n};\n$a   = 0;       // The start of the interval which contains a root\n$b   = 2;       // The end of the interval which contains a root\n$p   = 0;       // The initial guess for our root\n$tol = 0.00001; // Tolerance; how close to the actual solution we would like\n$x   = RootFinding\\FixedPointIteration::solve($g⟮x⟯, $a, $b, $p, $tol); // Solve for x where f(x) = 0\n```\n\n### Probability - Combinatorics\n```php\nuse MathPHP\\Probability\\Combinatorics;\n\n[$n, $x, $k] = [10, 3, 4];\n\n// Factorials\n$n！  = Combinatorics::factorial($n);\n$n‼︎   = Combinatorics::doubleFactorial($n);\n$x⁽ⁿ⁾ = Combinatorics::risingFactorial($x, $n);\n$x₍ᵢ₎ = Combinatorics::fallingFactorial($x, $n);\n$！n  = Combinatorics::subfactorial($n);\n\n// Permutations\n$nPn = Combinatorics::permutations($n);     // Permutations of n things, taken n at a time (same as factorial)\n$nPk = Combinatorics::permutations($n, $k); // Permutations of n things, taking only k of them\n\n// Combinations\n$nCk  = Combinatorics::combinations($n, $k);                            // n choose k without repetition\n$nC′k = Combinatorics::combinations($n, $k, Combinatorics::REPETITION); // n choose k with repetition (REPETITION const = true)\n\n// Central binomial coefficient\n$cbc = Combinatorics::centralBinomialCoefficient($n);\n\n// Catalan number\n$Cn = Combinatorics::catalanNumber($n);\n\n// Lah number\n$L⟮n、k⟯ = Combinatorics::lahNumber($n, $k)\n\n// Multinomial coefficient\n$groups    = [5, 2, 3];\n$divisions = Combinatorics::multinomial($groups);\n```\n\n### Probability - Continuous Distributions\n```php\nuse MathPHP\\Probability\\Distribution\\Continuous;\n\n$p = 0.1;\n\n// Beta distribution\n$α      = 1; // shape parameter\n$β      = 1; // shape parameter\n$x      = 2;\n$beta   = new Continuous\\Beta($α, $β);\n$pdf    = $beta-\u003epdf($x);\n$cdf    = $beta-\u003ecdf($x);\n$icdf   = $beta-\u003einverse($p);\n$μ      = $beta-\u003emean();\n$median = $beta-\u003emedian();\n$mode   = $beta-\u003emode();\n$σ²     = $beta-\u003evariance();\n\n// Cauchy distribution\n$x₀     = 2; // location parameter\n$γ      = 3; // scale parameter\n$x      = 1;\n$cauchy = new Continuous\\Cauchy(x₀, γ);\n$pdf    = $cauchy-\u003epdf(x);\n$cdf    = $cauchy-\u003ecdf(x);\n$icdf   = $cauchy-\u003einverse($p);\n$μ      = $cauchy-\u003emean();\n$median = $cauchy-\u003emedian();\n$mode   = $cauchy-\u003emode();\n\n// χ²-distribution (Chi-Squared)\n$k      = 2; // degrees of freedom\n$x      = 1;\n$χ²     = new Continuous\\ChiSquared($k);\n$pdf    = $χ²-\u003epdf($x);\n$cdf    = $χ²-\u003ecdf($x);\n$μ      = $χ²-\u003emean($x);\n$median = $χ²-\u003emedian();\n$mode   = $χ²-\u003emode();\n$σ²     = $χ²-\u003evariance();\n\n// Dirac delta distribution\n$x     = 1;\n$dirac = new Continuous\\DiracDelta();\n$pdf   = $dirac-\u003epdf($x);\n$cdf   = $dirac-\u003ecdf($x);\n$icdf  = $dirac-\u003einverse($p);\n$μ     = $dirac-\u003emean();\n\n// Exponential distribution\n$λ           = 1; // rate parameter\n$x           = 2;\n$exponential = new Continuous\\Exponential($λ);\n$pdf         = $exponential-\u003epdf($x);\n$cdf         = $exponential-\u003ecdf($x);\n$icdf        = $exponential-\u003einverse($p);\n$μ           = $exponential-\u003emean();\n$median      = $exponential-\u003emedian();\n$σ²          = $exponential-\u003evariance();\n\n// F-distribution\n$d₁   = 3; // degree of freedom v1\n$d₂   = 4; // degree of freedom v2\n$x    = 2;\n$f    = new Continuous\\F($d₁, $d₂);\n$pdf  = $f-\u003epdf($x);\n$cdf  = $f-\u003ecdf($x);\n$μ    = $f-\u003emean();\n$mode = $f-\u003emode();\n$σ²   = $f-\u003evariance();\n\n// Gamma distribution\n$k      = 2; // shape parameter\n$θ      = 3; // scale parameter\n$x      = 4;\n$gamma  = new Continuous\\Gamma($k, $θ);\n$pdf    = $gamma-\u003epdf($x);\n$cdf    = $gamma-\u003ecdf($x);\n$μ      = $gamma-\u003emean();\n$median = $gamma-\u003emedian();\n$mode   = $gamma-\u003emode();\n$σ²     = $gamma-\u003evariance();\n\n// Laplace distribution\n$μ       = 1;   // location parameter\n$b       = 1.5; // scale parameter (diversity)\n$x       = 1;\n$laplace = new Continuous\\Laplace($μ, $b);\n$pdf     = $laplace-\u003epdf($x);\n$cdf     = $laplace-\u003ecdf($x);\n$icdf    = $laplace-\u003einverse($p);\n$μ       = $laplace-\u003emean();\n$median  = $laplace-\u003emedian();\n$mode    = $laplace-\u003emode();\n$σ²      = $laplace-\u003evariance();\n\n// Logistic distribution\n$μ        = 2;   // location parameter\n$s        = 1.5; // scale parameter\n$x        = 3;\n$logistic = new Continuous\\Logistic($μ, $s);\n$pdf      = $logistic-\u003epdf($x);\n$cdf      = $logistic-\u003ecdf($x);\n$icdf     = $logistic-\u003einverse($p);\n$μ        = $logistic-\u003emean();\n$median   = $logistic-\u003emedian();\n$mode     = $logistic-\u003emode();\n$σ²       = $logisitic-\u003evariance();\n\n// Log-logistic distribution (Fisk distribution)\n$α           = 1; // scale parameter\n$β           = 1; // shape parameter\n$x           = 2;\n$logLogistic = new Continuous\\LogLogistic($α, $β);\n$pdf         = $logLogistic-\u003epdf($x);\n$cdf         = $logLogistic-\u003ecdf($x);\n$icdf        = $logLogistic-\u003einverse($p);\n$μ           = $logLogistic-\u003emean();\n$median      = $logLogistic-\u003emedian();\n$mode        = $logLogistic-\u003emode();\n$σ²          = $logLogistic-\u003evariance();\n\n// Log-normal distribution\n$μ         = 6;   // scale parameter\n$σ         = 2;   // location parameter\n$x         = 4.3;\n$logNormal = new Continuous\\LogNormal($μ, $σ);\n$pdf       = $logNormal-\u003epdf($x);\n$cdf       = $logNormal-\u003ecdf($x);\n$icdf      = $logNormal-\u003einverse($p);\n$μ         = $logNormal-\u003emean();\n$median    = $logNormal-\u003emedian();\n$mode      = $logNormal-\u003emode();\n$σ²        = $logNormal-\u003evariance();\n\n// Noncentral T distribution\n$ν            = 50; // degrees of freedom\n$μ            = 10; // noncentrality parameter\n$x            = 8;\n$noncenetralT = new Continuous\\NoncentralT($ν, $μ);\n$pdf          = $noncenetralT-\u003epdf($x);\n$cdf          = $noncenetralT-\u003ecdf($x);\n$μ            = $noncenetralT-\u003emean();\n\n// Normal distribution\n$σ      = 1;\n$μ      = 0;\n$x      = 2;\n$normal = new Continuous\\Normal($μ, $σ);\n$pdf    = $normal-\u003epdf($x);\n$cdf    = $normal-\u003ecdf($x);\n$icdf   = $normal-\u003einverse($p);\n$μ      = $normal-\u003emean();\n$median = $normal-\u003emedian();\n$mode   = $normal-\u003emode();\n$σ²     = $normal-\u003evariance();\n\n// Pareto distribution\n$a      = 1; // shape parameter\n$b      = 1; // scale parameter\n$x      = 2;\n$pareto = new Continuous\\Pareto($a, $b);\n$pdf    = $pareto-\u003epdf($x);\n$cdf    = $pareto-\u003ecdf($x);\n$icdf   = $pareto-\u003einverse($p);\n$μ      = $pareto-\u003emean();\n$median = $pareto-\u003emedian();\n$mode   = $pareto-\u003emode();\n$σ²     = $pareto-\u003evariance();\n\n// Standard normal distribution\n$z              = 2;\n$standardNormal = new Continuous\\StandardNormal();\n$pdf            = $standardNormal-\u003epdf($z);\n$cdf            = $standardNormal-\u003ecdf($z);\n$icdf           = $standardNormal-\u003einverse($p);\n$μ              = $standardNormal-\u003emean();\n$median         = $standardNormal-\u003emedian();\n$mode           = $standardNormal-\u003emode();\n$σ²             = $standardNormal-\u003evariance();\n\n// Student's t-distribution\n$ν        = 3;   // degrees of freedom\n$p        = 0.4; // proportion of area\n$x        = 2;\n$studentT = new Continuous\\StudentT::pdf($ν);\n$pdf      = $studentT-\u003epdf($x);\n$cdf      = $studentT-\u003ecdf($x);\n$t        = $studentT-\u003einverse2Tails($p);  // t such that the area greater than t and the area beneath -t is p\n$μ        = $studentT-\u003emean();\n$median   = $studentT-\u003emedian();\n$mode     = $studentT-\u003emode();\n$σ²       = $studentT-\u003evariance();\n\n// Uniform distribution\n$a       = 1; // lower boundary of the distribution\n$b       = 4; // upper boundary of the distribution\n$x       = 2;\n$uniform = new Continuous\\Uniform($a, $b);\n$pdf     = $uniform-\u003epdf($x);\n$cdf     = $uniform-\u003ecdf($x);\n$μ       = $uniform-\u003emean();\n$median  = $uniform-\u003emedian();\n$mode    = $uniform-\u003emode();\n$σ²      = $uniform-\u003evariance();\n\n// Weibull distribution\n$k       = 1; // shape parameter\n$λ       = 2; // scale parameter\n$x       = 2;\n$weibull = new Continuous\\Weibull($k, $λ);\n$pdf     = $weibull-\u003epdf($x);\n$cdf     = $weibull-\u003ecdf($x);\n$icdf    = $weibull-\u003einverse($p);\n$μ       = $weibull-\u003emean();\n$median  = $weibull-\u003emedian();\n$mode    = $weibull-\u003emode();\n\n// Other CDFs - All continuous distributions - Replace {$distribution} with desired distribution.\n$between = $distribution-\u003ebetween($x₁, $x₂);  // Probability of being between two points, x₁ and x₂\n$outside = $distribution-\u003eoutside($x₁, $x);   // Probability of being between below x₁ and above x₂\n$above   = $distribution-\u003eabove($x);          // Probability of being above x to ∞\n\n// Random Number Generator\n$random  = $distribution-\u003erand();  // A random number with a given distribution\n```\n\n### Probability - Discrete Distributions\n```php\nuse MathPHP\\Probability\\Distribution\\Discrete;\n\n// Bernoulli distribution (special case of binomial where n = 1)\n$p         = 0.3;\n$k         = 0;\n$bernoulli = new Discrete\\Bernoulli($p);\n$pmf       = $bernoulli-\u003epmf($k);\n$cdf       = $bernoulli-\u003ecdf($k);\n$μ         = $bernoulli-\u003emean();\n$median    = $bernoulli-\u003emedian();\n$mode      = $bernoulli-\u003emode();\n$σ²        = $bernoulli-\u003evariance();\n\n// Binomial distribution\n$n        = 2;   // number of events\n$p        = 0.5; // probability of success\n$r        = 1;   // number of successful events\n$binomial = new Discrete\\Binomial($n, $p);\n$pmf      = $binomial-\u003epmf($r);\n$cdf      = $binomial-\u003ecdf($r);\n$μ        = $binomial-\u003emean();\n$σ²       = $binomial-\u003evariance();\n\n// Categorical distribution\n$k             = 3;                                    // number of categories\n$probabilities = ['a' =\u003e 0.3, 'b' =\u003e 0.2, 'c' =\u003e 0.5]; // probabilities for categorices a, b, and c\n$categorical   = new Discrete\\Categorical($k, $probabilities);\n$pmf_a         = $categorical-\u003epmf('a');\n$mode          = $categorical-\u003emode();\n\n// Geometric distribution (failures before the first success)\n$p         = 0.5; // success probability\n$k         = 2;   // number of trials\n$geometric = new Discrete\\Geometric($p);\n$pmf       = $geometric-\u003epmf($k);\n$cdf       = $geometric-\u003ecdf($k);\n$μ         = $geometric-\u003emean();\n$median    = $geometric-\u003emedian();\n$mode      = $geometric-\u003emode();\n$σ²        = $geometric-\u003evariance();\n\n// Hypergeometric distribution\n$N        = 50; // population size\n$K        = 5;  // number of success states in the population\n$n        = 10; // number of draws\n$k        = 4;  // number of observed successes\n$hypergeo = new Discrete\\Hypergeometric($N, $K, $n);\n$pmf      = $hypergeo-\u003epmf($k);\n$cdf      = $hypergeo-\u003ecdf($k);\n$μ        = $hypergeo-\u003emean();\n$mode     = $hypergeo-\u003emode();\n$σ²       = $hypergeo-\u003evariance();\n\n// Negative binomial distribution (Pascal)\n$r                = 1;   // number of failures until the experiment is stopped\n$P                = 0.5; // probability of success on an individual trial\n$x                = 2;   // number of successes\n$negativeBinomial = new Discrete\\NegativeBinomial($r, $p);\n$pmf              = $negativeBinomial-\u003epmf($x);\n$cdf              = $negativeBinomial-\u003ecdf($x);\n$μ                = $negativeBinomial-\u003emean();\n$mode             = $negativeBinomial-\u003emode();\n$σ²               = $negativeBinomial-\u003evariance();\n\n// Pascal distribution (Negative binomial)\n$r      = 1;   // number of failures until the experiment is stopped\n$P      = 0.5; // probability of success on an individual trial\n$x      = 2;   // number of successes\n$pascal = new Discrete\\Pascal($r, $p);\n$pmf    = $pascal-\u003epmf($x);\n$cdf    = $pascal-\u003ecdf($x);\n$μ      = $pascal-\u003emean();\n$mode   = $pascal-\u003emode();\n$σ²     = $pascal-\u003evariance();\n\n// Poisson distribution\n$λ       = 2; // average number of successful events per interval\n$k       = 3; // events in the interval\n$poisson = new Discrete\\Poisson($λ);\n$pmf     = $poisson-\u003epmf($k);\n$cdf     = $poisson-\u003ecdf($k);\n$μ       = $poisson-\u003emean();\n$median  = $poisson-\u003emedian();\n$mode    = $poisson-\u003emode();\n$σ²      = $poisson-\u003evariance();\n\n// Shifted geometric distribution (probability to get one success)\n$p                = 0.5; // success probability\n$k                = 2;   // number of trials\n$shiftedGeometric = new Discrete\\ShiftedGeometric($p);\n$pmf              = $shiftedGeometric-\u003epmf($k);\n$cdf              = $shiftedGeometric-\u003ecdf($k);\n$μ                = $shiftedGeometric-\u003emean();\n$median           = $shiftedGeometric-\u003emedian();\n$mode             = $shiftedGeometric-\u003emode();\n$σ²               = $shiftedGeometric-\u003evariance();\n\n// Uniform distribution\n$a       = 1; // lower boundary of the distribution\n$b       = 4; // upper boundary of the distribution\n$k       = 2; // percentile\n$uniform = new Discrete\\Uniform($a, $b);\n$pmf     = $uniform-\u003epmf();\n$cdf     = $uniform-\u003ecdf($k);\n$μ       = $uniform-\u003emean();\n$median  = $uniform-\u003emedian();\n$σ²      = $uniform-\u003evariance();\n\n// Zipf distribution\n$k    = 2;   // rank\n$s    = 3;   // exponent\n$N    = 10;  // number of elements\n$zipf = new Discrete\\Zipf($s, $N);\n$pmf  = $zipf-\u003epmf($k);\n$cdf  = $zipf-\u003ecdf($k);\n$μ    = $zipf-\u003emean();\n$mode = $zipf-\u003emode();\n```\n\n### Probability - Multivariate Distributions\n```php\nuse MathPHP\\Probability\\Distribution\\Multivariate;\n\n// Dirichlet distribution\n$αs        = [1, 2, 3];\n$xs        = [0.07255081, 0.27811903, 0.64933016];\n$dirichlet = new Multivariate\\Dirichlet($αs);\n$pdf       = $dirichlet-\u003epdf($xs);\n\n// Normal distribution\n$μ      = [1, 1.1];\n$∑      = MatrixFactory::create([\n    [1, 0],\n    [0, 1],\n]);\n$X      = [0.7, 1.4];\n$normal = new Multivariate\\Normal($μ, $∑);\n$pdf    = $normal-\u003epdf($X);\n\n// Hypergeometric distribution\n$quantities   = [5, 10, 15];   // Suppose there are 5 black, 10 white, and 15 red marbles in an urn.\n$choices      = [2, 2, 2];     // If six marbles are chosen without replacement, the probability that exactly two of each color are chosen is:\n$distribution = new Multivariate\\Hypergeometric($quantities);\n$probability  = $distribution-\u003epmf($choices);    // 0.0795756\n\n// Multinomial distribution\n$frequencies   = [7, 2, 3];\n$probabilities = [0.40, 0.35, 0.25];\n$multinomial   = new Multivariate\\Multinomial($probabilities);\n$pmf           = $multinomial-\u003epmf($frequencies);\n```\n\n### Probability - Distribution Tables\n```php\nuse MathPHP\\Probability\\Distribution\\Table;\n\n// Provided solely for completeness' sake.\n// It is statistics tradition to provide these tables.\n// MathPHP has dynamic distribution CDF functions you can use instead.\n\n// Standard Normal Table (Z Table)\n$table       = Table\\StandardNormal::Z_SCORES;\n$probability = $table[1.5][0];                 // Value for Z of 1.50\n\n// t Distribution Tables\n$table   = Table\\TDistribution::ONE_SIDED_CONFIDENCE_LEVEL;\n$table   = Table\\TDistribution::TWO_SIDED_CONFIDENCE_LEVEL;\n$ν       = 5;  // degrees of freedom\n$cl      = 99; // confidence level\n$t       = $table[$ν][$cl];\n\n// t Distribution Tables\n$table = Table\\TDistribution::ONE_SIDED_ALPHA;\n$table = Table\\TDistribution::TWO_SIDED_ALPHA;\n$ν     = 5;     // degrees of freedom\n$α     = 0.001; // alpha value\n$t     = $table[$ν][$α];\n\n// χ² Distribution Table\n$table = Table\\ChiSquared::CHI_SQUARED_SCORES;\n$df    = 2;    // degrees of freedom\n$p     = 0.05; // P value\n$χ²    = $table[$df][$p];\n```\n\n### Sample Data\n```php\nuse MathPHP\\SampleData;\n\n// Famous sample data sets to experiment with\n\n// Motor Trend Car Road Tests (mtcars)\n$mtCars      = new SampleData\\MtCars();\n$rawData     = $mtCars-\u003egetData();                     // [[21, 6, 160, ... ], [30.4, 4, 71.1, ... ], ... ]\n$labeledData = $mtCars-\u003egetLabeledData();              // ['Mazda RX4' =\u003e ['mpg' =\u003e 21, 'cyl' =\u003e 6, 'disp' =\u003e 160, ... ], 'Honda Civic' =\u003e [ ... ], ...]\n$modelData   = $mtCars-\u003egetModelData('Ferrari Dino');  // ['mpg' =\u003e 19.7, 'cyl' =\u003e 6, 'disp' =\u003e 145, ... ]\n$mpgs        = $mtCars-\u003egetMpg();                      // ['Mazda RX4' =\u003e 21, 'Honda civic' =\u003e 30.4, ... ]\n// Getters for Mpg, Cyl, Disp, Hp, Drat, Wt, Qsec, Vs, Am, Gear, Carb\n\n// Edgar Anderson's Iris Data (iris)\n$iris         = new SampleData\\Iris();\n$rawData      = $iris-\u003egetData();         // [[5.1, 3.5, 1.4, 0.2, 'setosa'], [4.9, 3.0, 1.4, 0.2, 'setosa'], ... ]\n$labeledData  = $iris-\u003egetLabeledData();  // [['sepalLength' =\u003e 5.11, 'sepalWidth' =\u003e 3.5, 'petalLength' =\u003e 1.4, 'petalWidth' =\u003e 0.2, 'species' =\u003e 'setosa'], ... ]\n$petalLengths = $iris-\u003egetSepalLength();  // [5.1, 4.9, 4.7, ... ]\n// Getters for SepalLength, SepalWidth, PetalLength, PetalWidth, Species\n\n// The Effect of Vitamin C on Tooth Growth in Guinea Pigs (ToothGrowth)\n$toothGrowth = new SampleData\\ToothGrowth();\n$rawData     = $toothGrowth-\u003egetData();         // [[4.2, 'VC', 0.5], [11.5, 'VC', '0.5], ... ]\n$labeledData = $toothGrowth-\u003egetLabeledData();  // [['len' =\u003e 4.2, 'supp' =\u003e 'VC', 'dose' =\u003e 0.5], ... ]\n$lengths     = $toothGrowth-\u003egetLen();          // [4.2, 11.5, ... ]\n// Getters for Len, Supp, Dose\n\n// Results from an Experiment on Plant Growth (PlantGrowth)\n$plantGrowth = new SampleData\\PlantGrowth();\n$rawData     = $plantGrowth-\u003egetData();         // [[4.17, 'ctrl'], [5.58, 'ctrl'], ... ]\n$labeledData = $plantGrowth-\u003egetLabeledData();  // [['weight' =\u003e 4.17, 'group' =\u003e 'ctrl'], ['weight' =\u003e 5.58, 'group' =\u003e 'ctrl'], ... ]\n$weights     = $plantGrowth-\u003egetWeight();       // [4.17, 5.58, ... ]\n// Getters for Weight, Group\n\n// Violent Crime Rates by US State (USArrests)\n$usArrests   = new SampleData\\UsArrests();\n$rawData     = $usArrests-\u003erawData();              // [[13.2, 236, 58, 21.2], [10.0, 263, 48, 44.5], ... ]\n$labeledData = $usArrests-\u003egetLabeledData();       // ['Alabama' =\u003e ['murder' =\u003e 13.2, 'assault' =\u003e 236, 'urbanPop' =\u003e 58, 'rape' =\u003e 21.2], ... ]\n$stateData   = $usArrests-\u003egetStateData('Texas');  // ['murder' =\u003e 12.7, 'assault' =\u003e 201, 'urbanPop' =\u003e 80, 'rape' =\u003e 25.5]\n$murders     = $usArrests-\u003egetMurders();           // ['Alabama' =\u003e 13.2, 'Alaska' =\u003e 10.1, ... ]\n// Getters for Murder, Assault, UrbanPop, Rape\n\n// Data from Cereals (cereal)\n$cereal  = new SampleData\\Cereal();\n$cereals = $cereal-\u003egetCereals();    // ['B1', 'B2', 'B3', 'M1', 'M2', ... ]\n$X       = $cereal-\u003egetXData();      // [[0.002682755, 0.003370673, 0.004085942, ... ], [0.002781597, 0.003474863, 0.004191472, ... ], ... ]\n$Y       = $cereal-\u003egetYData();      // [[18373, 41.61500, 6.565000, ... ], [18536, 41.40500, 6.545000, ... ], ... ]\n$Ysc     = $cereal-\u003egetYscData();    // [[-0.1005049, 0.6265746, -1.1716630, ... ], [0.9233889, 0.1882929, -1.3185289, ... ], ... ]\n// Labeled data: getLabeledXData(), getLabeledYData(), getLabeledYscData()\n\n// Data from People (people)\n$people      = new SampleData\\People();\n$rawData     = $people-\u003egetData();         // [198, 92, -1, ... ], [184, 84, -1, ... ], ... ]\n$labeledData = $people-\u003egetLabeledData();  // ['Lars' =\u003e ['height' =\u003e 198, 'weight' =\u003e 92, 'hairLength' =\u003e -1, ... ]]\n$names       = $people-\u003egetNames();\n// Getters for names, height, weight, hairLength, shoeSize, age, income, beer, wine, sex, swim, region, iq\n```\n\n### Search\n```php\nuse MathPHP\\Search;\n\n// Search lists of numbers to find specific indexes\n\n$list = [1, 2, 3, 4, 5];\n\n$index   = Search::sorted($list, 2);   // Find the array index where an item should be inserted to maintain sorted order\n$index   = Search::argMax($list);      // Find the array index of the maximum value\n$index   = Search::nanArgMax($list);   // Find the array index of the maximum value, ignoring NANs\n$index   = Search::argMin($list);      // Find the array index of the minimum value\n$index   = Search::nanArgMin($list);   // Find the array index of the minimum value, ignoring NANs\n$indices = Search::nonZero($list);     // Find the array indices of the scalar values that are non-zero\n```\n\n### Sequences - Basic\n```php\nuse MathPHP\\Sequence\\Basic;\n\n$n = 5; // Number of elements in the sequence\n\n// Arithmetic progression\n$d           = 2;  // Difference between the elements of the sequence\n$a₁          = 1;  // Starting number for the sequence\n$progression = Basic::arithmeticProgression($n, $d, $a₁);\n// [1, 3, 5, 7, 9] - Indexed from 1\n\n// Geometric progression (arⁿ⁻¹)\n$a           = 2; // Scalar value\n$r           = 3; // Common ratio\n$progression = Basic::geometricProgression($n, $a, $r);\n// [2(3)⁰, 2(3)¹, 2(3)², 2(3)³] = [2, 6, 18, 54] - Indexed from 1\n\n// Square numbers (n²)\n$squares = Basic::squareNumber($n);\n// [0², 1², 2², 3², 4²] = [0, 1, 4, 9, 16] - Indexed from 0\n\n// Cubic numbers (n³)\n$cubes = Basic::cubicNumber($n);\n// [0³, 1³, 2³, 3³, 4³] = [0, 1, 8, 27, 64] - Indexed from 0\n\n// Powers of 2 (2ⁿ)\n$po2 = Basic::powersOfTwo($n);\n// [2⁰, 2¹, 2², 2³, 2⁴] = [1,  2,  4,  8,  16] - Indexed from 0\n\n// Powers of 10 (10ⁿ)\n$po10 = Basic::powersOfTen($n);\n// [10⁰, 10¹, 10², 10³,  10⁴] = [1, 10, 100, 1000, 10000] - Indexed from 0\n\n// Factorial (n!)\n$fact = Basic::factorial($n);\n// [0!, 1!, 2!, 3!, 4!] = [1,  1,  2,  6,  24] - Indexed from 0\n\n// Digit sum\n$digit_sum = Basic::digitSum($n);\n// [0, 1, 2, 3, 4] - Indexed from 0\n\n// Digital root\n$digit_root = Basic::digitalRoot($n);\n// [0, 1, 2, 3, 4] - Indexed from 0\n```\n\n### Sequences - Advanced\n```php\nuse MathPHP\\Sequence\\Advanced;\n\n$n = 6; // Number of elements in the sequence\n\n// Fibonacci (Fᵢ = Fᵢ₋₁ + Fᵢ₋₂)\n$fib = Advanced::fibonacci($n);\n// [0, 1, 1, 2, 3, 5] - Indexed from 0\n\n// Lucas numbers\n$lucas = Advanced::lucasNumber($n);\n// [2, 1, 3, 4, 7, 11] - Indexed from 0\n\n// Pell numbers\n$pell = Advanced::pellNumber($n);\n// [0, 1, 2, 5, 12, 29] - Indexed from 0\n\n// Triangular numbers (figurate number)\n$triangles = Advanced::triangularNumber($n);\n// [1, 3, 6, 10, 15, 21] - Indexed from 1\n\n// Pentagonal numbers (figurate number)\n$pentagons = Advanced::pentagonalNumber($n);\n// [1, 5, 12, 22, 35, 51] - Indexed from 1\n\n// Hexagonal numbers (figurate number)\n$hexagons = Advanced::hexagonalNumber($n);\n// [1, 6, 15, 28, 45, 66] - Indexed from 1\n\n// Heptagonal numbers (figurate number)\n$heptagons = Advanced::heptagonalNumber($n);\n// [1, 4, 7, 13, 18, 27] - Indexed from 1\n\n// Look-and-say sequence (describe the previous term!)\n$look_and_say = Advanced::lookAndSay($n);\n// ['1', '11', '21', '1211', '111221', '312211'] - Indexed from 1\n\n// Lazy caterer's sequence (central polygonal numbers)\n$lazy_caterer = Advanced::lazyCaterers($n);\n// [1, 2, 4, 7, 11, 16] - Indexed from 0\n\n// Magic squares series (magic constants; magic sums)\n$magic_squares = Advanced::magicSquares($n);\n// [0, 1, 5, 15, 34, 65] - Indexed from 0\n\n// Perfect numbers\n$perfect_numbers = Advanced::perfectNumbers($n);\n// [6, 28, 496, 8128, 33550336, 8589869056] - Indexed from 0\n\n// Perfect powers sequence\n$perfect_powers = Advanced::perfectPowers($n);\n// [4, 8, 9, 16, 25, 27] - Indexed from 0\n\n// Not perfect powers sequence\n$not_perfect_powers = Advanced::notPerfectPowers($n);\n// [2, 3, 5, 6, 7, 10] - Indexed from 0\n\n// Prime numbers up to n (n is not the number of elements in the sequence)\n$primes = Advanced::primesUpTo(30);\n// [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] - Indexed from 0\n```\n\n### Sequences - Non-Integer\n```php\nuse MathPHP\\Sequence\\NonInteger;\n\n$n = 4; // Number of elements in the sequence\n\n// Harmonic sequence\n$harmonic = NonInteger::harmonic($n);\n// [1, 3/2, 11/6, 25/12] - Indexed from 1\n\n// Generalized harmonic sequence\n$m           = 2;  // exponent\n$generalized = NonInteger::generalizedHarmonic($n, $m);\n// [1, 5 / 4, 49 / 36, 205 / 144] - Indexed from 1\n\n// Hyperharmonic sequence\n$r             = 2;  // depth of recursion\n$hyperharmonic = NonInteger::hyperharmonic($n, $r);\n// [1, 5/2, 26/6, 77/12] - Indexed from 1\n```\n\n### Set Theory\n```php\nuse MathPHP\\SetTheory\\Set;\nuse MathPHP\\SetTheory\\ImmutableSet;\n\n// Sets and immutable sets\n$A = new Set([1, 2, 3]);          // Can add and remove members\n$B = new ImmutableSet([3, 4, 5]); // Cannot modify set once created\n\n// Basic set data\n$set         = $A-\u003easArray();\n$cardinality = $A-\u003elength();\n$bool        = $A-\u003eisEmpty();\n\n// Set membership\n$true = $A-\u003eisMember(2);\n$true = $A-\u003eisNotMember(8);\n\n// Add and remove members\n$A-\u003eadd(4);\n$A-\u003eadd(new Set(['a', 'b']));\n$A-\u003eaddMulti([5, 6, 7]);\n$A-\u003eremove(7);\n$A-\u003eremoveMulti([5, 6]);\n$A-\u003eclear();\n\n// Set properties against other sets - return boolean\n$bool = $A-\u003eisDisjoint($B);\n$bool = $A-\u003eisSubset($B);         // A ⊆ B\n$bool = $A-\u003eisProperSubset($B);   // A ⊆ B \u0026 A ≠ B\n$bool = $A-\u003eisSuperset($B);       // A ⊇ B\n$bool = $A-\u003eisProperSuperset($B); // A ⊇ B \u0026 A ≠ B\n\n// Set operations with other sets - return a new Set\n$A∪B  = $A-\u003eunion($B);\n$A∩B  = $A-\u003eintersect($B);\n$A＼B = $A-\u003edifference($B);          // relative complement\n$AΔB  = $A-\u003esymmetricDifference($B);\n$A×B  = $A-\u003ecartesianProduct($B);\n\n// Other set operations\n$P⟮A⟯ = $A-\u003epowerSet();\n$C   = $A-\u003ecopy();\n\n// Print a set\nprint($A); // Set{1, 2, 3, 4, Set{a, b}}\n\n// PHP Interfaces\n$n = count($A);                 // Countable\nforeach ($A as $member) { ... } // Iterator\n\n// Fluent interface\n$A-\u003eadd(5)-\u003eadd(6)-\u003eremove(4)-\u003eaddMulti([7, 8, 9]);\n```\n\n### Statistics - ANOVA\n```php\nuse MathPHP\\Statistics\\ANOVA;\n\n// One-way ANOVA\n$sample1 = [1, 2, 3];\n$sample2 = [3, 4, 5];\n$sample3 = [5, 6, 7];\n   ⋮            ⋮\n\n$anova = ANOVA::oneWay($sample1, $sample2, $sample3);\nprint_r($anova);\n/* Array (\n    [ANOVA] =\u003e Array (             // ANOVA hypothesis test summary data\n            [treatment] =\u003e Array (\n                    [SS] =\u003e 24     // Sum of squares (between)\n                    [df] =\u003e 2      // Degrees of freedom\n                    [MS] =\u003e 12     // Mean squares\n                    [F]  =\u003e 12     // Test statistic\n                    [P]  =\u003e 0.008  // P value\n                )\n            [error] =\u003e Array (\n                    [SS] =\u003e 6      // Sum of squares (within)\n                    [df] =\u003e 6      // Degrees of freedom\n                    [MS] =\u003e 1      // Mean squares\n                )\n            [total] =\u003e Array (\n                    [SS] =\u003e 30     // Sum of squares (total)\n                    [df] =\u003e 8      // Degrees of freedom\n                )\n        )\n    [total_summary] =\u003e Array (     // Total summary data\n            [n]        =\u003e 9\n            [sum]      =\u003e 36\n            [mean]     =\u003e 4\n            [SS]       =\u003e 174\n            [variance] =\u003e 3.75\n            [sd]       =\u003e 1.9364916731037\n            [sem]      =\u003e 0.6454972243679\n        )\n    [data_summary] =\u003e Array (      // Data summary (each input sample)\n            [0] =\u003e Array ([n] =\u003e 3 [sum] =\u003e 6  [mean] =\u003e 2 [SS] =\u003e 14  [variance] =\u003e 1 [sd] =\u003e 1 [sem] =\u003e 0.57735026918963)\n            [1] =\u003e Array ([n] =\u003e 3 [sum] =\u003e 12 [mean] =\u003e 4 [SS] =\u003e 50  [variance] =\u003e 1 [sd] =\u003e 1 [sem] =\u003e 0.57735026918963)\n            [2] =\u003e Array ([n] =\u003e 3 [sum] =\u003e 18 [mean] =\u003e 6 [SS] =\u003e 110 [variance] =\u003e 1 [sd] =\u003e 1 [sem] =\u003e 0.57735026918963)\n        )\n) */\n\n// Two-way ANOVA\n/*        | Factor B₁ | Factor B₂ | Factor B₃ | ⋯\nFactor A₁ |  4, 6, 8  |  6, 6, 9  |  8, 9, 13 | ⋯\nFactor A₂ |  4, 8, 9  | 7, 10, 13 | 12, 14, 16| ⋯\n    ⋮           ⋮           ⋮           ⋮         */\n$factorA₁ = [\n  [4, 6, 8],    // Factor B₁\n  [6, 6, 9],    // Factor B₂\n  [8, 9, 13],   // Factor B₃\n];\n$factorA₂ = [\n  [4, 8, 9],    // Factor B₁\n  [7, 10, 13],  // Factor B₂\n  [12, 14, 16], // Factor B₃\n];\n       ⋮\n\n$anova = ANOVA::twoWay($factorA₁, $factorA₂);\nprint_r($anova);\n/* Array (\n    [ANOVA] =\u003e Array (          // ANOVA hypothesis test summary data\n            [factorA] =\u003e Array (\n                    [SS] =\u003e 32                 // Sum of squares\n                    [df] =\u003e 1                  // Degrees of freedom\n                    [MS] =\u003e 32                 // Mean squares\n                    [F]  =\u003e 5.6470588235294    // Test statistic\n                    [P]  =\u003e 0.034994350619895  // P value\n                )\n            [factorB] =\u003e Array (\n                    [SS] =\u003e 93                 // Sum of squares\n                    [df] =\u003e 2                  // Degrees of freedom\n                    [MS] =\u003e 46.5               // Mean squares\n                    [F]  =\u003e 8.2058823529412    // Test statistic\n                    [P]  =\u003e 0.0056767297582031 // P value\n                )\n            [interaction] =\u003e Array (\n                    [SS] =\u003e 7                  // Sum of squares\n                    [df] =\u003e 2                  // Degrees of freedom\n                    [MS] =\u003e 3.5                // Mean squares\n                    [F]  =\u003e 0.61764705882353   // Test statistic\n                    [P]  =\u003e 0.5555023440712    // P value\n                )\n            [error] =\u003e Array (\n                    [SS] =\u003e 68                 // Sum of squares (within)\n                    [df] =\u003e 12                 // Degrees of freedom\n                    [MS] =\u003e 5.6666666666667    // Mean squares\n                )\n            [total] =\u003e Array (\n                    [SS] =\u003e 200                // Sum of squares (total)\n                    [df] =\u003e 17                 // Degrees of freedom\n                )\n        )\n    [total_summary] =\u003e Array (    // Total summary data\n            [n]        =\u003e 18\n            [sum]      =\u003e 162\n            [mean]     =\u003e 9\n            [SS]       =\u003e 1658\n            [variance] =\u003e 11.764705882353\n            [sd]       =\u003e 3.4299717028502\n            [sem]      =\u003e 0.80845208345444\n        )\n    [summary_factorA]     =\u003e Array ( ... )   // Summary data of factor A\n    [summary_factorB]     =\u003e Array ( ... )   // Summary data of factor B\n    [summary_interaction] =\u003e Array ( ... )   // Summary data of interactions of factors A and B\n) */\n```\n\n### Statistics - Averages\n```php\nuse MathPHP\\Statistics\\Average;\n\n$numbers = [13, 18, 13, 14, 13, 16, 14, 21, 13];\n\n// Mean, median, mode\n$mean   = Average::mean($numbers);\n$median = Average::median($numbers);\n$mode   = Average::mode($numbers); // Returns an array — may be multimodal\n\n// Weighted mean\n$weights       = [12, 1, 23, 6, 12, 26, 21, 12, 1];\n$weighted_mean = Average::weightedMean($numbers, $weights)\n\n// Other means of a list of numbers\n$geometric_mean      = Average::geometricMean($numbers);\n$harmonic_mean       = Average::harmonicMean($numbers);\n$contraharmonic_mean = Average::contraharmonicMean($numbers);\n$quadratic_mean      = Average::quadraticMean($numbers);  // same as rootMeanSquare\n$root_mean_square    = Average::rootMeanSquare($numbers); // same as quadraticMean\n$trimean             = Average::trimean($numbers);\n$interquartile_mean  = Average::interquartileMean($numbers); // same as iqm\n$interquartile_mean  = Average::iqm($numbers);               // same as interquartileMean\n$cubic_mean          = Average::cubicMean($numbers);\n\n// Truncated mean (trimmed mean)\n$trim_percent   = 25;  // 25 percent of observations trimmed from each end of distribution\n$truncated_mean = Average::truncatedMean($numbers, $trim_percent);\n\n// Generalized mean (power mean)\n$p                = 2;\n$generalized_mean = Average::generalizedMean($numbers, $p); // same as powerMean\n$power_mean       = Average::powerMean($numbers, $p);       // same as generalizedMean\n\n// Lehmer mean\n$p           = 3;\n$lehmer_mean = Average::lehmerMean($numbers, $p);\n\n// Moving averages\n$n       = 3;\n$weights = [3, 2, 1];\n$SMA     = Average::simpleMovingAverage($numbers, $n);             // 3 n-point moving average\n$CMA     = Average::cumulativeMovingAverage($numbers);\n$WMA     = Average::weightedMovingAverage($numbers, $n, $weights);\n$EPA     = Average::exponentialMovingAverage($numbers, $n);\n\n// Means of two numbers\n[$x, $y]       = [24, 6];\n$agm           = Average::arithmeticGeometricMean($x, $y); // same as agm\n$agm           = Average::agm($x, $y);                     // same as arithmeticGeometricMean\n$log_mean      = Average::logarithmicMean($x, $y);\n$heronian_mean = Average::heronianMean($x, $y);\n$identric_mean = Average::identricMean($x, $y);\n\n// Averages report\n$averages = Average::describe($numbers);\nprint_r($averages);\n/* Array (\n    [mean]                =\u003e 15\n    [median]              =\u003e 14\n    [mode]                =\u003e Array ( [0] =\u003e 13 )\n    [geometric_mean]      =\u003e 14.789726414533\n    [harmonic_mean]       =\u003e 14.605077399381\n    [contraharmonic_mean] =\u003e 15.474074074074\n    [quadratic_mean]      =\u003e 15.235193176035\n    [trimean]             =\u003e 14.5\n    [iqm]                 =\u003e 14\n    [cubic_mean]          =\u003e 15.492307432707\n) */\n```\n\n### Statistics - Circular\n```php\nuse MathPHP\\Statistics\\Circular;\n\n$angles = [1.51269877, 1.07723915, 0.81992282];\n\n$θ = Circular::mean($angles);\n$R = Circular::resultantLength($angles);\n$ρ = Circular::meanResultantLength($angles);\n$V = Circular::variance($angles);\n$ν = Circular::standardDeviation($angles);\n\n// Descriptive circular statistics report\n$stats = Circular::describe($angles);\nprint_r($stats);\n/* Array (\n    [n]                     =\u003e 3\n    [mean]                  =\u003e 1.1354043006436\n    [resultant_length]      =\u003e 2.8786207547493\n    [mean_resultant_length] =\u003e 0.9595402515831\n    [variance]              =\u003e 0.040459748416901\n    [sd]                    =\u003e 0.28740568481722\n); */\n```\n\n### Statistics - Correlation\n```php\nuse MathPHP\\Statistics\\Correlation;\n\n$X = [1, 2, 3, 4, 5];\n$Y = [2, 3, 4, 4, 6];\n\n// Covariance\n$σxy = Correlation::covariance($X, $Y);  // Has optional parameter to set population (defaults to sample covariance)\n\n// Weighted covariance\n$w    = [2, 3, 1, 1, 5];\n$σxyw = Correlation::weightedCovariance($X, $Y, $w);\n\n// r - Pearson product-moment correlation coefficient (Pearson's r)\n$r = Correlation::r($X, $Y);  // Has optional parameter to set population (defaults to sample correlation coefficient)\n\n// Weighted correlation coefficient\n$rw = Correlation::weightedCorrelationCoefficient($X, $Y, $w);\n\n// R² - Coefficient of determination\n$R² = Correlation::r2($X, $Y);  // Has optional parameter to set population (defaults to sample coefficient of determination)\n\n// τ - Kendall rank correlation coefficient (Kendall's tau)\n$τ = Correlation::kendallsTau($X, $Y);\n\n// ρ - Spearman's rank correlation coefficient (Spearman's rho)\n$ρ = Correlation::spearmansRho($X, $Y);\n\n// Descriptive correlation report\n$stats = Correlation::describe($X, $Y);\nprint_r($stats);\n/* Array (\n    [cov] =\u003e 2.25\n    [r]   =\u003e 0.95940322360025\n    [r2]  =\u003e 0.92045454545455\n    [tau] =\u003e 0.94868329805051\n    [rho] =\u003e 0.975\n) */\n\n// Confidence ellipse - create an ellipse surrounding the data at a specified standard deviation\n$sd           = 1;\n$num_points   = 11; // Optional argument specifying number of points of the ellipse\n$ellipse_data = Correlation::confidenceEllipse($X, $Y, $sd, $num_points);\n\n```\n\n### Statistics - Descriptive\n```php\nuse MathPHP\\Statistics\\Descriptive;\n\n$numbers = [13, 18, 13, 14, 13, 16, 14, 21, 13];\n\n// Range and midrange\n$range    = Descriptive::range($numbers);\n$midrange = Descriptive::midrange($numbers);\n\n// Variance (population and sample)\n$σ² = Descriptive::populationVariance($numbers); // n degrees of freedom\n$S² = Descriptive::sampleVariance($numbers);     // n - 1 degrees of freedom\n\n// Variance (Custom degrees of freedom)\n$df = 5;                                    // degrees of freedom\n$S² = Descriptive::variance($numbers, $df); // can specify custom degrees of freedom\n\n// Weighted sample variance\n$weights = [0.1, 0.2, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1];\n$σ²w     = Descriptive::weightedSampleVariance($numbers, $weights, $biased = false);\n\n// Standard deviation (For a sample; uses sample variance)\n$σ = Descriptive::sd($numbers);                // same as standardDeviation;\n$σ = Descriptive::standardDeviation($numbers); // same as sd;\n\n// SD+ (Standard deviation for a population; uses population variance)\n$SD＋ = Descriptive::sd($numbers, Descriptive::POPULATION); // POPULATION constant = true\n$SD＋ = Descriptive::standardDeviation($numbers, true);     // same as sd with POPULATION constant\n\n// Coefficient of variation (cᵥ)\n$cᵥ = Descriptive::coefficientOfVariation($numbers);\n\n// MAD - mean/median absolute deviations\n$mean_mad   = Descriptive::meanAbsoluteDeviation($numbers);\n$median_mad = Descriptive::medianAbsoluteDeviation($numbers);\n\n// Quartiles (inclusive and exclusive methods)\n// [0% =\u003e 13, Q1 =\u003e 13, Q2 =\u003e 14, Q3 =\u003e 17, 100% =\u003e 21, IQR =\u003e 4]\n$quartiles = Descriptive::quartiles($numbers);          // Has optional parameter to specify method. Default is Exclusive\n$quartiles = Descriptive::quartilesExclusive($numbers);\n$quartiles = Descriptive::quartilesInclusive($numbers);\n\n// IQR - Interquartile range\n$IQR = Descriptive::interquartileRange($numbers); // Same as IQR; has optional parameter to specify quartile method.\n$IQR = Descriptive::iqr($numbers);                // Same as interquartileRange; has optional parameter to specify quartile method.\n\n// Percentiles\n$twentieth_percentile    = Descriptive::percentile($numbers, 20);\n$ninety_fifth_percentile = Descriptive::percentile($numbers, 95);\n\n// Midhinge\n$midhinge = Descriptive::midhinge($numbers);\n\n// Describe a list of numbers - descriptive stats report\n$stats = Descriptive::describe($numbers); // Has optional parameter to set population or sample calculations\nprint_r($stats);\n/* Array (\n    [n]          =\u003e 9\n    [min]        =\u003e 13\n    [max]        =\u003e 21\n    [mean]       =\u003e 15\n    [median]     =\u003e 14\n    [mode]       =\u003e Array ( [0] =\u003e 13 )\n    [range]      =\u003e 8\n    [midrange]   =\u003e 17\n    [variance]   =\u003e 8\n    [sd]         =\u003e 2.8284271247462\n    [cv]         =\u003e 0.18856180831641\n    [mean_mad]   =\u003e 2.2222222222222\n    [median_mad] =\u003e 1\n    [quartiles]  =\u003e Array (\n            [0%]   =\u003e 13\n            [Q1]   =\u003e 13\n            [Q2]   =\u003e 14\n            [Q3]   =\u003e 17\n            [100%] =\u003e 21\n            [IQR]  =\u003e 4\n        )\n    [midhinge]   =\u003e 15\n    [skewness]   =\u003e 1.4915533665654\n    [ses]        =\u003e 0.71713716560064\n    [kurtosis]   =\u003e 0.1728515625\n    [sek]        =\u003e 1.3997084244475\n    [sem]        =\u003e 0.94280904158206\n    [ci_95]      =\u003e Array (\n            [ci]          =\u003e 1.8478680091392\n            [lower_bound] =\u003e 13.152131990861\n            [upper_bound] =\u003e 16.847868009139\n        )\n    [ci_99]      =\u003e Array (\n            [ci]          =\u003e 2.4285158135783\n            [lower_bound] =\u003e 12.571484186422\n            [upper_bound] =\u003e 17.428515813578\n        )\n) */\n\n// Five number summary - five most important sample percentiles\n$summary = Descriptive::fiveNumberSummary($numbers);\n// [min, Q1, median, Q3, max]\n```\n\n### Statistics - Distance\n```php\nuse MathPHP\\Statistics\\Distance;\n\n// Probability distributions\n$X = [0.2, 0.5, 0.3];\n$Y = [0.1, 0.4, 0.5];\n\n// Distances\n$DB⟮X、Y⟯   = Distance::bhattacharyya($X, $Y);\n$H⟮X、Y⟯    = Distance::hellinger($X, $Y);\n$D⟮X、Y⟯    = Distance::minkowski($X, $Y, $p = 2);\n$d⟮X、Y⟯    = Distance::euclidean($X, $Y);          // L² distance\n$d₁⟮X、Y⟯   = Distance::manhattan($X, $Y);          // L¹ distance, taxicab geometry, city block distance\n$JSD⟮X‖Y⟯   = Distance::jensenShannon($X, $Y);\n$d⟮X、Y⟯    = Distance::canberra($X, Y);\nbrayCurtis = Distance::brayCurtis($X, $Y);\n$cosine    = Distance::cosine($X, $Y);\n$cos⟮α⟯     = Distance::cosineSimilarity($X, $Y);\n$D⟮X、Y⟯    = Distance::chebyshev($X, $Y);\n\n// Mahalanobis distance\n$x    = new Matrix([[6], [5]]);\n$data = new Matrix([\n    [4, 4, 5, 2, 3, 6, 9, 7, 4, 5],\n    [3, 7, 5, 7, 9, 5, 6, 2, 2, 7],\n]);\n$otherData = new Matrix([\n    [4, 4, 5, 2, 3, 6, 9, 7, 4, 5],\n    [3, 7, 5, 7, 9, 5, 6, 2, 2, 7],\n]);\n$y = new Matrix([[2], [2]]);\n$D = Distance::mahalanobis($x, $data);          // Mahalanobis distance from x to the centroid of the data.\n$D = Distance::mahalanobis($x, $data, $y);      // Mahalanobis distance between $x and $y using the data.\n$D = Distance::mahalanobis($data, $otherData);  // Mahalanobis distance between the centroids of two sets of data.\n```\n\n### Statistics - Distributions\n```php\nuse MathPHP\\Statistics\\Distribution;\n\n$grades = ['A', 'A', 'B', 'B', 'B', 'B', 'C', 'C', 'D', 'F'];\n\n// Frequency distributions (frequency and relative frequency)\n$frequencies          = Distribution::frequency($grades);         // [ A =\u003e 2,   B =\u003e 4,   C =\u003e 2,   D =\u003e 1,   F =\u003e 1   ]\n$relative_frequencies = Distribution::relativeFrequency($grades); // [ A =\u003e 0.2, B =\u003e 0.4, C =\u003e 0.2, D =\u003e 0.1, F =\u003e 0.1 ]\n\n// Cumulative frequency distributions (cumulative and cumulative relative)\n$cumulative_frequencies          = Distribution::cumulativeFrequency($grades);         // [ A =\u003e 2,   B =\u003e 6,   C =\u003e 8,   D =\u003e 9,   F =\u003e 10  ]\n$cumulative_relative_frequencies = Distribution::cumulativeRelativeFrequency($grades); // [ A =\u003e 0.2, B =\u003e 0.6, C =\u003e 0.8, D =\u003e 0.9, F =\u003e 1   ]\n\n// Ranking of data\n$values                       = [1, 2, 2, 3];\n$ordinal_ranking              = Distribution::ordinalRanking($values);              // 1, 2, 3, 4\n$standard_competition_ranking = Distribution::standardCompetitionRanking($values);  // 1, 2, 2, 4\n$modified_competition_ranking = Distribution::modifiedCompetitionRanking($values);  // 1, 3, 3, 4\n$fractional_ranking           = Distribution::fractionalRanking($values);           // 1, 2.5, 2.5, 4\n\n// Stem and leaf plot\n// Return value is array where keys are the stems, values are the leaves\n$values             = [44, 46, 47, 49, 63, 64, 66, 68, 68, 72, 72, 75, 76, 81, 84, 88, 106];\n$stem_and_leaf_plot = Distribution::stemAndLeafPlot($values);\n// [4 =\u003e [4, 6, 7, 9], 5 =\u003e [], 6 =\u003e [3, 4, 6, 8, 8], 7 =\u003e [2, 2, 5, 6], 8 =\u003e [1, 4, 8], 9 =\u003e [], 10 =\u003e [6]]\n\n// Optional second parameter will print stem and leaf plot to STDOUT\nDistribution::stemAndLeafPlot($values, Distribution::PRINT);\n/*\n 4 | 4 6 7 9\n 5 |\n 6 | 3 4 6 8 8\n 7 | 2 2 5 6\n 8 | 1 4 8\n 9 |\n10 | 6\n*/\n```\n\n### Statistics - Divergence\n```php\nuse MathPHP\\Statistics\\Divergence;\n\n// Probability distributions\n$X = [0.2, 0.5, 0.3];\n$Y = [0.1, 0.4, 0.5];\n\n// Divergences\n$Dkl⟮X‖Y⟯ = Divergence::kullbackLeibler($X, $Y);\n$JSD⟮X‖Y⟯ = Divergence::jensenShannon($X, $Y);\n```\n\n### Statistics - Effect Size\n```php\nuse MathPHP\\Statistics\\EffectSize;\n\n$SSt = 24;  // Sum of squares treatment\n$SSE = 300; // Sum of squares error\n$SST = 600; // Sum of squares total\n$dft = 1;   // Degrees of freedom treatment\n$MSE = 18;  // Mean squares error\n\n// η² - Eta-squared\n$η²  = EffectSize::etaSquared($SSt, $SST);\n$η²p = EffectSize::partialEtaSquared($SSt, $SSE);\n\n// ω² - Omega-squared\n$ω² = EffectSize::omegaSquared($SSt, $dft, $SST, $MSE);\n\n// Cohen's ƒ²\n$ƒ² = EffectSize::cohensF($η²);\n$ƒ² = EffectSize::cohensF($ω²);\n$ƒ² = EffectSize::cohensF($R²);\n\n// Cohen's q\n[$r₁, $r₂] = [0.1, 0.2];\n$q = EffectSize::cohensQ($r₁, $r₂);\n\n// Cohen's d\n[$μ₁, $σ₁] = [6.7, 1.2];\n[$μ₂, $σ₂] = [6, 1];\n$d = EffectSize::cohensD($μ₁, $μ₂, $σ₁, $σ₂);\n\n// Hedges' g\n[$μ₁, $σ₁, $n₁] = [6.7, 1.2, 15];\n[$μ₂, $σ₂, $n₂] = [6, 1, 15];\n$g = EffectSize::hedgesG($μ₁, $μ₂, $σ₁, $σ₂, $n₁, $n₂);\n\n// Glass' Δ\n$Δ = EffectSize::glassDelta($μ₁, $μ₂, $σ₂);\n```\n\n### Statistics - Experiments\n```php\nuse MathPHP\\Statistics\\Experiment;\n\n$a = 28;   // Exposed and event present\n$b = 129;  // Exposed and event absent\n$c = 4;    // Non-exposed and event present\n$d = 133;  // Non-exposed and event absent\n\n// Risk ratio (relative risk) - RR\n$RR = Experiment::riskRatio($a, $b, $c, $d);\n// ['RR' =\u003e 6.1083, 'ci_lower_bound' =\u003e 2.1976, 'ci_upper_bound' =\u003e 16.9784, 'p' =\u003e 0.0005]\n\n// Odds ratio (OR)\n$OR = Experiment::oddsRatio($a, $b, $c, $d);\n// ['OR' =\u003e 7.2171, 'ci_lower_bound' =\u003e 2.4624, 'ci_upper_bound' =\u003e 21.1522, 'p' =\u003e 0.0003]\n\n// Likelihood ratios (positive and negative)\n$LL = Experiment::likelihoodRatio($a, $b, $c, $d);\n// ['LL+' =\u003e 7.4444, 'LL-' =\u003e 0.3626]\n\n$sensitivity = 0.67;\n$specificity = 0.91;\n$LL          = Experiment::likelihoodRatioSS($sensitivity, $specificity);\n```\n\n### Statistics - Kernel Density Estimation\n```php\nuse MathPHP\\Statistics\\KernelDensityEstimation\n\n$data = [-2.76, -1.09, -0.5, -0.15, 0.22, 0.69, 1.34, 1.75];\n$x    = 0.5;\n\n// Density estimator with default bandwidth (normal distribution approximation) and kernel function (standard normal)\n$kde     = new KernelDensityEstimation($data);\n$density = $kde-\u003eevaluate($x)\n\n// Custom bandwidth\n$h = 0.1;\n$kde-\u003esetBandwidth($h);\n\n// Library of built-in kernel functions\n$kde-\u003esetKernelFunction(KernelDensityEstimation::STANDARD_NORMAL);\n$kde-\u003esetKernelFunction(KernelDensityEstimation::NORMAL);\n$kde-\u003esetKernelFunction(KernelDensityEstimation::UNIFORM);\n$kde-\u003esetKernelFunction(KernelDensityEstimation::TRIANGULAR);\n$kde-\u003esetKernelFunction(KernelDensityEstimation::EPANECHNIKOV);\n$kde-\u003esetKernelFunction(KernelDensityEstimation::TRICUBE);\n\n// Set custom kernel function (user-provided callable)\n$kernel = function ($x) {\n  if (abs($x) \u003e 1) {\n      return 0;\n  } else {\n      return 70 / 81 * ((1 - abs($x) ** 3) ** 3);\n  }\n};\n$kde-\u003esetKernelFunction($kernel);\n\n// All customization optionally can be done in the constructor\n$kde = new KernelDesnsityEstimation($data, $h, $kernel);\n```\n\n### Statistics - Multivariate - Principal Component Analysis\n```php\nuse MathPHP\\Statistics\\Multivariate\\PCA;\nuse MathPHP\\LinearAlgebra\\MatrixFactory;\n\n// Given\n$matrix = MatrixFactory::create($data);  // observations of possibly correlated variables\n$center = true;                          // do mean centering of data\n$scale  = true;                          // do standardization of data\n\n// Build a principal component analysis model to explore\n$model = new PCA($matrix, $center, $scale);\n\n// Scores and loadings of the PCA model\n$scores      = $model-\u003egetScores();       // Matrix of transformed standardized data with the loadings matrix\n$loadings    = $model-\u003egetLoadings();     // Matrix of unit eigenvectors of the correlation matrix\n$eigenvalues = $model-\u003egetEigenvalues();  // Vector of eigenvalues of components\n\n// Residuals, limits, critical values and more\n$R²         = $model-\u003egetR2();           // array of R² values\n$cumR²      = $model-\u003egetCumR2();        // array of cummulative R² values\n$Q          = $model-\u003egetQResiduals();   // Matrix of Q residuals\n$T²         = $model-\u003egetT2Distances();  // Matrix of T² distances\n$T²Critical = $model-\u003egetCriticalT2();   // array of critical limits of T²\n$QCritical  = $model-\u003egetCriticalQ();    // array of critical limits of Q\n```\n\n### Statistics - Multivariate - Partial Least Squares Regression\n```php\nuse MathPHP\\Statistics\\Multivariate\\PLS;\nuse MathPHP\\LinearAlgebra\\MatrixFactory;\nuse MathPHP\\SampleData;\n\n// Given\n$cereal = new SampleData\\Cereal();\n$X      = MatrixFactory::createNumeric($cereal-\u003egetXData());\n$Y      = MatrixFactory::createNumeric($cereal-\u003egetYData());\n\n// Build a partial least squares regression to explore\n$numberOfComponents = 5;\n$scale              = true;\n$pls                = new PLS($X, $Y, $numberOfComponents, $scale);\n\n// PLS model data\n$C = $pls-\u003egetYLoadings();     // Loadings for Y values (each loading column transforms F to U)\n$W = $pls-\u003egetXLoadings();     // Loadings for X values (each loading column transforms E into T)\n$T = $pls-\u003egetXScores();       // Scores for the X values (latent variables of X)\n$U = $pls-\u003egetYScores();       // Scores for the Y values (latent variables of Y)\n$B = $pls-\u003egetCoefficients();  // Regression coefficients (matrix that best transforms E into F)\n$P = $pls-\u003egetProjections();   // Projection matrix (each projection column transforms T into Ê)\n\n// Predict values (use regression model to predict new values of Y given values for X)\n$yPredictions = $pls-\u003epredict($xMatrix);\n```\n\n### Statistics - Outlier\n```php\nuse MathPHP\\Statistics\\Outlier;\n\n$data = [199.31, 199.53, 200.19, 200.82, 201.92, 201.95, 202.18, 245.57];\n$n    = 8;    // size of data\n$𝛼    = 0.05; // significance level\n\n// Grubb's test - two sided test\n$grubbsStatistic = Outlier::grubbsStatistic($data, Outlier::TWO_SIDED);\n$criticalValue   = Outlier::grubbsCriticalValue($𝛼, $n, Outlier::TWO_SIDED);\n\n// Grubbs' test - one sided test of minimum value\n$grubbsStatistic = Outlier::grubbsStatistic($data, Outlier::ONE_SIDED_LOWER);\n$criticalValue   = Outlier::grubbsCriticalValue($𝛼, $n, Outlier::ONE_SIDED);\n\n// Grubbs' test - one sided test of maximum value\n$grubbsStatistic = Outlier::grubbsStatistic($data, Outlier::ONE_SIDED_UPPER);\n$criticalValue   = Outlier::grubbsCriticalValue($𝛼, $n, Outlier::ONE_SIDED);\n```\n\n### Statistics - Random Variables\n```php\nuse MathPHP\\Statistics\\RandomVariable;\n\n$X = [1, 2, 3, 4];\n$Y = [2, 3, 4, 5];\n\n// Central moment (nth moment)\n$second_central_moment = RandomVariable::centralMoment($X, 2);\n$third_central_moment  = RandomVariable::centralMoment($X, 3);\n\n// Skewness (population, sample, and alternative general method)\n$skewness = RandomVariable::skewness($X);            // Optional type parameter to choose skewness type calculation. Defaults to sample skewness (similar to Excel's SKEW).\n$skewness = RandomVariable::sampleSkewness($X);      // Same as RandomVariable::skewness($X, RandomVariable::SAMPLE_SKEWNESS) - Similar to Excel's SKEW, SAS and SPSS, R (e1071) skewness type 2\n$skewness = RandomVariable::populationSkewness($X);  // Same as RandomVariable::skewness($X, RandomVariable::POPULATION_SKEWNESS) - Similar to Excel's SKEW.P, classic textbook definition, R (e1071) skewness type 1\n$skewness = RandomVariable::alternativeSkewness($X); // Same as RandomVariable::skewness($X, RandomVariable::ALTERNATIVE_SKEWNESS) - Alternative, classic definition of skewness\n$SES      = RandomVariable::ses(count($X));          // standard error of skewness\n\n// Kurtosis (excess)\n$kurtosis    = RandomVariable::kurtosis($X);           // Optional type parameter to choose kurtosis type calculation. Defaults to population kurtosis (similar to Excel's KURT).\n$kurtosis    = RandomVariable::sampleKurtosis($X);     // Same as RandomVariable::kurtosis($X, RandomVariable::SAMPLE_KURTOSIS) -  Similar to R (e1071) kurtosis type 1\n$kurtosis    = RandomVariable::populationKurtosis($X); // Same as RandomVariable::kurtosis($X, RandomVariable::POPULATION_KURTOSIS) - Similar to Excel's KURT, SAS and SPSS, R (e1071) kurtosis type 2\n$platykurtic = RandomVariable::isPlatykurtic($X);      // true if kurtosis is less than zero\n$leptokurtic = RandomVariable::isLeptokurtic($X);      // true if kurtosis is greater than zero\n$mesokurtic  = RandomVariable::isMesokurtic($X);       // true if kurtosis is zero\n$SEK         = RandomVariable::sek(count($X));         // standard error of kurtosis\n\n// Standard error of the mean (SEM)\n$sem = RandomVariable::standardErrorOfTheMean($X); // same as sem\n$sem = RandomVariable::sem($X);                    // same as standardErrorOfTheMean\n\n// Confidence interval\n$μ  = 90; // sample mean\n$n  = 9;  // sample size\n$σ  = 36; // standard deviation\n$cl = 99; // confidence level\n$ci = RandomVariable::confidenceInterval($μ, $n, $σ, $cl); // Array( [ci] =\u003e 30.91, [lower_bound] =\u003e 59.09, [upper_bound] =\u003e 120.91 )\n```\n\n### Statistics - Regressions\n```php\nuse MathPHP\\Statistics\\Regression;\n\n$points = [[1,2], [2,3], [4,5], [5,7], [6,8]];\n\n// Simple linear regression (least squares method)\n$regression = new Regression\\Linear($points);\n$parameters = $regression-\u003egetParameters();          // [m =\u003e 1.2209302325581, b =\u003e 0.6046511627907]\n$equation   = $regression-\u003egetEquation();            // y = 1.2209302325581x + 0.6046511627907\n$y          = $regression-\u003eevaluate(5);              // Evaluate for y at x = 5 using regression equation\n$ci         = $regression-\u003eci(5, 0.5);               // Confidence interval for x = 5 with p-value of 0.5\n$pi         = $regression-\u003epi(5, 0.5);               // Prediction interval for x = 5 with p-value of 0.5; Optional number of trials parameter.\n$Ŷ          = $regression-\u003eyHat();\n$r          = $regression-\u003er();                      // same as correlationCoefficient\n$r²         = $regression-\u003er2();                     // same as coefficientOfDetermination\n$se         = $regression-\u003estandardErrors();         // [m =\u003e se(m), b =\u003e se(b)]\n$t          = $regression-\u003etValues();                // [m =\u003e t, b =\u003e t]\n$p          = $regression-\u003etProbability();           // [m =\u003e p, b =\u003e p]\n$F          = $regression-\u003efStatistic();\n$p          = $regression-\u003efProbability();\n$h          = $regression-\u003eleverages();\n$e          = $regression-\u003eresiduals();\n$D          = $regression-\u003ecooksD();\n$DFFITS     = $regression-\u003edffits();\n$SStot      = $regression-\u003esumOfSquaresTotal();\n$SSreg      = $regression-\u003esumOfSquaresRegression();\n$SSres      = $regression-\u003esumOfSquaresResidual();\n$MSR        = $regression-\u003emeanSquareRegression();\n$MSE        = $regression-\u003emeanSquareResidual();\n$MSTO       = $regression-\u003emeanSquareTotal();\n$error      = $regression-\u003eerrorSd();                // Standard error of the residuals\n$V          = $regression-\u003eregressionVariance();\n$n          = $regression-\u003egetSampleSize();          // 5\n$points     = $regression-\u003egetPoints();              // [[1,2], [2,3], [4,5], [5,7], [6,8]]\n$xs         = $regression-\u003egetXs();                  // [1, 2, 4, 5, 6]\n$ys         = $regression-\u003egetYs();                  // [2, 3, 5, 7, 8]\n$ν          = $regression-\u003edegreesOfFreedom();\n\n// Linear regression through a fixed point (least squares method)\n$force_point = [0,0];\n$regression  = new Regression\\LinearThroughPoint($points, $force_point);\n$parameters  = $regression-\u003egetParameters();\n$equation    = $regression-\u003egetEquation();\n$y           = $regression-\u003eevaluate(5);\n$Ŷ           = $regression-\u003eyHat();\n$r           = $regression-\u003er();\n$r²          = $regression-\u003er2();\n ⋮                     ⋮\n\n// Theil–Sen estimator (Sen's slope estimator, Kendall–Theil robust line)\n$regression  = new Regression\\TheilSen($points);\n$parameters  = $regression-\u003egetParameters();\n$equation    = $regression-\u003egetEquation();\n$y           = $regression-\u003eevaluate(5);\n ⋮                     ⋮\n\n// Use Lineweaver-Burk linearization to fit data to the Michaelis–Menten model: y = (V * x) / (K + x)\n$regression  = new Regression\\LineweaverBurk($points);\n$parameters  = $regression-\u003egetParameters();  // [V, K]\n$equation    = $regression-\u003egetEquation();    // y = Vx / (K + x)\n$y           = $regression-\u003eevaluate(5);\n ⋮                     ⋮\n\n// Use Hanes-Woolf linearization to fit data to the Michaelis–Menten model: y = (V * x) / (K + x)\n$regression  = new Regression\\HanesWoolf($points);\n$parameters  = $regression-\u003egetParameters();  // [V, K]\n$equation    = $regression-\u003egetEquation();    // y = Vx / (K + x)\n$y           = $regression-\u003eevaluate(5);\n ⋮                     ⋮\n\n// Power law regression - power curve (least squares fitting)\n$regression = new Regression\\PowerLaw($points);\n$parameters = $regression-\u003egetParameters();   // [a =\u003e 56.483375436574, b =\u003e 0.26415375648621]\n$equation   = $regression-\u003egetEquation();     // y = 56.483375436574x^0.26415375648621\n$y          = $regression-\u003eevaluate(5);\n ⋮                     ⋮\n\n// LOESS - Locally Weighted Scatterplot Smoothing (Local regression)\n$α          = 1/3;                         // Smoothness parameter\n$λ          = 1;                           // Order of the polynomial fit\n$regression = new Regression\\LOESS($points, $α, $λ);\n$y          = $regression-\u003eevaluate(5);\n$Ŷ          = $regression-\u003eyHat();\n ⋮                     ⋮\n```\n\n### Statistics - Significance Testing\n```php\nuse MathPHP\\Statistics\\Significance;\n\n// Z test - One sample (z and p values)\n$Hₐ = 20;   // Alternate hypothesis (M Sample mean)\n$n  = 200;  // Sample size\n$H₀ = 19.2; // Null hypothesis (μ Population mean)\n$σ  = 6;    // SD of population (Standard error of the mean)\n$z  = Significance:zTest($Hₐ, $n, $H₀, $σ);           // Same as zTestOneSample\n$z  = Significance:zTestOneSample($Hₐ, $n, $H₀, $σ);  // Same as zTest\n/* [\n  'z'  =\u003e 1.88562, // Z score\n  'p1' =\u003e 0.02938, // one-tailed p value\n  'p2' =\u003e 0.0593,  // two-tailed p value\n] */\n\n// Z test - Two samples (z and p values)\n$μ₁ = 27;   // Sample mean of population 1\n$μ₂ = 33;   // Sample mean of population 2\n$n₁ = 75;   // Sample size of population 1\n$n₂ = 50;   // Sample size of population 2\n$σ₁ = 14.1; // Standard deviation of sample mean 1\n$σ₂ = 9.5;  // Standard deviation of sample mean 2\n$z  = Significance::zTestTwoSample($μ₁, $μ₂, $n₁, $n₂, $σ₁, $σ₂);\n/* [\n  'z'  =\u003e -2.36868418147285,  // z score\n  'p1' =\u003e 0.00893,            // one-tailed p value\n  'p2' =\u003e 0.0179,             // two-tailed p value\n] */\n\n// Z score\n$M = 8; // Sample mean\n$μ = 7; // Population mean\n$σ = 1; // Population SD\n$z = Significance::zScore($M, $μ, $σ);\n\n// T test - One sample (from sample data)\n$a     = [3, 4, 4, 5, 5, 5, 6, 6, 7, 8]; // Data set\n$H₀    = 300;                            // Null hypothesis (μ₀ Population mean)\n$tTest = Significance::tTest($a, $H₀)\nprint_r($tTest);\n/* Array (\n    [t]    =\u003e 0.42320736951516  // t score\n    [df]   =\u003e 9                 // degrees of freedom\n    [p1]   =\u003e 0.34103867713806  // one-tailed p value\n    [p2]   =\u003e 0.68207735427613  // two-tailed p value\n    [mean] =\u003e 5.3               // sample mean\n    [sd]   =\u003e 1.4944341180973   // standard deviation\n) */\n\n// T test - One sample (from summary data)\n$Hₐ    = 280; // Alternate hypothesis (M Sample mean)\n$s     = 50;  // Standard deviation of sample\n$n     = 15;  // Sample size\n$H₀    = 300; // Null hypothesis (μ₀ Population mean)\n$tTest = Significance::tTestOneSampleFromSummaryData($Hₐ, $s, $n, $H₀);\nprint_r($tTest);\n/* Array (\n    [t]    =\u003e -1.549193338483    // t score\n    [df]   =\u003e 14                 // degreees of freedom\n    [p1]   =\u003e 0.071820000122611  // one-tailed p value\n    [p2]   =\u003e 0.14364000024522   // two-tailed p value\n    [mean] =\u003e 280                // sample mean\n    [sd]   =\u003e 50                 // standard deviation\n) */\n\n// T test - Two samples (from sample data)\n$x₁    = [27.5, 21.0, 19.0, 23.6, 17.0, 17.9, 16.9, 20.1, 21.9, 22.6, 23.1, 19.6, 19.0, 21.7, 21.4];\n$x₂    = [27.1, 22.0, 20.8, 23.4, 23.4, 23.5, 25.8, 22.0, 24.8, 20.2, 21.9, 22.1, 22.9, 20.5, 24.4];\n$tTest = Significance::tTest($x₁, $x₂);\nprint_r($tTest);\n/* Array (\n    [t]     =\u003e -2.4553600286929   // t score\n    [df]    =\u003e 24.988527070145    // degrees of freedom\n    [p1]    =\u003e 0.010688914613979  // one-tailed p value\n    [p2]    =\u003e 0.021377829227958  // two-tailed p value\n    [mean1] =\u003e 20.82              // mean of sample x₁\n    [mean2] =\u003e 22.98667           // mean of sample x₂\n    [sd1]   =\u003e 2.804894           // standard deviation of x₁\n    [sd2]   =\u003e 1.952605           // standard deviation of x₂\n) */\n\n// T test - Two samples (from summary data)\n$μ₁    = 42.14; // Sample mean of population 1\n$μ₂    = 43.23; // Sample mean of population 2\n$n₁    = 10;    // Sample size of population 1\n$n₂    = 10;    // Sample size of population 2\n$σ₁    = 0.683; // Standard deviation of sample mean 1\n$σ₂    = 0.750; // Standard deviation of sample mean 2\n$tTest = Significance::tTe","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarkrogoyski%2Fmath-php","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarkrogoyski%2Fmath-php","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarkrogoyski%2Fmath-php/lists"}