# malenkiki/math

A work in progress about Math! Implemented or partially implemented mathematical concepts are: Complex number, Matrix, Normal distribution, Random, Angle, Random Complex, Descriptive Statistics and Parametric tests
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.
src/Malenki/Math
tests
.gitignore
.travis.yml
composer.json
phpunit.xml

# Math

Library to deal with some mathematical stuff.

Implemented or partially implemented mathematical concepts are: Complex number, Matrix, Normal distribution, Random, Angle, Random Complex, Descriptive Statistics, Parametric tests (Anova, Dependant t-Test) and Non-Parametric tests (Wilcoxon Signed-rank test, Wilcoxon-Mann-Whitney test, Kruskal-Wallis).

## Install

You can get this lib by downloading the ZIP archive, cloning this repository or using Composer with the following code to put into your `composer.json` file:

```{
"require": {"malenki/math": "dev-master"}
}```

## Angle

You can use angles as deg, gon, rad or turn. By default, radians is used.

```use \Malenki\Math\Unit\Angle;

\$a = new Angle(pi()/2);
var_dump(\$a->deg); // get degrees
var_dump(\$a->turn); // get turns```

You can get DMS style too:

```use \Malenki\Math\Unit\Angle;

\$a = new Angle(34.53, Angle::TYPE_DEG);
var_dump(\$a->dms); // get DMS object
var_dump(\$a->dms->str); // get DMS string '34°31′48″'```

You can test whether current angle is right, straight or perigon:

```use \Malenki\Math\Unit\Angle;

\$a = new Angle(pi() / 2);
var_dump(\$a->isRight()); // should return TRUE

\$b = new Angle(pi());
var_dump(\$b->isStraight()); // should return TRUE

\$c = new Angle(2 * M_PI);
var_dump(\$c->isPerigon()); // should return TRUE

\$d = new Angle(450, Angle::TYPE_DEG); //yes, ignore multiple turns :)
var_dump(\$d->isRight()); // should return TRUE```

You can test current angle with another to know is they are complementary or supplementary:

```use \Malenki\Math\Unit\Angle;

\$a = new Angle(M_PI / 3);
\$b = new Angle(M_PI / 6);
var_dump(\$a->isComplementary(\$b)); // should be TRUE
var_dump(\$b->isComplementary(\$a)); // should be TRUE

\$c = new Angle(M_PI / 2);
\$d = new Angle(90, Angle::TYPE_DEG);
var_dump(\$c->isSupplementary(\$d)); // should be TRUE
var_dump(\$d->isSupplementary(\$c)); // should be TRUE```

## Matrix

Creating matrix is simple, first step, you instanciate it with column numbers and row numbers, second step, you put data into it.

```use \Malenki\Math\Matrix;

//instanciate
\$m = new Matrix(3, 2);
//then populate
\$m->populate(array(1,2,3,4,5,6));
//or
//or

Getting data is not difficult too. You can get matrice’s size, content for a row or a column, all data and even a dump as a string.

```var_dump(\$m->cols); // amount of columns
var_dump(\$m->rows); // amount of rows

var_dump(\$m->getRow(0)); // get row having index 0
var_dump(\$m->getCol(1)); // get column having index 1

var_dump(\$m->getAll()); // Gets all data as array

// following will output that:
// 1  2
// 3  4
// 5  6
print(\$m);```

Getting matrix transpose is as simple as that:

`echo \$m->transpose();`

OK, you can get, you can set… but you can do more complicated things.

You can multiply matrix with another one, but beware of compatibility!

```use \Malenki\Math\Matrix;

\$n = new Matrix(2, 3);
\$n->populate(array(7, 8, 9, 10, 11, 12));

if(\$m->multiplyAllow(\$n))
{
print(\$m->multiply(\$n));
}```

You can multiply matrix with a scalar too, or a complex number:

```use \Malenki\Math\Number\Complex;

\$z = new Complex(2, -3);
\$n->multiply(2);
\$n->multiply(\$z);```

Addition is possible too, you must test before if size of each matrix is the same, or catch exception.

```try {
}
catch(\Exception \$e)
{
echo \$e->getMessage();
}

//or

if(\$m->sameSize(\$n))
{
}
else
{
echo "Cannot add M to N: not the same size!";
}```

Getting determinant of a square matrix is easy, just do the following:

```use \Malenki\Math\Matrix;

\$m = new Matrix(2,2);
\$m->populate(array(1,2,3,4));
var_dump(\$m->det()); // should be -2```

If you try to get determinant for a non square matrix, you get an Exception.

Inverse of square matrix is simple too, and like you can imagine, it is like that:

```use \Malenki\Math\Matrix;

\$m = new Matrix(2,2);
\$m->populate(array(1,2,3,4));
\$i = \$m->inverse();
echo \$i;
// should be:
// -2   1
// 1.5  -0.5```

