Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Evaluating expressions on arrays. #166

Open
mercurial-moon opened this issue Nov 15, 2024 · 2 comments
Open

Evaluating expressions on arrays. #166

mercurial-moon opened this issue Nov 15, 2024 · 2 comments
Labels

Comments

@mercurial-moon
Copy link

Hi,
Recently came across numexpr https://github.com/pydata/numexpr
that can do expressions on arrays eg. 3*a+4*b where a and b are arrays.

Is this kind of expression possible in ExpressionEvaluator.
if not can we get it done using linq or a lambda expression.

@codingseb
Copy link
Owner

Hi @mercurial-moon,

I am not a specialist of array operations and how it should be implemented.
EE do not implement it directly but it could be added with the code below as a start of a solution.
(If you inherits ExpressionEvaluator you can rededefine operators)

using CodingSeb.ExpressionEvaluator;
using Newtonsoft.Json;
using System.Collections;

ExpressionEvaluator evaluator = new EE();

evaluator.Variables["a"] = new double[] { 4d, 3.4 };

string expression = "3 * a"; 
Console.WriteLine(expression);
Console.WriteLine(JsonConvert.SerializeObject(evaluator.Evaluate(expression)));
Console.WriteLine(string.Empty);

public class EE : ExpressionEvaluator
{
    private Func<dynamic, dynamic, object> mutiplyFuncBase;
    private Func<dynamic, dynamic, object> addFuncBase;
    // ...

    private object ExtendedMultiply(dynamic left, dynamic right)
    {
        if (left is IEnumerable leftEnumerable)
            return leftEnumerable.Cast<object>().Select(element => ExtendedMultiply(element, right));
        if(right is IEnumerable rightEnumerable)
            return rightEnumerable.Cast<object>().Select(element => ExtendedMultiply(left, element));

            return mutiplyFuncBase(left, right);
    }

    private object ExtendedAdd(dynamic left, dynamic right)
    {
        // Here I am not sure how to implement it
        return null;
    }

    public EE()
    {
        var multiplyDict = OperatorsEvaluations.First(dict => dict.ContainsKey(ExpressionOperator.Multiply));
        mutiplyFuncBase = multiplyDict[ExpressionOperator.Multiply];
        multiplyDict[ExpressionOperator.Multiply] = ExtendedMultiply;

        var addDict = OperatorsEvaluations.First(dict => dict.ContainsKey(ExpressionOperator.Plus));
        addFuncBase = addDict[ExpressionOperator.Plus];
        addDict[ExpressionOperator.Plus] = ExtendedAdd;
    }
}

Otherwise if you want to use the Linq Select directly in the expression you need to pass your array as an array of object.

evaluator.Variables["a"] = new object[] { 4d, 3.4 };
evaluator.Evaluate("a.Select(element => element * 3)");

Or cast it with a.Cast<object>().Select(...)

One more time I am not sure if my implementation of array multiplication is correct. And do not know how to do the addition.

@mercurial-moon
Copy link
Author

Thanks for the reply @codingseb. Really appreciate it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants