Пример #1
0
        /// <summary>
        /// Splits an <see cref="MultiplicationOperNode"/> into terms and simplifies by common terms.
        /// </summary>
        /// <param name="node">The <see cref="MultiplicationOperNode"/> to simplify.</param>
        /// <param name="simplifier">The <see cref="Simplifier"/> calling.</param>
        /// <returns>The resulting <see cref="ExpNode"/>.</returns>
        public static MultiplicationOperNode SimplfiyMTerms(MultiplicationOperNode node, Simplifier simplifier)
        {
            SortedSet <MultiplicativeTerm> mTerms = new();

            for (int i = 0; i < node.ChildCount; i++)
            {
                MultiplicativeTerm mTerm = new(node.GetChild(i));

                if (mTerms.TryGetValue(mTerm, out MultiplicativeTerm existingMTerm))
                {
                    existingMTerm.AddToExponent(mTerm, simplifier);
                }
                else
                {
                    mTerms.Add(mTerm);
                }
            }

            node.ClearChildren();
            foreach (var term in mTerms)
            {
                node.AddChild(term.AsExpNode());
            }

            return(node);
        }
Пример #2
0
        /// <summary>
        /// Applies the multiplicative distributive property.
        /// </summary>
        /// <param name="node">The <see cref="MultiplicationOperNode"/> to simplify.</param>
        /// <param name="simplifier">The <see cref="Simplifier"/> calling.</param>
        /// <returns>The resuling <see cref="ExpNode"/>.</returns>
        public static ExpNode Distribute(MultiplicationOperNode node, Simplifier simplifier)
        {
            if (node.GetChild(node.ChildCount - 1) is ParenthesisOperNode parNode)
            {
                // Last child is parenthesis
                if (parNode.Child is AdditionOperNode aNode)
                {
                    // Last grandchild is addition
                    for (int i = 0; i < aNode.ChildCount; i++)
                    {
                        MultiplicationOperNode mNode = new();
                        mNode.AddChild(aNode.GetChild(i));
                        for (int j = 0; j < node.ChildCount - 1; j++)
                        {
                            mNode.AddChild(node.GetChild(j).Clone());
                        }

                        aNode.ReplaceChild(mNode, i);
                    }

                    return(aNode.Execute(simplifier));
                }
            }

            return(node);
        }
Пример #3
0
        /// <inheritdoc/>
        public override ExpNode Execute(MultiplicationOperNode node)
        {
            // TODO: Sinusoidal u substitutions
            // TODO: Constants recognitions for v
            Differentiator differentiator = new(_variable);

            // \int{u'vwx} = uvwx - \int{uv'wx} - \int{uvw'x} - \int{uvwx'}
            int partCount = node.ChildCount - 1;

            // Get u and du
            ExpNode du = node.GetChild(partCount);
            ExpNode u  = du.Clone().Execute(this);

            // Get dvs and vs
            ExpNode[] dvs = new ExpNode[partCount];
            ExpNode[] vs  = new ExpNode[partCount];
            for (int i = 0; i < partCount; i++)
            {
                vs[i]  = node.GetChild(i);
                dvs[i] = vs[i].Clone().Execute(differentiator);
            }

            AdditionOperNode aNode = new();

            // u*vs
            MultiplicationOperNode mNode = new();

            mNode.AddChild(u.Clone());
            for (int i = 0; i < partCount; i++)
            {
                mNode.AddChild(vs[i].Clone());
            }
            aNode.AddChild(mNode);

            // Combinatoric integrals
            for (int i = 0; i < partCount; i++)
            {
                IntegralOperNode intNode = new();
                mNode            = new MultiplicationOperNode();
                intNode.Variable = new VarValueNode(_variable);
                mNode.AddChild(u.Clone());
                for (int j = 0; j < partCount; j++)
                {
                    if (i == j)
                    {
                        mNode.AddChild(dvs[j].Clone());
                    }
                    else
                    {
                        mNode.AddChild(vs[j].Clone());
                    }
                }
                intNode.AddChild(mNode);
                aNode.AddChild(QuickOpers.Negative(intNode));
            }

            return(aNode);
        }
