예제 #1
0
        /// <inheritdoc/>
        public override ExpNode Execute(MultiplicationOperNode node)
        {
            double valueProg = 1;

            for (int i = 0; i < node.ChildCount; i++)
            {
                ExpNode simpleChild = node.GetChild(i).Execute(this);

                if (simpleChild is NumericalValueNode nvNode)
                {
                    valueProg *= nvNode.DoubleValue;
                    node.RemoveChild(i);
                    i--;
                }
                else if (simpleChild is MultiplicationOperNode mNode)
                {
                    mNode.TransferChildren(node);
                    node.RemoveChild(i);
                    i--;
                }
                else
                {
                    node.ReplaceChild(simpleChild, i);
                }
            }

            // Anything multiplied by 0, is zero
            if (valueProg == 0)
            {
                return(QuickOpers.MakeNumericalNode(0));
            }

            if (node.ChildCount == 0 || valueProg != 1)
            {
                node.AddChild(QuickOpers.MakeNumericalNode(valueProg));
            }

            MultiplicationHelpers.SimplfiyMTerms(node, this);

            if (node.ChildCount == 0)
            {
                return(QuickOpers.MakeNumericalNode(0));
            }
            else if (node.ChildCount == 1)
            {
                return(node.GetChild(0));
            }

            node = MultiplicationHelpers.MultiplyScalarTensor(node, this);

            if (node == null)
            {
                return(node);
            }

            return(MultiplicationHelpers.Distribute(node, this));
        }
예제 #2
0
        /// <inheritdoc/>
        public override ExpNode Execute(RecipricalOperNode node)
        {
            node.Child = node.Child.Execute(this);

            if (node.Child is NumericalValueNode nvNode)
            {
                return(QuickOpers.MakeNumericalNode(1 / nvNode.DoubleValue));
            }

            return(QuickOpers.Pow(node.Child, -1).Execute(this));
        }
예제 #3
0
        private void CompleteValue()
        {
            if (_state != ParserState.INT && _state != ParserState.FLOAT)
            {
                return;
            }

            double value = Convert.ToDouble(_cache);

            _tree.AddNode(QuickOpers.MakeNumericalNode(value));
            _cache = string.Empty;
        }
예제 #4
0
        /// <inheritdoc/>
        public override ExpNode Execute(PowOperNode node)
        {
            // TODO: Handle variable in exponent
            if (node.IsConstantBy(_variable))
            {
                return(QuickOpers.MakeNumericalNode(0));
            }

            var coefficient = node.RightChild;
            var @base       = node.LeftChild;
            var exponent    = QuickOpers.Add(-1, coefficient);

            return(QuickOpers.Multiply(coefficient, QuickOpers.Pow(@base, exponent)));
        }
예제 #5
0
        /// <inheritdoc/>
        public override ExpNode Execute(SineOperNode node)
        {
            if (node.IsConstantBy(_variable))
            {
                return(QuickOpers.MakeNumericalNode(0));
            }

            // Apply chain rule
            var coefficient = node.Child.Clone().Execute(this);
            // Apply table
            var sinFunc = SineTable(node);

            return(QuickOpers.Multiply(coefficient, sinFunc));
        }
예제 #6
0
        /// <summary>
        /// Converts the <see cref="NumericalValueNode"/> back to an <see cref="ExpNode"/>.
        /// </summary>
        /// <returns>The <see cref="NumericalValueNode"/> as an <see cref="ExpNode"/>.</returns>
        public ExpNode AsExpNode()
        {
            if (_exponent is NumericalValueNode nvNode)
            {
                if (nvNode.DoubleValue == 0)
                {
                    return(QuickOpers.MakeNumericalNode(1));
                }
                else if (nvNode.DoubleValue == 1)
                {
                    return(_base);
                }
            }

            return(QuickOpers.Pow(_base, _exponent));
        }
예제 #7
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MultiplicativeTerm"/> class.
        /// </summary>
        /// <param name="node">The node to create as a term.</param>
        public MultiplicativeTerm(ExpNode node)
        {
            DefaultPrinter printer = new();

            if (node is PowOperNode powNode)
            {
                _base     = powNode.LeftChild;
                _exponent = powNode.RightChild;
            }
            else
            {
                _base     = node;
                _exponent = QuickOpers.MakeNumericalNode(1);
            }
            _baseString = _base.Print(printer);
        }
