Giter Site home page Giter Site logo

math's Introduction

Hoa


Build status Code coverage Packagist License

Hoa is a modular, extensible and structured set of PHP libraries.
Moreover, Hoa aims at being a bridge between industrial and research worlds.

Hoa\Math

Help on IRC Help on Gitter Documentation Board

This library provides tools around mathematical operations.

Learn more.

Installation

With Composer, to include this library into your dependencies, you need to require hoa/math:

$ composer require hoa/math '~1.0'

For more installation procedures, please read the Source page.

Testing

Before running the test suites, the development dependencies must be installed:

$ composer install

Then, to run all the test suites:

$ vendor/bin/hoa test:run

For more information, please read the contributor guide.

Quick usage

We propose a quick overview of one feature: evaluation of arithmetical expressions.

Evaluation of arithmetical expressions

The hoa://Library/Math/Arithmetic.pp describes the form of an arithmetical expression. Therefore, we will use the classical workflow when manipulating a grammar, that involves the Hoa\Compiler library and the Hoa\Math\Visitor\Arithmetic class.

// 1. Load the compiler.
$compiler = Hoa\Compiler\Llk::load(
    new Hoa\File\Read('hoa://Library/Math/Arithmetic.pp')
);

// 2. Load the visitor, aka the “evaluator”.
$visitor    = new Hoa\Math\Visitor\Arithmetic();

// 3. Declare the expression.
$expression = '1 / 2 / 3 + 4 * (5 * 2 - 6) * PI / avg(7, 8, 9)';

// 4. Parse the expression.
$ast        = $compiler->parse($expression);

// 5. Evaluate.
var_dump(
    $visitor->visit($ast)
);

/**
 * Will output:
 *     float(6.4498519738463)
 */

// Bonus. Print the AST of the expression.
$dump = new Hoa\Compiler\Visitor\Dump();
echo $dump->visit($ast);

/**
 * Will output:
 *     >  #addition
 *     >  >  #division
 *     >  >  >  token(number, 1)
 *     >  >  >  #division
 *     >  >  >  >  token(number, 2)
 *     >  >  >  >  token(number, 3)
 *     >  >  #multiplication
 *     >  >  >  token(number, 4)
 *     >  >  >  #multiplication
 *     >  >  >  >  #group
 *     >  >  >  >  >  #substraction
 *     >  >  >  >  >  >  #multiplication
 *     >  >  >  >  >  >  >  token(number, 5)
 *     >  >  >  >  >  >  >  token(number, 2)
 *     >  >  >  >  >  >  token(number, 6)
 *     >  >  >  >  #division
 *     >  >  >  >  >  token(constant, PI)
 *     >  >  >  >  >  #function
 *     >  >  >  >  >  >  token(id, avg)
 *     >  >  >  >  >  >  token(number, 7)
 *     >  >  >  >  >  >  token(number, 8)
 *     >  >  >  >  >  >  token(number, 9)
 */

We can add functions and constants on the visitor, thanks to the addFunction and addConstant methods. Thus, we will add the rand function (with 2 parameters) and the ANSWER constant, set to 42:

$visitor->addFunction('rand', function ($min, $max) {
    return mt_rand($min, $max);
});
$visitor->addConstant('ANSWER', 42);

$expression = 'rand(ANSWER / 2, ANSWER * 2)'
var_dump(
    $visitor->visit($compiler->parse($expression))
);

/**
 * Could output:
 *     int(53)
 */

Documentation

The hack book of Hoa\Math contains detailed information about how to use this library and how it works.

To generate the documentation locally, execute the following commands:

$ composer require --dev hoa/devtools
$ vendor/bin/hoa devtools:documentation --open

More documentation can be found on the project's website: hoa-project.net.

Getting help

There are mainly two ways to get help:

Contribution

Do you want to contribute? Thanks! A detailed contributor guide explains everything you need to know.

License

Hoa is under the New BSD License (BSD-3-Clause). Please, see LICENSE for details.

Related projects

The following projects are using this library:

  • PSIH & PMSIpilot, PSIH is the leading French integrator of business intelligence solutions for the healthcare sector,
  • PHP Telegram Bot, Telegram bot based on the official Telegram Bot API.

math's People

Contributors

edsonmedina avatar hywan avatar jremes-foss avatar jubianchi avatar metalaka avatar mgratch avatar ph3nol avatar rparpa avatar shulard avatar stephpy avatar tyx avatar vonglasow avatar zackkatz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

math's Issues

Strange bug with #negative

Here is the expression I use : $expr = '2 + 2 / 2560.4 + - 2';

With PHP, I get:

<?php

