public void RunTest()
        {
            // Valid input - Minimization
            {
                var optimizer = new SystemPerformanceOptimizer();

                // Create the context.
                var testableContext =
                    TestablePartitionOptimizationContext00.Get();

                var context = testableContext.Context;

                // Set optimization parameters.
                int    sampleSize = 2000;
                double rarity     = 0.01;

                // Solve the problem.
                var results = optimizer.Optimize(
                    context,
                    rarity,
                    sampleSize);

                Assert.AreEqual(
                    expected: true,
                    actual: results.HasConverged);

                var expectedPartition = IndexPartition.Create(
                    testableContext.OptimalState);

                var actualPartition = IndexPartition.Create(
                    results.OptimalState);

                IndexPartitionAssert.HaveEqualIdentifiers(
                    expected: expectedPartition,
                    actual: actualPartition);

                IndexPartitionAssert.HaveEqualParts(
                    expected: expectedPartition,
                    actual: actualPartition);

                Assert.AreEqual(
                    expected: testableContext.OptimalPerformance,
                    actual: results.OptimalPerformance,
                    DoubleMatrixTest.Accuracy);
            }
        }
Пример #2
0
        public void CreateFromRowCollectionTest()
        {
            // elements is null
            {
                ArgumentExceptionAssert.Throw(
                    () =>
                {
                    var partition = IndexPartition.Create((DoubleMatrixRowCollection)null);
                },
                    expectedType: typeof(ArgumentNullException),
                    expectedPartialMessage: ArgumentExceptionAssert.NullPartialMessage,
                    expectedParameterName: "elements");
            }

            // elements is not null
            {
                // Create a matrix.
                var data = new double[18] {
                    0, 0, 1,
                    0, 0, 1,
                    0, 1, 0,
                    0, 1, 0,
                    1, 0, 0,
                    1, 0, 0
                };
                var matrix = DoubleMatrix.Dense(6, 3, data, StorageOrder.RowMajor);

                // Partition the matrix row indexes by the contents of each row:
                // a part is created for each distinct row.
                var elements = matrix.AsRowCollection();
                var actual   = IndexPartition.Create(elements);

                // Each part is identified by its corresponding row and contains
                // the indexes of the rows which are equal to the identifier.

                // Expected:
                //
                // Part identifier: 0                0                1
                //
                //      indexes: 0, 1
                //
                // Part identifier: 0                1                0
                //
                //      indexes: 2, 3
                //
                // Part identifier: 1                0                0
                //
                //      indexes: 4, 5
                //

                var expected = new IndexPartition <DoubleMatrixRow>
                {
                    partIndetifiers = new List <DoubleMatrixRow>(3)
                    {
                        elements[0],
                        elements[2],
                        elements[4]
                    },

                    parts = new Dictionary <DoubleMatrixRow, IndexCollection>(3)
                    {
                        { elements[0], IndexCollection.Default(1) },
                        { elements[2], IndexCollection.Range(2, 3) },
                        { elements[4], IndexCollection.Range(4, 5) }
                    }
                };

                IndexPartitionAssert.AreEqual(expected, actual);
            }
        }
Пример #3
0
        public void CreateFromIndexCollectionTest()
        {
            // elements is null
            {
                bool partitioner(int linearIndex)
                {
                    return(linearIndex < 3);
                }

                ArgumentExceptionAssert.Throw(
                    () =>
                {
                    var partition = IndexPartition.Create(
                        (IndexCollection)null,
                        partitioner);
                },
                    expectedType: typeof(ArgumentNullException),
                    expectedPartialMessage: ArgumentExceptionAssert.NullPartialMessage,
                    expectedParameterName: "elements");
            }

            // partitioner is null
            {
                Func <int, bool> partitioner = null;

                ArgumentExceptionAssert.Throw(
                    () =>
                {
                    var partition = IndexPartition.Create(
                        IndexCollection.Default(3),
                        partitioner);
                },
                    expectedType: typeof(ArgumentNullException),
                    expectedPartialMessage: ArgumentExceptionAssert.NullPartialMessage,
                    expectedParameterName: "partitioner");
            }

            // Valid parameters
            {
                // Create a matrix.
                var data = new double[16] {
                    -3, 3, 3, -1,
                    0, 2, -2, 2,
                    2, 1, -4, -5,
                    -8, 2, 7, -1
                };
                var matrix = DoubleMatrix.Dense(4, 4, data, StorageOrder.RowMajor);

                // Create the collection of linear indexes corresponding
                // to entries on the matrix main diagonal.
                var elements =
                    IndexCollection.Sequence(0, 1 + matrix.NumberOfRows, matrix.Count);

                // Create a partitioner which returns true if
                // the absolute value in a entry having the specified linear
                // index is less than 3, otherwise false.
                bool partitioner(int linearIndex)
                {
                    return(Math.Abs(matrix[linearIndex]) < 3.0);
                }

                // Partition the diagonal linear indexes through the
                // specified partitioner.
                var actual = IndexPartition.Create(elements, partitioner);

                // Two parts are created, one for diagonal
                // entries less than 3 in absolute value, the other for
                // entries not satisfying that condition.

                // Expected:
                //
                // Part identifier: False
                //      indexes: 0, 10
                //
                // Part identifier: True
                //      indexes: 5, 15
                //
                var expected = new IndexPartition <bool>
                {
                    partIndetifiers = new List <bool>(2)
                    {
                        false,
                        true
                    },

                    parts = new Dictionary <bool, IndexCollection>(2)
                    {
                        { false, IndexCollection.FromArray(new int[2] {
                                0, 10
                            }) },
                        { true, IndexCollection.FromArray(new int[2] {
                                5, 15
                            }) }
                    }
                };

                IndexPartitionAssert.AreEqual(expected, actual);
            }
        }
