GNU Octave 10.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 
Loading...
Searching...
No Matches
PermMatrix.cc
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////
2//
3// Copyright (C) 2008-2025 The Octave Project Developers
4//
5// See the file COPYRIGHT.md in the top-level directory of this
6// distribution or <https://octave.org/copyright/>.
7//
8// This file is part of Octave.
9//
10// Octave is free software: you can redistribute it and/or modify it
11// under the terms of the GNU General Public License as published by
12// the Free Software Foundation, either version 3 of the License, or
13// (at your option) any later version.
14//
15// Octave is distributed in the hope that it will be useful, but
16// WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18// GNU General Public License for more details.
19//
20// You should have received a copy of the GNU General Public License
21// along with Octave; see the file COPYING. If not, see
22// <https://www.gnu.org/licenses/>.
23//
24////////////////////////////////////////////////////////////////////////
25
26#if defined (HAVE_CONFIG_H)
27# include "config.h"
28#endif
29
30#include "PermMatrix.h"
31#include "idx-vector.h"
32#include "Array-util.h"
33#include "oct-locbuf.h"
34
35OCTAVE_NORETURN static
36void
37err_invalid_permutation ()
38{
39 (*current_liboctave_error_handler) ("PermMatrix: invalid permutation vector");
40}
41
42void
43PermMatrix::setup (const Array<octave_idx_type>& p, bool colp, bool check)
44{
45 if (check)
46 {
47 if (! octave::idx_vector (p).is_permutation (p.numel ()))
48 err_invalid_permutation ();
49 }
50
51 if (! colp)
52 *this = this->transpose ();
53}
54
55PermMatrix::PermMatrix (const Array<octave_idx_type>& p, bool colp, bool check)
57{
58 setup (p, colp, check);
59}
60
61void
62PermMatrix::setup (const octave::idx_vector& idx, bool colp, octave_idx_type n)
63{
64 octave_idx_type len = idx.length (n);
65
66 if (! idx.is_permutation (len))
67 err_invalid_permutation ();
68
70 for (octave_idx_type i = 0; i < len; i++) idxa(i) = idx(i);
72
73 if (! colp)
74 *this = this->transpose ();
75}
76
77PermMatrix::PermMatrix (const octave::idx_vector& idx, bool colp, octave_idx_type n)
79{
80 setup (idx, colp, n);
81}
82
85{
86 for (octave_idx_type i = 0; i < n; i++)
87 xelem (i) = i;
88}
89
92{
94 if (i < 0 || j < 0 || i > len || j > len)
95 (*current_liboctave_error_handler) ("index out of range");
96
97 return elem (i, j);
98}
99
102{
104
105 PermMatrix retval (len);
106
107 for (octave_idx_type i = 0; i < len; ++i)
108 retval.xelem (xelem (i)) = i;
109
110 return retval;
111}
112
115{
116 return transpose ();
117}
118
121{
122 // Determine the sign of a permutation in linear time.
123 // Is this widely known?
124
126 const octave_idx_type *pa = data ();
127
130
131 for (octave_idx_type i = 0; i < len; i++)
132 {
133 p[i] = pa[i];
134 q[p[i]] = i;
135 }
136
137 bool neg = false;
138
139 for (octave_idx_type i = 0; i < len; i++)
140 {
141 octave_idx_type j = p[i];
142 octave_idx_type k = q[i];
143 if (j != i)
144 {
145 p[k] = p[i];
146 q[j] = q[i];
147 neg = ! neg;
148 }
149 }
150
151 return neg ? -1 : 1;
152}
153
156{
157 if (m < 0)
158 return inverse ().pos_power (-m);
159 else if (m > 0)
160 return pos_power (m);
161 else
162 return PermMatrix (rows ());
163}
164
166PermMatrix::pos_power (octave_idx_type m) const
167{
168 octave_idx_type n = rows ();
169
170 const octave_idx_type *p = data ();
171 Array<octave_idx_type> res_pvec (dim_vector (n, 1), -1);
172 octave_idx_type *q = res_pvec.rwdata ();
173
174 for (octave_idx_type ics = 0; ics < n; ics++)
175 {
176 if (q[ics] > 0)
177 continue;
178
179 // go forward m steps or until a cycle is found.
180 octave_idx_type ic, j;
181 for (j = 1, ic = p[ics]; j != m && ic != ics; j++, ic = p[ic]) ;
182 if (ic == ics)
183 {
184 // reduce power.
185 octave_idx_type mm = m % j;
186 // go forward mm steps.
187 for (j = 0, ic = ics; j != mm; j++, ic = p[ic]) ;
188 }
189
190 // now ic = p^m[ics]. Loop through the whole cycle.
191 octave_idx_type jcs = ics;
192 do
193 {
194 q[jcs] = ic;
195 jcs = p[jcs]; ic = p[ic];
196 }
197 while (jcs != ics);
198
199 }
200
201 return PermMatrix (res_pvec, true, false);
202}
203
206{
207 return PermMatrix (n);
208}
209
212{
213 PermMatrix r;
214
215 const Array<octave_idx_type> ia = a.col_perm_vec ();
216 const Array<octave_idx_type> ib = b.col_perm_vec ();
217
218 octave_idx_type n = a.columns ();
219
220 if (n != b.rows ())
221 octave::err_nonconformant ("operator *", n, n, b.rows (), b.rows ());
222
223 r = PermMatrix (ia.index (octave::idx_vector (ib)), true, false);
224
225 return r;
226}
PermMatrix operator*(const PermMatrix &a, const PermMatrix &b)
N Dimensional Array with copy-on-write semantics.
Definition Array.h:130
octave_idx_type & xelem(octave_idx_type n)
Definition Array.h:525
Array< T, Alloc > index(const octave::idx_vector &i) const
Indexing without resizing.
Array< T, Alloc > & operator=(const Array< T, Alloc > &a)
Definition Array.h:365
const octave_idx_type * data() const
Definition Array.h:665
octave_idx_type numel() const
Number of elements in the array.
Definition Array.h:418
octave_idx_type elem(octave_idx_type i, octave_idx_type j) const
Definition PermMatrix.h:87
octave_idx_type rows() const
Definition PermMatrix.h:62
octave_idx_type checkelem(octave_idx_type i, octave_idx_type j) const
Definition PermMatrix.cc:91
PermMatrix()=default
PermMatrix inverse() const
static PermMatrix eye(octave_idx_type n)
octave_idx_type perm_length() const
Definition PermMatrix.h:66
octave_idx_type columns() const
Definition PermMatrix.h:64
octave_idx_type determinant() const
PermMatrix power(octave_idx_type n) const
const Array< octave_idx_type > & col_perm_vec() const
Definition PermMatrix.h:83
PermMatrix transpose() const
Vector representing the dimensions (size) of an Array.
Definition dim-vector.h:90
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
Definition oct-locbuf.h:44
F77_RET_T len
Definition xerbla.cc:61