コード例 #1
0
            public bool TryParseExpression(string expression, out ComplexFunction.ComplexFunction complexFunction, bool mutable = false)
            {
                complexFunction = null;

                if (operators.ContainsKey(expression))
                {
                    if (mutable)
                    {
                        //if (expression == "-" && ExpressionStack.Count == 1)
                        //{
                        //    //= "Could fix the minus...";
                        //}
                        // an unsupported operator
                        if (/*operators[expression].function == null || */ ExpressionStack.Count < operators[expression].ArgumentCount)
                        {
                            return(false);
                        }

                        // collect the arguments
                        var arguments = new ComplexFunction.ComplexFunction[operators[expression].ArgumentCount];

                        // remember about the reverse order!
                        for (int i = operators[expression].ArgumentCount - 1; i >= 0; i--)
                        {
                            arguments[i] = ExpressionStack.Pop();
                        }

                        complexFunction = ComplexFunction.Generator.Generate(expression, arguments);
                    }
                }
                else
                {
                    if (constants.ContainsKey(expression))
                    {
                        complexFunction = ComplexFunction.Generator.Generate(expression);
                    }
                    else
                    {
                        // could be a number
                        bool succeededParsing = double.TryParse(expression, out double result);

                        if (succeededParsing)
                        {
                            complexFunction = ComplexFunction.Generator.Generate("custom_constant", result);
                        }
                        else
                        {
                            return(false);
                        }
                    }
                }

                // let's be fair and do not provide anythin undefined if the user just asks for parsability
                if (!mutable)
                {
                    complexFunction = null;
                }

                return(true);
            }
コード例 #2
0
 public bool TryParseTree(out ComplexFunction.ComplexFunction returnValue)
 {
     if (ExpressionStack.Count == 1)
     {
         returnValue = ExpressionStack.Peek();
         return(true);
     }
     else
     {
         returnValue = null;
         return(false);
     }
 }
コード例 #3
0
        private void ComputeFractal(Complex complexCoordinates)
        {
            switch ((DragEffect)Settings.Instance.drageffect)
            {
            case DragEffect.Move:
                Settings.Instance.Center = CenterLastClicked - (GetComplexCoords(MouseLastMove, CenterLastClicked) - MouseLastClickedComplex);
                break;

            case DragEffect.SingleRoot:
                AlgorithmFunction = new ComplexFunction.ProductCF(Function,
                                                                  new ComplexFunction.DifferenceCF(new ComplexFunction.ArgumentCF(), new ComplexFunction.ConstantCF(complexCoordinates)));
                break;

            case DragEffect.DoubleRoot:
                AlgorithmFunction = new ComplexFunction.ProductCF(Function,
                                                                  new ComplexFunction.DifferenceCF(new ComplexFunction.ArgumentCF(), new ComplexFunction.ConstantCF(complexCoordinates)),
                                                                  new ComplexFunction.DifferenceCF(new ComplexFunction.ArgumentCF(), new ComplexFunction.ConstantCF(complexCoordinates))
                                                                  );
                break;

            case DragEffect.Singularity:
                AlgorithmFunction = new ComplexFunction.QuotientCF(Function,
                                                                   new ComplexFunction.DifferenceCF(new ComplexFunction.ArgumentCF(), new ComplexFunction.ConstantCF(complexCoordinates)));
                break;

            case DragEffect.Reset:
                AlgorithmFunction = Function;
                break;

            default:
                AlgorithmFunction = Function;
                break;
            }

            ComputeFractal();
        }
