
Comments and Discussions



Hi,
would it be possible that you integrate beside the parsing a conditional expression function.
For example: I would like to make some Decisions in my Application depending on values. In case
that "a > (b+c)" then return TRUE otherwise FALSE. In my case the app would translate the a,b,c into the following and sent it to the Parser: "5 >(3+4). In this case the Parser would return FALSE.
Do you get my point here. That function would be cool.





I have been running the tests and see something wrong....
For example, in one of the tests part of the expression is 2*log(4) and for that particular term the author expects a result of 2 but 2 * log(4) = 1.204119.
Also, in the tests the Log function is invoked as Log(n) where n is a number yet if you look at the source code you see that the Log function uses TWO arguments in SyntaxAnalysisRPN.
http://www.coralys.com/
http://simulation.lordofwingsPTY.com/





OK, it would have been nice if there was more comments in the source code as not everybody is a mind reader Would also be nice if the demo project (the calculator) was packaged in the zip project, less complication.
Anyway, I am working in an Electrical Engineering application and needed to work with impedances (series, parallel) and something I greatly missed here was that it only dealt with numbers.
I spent some time with the sources (grateful to the author) and decided to make use of the System.Numerics.Complex type instead of a double. Unfortunately there is no common interface for numeric types so that one can transparently handle multitype.
I am still not done with it (time permitting), currently all numbers are promoted to Complex. So you
could do something like this:
Complex c = parser.Parse("(2.5+8.9i) * 5 / 2i");
Obviously when using explicit complex numbers in the formulas, one must take care of enclosing them with parenthesis to identify them as one, otherwise the multiplication/division would take precedence and do the operation with only part (real or imaginary) part. That's a limitation I can live for the moment.
However, I added another great feature and that is the introduction of a DeclareVariable() method which takes a double with an overload for a Complex.
parser.DeclareVariable("AR25", new Complex(5, 18));
parser.DeclareVariable("AN30", 356.0);
And now, having "declared" those variables to the parser instance I can parse an expression like this:
Complex c = parser.Parse("5 + 540 * AR25 / AN30");
during precalculation the variable references are converted to references to the declared variables and then during calculation that value is fetched and used.
I tried refactoring it to use a base class and then specializations for double and Complex but as it turned out it was too complicated introducing too much overhead.
Here are the preliminary results on my system:
Ticks (Co)Author Type Variables Remarks

72 Y. Kalzhani double N.A. Original without any modification
144 DEGT double 0 Enhanced but referencing zero variables
216 DEGT Complex 0 Enhanced but referencing zero variables
349 DEGT double 0 Enhanced using Generics but referencing zero variables
495 DEGT Complex 0 Enhanced using Generics but referencing zero variables
611 DEGT Complex 3 Enhanced using Generics using 3 double variables
611 DEGT Complex 3 Enhanced referencing 3 double variables
738 DEGT Complex 3 Enhanced using Generics using 3 double variables
858 DEGT Complex 4 Enhanced using Generics using 4 Complex variables
http://www.coralys.com/
http://simulation.lordofwingsPTY.com/
modified 5Feb15 14:52pm.





The only thing missing here is symbol transformation. Seldom do you just have numbers. For practical use you would at least have variables defined that you can then use in the expression.
Would be nice if you could define variables that are then dynamically replaced during evaluation. For example
A = 5
B = 10
A * B + 3 * (B  A)
which would then evaluate to 65.
http://www.coralys.com/
http://simulation.lordofwingsPTY.com/





You have made a great job with this parser, if you have time I'd like to have mailing with you, my email address: jorgeham2000@gmail.com
Thanks
Jorge Ham







You did a quite good job with a really fast implementation. Your parser is well done in that direction! However, I wanted to compare your parser against one I wrote myself, and your parser had problems with more complicated strings, like
5268^16^5^72 17 89*24*37^24 58
Note that this is a autogenerated equation. Anyhow: decent job!





Thanks, but one moment, in an earlier version of the parser were analyzed and more complex lines, but they were illogical as those that you specify, a former math teacher convinced me to change my point of view about the convenience and consistency of such notation, so i change the parser and require parenthesis in expressions.





