/// <summary>
        /// Evaluates the function.
        /// </summary>
        /// <param name="Argument">Function argument.</param>
        /// <param name="Variables">Variables collection.</param>
        /// <returns>Function result.</returns>
        public override IElement Evaluate(IElement Argument, Variables Variables)
        {
            if (Argument is IMatrix Matrix)
            {
                if (Matrix is DoubleMatrix DoubleMatrix)
                {
                    return(this.EvaluateMatrix(DoubleMatrix, Variables));
                }

                if (Matrix is ComplexMatrix ComplexMatrix)
                {
                    return(this.EvaluateMatrix(ComplexMatrix, Variables));
                }

                if (Matrix is BooleanMatrix BooleanMatrix)
                {
                    return(this.EvaluateMatrix(BooleanMatrix, Variables));
                }

                return(this.EvaluateMatrix(Matrix, Variables));
            }
            else
            {
                return(this.EvaluateMatrix((IMatrix)MatrixDefinition.Encapsulate(new IElement[] { Argument }, 1, 1, this), Variables));
            }
        }
Beispiel #2
0
 /// <summary>
 /// Encapsulates a set of elements into a similar structure as that provided by the current element.
 /// </summary>
 /// <param name="Elements">New set of child elements, not necessarily of the same type as the child elements of the current object.</param>
 /// <param name="Node">Script node from where the encapsulation is done.</param>
 /// <returns>Encapsulated object of similar type as the current object.</returns>
 public override IElement Encapsulate(ICollection <IElement> Elements, ScriptNode Node)
 {
     return(MatrixDefinition.Encapsulate(Elements, this.rows, this.columns, Node));
 }
        private IElement EvaluateCanonicalExtension(IElement[] Arguments, Variables Variables)
        {
            ICollection <IElement> ChildElements;

            IEnumerator <IElement>[] e = new IEnumerator <IElement> [this.nrArguments];
            IElement            Argument;
            Encapsulation       Encapsulation = null;
            IMatrix             M;
            ISet                S;
            IVectorSpaceElement V;
            int Dimension = -1;
            int i, j;

            for (i = 0; i < this.nrArguments; i++)
            {
                Argument = Arguments[i];

                switch (this.argumentTypes[i])
                {
                case ArgumentType.Normal:
                    e[i] = null;
                    break;

                case ArgumentType.Scalar:
                    if (Argument.IsScalar)
                    {
                        e[i] = null;
                    }
                    else
                    {
                        ChildElements = Argument.ChildElements;

                        if (Dimension < 0)
                        {
                            Dimension = ChildElements.Count;
                        }
                        else if (ChildElements.Count != Dimension)
                        {
                            throw new ScriptRuntimeException("Argument dimensions not consistent.", this);
                        }

                        e[i] = ChildElements.GetEnumerator();
                        if (Encapsulation == null)
                        {
                            Encapsulation = Argument.Encapsulate;
                        }
                    }
                    break;

                case ArgumentType.Vector:
                    if (Argument is IVectorSpaceElement)
                    {
                        e[i] = null;
                    }
                    else if ((M = Argument as IMatrix) != null)
                    {
                        if (Dimension < 0)
                        {
                            Dimension = M.Rows;
                        }
                        else if (M.Rows != Dimension)
                        {
                            throw new ScriptRuntimeException("Argument dimensions not consistent.", this);
                        }

                        LinkedList <IElement> Vectors = new LinkedList <IElement>();

                        for (j = 0; j < Dimension; j++)
                        {
                            Vectors.AddLast(M.GetRow(j));
                        }

                        e[i] = Vectors.GetEnumerator();
                        if (Encapsulation == null)
                        {
                            Encapsulation = EncapsulateToVector;
                        }
                    }
                    else if ((S = Argument as ISet) != null)
                    {
                        int?Size = S.Size;
                        if (!Size.HasValue)
                        {
                            throw new ScriptRuntimeException("Argument dimensions not consistent.", this);
                        }

                        if (Dimension < 0)
                        {
                            Dimension = Size.Value;
                        }
                        else if (Size.Value != Dimension)
                        {
                            throw new ScriptRuntimeException("Argument dimensions not consistent.", this);
                        }

                        e[i] = S.ChildElements.GetEnumerator();
                        if (Encapsulation == null)
                        {
                            Encapsulation = Argument.Encapsulate;
                        }
                    }
                    else
                    {
                        Arguments[i] = VectorDefinition.Encapsulate(new IElement[] { Argument }, false, this);
                        e[i]         = null;
                    }
                    break;

                case ArgumentType.Set:
                    if (Argument is ISet)
                    {
                        e[i] = null;
                    }
                    else if ((V = Argument as IVectorSpaceElement) != null)
                    {
                        Arguments[i] = SetDefinition.Encapsulate(V.ChildElements, this);
                        e[i]         = null;
                    }
                    else if ((M = Argument as IMatrix) != null)
                    {
                        if (Dimension < 0)
                        {
                            Dimension = M.Rows;
                        }
                        else if (M.Rows != Dimension)
                        {
                            throw new ScriptRuntimeException("Argument dimensions not consistent.", this);
                        }

                        LinkedList <IElement> Vectors = new LinkedList <IElement>();

                        for (j = 0; j < Dimension; j++)
                        {
                            Vectors.AddLast(M.GetRow(j));
                        }

                        Arguments[i]  = Argument = SetDefinition.Encapsulate(Vectors, this);
                        ChildElements = Argument.ChildElements;

                        e[i] = ChildElements.GetEnumerator();
                        if (Encapsulation == null)
                        {
                            Encapsulation = EncapsulateToVector;
                        }
                    }
                    else
                    {
                        Arguments[i] = SetDefinition.Encapsulate(new IElement[] { Argument }, this);
                        e[i]         = null;
                    }
                    break;

                case ArgumentType.Matrix:
                    if (Argument is IMatrix)
                    {
                        e[i] = null;
                    }
                    else if ((V = Argument as IVectorSpaceElement) != null)
                    {
                        Arguments[i] = MatrixDefinition.Encapsulate(V.ChildElements, 1, V.Dimension, this);
                        e[i]         = null;
                    }
                    else if ((S = Argument as ISet) != null)
                    {
                        int?Size = S.Size;
                        if (!Size.HasValue)
                        {
                            throw new ScriptRuntimeException("Argument dimensions not consistent.", this);
                        }

                        if (Dimension < 0)
                        {
                            Dimension = Size.Value;
                        }
                        else if (Size.Value != Dimension)
                        {
                            throw new ScriptRuntimeException("Argument dimensions not consistent.", this);
                        }

                        e[i] = S.ChildElements.GetEnumerator();
                        if (Encapsulation == null)
                        {
                            Encapsulation = Argument.Encapsulate;
                        }
                    }
                    else
                    {
                        Arguments[i] = MatrixDefinition.Encapsulate(new IElement[] { Argument }, 1, 1, this);
                        e[i]         = null;
                    }
                    break;

                default:
                    throw new ScriptRuntimeException("Unhandled argument type.", this);
                }
            }

            if (Encapsulation != null)
            {
                LinkedList <IElement> Result     = new LinkedList <IElement>();
                IElement[]            Arguments2 = new IElement[this.nrArguments];

                for (j = 0; j < Dimension; j++)
                {
                    for (i = 0; i < this.nrArguments; i++)
                    {
                        if (e[i] == null || !e[i].MoveNext())
                        {
                            Arguments2[i] = Arguments[i];
                        }
                        else
                        {
                            Arguments2[i] = e[i].Current;
                        }
                    }

                    Result.AddLast(this.EvaluateCanonicalExtension(Arguments2, Variables));
                }

                return(Encapsulation(Result, this));
            }
            else
            {
                for (i = 0; i < this.nrArguments; i++)
                {
                    Variables[this.argumentNames[i]] = Arguments[i];
                }

                try
                {
                    return(this.op.Evaluate(Variables));
                }
                catch (ScriptReturnValueException ex)
                {
                    return(ex.ReturnValue);
                }
            }
        }