예제 #8
0
        /// <inheritdoc/>
        public override ExpNode Execute(AdditionOperNode node)
        {
            double valueProg = 0;

            for (int i = 0; i < node.ChildCount; i++)
            {
                ExpNode simpleChild = node.GetChild(i).Execute(this);

                if (simpleChild is NumericalValueNode nvNode)
                {
                    valueProg += nvNode.DoubleValue;
                    node.RemoveChild(i);
                    i--;
                }
                else if (simpleChild is AdditionOperNode aNode)
                {
                    aNode.TransferChildren(node);
                    node.RemoveChild(i);
                    i--;
                }
                else
                {
                    node.ReplaceChild(simpleChild, i);
                }
            }

            if (node.ChildCount == 0 || valueProg != 0)
            {
                node.AddChild(QuickOpers.MakeNumericalNode(valueProg));
            }

            AdditionHelpers.SimplfiyATerms(node);

            if (node.ChildCount == 0)
            {
                return(QuickOpers.MakeNumericalNode(0));
            }
            else if (node.ChildCount == 1)
            {
                return(node.GetChild(0));
            }

            return(AdditionHelpers.SumTensors(node, this));
        }
예제 #9
0
        /// <inheritdoc/>
        public override ExpNode Execute(PowOperNode node)
        {
            node.LeftChild  = node.LeftChild.Execute(this);
            node.RightChild = node.RightChild.Execute(this);

            if (node.LeftChild is NumericalValueNode lnvNode && node.RightChild is NumericalValueNode rnvNode)
            {
                return(QuickOpers.MakeNumericalNode(Math.Pow(lnvNode.DoubleValue, rnvNode.DoubleValue)));
            }

            if (node.RightChild is IntValueNode ivNode)
            {
                if (ivNode.DoubleValue == 0)
                {
                    return(QuickOpers.MakeNumericalNode(1));
                }
                if (ivNode.DoubleValue == 1)
                {
                    return(node.LeftChild);
                }

                if (node.LeftChild is ValueNode)
                {
                    // No good expanding
                    return(node);
                }

                int n = ivNode.Value;
                // Expand n times
                MultiplicationOperNode mNode = new();

                mNode.AddChild(node.LeftChild);
                for (int i = 1; i < n; i++)
                {
                    mNode.AddChild(node.LeftChild.Clone());
                }

                return(mNode.Execute(this));
            }

            return(PowerHelpers.Distribute(node));
        }
예제 #10
0
        /// <inheritdoc/>
        public override ExpNode Execute(SineOperNode node)
        {
            node.Child = node.Child.Execute(this);

            if (node.Child is NumericalValueNode nvNode)
            {
                double value = 0;
                switch (node.SineFunction)
                {
                case SineFunction.SINE:
                    value = Math.Sin(nvNode.DoubleValue);
                    break;

                case SineFunction.COSINE:
                    value = Math.Cos(nvNode.DoubleValue);
                    break;

                case SineFunction.TANGENT:
                    value = Math.Tan(nvNode.DoubleValue);
                    break;

                case SineFunction.COSECANT:
                    value = 1 / Math.Sin(nvNode.DoubleValue);
                    break;

                case SineFunction.SECANT:
                    value = 1 / Math.Cos(nvNode.DoubleValue);
                    break;

                case SineFunction.COTANGENT:
                    value = 1 / Math.Tan(nvNode.DoubleValue);
                    break;
                }

                return(QuickOpers.MakeNumericalNode(value));
            }

            return(node);
        }
예제 #11
0
        /// <inheritdoc/>
        public override ExpNode Execute(SignOperNode node)
        {
            node.Child = node.Child.Execute(this);
            switch (node.Sign)
            {
            case Sign.POSITIVE:
                return(node.Child);

            case Sign.NEGATIVE:
            {
                if (node.Child is NumericalValueNode nvNode)
                {
                    return(QuickOpers.MakeNumericalNode(nvNode.DoubleValue * -1));
                }

                return(QuickOpers.Multiply(-1, node.Child).Execute(this));
            }

            default:
                return(node);
            }
        }
예제 #12
0
 /// <inheritdoc/>
 public override ExpNode Execute(NumericalValueNode node)
 {
     return(QuickOpers.MakeNumericalNode(0));
 }
예제 #13
0
 /// <inheritdoc/>
 public override ExpNode Execute(VarValueNode node)
 {
     return(QuickOpers.MakeNumericalNode(node.Character == _variable.Character ? 1 : 0));
 }