I know what you mean, however, you are always allowed to specify a standard, i.e. in
68^16^5^72
there is a standard defined (otherwise you need to use brackets). The standard is the same as
68^((16)^(5^72)).
One example of such a case is 2^2^2^2. If you go from left to right you end up with 256 (2^2 = 4, 4^2 = 16, 16^2 = 256). However, this case must be used as 2^2 = 4, 2^4 = 16, 2^16 = 65536. Compare with Google and Wikipedia  for powers if no bracket is specified the standard case must be right to left.
I solved this problem by not only preferring operations with higher orders, but also with the same order from the right side. This does not change ordinary operations like +,,... but it makes a difference in this edge case.
Anyway I see the problem and I consider it more advanced and not necessary for a math parser. I just wanted to point that out (the parser should maybe not crash  maybe report an error or hand back a result that might be valid from another point of view). As I stated before the performance of your parser is unmatched, so congratulations for that!





This is a commonly known topic: Operator Associativity[^]. Each decent math expression parser knows about this and makes proper decisions while parsing the passed expression string.
E.g. a^{bc} is rightassociative as described e.g. in Tetration[^].
Associativity says, where to start drawing parethesis if you have a chain of operators of the same Precedence[^].
The same holds for the unary + and  sign operator. And on more complex languages: casting, indexing, member access, etc. They are all rightassociative.
The vast majority of operators are leftassociative, as the standard math operators dictate.
All other interpretations are unexpected behaviour and misleading, i.e. violating one of the base rules of user interaction and programming (avoid unexpected/misleading/unintuitive behaviour).
Your argument to inhibit that is a bit awkward, since the rule is not discussable from a standard point of view (see http://en.wikipedia.org/wiki/Tetration[^]).
Cheers
Andi





All I see in the code section is exe's. Not very useful





it`s demo app in section Browse code, its because i update my article and file MathParserTK, which have source code (updated only comments in code) and deleted old file with source code, my newer version of this article with source code is pending





Hi,
Have you seen my Sym project at sym.codeplex.com? It transforms algebraic equations and solves.
SymbolicComputation.com





yes, i saw it, good project, good luck





Could you update your image links, please? They are not working. (At least on my box)
I wasn't, now I am, then I won't be anymore.





I fixed it thanks for the post





Please show and explain the code.





Hi, just download zipfile MathParserTK_1_1 (i updated it), in file mathParserTK.cs I tried to explain the work of the parser code in the comments and how it can be changed.





Very few people here will download code sight unseen. Especially if it's just to see how it's done. Show and explain the code and if someone wants to use it he may download it.





Hello kirnbas,
your evaluator solution seems to me quite verbose and overcomplicated.
You might have a look at Mathematical Expression Parser Using Coco/R[^] which provides two solutions:
A) writing a similar evaluator in about 100 lines of code by using http://ssw.jku.at/Coco/[^]
B) writing the same evaluator, but hand crafted, in less than 150 lines of code
BTW: I also find that you should elaborate more on why you show us your trick  why should I red that? E.g. if talking about localized number scheme, then you must talk about the consequences and how you deal with these:
 What number formats exist (decimal point, thousand separator, ...)?
 How you deal with the ambiguities (you have to also localize the list separator)?
 Run the localization on kkKZ, kyKZ, enUS, deDE, deCH, svSE, svFI
The quirks on localization is that the coma is usually used as list separator (e.g. f(a,b) ) as well as thousand separator (enUS) or as decimal separator (deDE).
One approach is to allow the ambiguity and let the parser read greedily (letting the user to solve ambiguities by adding parenthesis, e.g. f((3,14159),(1,4142135)) ).
Another approach is to make the language not ambiguous and also take the list separator from the CultureInfo class (beside the thousand separator and the decimal separator).
At least this topic is worth an elaboration. That's why my vote of 3.
Cheers
Andi





You might want to elaborate on some of the inner workings, etc. This is extremely short for an article.







General News Suggestion Question Bug Answer Joke Rant Admin Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

First Posted  14 May 2012 
Views  46,993 
Downloads  4,651 
Bookmarked  58 times 

