Exemple #1
0
        /// <summary>
        /// Splits an <see cref="AdditionOperNode"/> into terms and simplifies by common terms.
        /// </summary>
        /// <param name="node">The <see cref="AdditionOperNode"/> to simplify.</param>
        /// <returns>The resulting <see cref="ExpNode"/>.</returns>
        public static AdditionOperNode SimplfiyATerms(AdditionOperNode node)
        {
            SortedSet <AdditiveTerm> aTerms = new();

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

                if (aTerms.TryGetValue(aTerm, out AdditiveTerm existingATerm))
                {
                    existingATerm.AddToCoefficient(aTerm);
                }
                else
                {
                    aTerms.Add(aTerm);
                }
            }

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

            return(node);
        }
Exemple #2
0
        /// <inheritdoc/>
        public override ExpNode Execute(AdditionOperNode node)
        {
            // Sum rule
            for (int i = 0; i < node.ChildCount; i++)
            {
                ExpNode diffChild = node.GetChild(i).Execute(this);
                node.ReplaceChild(diffChild, i);
            }

            return(node);
        }
Exemple #3
0
        /// <inheritdoc/>
        public override ExpNode Execute(PowOperNode node)
        {
            // TODO: Handle variable in exponent
            if (node.IsConstantBy(_variable))
            {
                return(ConstantRule(node));
            }

            // Increment exponent, divide by exponent
            AdditionOperNode   exponent    = QuickOpers.Add(1, node.RightChild);
            RecipricalOperNode coefficient = QuickOpers.Reciprical(exponent.Clone());
            PowOperNode        @base       = QuickOpers.Pow(node.LeftChild, exponent);

            return(QuickOpers.Multiply(coefficient, @base));
        }
Exemple #4
0
        /// <summary>
        /// Adds tensors.
        /// </summary>
        /// <param name="node">The <see cref="AdditionOperNode"/> containing tensors.</param>
        /// <param name="simplifier">The <see cref="Simplifier"/> calling.</param>
        /// <returns>The resuling <see cref="ExpNode"/>.</returns>
        public static ExpNode SumTensors(AdditionOperNode node, Simplifier simplifier)
        {
            if (node.GetChild(0) is TensorNode tensorNode)
            {
                for (int i = 1; i < node.ChildCount; i++)
                {
                    if (node.GetChild(i) is TensorNode otherTensorNode)
                    {
                        if (otherTensorNode.SizeIdentity == tensorNode.SizeIdentity)
                        {
                            for (int j = 0; j < tensorNode.ChildCount; j++)
                            {
                                ExpNode addedNode = QuickOpers
                                                    .Sum(tensorNode.GetChild(j), otherTensorNode.GetChild(j))
                                                    .Execute(simplifier);
                                tensorNode.ReplaceChild(addedNode, j);
                            }
                        }
                        else
                        {
                            return(simplifier.HandleError(new CannotAddTensors(simplifier, node, $"Cannot add tensor of shape {otherTensorNode.SizeIdentity} and tensor of shape {tensorNode.SizeIdentity}.")));
                        }
                    }
                    else
                    {
                        return(simplifier.HandleError(new CannotAddTensors(simplifier, node, "Cannot add scalar and tensor.")));
                    }
                }

                return(tensorNode);
            }
            else
            {
                // There is a scalar.
                // There cannot be any tensors
                for (int i = 1; i < node.ChildCount; i++)
                {
                    if (node.GetChild(i) is TensorNode)
                    {
                        return(simplifier.HandleError(new CannotAddTensors(simplifier, node, "Cannot add tensor and scalar.")));
                    }
                }
            }

            return(node);
        }
Exemple #5
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));
        }
Exemple #6
0
        /// <inheritdoc/>
        public override string Print(AdditionOperNode node)
        {
            string cache = string.Empty;

            // Add each child seperated by a '+'
            for (int i = 0; i < node.ChildCount; i++)
            {
                var  child        = node.GetChild(i);
                bool implicitSign = child is SignOperNode ||
                                    ((child is NumericalValueNode nvChild) && nvChild.DoubleValue < 0);
                if (!(i == 0 || implicitSign))
                {
                    // Don't add if is a negative sign operator,
                    // a negative numerical value
                    // or if first iteration
                    cache += "+";
                }

                cache += child.Print(this);
            }
            return(cache);
        }
Exemple #7
0
        // All methods by default call their direct parent type except ExpNode because it is the root type.
        // As a result, types only need to be overriden if they can't be handled by a parent type.

        /// <summary>
        /// Executes operation on an <see cref="AdditionOperNode"/>.
        /// </summary>
        /// <param name="node">The <see cref="AdditionOperNode"/> to execute operation on.</param>
        /// <returns>The result of the operation on an <see cref="AdditionOperNode"/>.</returns>
        public virtual ExpNode Execute(AdditionOperNode node) => Execute((NOperNode)node);
Exemple #8
0
 /// <summary>
 /// Initializes a new instance of the <see cref="CannotAddTensors"/> class.
 /// </summary>
 /// <param name="simplifier">The simplified that threw.</param>
 /// <param name="context">The <see cref="AdditionOperNode"/> that it threw simplifying.</param>
 /// <param name="message">The <see cref="Exception"/> message.</param>
 public CannotAddTensors(Simplifier simplifier, AdditionOperNode context, string message = "")
     : base(simplifier, context, message)
 {
 }
Exemple #9
0
        // All methods by default call their direct parent type except ExpNode because it is the root type.
        // As a result, types only need to be overriden if they can't be handled by a parent type.

        /// <summary>
        /// Prints an <see cref="AdditionOperNode"/>.
        /// </summary>
        /// <param name="node">The <see cref="AdditionOperNode"/> to print.</param>
        /// <returns>The <see cref="AdditionOperNode"/> printed to a string.</returns>
        public virtual string Print(AdditionOperNode node) => Print((NOperNode)node);