Arrays/Arraylists Problem

1.This question involves reasoning about one-dimensional and two-dimensional arrays of integers. You will write three static methods, all of which are in a single enclosing class, named DiverseArray (not shown). The first method returns the sum of the values of a one-dimensional array; the second method returns an array that represents the sums of the rows of a two-dimensional array; and the third method analyzes row sums.

(a) Write a static method arraySum that calculates and returns the sum of the entries in a specified one-dimensional array. The following example shows an array arr1 and the value returned by a call to arraySum.

public class DiverseArray {
    
    public static int arraySum (int[] arr) {
        int sum = 0;
        
        for (int i = 0; i < arr.length; i++) {
            sum += arr[i];
        }
        
        return sum;
    }

    public static void main (String args[]) {
        int[] testArray = {1, 3, 2, 7, 3};
        int sum = arraySum(testArray);
        System.out.println("The sum of the numbers in the array is: " + sum);
    }

}

DiverseArray.main(null);
The sum of the numbers in the array is: 16

(b) Write a static method rowSums that calculates the sums of each of the rows in a given two-dimensional array and returns these sums in a one-dimensional array. The method has one parameter, a two-dimensional array arr2D of int values. The array is in row-major order: arr2D[r][c] is the entry at row r and column c. The method returns a one-dimensional array with one entry for each row of arr2D such that each entry is the sum of the corresponding row in arr2D. As a reminder, each row of a two-dimensional array is a one-dimensional array

import java.util.Arrays;

public class DiverseArray {
    
    public static int arraySum (int[] arr) {
        int sum = 0;
        
        for (int i = 0; i < arr.length; i++) {
            sum += arr[i];
        }
        
        return sum;
    }

    public static int[] rowSums (int[][] arr2D) {
        int numRows = arr2D.length;
        int[] summedRows = new int[numRows];

        for (int i = 0; i < numRows; i++) {
            int sumRow = arraySum (arr2D[i]);
            summedRows[i] = sumRow;
        }

        return summedRows;
    }

    public static void main (String args[]) {
        int[][] mat1 = {
            {1, 3, 2, 7, 3},
            {10, 10, 4, 6, 2},
            {5, 3, 5, 9, 6},
            {7, 6, 4, 2, 1}
        };
        
        int[] result = rowSums(mat1);
        System.out.println("The sums of the rows are : " + Arrays.toString(result));
    }
}

DiverseArray.main(null);
The sums of the rows are : [16, 32, 28, 20]

(c) Write a static method isDiverse that determines whether or not a given two-dimensional array is diverse. The method has one parameter: a two-dimensional array arr2D of int values. The method should return true if all the row sums in the given array are unique; otherwise, it should return false. In the arrays shown above, the call isDiverse(mat1) returns true and the call isDiverse(mat2) returns false.

public class DiverseArray {
    
    public static int arraySum (int[] arr) {
        int sum = 0;
        
        for (int i = 0; i < arr.length; i++) {
            sum += arr[i];
        }
        
        return sum;
    }

    public static int[] rowSums (int[][] arr2D) {
        int numRows = arr2D.length;
        int[] summedRows = new int[numRows];

        for (int i = 0; i < numRows; i++) {
            int sumRow = arraySum (arr2D[i]);
            summedRows[i] = sumRow;
        }

        return summedRows;
    }

    public static boolean isDiverse(int[][] arr2D) {
        int[] summedRowArr = rowSums(arr2D);

        for (int i = 0; i < summedRowArr.length; i++) {
            int marker = summedRowArr[i];

            for (int j = i+1; j < summedRowArr.length; j++) {
                if (marker == summedRowArr[j]) {
                    return false;
                }
            }
        }
        return true;
    }

    public static void main (String args[]) {
        int[][] mat1 = {
            {1, 3, 2, 7, 3},
            {10, 10, 4, 6, 2},
            {5, 3, 5, 9, 6},
            {7, 6, 4, 2, 1}
        };

        int[][] mat2 = {
            {1, 1, 5, 3, 4},
            {12, 7, 6, 1, 9},
            {8, 11, 10, 2, 5},
            {3, 2, 3, 0, 6}
        };

        System.out.println("mat1 returns: " + isDiverse(mat1));
        System.out.println("mat2 returns: " + isDiverse(mat2));
    }
}


DiverseArray.main(null);
mat1 returns: true
mat2 returns: false

In Part A, I implemented the arraySum method to calculate the sum of elements in a one-dimensional array. This method was foundational, as it provided a basic yet crucial operation that I could reuse in subsequent parts of the problem.

For Part B, I extended the concept to two-dimensional arrays with the rowSums method. Here, I utilized nested loops to iterate through each row of the 2D array, applying the arraySum method to each row.

Part C, the isDiverse method, was where I integrated the components from Parts A and B to assess a more complex condition: the uniqueness of row sums in a 2D array. This required an understanding of how to compare elements within an array and identify unique values. The solution I developed for this part not only utilized the earlier rowSums method but also involved additional logic to check for uniqueness among sums.

Throughout this FRQ, my focus was on writing clear, efficient code. I relied on iterative loops to navigate through array elements, ensuring that each step of the process was logically sound and adhered to the problem requirements.

for (int iteration = 0; iteration < maxIterations; iteration++) {
    List<Double> predictions = predict(x_train);
    // Update coefficients and intercept
    double interceptGradient = 0.0;
    List<Double> slopeGradients = new ArrayList<>(coefficients.size());

    for (int i = 0; i < slopeGradients.size(); i++) {
        slopeGradients.set(i, 0.0);
    }

    for (int i = 0; i < x_train.size(); i++) {
        double predicted = predictions.get(i);
        interceptGradient += predicted - y_train.get(i);
        for (int j = 0; j < coefficients.size() - 1; j++) {
            slopeGradients.set(j, slopeGradients.get(j) + (predicted - y_train.get(i)) * x_train.get(i));
        }
    }

    intercept -= learningRate * interceptGradient / x_train.size();
    for (int i = 0; i < coefficients.size() - 1; i++) {
        coefficients.set(i, coefficients.get(i) - learningRate * slopeGradients.get(i) / x_train.size());
    }
}

From our Group Final Project, specifically the Logistic Regression Model, the above is an excerpt of code that really showcases the capabilities of ArrayLists in Java. The model is used, in tandem with a linear regressor, to project a player’s stats. The key part of the code that highlights the use of ArrayLists is in the train method, where we update the coefficients and intercept for the regression model. This part is crucial because it iteratively adjusts the model parameters based on the training data to improve the model’s predictions.

In this excerpt, I used ArrayLists to manage and dynamically update the coefficients and slope gradients. Unlike fixed-size arrays, ArrayLists in Java can resize dynamically, which is particularly useful in machine learning contexts like ours where the number of features (and thus coefficients) can vary.

Moreover, the ease of accessing and modifying elements in an ArrayList is demonstrated in this section of the code. Through the use of the get and set methods, I efficiently update the slope gradients and coefficients during each iteration of the training process.

Another significant aspect of using ArrayLists here is their ability to store complex data types, like Double objects in our case. This feature is especially useful in data science and machine learning applications, where handling floating-point numbers is common.