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

Overview

MathPHP Logo

MathPHP - Powerful Modern Math Library for PHP

The only library you need to integrate mathematical functions into your applications. It is a self-contained library in pure PHP with no external dependencies.

Coverage Status License

Features

Setup

Add the library to your composer.json file in your project:

{
  "require": {
      "markrogoyski/math-php": "1.*"
  }
}

Use composer to install the library:

$ php composer.phar install

Composer will install MathPHP inside your vendor folder. Then you can add the following to your .php files to use the library with Autoloading.

require_once __DIR__ . '/vendor/autoload.php';

Alternatively, use composer on the command line to require and install MathPHP:

$ php composer.phar require markrogoyski/math-php:1.*

Minimum Requirements

  • PHP 7

Usage

Algebra

use MathPHP\Algebra;

// Greatest common divisor (GCD)
$gcd = Algebra::gcd(8, 12);

// Extended greatest common divisor - gcd(a, b) = a*a' + b*b'
$gcd = Algebra::extendedGcd(12, 8); // returns array [gcd, a', b']

// Least common multiple (LCM)
$lcm = Algebra::lcm(5, 2);

// Factors of an integer
$factors = Algebra::factors(12); // returns [1, 2, 3, 4, 6, 12]

// Linear equation of one variable: ax + b = 0
list($a, $b) = [2, 4]; // 2x + 4 = 0
$x           = Algebra::linear($a, $b);

// Quadratic equation: ax² + bx + c = 0
list($a, $b, $c) = [1, 2, -8]; // x² + 2x - 8
list($x₁, $x₂)   = Algebra::quadratic($a, $b, $c);

// Discriminant: Δ = b² - 4ac
list($a, $b, $c) = [2, 3, 4]; // 3² - 4(2)(4)
$Δ               = Algebra::discriminant($a, $b, $c);

// Cubic equation: z³ + a₂z² + a₁z + a₀ = 0
list($a₃, $a₂, $a₁, $a₀) = [2, 9, 3, -4]; // 2x³ + 9x² + 3x -4
list($x₁, $x₂, $x₃)      = Algebra::cubic($a₃, $a₂, $a₁, $a₀);

// Quartic equation: a₄z⁴ + a₃z³ + a₂z² + a₁z + a₀ = 0
list($a₄, $a₃, $a₂, $a₁, $a₀) = [1, -10, 35, -50, 24]; // z⁴ - 10z³ + 35z² - 50z + 24 = 0
list($z₁, $z₂, $z₃, $z₄)      = Algebra::quartic($a₄, $a₃, $a₂, $a₁, $a₀);

Arithmetic

use MathPHP\Arithmetic;

$√x  = Arithmetic::isqrt(8);     // 2 Integer square root
$³√x = Arithmetic::cubeRoot(-8); // -2
$ⁿ√x = Arithmetic::root(81, 4);  // nᵗʰ root (4ᵗʰ): 3

// Sum of digits
$digit_sum    = Arithmetic::digitSum(99);    // 18
$digital_root = Arithmetic::digitalRoot(99); // 9

// Equality of numbers within a tolerance
$x = 0.00000003458;
$y = 0.00000003455;
$ε = 0.0000000001;
$almostEqual = Arithmetic::almostEqual($x, $y, $ε); // true

// Copy sign
$magnitude = 5;
$sign      = -3;
$signed_magnitude = Arithmetic::copySign($magnitude, $sign); // -5

// Modulo (Differs from PHP remainder (%) operator for negative numbers)
$dividend = 12;
$divisor  = 5;
$modulo   = Arithmetic::modulo($dividend, $divisor);  // 2
$modulo   = Arithmetic::modulo(-$dividend, $divisor); // 3

Finance

use MathPHP\Finance;

// Financial payment for a loan or annuity with compound interest
$rate          = 0.035 / 12; // 3.5% interest paid at the end of every month
$periods       = 30 * 12;    // 30-year mortgage
$present_value = 265000;     // Mortgage note of $265,000.00
$future_value  = 0;
$beginning     = false;      // Adjust the payment to the beginning or end of the period
$pmt           = Finance::pmt($rate, $periods, $present_value, $future_value, $beginning);

// Interest on a financial payment for a loan or annuity with compound interest.
$period = 1; // First payment period
$ipmt   = Finance::ipmt($rate, $period, $periods, $present_value, $future_value, $beginning);

// Principle on a financial payment for a loan or annuity with compound interest
$ppmt = Finance::ppmt($rate, $period, $periods, $present_value, $future_value = 0, $beginning);

// Number of payment periods of an annuity.
$periods = Finance::periods($rate, $payment, $present_value, $future_value, $beginning);

// Annual Equivalent Rate (AER) of an annual percentage rate (APR)
$nominal = 0.035; // APR 3.5% interest
$periods = 12;    // Compounded monthly
$aer     = Finance::aer($nominal, $periods);

// Annual nominal rate of an annual effective rate (AER)
$nomial = Finance::nominal($aer, $periods);

// Future value for a loan or annuity with compound interest
$payment = 1189.97;
$fv      = Finance::fv($rate, $periods, $payment, $present_value, $beginning)

// Present value for a loan or annuity with compound interest
$pv = Finance::pv($rate, $periods, $payment, $future_value, $beginning)

// Net present value of cash flows
$values = [-1000, 100, 200, 300, 400];
$npv    = Finance::npv($rate, $values);

// Interest rate per period of an annuity
$beginning = false; // Adjust the payment to the beginning or end of the period
$rate      = Finance::rate($periods, $payment, $present_value, $future_value, $beginning);

// Internal rate of return
$values = [-100, 50, 40, 30];
$irr    = Finance::irr($values); // Rate of return of an initial investment of $100 with returns of $50, $40, and $30

// Modified internal rate of return
$finance_rate      = 0.05; // 5% financing
$reinvestment_rate = 0.10; // reinvested at 10%
$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%

// Discounted payback of an investment
$values  = [-1000, 100, 200, 300, 400, 500];
$rate    = 0.1;
$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

// Profitability index
$values              = [-100, 50, 50, 50];
$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

Functions - Map - Single Array

use MathPHP\Functions\Map;

$x = [1, 2, 3, 4];

$sums        = Map\Single::add($x, 2);      // [3, 4, 5, 6]
$differences = Map\Single::subtract($x, 1); // [0, 1, 2, 3]
$products    = Map\Single::multiply($x, 5); // [5, 10, 15, 20]
$quotients   = Map\Single::divide($x, 2);   // [0.5, 1, 1.5, 2]
$          = Map\Single::square($x);      // [1, 4, 9, 16]
$          = Map\Single::cube($x);        // [1, 8, 27, 64]
$x⁴          = Map\Single::pow($x, 4);      // [1, 16, 81, 256]
$√x          = Map\Single::sqrt($x);        // [1, 1.414, 1.732, 2]
$∣x∣         = Map\Single::abs($x);         // [1, 2, 3, 4]
$maxes       = Map\Single::max($x, 3);      // [3, 3, 3, 4]
$mins        = Map\Single::min($x, 3);      // [1, 2, 3, 3]
$reciprocals = Map\Single::reciprocal($x);  // [1, 1/2, 1/3, 1/4]

Functions - Map - Multiple Arrays

use MathPHP\Functions\Map;

$x = [10, 10, 10, 10];
$y = [1,   2,  5, 10];

// Map function against elements of two or more arrays, item by item (by item ...)
$sums        = Map\Multi::add($x, $y);      // [11, 12, 15, 20]
$differences = Map\Multi::subtract($x, $y); // [9, 8, 5, 0]
$products    = Map\Multi::multiply($x, $y); // [10, 20, 50, 100]
$quotients   = Map\Multi::divide($x, $y);   // [10, 5, 2, 1]
$maxes       = Map\Multi::max($x, $y);      // [10, 10, 10, 10]
$mins        = Map\Multi::mins($x, $y);     // [1, 2, 5, 10]

// All functions work on multiple arrays; not limited to just two
$x    = [10, 10, 10, 10];
$y    = [1,   2,  5, 10];
$z    = [4,   5,  6,  7];
$sums = Map\Multi::add($x, $y, $z); // [15, 17, 21, 27]

Functions - Polynomial

use MathPHP\Functions\Polynomial;

// Polynomial x² + 2x + 3
$coefficients = [1, 2, 3]
$polynomial   = new Polynomial($coefficients);

// Evaluate for x = 3
$x = 3;
$y = $polynomial($x);  // 18: 3² + 2*3 + 3

// Calculus
$derivative = $polynomial->differentiate();  // Polynomial 2x + 2
$integral   = $polynomial->integrate();      // Polynomial ⅓x³ + x² + 3x

// Arithmetic
$sum        = $polynomial->add($polynomial);       // Polynomial 2x² + 4x + 6
$sum        = $polynomial->add(2);                 // Polynomial x² + 2x + 5
$difference = $polynomial->subtract($polynomial);  // Polynomial 0
$difference = $polynomial->subtract(2);            // Polynomial x² + 2x + 1
$product    = $polynomial->multiply($polynomial);  // Polynomial x⁴ + 4x³ + 10x² + 12x + 9
$product    = $polynomial->multiply(2);            // Polynomial 2x² + 4x + 6
$negated    = $polynomial->negate();               // Polynomial -x² - 2x - 3

// Data
$degree       = $polynomial->getDegree();        // 2
$coefficients = $polynomial->getCoefficients();  // [1, 2, 3]

// String representation
print($polynomial);  // x² + 2x + 3

// Roots
$polynomial = new Polynomial([1, -3, -4]);
$roots      = $polynomial->roots();         // [-1, 4]

Functions - Special Functions

use MathPHP\Functions\Special;

// Gamma function Γ(z)
$z = 4;
$Γ = Special::gamma($z);          // Uses gamma definition for integers and half integers; uses Lanczos approximation for real numbers
$Γ = Special::gammaLanczos($z);   // Lanczos approximation
$Γ = Special::gammaStirling($z);  // Stirling approximation

// Incomplete gamma functions - γ(s,t), Γ(s,x), P(s,x)
list($x, $s) = [1, 2];
$γ = Special::lowerIncompleteGamma($x, $s);
$Γ = Special::upperIncompleteGamma($x, $s);
$P = Special::regularizedLowerIncompleteGamma($x, $s);

// Beta function
list($x, $y) = [1, 2];
$β = Special::beta($x, $y);

// Incomplete beta functions
list($x, $a, $b) = [0.4, 2, 3];
$B  = Special::incompleteBeta($x, $a, $b);
$Iₓ = Special::regularizedIncompleteBeta($x, $a, $b);

// Multivariate beta function
$αs = [1, 2, 3];
$β  = Special::multivariateBeta($αs);

// Error function (Gauss error function)
$error = Special::errorFunction(2);              // same as erf
$error = Special::erf(2);                        // same as errorFunction
$error = Special::complementaryErrorFunction(2); // same as erfc
$error = Special::erfc(2);                       // same as complementaryErrorFunction

// Hypergeometric functions
$pFq = Special::generalizedHypergeometric($p, $q, $a, $b, $c, $z);
$F₁ = Special::confluentHypergeometric($a, $b, $z);
$F₁ = Special::hypergeometric($a, $b, $c, $z);

// Sign function (also known as signum or sgn)
$x    = 4;
$sign = Special::signum($x); // same as sgn
$sign = Special::sgn($x);    // same as signum

// Logistic function (logistic sigmoid function)
$x₀ = 2; // x-value of the sigmoid's midpoint
$L  = 3; // the curve's maximum value
$k  = 4; // the steepness of the curve
$x  = 5;
$logistic = Special::logistic($x₀, $L, $k, $x);

// Sigmoid function
$t = 2;
$sigmoid = Special::sigmoid($t);

// Softmax function
$𝐳    = [1, 2, 3, 4, 1, 2, 3];
$σ⟮𝐳⟯ⱼ = Special::softmax($𝐳);

Information Theory - Entropy

use MathPHP\InformationTheory\Entropy;

// Probability distributions
$p = [0.2, 0.5, 0.3];
$q = [0.1, 0.4, 0.5];

// Shannon entropy
$bits  = Entropy::shannonEntropy($p);         // log₂
$nats  = Entropy::shannonNatEntropy($p);      // ln
$harts = Entropy::shannonHartleyEntropy($p);  // log₁₀

// Cross entropy
$H⟮p、q⟯ = Entropy::crossEntropy($p, $q);       // log₂

// Joint entropy
$P⟮x、y⟯ = [1/2, 1/4, 1/4, 0];
H⟮x、y⟯ = Entropy::jointEntropy($P⟮x、y⟯);        // log₂

// Rényi entropy
$α    = 0.5;
$Hₐ⟮X⟯ = Entropy::renyiEntropy($p, $α);         // log₂

// Perplexity
$perplexity = Entropy::perplexity($p);         // log₂

Linear Algebra - Matrix

use MathPHP\LinearAlgebra\Matrix;
use MathPHP\LinearAlgebra\MatrixFactory;

// Create an m × n matrix from an array of arrays
$matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
];
$A = MatrixFactory::create($matrix);

// Basic matrix data
$array = $A->getMatrix();  // Original array of arrays
$rows  = $A->getM();       // number of rows
$cols  = $A->getN();       // number of columns

// Basic matrix element getters (zero-based indexing)
$row = $A->getRow(2);
$col = $A->getColumn(2);
$Aᵢⱼ = $A->get(2, 2);
$Aᵢⱼ = $A[2][2];

// Row operations
list($mᵢ, $mⱼ, $k) = [1, 2, 5];
$R = $A->rowInterchange($mᵢ, $mⱼ);
$R = $A->rowMultiply($mᵢ, $k);     // Multiply row mᵢ by k
$R = $A->rowAdd($mᵢ, $mⱼ, $k);     // Add k * row mᵢ to row mⱼ
$R = $A->rowExclude($mᵢ);          // Exclude row $mᵢ

// Column operations
list($nᵢ, $nⱼ, $k) = [1, 2, 5];
$R = $A->columnInterchange($nᵢ, $nⱼ);
$R = $A->columnMultiply($nᵢ, $k);     // Multiply column nᵢ by k
$R = $A->columnAdd($nᵢ, $nⱼ, $k);     // Add k * column nᵢ to column nⱼ
$R = $A->columnExclude($nᵢ);          // Exclude column $nᵢ

// Matrix augmentations - return a new Matrix
$AB⟯ = $A->augment($B);        // Augment on the right - standard augmentation
$AI⟯ = $A->augmentIdentity();  // Augment with the identity matrix
$AB⟯ = $A->augmentBelow($B);
$AB⟯ = $A->augmentAbove($B);
$BA⟯ = $A->augmentLeft($B);

// Matrix arithmetic operations - return a new Matrix
$AB = $A->add($B);
$AB  = $A->directSum($B);
$AB  = $A->kroneckerSum($B);
$AB  = $A->subtract($B);
$AB   = $A->multiply($B);
$A  = $A->scalarMultiply(2);
$A2 = $A->scalarDivide(2);
$A   = $A->negate();
$AB  = $A->hadamardProduct($B);
$AB  = $A->kroneckerProduct($B);

// Matrix operations - return a new Matrix
$Aᵀ   = $A->transpose();
$D    = $A->diagonal();
$A⁻¹   = $A->inverse();
$Mᵢⱼ   = $A->minorMatrix($mᵢ, $nⱼ);        // Square matrix with row mᵢ and column nⱼ removed
$Mk    = $A->leadingPrincipalMinor($k);    // kᵗʰ-order leading principal minor
$CM    = $A->cofactorMatrix();
$B     = $A->meanDeviation();              // optional parameter to specify data direction (variables in 'rows' or 'columns')
$S     = $A->covarianceMatrix();           // optional parameter to specify data direction (variables in 'rows' or 'columns')
$adjA⟯ = $A->adjugate();
$Mᵢⱼ   = $A->submatrix($mᵢ, $nᵢ, $mⱼ, $nⱼ) // Submatrix of A from row mᵢ, column nᵢ to row mⱼ, column nⱼ
$H     = $A->householder();

