/// <summary> /// Initializes a new instance of the <see cref="BiasingBehavior"/> class. /// </summary> /// <param name="context">The context.</param> /// <exception cref="ArgumentNullException">Thrown if <paramref name="context"/> is <c>null</c>.</exception> public BiasingBehavior(BehavioralBindingContext context) : base(context) { // Make sure that we have access to the voltage over the behavior var bp = context.GetParameterSet <Parameters>(); var state = context.GetState <IBiasingSimulationState>(); Variables = new OnePort <double>( state.GetSharedVariable(context.Nodes[0]), state.GetSharedVariable(context.Nodes[1])); // Create the derivatives, while also giving access to the voltage across the capacitor var replacer = new NodeReplacer { Map = new Dictionary <VariableNode, Node>(new VariableNodeComparer(null, null, bp.VariableComparer)) { { Node.Variable("x"), Node.Voltage(context.Nodes[0]) - Node.Voltage(context.Nodes[1]) } } }; Function = replacer.Build(bp.Function); Derivatives = context.CreateDerivatives(Function); DerivativeVariables = new Dictionary <VariableNode, IVariable <double> >(Derivatives.Comparer); foreach (var key in Derivatives.Keys) { DerivativeVariables.Add(key, context.MapNode(state, key)); } }
protected override Expression Transform(CallExpression lx) { if (!Operators.WildcardComparators.Contains(lx.OperatorName) || lx.Operands.Length != 2) { return(base.Transform(lx)); } var lhsIs = WildcardSearch.FindElementAtWildcard(lx.Operands[0]); var rhsIs = WildcardSearch.FindElementAtWildcard(lx.Operands[1]); if (lhsIs != null && rhsIs != null || lhsIs == null && rhsIs == null) { return(base.Transform(lx)); // N/A, or invalid } var wildcardPath = lhsIs != null ? lx.Operands[0] : lx.Operands[1]; var comparand = lhsIs != null ? lx.Operands[1] : lx.Operands[0]; var indexer = lhsIs ?? rhsIs !; var px = new ParameterExpression("p" + _nextParameter++); var nestedComparand = NodeReplacer.Replace(wildcardPath, indexer, px); var coll = indexer.Receiver; var wc = ((IndexerWildcardExpression)indexer.Index).Wildcard; var comparisonArgs = lhsIs != null ? new[] { nestedComparand, comparand } : new[] { comparand, nestedComparand }; var body = new CallExpression(lx.IgnoreCase, lx.OperatorName, comparisonArgs); var lambda = new LambdaExpression(new[] { px }, body); var op = Operators.ToRuntimeWildcardOperator(wc); var call = new CallExpression(false, op, coll, lambda); return(Transform(call)); }
// Reduces the size of a supplied expression tree by compiling parts of the tree into individual // delegates. Besides preventing the CLR from throwing stack overflow exceptions (which will happen // when the tree gets somewhere between 20,000 and 50,000 nodes), this can reduce the amount of code // that needs to be JITted and can therefore reduce the memory footprint of the application. private static Expression ReduceObjectGraphSize(Expression expression, Container container, Dictionary <Expression, InvocationExpression> reducedNodes = null) { var results = NodeSizeCalculator.Calculate(expression); while (results.TotalSize > container.Options.MaximumNumberOfNodesPerDelegate) { reducedNodes = reducedNodes ?? new Dictionary <Expression, InvocationExpression>(16); Expression mostReductiveNode = FindMostReductiveNodeOrNull(results, container.Options.MaximumNumberOfNodesPerDelegate); if (mostReductiveNode == null) { // In case mostReductiveNode is null, there's no good candidate to reduce the object // graph. In that case we break out. break; } // If the found mostReductiveNode has been reduced before, we use the previously compiled // value (instead of doing the compilation all over again). Otherwise we compile that node. InvocationExpression replacementNode = reducedNodes.ContainsKey(mostReductiveNode) ? reducedNodes[mostReductiveNode] : CompileToInvocation(mostReductiveNode, container, reducedNodes); reducedNodes[mostReductiveNode] = replacementNode; expression = NodeReplacer.Replace(expression, oldNode: mostReductiveNode, newNode: replacementNode); results = NodeSizeCalculator.Calculate(expression); } return(expression); }
public static TRoot Replace <TRoot, TNode>(this TRoot root, TNode node, Func <TNode, TNode?> computeReplacement) where TNode : SourceNode where TRoot : SourceNode { var replacer = new NodeReplacer <TNode>(new[] { node }, computeReplacement); return((TRoot?)replacer.Visit(root) ?? throw new InvalidOperationException()); }
public static TRoot Remove <TRoot, TNode>(this TRoot root, TNode node) where TNode : SourceNode where TRoot : SourceNode { var replacer = new NodeReplacer <TNode>(new[] { node }, x => null); return((TRoot?)replacer.Visit(root) ?? throw new InvalidOperationException()); }
public static Expression Replace(Expression expression, Expression oldNode, Expression newNode) { var replacer = new NodeReplacer { oldNode = oldNode, newNode = newNode }; return(replacer.Visit(expression)); }