Exemplo n.º 1
0
        public override AType Execute(AType right, AType left, Aplus environment = null)
        {
            if (left.Rank < 1 || right.Rank < 1)
            {
                throw new Error.Rank(this.RankErrorText);
            }

            if (left.Shape[left.Shape.Count - 1] != right.Shape[0])
            {
                throw new Error.Length(this.LengthErrorText);
            }

            // Calculate the axes for the right argument: (-1 rot iota rho rho right)
            AType targetAxes = DyadicFunctionInstance.Rotate.Execute(
                Enumerable.Range(0, right.Rank).ToAArray(), AInteger.Create(-1), environment);

            AType transposedRight = DyadicFunctionInstance.TransposeAxis.Execute(right, targetAxes, environment);

            AType result = WalkItems(left, transposedRight, environment);

            // by observation it seems that the reference implementation always returns float
            // we behave the same
            result.ConvertToFloat();

            if (result.Length == 0)
            {
                result.Shape = new List <int>(left.Shape.GetRange(0, left.Shape.Count - 1));
                if (right.Shape.Count > 1)
                {
                    result.Shape.AddRange(right.Shape.GetRange(1, right.Shape.Count - 1));
                }
            }

            return(result);
        }
Exemplo n.º 2
0
        public AType Execute(AType function, AType n, AType right, AType left, Aplus environment = null)
        {
            if (!(function.Data is AFunc))
            {
                throw new Error.NonFunction("Rank");
            }

            AFunc func = (AFunc)function.Data;

            if (!func.IsBuiltin)
            {
                if (func.Valence - 1 != 2)
                {
                    throw new Error.Valence("Rank");
                }
            }

            int[]       rankSpecifier = GetRankSpecifier(n, left, right, environment);
            RankJobInfo rankInfo      = new RankJobInfo(rankSpecifier, func);

            AType result = Walker(left, right, environment, rankInfo);

            if (rankInfo.FloatConvert && result.IsArray)
            {
                result.ConvertToFloat();
            }

            return(result);
        }
Exemplo n.º 3
0
        public override AType Execute(AType right, AType left, Aplus environment = null)
        {
            // First we check if one side is an ANull
            if (right.Type == ATypes.ANull)
            {
                return(AArray.Create(left.Type, left.Clone()));
            }
            else if (left.Type == ATypes.ANull)
            {
                return(AArray.Create(right.Type, right.Clone()));
            }

            // Type check
            if (!Utils.IsSameGeneralType(left, right))
            {
                throw new Error.Type(this.TypeErrorText);
            }

            AType result = CreateResult(right, left);

            // Convert to float if one of the arguments is an AFloat and the other is an AInteger
            if (Utils.DifferentNumberType(left, right))
            {
                result.ConvertToFloat();
            }

            return(result);
        }
Exemplo n.º 4
0
        /// <summary>
        /// </summary>
        /// <param name="right"></param>
        /// <param name="left"></param>
        private LaminateJobInfo CreateLaminateJob(AType right, AType left)
        {
            LaminateJobInfo laminateInfo =
                new LaminateJobInfo(left.Length != 0 ? left.Type : right.Type);

            if (left.IsArray && !right.IsArray)
            {
                laminateInfo.Left  = left.Clone();
                laminateInfo.Right = DyadicFunctionInstance.Reshape.Execute(right, left.Shape.ToAArray());
            }
            else if (!left.IsArray && right.IsArray)
            {
                laminateInfo.Right = right.Clone();
                laminateInfo.Left  = DyadicFunctionInstance.Reshape.Execute(left, right.Shape.ToAArray());
            }
            else
            {
                laminateInfo.Right = right.Clone();
                laminateInfo.Left  = left.Clone();
            }

            // check if the types are same

            if (right.Type != left.Type)
            {
                if (left.Type == ATypes.AFloat && right.Type == ATypes.AInteger)
                {
                    right = right.ConvertToFloat();
                }
                else if (left.Type == ATypes.AInteger && right.Type == ATypes.AFloat)
                {
                    left = left.ConvertToFloat();
                }
                else if (!(Utils.IsSameGeneralType(left, right) ||
                           left.Type == ATypes.ANull || right.Type == ATypes.ANull))
                {
                    throw new Error.Type(TypeErrorText);
                }
            }

            // check the length, shape and rank
            if (laminateInfo.Left.Rank != laminateInfo.Right.Rank)
            {
                throw new Error.Rank(RankErrorText);
            }

            if (!laminateInfo.Left.Shape.SequenceEqual(laminateInfo.Right.Shape))
            {
                throw new Error.Length(LengthErrorText);
            }

            if (laminateInfo.Left.Rank >= 9 || laminateInfo.Right.Rank >= 9)
            {
                throw new Error.MaxRank(MaxRankErrorText);
            }

            return(laminateInfo);
        }