// Matrix value operations - return a value
$trA⟯   = $A->trace();
$|A|    = $a->det();              // Determinant
$Mᵢⱼ    = $A->minor($mᵢ, $nⱼ);    // First minor
$Cᵢⱼ    = $A->cofactor($mᵢ, $nⱼ);
$rankA⟯ = $A->rank();

// Matrix vector operations - return a new Vector
$AB = $A->vectorMultiply($X₁);
$M  = $A->rowSums();
$M  = $A->columnSums();
$M  = $A->rowMeans();
$M  = $A->columnMeans();

// Matrix norms - return a value
$A‖₁ = $A->oneNorm();
$AF = $A->frobeniusNorm(); // Hilbert–Schmidt norm
$A‖∞ = $A->infinityNorm();
$max   = $A->maxNorm();

// Matrix reductions
$ref  = $A->ref();   // Matrix in row echelon form
$rref = $A->rref();  // Matrix in reduced row echelon form

// Matrix decompositions
// LU decomposition
$LU = $A->luDecomposition();
$L  = $LU->L;  // lower triangular matrix
$U  = $LU->U;  // upper triangular matrix
$P  = $LU-P;   // permutation matrix

// QR decomposition
$QR = $A->qrDecomposition();
$Q  = $QR->Q;  // orthogonal matrix
$R  = $QR->R;  // upper triangular matrix

// Crout decomposition
$LU = $A->croutDecomposition();
$L  = $LU->L;  // lower triangular matrix
$U  = $LU->U;  // normalized upper triangular matrix

// Cholesky decomposition
$LLᵀ = $A->choleskyDecomposition();
$L   = $LLᵀ->L;   // lower triangular matrix
$LT  = $LLᵀ->LT;  // transpose of lower triangular matrix

// Eigenvalues and eigenvectors
$eigenvalues   = $A->eigenvalues();   // array of eigenvalues
$eigenvecetors = $A->eigenvectors();  // Matrix of eigenvectors

// Solve a linear system of equations: Ax = b
$b = new Vector(1, 2, 3);
$x = $A->solve($b);

// Map a function over each element
$func = function($x) {
    return $x * 2;
};
$R = $A->map($func);  // using closure
$R = $A->map('abs');  // using callable

// Map a function over each row
$array = $A->mapRows('array_reverse');  // using callable returns matrix-like array of arrays
$array = $A->mapRows('array_sum');     // using callable returns array of aggregate calculations

// Matrix comparisons
$bool = $A->isEqual($B);

// Matrix properties - return a bool
$bool = $A->isSquare();
$bool = $A->isSymmetric();
$bool = $A->isSkewSymmetric();
$bool = $A->isSingular();
$bool = $A->isNonsingular();           // Same as isInvertible
$bool = $A->isInvertible();            // Same as isNonsingular
$bool = $A->isPositiveDefinite();
$bool = $A->isPositiveSemidefinite();
$bool = $A->isNegativeDefinite();
$bool = $A->isNegativeSemidefinite();
$bool = $A->isLowerTriangular();
$bool = $A->isUpperTriangular();
$bool = $A->isTriangular();
$bool = $A->isDiagonal();
$bool = $A->isRectangularDiagonal();
$bool = $A->isUpperBidiagonal();
$bool = $A->isLowerBidiagonal();
$bool = $A->isBidiagonal();
$bool = $A->isTridiagonal();
$bool = $A->isUpperHessenberg();
$bool = $A->isLowerHessenberg();
$bool = $A->isOrthogonal();
$bool = $A->isNormal();
$bool = $A->isIdempotent();
$bool = $A->isNilpotent();
$bool = $A->isInvolutory();
$bool = $A->isSignature();
$bool = $A->isRef();
$bool = $A->isRref();

// Other representations of matrix data
$vectors = $A->asVectors();                 // array of column vectors
$D       = $A->getDiagonalElements();       // array of the diagonal elements
$d       = $A->getSuperdiagonalElements();  // array of the superdiagonal elements
$d       = $A->getSubdiagonalElements();    // array of the subdiagonal elements

// String representation - Print a matrix
print($A);
/*
 [1, 2, 3]
 [2, 3, 4]
 [3, 4, 5]
 */

// PHP Predefined Interfaces
$json = json_encode($A); // JsonSerializable
$Aᵢⱼ  = $A[$mᵢ][$nⱼ];    // ArrayAccess

Linear Algebra - Matrix Construction (Factory)

$matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
];

// Matrix factory creates most appropriate matrix
$A = MatrixFactory::create($matrix);

// Matrix factory can create a matrix from an array of column vectors
use MathPHP\LinearAlgebra\Vector;
$X₁ = new Vector([1, 4, 7]);
$X₂ = new Vector([2, 5, 8]);
$X₃ = new Vector([3, 6, 9]);
$A  = MatrixFactory::createFromVectors([$X₁, $X₂, $X₃]);

// Specialized matrices
list($m, $n, $k, $angle, $size) = [4, 4, 2, 3.14159, 2];
$identity_matrix                = MatrixFactory::identity($n);                   // Ones on the main diagonal
$zero_matrix                    = MatrixFactory::zero($m, $n);                   // All zeros
$ones_matrix                    = MatrixFactory::one($m, $n);                    // All ones
$eye_matrix                     = MatrixFactory::eye($m, $n, $k);                // Ones (or other value) on the k-th diagonal
$exchange_matrix                = MatrixFactory::exchange($n);                   // Ones on the reverse diagonal
$downshift_permutation_matrix   = MatrixFactory::downshiftPermutation($n);       // Permutation matrix that pushes the components of a vector down one notch with wraparound
$upshift_permutation_matrix     = MatrixFactory::upshiftPermutation($n);         // Permutation matrix that pushes the components of a vector up one notch with wraparound
$diagonal_matrix                = MatrixFactory::diagonal([1, 2, 3]);            // 3 x 3 diagonal matrix with zeros above and below the diagonal
$hilbert_matrix                 = MatrixFactory::hilbert($n);                    // Square matrix with entries being the unit fractions
$vandermonde_matrix             = MatrixFactory::vandermonde([1, 2, 3], 4);      // 4 x 3 Vandermonde matrix
$random_matrix                  = MatrixFactory::random($m, $n);                 // m x n matrix of random integers
$givens_matrix                  = MatrixFactory::givens($m, $n, $angle, $size);  // givens rotation matrix

Linear Algebra - Vector

use MathPHP\LinearAlgebra\Vector;

// Vector
$A = new Vector([1, 2]);
$B = new Vector([2, 4]);

// Basic vector data
$array = $A->getVector();
$n     = $A->getN();           // number of elements
$M     = $A->asColumnMatrix(); // Vector as an nx1 matrix
$M     = $A->asRowMatrix();    // Vector as a 1xn matrix

// Basic vector elements (zero-based indexing)
$item = $A->get(1);

// Vector numeric operations - return a value
$sum               = $A->sum();
$A│               = $A->length();                            // same as l2Norm
$max               = $A->max();
$min               = $A->min();
$AB               = $A->dotProduct($B);                      // same as innerProduct
$AB               = $A->innerProduct($B);                    // same as dotProduct
$A⊥⋅B              = $A->perpDotProduct($B);
$radAngle          = $A->angleBetween($B);                    // angle in radians
$degAngle          = $A->angleBetween($B, $inDegrees = true); // angle in degrees
$taxicabDistance   = $A->l1Distance($B);                      // same as minkowskiDistance($B, 1)
$euclidDistance    = $A->l2Distance($B);                      // same as minkowskiDistance($B, 2)
$minkowskiDistance = $A->minkowskiDistance($B, $p = 2);

// Vector arithmetic operations - return a Vector
$AB  = $A->add($B);
$AB   = $A->subtract($B);
$A×B   = $A->multiply($B);
$AB  = $A->divide($B);
$kA    = $A->scalarMultiply($k);
$A/k  = $A->scalarDivide($k);

// Vector operations - return a Vector or Matrix
$AB  = $A->outerProduct($B);  // Same as direct product
$AB    = $A->directProduct($B); // Same as outer product
$AxB   = $A->crossProduct($B);
$AB   = $A->kroneckerProduct($B);
$Â     = $A->normalize();
$A⊥    = $A->perpendicular();
$projA = $A->projection($B);   // projection of A onto B
$perpA = $A->perp($B);         // perpendicular of A on B

// Vector norms - return a value
$l₁norm = $A->l1Norm();
$l²norm = $A->l2Norm();
$pnorm  = $A->pNorm();
$max    = $A->maxNorm();

// String representation
print($A);  // [1, 2]

// PHP standard interfaces
$n    = count($A);                // Countable
$json = json_encode($A);          // JsonSerializable
$Aᵢ   = $A[$i];                   // ArrayAccess
foreach ($A as $element) { ... }  // Iterator

Number - Arbitrary Length Integers

use MathPHP\Number;
use MathPHP\Functions;

// Create arbitrary-length big integers from int or string
$bigInt = new Number\ArbitraryInteger('876937869482938749389832');

// Unary functions
$−bigInt  = $bigInt->negate();
$√bigInt  = $bigInt->isqrt();       // Integer square root
$│bitInt│ = $bigInt->abs();         // Absolute value
$bigInt!  = $bigInt->fact();
$bool     = $bigInt->isPositive();

// Binary functions
$sum                  = $bigInt->add($bigInt);
$difference           = $bigInt->subtract($bigInt);
$product              = $bigInt->multiply($bigInt);
$quotient             = $bigInt->intdiv($divisor);
$mod                  = $bigInt->mod($divisor);
list($quotient, $mod) = $bigInt->fullIntdiv($divisor);
$pow                  = $bigInt->pow($exponent);
$shifted              = $bigInt->leftShift(2);

// Comparison functions
$bool = $bigInt->equals($bigInt);
$bool = $bigInt->greaterThan($bigInt);
$bool = $bigInt->lessThan($bigInt);

// Conversions
$int    = $bigInt->toInt();
$float  = $bigInt->toFloat();
$binary = $bigInt->toBinary();
$string = (string) $bigInt;

// Functions
$ackermann    = Functions\ArbitraryInteger::ackermann($bigInt);
$randomBigInt = Functions\ArbitaryInteger::rand($intNumberOfBytes);

Number - Complex Numbers

use MathPHP\Number\Complex;

list($r, $i) = [2, 4];
$complex     = new Complex($r, $i);

// Accessors
$r = $complex->r;
$i = $complex->i;

// Unary functions
$conjugate     = $complex->complexConjugate();
$│c│           = $complex->abs();     // absolute value (modulus)
$arg⟮c⟯         = $complex->arg();     // argument (phase)
$√c            = $complex->sqrt();    // positive square root
list($z₁, $z₂) = $complex->roots();
$c⁻¹           = $complex->inverse();
$−c            = $complex->negate();
$polar         = $complex->polarForm();

// Binary functions
$c+c = $complex->add($complex);
$c−c  = $complex->subtract($complex);
$c×c  = $complex->multiply($complex);
$c/c = $complex->divide($complex);

// Other functions
$bool   = $complex->equals($complex);
$string = (string) $complex;

Number - Rational Numbers

use MathPHP\Number\Rational;

$whole       = 0;
$numerator   = 2;
$denominator = 3;

$rational = new Rational($whole, $numerator, $denominator);  // ²/₃

// Get individual parts
$whole       = $rational->getWholePart();
$numerator   = $rational->getNumerator();
$denominator = $rational->getDenominator();

// Unary functions
$│rational│ = $rational->abs();
$inverse    = $rational->inverse();

// Binary functions
$sum            = $rational->add($rational);
$diff           = $rational->subtract($rational);
$product        = $rational->multiply($rational);
$quotient       = $rational->divide($rational);
$exponentiation = $rational->pow(2);

// Other functions
$bool   = $rational->equals($rational);
$float  = $rational->toFloat();
$string = (string) $rational;

Number Theory - Integers

use MathPHP\NumberTheory\Integer;

$n = 225;

// Prime factorization
$factors = Integer::primeFactorization($n);

// Divisor function
$int  = Integer::numberOfDivisors($n);
$int  = Integer::sumOfDivisors($n);

// Aliquot sums
$int  = Integer::aliquotSum($n);        // sum-of-divisors - n
$bool = Integer::isPerfectNumber($n);   // n = aliquot sum
$bool = Integer::isDeficientNumber($n); // n > aliquot sum
$bool = Integer::isAbundantNumber($n);  // n < aliquot sum

// Totients
$int  = Integer::totient($n);        // Jordan's totient k=1 (Euler's totient)
$int  = Integer::totient($n, 2);     // Jordan's totient k=2
$int  = Integer::cototient($n);      // Cototient
$int  = Integer::reducedTotient($n); // Carmichael's function

// Möbius function
$int  = Integer::mobius($n);

// Radical/squarefree kernel
$int  = Integer::radical($n);

// Squarefree
$bool = Integer::isSquarefree($n);

// Refactorable number
$bool = Integer::isRefactorableNumber($n);

// Sphenic number
$bool = Integer::isSphenicNumber($n);

// Perfect powers
$bool        = Integer::isPerfectPower($n);
list($m, $k) = Integer::perfectPower($n);

// Coprime
$bool = Integer::coprime(4, 35);

// Even and odd
$bool = Integer::isEven($n);
$bool = Integer::isOdd($n);

Numerical Analysis - Interpolation

use MathPHP\NumericalAnalysis\Interpolation;

// Interpolation is a method of constructing new data points with the range
// of a discrete set of known data points.
// Each integration method can take input in two ways:
//  1) As a set of points (inputs and outputs of a function)
//  2) As a callback function, and the number of function evaluations to
//     perform on an interval between a start and end point.

// Input as a set of points
$points = [[0, 1], [1, 4], [2, 9], [3, 16]];

// Input as a callback function
$f⟮x⟯ = function ($x) {
    return $x**2 + 2 * $x + 1;
};
list($start, $end, $n) = [0, 3, 4];

// Lagrange Polynomial
// Returns a function p(x) of x
$p = Interpolation\LagrangePolynomial::interpolate($points);                // input as a set of points
$p = Interpolation\LagrangePolynomial::interpolate($f⟮x⟯, $start, $end, $n); // input as a callback function

$p(0) // 1
$p(3) // 16

// Nevilles Method
// More accurate than Lagrange Polynomial Interpolation given the same input
// Returns the evaluation of the interpolating polynomial at the $target point
$target = 2;
$result = Interpolation\NevillesMethod::interpolate($target, $points);                // input as a set of points
$result = Interpolation\NevillesMethod::interpolate($target, $f⟮x⟯, $start, $end, $n); // input as a callback function

// Newton Polynomial (Forward)
// Returns a function p(x) of x
$p = Interpolation\NewtonPolynomialForward::interpolate($points);                // input as a set of points
$p = Interpolation\NewtonPolynomialForward::interpolate($f⟮x⟯, $start, $end, $n); // input as a callback function

$p(0) // 1
$p(3) // 16

// Natural Cubic Spline
// Returns a piecewise polynomial p(x)
$p = Interpolation\NaturalCubicSpline::interpolate($points);                // input as a set of points
$p = Interpolation\NaturalCubicSpline::interpolate($f⟮x⟯, $start, $end, $n); // input as a callback function

$p(0) // 1
$p(3) // 16

// Clamped Cubic Spline
// Returns a piecewise polynomial p(x)

// Input as a set of points
$points = [[0, 1, 0], [1, 4, -1], [2, 9, 4], [3, 16, 0]];

// Input as a callback function
$f⟮x⟯ = function ($x) {
    return $x**2 + 2 * $x + 1;
};
$f’⟮x⟯ = function ($x) {
    return 2*$x + 2;
};
list($start, $end, $n) = [0, 3, 4];

$p = Interpolation\ClampedCubicSpline::interpolate($points);                // input as a set of points
$p = Interpolation\ClampedCubicSpline::interpolate($f⟮x⟯, $f’⟮x⟯, $start, $end, $n); // input as a callback function

$p(0); // 1
$p(3); // 16

// Regular Grid Interpolation
// Returns a scalar

// Points defining the regular grid
$xs = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
$ys = [10, 11, 12, 13, 14, 15, 16, 17, 18, 19];
$zs = [110, 111, 112, 113, 114, 115, 116, 117, 118, 119];

