Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Performance improvements in Matrix.java and MatrixMath.java #1

Closed
OliverColeman opened this issue Jul 13, 2011 · 2 comments
Closed
Assignees
Milestone

Comments

@OliverColeman
Copy link

Hi there,

Was just poking through the code and noticed that the performance of the MatrixMath.dotProduct method isn't as good as it could be for two reasons: it creates copies of arrays unnecessarily using the Matrix.toPackedArray method, and the Matrix.toPackedArray method actually returns arrays of type Double rather than double.

On my machine (Intel i7, Ubuntu 11.04, Sun Java 1.6) the following alternate method runs between 10 and 14 times faster (the double/Double and array copying contribute approximately equally to the performance difference):

    public static double dotProduct2(final Matrix a, final Matrix b) {
        if (!a.isVector() || !b.isVector()) {
            throw new MatrixError("To take the dot product, both matrices must be vectors.");
        }

        final double[][] aArray = a.getData();
        final double[][] bArray = b.getData();

        final int aLength = aArray.length == 1 ? aArray[0].length : aArray.length;
        final int bLength = bArray.length == 1 ? bArray[0].length : bArray.length;

        if (aLength != bLength) {
            throw new MatrixError("To take the dot product, both matrices must be of the same length.");
        }

        double result = 0;
        if (aArray.length == 1 && bArray.length == 1) {
            for (int i = 0; i < aLength; i++) {
                result += aArray[0][i] * bArray[0][i];
            }
        }
        else if (aArray.length == 1 && bArray[0].length == 1) {
            for (int i = 0; i < aLength; i++) {
                result += aArray[0][i] * bArray[i][0];
            }
        }
        else if (aArray[0].length == 1 && bArray.length == 1) {
            for (int i = 0; i < aLength; i++) {
                result += aArray[i][0] * bArray[0][i];
            }
        }
        else if (aArray[0].length == 1 && bArray[0].length == 1) {
            for (int i = 0; i < aLength; i++) {
                result += aArray[i][0] * bArray[i][0];
            }
        }

        return result;
    }
@OliverColeman
Copy link
Author

Perhaps the bigger issue is Matrix.toPackedArray returning a Double[] rather than double[]. It's only called 4 times from within core, and no times in the workbench (didn't check other packages).

@jeffheaton
Copy link
Owner

Thanks for the code! I will take a look. As to the toPackedArray method, I will look at where it is called from. It used Double, a long time ago, because it was used by the genetic algorithms that placed them into a List. That code has since "evolved" int something better. So I am not sure toPackedArray has any reason to still use Double. I will take a look.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants