Click or drag to resize

IndexPartition Class

Provides static methods for creating index partition objects and for their evaluation in terms of linkage among parts.
Inheritance Hierarchy
SystemObject
  Novacta.AnalyticsIndexPartition

Namespace:  Novacta.Analytics
Assembly:  Novacta.Analytics (in Novacta.Analytics.dll) Version: 2.0.0
Syntax
public static class IndexPartition

The IndexPartition type exposes the following members.

Methods
  NameDescription
Public methodStatic memberCode exampleCreate(DoubleMatrix)
Creates a partition of positions in a collection of Double elements by aggregating those positions occupied by a same element.
Public methodStatic memberCode exampleCreate(DoubleMatrixRowCollection)
Creates a partition of positions in a collection of DoubleMatrixRow elements by aggregating those positions occupied by a same element.
Public methodStatic memberCode exampleCreateT(IEnumerableT)
Creates a partition of positions in a collection of elements by aggregating those positions occupied by a same element.
Public methodStatic memberCode exampleCreateT(IndexCollection, FuncInt32, T)
Creates a partition of the elements in an IndexCollection instance by aggregating those elements corresponding to a same part.
Public methodStatic memberDaviesBouldinIndex
Computes the Davies-Bouldin index to assess the quality of a given partition of the specified data.
Public methodStatic memberDunnIndex
Computes the Dunn index to assess the quality of a given partition of the specified data.
Public methodStatic memberMinimumCentroidLinkage
Computes the minimum centroid linkage among parts in the given partition of the specified data.
Top
Remarks

An index partition is a data structure that has a specific number of parts. Each part is a collection of zero-based indexes represented by an instance of type IndexCollection, and has an identifier whose type is a generic parameter. In its general form, an index partition can be constructed on the base of an IndexCollection instance: each index in the collection is passed to a FuncT, TResult object, which returns a value of type <T>, so that the indexes for which is returned the same value are inserted in the same part having such value as its identifier. This is the way an index partition is built by method CreateT(IndexCollection, FuncInt32, T). However, an index partition is often initialized by inspecting a collection of elements and adding a new part to the partition each time a new element is encountered while iterating over the collection. Such element is the identifier of the new part, which will store the positions, in the collection of elements, where reside values equal to the part identifier. As a consequence, the parts are mutually exclusive subsets of the range of available collection positions.

Instantiation of IndexPartition<T> objects

The IndexPartition class does not itself represent a partition. Instead, it is a class that provides the static method CreateT(IEnumerableT) for creating instances of the IndexPartitionT generic type. It also provides method Create(DoubleMatrix) and its overloaded versions that you can call to instantiate partition objects without having to explicitly specify the type of part identifiers when the type is Double or DoubleMatrixRow.

Partition evaluations

In Cluster Analysis, data collecting individual observations of multiple variables are partitioned in clusters trying to minimize the dissimilarity among clusters, or to maximize the similarity of the individuals in each cluster. To obtain such optimizations, a linkage between two given parts can be defined in terms of the pairwise distances of their observations, and linkage criterions can be applied to evaluate different partitions in the search for the optimal one. Some criterions are exposed in class IndexPartition as methods MinimumMeanLinkage, DunnIndex, and DaviesBouldinIndex.

Examples

In the following example, the row indexes of a matrix are partitioned by the contents of its first column. Each part is identified by a value, the part identifier, and contains the indexes of the rows in which the identifier is positioned in the first column.

Partitioning the rows of a matrix by the contents of one of its columns
using System;

namespace Novacta.Analytics.CodeExamples
{
    public class IndexPartitionExample0  
    {
        public void Main()
        {
            // 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 partition = IndexPartition.Create(matrix[":", 0]);

            // Each part is identified by its corresponding value and contains
            // the indexes of the rows in which the identifier
            // is positioned in column 0.
            Console.WriteLine();
            foreach (var identifier in partition.Identifiers) {
                Console.WriteLine("Part identifier: {0}", identifier);
                Console.WriteLine("     indexes: {0}", partition[identifier]);
                Console.WriteLine();
            }
        }
    }
}

// Executing method Main() produces the following output:
// 
// 
// Part identifier: 0
//      indexes: 0, 1, 2, 3
// 
// Part identifier: 1
//      indexes: 4, 5

