public static double Integrate(RPN rpn, RPN.Node expression, RPN.Node variable, RPN.Node a, RPN.Node b, RPN.Node frequencey) { return(Approximate(rpn, expression, variable, a, b, frequencey, new List <ApproximationModes>() { ApproximationModes.Simpson, ApproximationModes.Midpoint })); }
public bool CanRunSet(AST.SimplificationMode mode, RPN.Node node) { if (debug) { if (canExecuteTracker == null) { canExecuteTracker = new Dictionary <AST.SimplificationMode, Stopwatch>(); } if (!canExecuteTracker.ContainsKey(mode)) { Stopwatch temp = new Stopwatch(); temp.Reset(); canExecuteTracker.Add(mode, temp); } } bool result = false; Stopwatch sw = null; if (debug) { sw = canExecuteTracker[mode]; sw.Start(); } result = ContainsSet(mode) && (!HasSetRule(mode) || GetSetRule(mode).CanExecute(node)); if (debug) { sw.Stop(); } return(result); }
//Code from https://andrewlock.net/creating-an-ascii-art-tree-in-csharp/ public static string Print(this RPN.Node tree) { StringBuilder sb = new StringBuilder(); PrintNode(tree, "", ref sb); return(sb.ToString()); }
private static string getDecimalFormat(double value, double accuracy = 1E-4, int maxIteration = 10000) { RPN.Node foo = getDecimalFormatToNode(value, accuracy, maxIteration); if (foo == null) { return(null); } return(foo.ToInfix()); }
public bool CanExecute(RPN.Node node) { if (preRule != null && preRule.CanExecute(node)) { return(CanRun.Invoke(preRule.Execute(node))); } return(CanRun.Invoke(node)); }
private RPN.Node PreOrPostprocess(Rule rule, RPN.Node node) { if (rule != null) { //if we the pre rule confirms it is applicable run it! if (rule.CanExecute(node)) { Write($"\t{rule.Name}"); return(rule.Execute(node.Clone())); } } return(null); }
static void PrintNode(RPN.Node node, string indent, ref StringBuilder sb) { //node [Hash] ID:[$ID] Children:[$#] sb.AppendLine($"{node} [{node.ID} | {node.Children.Count} | {node.Token.Type} | {node.isRoot} | {node.GetHash()}]"); // Loop through the children recursively, passing in the // indent, and the isLast parameter var numberOfChildren = node.Children.Count; for (var i = 0; i < numberOfChildren; i++) { var child = node.Children[i]; var isLast = (i == (numberOfChildren - 1)); PrintChildNode(child, indent, isLast, ref sb); } }
public RPN.Node Execute(RPN.Node node) { RPN.Node assignment = PreOrPostprocess(preRule, node); if (assignment != null) { node = assignment; } Write($"\t{Name}"); node = Compute.Invoke(node); assignment = PreOrPostprocess(postRule, node); if (assignment != null) { node = assignment; } return(node); }
static void PrintChildNode(RPN.Node node, string indent, bool isLast, ref StringBuilder sb) { // Print the provided pipes/spaces indent sb.Append(indent); // Depending if this node is a last child, print the // corner or cross, and calculate the indent that will // be passed to its children if (isLast) { sb.Append(_corner); indent += _space; } else { sb.Append(_cross); indent += _vertical; } PrintNode(node, indent, ref sb); }
public static string Table(RPN rpn, RPN.Node expression, RPN.Node variable, RPN.Node a, RPN.Node b, RPN.Node frequencey) { //A regular function PostFix math = new PostFix(rpn); double start = math.Compute(a.ToPostFix().ToArray()); double end = math.Compute(b.ToPostFix().ToArray()); double freq = math.Compute(frequencey.ToPostFix().ToArray()); double PrevAnswer = 0; math.SetPolish(expression.ToPostFix().ToArray()); double DeltaX = end - start; double n = DeltaX / freq; int max = (int)Math.Ceiling(n); Tables <double> table = new Tables <double>(new Config() { Format = rpn.Data.DefaultFormat, Title = "Table" }); table.Add(new Schema(variable.Token.Value)); table.Add(new Schema($"f({variable.Token.Value})")); for (int x = 0; x <= max; x++) { double RealX = start + x * DeltaX / n; math.SetVariable("ans", PrevAnswer); math.SetVariable(variable.Token.Value, RealX); double answer = math.Compute(); table.Add(new double[] { RealX, answer }); PrevAnswer = answer; math.Reset(); } return(table.ToString()); }
public static double Approximate(RPN rpn, RPN.Node expression, RPN.Node variable, RPN.Node a, RPN.Node b, RPN.Node frequencey, List <ApproximationModes> modes) { PostFix math = new PostFix(rpn); RPN.Token[] Polish = expression.ToPostFix().ToArray(); double start = math.Compute(a.ToPostFix().ToArray()); double end = math.Compute(b.ToPostFix().ToArray()); bool multiplyByNegativeOne = end < start; if (multiplyByNegativeOne) { double temp = start; start = end; end = temp; } double freq = math.Compute(frequencey.ToPostFix().ToArray()); math.SetPolish(Polish); double Rsum = 0; double Lsum = 0; double MidSum = 0; double PrevAnswer = 0; double f_a = 0; int count = 0; double DeltaX = end - start; double n = DeltaX / freq; int max = (int)Math.Ceiling(n); for (int x = 0; x <= max; x++) { double RealX = start + x * DeltaX / n; math.SetVariable("ans", PrevAnswer); math.SetVariable(variable.Token.Value, RealX); double answer = math.Compute(); if (x == 0) { f_a = answer; } if (x % 2 == 0) { if (x < max) { Rsum += answer; } if (x > 0) { Lsum += answer; } } else { MidSum += answer; } PrevAnswer = answer; math.Reset(); count++; } double LApprox = (2 * Rsum * DeltaX / n); double RApprox = (2 * Lsum * DeltaX / n); double MApprox = (2 * MidSum * DeltaX / n); double TApprox = (LApprox + RApprox) / 2; freq = freq * 2; n = DeltaX / freq; double Simpson = double.NaN; if (n % 2 == 0) { Simpson = (TApprox + 2 * MApprox) / 3; } Dictionary <ApproximationModes, double> approximations = new Dictionary <ApproximationModes, double>() { { ApproximationModes.Simpson, Simpson }, { ApproximationModes.Midpoint, MApprox }, { ApproximationModes.Trapezoidal, TApprox }, { ApproximationModes.Left, LApprox }, { ApproximationModes.Right, RApprox } }; //Return based on mode requested for (int i = 0; i < modes.Count; i++) { double approximation = approximations[modes[i]]; if (!double.IsNaN(approximation)) { return(multiplyByNegativeOne ? approximation * -1 : approximation); } } return(multiplyByNegativeOne ? approximations[modes[0]] * -1 : approximations[modes[0]]); }
public static RPN.Node getDecimalFormatToNode(double value, double accuracy = 1E-4, int maxIteration = 10000) { //Algorithm from stack overflow. try { if (accuracy <= 0.0 || accuracy >= 1.0) { throw new ArgumentOutOfRangeException("accuracy", "Must be > 0 and < 1."); } int sign = Math.Sign(value); if (sign == -1) { value = Math.Abs(value); } // Accuracy is the maximum relative error; convert to absolute maxError double maxError = sign == 0 ? accuracy : value * accuracy; int n = (int)Math.Floor(value); value -= n; if (value < maxError) { return(null); } if (1 - maxError < value) { return(null); } // The lower fraction is 0/1 int lower_n = 0; int lower_d = 1; // The upper fraction is 1/1 int upper_n = 1; int upper_d = 1; int i = 0; while (true) { // The middle fraction is (lower_n + upper_n) / (lower_d + upper_d) int middle_n = lower_n + upper_n; int middle_d = lower_d + upper_d; if (middle_d * (value + maxError) < middle_n) { // real + error < middle : middle is our new upper upper_n = middle_n; upper_d = middle_d; } else if (middle_n < (value - maxError) * middle_d) { // middle < real - error : middle is our new lower lower_n = middle_n; lower_d = middle_d; } else { int numerator = (n * middle_d + middle_n); int denominator = middle_d; if (numerator > 10000 || denominator > 10000) { return(null); } RPN.Node f = new RPN.Node(new RPN.Node[] { new RPN.Node(denominator), new RPN.Node(numerator * sign) }, new RPN.Token("/", 2, RPN.Type.Operator)); // Middle is our best fraction return(f); } i++; if (i > maxIteration) { return(null); } } } catch (Exception ex) { return(null); } }
/// <summary> /// This executes any possible simplification in the appropriate /// set. /// </summary> /// <param name="mode">The set to look in</param> /// <param name="node">The node to apply over</param> /// <returns>A new node that is the result of the application of the rule or null /// when no rule could be run</returns> public RPN.Node Execute(AST.SimplificationMode mode, RPN.Node node) { if (!ruleSet.ContainsKey(mode)) { throw new KeyNotFoundException("The optimization set was not found"); } List <Rule> rules = ruleSet[mode]; Stopwatch sw = null; if (debug) { if (ruleSetTracker == null) { ruleSetTracker = new Dictionary <AST.SimplificationMode, Stopwatch>(); } if (ruleSetTracker.ContainsKey(mode)) { sw = ruleSetTracker[mode]; } else { sw = new Stopwatch(); ruleSetTracker.Add(mode, sw); } sw.Start(); } if (!hits.ContainsKey(mode)) { hits.Add(mode, 0); } for (int i = 0; i < rules.Count; i++) { Rule rule = rules[i]; if (rule.CanExecute(node)) { RPN.Node temp = rule.Execute(node); if (debug) { sw.Stop(); } if (rule.DebugMode()) { Write("The output of : " + temp.ToInfix()); } hits[mode] = hits[mode] + 1; return(temp); } } if (debug) { sw.Stop(); } return(null); }