GNU Octave  9.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
boolSparse.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 1998-2024 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 <istream>
31 #include <ostream>
32 #include <vector>
33 
34 #include "quit.h"
35 #include "lo-ieee.h"
36 #include "lo-mappers.h"
37 
38 #include "boolSparse.h"
39 #include "dSparse.h"
40 #include "oct-locbuf.h"
41 
42 #include "Sparse-op-defs.h"
43 
44 // SparseBoolMatrix class.
45 
46 bool
48 {
49  octave_idx_type nr = rows ();
50  octave_idx_type nc = cols ();
51  octave_idx_type nz = nnz ();
52  octave_idx_type nr_a = a.rows ();
53  octave_idx_type nc_a = a.cols ();
54  octave_idx_type nz_a = a.nnz ();
55 
56  if (nr != nr_a || nc != nc_a || nz != nz_a)
57  return false;
58 
59  for (octave_idx_type i = 0; i < nc + 1; i++)
60  if (cidx (i) != a.cidx (i))
61  return false;
62 
63  for (octave_idx_type i = 0; i < nz; i++)
64  if (data (i) != a.data (i) || ridx (i) != a.ridx (i))
65  return false;
66 
67  return true;
68 }
69 
70 bool
72 {
73  return !(*this == a);
74 }
75 
79 {
80  Sparse<bool>::insert (a, r, c);
81  return *this;
82 }
83 
86  const Array<octave_idx_type>& indx)
87 {
88  Sparse<bool>::insert (a, indx);
89  return *this;
90 }
91 
95 {
96  // Don't use numel to avoid all possibility of an overflow
97  if (rb.rows () > 0 && rb.cols () > 0)
98  insert (rb, ra_idx(0), ra_idx(1));
99  return *this;
100 }
101 
102 // unary operations
103 
106 {
107  octave_idx_type nr = rows ();
108  octave_idx_type nc = cols ();
109  octave_idx_type nz1 = nnz ();
110  octave_idx_type nz2 = nr*nc - nz1;
111 
112  SparseBoolMatrix r (nr, nc, nz2);
113 
114  octave_idx_type ii = 0;
115  octave_idx_type jj = 0;
116  r.cidx (0) = 0;
117  for (octave_idx_type i = 0; i < nc; i++)
118  {
119  for (octave_idx_type j = 0; j < nr; j++)
120  {
121  if (jj < cidx (i+1) && ridx (jj) == j)
122  jj++;
123  else
124  {
125  r.data (ii) = true;
126  r.ridx (ii++) = j;
127  }
128  }
129  r.cidx (i+1) = ii;
130  }
131 
132  return r;
133 }
134 
135 // other operations
136 
137 // FIXME: Do these really belong here? Maybe they should be in a base class?
138 
140 SparseBoolMatrix::all (int dim) const
141 {
142  SPARSE_ALL_OP (dim);
143 }
144 
146 SparseBoolMatrix::any (int dim) const
147 {
148  Sparse<bool> retval;
149  octave_idx_type nr = rows ();
150  octave_idx_type nc = cols ();
151  octave_idx_type nz = nnz ();
152  if (dim == -1)
153  dim = (nr == 1 && nc != 1) ? 1 : 0;
154 
155  if (dim == 0)
156  {
157  // Result is a row vector.
158  retval = Sparse<bool> (1, nc);
159  retval.xcidx (0) = 0;
160  for (octave_idx_type i = 0; i < nc; i++)
161  retval.xcidx (i+1) = retval.xcidx (i) + (cidx (i+1) > cidx (i));
162  octave_idx_type new_nz = retval.xcidx (nc);
163  retval.change_capacity (new_nz);
164  std::fill_n (retval.ridx (), new_nz, static_cast<octave_idx_type> (0));
165  std::fill_n (retval.data (), new_nz, true);
166  }
167  else if (dim == 1)
168  {
169  // Result is a column vector.
170  if (nz > nr/4)
171  {
172  // We can use O(nr) memory.
173  Array<bool> tmp (dim_vector (nr, 1), false);
174  for (octave_idx_type i = 0; i < nz; i++)
175  tmp.xelem (ridx (i)) = true;
176  retval = tmp;
177  }
178  else
179  {
180  Array<octave_idx_type> tmp (dim_vector (nz, 1));
181  std::copy_n (ridx (), nz, tmp.fortran_vec ());
182  retval = Sparse<bool> (Array<bool> (dim_vector (1, 1), true),
183  octave::idx_vector (tmp),
184  octave::idx_vector (0), nr, 1, false);
185  }
186  }
187 
188  return retval;
189 }
190 
192 SparseBoolMatrix::sum (int dim) const
193 {
194  Sparse<double> retval;
195  octave_idx_type nr = rows ();
196  octave_idx_type nc = cols ();
197  octave_idx_type nz = nnz ();
198  if (dim == -1)
199  dim = (nr == 1 && nc != 1) ? 1 : 0;
200 
201  if (dim == 0)
202  {
203  // Result is a row vector.
204  retval = Sparse<double> (1, nc);
205  for (octave_idx_type i = 0; i < nc; i++)
206  retval.xcidx (i+1) = retval.xcidx (i) + (cidx (i+1) > cidx (i));
207  octave_idx_type new_nz = retval.xcidx (nc);
208  retval.change_capacity (new_nz);
209  std::fill_n (retval.ridx (), new_nz, static_cast<octave_idx_type> (0));
210  for (octave_idx_type i = 0, k = 0; i < nc; i++)
211  {
212  octave_idx_type c = cidx (i+1) - cidx (i);
213  if (c > 0)
214  retval.xdata (k++) = c;
215  }
216  }
217  else if (dim == 1)
218  {
219  // Result is a column vector.
220  if (nz > nr)
221  {
222  // We can use O(nr) memory.
223  Array<double> tmp (dim_vector (nr, 1), 0);
224  for (octave_idx_type i = 0; i < nz; i++)
225  tmp.xelem (ridx (i)) += 1.0;
226  retval = tmp;
227  }
228  else
229  {
230  Array<octave_idx_type> tmp (dim_vector (nz, 1));
231  std::copy_n (ridx (), nz, tmp.fortran_vec ());
232  retval = Sparse<double> (Array<double> (dim_vector (1, 1), 1.0),
233  octave::idx_vector (tmp),
234  octave::idx_vector (0), nr, 1);
235  }
236  }
237 
238  return retval;
239 }
240 
243 {
244  return Sparse<bool>::diag (k);
245 }
246 
249 {
250  octave_idx_type nr = rows ();
251  octave_idx_type nc = cols ();
252 
253  boolMatrix retval (nr, nc, false);
254  for (octave_idx_type j = 0; j < nc; j++)
255  for (octave_idx_type i = cidx (j); i < cidx (j+1); i++)
256  retval.elem (ridx (i), j) = data (i);
257 
258  return retval;
259 }
260 
261 std::ostream&
262 operator << (std::ostream& os, const SparseBoolMatrix& a)
263 {
264  octave_idx_type nc = a.cols ();
265 
266  // add one to the printed indices to go from
267  // zero-based to one-based arrays
268  for (octave_idx_type j = 0; j < nc; j++)
269  {
270  octave_quit ();
271  for (octave_idx_type i = a.cidx (j); i < a.cidx (j+1); i++)
272  os << a.ridx (i) + 1 << ' ' << j + 1 << ' ' << a.data (i) << "\n";
273  }
274 
275  return os;
276 }
277 
278 std::istream&
279 operator >> (std::istream& is, SparseBoolMatrix& a)
280 {
281  typedef SparseBoolMatrix::element_type elt_type;
282 
283  return read_sparse_matrix<elt_type> (is, a, octave::read_value<bool>);
284 }
285 
288 {
289  return Sparse<bool>::squeeze ();
290 }
291 
293 SparseBoolMatrix::index (const octave::idx_vector& i, bool resize_ok) const
294 {
295  return Sparse<bool>::index (i, resize_ok);
296 }
297 
300  bool resize_ok) const
301 {
302  return Sparse<bool>::index (i, j, resize_ok);
303 }
304 
306 SparseBoolMatrix::reshape (const dim_vector& new_dims) const
307 {
308  return Sparse<bool>::reshape (new_dims);
309 }
310 
313 {
314  return Sparse<bool>::permute (vec, inv);
315 }
316 
319 {
320  return Sparse<bool>::ipermute (vec);
321 }
322 
325 
328 
#define SPARSE_SSM_BOOL_OPS(S, M)
#define SPARSE_SMS_EQNE_OPS(M, S)
#define SPARSE_SSM_EQNE_OPS(S, M)
#define SPARSE_SMSM_EQNE_OPS(M1, M2)
#define SPARSE_SMSM_BOOL_OPS(M1, M2)
#define SPARSE_SMS_BOOL_OPS(M, S)
#define SPARSE_ALL_OP(DIM)
std::ostream & operator<<(std::ostream &os, const SparseBoolMatrix &a)
Definition: boolSparse.cc:262
std::istream & operator>>(std::istream &is, SparseBoolMatrix &a)
Definition: boolSparse.cc:279
T & elem(octave_idx_type n)
Size of the specified dimension.
Definition: Array.h:562
T * fortran_vec()
Size of the specified dimension.
Definition: Array-base.cc:1764
T & xelem(octave_idx_type n)
Size of the specified dimension.
Definition: Array.h:524
SparseBoolMatrix & insert(const SparseBoolMatrix &a, octave_idx_type r, octave_idx_type c)
Definition: boolSparse.cc:77
SparseBoolMatrix reshape(const dim_vector &new_dims) const
Definition: boolSparse.cc:306
SparseBoolMatrix ipermute(const Array< octave_idx_type > &vec) const
Definition: boolSparse.cc:318
SparseBoolMatrix permute(const Array< octave_idx_type > &vec, bool inv=false) const
Definition: boolSparse.cc:312
bool operator!=(const SparseBoolMatrix &a) const
Definition: boolSparse.cc:71
SparseBoolMatrix diag(octave_idx_type k=0) const
Definition: boolSparse.cc:242
SparseBoolMatrix index(const octave::idx_vector &i, bool resize_ok) const
Definition: boolSparse.cc:293
SparseBoolMatrix all(int dim=-1) const
Definition: boolSparse.cc:140
boolMatrix matrix_value() const
Definition: boolSparse.cc:248
SparseMatrix sum(int dim=-1) const
Definition: boolSparse.cc:192
SparseBoolMatrix operator!() const
Definition: boolSparse.cc:105
SparseBoolMatrix squeeze() const
Definition: boolSparse.cc:287
bool operator==(const SparseBoolMatrix &a) const
Definition: boolSparse.cc:47
SparseBoolMatrix any(int dim=-1) const
Definition: boolSparse.cc:146
SparseBoolMatrix concat(const SparseBoolMatrix &rb, const Array< octave_idx_type > &ra_idx)
Definition: boolSparse.cc:93
octave_idx_type cols() const
Definition: Sparse.h:352
Sparse< T, Alloc > diag(octave_idx_type k=0) const
Definition: Sparse.cc:2493
Sparse< T, Alloc > permute(const Array< octave_idx_type > &vec, bool inv=false) const
Definition: Sparse.cc:931
octave_idx_type * xcidx()
Definition: Sparse.h:602
Sparse< T, Alloc > squeeze() const
Definition: Sparse.h:373
T * xdata()
Definition: Sparse.h:576
Sparse< T, Alloc > index(const octave::idx_vector &i, bool resize_ok=false) const
Definition: Sparse.cc:1434
octave_idx_type * cidx()
Definition: Sparse.h:596
bool * data()
Definition: Sparse.h:574
octave_idx_type * ridx()
Definition: Sparse.h:583
Sparse< T, Alloc > & insert(const Sparse< T, Alloc > &a, octave_idx_type r, octave_idx_type c)
Definition: Sparse.cc:1044
bool element_type
Definition: Sparse.h:52
octave_idx_type nnz() const
Actual number of nonzero terms.
Definition: Sparse.h:339
octave_idx_type rows() const
Definition: Sparse.h:351
void change_capacity(octave_idx_type nz)
Definition: Sparse.h:556
Sparse< T, Alloc > ipermute(const Array< octave_idx_type > &vec) const
Definition: Sparse.h:545
Sparse< T, Alloc > reshape(const dim_vector &new_dims) const
Definition: Sparse.cc:848
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:94
octave::idx_vector idx_vector
Definition: idx-vector.h:1022
template bool read_value< bool >(std::istream &is)
T * r
Definition: mx-inlines.cc:781
const octave_base_value const Array< octave_idx_type > & ra_idx