/// <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))); }
/// <inheritdoc/> public override ExpNode Execute(VarValueNode node) { if (node.Character != _variable.Character) { return(ConstantRule(node)); } return(QuickOpers.Multiply(.5, QuickOpers.Pow(node, 2))); }
/// <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); }
/// <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))); }
/// <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))); }
/// <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)); }
/// <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)); }
/// <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)); }
/// <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); } }