Esempio n. 1
0
 //TODO
 public double Get(double[,] data1, double[,] data2, int index1, int index2, MatrixAccess access)
 {
     if (access == MatrixAccess.Rows)
     {
         int      n = data1.GetLength(1);
         double[] x = new double[n];
         double[] y = new double[n];
         for (int i = 0; i < n; i++)
         {
             x[i] = data1[index1, i];
             y[i] = data2[index2, i];
         }
         return(Get(x, y));
     }
     else
     {
         int      n = data1.GetLength(0);
         double[] x = new double[n];
         double[] y = new double[n];
         for (int i = 0; i < n; i++)
         {
             x[i] = data1[i, index1];
             y[i] = data2[i, index2];
         }
         return(Get(x, y));
     }
 }
        /// <summary>
        /// Performs a hierarchical clustering on the the given data matrix.
        /// </summary>
        /// <param name="data">Data matrix that is going to be clustered.</param>
        /// <param name="access">Specifies whether rows or columns are to be clustered</param>
        /// <param name="distance">Defines the distance between two elements</param>
        /// <param name="linkage">Specifies the linkage for the clustering.</param>
        /// <param name="preserveOrder"></param>
        /// <param name="periodic"></param>
        /// <param name="nthreads"></param>
        /// <param name="progress"></param>
        /// <returns>An array of cluster nodes defining the resulting tree.</returns>
        public HierarchicalClusterNode[] TreeCluster(MatrixIndexer data, MatrixAccess access, IDistance distance,
			HierarchicalClusterLinkage linkage, bool preserveOrder, bool periodic, int nthreads, Action<int> progress)
        {
            int nelements = (access == MatrixAccess.Rows) ? data.RowCount : data.ColumnCount;
            if (nelements < 2){
                return new HierarchicalClusterNode[0];
            }
            float[,] distMatrix = DistanceMatrix(data, distance, access);
            return TreeCluster(distMatrix, linkage, preserveOrder, periodic, nthreads, progress);
        }
        /// <summary>
        /// Performs a hierarchical clustering on the the given data matrix.
        /// </summary>
        /// <param name="data">Data matrix that is going to be clustered.</param>
        /// <param name="access">Specifies whether rows or columns are to be clustered</param>
        /// <param name="distance">Defines the distance between two elements</param>
        /// <param name="linkage">Specifies the linkage for the clustering.</param>
        /// <param name="preserveOrder"></param>
        /// <param name="periodic"></param>
        /// <param name="nthreads"></param>
        /// <param name="progress"></param>
        /// <returns>An array of cluster nodes defining the resulting tree.</returns>
        public HierarchicalClusterNode[] TreeCluster(MatrixIndexer data, MatrixAccess access, IDistance distance,
                                                     HierarchicalClusterLinkage linkage, bool preserveOrder, bool periodic, int nthreads, Action <int> progress)
        {
            int nelements = (access == MatrixAccess.Rows) ? data.RowCount : data.ColumnCount;

            if (nelements < 2)
            {
                return(new HierarchicalClusterNode[0]);
            }
            float[,] distMatrix = DistanceMatrix(data, distance, access);
            return(TreeCluster(distMatrix, linkage, preserveOrder, periodic, nthreads, progress));
        }
Esempio n. 4
0
        public static bool HasNanOrInf(MatrixIndexer m, MatrixAccess access)
        {
            switch (access)
            {
            case MatrixAccess.Columns:
                return(HasNaNOrInfColumns(m));

            case MatrixAccess.Rows:
                return(HasNaNOrInfRows(m));

            default:
                throw new NotImplementedException($"Not implemented for access {access}");
            }
        }
Esempio n. 5
0
 public double Get(double[,] data1, double[,] data2, int index1, int index2, MatrixAccess access)
 {
     if (access == MatrixAccess.Rows)
     {
         int    n   = data1.GetLength(1);
         int    c   = 0;
         double sum = 0;
         for (int i = 0; i < n; i++)
         {
             double d = data1[index1, i] - data2[index2, i];
             if (!double.IsNaN(d))
             {
                 sum += Math.Abs(d);
                 c++;
             }
         }
         if (c == 0)
         {
             return(double.NaN);
         }
         return(sum / c * n);
     }
     else
     {
         int    n   = data1.GetLength(0);
         int    c   = 0;
         double sum = 0;
         for (int i = 0; i < n; i++)
         {
             double d = data1[i, index1] - data2[i, index2];
             if (!double.IsNaN(d))
             {
                 sum += Math.Abs(d);
                 c++;
             }
         }
         if (c == 0)
         {
             return(double.NaN);
         }
         return(sum / c * n);
     }
 }
