math-php icon indicating copy to clipboard operation
math-php copied to clipboard

Work with algebraic expressions?

Open Itangalo opened this issue 5 years ago • 6 comments

I'm looking for a PHP math library that can evaluate and simplify algebraic expressions, e.g. evaluate "2x + 3y" when given values for x and y; and simplify "x + 2x" to 3x.

Is this kind of functionality anywhere on the roadmap for this project?

Itangalo avatar May 23 '20 17:05 Itangalo

20 years ago or so I wrote a command line program in C++ to do stuff like that...for fun. Not too hard really. If I were to try again I’d use it as an opportunity to learn ANTLR.

Beakerboy avatar May 24 '20 03:05 Beakerboy

Ok, to me it sounds pretty difficult, but I'm glad if others find it non-difficult. :-)

If anyone's interested: I've found a PHP library that does these sort of things (evalmath.class.php), which I made a clone of at GitHub some years ago (link). It is old code, and I doubt it would stand up to modern standards. I've only made trivial changes to the code, and can't claim to understand it (nor have I studied it – only used it in an old project).

Itangalo avatar May 24 '20 21:05 Itangalo

Hi @Itangalo,

To answer your original question, there were no immediate plans to add this kind of algebraic expression solver functionality, but I can definitely add it to the list of feature requests, and who knows, maybe some other users will also request it and spur development or get someone to submit a pull request for it. Or maybe @Beakerboy will find some long lost C++ code he wants to translate to PHP. You never know.

Thanks for your feedback and feature request.

Mark

markrogoyski avatar May 25 '20 05:05 markrogoyski

  • Validate the text that it only contains numbers, letters, operators (+-*/^) or parenthesis.
  • Verify that the number of opening and closing parenthesis match.
  • Verify that the expression does not begin or end with an operator. Verify that there are not two letters in a row, or two operators in a row.
  • Verify that ‘^(‘ does not exist. Simple exponents only.
  • Find the longest substring that does not contain a parenthesis.
  • Explode the string by ‘+’ and ‘-‘.
  • Explode these elements by ‘*’ and ‘/‘.
  • Finally explode by ‘^’.
  • Use the Polynomial object to recombine.
  • Repeat....

Beakerboy avatar May 25 '20 10:05 Beakerboy

@Beakerboy: Interesting algorithm, but a shame that only simple exponents are allowed. Another library I looked at some time ago (https://github.com/josdejong/mathjs, built on JavaScript) had lists of both unary and binary operators, and also functions like log() and sin(). I expect that the fundamental algorithm is kind of the same, though – explode the expression in a reverse order of operator priority, then evaluate and recombine. Makes sense.

Your algorithm does not simplify "2x + x" to "3x", correct?

Itangalo avatar May 26 '20 18:05 Itangalo

This is how I did things with my “for fun” application back then. It prevented y^x and other non-Polynomial cases. It would simplify your example because the Polynomial class is an array where each element is the scalar value that is multiplied by x raised to each exponent. This would convert to Polynomial([0,2]) + Polynomial([0,1])) Which would equal Polynomial([0,3]). If this were cast to a string, the result would be “3x”.

In the case of the application I made, I stored a multidimensional array where each axis was a different parameter, this allowed for the simplification and evaluation of functions with x, y, z, or anything, each combined with each other with varying exponents. On a first pass I scanned the string and made a list of how many unique parameters there were (just x, just y, a and b, etc) and it created the matrix and the table of which axis represented which parameter from that.

Beakerboy avatar May 26 '20 19:05 Beakerboy