Пример #4
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));
        }
Пример #5
0
        /// <summary>
        /// Multiplies a tensor by scalars.
        /// </summary>
        /// <param name="node">The <see cref="MultiplicationOperNode"/> to simplify.</param>
        /// <param name="simplifier">The <see cref="Simplifier"/> calling.</param>
        /// <returns>The resuling <see cref="MultiplicationOperNode"/>.</returns>
        public static MultiplicationOperNode MultiplyScalarTensor(MultiplicationOperNode node, Simplifier simplifier)
        {
            TensorNode tensor1 = null;
            int        ti      = -1;

            for (int i = 0; i < node.ChildCount; i++)
            {
                if (i == ti)
                {
                    continue;
                }

                if (node.GetChild(i) is TensorNode tensor2)
                {
                    if (tensor1 != null)
                    {
                        if (i < ti)
                        {
                            TensorNode swap = tensor1;
                            tensor1 = tensor2;
                            tensor2 = swap;
                        }

                        if (!tensor1.CanMatrixMultiply(tensor2))
                        {
                            return((MultiplicationOperNode)simplifier.HandleError(new CannotMultiplyTensors(simplifier, node, $"Tensor nodes of size {tensor1.SizeIdentity} and {tensor2.SizeIdentity} could not be multiplied.")));
                        }
                    }
                    else
                    {
                        tensor1 = tensor2;
                        ti      = i;
                        i       = -1;
                    }
                }
                else
                {
                    if (tensor1 != null)
                    {
                        for (int j = 0; j < tensor1.ChildCount; j++)
                        {
                            ExpNode simpleChild = QuickOpers.Multiply(tensor1.GetChild(j), node.GetChild(i)).Execute(simplifier);
                            tensor1.ReplaceChild(simpleChild, j);
                        }

                        node.RemoveChild(i);
                        if (i < ti)
                        {
                            ti--;
                        }
                        i--;
                    }
                }
            }

            return(node);
        }
Пример #6
0
        /// <inheritdoc/>
        public override string Print(MultiplicationOperNode node)
        {
            string cache = string.Empty;

            // No need to seperate with '*'
            // All remain multiplication should be represented with implied
            for (int i = 0; i < node.ChildCount; i++)
            {
                cache += node.GetChild(i).Print(this);
            }
            return(cache);
        }
Пример #7
0
        /// <inheritdoc/>
        public override ExpNode Execute(MultiplicationOperNode node)
        {
            // Product rule
            AdditionOperNode aNode = new();

            for (int i = 0; i < node.ChildCount; i++)
            {
                MultiplicationOperNode mNode = new();
                mNode.AddChild(node.GetChild(i).Clone().Execute(this));
                for (int j = 0; j < node.ChildCount; j++)
                {
                    if (j != i)
                    {
                        mNode.AddChild(node.GetChild(j).Clone());
                    }
                }

                aNode.AddChild(mNode);
            }
            return(aNode);
        }
Пример #8
0
 /// <summary>
 /// Executes operation on a <see cref="MultiplicationOperNode"/>.
 /// </summary>
 /// <param name="node">The <see cref="MultiplicationOperNode"/> to execute operation on.</param>
 /// <returns>The result of the operation on a <see cref="MultiplicationOperNode"/>.</returns>
 public virtual ExpNode Execute(MultiplicationOperNode node) => Execute((NOperNode)node);
Пример #9
0
 /// <summary>
 /// Prints a <see cref="MultiplicationOperNode"/>.
 /// </summary>
 /// <param name="node">The <see cref="MultiplicationOperNode"/> to print.</param>
 /// <returns>The <see cref="MultiplicationOperNode"/> printed to a string.</returns>
 public virtual string Print(MultiplicationOperNode node) => Print((NOperNode)node);