/// <inheritdoc/> public override ExpNode Execute(MultiplicationOperNode node) { double valueProg = 1; 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 MultiplicationOperNode mNode) { mNode.TransferChildren(node); node.RemoveChild(i); i--; } else { node.ReplaceChild(simpleChild, i); } } // Anything multiplied by 0, is zero if (valueProg == 0) { return(QuickOpers.MakeNumericalNode(0)); } if (node.ChildCount == 0 || valueProg != 1) { node.AddChild(QuickOpers.MakeNumericalNode(valueProg)); } MultiplicationHelpers.SimplfiyMTerms(node, this); if (node.ChildCount == 0) { return(QuickOpers.MakeNumericalNode(0)); } else if (node.ChildCount == 1) { return(node.GetChild(0)); } node = MultiplicationHelpers.MultiplyScalarTensor(node, this); if (node == null) { return(node); } return(MultiplicationHelpers.Distribute(node, this)); }
/// <inheritdoc/> public override ExpNode Execute(RecipricalOperNode node) { node.Child = node.Child.Execute(this); if (node.Child is NumericalValueNode nvNode) { return(QuickOpers.MakeNumericalNode(1 / nvNode.DoubleValue)); } return(QuickOpers.Pow(node.Child, -1).Execute(this)); }
private void CompleteValue() { if (_state != ParserState.INT && _state != ParserState.FLOAT) { return; } double value = Convert.ToDouble(_cache); _tree.AddNode(QuickOpers.MakeNumericalNode(value)); _cache = string.Empty; }
/// <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)); }
/// <summary> /// Converts the <see cref="NumericalValueNode"/> back to an <see cref="ExpNode"/>. /// </summary> /// <returns>The <see cref="NumericalValueNode"/> as an <see cref="ExpNode"/>.</returns> public ExpNode AsExpNode() { if (_exponent is NumericalValueNode nvNode) { if (nvNode.DoubleValue == 0) { return(QuickOpers.MakeNumericalNode(1)); } else if (nvNode.DoubleValue == 1) { return(_base); } } return(QuickOpers.Pow(_base, _exponent)); }
/// <summary> /// Initializes a new instance of the <see cref="MultiplicativeTerm"/> class. /// </summary> /// <param name="node">The node to create as a term.</param> public MultiplicativeTerm(ExpNode node) { DefaultPrinter printer = new(); if (node is PowOperNode powNode) { _base = powNode.LeftChild; _exponent = powNode.RightChild; } else { _base = node; _exponent = QuickOpers.MakeNumericalNode(1); } _baseString = _base.Print(printer); }
/// <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)); }
/// <inheritdoc/> public override ExpNode Execute(PowOperNode node) { node.LeftChild = node.LeftChild.Execute(this); node.RightChild = node.RightChild.Execute(this); if (node.LeftChild is NumericalValueNode lnvNode && node.RightChild is NumericalValueNode rnvNode) { return(QuickOpers.MakeNumericalNode(Math.Pow(lnvNode.DoubleValue, rnvNode.DoubleValue))); } if (node.RightChild is IntValueNode ivNode) { if (ivNode.DoubleValue == 0) { return(QuickOpers.MakeNumericalNode(1)); } if (ivNode.DoubleValue == 1) { return(node.LeftChild); } if (node.LeftChild is ValueNode) { // No good expanding return(node); } int n = ivNode.Value; // Expand n times MultiplicationOperNode mNode = new(); mNode.AddChild(node.LeftChild); for (int i = 1; i < n; i++) { mNode.AddChild(node.LeftChild.Clone()); } return(mNode.Execute(this)); } return(PowerHelpers.Distribute(node)); }
/// <inheritdoc/> public override ExpNode Execute(SineOperNode node) { node.Child = node.Child.Execute(this); if (node.Child is NumericalValueNode nvNode) { double value = 0; switch (node.SineFunction) { case SineFunction.SINE: value = Math.Sin(nvNode.DoubleValue); break; case SineFunction.COSINE: value = Math.Cos(nvNode.DoubleValue); break; case SineFunction.TANGENT: value = Math.Tan(nvNode.DoubleValue); break; case SineFunction.COSECANT: value = 1 / Math.Sin(nvNode.DoubleValue); break; case SineFunction.SECANT: value = 1 / Math.Cos(nvNode.DoubleValue); break; case SineFunction.COTANGENT: value = 1 / Math.Tan(nvNode.DoubleValue); break; } return(QuickOpers.MakeNumericalNode(value)); } return(node); }
/// <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); } }
/// <inheritdoc/> public override ExpNode Execute(NumericalValueNode node) { return(QuickOpers.MakeNumericalNode(0)); }
/// <inheritdoc/> public override ExpNode Execute(VarValueNode node) { return(QuickOpers.MakeNumericalNode(node.Character == _variable.Character ? 1 : 0)); }