/// <inheritdoc/>
        public FieldMatrix <T> power(int p)
        {
            if (p < 0)
            {
                throw new NotPositiveException <Int32>(p);
            }

            if (!isSquare())
            {
                throw new NonSquareMatrixException(getRowDimension(), getColumnDimension());
            }

            if (p == 0)
            {
                return(MatrixUtils.createFieldIdentityMatrix(this.getField(), this.getRowDimension()));
            }

            if (p == 1)
            {
                return(this.copy());
            }

            int power = p - 1;

            /*
             * Only log_2(p) operations is used by doing as follows:
             * 5^214 = 5^128 * 5^64 * 5^16 * 5^4 * 5^2
             *
             * In general, the same approach is used for A^p.
             */

            char[]       binaryRepresentation = Convert.ToString(power, 2).ToCharArray();
            List <Int32> nonZeroPositions     = new List <Int32>();

            for (int i = 0; i < binaryRepresentation.Length; ++i)
            {
                if (binaryRepresentation[i] == '1')
                {
                    int pos = binaryRepresentation.Length - i - 1;
                    nonZeroPositions.Add(pos);
                }
            }

            List <FieldMatrix <T> > results = new List <FieldMatrix <T> >(binaryRepresentation.Length);

            results[0] = this.copy();

            for (int i = 1; i < binaryRepresentation.Length; ++i)
            {
                FieldMatrix <T> s = results[i - 1];
                FieldMatrix <T> r = s.multiply(s);
                results[i] = r;
            }

            FieldMatrix <T> result = this.copy();

            foreach (int i in nonZeroPositions)
            {
                result = result.multiply(results[i]);
            }

            return(result);
        }