Example #1
0
        /// <inheritdoc/>
        public override ExpNode Execute(VectorProductOperNode node)
        {
            // Verify left and right child are two multiplyable vectors.
            if (node.LeftChild is TensorNode vector1 && vector1.DimensionCount == 1 &&
                node.RightChild is TensorNode vector2 && vector2.DimensionCount == 1 &&
                vector1.SizeIdentity == vector2.SizeIdentity)
            {
                int size = vector1.GetDimensionSize(1);
                switch (node.ProductMethod)
                {
                case VectorProductMethod.DOT:
                    ExpNode[] terms = new ExpNode[size];
                    for (int i = 0; i < size; i++)
                    {
                        terms[i] = QuickOpers.Multiply(vector1.GetChild(i), vector2.GetChild(i));
                    }
                    return(QuickOpers.Sum(terms).Execute(this));

                case VectorProductMethod.CROSS:     // TODO: Convert to matrix notation for determinant
                default:
                    return(node);
                }
            }

            return(HandleError(new CannotMultiplyTensors(this, node)));
        }
Example #2
0
 /// <inheritdoc/>
 public override ExpNode Execute(VarValueNode node)
 {
     if (node.Character != _variable.Character)
     {
         return(ConstantRule(node));
     }
     return(QuickOpers.Multiply(.5, QuickOpers.Pow(node, 2)));
 }
Example #3
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);
        }
Example #4
0
        /// <inheritdoc/>
        public override ExpNode Execute(VectorProjOperNode node)
        {
            if (node.LeftChild.AreEqualSizeVectors(node.RightChild, out TensorNode a, out TensorNode b))
            {
                VectorProductOperNode adotb = QuickOpers.DotProduct(a, (TensorNode)b.Clone());
                BOperNode             bdotb = QuickOpers.DotProduct((TensorNode)b.Clone(), (TensorNode)b.Clone());

                return(QuickOpers.Multiply(b, adotb, QuickOpers.Reciprical(bdotb)).Execute(this));
            }

            return(HandleError(new CannotVectorProject(this, node)));
        }
Example #5
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)));
        }
Example #6
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));
        }
Example #7
0
        /// <inheritdoc/>
        public override ExpNode Execute(SineOperNode node)
        {
            if (node.IsConstantBy(_variable))
            {
                return(ConstantRule(node));
            }

            Differentiator diff = new(_variable);
            // Apply ChainRule
            var coefficient = node.Child.Execute(diff);
            // Apply table
            var sinFunc = SineTable(node);

            return(QuickOpers.Multiply(QuickOpers.Reciprical(coefficient), sinFunc));
        }
Example #8
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));
        }
Example #9
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);
            }
        }