Beispiel #1
0
        static void Main(string[] args)
        {
            // BigFloat configuration
            BigFloat.RoundingMode = BigFloat.RoundingModeType.TRIM;
            BigFloat.RoundingDigits = 4;
            BigFloat.DefaultPrecision = new Library.Numerics.PrecisionSpec(16, Library.Numerics.PrecisionSpec.BaseType.DEC);

            /*
            BigDecimal a = BigDecimal.Parse("1234567865757567");
            BigDecimal b = BigDecimal.Parse("1233425678");
            BigDecimal n = 15;
            BigDecimal x, y;

            x = b * BigDecimal.Log10(a);
            y = (BigDecimal.Pow(10, x - BigDecimal.Round(x) + n - 1));
            Console.WriteLine("Result: {0}*10^{1}\n", BigDecimal.Round(y), BigDecimal.Round(x));
            */

            Stopwatch Time = new Stopwatch();
            string input = "(6/(6x)) + a^(x)/a + 6x/3 + x(x-5)(x+3)(x-54x+54x)x^3 = -4x^5";

            MathNode Node = new MathNode(input);
            Console.WriteLine("\n Equation:  {0}", input);

            MathTree t = new MathTree(Node);
            //  t.Print();

            Time.Start();
            Node.Simplify();
            Time.Stop();

            Node.SolveEqual();
            Node.Simplify();

            // Rearrange the terms
            Node.Rearrange();

            Console.WriteLine("\n Expanded: {0}\n\n", Node.ToString());

            /*
            if (Node.type == NodeTypes.Equal)
            {
                Tuple<List<BigFloat>, List<BigFloat>> Roots = Node.Roots();

                if (!Object.ReferenceEquals(Roots.Item1, null))
                {
                    List<Tuple<BigFloat, BigFloat>> Roots2 = Roots.Item1.Zip(Roots.Item2, (x, y) => Tuple.Create(x, y)).ToList();

                    bool FirstReal = true;
                    bool FirstImag = true;

                    foreach (Tuple<BigFloat, BigFloat> Real in Roots2.Where(x => x.Item2.IsZero()))
                    {
                        if (FirstReal)
                        {
                            Console.WriteLine("\n\n Real Zero Values: \n");
                            FirstReal = false;
                        }

                        Console.WriteLine(" x = {0}", Real.Item1);
                    }

                    foreach (Tuple<BigFloat, BigFloat> Imaginary in Roots2.Where(x => !x.Item2.IsZero()))
                    {

                        if (FirstImag)
                        {
                            Console.WriteLine("\n\n Imaginary Zero Values: \n");
                            FirstImag = false;
                        }

                        Console.WriteLine(" x = {0} + {1}i", Imaginary.Item1, Imaginary.Item2);
                    }

                    Console.WriteLine();
                }
            }*/
        }
Beispiel #2
0
        /// <summary>
        /// Parse a list of elements into a MathNode
        /// </summary>
        /// <param name="Elements"></param>
        /// <returns></returns>
        private MathNode ParseString(List<Tuple<string, string>> Elements)
        {
            // Remove white-spaces
            while (Elements.Any() && Elements.First().Item1 == " ") Elements.RemoveAt(0);
            while (Elements.Any() && Elements.Last().Item1 == " ") Elements.RemoveAt(Elements.Count - 1);

            // No Elements (?)
            if (Elements.Count == 0)
            {
                return new MathNode(NodeTypes.Empty);
            }

            // Remove extra parentheses
            if (Elements.Any(x => x.Item1 == "("))
            {
                Elements = StripParentheses(Elements);
            }

            NodeTypes Type = NodeTypes.Empty;
            List<Tuple<string, int>> Signs = new List<Tuple<string, int>>();

            int insideBrackets = 0;
            for (int i = 0; i < Elements.Count; i++)
            {
                if (Elements[i].Item1 == "(") insideBrackets++;
                if (Elements[i].Item1 == ")") insideBrackets--;

                if(insideBrackets == 0)
                {
                    if (Elements[i].Item2 == ParsedType.Operator.ToString())
                    {
                        Signs.Add(Tuple.Create(Elements[i].Item1, i));
                    }
                }
            }

            if (Type == NodeTypes.Empty)
            {
                if (Signs.Any(x => x.Item1 == "="))
                {
                    Type = NodeTypes.Equal;
                }
                else if (Signs.Any(x => x.Item1 == "+"))
                {
                    Type = NodeTypes.Addition;
                }
                else if (Signs.Any(x => x.Item1 == "-"))
                {
                    Type = NodeTypes.Subtraction;
                }
                else if (Signs.Any(x => x.Item1 == "*"))
                {
                    Type = NodeTypes.Multiplication;
                }
                else if (Signs.Any(x => x.Item1 == "/"))
                {
                    Type = NodeTypes.Division;
                }
                else if (Signs.Any(x => x.Item1 == "^"))
                {
                    Type = NodeTypes.Exponentiation;
                }
            }

            if (Elements.Count == 1 || Type == NodeTypes.Empty)
            {
                // ---------------------
                // Simple MathNode
                // ---------------------

                // Number MathNode
                if (Elements[0].Item2 == NodeTypes.Number.ToString())
                {
                    return new MathNode(NodeTypes.Number, new BigFloat(Elements[0].Item1.ToString(), BigFloat.DefaultPrecision));
                }

                // Symbol MathNode
                if (Elements[0].Item2 == NodeTypes.Symbol.ToString())
                {
                    return new MathNode(NodeTypes.Symbol, Elements[0].Item1);
                }

                string Result = string.Join(string.Empty, Elements.Select(x => x.Item1));

                if (FindFunctionName(Result) != null)
                {
                    Type = NodeTypes.Function;
                    // Strip "cos" from "cos(3x+6)"
                    // We only need the "cos" ;)

                    Elements = Elements.GetRange(2, Elements.Count - 2);

                    MathNode FunctionMathNode = new MathNode(NodeTypes.Function);
                    FunctionMathNode.symbol = FindFunctionName(Result);
                    FunctionMathNode.AddChild(ParseString(Elements));

                    return FunctionMathNode;
                }

                return new MathNode(NodeTypes.Empty);
            }
            else if (Elements.Count > 1)
            {
                // ---------------------
                // Complex MathNode
                // ---------------------

                // The result
                MathNode Main = new MathNode(Type);

                // ---------------------
                // Define the splitter character
                // ---------------------
                string Splitter =

                    // Simple operators
                    Type == NodeTypes.Addition ? "+" :
                    Type == NodeTypes.Division ? "/" :
                    Type == NodeTypes.Multiplication ? "*" :
                    Type == NodeTypes.Subtraction ? "-" :
                    Type == NodeTypes.Exponentiation ? "^" :
                    Type == NodeTypes.Equal ? "=" : " ";

                // Debug

                List<int> SplittersLocations = Signs.Where(x => x.Item1 == Splitter).Select(x => x.Item2).ToList();

                if (SplittersLocations.Count == 0)
                {
                    throw new Exception("Wrongly declared as " + Type + " ( " + Result + " ) ");
                }

                SplittersLocations.Add(Elements.Count);

                for (int i = 0; i < SplittersLocations.Count; i++)
                {
                    int last = i >= 1 ? SplittersLocations[i - 1] + 1 : 0;
                    Main.AddChild(ParseString(Elements.GetRange(last, SplittersLocations[i] - last).ToList()));
                }

                return Main;
            }

            return new MathNode(NodeTypes.Empty);
        }