Works out the index of the k minimum values in the matrix in a given column - Java java.lang

Java examples for java.lang:Math Matrix

Description

Works out the index of the k minimum values in the matrix in a given column

Demo Code

/*/*from w w  w  . j a v a 2 s .  co  m*/
 *  Java Information Dynamics Toolkit (JIDT)
 *  Copyright (C) 2012, Joseph T. Lizier
 *  
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *  
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
//package com.java2s;

public class Main {
    /**
     * Works out the index of the k minimum values in the matrix in a given column 
     * 
     * @param matrix data
     * @param column which column of the data to find the min values from
     * @param k how many min values to return
     * @return an array of the (row) indices in the array with the k min values,
     *  with closest match first.
     * @throws Exception 
     */
    public static int[] kMinIndices(double[][] matrix, int column, int k)
            throws Exception {
        if (matrix.length < k) {
            throw new Exception(String.format(
                    "Length of array (%d) is less than k (%d)",
                    matrix.length, k));
        }
        // Hold the k minimum elements in strictly increasing order from 0 .. k-1
        double[] mins = new double[k];
        int[] minIndices = new int[k];
        if (k == 1) {
            minIndices[0] = minIndex(matrix, column);
            return minIndices;
        }
        for (int i = 0; i < k; i++) {
            mins[i] = Double.POSITIVE_INFINITY;
            minIndices[i] = -1;
        }
        for (int t = 0; t < matrix.length; t++) {
            // Assume that k is small enough that there is no point doing binary
            //  searches to find the best place to insert this element in the minimums (if required).
            // First check if it's smaller than the current kth min:
            if (matrix[t][column] < mins[k - 1]) {
                mins[k - 1] = matrix[t][column];
                minIndices[k - 1] = t;
                // Now check if we need to reorder the array of minimums, keeping it sorted
                for (int i = k - 2; i >= 0; i--) {
                    if (matrix[t][column] < mins[i]) {
                        // Swap array[t] along from mins[i+1]:
                        mins[i + 1] = mins[i];
                        minIndices[i + 1] = minIndices[i];
                        mins[i] = matrix[t][column];
                        minIndices[i] = t;
                        continue;
                    }
                    // else no need to keep checking the array is sorted correctly
                    break;
                }
            }
        }
        // Return the indices of the k mins
        return minIndices;
    }

    /**
     * Works out the index of the minimum value in the matrix in a given column 
     * 
     * @param matrix
     * @param column
     * @return
     */
    public static int minIndex(double[][] matrix, int column) {
        // double min = 0.0;
        // Allow ArrayIndexOutOfBoundsException if matrix is size 0
        double min = matrix[0][column];
        int minIndex = 0;
        for (int i = 1; i < matrix.length; i++) {
            if (Double.isNaN(min) || (matrix[i][column] < min)) {
                min = matrix[i][column];
                minIndex = i;
            }
        }
        return minIndex;
    }
}

Related Tutorials