In the following example, the row indexes of a matrix are partitioned by the contents of its rows. Each part is identified by a distinct row, the part identifier, and contains the indexes of the rows which are equal to the identifier.

Partitioning the rows of a matrix by their contents
using System;

namespace Novacta.Analytics.CodeExamples
{
    public class IndexPartitionExample1  
    {
        public void Main()
        {
            // 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 partition = IndexPartition.Create(matrix.AsRowCollection());

            // Each part is identified by its corresponding row and contains
            // the indexes of the rows which are equal to the identifier.
            Console.WriteLine();
            foreach (var identifier in partition.Identifiers) {
                Console.WriteLine("Part identifier: {0}", identifier);
                Console.WriteLine("     indexes: {0}", partition[identifier]);
                Console.WriteLine();
            }
        }
    }
}

// Executing method Main() produces the following output:
// 
// 
// Part identifier: 0                0                1                
//      indexes: 0, 1
// 
// Part identifier: 0                1                0                
//      indexes: 2, 3
// 
// Part identifier: 1                0                0                
//      indexes: 4, 5

In the following example, the linear indexes of a matrix are partitioned by the sign of its entries. The part corresponding to zero entries is identified by zero, the part corresponding to positive entries by 1, and the part of negative entries by -1.

Partitioning the linear indexes of a matrix by the sign of its entries
using System;

namespace Novacta.Analytics.CodeExamples
{
    public class IndexPartitionExample2  
    {
        public void Main()
        {
            // 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 partition = 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).
            Console.WriteLine();
            foreach (var identifier in partition.Identifiers) {
                Console.WriteLine("Part identifier: {0}", identifier);
                Console.WriteLine("     indexes: {0}", partition[identifier]);
                Console.WriteLine();
            }
        }
    }
}

// Executing method Main() produces the following output:
// 
// 
// Part identifier: -1
//      indexes: 3, 4, 6
// 
// Part identifier: 0
//      indexes: 0, 1
// 
// Part identifier: 1
//      indexes: 2, 5, 7

In the following example, the indexes of an array of strings are partitioned by their contents.

Partitioning the indexes of an array by its contents
using System;

namespace Novacta.Analytics.CodeExamples
{
    public class IndexPartitionExample3  
    {
        public void Main()
        {
            // Create an array of strings.
            var data = new string[6] {
                "one",
                "two",
                "one",
                "one",
                "three",
                "three"
            };

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

            // The partition contains three parts, identified, respectively,
            // by the strings "one", "two", and "three".
            Console.WriteLine();
            foreach (var identifier in partition.Identifiers) {
                Console.WriteLine("Part identifier: {0}", identifier);
                Console.WriteLine("     indexes: {0}", partition[identifier]);
                Console.WriteLine();
            }
        }
    }
}

// Executing method Main() produces the following output:
// 
// 
// Part identifier: one
//      indexes: 0, 2, 3
// 
// Part identifier: three
//      indexes: 4, 5
// 
// Part identifier: two
//      indexes: 1

In the following example, the linear indexes of the main diagonal of a matrix are partitioned by checking if their corresponding entries are less than 3 in absolute value. Two parts are created, one for diagonal entries less than 3 in absolute value, the other for entries not satisfying that condition.

Partitioning the main diagonal entries of a matrix by their absolute value satisfying a certain condition
using System;

namespace Novacta.Analytics.CodeExamples
{
    public class IndexPartitionExample5  
    {
        public void Main()
        {
            // 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 diagonalIndexes = 
                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 partition = IndexPartition.Create(diagonalIndexes, partitioner);

            // Two parts are created, one for diagonal
            // entries less than 3 in absolute value, the other for 
            // entries not satisfying that condition.
            Console.WriteLine();
            foreach (var identifier in partition.Identifiers) {
                Console.WriteLine("Part identifier: {0}", identifier);
                Console.WriteLine("     indexes: {0}", partition[identifier]);
                Console.WriteLine();
            }
        }
    }
}

// Executing method Main() produces the following output:
// 
// 
// Part identifier: False
//      indexes: 0, 10
// 
// Part identifier: True
//      indexes: 5, 15

See Also