public static SubtractAssign ( Expression left, Expression right ) : BinaryExpression | ||
left | Expression | An |
right | Expression | An |
Результат | BinaryExpression |
protected override object VisitAssignment(Assignment A) { LinqExpr value = target.Compile(A.Value); switch (A.Operator) { case Operator.Add: target.Add(LinqExpr.AddAssign(target.LookUp(A.Assign), value)); break; case Operator.Subtract: target.Add(LinqExpr.SubtractAssign(target.LookUp(A.Assign), value)); break; case Operator.Multiply: target.Add(LinqExpr.MultiplyAssign(target.LookUp(A.Assign), value)); break; case Operator.Divide: target.Add(LinqExpr.DivideAssign(target.LookUp(A.Assign), value)); break; case Operator.Power: target.Add(LinqExpr.PowerAssign(target.LookUp(A.Assign), value)); break; case Operator.And: target.Add(LinqExpr.AndAssign(target.LookUp(A.Assign), value)); break; case Operator.Or: target.Add(LinqExpr.OrAssign(target.LookUp(A.Assign), value)); break; case Operator.Equal: LinqExpr x = target.LookUp(A.Assign); if (x == null) { x = target.DeclInit(A.Assign, A.Value); } target.Add(LinqExpr.Assign(x, value)); break; default: throw new NotImplementedException("Operator not implemented for assignment."); } return(null); }
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(); } }
// Generate code to perform row reduction. private static void RowReduce(CodeGen code, LinqExpr Ab, int M, int N) { // For each variable in the system... for (int j = 0; j + 1 < N; ++j) { LinqExpr _j = LinqExpr.Constant(j); LinqExpr Abj = code.ReDeclInit <double[]>("Abj", LinqExpr.ArrayAccess(Ab, _j)); // int pi = j LinqExpr pi = code.ReDeclInit <int>("pi", _j); // double max = |Ab[j][j]| LinqExpr max = code.ReDeclInit <double>("max", Abs(LinqExpr.ArrayAccess(Abj, _j))); // Find a pivot row for this variable. //code.For(j + 1, M, _i => //{ for (int i = j + 1; i < M; ++i) { LinqExpr _i = LinqExpr.Constant(i); // if(|Ab[i][j]| > max) { pi = i, max = |Ab[i][j]| } LinqExpr maxj = code.ReDeclInit <double>("maxj", Abs(LinqExpr.ArrayAccess(LinqExpr.ArrayAccess(Ab, _i), _j))); code.Add(LinqExpr.IfThen( LinqExpr.GreaterThan(maxj, max), LinqExpr.Block( LinqExpr.Assign(pi, _i), LinqExpr.Assign(max, maxj)))); } // (Maybe) swap the pivot row with the current row. LinqExpr Abpi = code.ReDecl <double[]>("Abpi"); code.Add(LinqExpr.IfThen( LinqExpr.NotEqual(_j, pi), LinqExpr.Block( new[] { LinqExpr.Assign(Abpi, LinqExpr.ArrayAccess(Ab, pi)) }.Concat( Enumerable.Range(j, N + 1 - j).Select(x => Swap( LinqExpr.ArrayAccess(Abj, LinqExpr.Constant(x)), LinqExpr.ArrayAccess(Abpi, LinqExpr.Constant(x)), code.ReDecl <double>("swap"))))))); //// It's hard to believe this swap isn't faster than the above... //code.Add(LinqExpr.IfThen(LinqExpr.NotEqual(_j, pi), LinqExpr.Block( // Swap(LinqExpr.ArrayAccess(Ab, _j), LinqExpr.ArrayAccess(Ab, pi), Redeclare<double[]>(code, "temp")), // LinqExpr.Assign(Abj, LinqExpr.ArrayAccess(Ab, _j))))); // Eliminate the rows after the pivot. LinqExpr p = code.ReDeclInit <double>("p", LinqExpr.ArrayAccess(Abj, _j)); //code.For(j + 1, M, _i => //{ for (int i = j + 1; i < M; ++i) { LinqExpr _i = LinqExpr.Constant(i); LinqExpr Abi = code.ReDeclInit <double[]>("Abi", LinqExpr.ArrayAccess(Ab, _i)); // s = Ab[i][j] / p LinqExpr s = code.ReDeclInit <double>("scale", LinqExpr.Divide(LinqExpr.ArrayAccess(Abi, _j), p)); // Ab[i] -= Ab[j] * s for (int ji = j + 1; ji < N + 1; ++ji) { code.Add(LinqExpr.SubtractAssign( LinqExpr.ArrayAccess(Abi, LinqExpr.Constant(ji)), LinqExpr.Multiply(LinqExpr.ArrayAccess(Abj, LinqExpr.Constant(ji)), s))); } } } }
public void BinaryExpression_SubtractAssign() => UnsupportedBinaryExpr(Property.Id, id => Expr.SubtractAssign(id, Expr.Constant(3)), ExpressionType.SubtractAssign);