Giter VIP home page Giter VIP logo

phpmathobjects's Introduction

PHPMathObjects - A PHP library to handle mathematical objects

Tests GitHub License Coverage Status

The PHPMathObjects library was created with crystallographic applications in mind but should be suitable for broad variety of projects. The library has 100 % coverage with unit tests and is performance-optimized. Being actively developed, it is not yet suitable for production environment since the current API is subject to change.

Installation

Install PHPMathObjects using Composer:

composer require sivlev/phpmathobjects

or include the following line to your composer.json file:

"sivlev/phpmathobjects": "*"

Requirements

The library requires PHP 8.2 or above. No other external dependencies are required.

How to use

This section contains simplified lists of PHPMathObjects API methods. Some parameters with default values are omitted for clarity. For full API reference please refer to docs.

Contents

General mathematics

Math

Math class contains common math functions that may be needed in various areas. The functions are implemented as static methods.

// Check if the number equals zero within the given tolerance
$isZero = Math::isZero(0.000002);                       // Returns false
$isZero = Math::isZero(0.000002, 1e-3);                 // Returns true

// Check if the number does not equal zero within the given tolerance
$isNotZero = Math::isNotZero(0.000002);                 // Returns true
$isNotZero = Math::isNotZero(0.000002, 1e-3);           // Returns false

// Check if two numbers are equal within the given tolerance
$areEqual = Math::areEqual(0.000002, 0.000003);         // Returns false
$areEqual = Math::areEqual(0.000002, 0.000003, 1e-3);   // Returns true

// Compare two numeric arrays elementwise within the given tolerance
$areEqual = Math::areArraysEqual([1, 2, 3], [1, 2, 3]); // Returns true

// Find the greatest common divisor of two numbers
$gcd = Math::gcd(28, 35);       // Returns 7

Linear Algebra

Matrix

Many matrix methods in PHPMathObjects are implemented in two versions: non-mutating (return a new matrix object) and mutating (change the existing matrix). The latter method names have a letter "m" in the beginning, e.g. add() and mAdd(), transpose() and mTranspose(), etc. You can decide which method is more suitable for a particular task. Usually the mutating methods are slightly faster than non-mutating ones because no new object instantiation is needed.

// Create a new matrix object using class constructor
$matrix = new Matrix([
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
]);

// Or use a suitable factory method
$matrix = Matrix::fill(3, 4, 0.1);          // Make a 3x4 matrix and fill its elements with 0.1
$matrix = Matrix::identity(3);              // Make a 3x3 identity matrix
$matrix = Matrix::random(5, 8, -3.5, 9.5)   // Make a 5x8 matrix filled with random float numbers between -3.5 and 9.5
$matrix = Matrix::randomInt(3, 3, 1, 10)    // Make a 3x3 matrix filled with random integer numbers between 1 and 10

// Matrix dimensions
$rows = $matrix->rows();
$columns = $matrix->columns();
$numberOfElements = $matrix->size(); 
$numberOfElements = count($matrix);         // Alternative way as Matrix implements "Countable" interface

// Get matrix as array
$array = $matrix->toArray(); 

// Element getters and setters (zero-based indexing)
$element = $matrix->get(1, 2);
$matrix->set(1, 2, -15.6);
$element = $matrix->set(1, 2, 100)->get(1, 2); // Set() method returns $this so it can be chained
$doesElementExist = $matrix->isSet(2, 1);

// Alternative getters and setters via "ArrayAccess" interface
$element = $matrix[[1, 2]];    // Note the format of the index. The problem is that PHP supports native ArrayAccess for 1D arrays only
$matrix[[1, 2]] = 15;
$doesElementExist = isset($matrix[[1, 2]]);

// Matrix properties
$isSquare = $matrix->isSquare(); 

// Compare matrices
$equal = $matrix->isEqual($anotherMatrix);          // Compare elementwise within a default tolerance of 1.0e^-8
$equal = $matrix->isEqual($anotherMatrix, 1e-8);    // Or set the tolerance explicitly
$equal = $matrix->isEqualExactly($anotherMatrix);   // Compare matrices elementwise with '===' operator

// Check if the matrix has zero elements only
$isZero = $matrix->isZero($tolerance);              // Check if zero elementwise within the given tolerance (default is 1.0e^-8)
$isZeroExactly = $matrix->isZeroExactly();          // Check if zero elementwise exactly using the '===' operator

// Matrix arithmetics
$sum = $matrix->add($anotherMatrix);
$difference = $matrix->subtract($anotherMatrix);
$multiplication = $matrix->multiply($anotherMatrix);
$multiplicationByScalar = $matrix->multiplyByScalar($scalarIntOrFloat);
$signsChanged = $matrix->changeSign();

// Matrix arithmetics (mutating methods)
$matrix->mAdd($anotherMatrix);
$matrix->mSubtract($anotherMatrix);
$matrix->mMultiply($anotherMatrix);
$matrix->mMultiplyByScalar($scalarIntOrFloat);
$matrix->mChangeSign();

// Matrix unary operations
$transpose = $matrix->transpose();
$trace = $matrix->trace();
$determinant = $matrix->determinant();
$rowEchelonForm = $matrix->ref();
$reducedRowEchelonForm = $matrix->rref();

// Matrix unary operations (mutating methods)
$matrix->mTranspose();
$matrix->mRef();             //Row echelon form
$matrix->mRref();            //Reduced row echelon form