Пример #4
0
        public void CreateFromEnumerableTest()
        {
            // elements is null
            {
                ArgumentExceptionAssert.Throw(
                    () =>
                {
                    var partition = IndexPartition.Create((string[])null);
                },
                    expectedType: typeof(ArgumentNullException),
                    expectedPartialMessage: ArgumentExceptionAssert.NullPartialMessage,
                    expectedParameterName: "elements");
            }

            // elements is not null
            {
                // Create an array of strings.
                var elements = new string[6] {
                    "one",
                    "two",
                    "one",
                    "one",
                    "three",
                    "three"
                };

                // Partition the array positions by their contents.
                var actual = IndexPartition.Create(elements);

                // The partition contains three parts, identified, respectively,
                // by the strings "one", "two", and "three".

                // Expected:
                //
                // Part identifier: one
                //      indexes: 0, 2, 3
                //
                // Part identifier: three
                //      indexes: 4, 5
                //
                // Part identifier: two
                //      indexes: 1

                var expected = new IndexPartition <string>
                {
                    partIndetifiers = new List <string>(3)
                    {
                        "one",
                        "three",
                        "two"
                    },

                    parts = new Dictionary <string, IndexCollection>(3)
                    {
                        { "one", IndexCollection.FromArray(new int[] { 0, 2, 3 }) },
                        { "three", IndexCollection.Range(4, 5) },
                        { "two", IndexCollection.FromArray(new int[] { 1 }) }
                    }
                };

                IndexPartitionAssert.AreEqual(expected, actual);
            }
        }
