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); }
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); }
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); }
/// <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); }
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); }
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); }
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; }
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)); }
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)); }
//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; }
//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); }
/// <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); }
/// <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; }