/// <summary> /// Evaluates the function on a vector argument. /// </summary> /// <param name="Argument">Function argument.</param> /// <param name="Variables">Variables collection.</param> /// <returns>Function result.</returns> public override IElement EvaluateVector(IVector Argument, Variables Variables) { IRingElement Result = null; IRingElement RE; IRingElement Product; foreach (IElement E in Argument.ChildElements) { RE = E as IRingElement; if (RE is null) { if (Argument.ChildElements.Count == 1) { return(E); } else { throw new ScriptRuntimeException("Elements cannot be multiplied.", this); } } if (Result is null) { Result = RE; } else { Product = Result.MultiplyRight(RE); if (Product is null) { Product = (IRingElement)Operators.Arithmetics.Multiply.EvaluateMultiplication(Result, RE, this); } Result = Product; } } if (Result is null) { return(ObjectValue.Null); } else { return(Result); } }
/// <summary> /// Multiplies two ring elements, if possible. /// </summary> /// <param name="Left">Left element.</param> /// <param name="Right">Right element.</param> /// <returns>Result, if understood, null otherwise.</returns> public virtual IRingElement Multiply(IRingElement Left, IRingElement Right) { IRingElement Result; Result = Left.MultiplyRight(Right); if (Result != null) { return(Result); } Result = Right.MultiplyLeft(Left); if (Result != null) { return(Result); } return(null); }
/// <summary> /// Calculates the average of the elements of a vector. /// </summary> /// <param name="Vector">Vector</param> /// <param name="Node">Node performing evaluation.</param> /// <returns>Average of elements.</returns> public static IElement EvaluateAverage(IVector Vector, ScriptNode Node) { IElement Result = Vectors.Sum.EvaluateSum(Vector, Node); int n = Vector.Dimension; if (Result == null) { return(ObjectValue.Null); } else { IRingElement RE = Result as IRingElement; IRingElement Avg; if (RE != null && (Avg = RE.MultiplyRight(new DoubleNumber(1.0 / n))) != null) { return(Avg); } else { return(Operators.Arithmetics.Divide.EvaluateDivision(Result, new DoubleNumber(n), Node)); } } }
/// <summary> /// Multiplies two operands. /// </summary> /// <param name="Left">Left operand.</param> /// <param name="Right">Right operand.</param> /// <param name="Node">Node performing the operation.</param> /// <returns>Result</returns> public static IElement EvaluateMultiplication(IElement Left, IElement Right, ScriptNode Node) { IRingElement LE = Left as IRingElement; IRingElement RE = Right as IRingElement; IElement Result; if (LE != null && RE != null) { Result = LE.MultiplyRight(RE); if (Result != null) { return(Result); } Result = RE.MultiplyLeft(LE); if (Result != null) { return(Result); } } if (Left.IsScalar) { if (Right.IsScalar) { ISet LeftSet = Left.AssociatedSet; ISet RightSet = Right.AssociatedSet; if (!LeftSet.Equals(RightSet)) { if (!Expression.Upgrade(ref Left, ref LeftSet, ref Right, ref RightSet, Node)) { throw new ScriptRuntimeException("Incompatible operands.", Node); } LE = Left as IRingElement; RE = Right as IRingElement; if (LE != null && RE != null) { Result = LE.MultiplyRight(RE); if (Result != null) { return(Result); } Result = RE.MultiplyLeft(LE); if (Result != null) { return(Result); } } } throw new ScriptRuntimeException("Operands cannot be multiplied.", Node); } else { LinkedList <IElement> Elements = new LinkedList <IElement>(); foreach (IElement RightChild in Right.ChildElements) { Elements.AddLast(EvaluateMultiplication(Left, RightChild, Node)); } return(Right.Encapsulate(Elements, Node)); } } else { if (Right.IsScalar) { LinkedList <IElement> Elements = new LinkedList <IElement>(); foreach (IElement LeftChild in Left.ChildElements) { Elements.AddLast(EvaluateMultiplication(LeftChild, Right, Node)); } return(Left.Encapsulate(Elements, Node)); } else { ICollection <IElement> LeftChildren = Left.ChildElements; ICollection <IElement> RightChildren = Right.ChildElements; if (LeftChildren.Count == RightChildren.Count) { LinkedList <IElement> Elements = new LinkedList <IElement>(); IEnumerator <IElement> eLeft = LeftChildren.GetEnumerator(); IEnumerator <IElement> eRight = RightChildren.GetEnumerator(); try { while (eLeft.MoveNext() && eRight.MoveNext()) { Elements.AddLast(EvaluateMultiplication(eLeft.Current, eRight.Current, Node)); } } finally { eLeft.Dispose(); eRight.Dispose(); } return(Left.Encapsulate(Elements, Node)); } else { LinkedList <IElement> LeftResult = new LinkedList <IElement>(); foreach (IElement LeftChild in LeftChildren) { LinkedList <IElement> RightResult = new LinkedList <IElement>(); foreach (IElement RightChild in RightChildren) { RightResult.AddLast(EvaluateMultiplication(LeftChild, RightChild, Node)); } LeftResult.AddLast(Right.Encapsulate(RightResult, Node)); } return(Left.Encapsulate(LeftResult, Node)); } } } }