1
\$\begingroup\$

After previous review I chose to alter this project to use lazy evaluation. Looking for any and all improvement feedback.

This project is meant to represent a two dimensional data set, i.e., single-input/single-output data or paired data. I have added every feature I could think a would-be statistician might want, but I am happy to add any more that can be thought of.

package com.glass.wood.statistics;
import java.util.ArrayList;
import java.util.List;

/**
* This class is used to model a data sampled from a standard distribution, and computes several values used
* to analyze the behavior of the population to which the sample belongs.
* The values computed and retained for both input and output are:
*       Mean
*       Min/Max 
*       Sum of Squared Error
*       Mean Squared Error(Variance)
*       Standard Deviation (Standard Error)
*       Sum
*       Square Sum
*Singular Variables are:
*       R correlation
*      Covariance
*       Linear fit equation
*       input*output Product Sum  
* @author wood
*/
public class XYSamples {
    private float size;
    private float xMean, xMin, xMax, xVariance, xError, xSumSquaredError;
    private float yMean, yMin, yMax, yVariance, yError, ySumSquaredError;
    private float xSum, ySum, xySum, x2Sum, y2Sum;
    private float R, covariance;
    private boolean valid;

    private LinearEquation fitFunction;


    //Using List for the AddAll function which is not available to the list object.
    private List<Float> X;
    private List<Float> Y;
    //-------------------------------------------------------------------------------------------------------------
    // Constructors
    // -------------------------------------------------------------------------------------------------------------
    public XYSamples() {
        initSample();
    }

    public XYSamples(List<Float> xData, List<Float> yData) {
        initSample();
        addValues(xData, yData);
    }

    private void initSample(){
        //Initialize Accumulators
        size = 0;
        xSum = 0;
        ySum = 0;
        xySum = 0;
        x2Sum = 0;
        y2Sum = 0;

        //Initialize List
        X = new ArrayList<Float>();
        Y = new ArrayList<Float>();

        //Initialize comparator values
        xMin = Float.MAX_VALUE;
        yMin = Float.MAX_VALUE;
        xMax = -Float.MAX_VALUE;
        yMax = -Float.MAX_VALUE;
    }

    //--------------------------------------------------------------------------------------------------------------
    //      Populate Sample
    //--------------------------------------------------------------------------------------------------------------

    //As the above suggests, the below methods serve to extract values from Lists and add them to the 
    //appropriate input or output list

    /**
     * This method allows the user to add additional values to the existing data set
     * Checks for new max or min now, to avoid iterating through the entire input/output set needlessly,
     * then calls setValues() to recalculate sample analysis
     * @param toAdd
     */
    public void addValues(List<Float> input, List<Float> output) {
        X.addAll(input);
        Y.addAll(output);
        valid = false;
    }
    //-------------------------------------------------------------------------------------------------------------
    //      Basic Analysis
    //-------------------------------------------------------------------------------------------------------------     
    /**
     * s the Sample Mean by creating a running summation of the values and then dividing by the
     * number of values in the set
     * @return double
     */
    private float mean(float sum) {
        return sum / size;
    }

    /**
     * s the Sum of the Squared Error for the sample, which is used to  the variance and 
     * standard error
     * @return double
     */
    private float squaredError(List<Float> data, float mean){
        float temp;
        float tempSum = 0;
        for (float value: data) {
            temp = (float) Math.pow(value - mean, 2);
            tempSum += temp;
        }
        return tempSum;
    }

    /**
     * The sample variance carries a bias of n-1/n, where n is the size of the sample. Multiplying this values 
     * by n/n-1 removes this bias as an estimate of the population variance. This results in the variance 
     * being calculated with n-1 as opposed to n
     * @return double
     */
    private float variance(float sumsquaredError) {
        return sumsquaredError / (size-1);
    }
    /**
     * The covariance carries the same bias as variance, thus we divide by n-
     * @return float
     */
    private float covariance(){
        float runSum = 0;
        for(int i = 0; i < X.size(); i++){
            runSum += (X.get(i) - xMean) * (Y.get(i) - yMean);
        }
        return runSum/(X.size() -1);
    }

    /**
     * As a population estimate, the samples standard error carries a bias of sqrt(n-1.5)/sqrt(n)). Removing
     * this bias, as above with variance, results in calculating with sqrt(n-.5) as the denominator
     * @return
     */
    private float standardError(float sumSquaredError){
        return (float) Math.sqrt(sumSquaredError / (size-1.5));
    }
    //-------------------------------------------------------------------------------------------------------------
    //      Summations
    //-------------------------------------------------------------------------------------------------------------

    //The methods below return summations of the given data