// Matrix resizing and concatenation
$joinRight = $matrix->joinRight($anotherMatrix);
$joinBottom = $matrix->joinBottom($anotherMatrix);

// Matrix resizing and concatenation (mutating methods)
$matrix->mJoinRight($anotherMatrix);
$matrix->mJoinBottom($anotherMatrix);

 // Create a 1x2 submatrix starting from the element at row 0, column 0 till the element at row 1, column 2 
$submatrix = $matrix->submatrix(0, 0, 1, 2);

// Convert a matrix row or column to a Vector object
$rowVector = $matrix->rowToVector(1);
$columnVector = $matrix->columnToVector(2);

// Conversion to a string representation
$string = $matrix->toString();
$string = (string) $matrix;
// Both ways will return
// [1, 2, 3]
// [4, 5, 6]
// [7, 8, 9]

Vector

Vector class extends the Matrix class so all Matrix methods are available too. Some of them have additional wrappers for more convenient usage, e.g. fill() vs. vectorFill().

// Create a new vector using the class constructor
$rowVector = new Vector([[1, 2, 3]]);
$columnVector = new Vector([
    [1],
    [2],
    [3],
]);

// Or use a suitable factory method
$vector = Vector::fromArray([1, 2, 3], VectorEnum::Column);   // Creates a [[1], [2], [3]] column vector
$vector = Vector::vectorFill(5, 1.1, VectorEnum::Row);         // Creates a [[1.1, 1.1, 1.1, 1.1, 1.1]] row vector
$vector = Vector::vectorRandom(5, -3.5, 9.5)   // Make a with 5-component vector filled with random float numbers between -3.5 and 9.5
$vector = Vector::randomInt(3, 1, 10)    // Make a 3-component vector filled with random integer numbers between 1 and 10

// Get the vector type (orientation)
$rowVector->vectorType();                 // Returns VectorEnum::Row
$columnVector->vectorType();              // Returns VectorEnum::Column

// Vector size
$numberOfComponents = $rowVector->size(); // Returns 3
$numberOfElements = count($rowVector);    // Alternative way as Vector implements "Countable" interface
$rows = $rowVector->rows();               // Returns 1
$columns = $rowVector->columns();         // Returns 3
$rows = $columnVector->rows();               // Returns 3
$columns = $columnVector->columns();         // Returns 1  

// Element getters and setters (zero-based indexing)
$element = $rowVector->vGet(2);            // Equivalent to get(1, 2) using the Matrix method
$rowVector->vSet(2, -15.6);                // Equivalent to set(1, 2, -15.6) using the Matrix method
$doesElementExist = $rowVector->vIsSet(2); // Equivalent to isSet(2) using the Matrix method 

// Alternative getters and setters via "ArrayAccess" interface
$element = $rowVector[2];    // Equivalent to $rowVector->vGet(2)
$rowVector[2] = 15;          // Equivalent to $rowVector->vSet(2, 15) 
$doesElementExist = isset($rowVector[2]);

// Get vector as an array
$columnVector->toArray();
/* Returns the 2D column array:
 * [
 *  [1],
 *  [2],
 *  [3],
 * ]
 */
$columnVector->toPlainArray();      // Returns a 1D array [1, 2, 3]

// Get a subvector
$subvector = $rowVector->subvector(1, 2); // Returns a new vector [2, 3]

// Vector binary operations
dotProduct = $rowVector->dotProduct($anotherVector);
$crossProduct = $rowVector->crossProduct($anotherVector);

// Conversion to a string representation
$string = $rowVector->toString();
$string = (string) $rowVector;
// Both ways will return
// [1, 2, 3]
$string = $columnVector->toString();
$string = (string) $columnVector;
// Both ways will return
// [1]
// [2]
// [3]

Numbers

Rational

A class to store rational numbers and perform mathematical operations on them

// Create a new rational number using class constructor Rational($whole, $numerator, $denominator)
$r = new Rational(5, 1, 2);             // Creates a rational number 1 1/2

// Or use a suitable class constructor
$r = Rational::fromString("-5 1/3");    // Equivalent to "new Rational(-5, -1, 3)"
$r = Rational::fromInt(15);             // Equivalent to "new Rational(15, 0, 1)"
$r = Rational::fromFloat(0.333333);     // Equivalent to "new Rational(0, 1, 3)"

// Convert a rational to a float
$r = Rational::fromString("1/3");
$float = $r->toFloat();                 // Returns 0.33333333333

// Convert a rational to a text form using toString() method
$string = $r->toString();               // Returns "-5 1/3"
// or string cast
$string = (string) $r;  

// Compare a rational number with zero
$isZero = $r->isZero();
// Or with another rational
$isEqual = $r->isEqual($anotherRational);

// Check if the rational number is negative
$isNegative = $r->isNegative();
// Or if it is positive
$isPositive = $r->isPositive();

// Check if the rational number is an integer
$isInteger = $r->isInteger();

// Calculate the reciprocal (multiplicative inverse)
$reciprocal = $r->reciprocal();

// Arithmetics with rationals
$r1 = Rational::fromString("2 3/8");
$r2 = Rational::fromString("4 9/17");
$sum = $r1->add($r2);
$difference = $r1->subtract($r2);
$multiplication = $r1->multiply($r2);
$division = $r1->divide($r2);

phpmathobjects's People

Contributors

sivlev avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.