boolSparse.cc

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 2004-2012 David Bateman
00004 Copyright (C) 1998-2004 Andy Adler
00005 Copyright (C) 2010 VZLU Prague
00006 
00007 This file is part of Octave.
00008 
00009 Octave is free software; you can redistribute it and/or modify it
00010 under the terms of the GNU General Public License as published by the
00011 Free Software Foundation; either version 3 of the License, or (at your
00012 option) any later version.
00013 
00014 Octave is distributed in the hope that it will be useful, but WITHOUT
00015 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00016 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00017 for more details.
00018 
00019 You should have received a copy of the GNU General Public License
00020 along with Octave; see the file COPYING.  If not, see
00021 <http://www.gnu.org/licenses/>.
00022 
00023 */
00024 
00025 #ifdef HAVE_CONFIG_H
00026 #include <config.h>
00027 #endif
00028 
00029 #include <iostream>
00030 #include <vector>
00031 
00032 #include "config.h"
00033 #include "quit.h"
00034 #include "lo-ieee.h"
00035 #include "lo-mappers.h"
00036 
00037 #include "boolSparse.h"
00038 #include "dSparse.h"
00039 #include "oct-mem.h"
00040 #include "oct-locbuf.h"
00041 
00042 // SparseBoolMatrix class.
00043 
00044 bool
00045 SparseBoolMatrix::operator == (const SparseBoolMatrix& a) const
00046 {
00047   octave_idx_type nr = rows ();
00048   octave_idx_type nc = cols ();
00049   octave_idx_type nz = nnz ();
00050   octave_idx_type nr_a = a.rows ();
00051   octave_idx_type nc_a = a.cols ();
00052   octave_idx_type nz_a = a.nnz ();
00053 
00054   if (nr != nr_a || nc != nc_a || nz != nz_a)
00055     return false;
00056 
00057   for (octave_idx_type i = 0; i < nc + 1; i++)
00058     if (cidx(i) != a.cidx(i))
00059         return false;
00060 
00061   for (octave_idx_type i = 0; i < nz; i++)
00062     if (data(i) != a.data(i) || ridx(i) != a.ridx(i))
00063       return false;
00064 
00065   return true;
00066 }
00067 
00068 bool
00069 SparseBoolMatrix::operator != (const SparseBoolMatrix& a) const
00070 {
00071   return !(*this == a);
00072 }
00073 
00074 SparseBoolMatrix&
00075 SparseBoolMatrix::insert (const SparseBoolMatrix& a, octave_idx_type r, octave_idx_type c)
00076 {
00077   Sparse<bool>::insert (a, r, c);
00078   return *this;
00079 }
00080 
00081 SparseBoolMatrix&
00082 SparseBoolMatrix::insert (const SparseBoolMatrix& a, const Array<octave_idx_type>& indx)
00083 {
00084   Sparse<bool>::insert (a, indx);
00085   return *this;
00086 }
00087 
00088 SparseBoolMatrix
00089 SparseBoolMatrix::concat (const SparseBoolMatrix& rb, const Array<octave_idx_type>& ra_idx)
00090 {
00091   // Don't use numel to avoid all possiblity of an overflow
00092   if (rb.rows () > 0 && rb.cols () > 0)
00093     insert (rb, ra_idx(0), ra_idx(1));
00094   return *this;
00095 }
00096 
00097 // unary operations
00098 
00099 SparseBoolMatrix
00100 SparseBoolMatrix::operator ! (void) const
00101 {
00102   octave_idx_type nr = rows ();
00103   octave_idx_type nc = cols ();
00104   octave_idx_type nz1 = nnz ();
00105   octave_idx_type nz2 = nr*nc - nz1;
00106 
00107   SparseBoolMatrix r (nr, nc, nz2);
00108 
00109   octave_idx_type ii = 0;
00110   octave_idx_type jj = 0;
00111   r.cidx (0) = 0;
00112   for (octave_idx_type i = 0; i < nc; i++)
00113     {
00114       for (octave_idx_type j = 0; j < nr; j++)
00115         {
00116           if (jj < cidx(i+1) && ridx(jj) == j)
00117             jj++;
00118           else
00119             {
00120               r.data(ii) = true;
00121               r.ridx(ii++) = j;
00122             }
00123         }
00124       r.cidx (i+1) = ii;
00125     }
00126 
00127   return r;
00128 }
00129 
00130 // other operations
00131 
00132 // FIXME Do these really belong here?  Maybe they should be
00133 // in a base class?
00134 
00135 SparseBoolMatrix
00136 SparseBoolMatrix::all (int dim) const
00137 {
00138   SPARSE_ALL_OP (dim);
00139 }
00140 
00141 SparseBoolMatrix
00142 SparseBoolMatrix::any (int dim) const
00143 {
00144   Sparse<bool> retval;
00145   octave_idx_type nr = rows (), nc = cols (), nz = nnz ();
00146   if (dim == -1)
00147     dim = (nr == 1 && nc != 1) ? 1 : 0;
00148 
00149   if (dim == 0)
00150     {
00151       // Result is a row vector.
00152       retval = Sparse<bool> (1, nc);
00153       retval.xcidx(0) = 0;
00154       for (octave_idx_type i = 0; i < nc; i++)
00155         retval.xcidx(i+1) = retval.xcidx(i) + (cidx(i+1) > cidx(i));
00156       octave_idx_type new_nz = retval.xcidx(nc);
00157       retval.change_capacity (new_nz);
00158       fill_or_memset (new_nz, static_cast<octave_idx_type> (0), retval.ridx ());
00159       fill_or_memset (new_nz, true, retval.data ());
00160     }
00161   else if (dim == 1)
00162     {
00163       // Result is a column vector.
00164       if (nz > nr/4)
00165         {
00166           // We can use O(nr) memory.
00167           Array<bool> tmp (dim_vector (nr, 1), false);
00168           for (octave_idx_type i = 0; i < nz; i++)
00169             tmp.xelem(ridx(i)) = true;
00170           retval = tmp;
00171         }
00172       else
00173         {
00174           Array<octave_idx_type> tmp (dim_vector (nz, 1));
00175           copy_or_memcpy (nz, ridx (), tmp.fortran_vec ());
00176           retval = Sparse<bool> (Array<bool> (dim_vector (1, 1), true),
00177                                  idx_vector (tmp),
00178                                  idx_vector (static_cast<octave_idx_type> (0)),
00179                                  nr, 1, false);
00180         }
00181     }
00182 
00183   return retval;
00184 }
00185 
00186 SparseMatrix
00187 SparseBoolMatrix::sum (int dim) const
00188 {
00189   Sparse<double> retval;
00190   octave_idx_type nr = rows (), nc = cols (), nz = nnz ();
00191   if (dim == -1)
00192     dim = (nr == 1 && nc != 1) ? 1 : 0;
00193 
00194   if (dim == 0)
00195     {
00196       // Result is a row vector.
00197       retval = Sparse<double> (1, nc);
00198       for(octave_idx_type i = 0; i < nc; i++)
00199         retval.xcidx(i+1) = retval.xcidx(i) + (cidx(i+1) > cidx(i));
00200       octave_idx_type new_nz = retval.xcidx(nc);
00201       retval.change_capacity (new_nz);
00202       fill_or_memset (new_nz, static_cast<octave_idx_type> (0), retval.ridx ());
00203       for(octave_idx_type i = 0, k = 0; i < nc; i++)
00204         {
00205           octave_idx_type c = cidx(i+1) - cidx(i);
00206           if (c > 0)
00207             retval.xdata(k++) = c;
00208         }
00209     }
00210   else if (dim == 1)
00211     {
00212       // Result is a column vector.
00213       if (nz > nr)
00214         {
00215           // We can use O(nr) memory.
00216           Array<double> tmp (dim_vector (nr, 1), 0);
00217           for (octave_idx_type i = 0; i < nz; i++)
00218             tmp.xelem(ridx(i)) += 1.0;
00219           retval = tmp;
00220         }
00221       else
00222         {
00223           Array<octave_idx_type> tmp (dim_vector (nz, 1));
00224           copy_or_memcpy (nz, ridx (), tmp.fortran_vec ());
00225           retval = Sparse<double> (Array<double> (dim_vector (1, 1), 1.0),
00226                                    idx_vector (tmp),
00227                                    idx_vector (static_cast<octave_idx_type> (0)),
00228                                    nr, 1);
00229         }
00230     }
00231 
00232   return retval;
00233 }
00234 
00235 SparseBoolMatrix
00236 SparseBoolMatrix::diag (octave_idx_type k) const
00237 {
00238   return Sparse<bool>::diag (k);
00239 }
00240 
00241 boolMatrix
00242 SparseBoolMatrix::matrix_value (void) const
00243 {
00244   octave_idx_type nr = rows ();
00245   octave_idx_type nc = cols ();
00246 
00247   boolMatrix retval (nr, nc, false);
00248   for (octave_idx_type j = 0; j < nc; j++)
00249     for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
00250       retval.elem (ridx(i), j) = data (i);
00251 
00252   return retval;
00253 }
00254 
00255 std::ostream&
00256 operator << (std::ostream& os, const SparseBoolMatrix& a)
00257 {
00258   octave_idx_type nc = a.cols ();
00259 
00260    // add one to the printed indices to go from
00261    //  zero-based to one-based arrays
00262    for (octave_idx_type j = 0; j < nc; j++)
00263      {
00264        octave_quit ();
00265        for (octave_idx_type i = a.cidx(j); i < a.cidx(j+1); i++)
00266          os << a.ridx(i) + 1 << " "  << j + 1 << " " << a.data(i) << "\n";
00267      }
00268 
00269   return os;
00270 }
00271 
00272 std::istream&
00273 operator >> (std::istream& is, SparseBoolMatrix& a)
00274 {
00275   typedef SparseBoolMatrix::element_type elt_type;
00276 
00277   return read_sparse_matrix<elt_type> (is, a, octave_read_value<bool>);
00278 }
00279 
00280 SparseBoolMatrix
00281 SparseBoolMatrix::squeeze (void) const
00282 {
00283   return Sparse<bool>::squeeze ();
00284 }
00285 
00286 SparseBoolMatrix
00287 SparseBoolMatrix::index (const idx_vector& i, bool resize_ok) const
00288 {
00289   return Sparse<bool>::index (i, resize_ok);
00290 }
00291 
00292 SparseBoolMatrix
00293 SparseBoolMatrix::index (const idx_vector& i, const idx_vector& j, bool resize_ok) const
00294 {
00295   return Sparse<bool>::index (i, j, resize_ok);
00296 }
00297 
00298 SparseBoolMatrix
00299 SparseBoolMatrix::reshape (const dim_vector& new_dims) const
00300 {
00301   return Sparse<bool>::reshape (new_dims);
00302 }
00303 
00304 SparseBoolMatrix
00305 SparseBoolMatrix::permute (const Array<octave_idx_type>& vec, bool inv) const
00306 {
00307   return Sparse<bool>::permute (vec, inv);
00308 }
00309 
00310 SparseBoolMatrix
00311 SparseBoolMatrix::ipermute (const Array<octave_idx_type>& vec) const
00312 {
00313   return Sparse<bool>::ipermute (vec);
00314 }
00315 
00316 SPARSE_SMS_EQNE_OPS (SparseBoolMatrix, false, , bool, false, )
00317 SPARSE_SMS_BOOL_OPS (SparseBoolMatrix, bool, false)
00318 
00319 SPARSE_SSM_EQNE_OPS (bool, false, , SparseBoolMatrix, false, )
00320 SPARSE_SSM_BOOL_OPS (bool, SparseBoolMatrix, false)
00321 
00322 SPARSE_SMSM_EQNE_OPS (SparseBoolMatrix, false, , SparseBoolMatrix, false, )
00323 SPARSE_SMSM_BOOL_OPS (SparseBoolMatrix, SparseBoolMatrix, false)
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines