Skip to content

Commit

Permalink
#131 - Support aliases for simplify, deriv and etc.
Browse files Browse the repository at this point in the history
  • Loading branch information
sys27 committed Jul 13, 2023
1 parent bb1ec81 commit fce78b9
Show file tree
Hide file tree
Showing 19 changed files with 163 additions and 141 deletions.
7 changes: 1 addition & 6 deletions xFunc.Maths/Analyzers/TypeAnalyzers/ResultTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public enum ResultTypes
/// <summary>
/// The expression returns other expression.
/// </summary>
Expression = 1 << 6,
Function = 1 << 6,

/// <summary>
/// The expression returns an angle.
Expand Down Expand Up @@ -95,9 +95,4 @@ public enum ResultTypes
/// The expression returns a volume number.
/// </summary>
VolumeNumber = 1 << 15,

/// <summary>
/// The expression return a function.
/// </summary>
Function = 1 << 16,
}
8 changes: 4 additions & 4 deletions xFunc.Maths/Analyzers/TypeAnalyzers/TypeAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -566,7 +566,7 @@ public virtual ResultTypes Analyze(Assign exp)

/// <inheritdoc />
public virtual ResultTypes Analyze(Del exp)
=> CheckArgument(exp, ResultTypes.Expression);
=> CheckArgument(exp, ResultTypes.Function);

/// <inheritdoc />
public virtual ResultTypes Analyze(Derivative exp)
Expand All @@ -575,10 +575,10 @@ public virtual ResultTypes Analyze(Derivative exp)
ArgNull(ExceptionArgument.exp);

if (exp.ParametersCount == 1)
return ResultTypes.Expression;
return ResultTypes.Function;

if (exp.ParametersCount == 2 && exp[1] is Variable)
return ResultTypes.Expression;
return ResultTypes.Function;

if (exp.ParametersCount == 3 && exp[1] is Variable && exp[2] is Number)
return ResultTypes.Number;
Expand Down Expand Up @@ -1170,7 +1170,7 @@ public virtual ResultTypes Analyze(Round exp)

/// <inheritdoc />
public virtual ResultTypes Analyze(Simplify exp)
=> CheckArgument(exp, ResultTypes.Undefined);
=> CheckArgument(exp, ResultTypes.Function);

/// <inheritdoc />
public virtual ResultTypes Analyze(Sqrt exp)
Expand Down
24 changes: 19 additions & 5 deletions xFunc.Maths/Expressions/Del.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using static xFunc.Maths.ThrowHelpers;