var_dump((float) eval('return ' . $expr . ';')); // float(0.00078112794875818)

With Math, I get:

<?php
use Hoa\Compiler;
use Hoa\File;
use Hoa\Math\Visitor\Arithmetic;

$compiler = Compiler\Llk\Llk::load(new File\Read('hoa://Library/Math/Arithmetic.pp'));
$visitor  = new Arithmetic();
$dump = new Compiler\Visitor\Dump();

$ast = $compiler->parse($expr);

echo $dump->visit($ast);
var_dump((float) $visitor->visit($ast)); // float(0.00078112794875795)

Here is the produced AST:

>  #addition
>  >  token(number, 2)
>  >  #addition
>  >  >  #division
>  >  >  >  token(number, 2)
>  >  >  >  token(number, 2560.4)
>  >  >  #negative
>  >  >  >  token(number, 2)

Changing the expression to:

  • 2 + 2 / 2560.4 - 2 makes both results identical,
  • 2 + 2 / 2560.4 + - 3 makes both results identical,
  • 2 + 2 / 2560.3 + - 2 makes both results identical,
  • 2 + 2 / 2560.4 + - - 2 makes both results identical,
  • 2 + 2 / 2560.4 + - + 2 makes results different,
  • ...

Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

Doesn't work with laravel

After running composer require hoa/math '~1.0' on my laravel based project, my blade view templates stop working and throw strange errors like Call to a member function style() on string. Is there something I'm doing wrong?

Evaluating multiple formulas with the same variable names

Hello,

I have problems trying to evaluate multiple formulas that uses the same variable names.

When evaluate a set of formulas which have the same variable name I get his exeception:

Hoa\Math\Exception\AlreadyDefinedConstant: Constant VAR1 is already defined.

but I create an instance every time I do an operation like that:

public function evaluateFormula($expression, $variables = array())
{
        $result = null;
        $visitor = new Arithmetic();
        $compiler = Llk::load(new Read('hoa://Library/Math/Arithmetic.pp'));

        if (count($variables) > 0) {
            foreach ($variables as $key => $value)
                $visitor->addConstant($key, $value);

            try {
                $result = $visitor->visit($compiler->parse($expression));
            } catch (\Exception $e) {
                echo $e->getMessage();
            }
        }

        return $result;
    }
}

The call

$formservice = new FormulaService();
$result = $formservice->evaluateFormula("VAR1 + VAR2", array(
      "VAR1" => 1,
      "VAR2" => 2));

$this->assertEquals(3, $result);

$formservice = new FormulaService();
$result = $formservice->evaluateFormula("VAR1 + VAR1", array(
      "VAR1" => 1));

$this->assertEquals(2, $result);

Decimals without a leading integer cause errors

Example:
$expression = '.35 + .65';
$ast = $compiler->parse($expression);
echo $visitor->visit($ast);

Result:
Uncaught Hoa\Compiler\Exception\UnrecognizedToken, code: 0
Message: Unrecognized token "." at line 1 and column 1: .35 + .65 ↑
File: /web/htdocs/lmifirearms/vendor/hoa/compiler/Llk/Lexer.php
Line: 1

BUT

$expression = '0.35 + 0.65';
$ast = $compiler->parse($expression);
echo $visitor->visit($ast);

Works fine.

This is problematic if evaluating formulas entered by end users, which I am ;-).
Thanks


Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

composer ?

Can you add a version tag for installation with composer ?

Thanks

Why change the initial behavior for trigonometry operator ?

Hi !

We have an issue with Math lib as PHP (and other main languages) use sin, cos, ... with radian value as parameter. But Hoa\Math change that for degree value.

What about going back on this behavior ? And thanks to deg2rad we will be able to perform the same kind of operation.

I'm ready to do the PR if it seems ok for everyone.

Improve library

I recently opened 3 linked PRs and they all need to be discussed correctly to be integrated altogether.

Let's sum-up:

  • #38: adds new constants (original PR was #20)
  • #39: allows constants/ids names to start with digits
  • #40: adds support for hex/oct/bin notations

The #38 and #40 are ready, event though the #38 is kind of blocked by #39. What I think we should do:

  • Close the #39 thus disallowing constants/ids names to start with digits
  • Edit the #38 to remove constants starting with digit (and replace those with their plain names, e.g 2_ => TWO_)
  • Edit #40 to use standard/generic notation for hex (0x...), octal (0...) and binary (0b...)
  • Keep standard decimal notation, e.g no prefix for them (1337 would just be 1337)
  • Merge #38
  • Merge #40

Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

There should be a way to preserve keys with CartesianProduct

This is a feature request.

Input:

