JMU
Neighborhoods
A Programming Pattern


Prof. David Bernstein
James Madison University

Computer Science Department
bernstdh@jmu.edu


Motivation
Motivation (cont.)

Visualization of an Example Array
images/Neighborhoods_Array.svg

Visualization of an Example Array of Arrays
images/Neighborhoods_Matrix.svg

Review
Thinking About the Problem
The Pattern
Examples
Using an Array
javaexamples/programmingpatterns/Neighborhoods.java (Fragment: 0)
    /**
     * Calculate the average of the elements of the data array that
     * are in a neighborhood (of a given size) of a particular element.
     *
     * @param data  The data array
     * @param index The element in the middle of the neighborhood
     * @param size  The size of the neighborhood (which must be odd)
     * @return The average
     */
    public double naverage(double[] data, int index, int size) {
        double total;
        int    start, stop;

        start = index - size / 2;
        stop  = index + size / 2; // Equivalently: stop = start + size - 1
        total = 0.0;
        for (int i = start; i <= stop; i++) {
            total += data[i];
        }
        return total / (double) size;
    }
        
Examples (cont.)
Using an Array of Arrays
javaexamples/programmingpatterns/Neighborhoods.java (Fragment: 1)
    /**
     * Calculate the average of the elements of the data matrix that
     * are in a square neighborhood (of a given size) of a particular
     * element.
     *
     * @param data  The data array
     * @param row   The row of the element in the center of the neighborhood
     * @param col   The column of the element in the center of the neighborhood
     * @param size  The size of the neighborhood (which must be odd)
     * @return The average
     */
    public double naverage(double[][] data, int row, int col, int size) {
        double total;
        int    cstart, cstop, rstart, rstop;

        rstart = row - size / 2;
        rstop  = row + size / 2;
        cstart = col - size / 2;
        cstop  = col + size / 2;

        total = 0.0;
        for (int r = rstart; r <= rstop; r++) {
            for (int c = cstart; c <= cstop; c++) {
                total += data[r][c];
            }
        }
        return total / (double) (size * size);
    }
        
Examples (cont.)
Using an Array of Arrays - Ignoring the Center Element
javaexamples/programmingpatterns/Neighborhoods.java (Fragment: 3)
    /**
     * Calculate the average of the elements of the data matrix that
     * are in a square neighborhood (of a given size) of a particular
     * element excluding the element at the center of the neighborhood.
     *
     * @param data  The data array
     * @param row   The row of the element in the center of the neighborhood
     * @param col   The column of the element in the center of the neighborhood
     * @param size  The size of the neighborhood (which must be odd)
     * @return The average
     */
    public double xnaverage(double[][] data, int row, int col, int size) {
        double total;
        int    cstart, cstop, rstart, rstop;

        rstart = row - size / 2;
        rstop  = row + size / 2;
        cstart = col - size / 2;
        cstop  = col + size / 2;

        total = 0.0;
        for (int r = rstart; r <= rstop; r++) {
            for (int c = cstart; c <= cstop; c++) {
                if ((row != r) || (col != c)) {
                    total += data[r][c];
                }
            }
        }
        return total / (double) (size * size - 1.0);
    }
        
Examples (cont.)
Using an Array of Arrays - A Plus-Sign-Shaped Neighborhood
javaexamples/programmingpatterns/Neighborhoods.java (Fragment: 2)
    /**
     * Calculate the average of the elements of the data matrix that
     * are in a plus-sign-shaped neighborhood (of a given size) of a
     * particular element.
     *
     * @param data  The data array
     * @param row   The row of the element in the center of the neighborhood
     * @param col   The column of the element in the center of the neighborhood
     * @param size  The size of the neighborhood (which must be odd)
     * @return The average
     */
    public double paverage(double[][] data, int row, int col, int size) {
        double total;
        int    count, cstart, cstop, rstart, rstop;

        rstart = row - size / 2;
        rstop  = row + size / 2;
        cstart = col - size / 2;
        cstop  = col + size / 2;

        total = 0.0;
        count = 0;        
        for (int r = rstart; r <= rstop; r++) {
            total += data[r][col];
            ++count;
        }

        for (int c = cstart; c <= cstop; c++) {
            total += data[row][c];
            ++count;
        }

        // Eliminate the double counting
        total -= data[row][col];
        --count;
        
        return total / (double) count;
    }