Esempio n. 6
0
 public double Get(double[,] data1, double[,] data2, int index1, int index2, MatrixAccess access)
 {
     if (access == MatrixAccess.Rows)
     {
         int    n   = data1.GetLength(1);
         double max = double.MinValue;
         for (int i = 0; i < n; i++)
         {
             double d = data1[index1, i] - data2[index2, i];
             if (double.IsNaN(d) || double.IsInfinity(d))
             {
                 continue;
             }
             double dist = Math.Abs(d);
             if (dist > max)
             {
                 max = dist;
             }
         }
         return(max == double.MinValue ? double.NaN : max);
     }
     else
     {
         int    n   = data1.GetLength(0);
         double max = double.MinValue;
         for (int i = 0; i < n; i++)
         {
             double d = data1[i, index1] - data2[i, index2];
             if (double.IsNaN(d) || double.IsInfinity(d))
             {
                 continue;
             }
             double dist = Math.Abs(d);
             if (dist > max)
             {
                 max = dist;
             }
         }
         return(max == double.MinValue ? double.NaN : max);
     }
 }
Esempio n. 7
0
 public double Get(double[,] data1, double[,] data2, int index1, int index2, MatrixAccess access)
 {
     if (access == MatrixAccess.Rows)
     {
         int    n   = data1.GetLength(1);
         double sum = 0;
         int    c   = 0;
         for (int i = 0; i < n; i++)
         {
             double d = data1[index1, i] - data2[index2, i];
             if (double.IsNaN(d))
             {
                 continue;
             }
             sum += d * d;
             c++;
         }
         return(c == 0 ? double.NaN : Math.Sqrt(sum / c * n));
     }
     else
     {
         int    n   = data1.GetLength(0);
         double sum = 0;
         int    c   = 0;
         for (int i = 0; i < n; i++)
         {
             double d = data1[i, index1] - data2[i, index2];
             if (double.IsNaN(d))
             {
                 continue;
             }
             sum += d * d;
             c++;
         }
         return(c == 0 ? double.NaN : Math.Sqrt(sum / c * n));
     }
 }
 public double Get(double[,] data1, double[,] data2, int index1, int index2, MatrixAccess access)
 {
     if (access == MatrixAccess.Rows){
         int n = data1.GetLength(1);
         double sum = 0;
         int c = 0;
         for (int i = 0; i < n; i++){
             double d = data1[index1, i] - data2[index2, i];
             if (double.IsNaN(d)){
                 continue;
             }
             sum += d*d;
             c++;
         }
         return c == 0 ? double.NaN : Math.Sqrt(sum/c*n);
     } else{
         int n = data1.GetLength(0);
         double sum = 0;
         int c = 0;
         for (int i = 0; i < n; i++){
             double d = data1[i, index1] - data2[i, index2];
             if (double.IsNaN(d)){
                 continue;
             }
             sum += d*d;
             c++;
         }
         return c == 0 ? double.NaN : Math.Sqrt(sum/c*n);
     }
 }
Esempio n. 9
0
 //TODO
 public double Get(double[,] data1, double[,] data2, int index1, int index2, MatrixAccess access)
 {
     if (access == MatrixAccess.Rows){
         int n = data1.GetLength(1);
         double[] x = new double[n];
         double[] y = new double[n];
         for (int i = 0; i < n; i++){
             x[i] = data1[index1, i];
             y[i] = data2[index2, i];
         }
         return Get(x, y);
     } else{
         int n = data1.GetLength(0);
         double[] x = new double[n];
         double[] y = new double[n];
         for (int i = 0; i < n; i++){
             x[i] = data1[i, index1];
             y[i] = data2[i, index2];
         }
         return Get(x, y);
     }
 }
