apollonin/numphp

View on GitHub
README.md

Summary

Maintainability
Test Coverage
# Numphp

[![Build Status](https://travis-ci.org/apollonin/numphp.svg?branch=master)](https://travis-ci.org/apollonin/numphp)
[![Latest Stable Version](https://poser.pugx.org/apollonin/numphp/v/stable)](https://packagist.org/packages/apollonin/numphp)
[![Total Downloads](https://poser.pugx.org/apollonin/numphp/downloads)](https://packagist.org/packages/apollonin/numphp)
[![License](https://poser.pugx.org/apollonin/numphp/license)](https://packagist.org/packages/apollonin/numphp)
[![codecov](https://codecov.io/gh/apollonin/numphp/branch/master/graph/badge.svg)](https://codecov.io/gh/apollonin/numphp)
[![Maintainability](https://api.codeclimate.com/v1/badges/9cda6d0e7e7967900ff2/maintainability)](https://codeclimate.com/github/apollonin/numphp/maintainability)
[![Test Coverage](https://api.codeclimate.com/v1/badges/9cda6d0e7e7967900ff2/test_coverage)](https://codeclimate.com/github/apollonin/numphp/test_coverage)

Numphp is a library for number manipulations. If you have an array of numbers, numphp gives you an ability to perform a wide range of useful operations.

Contributions are highly appreciated.

## Installation

### With composer

```
composer require apollonin/numphp
```


## Available features

**Arrays**

* get item by index
* get items by array of indexes
* get items by condition
  * eq, gt, gte, lt, lte, neq - equals, greater than, and so on
* get items by complex conditions
  * b_and, b_or - bitwise AND and OR
* set items values according to conditions, indexes or slices
* apply math operations to whole array
  * mul, div, add, sub, pow, mod
* get slice of array
* get statistical values from array
  * count, max, mean, median, min, sum
  * describe - special method that displays all above values
* Get dimensional data
  * shape
  * dimension
* Concatenate arrays

np_array also has classical array behaviour. So you are able to iterate through it as usual.

**Matrix**

Matrix is a special case of arrays. At the moment, we only support 2d matrices. Full support for n-dimensional matrices is on the way. 

You can perform all the same operations and comparisons as with arrays. Refer to Matrix section below in usage examples.

**Dimensional Manipulation**

You are able to change dimensions for existed array or matrix. Use `flatten` or `reshape` methods.

**Random Module**

Numphp also provides convenient ways to generate new np_arrays and populate them with random values. Available methods are

* rand
* randint

If `size` parameter is given, returns np_array with appropriate elements. Otherwise, it returns single random value.

**Generators**

For quick stub array creation you may use these convenient predefined methods

* ones - creates array full of 1
* zeros - creates array full of 0 
* full- creates array full of provided fill_value
* arange - creates evenly spaced values within a given interval.
* fib - creates Fibonacci numbers
* formula - returns sequence of numbers, based on provided formula


## Usage Examples

### Indexing

**create new array**
```php
$list = new np_array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
```

**Get items by their indexes**

```php
$result = $list[[2,3]];

// result
[2, 3]
```

To get item as single value - pass index as single value as well

```php
$result = $list[1];

// result
1
```

**Get items by condition**

```php
$result = $list[$list->gt(5)];

// result
[6, 7, 8, 9]
```

You may also access index by string representations of comparison. 

```php
// gives the same result as above
$result = $list[$list['> 5']];
```

*Important note about conditional indexing: conditional operator returns masking array:*



```php
  $mask = $list->gt(5);

  // mask
  [false, false, false, false, false, false, true, true, true, true]

  // and then
  $result = $list[$mask];

  // result 
  [6, 7, 8, 9]
```

You also can pass another array as an argument. In this case the comparison will be applied for each element respectively.

```php
$result = $list[$list->gt([5, 6, 7, 8, 9, 3, 4, 5, 6, 7])];

// result
[6, 7, 8, 9]
```


**Get items by conditions**

*b_and* - "bitwise" and

```php
$resuilt = $list[Bitwise::b_and($list->gte(5), $list->lt(8))];

// result
[5, 6, 7]
```

**Array-like behaviour**

You may also iterate your np_array object as usual

```php
foreach ($list as $item) {
    echo $item . " ";
}

// output
0 1 2 3 4 5 6 7 8 9
```


### Slicing

You may get slices of your np_array in a very convenient way. Just pass string formatted like `start:[stop][:step]` as index and you'll get result.

```php
$result = $list['1:5'];

//result
[1, 2, 3, 4]


$result = $list['1:5:2'];

//result
[1, 3]
```

You can even skip `stop` and `step` values, which means: get all items from `start` to the end of array.

```php
$result = $list['1:'];

//result
[1, 2, 3, 4, 5, 6, 7, 8, 9]
``` 

You may even skip `start` value; it will be considered as 0 in this case

```php
$result = $list[':'];

//result
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
```

Negative `start` or `stop` means indexes count from the end of array

```php
$result = $list['-7:6'];

//result
[3, 4, 5]
```


### Set item values

**Set items by indexes**

```php
$result = clone($list);
$result[[2,3]] = 999;

// result
[0, 1, 999, 999, 4, 5, 6, 7, 8, 9]
```

**Set items by conditions**

```php
$result = clone($list);
$result[$result->gte(5)] = 999;

// result
[0, 1, 2, 3, 4, 999, 999, 999, 999, 999]
```

**Set items by slice**

```php
$result = clone($list);
$result['1:3'] = 999;

// result
[0, 999, 999, 3, 4, 5, 6, 7, 8, 9]
```

**Adding new items**

Of course, you may add new items as usual

```php
$result = clone($list);
$result[] = 999;

// result 
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 999]
```

### Math operations

You are able to apply certain math operations to the whole array. It will apply to each element.

```php
$result = $list->add(100);

// result 
[100, 101, 102, 103, 104, 105, 106, 107, 108, 109]
```

You may also perform math operation under two np_arrays

```php
$result = $list->add(new np_array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]))

//result
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
```

Or event np_array and normal array!

```php
$result = $list->add([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);

//result
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
```



### Random module

**Create array with random floats**

```php
use numphp\Random\Random;

$result = Random::rand(5)

// result
[0.64488127438579, 0.21702189986455, 0.96931800524207, 0.78197341448719, 0.89214772632911]

```

**Array with random integers**

```php
use numphp\Random\Random;

$result = Random::randint(5, 15, 10);

// result
[13, 9, 12, 14, 6, 15, 8, 9, 5, 13]
```


### Generators module

**create array full of zeros, ones or fill_value**

```php
use numphp\Generator\Generator;

$result = Generator::zeros(5);

//result
[0, 0, 0, 0, 0]


$result = Generator::ones(5);

//result
[1, 1, 1, 1, 1]

$result = Generator::full(5, 999);

//result
[999, 999, 999, 999, 999]
```

**Create array within a range and given interval**

```php
use numphp\Generator\Generator;

$result = Generator::arange(1, 15, 2);

//result
[1, 3, 5, 7, 9, 11, 13]
```

**Generate N [Fibonacci](https://en.wikipedia.org/wiki/Fibonacci_number) numbers**

```php
use numphp\Generator\Generator;

$result = Generator::fib(6);

//result
[1, 1, 2, 3, 5, 8]
```


**Generate numbers according to formula**

Provide [callable](http://php.net/manual/en/language.types.callable.php) as a first argument. It must return value, that will be used in sequence.

```php
use numphp\Generator\Generator;

$result = Generator::formula(function($n){return 2*$n+1;}, 1, 5);

//result
[3, 5, 7, 9]
```

**Generate matrix with given diagonal**

```
$matrix = Generator::diagonal([5, 3, 1]);

// matrix
[[5, 0, 0],
[0, 3, 0],
[0, 0, 1]]
```


### Matrix operations

Generally the syntax and features are the same as for arrays

**Creation**

```
$matrix = new np_array([[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]);

// matrix
[[ 0,  1,  2,  3],
 [ 4,  5,  6,  7],
 [ 8,  9, 10, 11]]
```

**Indexing**

Indexing is done in respect to X-axis (rows)

```
$result = $matrix[0];

//result
[0, 1, 2, 3]
```

**Slicing**

```
$result = $matrix['1:3'];

//result
[[ 4,  5,  6,  7],
 [ 8,  9, 10, 11]]
```

**Comparisons**

```
$result = $matrix[$matrix->gt(5)];

//result
[6, 7, 8, 9, 10, 11]
```

Keep in mind 'masking' feature

```
$mask = $matrix->gt(5);

//mask 
[[false, false, false, false],
[false, false, true, true],
[true, true, true, true]]
```

**Changing values**

```
$matrix[$matrix->gte(5)] = 999;

//matrix
[[  0,   1,   2,   3],
 [  4, 999, 999, 999],
 [999, 999, 999, 999]]
```

**Math operations**

```
$result = $matrix->mul(5);

//result
[[ 0,  5, 10, 15],
 [20, 25, 30, 35],
 [40, 45, 50, 55]]
```

**Get shape of matrix**

```
$shape = $matrix->shape;

//shape: [rows, cols]
[3, 4]
```

And if you just need count of dimensions

```
$dimensions = $matrix->dimensions;

//dimensions
2
```


**Diagonal**

```
$result = $matrix->diagonal();

//result 
[0, 5, 10]

```

or you can set offset for diagonal

```
$result = $matrix->diagonal(2);

//result 
[2, 7]

```

## Changing dimensions

**Flatten matrix**

You can get 1-D array from matrix.

```
$result = $matrix->flatten();

//result
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
```

**Reshaping**

You also can change current shape of matrix to any desired.

```
$result = $matrix->reshape([6, 2]);

//result
[[ 0,  1],
 [ 2,  3],
 [ 4,  5],
 [ 6,  7],
 [ 8,  9],
 [10, 11]]
```


## Concatenation

**concatenate arrays**

You can concatenate two or more arrays into one. Logic is similar to [array_merge](http://php.net/manual/en/function.array-merge.php) native php method

```
$l1 = Generator::arange(1, 5);
$l2 = Generator::arange(5, 8);
$l3 = Generator::arange(8, 10);

$result = np::concatenate($l1, $l2, $l3)

//result
[1, 2, 3, 4, 5, 6, 7, 8, 9]
```

**concatenate matrixes**

The same logic can be applied to matrixes

```
$m2 = Generator::ones([1, 4]);
$result = np::concatenate($matrix, $m2)

//result
[[ 0,  1,  2,  3],
 [ 4,  5,  6,  7],
 [ 8,  9, 10, 11],
 [ 1,  1,  1,  1]]

```