/// <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); }
/// <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); }