Esempio n. 1
0
        /// <summary>
        /// Tries to multiply an element to the current element, from the left.
        /// </summary>
        /// <param name="Element">Element to multiply.</param>
        /// <returns>Result, if understood, null otherwise.</returns>
        public override IRingElement MultiplyLeft(IRingElement Element)
        {
            Complex[,] Values = this.Values;
            ComplexNumber Number = Element as ComplexNumber;
            ComplexMatrix Matrix;

            Complex[,] v;
            Complex n;
            int     x, y, z;

            if (!(Number is null))
            {
                n = Number.Value;
                v = new Complex[this.rows, this.columns];

                for (y = 0; y < this.rows; y++)
                {
                    for (x = 0; x < this.columns; x++)
                    {
                        v[y, x] = n * Values[y, x];
                    }
                }

                return(new ComplexMatrix(v));
            }
Esempio n. 2
0
        /// <summary>
        /// Tries to multiply an element to the current element, from the left.
        /// </summary>
        /// <param name="Element">Element to multiply.</param>
        /// <returns>Result, if understood, null otherwise.</returns>
        public override IRingElement MultiplyLeft(IRingElement Element)
        {
            double[,] Values = this.Values;
            DoubleNumber Number = Element as DoubleNumber;
            DoubleMatrix Matrix;

            double[,] v;
            double n;
            int    x, y, z;

            if (!(Number is null))
            {
                n = Number.Value;
                v = new double[this.rows, this.columns];

                for (y = 0; y < this.rows; y++)
                {
                    for (x = 0; x < this.columns; x++)
                    {
                        v[y, x] = n * Values[y, x];
                    }
                }

                return(new DoubleMatrix(v));
            }
Esempio n. 3
0
        private IElement Evaluate(IElement Element)
        {
            IRingElement E = Operand as IRingElement;

            if (E != null)
            {
                E = E.Invert();
                if (E == null)
                {
                    throw new ScriptRuntimeException("Operand not invertible.", this);
                }
                else
                {
                    return(E);
                }
            }
            else if (E.IsScalar)
            {
                throw new ScriptRuntimeException("Operand not invertible.", this);
            }
            else
            {
                LinkedList <IElement> Elements = new LinkedList <IElement>();

                foreach (IElement E2 in E.ChildElements)
                {
                    Elements.AddLast(this.Evaluate(E2));
                }

                return(E.Encapsulate(Elements, this));
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Evaluates the operator.
        /// </summary>
        /// <param name="Operand">Operand.</param>
        /// <returns>Result</returns>
        public virtual IElement Evaluate(IElement Operand)
        {
            if (Operand is DoubleNumber DOp)
            {
                double d = DOp.Value;
                return(new DoubleNumber(d * d * d));
            }

            if (Operand is IRingElement E)
            {
                IRingElement E2 = (IRingElement)Multiply.EvaluateMultiplication(E, E, this);
                return(Multiply.EvaluateMultiplication(E2, E, this));
            }

            if (Operand.IsScalar)
            {
                throw new ScriptRuntimeException("Scalar operands must be double values or ring elements.", this);
            }

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

            foreach (IElement Child in Operand.ChildElements)
            {
                Result.AddLast(this.Evaluate(Child));
            }

            return(Operand.Encapsulate(Result, this));
        }
Esempio n. 5
0
        /// <summary>
        /// Tries to multiply an element to the current element, from the left.
        /// </summary>
        /// <param name="Element">Element to multiply.</param>
        /// <returns>Result, if understood, null otherwise.</returns>
        public override IRingElement MultiplyLeft(IRingElement Element)
        {
            IElement[,] Values = this.Values;
            ObjectMatrix Matrix;

            IElement[,] v;
            IElement n;
            int      x, y, z;

            if (Element.IsScalar)
            {
                v = new IElement[this.rows, this.columns];

                for (y = 0; y < this.rows; y++)
                {
                    for (x = 0; x < this.columns; x++)
                    {
                        v[y, x] = Operators.Arithmetics.Multiply.EvaluateMultiplication(Element, Values[y, x], null);
                    }
                }

                return(new ObjectMatrix(v));
            }
            else if (!((Matrix = Element as ObjectMatrix) is null))
            {
                if (Matrix.columns != this.rows)
                {
                    return(null);
                }

                IElement[,] Values2 = Matrix.Values;

                v = new IElement[Matrix.rows, this.columns];

                for (y = 0; y < Matrix.rows; y++)
                {
                    for (x = 0; x < this.columns; x++)
                    {
                        n = null;

                        for (z = 0; z < this.rows; z++)
                        {
                            if (n is null)
                            {
                                n = Operators.Arithmetics.Multiply.EvaluateMultiplication(Values2[y, z], Values[z, x], null);
                            }
                            else
                            {
                                n = Operators.Arithmetics.Add.EvaluateAddition(n,
                                                                               Operators.Arithmetics.Multiply.EvaluateMultiplication(Values2[y, z], Values[z, x], null), null);
                            }
                        }

                        v[y, x] = n;
                    }
                }

                return(new ObjectMatrix(v));
            }
Esempio n. 6
0
        /// <summary>
        /// Tries to multiply an element to the current element, from the left.
        /// </summary>
        /// <param name="Element">Element to multiply.</param>
        /// <returns>Result, if understood, null otherwise.</returns>
        public override IRingElement MultiplyLeft(IRingElement Element)
        {
            Complex[,] Values = this.Values;
            ComplexNumber Number = Element as ComplexNumber;
            ComplexMatrix Matrix;

            Complex[,] v;
            Complex n;
            int     x, y, z;

            if (Number != null)
            {
                n = Number.Value;
                v = new Complex[this.rows, this.columns];

                for (y = 0; y < this.rows; y++)
                {
                    for (x = 0; x < this.columns; x++)
                    {
                        v[y, x] = n * Values[y, x];
                    }
                }

                return(new ComplexMatrix(v));
            }
            else if ((Matrix = Element as ComplexMatrix) != null)
            {
                if (Matrix.columns != this.rows)
                {
                    return(null);
                }

                Complex[,] Values2 = Matrix.Values;

                v = new Complex[Matrix.rows, this.columns];
                for (y = 0; y < Matrix.rows; y++)
                {
                    for (x = 0; x < this.columns; x++)
                    {
                        n = 0;

                        for (z = 0; z < this.rows; z++)
                        {
                            n += Values2[y, z] * Values[z, x];
                        }

                        v[y, x] = n;
                    }
                }

                return(new ComplexMatrix(v));
            }
            else
            {
                return(null);
            }
        }
Esempio n. 7
0
        /// <summary>
        /// Tries to multiply an element to the current element, from the right.
        /// </summary>
        /// <param name="Element">Element to multiply.</param>
        /// <returns>Result, if understood, null otherwise.</returns>
        public override IRingElement MultiplyRight(IRingElement Element)
        {
            double[,] Values = this.Values;
            DoubleNumber Number = Element as DoubleNumber;
            DoubleMatrix Matrix;

            double[,] v;
            double n;
            int    x, y, z;

            if (Number != null)
            {
                n = Number.Value;
                v = new double[this.rows, this.columns];

                for (y = 0; y < this.rows; y++)
                {
                    for (x = 0; x < this.columns; x++)
                    {
                        v[y, x] = n * Values[y, x];
                    }
                }

                return(new DoubleMatrix(v));
            }
            else if ((Matrix = Element as DoubleMatrix) != null)
            {
                if (this.columns != Matrix.rows)
                {
                    return(null);
                }

                double[,] Values2 = Matrix.Values;

                v = new double[this.rows, Matrix.columns];
                for (y = 0; y < this.rows; y++)
                {
                    for (x = 0; x < Matrix.columns; x++)
                    {
                        n = 0;

                        for (z = 0; z < this.columns; z++)
                        {
                            n += Values[y, z] * Values2[z, x];
                        }

                        v[y, x] = n;
                    }
                }

                return(new DoubleMatrix(v));
            }
            else
            {
                return(null);
            }
        }
Esempio n. 8
0
        /// <summary>
        /// Divides the right ring element from the left one: Left*(1/Right)
        /// </summary>
        /// <param name="Left">Left element.</param>
        /// <param name="Right">Right element.</param>
        /// <returns>Result, if understood, null otherwise.</returns>
        public override sealed IRingElement RightDivide(IRingElement Left, IRingElement Right)
        {
            ICommutativeRingElement L = Left as ICommutativeRingElement;
            ICommutativeRingElement R = Right as ICommutativeRingElement;

            if (L is null || R is null)
            {
                return(base.RightDivide(Left, Right));
            }
Esempio n. 9
0
 /// <summary>
 /// Performs a scalar multiplication, if possible.
 /// </summary>
 /// <param name="Scalar">Scalar element.</param>
 /// <param name="ModuleElement">Module element.</param>
 /// <returns>Result, if understood, null otherwise.</returns>
 public virtual ILeftModuleElement MultiplyScalarLeft(IRingElement Scalar, ILeftModuleElement ModuleElement)
 {
     if (ModuleElement is IModuleElement E)
     {
         return(this.MultiplyScalar(Scalar, E));
     }
     else
     {
         return(null);
     }
 }
 /// <summary>
 /// Tries to multiply an element to the current element, from the right.
 /// </summary>
 /// <param name="Element">Element to multiply.</param>
 /// <returns>Result, if understood, null otherwise.</returns>
 public override IRingElement MultiplyRight(IRingElement Element)
 {
     if (Element is ICommutativeRingElement E)
     {
         return(this.Multiply(E));
     }
     else
     {
         return(null);
     }
 }
Esempio n. 11
0
 /// <summary>
 /// Tries to multiply a scalar to the current element.
 /// </summary>
 /// <param name="Scalar">Scalar to multiply.</param>
 /// <returns>Result, if understood, null otherwise.</returns>
 public override IModuleElement MultiplyScalar(IRingElement Scalar)
 {
     if (Scalar is IFieldElement FieldElement)
     {
         return(this.MultiplyScalar(FieldElement));
     }
     else
     {
         return(null);
     }
 }
Esempio n. 12
0
        /// <summary>
        /// Tries to multiply an element to the current element, from the right.
        /// </summary>
        /// <param name="Element">Element to multiply.</param>
        /// <returns>Result, if understood, null otherwise.</returns>
        public override IRingElement MultiplyRight(IRingElement Element)
        {
            ICommutativeRingElement E = Element as ICommutativeRingElement;

            if (E == null)
            {
                return(null);
            }
            else
            {
                return(this.Multiply(E));
            }
        }
Esempio n. 13
0
        /// <summary>
        /// Performs a scalar multiplication, if possible.
        /// </summary>
        /// <param name="Scalar">Scalar element.</param>
        /// <param name="ModuleElement">Module element.</param>
        /// <returns>Result, if understood, null otherwise.</returns>
        public virtual ILeftModuleElement MultiplyScalarLeft(IRingElement Scalar, ILeftModuleElement ModuleElement)
        {
            IModuleElement E = ModuleElement as IModuleElement;

            if (E == null)
            {
                return(null);
            }
            else
            {
                return(this.MultiplyScalar(Scalar, E));
            }
        }
        /// <summary>
        /// Tries to multiply a scalar to the current element.
        /// </summary>
        /// <param name="Scalar">Scalar to multiply.</param>
        /// <returns>Result, if understood, null otherwise.</returns>
        public override IModuleElement MultiplyScalar(IRingElement Scalar)
        {
            IFieldElement FieldElement = Scalar as IFieldElement;

            if (FieldElement is null)
            {
                return(null);
            }
            else
            {
                return(this.MultiplyScalar(FieldElement));
            }
        }
Esempio n. 15
0
        /// <summary>
        /// Divides the left ring element from the right one: (1/Left)*Right.
        /// </summary>
        /// <param name="Left">Left element.</param>
        /// <param name="Right">Right element.</param>
        /// <returns>Result, if understood, null otherwise.</returns>
        public virtual IRingElement LeftDivide(IRingElement Left, IRingElement Right)
        {
            IRingElement Inverse = Left.Invert();

            if (Inverse == null)
            {
                return(null);
            }
            else
            {
                return(this.Multiply(Inverse, Right) as IRingElement);
            }
        }
Esempio n. 16
0
        /// <summary>
        /// Divides the right ring element from the left one: Left*(1/Right)
        /// </summary>
        /// <param name="Left">Left element.</param>
        /// <param name="Right">Right element.</param>
        /// <returns>Result, if understood, null otherwise.</returns>
        public override sealed IRingElement RightDivide(IRingElement Left, IRingElement Right)
        {
            ICommutativeRingElement L = Left as ICommutativeRingElement;
            ICommutativeRingElement R = Right as ICommutativeRingElement;

            if (L == null || R == null)
            {
                return(base.RightDivide(Left, Right));
            }
            else
            {
                return(this.Divide(L, R));
            }
        }
Esempio n. 17
0
        /// <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)
        {
            IRingElement E = Argument as IRingElement;

            if (E != null)
            {
                E = E.Invert();
                if (E != null)
                {
                    return(E);
                }
            }

            return(base.Evaluate(Argument, Variables));
        }
Esempio n. 18
0
        /// <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);
            }
        }
Esempio n. 19
0
        /// <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);
        }
Esempio n. 20
0
        /// <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));
                }
            }
        }
