public IntervalSet Operate(IntervalSet operand1, IntervalSet operand2) { if (operand1.Dimension != operand2.Dimension) { throw new ApplicationException("Dimensions don't match"); } //Find all boundaries for both interval sets decimal[] boundaries = IntervalSet.GetAllBoundaries(operand1, operand2); List <BinaryInterval> semiproduct = BuildBinaryInterval(operand1, operand2); //Calculate resulting function for each interval IntervalSet output = new IntervalSet(operand1.Dimension); foreach (BinaryInterval operands in semiproduct) { Operate(operands, ref output); } return(output); }
/// <summary> /// Creates common set of intervals for both operands /// </summary> /// <param name="operand1"></param> /// <param name="operand2"></param> /// <returns></returns> internal static List <BinaryInterval> BuildBinaryInterval(IntervalSet operand1, IntervalSet operand2) { decimal[] boundaries = IntervalSet.GetAllBoundaries(operand1, operand2); List <BinaryInterval> semiproduct = new List <BinaryInterval>(); for (uint i = 0; i < boundaries.Length; i++) { decimal boundary = boundaries[i]; //singleton [boundary, boundary] Interval?singleton1 = operand1.GetExactInterval(boundary, boundary); Interval?singleton2 = operand2.GetExactInterval(boundary, boundary); if (singleton1.HasValue && singleton2.HasValue) { semiproduct.Add(new BinaryInterval(boundary, boundary, singleton1.Value.Coefficients, singleton2.Value.Coefficients)); } else if (singleton1.HasValue && i < (boundaries.Length - 1)) { Interval?range2 = operand2.GetSubinterval(boundary, boundaries[i + 1]); if (range2.HasValue) { semiproduct.Add(new BinaryInterval(boundary, boundary, singleton1.Value.Coefficients, range2.Value.Coefficients)); } } else if (singleton2.HasValue && i < (boundaries.Length - 1)) { Interval?range1 = (operand1.GetSubinterval(boundary, boundaries[i + 1])); semiproduct.Add(new BinaryInterval(boundary, boundary, range1.Value.Coefficients, singleton2.Value.Coefficients)); } else if (singleton1.HasValue) { Interval?range2 = operand2.GetSubinterval(boundary, boundary); semiproduct.Add(new BinaryInterval(boundary, boundary, singleton1.Value.Coefficients, range2.Value.Coefficients)); } else if (singleton2.HasValue) { Interval?range1 = operand1.GetSubinterval(boundary, boundary); semiproduct.Add(new BinaryInterval(boundary, boundary, range1.Value.Coefficients, singleton2.Value.Coefficients)); } //// //range [boundary, boundaries[i+1] ] if (i < (boundaries.Length - 1)) { decimal boundary2 = boundaries[i + 1]; Interval?range1 = operand1.GetSubinterval(boundary, boundaries[i + 1]); Interval?range2 = operand2.GetSubinterval(boundary, boundaries[i + 1]); if (range1.HasValue && range2.HasValue) { semiproduct.Add(new BinaryInterval(boundary, boundary2, range1.Value.Coefficients, range2.Value.Coefficients)); } else if (range1.HasValue) { semiproduct.Add(new BinaryInterval(boundary, boundary2, range1.Value.Coefficients, new decimal[] { 0 })); } else if (range2.HasValue) { semiproduct.Add(new BinaryInterval(boundary, boundary2, new decimal[] { 0 }, range2.Value.Coefficients)); } } //// } return(semiproduct); }