public static Add ( |
||
left | An |
|
right | An |
|
Результат |
public void Binary() { var param = LinqExpression.Parameter(typeof(int)); var expression = LinqExpression.Add(param, param); ShouldRoundrip(expression); }
public void ZeroOneRemoval() { var x = VF("x"); var ex = Ex.Block(Ex.Add(x, E1), Ex.Add(x, E0), E1.Mul(x), x.Mul(E0), x.Sub(E0), E0.Sub(x)); AreEqual("((x+1);\n(x+0);\n(1*x);\n(x*0);\n(x-0);\n(0-x);)", ex.Debug()); AreEqual("((x+1);\nx;\nx;\n0;\nx;\n(0-x);)", ex.FlatDebug()); }
static E Compile( ElementExpression expression, Dictionary <string, ParameterExpression> spans, Dictionary <string, ParameterExpression> indices) { switch (expression.ArityKind) { case ArityKind.Element: return(Compile(expression.Element, spans, indices)); case ArityKind.Unary: switch (expression.UnaryKind) { case UnaryExpressionKind.Exp: throw new NotImplementedException(); case UnaryExpressionKind.Log: throw new NotImplementedException(); default: throw new NotSupportedException(); } case ArityKind.Binary: switch (expression.BinaryKind) { case BinaryExpressionKind.Add: return(E.Add( Compile(expression.Expr1, spans, indices), Compile(expression.Expr2, spans, indices))); case BinaryExpressionKind.Subtract: return(E.Add( Compile(expression.Expr1, spans, indices), E.Negate(Compile(expression.Expr2, spans, indices)))); case BinaryExpressionKind.Multiply: return(E.Multiply( Compile(expression.Expr1, spans, indices), Compile(expression.Expr2, spans, indices))); case BinaryExpressionKind.Divide: return(E.Divide( Compile(expression.Expr1, spans, indices), Compile(expression.Expr2, spans, indices))); default: throw new NotSupportedException(); } case ArityKind.Ternary: throw new NotImplementedException(); default: throw new NotSupportedException(); } }
/// <summary> /// Home towards a target location at a fixed speed. /// </summary> /// <remarks> /// Use with StopSampling to home for only a few seconds. /// <para>This is primarily for use with non-rotational velocity. /// Rotational use creates: contracting spirals (0,90), circle around player [90], expanding spiral (90,180).</para> /// </remarks> /// <param name="speed">Speed</param> /// <param name="location">Target location</param> /// <returns></returns> public static ExTP VHome(ExBPY speed, ExTP location) { TExV2 l = new TExV2(); return(bpi => Ex.Block(new ParameterExpression[] { l }, Ex.Assign(l, location(bpi).Sub(bpi.loc)), l.Mul(Ex.Divide(speed(bpi), Sqrt(Ex.Add(SqrMag(l), EPS)))) )); }
public static ExCoordF CartesianRot(ExTP erv) => (c, s, bpi, nrv, fxy) => { var v2 = new TExV2(); return(Ex.Block(new ParameterExpression[] { v2 }, Ex.Assign(v2, erv(bpi)), fxy(Ex.Subtract(Ex.Multiply(c, v2.x), Ex.Multiply(s, v2.y)), Ex.Add(Ex.Multiply(s, v2.x), Ex.Multiply(c, v2.y))), Expression.Empty() )); };
public void TestConvert() { Ex ex = Ex.Add(ExC(5.2f), Ex.Convert(Ex.Convert(Ex.Add(ExC(1.2f), ExC(2.1f)), typeof(int)), typeof(float))); AreEqual("(5.2+(1.2+2.1):>Int32:>Single)", ex.Debug()); AreEqual("8.2", ex.FlatDebug()); var x = VF("x"); ex = Ex.Add(ExC(5), Ex.Convert(Ex.Add(x, Ex.Add(ExC(1.2f), ExC(2.1f))), typeof(int))); AreEqual("(5+(x+(1.2+2.1)):>Int32)", ex.Debug()); AreEqual("(5+(x+3.3):>Int32)", ex.FlatDebug()); }
public static ExCoordF Polar2(ExTP radThetaDeg) { var rt = new TExV2(); var lookup = new TExV2(); return((c, s, bpi, nrv, fxy) => Ex.Block(new ParameterExpression[] { rt, lookup }, Ex.Assign(rt, radThetaDeg(bpi)), Ex.Assign(lookup, ExM.CosSinDeg(rt.y)), fxy(Ex.Subtract(Ex.Multiply(c, lookup.x), Ex.Multiply(s, lookup.y)).Mul(rt.x), Ex.Add(Ex.Multiply(s, lookup.x), Ex.Multiply(c, lookup.y)).Mul(rt.x)), Expression.Empty() )); }
public static ExCoordF Polar(ExBPY r, ExBPY theta) { var vr = ExUtils.VFloat(); var lookup = new TExV2(); return((c, s, bpi, nrv, fxy) => Ex.Block(new[] { vr, lookup }, Ex.Assign(lookup, ExM.CosSinDeg(theta(bpi))), Ex.Assign(vr, r(bpi)), fxy(Ex.Subtract(Ex.Multiply(c, lookup.x), Ex.Multiply(s, lookup.y)).Mul(vr), Ex.Add(Ex.Multiply(s, lookup.x), Ex.Multiply(c, lookup.y)).Mul(vr)), Expression.Empty() )); }
static E Compile( IndexExpression expression, Dictionary <string, ParameterExpression> spans, Dictionary <string, ParameterExpression> indices) { switch (expression.ArityKind) { case IndexExpressionArityKind.Constant: return(E.Constant(expression.Constant)); case IndexExpressionArityKind.Index: return(indices[expression.Index.Name]); case IndexExpressionArityKind.Element: if (expression.Element.Symbol.Shape.Kind != ElementKind.Int32) { throw new InvalidOperationException("Integer tensor requires for table lookups."); } return(Compile(expression.Element, spans, indices)); case IndexExpressionArityKind.Binary: switch (expression.BinaryKind) { case BinaryExpressionKind.Add: return(E.Add( Compile(expression.Expr1, spans, indices), Compile(expression.Expr2, spans, indices))); case BinaryExpressionKind.Subtract: return(E.Add( Compile(expression.Expr1, spans, indices), E.Negate(Compile(expression.Expr2, spans, indices)))); case BinaryExpressionKind.Multiply: return(E.Multiply( Compile(expression.Expr1, spans, indices), Compile(expression.Expr2, spans, indices))); case BinaryExpressionKind.Divide: return(E.Divide( Compile(expression.Expr1, spans, indices), Compile(expression.Expr2, spans, indices))); default: throw new NotSupportedException(); } default: throw new NotSupportedException(); } }
public void BinaryMethod() { var zero = LinqExpression.Default( typeof(long)); var expression = LinqExpression.Add( zero, zero, typeof(SampleClass).GetMethod(nameof(SampleClass.Equal))); ShouldRoundrip(expression); }
public void TestIfThen() { var y = VF("y"); var ex = Ex.Block(new[] { y }, Ex.Assign(y, ExC(4f)), Ex.Condition(Ex.GreaterThan(y, ExC(3f)), Ex.Assign(y, ExC(3f)), Ex.Add(y, ExC(1f)) ), Ex.Add(y, ExC(2f))); AreEqual("((y=4);\nif(y>3){(y=3)}else{(y+1)};\n(y+2);)", ex.Debug()); ex = Ex.Block(new[] { y }, Ex.Assign(y, ExC(4f)), Ex.Condition(Ex.GreaterThan(y, ExC(3f)), Ex.Add(y, ExC(1f)), Ex.Assign(y, ExC(3f)) ), Ex.Add(y, ExC(2f))); AreEqual("((y=4);\n5;\n6;)", ex.FlatDebug()); }
public static Func <TExArgCtx, TEx <T> > Pivot <S, T>(Func <TExArgCtx, TEx <float> > pivot, Func <TExArgCtx, TEx <T> > f1, Func <TExArgCtx, TEx <T> > f2, Func <TExArgCtx, TEx> pivotVar) where S : TEx, new() => t => { var pv = VFloat(); var pivotT = t.MakeCopyForType <S>(out var currEx, out var pivotEx); return(Ex.Block(new[] { pv }, pv.Is(pivot(t)), Ex.Condition(pv.LT(pivotVar(t)), Ex.Block(new ParameterExpression[] { pivotEx }, Ex.Assign(pivotEx, currEx), Ex.Assign(pivotVar(pivotT), pv), Ex.Add(f1(pivotT), Ex.Subtract(f2(t), f2(pivotT))) ), f1(t) ) )); };
// Solve a system of linear equations private static void Solve(CodeGen code, LinqExpr Ab, IEnumerable <LinearCombination> Equations, IEnumerable <Expression> Unknowns) { LinearCombination[] eqs = Equations.ToArray(); Expression[] deltas = Unknowns.ToArray(); int M = eqs.Length; int N = deltas.Length; // Initialize the matrix. for (int i = 0; i < M; ++i) { LinqExpr Abi = code.ReDeclInit <double[]>("Abi", LinqExpr.ArrayAccess(Ab, LinqExpr.Constant(i))); for (int x = 0; x < N; ++x) { code.Add(LinqExpr.Assign( LinqExpr.ArrayAccess(Abi, LinqExpr.Constant(x)), code.Compile(eqs[i][deltas[x]]))); } code.Add(LinqExpr.Assign( LinqExpr.ArrayAccess(Abi, LinqExpr.Constant(N)), code.Compile(eqs[i][1]))); } // Gaussian elimination on this turd. //RowReduce(code, Ab, M, N); code.Add(LinqExpr.Call( GetMethod <Simulation>("RowReduce", Ab.Type, typeof(int), typeof(int)), Ab, LinqExpr.Constant(M), LinqExpr.Constant(N))); // Ab is now upper triangular, solve it. for (int j = N - 1; j >= 0; --j) { LinqExpr _j = LinqExpr.Constant(j); LinqExpr Abj = code.ReDeclInit <double[]>("Abj", LinqExpr.ArrayAccess(Ab, _j)); LinqExpr r = LinqExpr.ArrayAccess(Abj, LinqExpr.Constant(N)); for (int ji = j + 1; ji < N; ++ji) { r = LinqExpr.Add(r, LinqExpr.Multiply(LinqExpr.ArrayAccess(Abj, LinqExpr.Constant(ji)), code[deltas[ji]])); } code.DeclInit(deltas[j], LinqExpr.Divide(LinqExpr.Negate(r), LinqExpr.ArrayAccess(Abj, _j))); } }
public void TestWhereArithmetic() { var parameter = LinqExpression.Parameter(typeof(NumbersModel), "x"); var n1 = LinqExpression.Property(parameter, "Number1"); var n2 = LinqExpression.Property(parameter, "Number2"); var m2g8 = new Func <int, int, bool>((x1, x2) => x1 * 2 > 8); var d2g3 = new Func <int, int, bool>((x1, x2) => x1 / 2 > 3); var m2e0 = new Func <int, int, bool>((x1, x2) => (x1 % 2) == 0); var a5g10 = new Func <int, int, bool>((x1, x2) => x1 + 5 > 10); var s5g0 = new Func <int, int, bool>((x1, x2) => x1 - 5 > 0); var mn2g10 = new Func <int, int, bool>((x1, x2) => x1 * x2 > 10); var dn1g3 = new Func <int, int, bool>((x1, x2) => x2 / x1 > 3); var mn2e0 = new Func <int, int, bool>((x1, x2) => (x1 % x2) == 0); var an2e10 = new Func <int, int, bool>((x1, x2) => x1 + x2 == 10); var sn2g0 = new Func <int, int, bool>((x1, x2) => x1 - x2 > 0); var cases = new[] { Tuple.Create((LinqExpression)LinqExpression.GreaterThan(LinqExpression.Multiply(n1, LinqExpression.Constant(2)), LinqExpression.Constant(8)), (Func <NumbersModel, object, bool>)TestWhereMathValidator, (object)m2g8, parameter), Tuple.Create((LinqExpression)LinqExpression.GreaterThan(LinqExpression.Divide(n1, LinqExpression.Constant(2)), LinqExpression.Constant(3)), (Func <NumbersModel, object, bool>)TestWhereMathValidator, (object)d2g3, parameter), Tuple.Create((LinqExpression)LinqExpression.Equal(LinqExpression.Modulo(n1, LinqExpression.Constant(2)), LinqExpression.Constant(0)), (Func <NumbersModel, object, bool>)TestWhereMathValidator, (object)m2e0, parameter), Tuple.Create((LinqExpression)LinqExpression.GreaterThan(LinqExpression.Add(n1, LinqExpression.Constant(5)), LinqExpression.Constant(10)), (Func <NumbersModel, object, bool>)TestWhereMathValidator, (object)a5g10, parameter), Tuple.Create((LinqExpression)LinqExpression.GreaterThan(LinqExpression.Subtract(n1, LinqExpression.Constant(5)), LinqExpression.Constant(0)), (Func <NumbersModel, object, bool>)TestWhereMathValidator, (object)s5g0, parameter), Tuple.Create((LinqExpression)LinqExpression.GreaterThan(LinqExpression.Multiply(n1, n2), LinqExpression.Constant(10)), (Func <NumbersModel, object, bool>)TestWhereMathValidator, (object)mn2g10, parameter), Tuple.Create((LinqExpression)LinqExpression.GreaterThan(LinqExpression.Divide(n2, n1), LinqExpression.Constant(3)), (Func <NumbersModel, object, bool>)TestWhereMathValidator, (object)dn1g3, parameter), Tuple.Create((LinqExpression)LinqExpression.Equal(LinqExpression.Modulo(n1, n2), LinqExpression.Constant(0)), (Func <NumbersModel, object, bool>)TestWhereMathValidator, (object)mn2e0, parameter), Tuple.Create((LinqExpression)LinqExpression.Equal(LinqExpression.Add(n1, n2), LinqExpression.Constant(10)), (Func <NumbersModel, object, bool>)TestWhereMathValidator, (object)an2e10, parameter), Tuple.Create((LinqExpression)LinqExpression.GreaterThan(LinqExpression.Subtract(n1, n2), LinqExpression.Constant(0)), (Func <NumbersModel, object, bool>)TestWhereMathValidator, (object)sn2g0, parameter) }; LoadModelNumbers(10); RunTestWithNumbers(new[] { 6, 3, 5, 5, 5, 7, 2, 3, 10, 5 }, cases); }
static E CompileAsIndex( Element element, Dictionary <string, ParameterExpression> spans, Dictionary <string, ParameterExpression> indices) { var strides = element.Symbol.Shape.Strides(); var expr = Compile(element.Expressions.Last(), spans, indices); for (var i = element.Expressions.Count - 2; i >= 0; i--) { expr = E.Add( E.Multiply( E.Constant(strides[i]), Compile(element.Expressions[i], spans, indices)), expr); } return(expr); }
public void TestReplaceWithVars() { var x = VF("x"); Expression ex = Ex.Add(ExC(5f), Expression.Call(null, typeof(Mathf).GetMethod("Sin"), Ex.Add(x, Ex.Multiply(ExC(2f), ExC(1.5f))))); AreEqual("(5+Mathf.Sin(Null,(x+(2*1.5))))", ex.Debug()); AreEqual("(5+Mathf.Sin(Null,(x+3)))", ex.FlatDebug()); var y = VF("y"); ex = Ex.Block(new[] { y }, Ex.Assign(y, ExC(3f)), Ex.Add(y, E2)); AreEqual("((y=3);\n(y+2);)", ex.Debug()); AreEqual("((y=3);\n5;)", ex.FlatDebug()); ex = Ex.Block(new[] { y }, Ex.Assign(y, E1), Ex.Add(ExC(5f), Ex.Call(null, typeof(Mathf).GetMethod("Sin"), Ex.Add(y, Ex.Multiply(ExC(2f), ExC(1.5f)))))); AreEqual("((y=1);\n(5+Mathf.Sin(Null,(y+(2*1.5))));)", ex.Debug()); AreEqual("((y=1);\n4.243197;)", ex.FlatDebug()); AreEqual(4.2431974, Compile(ex.Flatten()), err); ex = Ex.Block(new[] { y }, Ex.Assign(y, x), Ex.Add(ExC(5f), Expression.Call(null, typeof(Mathf).GetMethod("Sin"), Ex.Add(y, Ex.Multiply(E2, ExC(1.5f)))))); AreEqual("((y=x);\n(5+Mathf.Sin(Null,(y+(2*1.5))));)", ex.Debug()); AreEqual("((y=x);\n(5+Mathf.Sin(Null,(x+3)));)", ex.FlatDebug()); }
public static Expression <Func <Complex, Complex> > GetExpression([NotNull] Complex[] A) { var length = A.Length; Ex y; var px = Ex.Parameter(typeof(Complex), "z"); if (length == 0) { y = Ex.Constant(0d); } else { y = Ex.Constant(A[length - 1]); for (var i = 1; i < length; i++) { y = Ex.Add(Ex.Multiply(y, px), Ex.Constant(A[length - 1 - i])); } } return(Ex.Lambda <Func <Complex, Complex> >(y, px)); }
public override SysExpr ToExpression() { switch (NodeType) { case ExpressionType.Add: return(SysExpr.Add(Left.ToExpression(), Right.ToExpression())); case ExpressionType.Subtract: return(SysExpr.Subtract(Left.ToExpression(), Right.ToExpression())); case ExpressionType.Multiply: return(SysExpr.Multiply(Left.ToExpression(), Right.ToExpression())); case ExpressionType.Divide: return(SysExpr.Divide(Left.ToExpression(), Right.ToExpression())); case ExpressionType.Coalesce: return(SysExpr.Coalesce(Left.ToExpression(), Right.ToExpression())); default: throw new NotSupportedException($"Not a valid {NodeType} for arithmetic binary expression."); } }
public void Method() { var zero = LinqExpression.Default( typeof(long)); var expected = LinqExpression.Add( zero, zero, typeof(SampleClass).GetMethod(nameof(SampleClass.Equal))); var actual = $@" @prefix : <http://example.com/> . @prefix xt: <http://example.com/ExpressionTypes/> . :s :binaryExpressionType xt:Add ; :binaryLeft _:zero ; :binaryRight _:zero ; :binaryMethod [ :memberType [ :typeName ""GraphEngine.Tests.SampleClass, GraphEngine.Tests"" ; ] ; :memberName ""Equal"" ; ] ; . _:zero :defaultType [ :typeName ""System.Int64"" ; ] ; . "; ShouldBe(actual, expected); }
private BinaryExpression BinaryExpression( ExpressionType nodeType, System.Type type, JObject obj) { var left = this.Prop(obj, "left", this.Expression); var right = this.Prop(obj, "right", this.Expression); var method = this.Prop(obj, "method", this.Method); var conversion = this.Prop(obj, "conversion", this.LambdaExpression); var liftToNull = this.Prop(obj, "liftToNull").Value <bool>(); switch (nodeType) { case ExpressionType.Add: return(Expr.Add(left, right, method)); case ExpressionType.AddAssign: return(Expr.AddAssign(left, right, method, conversion)); case ExpressionType.AddAssignChecked: return(Expr.AddAssignChecked(left, right, method, conversion)); case ExpressionType.AddChecked: return(Expr.AddChecked(left, right, method)); case ExpressionType.And: return(Expr.And(left, right, method)); case ExpressionType.AndAlso: return(Expr.AndAlso(left, right, method)); case ExpressionType.AndAssign: return(Expr.AndAssign(left, right, method, conversion)); case ExpressionType.ArrayIndex: return(Expr.ArrayIndex(left, right)); case ExpressionType.Assign: return(Expr.Assign(left, right)); case ExpressionType.Coalesce: return(Expr.Coalesce(left, right, conversion)); case ExpressionType.Divide: return(Expr.Divide(left, right, method)); case ExpressionType.DivideAssign: return(Expr.DivideAssign(left, right, method, conversion)); case ExpressionType.Equal: return(Expr.Equal(left, right, liftToNull, method)); case ExpressionType.ExclusiveOr: return(Expr.ExclusiveOr(left, right, method)); case ExpressionType.ExclusiveOrAssign: return(Expr.ExclusiveOrAssign(left, right, method, conversion)); case ExpressionType.GreaterThan: return(Expr.GreaterThan(left, right, liftToNull, method)); case ExpressionType.GreaterThanOrEqual: return(Expr.GreaterThanOrEqual(left, right, liftToNull, method)); case ExpressionType.LeftShift: return(Expr.LeftShift(left, right, method)); case ExpressionType.LeftShiftAssign: return(Expr.LeftShiftAssign(left, right, method, conversion)); case ExpressionType.LessThan: return(Expr.LessThan(left, right, liftToNull, method)); case ExpressionType.LessThanOrEqual: return(Expr.LessThanOrEqual(left, right, liftToNull, method)); case ExpressionType.Modulo: return(Expr.Modulo(left, right, method)); case ExpressionType.ModuloAssign: return(Expr.ModuloAssign(left, right, method, conversion)); case ExpressionType.Multiply: return(Expr.Multiply(left, right, method)); case ExpressionType.MultiplyAssign: return(Expr.MultiplyAssign(left, right, method, conversion)); case ExpressionType.MultiplyAssignChecked: return(Expr.MultiplyAssignChecked(left, right, method, conversion)); case ExpressionType.MultiplyChecked: return(Expr.MultiplyChecked(left, right, method)); case ExpressionType.NotEqual: return(Expr.NotEqual(left, right, liftToNull, method)); case ExpressionType.Or: return(Expr.Or(left, right, method)); case ExpressionType.OrAssign: return(Expr.OrAssign(left, right, method, conversion)); case ExpressionType.OrElse: return(Expr.OrElse(left, right, method)); case ExpressionType.Power: return(Expr.Power(left, right, method)); case ExpressionType.PowerAssign: return(Expr.PowerAssign(left, right, method, conversion)); case ExpressionType.RightShift: return(Expr.RightShift(left, right, method)); case ExpressionType.RightShiftAssign: return(Expr.RightShiftAssign(left, right, method, conversion)); case ExpressionType.Subtract: return(Expr.Subtract(left, right, method)); case ExpressionType.SubtractAssign: return(Expr.SubtractAssign(left, right, method, conversion)); case ExpressionType.SubtractAssignChecked: return(Expr.SubtractAssignChecked(left, right, method, conversion)); case ExpressionType.SubtractChecked: return(Expr.SubtractChecked(left, right, method)); default: throw new NotSupportedException(); } }
public static Ex Add(this Ex me, float other) => me.Add(Ex.Constant(other));
//See notes for why these exist public static Ex AddAssign(Ex into, Ex from) => Ex.Assign(into, Ex.Add(into, from));
public void ReplaceMember() { var x = V <Vector2>("x"); var y = VF("y"); var ex = Ex.Block(new[] { x }, Ex.Assign(x, ExC(new Vector2(2f, 3f))), Ex.Field(x, "x").Add(ExC(6f))); AreEqual("((x=(2.0, 3.0));\n(x.x+6);)", ex.Debug()); AreEqual("((x=(2.0, 3.0));\n8;)", ex.FlatDebug()); AreEqual(Compile(ex.Flatten()), 8f); ex = Ex.Block(new[] { x }, Ex.Assign(x, ExC(new Vector2(2f, 3f))), Ex.IfThen(y.GT(E1), x.Is(ExC(Vector2.right))), Ex.Add(Ex.Field(x, "x"), ExC(6f))); AreEqual("((x=(2.0, 3.0));\nif(y>1){(x=(1.0, 0.0))}else{};\n(x.x+6);)", ex.FlatDebug()); ex = Ex.Block(new[] { x }, x.Is(ExC(new Vector2(2f, 3f))), Ex.IfThen(y.GT(E1), Ex.Field(x, "x").Is(ExC(6f))), Ex.Add(Ex.Field(x, "x"), ExC(6f))); AreEqual("((x=(2.0, 3.0));\nif(y>1){(x.x=6)}else{};\n(x.x+6);)", ex.FlatDebug()); }
private static Expression <Func <T, bool> > CreateDateTimeComparerLambda <T>(Expression expression, ParameterExpression parameter, string keyword) { var indexOfEmptySpace = Expression.Call(expression, InternalExpressionExtensions.GetIndexOfMethod(), Expression.Constant(" ")); var dateExpression = Expression.Call(expression, InternalExpressionExtensions.GetSubstringWithStartAndEndMethod(), Expression.Constant(0), indexOfEmptySpace); var timeExpression = Expression.Call(expression, InternalExpressionExtensions.GetSubstringWithStartMethod(), Expression.Add(indexOfEmptySpace, Expression.Constant(1))); var date = keyword; var time = keyword; if (keyword.Contains(' ') == true) { var dateAndTime = keyword.Split(new char[] { ' ' }); var dateComparerExpression = GetDateComparerExpression <T>(dateExpression, parameter, dateAndTime[0]); var timeComparerExpression = GetTimeComparerExpression <T>(timeExpression, parameter, dateAndTime[1], InternalExpressionExtensions.GetStartsWithMethod()); //o => o.ComparerMethod((property ?? "").Substring(0, property.IndexOf(' ')).ToLower().Contains(date)) // .And(o.ComparerMethod((property ?? "").Substring(property.IndexOf(' ')).ToLower().StartsWith(time))) return(dateComparerExpression.And(timeComparerExpression)); } else { var dateComparerExpression = GetDateComparerExpression <T>(dateExpression, parameter, date); var timeComparerExpression = GetTimeComparerExpression <T>(timeExpression, parameter, time, InternalExpressionExtensions.GetContainsMethod()); //o => o.ComparerMethod((property ?? "").Substring(0, property.IndexOf(' ')).ToLower().Contains(date)) // .Or(o.ComparerMethod((property ?? "").Substring(property.IndexOf(' ')).ToLower().Contains(time))) return(dateComparerExpression.Or(timeComparerExpression)); } }
public static Expression Add(Expression arg0, Expression arg1) { return(new Expression(LinqExpression.Add(arg0, arg1))); }
// The resulting lambda processes N samples, using buffers provided for Input and Output: // void Process(int N, double t0, double T, double[] Input0 ..., double[] Output0 ...) // { ... } private Delegate DefineProcess() { // Map expressions to identifiers in the syntax tree. List <KeyValuePair <Expression, LinqExpr> > inputs = new List <KeyValuePair <Expression, LinqExpr> >(); List <KeyValuePair <Expression, LinqExpr> > outputs = new List <KeyValuePair <Expression, LinqExpr> >(); // Lambda code generator. CodeGen code = new CodeGen(); // Create parameters for the basic simulation info (N, t, Iterations). ParamExpr SampleCount = code.Decl <int>(Scope.Parameter, "SampleCount"); ParamExpr t = code.Decl(Scope.Parameter, Simulation.t); // Create buffer parameters for each input... foreach (Expression i in Input) { inputs.Add(new KeyValuePair <Expression, LinqExpr>(i, code.Decl <double[]>(Scope.Parameter, i.ToString()))); } // ... and output. foreach (Expression i in Output) { outputs.Add(new KeyValuePair <Expression, LinqExpr>(i, code.Decl <double[]>(Scope.Parameter, i.ToString()))); } // Create globals to store previous values of inputs. foreach (Expression i in Input.Distinct()) { AddGlobal(i.Evaluate(t_t0)); } // Define lambda body. // int Zero = 0 LinqExpr Zero = LinqExpr.Constant(0); // double h = T / Oversample LinqExpr h = LinqExpr.Constant(TimeStep / (double)Oversample); // Load the globals to local variables and add them to the map. foreach (KeyValuePair <Expression, GlobalExpr <double> > i in globals) { code.Add(LinqExpr.Assign(code.Decl(i.Key), i.Value)); } foreach (KeyValuePair <Expression, LinqExpr> i in inputs) { code.Add(LinqExpr.Assign(code.Decl(i.Key), code[i.Key.Evaluate(t_t0)])); } // Create arrays for linear systems. int M = Solution.Solutions.OfType <NewtonIteration>().Max(i => i.Equations.Count(), 0); int N = Solution.Solutions.OfType <NewtonIteration>().Max(i => i.UnknownDeltas.Count(), 0) + 1; LinqExpr JxF = code.DeclInit <double[][]>("JxF", LinqExpr.NewArrayBounds(typeof(double[]), LinqExpr.Constant(M))); for (int j = 0; j < M; ++j) { code.Add(LinqExpr.Assign(LinqExpr.ArrayAccess(JxF, LinqExpr.Constant(j)), LinqExpr.NewArrayBounds(typeof(double), LinqExpr.Constant(N)))); } // for (int n = 0; n < SampleCount; ++n) ParamExpr n = code.Decl <int>("n"); code.For( () => code.Add(LinqExpr.Assign(n, Zero)), LinqExpr.LessThan(n, SampleCount), () => code.Add(LinqExpr.PreIncrementAssign(n)), () => { // Prepare input samples for oversampling interpolation. Dictionary <Expression, LinqExpr> dVi = new Dictionary <Expression, LinqExpr>(); foreach (Expression i in Input.Distinct()) { LinqExpr Va = code[i]; // Sum all inputs with this key. IEnumerable <LinqExpr> Vbs = inputs.Where(j => j.Key.Equals(i)).Select(j => j.Value); LinqExpr Vb = LinqExpr.ArrayAccess(Vbs.First(), n); foreach (LinqExpr j in Vbs.Skip(1)) { Vb = LinqExpr.Add(Vb, LinqExpr.ArrayAccess(j, n)); } // dVi = (Vb - Va) / Oversample code.Add(LinqExpr.Assign( Decl <double>(code, dVi, i, "d" + i.ToString().Replace("[t]", "")), LinqExpr.Multiply(LinqExpr.Subtract(Vb, Va), LinqExpr.Constant(1.0 / (double)Oversample)))); } // Prepare output sample accumulators for low pass filtering. Dictionary <Expression, LinqExpr> Vo = new Dictionary <Expression, LinqExpr>(); foreach (Expression i in Output.Distinct()) { code.Add(LinqExpr.Assign( Decl <double>(code, Vo, i, i.ToString().Replace("[t]", "")), LinqExpr.Constant(0.0))); } // int ov = Oversample; // do { -- ov; } while(ov > 0) ParamExpr ov = code.Decl <int>("ov"); code.Add(LinqExpr.Assign(ov, LinqExpr.Constant(Oversample))); code.DoWhile(() => { // t += h code.Add(LinqExpr.AddAssign(t, h)); // Interpolate the input samples. foreach (Expression i in Input.Distinct()) { code.Add(LinqExpr.AddAssign(code[i], dVi[i])); } // Compile all of the SolutionSets in the solution. foreach (SolutionSet ss in Solution.Solutions) { if (ss is LinearSolutions) { // Linear solutions are easy. LinearSolutions S = (LinearSolutions)ss; foreach (Arrow i in S.Solutions) { code.DeclInit(i.Left, i.Right); } } else if (ss is NewtonIteration) { NewtonIteration S = (NewtonIteration)ss; // Start with the initial guesses from the solution. foreach (Arrow i in S.Guesses) { code.DeclInit(i.Left, i.Right); } // int it = iterations LinqExpr it = code.ReDeclInit <int>("it", Iterations); // do { ... --it } while(it > 0) code.DoWhile((Break) => { // Solve the un-solved system. Solve(code, JxF, S.Equations, S.UnknownDeltas); // Compile the pre-solved solutions. if (S.KnownDeltas != null) { foreach (Arrow i in S.KnownDeltas) { code.DeclInit(i.Left, i.Right); } } // bool done = true LinqExpr done = code.ReDeclInit("done", true); foreach (Expression i in S.Unknowns) { LinqExpr v = code[i]; LinqExpr dv = code[NewtonIteration.Delta(i)]; // done &= (|dv| < |v|*epsilon) code.Add(LinqExpr.AndAssign(done, LinqExpr.LessThan(LinqExpr.Multiply(Abs(dv), LinqExpr.Constant(1e4)), LinqExpr.Add(Abs(v), LinqExpr.Constant(1e-6))))); // v += dv code.Add(LinqExpr.AddAssign(v, dv)); } // if (done) break code.Add(LinqExpr.IfThen(done, Break)); // --it; code.Add(LinqExpr.PreDecrementAssign(it)); }, LinqExpr.GreaterThan(it, Zero)); //// bool failed = false //LinqExpr failed = Decl(code, code, "failed", LinqExpr.Constant(false)); //for (int i = 0; i < eqs.Length; ++i) // // failed |= |JxFi| > epsilon // code.Add(LinqExpr.OrAssign(failed, LinqExpr.GreaterThan(Abs(eqs[i].ToExpression().Compile(map)), LinqExpr.Constant(1e-3)))); //code.Add(LinqExpr.IfThen(failed, ThrowSimulationDiverged(n))); } } // Update the previous timestep variables. foreach (SolutionSet S in Solution.Solutions) { foreach (Expression i in S.Unknowns.Where(i => globals.Keys.Contains(i.Evaluate(t_t0)))) { code.Add(LinqExpr.Assign(code[i.Evaluate(t_t0)], code[i])); } } // Vo += i foreach (Expression i in Output.Distinct()) { LinqExpr Voi = LinqExpr.Constant(0.0); try { Voi = code.Compile(i); } catch (Exception Ex) { Log.WriteLine(MessageType.Warning, Ex.Message); } code.Add(LinqExpr.AddAssign(Vo[i], Voi)); } // Vi_t0 = Vi foreach (Expression i in Input.Distinct()) { code.Add(LinqExpr.Assign(code[i.Evaluate(t_t0)], code[i])); } // --ov; code.Add(LinqExpr.PreDecrementAssign(ov)); }, LinqExpr.GreaterThan(ov, Zero)); // Output[i][n] = Vo / Oversample foreach (KeyValuePair <Expression, LinqExpr> i in outputs) { code.Add(LinqExpr.Assign(LinqExpr.ArrayAccess(i.Value, n), LinqExpr.Multiply(Vo[i.Key], LinqExpr.Constant(1.0 / (double)Oversample)))); } // Every 256 samples, check for divergence. if (Vo.Any()) { code.Add(LinqExpr.IfThen(LinqExpr.Equal(LinqExpr.And(n, LinqExpr.Constant(0xFF)), Zero), LinqExpr.Block(Vo.Select(i => LinqExpr.IfThenElse(IsNotReal(i.Value), ThrowSimulationDiverged(n), LinqExpr.Assign(i.Value, RoundDenormToZero(i.Value))))))); } }); // Copy the global state variables back to the globals. foreach (KeyValuePair <Expression, GlobalExpr <double> > i in globals) { code.Add(LinqExpr.Assign(i.Value, code[i.Key])); } LinqExprs.LambdaExpression lambda = code.Build(); Delegate ret = lambda.Compile(); return(ret); }
// Returns a * b + c. private static LinqExpr MultiplyAdd(LinqExpr a, LinqExpr b, LinqExpr c) { return(LinqExpr.Add(LinqExpr.Multiply(a, b), c)); }