Diferencias con el ex4j original » History » Version 1
  Federico Vera, 2018-07-12 22:11 
  
| 1 | 1 | Federico Vera | # Diferencias con el ex4j original | 
|---|---|---|---|
| 2 | |||
| 3 | {{>toc}} | ||
| 4 | # Nota | ||
| 5 | Existen muchas diferencias con `exp4j` original, algunas de las cuales pueden causar problemas de compatibilidad para usuarios avanzados de `exp4j`. | ||
| 6 | |||
| 7 | # Diferencias Generales | ||
| 8 | Entre los cambios mas significativos de esta versión de `exp4j` se encuentran: un simplificador (preevaluador), manejo de variables, funciones adicionales, enums, [[Diferencias con el ex4j original#Constantes como funciones|*constantes como funciones*]] e impresión de tokens. | ||
| 9 | |||
| 10 | ## Naive Simplifier | ||
| 11 | The simplifier is a nice feature ([Original discussion](https://github.com/fasseg/exp4j/issues/26)) when you have operations that can be resolved the use of variables, for instance consider the expression `2^x + 4 / 2` could be turned into `2^x + 2`. Doesn't seem like much... does it? but when you use multiple formulas, lots of constants, multiple `x` values (i.e. plotting) this little difference comes in handy ([First performance test](https://github.com/fasseg/exp4j/issues/26#issuecomment-70547026)). | ||
| 12 | |||
| 13 | The other nice trick is when using expressions like `if(exp, v_true, v_false)`, the simplifier could remove the entire `if` block, for instance `if(1 > 0 & 3 < 4, a * pi(), e())` will be converted to `a * pi()` (actually to `if(1, a * pi(), e())`... _I'm still working on it..._ | ||
| 14 | |||
| 15 | ### Using the Simplifier | ||
| 16 | The simplifier is disabled by default, since it's really not needed when evaluating an expression only once (the simplifier needs to do one whole evaluation in order to work). | ||
| 17 | |||
| 18 | To activate it simply pass `true` to the builder: | ||
| 19 | |||
| 20 | ~~~java | ||
| 21 | // by default ExpressionBuilder#build() is #build(false) | ||
| 22 |     Expression ex = new ExpressionBuilder("2^3 + 4 / 2").build(true); | ||
| 23 | double result = ex.evaluate(); | ||
| 24 | ~~~ | ||
| 25 | |||
| 26 | ### A little note | ||
| 27 | A simplifier _**should**_ only simplify deterministic functions, so there's now a `deterministic` flag in each function creation (`true` by default). So if you have [non-deterministic](https://en.wikipedia.org/wiki/Nondeterministic_algorithm) functions in your code, you'll need to change your function declaration from this: | ||
| 28 | |||
| 29 | ~~~java | ||
| 30 |     Function rand_deterministic = new Function("randd", 0) { | ||
| 31 | @Override | ||
| 32 |         public double apply(double... args) { | ||
| 33 | // This will be an epic simplification fail | ||
| 34 | return Math.random(); | ||
| 35 | } | ||
| 36 | }; | ||
| 37 | ~~~ | ||
| 38 | To this: | ||
| 39 | ~~~java | ||
| 40 |     Function rand_NOT_deterministic = new Function("randnd", 0, false) { | ||
| 41 | // This flag ^^^^^ | ||
| 42 | @Override | ||
| 43 |         public double apply(double... args) { | ||
| 44 | return Math.random(); | ||
| 45 | } | ||
| 46 | }; | ||
| 47 | ~~~ | ||
| 48 | |||
| 49 | This will be the most annoying thing for users with lot's of custom non-deterministic functions... although most users should not notice it (simplifier is disabled by default) | ||
| 50 | |||
| 51 | ## Internal variable handling | ||
| 52 | This isn't really an issue in itself, it makes `exp4j` gain some performance, avoid possible errors, and improve code readability. But doesn't honor the _inmutable token_ filosophy of both `exp4j` and stack based calculators, so if you want to start hacking in this fork you should take this into account. | ||
| 53 | |||
| 54 | ### So... what's the change? | ||
| 55 | The real changes is commit:d2d96fce and in commit:7f280988 you can see an example of one the pitfalls. | ||
| 56 | |||
| 57 | The original `exp4j` uses one token per variable, that's to say one token each time a variable is present in an expression which creates every time a variable is set, a state where the same variable has a different values in an expression. That's really a no go for me. | ||
| 58 | |||
| 59 | This version of `exp4j` uses the same token for each and every time a variable is present in an expression, which means that the moment you set a variable it was changed in every occurrence. | ||
| 60 | |||
| 61 | ## Enums instead of final int variables | ||
| 62 | This should not be a problem for anybody, but it's necessary to address the change `->` commit:39dff556. | ||
| 63 | |||
| 64 | ## Token printing | ||
| 65 | Some might call this a debugging tool, others the reason of a 50% increase in the final jar size, I simply call it token printing... it allowed me create a view of the internal expression. | ||
| 66 | ### Why should you care? | ||
| 67 | Well the thing is, you probably won't, but there are some cases when using this sort of tools for research you need a way to audit the internals of the expression, not to try and guarantee result reproducibility, but to build extra trust in the expression that's being evaluated (_also... it's an awesome debbuging tool!_). | ||
| 68 | ### How to print the tokens? | ||
| 69 | The two basic ways are: | ||
| 70 | ~~~java | ||
| 71 |    Expression exp = new ExpressionBuilder("2x + 1").variable("x").build(); | ||
| 72 | String out1 = exp.toString(); | ||
| 73 | // out1 -> 2.0 x * 1.0 + | ||
| 74 | String out2 = exp.toTokenString(); | ||
| 75 | // out2 -> NUMBER[2.0] VARIABLE[x] OPERATOR[*] NUMBER[1.0] OPERATOR[+] | ||
| 76 | ~~~ | ||
| 77 | |||
| 78 | ## Constantes como funciones | ||
| 79 | We finally got to the change that will annoy most users and it's the change that will most probably _break_ things. In the original `exp4j` the constants where declared as simply constants, in this version constants are declared as functions so for instance `d * pi` is now `d * pi()`, this isn't an extreme change, but the reasoning is: some times your variables can have the name of constants... since users are not expected to know each and every constant implemented in `exp4j` this can cause trouble. | ||
| 80 | |||
| 81 | ## Translations | ||
| 82 | All messages can now be translated, and have already been translated to Spanish. | ||
| 83 | |||
| 84 | ## Serialization | ||
| 85 | All expressions are now `Serializable`! | ||
| 86 | |||
| 87 | ## Extra functions | ||
| 88 | Checkout the wiki pages for: | ||
| 89 | * [[Built in Functions]] | ||
| 90 | * [[Built in Operators]] | ||
| 91 | * [[Extra Functions and Operators]] |