The cofactor matrix, used be previous method, is compute with that:

```use \Malenki\Math\Matrix;

\$m = new Matrix(2,2);
\$m->populate(array(1,2,3,4));
\$c = \$m->cofactor();
echo \$c;```

## Complex

Using complex is like a child game: instanciate it with real part and imaginary part. That’s all!

```use \Malenki\Math\Number\Complex;

\$z = new Complex(2, -3);```

But you can create complex number using rho and theta values, theta can be simple float or Angle object:

```use \Malenki\Math\Number\Complex;
use \Malenki\Math\Unit\Angle;

\$z = new Complex(1, pi(), Complex::TRIGONOMETRIC);
// or
\$a = new Angle(M_PI);
\$z = new Complex(1, \$a); // 3rd argument is useless if Angle is used as second argumeent```

Complex number object acts like string too, remembering its original form:

```use \Malenki\Math\Number\Complex;
use \Malenki\Math\Unit\Angle;

\$z = new Complex(2, -3);
echo \$z; // print "2-3i"
\$zz = new Complex(1, new Angle(3 * M_PI / 2));
echo \$zz; // print "cos 4.712389 + i⋅sin 4.712389"```

You have some magic getters:

```use \Malenki\Math\Number\Complex;

\$z = new Complex(1,2);
var_dump(\$z->real); // real part
var_dump(\$z->re); // real part
var_dump(\$z->r); // real part
var_dump(\$z->imaginary); // imaginary part
var_dump(\$z->im); //imaginary part
var_dump(\$z->i); // imaginary part
var_dump(\$z->rho); // modulus aka norm
var_dump(\$z->theta); // argument (angle)```

```use \Malenki\Math\Number\Complex;

\$z = new Complex(1,2);
\$zz = new Complex(2,3);
echo \$z->add(\$zz); // give new complex nulber
echo \$z->multiply(\$zz); // give another complex number```

Get negative and conjugate is simple too:

```use \Malenki\Math\Number\Complex;

\$z = new Complex(1,2);
echo \$z->conjugate();
echo \$z->negative();```

## Normal distribution

You can play with graph for given mean and standard deviation, or you can generate fake samples.

Some examples to understand:

```use \Malenki\Math\Stats\NormalDistribution;

// Normal Distribution with mean equals to 2 and has standard deviation of 0.3
\$nd = new NormalDistribution(2, 0.3);

// you can get value of function:
\$nd->f(3);

// you can generate fake sample following the current normal distribution:
\$nd->samples(100); // 100 elements into an array```

## Factorial

You can get factorial of one integer, it is very easy to use, instanciate it with `n` rank and then get value by calling `result` attribute.

```use \Malenki\Math\Factorial;

\$f = new Factorial(5);
\$f->result; // should be 120
\$f->n; // you can get rank as reminder too.```

String context is available too:

```use \Malenki\Math\Factorial;

\$f = new Factorial(5);
echo \$f; // string '120'```

## Random

You can play with random numbers, included into integer range or as float between 0 and 1.

You can take one:

```use \Malenki\Math\Random;

\$r = new Random(); // double form 0 to 1 only
var_dump(\$r->get());

\$r = new Random(-5, 18); // integer range
var_dump(\$r->get());```

You can take many:

```use \Malenki\Math\Random;

\$r = new Random(); // double form 0 to 1 only
var_dump(\$r->getMany(5));

\$r = new Random(-5, 18); // integer range
var_dump(\$r->getMany(5));```

You can take many without replacement:

```use \Malenki\Math\Random;

\$r = new Random(); // double form 0 to 1 only
var_dump(\$r->getManyWithoutReplacement(5));

\$r = new Random(-5, 18); // integer range
var_dump(\$r->getManyWithoutReplacement(5));```

## Random Complex Number

This class allows you to get one or many complex numbers with real and imaginary or rho and theta inside given range.

So, to get one complex number with its real part into `[2, 6.5]` range and its imaginary part into `[-2, 5]` range, you must do that:

```use \Malenki\Math\RandomComplex;

\$rc = new RandomComplex();
\$rc->r(2, 6.5)->i(-2, 5)->get();```

You can do that with trigonometric form too, but now with 10 generated items:

```use \Malenki\Math\RandomComplex;

\$rc = new RandomComplex();
\$rc->rho(1, 5)->theta(M_PI / 4, M_PI /2)->getMany(10);```

## Descriptive Statistics

You can do a lot of stats about data, like mean, variance, standard deviation, kurtosis, etc.

You can put all values at once while instanciating:

```use \Malenki\Math\Stats\Stats;
\$s = new Stats(array(1,2,4,2,6,4));```

You can add others data after too:

