public RealSquareMatrix power()

in commons-statistics-inference/src/main/java/org/apache/commons/statistics/inference/SquareMatrixSupport.java [130:189]


        public RealSquareMatrix power(int n) {
            checkExponent(n);
            if (n == 0) {
                return identity();
            }
            if (n == 1) {
                return this;
            }

            // Here at least 1 multiplication occurs.
            // Compute the power by repeat squaring and multiplication:
            // 13 = 1101
            // x^13 = x^8 * x^4 * x^1
            //      = ((x^2 * x)^2)^2 * x
            // 21 = 10101
            // x^21 = x^16 * x^4 * x^1
            //      = (((x^2)^2 * x)^2)^2 * x
            // 1. Find highest set bit in n
            // 2. Initialise result as x
            // 3. For remaining bits (0 or 1) below the highest set bit:
            //    - square the current result
            //    - if the current bit is 1 then multiply by x
            // In this scheme we require 2 matrix array allocations and a column array.

            // Working arrays
            final double[] col = new double[dim];
            double[] b = new double[data.length];
            double[] tmp;

            // Initialise result as A^1.
            final double[] a = data;
            final int ea = exp;
            double[] r = a.clone();
            int er = ea;

            // Shift the highest set bit off the top.
            // Any remaining bits are detected in the sign bit.
            final int shift = Integer.numberOfLeadingZeros(n) + 1;
            int bits = n << shift;

            // Process remaining bits below highest set bit.
            for (int i = 32 - shift; i != 0; i--, bits <<= 1) {
                // Square the result
                er = multiply(r, er, r, er, col, b);
                // Recycle working array
                tmp = b;
                b = r;
                r = tmp;
                if (bits < 0) {
                    // Multiply by A
                    er = multiply(r, er, a, ea, col, b);
                    // Recycle working array
                    tmp = b;
                    b = r;
                    r = tmp;
                }
            }

            return new ArrayRealSquareMatrix(dim, r, er);
        }