Пример #5
0
        public void CreateFromDoubleMatrixTest()
        {
            // elements is null
            {
                ArgumentExceptionAssert.Throw(
                    () =>
                {
                    var partition = IndexPartition.Create((DoubleMatrix)null);
                },
                    expectedType: typeof(ArgumentNullException),
                    expectedPartialMessage: ArgumentExceptionAssert.NullPartialMessage,
                    expectedParameterName: "elements");
            }

            // elements is a vector
            {
                // Create a matrix
                var data = new double[18] {
                    0, 0, 1,
                    0, 0, 1,
                    0, 1, 0,
                    0, 1, 0,
                    1, 0, 0,
                    1, 0, 0
                };
                var matrix = DoubleMatrix.Dense(6, 3, data, StorageOrder.RowMajor);

                // Partition the matrix row indexes by the contents of column 0:
                // a part is created for each distinct value in column 0
                var elements = matrix[":", 0];
                var actual   = IndexPartition.Create(elements);

                // Each part is identified by its corresponding value and contains
                // the indexes of the rows in which the identifier
                // is positioned in column 0

                // Expected:
                //
                // Part identifier: 0
                //      indexes: 0, 1, 2, 3
                //
                // Part identifier: 1
                //      indexes: 4, 5

                IndexPartition <double> expected = new()
                {
                    partIndetifiers = new List <double>(2)
                    {
                        0.0,
                        1.0
                    },

                    parts = new Dictionary <double, IndexCollection>(2)
                    {
                        { 0.0, IndexCollection.Default(3) },
                        { 1.0, IndexCollection.Range(4, 5) }
                    }
                };

                IndexPartitionAssert.AreEqual(expected, actual);
            }

            // elements is a matrix of signs
            {
                // Create a matrix.
                var data = new double[8] {
                    0, 1, -2, -3,
                    0, -1, 2, 3
                };
                var matrix = DoubleMatrix.Dense(2, 4, data, StorageOrder.RowMajor);

                // Check the sign of its entries
                var signs = DoubleMatrix.Dense(matrix.NumberOfRows, matrix.NumberOfColumns);
                for (int i = 0; i < matrix.Count; i++)
                {
                    signs[i] = Math.Sign(matrix[i]);
                }

                // Partition the matrix linear indexes by the sign of each entry
                var actual = IndexPartition.Create(signs);

                // The partition contains three parts, the zero part, identified by 0,
                // the negative part (identified by -1), and the positive one
                // (identified by 1).

                // Expected:
                //
                // Part identifier: -1
                //      indexes: 3, 4, 6
                //
                // Part identifier: 0
                //      indexes: 0, 1
                //
                // Part identifier: 1
                //      indexes: 2, 5, 7
                //

                IndexPartition <double> expected = new()
                {
                    partIndetifiers = new List <double>(3)
                    {
                        -1.0,
                        0.0,
                        1.0
                    },

                    parts = new Dictionary <double, IndexCollection>(3)
                    {
                        { -1.0, IndexCollection.FromArray(new int[] { 3, 4, 6 }) },
                        { 0.0, IndexCollection.Default(1) },
                        { 1.0, IndexCollection.FromArray(new int[] { 2, 5, 7 }) }
                    }
                };

                IndexPartitionAssert.AreEqual(expected, actual);
            }

            // elements is a matrix of data
            {
                // Create a matrix
                var data = new double[6] {
                    1, 3,
                    0, 2,
                    2, 1
                };
                var elements = DoubleMatrix.Dense(3, 2, data, StorageOrder.RowMajor);

                // Partition the matrix linear indexes by the content of
                // matrix entries: a part is created for each distinct matrix value
                var actual = IndexPartition.Create(elements);

                // Each part is identified by its corresponding value and contains
                // the linear indexes of the entries in which the identifier
                // is positioned.

                // This code example produces the following output:
                //
                //
                // Part identifier: 0
                //      indexes: 1
                //
                // Part identifier: 1
                //      indexes: 0, 5
                //
                // Part identifier: 2
                //      indexes: 2, 4
                //
                // Part identifier: 3
                //      indexes: 3
                //

                var expected = new IndexPartition <double>
                {
                    partIndetifiers = new List <double>(3)
                    {
                        0.0,
                        1.0,
                        2.0,
                        3.0
                    },

                    parts = new Dictionary <double, IndexCollection>(3)
                    {
                        { 0.0, IndexCollection.FromArray(new int[] { 1 }) },
                        { 1.0, IndexCollection.FromArray(new int[] { 0, 5 }) },
                        { 2.0, IndexCollection.FromArray(new int[] { 2, 4 }) },
                        { 3.0, IndexCollection.FromArray(new int[] { 3 }) }
                    }
                };

                IndexPartitionAssert.AreEqual(expected, actual);
            }
        }