```\$s->merge(array(8,4,6,3)); // to add several values

Counting values is as easy to use `count()`:

```use \Malenki\Math\Stats\Stats;
\$s = new Stats(array(1,2,4,2,6,4));
var_dump(count(\$s));```

Many means are avaialble too:

```use \Malenki\Math\Stats\Stats;
\$s = new Stats(array(1,2,4,2,6,4));

// arithmetic mean
var_dump(\$s->arithmeticMean());
var_dump(\$s->arithmetic_mean);
var_dump(\$s->mean);
var_dump(\$s->A);
var_dump(\$s->mu);

// harmonic mean
var_dump(\$s->harmonicMean());
var_dump(\$s->harmonic_mean);
var_dump(\$s->subcontrary_mean);
var_dump(\$s->H);

// geometric mean
var_dump(\$s->geometricMean());
var_dump(\$s->geometric_mean);
var_dump(\$s->G);

// root mean square aka RMS
var_dump(\$s->rootMeanSquare());
var_dump(\$s->root_mean_square);
var_dump(\$s->rms);
var_dump(\$s->Q);```

Variance, population or sample are available with standard deviation too:

```use \Malenki\Math\Stats\Stats;
\$s = new Stats(array(1,2,4,2,6,4));

// Variance (population)
var_dump(\$s->variance());
var_dump(\$s->var);
var_dump(\$s->variance);
var_dump(\$s->population_variance);

// Variance (sample)
var_dump(\$s->sampleVariance());
var_dump(\$s->sample_variance);
var_dump(\$s->s2);

// Standard deviation
var_dump(\$s->standardDeviation());
var_dump(\$s->standard_deviation);
var_dump(\$s->stdev);
var_dump(\$s->stddev);
var_dump(\$s->sigma);```

Quartiles and median:

```use \Malenki\Math\Stats\Stats;
\$s = new Stats(array(1,2,4,2,6,4));

var_dump(\$s->quartile(1));

var_dump(\$s->quartile(2));
//or
var_dump(\$s->mediane());

var_dump(\$s->quartile(3));

// or just by magic getters:

var_dump(\$s->first_quartile);
var_dump(\$s->second_quartile);
var_dump(\$s->third_quartile);
var_dump(\$s->last_quartile);
var_dump(\$s->mediane);```

Getting mode(s):

```\$s = new Stats(array(1,2,3,2,4,1,5));
var_dump(\$s->mode); // returned array has 2 values

\$s = new Stats(array(1,3,2,4,1,5));
var_dump(\$s->mode); // returned array has 1 value```

Frequencies, relative frequencies and cumulative frequencies:

```var_dump(\$s->frequency);
var_dump(\$s->relative_frequency);
var_dump(\$s->cumulative_frequency);
// or methods
var_dump(\$s->frequency());
var_dump(\$s->relativeFrequency());
var_dump(\$s->cumulativeFrequency());```

Kurtosis and its tests are available:

```use \Malenki\Math\Stats\Stats;
\$s = new Stats(array(1,2,4,2,6,4));

var_dump(\$s->kurtosis);
var_dump(\$s->is_platykurtic);
var_dump(\$s->is_leptokurtic);
var_dump(\$s->is_mesokurtic);

// or method way:
var_dump(\$s->kurtosis());
var_dump(\$s->isPlatykurtic());
var_dump(\$s->isLeptokurtic());
var_dump(\$s->isMesokurtic());```

## Parametric Tests

### Anova

One example is better than long blahblah:

```use Malenki\Math\Stats\ParametricTest\Anova;
\$a = new Anova();
\$a->add(array(6, 8, 4, 5, 3, 4));
\$a->add(array(8, 12, 9, 11, 6, 8));
\$a->add(array(13, 9, 11, 8, 7, 12));

// degrees of freedom
echo \$a->degrees_of_freedom;
echo \$a->dof;
echo \$a->degreesOfFreedom();
echo \$a->dof();

// Within group degrees of freedom
echo \$a->within_group_degrees_of_freedom;
echo \$a->WithinGroupDegreesOfFreedom();
echo \$a->wgdof();

echo \$a->f;
//or
echo \$a->f_ratio;
//or
echo \$a->f();
//or
echo \$a->fRatio();
// should be around 9.3```

### Dependant t-Test

```use Malenki\Math\Stats\ParametricTest\TTest;
\$t = new Dependant();
\$t->add(array(24, 17, 32, 14, 16, 22, 26, 19, 19, 22, 21, 25, 16, 24, 18));
\$t->add(array(26, 24, 31, 17, 17, 25, 25, 24, 22, 23, 26, 28, 19, 23, 22));

// Degree Of Freedom
echo \$t->dof(); // should be 14

// Sigma, the standard deviation
echo \$t->sigma(); // Should be around 0.608

// The t-value
echo \$t->t(); // Should be around -4.054```

TODO