namespace xFunc.Maths.Expressions;
Expand Down Expand Up @@ -54,21 +55,34 @@ public Del(IDifferentiator differentiator, ISimplifier simplifier, IExpression e
/// <inheritdoc />
public override object Execute(ExpressionParameters? parameters)
{
var result = Argument.Execute(parameters);
if (result is not Lambda lambda)
throw new ResultIsNotSupportedException(this, result);

var context = new DifferentiatorContext(parameters);
var body = lambda.Body;
var variables = Helpers.GetAllVariables(body);
if (!variables.TryGetNonEnumeratedCount(out var variablesCount))
variablesCount = variables.Count();

Check warning on line 66 in xFunc.Maths/Expressions/Del.cs

View check run for this annotation

Codecov / codecov/patch

xFunc.Maths/Expressions/Del.cs#L66

Added line #L66 was not covered by tests

var variables = Helpers.GetAllVariables(Argument).ToList();
var vector = ImmutableArray.CreateBuilder<IExpression>(variables.Count);
var vectorItems = new IExpression[variablesCount];
var i = 0;

foreach (var variable in variables)
{
context.Variable = variable;

vector.Add(Argument
vectorItems[i] = body
.Analyze(differentiator, context)
.Analyze(simplifier));
.Analyze(simplifier);

i++;
}

return new Vector(vector.ToImmutableArray());
var resultLambda = new Vector(Unsafe.As<IExpression[], ImmutableArray<IExpression>>(ref vectorItems))
.ToLambda();

return resultLambda;
}

/// <inheritdoc />
Expand Down
12 changes: 9 additions & 3 deletions xFunc.Maths/Expressions/Derivative.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,20 +84,26 @@ public class Derivative : DifferentParametersExpression
/// <inheritdoc />
public override object Execute(ExpressionParameters? parameters)
{
var result = Expression.Execute(parameters);
if (result is not Lambda lambda)
throw new ResultIsNotSupportedException(this, result);

var variable = Variable;
var context = new DifferentiatorContext(parameters, variable);
var diff = Analyze(Differentiator, context);
var derivative = lambda.Body.Analyze(Differentiator, context);

var point = DerivativePoint;
if (point is not null)
{
parameters ??= new ExpressionParameters();
parameters[variable.Name] = point.Value;

return diff.Execute(parameters);
return derivative.Execute(parameters);
}

return diff.Analyze(Simplifier);
return derivative
.Analyze(Simplifier)
.ToLambda();
}

/// <inheritdoc />
Expand Down
9 changes: 9 additions & 0 deletions xFunc.Maths/Expressions/Lambda.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,15 @@ namespace xFunc.Maths.Expressions;
/// </summary>
public readonly struct Lambda : IEquatable<Lambda>
{
/// <summary>
/// Initializes a new instance of the <see cref="Lambda"/> struct.
/// </summary>
/// <param name="body">The body of the function.</param>
public Lambda(IExpression body)
: this(ImmutableArray.Create<string>(), body)
{
}

/// <summary>
/// Initializes a new instance of the <see cref="Lambda"/> struct.
/// </summary>
Expand Down
44 changes: 44 additions & 0 deletions xFunc.Maths/Expressions/LambdaExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright (c) Dmytro Kyshchenko. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace xFunc.Maths.Expressions;

/// <summary>
/// Extension methods for <see cref="Lambda"/> and <see cref="LambdaExpression"/>.
/// </summary>
public static class LambdaExtensions
{
/// <summary>
/// Converts <paramref name="exp"/> to <see cref="Lambda"/> without parameters.
/// </summary>
/// <param name="exp">The expression to convert.</param>
/// <returns>The lambda.</returns>
public static Lambda ToLambda(this IExpression exp)
=> new Lambda(exp);

/// <summary>
/// Converts <paramref name="exp"/> to <see cref="Lambda"/> without parameters.
/// </summary>
/// <param name="exp">The expression to convert.</param>
/// <param name="variables">The list of lambda parameters.</param>
/// <returns>The lambda.</returns>
public static Lambda ToLambda(this IExpression exp, params string[] variables)
=> new Lambda(variables, exp);

/// <summary>
/// Converts <paramref name="exp"/> to <see cref="LambdaExpression"/> without parameters.
/// </summary>
/// <param name="exp">The expression to convert.</param>
/// <returns>The lambda expression.</returns>
public static LambdaExpression ToLambdaExpression(this IExpression exp)
=> ToLambda(exp).AsExpression();

/// <summary>
/// Converts <paramref name="exp"/> to <see cref="LambdaExpression"/> without parameters.
/// </summary>
/// <param name="exp">The expression to convert.</param>
/// <param name="variables">The list of lambda parameters.</param>
/// <returns>The lambda expression.</returns>
public static LambdaExpression ToLambdaExpression(this IExpression exp, params string[] variables)
=> ToLambda(exp, variables).AsExpression();
}
12 changes: 11 additions & 1 deletion xFunc.Maths/Expressions/Simplify.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,17 @@ internal Simplify(ISimplifier simplifier, ImmutableArray<IExpression> arguments)
/// <exception cref="ArgumentNullException">Simplifier is null.</exception>
/// <seealso cref="ExpressionParameters" />
public override object Execute(ExpressionParameters? parameters)
=> Analyze(simplifier);
{
var result = Argument.Execute(parameters);
if (result is not Lambda lambda)
throw new ResultIsNotSupportedException(this, result);

var simplifiedExpression = lambda.Body
.Analyze(simplifier)
.ToLambda();

return simplifiedExpression;
}

/// <inheritdoc />
protected override TResult AnalyzeInternal<TResult>(IAnalyzer<TResult> analyzer)
Expand Down
6 changes: 0 additions & 6 deletions xFunc.Maths/Processor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -139,12 +139,6 @@ bool boolean
string str
=> new StringResult(str),

IExpression expression when simplify
=> new ExpressionResult(Simplify(expression)),

IExpression expression
=> new ExpressionResult(expression),

Lambda lambda
=> new LambdaResult(lambda),

Expand Down
26 changes: 0 additions & 26 deletions xFunc.Maths/Results/ExpressionResult.cs

This file was deleted.

4 changes: 2 additions & 2 deletions xFunc.Tests/Analyzers/DifferentiatorTests/NullArgumentTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ public void VariableContextArgumentTest()
public void CallExpressionContextNullArgument()
{
var exp = new CallExpression(
new Lambda(new[] { "x" }, Variable.X).AsExpression(),
Variable.X.ToLambdaExpression(Variable.X.Name),
new IExpression[] { Variable.X }.ToImmutableArray());

Assert.Throws<NotSupportedException>(() => exp.Analyze(differentiator, null));
Expand All @@ -188,7 +188,7 @@ public void CallExpressionContextNullArgument()
[Fact]
public void LambdaExpressionContextNullArgument()
{
var exp = new Lambda(new[] { "x" }, Variable.X).AsExpression();
var exp = Variable.X.ToLambdaExpression(Variable.X.Name);

Assert.Throws<NotSupportedException>(() => exp.Analyze(differentiator, null));
}
Expand Down
6 changes: 3 additions & 3 deletions xFunc.Tests/Analyzers/Formatters/CommonFormatterTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -496,8 +496,8 @@ public void UndefineToStringTest()
[Fact]
public void LambdaExpressionToStringArgTest()
{
var exp = new Lambda(new[] { "x", "y" }, new Add(Variable.X, Variable.Y))
.AsExpression();
var exp = new Add(Variable.X, Variable.Y)
.ToLambdaExpression(Variable.X, Variable.Y);

Assert.Equal("(x, y) => x + y", exp.ToString());
}
Expand All @@ -516,7 +516,7 @@ public void CallExpressionToStringArgTest()
public void InlineCallExpressionToStringArgTest()
{
var exp = new CallExpression(
new Lambda(new[] { "x" }, Variable.X).AsExpression(),
Variable.X.ToLambdaExpression(Variable.X.Name),
new IExpression[] { new Number(5) }.ToImmutableArray());

Assert.Equal("((x) => x)(5)", exp.ToString());
Expand Down
11 changes: 5 additions & 6 deletions xFunc.Tests/Analyzers/TypeAnalyzerTests/StandardTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public void TestDelVector()
var simp = new Simplifier();
var exp = new Del(diff, simp, Number.Two);

Test(exp, ResultTypes.Expression);
Test(exp, ResultTypes.Function);
}

[Fact]
Expand All @@ -33,7 +33,7 @@ public void TestDerivExpression()
var simp = new Simplifier();
var exp = new Derivative(diff, simp, Variable.X);

Test(exp, ResultTypes.Expression);
Test(exp, ResultTypes.Function);
}

[Fact]
Expand All @@ -43,7 +43,7 @@ public void TestDerivExpressionWithVar()
var simp = new Simplifier();
var exp = new Derivative(diff, simp, Variable.X, Variable.X);

Test(exp, ResultTypes.Expression);
Test(exp, ResultTypes.Function);
}

[Fact]
Expand Down Expand Up @@ -384,7 +384,7 @@ public void TestNumber()
public void TestSimplify()
{
var simp = new Simplifier();
Test(new Simplify(simp, Variable.X), ResultTypes.Undefined);
Test(new Simplify(simp, Variable.X), ResultTypes.Function);
}

[Fact]
Expand All @@ -408,8 +408,7 @@ public void TestCallExpression()
[Fact]
public void TestLambdaExpression()
{
var exp = new Lambda(Array.Empty<string>(), Number.One)
.AsExpression();
var exp = Number.One.ToLambdaExpression();

Test(exp, ResultTypes.Function);
}
Expand Down
9 changes: 3 additions & 6 deletions xFunc.Tests/Expressions/AssignTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,7 @@ public void OverrideConstTest()
[Fact]
public void DefineFuncTest()
{
var function = new Lambda(Array.Empty<string>(), Number.One)
.AsExpression();
var function = Number.One.ToLambdaExpression();
var variable = new Variable("f");
var exp = new Assign(variable, function);

Expand All @@ -72,10 +71,8 @@ public void DefineFuncTest()
[Fact]
public void DefineFuncWithParamsTest()
{
var function = new Lambda(
new[] { "x", "y" },
new Add(Variable.X, Variable.Y))
.AsExpression();
var function = new Add(Variable.X, Variable.Y)
.ToLambdaExpression(Variable.X.Name, Variable.Y.Name);
var variable = new Variable("f");
var exp = new Assign(variable, function);

Expand Down

0 comments on commit fce78b9

Please sign in to comment.