// Data on the regular grid in n dimensions
$data = [];
$func = function ($x, $y, $z) {
    return 2 * $x + 3 * $y - $z;
};
foreach ($xs as $i => $x) {
    foreach ($ys as $j => $y) {
        foreach ($zs as $k => $z) {
            $data[$i][$j][$k] = $func($x, $y, $z);
        }
    }
}

// Constructing a RegularGridInterpolator
$rgi = new Interpolation\RegularGridInterpolator([$xs, $ys, $zs], $data, 'linear');  // 'nearest' method also available

// Interpolating coordinates on the regular grid
$coordinates   = [2.21, 12.1, 115.9];
$interpolation = $rgi($coordinates);  // -75.18

Numerical Analysis - Numerical Differentiation

use MathPHP\NumericalAnalysis\NumericalDifferentiation;

// Numerical Differentiation approximates the derivative of a function.
// Each Differentiation method can take input in two ways:
//  1) As a set of points (inputs and outputs of a function)
//  2) As a callback function, and the number of function evaluations to
//     perform on an interval between a start and end point.

// Input as a callback function
$f⟮x⟯ = function ($x) {
    return $x**2 + 2 * $x + 1;
};

// Three Point Formula
// Returns an approximation for the derivative of our input at our target

// Input as a set of points
$points = [[0, 1], [1, 4], [2, 9]];

$target = 0;
list($start, $end, $n) = [0, 2, 3];
$derivative = NumericalDifferentiation\ThreePointFormula::differentiate($target, $points);                // input as a set of points
$derivative = NumericalDifferentiation\ThreePointFormula::differentiate($target, $f⟮x⟯, $start, $end, $n); // input as a callback function

// Five Point Formula
// Returns an approximation for the derivative of our input at our target

// Input as a set of points
$points = [[0, 1], [1, 4], [2, 9], [3, 16], [4, 25]];

$target = 0;
list($start, $end, $n) = [0, 4, 5];
$derivative = NumericalDifferentiation\FivePointFormula::differentiate($target, $points);                // input as a set of points
$derivative = NumericalDifferentiation\FivePointFormula::differentiate($target, $f⟮x⟯, $start, $end, $n); // input as a callback function

// Second Derivative Midpoint Formula
// Returns an approximation for the second derivative of our input at our target

// Input as a set of points
$points = [[0, 1], [1, 4], [2, 9];

$target = 1;
list($start, $end, $n) = [0, 2, 3];
$derivative = NumericalDifferentiation\SecondDerivativeMidpointFormula::differentiate($target, $points);                // input as a set of points
$derivative = NumericalDifferentiation\SecondDerivativeMidpointFormula::differentiate($target, $f⟮x⟯, $start, $end, $n); // input as a callback function

Numerical Analysis - Numerical Integration

use MathPHP\NumericalAnalysis\NumericalIntegration;

// Numerical integration approximates the definite integral of a function.
// Each integration method can take input in two ways:
//  1) As a set of points (inputs and outputs of a function)
//  2) As a callback function, and the number of function evaluations to
//     perform on an interval between a start and end point.

// Trapezoidal Rule (closed Newton-Cotes formula)
$points = [[0, 1], [1, 4], [2, 9], [3, 16]];
$∫f⟮x⟯dx = NumericalIntegration\TrapezoidalRule::approximate($points); // input as a set of points

$f⟮x⟯ = function ($x) {
    return $x**2 + 2 * $x + 1;
};
list($start, $end, $n) = [0, 3, 4];
$∫f⟮x⟯dx = NumericalIntegration\TrapezoidalRule::approximate($f⟮x⟯, $start, $end, $n); // input as a callback function

// Simpsons Rule (closed Newton-Cotes formula)
$points = [[0, 1], [1, 4], [2, 9], [3, 16], [4,3]];
$∫f⟮x⟯dx = NumericalIntegration\SimpsonsRule::approximate($points); // input as a set of points

$f⟮x⟯ = function ($x) {
    return $x**2 + 2 * $x + 1;
};
list($start, $end, $n) = [0, 3, 5];
$∫f⟮x⟯dx = NumericalIntegration\SimpsonsRule::approximate($f⟮x⟯, $start, $end, $n); // input as a callback function

// Simpsons 3/8 Rule (closed Newton-Cotes formula)
$points = [[0, 1], [1, 4], [2, 9], [3, 16]];
$∫f⟮x⟯dx = NumericalIntegration\SimpsonsThreeEighthsRule::approximate($points); // input as a set of points

$f⟮x⟯ = function ($x) {
    return $x**2 + 2 * $x + 1;
};
list($start, $end, $n) = [0, 3, 5];
$∫f⟮x⟯dx = NumericalIntegration\SimpsonsThreeEighthsRule::approximate($f⟮x⟯, $start, $end, $n); // input as a callback function

// Booles Rule (closed Newton-Cotes formula)
$points = [[0, 1], [1, 4], [2, 9], [3, 16], [4, 25]];
$∫f⟮x⟯dx = NumericalIntegration\BoolesRule::approximate($points); // input as a set of points

$f⟮x⟯ = function ($x) {
    return $x**3 + 2 * $x + 1;
};
list($start, $end, $n) = [0, 4, 5];
$∫f⟮x⟯dx = NumericalIntegration\BoolesRuleRule::approximate($f⟮x⟯, $start, $end, $n); // input as a callback function

// Rectangle Method (open Newton-Cotes formula)
$points = [[0, 1], [1, 4], [2, 9], [3, 16]];
$∫f⟮x⟯dx = NumericalIntegration\RectangleMethod::approximate($points); // input as a set of points

$f⟮x⟯ = function ($x) {
    return $x**2 + 2 * $x + 1;
};
list($start, $end, $n) = [0, 3, 4];
$∫f⟮x⟯dx = NumericalIntegration\RectangleMethod::approximate($f⟮x⟯, $start, $end, $n); // input as a callback function

// Midpoint Rule (open Newton-Cotes formula)
$points = [[0, 1], [1, 4], [2, 9], [3, 16]];
$∫f⟮x⟯dx = NumericalIntegration\MidpointRule::approximate($points); // input as a set of points

$f⟮x⟯ = function ($x) {
    return $x**2 + 2 * $x + 1;
};
list($start, $end, $n) = [0, 3, 4];
$∫f⟮x⟯dx = NumericalIntegration\MidpointRule::approximate($f⟮x⟯, $start, $end, $n); // input as a callback function

Numerical Analysis - Root Finding

use MathPHP\NumericalAnalysis\RootFinding;

// Root-finding methods solve for a root of a polynomial.

// f(x) = x⁴ + 8x³ -13x² -92x + 96
$f⟮x⟯ = function($x) {
    return $x**4 + 8 * $x**3 - 13 * $x**2 - 92 * $x + 96;
};

// Newton's Method
$args     = [-4.1];  // Parameters to pass to callback function (initial guess, other parameters)
$target   = 0;       // Value of f(x) we a trying to solve for
$tol      = 0.00001; // Tolerance; how close to the actual solution we would like
$position = 0;       // Which element in the $args array will be changed; also serves as initial guess. Defaults to 0.
$x        = RootFinding\NewtonsMethod::solve($f⟮x⟯, $args, $target, $tol, $position); // Solve for x where f(x) = $target

// Secant Method
$p₀  = -1;      // First initial approximation
$p₁  = 2;       // Second initial approximation
$tol = 0.00001; // Tolerance; how close to the actual solution we would like
$x   = RootFinding\SecantMethod::solve($f⟮x⟯, $p₀, $p₁, $tol); // Solve for x where f(x) = 0

// Bisection Method
$a   = 2;       // The start of the interval which contains a root
$b   = 5;       // The end of the interval which contains a root
$tol = 0.00001; // Tolerance; how close to the actual solution we would like
$x   = RootFinding\BisectionMethod::solve($f⟮x⟯, $a, $b, $tol); // Solve for x where f(x) = 0

// Fixed-Point Iteration
// f(x) = x⁴ + 8x³ -13x² -92x + 96
// Rewrite f(x) = 0 as (x⁴ + 8x³ -13x² + 96)/92 = x
// Thus, g(x) = (x⁴ + 8x³ -13x² + 96)/92
$g⟮x⟯ = function($x) {
    return ($x**4 + 8 * $x**3 - 13 * $x**2 + 96)/92;
};
$a   = 0;       // The start of the interval which contains a root
$b   = 2;       // The end of the interval which contains a root
$p   = 0;       // The initial guess for our root
$tol = 0.00001; // Tolerance; how close to the actual solution we would like
$x   = RootFinding\FixedPointIteration::solve($g⟮x⟯, $a, $b, $p, $tol); // Solve for x where f(x) = 0

Probability - Combinatorics

use MathPHP\Probability\Combinatorics;

list($n, $x, $k) = [10, 3, 4];

// Factorials
$n!  = Combinatorics::factorial($n);
$n‼︎   = Combinatorics::doubleFactorial($n);
$x⁽ⁿ⁾ = Combinatorics::risingFactorial($x, $n);
$x₍ᵢ₎ = Combinatorics::fallingFactorial($x, $n);
$!n  = Combinatorics::subfactorial($n);

// Permutations
$nPn = Combinatorics::permutations($n);     // Permutations of n things, taken n at a time (same as factorial)
$nPk = Combinatorics::permutations($n, $k); // Permutations of n things, taking only k of them

// Combinations
$nCk  = Combinatorics::combinations($n, $k);                            // n choose k without repetition
$nC′k = Combinatorics::combinations($n, $k, Combinatorics::REPETITION); // n choose k with repetition (REPETITION const = true)

// Central binomial coefficient
$cbc = Combinatorics::centralBinomialCoefficient($n);

// Catalan number
$Cn = Combinatorics::catalanNumber($n);

// Lah number
$L⟮n、k⟯ = Combinatorics::lahNumber($n, $k)

// Multinomial coefficient
$groups    = [5, 2, 3];
$divisions = Combinatorics::multinomial($groups);

Probability - Continuous Distributions

use MathPHP\Probability\Distribution\Continuous;

$p = 0.1;

// Beta distribution
$α      = 1; // shape parameter
$β      = 1; // shape parameter
$x      = 2;
$beta   = new Continuous\Beta($α, $β);
$pdf    = $beta->pdf($x);
$cdf    = $beta->cdf($x);
$icdf   = $beta->inverse($p);
$μ      = $beta->mean();
$median = $beta->median();
$mode   = $beta->mode();
$σ²     = $beta->variance();

// Cauchy distribution
$x₀     = 2; // location parameter
$γ      = 3; // scale parameter
$x      = 1;
$cauchy = new Continuous\Cauchy(x₀, γ);
$pdf    = $cauchy->pdf(x);
$cdf    = $cauchy->cdf(x);
$icdf   = $cauchy->inverse($p);
$μ      = $cauchy->mean();
$median = $cauchy->median();
$mode   = $cauchy->mode();

// χ²-distribution (Chi-Squared)
$k      = 2; // degrees of freedom
$x      = 1;
$χ²     = new Continuous\ChiSquared($k);
$pdf    = $χ²->pdf($x);
$cdf    = $χ²->cdf($x);
$μ      = $χ²->mean($x);
$median = $χ²->median();
$mode   = $χ²->mode();
$σ²     = $χ²->variance();

// Dirac delta distribution
$x     = 1;
$dirac = new Continuous\DiracDelta();
$pdf   = $dirac->pdf($x);
$cdf   = $dirac->cdf($x);
$icdf  = $dirac->inverse($p);
$μ     = $dirac->mean();

// Exponential distribution
$λ           = 1; // rate parameter
$x           = 2;
$exponential = new Continuous\Exponential($λ);
$pdf         = $exponential->pdf($x);
$cdf         = $exponential->cdf($x);
$icdf        = $exponential->inverse($p);
$μ           = $exponential->mean();
$median      = $exponential->median();
$σ²          = $exponential->variance();

// F-distribution
$d₁   = 3; // degree of freedom v1
$d₂   = 4; // degree of freedom v2
$x    = 2;
$f    = new Continuous\F($d₁, $d₂);
$pdf  = $f->pdf($x);
$cdf  = $f->cdf($x);
$μ    = $f->mean();
$mode = $f->mode();
$σ²   = $f->variance();

// Gamma distribution
$k      = 2; // shape parameter
$θ      = 3; // scale parameter
$x      = 4;
$gamma  = new Continuous\Gamma($k, $θ);
$pdf    = $gamma->pdf($x);
$cdf    = $gamma->cdf($x);
$μ      = $gamma->mean();
$median = $gamma->median();
$mode   = $gamma->mode();
$σ²     = $gamma->variance();

// Laplace distribution
$μ       = 1;   // location parameter
$b       = 1.5; // scale parameter (diversity)
$x       = 1;
$laplace = new Continuous\Laplace($μ, $b);
$pdf     = $laplace->pdf($x);
$cdf     = $laplace->cdf($x);
$icdf    = $laplace->inverse($p);
$μ       = $laplace->mean();
$median  = $laplace->median();
$mode    = $laplace->mode();
$σ²      = $laplace->variance();

// Logistic distribution
$μ        = 2;   // location parameter
$s        = 1.5; // scale parameter
$x        = 3;
$logistic = new Continuous\Logistic($μ, $s);
$pdf      = $logistic->pdf($x);
$cdf      = $logistic->cdf($x);
$icdf     = $logistic->inverse($p);
$μ        = $logistic->mean();
$median   = $logistic->median();
$mode     = $logistic->mode();
$σ²       = $logisitic->variance();

// Log-logistic distribution (Fisk distribution)
$α           = 1; // scale parameter
$β           = 1; // shape parameter
$x           = 2;
$logLogistic = new Continuous\LogLogistic($α, $β);
$pdf         = $logLogistic->pdf($x);
$cdf         = $logLogistic->cdf($x);
$icdf        = $logLogistic->inverse($p);
$μ           = $logLogistic->mean();
$median      = $logLogistic->median();
$mode        = $logLogistic->mode();
$σ²          = $logLogistic->variance();

// Log-normal distribution
$μ         = 6;   // scale parameter
$σ         = 2;   // location parameter
$x         = 4.3;
$logNormal = new Continuous\LogNormal($μ, $σ);
$pdf       = $logNormal->pdf($x);
$cdf       = $logNormal->cdf($x);
$icdf      = $logNormal->inverse($p);
$μ         = $logNormal->mean();
$median    = $logNormal->median();
$mode      = $logNormal->mode();
$σ²        = $logNormal->variance();

// Noncentral T distribution
$ν            = 50; // degrees of freedom
$μ            = 10; // noncentrality parameter
$x            = 8;
$noncenetralT = new Continuous\NoncentralT($ν, $μ);
$pdf          = $noncenetralT->pdf($x);
$cdf          = $noncenetralT->cdf($x);
$μ            = $noncenetralT->mean();

// Normal distribution
$σ      = 1;
$μ      = 0;
$x      = 2;
$normal = new Continuous\Normal($μ, $σ);
$pdf    = $normal->pdf($x);
$cdf    = $normal->cdf($x);
$icdf   = $normal->inverse($p);
$μ      = $normal->mean();
$median = $normal->median();
$mode   = $normal->mode();
$σ²     = $normal->variance();

// Pareto distribution
$a      = 1; // shape parameter
$b      = 1; // scale parameter
$x      = 2;
$pareto = new Continuous\Pareto($a, $b);
$pdf    = $pareto->pdf($x);
$cdf    = $pareto->cdf($x);
$icdf   = $pareto->inverse($p);
$μ      = $pareto->mean();
$median = $pareto->median();
$mode   = $pareto->mode();
$σ²     = $pareto->variance();

// Standard normal distribution
$z              = 2;
$standardNormal = new Continuous\StandardNormal();
$pdf            = $standardNormal->pdf($z);
$cdf            = $standardNormal->cdf($z);
$icdf           = $standardNormal->inverse($p);
$μ              = $standardNormal->mean();
$median         = $standardNormal->median();
$mode           = $standardNormal->mode();
$σ²             = $standardNormal->variance();

// Student's t-distribution
$ν        = 3;   // degrees of freedom
$p        = 0.4; // proportion of area
$x        = 2;
$studentT = new Continuous\StudentT::pdf($ν);
$pdf      = $studentT->pdf($x);
$cdf      = $studentT->cdf($x);
$t        = $studentT->inverse2Tails($p);  // t such that the area greater than t and the area beneath -t is p
$μ        = $studentT->mean();
$median   = $studentT->median();
$mode     = $studentT->mode();
$σ²       = $studentT->variance();

// Uniform distribution
$a       = 1; // lower boundary of the distribution
$b       = 4; // upper boundary of the distribution
$x       = 2;
$uniform = new Continuous\Uniform($a, $b);
$pdf     = $uniform->pdf($x);
$cdf     = $uniform->cdf($x);
$μ       = $uniform->mean();
$median  = $uniform->median();
$mode    = $uniform->mode();
$σ²      = $uniform->variance();

// Weibull distribution
$k       = 1; // shape parameter
$λ       = 2; // scale parameter
$x       = 2;
$weibull = new Continuous\Weibull($k, $λ);
$pdf     = $weibull->pdf($x);
$cdf     = $weibull->cdf($x);
$icdf    = $weibull->inverse($p);
$μ       = $weibull->mean();
$median  = $weibull->median();
$mode    = $weibull->mode();

// Other CDFs - All continuous distributions - Replace {$distribution} with desired distribution.
$between = $distribution->between($x₁, $x₂);  // Probability of being between two points, x₁ and x₂
$outside = $distribution->outside($x₁, $x);   // Probability of being between below x₁ and above x₂
$above   = $distribution->above($x);          // Probability of being above x to ∞

// Random Number Generator
$random  = $distribution->rand();  // A random number with a given distribution

Probability - Discrete Distributions

use MathPHP\Probability\Distribution\Discrete;

// Bernoulli distribution (special case of binomial where n = 1)
$p         = 0.3;
$k         = 0;
$bernoulli = new Discrete\Bernoulli($p);
$pmf       = $bernoulli->pmf($k);
$cdf       = $bernoulli->cdf($k);
$μ         = $bernoulli->mean();
$median    = $bernoulli->median();
$mode      = $bernoulli->mode();
$σ²        = $bernoulli->variance();

// Binomial distribution
$n        = 2;   // number of events
$p        = 0.5; // probability of success
$r        = 1;   // number of successful events
$binomial = new Discrete\Binomial($n, $p);
$pmf      = $binomial->pmf($r);
$cdf      = $binomial->cdf($r);
$μ        = $binomial->mean();
$σ²       = $binomial->variance();

// Categorical distribution
$k             = 3;                                    // number of categories
$probabilities = ['a' => 0.3, 'b' => 0.2, 'c' => 0.5]; // probabilities for categorices a, b, and c
$categorical   = new Discrete\Categorical($k, $probabilities);
$pmf_a         = $categorical->pmf('a');
$mode          = $categorical->mode();

// Geometric distribution (failures before the first success)
$p         = 0.5; // success probability
$k         = 2;   // number of trials
$geometric = new Discrete\Geometric($p);
$pmf       = $geometric->pmf($k);
$cdf       = $geometric->cdf($k);
$μ         = $geometric->mean();
$median    = $geometric->median();
$mode      = $geometric->mode();
$σ²        = $geometric->variance();

// Hypergeometric distribution
$N        = 50; // population size
$K        = 5;  // number of success states in the population
$n        = 10; // number of draws
$k        = 4;  // number of observed successes
$hypergeo = new Discrete\Hypergeometric($N, $K, $n);
$pmf      = $hypergeo->pmf($k);
$cdf      = $hypergeo->cdf($k);
$μ        = $hypergeo->mean();
$mode     = $hypergeo->mode();
$σ²       = $hypergeo->variance();

// Negative binomial distribution (Pascal)
$r                = 1;   // number of failures until the experiment is stopped
$P                = 0.5; // probability of success on an individual trial
$x                = 2;   // number of successes
$negativeBinomial = new Discrete\NegativeBinomial($r, $p);
$pmf              = $negativeBinomial->pmf($x);
$cdf              = $negativeBinomial->cdf($x);
$μ                = $negativeBinomial->mean();
$mode             = $negativeBinomial->mode();
$σ²               = $negativeBinomial->variance();

// Pascal distribution (Negative binomial)
$r      = 1;   // number of failures until the experiment is stopped
$P      = 0.5; // probability of success on an individual trial
$x      = 2;   // number of successes
$pascal = new Discrete\Pascal($r, $p);
$pmf    = $pascal->pmf($x);
$cdf    = $pascal->cdf($x);
$μ      = $pascal->mean();
$mode   = $pascal->mode();
$σ²     = $pascal->variance();

// Poisson distribution
$λ       = 2; // average number of successful events per interval
$k       = 3; // events in the interval
$poisson = new Discrete\Poisson($λ);
$pmf     = $poisson->pmf($k);
$cdf     = $poisson->cdf($k);
$μ       = $poisson->mean();
$median  = $poisson->median();
$mode    = $poisson->mode();
$σ²      = $poisson->variance();

// Shifted geometric distribution (probability to get one success)
$p                = 0.5; // success probability
$k                = 2;   // number of trials
$shiftedGeometric = new Discrete\ShiftedGeometric($p);
$pmf              = $shiftedGeometric->pmf($k);
$cdf              = $shiftedGeometric->cdf($k);
$μ                = $shiftedGeometric->mean();
$median           = $shiftedGeometric->median();
$mode             = $shiftedGeometric->mode();
$σ²               = $shiftedGeometric->variance();

// Uniform distribution
$a       = 1; // lower boundary of the distribution
$b       = 4; // upper boundary of the distribution
$k       = 2; // percentile
$uniform = new Discrete\Uniform($a, $b);
$pmf     = $uniform->pmf();
$cdf     = $uniform->cdf($k);
$μ       = $uniform->mean();
$median  = $uniform->median();
$σ²      = $uniform->variance();

Probability - Multivariate Distributions

use MathPHP\Probability\Distribution\Multivariate;

// Dirichlet distribution
$αs        = [1, 2, 3];
$xs        = [0.07255081, 0.27811903, 0.64933016];
$dirichlet = new Multivariate\Dirichlet($αs);
$pdf       = $dirichlet->pdf($xs);

// Normal distribution
$μ      = [1, 1.1];
$∑      = MatrixFactory::create([
    [1, 0],
    [0, 1],
]);
$X      = [0.7, 1.4];
$normal = new Multivariate\Normal($μ, $∑);
$pdf    = $normal->pdf($X);

// Hypergeometric distribution
$quantities   = [5, 10, 15];   // Suppose there are 5 black, 10 white, and 15 red marbles in an urn.
$choices      = [2, 2, 2];     // If six marbles are chosen without replacement, the probability that exactly two of each color are chosen is:
$distribution = new Multivariate\Hypergeometric($quantities);
$probability  = $distribution->pmf($choices);    // 0.0795756

// Multinomial distribution
$frequencies   = [7, 2, 3];
$probabilities = [0.40, 0.35, 0.25];
$multinomial   = new Multivariate\Multinomial($probabilities);
$pmf           = $multinomial->pmf($frequencies);

Probability - Distribution Tables

use MathPHP\Probability\Distribution\Table;

// Provided solely for completeness' sake.
// It is statistics tradition to provide these tables.
// MathPHP has dynamic distribution CDF functions you can use instead.

// Standard Normal Table (Z Table)
$table       = Table\StandardNormal::Z_SCORES;
$probability = $table[1.5][0];                 // Value for Z of 1.50

// t Distribution Tables
$table   = Table\TDistribution::ONE_SIDED_CONFIDENCE_LEVEL;
$table   = Table\TDistribution::TWO_SIDED_CONFIDENCE_LEVEL;
$ν       = 5;  // degrees of freedom
$cl      = 99; // confidence level
$t       = $table[$ν][$cl];

// t Distribution Tables
$table = Table\TDistribution::ONE_SIDED_ALPHA;
$table = Table\TDistribution::TWO_SIDED_ALPHA;
$ν     = 5;     // degrees of freedom
$α     = 0.001; // alpha value
$t     = $table[$ν][$α];

// χ² Distribution Table
$table = Table\ChiSquared::CHI_SQUARED_SCORES;
$df    = 2;    // degrees of freedom
$p     = 0.05; // P value
$χ²    = $table[$df][$p];

Sample Data

use MathPHP\SampleData;

// Famous sample data sets to experiment with

// Motor Trend Car Road Tests (mtcars)
$mtCars      = new SampleData\MtCars();
$rawData     = $mtCars->getData();                     // [[21, 6, 160, ... ], [30.4, 4, 71.1, ... ], ... ]
$labeledData = $mtCars->getLabeledData();              // ['Mazda RX4' => ['mpg' => 21, 'cyl' => 6, 'disp' => 160, ... ], 'Honda Civic' => [ ... ], ...]
$modelData   = $mtCars->getModelData('Ferrari Dino');  // ['mpg' => 19.7, 'cyl' => 6, 'disp' => 145, ... ]
$mpgs        = $mtCars->getMpg();                      // ['Mazda RX4' => 21, 'Honda civic' => 30.4, ... ]
// Getters for Mpg, Cyl, Disp, Hp, Drat, Wt, Qsec, Vs, Am, Gear, Carb

// Edgar Anderson's Iris Data (iris)
$iris         = new SampleData\Iris();
$rawData      = $iris->getData();         // [[5.1, 3.5, 1.4, 0.2, 'setosa'], [4.9, 3.0, 1.4, 0.2, 'setosa'], ... ]
$labeledData  = $iris->getLabeledData();  // [['sepalLength' => 5.11, 'sepalWidth' => 3.5, 'petalLength' => 1.4, 'petalWidth' => 0.2, 'species' => 'setosa'], ... ]
$petalLengths = $iris->getSepalLength();  // [5.1, 4.9, 4.7, ... ]
// Getters for SepalLength, SepalWidth, PetalLength, PetalWidth, Species

// The Effect of Vitamin C on Tooth Growth in Guinea Pigs (ToothGrowth)
$toothGrowth = new SampleData\ToothGrowth();
$rawData     = $toothGrowth->getData();         // [[4.2, 'VC', 0.5], [11.5, 'VC', '0.5], ... ]
$labeledData = $toothGrowth->getLabeledData();  // [['len' => 4.2, 'supp' => 'VC', 'dose' => 0.5], ... ]
$lengths     = $toothGrowth->getLen();          // [4.2, 11.5, ... ]
// Getters for Len, Supp, Dose

// Results from an Experiment on Plant Growth (PlantGrowth)
$plantGrowth = new SampleData\PlantGrowth();
$rawData     = $plantGrowth->getData();         // [[4.17, 'ctrl'], [5.58, 'ctrl'], ... ]
$labeledData = $plantGrowth->getLabeledData();  // [['weight' => 4.17, 'group' => 'ctrl'], ['weight' => 5.58, 'group' => 'ctrl'], ... ]
$weights     = $plantGrowth->getWeight();       // [4.17, 5.58, ... ]
// Getters for Weight, Group

// Violent Crime Rates by US State (USArrests)
$usArrests   = new SampleData\UsArrests();
$rawData     = $usArrests->rawData();              // [[13.2, 236, 58, 21.2], [10.0, 263, 48, 44.5], ... ]
$labeledData = $usArrests->getLabeledData();       // ['Alabama' => ['murder' => 13.2, 'assault' => 236, 'urbanPop' => 58, 'rape' => 21.2], ... ]
$stateData   = $usArrests->getStateData('Texas');  // ['murder' => 12.7, 'assault' => 201, 'urbanPop' => 80, 'rape' => 25.5]
$murders     = $usArrests->getMurders();           // ['Alabama' => 13.2, 'Alaska' => 10.1, ... ]
// Getters for Murder, Assault, UrbanPop, Rape

// Data from Cereals (cereal)
$cereal  = new SampleData\Cereal();
$cereals = $cereal->getCereals();    // ['B1', 'B2', 'B3', 'M1', 'M2', ... ]
$X       = $cereal->getXData();      // [[0.002682755, 0.003370673, 0.004085942, ... ], [0.002781597, 0.003474863, 0.004191472, ... ], ... ]
$Y       = $cereal->getYData();      // [[18373, 41.61500, 6.565000, ... ], [18536, 41.40500, 6.545000, ... ], ... ]
$Ysc     = $cereal->getYscData();    // [[-0.1005049, 0.6265746, -1.1716630, ... ], [0.9233889, 0.1882929, -1.3185289, ... ], ... ]
// Labeled data: getLabeledXData(), getLabeledYData(), getLabeledYscData()

Search

use MathPHP\Search;

// Search lists of numbers to find specific indexes

$list = [1, 2, 3, 4, 5];

$index   = Search::sorted($list, 2);   // Find the array index where an item should be inserted to maintain sorted order
$index   = Search::argMax($list);      // Find the array index of the maximum value
$index   = Search::nanArgMax($list);   // Find the array index of the maximum value, ignoring NANs
$index   = Search::argMin($list);      // Find the array index of the minimum value
$index   = Search::nanArgMin($list);   // Find the array index of the minimum value, ignoring NANs
$indices = Search::nonZero($list);     // Find the array indices of the scalar values that are non-zero

Sequences - Basic

use MathPHP\Sequence\Basic;

$n = 5; // Number of elements in the sequence

// Arithmetic progression
$d           = 2;  // Difference between the elements of the sequence
$a₁          = 1;  // Starting number for the sequence
$progression = Basic::arithmeticProgression($n, $d, $a₁);
// [1, 3, 5, 7, 9] - Indexed from 1

// Geometric progression (arⁿ⁻¹)
$a           = 2; // Scalar value
$r           = 3; // Common ratio
$progression = Basic::geometricProgression($n, $a, $r);
// [2(3)⁰, 2(3)¹, 2(3)², 2(3)³] = [2, 6, 18, 54] - Indexed from 1

// Square numbers (n²)
$squares = Basic::squareNumber($n);
// [0², 1², 2², 3², 4²] = [0, 1, 4, 9, 16] - Indexed from 0

// Cubic numbers (n³)
$cubes = Basic::cubicNumber($n);
// [0³, 1³, 2³, 3³, 4³] = [0, 1, 8, 27, 64] - Indexed from 0

// Powers of 2 (2ⁿ)
$po2 = Basic::powersOfTwo($n);
// [2⁰, 2¹, 2², 2³, 2⁴] = [1,  2,  4,  8,  16] - Indexed from 0

// Powers of 10 (10ⁿ)
$po10 = Basic::powersOfTen($n);
// [10⁰, 10¹, 10², 10³,  10⁴] = [1, 10, 100, 1000, 10000] - Indexed from 0

// Factorial (n!)
$fact = Basic::factorial($n);
// [0!, 1!, 2!, 3!, 4!] = [1,  1,  2,  6,  24] - Indexed from 0

// Digit sum
$digit_sum = Basic::digitSum($n);
// [0, 1, 2, 3, 4] - Indexed from 0

// Digital root
$digit_root = Basic::digitalRoot($n);
// [0, 1, 2, 3, 4] - Indexed from 0

Sequences - Advanced

use MathPHP\Sequence\Advanced;

$n = 6; // Number of elements in the sequence

// Fibonacci (Fᵢ = Fᵢ₋₁ + Fᵢ₋₂)
$fib = Advanced::fibonacci($n);
// [0, 1, 1, 2, 3, 5] - Indexed from 0

// Lucas numbers
$lucas = Advanced::lucasNumber($n);
// [2, 1, 3, 4, 7, 11] - Indexed from 0

// Pell numbers
$pell = Advanced::pellNumber($n);
// [0, 1, 2, 5, 12, 29] - Indexed from 0

// Triangular numbers (figurate number)
$triangles = Advanced::triangularNumber($n);
// [1, 3, 6, 10, 15, 21] - Indexed from 1

// Pentagonal numbers (figurate number)
$pentagons = Advanced::pentagonalNumber($n);
// [1, 5, 12, 22, 35, 51] - Indexed from 1

// Hexagonal numbers (figurate number)
$hexagons = Advanced::hexagonalNumber($n);
// [1, 6, 15, 28, 45, 66] - Indexed from 1

// Heptagonal numbers (figurate number)
$hexagons = Advanced::heptagonalNumber($n);
// [1, 4, 7, 13, 18, 27] - Indexed from 1

// Look-and-say sequence (describe the previous term!)
$look_and_say = Advanced::lookAndSay($n);
// ['1', '11', '21', '1211', '111221', '312211'] - Indexed from 1

// Lazy caterer's sequence (central polygonal numbers)
$lazy_caterer = Advanced::lazyCaterers($n);
// [1, 2, 4, 7, 11, 16] - Indexed from 0

// Magic squares series (magic constants; magic sums)
$magic_squares = Advanced::magicSquares($n);
// [0, 1, 5, 15, 34, 65] - Indexed from 0

// Perfect numbers
$perfect_numbers = Advanced::perfectNumbers($n);
// [6, 28, 496, 8128, 33550336, 8589869056] - Indexed from 0

// Perfect powers sequence
$perfect_powers = Advanced::perfectPowers($n);
// [4, 8, 9, 16, 25, 27] - Indexed from 0

// Not perfect powers sequence
$not_perfect_powers = Advanced::notPerfectPowers($n);
// [2, 3, 5, 6, 7, 10] - Indexed from 0

// Prime numbers up to n (n is not the number of elements in the sequence)
$primes = Advanced::primesUpTo(30);
// [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] - Indexed from 0

Sequences - Non-Integer

use MathPHP\Sequence\NonInteger;

$n = 4; // Number of elements in the sequence

// Harmonic sequence
$harmonic_sequence = NonInteger::harmonic($n);
// [1, 3/2, 11/6, 25/12] - Indexed from 1

// Hyperharmonic sequence
$p = 2;
$hyperharmonic_sequence = NonInteger::hyperharmonic($n, $p);
// [1, 5/4, 49/36, 205/144] - Indexed from 1

Set Theory

use MathPHP\SetTheory\Set;
use MathPHP\SetTheory\ImmutableSet;

// Sets and immutable sets
$A = new Set([1, 2, 3]);          // Can add and remove members
$B = new ImmutableSet([3, 4, 5]); // Cannot modify set once created

// Basic set data
$set         = $A->asArray();
$cardinality = $A->length();
$bool        = $A->isEmpty();

// Set membership
$true = $A->isMember(2);
$true = $A->isNotMember(8);

// Add and remove members
$A->add(4);
$A->add(new Set(['a', 'b']));
$A->addMulti([5, 6, 7]);
$A->remove(7);
$A->removeMulti([5, 6]);
$A->clear();

// Set properties against other sets - return boolean
$bool = $A->isDisjoint($B);
$bool = $A->isSubset($B);         // A ⊆ B
$bool = $A->isProperSubset($B);   // A ⊆ B & A ≠ B
$bool = $A->isSuperset($B);       // A ⊇ B
$bool = $A->isProperSuperset($B); // A ⊇ B & A ≠ B

// Set operations with other sets - return a new Set
$AB  = $A->union($B);
$AB  = $A->intersect($B);
$AB = $A->difference($B);          // relative complement
$AΔB  = $A->symmetricDifference($B);
$A×B  = $A->cartesianProduct($B);

// Other set operations
$PA⟯ = $A->powerSet();
$C   = $A->copy();

// Print a set
print($A); // Set{1, 2, 3, 4, Set{a, b}}

// PHP Interfaces
$n = count($A);                 // Countable
foreach ($A as $member) { ... } // Iterator

// Fluent interface
$A->add(5)->add(6)->remove(4)->addMulti([7, 8, 9]);

Statistics - ANOVA

use MathPHP\Statistics\ANOVA;

// One-way ANOVA
$sample1 = [1, 2, 3];
$sample2 = [3, 4, 5];
$sample3 = [5, 6, 7];
   ⋮            ⋮

$anova = ANOVA::oneWay($sample1, $sample2, $sample3);
print_r($anova);
/* Array (
    [ANOVA] => Array (             // ANOVA hypothesis test summary data
            [treatment] => Array (
                    [SS] => 24     // Sum of squares (between)
                    [df] => 2      // Degrees of freedom
                    [MS] => 12     // Mean squares
                    [F]  => 12     // Test statistic
                    [P]  => 0.008  // P value
                )
            [error] => Array (
                    [SS] => 6      // Sum of squares (within)
                    [df] => 6      // Degrees of freedom
                    [MS] => 1      // Mean squares
                )
            [total] => Array (
                    [SS] => 30     // Sum of squares (total)
                    [df] => 8      // Degrees of freedom
                )
        )
    [total_summary] => Array (     // Total summary data
            [n]        => 9
            [sum]      => 36
            [mean]     => 4
            [SS]       => 174
            [variance] => 3.75
            [sd]       => 1.9364916731037
            [sem]      => 0.6454972243679
        )
    [data_summary] => Array (      // Data summary (each input sample)
            [0] => Array ([n] => 3 [sum] => 6  [mean] => 2 [SS] => 14  [variance] => 1 [sd] => 1 [sem] => 0.57735026918963)
            [1] => Array ([n] => 3 [sum] => 12 [mean] => 4 [SS] => 50  [variance] => 1 [sd] => 1 [sem] => 0.57735026918963)
            [2] => Array ([n] => 3 [sum] => 18 [mean] => 6 [SS] => 110 [variance] => 1 [sd] => 1 [sem] => 0.57735026918963)
        )
) */

// Two-way ANOVA
/*        | Factor B₁ | Factor B₂ | Factor B₃ | ⋯
Factor A₁ |  4, 6, 8  |  6, 6, 9  |  8, 9, 13 | ⋯
Factor A₂ |  4, 8, 9  | 7, 10, 13 | 12, 14, 16| ⋯
    ⋮           ⋮           ⋮           ⋮         */
$factorA₁ = [
  [4, 6, 8],    // Factor B₁
  [6, 6, 9],    // Factor B₂
  [8, 9, 13],   // Factor B₃
];
$factorA₂ = [
  [4, 8, 9],    // Factor B₁
  [7, 10, 13],  // Factor B₂
  [12, 14, 16], // Factor B₃
];
       ⋮

$anova = ANOVA::twoWay($factorA₁, $factorA₂);
print_r($anova);
/* Array (
    [ANOVA] => Array (          // ANOVA hypothesis test summary data
            [factorA] => Array (
                    [SS] => 32                 // Sum of squares
                    [df] => 1                  // Degrees of freedom
                    [MS] => 32                 // Mean squares
                    [F]  => 5.6470588235294    // Test statistic
                    [P]  => 0.034994350619895  // P value
                )
            [factorB] => Array (
                    [SS] => 93                 // Sum of squares
                    [df] => 2                  // Degrees of freedom
                    [MS] => 46.5               // Mean squares
                    [F]  => 8.2058823529412    // Test statistic
                    [P]  => 0.0056767297582031 // P value
                )
            [interaction] => Array (
                    [SS] => 7                  // Sum of squares
                    [df] => 2                  // Degrees of freedom
                    [MS] => 3.5                // Mean squares
                    [F]  => 0.61764705882353   // Test statistic
                    [P]  => 0.5555023440712    // P value
                )
            [error] => Array (
                    [SS] => 68                 // Sum of squares (within)
                    [df] => 12                 // Degrees of freedom
                    [MS] => 5.6666666666667    // Mean squares
                )
            [total] => Array (
                    [SS] => 200                // Sum of squares (total)
                    [df] => 17                 // Degrees of freedom
                )
        )
    [total_summary] => Array (    // Total summary data
            [n]        => 18
            [sum]      => 162
            [mean]     => 9
            [SS]       => 1658
            [variance] => 11.764705882353
            [sd]       => 3.4299717028502
            [sem]      => 0.80845208345444
        )
    [summary_factorA]     => Array ( ... )   // Summary data of factor A
    [summary_factorB]     => Array ( ... )   // Summary data of factor B
    [summary_interaction] => Array ( ... )   // Summary data of interactions of factors A and B
) */

Statistics - Averages

use MathPHP\Statistics\Average;

$numbers = [13, 18, 13, 14, 13, 16, 14, 21, 13];

// Mean, median, mode
$mean   = Average::mean($numbers);
$median = Average::median($numbers);
$mode   = Average::mode($numbers); // Returns an array — may be multimodal

// Weighted mean
$weights       = [12, 1, 23, 6, 12, 26, 21, 12, 1];
$weighted_mean = Average::weightedMean($numbers, $weights)

// Other means of a list of numbers
$geometric_mean      = Average::geometricMean($numbers);
$harmonic_mean       = Average::harmonicMean($numbers);
$contraharmonic_mean = Average::contraharmonicMean($numbers);
$quadratic_mean      = Average::quadraticMean($numbers);  // same as rootMeanSquare
$root_mean_square    = Average::rootMeanSquare($numbers); // same as quadraticMean
$trimean             = Average::trimean($numbers);
$interquartile_mean  = Average::interquartileMean($numbers); // same as iqm
$interquartile_mean  = Average::iqm($numbers);               // same as interquartileMean
$cubic_mean          = Average::cubicMean($numbers);

// Truncated mean (trimmed mean)
$trim_percent   = 25;
$truncated_mean = Average::truncatedMean($numbers, $trim_percent);

// Generalized mean (power mean)
$p                = 2;
$generalized_mean = Average::generalizedMean($numbers, $p); // same as powerMean
$power_mean       = Average::powerMean($numbers, $p);       // same as generalizedMean

// Lehmer mean
$p           = 3;
$lehmer_mean = Average::lehmerMean($numbers, $p);

// Moving averages
$n       = 3;
$weights = [3, 2, 1];
$SMA     = Average::simpleMovingAverage($numbers, $n);             // 3 n-point moving average
$CMA     = Average::cumulativeMovingAverage($numbers);
$WMA     = Average::weightedMovingAverage($numbers, $n, $weights);
$EPA     = Average::exponentialMovingAverage($numbers, $n);

// Means of two numbers
list($x, $y) = [24, 6];
$agm           = Average::arithmeticGeometricMean($x, $y); // same as agm
$agm           = Average::agm($x, $y);                     // same as arithmeticGeometricMean
$log_mean      = Average::logarithmicMean($x, $y);
$heronian_mean = Average::heronianMean($x, $y);
$identric_mean = Average::identricMean($x, $y);

// Averages report
$averages = Average::describe($numbers);
print_r($averages);
/* Array (
    [mean]                => 15
    [median]              => 14
    [mode]                => Array ( [0] => 13 )
    [geometric_mean]      => 14.789726414533
    [harmonic_mean]       => 14.605077399381
    [contraharmonic_mean] => 15.474074074074
    [quadratic_mean]      => 15.235193176035
    [trimean]             => 14.5
    [iqm]                 => 14
    [cubic_mean]          => 15.492307432707
) */

Statistics - Circular

use MathPHP\Statistics\Circular;

$angles = [1.51269877, 1.07723915, 0.81992282];

$θ = Circular::mean($angles);
$R = Circular::resultantLength($angles);
$ρ = Circular::meanResultantLength($angles);
$V = Circular::variance($angles);
$ν = Circular::standardDeviation($angles);

// Descriptive circular statistics report
$stats = Circular::describe($angles);
print_r($stats);
/* Array (
    [n]                     => 3
    [mean]                  => 1.1354043006436
    [resultant_length]      => 2.8786207547493
    [mean_resultant_length] => 0.9595402515831
    [variance]              => 0.040459748416901
    [sd]                    => 0.28740568481722
); */

Statistics - Correlation

use MathPHP\Statistics\Correlation;

$X = [1, 2, 3, 4, 5];
$Y = [2, 3, 4, 4, 6];

// Covariance
$σxy = Correlation::covariance($X, $Y);  // Has optional parameter to set population (defaults to sample covariance)

// Weighted covariance
$w    = [2, 3, 1, 1, 5];
$σxyw = Correlation::weightedCovariance($X, $Y, $w);

// r - Pearson product-moment correlation coefficient (Pearson's r)
$r = Correlation::r($X, $Y);  // Has optional parameter to set population (defaults to sample correlation coefficient)

// Weighted correlation coefficient
$rw = Correlation::weightedCorrelationCoefficient($X, $Y, $w);

// R² - Coefficient of determination
$ = Correlation::r2($X, $Y);  // Has optional parameter to set population (defaults to sample coefficient of determination)

// τ - Kendall rank correlation coefficient (Kendall's tau)
$τ = Correlation::kendallsTau($X, $Y);

// ρ - Spearman's rank correlation coefficient (Spearman's rho)
$ρ = Correlation::spearmansRho($X, $Y);

// Descriptive correlation report
$stats = Correlation::describe($X, $Y);
print_r($stats);
/* Array (
    [cov] => 2.25
    [r]   => 0.95940322360025
    [r2]  => 0.92045454545455
    [tau] => 0.94868329805051
    [rho] => 0.975
) */

// Confidence ellipse - create an ellipse surrounding the data at a specified standard deviation
$sd           = 1;
$num_points   = 11; // Optional argument specifying number of points of the ellipse
$ellipse_data = Correlation::confidenceEllipse($X, $Y, $sd, $num_points);

Statistics - Descriptive

use MathPHP\Statistics\Descriptive;

$numbers = [13, 18, 13, 14, 13, 16, 14, 21, 13];

// Range and midrange
$range    = Descriptive::range($numbers);
$midrange = Descriptive::midrange($numbers);

// Variance (population and sample)
$σ² = Descriptive::populationVariance($numbers); // n degrees of freedom
$ = Descriptive::sampleVariance($numbers);     // n - 1 degrees of freedom

// Variance (Custom degrees of freedom)
$df = 5;                                    // degrees of freedom
$ = Descriptive::variance($numbers, $df); // can specify custom degrees of freedom

// Weighted sample variance
$weights = [0.1, 0.2, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1];
$σ²w     = Descriptive::weightedSampleVariance($numbers, $weights, $biased = false);

// Standard deviation (For a sample; uses sample variance)
$σ = Descriptive::sd($numbers);                // same as standardDeviation;
$σ = Descriptive::standardDeviation($numbers); // same as sd;

// SD+ (Standard deviation for a population; uses population variance)
$SD+ = Descriptive::sd($numbers, Descriptive::POPULATION); // POPULATION constant = true
$SD+ = Descriptive::standardDeviation($numbers, true);     // same as sd with POPULATION constant

// Coefficient of variation (cᵥ)
$cᵥ = Descriptive::coefficientOfVariation($numbers);

// MAD - mean/median absolute deviations
$mean_mad   = Descriptive::meanAbsoluteDeviation($numbers);
$median_mad = Descriptive::medianAbsoluteDeviation($numbers);

// Quartiles (inclusive and exclusive methods)
// [0% => 13, Q1 => 13, Q2 => 14, Q3 => 17, 100% => 21, IQR => 4]
$quartiles = Descriptive::quartiles($numbers);          // Has optional parameter to specify method. Default is Exclusive
$quartiles = Descriptive::quartilesExclusive($numbers);
$quartiles = Descriptive::quartilesInclusive($numbers);

// IQR - Interquartile range
$IQR = Descriptive::interquartileRange($numbers); // Same as IQR; has optional parameter to specify quartile method.
$IQR = Descriptive::iqr($numbers);                // Same as interquartileRange; has optional parameter to specify quartile method.

// Percentiles
$twentieth_percentile    = Descriptive::percentile($numbers, 20);
$ninety_fifth_percentile = Descriptive::percentile($numbers, 95);

// Midhinge
$midhinge = Descriptive::midhinge($numbers);

// Describe a list of numbers - descriptive stats report
$stats = Descriptive::describe($numbers); // Has optional parameter to set population or sample calculations
print_r($stats);
/* Array (
    [n]          => 9
    [min]        => 13
    [max]        => 21
    [mean]       => 15
    [median]     => 14
    [mode]       => Array ( [0] => 13 )
    [range]      => 8
    [midrange]   => 17
    [variance]   => 8
    [sd]         => 2.8284271247462
    [cv]         => 0.18856180831641
    [mean_mad]   => 2.2222222222222
    [median_mad] => 1
    [quartiles]  => Array (
            [0%]   => 13
            [Q1]   => 13
            [Q2]   => 14
            [Q3]   => 17
            [100%] => 21
            [IQR]  => 4
        )
    [midhinge]   => 15
    [skewness]   => 1.4915533665654
    [ses]        => 0.71713716560064
    [kurtosis]   => 0.1728515625
    [sek]        => 1.3997084244475
    [sem]        => 0.94280904158206
    [ci_95]      => Array (
            [ci]          => 1.8478680091392
            [lower_bound] => 13.152131990861
            [upper_bound] => 16.847868009139
        )
    [ci_99]      => Array (
            [ci]          => 2.4285158135783
            [lower_bound] => 12.571484186422
            [upper_bound] => 17.428515813578
        )
) */

// Five number summary - five most important sample percentiles
$summary = Descriptive::fiveNumberSummary($numbers);
// [min, Q1, median, Q3, max]

Statistics - Distance

use MathPHP\Statistics\Distance;

// Probability distributions
$X = [0.2, 0.5, 0.3];
$Y = [0.1, 0.4, 0.5];

// Distances
$DBXY⟯   = Distance::bhattacharyyaDistance($X, $Y);
$HXY⟯    = Distance::hellingerDistance($X, $Y);
$DXY⟯    = Distance::minkowski($X, $Y, $p = 2);
$dXY⟯    = Distance::euclidean($X, $Y);               // L² distance
$d₁⟮XY⟯   = Distance::manhattan($X, $Y);               // L¹ distance, taxicab geometry, city block distance
$JSDXY⟯   = Distance::jensenShannon($X, $Y);
$dXY⟯    = Distance::canberra($X, Y);
brayCurtis = Distance::brayCurtis($X, $Y);
$cosine    = Distance::cosine($X, $Y);
$cos⟮α⟯     = Distance::cosineSimilarity($X, $Y);

// Mahalanobis distance
$x    = new Matrix([[6], [5]]);
$data = new Matrix([
    [4, 4, 5, 2, 3, 6, 9, 7, 4, 5],
    [3, 7, 5, 7, 9, 5, 6, 2, 2, 7],
]);
$otherData = new Matrix([
    [4, 4, 5, 2, 3, 6, 9, 7, 4, 5],
    [3, 7, 5, 7, 9, 5, 6, 2, 2, 7],
]);
$y = new Matrix([[2], [2]]);
$D = Distance::mahalanobis($x, $data);          // Mahalanobis distance from x to the centroid of the data.
$D = Distance::mahalanobis($x, $data, $y);      // Mahalanobis distance between $x and $y using the data.
$D = Distance::mahalanobis($data, $otherData);  // Mahalanobis distance between the centroids of two sets of data.

Statistics - Distributions

use MathPHP\Statistics\Distribution;

$grades = ['A', 'A', 'B', 'B', 'B', 'B', 'C', 'C', 'D', 'F'];

// Frequency distributions (frequency and relative frequency)
$frequencies          = Distribution::frequency($grades);         // [ A => 2,   B => 4,   C => 2,   D => 1,   F => 1   ]
$relative_frequencies = Distribution::relativeFrequency($grades); // [ A => 0.2, B => 0.4, C => 0.2, D => 0.1, F => 0.1 ]

// Cumulative frequency distributions (cumulative and cumulative relative)
$cumulative_frequencies          = Distribution::cumulativeFrequency($grades);         // [ A => 2,   B => 6,   C => 8,   D => 9,   F => 10  ]
$cumulative_relative_frequencies = Distribution::cumulativeRelativeFrequency($grades); // [ A => 0.2, B => 0.6, C => 0.8, D => 0.9, F => 1   ]

// Ranking of data
$values                       = [1, 2, 2, 3];
$ordinal_ranking              = Distribution::ordinalRanking($values);              // 1, 2, 3, 4
$standard_competition_ranking = Distribution::standardCompetitionRanking($values);  // 1, 2, 2, 4
$modified_competition_ranking = Distribution::modifiedCompetitionRanking($values);  // 1, 3, 3, 4
$fractional_ranking           = Distribution::fractionalRanking($values);           // 1, 2.5, 2.5, 4

// Stem and leaf plot
// Return value is array where keys are the stems, values are the leaves
$values             = [44, 46, 47, 49, 63, 64, 66, 68, 68, 72, 72, 75, 76, 81, 84, 88, 106];
$stem_and_leaf_plot = Distribution::stemAndLeafPlot($values);
// [4 => [4, 6, 7, 9], 5 => [], 6 => [3, 4, 6, 8, 8], 7 => [2, 2, 5, 6], 8 => [1, 4, 8], 9 => [], 10 => [6]]

// Optional second parameter will print stem and leaf plot to STDOUT
Distribution::stemAndLeafPlot($values, Distribution::PRINT);
/*
 4 | 4 6 7 9
 5 |
 6 | 3 4 6 8 8
 7 | 2 2 5 6
 8 | 1 4 8
 9 |
10 | 6
*/

Statistics - Divergence

use MathPHP\Statistics\Divergence;

// Probability distributions
$X = [0.2, 0.5, 0.3];
$Y = [0.1, 0.4, 0.5];

// Divergences
$DklXY⟯ = Divergence::kullbackLeibler($X, $Y);
$JSDXY⟯ = Divergence::jensenShannon($X, $Y);

Statistics - Effect Size

use MathPHP\Statistics\EffectSize;

$SSt = 24;  // Sum of squares treatment
$SSE = 300; // Sum of squares error
$SST = 600; // Sum of squares total
$dft = 1;   // Degrees of freedom treatment
$MSE = 18;  // Mean squares error

// η² - Eta-squared
$η²  = EffectSize::etaSquared($SSt, $SST);
$η²p = EffectSize::partialEtaSquared($SSt, $SSE);

// ω² - Omega-squared
$ω² = EffectSize::omegaSquared($SSt, $dft, $SST, $MSE);

// Cohen's ƒ²
$ƒ² = EffectSize::cohensF($η²);
$ƒ² = EffectSize::cohensF($ω²);
$ƒ² = EffectSize::cohensF($);

// Cohen's q
list($r₁, $r₂) = [0.1, 0.2];
$q = EffectSize::cohensQ($r₁, $r₂);

// Cohen's d
list($μ₁, $σ₁) = [6.7, 1.2];
list($μ₂, $σ₂) = [6, 1];
$d = EffectSize::cohensD($μ₁, $μ₂, $σ₁, $σ₂);

// Hedges' g
list($μ₁, $σ₁, $n₁) = [6.7, 1.2, 15];
list($μ₂, $σ₂, $n₂) = [6, 1, 15];
$g = EffectSize::hedgesG($μ₁, $μ₂, $σ₁, $σ₂, $n₁, $n₂);

// Glass' Δ
$Δ = EffectSize::glassDelta($μ₁, $μ₂, $σ₂);

Statistics - Experiments

use MathPHP\Statistics\Experiment;

$a = 28;   // Exposed and event present
$b = 129;  // Exposed and event absent
$c = 4;    // Non-exposed and event present
$d = 133;  // Non-exposed and event absent

// Risk ratio (relative risk) - RR
$RR = Experiment::riskRatio($a, $b, $c, $d);
// ['RR' => 6.1083, 'ci_lower_bound' => 2.1976, 'ci_upper_bound' => 16.9784, 'p' => 0.0005]

// Odds ratio (OR)
$OR = Experiment::oddsRatio($a, $b, $c, $d);
// ['OR' => 7.2171, 'ci_lower_bound' => 2.4624, 'ci_upper_bound' => 21.1522, 'p' => 0.0003]

// Likelihood ratios (positive and negative)
$LL = Experiment::likelihoodRatio($a, $b, $c, $d);
// ['LL+' => 7.4444, 'LL-' => 0.3626]

$sensitivity = 0.67;
$specificity = 0.91;
$LL          = Experiment::likelihoodRatioSS($sensitivity, $specificity);

Statistics - Kernel Density Estimation

use MathPHP\Statistics\KernelDensityEstimation

$data = [-2.76, -1.09, -0.5, -0.15, 0.22, 0.69, 1.34, 1.75];
$x    = 0.5;

// Density estimator with default bandwidth (normal distribution approximation) and kernel function (standard normal)
$kde     = new KernelDensityEstimation($data);
$density = $kde->evaluate($x)

// Custom bandwidth
$h = 0.1;
$kde->setBandwidth($h);

// Library of built-in kernel functions
$kde->setKernelFunction(KernelDensityEstimation::STANDARD_NORMAL);
$kde->setKernelFunction(KernelDensityEstimation::NORMAL);
$kde->setKernelFunction(KernelDensityEstimation::UNIFORM);
$kde->setKernelFunction(KernelDensityEstimation::TRIANGULAR);
$kde->setKernelFunction(KernelDensityEstimation::EPANECHNIKOV);
$kde->setKernelFunction(KernelDensityEstimation::TRICUBE);

// Set custom kernel function (user-provided callable)
$kernel = function ($x) {
  if (abs($x) > 1) {
      return 0;
  } else {
      return 70 / 81 * ((1 - abs($x) ** 3) ** 3);
  }
};
$kde->setKernelFunction($kernel);

// All customization optionally can be done in the constructor
$kde = new KernelDesnsityEstimation($data, $h, $kernel);

Statistics - Multivariate - Principal Component Analysis

use MathPHP\Statistics\Multivariate\PCA;
use MathPHP\LinearAlgebra\MatrixFactory;

// Given
$matrix = MatrixFactory::create($data);  // observations of possibly correlated variables
$center = true;                          // do mean centering of data
$scale  = true;                          // do standardization of data

// Build a principal component analysis model to explore
$model = new PCA($matrix, $center, $scale);

// Scores and loadings of the PCA model
$scores      = $model->getScores();       // Matrix of transformed standardized data with the loadings matrix
$loadings    = $model->getLoadings();     // Matrix of unit eigenvectors of the correlation matrix
$eigenvalues = $model->getEigenvalues();  // Vector of eigenvalues of components

// Residuals, limits, critical values and more
$         = $model->getR2();           // array of R² values
$cumR²      = $model->getCumR2();        // array of cummulative R² values
$Q          = $model->getQResiduals();   // Matrix of Q residuals
$         = $model->getT2Distances();  // Matrix of T² distances
$T²Critical = $model->getCriticalT2();   // array of critical limits of T²
$QCritical  = $model->getCriticalQ();    // array of critical limits of Q

Statistics - Outlier

use MathPHP\Statistics\Outlier;

$data = [199.31, 199.53, 200.19, 200.82, 201.92, 201.95, 202.18, 245.57];
$n    = 8;    // size of data
$𝛼    = 0.05; // significance level

// Grubb's test - two sided test
$grubbsStatistic = Outlier::grubbsStatistic($data, Outlier::TWO_SIDED);
$criticalValue   = Outlier::grubbsCriticalValue($𝛼, $n, Outlier::TWO_SIDED);

// Grubbs' test - one sided test of minimum value
$grubbsStatistic = Outlier::grubbsStatistic($data, Outlier::ONE_SIDED_LOWER);
$criticalValue   = Outlier::grubbsCriticalValue($𝛼, $n, Outlier::ONE_SIDED);

// Grubbs' test - one sided test of maximum value
$grubbsStatistic = Outlier::grubbsStatistic($data, Outlier::ONE_SIDED_UPPER);
$criticalValue   = Outlier::grubbsCriticalValue($𝛼, $n, Outlier::ONE_SIDED);

Statistics - Random Variables

use MathPHP\Statistics\RandomVariable;

$X = [1, 2, 3, 4];
$Y = [2, 3, 4, 5];

// Central moment (nth moment)
$second_central_moment = RandomVariable::centralMoment($X, 2);
$third_central_moment  = RandomVariable::centralMoment($X, 3);

// Skewness (population, sample, and alternative general method)
$skewness = RandomVariable::skewness($X);            // Optional type parameter to choose skewness type calculation. Defaults to sample skewness (similar to Excel's SKEW).
$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
$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
$skewness = RandomVariable::alternativeSkewness($X); // Same as RandomVariable::skewness($X, RandomVariable::ALTERNATIVE_SKEWNESS) - Alternative, classic definition of skewness
$SES      = RandomVariable::ses(count($X));          // standard error of skewness

// Kurtosis (excess)
$kurtosis    = RandomVariable::kurtosis($X);           // Optional type parameter to choose kurtosis type calculation. Defaults to population kurtosis (similar to Excel's KURT).
$kurtosis    = RandomVariable::sampleKurtosis($X);     // Same as RandomVariable::kurtosis($X, RandomVariable::SAMPLE_KURTOSIS) -  Similar to R (e1071) kurtosis type 1
$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
$platykurtic = RandomVariable::isPlatykurtic($X);      // true if kurtosis is less than zero
$leptokurtic = RandomVariable::isLeptokurtic($X);      // true if kurtosis is greater than zero
$mesokurtic  = RandomVariable::isMesokurtic($X);       // true if kurtosis is zero
$SEK         = RandomVariable::sek(count($X));         // standard error of kurtosis

// Standard error of the mean (SEM)
$sem = RandomVariable::standardErrorOfTheMean($X); // same as sem
$sem = RandomVariable::sem($X);                    // same as standardErrorOfTheMean

// Confidence interval
$μ  = 90; // sample mean
$n  = 9;  // sample size
$σ  = 36; // standard deviation
$cl = 99; // confidence level
$ci = RandomVariable::confidenceInterval($μ, $n, $σ, $cl); // Array( [ci] => 30.91, [lower_bound] => 59.09, [upper_bound] => 120.91 )

Statistics - Regressions

use MathPHP\Statistics\Regression;

$points = [[1,2], [2,3], [4,5], [5,7], [6,8]];

// Simple linear regression (least squares method)
$regression = new Regression\Linear($points);
$parameters = $regression->getParameters();          // [m => 1.2209302325581, b => 0.6046511627907]
$equation   = $regression->getEquation();            // y = 1.2209302325581x + 0.6046511627907
$y          = $regression->evaluate(5);              // Evaluate for y at x = 5 using regression equation
$ci         = $regression->ci(5, 0.5);               // Confidence interval for x = 5 with p-value of 0.5
$pi         = $regression->pi(5, 0.5);               // Prediction interval for x = 5 with p-value of 0.5; Optional number of trials parameter.
$Ŷ          = $regression->yHat();
$r          = $regression->r();                      // same as correlationCoefficient
$         = $regression->r2();                     // same as coefficientOfDetermination
$se         = $regression->standardErrors();         // [m => se(m), b => se(b)]
$t          = $regression->tValues();                // [m => t, b => t]
$p          = $regression->tProbability();           // [m => p, b => p]
$F          = $regression->fStatistic();
$p          = $regression->fProbability();
$h          = $regression->leverages();
$e          = $regression->residuals();
$D          = $regression->cooksD();
$DFFITS     = $regression->dffits();
$SStot      = $regression->sumOfSquaresTotal();
$SSreg      = $regression->sumOfSquaresRegression();
$SSres      = $regression->sumOfSquaresResidual();
$MSR        = $regression->meanSquareRegression();
$MSE        = $regression->meanSquareResidual();
$MSTO       = $regression->meanSquareTotal();
$error      = $regression->errorSd();                // Standard error of the residuals
$V          = $regression->regressionVariance();
$n          = $regression->getSampleSize();          // 5
$points     = $regression->getPoints();              // [[1,2], [2,3], [4,5], [5,7], [6,8]]
$xs         = $regression->getXs();                  // [1, 2, 4, 5, 6]
$ys         = $regression->getYs();                  // [2, 3, 5, 7, 8]
$ν          = $regression->degreesOfFreedom();

// Linear regression through a fixed point (least squares method)
$force_point = [0,0];
$regression  = new Regression\LinearThroughPoint($points, $force_point);
$parameters  = $regression->getParameters();
$equation    = $regression->getEquation();
$y           = $regression->evaluate(5);
$Ŷ           = $regression->yHat();
$r           = $regression->r();
$          = $regression->r2();
 ⋮                     ⋮

// Theil–Sen estimator (Sen's slope estimator, Kendall–Theil robust line)
$regression  = new Regression\TheilSen($points);
$parameters  = $regression->getParameters();
$equation    = $regression->getEquation();
$y           = $regression->evaluate(5);
 ⋮                     ⋮

// Use Lineweaver-Burk linearization to fit data to the Michaelis–Menten model: y = (V * x) / (K + x)
$regression  = new Regression\LineweaverBurk($points);
$parameters  = $regression->getParameters();  // [V, K]
$equation    = $regression->getEquation();    // y = Vx / (K + x)
$y           = $regression->evaluate(5);
 ⋮                     ⋮

// Use Hanes-Woolf linearization to fit data to the Michaelis–Menten model: y = (V * x) / (K + x)
$regression  = new Regression\HanesWoolf($points);
$parameters  = $regression->getParameters();  // [V, K]
$equation    = $regression->getEquation();    // y = Vx / (K + x)
$y           = $regression->evaluate(5);
 ⋮                     ⋮

// Power law regression - power curve (least squares fitting)
$regression = new Regression\PowerLaw($points);
$parameters = $regression->getParameters();   // [a => 56.483375436574, b => 0.26415375648621]
$equation   = $regression->getEquation();     // y = 56.483375436574x^0.26415375648621
$y          = $regression->evaluate(5);
 ⋮                     ⋮

// LOESS - Locally Weighted Scatterplot Smoothing (Local regression)
$α          = 1/3;                         // Smoothness parameter
$λ          = 1;                           // Order of the polynomial fit
$regression = new Regression\LOESS($points, $α, $λ);
$y          = $regression->evaluate(5);
$Ŷ          = $regression->yHat();
 ⋮                     ⋮

Statistics - Significance Testing

use MathPHP\Statistics\Significance;

// Z test - One sample (z and p values)
$Hₐ = 20;   // Alternate hypothesis (M Sample mean)
$n  = 200;  // Sample size
$H₀ = 19.2; // Null hypothesis (μ Population mean)
$σ  = 6;    // SD of population (Standard error of the mean)
$z  = Significance:zTest($Hₐ, $n, $H₀, $σ);           // Same as zTestOneSample
$z  = Significance:zTestOneSample($Hₐ, $n, $H₀, $σ);  // Same as zTest
/* [
  'z'  => 1.88562, // Z score
  'p1' => 0.02938, // one-tailed p value
  'p2' => 0.0593,  // two-tailed p value
] */

// Z test - Two samples (z and p values)
$μ₁ = 27;   // Sample mean of population 1
$μ₂ = 33;   // Sample mean of population 2
$n₁ = 75;   // Sample size of population 1
$n₂ = 50;   // Sample size of population 2
$σ₁ = 14.1; // Standard deviation of sample mean 1
$σ₂ = 9.5;  // Standard deviation of sample mean 2
$z  = Significance::zTestTwoSample($μ₁, $μ₂, $n₁, $n₂, $σ₁, $σ₂);
/* [
  'z'  => -2.36868418147285,  // z score
  'p1' => 0.00893,            // one-tailed p value
  'p2' => 0.0179,             // two-tailed p value
] */

// Z score
$M = 8; // Sample mean
$μ = 7; // Population mean
$σ = 1; // Population SD
$z = Significance::zScore($M, $μ, $σ);

// T test - One sample (from sample data)
$a     = [3, 4, 4, 5, 5, 5, 6, 6, 7, 8]; // Data set
$H₀    = 300;                            // Null hypothesis (μ₀ Population mean)
$tTest = Significance::tTest($a, $H₀)
print_r($tTest);
/* Array (
    [t]    => 0.42320736951516  // t score
    [df]   => 9                 // degrees of freedom
    [p1]   => 0.34103867713806  // one-tailed p value
    [p2]   => 0.68207735427613  // two-tailed p value
    [mean] => 5.3               // sample mean
    [sd]   => 1.4944341180973   // standard deviation
) */

// T test - One sample (from summary data)
$Hₐ    = 280; // Alternate hypothesis (M Sample mean)
$s     = 50;  // Standard deviation of sample
$n     = 15;  // Sample size
$H₀    = 300; // Null hypothesis (μ₀ Population mean)
$tTest = Significance::tTestOneSampleFromSummaryData($Hₐ, $s, $n, $H₀);
print_r($tTest);
/* Array (
    [t]    => -1.549193338483    // t score
    [df]   => 14                 // degreees of freedom
    [p1]   => 0.071820000122611  // one-tailed p value
    [p2]   => 0.14364000024522   // two-tailed p value
    [mean] => 280                // sample mean
    [sd]   => 50                 // standard deviation
) */

// T test - Two samples (from sample data)
$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];
$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];
$tTest = Significance::tTest($x₁, $x₂);
print_r($tTest);
/* Array (
    [t]     => -2.4553600286929   // t score
    [df]    => 24.988527070145    // degrees of freedom
    [p1]    => 0.010688914613979  // one-tailed p value
    [p2]    => 0.021377829227958  // two-tailed p value
    [mean1] => 20.82              // mean of sample x₁
    [mean2] => 22.98667           // mean of sample x₂
    [sd1]   => 2.804894           // standard deviation of x₁
    [sd2]   => 1.952605           // standard deviation of x₂
) */

