/// <summary> /// Creates a dimension-index combination generator to be used in the pairwise exploration of a Matrix. /// </summary> /// <param name="numberOfDimensions">Total number of dimensions in the matrix explored.</param> /// <param name="order">The order of overall exploration (2 for pairwise).</param> /// <param name="extendedCoverageDimensionIndexSubsets"> /// Sets of dimension indexes with associated order that should be covered at a higher order. For example, /// a tuple like ({1, 3, 6, 7}, 3) means that all order 3 combinations of the second, fourth, seventh and eighth dimensions should be returned. /// </param> /// <param name="noCoverageGuaranteeDimensionIndexes"> /// The set of dimension indexes that should not be covered - this means that no combinations returned will contain /// any of these indexes. /// </param> /// <returns> /// A combination generator that returns all the combinations of indexes that should be covered in this exploration. /// </returns> public static DimensionIndexCombinationGenerator Create(int numberOfDimensions, int order, IEnumerable<Tuple<ReadOnlyCollection<int>, int>> extendedCoverageDimensionIndexSubsets, IEnumerable<int> noCoverageGuaranteeDimensionIndexes) { DimensionIndexCombinationGenerator basic = new PrimitiveDimensionIndexCombinationGenerator(numberOfDimensions, order); IEnumerable<DimensionIndexCombinationGenerator> underlyingGenerators = Enumerable.Repeat(basic, 1); if (extendedCoverageDimensionIndexSubsets != null) { // Add more combinations to cover the extended-coverage subset. Done for each subset { a0, ..., am } // by generating the combinations for { 0, ..., m } using the PrimitiveDimensionIndexCombinationGenerator, then // translating them into combinations for { a0, ..., am } using the TranslatedDimensionIndexCombinationGenerator. underlyingGenerators = underlyingGenerators.Concat( extendedCoverageDimensionIndexSubsets.Select(s => new TranslatedDimensionIndexCombinationGenerator(new PrimitiveDimensionIndexCombinationGenerator(s.Item1.Count, s.Item2), s.Item1) as DimensionIndexCombinationGenerator ) ); } DimensionIndexCombinationGenerator ret = new CompositeDimensionIndexCombinationGenerator(underlyingGenerators); if (noCoverageGuaranteeDimensionIndexes != null) { // Filter out any combinations that contain any of the indexes of dimensions we don't want to cover. ret = new FilteredDimensionIndexCombinationGenerator(ret, seq => !seq.Intersect(noCoverageGuaranteeDimensionIndexes).Any()); } return ret; }
/// <summary> /// Creates a dimension-index combination generator to be used in the pairwise exploration of a Matrix. /// </summary> /// <param name="numberOfDimensions">Total number of dimensions in the matrix explored.</param> /// <param name="order">The order of overall exploration (2 for pairwise).</param> /// <param name="extendedCoverageDimensionIndexSubsets"> /// Sets of dimension indexes with associated order that should be covered at a higher order. For example, /// a tuple like ({1, 3, 6, 7}, 3) means that all order 3 combinations of the second, fourth, seventh and eighth dimensions should be returned. /// </param> /// <param name="noCoverageGuaranteeDimensionIndexes"> /// The set of dimension indexes that should not be covered - this means that no combinations returned will contain /// any of these indexes. /// </param> /// <returns> /// A combination generator that returns all the combinations of indexes that should be covered in this exploration. /// </returns> public static DimensionIndexCombinationGenerator Create(int numberOfDimensions, int order, IEnumerable <Tuple <ReadOnlyCollection <int>, int> > extendedCoverageDimensionIndexSubsets, IEnumerable <int> noCoverageGuaranteeDimensionIndexes) { DimensionIndexCombinationGenerator basic = new PrimitiveDimensionIndexCombinationGenerator(numberOfDimensions, order); IEnumerable <DimensionIndexCombinationGenerator> underlyingGenerators = Enumerable.Repeat(basic, 1); if (extendedCoverageDimensionIndexSubsets != null) { // Add more combinations to cover the extended-coverage subset. Done for each subset { a0, ..., am } // by generating the combinations for { 0, ..., m } using the PrimitiveDimensionIndexCombinationGenerator, then // translating them into combinations for { a0, ..., am } using the TranslatedDimensionIndexCombinationGenerator. underlyingGenerators = underlyingGenerators.Concat( extendedCoverageDimensionIndexSubsets.Select(s => new TranslatedDimensionIndexCombinationGenerator(new PrimitiveDimensionIndexCombinationGenerator(s.Item1.Count, s.Item2), s.Item1) as DimensionIndexCombinationGenerator ) ); } DimensionIndexCombinationGenerator ret = new CompositeDimensionIndexCombinationGenerator(underlyingGenerators); if (noCoverageGuaranteeDimensionIndexes != null) { // Filter out any combinations that contain any of the indexes of dimensions we don't want to cover. ret = new FilteredDimensionIndexCombinationGenerator(ret, seq => !seq.Intersect(noCoverageGuaranteeDimensionIndexes).Any()); } return(ret); }