Esempio n. 21
0
        /// <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));
                    }
                }
            }
        }
Esempio n. 22
0
 /// <summary>
 /// Divides the right ring element from the left one: Left*(1/Right)
 /// </summary>
 /// <param name="Left">Left element.</param>
 /// <param name="Right">Right element.</param>
 /// <returns>Result, if understood, null otherwise.</returns>
 public override sealed IRingElement RightDivide(IRingElement Left, IRingElement Right)
 {
     if (Left is ICommutativeRingElement L && Right is ICommutativeRingElement R)
     {
         return(this.Divide(L, R));
     }
Esempio n. 23
0
 /// <summary>
 /// Tries to multiply an element to the current element, from the right.
 /// </summary>
 /// <param name="Element">Element to multiply.</param>
 /// <returns>Result, if understood, null otherwise.</returns>
 public override IRingElement MultiplyRight(IRingElement Element)
 {
     return(null);
 }
Esempio n. 24
0
        /// <summary>
        /// Divides the left operand from the right one.
        /// </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 EvaluateDivision(IElement Left, IElement Right, ScriptNode Node)
        {
            IRingElement LE = Left as IRingElement;
            IRingElement RE = Right as IRingElement;
            IElement     Result;
            IRingElement Temp;

            if (LE != null && RE != null)
            {
                // TODO: Optimize in case of matrices. It's more efficient to employ a solve algorithm than to compute the inverse and the multiply.

                Temp = LE.Invert();
                if (Temp != null)
                {
                    Result = RE.MultiplyLeft(Temp);
                    if (Result != null)
                    {
                        return(Result);
                    }

                    Result = Temp.MultiplyRight(RE);
                    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)
                        {
                            Temp = LE.Invert();
                            if (Temp != null)
                            {
                                Result = RE.MultiplyLeft(Temp);
                                if (Result != null)
                                {
                                    return(Result);
                                }

                                Result = Temp.MultiplyRight(RE);
                                if (Result != null)
                                {
                                    return(Result);
                                }
                            }
                        }
                    }

                    throw new ScriptRuntimeException("Operands cannot be divided.", Node);
                }
                else
                {
                    LinkedList <IElement> Elements = new LinkedList <IElement>();

                    foreach (IElement RightChild in Right.ChildElements)
                    {
                        Elements.AddLast(EvaluateDivision(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(EvaluateDivision(LeftChild, Right, Node));
                    }

                    return(Left.Encapsulate(Elements, Node));
                }
                else
                {
                    ISet Set1 = Left as ISet;
                    ISet Set2 = Right as ISet;

                    if (Set1 != null && Set2 != null)
                    {
                        return(new SetDifference(Set1, Set2));
                    }
                    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(EvaluateDivision(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(EvaluateDivision(LeftChild, RightChild, Node));
                                }

                                LeftResult.AddLast(Right.Encapsulate(RightResult, Node));
                            }

                            return(Left.Encapsulate(LeftResult, Node));
                        }
                    }
                }
            }
        }