Пример #6
0
        public void DiscoverTest()
        {
            // data is null
            {
                string parameterName = "data";

                ArgumentExceptionAssert.Throw(
                    () =>
                {
                    Clusters.Discover(
                        data: null,
                        maximumNumberOfParts: 2);
                },
                    expectedType: typeof(ArgumentNullException),
                    expectedPartialMessage:
                    ArgumentExceptionAssert.NullPartialMessage,
                    expectedParameterName: parameterName);
            }

            // maximumNumberOfParts is one
            {
                var STR_EXCEPT_PAR_MUST_BE_GREATER_THAN_VALUE =
                    string.Format(
                        ImplementationServices.GetResourceString(
                            "STR_EXCEPT_PAR_MUST_BE_GREATER_THAN_VALUE"),
                        "1");

                string parameterName = "maximumNumberOfParts";

                ArgumentExceptionAssert.Throw(
                    () =>
                {
                    Clusters.Discover(
                        data: DoubleMatrix.Dense(10, 5),
                        maximumNumberOfParts: 1);
                },
                    expectedType: typeof(ArgumentOutOfRangeException),
                    expectedPartialMessage:
                    STR_EXCEPT_PAR_MUST_BE_GREATER_THAN_VALUE,
                    expectedParameterName: parameterName);
            }

            // maximumNumberOfParts is zero
            {
                var STR_EXCEPT_PAR_MUST_BE_GREATER_THAN_VALUE =
                    string.Format(
                        ImplementationServices.GetResourceString(
                            "STR_EXCEPT_PAR_MUST_BE_GREATER_THAN_VALUE"),
                        "1");

                string parameterName = "maximumNumberOfParts";

                ArgumentExceptionAssert.Throw(
                    () =>
                {
                    Clusters.Discover(
                        data: DoubleMatrix.Dense(10, 5),
                        maximumNumberOfParts: 0);
                },
                    expectedType: typeof(ArgumentOutOfRangeException),
                    expectedPartialMessage:
                    STR_EXCEPT_PAR_MUST_BE_GREATER_THAN_VALUE,
                    expectedParameterName: parameterName);
            }

            // maximumNumberOfParts is negative
            {
                var STR_EXCEPT_PAR_MUST_BE_GREATER_THAN_VALUE =
                    string.Format(
                        ImplementationServices.GetResourceString(
                            "STR_EXCEPT_PAR_MUST_BE_GREATER_THAN_VALUE"),
                        "1");

                string parameterName = "maximumNumberOfParts";

                ArgumentExceptionAssert.Throw(
                    () =>
                {
                    Clusters.Discover(
                        data: DoubleMatrix.Dense(10, 5),
                        maximumNumberOfParts: -1);
                },
                    expectedType: typeof(ArgumentOutOfRangeException),
                    expectedPartialMessage:
                    STR_EXCEPT_PAR_MUST_BE_GREATER_THAN_VALUE,
                    expectedParameterName: parameterName);
            }

            // maximumNumberOfParts is equal to the number of rows in data
            {
                var STR_EXCEPT_PAR_MUST_BE_LESS_THAN_OTHER_ROWS =
                    string.Format(
                        ImplementationServices.GetResourceString(
                            "STR_EXCEPT_PAR_MUST_BE_LESS_THAN_OTHER_ROWS"),
                        "maximumNumberOfParts",
                        "data");

                string parameterName = "maximumNumberOfParts";

                ArgumentExceptionAssert.Throw(
                    () =>
                {
                    Clusters.Discover(
                        data: DoubleMatrix.Dense(10, 5),
                        maximumNumberOfParts: 10);
                },
                    expectedType: typeof(ArgumentException),
                    expectedPartialMessage:
                    STR_EXCEPT_PAR_MUST_BE_LESS_THAN_OTHER_ROWS,
                    expectedParameterName: parameterName);
            }

            // maximumNumberOfParts is greater than the number of rows in data
            {
                var STR_EXCEPT_PAR_MUST_BE_LESS_THAN_OTHER_ROWS =
                    string.Format(
                        ImplementationServices.GetResourceString(
                            "STR_EXCEPT_PAR_MUST_BE_LESS_THAN_OTHER_ROWS"),
                        "maximumNumberOfParts",
                        "data");

                string parameterName = "maximumNumberOfParts";

                ArgumentExceptionAssert.Throw(
                    () =>
                {
                    Clusters.Discover(
                        data: DoubleMatrix.Dense(10, 5),
                        maximumNumberOfParts: 11);
                },
                    expectedType: typeof(ArgumentException),
                    expectedPartialMessage:
                    STR_EXCEPT_PAR_MUST_BE_LESS_THAN_OTHER_ROWS,
                    expectedParameterName: parameterName);
            }

            // Valid input
            {
                const int numberOfItems    = 12;
                const int numberOfFeatures = 7;

                var source = DoubleMatrix.Dense(numberOfItems, 1,
                                                new double[numberOfItems]
                {
                    0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2
                });

                var expectedPartition = IndexPartition.Create(source);
                var data = DoubleMatrix.Dense(numberOfItems, numberOfFeatures);

                double mu = 1.0;

                var partIdentifiers = expectedPartition.Identifiers;

                for (int i = 0; i < partIdentifiers.Count; i++)
                {
                    var part     = expectedPartition[partIdentifiers[i]];
                    int partSize = part.Count;
                    for (int j = 0; j < partSize; j++)
                    {
                        data[part[j], ":"] += mu;
                    }
                    mu += 5.0;
                }

                var actualPartition = Clusters.Discover(
                    data: data,
                    maximumNumberOfParts: 3);

                IndexPartitionAssert.HaveEqualIdentifiers(
                    expected: expectedPartition,
                    actual: actualPartition);

                IndexPartitionAssert.HaveEqualParts(
                    expected: expectedPartition,
                    actual: actualPartition);
            }
        }