// T test - Two samples (from summary data)
$μ₁    = 42.14; // Sample mean of population 1
$μ₂    = 43.23; // Sample mean of population 2
$n₁    = 10;    // Sample size of population 1
$n₂    = 10;    // Sample size of population 2
$σ₁    = 0.683; // Standard deviation of sample mean 1
$σ₂    = 0.750; // Standard deviation of sample mean 2
$tTest = Significance::tTestTwoSampleFromSummaryData($μ₁, $μ₂, $n₁, $n₂, $σ₁, $σ₂);
print_r($tTest);
/* Array (
   [t] => -3.3972305988708     // t score
   [df] => 17.847298548027     // degrees of freedom
   [p1] => 0.0016211251126198  // one-tailed p value
   [p2] => 0.0032422502252396  // two-tailed p value
   [mean1] => 42.14
   [mean2] => 43.23
   [sd1] => 0.6834553
   [sd2] => 0.7498889
] */

// T score
$Hₐ = 280; // Alternate hypothesis (M Sample mean)
$s  = 50;  // SD of sample
$n  = 15;  // Sample size
$H₀ = 300; // Null hypothesis (μ₀ Population mean)
$t  = Significance::tScore($Hₐ, $s, $n, $H);

// χ² test (chi-squared goodness of fit test)
$observed = [4, 6, 17, 16, 8, 9];
$expected = [10, 10, 10, 10, 10, 10];
$χ²       = Significance::chiSquaredTest($observed, $expected);
// ['chi-square' => 14.2, 'p' => 0.014388]

