예제 #1
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);
        }
예제 #2
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);
        }