Exemplo n.º 5
0
        public override DLR.Expression Generate(AplusScope scope)
        {
            if (this.list.Count == 1)
            {
                return(this.list.First.Value.Generate(scope));
            }

            AType items = null;

            if (this.type == ConstantType.Integer)
            {
                bool convertToFloat = false;
                items = AArray.Create(ATypes.AInteger);
                foreach (Constant item in this.list)
                {
                    AType value = item.AsNumericAType;
                    items.Add(value);

                    if (value.Type == ATypes.AFloat)
                    {
                        convertToFloat = true;
                    }
                }

                // Convert integer items in previous array to float
                if (convertToFloat)
                {
                    items.ConvertToFloat();
                }
            }
            // Treat the Infinite constants same as floats
            else if (this.type == ConstantType.Double ||
                     this.type == ConstantType.PositiveInfinity ||
                     this.type == ConstantType.NegativeInfinity)
            {
                items = AArray.Create(ATypes.AFloat);
                foreach (Constant item in this.list)
                {
                    items.Add(AFloat.Create(item.AsFloat));
                }
            }
            else if (this.type == ConstantType.Symbol)
            {
                items = AArray.Create(ATypes.ASymbol);
                foreach (Constant item in this.list)
                {
                    items.Add(ASymbol.Create(item.AsString));
                }
            }
            else
            {
                throw new Error.Parse(String.Format("Unknow ConstantType({0}) in current context", this.type));
            }

            DLR.Expression result = DLR.Expression.Constant(items, typeof(AType));
            // Example: .Constant<AplusCore.Types.AArray`1[AplusCore.Types.AInteger]>(1 2)
            return(result);
        }
Exemplo n.º 6
0
        protected override AType PostProcess(AType argument, AType result)
        {
            // if there is any float in the integer list, convert the whole list to float
            if (argument.Type == ATypes.AInteger && result.Any(item => item.Type == ATypes.AFloat))
            {
                result.ConvertToFloat();
            }

            return(result);
        }
Exemplo n.º 7
0
        protected override AType PostProcess(AType argument, AType result)
        {
            // if there is any float in the integer list, convert the whole list to float
            if (argument.Type == ATypes.AInteger && result.Any(item => item.Type == ATypes.AFloat))
            {
                result.ConvertToFloat();
            }

            return result;
        }
Exemplo n.º 8
0
        public void Power2Arrays()
        {
            AType expected = this.engine.Execute <AType>("3 4 rho 1 1 1 1 10 100 1000 10000 100 10000 1000000 100000000");

            expected.ConvertToFloat(); // because of whole numbers

            ScriptScope scope = this.engine.CreateScope();

            scope.SetVariable(".y", this.engine.Execute <AType>("1 10 100"));
            scope.SetVariable(".x", this.engine.Execute <AType>("1 2 3 4"));

            AType result = this.engine.Execute <AType>("y ^. x", scope);

            Assert.AreEqual(expected, result);
            Assert.AreEqual(InfoResult.OK, result.CompareInfos(expected));
        }
Exemplo n.º 9
0
        public void InnerProductVsRank()
        {
            ScriptScope scope = this.engine.CreateScope();

            this.engine.Execute <AType>("a pdt b : +/ a * b", scope);
            this.engine.Execute <AType>("y InnerProduct x : y (pdt @ 1 1 0)(-1 rot iota rho rho x) flip x", scope);

            AType expected = AArray.Create(ATypes.AInteger,
                                           AArray.Create(ATypes.AInteger, AInteger.Create(20), AInteger.Create(23), AInteger.Create(26), AInteger.Create(29)),
                                           AArray.Create(ATypes.AInteger, AInteger.Create(56), AInteger.Create(68), AInteger.Create(80), AInteger.Create(92))
                                           );

            AType result_rank = this.engine.Execute <AType>("InnerProduct{iota 2 3; iota 3 4}", scope);
            AType result_ip   = this.engine.Execute <AType>("(iota 2 3) +.* iota 3 4", scope);

            Assert.AreEqual(expected, result_rank);
            Assert.AreEqual(InfoResult.OK, result_rank.CompareInfos(expected));

            expected.ConvertToFloat(); // inner product always returns float

            Assert.AreEqual(expected, result_ip);
            Assert.AreEqual(InfoResult.OK, result_ip.CompareInfos(expected));
        }
Exemplo n.º 10
0
        //If the argument type is integer, the result can be float than
        //we have to convert all items to float.
        protected override AType PostProcess(AType argument, AType result)
        {
            if (argument.Type == ATypes.AInteger)
            {
                bool convert = false;

                foreach (AType item in result)
                {
                    if (item.Type == ATypes.AFloat)
                    {
                        convert = true;
                        break;
                    }
                }

                if (convert)
                {
                    result.ConvertToFloat();
                }
            }

            return result;
        }
Exemplo n.º 11
0
        //If the argument type is integer, the result can be float than
        //we have to convert all items to float.
        protected override AType PostProcess(AType argument, AType result)
        {
            if (argument.Type == ATypes.AInteger)
            {
                bool convert = false;

                foreach (AType item in result)
                {
                    if (item.Type == ATypes.AFloat)
                    {
                        convert = true;
                        break;
                    }
                }

                if (convert)
                {
                    result.ConvertToFloat();
                }
            }

            return(result);
        }