Esempio n. 25
0
 /// <summary>
 /// Performs a scalar multiplication, if possible.
 /// </summary>
 /// <param name="Scalar">Scalar element.</param>
 /// <param name="ModuleElement">Module element.</param>
 /// <returns>Result, if understood, null otherwise.</returns>
 public abstract ILeftModuleElement MultiplyScalarLeft(IRingElement Scalar, ILeftModuleElement ModuleElement);
Esempio n. 26
0
 /// <summary>
 /// Performs a scalar multiplication, if possible.
 /// </summary>
 /// <param name="ModuleElement">Module element.</param>
 /// <param name="Scalar">Scalar element.</param>
 /// <returns>Result, if understood, null otherwise.</returns>
 public abstract IRightModuleElement MultiplyScalarRight(IRightModuleElement ModuleElement, IRingElement Scalar);
Esempio n. 27
0
 /// <summary>
 /// Performs a scalar multiplication, if possible.
 /// </summary>
 /// <param name="ModuleElement">Module element.</param>
 /// <param name="Scalar">Scalar element.</param>
 /// <returns>Result, if understood, null otherwise.</returns>
 public virtual IModuleElement MultiplyScalar(IRingElement Scalar, IModuleElement ModuleElement)
 {
     return(ModuleElement.MultiplyScalar(Scalar));
 }