コード例 #4
0
        public static bool TryParse(string formula, out ComplexFunction.ComplexFunction complexFunction)
        {
            var    expressionQueue = new ParseTreeGenerator();
            var    operatorStack   = new Stack <string>();
            string lastExpression  = string.Empty;
            string expression      = string.Empty;

            complexFunction = null;
            bool delayUntilLast = false;
            int  deepness       = 0;

            // remove all whitespace characters
            formula = Regex.Replace(formula, @"\s+", "");

            try
            {
                for (int cursor = 0; cursor < formula.Length; cursor++)
                {
                    expression += formula[cursor].ToString().ToLower();

                    if (!expressionQueue.TryParseExpression(expression, out _, false))
                    {
                        continue;
                    }

                    var lastPossibility = cursor == formula.Length - 1 || !expressionQueue.TryParseExpression(expression + formula[cursor + 1], out _, false);

                    // nonoperator should be interpreted lazily
                    // operators should be treated firstly

                    // first successful encounter
                    if (!delayUntilLast)
                    {
                        delayUntilLast = true;
                        // succeeded interpreting the first time// if able to parse, but no further (lazy evaluation)
                        if (operators.ContainsKey(expression))
                        {
                            if (expression == "-")
                            {
                                if (operators.ContainsKey(lastExpression))
                                {
                                    if (operators[lastExpression].IsOpening || lastExpression != ")")
                                    {
                                        // "sin(-" "acos(-" "(-" "*-" "--" "+-" "^-"
                                        // interpret as negation
                                        // carry on to last interpretation]

                                        // consider replacing "-" with "(-1)*" or "i*i*"
                                        switch (expression)
                                        {
                                        case "-":
                                            // important negation
                                            formula = formula.Remove(cursor, 1).Insert(cursor, "_&");
                                            break;
                                            //case "+":
                                            //    formula = formula.Remove(cursor, 1);
                                            //    break;
                                        }
                                        cursor    -= expression.Length;
                                        expression = string.Empty;
                                        continue;
                                    }
                                    else
                                    {
                                        // )-
                                        // interpret as subtraction
                                    }
                                }
                                else
                                {
                                    // a variable
                                    // 1234-
                                    // z-
                                    // could be 123+456-
                                    // interpret as subtraction
                                }
                            }
                        }
                        // expression is not an operator
                        else if (lastExpression != string.Empty && !operators.ContainsKey(lastExpression))
                        {
                            // should not be the case that nonoperator follows another nonoperator (as if it was implicit multiplication)
                            return(false);
                        }
                        else
                        {
                            // last time I've interpreted an operator
                            // it is alwright
                            if (!lastPossibility)
                            {
                                continue;
                            }
                        }
                    }
                    else if (!lastPossibility)
                    {
                        continue;
                    }
                    // other cases consider subsequent (not first) succsessful interpretation

                    if (operators.ContainsKey(expression))
                    {
                        if (expression == ",")
                        {
                            // crush to another "," or to "sin("
                        }
                        else if (expression == ")")
                        {
                            // crushing until "(" or "sin(" found
                            while (operatorStack.Count > 0 && !operators[operatorStack.Peek()].IsOpening)
                            {
                                expressionQueue.Enqueue(operatorStack.Pop());
                            }

                            // no "(" nor "sin(" found that is an error!
                            if (operatorStack.Count == 0)
                            {
                                return(false);
                            }

                            var openingOperator = operatorStack.Pop();

                            // an opening operator that is not "(" should carry useful information with it, let's keep it!
                            if (openingOperator != "(")
                            {
                                expressionQueue.Enqueue(openingOperator);
                            }

                            --deepness;
                        }
                        else if (operators[expression].IsOpening)
                        {
                            // highest priority when adding yet lowest when already inside (to stop propagating)
                            operatorStack.Push(expression);
                            ++deepness;
                        }
                        else
                        {
                            // > and >= shoud be differentiated when computing from the right or from the left
                            // rightmost evaluation works ONLY for supported operators and ONLY if the are neighbouring to each other
                            // leftmost evaluation pops more often
                            while (operatorStack.Count > 0 &&
                                   !operators[operatorStack.Peek()].IsOpening &&
                                   operators[operatorStack.Peek()].Priority >= operators[expression].Priority)
                            {
                                expressionQueue.Enqueue(operatorStack.Pop());
                            }

                            operatorStack.Push(expression);
                        }
                    }
                    else
                    {
                        // a constant value like "12345", or argument "z"
                        expressionQueue.Enqueue(expression);
                    }

                    lastExpression = expression;
                    // clear the expression before proceeding
                    expression     = string.Empty;
                    delayUntilLast = false;
                }

                if (deepness != 0 || expression != string.Empty)
                {
                    return(false);
                }

                while (operatorStack.Count > 0)
                {
                    expressionQueue.Enqueue(operatorStack.Pop());
                }

                return(expressionQueue.TryParseTree(out complexFunction));
            }
            catch (ArgumentException e)
            {
                // incorrect formula
                return(false);
            }
        }
        public FractalAlgorithm GetAutoConfiguredAlgorithmByID(Algorithm algorithmID, params ComplexFunction.ComplexFunction[] Derivatives)
        {
            if (Derivatives.Length == 0)
            {
                return(new NullAlgorithm());
            }

            FractalAlgorithm algorithm;

            switch (algorithmID)
            {
            // actually we really need the derivative so really (... >= 2)
            case Algorithm.Newton:
                if (Derivatives.Length < 2)
                {
                    Derivatives = new ComplexFunction.ComplexFunction[] { Derivatives[0], Derivatives[0].GetDerivative() };
                }
                algorithm = new NewtonFractal();
                break;

            case Algorithm.Halley:
                if (Derivatives.Length < 2)
                {
                    Derivatives = new ComplexFunction.ComplexFunction[] { Derivatives[0], Derivatives[0].GetDerivative() };
                }
                if (Derivatives.Length < 3)
                {
                    Derivatives = new ComplexFunction.ComplexFunction[] { Derivatives[0], Derivatives[1], Derivatives[1].GetDerivative() };
                }
                algorithm = new HalleyFractal();
                break;

            case Algorithm.Quadruple:
                if (Derivatives.Length < 2)
                {
                    Derivatives = new ComplexFunction.ComplexFunction[] { Derivatives[0], Derivatives[0].GetDerivative() };
                }
                if (Derivatives.Length < 3)
                {
                    Derivatives = new ComplexFunction.ComplexFunction[] { Derivatives[0], Derivatives[1], Derivatives[1].GetDerivative() };
                }
                if (Derivatives.Length < 4)
                {
                    Derivatives = new ComplexFunction.ComplexFunction[] { Derivatives[0], Derivatives[1], Derivatives[2], Derivatives[2].GetDerivative() };
                }
                algorithm = new HalleyFractal();
                break;

            case Algorithm.Halley_overnewtoned:
                if (Derivatives.Length < 2)
                {
                    Derivatives = new ComplexFunction.ComplexFunction[] { Derivatives[0], Derivatives[0].GetDerivative() };
                }
                if (Derivatives.Length < 3)
                {
                    Derivatives = new ComplexFunction.ComplexFunction[] { Derivatives[0], Derivatives[1], Derivatives[1].GetDerivative() };
                }
                algorithm = new HalleyNewton();
                break;

            case Algorithm.Halley_without_derivative:
                algorithm = new HalleyWithoutDerivativeFractal();
                break;

            case Algorithm.Quadratic:
                if (Derivatives.Length < 2)
                {
                    Derivatives = new ComplexFunction.ComplexFunction[] { Derivatives[0], Derivatives[0].GetDerivative() };
                }
                if (Derivatives.Length < 3)
                {
                    Derivatives = new ComplexFunction.ComplexFunction[] { Derivatives[0], Derivatives[1], Derivatives[1].GetDerivative() };
                }
                algorithm = new QuadraticFractal();
                break;

            case Algorithm.Quadratic_without_derivative:
                algorithm = new QuadraticWithoutDerivativeFractal();
                break;

            case Algorithm.Newton_without_derivative:
                algorithm = new NewtonWithoutDerivativeFractal();
                break;

            case Algorithm.Secant_Newton_combination:
                algorithm = new SecantNewtonFractal();
                break;

            case Algorithm.Secant:
                algorithm = new SecantFractal();
                break;

            case Algorithm.Muller:
                algorithm = new MullerFractal();
                break;

            case Algorithm.Moler_real:
                algorithm = new MolerRealFractal();
                break;

            case Algorithm.Inverse:
                algorithm = new InverseQuadraticFractal();
                break;

            case Algorithm.Steffensen:
                algorithm = new SteffensenFractal();
                break;

            case Algorithm.Custom:
                algorithm = new CustomFractal();
                break;

            default:
                algorithm = new NullAlgorithm();
                break;
            }

            algorithm.Derivatives           = Derivatives;
            algorithm.MaximumIterationCount = Settings.Instance.iterations;

            if (algorithm is ParametrizedFractalAlgorithm)
            {
                (algorithm as ParametrizedFractalAlgorithm).Parameter = (double)Settings.Instance.parameter;
            }

            return(algorithm);
        }