    private float sum(List<Float> data){
        float tempSum = 0;
        for(float item : data){
            tempSum += item;
        }
        return tempSum;
    }

    private float productSum(List<Float> data1, List<Float> data2){
        float tempSum = 0;
        for(int i = 0; i < data1.size(); i++){
            tempSum += (data1.get(i)* data2.get(i));
        }
        return tempSum;
    }

    private float squareSum(List<Float> data){
        float tempSum = 0;
        for(float item: data){
            tempSum += Math.pow(item, 2);
        }
        return tempSum;
    }
    //-------------------------------------------------------------------------------------------------------------
    //      Regression Analysis
    //-------------------------------------------------------------------------------------------------------------     

        //The methods below perform regression on the samples input and output to   linear equation
    //of form Slope*(input) + Intercept = (output). R^2 correlation is returned as a decimal between 0 and 1

    private float correlation(){
        float numerator = (X.size() * xySum) - (xSum * ySum);
        float denominatorLeft = (X.size() * x2Sum) - ((float)Math.pow(xSum, ));
        float denominatorRight = (Y.size() * y2Sum) - ((float)Math.pow(ySum, ));

            return umerator/((float)Math.sqrt(denominatorLeft*denominatorRight));   
    }

    private LinearEquation linearFit(){         
        float slope = slope(xySum, xSum, ySum, x2Sum);
        float intercept = intercept(xySum, xSum, ySum, x2Sum);


        LinearEquation toReturn = new LinearEquation(slope, intercept);
        return toReturn;
    }
    private float slope(float xySum, float xSum, float ySum, float x2Sum) {
        float numerator = (X.size()*xySum) - (xSum*ySum);
        float denominator = (X.size()*x2Sum) - (float)Math.pow(xSum, 2);
        return numerator/denominator;
    }

        private float intercept(float xySum, float xSum, float ySum, float x2Sum) 
        float numerator = (ySum*x2Sum) - (xSum*xySum);
        float denominator = (X.size()*x2Sum) - (float)Math.pow(xSum, 2);
        return numerator/denominator;
    }
    //-------------------------------------------------------------------------------------------------------------
    //      Validate
    //-------------------------------------------------------------------------------------------------------------
    private void validate(){
        if(!valid){
            //Check input minimum and maximum
            float temp;
            for(int i = 0; i < X.size(); i++){
                temp = X.get(i);
                if(temp > xMax){
                    xMax = temp;
                }
                if(temp < xMin){
                    xMin = temp;
                }
            }

            //Check output minimum and maximum
            for(int i = 0; i < Y.size(); i++){
                temp = Y.get(i);
                if(temp > yMax){
                    yMax = temp;
                }
                if(temp < yMin){
                    yMin = temp;
                }
            }

            size = (float)X.size();
            xSum = sum(X);
            ySum = sum(Y);
            x2Sum = squareSum(X);
            y2Sum = squareSum(Y);
            xySum = productSum(X,Y);
            xMean = mean(xSum);
            yMean = mean(ySum);
            xSumSquaredError = squaredError(X, xMean);
            ySumSquaredError = squaredError(Y, yMean);
            xVariance = variance(xSumSquaredError);
            yVariance = variance(ySumSquaredError);
            xError = standardError(xSumSquaredError);
            yError = standardError(ySumSquaredError);
            R = correlation();
            covariance = covariance();
            fitFunction = linearFit();
        }
    }


    //-------------------------------------------------------------------------------------------------------------
    //      Getters
    //-------------------------------------------------------------------------------------------------------------
    public float getSize(){validate(); return size;}
    public float getXMean(){validate(); return xMean;}
    public float getYMean(){validate(); return yMean;}
    public float getXMin(){validate(); return xMin;}
    public float getYMin(){validate(); return yMin;}
    public float getXMax(){validate(); return xMax;}
    public float getYMax(){validate(); return yMax;}
    public float getXVariance(){validate(); return xVariance;}
    public float getYVariance(){validate(); return yVariance;}
    public float getXError(){validate(); return xError;}
    public float getYError(){validate(); return yError;}
    public float getXSumsquaredError(){validate(); return xSumSquaredError;}
    public float getYSumsquaredError(){validate(); return ySumSquaredError;}
    public float getXSum(){validate(); return xSum;}
    public float getYSum(){validate(); return ySum;}
    public float getXSquareSum(){validate(); return x2Sum;}
    public float getYSquareSum(){validate(); return y2Sum;}
    public float getProductSum(){validate(); return xySum;}     
    public float getR(){validate(); return R;}
    public float getRSquare(){validate(); return (float)Math.pow(R,2);}
    public float getCovariance(){validate(); return covariance;}
    public LinearEquation getLinearFit(){validate(); return fitFunction;}
}
```
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.