Trigonometry

use MathPHP\Trigonometry;

$n      = 9;
$points = Trigonometry::unitCircle($n); // Produce n number of points along the unit circle

Unit Tests

Beyond 100% code coverage!

MathPHP has thousands of unit tests testing individual functions directly with numerous data inputs to achieve 100% test coverage. MathPHP unit tests also test mathematical axioms which indirectly test the same functions in multiple different ways ensuring that those math properties all work out according to the axioms.

$ cd tests
$ phpunit

Coverage Status

Standards

MathPHP conforms to the following standards:

License

MathPHP is licensed under the MIT License.

Comments
  • What other classes could go in the Numbers namespace?

    What other classes could go in the Numbers namespace?

    I was mulling over this question in my head today. Do you foresee any future need for a rational number class? If a user would want to do calculations with numbers and not have to worry about floating point errors, a class could be created with three integer properties, one for the whole number, and two for the fractional part. We could define all the algebraic functions to work on rational numbers, and reduce the fraction after each calculation to keep them from growing.

    Any other number classes you can think of?

    opened by Beakerboy 31
  • Consider Changing Root Namespace

    Consider Changing Root Namespace

    There was a suggestion that \Math might be too generic and possibly collide with other projects. So perhaps change the root namespace to the project name \MathPHP.

    Thoughts?

    opened by markrogoyski 28
  • PLS

    PLS

    I've created a PLS class that calculates all the standard matrices used for PLS regression. R has a few different PLS implementations in different libraries. the mvr() function appears to be the most mature, but does a lot of optimization behind the scenes. the chemometrics/pls2_nipals() function looks like a textbook example of the algorithm and provides results that can be used to test against.

    opened by Beakerboy 21
  • Qr Decomposition

    Qr Decomposition

    QR Decomposition is the first step towards Eigenvalues for larger matrices, and for more numerically stable Linear Least Squares Regression.

    This is an implementation of the Gram-Schmidt process. The Householder process is apparently better, but I do not understand how it works yet.

    opened by Beakerboy 21
  • Error in the Matrix Solver

    Error in the Matrix Solver

    Dear team behind this amazing set of tools: thanks for making my life a lot easier. I am using Math PHP and loving it. I have encountered what I believe to be a shortcoming of the solver for matrix equations. I am using the solver succesfully for many other matrices, but for this one I am getting this error: billede billede

    I know the matrix equation can be solved, since I am doing this without any problems in other math software such as Maple. You can have a look at the matrix structure in the attached file. Perhaps it is this structure which forces the solver to do the devision by zero? I am not adept at matrix decomposition, but maybe this is an inherent shortcoming of LU decomposition? Do you have any workaround?

    matrix49x49.xlsx

    bug 
    opened by Labaneseren 20
  • Add: Angle and distances between two vectors

    Add: Angle and distances between two vectors

    Hey @markrogoyski,

    here are my suggested changes regarding #377. Since this is my first "real" contribution to an Open Source project, please be nice to me :-D

    -Florian

    opened by nessor 16
  • Discussion - Refactor Distributions

    Discussion - Refactor Distributions

    What do you think? Have you looked at my code? Each distribution has a PDF, and CDF function. The parent Distribution class has an inverse method which uses Newton's method to do the inverse CDF. For Student-T, I have a separate "two-tails" method which uses the same process to get the tails.

    In reality, this is all well-and-good for continuous distributions. I need to rename my Distribution class to Contunuous and create a Discrete class which will operate in discrete terms.

    Additional distribution statistics could be added to each child type without cluttering up one big class, each could have it's own mean, mode, skew, etc.

    opened by Beakerboy 16
  • Planning for Version 2.0

    Planning for Version 2.0

    To keep moving forward and have smaller milestones for releases, here is what I'm considering for MathPHP v2.0 which will be the first backwards incompatible release.

    Key Changes

    • Support PHP 7.2 as a minimum version
    • Improvements to the code base using PHP 7.1 and 7.2 features
    • Support PHPUnit 8.0
    • Put PHP functions in qualified root namespace (Issue 367)

    As these changes are being implemented, continue to add new math features. Version 2.0 will not be dependent on any particular new math functionality.

    After the release of v2.0, the v1.0 branch will only get bug fixes.

    Reasons for Changes

    PHP 7.2 is currently the lowest officially supported version. PHP 7.1 and 7.2 have new features that will improve the quality of the codebase. 7.2 will officially not be supported in a few months, but as a library, it is better to support the lowest version possible. And 7.3 doesn't offer compelling features to not support a still-officially-supported version. I think the next version jump will be to 7.4.

    PHPUnit does not support versions 6.0 or 7.0 anymore. 8.0 is their minimum supported version. It is tied to PHP 7.2.

    The root namespace qualifier, while minor, does improve performance. But more importantly, it communicates explicitly where the function is from and that improves readability. Further, we are already doing the root qualifier on constants, so it will be consistent with the coding style of the project.

    Approach

    I will create a 1.0 branch and a 2.0 branch. I'm still considering whether it makes sense to keep a develop branch around, or just do all development in the latest versioned branch.

    My goal is to keep the scope of this small to get it done rather quickly, and have future development have access to the nice features of PHP 7.1 and 7.2.

    Thoughts and comments welcome!

    opened by markrogoyski 15
  • MatrixBase Class

    MatrixBase Class

    The first pass at moving universal methods to an abstract base class. Any methods which do not perform arithmetic should be able to move here. The MatrixBase would need to contain or add a abstract function declaration for any $this->foo() methods that are used within this class. Adding implements ObjectArithmetic to any child class will probably be good too.

    opened by Beakerboy 15
  • More efficient Combination algorithm

    More efficient Combination algorithm

    Permutation can be improved similarly. This will help hypergeometric. instead of being limited by n! overflowing , it's limited by n! / max(n-k,k)! overflowing

    opened by Beakerboy 14
  • Data direction standard

    Data direction standard

    It looks like we have a few methods which operate under the assumption that the source matrix will be organized with variables in the m direction and samples in the n. For example, sampleMeans() averages each row.

    It looks like both R and Matlab operate u beer the opposite standard, but numpy uses what we have. Personally I vote for what R and Matlab do since that’s how I organize data in a spreadsheet and it seems more intuitive. What do you think?

    opened by Beakerboy 14
  • Document additional Matrix Row Operations and add their Columnar counterparts

    Document additional Matrix Row Operations and add their Columnar counterparts

    While working on #459, I noticed that there's a NumericMatrix->rowAddScalar() method that isn't documented and that there is no matching columnAddScalar. Should this be rectified? I couldn't find an issue referencing their implementation.

    Edit: Noticed there's also rowSubtract and rowSubtractScalar

    opened by Aweptimum 5
  • Add row/column algebra methods to Matrix for Vector

    Add row/column algebra methods to Matrix for Vector

    This request doesn't really have any justification in the pure linear algebra world, but I have run into a use case where I want to treat 3 columns of a 3x3 matrix as vectors. This 3x3 matrix is constructed from 3 column vectors so that I can easily multiply it by another 3x3 rotation matrix (rotating the 3 vectors in one operation). The issue is that I'd still like to operate on the individual columns of the matrix. It would be convenient if there were methods similar to the columnAdd/rowAdd methods and friends that took a row/column index and a vector as arguments.

    $mat = MatrixFactory::createIdentity(3);
    $displacement = new Vector([2,0,0]);
    $mat  = $mat->columnAdd(0, $displacement);
    var_dump($mat->getColumn(0)) // prints [3,0,0]
    

    Currently I'm doing this instead:

    $mat = MatrixFactory::createIdentity(3);
    $zero = new Vector([0,0,0]);
    $displacement = new Vector([2,0,0]);
    $displacementMat = MatrixFactory::createFromVectors([
        $displacement, $zero, $zero
    ]);
    $mat = $mat->add($displacementMat);
    

    Which isn't much more trouble to write, it's just less clear what's going on.

    Understandable if it's preferred to not add these kinds of methods.

    opened by Aweptimum 3
  • Kernel Density Estimation: Improved Sheather-Jones algorithm

    Kernel Density Estimation: Improved Sheather-Jones algorithm

    The KernelDensityEstimation class currently includes the normal distribution approximation bandwidth estimator (see KernelDensityEstimation::getDefaultBandwith()) when no bandwidth is passed to the constructor.

    It would be useful to have the possibility to choose the Improved Sheather-Jones algorithm as the bandwidth function. Especially when working with non-normal-distributed datasets.

    Some resources about Sheather-Jones :

    • https://kdepy.readthedocs.io/en/latest/bandwidth.html#the-improved-sheather-jones-algorithm
    • https://jurnal.fmipa.unila.ac.id/snmk/article/download/2105/1543
    • https://www.jstor.org/stable/2345597
    • Python implementation: https://user-web.icecube.wisc.edu/~peller/pisa_docs/_modules/pisa/utils/vbwkde.html
    opened by orlandothoeny 4
  • Could math-php support KPHP?

    Could math-php support KPHP?

    The KPHP ( https://github.com/VKCOM/kphp ) project can compile a limited subset of PHP to a native executable binary. and we could get great performance from KPHP.

    opened by zjsxwc 1
  • Add vector, matrix and quaternion operations for 3d geometry

    Add vector, matrix and quaternion operations for 3d geometry

    The library could more easily support common 3d geometry operations as e.g. used in cad and games. Vector: If we could add left/right-handed cross product? If we could slerp and interpolate using a function? Matrix: If we could factory scale, rotation and translation 2x2, 3x3 and 4x4 (+w) matrices and maybe their inverses? Quaternion: If we could factory from axis+angle, euler or at+up vectors? If we could slerp, nlerp and interpolate using a function? It is also very useful in 3d to have a Transform type that keeps scale, translation and rotation as separate vectors and a quaternion. This eliminates many matrix inversions e.g. when animating boned 3d meshes. Stretch goal nice to have a Project type that can do perspective and isometric projections. from 3d to 2d for rendering. Since these operations are all very simple, is it better for me to write the code and for someone then to validate the code, or is it easier for somebody who already understands the code to add these? I'd be happy to provide C++ sample code.

    opened by bbesseling 1
Releases(v2.7.0)
  • v2.7.0(Dec 31, 2022)

    Improvements

    • Improved algorithm for regularizedIncompleteBeta: Addresses issue 458
    • Issue 456: Improved PHPDoc blocks: Changed "number" to "int|float"
    • Added PHP 8.2 for CI test target
    Source code(tar.gz)
    Source code(zip)
  • v2.6.0(Apr 10, 2022)

    v2.6.0 - 2022-04-10

    Improvements

    • Average::truncatedMean behavior at 50% trim made consistent
    • PHP 8.1 compatibility improvements

    Backwards Incompatible Changes

    • Average::truncatedMean throws exception if trim percent greater than 50% rather than error or unpredictable results.
    Source code(tar.gz)
    Source code(zip)
  • v2.5.0(Nov 22, 2021)

    New Features

    • Special function logbeta
    • Special function logGamma
    • Special function logGammaCorr
    • Special function stirlingError

    Improvements

    • Improvements in StudentT continuous distribution
    • Improvements in special function gamma
    • Improvements in special function beta

    Bug Fixes

    • Issue 393 (regularizedIncompleteBeta NAN)
    • Issue 429 (Linear regression CI division by zero)
    Source code(tar.gz)
    Source code(zip)
  • v2.4.0(Jul 28, 2021)

    New Features

    • Complex Exponential (exp)
    • Complex Exponentiation (pow)
    • Zipf's Law Discrete Distribution
    • Generalized harmonic non-integer sequence

    Improvements

    • Fixed Complex polarForm to compute the right values
    • Fixed hyperharnomic non-integer sequence. Previously was computing the wrong thing
    • Fixed how ArbitraryInterger handles pow of negative exponents

    Backwards Incompatible Changes

    • Complex polarForm now returns an array rather than a Complex number, as the Complex return was incorrect
    • Interface to hyperharmonic non-integer sequence changed due to previous implementation being incorrect
    Source code(tar.gz)
    Source code(zip)
  • v2.3.0(Jul 14, 2021)

  • v2.2.0(Jul 11, 2021)

  • v2.1.0(Jul 7, 2021)

  • v2.0.0(May 9, 2021)

    New Features

    • Matrix Improvements
      • walk method to map a function to all values without mutation or returning a value
      • MatrixFactory creates more matrix types
      • MatrixFactory::createNumeric to create NumericMatrix types
      • MatrixFactory::createFromRowVector
      • MatrixFactory::createFromColumnVector
      • Internal ObjectMatrix improvements
        • Add trace
        • Add scalarMultiply
      • Add initial ComplexMatrix
    • Sample data People

    Improvements

    • Bug fixes
      • Issue 414 fixed - PCA/Eigenvalue convergence
      • Issue 413 fixed - matrix solve with singular matrix using RREF

    Migration - Upgrading to v2.0 from v1.0

    • PHP minimum version now 7.2 (was 7.0)
    • Deprecated code removed (backwards-incompatible change)
      • MathPHP\Statistics\Distance::kullbackLeiblerDivergence removed (Use MathPHP\Statistics\Divergence::kullbackLeibler instead)
      • MathPHP\Statistics\Distance::jensenShannonDivergence removed (Use MathPHP\Statistics\Divergence::jensenShannon instead)
      • Matrix Decompositions no longer implement \ArrayAccess interface to access decomposition matrixes. Use properties instead.
        • MathPHP\LinearAlgebra\Decomposition\Cholesky
          • $cholesky['L'], $cholesky['Lᵀ'], $cholesky['LT'] removed, use $cholesky->L, $cholesky->Lᵀ, $cholesky->LT instead.
        • MathPHP\LinearAlgebra\Decomposition\Crout
          • $crout['L'], $crout['U'] removed, use $crout->L, $crout->U instead.
        • MathPHP\LinearAlgebra\Decomposition\LU
          • $LU['L'], LU['U'], LU['P'] removed, use $LU->L, $LU->U, $LU->P instead.
        • MathPHP\LinearAlgebra\Decomposition\QR
          • $QR['Q'], $QR['R'] removed, use $QR->Q, $QR->R instead.
    • Methods renamed (backwards-incompatible change)
      • MathPHP\Statistics\Distance::bhattacharyyaDistance renamed to MathPHP\Statistics\Distance::bhattacharyya
      • MathPHP\Statistics\Distance::hellingerDistance renamed to MathPHP\Statistics\Distance::hellinger
    • Moved Functionality (backwards-incompatible change)
      • MathPHP\Functions\Polynomial moved to MathPHP\Expression\Polynomial
      • MathPHP\Functions\Piecewise moved to MathPHP\Expression\Piecewise
    • Matrix internal refactoring
      • Note: These changes will not affect any client code as long as matrices were created using MatrixFactory.
      • Matrix is not a base abstract class for all matrix classes to extend
      • Matrix renamed NumericMatrix
      • Matrix base method createZeroValue
        • Use case is various ObjectMatrix classes that implement ObjectArithmetic
      • RowVector removed. Use MatrixFactory::createFromRowVector instead
      • ColumnVector removed. Use MatrixFactory::createFromColumnVector instead
    Source code(tar.gz)
    Source code(zip)
  • v1.11.0(May 9, 2021)

  • v1.10.0(Dec 19, 2020)

  • v1.9.0(Dec 13, 2020)

    New Features

    • Vector min and max
    • Arithmetic isqrt (integer square root)

    Improvements

    • Remove Travis CI (Moved CI to Github Actions in v1.8.0 release)
    • Rearrange non-code files
    Source code(tar.gz)
    Source code(zip)
  • v1.8.0(Dec 11, 2020)

    Improvements

    • Improve permutations algorithm to be more efficient and more numerically stable
    • Qualify PHP function names with root namespace
    • Move CI to Github Actions
    Source code(tar.gz)
    Source code(zip)
  • v1.7.0(Nov 15, 2020)

    New Features

    • Algebra linear equation of one variable
    • Rational number inverse
    • Rational number pow

    Improvements

    • Improve combinations algorithm to be more efficient and more numerically stable
    • Internal Matrix class reorganization
    Source code(tar.gz)
    Source code(zip)
  • v1.6.0(Oct 22, 2020)

    New Features

    • Special function regularized lower incomplete gamma
    • Cereal sample data set

    Improvements

    • Define boundary condition for lower incomplete gamma function
    Source code(tar.gz)
    Source code(zip)
  • v1.5.0(Oct 13, 2020)

    v1.5.0

    New Features

    • Matrix LU solve
    • Matrix QR solve

    Improvements

    • Bugfix (Issue 386) Matrix solve improvements
    • Matrix solve has optional method parameter to force a solve method
    • Bugfix ArbitraryInteger multiplication sign not taken into account
    Source code(tar.gz)
    Source code(zip)
  • v1.4.0(Oct 3, 2020)

    New Features

    • Multivariate Regular Grid Interpolation
    • Jensen-Shannon Distance
    • Canberra Distance
    • Search Sorted
    • Search ArgMax
    • Search NanArgMax
    • Search ArgMin
    • Serach NanArgMin
    • Search NonZero

    Improvements

    • Divergence factored out of Distance into new Divergence class

    Backwards Incompatible Changes

    • Legacy Distance divergences marked as deprecated (To be removed in v2.0.0)
    Source code(tar.gz)
    Source code(zip)
  • v1.3.0(Aug 25, 2020)

    New Features

    • LinearAlgebra\Vector
      • Angle between two vectors
      • L¹ distance of two vectors
      • L² distance of two vectors
      • Minkowski distance of two vectors
    • Statistics\Distance
      • Minkowski distance
      • Euclidean distance (L² distance)
      • Manhattan distance (Taxicab geometry, L¹ distance, etc.)
      • Cosine distance
      • Cosine similarity
    Source code(tar.gz)
    Source code(zip)
  • v1.2.0(Jul 25, 2020)

    New Features

    • Ranking
      • Ordinal ranking
      • Standard competition ranking
      • Modified competition ranking
      • Fractional ranking

    Improvements

    • (Issue 380) Fixed Spearman's Rho calculation when there are rank ties
    Source code(tar.gz)
    Source code(zip)
  • v1.1.0(Apr 20, 2020)

  • v1.0.0(Apr 14, 2020)

  • v0.62.0(Apr 9, 2020)

  • v0.61.0(Mar 23, 2020)

  • v0.60.0(Feb 27, 2020)

  • v0.59.0(Feb 19, 2020)

    New Features

    • Add population and sample kurtosis
    • Changed default kurtosis algorithm to the more common population kurtosis
    • kurtosis now takes an optional parameter to set the kurtosis type algorithm
    Source code(tar.gz)
    Source code(zip)
  • v0.58.0(Feb 7, 2020)

    Improvements

    • Changed default skewness algorithm to the more common sample skewness
    • skewness now takes an optional parameter to set the skewness type algorithm
    • Improvements to skewness algorithms
    Source code(tar.gz)
    Source code(zip)
  • v0.57.0(Jan 8, 2020)

    New Features

    • Number\Rational basic getters
      • getWholePart
      • getNumerator
      • getDenominator
    • Set Theory n-ary Cartesian product

    Improvements

    • Data direction control for Matrix meanDeviation and covarianceMatrix
    • Algebra factors performance improvement
    Source code(tar.gz)
    Source code(zip)
  • v0.56.0(Dec 4, 2019)

    New Features

    • Number Theory
      • isDeficientNumber
      • isAbundantNumber
      • aliquotSum
      • radical
      • totient
      • cototient
      • reducedTotient
      • mobius
      • isSquarefree
      • isRefactorableNumber
      • isSphenicNumber
      • numberOfDivisors
      • sumOfDivisors

    Improvements

    • Optimization of prime factorization algorithm
    Source code(tar.gz)
    Source code(zip)
  • v0.55.0(Nov 19, 2019)

  • v0.54.0(Oct 13, 2019)

    New Features

    • Matrix isNilpotent
    • Matrix isRectangularDiagonal
    • Matrix mapRows
    • MathPHP logo

    Improvements

    • MatrixFactory random matrix custom lower and upper bounds for random number
    • PSR-12 style compliance
    • Bugfix: powerIteration random failure - Issue 346
    Source code(tar.gz)
    Source code(zip)
  • v0.53.0(Sep 10, 2019)

    New Features

    • Matrix QR decomposition using Householder reflections
    • Matrix Householder transformation
    • MatrixFactory random matrix
    • MatrixFactory givens rotation matrix
    • Matrix isIdempotent
    • Matrix Eigenvalue power iteration
    • Matrix Eigenvalue jacobi method
    • Arithmetic root (nᵗʰ root)
    • Vector arithmetic multiply and divide
    • Vector Iterator interface

    Improvements

    • Internal improvements to Matrix
    • Matrix decompositions returned as objects
    • Matrix Cholesky decomposition provides L transpose
    Source code(tar.gz)
    Source code(zip)
Owner
Mark Rogoyski
Developer of MathPHP and Honyaku Star.
Mark Rogoyski
Library for converting units and sizes in PHP

php-conversion Library for converting units and sizes in PHP. Units supported Acceleration Angle Area Digital information Electric current Frequency F

Christoffer Niska 122 Mar 16, 2021
Tensor is a library and extension that provides objects for scientific computing in PHP.

Tensor is a library and extension that provides objects for scientific computing in PHP. The multithreaded extension is especially suited for computing large sets of numbers. In some cases, the extension is 230X faster than the same operation in PHPland. Tensor is used by libraries such as Rubix ML to build and accelerate machine learning algorithms such as linear regression, dimensionality reduction, and neural networks.

Rubix 157 Jan 3, 2023
PHP version of Google's phone number handling library

libphonenumber for PHP What is it? A PHP library for parsing, formatting, storing and validating international phone numbers. This library is based on

Joshua Gigg 4.2k Jan 7, 2023
A PHP 5.3+ mathematics library, providing functionality for large numbers

Moontoast Math Library Moontoast\Math is useful for working with integers that are larger than (or may become larger than, through mathematical comput

Moontoast 245 Sep 8, 2022
Advanced Mathematics Library for PHP (port of Numbers.js)

Numbers.php Numbers.php - an advanced mathematics toolkit for PHP >= 5.3. It is a port of Numbers.js - same toolkit for JavaScript. There is a version

null 159 Jul 24, 2022
BigNum library for PHP compatible with bn.js

BigNum library for PHP Information This library provides a PHP Big Number API compatible with bn.js and is used in Fast PHP ECC library elliptic-php.

Simplito 16 Nov 13, 2022
Arbitrary-precision arithmetic library for PHP

Arbitrary-precision arithmetic library for PHP

Brick 1.4k Jan 1, 2023
Library to parse, format and convert byte units

Byte Units This is a utility component for parsing, formatting, converting and manipulating byte units in various formats. Usage <?php // Bytes manip

Gabriele Lana 156 Dec 9, 2022
A library for handling physical quantities and the units of measure in which they're represented.

PHP Units of Measure master: Introduction This is a PHP library for representing and converting physical units of measure. The utility of this library

Jonathan Hanson 21 Sep 28, 2022
Unit converter and calculator for php

Unit converter and calculator This library uses the awesome lisachenko/z-engine to allow mathematical operations on objects, allowing to do stuff like

Dominik Chrástecký 8 Apr 8, 2022
PHP package that provides functions for calculating mathematical statistics of numeric data

Statistics PHP package PHP package that provides functions for calculating mathematical statistics of numeric data. In this package I'm collecting som

Hi Folks! 289 Dec 27, 2022
PHP package that provides functions for calculating mathematical statistics of numeric data.

Statistics PHP package PHP package that provides functions for calculating mathematical statistics of numeric data. In this package I'm collecting som

Hi Folks! 290 Dec 29, 2022
Sey is a powerful math interpreter with infinite-precision.

Sey, pronounce say, is a powerful math interpreter with infinite-precision.

Félix Dorn 13 Oct 1, 2022
A simple Object Oriented wrapper for Linear API, written with PHP.

PHP Linear API A simple Object Oriented wrapper for Linear API, written with PHP. NOTE You should take a look Linear GraphQL API Schema for all nodes

Mustafa KÜÇÜK 6 Sep 2, 2022
A Magento 2 module that allows for creating discrete PDP (Product Detail Pages) page layouts for customers landing on the site from a PPC (Pay Per Click) link/ad by allowing routing to the same pages using a `/ppc/` prefix in the URL path.

A Magento 2 module that allows for creating discrete PDP (Product Detail Pages) page layouts for customers landing on the site from a PPC (Pay Per Click) link/ad by allowing routing to the same pages using a `/ppc/` prefix in the URL path.

null 16 Nov 11, 2022
Enhancement to Magento to allow simple product prices to be used instead of the default special-case configurable product prices

Simple Configurable Products Extension For Magento This documentation applies to SCP versions 0.7 onwards. The documentation for SCP v0.6 and earlier

Simon King 288 Nov 7, 2022
The plugin allows to execute math operations in the server or console.

General The plugin allows to execute math operations in the server or console with /calculator command Arithmetic Operators List of supported arithmet

NhanAZ's PocketMine-MP Plugins 3 Oct 20, 2022
Simple, image-based, mathematical captcha, with increasing levels of difficulty

simple-captcha Simple, image-based, mathematical captcha, with increasing levels of difficulty version 1.1.0 see also: ModelView a simple, fast, power

Nikos M. 6 Dec 18, 2022
Simple MySQL library for PHP 5.4+ includes Query Builder, PDO Native functions, Helper functions for quick use.

Simple MySQL library for PHP 5.4+ includes Query Builder, PDO Native functions, Helper functions for quick use.

Kodols 9 Dec 22, 2022