Mercurial > octave-dspies
diff liboctave/PermMatrix.cc @ 8958:6ccc12cc65ef
implement raising a permutation matrix to integer power
author | Jaroslav Hajek <highegg@gmail.com> |
---|---|
date | Wed, 11 Mar 2009 14:07:24 +0100 |
parents | eb63fbe60fab |
children | 9fba7e1da785 |
line wrap: on
line diff
--- a/liboctave/PermMatrix.cc Wed Mar 11 10:42:04 2009 +0100 +++ b/liboctave/PermMatrix.cc Wed Mar 11 14:07:24 2009 +0100 @@ -118,6 +118,53 @@ } PermMatrix +PermMatrix::power (octave_idx_type m) const +{ + octave_idx_type n = rows (); + bool res_colp = _colp; + if (m < 0) + { + res_colp = ! res_colp; + m = -m; + } + else if (m == 0) + return PermMatrix (n); + + const octave_idx_type *p = data (); + Array<octave_idx_type> res_pvec (n, -1); + octave_idx_type *q = res_pvec.fortran_vec (); + + for (octave_idx_type ics = 0; ics < n; ics++) + { + if (q[ics] > 0) + continue; + + // go forward m steps or until a cycle is found. + octave_idx_type ic, j; + for (j = 1, ic = p[ics]; j != m && ic != ics; j++, ic = p[ic]) ; + if (ic == ics) + { + // reduce power. + octave_idx_type mm = m % j; + // go forward mm steps. + for (j = 0, ic = ics; j != mm; j++, ic = p[ic]) ; + } + + // now ic = p^m[ics]. Loop through the whole cycle. + octave_idx_type jcs = ics; + do + { + q[jcs] = ic; + jcs = p[jcs]; ic = p[ic]; + } + while (jcs != ics); + + } + + return PermMatrix (res_pvec, res_colp, false); +} + +PermMatrix operator *(const PermMatrix& a, const PermMatrix& b) { const Array<octave_idx_type> ia = a.pvec (), ib = b.pvec ();