$data = [
    'hair' => [
        'blond',
        'black'
    ],
    'eyes' => [
        'blue',
        'green',
    ]
];

Expected output:

Array
(
    [0] => Array
        (
            [hair] => blond
            [eyes] => blue
        )

    [1] => Array
        (
            [hair] => blond
            [eyes] => green
        )

    [2] => Array
        (
            [hair] => black
            [eyes] => blue
        )

    [3] => Array
        (
            [hair] => black
            [eyes] => green
        )
)

Use case:

combining all possible route parameter values for sitemap generation


Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

Left associative operators

+, -, * and / are left associative operators
pp grammar seems to define them as right associative

Here is a sample
$ echo '4/2*3' | Hoa/Core/Bin/hoa compiler:pp Hoa/Math/Arithmetic.pp 0 --visitor dump

#division

token(number, 4)
#multiplication

token(number, 2)
token(number, 3)

We shouldn't have a node for multiplication as a division child

Mathematical Functions

Currently this library includes no mathematical functions. For PHPBench I needed access to basic statistic functions, e.g. average, stddev, variance, etc. and later I needed to port a Kernel Distribution estimator class, it would be great to move these over to this library.

Reference libraries / projects:

I would like to start with porting the minimum required for PHPBench:

Functions or static methods?

Should we use functions or static methods? i.e.

$mean = Stats::mean(Core::linspace(1, 10, 10));

or

$mean = Stats\mean(Core\linspace(1, 10, 10));

I tend to prefer the functional approach, but it is not possible to "autoload" functions, so we would have to include the whole library everytime.

{
    "autoload": {
        "files": [
            "lib/core.php",
            "lib/stats.php",
            "lib/financial.php",
        ]
    }
}

Perhaps the overhead would be insignificant, but maybe it would be better to use static methods anyway, thoughts?

Package Organisation

Currently the source code for this package is located in the root directory, along with some "non-code" files. Which I am not sure is a great idea, f.e. the Bin directory, which (I think) this case stands for "binary" but this also has a mathematical significance. Which could block us in the future.

Equally the Context and Arithmetic.pp files share the same concern as the Bin\Calc.php, so I would rather these were all in a sub-namespace:

Parser/ // or whatever this could be named
   Calc.php
   Arithimetic.php
   Context.php
Combinatronics/
Sampler/
Stats/
    Kde.php
    GaussianBlah.php
    GammaBlah.php
    Stats.php // file containing functions (if that is what we do)
Financial/
LinearAlgebra/
Etc../

Options or Arguments?

PHP does not currently have named parameters, which really sucks.

Taking an example from R:

matrix(data = NA, nrow = 1, ncol = 1, byrow = FALSE,
       dimnames = NULL)

So we have the choice of either:

function matrix($data = null, $nrow = 1, $ncol = 1, $byrow = false, $dimnames = null)

or

function matrix($data, array $options = array())
{
    $options = array_merge([
        'nrow' => 1,
        'ncol' => 1,
        'byrow' => false,
        'dimnames' => null
    ], $options);
}

The first is pretty bad IMO, and the second really requires a utility to validate the options. In this case a class would probably be a better solution, but this sort of thing is quite frequent, so it would be good to have a stragtegy to deal with it.

Vectorized Operations

R and numpy support vectorized operations, e.g.

$x  = array(1, 2, 3);
$y = array(2,3,4);
$x + $y; // array(3, 5, 7)

I think it would be good to support this:

Vector::add($x, $y); // array(3, 5, 7)
Vector::multiple($x, $y);
Vector::div($x, $y); 
// etc

Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

What is the difference between addConstant and addVariable

Trying to use the library but ran into an unexpected behaviour, hoping you can help.

I expected this to work when I use addConstant, but only works with addVariable.

// 1. Load the compiler.
$compiler = Hoa\Compiler\Llk::load(
    new Hoa\File\Read('hoa://Library/Math/Arithmetic.pp')
);

// 2. Load the visitor, aka the “evaluator”.
$visitor    = new Hoa\Math\Visitor\Arithmetic();

// 3. Declare the expression.
$expression = '(M * X) + C';

$visitor->addConstant('M', 2);
$visitor->addConstant('X', 1);
$visitor->addConstant('C', 3);


//$visitor->addVariable('M', function() { return 2; });
//$visitor->addVariable('X', function() { return 1; });
//$visitor->addVariable('C', function() { return 3; });


// 4. Parse the expression.
$ast        = $compiler->parse($expression);

// 5. Evaluate.
var_dump(
    $visitor->visit($ast)
);

What is the expected usage of addConstant vs addVariable?

Should there be a check to use the variable and if none found fallback to using the constants otherwise throw an error?

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.