Esempio n. 28
0
 /// <summary>
 /// Tries to multiply an element to the current element, from the left.
 /// </summary>
 /// <param name="Element">Element to multiply.</param>
 /// <returns>Result, if understood, null otherwise.</returns>
 public abstract IRingElement MultiplyLeft(IRingElement Element);
Esempio n. 29
0
        /// <summary>
        /// Calculates Left ^ Right.
        /// </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 EvaluatePower(IElement Left, IElement Right, ScriptNode Node)
        {
            DoubleNumber DR = Right as DoubleNumber;

            if (Left is DoubleNumber DL && DR != null)
            {
                return(new DoubleNumber(Math.Pow(DL.Value, DR.Value)));
            }

            if (Left is IRingElement LE && DR != null)
            {
                double d = DR.Value;
                if (d >= long.MinValue && d <= long.MaxValue && Math.Truncate(d) == d)
                {
                    long n = (long)d;

                    if (n < 0)
                    {
                        LE = LE.Invert();
                        if (LE == null)
                        {
                            throw new ScriptRuntimeException("Base element not invertible.", Node);
                        }

                        n = -n;
                    }
                    else if (n == 0)
                    {
                        if (!(LE is ICommutativeRingWithIdentityElement LE2))
                        {
                            throw new ScriptRuntimeException("Base element ring does not have unity.", Node);
                        }

                        return(LE2.One);
                    }

                    IRingElement Result = null;

                    while (n > 0)
                    {
                        if ((n & 1) == 1)
                        {
                            if (Result == null)
                            {
                                Result = LE;
                            }
                            else
                            {
                                Result = (IRingElement)Multiply.EvaluateMultiplication(Result, LE, Node);
                            }
                        }

                        n >>= 1;
                        if (n > 0)
                        {
                            LE = (IRingElement)Multiply.EvaluateMultiplication(LE, LE, Node);
                        }
                    }

                    return(Result);
                }
                else
                {
                    throw new ScriptRuntimeException("Exponent too large.", Node);
                }
            }

            if (Left.IsScalar)
            {
                if (Right.IsScalar)
                {
                    throw new ScriptRuntimeException("Power operation could not be computed.", Node);
                }
                else
                {
                    LinkedList <IElement> Elements = new LinkedList <IElement>();

                    foreach (IElement RightChild in Right.ChildElements)
                    {
                        Elements.AddLast(EvaluatePower(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(EvaluatePower(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(EvaluatePower(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(EvaluatePower(LeftChild, RightChild, Node));
                            }

                            LeftResult.AddLast(Right.Encapsulate(RightResult, Node));
                        }

                        return(Left.Encapsulate(LeftResult, Node));
                    }
                }
            }
        }
Esempio n. 30
0
 /// <summary>
 /// Tries to multiply an element to the current element, from the right.
 /// </summary>
 /// <param name="Element">Element to multiply.</param>
 /// <returns>Result, if understood, null otherwise.</returns>
 public abstract IRingElement MultiplyRight(IRingElement Element);