Exemplo n.º 12
0
        /// <summary>
        /// Argument is a nested vector than we: >(0#x), >(1#x),..., >(-1+#x)#x
        /// </summary>
        /// <param name="argument"></param>
        /// <returns></returns>
        private AType NestedVector(AType argument)
        {
            AType result = AArray.Create(ATypes.AArray);

            // disclose the first item of the argument, get type, rank and shape
            AType disclosedItem  = MonadicFunctionInstance.Disclose.Execute(argument[0]);
            AType disclosedArray = disclosedItem.IsArray ? disclosedItem : AArray.Create(disclosedItem.Type, disclosedItem);

            ATypes     type  = disclosedArray.Type;
            int        rank  = disclosedArray.Rank;
            List <int> shape = disclosedArray.Shape;

            bool convertToFloat = false;

            // first Float null item
            bool FloatNull = (disclosedArray.Length == 0 && type == ATypes.AFloat);

            // add first item to the result
            int length = Catenate(disclosedArray, result);

            for (int i = 1; i < argument.Length; i++)
            {
                //Disclose ith item.
                disclosedItem = MonadicFunctionInstance.Disclose.Execute(argument[i]);
                // TODO: do we need these checks?
                disclosedArray = disclosedItem.IsArray ? disclosedItem : AArray.Create(disclosedItem.Type, disclosedItem);

                if (disclosedArray.Length == 0)
                {
                    // skip empty items
                    continue;
                }


                if (type != disclosedArray.Type)
                {
                    // if one item of the argument is Float then all item will be Float
                    // if and only if other items is Integers or Floats.
                    if (type == ATypes.AFloat && disclosedArray.Type == ATypes.AInteger)
                    {
                        if (FloatNull)
                        {
                            type = ATypes.AInteger;
                        }
                        else
                        {
                            convertToFloat = true;
                        }
                    }
                    else if (type == ATypes.AInteger && disclosedArray.Type == ATypes.AFloat)
                    {
                        convertToFloat = true;
                    }
                    else if (type == ATypes.ANull)
                    {
                        type = disclosedArray.Type;
                    }
                    else if (!type.MixedType() || !disclosedArray.MixedType())
                    {
                        // type is differnce so we throw Type error
                        throw new Error.Type(TypeErrorText);
                    }
                }

                FloatNull = false;

                if (rank != disclosedArray.Rank)
                {
                    throw new Error.Rank(RankErrorText);
                }

                // mismatch error arise if actual item has bigger rank than 1 and has a different shape
                if (!shape.SequenceEqual(disclosedArray.Shape))
                {
                    if (shape.Count > 1 || disclosedArray.Shape.Count > 1)
                    {
                        throw new Error.Mismatch(MismatchErrorText);
                    }
                }

                length += Catenate(disclosedArray, result);
            }

            // set result properties
            result.Length = length;
            result.Rank   = rank;
            result.Shape  = new List <int>()
            {
                length
            };
            if (rank > 1)
            {
                result.Shape.AddRange(shape.GetRange(1, shape.Count - 1));
            }

            // convert items to Float, if this flag is true.
            if (convertToFloat)
            {
                result.ConvertToFloat();
            }
            else
            {
                result.Type = type;
            }

            return(result);
        }
Exemplo n.º 13
0
        /// <summary>
        /// </summary>
        /// <param name="right"></param>
        /// <param name="left"></param>
        private LaminateJobInfo CreateLaminateJob(AType right, AType left)
        {
            LaminateJobInfo laminateInfo =
                new LaminateJobInfo(left.Length != 0 ? left.Type : right.Type);
            
            if (left.IsArray && !right.IsArray)
            {
                laminateInfo.Left = left.Clone();
                laminateInfo.Right = DyadicFunctionInstance.Reshape.Execute(right, left.Shape.ToAArray());
            }
            else if (!left.IsArray && right.IsArray)
            {
                laminateInfo.Right = right.Clone();
                laminateInfo.Left = DyadicFunctionInstance.Reshape.Execute(left, right.Shape.ToAArray());
            }
            else
            {
                laminateInfo.Right = right.Clone();
                laminateInfo.Left = left.Clone();
            }

            // check if the types are same

            if (right.Type != left.Type)
            {
                if (left.Type == ATypes.AFloat && right.Type == ATypes.AInteger)
                {
                    right = right.ConvertToFloat();
                }
                else if (left.Type == ATypes.AInteger && right.Type == ATypes.AFloat)
                {
                    left = left.ConvertToFloat();
                }
                else if (!(Utils.IsSameGeneralType(left, right) 
                    || left.Type == ATypes.ANull || right.Type == ATypes.ANull))
                {
                    throw new Error.Type(TypeErrorText);
                }
            }

            // check the length, shape and rank
            if (laminateInfo.Left.Rank != laminateInfo.Right.Rank)
            {
                throw new Error.Rank(RankErrorText);
            }

            if (!laminateInfo.Left.Shape.SequenceEqual(laminateInfo.Right.Shape))
            {
                throw new Error.Length(LengthErrorText);
            }

            if (laminateInfo.Left.Rank >= 9 || laminateInfo.Right.Rank >= 9)
            {
                throw new Error.MaxRank(MaxRankErrorText);
            }

            return laminateInfo;
        }