fkleon / math-expressions

A library for parsing and evaluating mathematical expressions, supporting real numbers, vectors, and basic interval arithmetic.
https://pub.dev/packages/math_expressions
MIT License
100 stars 35 forks source link

Variable argument Generic functions & fixes #54

Closed kamimark closed 3 years ago

kamimark commented 3 years ago

Added capability to create generic functions with variable arguments like min, max,. Fixed issue when passing negative value to a function as not the first argument. Ex. min(0,-2)

fkleon commented 3 years ago

Thanks for this pull request, @kamimark. It's a great feature. I'll have a closer look later this week.

fkleon commented 3 years ago

Sorry for the delay in getting back to you about this.

I've reviewed these changes and was missing some tests to satisfy myself that it's working as intended. So I've gone ahead and added some tests and usage example to this on the generic-functions branch. Have a look at those and let me know what you think. The example is essentially this:

Parser p = Parser();
p.addGenericFunction('my_min', (List<double> args) => args.reduce(math.min));
Expression exp = p.parse('my_min(1, x, -1)');

With those changes, this library would have two ways to define "custom" functions:

The naming doesn't make this important distinction very clear, but I also don't have a better suggestion right now.

Let me know what you think, still happy to merge this (with tests from my branch).

kamimark commented 3 years ago

Seems good. I guess the name can be AlgorithmicFunction instead of generic

About the double type, maybe it can just throw exception? Since it doesn't make much sense not to return double? Maybe it does... Not sure.

On Sat, Jul 31, 2021, 14:20 Frederik Leonhardt @.***> wrote:

@.**** commented on this pull request.

In lib/src/functions.dart https://github.com/fkleon/math-expressions/pull/54#discussion_r680346684 :

@@ -943,3 +950,24 @@ class Sgn extends DefaultFunction { throw UnimplementedError('Can not evaluate $name on $type yet.'); } } + +class GenericFunction extends DefaultFunction {

  • /// Creates a genetic function with variable number of arguments.
  • ///
  • /// For example, to create min(2,23,4,5,2314,213,5,324):
  • ///
  • GenericFunction(String name, List args, this.handler) : super._any(name, args);
  • dynamic handler;
  • @override
  • dynamic evaluate(EvaluationType type, ContextModel context) {
  • List values = args.map((v) => (v.value ?? context.getExpression(v.name)).evaluate(type, context)).toList();

This mapping needs to go into the if (type == EvaluationType.REAL) block below since we can't guarantee that evaluate on each expression will always result in a double.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/fkleon/math-expressions/pull/54#pullrequestreview-719568194, or unsubscribe https://github.com/notifications/unsubscribe-auth/AD52YCEBFTDDERHAG66QTS3T2PL6TANCNFSM463T3H4A .

fkleon commented 3 years ago

Thank you again, have published this as version 2.2.0