Esempio n. 1
0
 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
     }));
 }
Esempio n. 2
0
        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);
        }
Esempio n. 3
0
        //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());
        }
Esempio n. 4
0
 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());
 }
Esempio n. 5
0
        public bool CanExecute(RPN.Node node)
        {
            if (preRule != null && preRule.CanExecute(node))
            {
                return(CanRun.Invoke(preRule.Execute(node)));
            }

            return(CanRun.Invoke(node));
        }
Esempio n. 6
0
        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);
        }
Esempio n. 7
0
        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);
            }
        }
Esempio n. 8
0
        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);
        }
Esempio n. 9
0
        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);
        }
Esempio n. 10
0
        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());
        }
Esempio n. 11
0
        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]]);
        }
Esempio n. 12
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);
            }
        }
Esempio n. 13
0
        /// <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);
        }