Esempio n. 10
0
 public double Get(double[,] data1, double[,] data2, int index1, int index2, MatrixAccess access)
 {
     if (access == MatrixAccess.Rows){
         int n = data1.GetLength(1);
         int c = 0;
         double sum = 0;
         for (int i = 0; i < n; i++){
             double d = data1[index1, i] - data2[index2, i];
             if (!double.IsNaN(d)){
                 sum += Math.Abs(d);
                 c++;
             }
         }
         if (c == 0){
             return double.NaN;
         }
         return sum/c*n;
     } else{
         int n = data1.GetLength(0);
         int c = 0;
         double sum = 0;
         for (int i = 0; i < n; i++){
             double d = data1[i, index1] - data2[i, index2];
             if (!double.IsNaN(d)){
                 sum += Math.Abs(d);
                 c++;
             }
         }
         if (c == 0){
             return double.NaN;
         }
         return sum/c*n;
     }
 }
        public HierarchicalClusterNode[] TreeClusterKmeans(MatrixIndexer data, MatrixAccess access, IDistance distance,
			HierarchicalClusterLinkage linkage, bool preserveOrder, bool periodic, int nthreads, int nmeans, int restarts,
			int maxIter, Action<int> progress)
        {
            int nelements = (access == MatrixAccess.Rows) ? data.RowCount : data.ColumnCount;
            if (nelements <= nmeans){
                return TreeCluster(data, access, distance, linkage, preserveOrder, periodic, nthreads, progress);
            }
            float[,] c;
            int[] inds;
            if (access == MatrixAccess.Rows){
                KmeansClustering.GenerateClusters(data, nmeans, maxIter, restarts, progress, out c, out inds);
            } else{
                KmeansClustering.GenerateClusters(data.Transpose(), nmeans, maxIter, restarts, progress, out c, out inds);
            }
            float[,] distMatrix = DistanceMatrix(new FloatMatrixIndexer(c), distance, MatrixAccess.Rows);
            HierarchicalClusterNode[] nodes = TreeCluster(distMatrix, linkage, preserveOrder, periodic, nthreads, progress);
            Dictionary<int, int[]> clusters;
            Dictionary<int, int> singletons;
            RearrangeClusters(inds, c.GetLength(0), out clusters, out singletons);
            HierarchicalClusterNode[] newNodes = new HierarchicalClusterNode[nelements - 1];
            int fill = nelements - nmeans;
            Array.Copy(nodes, 0, newNodes, fill, nodes.Length);
            int pos = 0;
            for (int i = fill; i < newNodes.Length; i++){
                HierarchicalClusterNode node = newNodes[i];
                if (node.left < 0){
                    node.left -= fill;
                } else if (singletons.ContainsKey(node.left)){
                    node.left = singletons[node.left];
                } else{
                    if (clusters.ContainsKey(node.left)){
                        HierarchicalClusterNode[] branch = FillTerminalBranch(clusters[node.left], pos);
                        Array.Copy(branch, 0, newNodes, pos, branch.Length);
                        pos += branch.Length;
                        node.left = -pos;
                    }
                }
                if (node.right < 0){
                    node.right -= fill;
                } else if (singletons.ContainsKey(node.right)){
                    node.right = singletons[node.right];
                } else{
                    if (clusters.ContainsKey(node.right)){
                        HierarchicalClusterNode[] branch = FillTerminalBranch(clusters[node.right], pos);
                        Array.Copy(branch, 0, newNodes, pos, branch.Length);
                        pos += branch.Length;
                        node.right = -pos;
                    }
                }
            }
            return newNodes;
        }
 private static float[,] DistanceMatrix(MatrixIndexer data, IDistance distance, MatrixAccess access)
 {
     int nrows = data.RowCount;
     int ncols = data.ColumnCount;
     int nelements = (access == MatrixAccess.Rows) ? nrows : ncols;
     float[,] result = new float[nelements, nelements];
     for (int i = 0; i < nelements; i++){
         for (int j = 0; j < i; j++){
             result[i, j] = (float) distance.Get(GetVector(data, i, access), GetVector(data, j, access));
         }
     }
     return result;
 }
        public HierarchicalClusterNode[] TreeClusterKmeans(MatrixIndexer data, MatrixAccess access, IDistance distance,
                                                           HierarchicalClusterLinkage linkage, bool preserveOrder, bool periodic, int nthreads, int nmeans, int restarts,
                                                           int maxIter, Action <int> progress)
        {
            int nelements = (access == MatrixAccess.Rows) ? data.RowCount : data.ColumnCount;

            if (nelements <= nmeans)
            {
                return(TreeCluster(data, access, distance, linkage, preserveOrder, periodic, nthreads, progress));
            }
            float[,] c;
            int[] inds;
            if (access == MatrixAccess.Rows)
            {
                KmeansClustering.GenerateClusters(data, nmeans, maxIter, restarts, progress, out c, out inds);
            }
            else
            {
                KmeansClustering.GenerateClusters(data.Transpose(), nmeans, maxIter, restarts, progress, out c, out inds);
            }
            float[,] distMatrix = DistanceMatrix(new FloatMatrixIndexer(c), distance, MatrixAccess.Rows);
            HierarchicalClusterNode[] nodes = TreeCluster(distMatrix, linkage, preserveOrder, periodic, nthreads, progress);
            Dictionary <int, int[]>   clusters;
            Dictionary <int, int>     singletons;

            RearrangeClusters(inds, c.GetLength(0), out clusters, out singletons);
            HierarchicalClusterNode[] newNodes = new HierarchicalClusterNode[nelements - 1];
            int fill = nelements - nmeans;

            Array.Copy(nodes, 0, newNodes, fill, nodes.Length);
            int pos = 0;

            for (int i = fill; i < newNodes.Length; i++)
            {
                HierarchicalClusterNode node = newNodes[i];
                if (node.left < 0)
                {
                    node.left -= fill;
                }
                else if (singletons.ContainsKey(node.left))
                {
                    node.left = singletons[node.left];
                }
                else
                {
                    if (clusters.ContainsKey(node.left))
                    {
                        HierarchicalClusterNode[] branch = FillTerminalBranch(clusters[node.left], pos);
                        Array.Copy(branch, 0, newNodes, pos, branch.Length);
                        pos      += branch.Length;
                        node.left = -pos;
                    }
                }
                if (node.right < 0)
                {
                    node.right -= fill;
                }
                else if (singletons.ContainsKey(node.right))
                {
                    node.right = singletons[node.right];
                }
                else
                {
                    if (clusters.ContainsKey(node.right))
                    {
                        HierarchicalClusterNode[] branch = FillTerminalBranch(clusters[node.right], pos);
                        Array.Copy(branch, 0, newNodes, pos, branch.Length);
                        pos       += branch.Length;
                        node.right = -pos;
                    }
                }
            }
            return(newNodes);
        }
 private static BaseVector GetVector(MatrixIndexer data, int index, MatrixAccess access)
 {
     return(access == MatrixAccess.Rows ? data.GetRow(index) : data.GetColumn(index));
 }
        private static float[,] DistanceMatrix(MatrixIndexer data, IDistance distance, MatrixAccess access)
        {
            int nrows     = data.RowCount;
            int ncols     = data.ColumnCount;
            int nelements = (access == MatrixAccess.Rows) ? nrows : ncols;

            float[,] result = new float[nelements, nelements];
            for (int i = 0; i < nelements; i++)
            {
                for (int j = 0; j < i; j++)
                {
                    result[i, j] = (float)distance.Get(GetVector(data, i, access), GetVector(data, j, access));
                }
            }
            return(result);
        }
Esempio n. 16
0
 public double Get(double[,] data1, double[,] data2, int index1, int index2, MatrixAccess access)
 {
     if (access == MatrixAccess.Rows){
         int n = data1.GetLength(1);
         double max = double.MinValue;
         for (int i = 0; i < n; i++){
             double d = data1[index1, i] - data2[index2, i];
             if (double.IsNaN(d) || double.IsInfinity(d)){
                 continue;
             }
             double dist = Math.Abs(d);
             if (dist > max){
                 max = dist;
             }
         }
         return max == double.MinValue ? double.NaN : max;
     } else{
         int n = data1.GetLength(0);
         double max = double.MinValue;
         for (int i = 0; i < n; i++){
             double d = data1[i, index1] - data2[i, index2];
             if (double.IsNaN(d) || double.IsInfinity(d)){
                 continue;
             }
             double dist = Math.Abs(d);
             if (dist > max){
                 max = dist;
             }
         }
         return max == double.MinValue ? double.NaN : max;
     }
 }
 private static BaseVector GetVector(MatrixIndexer data, int index, MatrixAccess access)
 {
     return access == MatrixAccess.Rows ? data.GetRow(index) : data.GetColumn(index);
 }